diff --git a/CHANGELOG.md b/CHANGELOG.md index 835eb5fc..18192632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ * [UIQM-558](https://issues.folio.org/browse/UIQM-558) *BREAKING* bump `react-intl` to `v6.4.4`. * [UIQM-559](https://issues.folio.org/browse/UIQM-559) Make auto-linking for the consortium. * [UIQM-558](https://issues.folio.org/browse/UIQM-558) Allow a user to select a location code from the plugin. +* [UIQM-431](https://issues.folio.org/browse/UIQM-431) Marc record fixed field 008 with proper order. ## [6.0.2](https://github.com/folio-org/ui-quick-marc/tree/v6.0.2) (2023-03-30) diff --git a/src/QuickMarcEditor/QuickMarcCreateWrapper.js b/src/QuickMarcEditor/QuickMarcCreateWrapper.js index ce1e2bba..318ec453 100644 --- a/src/QuickMarcEditor/QuickMarcCreateWrapper.js +++ b/src/QuickMarcEditor/QuickMarcCreateWrapper.js @@ -39,6 +39,7 @@ const propTypes = { location: ReactRouterPropTypes.location.isRequired, locations: PropTypes.object.isRequired, marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + marcSpec: PropTypes.object.isRequired, mutator: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, }; @@ -52,6 +53,7 @@ const QuickMarcCreateWrapper = ({ history, location, marcType, + marcSpec, locations, }) => { const showCallout = useShowCallout(); @@ -67,11 +69,11 @@ const QuickMarcCreateWrapper = ({ autopopulatePhysDescriptionField, autopopulateMaterialCharsField, marcRecord => autopopulateSubfieldSection(marcRecord, marcType), - marcRecord => cleanBytesFields(marcRecord, marcType), + marcRecord => cleanBytesFields(marcRecord, marcSpec), )(formValues); return formValuesForCreate; - }, [marcType]); + }, [marcType, marcSpec]); const validate = useCallback((formValues) => { const formValuesForValidation = prepareForSubmit(formValues); @@ -182,6 +184,7 @@ const QuickMarcCreateWrapper = ({ onSubmit={onSubmit} action={action} marcType={marcType} + marcSpec={marcSpec} httpError={httpError} validate={validate} /> diff --git a/src/QuickMarcEditor/QuickMarcDeriveWrapper.js b/src/QuickMarcEditor/QuickMarcDeriveWrapper.js index d863304b..425af3eb 100644 --- a/src/QuickMarcEditor/QuickMarcDeriveWrapper.js +++ b/src/QuickMarcEditor/QuickMarcDeriveWrapper.js @@ -36,6 +36,7 @@ const propTypes = { initialValues: PropTypes.object.isRequired, instance: PropTypes.object, marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + marcSpec: PropTypes.object.isRequired, mutator: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, }; @@ -47,6 +48,7 @@ const QuickMarcDeriveWrapper = ({ initialValues, mutator, marcType, + marcSpec, }) => { const showCallout = useShowCallout(); const { linkableBibFields, actualizeLinks, linkingRules } = useAuthorityLinking({ marcType, action }); @@ -62,11 +64,11 @@ const QuickMarcDeriveWrapper = ({ autopopulatePhysDescriptionField, autopopulateMaterialCharsField, marcRecord => autopopulateSubfieldSection(marcRecord, marcType), - marcRecord => cleanBytesFields(marcRecord, marcType), + marcRecord => cleanBytesFields(marcRecord, marcSpec), )(formValues); return formValuesForDerive; - }, [marcType]); + }, [marcType, marcSpec]); const validate = useCallback((formValues) => { const formValuesForValidation = prepareForSubmit(formValues); @@ -157,6 +159,7 @@ const QuickMarcDeriveWrapper = ({ onSubmit={onSubmit} action={action} marcType={marcType} + marcSpec={marcSpec} httpError={httpError} confirmRemoveAuthorityLinking validate={validate} diff --git a/src/QuickMarcEditor/QuickMarcEditWrapper.js b/src/QuickMarcEditor/QuickMarcEditWrapper.js index 91d966af..79a534eb 100644 --- a/src/QuickMarcEditor/QuickMarcEditWrapper.js +++ b/src/QuickMarcEditor/QuickMarcEditWrapper.js @@ -50,6 +50,7 @@ const propTypes = { initialValues: PropTypes.object.isRequired, instance: PropTypes.object, marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + marcSpec: PropTypes.object.isRequired, mutator: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, onCheckCentralTenantPerm: PropTypes.func, @@ -63,6 +64,7 @@ const QuickMarcEditWrapper = ({ initialValues, mutator, marcType, + marcSpec, linksCount, locations, refreshPageData, @@ -140,7 +142,7 @@ const QuickMarcEditWrapper = ({ autopopulatePhysDescriptionField, autopopulateMaterialCharsField, marcRecord => autopopulateSubfieldSection(marcRecord, marcType), - marcRecord => cleanBytesFields(marcRecord, marcType), + marcRecord => cleanBytesFields(marcRecord, marcSpec), combineSplitFields, )(formValues); @@ -232,6 +234,7 @@ const QuickMarcEditWrapper = ({ initialValues, instance, marcType, + marcSpec, mutator, linksCount, location, @@ -253,6 +256,7 @@ const QuickMarcEditWrapper = ({ onSubmit={onSubmit} action={action} marcType={marcType} + marcSpec={marcSpec} locations={locations} httpError={httpError} externalRecordPath={externalRecordPath} diff --git a/src/QuickMarcEditor/QuickMarcEditor.js b/src/QuickMarcEditor/QuickMarcEditor.js index 2843531c..f167c7c2 100644 --- a/src/QuickMarcEditor/QuickMarcEditor.js +++ b/src/QuickMarcEditor/QuickMarcEditor.js @@ -91,6 +91,7 @@ const QuickMarcEditor = ({ getState, }, marcType, + marcSpec, locations, httpError, externalRecordPath, @@ -125,8 +126,8 @@ const QuickMarcEditor = ({ }, [records]); const leader = records[0]; - const type = leader?.content?.[6]; - const subtype = leader?.content?.[7]; + const type = leader?.content?.[6] || ''; + const subtype = leader?.content?.[7] || ''; const saveFormDisabled = action === QUICK_MARC_ACTIONS.EDIT ? pristine || submitting @@ -475,6 +476,7 @@ const QuickMarcEditor = ({ type={type} subtype={subtype} marcType={marcType} + marcSpec={marcSpec} instance={instance} linksCount={linksCount} isLoadingLinkSuggestions={isLoadingLinkSuggestions} @@ -551,6 +553,7 @@ QuickMarcEditor.propTypes = { reset: PropTypes.func.isRequired, }), marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + marcSpec: PropTypes.object.isRequired, linksCount: PropTypes.number, locations: PropTypes.arrayOf(PropTypes.object).isRequired, httpError: PropTypes.shape({ diff --git a/src/QuickMarcEditor/QuickMarcEditorContainer.js b/src/QuickMarcEditor/QuickMarcEditorContainer.js index e02792c2..2debb36b 100644 --- a/src/QuickMarcEditor/QuickMarcEditorContainer.js +++ b/src/QuickMarcEditor/QuickMarcEditorContainer.js @@ -25,6 +25,7 @@ import { MARC_RECORD_STATUS_API, MARC_TYPES, LINKING_RULES_API, + MARC_SPEC_API, } from '../common/constants'; import { @@ -85,6 +86,7 @@ const QuickMarcEditorContainer = ({ const [locations, setLocations] = useState(); const [isLoading, setIsLoading] = useState(true); const [linksCount, setLinksCount] = useState(0); + const [marcSpec, setMarcSpec] = useState(); const searchParams = new URLSearchParams(location.search); const { token, locale } = stripes.okapi; @@ -146,8 +148,27 @@ const QuickMarcEditorContainer = ({ ? fetchLinksCount([externalId]) : Promise.resolve(); - await Promise.all([instancePromise, marcRecordPromise, locationsPromise, linksCountPromise, linkingRulesPromise]) - .then(([instanceResponse, marcRecordResponse, locationsResponse, linksCountResponse, linkingRulesResponse]) => { + const marcSpecPromise = mutator.marcSpec.GET({ + path: `${MARC_SPEC_API}/${marcType}/008`, + ...headers, + }); + + await Promise.all([ + instancePromise, + marcRecordPromise, + locationsPromise, + linksCountPromise, + linkingRulesPromise, + marcSpecPromise, + ]) + .then(([ + instanceResponse, + marcRecordResponse, + locationsResponse, + linksCountResponse, + linkingRulesResponse, + marcSpecResponse, + ]) => { if (marcType === MARC_TYPES.AUTHORITY) { setLinksCount(linksCountResponse.links[0].totalLinks); } @@ -165,7 +186,7 @@ const QuickMarcEditorContainer = ({ if (action === QUICK_MARC_ACTIONS.CREATE) { dehydratedMarcRecord = createRecordDefaults[marcType](instanceResponse); } else { - dehydratedMarcRecord = dehydrateMarcRecordResponse(marcRecordResponse, marcType); + dehydratedMarcRecord = dehydrateMarcRecordResponse(marcRecordResponse, marcType, marcSpecResponse); } const formattedMarcRecord = formatMarcRecordByQuickMarcAction(dehydratedMarcRecord, action, marcType); @@ -175,6 +196,7 @@ const QuickMarcEditorContainer = ({ setInstance(instanceResponse); setMarcRecord(marcRecordWithSplitFields); setLocations(locationsResponse); + setMarcSpec(marcSpecResponse); setIsLoading(false); }) .catch(() => { @@ -219,6 +241,7 @@ const QuickMarcEditorContainer = ({ location={location} locations={locations} marcType={marcType} + marcSpec={marcSpec} refreshPageData={loadData} externalRecordPath={externalRecordUrl} resources={resources} @@ -263,6 +286,13 @@ QuickMarcEditorContainer.manifest = Object.freeze({ path: LINKING_RULES_API, throwErrors: false, }, + marcSpec: { + type: 'okapi', + fetch: false, + accumulate: true, + path: MARC_SPEC_API, + throwErrors: false, + }, }); QuickMarcEditorContainer.propTypes = propTypes; diff --git a/src/QuickMarcEditor/QuickMarcEditorContainer.test.js b/src/QuickMarcEditor/QuickMarcEditorContainer.test.js index 7ea32a09..99a7fb43 100644 --- a/src/QuickMarcEditor/QuickMarcEditorContainer.test.js +++ b/src/QuickMarcEditor/QuickMarcEditorContainer.test.js @@ -133,6 +133,9 @@ describe('Given Quick Marc Editor Container', () => { linkingRules: { GET: jest.fn().mockResolvedValue([]), }, + marcSpec: { + GET: jest.fn(() => Promise.resolve()), + }, }; applyCentralTenantInHeaders.mockReturnValue(false); diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/BytesField/BytesField.js b/src/QuickMarcEditor/QuickMarcEditorRows/BytesField/BytesField.js index 1cae81b0..37a38743 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/BytesField/BytesField.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/BytesField/BytesField.js @@ -7,6 +7,7 @@ import { FormattedMessage } from 'react-intl'; import { Label, TextField, + Tooltip, Select, } from '@folio/stripes/components'; @@ -24,6 +25,8 @@ export const SUBFIELD_TYPES = { const renderSubField = (name, config) => { const fieldName = `${name}.${config.name}`; const label = ; + const hint = config.hint ? config.hint : config.name; + const labelHint = ; const defaultValue = new Array(config.length || 1).fill('\\').join(''); if (config.type === SUBFIELD_TYPES.BYTES) { @@ -45,19 +48,30 @@ const renderSubField = (name, config) => { id={`ui-quick-marc.record.fixedField.${config.name}`} > {([ariaLabel]) => ( - value || defaultValue} - defaultValue={defaultValue} - /> + + + {({ ref, ariaIds }) => ( + value || defaultValue} + defaultValue={defaultValue} + /> + )} + )} ); @@ -92,19 +106,29 @@ const renderSubField = (name, config) => { return ( {([ariaLabel]) => ( - + + {({ ref, ariaIds }) => ( + + )} + )} ); diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/AuthorityFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/AuthorityFixedField.js index 0dcf8bdb..4c6153bc 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/AuthorityFixedField.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/AuthorityFixedField.js @@ -3,91 +3,9 @@ import PropTypes from 'prop-types'; import { BytesField, - SUBFIELD_TYPES, } from '../BytesField'; -const config = { - fields: [ - { - name: 'Geo Subd', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Roman', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Lang', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Kind rec', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Cat Rules', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'SH Sys', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Series', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Numb Series', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Main use', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Subj use', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Series use', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Type Subd', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Govt Ag', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'RefEval', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'RecUpd', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Pers Name', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Level Est', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Mod Rec Est', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Source', - type: SUBFIELD_TYPES.BYTE, - }, - ], -}; - -const AuthorityFixedField = ({ name }) => { +const AuthorityFixedField = ({ name, config }) => { return ( { AuthorityFixedField.propTypes = { name: PropTypes.string.isRequired, + config: PropTypes.object.isRequired, }; AuthorityFixedField.displayName = 'AuthorityFixedField'; -AuthorityFixedField.configFields = config.fields; export default AuthorityFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BibliographicFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BibliographicFixedField.js new file mode 100644 index 00000000..ef9227fe --- /dev/null +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BibliographicFixedField.js @@ -0,0 +1,24 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { + BytesField, +} from '../BytesField'; + +const BibliographicFixedField = ({ name, config }) => { + return ( + + ); +}; + +BibliographicFixedField.propTypes = { + name: PropTypes.string.isRequired, + config: PropTypes.object.isRequired, +}; + +BibliographicFixedField.displayName = 'BibliographicFixedField'; + +export default BibliographicFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BookFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BookFixedField.js deleted file mode 100644 index 36dd8816..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BookFixedField.js +++ /dev/null @@ -1,104 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - type: SUBFIELD_TYPES.BYTE, - name: 'Srce', - }, - { - name: 'Audn', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.STRING, - name: 'Lang', - length: 3, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Form', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Conf', - }, - { - name: 'Biog', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'MRec', - }, - { - name: 'Ctry', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Cont', - type: SUBFIELD_TYPES.BYTES, - bytes: 4, - }, - { - name: 'GPub', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'LitF', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Indx', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Ills', - type: SUBFIELD_TYPES.BYTES, - bytes: 4, - }, - { - name: 'Fest', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'DtSt', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const BookFixedField = ({ name }) => { - return ( - - ); -}; - -BookFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -BookFixedField.displayName = 'BookFixedField'; -BookFixedField.configFields = config.fields; - -export default BookFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ComputerFileFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ComputerFileFixedField.js deleted file mode 100644 index 91291e7b..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ComputerFileFixedField.js +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - type: SUBFIELD_TYPES.BYTE, - name: 'Srce', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Audn', - }, - { - type: SUBFIELD_TYPES.STRING, - name: 'Lang', - length: 3, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Form', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'GPub', - }, - { - name: 'MRec', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Ctry', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'File', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'DtSt', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const ComputerFileFixedField = ({ name }) => { - return ( - - ); -}; - -ComputerFileFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -ComputerFileFixedField.displayName = 'ComputerFileFixedField'; -ComputerFileFixedField.configFields = config.fields; - -export default ComputerFileFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ContinuingResourceFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ContinuingResourceFixedField.js deleted file mode 100644 index 9630b7b4..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ContinuingResourceFixedField.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - type: SUBFIELD_TYPES.BYTE, - name: 'Srce', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'GPub', - }, - { - type: SUBFIELD_TYPES.STRING, - name: 'Lang', - length: 3, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Form', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Conf', - }, - { - name: 'Freq', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'MRec', - }, - { - type: SUBFIELD_TYPES.STRING, - name: 'Ctry', - length: 3, - }, - { - name: 'S/L', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Orig', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'EntW', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Regl', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Alph', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'SrTp', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Cont', - type: SUBFIELD_TYPES.BYTES, - bytes: 3, - }, - { - name: 'DtSt', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const ContinuingResourceFixedField = ({ name }) => { - return ( - - ); -}; - -ContinuingResourceFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -ContinuingResourceFixedField.displayName = 'ContinuingResourceFixedField'; -ContinuingResourceFixedField.configFields = config.fields; - -export default ContinuingResourceFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js index 855af0b3..ef59ee3a 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js @@ -1,54 +1,28 @@ import React from 'react'; import { MARC_TYPES } from '../../../common/constants'; +import { LEADER_TAG } from '../../constants'; +import { + SUBFIELD_TYPES, +} from '../BytesField'; -import BookFixedField from './BookFixedField'; -import ComputerFileFixedField from './ComputerFileFixedField'; -import ContinuingResourceFixedField from './ContinuingResourceFixedField'; -import MapFixedField from './MapFixedField'; -import MixedMaterialFixedField from './MixedMaterialFixedField'; -import ScoreFixedField from './ScoreFixedField'; -import SoundRecordingFixedField from './SoundRecordingFixedField'; -import VisualMaterialFixedField from './VisualMaterialFixedField'; import HoldingsFixedField from './HoldingsFixedField'; import AuthorityFixedField from './AuthorityFixedField'; +import BibliographicFixedField from './BibliographicFixedField'; export const FixedFieldFactory = { - getFixedFieldByType(marcType, type, subtype) { + getFixedFieldByType(marcType) { let FixedField; - switch (true) { - case marcType === MARC_TYPES.HOLDINGS: + switch (marcType) { + case MARC_TYPES.HOLDINGS: FixedField = HoldingsFixedField; break; - case marcType === MARC_TYPES.AUTHORITY: + case MARC_TYPES.AUTHORITY: FixedField = AuthorityFixedField; break; - case type === 'a' && ['b', 'i', 's'].includes(subtype): - case type === 's': - FixedField = ContinuingResourceFixedField; - break; - case type === 'a' && ['a', 'c', 'd', 'm'].includes(subtype): - case type === 't': - FixedField = BookFixedField; - break; - case type === 'm': - FixedField = ComputerFileFixedField; - break; - case ['e', 'f'].includes(type): - FixedField = MapFixedField; - break; - case type === 'p': - FixedField = MixedMaterialFixedField; - break; - case ['c', 'd'].includes(type): - FixedField = ScoreFixedField; - break; - case ['i', 'j'].includes(type): - FixedField = SoundRecordingFixedField; - break; - case ['g', 'k', 'o', 'r'].includes(type): - FixedField = VisualMaterialFixedField; + case MARC_TYPES.BIB: + FixedField = BibliographicFixedField; break; default: FixedField = null; @@ -56,9 +30,83 @@ export const FixedFieldFactory = { return FixedField; }, - getFixedField(name, marcType, type, subtype) { - const FixedField = this.getFixedFieldByType(marcType, type, subtype); - return FixedField ? : null; + getDocumentType(marcSpec, type, subtype) { + let idx = -1; + + if (!marcSpec?.spec) { + return undefined; + } + + const checkTypeSubType = (orElement) => { + const hasTypePos = orElement.positions['6'] || false; + const hasSubTypePos = orElement.positions['7'] || false; + const typeOK = hasTypePos && orElement.positions['6'].includes(type); + const subTypeOK = hasSubTypePos ? hasSubTypePos && orElement.positions['7'].includes(subtype) : true; + + return (typeOK && subTypeOK); + }; + + marcSpec.spec.types.forEach((marcType, indexType) => { + marcType.identifiedBy.or.forEach(orElement => { + if (orElement.tag === LEADER_TAG) { + if (checkTypeSubType(orElement)) { + idx = indexType; + } + } + }); + }); + + return idx !== -1 ? marcSpec.spec.types[idx] : undefined; + }, + + getConfigFixedField(marcSpec, type, subtype = '') { + const documentType = this.getDocumentType(marcSpec, type, subtype); + const config = { + fields: [], + type: documentType?.code || undefined, + }; + + if (!documentType) { + return config; + } + + config.fields = documentType.items.filter(x => !x.readOnly).map((item) => { + if (item.isArray) { + return { + name: item.code, + hint: item.name, + type: SUBFIELD_TYPES.BYTES, + bytes: item.length, + position: item.position, + }; + } + + if (!item.isArray && item.length > 1) { + return { + name: item.code, + hint: item.name, + type: SUBFIELD_TYPES.STRING, + length: item.length, + position: item.position, + }; + } + + return { + name: item.code, + hint: item.name, + type: SUBFIELD_TYPES.BYTE, + position: item.position, + }; + }); + + return config; + }, + + getFixedField(name, marcType, marcSpec, type, subtype) { + const FixedField = this.getFixedFieldByType(marcType); + const configFixedField = this.getConfigFixedField(marcSpec, type, subtype); + + return FixedField ? : null; }, }; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js index 00ca8dbe..ec7e96da 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js @@ -2,72 +2,120 @@ import '@folio/stripes-acq-components/test/jest/__mock__'; import { FixedFieldFactory } from './FixedFieldFactory'; -import BookFixedField from './BookFixedField'; -import ComputerFileFixedField from './ComputerFileFixedField'; -import ContinuingResourceFixedField from './ContinuingResourceFixedField'; -import MapFixedField from './MapFixedField'; -import MixedMaterialFixedField from './MixedMaterialFixedField'; -import ScoreFixedField from './ScoreFixedField'; -import SoundRecordingFixedField from './SoundRecordingFixedField'; -import VisualMaterialFixedField from './VisualMaterialFixedField'; +import BibliographicFixedField from './BibliographicFixedField'; import HoldingsFixedField from './HoldingsFixedField'; import AuthorityFixedField from './AuthorityFixedField'; import { MARC_TYPES } from '../../../common/constants'; +import marcSpecificationBib from '../../../../test/mocks/marcSpecificationBib'; +import marcSpecificationAuth from '../../../../test/mocks/marcSpecificationAuth'; +import marcSpecificationHold from '../../../../test/mocks/marcSpecificationHold'; describe('FixedFieldFactory', () => { - it('should create correct fields', () => { + it('should create correct marc type fixed field', () => { expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'a', 'm').type.displayName, - ).toBe(BookFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB).type.displayName, + ).toBe(BibliographicFixedField.displayName); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 't').type.displayName, - ).toBe(BookFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.AUTHORITY).type.displayName, + ).toBe(AuthorityFixedField.displayName); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.HOLDINGS, 't').type.displayName, + FixedFieldFactory.getFixedField('records', MARC_TYPES.HOLDINGS).type.displayName, ).toBe(HoldingsFixedField.displayName); + }); + it('should create correct document type', () => { expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'm').type.displayName, - ).toBe(ComputerFileFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 'm').props.config.type, + ).toBe('books'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'a', 's').type.displayName, - ).toBe(ContinuingResourceFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 'a').props.config.type, + ).toBe('books'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 's').type.displayName, - ).toBe(ContinuingResourceFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 'd').props.config.type, + ).toBe('books'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'f').type.displayName, - ).toBe(MapFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 'x').props.config.type, + ).toBe(undefined); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'p').type.displayName, - ).toBe(MixedMaterialFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 't').props.config.type, + ).toBe('books'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'c').type.displayName, - ).toBe(ScoreFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'c').props.config.type, + ).toBe('scores'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'i').type.displayName, - ).toBe(SoundRecordingFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'i').props.config.type, + ).toBe('sound_recordings'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'r').type.displayName, - ).toBe(VisualMaterialFixedField.displayName); + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 'b').props.config.type, + ).toBe('continuing_resources'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.AUTHORITY).type.displayName, + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 'i').props.config.type, + ).toBe('continuing_resources'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'a', 's').props.config.type, + ).toBe('continuing_resources'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 's').props.config.type, + ).toBe('continuing_resources'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'm').props.config.type, + ).toBe('computer_files'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'g').props.config.type, + ).toBe('visual_materials'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'e').props.config.type, + ).toBe('maps'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'f').props.config.type, + ).toBe('maps'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'p').props.config.type, + ).toBe('mixed_materials'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.AUTHORITY, marcSpecificationAuth, 'z').props.config.type, + ).toBe('unknown'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.AUTHORITY, marcSpecificationAuth, 'z').type.displayName, ).toBe(AuthorityFixedField.displayName); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.HOLDINGS, marcSpecificationHold, 'u').props.config.type, + ).toBe('unknown'); + + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.HOLDINGS, marcSpecificationHold, 'u').type.displayName, + ).toBe(HoldingsFixedField.displayName); + }); + + it('should return undefined type when there is no matched field', () => { + expect( + FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, marcSpecificationBib, 'l').props.config.type, + ).toBe(undefined); }); - it('should return null when there is no matched field', () => { + it('should return null when marc types is wrong', () => { expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'l'), + FixedFieldFactory.getFixedField('records', 'instance', marcSpecificationBib, 'l'), ).toBe(null); }); }); diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js index 3e9f9fb0..3762d560 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js @@ -3,69 +3,9 @@ import PropTypes from 'prop-types'; import { BytesField, - SUBFIELD_TYPES, } from '../BytesField'; -const config = { - fields: [ - { - name: 'AcqStatus', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'AcqMethod', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'AcqEndDate', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Gen ret', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Spec ret', - type: SUBFIELD_TYPES.BYTES, - bytes: 3, - }, - { - name: 'Compl', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Copies', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Lend', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Repro', - type: SUBFIELD_TYPES.STRING, - length: 1, - }, - { - name: 'Lang', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Sep/comp', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Rept date', - type: SUBFIELD_TYPES.STRING, - length: 6, - }, - ], -}; - -const HoldingsFixedField = ({ name }) => { +const HoldingsFixedField = ({ name, config }) => { return ( { HoldingsFixedField.propTypes = { name: PropTypes.string.isRequired, + config: PropTypes.object.isRequired, }; HoldingsFixedField.displayName = 'HoldingsFixedField'; -HoldingsFixedField.configFields = config.fields; export default HoldingsFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MapFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MapFixedField.js deleted file mode 100644 index 1ca032e1..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MapFixedField.js +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - name: 'Srce', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Relf', - type: SUBFIELD_TYPES.BYTES, - bytes: 4, - }, - { - name: 'Lang', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Form', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'GPub', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'SpFm', - type: SUBFIELD_TYPES.BYTES, - bytes: 2, - }, - { - name: 'MRec', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Ctry', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'CrTp', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Indx', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Proj', - type: SUBFIELD_TYPES.BYTES, - bytes: 2, - }, - { - name: 'DtSt', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const MapFixedField = ({ name }) => { - return ( - - ); -}; - -MapFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -MapFixedField.displayName = 'MapFixedField'; -MapFixedField.configFields = config.fields; - -export default MapFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MixedMaterialFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MixedMaterialFixedField.js deleted file mode 100644 index 5b220724..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MixedMaterialFixedField.js +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - name: 'Srce', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Lang', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Form', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'MRec', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Ctry', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'DtSt', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const MixedMaterialFixedField = ({ name }) => { - return ( - - ); -}; - -MixedMaterialFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -MixedMaterialFixedField.displayName = 'MixedMaterialFixedField'; -MixedMaterialFixedField.configFields = config.fields; - -export default MixedMaterialFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ScoreFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ScoreFixedField.js deleted file mode 100644 index 33c16d19..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ScoreFixedField.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - name: 'Srce', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Audn', - }, - { - type: SUBFIELD_TYPES.STRING, - name: 'Lang', - length: 3, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Form', - }, - { - name: 'Comp', - type: SUBFIELD_TYPES.STRING, - length: 2, - }, - { - type: SUBFIELD_TYPES.BYTES, - name: 'AccM', - bytes: 6, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'MRec', - }, - { - type: SUBFIELD_TYPES.STRING, - name: 'Ctry', - length: 3, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Part', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'TrAr', - }, - { - name: 'FMus', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.BYTES, - name: 'LTxt', - bytes: 2, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'DtSt', - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const ScoreFixedField = ({ name }) => { - return ( - - ); -}; - -ScoreFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -ScoreFixedField.displayName = 'ScoreFixedField'; -ScoreFixedField.configFields = config.fields; - -export default ScoreFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/SoundRecordingFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/SoundRecordingFixedField.js deleted file mode 100644 index 4b124671..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/SoundRecordingFixedField.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - type: SUBFIELD_TYPES.BYTE, - name: 'Srce', - }, - { - name: 'Audn', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Lang', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Form', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Comp', - type: SUBFIELD_TYPES.STRING, - length: 2, - }, - { - name: 'AccM', - type: SUBFIELD_TYPES.BYTES, - bytes: 6, - }, - { - name: 'MRec', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Ctry', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Part', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'TrAr', - }, - { - name: 'FMus', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'LTxt', - type: SUBFIELD_TYPES.BYTES, - bytes: 2, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'DtSt', - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const SoundRecordingFixedField = ({ name }) => { - return ( - - ); -}; - -SoundRecordingFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -SoundRecordingFixedField.displayName = 'SoundRecordingFixedField'; -SoundRecordingFixedField.configFields = config.fields; - -export default SoundRecordingFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/VisualMaterialFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/VisualMaterialFixedField.js deleted file mode 100644 index 0ff12976..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/VisualMaterialFixedField.js +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { - BytesField, - SUBFIELD_TYPES, -} from '../BytesField'; - -const config = { - fields: [ - { - type: SUBFIELD_TYPES.BYTE, - name: 'Srce', - }, - { - name: 'Audn', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Lang', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - name: 'Form', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'GPub', - type: SUBFIELD_TYPES.BYTE, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'MRec', - }, - { - name: 'Ctry', - type: SUBFIELD_TYPES.STRING, - length: 3, - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'Tech', - }, - { - type: SUBFIELD_TYPES.BYTE, - name: 'TMat', - }, - { - name: 'Time', - type: SUBFIELD_TYPES.BYTES, - bytes: 3, - }, - { - name: 'DtSt', - type: SUBFIELD_TYPES.BYTE, - }, - { - name: 'Date1', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - { - name: 'Date2', - type: SUBFIELD_TYPES.STRING, - length: 4, - }, - ], -}; - -const VisualMaterialFixedField = ({ name }) => { - return ( - - ); -}; - -VisualMaterialFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -VisualMaterialFixedField.displayName = 'VisualMaterialFixedField'; -VisualMaterialFixedField.configFields = config.fields; - -export default VisualMaterialFixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/index.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/index.js index 22f4b296..a5b285bb 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/index.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/index.js @@ -1,11 +1,5 @@ export * from './FixedFieldFactory'; -export { default as BookFixedField } from './BookFixedField'; -export { default as ComputerFileFixedField } from './ComputerFileFixedField'; -export { default as ContinuingResourceFixedField } from './ContinuingResourceFixedField'; -export { default as MapFixedField } from './MapFixedField'; -export { default as MixedMaterialFixedField } from './MixedMaterialFixedField'; -export { default as ScoreFixedField } from './ScoreFixedField'; -export { default as SoundRecordingFixedField } from './SoundRecordingFixedField'; -export { default as VisualMaterialFixedField } from './VisualMaterialFixedField'; export { default as AutorityFixedField } from './AuthorityFixedField'; +export { default as BibliographicFixedField } from './BibliographicFixedField'; +export { default as HoldingsFixedField } from './HoldingsFixedField'; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/BookMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/BookMaterialCharsFieldConfig.js index 9fd6031d..f85989c3 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/BookMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/BookMaterialCharsFieldConfig.js @@ -3,44 +3,54 @@ import { SUBFIELD_TYPES } from '../BytesField'; const BookMaterialCharsFieldConfig = [ { name: 'Ills', + hint: 'Illustrations', type: SUBFIELD_TYPES.BYTES, bytes: 4, }, { name: 'Audn', + hint: 'Target audience', type: SUBFIELD_TYPES.BYTE, }, { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, { name: 'Cont', + hint: 'Nature of contents', type: SUBFIELD_TYPES.BYTES, bytes: 4, }, { name: 'GPub', + hint: 'Government publication', type: SUBFIELD_TYPES.BYTE, }, { name: 'Conf', + hint: 'Conference publication', type: SUBFIELD_TYPES.BYTE, }, { name: 'Fest', + hint: 'Festschrift', type: SUBFIELD_TYPES.BYTE, }, { name: 'Indx', + hint: 'Index', type: SUBFIELD_TYPES.BYTE, }, { name: 'LitF', + hint: 'Literary form', type: SUBFIELD_TYPES.BYTE, }, { name: 'Biog', + hint: 'Biography', type: SUBFIELD_TYPES.BYTE, }, ]; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ComputerFileMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ComputerFileMaterialCharsFieldConfig.js index 68b4e42f..8207cb63 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ComputerFileMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ComputerFileMaterialCharsFieldConfig.js @@ -3,18 +3,22 @@ import { SUBFIELD_TYPES } from '../BytesField'; const ComputerFileMaterialCharsFieldConfig = [ { name: 'Audn', + hint: 'Target audience', type: SUBFIELD_TYPES.BYTE, }, { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, { name: 'File', + hint: 'Type of computer file', type: SUBFIELD_TYPES.BYTE, }, { name: 'GPub', + hint: 'Government publication', type: SUBFIELD_TYPES.BYTE, }, ]; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ContinuingMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ContinuingMaterialCharsFieldConfig.js index ddf948f7..95f15527 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ContinuingMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/ContinuingMaterialCharsFieldConfig.js @@ -3,47 +3,58 @@ import { SUBFIELD_TYPES } from '../BytesField'; const ContinuingMaterialCharsFieldConfig = [ { name: 'Regl', + hint: 'Regularity', type: SUBFIELD_TYPES.BYTE, }, { name: 'Freq', + hint: 'Frequency', type: SUBFIELD_TYPES.BYTE, }, { name: 'Orig', + hint: 'Form of original item', type: SUBFIELD_TYPES.BYTE, }, { name: 'EntW', + hint: 'Nature of entire work', type: SUBFIELD_TYPES.BYTE, }, { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, { name: 'Cont', + hint: 'Nature of contents', type: SUBFIELD_TYPES.BYTES, bytes: 3, }, { name: 'SrTp', + hint: 'Type of continuing resource', type: SUBFIELD_TYPES.BYTE, }, { name: 'GPub', + hint: 'Government publication', type: SUBFIELD_TYPES.BYTE, }, { name: 'Conf', + hint: 'Conference publication', type: SUBFIELD_TYPES.BYTE, }, { name: 'Alph', + hint: 'Original alphabet or script of title', type: SUBFIELD_TYPES.BYTE, }, { name: 'S/L', + hint: 'Entry convention', type: SUBFIELD_TYPES.BYTE, }, ]; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MapMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MapMaterialCharsFieldConfig.js index 1991a5e5..b9b4637f 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MapMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MapMaterialCharsFieldConfig.js @@ -3,32 +3,39 @@ import { SUBFIELD_TYPES } from '../BytesField'; const MapMaterialCharsFieldConfig = [ { name: 'Relf', + hint: 'Relief', type: SUBFIELD_TYPES.BYTES, bytes: 4, }, { name: 'Proj', + hint: 'Projection', type: SUBFIELD_TYPES.BYTES, bytes: 2, }, { name: 'CrTp', + hint: 'Type of cartographic material', type: SUBFIELD_TYPES.BYTE, }, { name: 'GPub', + hint: 'Government publication', type: SUBFIELD_TYPES.BYTE, }, { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, { name: 'Indx', + hint: 'Index', type: SUBFIELD_TYPES.BYTE, }, { name: 'SpFm', + hint: 'Special format characteristics', type: SUBFIELD_TYPES.BYTES, bytes: 2, }, diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MediaMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MediaMaterialCharsFieldConfig.js index 95b77e46..aebd8d6c 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MediaMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MediaMaterialCharsFieldConfig.js @@ -3,37 +3,45 @@ import { SUBFIELD_TYPES } from '../BytesField'; const MediaMaterialCharsFieldConfig = [ { name: 'Comp', + hint: 'Form of composition', type: SUBFIELD_TYPES.STRING, length: 2, }, { name: 'FMus', + hint: 'Format of music', type: SUBFIELD_TYPES.BYTE, }, { name: 'Part', + hint: 'Music parts', type: SUBFIELD_TYPES.BYTE, }, { name: 'Audn', + hint: 'Target audience', type: SUBFIELD_TYPES.BYTE, }, { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, { name: 'AccM', + hint: 'Accompanying matter', type: SUBFIELD_TYPES.BYTES, bytes: 6, }, { name: 'LTxt', + hint: 'Literary text for sound recordings', type: SUBFIELD_TYPES.BYTES, bytes: 2, }, { name: 'TrAr', + hint: 'Transposition and arrangement', type: SUBFIELD_TYPES.BYTE, }, ]; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MixedMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MixedMaterialCharsFieldConfig.js index 3894e750..ec298bf4 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MixedMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/MixedMaterialCharsFieldConfig.js @@ -3,6 +3,7 @@ import { SUBFIELD_TYPES } from '../BytesField'; const MixedMaterialCharsFieldConfig = [ { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, ]; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/VisualMaterialCharsFieldConfig.js b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/VisualMaterialCharsFieldConfig.js index bdf40a5a..8d8bfac1 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/VisualMaterialCharsFieldConfig.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/MaterialCharsField/VisualMaterialCharsFieldConfig.js @@ -3,27 +3,33 @@ import { SUBFIELD_TYPES } from '../BytesField'; const VisualMaterialCharsFieldConfig = [ { name: 'Time', + hint: 'Running time for motion pictures and videorecordings', type: SUBFIELD_TYPES.BYTES, bytes: 3, }, { name: 'Audn', + hint: 'Target audience', type: SUBFIELD_TYPES.BYTE, }, { name: 'GPub', + hint: 'Government publication', type: SUBFIELD_TYPES.BYTE, }, { name: 'Form', + hint: 'Form of item', type: SUBFIELD_TYPES.BYTE, }, { name: 'TMat', + hint: 'Type of visual material', type: SUBFIELD_TYPES.BYTE, }, { name: 'Tech', + hint: 'Technique', type: SUBFIELD_TYPES.BYTE, }, ]; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js index b8be347e..b827057b 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js @@ -79,6 +79,7 @@ const QuickMarcEditorRows = ({ updateRecord, }, marcType, + marcSpec, instance, linksCount, isLoadingLinkSuggestions, @@ -292,7 +293,7 @@ const QuickMarcEditorRows = ({ isRequestToCentralTenantFromMember, onCheckCentralTenantPerm, ); - const canBeLinkedAuto = isRecordForAutoLinking(recordRow, autoLinkableBibFields); + const canBeLinkedAuto = isRecordForAutoLinking(recordRow, autoLinkableBibFields) || false; const canViewAuthorityRecord = stripes.hasPerm('ui-marc-authorities.authority-record.view') && recordRow._isLinked; @@ -469,7 +470,7 @@ const QuickMarcEditorRows = ({ { isFixedField && ( FixedFieldFactory.getFixedField( - `${name}.content`, marcType, type, subtype, + `${name}.content`, marcType, marcSpec, type, subtype, ) ) } @@ -594,6 +595,7 @@ QuickMarcEditorRows.propTypes = { updateRecord: PropTypes.func.isRequired, }), marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + marcSpec: PropTypes.object.isRequired, onCheckCentralTenantPerm: PropTypes.func, }; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js index df618489..aa5796d5 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js @@ -57,6 +57,10 @@ jest.mock('../../queries', () => ({ sourceFiles: [], isLoading: false, }), + useMarcSpecifications: jest.fn().mockReturnValue({ + fixedFieldRules: {}, + isLoading: false, + }), })); const initValues = [ @@ -132,6 +136,7 @@ const initValues = [ ]; let values = [...initValues]; +const marcSpec = {}; const addRecordMock = jest.fn().mockImplementation(({ index }) => { values.splice(index, 0, { id: 'new-1', @@ -158,6 +163,7 @@ const getComponent = (props) => ( type="a" action={QUICK_MARC_ACTIONS.EDIT} marcType={MARC_TYPES.BIB} + marcSpec={marcSpec} mutators={{ addRecord: addRecordMock, deleteRecord: deleteRecordMock, diff --git a/src/QuickMarcEditor/QuickMarcRecordInfo/QuickMarcRecordInfo.js b/src/QuickMarcEditor/QuickMarcRecordInfo/QuickMarcRecordInfo.js index 5885ce1d..4e807af3 100644 --- a/src/QuickMarcEditor/QuickMarcRecordInfo/QuickMarcRecordInfo.js +++ b/src/QuickMarcEditor/QuickMarcRecordInfo/QuickMarcRecordInfo.js @@ -56,7 +56,7 @@ export const QuickMarcRecordInfo = ({ className={styles.quickMarcRecordInfoWrapper} data-test-quick-marc-record-info > - {marcType === MARC_TYPES.AUTHORITY && ( + {marcType === MARC_TYPES.AUTHORITY && correspondingMarcTag && ( <>  •  diff --git a/src/QuickMarcEditor/utils.js b/src/QuickMarcEditor/utils.js index a62006d4..0e501454 100644 --- a/src/QuickMarcEditor/utils.js +++ b/src/QuickMarcEditor/utils.js @@ -215,13 +215,13 @@ export const fillEmptyPhysDescriptionFieldValues = (type, field) => { return fillEmptyFieldValues({ fieldConfigByType, field }); }; -export const fillEmptyFixedFieldValues = (marcType, type, blvl, field) => { +export const fillEmptyFixedFieldValues = (marcType, marcSpec, type, blvl, field) => { const fieldConfigByType = FixedFieldFactory - .getFixedFieldByType( - marcType, + .getConfigFixedField( + marcSpec, type, blvl, - )?.configFields ?? []; + )?.fields ?? []; let hiddenValues = {}; @@ -1188,7 +1188,7 @@ export const autopopulatePhysDescriptionField = (formValues) => { }; }; -export const autopopulateFixedField = (formValues, marcType) => { +export const autopopulateFixedField = (formValues, marcType, marcSpec) => { const { records } = formValues; const leader = records.find(field => field.tag === LEADER_TAG); @@ -1204,7 +1204,7 @@ export const autopopulateFixedField = (formValues, marcType) => { return { ...field, - content: fillEmptyFixedFieldValues(marcType, type, blvl, field), + content: fillEmptyFixedFieldValues(marcType, marcSpec, type, blvl, field), }; }), }; @@ -1248,9 +1248,13 @@ export const autopopulateSubfieldSection = (formValues, marcType = MARC_TYPES.BI }; }; -export const cleanBytesFields = (formValues, marcType) => { +export const cleanBytesFields = (formValues, marcSpec) => { const { records } = formValues; + const leader = records.find(field => field.tag === LEADER_TAG); + const type = leader.content[6]; + const blvl = leader.content[7]; + const cleanedRecords = records.map((field) => { if (isString(field.content)) { return field; @@ -1268,7 +1272,7 @@ export const cleanBytesFields = (formValues, marcType) => { if (isFixedFieldRow(field)) { fieldConfigByType = FixedFieldFactory - .getFixedFieldByType(marcType, field.content.Type, field.content.BLvl)?.configFields ?? []; + .getConfigFixedField(marcSpec, type, blvl)?.fields ?? []; } const content = Object.entries(field.content).reduce((acc, [key, value]) => { @@ -1506,10 +1510,10 @@ const addLeaderFieldAndIdToRecords = (marcRecordResponse) => ({ ], }); -export const dehydrateMarcRecordResponse = (marcRecordResponse, marcType) => ( +export const dehydrateMarcRecordResponse = (marcRecordResponse, marcType, marcSpec) => ( flow( addLeaderFieldAndIdToRecords, - marcRecord => autopopulateFixedField(marcRecord, marcType), + marcRecord => autopopulateFixedField(marcRecord, marcType, marcSpec), autopopulatePhysDescriptionField, autopopulateMaterialCharsField, )(marcRecordResponse) diff --git a/src/QuickMarcEditor/utils.test.js b/src/QuickMarcEditor/utils.test.js index ece8ac7d..fc7eb0d8 100644 --- a/src/QuickMarcEditor/utils.test.js +++ b/src/QuickMarcEditor/utils.test.js @@ -13,6 +13,10 @@ import { MARC_TYPES } from '../common/constants'; import { RECORD_STATUS_NEW } from './QuickMarcRecordInfo/constants'; import * as utils from './utils'; +import marcSpecificationBib from '../../test/mocks/marcSpecificationBib'; +import marcSpecificationAuth from '../../test/mocks/marcSpecificationAuth'; +import marcSpecificationHold from '../../test/mocks/marcSpecificationHold'; + jest.mock('uuid', () => { return { v4: () => 'uuid', @@ -79,7 +83,8 @@ describe('QuickMarcEditor utils', () => { }, ], }; - const dehydratedMarcRecord = utils.dehydrateMarcRecordResponse(marcRecord, MARC_TYPES.BIB); + + const dehydratedMarcRecord = utils.dehydrateMarcRecordResponse(marcRecord, MARC_TYPES.BIB, marcSpecificationBib); const field006 = dehydratedMarcRecord.records[2]; const field007 = dehydratedMarcRecord.records[3]; const field008 = dehydratedMarcRecord.records[4]; @@ -1590,7 +1595,7 @@ describe('QuickMarcEditor utils', () => { }, }; - expect(utils.fillEmptyFixedFieldValues(marcType, type, blvl, field)).toMatchObject({ + expect(utils.fillEmptyFixedFieldValues(marcType, marcSpecificationBib, type, blvl, field)).toMatchObject({ Srce: '\\', Audn: '\\', Lang: 'eng', @@ -1616,7 +1621,7 @@ describe('QuickMarcEditor utils', () => { describe('when marc type is Authority', () => { it('should add Authority specific hidden fields', () => { const marcType = MARC_TYPES.AUTHORITY; - const type = ''; + const type = 'z'; const blvl = ''; const field = { content: { @@ -1624,7 +1629,7 @@ describe('QuickMarcEditor utils', () => { }, }; - expect(utils.fillEmptyFixedFieldValues(marcType, type, blvl, field)).toMatchObject({ + expect(utils.fillEmptyFixedFieldValues(marcType, marcSpecificationAuth, type, blvl, field)).toMatchObject({ 'Geo Subd': '\\', 'Kind rec': '\\', 'SH Sys': '\\', @@ -1650,6 +1655,34 @@ describe('QuickMarcEditor utils', () => { }); }); }); + + describe('when marc type is Holding', () => { + it('should add Holding specific hidden fields', () => { + const marcType = MARC_TYPES.HOLDINGS; + const type = 'u'; + const blvl = ''; + const field = { + content: { + Compl: 'a', + }, + }; + + expect(utils.fillEmptyFixedFieldValues(marcType, marcSpecificationHold, type, blvl, field)).toMatchObject({ + AcqStatus: '\\', + AcqMethod: '\\', + AcqEndDate: '\\\\\\\\', + 'Gen ret': '\\', + 'Spec ret': ['\\', '\\', '\\'], + Compl: 'a', + Copies: '\\\\\\', + Lend: '\\', + Repro: '\\', + Lang: '\\\\\\', + 'Sep/comp': '\\', + 'Rept date': '\\\\\\\\\\\\', + }); + }); + }); }); describe('formatMarcRecordByQuickMarcAction', () => { @@ -2156,6 +2189,9 @@ describe('QuickMarcEditor utils', () => { it('should return cleaned records', () => { const record = { records: [{ + tag: 'LDR', + content: '03685cgm\\a2200757\\i\\4500', + }, { tag: '001', content: 'some content', }, { @@ -2211,6 +2247,9 @@ describe('QuickMarcEditor utils', () => { }; const expectedRecord = { records: [{ + tag: 'LDR', + content: '03685cgm\\a2200757\\i\\4500', + }, { tag: '001', content: 'some content', }, { @@ -2263,7 +2302,7 @@ describe('QuickMarcEditor utils', () => { }, }; - expect(utils.cleanBytesFields(record, MARC_TYPES.BIB)).toEqual(expectedRecord); + expect(utils.cleanBytesFields(record, marcSpecificationBib)).toEqual(expectedRecord); }); }); diff --git a/src/common/constants/api.js b/src/common/constants/api.js index c2053d66..7b4b52c6 100644 --- a/src/common/constants/api.js +++ b/src/common/constants/api.js @@ -9,3 +9,4 @@ export const EXTERNAL_INSTANCE_APIS = { export const MARC_RECORD_API = 'records-editor/records'; export const MARC_RECORD_STATUS_API = `${MARC_RECORD_API}/status`; export const LINKING_RULES_API = 'linking-rules/instance-authority'; +export const MARC_SPEC_API = 'marc-specifications'; diff --git a/test/mocks/marcSpecificationAuth.js b/test/mocks/marcSpecificationAuth.js new file mode 100644 index 00000000..ff577443 --- /dev/null +++ b/test/mocks/marcSpecificationAuth.js @@ -0,0 +1,231 @@ +const marcSpecificationAuth = { + tag: '008', + spec: { + types: [ + { + code: 'unknown', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['z'], + }, + }, + ], + }, + items: [ + { + code: 'Entered', + name: 'Date entered on file', + order: 0, + position: 0, + length: 5, + isArray: false, + readOnly: true, + }, + { + code: 'Geo Subd', + name: 'Direct or indirect geographic subdivision', + order: 1, + position: 6, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Roman', + name: 'Romanization scheme', + order: 2, + position: 7, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Lang', + name: 'Language of catalog', + order: 3, + position: 8, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Kind rec', + name: 'Kind of record', + order: 4, + position: 9, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Cat Rules', + name: 'Descriptive cataloging rules', + order: 5, + position: 10, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'SH Sys', + name: 'Subject heading system/thesaurus', + order: 6, + position: 11, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Series', + name: 'Type of series', + order: 7, + position: 12, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Numb Series', + name: 'Numbered or unnumbered series', + order: 8, + position: 13, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Main use', + name: 'Heading use – main or added entry', + order: 9, + position: 14, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Subj use', + name: 'Heading use – subject added entry', + order: 10, + position: 15, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Series use', + name: 'Heading use – series added entry', + order: 11, + position: 16, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Type Subd', + name: 'Type of subject subdivision', + order: 12, + position: 17, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Undefined', + name: 'Undefined character positions', + order: 13, + position: 18, + length: 10, + isArray: false, + readOnly: true, + }, + { + code: 'Govt Ag', + name: 'Type of government agency', + order: 14, + position: 28, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'RefEval', + name: 'Reference evaluation', + order: 15, + position: 29, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Undefined', + name: 'Undefined character position', + order: 16, + position: 30, + length: 1, + isArray: false, + readOnly: true, + }, + { + code: 'RecUpd', + name: 'Record update in process', + order: 17, + position: 31, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Pers Name', + name: 'Undifferentiated personal name', + order: 18, + position: 32, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Level Est', + name: 'Level of establishment', + order: 18, + position: 33, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Undefined', + name: 'Undefined character positions', + order: 18, + position: 34, + length: 4, + isArray: false, + readOnly: true, + }, + { + code: 'Mod Rec Est', + name: 'Modified record', + order: 18, + position: 38, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Source', + name: 'Cataloging source', + order: 18, + position: 39, + length: 1, + isArray: false, + readOnly: false, + }, + ], + }, + ], + }, +}; + +export default marcSpecificationAuth; diff --git a/test/mocks/marcSpecificationBib.js b/test/mocks/marcSpecificationBib.js new file mode 100644 index 00000000..95c0a8a0 --- /dev/null +++ b/test/mocks/marcSpecificationBib.js @@ -0,0 +1,461 @@ +const marcSpecificationBib = { + tag: '008', + spec: { + types: [ + { + code: 'books', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['a'], + 7: ['a', 'c', 'd', 'm'], + }, + }, + { + tag: 'LDR', + positions: { + 6: ['t'], + }, + }, + ], + }, + items: [ + { + code: 'Entered', + name: 'Date entered on file', + order: 0, + position: 0, + length: 5, + isArray: false, + readOnly: true, + }, + { + code: 'DtSt', + name: 'Type of date/Publication status', + order: 1, + position: 6, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Date1', + name: 'Start date', + order: 2, + position: 7, + length: 4, + isArray: false, + readOnly: false, + }, + { + code: 'Date2', + name: 'End date', + order: 3, + position: 11, + length: 4, + isArray: false, + readOnly: false, + }, + { + code: 'Ctry', + name: 'Place of publication, production, or execution', + order: 4, + position: 15, + length: 3, + isArray: false, + readOnly: false, + }, + { + code: 'Ills', + name: 'Illustrations', + order: 5, + position: 18, + length: 4, + isArray: true, + readOnly: false, + }, + { + code: 'Audn', + name: 'Target audience', + order: 6, + position: 22, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Form', + name: 'Form of item', + order: 7, + position: 23, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Cont', + name: 'Nature of contents', + order: 8, + position: 24, + length: 4, + isArray: true, + readOnly: false, + }, + { + code: 'GPub', + name: 'Government publication', + order: 9, + position: 28, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Conf', + name: 'Conference publication', + order: 10, + position: 29, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Fest', + name: 'Festschrift', + order: 11, + position: 30, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Indx', + name: 'Index', + order: 12, + position: 31, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Und', + name: 'Undefined', + order: 13, + position: 32, + length: 1, + isArray: false, + readOnly: true, + }, + { + code: 'LitF', + name: 'Literary form', + order: 14, + position: 33, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Biog', + name: 'Biography', + order: 15, + position: 34, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Lang', + name: 'Language', + order: 16, + position: 35, + length: 3, + isArray: false, + readOnly: false, + }, + { + code: 'MRec', + name: 'Modified record', + order: 17, + position: 38, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Srce', + name: 'Cataloging source', + order: 18, + position: 39, + length: 1, + isArray: false, + readOnly: false, + }, + ], + }, + { + code: 'scores', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['c', 'd'], + }, + }, + ], + }, + items: [], + }, + { + code: 'sound_recordings', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['i', 'j'], + }, + }, + ], + }, + items: [], + }, + { + code: 'continuing_resources', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['a'], + 7: ['b', 'i', 's'], + }, + }, + { + tag: 'LDR', + positions: { + 6: ['s'], + }, + }, + ], + }, + items: [], + }, + { + code: 'computer_files', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['m'], + }, + }, + ], + }, + items: [], + }, + { + code: 'visual_materials', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['g', 'k', 'o', 'r'], + }, + }, + ], + }, + items: [ + { + code: 'Entered', + name: 'Date entered on file', + order: 0, + position: 0, + length: 5, + isArray: false, + readOnly: true, + }, + { + code: 'DtSt', + name: 'Type of date/Publication status', + order: 1, + position: 6, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Date1', + name: 'Start date', + order: 2, + position: 7, + length: 4, + isArray: false, + readOnly: false, + }, + { + code: 'Date2', + name: 'End date', + order: 3, + position: 11, + length: 4, + isArray: false, + readOnly: false, + }, + { + code: 'Ctry', + name: 'Place of publication, production, or execution', + order: 4, + position: 15, + length: 3, + isArray: false, + readOnly: false, + }, + { + code: 'Time', + name: 'Running time for motion pictures and videorecordings', + order: 5, + position: 18, + length: 3, + isArray: true, + readOnly: false, + }, + { + code: 'Und', + name: 'Undefined', + order: 6, + position: 21, + length: 1, + isArray: false, + readOnly: true, + }, + { + code: 'Audn', + name: 'Target audience', + order: 7, + position: 22, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Und', + name: 'Undefined', + order: 8, + position: 23, + length: 5, + isArray: false, + readOnly: true, + }, + { + code: 'GPub', + name: 'Government publication', + order: 9, + position: 28, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Form', + name: 'Form of item', + order: 10, + position: 29, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Und', + name: 'Undefined', + order: 11, + position: 30, + length: 3, + isArray: false, + readOnly: true, + }, + { + code: 'TMat', + name: 'Type of visual material', + order: 12, + position: 33, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Tech', + name: 'Technique', + order: 13, + position: 34, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Lang', + name: 'Language', + order: 14, + position: 35, + length: 3, + isArray: false, + readOnly: false, + }, + { + code: 'MRec', + name: 'Modified record', + order: 15, + position: 38, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Srce', + name: 'Cataloging source', + order: 16, + position: 39, + length: 1, + isArray: false, + readOnly: false, + }, + ], + }, + { + code: 'maps', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['e', 'f'], + }, + }, + ], + }, + items: [], + }, + { + code: 'mixed_materials', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['p'], + }, + }, + ], + }, + items: [], + }, + ], + }, +}; + +export default marcSpecificationBib; diff --git a/test/mocks/marcSpecificationHold.js b/test/mocks/marcSpecificationHold.js new file mode 100644 index 00000000..8e81f10e --- /dev/null +++ b/test/mocks/marcSpecificationHold.js @@ -0,0 +1,141 @@ +const marcSpecificationHold = { + tag: '008', + spec: { + types: [ + { + code: 'unknown', + identifiedBy: { + or: [ + { + tag: 'LDR', + positions: { + 6: ['u', 'v', 'x', 'y'], + }, + }, + ], + }, + items: [ + { + code: 'Entered', + name: 'Date entered on file', + order: 0, + position: 0, + length: 5, + isArray: false, + readOnly: true, + }, + { + code: 'AcqStatus', + name: 'Receipt, acquisition, or access status', + order: 1, + position: 6, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'AcqMethod', + name: 'Method of acquisition', + order: 2, + position: 7, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'AcqEndDate', + name: 'Expected acquisition end date', + order: 3, + position: 8, + length: 4, + isArray: false, + readOnly: false, + }, + { + code: 'Gen ret', + name: 'General retention policy', + order: 4, + position: 12, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Spec ret', + name: 'Specific retention policy', + order: 5, + position: 13, + length: 3, + isArray: true, + readOnly: false, + }, + { + code: 'Compl', + name: 'Completeness', + order: 6, + position: 16, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Copies', + name: 'Number of copies reported', + order: 7, + position: 17, + length: 3, + isArray: false, + readOnly: false, + }, + { + code: 'Lend', + name: 'Lending policy', + order: 8, + position: 20, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Repro', + name: 'Reproduction policy', + order: 9, + position: 21, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Lang', + name: 'Language', + order: 10, + position: 22, + length: 3, + isArray: false, + readOnly: false, + }, + { + code: 'Sep/comp', + name: 'Separate or composite copy report', + order: 11, + position: 25, + length: 1, + isArray: false, + readOnly: false, + }, + { + code: 'Rept date', + name: 'Date of report', + order: 12, + position: 26, + length: 6, + isArray: false, + readOnly: false, + }, + ], + }, + ], + }, +}; + +export default marcSpecificationHold; diff --git a/translations/ui-quick-marc/en.json b/translations/ui-quick-marc/en.json index 08b5b38c..3b6b7c64 100644 --- a/translations/ui-quick-marc/en.json +++ b/translations/ui-quick-marc/en.json @@ -162,6 +162,130 @@ "record.fixedField.Kind of color stock or print": "KoCSoP", "record.fixedField.Refined categories of color": "RCoC", + "record.fixedField.tip.Date entered on file": "Date entered on file", + "record.fixedField.tip.Type of date/Publication status": "Type of date/Publication status", + "record.fixedField.tip.Start date": "Start date", + "record.fixedField.tip.End date": "End date", + "record.fixedField.tip.Place of publication, production, or execution": "Place of publication, production, or execution", + "record.fixedField.tip.Illustrations": "Illustrations", + "record.fixedField.tip.Target audience": "Target audience", + "record.fixedField.tip.Form of item": "Form of item", + "record.fixedField.tip.Nature of contents": "Nature of contents", + "record.fixedField.tip.Government publication": "Government publication", + "record.fixedField.tip.Conference publication": "Conference publication", + "record.fixedField.tip.Festschrift": "Festschrift", + "record.fixedField.tip.Index": "Index", + "record.fixedField.tip.Undefined": "Undefined", + "record.fixedField.tip.Literary form": "Literary form", + "record.fixedField.tip.Biography": "Biography", + "record.fixedField.tip.Language": "Language", + "record.fixedField.tip.Modified record": "Modified record", + "record.fixedField.tip.Cataloging source": "Cataloging source", + "record.fixedField.tip.Form of composition": "Form of composition", + "record.fixedField.tip.Format of music": "Format of music", + "record.fixedField.tip.Music parts": "Music parts", + "record.fixedField.tip.Accompanying matter": "Accompanying matter", + "record.fixedField.tip.Literary text for sound recordings": "Literary text for sound recordings", + "record.fixedField.tip.Transposition and arrangement": "Transposition and arrangement", + "record.fixedField.tip.Frequency": "Frequency", + "record.fixedField.tip.Regularity": "Regularity", + "record.fixedField.tip.Type of continuing resource": "Type of continuing resource", + "record.fixedField.tip.Form of original item": "Form of original item", + "record.fixedField.tip.Nature of entire work": "Nature of entire work", + "record.fixedField.tip.Original alphabet or script of title": "Original alphabet or script of title", + "record.fixedField.tip.Entry convention": "Entry convention", + "record.fixedField.tip.Type of computer file": "Type of computer file", + "record.fixedField.tip.Running time for motion pictures and videorecordings": "Running time for motion pictures and videorecordings", + "record.fixedField.tip.Type of visual material": "Type of visual material", + "record.fixedField.tip.Technique": "Technique", + "record.fixedField.tip.Relief": "Relief", + "record.fixedField.tip.Projection": "Projection", + "record.fixedField.tip.Type of cartographic material": "Type of cartographic material", + "record.fixedField.tip.Special format characteristics": "Special format characteristics", + "record.fixedField.tip.Receipt, acquisition, or access status": "Receipt, acquisition, or access status", + "record.fixedField.tip.Method of acquisition": "Method of acquisition", + "record.fixedField.tip.Expected acquisition end date": "Expected acquisition end date", + "record.fixedField.tip.General retention policy": "General retention policy", + "record.fixedField.tip.Specific retention policy": "Specific retention policy", + "record.fixedField.tip.Completeness": "Completeness", + "record.fixedField.tip.Number of copies reported": "Number of copies reported", + "record.fixedField.tip.Lending policy": "Lending policy", + "record.fixedField.tip.Reproduction policy": "Reproduction policy", + "record.fixedField.tip.Separate or composite copy report": "Separate or composite copy report", + "record.fixedField.tip.Date of report": "Date of report", + "record.fixedField.tip.Direct or indirect geographic subdivision": "Direct or indirect geographic subdivision", + "record.fixedField.tip.Romanization scheme": "Romanization scheme", + "record.fixedField.tip.Language of catalog": "Language of catalog", + "record.fixedField.tip.Kind of record": "Kind of record", + "record.fixedField.tip.Descriptive cataloging rules": "Descriptive cataloging rules", + "record.fixedField.tip.Subject heading system/thesaurus": "Subject heading system/thesaurus", + "record.fixedField.tip.Type of series": "Type of series", + "record.fixedField.tip.Numbered or unnumbered series": "Numbered or unnumbered series", + "record.fixedField.tip.Heading use – main or added entry": "Heading use – main or added entry", + "record.fixedField.tip.Heading use – subject added entry": "Heading use – subject added entry", + "record.fixedField.tip.Heading use – series added entry": "Heading use – series added entry", + "record.fixedField.tip.Type of subject subdivision": "Type of subject subdivision", + "record.fixedField.tip.Undefined character positions": "Undefined character positions", + "record.fixedField.tip.Type of government agency": "Type of government agency", + "record.fixedField.tip.Reference evaluation": "Reference evaluation", + "record.fixedField.tip.Undefined character position": "Undefined character position", + "record.fixedField.tip.Record update in process": "Record update in process", + "record.fixedField.tip.Undifferentiated personal name": "Undifferentiated personal name", + "record.fixedField.tip.Level of establishment": "Level of establishment", + + "record.fixedField.tip.Category": "Type", + "record.fixedField.tip.SMD": "SMD", + "record.fixedField.tip.Braille music format": "Braille music format", + "record.fixedField.tip.Special physical characteristics": "Special physical characteristics", + "record.fixedField.tip.Color": "Color", + "record.fixedField.tip.Dimensions": "Dimensions", + "record.fixedField.tip.Sound": "Sound", + "record.fixedField.tip.Image bit depth": "Image bit depth", + "record.fixedField.tip.File formats": "File formats", + "record.fixedField.tip.Quality assurance target(s)": "Quality assurance target(s)", + "record.fixedField.tip.Antecedent/ Source": "Antecedent/ Source", + "record.fixedField.tip.Level of compression": "Level of compression", + "record.fixedField.tip.Reformatting quality": "Reformatting quality", + "record.fixedField.tip.Type of reproduction": "Type of reproduction", + "record.fixedField.tip.Physical medium": "Physical medium", + "record.fixedField.tip.Production/reproduction details": "Production/reproduction details", + "record.fixedField.tip.Positive/negative aspect": "Positive/negative aspect", + "record.fixedField.tip.Reduction ratio range/Reduction ratio": "Reduction ratio range/Reduction ratio", + "record.fixedField.tip.Emulsion on film": "Emulsion on film", + "record.fixedField.tip.Generation": "Generation", + "record.fixedField.tip.Base of film": "Base of film", + "record.fixedField.tip.Videorecording format": "Videorecording format", + "record.fixedField.tip.Sound on medium or separate": "Sound on medium or separate", + "record.fixedField.tip.Medium for sound": "Medium for sound", + "record.fixedField.tip.Configuration of playback channels": "Configuration of playback channels", + "record.fixedField.tip.Class of braille writing": "Class of braille writing", + "record.fixedField.tip.Level of contraction": "Level of contraction", + "record.fixedField.tip.Speed": "Speed", + "record.fixedField.tip.Groove width/ groove pitch": "Groove width/ groove pitch", + "record.fixedField.tip.Tape width": "Tape width", + "record.fixedField.tip.Tape configuration": "Tape configuration", + "record.fixedField.tip.Kind of disc, cylinder, or tape": "Kind of disc, cylinder, or tape", + "record.fixedField.tip.Kind of material": "Kind of material", + "record.fixedField.tip.Kind of cutting": "Kind of cutting", + "record.fixedField.tip.Special playback characteristics": "Special playback characteristics", + "record.fixedField.tip.Capture and storage technique": "Capture and storage technique", + "record.fixedField.tip.Attitude of sensor": "Attitude of sensor", + "record.fixedField.tip.Altitude of sensor": "Altitude of sensor", + "record.fixedField.tip.Cloud cover": "Cloud cover", + "record.fixedField.tip.Platform construction type": "Platform construction type", + "record.fixedField.tip.Platform use category": "Platform use category", + "record.fixedField.tip.Sensor type": "Sensor type", + "record.fixedField.tip.Data type": "Data type", + "record.fixedField.tip.Base of emulsion": "Base of emulsion", + "record.fixedField.tip.Secondary support material": "Secondary support material", + "record.fixedField.tip.Primary support material": "Primary support material", + "record.fixedField.tip.Motion picture presentation format": "Motion picture presentation format", + "record.fixedField.tip.Production elements": "Production elements", + "record.fixedField.tip.Film inspection date": "Film inspection date", + "record.fixedField.tip.Deterioration stage": "Deterioration stage", + "record.fixedField.tip.Kind of color stock or print": "Kind of color stock or print", + "record.fixedField.tip.Refined categories of color": "Refined categories of color", + "record.load.error": "Record cannot be found or loaded.", "record.error.leader.length": "Record cannot be saved. The Leader must contain 24 characters, including null spaces.",