Skip to content

Commit 96dcf95

Browse files
committed
UIQM-791 show "Optimistic locking" message when an non-mapped Instance fields have been updated
1 parent 350d08f commit 96dcf95

File tree

9 files changed

+4
-146
lines changed

9 files changed

+4
-146
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* [UIQM-789](https://issues.folio.org/browse/UIQM-789) Add new `initialValues` prop to quickMARC to initialize it with some pre-existing values.
1414
* [UIQM-790](https://issues.folio.org/browse/UIQM-790) Allow to initialize quickMARC with pre-edited values.
1515
* [UIQM-781](https://issues.folio.org/browse/UIQM-781) Allow editing 005 field tags.
16+
* [UIQM-791](https://issues.folio.org/browse/UIQM-791) show "Optimistic locking" message when an non-mapped Instance fields have been updated.
1617

1718
## [10.0.4](https://github.com/folio-org/ui-quick-marc/tree/v10.0.4) (2025-07-14)
1819

src/QuickMarcEditor/QuickMarcEditorContainer.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ const QuickMarcEditorContainer = ({
9797
setInstance,
9898
setMarcRecord,
9999
setPreEditedValues,
100-
setRelatedRecordVersion,
101100
getIsShared,
102101
isUsingRouter,
103102
} = useContext(QuickMarcContext);
@@ -252,7 +251,6 @@ const QuickMarcEditorContainer = ({
252251
);
253252
}
254253

255-
setRelatedRecordVersion(instanceResponse?._version);
256254
setInstance(instanceResponse);
257255
setMarcRecord(formatInitialValues(dehydratedMarcRecord, _action, linkingRulesResponse));
258256

@@ -288,7 +286,6 @@ const QuickMarcEditorContainer = ({
288286
centralTenantId,
289287
token,
290288
locale,
291-
setRelatedRecordVersion,
292289
getIsShared,
293290
stripes,
294291
]);

src/QuickMarcEditor/QuickMarcEditorContainer.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ jest.mock('../queries', () => ({
6565
const getInstance = () => ({
6666
id: faker.random.uuid(),
6767
title: `ui-quick-marc.${MARC_TYPES.BIB}-record.edit.title`,
68-
_version: '1',
6968
});
7069

7170
const record = {

src/QuickMarcEditor/useSaveRecord/useSaveRecord.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ const useSaveRecord = ({
150150
prepareForSubmit,
151151
mutator,
152152
linksCount,
153-
isRequestToCentralTenantFromMember,
154153
tenantId,
155154
refreshPageData,
156155
onClose,

src/QuickMarcEditor/useSaveRecord/useSaveRecord.test.js

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,6 @@ const getMutator = (instance) => ({
9191
quickMarcRecordStatus: {
9292
GET: jest.fn(() => Promise.resolve({})),
9393
},
94-
quickMarcEditInstance: {
95-
GET: jest.fn(() => Promise.resolve(instance)),
96-
},
9794
locations: {
9895
GET: () => Promise.resolve({}),
9996
},
@@ -622,7 +619,6 @@ const getInitialValues = (action, marcType) => {
622619
[QUICK_MARC_ACTIONS.EDIT]: () => ({
623620
leader: leadersMap[marcType],
624621
records: recordsMap[action]()[marcType],
625-
relatedRecordVersion: 1,
626622
}),
627623
[QUICK_MARC_ACTIONS.DERIVE]: () => ({
628624
leader: bibLeader,
@@ -661,7 +657,6 @@ const getFormValues = (action, marcType) => {
661657
marcFormat: marcType.toUpperCase(),
662658
parsedRecordDtoId: '00000000-0000-0000-0000-000000000000',
663659
records: recordsMap[action]()[marcType],
664-
relatedRecordVersion: 1,
665660
suppressDiscovery: false,
666661
updateInfo: { recordState: 'NEW' },
667662
}),
@@ -924,7 +919,6 @@ describe('useSaveRecord', () => {
924919
},
925920
],
926921
'parsedRecordDtoId': '00000000-0000-0000-0000-000000000000',
927-
'relatedRecordVersion': 1,
928922
'marcFormat': 'BIBLIOGRAPHIC',
929923
'suppressDiscovery': false,
930924
'updateInfo': {
@@ -967,7 +961,6 @@ describe('useSaveRecord', () => {
967961
},
968962
],
969963
'parsedRecordDtoId': '00000000-0000-0000-0000-000000000000',
970-
'relatedRecordVersion': 1,
971964
'marcFormat': 'BIBLIOGRAPHIC',
972965
'suppressDiscovery': false,
973966
'updateInfo': {
@@ -989,7 +982,6 @@ describe('useSaveRecord', () => {
989982
marcFormat: MARC_TYPES.AUTHORITY.toUpperCase(),
990983
parsedRecordDtoId: '00000000-0000-0000-0000-000000000000',
991984
records: undefined,
992-
relatedRecordVersion: 1,
993985
suppressDiscovery: false,
994986
updateInfo: { recordState: 'NEW' },
995987
_actionType: 'create',
@@ -1507,42 +1499,6 @@ describe('useSaveRecord', () => {
15071499
});
15081500
});
15091501

1510-
describe('when there is a record returned with different version', () => {
1511-
it('should return the optimistic locking error', async () => {
1512-
const marcType = MARC_TYPES.BIB;
1513-
const action = QUICK_MARC_ACTIONS.EDIT;
1514-
1515-
const { result } = renderHook(useSaveRecord, {
1516-
initialProps: {
1517-
...getInitialProps(marcType),
1518-
mutator: getMutator({
1519-
...getInstance(),
1520-
_version: '2',
1521-
}),
1522-
},
1523-
wrapper: getWrapper({
1524-
quickMarcContext: {
1525-
action,
1526-
marcType,
1527-
initialValues: getInitialValues(action, marcType),
1528-
instance: {
1529-
...getInstance(),
1530-
_version: '1',
1531-
},
1532-
},
1533-
}),
1534-
});
1535-
1536-
await act(async () => result.current.onSubmit(getFormValues(QUICK_MARC_ACTIONS.EDIT, marcType)));
1537-
1538-
expect(result.current.httpError).toEqual({
1539-
errorType: ERROR_TYPES.OPTIMISTIC_LOCKING,
1540-
message: 'ui-quick-marc.record.save.error.derive',
1541-
});
1542-
expect(mockUpdateMarcRecord).not.toHaveBeenCalled();
1543-
});
1544-
});
1545-
15461502
describe('when there is an error during PUT request due to optimistic locking', () => {
15471503
it('should return the error', async () => {
15481504
const marcType = MARC_TYPES.BIB;
@@ -1578,38 +1534,6 @@ describe('useSaveRecord', () => {
15781534
});
15791535
});
15801536

1581-
describe('when record not found (already deleted)', () => {
1582-
it('should return the error', async () => {
1583-
const marcType = MARC_TYPES.BIB;
1584-
const action = QUICK_MARC_ACTIONS.EDIT;
1585-
1586-
const { result } = renderHook(useSaveRecord, {
1587-
initialProps: {
1588-
...getInitialProps(marcType),
1589-
mutator: {
1590-
...getMutator(getInstance()),
1591-
quickMarcEditInstance: { GET: jest.fn().mockRejectedValue({ httpStatus: 404 }) },
1592-
},
1593-
},
1594-
wrapper: getWrapper({
1595-
quickMarcContext: {
1596-
action,
1597-
marcType,
1598-
initialValues: getInitialValues(action, marcType),
1599-
instance: getInstance(),
1600-
},
1601-
}),
1602-
});
1603-
1604-
await act(async () => result.current.onSubmit(getFormValues(QUICK_MARC_ACTIONS.EDIT, marcType)));
1605-
1606-
expect(result.current.httpError).toEqual({
1607-
errorType: 'other',
1608-
httpStatus: 404,
1609-
});
1610-
});
1611-
});
1612-
16131537
describe('when a member tenant edits a shared record', () => {
16141538
it('should apply the central tenant id for all authority linking ', async () => {
16151539
checkIfUserInMemberTenant.mockClear().mockReturnValue(true);
@@ -1952,7 +1876,6 @@ describe('useSaveRecord', () => {
19521876
'parsedRecordDtoId': '2b56625f-1ca0-4ada-a32d-2667be1bd509',
19531877
'externalId': 'e72f49c9-9bbf-4d2b-89eb-3d2ee5878530',
19541878
'externalHrid': 'in00000000035',
1955-
'relatedRecordVersion': 1,
19561879
};
19571880

19581881
await result.current.onSubmit(formValues);

src/QuickMarcEditor/useSaveRecord/useSubmitRecord/useSumbitRecord.js

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@ import {
88
useParams,
99
} from 'react-router-dom';
1010
import noop from 'lodash/noop';
11-
import isNil from 'lodash/isNil';
1211

1312
import {
1413
useStripes,
1514
checkIfUserInCentralTenant,
1615
checkIfUserInMemberTenant,
1716
} from '@folio/stripes/core';
1817
import { useShowCallout } from '@folio/stripes-acq-components';
19-
import { getHeaders } from '@folio/stripes-marc-components';
2018

21-
import { ERROR_TYPES, EXTERNAL_INSTANCE_APIS, MARC_TYPES } from '../../../common';
19+
import { MARC_TYPES } from '../../../common';
2220
import {
2321
are010Or1xxUpdated,
2422
getFieldIds,
@@ -37,7 +35,6 @@ const useSubmitRecord = ({
3735
prepareForSubmit,
3836
mutator,
3937
linksCount,
40-
isRequestToCentralTenantFromMember,
4138
tenantId,
4239
refreshPageData,
4340
onClose,
@@ -53,17 +50,12 @@ const useSubmitRecord = ({
5350
const stripes = useStripes();
5451
const [httpError, setHttpError] = useState(null);
5552

56-
const { token, locale } = stripes.okapi;
57-
const centralTenantId = stripes.user.user.consortium?.centralTenantId;
58-
5953
const {
6054
action,
6155
marcType,
6256
basePath,
6357
initialValues,
64-
instance,
6558
continueAfterSave,
66-
relatedRecordVersion,
6759
setIsShared,
6860
isUsingRouter,
6961
} = useContext(QuickMarcContext);
@@ -209,35 +201,16 @@ const useSubmitRecord = ({
209201

210202
const formValuesToProcess = prepareForSubmit(formValues);
211203

212-
const path = EXTERNAL_INSTANCE_APIS[marcType];
213-
214-
const fetchInstance = async () => {
215-
const fetchedInstance = await mutator.quickMarcEditInstance.GET({
216-
path: `${path}/${formValuesToProcess.externalId}`,
217-
...(isRequestToCentralTenantFromMember && { headers: getHeaders(centralTenantId, token, locale) }),
218-
});
219-
220-
return fetchedInstance;
221-
};
222-
223204
let formValuesToHydrate;
224-
let instanceResponse;
225205

226206
try {
227207
const actualizeLinksPromise = marcType === MARC_TYPES.BIB
228208
? actualizeLinks(formValuesToProcess)
229209
: Promise.resolve(formValuesToProcess);
230210

231-
const [
232-
formValuesWithActualizedLinkedFields,
233-
instanceData,
234-
] = await Promise.all([
235-
actualizeLinksPromise,
236-
fetchInstance(),
237-
]);
211+
const formValuesWithActualizedLinkedFields = await actualizeLinksPromise;
238212

239213
formValuesToHydrate = formValuesWithActualizedLinkedFields;
240-
instanceResponse = instanceData;
241214
} catch (errorResponse) {
242215
const parsedError = await parseHttpError(errorResponse);
243216

@@ -246,22 +219,7 @@ const useSubmitRecord = ({
246219
return undefined;
247220
}
248221

249-
const prevVersion = instance._version;
250-
const lastVersion = instanceResponse._version;
251-
252-
if (!isNil(prevVersion) && !isNil(lastVersion) && prevVersion !== lastVersion) {
253-
setHttpError({
254-
errorType: ERROR_TYPES.OPTIMISTIC_LOCKING,
255-
message: 'ui-quick-marc.record.save.error.derive',
256-
});
257-
258-
return null;
259-
}
260-
261222
formValuesToHydrate._actionType = 'edit';
262-
formValuesToHydrate.relatedRecordVersion = marcType === MARC_TYPES.AUTHORITY
263-
? instance._version
264-
: relatedRecordVersion;
265223

266224
const formValuesToSave = hydrateMarcRecord(formValuesToHydrate);
267225

@@ -301,18 +259,11 @@ const useSubmitRecord = ({
301259
showCallout,
302260
refreshPageData,
303261
initialValues,
304-
instance,
305262
marcType,
306-
mutator,
307263
linksCount,
308264
prepareForSubmit,
309265
actualizeLinks,
310-
centralTenantId,
311-
token,
312-
locale,
313266
updateMarcRecord,
314-
isRequestToCentralTenantFromMember,
315-
relatedRecordVersion,
316267
_externalId,
317268
_instanceId,
318269
continueAfterSave,
@@ -336,7 +287,6 @@ const useSubmitRecord = ({
336287
return null;
337288
}
338289

339-
formValuesToHydrate.relatedRecordVersion = 1;
340290
formValuesToHydrate._actionType = 'create';
341291

342292
const formValuesForDerive = hydrateMarcRecord(formValuesToHydrate);

src/QuickMarcEditor/utils.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,8 @@ export const parseHttpError = async (httpError) => {
145145

146146
export const saveLinksToNewRecord = async (mutator, externalId, marcRecord) => {
147147
// request derived Instance record
148-
const instancePromise = mutator.quickMarcEditInstance.GET({ path: `${EXTERNAL_INSTANCE_APIS[MARC_TYPES.BIB]}/${externalId}` });
149148
// request derived MARC Bib record
150-
const marcPromise = mutator.quickMarcEditMarcRecord.GET({ params: { externalId } });
151-
152-
return Promise.all([instancePromise, marcPromise]).then(([{ _version }, derivedRecord]) => {
149+
return mutator.quickMarcEditMarcRecord.GET({ params: { externalId } }).then(derivedRecord => {
153150
// copy linking data to new record
154151
derivedRecord.fields = derivedRecord.fields.map((field) => {
155152
// matching field from POST request
@@ -169,7 +166,6 @@ export const saveLinksToNewRecord = async (mutator, externalId, marcRecord) => {
169166
return field;
170167
});
171168

172-
derivedRecord.relatedRecordVersion = parseInt(_version, 10);
173169
derivedRecord._actionType = 'edit';
174170

175171
return mutator.quickMarcEditMarcRecord.PUT(derivedRecord);
@@ -458,7 +454,6 @@ export const formatMarcRecordByQuickMarcAction = (marcRecord, action, marcType)
458454
if (action === QUICK_MARC_ACTIONS.CREATE) {
459455
return {
460456
...marcRecord,
461-
relatedRecordVersion: 1,
462457
marcFormat: marcType.toUpperCase(),
463458
suppressDiscovery: false,
464459
updateInfo: {

src/QuickMarcEditor/utils.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,6 @@ describe('QuickMarcEditor utils', () => {
800800

801801
const expectedRecord = {
802802
...record,
803-
relatedRecordVersion: 1,
804803
marcFormat: 'HOLDINGS',
805804
suppressDiscovery: false,
806805
updateInfo: {

src/contexts/QuickMarcContext/QuickMarcContext.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ const QuickMarcProvider = ({
3939
const [marcRecord, setMarcRecord] = useState(null);
4040
const [preEditedValues, setPreEditedValues] = useState(null);
4141
const [selectedSourceFile, setSelectedSourceFile] = useState(null);
42-
const [_relatedRecordVersion, setRelatedRecordVersion] = useState();
4342
const validationErrors = useRef({});
4443
const continueAfterSave = useRef(false);
4544

@@ -77,8 +76,6 @@ const QuickMarcProvider = ({
7776
setSelectedSourceFile,
7877
validationErrorsRef: validationErrors,
7978
setValidationErrors,
80-
relatedRecordVersion: _relatedRecordVersion,
81-
setRelatedRecordVersion,
8279
continueAfterSave,
8380
action,
8481
marcType,
@@ -98,8 +95,6 @@ const QuickMarcProvider = ({
9895
setSelectedSourceFile,
9996
validationErrors,
10097
setValidationErrors,
101-
_relatedRecordVersion,
102-
setRelatedRecordVersion,
10398
continueAfterSave,
10499
action,
105100
marcType,

0 commit comments

Comments
 (0)