@byline/host-tanstack-start 4.19.0 → 5.1.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/chrome/admin-app-bar.d.ts +7 -0
- package/dist/admin-shell/chrome/admin-app-bar.js +10 -2
- package/dist/admin-shell/chrome/session-change-boundary.d.ts +14 -0
- package/dist/admin-shell/chrome/session-change-boundary.js +87 -0
- package/dist/admin-shell/chrome/session-change-boundary.test.d.ts +8 -0
- package/dist/admin-shell/chrome/sign-in-page.d.ts +2 -1
- package/dist/admin-shell/chrome/sign-in-page.js +60 -3
- package/dist/admin-shell/collections/edit.d.ts +1 -1
- package/dist/admin-shell/collections/edit.js +151 -31
- 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 +9 -4
- 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 +98 -19
- package/dist/integrations/byline-admin-services.js +7 -1
- package/dist/integrations/byline-field-services.js +2 -9
- package/dist/integrations/client-ip.d.ts +19 -0
- package/dist/integrations/client-ip.js +34 -0
- package/dist/integrations/session-coordination.d.ts +24 -0
- package/dist/integrations/session-coordination.js +85 -0
- package/dist/integrations/session-middleware.d.ts +11 -0
- package/dist/integrations/session-middleware.js +94 -0
- package/dist/integrations/session-request-kind.d.ts +9 -0
- package/dist/integrations/session-request-kind.js +10 -0
- package/dist/integrations/session-request-middleware.d.ts +9 -0
- package/dist/integrations/session-request-middleware.js +7 -0
- package/dist/integrations/sign-in-body.d.ts +12 -0
- package/dist/integrations/sign-in-body.js +52 -0
- package/dist/integrations/sign-in-middleware.d.ts +9 -0
- package/dist/integrations/sign-in-middleware.js +10 -0
- package/dist/routes/create-admin-layout-route.js +46 -31
- 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-sign-in-route.js +4 -2
- package/dist/routes/create-singleton-route.d.ts +2 -0
- package/dist/routes/create-singleton-route.js +4 -3
- package/dist/server-fns/admin-account/change-password.d.ts +3 -1
- package/dist/server-fns/admin-account/change-password.js +9 -3
- package/dist/server-fns/admin-account/get.d.ts +3 -1
- package/dist/server-fns/admin-account/get.js +4 -1
- package/dist/server-fns/admin-account/index.d.ts +5 -5
- package/dist/server-fns/admin-account/update.d.ts +3 -1
- package/dist/server-fns/admin-account/update.js +4 -1
- package/dist/server-fns/admin-activity/get.d.ts +3 -1
- package/dist/server-fns/admin-activity/get.js +4 -1
- package/dist/server-fns/admin-permissions/get-role-abilities.d.ts +3 -1
- package/dist/server-fns/admin-permissions/get-role-abilities.js +4 -1
- package/dist/server-fns/admin-permissions/index.d.ts +4 -4
- package/dist/server-fns/admin-permissions/list-registered.d.ts +3 -1
- package/dist/server-fns/admin-permissions/list-registered.js +4 -1
- package/dist/server-fns/admin-permissions/set-role-abilities.d.ts +3 -1
- package/dist/server-fns/admin-permissions/set-role-abilities.js +4 -1
- package/dist/server-fns/admin-permissions/who-has.d.ts +3 -1
- package/dist/server-fns/admin-permissions/who-has.js +4 -1
- package/dist/server-fns/admin-roles/create.d.ts +3 -1
- package/dist/server-fns/admin-roles/create.js +4 -1
- package/dist/server-fns/admin-roles/delete.d.ts +3 -1
- package/dist/server-fns/admin-roles/delete.js +4 -1
- package/dist/server-fns/admin-roles/get.d.ts +3 -1
- package/dist/server-fns/admin-roles/get.js +4 -1
- package/dist/server-fns/admin-roles/index.d.ts +6 -6
- package/dist/server-fns/admin-roles/list.d.ts +3 -1
- package/dist/server-fns/admin-roles/list.js +4 -1
- package/dist/server-fns/admin-roles/reorder.d.ts +3 -1
- package/dist/server-fns/admin-roles/reorder.js +4 -1
- package/dist/server-fns/admin-roles/update.d.ts +3 -1
- package/dist/server-fns/admin-roles/update.js +4 -1
- package/dist/server-fns/admin-users/create.d.ts +3 -1
- package/dist/server-fns/admin-users/create.js +4 -1
- package/dist/server-fns/admin-users/delete.d.ts +3 -1
- package/dist/server-fns/admin-users/delete.js +4 -1
- package/dist/server-fns/admin-users/disable.d.ts +3 -1
- package/dist/server-fns/admin-users/disable.js +4 -1
- package/dist/server-fns/admin-users/enable.d.ts +3 -1
- package/dist/server-fns/admin-users/enable.js +4 -1
- package/dist/server-fns/admin-users/get-user-roles.d.ts +3 -1
- package/dist/server-fns/admin-users/get-user-roles.js +4 -1
- package/dist/server-fns/admin-users/get.d.ts +3 -1
- package/dist/server-fns/admin-users/get.js +4 -1
- package/dist/server-fns/admin-users/index.d.ts +10 -10
- package/dist/server-fns/admin-users/list.d.ts +3 -1
- package/dist/server-fns/admin-users/list.js +4 -1
- package/dist/server-fns/admin-users/set-password.d.ts +3 -1
- package/dist/server-fns/admin-users/set-password.js +4 -1
- package/dist/server-fns/admin-users/set-user-roles.d.ts +3 -1
- package/dist/server-fns/admin-users/set-user-roles.js +4 -1
- package/dist/server-fns/admin-users/update.d.ts +3 -1
- package/dist/server-fns/admin-users/update.js +4 -1
- package/dist/server-fns/ai/execute.d.ts +3 -1
- package/dist/server-fns/ai/execute.js +4 -1
- package/dist/server-fns/ai/index.d.ts +1 -1
- package/dist/server-fns/analytics/maintenance.d.ts +6 -2
- package/dist/server-fns/analytics/maintenance.js +7 -2
- package/dist/server-fns/analytics/queries.d.ts +18 -6
- package/dist/server-fns/analytics/queries.js +19 -6
- package/dist/server-fns/auth/current-user.d.ts +1 -0
- package/dist/server-fns/auth/current-user.js +5 -2
- package/dist/server-fns/auth/renew.d.ts +13 -0
- package/dist/server-fns/auth/renew.js +45 -0
- package/dist/server-fns/auth/sign-in.d.ts +2 -1
- package/dist/server-fns/auth/sign-in.js +88 -17
- package/dist/server-fns/auth/sign-out.d.ts +3 -1
- package/dist/server-fns/auth/sign-out.js +38 -6
- package/dist/server-fns/collections/audit.d.ts +3 -1
- package/dist/server-fns/collections/audit.js +4 -1
- package/dist/server-fns/collections/copy-to-locale.d.ts +5 -1
- package/dist/server-fns/collections/copy-to-locale.js +7 -2
- package/dist/server-fns/collections/create.d.ts +4 -1
- package/dist/server-fns/collections/create.js +8 -3
- package/dist/server-fns/collections/delete-locale.d.ts +5 -1
- package/dist/server-fns/collections/delete-locale.js +7 -2
- 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 +5 -1
- package/dist/server-fns/collections/delete.js +8 -3
- package/dist/server-fns/collections/duplicate.d.ts +5 -1
- package/dist/server-fns/collections/duplicate.js +8 -3
- package/dist/server-fns/collections/get.d.ts +1 -0
- package/dist/server-fns/collections/get.js +12 -6
- package/dist/server-fns/collections/history.d.ts +3 -1
- package/dist/server-fns/collections/history.js +4 -1
- package/dist/server-fns/collections/index.d.ts +21 -21
- package/dist/server-fns/collections/list.d.ts +3 -1
- package/dist/server-fns/collections/list.js +15 -4
- package/dist/server-fns/collections/reindex.d.ts +3 -1
- package/dist/server-fns/collections/reindex.js +4 -1
- package/dist/server-fns/collections/reorder.d.ts +10 -2
- package/dist/server-fns/collections/reorder.js +23 -76
- package/dist/server-fns/collections/restore-version.d.ts +6 -1
- package/dist/server-fns/collections/restore-version.js +8 -2
- package/dist/server-fns/collections/save-outcome.d.ts +1 -0
- package/dist/server-fns/collections/save-outcome.js +1 -0
- package/dist/server-fns/collections/scheduled-publication.d.ts +64 -7
- package/dist/server-fns/collections/scheduled-publication.js +42 -21
- package/dist/server-fns/collections/set-list-view-preference.d.ts +3 -1
- package/dist/server-fns/collections/set-list-view-preference.js +4 -1
- package/dist/server-fns/collections/stats.js +4 -1
- package/dist/server-fns/collections/status.d.ts +14 -2
- package/dist/server-fns/collections/status.js +18 -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 +29 -6
- package/dist/server-fns/collections/tree.js +32 -17
- package/dist/server-fns/collections/update.d.ts +18 -6
- package/dist/server-fns/collections/update.js +39 -20
- package/dist/server-fns/collections/upload.d.ts +11 -1
- package/dist/server-fns/collections/upload.js +6 -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/i18n/set-locale.d.ts +3 -1
- package/dist/server-fns/i18n/set-locale.js +18 -3
- package/dist/server-fns/preview/disable.d.ts +3 -1
- package/dist/server-fns/preview/disable.js +4 -1
- package/dist/server-fns/preview/enable.d.ts +3 -1
- package/dist/server-fns/preview/enable.js +4 -1
- 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 +9 -2
- package/dist/server-fns/singletons/cancel-scheduled-publish.js +7 -1
- package/dist/server-fns/singletons/change-status.d.ts +5 -1
- package/dist/server-fns/singletons/change-status.js +7 -1
- package/dist/server-fns/singletons/confirm-scheduled-publish.d.ts +8 -2
- package/dist/server-fns/singletons/confirm-scheduled-publish.js +7 -2
- package/dist/server-fns/singletons/copy-to-locale.d.ts +5 -1
- package/dist/server-fns/singletons/copy-to-locale.js +7 -2
- package/dist/server-fns/singletons/find-by-version.d.ts +3 -1
- package/dist/server-fns/singletons/find-by-version.js +4 -1
- package/dist/server-fns/singletons/get-scheduled-publish.d.ts +3 -1
- package/dist/server-fns/singletons/get-scheduled-publish.js +4 -1
- package/dist/server-fns/singletons/get.d.ts +6 -4
- package/dist/server-fns/singletons/get.js +4 -1
- package/dist/server-fns/singletons/history.d.ts +3 -1
- package/dist/server-fns/singletons/history.js +4 -1
- package/dist/server-fns/singletons/restore-version.d.ts +5 -1
- package/dist/server-fns/singletons/restore-version.js +9 -3
- package/dist/server-fns/singletons/schedule-publish.d.ts +8 -2
- package/dist/server-fns/singletons/schedule-publish.js +7 -2
- package/dist/server-fns/singletons/unpublish.d.ts +5 -1
- package/dist/server-fns/singletons/unpublish.js +7 -1
- package/dist/server-fns/singletons/update.d.ts +6 -4
- package/dist/server-fns/singletons/update.js +8 -4
- package/dist/server-fns/structural-receipt.d.ts +4 -0
- package/dist/server-fns/structural-receipt.js +31 -0
- package/package.json +20 -20
- package/src/admin-shell/chrome/admin-app-bar.tsx +11 -6
- package/src/admin-shell/chrome/session-change-boundary.test.tsx +78 -0
- package/src/admin-shell/chrome/session-change-boundary.tsx +94 -0
- package/src/admin-shell/chrome/sign-in-page.tsx +68 -3
- package/src/admin-shell/collections/edit.tsx +173 -54
- 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 +12 -3
- package/src/admin-shell/collections/save-navigation.test.tsx +156 -8
- 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 +3 -1
- package/src/admin-shell/singletons/history.tsx +10 -2
- package/src/admin-shell/singletons/view.test.tsx +59 -18
- package/src/admin-shell/singletons/view.tsx +110 -29
- package/src/integrations/byline-admin-services.ts +7 -1
- package/src/integrations/byline-field-services.ts +2 -3
- package/src/integrations/client-ip.test.node.ts +45 -0
- package/src/integrations/client-ip.ts +54 -0
- package/src/integrations/framework-fetch-shape.test.node.ts +56 -0
- package/src/integrations/session-client.test.node.ts +121 -0
- package/src/integrations/session-coordination.test.node.ts +77 -0
- package/src/integrations/session-coordination.ts +96 -0
- package/src/integrations/session-middleware.test.node.ts +87 -0
- package/src/integrations/session-middleware.ts +107 -0
- package/src/integrations/session-request-kind.ts +18 -0
- package/src/integrations/session-request-middleware.ts +17 -0
- package/src/integrations/sign-in-body.test.node.ts +59 -0
- package/src/integrations/sign-in-body.ts +50 -0
- package/src/integrations/sign-in-middleware.ts +24 -0
- package/src/routes/create-admin-layout-route.tsx +48 -30
- package/src/routes/create-collection-edit-route.tsx +1 -0
- package/src/routes/create-collection-list-route.tsx +13 -2
- package/src/routes/create-sign-in-route.tsx +10 -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/admin-account/change-password.test.node.ts +69 -0
- package/src/server-fns/admin-account/change-password.ts +13 -2
- package/src/server-fns/admin-account/get.ts +2 -0
- package/src/server-fns/admin-account/update.ts +2 -0
- package/src/server-fns/admin-activity/get.ts +2 -0
- package/src/server-fns/admin-permissions/get-role-abilities.ts +2 -0
- package/src/server-fns/admin-permissions/list-registered.ts +5 -4
- package/src/server-fns/admin-permissions/set-role-abilities.ts +2 -0
- package/src/server-fns/admin-permissions/who-has.ts +2 -0
- package/src/server-fns/admin-roles/create.ts +2 -0
- package/src/server-fns/admin-roles/delete.ts +2 -0
- package/src/server-fns/admin-roles/get.ts +2 -0
- package/src/server-fns/admin-roles/list.ts +5 -4
- package/src/server-fns/admin-roles/reorder.ts +2 -0
- package/src/server-fns/admin-roles/update.ts +2 -0
- package/src/server-fns/admin-users/create.ts +2 -0
- package/src/server-fns/admin-users/delete.ts +2 -0
- package/src/server-fns/admin-users/disable.ts +2 -0
- package/src/server-fns/admin-users/enable.ts +2 -0
- package/src/server-fns/admin-users/get-user-roles.ts +2 -0
- package/src/server-fns/admin-users/get.ts +2 -0
- package/src/server-fns/admin-users/list.ts +2 -0
- package/src/server-fns/admin-users/set-password.ts +2 -0
- package/src/server-fns/admin-users/set-user-roles.ts +2 -0
- package/src/server-fns/admin-users/update.ts +2 -0
- package/src/server-fns/ai/execute.ts +3 -0
- package/src/server-fns/analytics/maintenance.ts +4 -0
- package/src/server-fns/analytics/queries.ts +14 -8
- package/src/server-fns/auth/current-user.ts +7 -3
- package/src/server-fns/auth/renew.test.node.ts +85 -0
- package/src/server-fns/auth/renew.ts +54 -0
- package/src/server-fns/auth/sign-in.test.node.ts +114 -0
- package/src/server-fns/auth/sign-in.ts +80 -27
- package/src/server-fns/auth/sign-out.test.node.ts +85 -0
- package/src/server-fns/auth/sign-out.ts +44 -19
- package/src/server-fns/collections/audit.ts +2 -0
- package/src/server-fns/collections/copy-to-locale.ts +43 -36
- package/src/server-fns/collections/create.ts +56 -50
- package/src/server-fns/collections/delete-locale.ts +43 -32
- 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 +46 -38
- package/src/server-fns/collections/duplicate.ts +40 -32
- package/src/server-fns/collections/get.ts +11 -4
- package/src/server-fns/collections/history.ts +2 -0
- package/src/server-fns/collections/list.ts +10 -3
- package/src/server-fns/collections/reindex.ts +2 -0
- package/src/server-fns/collections/reorder.ts +34 -124
- package/src/server-fns/collections/restore-version.ts +49 -39
- package/src/server-fns/collections/revision-input.test.node.ts +122 -0
- package/src/server-fns/collections/save-outcome.test.node.ts +3 -0
- package/src/server-fns/collections/save-outcome.ts +2 -0
- package/src/server-fns/collections/scheduled-publication.ts +149 -115
- package/src/server-fns/collections/set-list-view-preference.ts +2 -0
- package/src/server-fns/collections/stats.ts +2 -0
- package/src/server-fns/collections/status.ts +89 -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 +156 -122
- package/src/server-fns/collections/update.ts +113 -86
- package/src/server-fns/collections/upload-singleton.test.node.ts +10 -7
- package/src/server-fns/collections/upload.ts +91 -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/i18n/set-locale.ts +19 -3
- package/src/server-fns/preview/disable.ts +8 -4
- package/src/server-fns/preview/enable.ts +9 -5
- package/src/server-fns/singleton-document-read.ts +7 -3
- package/src/server-fns/singletons/cancel-scheduled-publish.ts +12 -3
- package/src/server-fns/singletons/change-status.ts +12 -3
- package/src/server-fns/singletons/confirm-scheduled-publish.ts +14 -6
- package/src/server-fns/singletons/copy-to-locale.ts +22 -15
- package/src/server-fns/singletons/find-by-version.ts +2 -0
- package/src/server-fns/singletons/get-scheduled-publish.ts +2 -0
- package/src/server-fns/singletons/get.ts +5 -3
- package/src/server-fns/singletons/history.ts +2 -0
- package/src/server-fns/singletons/restore-version.ts +19 -12
- package/src/server-fns/singletons/schedule-publish.ts +20 -7
- package/src/server-fns/singletons/singletons.test.node.ts +69 -25
- package/src/server-fns/singletons/unpublish.ts +12 -3
- package/src/server-fns/singletons/update.ts +23 -16
- package/src/server-fns/structural-receipt.ts +41 -0
|
@@ -33,11 +33,11 @@ import {
|
|
|
33
33
|
hasDeleteSideEffectFailures,
|
|
34
34
|
scheduleCollectionDocumentPublish,
|
|
35
35
|
unpublishDocument,
|
|
36
|
-
updateCollectionDocumentSystemFields,
|
|
37
36
|
updateCollectionDocumentWithPatches,
|
|
38
37
|
updateDocumentStatus,
|
|
39
38
|
} from '../../server-fns/collections/index.js'
|
|
40
39
|
import { useNavigate } from '../chrome/loose-router.js'
|
|
40
|
+
import { useDocumentMutationState } from '../document-mutation-state.js'
|
|
41
41
|
import { useTanStackNavigationGuard } from './tanstack-navigation-guard.js'
|
|
42
42
|
import { ViewMenu } from './view-menu.js'
|
|
43
43
|
import type { SerializedDocumentPublishSchedule } from '../../server-fns/collections/index.js'
|
|
@@ -51,7 +51,7 @@ type EditState = {
|
|
|
51
51
|
export const EditView = ({
|
|
52
52
|
collectionDefinition,
|
|
53
53
|
adminConfig,
|
|
54
|
-
initialData,
|
|
54
|
+
initialData: loadedData,
|
|
55
55
|
locale,
|
|
56
56
|
contentLocales,
|
|
57
57
|
defaultContentLocale,
|
|
@@ -66,6 +66,8 @@ export const EditView = ({
|
|
|
66
66
|
/** URL-encoded list search state to return to on close — see list-return-state.ts. */
|
|
67
67
|
returnSearch?: Record<string, unknown>
|
|
68
68
|
}) => {
|
|
69
|
+
const mutation = useDocumentMutationState(loadedData)
|
|
70
|
+
const initialData = mutation.document ?? loadedData
|
|
69
71
|
const toastManager = useToastManager()
|
|
70
72
|
const { t } = useTranslation('byline-admin')
|
|
71
73
|
const [_editState, setEditState] = useState<EditState>({
|
|
@@ -131,9 +133,16 @@ export const EditView = ({
|
|
|
131
133
|
|
|
132
134
|
const handleStatusChange = async (status: string) => {
|
|
133
135
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
mutation.assertWritable()
|
|
137
|
+
const result = await updateDocumentStatus({
|
|
138
|
+
data: {
|
|
139
|
+
expectedRevision: mutation.expectedRevision(),
|
|
140
|
+
collection: path,
|
|
141
|
+
id: String(initialData.id),
|
|
142
|
+
status,
|
|
143
|
+
},
|
|
136
144
|
})
|
|
145
|
+
mutation.adopt(result)
|
|
137
146
|
const description = t('collections.edit.statusChangedDescription', { status })
|
|
138
147
|
toastManager.add({
|
|
139
148
|
title: t('collections.edit.statusUpdateTitle', { label: singular }),
|
|
@@ -153,9 +162,16 @@ export const EditView = ({
|
|
|
153
162
|
search: (prev: Record<string, unknown>) => ({ ...prev }),
|
|
154
163
|
})
|
|
155
164
|
} catch (err) {
|
|
165
|
+
const handled = mutation.report(err)
|
|
166
|
+
if (handled === 'blocked') throw err
|
|
167
|
+
if (handled === 'committed') {
|
|
168
|
+
notifyCommittedHookFailure()
|
|
169
|
+
reloadDocument()
|
|
170
|
+
return
|
|
171
|
+
}
|
|
156
172
|
console.error('Status change error:', err)
|
|
157
173
|
const description = t('collections.edit.statusChangeFailedDescription', {
|
|
158
|
-
message: (
|
|
174
|
+
message: t('documentConcurrency.failed'),
|
|
159
175
|
})
|
|
160
176
|
toastManager.add({
|
|
161
177
|
title: t('collections.edit.statusUpdateTitle', { label: singular }),
|
|
@@ -181,14 +197,17 @@ export const EditView = ({
|
|
|
181
197
|
|
|
182
198
|
const handleSchedulePublication = async ({ publishAt }: { publishAt: string }) => {
|
|
183
199
|
try {
|
|
184
|
-
|
|
200
|
+
mutation.assertWritable()
|
|
201
|
+
const result = await scheduleCollectionDocumentPublish({
|
|
185
202
|
data: {
|
|
203
|
+
expectedRevision: mutation.expectedRevision(),
|
|
186
204
|
collection: path,
|
|
187
205
|
id: String(initialData.id),
|
|
188
206
|
publishAt,
|
|
189
207
|
expectedVersionId: String(initialData.versionId),
|
|
190
208
|
},
|
|
191
209
|
})
|
|
210
|
+
mutation.adopt(result)
|
|
192
211
|
toastManager.add({
|
|
193
212
|
title: t('scheduledPublication.toast.scheduledTitle'),
|
|
194
213
|
description: t('scheduledPublication.toast.scheduledDescription'),
|
|
@@ -196,9 +215,16 @@ export const EditView = ({
|
|
|
196
215
|
})
|
|
197
216
|
reloadDocument()
|
|
198
217
|
} catch (err) {
|
|
218
|
+
const handled = mutation.report(err)
|
|
219
|
+
if (handled === 'blocked') throw err
|
|
220
|
+
if (handled === 'committed') {
|
|
221
|
+
notifyCommittedHookFailure()
|
|
222
|
+
reloadDocument()
|
|
223
|
+
return
|
|
224
|
+
}
|
|
199
225
|
toastManager.add({
|
|
200
226
|
title: t('scheduledPublication.toast.failedTitle'),
|
|
201
|
-
description: (
|
|
227
|
+
description: t('documentConcurrency.failed'),
|
|
202
228
|
data: { intent: 'danger', iconType: 'danger', icon: true, close: true },
|
|
203
229
|
})
|
|
204
230
|
throw err
|
|
@@ -207,13 +233,16 @@ export const EditView = ({
|
|
|
207
233
|
|
|
208
234
|
const handleConfirmScheduledPublication = async () => {
|
|
209
235
|
try {
|
|
210
|
-
|
|
236
|
+
mutation.assertWritable()
|
|
237
|
+
const result = await confirmCollectionDocumentScheduledPublish({
|
|
211
238
|
data: {
|
|
239
|
+
expectedRevision: mutation.expectedRevision(),
|
|
212
240
|
collection: path,
|
|
213
241
|
id: String(initialData.id),
|
|
214
242
|
expectedVersionId: String(initialData.versionId),
|
|
215
243
|
},
|
|
216
244
|
})
|
|
245
|
+
mutation.adopt(result)
|
|
217
246
|
toastManager.add({
|
|
218
247
|
title: t('scheduledPublication.toast.confirmedTitle'),
|
|
219
248
|
description: t('scheduledPublication.toast.confirmedDescription'),
|
|
@@ -221,9 +250,16 @@ export const EditView = ({
|
|
|
221
250
|
})
|
|
222
251
|
reloadDocument()
|
|
223
252
|
} catch (err) {
|
|
253
|
+
const handled = mutation.report(err)
|
|
254
|
+
if (handled === 'blocked') throw err
|
|
255
|
+
if (handled === 'committed') {
|
|
256
|
+
notifyCommittedHookFailure()
|
|
257
|
+
reloadDocument()
|
|
258
|
+
return
|
|
259
|
+
}
|
|
224
260
|
toastManager.add({
|
|
225
261
|
title: t('scheduledPublication.toast.failedTitle'),
|
|
226
|
-
description: (
|
|
262
|
+
description: t('documentConcurrency.failed'),
|
|
227
263
|
data: { intent: 'danger', iconType: 'danger', icon: true, close: true },
|
|
228
264
|
})
|
|
229
265
|
throw err
|
|
@@ -232,9 +268,15 @@ export const EditView = ({
|
|
|
232
268
|
|
|
233
269
|
const handleCancelScheduledPublication = async () => {
|
|
234
270
|
try {
|
|
271
|
+
mutation.assertWritable()
|
|
235
272
|
const result = await cancelCollectionDocumentScheduledPublish({
|
|
236
|
-
data: {
|
|
273
|
+
data: {
|
|
274
|
+
expectedRevision: mutation.expectedRevision(),
|
|
275
|
+
collection: path,
|
|
276
|
+
id: String(initialData.id),
|
|
277
|
+
},
|
|
237
278
|
})
|
|
279
|
+
mutation.adopt({ ...result, documentId: String(initialData.id) })
|
|
238
280
|
const cancelled = result.status === 'cancelled'
|
|
239
281
|
toastManager.add({
|
|
240
282
|
title: cancelled
|
|
@@ -252,9 +294,16 @@ export const EditView = ({
|
|
|
252
294
|
})
|
|
253
295
|
reloadDocument()
|
|
254
296
|
} catch (err) {
|
|
297
|
+
const handled = mutation.report(err)
|
|
298
|
+
if (handled === 'blocked') throw err
|
|
299
|
+
if (handled === 'committed') {
|
|
300
|
+
notifyCommittedHookFailure()
|
|
301
|
+
reloadDocument()
|
|
302
|
+
return
|
|
303
|
+
}
|
|
255
304
|
toastManager.add({
|
|
256
305
|
title: t('scheduledPublication.toast.failedTitle'),
|
|
257
|
-
description: (
|
|
306
|
+
description: t('documentConcurrency.failed'),
|
|
258
307
|
data: { intent: 'danger', iconType: 'danger', icon: true, close: true },
|
|
259
308
|
})
|
|
260
309
|
throw err
|
|
@@ -275,7 +324,15 @@ export const EditView = ({
|
|
|
275
324
|
|
|
276
325
|
const handleUnpublish = async () => {
|
|
277
326
|
try {
|
|
278
|
-
|
|
327
|
+
mutation.assertWritable()
|
|
328
|
+
const result = await unpublishDocument({
|
|
329
|
+
data: {
|
|
330
|
+
expectedRevision: mutation.expectedRevision(),
|
|
331
|
+
collection: path,
|
|
332
|
+
id: String(initialData.id),
|
|
333
|
+
},
|
|
334
|
+
})
|
|
335
|
+
mutation.adopt(result)
|
|
279
336
|
const description = t('collections.edit.unpublishedDescription')
|
|
280
337
|
toastManager.add({
|
|
281
338
|
title: t('collections.edit.unpublishTitle', { label: singular }),
|
|
@@ -294,9 +351,16 @@ export const EditView = ({
|
|
|
294
351
|
search: (prev: Record<string, unknown>) => ({ ...prev }),
|
|
295
352
|
})
|
|
296
353
|
} catch (err) {
|
|
354
|
+
const handled = mutation.report(err)
|
|
355
|
+
if (handled === 'blocked') throw err
|
|
356
|
+
if (handled === 'committed') {
|
|
357
|
+
notifyCommittedHookFailure()
|
|
358
|
+
reloadDocument()
|
|
359
|
+
return
|
|
360
|
+
}
|
|
297
361
|
console.error('Unpublish error:', err)
|
|
298
362
|
const description = t('collections.edit.unpublishFailedDescription', {
|
|
299
|
-
message: (
|
|
363
|
+
message: t('documentConcurrency.failed'),
|
|
300
364
|
})
|
|
301
365
|
toastManager.add({
|
|
302
366
|
title: t('collections.edit.unpublishTitle', { label: singular }),
|
|
@@ -314,8 +378,13 @@ export const EditView = ({
|
|
|
314
378
|
|
|
315
379
|
const handleDuplicate = async () => {
|
|
316
380
|
try {
|
|
381
|
+
mutation.assertWritable()
|
|
317
382
|
const result = await duplicateCollectionDocument({
|
|
318
|
-
data: {
|
|
383
|
+
data: {
|
|
384
|
+
expectedRevision: mutation.expectedRevision(),
|
|
385
|
+
collection: path,
|
|
386
|
+
id: String(initialData.id),
|
|
387
|
+
},
|
|
319
388
|
})
|
|
320
389
|
if (hasCommittedDocumentHookFailure(result)) {
|
|
321
390
|
notifyCommittedHookFailure()
|
|
@@ -352,9 +421,16 @@ export const EditView = ({
|
|
|
352
421
|
search: (prev: Record<string, unknown>) => ({ ...prev }),
|
|
353
422
|
})
|
|
354
423
|
} catch (err) {
|
|
424
|
+
const handled = mutation.report(err)
|
|
425
|
+
if (handled === 'blocked') throw err
|
|
426
|
+
if (handled === 'committed') {
|
|
427
|
+
notifyCommittedHookFailure()
|
|
428
|
+
reloadDocument()
|
|
429
|
+
return
|
|
430
|
+
}
|
|
355
431
|
console.error('Duplicate error:', err)
|
|
356
432
|
const description = t('collections.edit.duplicateFailedDescription', {
|
|
357
|
-
message: (
|
|
433
|
+
message: t('documentConcurrency.failed'),
|
|
358
434
|
})
|
|
359
435
|
toastManager.add({
|
|
360
436
|
title: t('collections.edit.duplicateTitle', { label: singular }),
|
|
@@ -378,8 +454,10 @@ export const EditView = ({
|
|
|
378
454
|
overwrite: boolean
|
|
379
455
|
}) => {
|
|
380
456
|
try {
|
|
457
|
+
mutation.assertWritable()
|
|
381
458
|
const result = await copyDocumentToLocale({
|
|
382
459
|
data: {
|
|
460
|
+
expectedRevision: mutation.expectedRevision(),
|
|
383
461
|
collection: path,
|
|
384
462
|
id: String(initialData.id),
|
|
385
463
|
sourceLocale: locale ?? defaultContentLocale,
|
|
@@ -387,6 +465,7 @@ export const EditView = ({
|
|
|
387
465
|
overwrite,
|
|
388
466
|
},
|
|
389
467
|
})
|
|
468
|
+
mutation.adopt(result)
|
|
390
469
|
if (hasCommittedDocumentHookFailure(result)) {
|
|
391
470
|
notifyCommittedHookFailure()
|
|
392
471
|
notifyScheduleSuspended()
|
|
@@ -438,9 +517,16 @@ export const EditView = ({
|
|
|
438
517
|
search: (prev: Record<string, unknown>) => ({ ...prev, locale: targetLocale }),
|
|
439
518
|
})
|
|
440
519
|
} catch (err) {
|
|
520
|
+
const handled = mutation.report(err)
|
|
521
|
+
if (handled === 'blocked') throw err
|
|
522
|
+
if (handled === 'committed') {
|
|
523
|
+
notifyCommittedHookFailure()
|
|
524
|
+
reloadDocument()
|
|
525
|
+
return
|
|
526
|
+
}
|
|
441
527
|
console.error('Copy to locale error:', err)
|
|
442
528
|
const description = t('collections.edit.copyFailedDescription', {
|
|
443
|
-
message: (
|
|
529
|
+
message: t('documentConcurrency.failed'),
|
|
444
530
|
})
|
|
445
531
|
toastManager.add({
|
|
446
532
|
title: t('collections.edit.copyToLocaleTitle', { label: singular }),
|
|
@@ -458,13 +544,16 @@ export const EditView = ({
|
|
|
458
544
|
|
|
459
545
|
const handleDeleteLocale = async ({ targetLocale }: { targetLocale: string }) => {
|
|
460
546
|
try {
|
|
547
|
+
mutation.assertWritable()
|
|
461
548
|
const result = await deleteDocumentLocale({
|
|
462
549
|
data: {
|
|
550
|
+
expectedRevision: mutation.expectedRevision(),
|
|
463
551
|
collection: path,
|
|
464
552
|
id: String(initialData.id),
|
|
465
553
|
locale: targetLocale,
|
|
466
554
|
},
|
|
467
555
|
})
|
|
556
|
+
mutation.adopt(result)
|
|
468
557
|
if (hasCommittedDocumentHookFailure(result)) {
|
|
469
558
|
notifyCommittedHookFailure()
|
|
470
559
|
notifyScheduleSuspended()
|
|
@@ -501,9 +590,16 @@ export const EditView = ({
|
|
|
501
590
|
search: (prev: Record<string, unknown>) => ({ ...prev, locale: defaultContentLocale }),
|
|
502
591
|
})
|
|
503
592
|
} catch (err) {
|
|
593
|
+
const handled = mutation.report(err)
|
|
594
|
+
if (handled === 'blocked') throw err
|
|
595
|
+
if (handled === 'committed') {
|
|
596
|
+
notifyCommittedHookFailure()
|
|
597
|
+
reloadDocument()
|
|
598
|
+
return
|
|
599
|
+
}
|
|
504
600
|
console.error('Delete locale error:', err)
|
|
505
601
|
const description = t('collections.edit.deleteLocaleFailedDescription', {
|
|
506
|
-
message: (
|
|
602
|
+
message: t('documentConcurrency.failed'),
|
|
507
603
|
})
|
|
508
604
|
toastManager.add({
|
|
509
605
|
title: t('collections.edit.deleteLocaleTitle', { label: singular }),
|
|
@@ -521,9 +617,28 @@ export const EditView = ({
|
|
|
521
617
|
|
|
522
618
|
const handleDelete = async () => {
|
|
523
619
|
try {
|
|
620
|
+
mutation.assertWritable()
|
|
524
621
|
const result = await deleteDocument({
|
|
525
|
-
data: {
|
|
622
|
+
data: {
|
|
623
|
+
expectedRevision: mutation.expectedRevision(),
|
|
624
|
+
collection: path,
|
|
625
|
+
id: String(initialData.id),
|
|
626
|
+
},
|
|
526
627
|
})
|
|
628
|
+
if (result.scheduledPublicationsNeedReconfirmation) {
|
|
629
|
+
toastManager.add({
|
|
630
|
+
title: t('documentConcurrency.schedulesTitle'),
|
|
631
|
+
description: (
|
|
632
|
+
<>
|
|
633
|
+
<p>{t('documentConcurrency.schedules')}</p>
|
|
634
|
+
<a href={getAdminRoutePath('scheduled-publications')}>
|
|
635
|
+
{t('documentConcurrency.reviewSchedules')}
|
|
636
|
+
</a>
|
|
637
|
+
</>
|
|
638
|
+
),
|
|
639
|
+
data: { intent: 'warning', iconType: 'warning', icon: true, close: true },
|
|
640
|
+
})
|
|
641
|
+
}
|
|
527
642
|
const hasSideEffectFailures = hasDeleteSideEffectFailures(result)
|
|
528
643
|
const description = hasSideEffectFailures
|
|
529
644
|
? t('collections.edit.deletedWithWarningsDescription', { label: singular })
|
|
@@ -552,9 +667,16 @@ export const EditView = ({
|
|
|
552
667
|
search: returnSearch,
|
|
553
668
|
})
|
|
554
669
|
} catch (err) {
|
|
670
|
+
const handled = mutation.report(err)
|
|
671
|
+
if (handled === 'blocked') throw err
|
|
672
|
+
if (handled === 'committed') {
|
|
673
|
+
notifyCommittedHookFailure()
|
|
674
|
+
reloadDocument()
|
|
675
|
+
return
|
|
676
|
+
}
|
|
555
677
|
console.error('Delete error:', err)
|
|
556
678
|
const description = t('collections.edit.deleteFailedDescription', {
|
|
557
|
-
message: (
|
|
679
|
+
message: t('documentConcurrency.failed'),
|
|
558
680
|
})
|
|
559
681
|
toastManager.add({
|
|
560
682
|
title: t('collections.edit.deleteTitle', { label: singular }),
|
|
@@ -593,41 +715,24 @@ export const EditView = ({
|
|
|
593
715
|
systemAvailableLocales?: string[]
|
|
594
716
|
}) => {
|
|
595
717
|
try {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
// mints a new draft version. Skipped entirely when only the system
|
|
615
|
-
// fields changed, so a path/advertising edit never creates an empty
|
|
616
|
-
// content version.
|
|
617
|
-
if (contentDirty) {
|
|
618
|
-
const result = await updateCollectionDocumentWithPatches({
|
|
619
|
-
data: {
|
|
620
|
-
collection: path,
|
|
621
|
-
id: String(initialData.id),
|
|
622
|
-
patches,
|
|
623
|
-
versionId: initialData.versionId as string | undefined,
|
|
624
|
-
locale,
|
|
625
|
-
},
|
|
626
|
-
})
|
|
627
|
-
hookFailed = hasCommittedDocumentHookFailure(result)
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
if (contentDirty && scheduledPublication?.state === 'armed') {
|
|
718
|
+
mutation.assertWritable()
|
|
719
|
+
const result = await updateCollectionDocumentWithPatches({
|
|
720
|
+
data: {
|
|
721
|
+
collection: path,
|
|
722
|
+
id: String(initialData.id),
|
|
723
|
+
expectedRevision: mutation.expectedRevision(),
|
|
724
|
+
patches: contentDirty ? patches : [],
|
|
725
|
+
locale,
|
|
726
|
+
...(pathDirty ? { path: systemPath ?? null } : {}),
|
|
727
|
+
...(availableLocalesDirty ? { availableLocales: systemAvailableLocales ?? [] } : {}),
|
|
728
|
+
},
|
|
729
|
+
})
|
|
730
|
+
mutation.adopt(result)
|
|
731
|
+
const hookFailed = hasCommittedDocumentHookFailure(result)
|
|
732
|
+
if (
|
|
733
|
+
(contentDirty || pathDirty || availableLocalesDirty) &&
|
|
734
|
+
scheduledPublication?.state === 'armed'
|
|
735
|
+
) {
|
|
631
736
|
notifyScheduleSuspended()
|
|
632
737
|
}
|
|
633
738
|
|
|
@@ -662,6 +767,13 @@ export const EditView = ({
|
|
|
662
767
|
ignoreBlocker: true,
|
|
663
768
|
})
|
|
664
769
|
} catch (err) {
|
|
770
|
+
const handled = mutation.report(err)
|
|
771
|
+
if (handled === 'blocked') throw err
|
|
772
|
+
if (handled === 'committed') {
|
|
773
|
+
notifyCommittedHookFailure()
|
|
774
|
+
reloadDocument()
|
|
775
|
+
return
|
|
776
|
+
}
|
|
665
777
|
console.error('Network error:', err)
|
|
666
778
|
const description = t('collections.edit.updateFailedDescription', { label: singularLower })
|
|
667
779
|
toastManager.add({
|
|
@@ -687,6 +799,13 @@ export const EditView = ({
|
|
|
687
799
|
<Section>
|
|
688
800
|
<Container>
|
|
689
801
|
<FormRenderer
|
|
802
|
+
mutationIssue={mutation.issue}
|
|
803
|
+
mutationsBlocked={mutation.blocked}
|
|
804
|
+
observedRevision={mutation.revision}
|
|
805
|
+
onMutationError={mutation.report}
|
|
806
|
+
onTreeMutationCommitted={mutation.adopt}
|
|
807
|
+
scheduledPublicationsNeedReconfirmation={mutation.scheduleNotice}
|
|
808
|
+
scheduledPublicationsHref={getAdminRoutePath('scheduled-publications')}
|
|
690
809
|
mode="edit"
|
|
691
810
|
fields={fields}
|
|
692
811
|
onSubmit={handleSubmit}
|
|
@@ -155,6 +155,7 @@ export const HistoryView = ({
|
|
|
155
155
|
currentVersionId,
|
|
156
156
|
restoreStatusLabel,
|
|
157
157
|
openCompare,
|
|
158
|
+
mutationsBlocked,
|
|
158
159
|
openRestore,
|
|
159
160
|
}) =>
|
|
160
161
|
columns.flatMap((column) => {
|
|
@@ -213,6 +214,7 @@ export const HistoryView = ({
|
|
|
213
214
|
variant="outlined"
|
|
214
215
|
size="xs"
|
|
215
216
|
intent="noeffect"
|
|
217
|
+
disabled={mutationsBlocked}
|
|
216
218
|
onClick={openRestore}
|
|
217
219
|
className={cx('byline-coll-history-restore-button', styles.restoreButton)}
|
|
218
220
|
title={t('collections.history.restoreButtonTitle', {
|
|
@@ -279,8 +281,15 @@ export const HistoryView = ({
|
|
|
279
281
|
rowPresentation={rowPresentation}
|
|
280
282
|
loadHistoricalVersion={getCollectionDocumentVersion}
|
|
281
283
|
onPageSizeChange={handlePageSizeChange}
|
|
282
|
-
restoreVersion={(versionId) =>
|
|
283
|
-
restoreDocumentVersion({
|
|
284
|
+
restoreVersion={(versionId, expectedRevision) =>
|
|
285
|
+
restoreDocumentVersion({
|
|
286
|
+
data: {
|
|
287
|
+
expectedRevision,
|
|
288
|
+
collection,
|
|
289
|
+
id,
|
|
290
|
+
versionId,
|
|
291
|
+
},
|
|
292
|
+
})
|
|
284
293
|
}
|
|
285
294
|
onRestoreComplete={async () => {
|
|
286
295
|
await router.invalidate()
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DocumentMutationNotice } from '../document-mutation-notice.js'
|
|
2
|
+
import { useDocumentMutationState } from '../document-mutation-state.js'
|
|
1
3
|
/**
|
|
2
4
|
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
5
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
@@ -178,6 +180,7 @@ export const ListView = ({
|
|
|
178
180
|
const navigate = useNavigate()
|
|
179
181
|
const router = useRouter()
|
|
180
182
|
const toastManager = useToastManager()
|
|
183
|
+
const mutation = useDocumentMutationState(undefined)
|
|
181
184
|
const { t } = useTranslation('byline-admin')
|
|
182
185
|
const location = useRouterState({ select: (s) => s.location })
|
|
183
186
|
|
|
@@ -191,10 +194,10 @@ export const ListView = ({
|
|
|
191
194
|
const [localDocs, setLocalDocs] = useState(data.docs)
|
|
192
195
|
const [isReordering, setIsReordering] = useState(false)
|
|
193
196
|
useEffect(() => {
|
|
194
|
-
if (!isReordering) {
|
|
197
|
+
if (!isReordering && !mutation.blocked) {
|
|
195
198
|
setLocalDocs(data.docs)
|
|
196
199
|
}
|
|
197
|
-
}, [data.docs, isReordering])
|
|
200
|
+
}, [data.docs, isReordering, mutation.blocked])
|
|
198
201
|
|
|
199
202
|
// Drag is only meaningful in the canonical view: the default order_key
|
|
200
203
|
// sort, no search, no status filter. Otherwise the visible order isn't
|
|
@@ -209,7 +212,7 @@ export const ListView = ({
|
|
|
209
212
|
}
|
|
210
213
|
const isCanonicalView =
|
|
211
214
|
!searchParams.order && !searchParams.desc && !searchParams.query && !searchParams.status
|
|
212
|
-
const dragEnabled = orderable && isCanonicalView && !!onReorder
|
|
215
|
+
const dragEnabled = orderable && isCanonicalView && !!onReorder && !mutation.blocked
|
|
213
216
|
|
|
214
217
|
// The *effective* sort for the header indicators: explicit URL params win;
|
|
215
218
|
// otherwise the server echoes a configured `defaultSort` (admin config)
|
|
@@ -226,7 +229,7 @@ export const ListView = ({
|
|
|
226
229
|
|
|
227
230
|
const handleDragEnd = async (event: DragEndEvent) => {
|
|
228
231
|
const { active, over } = event
|
|
229
|
-
if (!over || active.id === over.id || !onReorder) return
|
|
232
|
+
if (mutation.blocked || isReordering || !over || active.id === over.id || !onReorder) return
|
|
230
233
|
const oldIndex = localDocs.findIndex((d) => d.id === active.id)
|
|
231
234
|
const newIndex = localDocs.findIndex((d) => d.id === over.id)
|
|
232
235
|
if (oldIndex < 0 || newIndex < 0 || oldIndex === newIndex) return
|
|
@@ -242,14 +245,26 @@ export const ListView = ({
|
|
|
242
245
|
const before = next[newIndex - 1]?.id ?? null
|
|
243
246
|
const after = next[newIndex + 1]?.id ?? null
|
|
244
247
|
try {
|
|
245
|
-
|
|
248
|
+
mutation.assertWritable()
|
|
249
|
+
const receipt = await onReorder({
|
|
246
250
|
documentId: String(active.id),
|
|
247
251
|
beforeDocumentId: before,
|
|
248
252
|
afterDocumentId: after,
|
|
249
253
|
})
|
|
250
|
-
|
|
254
|
+
mutation.reportStructure(receipt)
|
|
255
|
+
try {
|
|
256
|
+
await router.invalidate()
|
|
257
|
+
} catch {
|
|
258
|
+
// The mutation committed; a failed refresh must not undo its UI receipt.
|
|
259
|
+
toastManager.add({
|
|
260
|
+
title: t('collections.list.treeRefreshFailedToast'),
|
|
261
|
+
description: t('collections.list.treeRefreshFailedDescription'),
|
|
262
|
+
data: { intent: 'warning', iconType: 'warning', icon: true, close: true },
|
|
263
|
+
})
|
|
264
|
+
}
|
|
251
265
|
} catch (_err) {
|
|
252
266
|
setLocalDocs(previousDocs)
|
|
267
|
+
if (mutation.report(_err)) return
|
|
253
268
|
toastManager.add({
|
|
254
269
|
title: t('collections.list.reorderFailedToast'),
|
|
255
270
|
description: t('collections.list.reorderFailedDescription'),
|
|
@@ -359,6 +374,7 @@ export const ListView = ({
|
|
|
359
374
|
return (
|
|
360
375
|
<Section>
|
|
361
376
|
<Container>
|
|
377
|
+
<DocumentMutationNotice issue={mutation.issue} scheduleNotice={mutation.scheduleNotice} />
|
|
362
378
|
<div className={cx('byline-coll-list-head', styles.head)}>
|
|
363
379
|
<h1 className={cx('byline-coll-list-title', styles.title)}>
|
|
364
380
|
{data.included.collection.labels.plural as string}
|
|
@@ -26,6 +26,8 @@ import { hasCommittedDocumentHookFailure } from '../../server-fns/collections/sa
|
|
|
26
26
|
import styles from './restore-version-modal.module.css'
|
|
27
27
|
|
|
28
28
|
interface RestoreVersionModalProps {
|
|
29
|
+
disabled?: boolean
|
|
30
|
+
onMutationError?: (error: unknown) => unknown
|
|
29
31
|
versionLabel: string
|
|
30
32
|
versionNumber: number
|
|
31
33
|
restoreStatusLabel: string
|
|
@@ -35,6 +37,8 @@ interface RestoreVersionModalProps {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export function RestoreVersionModal({
|
|
40
|
+
disabled = false,
|
|
41
|
+
onMutationError,
|
|
38
42
|
versionLabel,
|
|
39
43
|
versionNumber,
|
|
40
44
|
restoreStatusLabel,
|
|
@@ -48,7 +52,7 @@ export function RestoreVersionModal({
|
|
|
48
52
|
const [pending, setPending] = useState(false)
|
|
49
53
|
|
|
50
54
|
async function handleRestore() {
|
|
51
|
-
if (pending) return
|
|
55
|
+
if (pending || disabled) return
|
|
52
56
|
setPending(true)
|
|
53
57
|
setError(null)
|
|
54
58
|
try {
|
|
@@ -63,6 +67,11 @@ export function RestoreVersionModal({
|
|
|
63
67
|
onClose()
|
|
64
68
|
await onRestoreComplete()
|
|
65
69
|
} catch (err) {
|
|
70
|
+
if (onMutationError?.(err)) {
|
|
71
|
+
setPending(false)
|
|
72
|
+
onClose()
|
|
73
|
+
return
|
|
74
|
+
}
|
|
66
75
|
const code = getErrorCode(err)
|
|
67
76
|
if (code === 'ERR_INVALID_TRANSITION') {
|
|
68
77
|
setError(t('collections.restore.errors.alreadyCurrent'))
|
|
@@ -113,7 +122,7 @@ export function RestoreVersionModal({
|
|
|
113
122
|
intent="noeffect"
|
|
114
123
|
size="sm"
|
|
115
124
|
onClick={onClose}
|
|
116
|
-
disabled={pending}
|
|
125
|
+
disabled={pending || disabled}
|
|
117
126
|
className={cx('byline-coll-restore-button', styles.button)}
|
|
118
127
|
>
|
|
119
128
|
{t('common.actions.cancel')}
|
|
@@ -123,7 +132,7 @@ export function RestoreVersionModal({
|
|
|
123
132
|
intent="primary"
|
|
124
133
|
onClick={handleRestore}
|
|
125
134
|
style={{ minWidth: '80px' }}
|
|
126
|
-
disabled={pending}
|
|
135
|
+
disabled={pending || disabled}
|
|
127
136
|
className={cx('byline-coll-restore-button', styles.button)}
|
|
128
137
|
>
|
|
129
138
|
{pending === true ? (
|