From 2e8a25fdfe2171fe99052ac4334f627c885701d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Turek?= <128044179+przemyslawturek@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:56:18 +0200 Subject: [PATCH] UIQM-431 Marc record fixed field 008 with proper order. (#602) * UIQM-431 Marc record fixed field 008 with proper order. Depends of marc specifications api for fixed field 008. * Fix after code review Made changes as suggested * Replace Bibliographic, Authority, Holdings FixedField to one FixedField Replace Bibliographic, Authority, Holdings FixedField to one FixedField Refactory getFixedField without marcType Removed unnecessary tests, fixed current without using the marcType props --- CHANGELOG.md | 3 +- src/QuickMarcEditor/QuickMarcCreateWrapper.js | 7 +- src/QuickMarcEditor/QuickMarcDeriveWrapper.js | 7 +- src/QuickMarcEditor/QuickMarcEditWrapper.js | 6 +- src/QuickMarcEditor/QuickMarcEditor.js | 7 +- .../QuickMarcEditorContainer.js | 36 +- .../QuickMarcEditorContainer.test.js | 3 + .../BytesField/BytesField.js | 76 ++- .../FixedField/AuthorityFixedField.js | 106 ---- .../FixedField/BookFixedField.js | 104 ---- .../FixedField/ComputerFileFixedField.js | 78 --- .../ContinuingResourceFixedField.js | 107 ---- .../FixedField/FixedField.js | 22 + .../FixedField/FixedFieldFactory.js | 127 +++-- .../FixedField/FixedFieldFactory.test.js | 95 ++-- .../FixedField/HoldingsFixedField.js | 84 ---- .../FixedField/MapFixedField.js | 93 ---- .../FixedField/MixedMaterialFixedField.js | 66 --- .../FixedField/ScoreFixedField.js | 97 ---- .../FixedField/SoundRecordingFixedField.js | 97 ---- .../FixedField/VisualMaterialFixedField.js | 87 ---- .../QuickMarcEditorRows/FixedField/index.js | 10 +- .../BookMaterialCharsFieldConfig.js | 10 + .../ComputerFileMaterialCharsFieldConfig.js | 4 + .../ContinuingMaterialCharsFieldConfig.js | 11 + .../MapMaterialCharsFieldConfig.js | 7 + .../MediaMaterialCharsFieldConfig.js | 8 + .../MixedMaterialCharsFieldConfig.js | 1 + .../VisualMaterialCharsFieldConfig.js | 6 + .../QuickMarcEditorRows.js | 4 +- .../QuickMarcEditorRows.test.js | 2 + .../QuickMarcRecordInfo.js | 2 +- src/QuickMarcEditor/utils.js | 24 +- src/QuickMarcEditor/utils.test.js | 49 +- src/common/constants/api.js | 1 + test/mocks/fixedFieldSpecAuth.js | 231 +++++++++ test/mocks/fixedFieldSpecBib.js | 461 ++++++++++++++++++ test/mocks/fixedFieldSpecHold.js | 141 ++++++ translations/ui-quick-marc/en.json | 124 +++++ 39 files changed, 1328 insertions(+), 1076 deletions(-) delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/AuthorityFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/BookFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ComputerFileFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ContinuingResourceFixedField.js create mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MapFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/MixedMaterialFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/ScoreFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/SoundRecordingFixedField.js delete mode 100644 src/QuickMarcEditor/QuickMarcEditorRows/FixedField/VisualMaterialFixedField.js create mode 100644 test/mocks/fixedFieldSpecAuth.js create mode 100644 test/mocks/fixedFieldSpecBib.js create mode 100644 test/mocks/fixedFieldSpecHold.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0691cd89..a7752b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,7 +57,8 @@ * [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-562](https://issues.folio.org/browse/UIQM-562) Fix optimistic locking error doesn't appear when edit "MARC authority" record. -* [UIQM-564](https://issues.folio.org/browse/UIQM-564) Hide permission `quickMARC: Create a new MARC authority record`. +* [UIQM-564](https://issues.folio.org/browse/UIQM-564) Hide permission `quickMARC: Create a new MARC authority record +* [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..0dfc94bc 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, + fixedFieldSpec: PropTypes.object.isRequired, mutator: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, }; @@ -52,6 +53,7 @@ const QuickMarcCreateWrapper = ({ history, location, marcType, + fixedFieldSpec, locations, }) => { const showCallout = useShowCallout(); @@ -67,11 +69,11 @@ const QuickMarcCreateWrapper = ({ autopopulatePhysDescriptionField, autopopulateMaterialCharsField, marcRecord => autopopulateSubfieldSection(marcRecord, marcType), - marcRecord => cleanBytesFields(marcRecord, marcType), + marcRecord => cleanBytesFields(marcRecord, fixedFieldSpec), )(formValues); return formValuesForCreate; - }, [marcType]); + }, [marcType, fixedFieldSpec]); const validate = useCallback((formValues) => { const formValuesForValidation = prepareForSubmit(formValues); @@ -182,6 +184,7 @@ const QuickMarcCreateWrapper = ({ onSubmit={onSubmit} action={action} marcType={marcType} + fixedFieldSpec={fixedFieldSpec} httpError={httpError} validate={validate} /> diff --git a/src/QuickMarcEditor/QuickMarcDeriveWrapper.js b/src/QuickMarcEditor/QuickMarcDeriveWrapper.js index d863304b..4bc6c5fb 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, + fixedFieldSpec: PropTypes.object.isRequired, mutator: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, }; @@ -47,6 +48,7 @@ const QuickMarcDeriveWrapper = ({ initialValues, mutator, marcType, + fixedFieldSpec, }) => { 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, fixedFieldSpec), )(formValues); return formValuesForDerive; - }, [marcType]); + }, [marcType, fixedFieldSpec]); const validate = useCallback((formValues) => { const formValuesForValidation = prepareForSubmit(formValues); @@ -157,6 +159,7 @@ const QuickMarcDeriveWrapper = ({ onSubmit={onSubmit} action={action} marcType={marcType} + fixedFieldSpec={fixedFieldSpec} httpError={httpError} confirmRemoveAuthorityLinking validate={validate} diff --git a/src/QuickMarcEditor/QuickMarcEditWrapper.js b/src/QuickMarcEditor/QuickMarcEditWrapper.js index 7df562ac..d9b1879c 100644 --- a/src/QuickMarcEditor/QuickMarcEditWrapper.js +++ b/src/QuickMarcEditor/QuickMarcEditWrapper.js @@ -51,6 +51,7 @@ const propTypes = { initialValues: PropTypes.object.isRequired, instance: PropTypes.object, marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + fixedFieldSpec: PropTypes.object.isRequired, mutator: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, onCheckCentralTenantPerm: PropTypes.func, @@ -64,6 +65,7 @@ const QuickMarcEditWrapper = ({ initialValues, mutator, marcType, + fixedFieldSpec, linksCount, locations, refreshPageData, @@ -141,7 +143,7 @@ const QuickMarcEditWrapper = ({ autopopulatePhysDescriptionField, autopopulateMaterialCharsField, marcRecord => autopopulateSubfieldSection(marcRecord, marcType), - marcRecord => cleanBytesFields(marcRecord, marcType), + marcRecord => cleanBytesFields(marcRecord, fixedFieldSpec), combineSplitFields, )(formValues); @@ -233,6 +235,7 @@ const QuickMarcEditWrapper = ({ initialValues, instance, marcType, + fixedFieldSpec, mutator, linksCount, location, @@ -254,6 +257,7 @@ const QuickMarcEditWrapper = ({ onSubmit={onSubmit} action={action} marcType={marcType} + fixedFieldSpec={fixedFieldSpec} locations={locations} httpError={httpError} externalRecordPath={externalRecordPath} diff --git a/src/QuickMarcEditor/QuickMarcEditor.js b/src/QuickMarcEditor/QuickMarcEditor.js index 2843531c..e233acc6 100644 --- a/src/QuickMarcEditor/QuickMarcEditor.js +++ b/src/QuickMarcEditor/QuickMarcEditor.js @@ -91,6 +91,7 @@ const QuickMarcEditor = ({ getState, }, marcType, + fixedFieldSpec, 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} + fixedFieldSpec={fixedFieldSpec} instance={instance} linksCount={linksCount} isLoadingLinkSuggestions={isLoadingLinkSuggestions} @@ -551,6 +553,7 @@ QuickMarcEditor.propTypes = { reset: PropTypes.func.isRequired, }), marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + fixedFieldSpec: 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..ddd4927f 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 [fixedFieldSpec, setFixedFieldSpec] = 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 fixedFieldSpecPromise = mutator.fixedFieldSpec.GET({ + path: `${MARC_SPEC_API}/${marcType}/008`, + ...headers, + }); + + await Promise.all([ + instancePromise, + marcRecordPromise, + locationsPromise, + linksCountPromise, + linkingRulesPromise, + fixedFieldSpecPromise, + ]) + .then(([ + instanceResponse, + marcRecordResponse, + locationsResponse, + linksCountResponse, + linkingRulesResponse, + fixedFieldSpecResponse, + ]) => { 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, fixedFieldSpecResponse); } const formattedMarcRecord = formatMarcRecordByQuickMarcAction(dehydratedMarcRecord, action, marcType); @@ -175,6 +196,7 @@ const QuickMarcEditorContainer = ({ setInstance(instanceResponse); setMarcRecord(marcRecordWithSplitFields); setLocations(locationsResponse); + setFixedFieldSpec(fixedFieldSpecResponse); setIsLoading(false); }) .catch(() => { @@ -219,6 +241,7 @@ const QuickMarcEditorContainer = ({ location={location} locations={locations} marcType={marcType} + fixedFieldSpec={fixedFieldSpec} refreshPageData={loadData} externalRecordPath={externalRecordUrl} resources={resources} @@ -263,6 +286,13 @@ QuickMarcEditorContainer.manifest = Object.freeze({ path: LINKING_RULES_API, throwErrors: false, }, + fixedFieldSpec: { + 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..abf60c10 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([]), }, + fixedFieldSpec: { + 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 deleted file mode 100644 index 0dcf8bdb..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/AuthorityFixedField.js +++ /dev/null @@ -1,106 +0,0 @@ -import React from 'react'; -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 }) => { - return ( - - ); -}; - -AuthorityFixedField.propTypes = { - name: PropTypes.string.isRequired, -}; - -AuthorityFixedField.displayName = 'AuthorityFixedField'; -AuthorityFixedField.configFields = config.fields; - -export default AuthorityFixedField; 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/FixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedField.js new file mode 100644 index 00000000..4b610da7 --- /dev/null +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedField.js @@ -0,0 +1,22 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { + BytesField, +} from '../BytesField'; + +const FixedField = ({ name, config }) => { + return ( + + ); +}; + +FixedField.propTypes = { + name: PropTypes.string.isRequired, + config: PropTypes.object.isRequired, +}; + +export default FixedField; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js index 855af0b3..67ad1e32 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.js @@ -1,64 +1,83 @@ import React from 'react'; -import { MARC_TYPES } from '../../../common/constants'; - -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 { LEADER_TAG } from '../../constants'; +import { + SUBFIELD_TYPES, +} from '../BytesField'; + +import FixedField from './FixedField'; export const FixedFieldFactory = { - getFixedFieldByType(marcType, type, subtype) { - let FixedField; - - switch (true) { - case marcType === MARC_TYPES.HOLDINGS: - FixedField = HoldingsFixedField; - break; - case marcType === 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; - break; - default: - FixedField = null; + + getFixedFieldType(fixedFieldSpec, type, subtype) { + if (!fixedFieldSpec?.spec) { + return undefined; + } + + const checkTypeSubType = (fieldIdentifier) => { + const hasTypePos = fieldIdentifier.positions['6'] || false; + const hasSubTypePos = fieldIdentifier.positions['7'] || false; + const typeOK = hasTypePos && fieldIdentifier.positions['6'].includes(type); + const subTypeOK = hasSubTypePos ? hasSubTypePos && fieldIdentifier.positions['7'].includes(subtype) : true; + + return (typeOK && subTypeOK); + }; + + const fixedFieldType = fixedFieldSpec.spec.types.find((fixedFieldTypeFind) => { + return fixedFieldTypeFind.identifiedBy.or.some((fieldIdentifier) => { + return fieldIdentifier.tag === LEADER_TAG && checkTypeSubType(fieldIdentifier); + }); + }); + + return fixedFieldType; + }, + + getConfigFixedField(fixedFieldSpec, type, subtype = '') { + const fixedFieldType = this.getFixedFieldType(fixedFieldSpec, type, subtype); + const config = { + fields: [], + type: fixedFieldType?.code || undefined, + }; + + if (!fixedFieldType) { + return config; } - return FixedField; + config.fields = fixedFieldType.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, type, subtype) { - const FixedField = this.getFixedFieldByType(marcType, type, subtype); - return FixedField ? : null; + getFixedField(name, fixedFieldSpec, type, subtype) { + const configFixedField = this.getConfigFixedField(fixedFieldSpec, type, subtype); + + return ; }, }; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js index 00ca8dbe..c0a4cb12 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/FixedFieldFactory.test.js @@ -1,73 +1,88 @@ 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 HoldingsFixedField from './HoldingsFixedField'; -import AuthorityFixedField from './AuthorityFixedField'; -import { MARC_TYPES } from '../../../common/constants'; +import fixedFieldSpecBib from '../../../../test/mocks/fixedFieldSpecBib'; +import fixedFieldSpecAuth from '../../../../test/mocks/fixedFieldSpecAuth'; +import fixedFieldSpecHold from '../../../../test/mocks/fixedFieldSpecHold'; describe('FixedFieldFactory', () => { - it('should create correct fields', () => { + it('should create correct fixed field type', () => { + expect( + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 'm').props.config.type, + ).toBe('books'); + + expect( + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 'a').props.config.type, + ).toBe('books'); + + expect( + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 'd').props.config.type, + ).toBe('books'); + + expect( + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 'x').props.config.type, + ).toBe(undefined); + + expect( + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 't').props.config.type, + ).toBe('books'); + + expect( + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'c').props.config.type, + ).toBe('scores'); + expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'a', 'm').type.displayName, - ).toBe(BookFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'i').props.config.type, + ).toBe('sound_recordings'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 't').type.displayName, - ).toBe(BookFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 'b').props.config.type, + ).toBe('continuing_resources'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.HOLDINGS, 't').type.displayName, - ).toBe(HoldingsFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 'i').props.config.type, + ).toBe('continuing_resources'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'm').type.displayName, - ).toBe(ComputerFileFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'a', 's').props.config.type, + ).toBe('continuing_resources'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'a', 's').type.displayName, - ).toBe(ContinuingResourceFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 's').props.config.type, + ).toBe('continuing_resources'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 's').type.displayName, - ).toBe(ContinuingResourceFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'm').props.config.type, + ).toBe('computer_files'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'f').type.displayName, - ).toBe(MapFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'g').props.config.type, + ).toBe('visual_materials'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'p').type.displayName, - ).toBe(MixedMaterialFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'e').props.config.type, + ).toBe('maps'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'c').type.displayName, - ).toBe(ScoreFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'f').props.config.type, + ).toBe('maps'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'i').type.displayName, - ).toBe(SoundRecordingFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'p').props.config.type, + ).toBe('mixed_materials'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'r').type.displayName, - ).toBe(VisualMaterialFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecAuth, 'z').props.config.type, + ).toBe('unknown'); expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.AUTHORITY).type.displayName, - ).toBe(AuthorityFixedField.displayName); + FixedFieldFactory.getFixedField('records', fixedFieldSpecHold, 'u').props.config.type, + ).toBe('unknown'); }); - it('should return null when there is no matched field', () => { + it('should return undefined type when there is no matched field', () => { expect( - FixedFieldFactory.getFixedField('records', MARC_TYPES.BIB, 'l'), - ).toBe(null); + FixedFieldFactory.getFixedField('records', fixedFieldSpecBib, 'l').props.config.type, + ).toBe(undefined); }); }); diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js deleted file mode 100644 index 3e9f9fb0..00000000 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/HoldingsFixedField.js +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -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 }) => { - return ( - - ); -}; - -HoldingsFixedField.propTypes = { - name: PropTypes.string.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..c4c18bd4 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/index.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/FixedField/index.js @@ -1,11 +1,3 @@ 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 FixedField } from './FixedField'; 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..db811642 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js @@ -79,6 +79,7 @@ const QuickMarcEditorRows = ({ updateRecord, }, marcType, + fixedFieldSpec, instance, linksCount, isLoadingLinkSuggestions, @@ -469,7 +470,7 @@ const QuickMarcEditorRows = ({ { isFixedField && ( FixedFieldFactory.getFixedField( - `${name}.content`, marcType, type, subtype, + `${name}.content`, fixedFieldSpec, type, subtype, ) ) } @@ -594,6 +595,7 @@ QuickMarcEditorRows.propTypes = { updateRecord: PropTypes.func.isRequired, }), marcType: PropTypes.oneOf(Object.values(MARC_TYPES)).isRequired, + fixedFieldSpec: PropTypes.object.isRequired, onCheckCentralTenantPerm: PropTypes.func, }; diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js index df618489..67a199a9 100644 --- a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js +++ b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.test.js @@ -132,6 +132,7 @@ const initValues = [ ]; let values = [...initValues]; +const marcSpec = {}; const addRecordMock = jest.fn().mockImplementation(({ index }) => { values.splice(index, 0, { id: 'new-1', @@ -158,6 +159,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..049fdf08 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 fixedFieldSpecBib from '../../test/mocks/fixedFieldSpecBib'; +import fixedFieldSpecAuth from '../../test/mocks/fixedFieldSpecAuth'; +import fixedFieldSpecHold from '../../test/mocks/fixedFieldSpecHold'; + 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, fixedFieldSpecBib); 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, fixedFieldSpecBib, 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, fixedFieldSpecAuth, 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, fixedFieldSpecHold, 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, fixedFieldSpecBib)).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/fixedFieldSpecAuth.js b/test/mocks/fixedFieldSpecAuth.js new file mode 100644 index 00000000..f8276a40 --- /dev/null +++ b/test/mocks/fixedFieldSpecAuth.js @@ -0,0 +1,231 @@ +const fixedFieldSpecAuth = { + 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 fixedFieldSpecAuth; diff --git a/test/mocks/fixedFieldSpecBib.js b/test/mocks/fixedFieldSpecBib.js new file mode 100644 index 00000000..5ef0f399 --- /dev/null +++ b/test/mocks/fixedFieldSpecBib.js @@ -0,0 +1,461 @@ +const fixedFieldSpecBib = { + 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 fixedFieldSpecBib; diff --git a/test/mocks/fixedFieldSpecHold.js b/test/mocks/fixedFieldSpecHold.js new file mode 100644 index 00000000..5d8be858 --- /dev/null +++ b/test/mocks/fixedFieldSpecHold.js @@ -0,0 +1,141 @@ +const fixedFieldSpecHold = { + 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 fixedFieldSpecHold; 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.",