@strapi/content-manager 5.55.1 → 5.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/pages/EditView/components/DocumentActions.js +133 -129
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +137 -133
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +113 -28
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +113 -29
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +8 -3
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +8 -3
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations/RelationModal.d.ts +27 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +4 -4
- package/dist/server/controllers/relations.js +4 -0
- package/dist/server/controllers/relations.js.map +1 -1
- package/dist/server/controllers/relations.mjs +4 -0
- package/dist/server/controllers/relations.mjs.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -48,23 +48,38 @@ const publishConfirmDialogOpeners = new Map();
|
|
|
48
48
|
const openPublishConfirmDialog = (scope)=>{
|
|
49
49
|
publishConfirmDialogOpeners.get(scope)?.();
|
|
50
50
|
};
|
|
51
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Builds the local-form patch needed to connect a newly created/published relation into the
|
|
53
|
+
* parent's own relation field, given that field's CURRENT (possibly unsaved) live value.
|
|
54
|
+
*
|
|
55
|
+
* This only ever touches the parent's in-memory form state (via `setParentFormValue`, sourced
|
|
56
|
+
* from the parent's own `useForm(...).onChange`) — it deliberately never persists the parent
|
|
57
|
+
* document to the server, so connecting a relation on the fly can't silently save unrelated
|
|
58
|
+
* unsaved edits made elsewhere in the parent's form.
|
|
59
|
+
*/ const buildRelationConnectPatch = (currentFieldValue, fieldToConnect, data, status, fieldToConnectUID)=>{
|
|
60
|
+
// Spread the freshly created/published document first so its own mainField (e.g. `name`) and
|
|
61
|
+
// other attributes — including its real numeric `id`, not just `documentId` — are available.
|
|
62
|
+
// Without the real `id`, the relation field's "already connected" search filter (which keys off
|
|
63
|
+
// `rel.id`) can't recognize this item, so it would stay selectable in the relation combobox
|
|
64
|
+
// even after being connected. Keeping the label/status render correct needs the mainField too,
|
|
65
|
+
// which is why we still spread the whole document rather than only picking id/documentId/locale.
|
|
52
66
|
const relationToConnect = {
|
|
53
|
-
|
|
67
|
+
...data,
|
|
54
68
|
documentId: data.documentId,
|
|
55
|
-
locale: data.locale
|
|
69
|
+
locale: data.locale,
|
|
70
|
+
...status ? {
|
|
71
|
+
status
|
|
72
|
+
} : {}
|
|
56
73
|
};
|
|
57
74
|
/*
|
|
58
|
-
* Check if the fieldToConnect
|
|
59
|
-
*
|
|
60
|
-
|
|
61
|
-
*/ const fieldValue = objects.getIn(parentDataToUpdate, fieldToConnect);
|
|
62
|
-
const relationFieldValue = objects.isObject(fieldValue) ? fieldValue : undefined;
|
|
75
|
+
* Check if the fieldToConnect already has a value. This happens in particular when in the
|
|
76
|
+
* parent document you have created a new component without saving.
|
|
77
|
+
*/ const relationFieldValue = objects.isObject(currentFieldValue) ? currentFieldValue : undefined;
|
|
63
78
|
const isFieldPresent = relationFieldValue !== undefined;
|
|
64
79
|
const fieldPath = fieldToConnect.split('.');
|
|
65
80
|
const fieldName = fieldPath.at(-1);
|
|
66
81
|
if (!fieldName) {
|
|
67
|
-
return
|
|
82
|
+
return null;
|
|
68
83
|
}
|
|
69
84
|
const parentPath = fieldPath.slice(0, -1).join('.');
|
|
70
85
|
const existingConnect = Array.isArray(relationFieldValue?.connect) ? relationFieldValue.connect : [];
|
|
@@ -80,11 +95,10 @@ const connectRelationToParent = (parentDataToUpdate, fieldToConnect, data, field
|
|
|
80
95
|
connect,
|
|
81
96
|
disconnect: []
|
|
82
97
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
return dataWithRelation;
|
|
98
|
+
return {
|
|
99
|
+
relationValue,
|
|
100
|
+
componentUIDPath: !isFieldPresent && fieldToConnectUID && parentPath ? `${parentPath}.__component` : undefined
|
|
101
|
+
};
|
|
88
102
|
};
|
|
89
103
|
const DocumentActions = ({ actions })=>{
|
|
90
104
|
const { formatMessage } = reactIntl.useIntl();
|
|
@@ -469,18 +483,6 @@ const transformData = (data)=>{
|
|
|
469
483
|
return data;
|
|
470
484
|
};
|
|
471
485
|
const transformDocumentData = (data)=>transformData(data);
|
|
472
|
-
const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentFormValues, options)=>{
|
|
473
|
-
const parentDataToUpdate = parentFormValues ?? fallbackParentFormValues;
|
|
474
|
-
if (!parentDataToUpdate) {
|
|
475
|
-
return parentDataToUpdate;
|
|
476
|
-
}
|
|
477
|
-
const { data: data$1 } = data.handleInvisibleAttributes(transformDocumentData(parentDataToUpdate), {
|
|
478
|
-
...options,
|
|
479
|
-
// The live snapshot can omit saved invisible fields, so retain the parent's saved initial values.
|
|
480
|
-
initialValues: fallbackParentFormValues
|
|
481
|
-
});
|
|
482
|
-
return data$1;
|
|
483
|
-
};
|
|
484
486
|
/* -------------------------------------------------------------------------------------------------
|
|
485
487
|
* DocumentActionComponents
|
|
486
488
|
* -----------------------------------------------------------------------------------------------*/ const PublishAction = ({ activeTab, documentId, model, collectionType, meta, document })=>{
|
|
@@ -498,6 +500,7 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
498
500
|
}));
|
|
499
501
|
const { publish, isLoading } = useDocumentActions.useDocumentActions();
|
|
500
502
|
const onPreview = Preview.usePreviewContext('PublishAction', (state)=>state.onPreview, false);
|
|
503
|
+
const [fetchDraftDocument] = documents.useLazyGetDocumentQuery();
|
|
501
504
|
const [countDraftRelations, { isError: isErrorDraftRelations }] = documents.useGetDraftRelationCountQuery();
|
|
502
505
|
const [localDraftRelationCounts, setLocalDraftRelationCounts] = React__namespace.useState(draftRelationCounts.EMPTY_DRAFT_RELATION_COUNTS);
|
|
503
506
|
const [serverDraftRelationCounts, setServerDraftRelationCounts] = React__namespace.useState(draftRelationCounts.EMPTY_DRAFT_RELATION_COUNTS);
|
|
@@ -515,18 +518,15 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
515
518
|
// need to discriminate if the publish is coming from a relation modal or in the edit view
|
|
516
519
|
const relationContext = RelationModal.useRelationModal('PublishAction', ()=>true, false);
|
|
517
520
|
const fromRelationModal = relationContext != undefined;
|
|
518
|
-
const isRelationModalOpen = RelationModal.useRelationModal('PublishAction', (state)=>state.state.isModalOpen, false);
|
|
519
521
|
const publishConfirmScope = fromRelationModal ? 'relation-modal' : onPreview ? 'preview' : 'panel';
|
|
520
522
|
const dispatch = RelationModal.useRelationModal('PublishAction', (state)=>state.dispatch);
|
|
521
523
|
const fieldToConnect = RelationModal.useRelationModal('PublishAction', (state)=>state.state.fieldToConnect, false);
|
|
522
524
|
const fieldToConnectUID = RelationModal.useRelationModal('PublishAction', (state)=>state.state.fieldToConnectUID, false);
|
|
523
525
|
const getParentFormValues = RelationModal.useRelationModal('PublishAction', (state)=>state.state.getParentFormValues, false);
|
|
526
|
+
const setParentFormValue = RelationModal.useRelationModal('PublishAction', (state)=>state.state.setParentFormValue, false);
|
|
524
527
|
const documentHistory = RelationModal.useRelationModal('PublishAction', (state)=>state.state.documentHistory, false);
|
|
525
|
-
const rootDocumentMeta = RelationModal.useRelationModal('PublishAction', (state)=>state.rootDocumentMeta);
|
|
526
528
|
const dispatchGuidedTour = strapiAdmin.useGuidedTour('PublishAction', (s)=>s.dispatch);
|
|
527
529
|
const { currentDocumentMeta } = useDocumentContext.useDocumentContext('PublishAction');
|
|
528
|
-
const [updateDocumentMutation] = documents.useUpdateDocumentMutation();
|
|
529
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
|
530
530
|
const idToPublish = currentDocumentMeta.documentId || id;
|
|
531
531
|
React__namespace.useEffect(()=>{
|
|
532
532
|
if (isErrorDraftRelations) {
|
|
@@ -599,16 +599,6 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
599
599
|
}, [
|
|
600
600
|
fetchDraftRelationsCount
|
|
601
601
|
]);
|
|
602
|
-
const parentDocumentMetaToUpdate = documentHistory?.at(-2) ?? rootDocumentMeta;
|
|
603
|
-
const parentDocumentData = useDocument.useDocument({
|
|
604
|
-
documentId: parentDocumentMetaToUpdate?.documentId,
|
|
605
|
-
model: parentDocumentMetaToUpdate?.model,
|
|
606
|
-
collectionType: parentDocumentMetaToUpdate?.collectionType,
|
|
607
|
-
params: parentDocumentMetaToUpdate?.params
|
|
608
|
-
}, {
|
|
609
|
-
skip: !parentDocumentMetaToUpdate
|
|
610
|
-
});
|
|
611
|
-
const { getInitialFormValues } = useDocument.useDoc();
|
|
612
602
|
const isDocumentPublished = (document?.[attributes.PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc)=>doc[attributes.PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== 'modified';
|
|
613
603
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
614
604
|
const performPublish = async ()=>{
|
|
@@ -665,6 +655,17 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
665
655
|
// Reset form with current values as new initial values (clears errors/submitting and sets modified to false)
|
|
666
656
|
if ('data' in res) {
|
|
667
657
|
resetForm(getValues());
|
|
658
|
+
// This document is now persisted with whatever local connect patches were merged into
|
|
659
|
+
// it, if any (see the pendingConnects explanation below) — they'd be stale from here on.
|
|
660
|
+
dispatch?.({
|
|
661
|
+
type: 'CLEAR_PENDING_CONNECTS',
|
|
662
|
+
payload: {
|
|
663
|
+
documentMeta: {
|
|
664
|
+
model,
|
|
665
|
+
documentId: res.data.documentId
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
});
|
|
668
669
|
dispatchGuidedTour({
|
|
669
670
|
type: 'set_completed_actions',
|
|
670
671
|
payload: [
|
|
@@ -690,42 +691,45 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
690
691
|
params: currentDocumentMeta.params
|
|
691
692
|
};
|
|
692
693
|
/*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
694
|
+
* Connect the newly published document to the parent's relation field, purely in local
|
|
695
|
+
* form state — never on the server. This must not persist the parent document,
|
|
696
|
+
* otherwise publishing here would silently save any of the parent's other unrelated
|
|
697
|
+
* unsaved edits too.
|
|
698
|
+
*
|
|
699
|
+
* The parent is either the root document that originally opened the modal (its own Form
|
|
700
|
+
* stays mounted for the whole session, so it's safe to write into directly) or a nested
|
|
701
|
+
* document still further up the modal's documentHistory (whose Form is the SAME shared
|
|
702
|
+
* instance the modal reuses at every level, wholesale-replaced on every navigation — a
|
|
703
|
+
* direct write there would land on the wrong document and be gone the moment we
|
|
704
|
+
* navigate). For the latter the patch is queued on GO_TO_CREATED_RELATION below instead,
|
|
705
|
+
* to be re-applied once that document becomes current again.
|
|
706
|
+
*/ const isNestedParent = Array.isArray(documentHistory) && documentHistory.length >= 2;
|
|
707
|
+
let connectPatch;
|
|
708
|
+
if (fieldToConnect && (setParentFormValue || isNestedParent)) {
|
|
709
|
+
const currentFieldValue = objects.getIn(getParentFormValues?.(), fieldToConnect);
|
|
710
|
+
// Publishing a brand-new document creates two rows sharing one documentId — a draft
|
|
711
|
+
// and a published one, each with its own numeric id. The parent's relation search
|
|
712
|
+
// (and its "already connected" filter) identifies items by the draft row's id, so
|
|
713
|
+
// connecting with the publish response's id would leave this relation still
|
|
714
|
+
// selectable there. Fetch the draft row to get the id the search actually expects.
|
|
715
|
+
const draftDocument = await fetchDraftDocument({
|
|
716
|
+
collectionType,
|
|
717
|
+
model,
|
|
718
|
+
documentId: res.data.documentId,
|
|
719
|
+
params: currentDocumentMeta.params
|
|
701
720
|
});
|
|
702
|
-
const
|
|
703
|
-
if (
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
toggleNotification({
|
|
715
|
-
type: 'danger',
|
|
716
|
-
message: formatAPIError(updateRes.error)
|
|
717
|
-
});
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
} catch (err) {
|
|
721
|
-
toggleNotification({
|
|
722
|
-
type: 'danger',
|
|
723
|
-
message: formatMessage({
|
|
724
|
-
id: 'notification.error',
|
|
725
|
-
defaultMessage: 'An error occurred'
|
|
726
|
-
})
|
|
727
|
-
});
|
|
728
|
-
throw err;
|
|
721
|
+
const patch = buildRelationConnectPatch(currentFieldValue, fieldToConnect, draftDocument.data?.data ?? res.data, 'published', fieldToConnectUID);
|
|
722
|
+
if (patch && isNestedParent) {
|
|
723
|
+
connectPatch = {
|
|
724
|
+
fieldToConnect,
|
|
725
|
+
relationValue: patch.relationValue,
|
|
726
|
+
componentUIDPath: patch.componentUIDPath,
|
|
727
|
+
componentUID: patch.componentUIDPath ? fieldToConnectUID : undefined
|
|
728
|
+
};
|
|
729
|
+
} else if (patch && setParentFormValue) {
|
|
730
|
+
setParentFormValue(fieldToConnect, patch.relationValue);
|
|
731
|
+
if (patch.componentUIDPath) {
|
|
732
|
+
setParentFormValue(patch.componentUIDPath, fieldToConnectUID);
|
|
729
733
|
}
|
|
730
734
|
}
|
|
731
735
|
}
|
|
@@ -733,7 +737,8 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
733
737
|
type: 'GO_TO_CREATED_RELATION',
|
|
734
738
|
payload: {
|
|
735
739
|
document: newRelation,
|
|
736
|
-
shouldBypassConfirmation: true
|
|
740
|
+
shouldBypassConfirmation: true,
|
|
741
|
+
connectPatch
|
|
737
742
|
}
|
|
738
743
|
});
|
|
739
744
|
}
|
|
@@ -779,7 +784,9 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
779
784
|
return;
|
|
780
785
|
}
|
|
781
786
|
e.preventDefault();
|
|
782
|
-
|
|
787
|
+
// When a relation modal is open, only its own PublishAction instance (fromRelationModal)
|
|
788
|
+
// should react to the shortcut — otherwise the background entry publishes at the same time.
|
|
789
|
+
if (!fromRelationModal && RelationModal.isAnyRelationModalOpen()) {
|
|
783
790
|
return;
|
|
784
791
|
}
|
|
785
792
|
if (isDisabled) {
|
|
@@ -799,7 +806,6 @@ const prepareParentDataForRelationUpdate = (parentFormValues, fallbackParentForm
|
|
|
799
806
|
fromRelationModal,
|
|
800
807
|
getFreshDraftRelationCounts,
|
|
801
808
|
isDisabled,
|
|
802
|
-
isRelationModalOpen,
|
|
803
809
|
performPublish,
|
|
804
810
|
publishConfirmScope,
|
|
805
811
|
schema?.options?.draftAndPublish
|
|
@@ -895,7 +901,6 @@ const UpdateAction = ({ activeTab, documentId, model, collectionType })=>{
|
|
|
895
901
|
const { currentDocument: { components } } = useDocumentContext.useDocumentContext('UpdateAction');
|
|
896
902
|
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
|
897
903
|
const onPreview = Preview.usePreviewContext('UpdateAction', (state)=>state.onPreview, false);
|
|
898
|
-
const { getInitialFormValues } = useDocument.useDoc();
|
|
899
904
|
const isSubmitting = strapiAdmin.useForm('UpdateAction', ({ isSubmitting })=>isSubmitting);
|
|
900
905
|
const modified = strapiAdmin.useForm('UpdateAction', ({ modified })=>modified);
|
|
901
906
|
const setSubmitting = strapiAdmin.useForm('UpdateAction', ({ setSubmitting })=>setSubmitting);
|
|
@@ -911,21 +916,10 @@ const UpdateAction = ({ activeTab, documentId, model, collectionType })=>{
|
|
|
911
916
|
const fieldToConnect = RelationModal.useRelationModal('UpdateAction', (state)=>state.state.fieldToConnect, false);
|
|
912
917
|
const fieldToConnectUID = RelationModal.useRelationModal('PublishAction', (state)=>state.state.fieldToConnectUID, false);
|
|
913
918
|
const getParentFormValues = RelationModal.useRelationModal('UpdateAction', (state)=>state.state.getParentFormValues, false);
|
|
919
|
+
const setParentFormValue = RelationModal.useRelationModal('UpdateAction', (state)=>state.state.setParentFormValue, false);
|
|
914
920
|
const documentHistory = RelationModal.useRelationModal('UpdateAction', (state)=>state.state.documentHistory, false);
|
|
915
|
-
const rootDocumentMeta = RelationModal.useRelationModal('UpdateAction', (state)=>state.rootDocumentMeta);
|
|
916
921
|
const fromRelationModal = relationContext != undefined;
|
|
917
922
|
const { currentDocumentMeta } = useDocumentContext.useDocumentContext('UpdateAction');
|
|
918
|
-
const [updateDocumentMutation] = documents.useUpdateDocumentMutation();
|
|
919
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
|
920
|
-
const parentDocumentMetaToUpdate = documentHistory?.at(-2) ?? rootDocumentMeta;
|
|
921
|
-
const parentDocumentData = useDocument.useDocument({
|
|
922
|
-
documentId: parentDocumentMetaToUpdate?.documentId,
|
|
923
|
-
model: parentDocumentMetaToUpdate?.model,
|
|
924
|
-
collectionType: parentDocumentMetaToUpdate?.collectionType,
|
|
925
|
-
params: parentDocumentMetaToUpdate?.params
|
|
926
|
-
}, {
|
|
927
|
-
skip: !parentDocumentMetaToUpdate
|
|
928
|
-
});
|
|
929
923
|
const { schema } = useDocument.useDoc();
|
|
930
924
|
const suitableSchema = fromRelationModal ? relationalModalSchema : schema;
|
|
931
925
|
const hasDraftAndPublished = suitableSchema?.options?.draftAndPublish ?? false;
|
|
@@ -997,6 +991,17 @@ const UpdateAction = ({ activeTab, documentId, model, collectionType })=>{
|
|
|
997
991
|
setErrors(formatValidationErrors(res.error));
|
|
998
992
|
} else {
|
|
999
993
|
resetForm(latestValues);
|
|
994
|
+
// This document is now persisted with whatever local connect patches were merged into
|
|
995
|
+
// it, if any (see the pendingConnects explanation below) — they'd be stale from here on.
|
|
996
|
+
dispatch?.({
|
|
997
|
+
type: 'CLEAR_PENDING_CONNECTS',
|
|
998
|
+
payload: {
|
|
999
|
+
documentMeta: {
|
|
1000
|
+
model,
|
|
1001
|
+
documentId
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1000
1005
|
}
|
|
1001
1006
|
} else {
|
|
1002
1007
|
const { data: data$1 } = data.handleInvisibleAttributes(transformDocumentData(latestValues), {
|
|
@@ -1017,43 +1022,34 @@ const UpdateAction = ({ activeTab, documentId, model, collectionType })=>{
|
|
|
1017
1022
|
params: currentDocumentMeta.params
|
|
1018
1023
|
};
|
|
1019
1024
|
/*
|
|
1020
|
-
*
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
} catch (err) {
|
|
1049
|
-
toggleNotification({
|
|
1050
|
-
type: 'danger',
|
|
1051
|
-
message: formatMessage({
|
|
1052
|
-
id: 'notification.error',
|
|
1053
|
-
defaultMessage: 'An error occurred'
|
|
1054
|
-
})
|
|
1055
|
-
});
|
|
1056
|
-
throw err;
|
|
1025
|
+
* Connect the newly created document to the parent's relation field, purely in local
|
|
1026
|
+
* form state — never on the server. This must not persist the parent document,
|
|
1027
|
+
* otherwise saving here would silently save any of the parent's other unrelated
|
|
1028
|
+
* unsaved edits too.
|
|
1029
|
+
*
|
|
1030
|
+
* The parent is either the root document that originally opened the modal (its own
|
|
1031
|
+
* Form stays mounted for the whole session, so it's safe to write into directly) or a
|
|
1032
|
+
* nested document still further up the modal's documentHistory (whose Form is the
|
|
1033
|
+
* SAME shared instance the modal reuses at every level, wholesale-replaced on every
|
|
1034
|
+
* navigation — a direct write there would land on the wrong document and be gone the
|
|
1035
|
+
* moment we navigate). For the latter the patch is queued on GO_TO_CREATED_RELATION
|
|
1036
|
+
* below instead, to be re-applied once that document becomes current again.
|
|
1037
|
+
*/ const isNestedParent = Array.isArray(documentHistory) && documentHistory.length >= 2;
|
|
1038
|
+
let connectPatch;
|
|
1039
|
+
if (fieldToConnect && (setParentFormValue || isNestedParent)) {
|
|
1040
|
+
const currentFieldValue = objects.getIn(getParentFormValues?.(), fieldToConnect);
|
|
1041
|
+
const patch = buildRelationConnectPatch(currentFieldValue, fieldToConnect, res.data, hasDraftAndPublished ? 'draft' : undefined, fieldToConnectUID);
|
|
1042
|
+
if (patch && isNestedParent) {
|
|
1043
|
+
connectPatch = {
|
|
1044
|
+
fieldToConnect,
|
|
1045
|
+
relationValue: patch.relationValue,
|
|
1046
|
+
componentUIDPath: patch.componentUIDPath,
|
|
1047
|
+
componentUID: patch.componentUIDPath ? fieldToConnectUID : undefined
|
|
1048
|
+
};
|
|
1049
|
+
} else if (patch && setParentFormValue) {
|
|
1050
|
+
setParentFormValue(fieldToConnect, patch.relationValue);
|
|
1051
|
+
if (patch.componentUIDPath) {
|
|
1052
|
+
setParentFormValue(patch.componentUIDPath, fieldToConnectUID);
|
|
1057
1053
|
}
|
|
1058
1054
|
}
|
|
1059
1055
|
}
|
|
@@ -1061,7 +1057,8 @@ const UpdateAction = ({ activeTab, documentId, model, collectionType })=>{
|
|
|
1061
1057
|
type: 'GO_TO_CREATED_RELATION',
|
|
1062
1058
|
payload: {
|
|
1063
1059
|
document: createdRelation,
|
|
1064
|
-
shouldBypassConfirmation: true
|
|
1060
|
+
shouldBypassConfirmation: true,
|
|
1061
|
+
connectPatch
|
|
1065
1062
|
}
|
|
1066
1063
|
});
|
|
1067
1064
|
} else {
|
|
@@ -1098,12 +1095,19 @@ const UpdateAction = ({ activeTab, documentId, model, collectionType })=>{
|
|
|
1098
1095
|
handleUpdateRef.current = handleUpdate;
|
|
1099
1096
|
const isDisabledRef = React__namespace.useRef(isDisabled);
|
|
1100
1097
|
isDisabledRef.current = isDisabled;
|
|
1098
|
+
const fromRelationModalRef = React__namespace.useRef(fromRelationModal);
|
|
1099
|
+
fromRelationModalRef.current = fromRelationModal;
|
|
1101
1100
|
React__namespace.useEffect(()=>{
|
|
1102
1101
|
const handleKeyDown = (e)=>{
|
|
1103
1102
|
if (keyboardShortcuts.getEditViewShortcut(e) !== 'save') {
|
|
1104
1103
|
return;
|
|
1105
1104
|
}
|
|
1106
1105
|
e.preventDefault();
|
|
1106
|
+
// When a relation modal is open, only its own UpdateAction instance (fromRelationModal)
|
|
1107
|
+
// should react to the shortcut — otherwise the background entry saves at the same time.
|
|
1108
|
+
if (!fromRelationModalRef.current && RelationModal.isAnyRelationModalOpen()) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1107
1111
|
if (!isDisabledRef.current) {
|
|
1108
1112
|
handleUpdateRef.current();
|
|
1109
1113
|
}
|