@byline/host-tanstack-start 4.18.0 → 5.0.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-shell/collections/create.js +22 -5
- package/dist/admin-shell/collections/edit.d.ts +1 -1
- package/dist/admin-shell/collections/edit.js +222 -34
- package/dist/admin-shell/collections/history.js +4 -2
- package/dist/admin-shell/collections/list.js +30 -6
- package/dist/admin-shell/collections/restore-version-modal.d.ts +3 -1
- package/dist/admin-shell/collections/restore-version-modal.js +23 -6
- package/dist/admin-shell/collections/save-navigation.test.d.ts +8 -0
- package/dist/admin-shell/collections/tree-list.js +16 -6
- package/dist/admin-shell/collections/version-history.d.ts +2 -1
- package/dist/admin-shell/collections/version-history.js +11 -2
- package/dist/admin-shell/document-mutation-notice.d.ts +6 -0
- package/dist/admin-shell/document-mutation-notice.js +53 -0
- package/dist/admin-shell/document-mutation-state.d.ts +22 -0
- package/dist/admin-shell/document-mutation-state.js +71 -0
- package/dist/admin-shell/document-mutation-state.test.d.ts +1 -0
- package/dist/admin-shell/scheduled-publications/list.js +15 -5
- package/dist/admin-shell/singletons/history.js +4 -2
- package/dist/admin-shell/singletons/view.d.ts +1 -1
- package/dist/admin-shell/singletons/view.js +108 -23
- package/dist/integrations/byline-field-services.js +2 -9
- package/dist/routes/create-collection-edit-route.js +1 -1
- package/dist/routes/create-collection-list-route.d.ts +0 -7
- package/dist/routes/create-collection-list-route.js +7 -9
- package/dist/routes/create-singleton-route.d.ts +2 -0
- package/dist/routes/create-singleton-route.js +4 -3
- package/dist/server-fns/collections/copy-to-locale.d.ts +4 -8
- package/dist/server-fns/collections/copy-to-locale.js +17 -8
- package/dist/server-fns/collections/create.d.ts +2 -8
- package/dist/server-fns/collections/create.js +20 -10
- package/dist/server-fns/collections/delete-locale.d.ts +4 -8
- package/dist/server-fns/collections/delete-locale.js +15 -6
- package/dist/server-fns/collections/delete-outcome.d.ts +7 -3
- package/dist/server-fns/collections/delete-outcome.js +4 -0
- package/dist/server-fns/collections/delete.d.ts +2 -7
- package/dist/server-fns/collections/delete.js +5 -3
- package/dist/server-fns/collections/duplicate.d.ts +4 -8
- package/dist/server-fns/collections/duplicate.js +14 -5
- package/dist/server-fns/collections/get.d.ts +1 -7
- package/dist/server-fns/collections/get.js +5 -4
- package/dist/server-fns/collections/index.d.ts +1 -0
- package/dist/server-fns/collections/index.js +1 -0
- package/dist/server-fns/collections/list.d.ts +0 -7
- package/dist/server-fns/collections/list.js +11 -3
- package/dist/server-fns/collections/reorder.d.ts +7 -8
- package/dist/server-fns/collections/reorder.js +20 -76
- package/dist/server-fns/collections/restore-version.d.ts +4 -8
- package/dist/server-fns/collections/restore-version.js +22 -12
- package/dist/server-fns/collections/save-outcome.d.ts +24 -0
- package/dist/server-fns/collections/save-outcome.js +19 -0
- package/dist/server-fns/collections/scheduled-publication.d.ts +49 -9
- package/dist/server-fns/collections/scheduled-publication.js +31 -21
- package/dist/server-fns/collections/status.d.ts +8 -7
- package/dist/server-fns/collections/status.js +13 -5
- package/dist/server-fns/collections/tree-mutation.d.ts +7 -6
- package/dist/server-fns/collections/tree-mutation.js +17 -5
- package/dist/server-fns/collections/tree.d.ts +14 -8
- package/dist/server-fns/collections/tree.js +21 -17
- package/dist/server-fns/collections/update.d.ts +14 -11
- package/dist/server-fns/collections/update.js +48 -24
- package/dist/server-fns/collections/upload.d.ts +1 -0
- package/dist/server-fns/collections/upload.js +3 -2
- package/dist/server-fns/document-mutation-errors.d.ts +5 -0
- package/dist/server-fns/document-mutation-errors.js +50 -0
- package/dist/server-fns/editable-revision.d.ts +9 -0
- package/dist/server-fns/editable-revision.js +11 -0
- package/dist/server-fns/singleton-document-read.d.ts +1 -1
- package/dist/server-fns/singleton-document-read.js +7 -3
- package/dist/server-fns/singletons/cancel-scheduled-publish.d.ts +6 -8
- package/dist/server-fns/singletons/cancel-scheduled-publish.js +4 -1
- package/dist/server-fns/singletons/change-status.d.ts +2 -7
- package/dist/server-fns/singletons/change-status.js +4 -1
- package/dist/server-fns/singletons/confirm-scheduled-publish.d.ts +5 -8
- package/dist/server-fns/singletons/confirm-scheduled-publish.js +4 -2
- package/dist/server-fns/singletons/copy-to-locale.d.ts +2 -7
- package/dist/server-fns/singletons/copy-to-locale.js +16 -5
- package/dist/server-fns/singletons/get.d.ts +4 -4
- package/dist/server-fns/singletons/restore-version.d.ts +2 -7
- package/dist/server-fns/singletons/restore-version.js +13 -1
- package/dist/server-fns/singletons/schedule-publish.d.ts +5 -8
- package/dist/server-fns/singletons/schedule-publish.js +4 -2
- package/dist/server-fns/singletons/unpublish.d.ts +2 -7
- package/dist/server-fns/singletons/unpublish.js +4 -1
- package/dist/server-fns/singletons/update.d.ts +4 -11
- package/dist/server-fns/singletons/update.js +16 -8
- package/dist/server-fns/structural-receipt.d.ts +4 -0
- package/dist/server-fns/structural-receipt.js +31 -0
- package/package.json +11 -11
- package/src/admin-shell/collections/create.tsx +22 -3
- package/src/admin-shell/collections/edit.tsx +233 -61
- package/src/admin-shell/collections/history.tsx +11 -2
- package/src/admin-shell/collections/list.tsx +22 -6
- package/src/admin-shell/collections/restore-version-modal.tsx +23 -5
- package/src/admin-shell/collections/save-navigation.test.tsx +532 -0
- package/src/admin-shell/collections/tree-list.tsx +16 -6
- package/src/admin-shell/collections/version-history.tsx +13 -3
- package/src/admin-shell/document-mutation-notice.tsx +45 -0
- package/src/admin-shell/document-mutation-state.test.tsx +146 -0
- package/src/admin-shell/document-mutation-state.ts +95 -0
- package/src/admin-shell/scheduled-publications/list.tsx +16 -6
- package/src/admin-shell/singletons/history.test.tsx +46 -1
- package/src/admin-shell/singletons/history.tsx +10 -2
- package/src/admin-shell/singletons/view.test.tsx +86 -18
- package/src/admin-shell/singletons/view.tsx +145 -45
- package/src/integrations/byline-field-services.ts +2 -3
- package/src/routes/create-collection-edit-route.tsx +1 -0
- package/src/routes/create-collection-list-route.tsx +13 -2
- package/src/routes/create-singleton-route.test.node.ts +10 -2
- package/src/routes/create-singleton-route.tsx +6 -4
- package/src/server-fns/collections/copy-to-locale.ts +48 -29
- package/src/server-fns/collections/create.ts +56 -44
- package/src/server-fns/collections/delete-locale.ts +48 -25
- package/src/server-fns/collections/delete-outcome.test.node.ts +16 -0
- package/src/server-fns/collections/delete-outcome.ts +27 -16
- package/src/server-fns/collections/delete.ts +44 -38
- package/src/server-fns/collections/duplicate.ts +45 -25
- package/src/server-fns/collections/get.ts +8 -4
- package/src/server-fns/collections/index.ts +1 -0
- package/src/server-fns/collections/list.ts +8 -3
- package/src/server-fns/collections/reorder.ts +32 -124
- package/src/server-fns/collections/restore-version.ts +51 -36
- package/src/server-fns/collections/revision-input.test.node.ts +108 -0
- package/src/server-fns/collections/save-outcome.test.node.ts +80 -0
- package/src/server-fns/collections/save-outcome.ts +57 -0
- package/src/server-fns/collections/scheduled-publication.ts +138 -111
- package/src/server-fns/collections/status.ts +86 -64
- package/src/server-fns/collections/tree-mutation.test.node.ts +87 -29
- package/src/server-fns/collections/tree-mutation.ts +28 -11
- package/src/server-fns/collections/tree.ts +150 -122
- package/src/server-fns/collections/update.ts +110 -71
- package/src/server-fns/collections/upload-singleton.test.node.ts +3 -7
- package/src/server-fns/collections/upload.ts +81 -77
- package/src/server-fns/document-mutation-errors.ts +67 -0
- package/src/server-fns/document-mutation-transport.test.node.ts +211 -0
- package/src/server-fns/editable-revision.test.node.ts +23 -0
- package/src/server-fns/editable-revision.ts +18 -0
- package/src/server-fns/singleton-document-read.ts +7 -3
- package/src/server-fns/singletons/cancel-scheduled-publish.ts +10 -3
- package/src/server-fns/singletons/change-status.ts +10 -3
- package/src/server-fns/singletons/confirm-scheduled-publish.ts +12 -6
- package/src/server-fns/singletons/copy-to-locale.ts +20 -8
- package/src/server-fns/singletons/get.ts +3 -3
- package/src/server-fns/singletons/restore-version.ts +17 -3
- package/src/server-fns/singletons/schedule-publish.ts +18 -7
- package/src/server-fns/singletons/singletons.test.node.ts +96 -24
- package/src/server-fns/singletons/unpublish.ts +10 -3
- package/src/server-fns/singletons/update.ts +21 -9
- package/src/server-fns/structural-receipt.ts +41 -0
|
@@ -5,7 +5,7 @@ import { useTranslation } from "@byline/i18n/react";
|
|
|
5
5
|
import { Container, Section, useToastManager } from "@byline/ui/react";
|
|
6
6
|
import { getAdminRoutePath } from "../../routes/admin-path.js";
|
|
7
7
|
import { decodeListReturnState } from "../../routes/list-return-state.js";
|
|
8
|
-
import { createCollectionDocument } from "../../server-fns/collections/index.js";
|
|
8
|
+
import { createCollectionDocument, hasCommittedDocumentHookFailure } from "../../server-fns/collections/index.js";
|
|
9
9
|
import { useNavigate } from "../chrome/loose-router.js";
|
|
10
10
|
import { useTanStackNavigationGuard } from "./tanstack-navigation-guard.js";
|
|
11
11
|
const CreateView = ({ collectionDefinition, adminConfig, initialData, from })=>{
|
|
@@ -31,6 +31,17 @@ const CreateView = ({ collectionDefinition, adminConfig, initialData, from })=>{
|
|
|
31
31
|
} : {}
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
|
+
const hookFailed = hasCommittedDocumentHookFailure(result);
|
|
35
|
+
if (hookFailed) toastManager.add({
|
|
36
|
+
title: t('collections.save.hookFailedToast'),
|
|
37
|
+
description: t("collections.save.hookFailedDescription"),
|
|
38
|
+
data: {
|
|
39
|
+
intent: 'warning',
|
|
40
|
+
iconType: 'warning',
|
|
41
|
+
icon: true,
|
|
42
|
+
close: true
|
|
43
|
+
}
|
|
44
|
+
});
|
|
34
45
|
result?.documentId ? navigate({
|
|
35
46
|
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
36
47
|
params: {
|
|
@@ -38,9 +49,12 @@ const CreateView = ({ collectionDefinition, adminConfig, initialData, from })=>{
|
|
|
38
49
|
id: result.documentId
|
|
39
50
|
},
|
|
40
51
|
search: {
|
|
41
|
-
|
|
52
|
+
...hookFailed ? {} : {
|
|
53
|
+
action: 'created'
|
|
54
|
+
},
|
|
42
55
|
from
|
|
43
|
-
}
|
|
56
|
+
},
|
|
57
|
+
ignoreBlocker: true
|
|
44
58
|
}) : navigate({
|
|
45
59
|
to: getAdminRoutePath('collections', '$collection'),
|
|
46
60
|
params: {
|
|
@@ -48,8 +62,11 @@ const CreateView = ({ collectionDefinition, adminConfig, initialData, from })=>{
|
|
|
48
62
|
},
|
|
49
63
|
search: {
|
|
50
64
|
...decodeListReturnState(from),
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
...hookFailed ? {} : {
|
|
66
|
+
action: 'created'
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
ignoreBlocker: true
|
|
53
70
|
});
|
|
54
71
|
} catch (err) {
|
|
55
72
|
console.error(err);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { CollectionAdminConfig, MultiCollectionDefinition } from '@byline/core';
|
|
9
9
|
import type { AnyCollectionSchemaTypes } from '@byline/core/zod-schemas';
|
|
10
10
|
import type { ContentLocaleOption } from './view-menu.js';
|
|
11
|
-
export declare const EditView: ({ collectionDefinition, adminConfig, initialData, locale, contentLocales, defaultContentLocale, returnSearch, }: {
|
|
11
|
+
export declare const EditView: ({ collectionDefinition, adminConfig, initialData: loadedData, locale, contentLocales, defaultContentLocale, returnSearch, }: {
|
|
12
12
|
collectionDefinition: MultiCollectionDefinition;
|
|
13
13
|
adminConfig?: CollectionAdminConfig;
|
|
14
14
|
initialData: AnyCollectionSchemaTypes['UpdateType'];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { FormRenderer } from "@byline/admin/react";
|
|
4
4
|
import { getDefaultStatus, getWorkflow, getWorkflowStatuses, validateStatusTransition } from "@byline/core";
|
|
@@ -6,11 +6,14 @@ import { useTranslation } from "@byline/i18n/react";
|
|
|
6
6
|
import { Container, Section, useToastManager } from "@byline/ui/react";
|
|
7
7
|
import { getAdminRoutePath } from "../../routes/admin-path.js";
|
|
8
8
|
import { clearListReturnState } from "../../routes/list-return-storage.js";
|
|
9
|
-
import { cancelCollectionDocumentScheduledPublish, confirmCollectionDocumentScheduledPublish, copyDocumentToLocale, deleteDocument, deleteDocumentLocale, duplicateCollectionDocument, hasDeleteSideEffectFailures, scheduleCollectionDocumentPublish, unpublishDocument,
|
|
9
|
+
import { cancelCollectionDocumentScheduledPublish, confirmCollectionDocumentScheduledPublish, copyDocumentToLocale, deleteDocument, deleteDocumentLocale, duplicateCollectionDocument, hasCommittedDocumentHookFailure, hasDeleteSideEffectFailures, scheduleCollectionDocumentPublish, unpublishDocument, updateCollectionDocumentWithPatches, updateDocumentStatus } from "../../server-fns/collections/index.js";
|
|
10
10
|
import { useNavigate } from "../chrome/loose-router.js";
|
|
11
|
+
import { useDocumentMutationState } from "../document-mutation-state.js";
|
|
11
12
|
import { useTanStackNavigationGuard } from "./tanstack-navigation-guard.js";
|
|
12
13
|
import { ViewMenu } from "./view-menu.js";
|
|
13
|
-
const EditView = ({ collectionDefinition, adminConfig, initialData, locale, contentLocales, defaultContentLocale, returnSearch })=>{
|
|
14
|
+
const EditView = ({ collectionDefinition, adminConfig, initialData: loadedData, locale, contentLocales, defaultContentLocale, returnSearch })=>{
|
|
15
|
+
const mutation = useDocumentMutationState(loadedData);
|
|
16
|
+
const initialData = mutation.document ?? loadedData;
|
|
14
17
|
const toastManager = useToastManager();
|
|
15
18
|
const { t } = useTranslation('byline-admin');
|
|
16
19
|
const [_editState, setEditState] = useState({
|
|
@@ -43,6 +46,23 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
43
46
|
}
|
|
44
47
|
});
|
|
45
48
|
};
|
|
49
|
+
const notifyCommittedHookFailure = ()=>{
|
|
50
|
+
const description = t("collections.save.hookFailedDescription");
|
|
51
|
+
toastManager.add({
|
|
52
|
+
title: t('collections.save.hookFailedToast'),
|
|
53
|
+
description,
|
|
54
|
+
data: {
|
|
55
|
+
intent: 'warning',
|
|
56
|
+
iconType: 'warning',
|
|
57
|
+
icon: true,
|
|
58
|
+
close: true
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
setEditState({
|
|
62
|
+
status: 'warning',
|
|
63
|
+
message: description
|
|
64
|
+
});
|
|
65
|
+
};
|
|
46
66
|
const handleLocaleChange = (newLocale)=>{
|
|
47
67
|
navigate({
|
|
48
68
|
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
@@ -58,13 +78,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
58
78
|
};
|
|
59
79
|
const handleStatusChange = async (status)=>{
|
|
60
80
|
try {
|
|
61
|
-
|
|
81
|
+
mutation.assertWritable();
|
|
82
|
+
const result = await updateDocumentStatus({
|
|
62
83
|
data: {
|
|
84
|
+
expectedRevision: mutation.expectedRevision(),
|
|
63
85
|
collection: path,
|
|
64
86
|
id: String(initialData.id),
|
|
65
87
|
status
|
|
66
88
|
}
|
|
67
89
|
});
|
|
90
|
+
mutation.adopt(result);
|
|
68
91
|
const description = t("collections.edit.statusChangedDescription", {
|
|
69
92
|
status
|
|
70
93
|
});
|
|
@@ -95,9 +118,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
95
118
|
})
|
|
96
119
|
});
|
|
97
120
|
} catch (err) {
|
|
121
|
+
const handled = mutation.report(err);
|
|
122
|
+
if ('blocked' === handled) throw err;
|
|
123
|
+
if ('committed' === handled) {
|
|
124
|
+
notifyCommittedHookFailure();
|
|
125
|
+
reloadDocument();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
98
128
|
console.error('Status change error:', err);
|
|
99
129
|
const description = t("collections.edit.statusChangeFailedDescription", {
|
|
100
|
-
message:
|
|
130
|
+
message: t('documentConcurrency.failed')
|
|
101
131
|
});
|
|
102
132
|
toastManager.add({
|
|
103
133
|
title: t('collections.edit.statusUpdateTitle', {
|
|
@@ -131,14 +161,17 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
131
161
|
};
|
|
132
162
|
const handleSchedulePublication = async ({ publishAt })=>{
|
|
133
163
|
try {
|
|
134
|
-
|
|
164
|
+
mutation.assertWritable();
|
|
165
|
+
const result = await scheduleCollectionDocumentPublish({
|
|
135
166
|
data: {
|
|
167
|
+
expectedRevision: mutation.expectedRevision(),
|
|
136
168
|
collection: path,
|
|
137
169
|
id: String(initialData.id),
|
|
138
170
|
publishAt,
|
|
139
171
|
expectedVersionId: String(initialData.versionId)
|
|
140
172
|
}
|
|
141
173
|
});
|
|
174
|
+
mutation.adopt(result);
|
|
142
175
|
toastManager.add({
|
|
143
176
|
title: t('scheduledPublication.toast.scheduledTitle'),
|
|
144
177
|
description: t("scheduledPublication.toast.scheduledDescription"),
|
|
@@ -151,9 +184,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
151
184
|
});
|
|
152
185
|
reloadDocument();
|
|
153
186
|
} catch (err) {
|
|
187
|
+
const handled = mutation.report(err);
|
|
188
|
+
if ('blocked' === handled) throw err;
|
|
189
|
+
if ('committed' === handled) {
|
|
190
|
+
notifyCommittedHookFailure();
|
|
191
|
+
reloadDocument();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
154
194
|
toastManager.add({
|
|
155
195
|
title: t('scheduledPublication.toast.failedTitle'),
|
|
156
|
-
description:
|
|
196
|
+
description: t('documentConcurrency.failed'),
|
|
157
197
|
data: {
|
|
158
198
|
intent: 'danger',
|
|
159
199
|
iconType: 'danger',
|
|
@@ -166,13 +206,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
166
206
|
};
|
|
167
207
|
const handleConfirmScheduledPublication = async ()=>{
|
|
168
208
|
try {
|
|
169
|
-
|
|
209
|
+
mutation.assertWritable();
|
|
210
|
+
const result = await confirmCollectionDocumentScheduledPublish({
|
|
170
211
|
data: {
|
|
212
|
+
expectedRevision: mutation.expectedRevision(),
|
|
171
213
|
collection: path,
|
|
172
214
|
id: String(initialData.id),
|
|
173
215
|
expectedVersionId: String(initialData.versionId)
|
|
174
216
|
}
|
|
175
217
|
});
|
|
218
|
+
mutation.adopt(result);
|
|
176
219
|
toastManager.add({
|
|
177
220
|
title: t('scheduledPublication.toast.confirmedTitle'),
|
|
178
221
|
description: t("scheduledPublication.toast.confirmedDescription"),
|
|
@@ -185,9 +228,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
185
228
|
});
|
|
186
229
|
reloadDocument();
|
|
187
230
|
} catch (err) {
|
|
231
|
+
const handled = mutation.report(err);
|
|
232
|
+
if ('blocked' === handled) throw err;
|
|
233
|
+
if ('committed' === handled) {
|
|
234
|
+
notifyCommittedHookFailure();
|
|
235
|
+
reloadDocument();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
188
238
|
toastManager.add({
|
|
189
239
|
title: t('scheduledPublication.toast.failedTitle'),
|
|
190
|
-
description:
|
|
240
|
+
description: t('documentConcurrency.failed'),
|
|
191
241
|
data: {
|
|
192
242
|
intent: 'danger',
|
|
193
243
|
iconType: 'danger',
|
|
@@ -200,12 +250,18 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
200
250
|
};
|
|
201
251
|
const handleCancelScheduledPublication = async ()=>{
|
|
202
252
|
try {
|
|
253
|
+
mutation.assertWritable();
|
|
203
254
|
const result = await cancelCollectionDocumentScheduledPublish({
|
|
204
255
|
data: {
|
|
256
|
+
expectedRevision: mutation.expectedRevision(),
|
|
205
257
|
collection: path,
|
|
206
258
|
id: String(initialData.id)
|
|
207
259
|
}
|
|
208
260
|
});
|
|
261
|
+
mutation.adopt({
|
|
262
|
+
...result,
|
|
263
|
+
documentId: String(initialData.id)
|
|
264
|
+
});
|
|
209
265
|
const cancelled = 'cancelled' === result.status;
|
|
210
266
|
toastManager.add({
|
|
211
267
|
title: cancelled ? t('scheduledPublication.toast.cancelledTitle') : t('scheduledPublication.toast.cancelLostTitle'),
|
|
@@ -219,9 +275,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
219
275
|
});
|
|
220
276
|
reloadDocument();
|
|
221
277
|
} catch (err) {
|
|
278
|
+
const handled = mutation.report(err);
|
|
279
|
+
if ('blocked' === handled) throw err;
|
|
280
|
+
if ('committed' === handled) {
|
|
281
|
+
notifyCommittedHookFailure();
|
|
282
|
+
reloadDocument();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
222
285
|
toastManager.add({
|
|
223
286
|
title: t('scheduledPublication.toast.failedTitle'),
|
|
224
|
-
description:
|
|
287
|
+
description: t('documentConcurrency.failed'),
|
|
225
288
|
data: {
|
|
226
289
|
intent: 'danger',
|
|
227
290
|
iconType: 'danger',
|
|
@@ -236,12 +299,15 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
236
299
|
const restoreWarnings = initialData?._restoreWarnings;
|
|
237
300
|
const handleUnpublish = async ()=>{
|
|
238
301
|
try {
|
|
239
|
-
|
|
302
|
+
mutation.assertWritable();
|
|
303
|
+
const result = await unpublishDocument({
|
|
240
304
|
data: {
|
|
305
|
+
expectedRevision: mutation.expectedRevision(),
|
|
241
306
|
collection: path,
|
|
242
307
|
id: String(initialData.id)
|
|
243
308
|
}
|
|
244
309
|
});
|
|
310
|
+
mutation.adopt(result);
|
|
245
311
|
const description = t("collections.edit.unpublishedDescription");
|
|
246
312
|
toastManager.add({
|
|
247
313
|
title: t('collections.edit.unpublishTitle', {
|
|
@@ -270,9 +336,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
270
336
|
})
|
|
271
337
|
});
|
|
272
338
|
} catch (err) {
|
|
339
|
+
const handled = mutation.report(err);
|
|
340
|
+
if ('blocked' === handled) throw err;
|
|
341
|
+
if ('committed' === handled) {
|
|
342
|
+
notifyCommittedHookFailure();
|
|
343
|
+
reloadDocument();
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
273
346
|
console.error('Unpublish error:', err);
|
|
274
347
|
const description = t("collections.edit.unpublishFailedDescription", {
|
|
275
|
-
message:
|
|
348
|
+
message: t('documentConcurrency.failed')
|
|
276
349
|
});
|
|
277
350
|
toastManager.add({
|
|
278
351
|
title: t('collections.edit.unpublishTitle', {
|
|
@@ -294,12 +367,28 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
294
367
|
};
|
|
295
368
|
const handleDuplicate = async ()=>{
|
|
296
369
|
try {
|
|
370
|
+
mutation.assertWritable();
|
|
297
371
|
const result = await duplicateCollectionDocument({
|
|
298
372
|
data: {
|
|
373
|
+
expectedRevision: mutation.expectedRevision(),
|
|
299
374
|
collection: path,
|
|
300
375
|
id: String(initialData.id)
|
|
301
376
|
}
|
|
302
377
|
});
|
|
378
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
379
|
+
notifyCommittedHookFailure();
|
|
380
|
+
navigate({
|
|
381
|
+
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
382
|
+
params: {
|
|
383
|
+
collection: path,
|
|
384
|
+
id: result.documentId
|
|
385
|
+
},
|
|
386
|
+
search: (prev)=>({
|
|
387
|
+
...prev
|
|
388
|
+
})
|
|
389
|
+
});
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
303
392
|
const description = result.pathRetried ? t("collections.edit.duplicatedAutoPathDescription", {
|
|
304
393
|
path: result.newPath
|
|
305
394
|
}) : t("collections.edit.duplicatedPathDescription", {
|
|
@@ -334,9 +423,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
334
423
|
})
|
|
335
424
|
});
|
|
336
425
|
} catch (err) {
|
|
426
|
+
const handled = mutation.report(err);
|
|
427
|
+
if ('blocked' === handled) throw err;
|
|
428
|
+
if ('committed' === handled) {
|
|
429
|
+
notifyCommittedHookFailure();
|
|
430
|
+
reloadDocument();
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
337
433
|
console.error('Duplicate error:', err);
|
|
338
434
|
const description = t("collections.edit.duplicateFailedDescription", {
|
|
339
|
-
message:
|
|
435
|
+
message: t('documentConcurrency.failed')
|
|
340
436
|
});
|
|
341
437
|
toastManager.add({
|
|
342
438
|
title: t('collections.edit.duplicateTitle', {
|
|
@@ -358,8 +454,10 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
358
454
|
};
|
|
359
455
|
const handleCopyToLocale = async ({ targetLocale, overwrite })=>{
|
|
360
456
|
try {
|
|
457
|
+
mutation.assertWritable();
|
|
361
458
|
const result = await copyDocumentToLocale({
|
|
362
459
|
data: {
|
|
460
|
+
expectedRevision: mutation.expectedRevision(),
|
|
363
461
|
collection: path,
|
|
364
462
|
id: String(initialData.id),
|
|
365
463
|
sourceLocale: locale ?? defaultContentLocale,
|
|
@@ -367,6 +465,23 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
367
465
|
overwrite
|
|
368
466
|
}
|
|
369
467
|
});
|
|
468
|
+
mutation.adopt(result);
|
|
469
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
470
|
+
notifyCommittedHookFailure();
|
|
471
|
+
notifyScheduleSuspended();
|
|
472
|
+
navigate({
|
|
473
|
+
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
474
|
+
params: {
|
|
475
|
+
collection: path,
|
|
476
|
+
id: String(initialData.id)
|
|
477
|
+
},
|
|
478
|
+
search: (prev)=>({
|
|
479
|
+
...prev,
|
|
480
|
+
locale: targetLocale
|
|
481
|
+
})
|
|
482
|
+
});
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
370
485
|
const sourceLabel = contentLocales.find((l)=>l.code === result.sourceLocale)?.label ?? result.sourceLocale;
|
|
371
486
|
const targetLabel = contentLocales.find((l)=>l.code === result.targetLocale)?.label ?? result.targetLocale;
|
|
372
487
|
const description = result.fieldsUpdated > 0 ? t("collections.edit.copiedFieldsDescription", {
|
|
@@ -409,9 +524,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
409
524
|
})
|
|
410
525
|
});
|
|
411
526
|
} catch (err) {
|
|
527
|
+
const handled = mutation.report(err);
|
|
528
|
+
if ('blocked' === handled) throw err;
|
|
529
|
+
if ('committed' === handled) {
|
|
530
|
+
notifyCommittedHookFailure();
|
|
531
|
+
reloadDocument();
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
412
534
|
console.error('Copy to locale error:', err);
|
|
413
535
|
const description = t("collections.edit.copyFailedDescription", {
|
|
414
|
-
message:
|
|
536
|
+
message: t('documentConcurrency.failed')
|
|
415
537
|
});
|
|
416
538
|
toastManager.add({
|
|
417
539
|
title: t('collections.edit.copyToLocaleTitle', {
|
|
@@ -433,13 +555,32 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
433
555
|
};
|
|
434
556
|
const handleDeleteLocale = async ({ targetLocale })=>{
|
|
435
557
|
try {
|
|
558
|
+
mutation.assertWritable();
|
|
436
559
|
const result = await deleteDocumentLocale({
|
|
437
560
|
data: {
|
|
561
|
+
expectedRevision: mutation.expectedRevision(),
|
|
438
562
|
collection: path,
|
|
439
563
|
id: String(initialData.id),
|
|
440
564
|
locale: targetLocale
|
|
441
565
|
}
|
|
442
566
|
});
|
|
567
|
+
mutation.adopt(result);
|
|
568
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
569
|
+
notifyCommittedHookFailure();
|
|
570
|
+
notifyScheduleSuspended();
|
|
571
|
+
navigate({
|
|
572
|
+
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
573
|
+
params: {
|
|
574
|
+
collection: path,
|
|
575
|
+
id: String(initialData.id)
|
|
576
|
+
},
|
|
577
|
+
search: (prev)=>({
|
|
578
|
+
...prev,
|
|
579
|
+
locale: defaultContentLocale
|
|
580
|
+
})
|
|
581
|
+
});
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
443
584
|
const targetLabel = contentLocales.find((l)=>l.code === result.locale)?.label ?? result.locale;
|
|
444
585
|
const description = t("collections.edit.deletedLocaleDescription", {
|
|
445
586
|
label: singular,
|
|
@@ -474,9 +615,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
474
615
|
})
|
|
475
616
|
});
|
|
476
617
|
} catch (err) {
|
|
618
|
+
const handled = mutation.report(err);
|
|
619
|
+
if ('blocked' === handled) throw err;
|
|
620
|
+
if ('committed' === handled) {
|
|
621
|
+
notifyCommittedHookFailure();
|
|
622
|
+
reloadDocument();
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
477
625
|
console.error('Delete locale error:', err);
|
|
478
626
|
const description = t("collections.edit.deleteLocaleFailedDescription", {
|
|
479
|
-
message:
|
|
627
|
+
message: t('documentConcurrency.failed')
|
|
480
628
|
});
|
|
481
629
|
toastManager.add({
|
|
482
630
|
title: t('collections.edit.deleteLocaleTitle', {
|
|
@@ -498,12 +646,34 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
498
646
|
};
|
|
499
647
|
const handleDelete = async ()=>{
|
|
500
648
|
try {
|
|
649
|
+
mutation.assertWritable();
|
|
501
650
|
const result = await deleteDocument({
|
|
502
651
|
data: {
|
|
652
|
+
expectedRevision: mutation.expectedRevision(),
|
|
503
653
|
collection: path,
|
|
504
654
|
id: String(initialData.id)
|
|
505
655
|
}
|
|
506
656
|
});
|
|
657
|
+
if (result.scheduledPublicationsNeedReconfirmation) toastManager.add({
|
|
658
|
+
title: t('documentConcurrency.schedulesTitle'),
|
|
659
|
+
description: /*#__PURE__*/ jsxs(Fragment, {
|
|
660
|
+
children: [
|
|
661
|
+
/*#__PURE__*/ jsx("p", {
|
|
662
|
+
children: t('documentConcurrency.schedules')
|
|
663
|
+
}),
|
|
664
|
+
/*#__PURE__*/ jsx("a", {
|
|
665
|
+
href: getAdminRoutePath('scheduled-publications'),
|
|
666
|
+
children: t('documentConcurrency.reviewSchedules')
|
|
667
|
+
})
|
|
668
|
+
]
|
|
669
|
+
}),
|
|
670
|
+
data: {
|
|
671
|
+
intent: 'warning',
|
|
672
|
+
iconType: 'warning',
|
|
673
|
+
icon: true,
|
|
674
|
+
close: true
|
|
675
|
+
}
|
|
676
|
+
});
|
|
507
677
|
const hasSideEffectFailures = hasDeleteSideEffectFailures(result);
|
|
508
678
|
const description = hasSideEffectFailures ? t("collections.edit.deletedWithWarningsDescription", {
|
|
509
679
|
label: singular
|
|
@@ -523,7 +693,7 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
523
693
|
}
|
|
524
694
|
});
|
|
525
695
|
setEditState({
|
|
526
|
-
status: 'success',
|
|
696
|
+
status: hasSideEffectFailures ? 'warning' : 'success',
|
|
527
697
|
message: description
|
|
528
698
|
});
|
|
529
699
|
clearListReturnState(path, String(initialData.id));
|
|
@@ -535,9 +705,16 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
535
705
|
search: returnSearch
|
|
536
706
|
});
|
|
537
707
|
} catch (err) {
|
|
708
|
+
const handled = mutation.report(err);
|
|
709
|
+
if ('blocked' === handled) throw err;
|
|
710
|
+
if ('committed' === handled) {
|
|
711
|
+
notifyCommittedHookFailure();
|
|
712
|
+
reloadDocument();
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
538
715
|
console.error('Delete error:', err);
|
|
539
716
|
const description = t("collections.edit.deleteFailedDescription", {
|
|
540
|
-
message:
|
|
717
|
+
message: t('documentConcurrency.failed')
|
|
541
718
|
});
|
|
542
719
|
toastManager.add({
|
|
543
720
|
title: t('collections.edit.deleteTitle', {
|
|
@@ -559,10 +736,13 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
559
736
|
};
|
|
560
737
|
const handleSubmit = async ({ data: _data, patches, contentDirty, pathDirty, systemPath, availableLocalesDirty, systemAvailableLocales })=>{
|
|
561
738
|
try {
|
|
562
|
-
|
|
739
|
+
mutation.assertWritable();
|
|
740
|
+
const result = await updateCollectionDocumentWithPatches({
|
|
563
741
|
data: {
|
|
564
742
|
collection: path,
|
|
565
743
|
id: String(initialData.id),
|
|
744
|
+
expectedRevision: mutation.expectedRevision(),
|
|
745
|
+
patches: contentDirty ? patches : [],
|
|
566
746
|
locale,
|
|
567
747
|
...pathDirty ? {
|
|
568
748
|
path: systemPath ?? null
|
|
@@ -572,33 +752,26 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
572
752
|
} : {}
|
|
573
753
|
}
|
|
574
754
|
});
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
patches,
|
|
580
|
-
versionId: initialData.versionId,
|
|
581
|
-
locale
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
|
-
if (contentDirty && scheduledPublication?.state === 'armed') notifyScheduleSuspended();
|
|
585
|
-
const description = t("collections.edit.updatedDescription", {
|
|
755
|
+
mutation.adopt(result);
|
|
756
|
+
const hookFailed = hasCommittedDocumentHookFailure(result);
|
|
757
|
+
if ((contentDirty || pathDirty || availableLocalesDirty) && scheduledPublication?.state === 'armed') notifyScheduleSuspended();
|
|
758
|
+
const description = hookFailed ? t("collections.save.hookFailedDescription") : t("collections.edit.updatedDescription", {
|
|
586
759
|
label: singularLower
|
|
587
760
|
});
|
|
588
761
|
toastManager.add({
|
|
589
|
-
title: t('collections.edit.updateTitle', {
|
|
762
|
+
title: hookFailed ? t('collections.save.hookFailedToast') : t('collections.edit.updateTitle', {
|
|
590
763
|
label: singular
|
|
591
764
|
}),
|
|
592
765
|
description,
|
|
593
766
|
data: {
|
|
594
|
-
intent: 'success',
|
|
595
|
-
iconType: 'success',
|
|
767
|
+
intent: hookFailed ? 'warning' : 'success',
|
|
768
|
+
iconType: hookFailed ? 'warning' : 'success',
|
|
596
769
|
icon: true,
|
|
597
770
|
close: true
|
|
598
771
|
}
|
|
599
772
|
});
|
|
600
773
|
setEditState({
|
|
601
|
-
status: 'success',
|
|
774
|
+
status: hookFailed ? 'warning' : 'success',
|
|
602
775
|
message: description
|
|
603
776
|
});
|
|
604
777
|
navigate({
|
|
@@ -609,9 +782,17 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
609
782
|
},
|
|
610
783
|
search: (prev)=>({
|
|
611
784
|
...prev
|
|
612
|
-
})
|
|
785
|
+
}),
|
|
786
|
+
ignoreBlocker: true
|
|
613
787
|
});
|
|
614
788
|
} catch (err) {
|
|
789
|
+
const handled = mutation.report(err);
|
|
790
|
+
if ('blocked' === handled) throw err;
|
|
791
|
+
if ('committed' === handled) {
|
|
792
|
+
notifyCommittedHookFailure();
|
|
793
|
+
reloadDocument();
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
615
796
|
console.error('Network error:', err);
|
|
616
797
|
const description = t("collections.edit.updateFailedDescription", {
|
|
617
798
|
label: singularLower
|
|
@@ -638,6 +819,13 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
|
|
|
638
819
|
return /*#__PURE__*/ jsx(Section, {
|
|
639
820
|
children: /*#__PURE__*/ jsx(Container, {
|
|
640
821
|
children: /*#__PURE__*/ jsx(FormRenderer, {
|
|
822
|
+
mutationIssue: mutation.issue,
|
|
823
|
+
mutationsBlocked: mutation.blocked,
|
|
824
|
+
observedRevision: mutation.revision,
|
|
825
|
+
onMutationError: mutation.report,
|
|
826
|
+
onTreeMutationCommitted: mutation.adopt,
|
|
827
|
+
scheduledPublicationsNeedReconfirmation: mutation.scheduleNotice,
|
|
828
|
+
scheduledPublicationsHref: getAdminRoutePath('scheduled-publications'),
|
|
641
829
|
mode: "edit",
|
|
642
830
|
fields: fields,
|
|
643
831
|
onSubmit: handleSubmit,
|
|
@@ -91,7 +91,7 @@ const HistoryView = ({ collectionDefinition, adminConfig, data, auditLog, workfl
|
|
|
91
91
|
];
|
|
92
92
|
}),
|
|
93
93
|
auditColSpan: columns.length + (hasRestoreColumn ? 1 : 0),
|
|
94
|
-
renderCells: ({ document, versionId, versionNumber, currentVersionId, restoreStatusLabel, openCompare, openRestore })=>columns.flatMap((column)=>{
|
|
94
|
+
renderCells: ({ document, versionId, versionNumber, currentVersionId, restoreStatusLabel, openCompare, mutationsBlocked, openRestore })=>columns.flatMap((column)=>{
|
|
95
95
|
const value = getColumnValue(document, String(column.fieldName));
|
|
96
96
|
const dataCell = /*#__PURE__*/ jsx(Table.Cell, {
|
|
97
97
|
className: clsx({
|
|
@@ -126,6 +126,7 @@ const HistoryView = ({ collectionDefinition, adminConfig, data, auditLog, workfl
|
|
|
126
126
|
variant: "outlined",
|
|
127
127
|
size: "xs",
|
|
128
128
|
intent: "noeffect",
|
|
129
|
+
disabled: mutationsBlocked,
|
|
129
130
|
onClick: openRestore,
|
|
130
131
|
className: clsx('byline-coll-history-restore-button', history_module.restoreButton),
|
|
131
132
|
title: t('collections.history.restoreButtonTitle', {
|
|
@@ -209,8 +210,9 @@ const HistoryView = ({ collectionDefinition, adminConfig, data, auditLog, workfl
|
|
|
209
210
|
rowPresentation: rowPresentation,
|
|
210
211
|
loadHistoricalVersion: getCollectionDocumentVersion,
|
|
211
212
|
onPageSizeChange: handlePageSizeChange,
|
|
212
|
-
restoreVersion: (versionId)=>restoreDocumentVersion({
|
|
213
|
+
restoreVersion: (versionId, expectedRevision)=>restoreDocumentVersion({
|
|
213
214
|
data: {
|
|
215
|
+
expectedRevision,
|
|
214
216
|
collection,
|
|
215
217
|
id,
|
|
216
218
|
versionId
|