diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f86733d..006de6a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* [UIQM-430](https://issues.folio.org/browse/UIQM-430) If the user manually enters the $9 field on a non-linkable, then hide the authorized icon on the view source.
* [UIQM-426](https://issues.folio.org/browse/UIQM-426) Show error if $9 is added during deriving.
* [UIQM-422](https://issues.folio.org/browse/UIQM-422) Edit/Derive MARC bib | Show Type label on 006 and 007 MARC fields.
+* [UIQM-426](https://issues.folio.org/browse/UIQM-426) Allow a user to manual enter/edit $9 for non-linkable/non-controllable bib field
## [6.0.1](https://github.com/folio-org/ui-quick-marc/tree/v6.0.1) (2023-03-14)
diff --git a/src/QuickMarcEditor/QuickMarcEditWrapper.js b/src/QuickMarcEditor/QuickMarcEditWrapper.js
index c1e5224a..d2e1a81e 100644
--- a/src/QuickMarcEditor/QuickMarcEditWrapper.js
+++ b/src/QuickMarcEditor/QuickMarcEditWrapper.js
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
import { useShowCallout } from '@folio/stripes-acq-components';
import QuickMarcEditor from './QuickMarcEditor';
-
+import { useAuthorityLinking } from '../hooks';
import { QUICK_MARC_ACTIONS } from './constants';
import {
EXTERNAL_INSTANCE_APIS,
@@ -56,6 +56,7 @@ const QuickMarcEditWrapper = ({
const showCallout = useShowCallout();
const location = useLocation();
const [httpError, setHttpError] = useState(null);
+ const { linkableBibFields } = useAuthorityLinking();
const prepareForSubmit = useCallback((formValues) => {
const formValuesToSave = removeDeletedRecords(formValues);
@@ -78,6 +79,7 @@ const QuickMarcEditWrapper = ({
locations,
linksCount,
naturalId: instance.naturalId,
+ linkableBibFields,
});
if (validationErrorMessage) {
@@ -85,7 +87,7 @@ const QuickMarcEditWrapper = ({
}
return undefined;
- }, [initialValues, linksCount, locations, marcType, prepareForSubmit, instance.naturalId]);
+ }, [initialValues, linksCount, locations, marcType, prepareForSubmit, instance.naturalId, linkableBibFields]);
const onSubmit = useCallback(async (formValues) => {
let is1xxOr010Updated = false;
diff --git a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js
index 5c59fef6..10ce9aad 100644
--- a/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js
+++ b/src/QuickMarcEditor/QuickMarcEditorRows/QuickMarcEditorRows.js
@@ -239,7 +239,7 @@ const QuickMarcEditorRows = ({
const isContentField = !(isLocationField || isFixedField || isMaterialCharsField || isPhysDescriptionField);
const isMARCFieldProtections = marcType !== MARC_TYPES.HOLDINGS && action === QUICK_MARC_ACTIONS.EDIT;
const isProtectedField = recordRow.isProtected;
- const isLinkVisible = checkCanBeLinked(stripes, marcType, action, linkableBibFields, recordRow.tag);
+ const isLinkVisible = checkCanBeLinked(stripes, marcType, linkableBibFields, recordRow.tag);
const canViewAuthorityRecord = stripes.hasPerm('ui-marc-authorities.authority-record.view') && recordRow._isLinked;
diff --git a/src/QuickMarcEditor/utils.js b/src/QuickMarcEditor/utils.js
index c39d7a17..9bc6ab92 100644
--- a/src/QuickMarcEditor/utils.js
+++ b/src/QuickMarcEditor/utils.js
@@ -427,7 +427,7 @@ export const checkDuplicate010Field = (marcRecords) => {
return undefined;
};
-export const checkCanBeLinked = (stripes, marcType, action, linkableBibFields, tag) => (
+export const checkCanBeLinked = (stripes, marcType, linkableBibFields, tag) => (
stripes.hasPerm('ui-quick-marc.quick-marc-authority-records.linkUnlink') &&
marcType === MARC_TYPES.BIB &&
linkableBibFields.includes(tag)
@@ -446,19 +446,17 @@ export const validateSubfield = (marcRecords, initialMarcRecords) => {
return undefined;
};
-const validate$9 = (marcRecords, uncontrolledSubfields) => {
- const hasEntered$9 = marcRecords.some(field => {
- if (typeof field.content !== 'string') {
- return false;
- }
+const validate$9InLinkable = (marcRecords, linkableBibFields, uncontrolledSubfields) => {
+ const fieldsToCheck = marcRecords.filter(field => linkableBibFields.includes(field.tag));
- if (field.subfieldGroups) {
- return uncontrolledSubfields.some(subfield => {
- return field.subfieldGroups[subfield] && '$9' in getContentSubfieldValue(field.subfieldGroups[subfield]);
- });
+ const hasEntered$9 = fieldsToCheck.some(field => {
+ if (!field.subfieldGroups) {
+ return '$9' in getContentSubfieldValue(field.content);
}
- return '$9' in getContentSubfieldValue(field.content);
+ return uncontrolledSubfields.some(subfield => {
+ return field.subfieldGroups[subfield] && '$9' in getContentSubfieldValue(field.subfieldGroups[subfield]);
+ });
});
if (hasEntered$9) {
@@ -516,7 +514,7 @@ const validateSubfieldsThatCanBeControlled = (marcRecords, uncontrolledSubfields
return null;
};
-const validateMarcBibRecord = (marcRecords) => {
+const validateMarcBibRecord = (marcRecords, linkableBibFields) => {
const titleRecords = marcRecords.filter(({ tag }) => tag === '245');
if (titleRecords.length === 0) {
@@ -529,7 +527,7 @@ const validateMarcBibRecord = (marcRecords) => {
const uncontrolledSubfields = ['uncontrolledAlpha', 'uncontrolledNumber'];
- const $9Error = validate$9(marcRecords, uncontrolledSubfields);
+ const $9Error = validate$9InLinkable(marcRecords, linkableBibFields, uncontrolledSubfields);
if ($9Error) {
return $9Error;
@@ -685,6 +683,7 @@ export const validateMarcRecord = ({
locations = [],
linksCount,
naturalId,
+ linkableBibFields = [],
}) => {
const marcRecords = marcRecord.records || [];
const initialMarcRecords = initialValues.records;
@@ -699,7 +698,7 @@ export const validateMarcRecord = ({
let validationResult;
if (marcType === MARC_TYPES.BIB) {
- validationResult = validateMarcBibRecord(marcRecords);
+ validationResult = validateMarcBibRecord(marcRecords, linkableBibFields);
} else if (marcType === MARC_TYPES.HOLDINGS) {
validationResult = validateMarcHoldingsRecord(marcRecords, locations);
} else if (marcType === MARC_TYPES.AUTHORITY) {
diff --git a/src/QuickMarcEditor/utils.test.js b/src/QuickMarcEditor/utils.test.js
index 747cc5a4..1f17bb01 100644
--- a/src/QuickMarcEditor/utils.test.js
+++ b/src/QuickMarcEditor/utils.test.js
@@ -419,6 +419,15 @@ describe('QuickMarcEditor utils', () => {
'_isDeleted': false,
'_isLinked': false,
},
+ {
+ 'tag': '500',
+ 'content': '$a Black Panther $c (Fictitious character) $v Comic books, strips, etc.',
+ 'indicators': ['0', '0'],
+ 'isProtected': false,
+ 'id': '402c0aec-5e1b-49a3-83a2-da788f48b27a',
+ '_isDeleted': false,
+ '_isLinked': false,
+ },
],
};
@@ -430,19 +439,33 @@ describe('QuickMarcEditor utils', () => {
expect(utils.validateMarcRecord({
marcRecord: record,
initialValues,
+ linkableBibFields: ['100', '600'],
}).props.id).toBe('ui-quick-marc.record.error.$9');
});
- it('should return an error for a not linked field', () => {
+ it('should return an error for linkable field', () => {
const record = cloneDeep(initialValues);
- record.records[4].content += ' $9 fakeValue';
+ record.records[4].content = '$9 fakeValue';
expect(utils.validateMarcRecord({
marcRecord: record,
initialValues,
+ linkableBibFields: ['100', '600'],
}).props.id).toBe('ui-quick-marc.record.error.$9');
});
+
+ it('should not return an error for a not linkable field', () => {
+ const record = cloneDeep(initialValues);
+
+ record.records[5].content += ' $9 fakeValue';
+
+ expect(utils.validateMarcRecord({
+ marcRecord: record,
+ initialValues,
+ linkableBibFields: ['100', '600'],
+ })).toBeUndefined();
+ });
});
describe('when a user enters into the linked field subfield(s) that can be controlled', () => {
diff --git a/translations/ui-quick-marc/en.json b/translations/ui-quick-marc/en.json
index c506349b..1c7637bc 100644
--- a/translations/ui-quick-marc/en.json
+++ b/translations/ui-quick-marc/en.json
@@ -186,7 +186,7 @@
"record.error.tag.nonDigits": "Invalid MARC tag. Please try again.",
"record.error.subfield": "Missing a subfield value for a MARC tag",
"record.error.location.invalid": "852 $b contains an invalid Location code. Please try again.",
- "record.error.$9": "$9 is not a valid subfield.",
+ "record.error.$9": "$9 is an invalid subfield for linkable bibliographic fields.",
"record.error.1xx.change": "Cannot change the saved MARC authority field {tag} because it controls a bibliographic field(s). To change this 1XX, you must unlink all controlled bibliographic fields.",
"record.error.1xx.add$t": "Cannot add a $t to the ${tag} field because it controls a bibliographic field(s) that cannot control this subfield. To change this 1XX value, you must unlink all controlled bibliographic fields that cannot control $t.",
"record.error.1xx.remove$t": "Cannot remove $t from the ${tag} field because it controls a bibliographic field(s) that requires this subfield. To change this 1XX value, you must unlink all controlled bibliographic fields that requires $t to be controlled.",