@byline/host-tanstack-start 4.18.0 → 4.19.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.js +85 -17
- package/dist/admin-shell/collections/restore-version-modal.js +14 -2
- package/dist/admin-shell/collections/save-navigation.test.d.ts +8 -0
- package/dist/admin-shell/singletons/view.js +10 -4
- package/dist/server-fns/collections/copy-to-locale.d.ts +2 -1
- package/dist/server-fns/collections/copy-to-locale.js +13 -6
- package/dist/server-fns/collections/create.d.ts +1 -1
- package/dist/server-fns/collections/create.js +15 -7
- package/dist/server-fns/collections/delete-locale.d.ts +2 -1
- package/dist/server-fns/collections/delete-locale.js +11 -4
- package/dist/server-fns/collections/duplicate.d.ts +2 -1
- package/dist/server-fns/collections/duplicate.js +10 -3
- package/dist/server-fns/collections/index.d.ts +1 -0
- package/dist/server-fns/collections/index.js +1 -0
- package/dist/server-fns/collections/restore-version.d.ts +1 -1
- package/dist/server-fns/collections/restore-version.js +17 -10
- package/dist/server-fns/collections/save-outcome.d.ts +23 -0
- package/dist/server-fns/collections/save-outcome.js +18 -0
- package/dist/server-fns/collections/update.d.ts +3 -1
- package/dist/server-fns/collections/update.js +17 -7
- package/dist/server-fns/singletons/copy-to-locale.js +14 -5
- package/dist/server-fns/singletons/restore-version.js +10 -1
- package/dist/server-fns/singletons/update.js +12 -5
- package/package.json +10 -10
- package/src/admin-shell/collections/create.tsx +22 -3
- package/src/admin-shell/collections/edit.tsx +63 -10
- package/src/admin-shell/collections/restore-version-modal.tsx +11 -2
- package/src/admin-shell/collections/save-navigation.test.tsx +384 -0
- package/src/admin-shell/singletons/history.test.tsx +43 -0
- package/src/admin-shell/singletons/view.test.tsx +27 -0
- package/src/admin-shell/singletons/view.tsx +35 -16
- package/src/server-fns/collections/copy-to-locale.ts +43 -29
- package/src/server-fns/collections/create.ts +16 -8
- package/src/server-fns/collections/delete-locale.ts +38 -24
- package/src/server-fns/collections/duplicate.ts +38 -24
- package/src/server-fns/collections/index.ts +1 -0
- package/src/server-fns/collections/restore-version.ts +16 -9
- package/src/server-fns/collections/save-outcome.test.node.ts +77 -0
- package/src/server-fns/collections/save-outcome.ts +55 -0
- package/src/server-fns/collections/update.ts +23 -8
- package/src/server-fns/singletons/copy-to-locale.ts +16 -9
- package/src/server-fns/singletons/restore-version.ts +12 -3
- package/src/server-fns/singletons/singletons.test.node.ts +34 -0
- package/src/server-fns/singletons/update.ts +12 -5
|
@@ -3,6 +3,7 @@ import { getAdminRequestContext } from "@byline/client/server";
|
|
|
3
3
|
import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
|
|
4
4
|
import { updateDocumentSystemFields, updateDocumentWithPatches } from "@byline/core/services";
|
|
5
5
|
import { ensureCollection } from "../../integrations/api-utils.js";
|
|
6
|
+
import { toCommittedDocumentHookFailureResponse } from "./save-outcome.js";
|
|
6
7
|
const updateCollectionDocumentWithPatches = createServerFn({
|
|
7
8
|
method: 'POST'
|
|
8
9
|
}).validator((input)=>input).handler(async ({ data: input })=>{
|
|
@@ -27,14 +28,23 @@ const updateCollectionDocumentWithPatches = createServerFn({
|
|
|
27
28
|
slugifier: serverConfig.slugifier,
|
|
28
29
|
requestContext: await getAdminRequestContext()
|
|
29
30
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
let result;
|
|
32
|
+
try {
|
|
33
|
+
result = await updateDocumentWithPatches(ctx, {
|
|
34
|
+
documentId: id,
|
|
35
|
+
patches,
|
|
36
|
+
documentVersionId: versionId,
|
|
37
|
+
locale: locale ?? serverConfig.i18n.content.defaultLocale
|
|
38
|
+
});
|
|
39
|
+
} catch (error) {
|
|
40
|
+
const committedFailure = toCommittedDocumentHookFailureResponse(error);
|
|
41
|
+
if (null != committedFailure) return committedFailure;
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
36
44
|
return {
|
|
37
|
-
status: 'ok'
|
|
45
|
+
status: 'ok',
|
|
46
|
+
documentId: result.documentId,
|
|
47
|
+
documentVersionId: result.documentVersionId
|
|
38
48
|
};
|
|
39
49
|
});
|
|
40
50
|
const updateCollectionDocumentSystemFields = createServerFn({
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { getAdminBylineClient } from "@byline/client/server";
|
|
3
|
+
import { toCommittedDocumentHookFailureResponse } from "../collections/save-outcome.js";
|
|
3
4
|
import { serialise } from "../serialise.js";
|
|
4
5
|
const copySingletonToLocale = createServerFn({
|
|
5
6
|
method: 'POST'
|
|
6
|
-
}).validator((input)=>input).handler(async ({ data })=>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
|
+
try {
|
|
9
|
+
return serialise(await getAdminBylineClient().singleton(data.singleton).copyToLocale({
|
|
10
|
+
sourceLocale: data.sourceLocale,
|
|
11
|
+
targetLocale: data.targetLocale,
|
|
12
|
+
overwrite: data.overwrite
|
|
13
|
+
}));
|
|
14
|
+
} catch (error) {
|
|
15
|
+
const committedFailure = toCommittedDocumentHookFailureResponse(error);
|
|
16
|
+
if (null != committedFailure) return committedFailure;
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
11
20
|
export { copySingletonToLocale };
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { getAdminBylineClient } from "@byline/client/server";
|
|
3
|
+
import { toCommittedDocumentHookFailureResponse } from "../collections/save-outcome.js";
|
|
3
4
|
import { serialise } from "../serialise.js";
|
|
4
5
|
const restoreSingletonVersion = createServerFn({
|
|
5
6
|
method: 'POST'
|
|
6
|
-
}).validator((input)=>input).handler(async ({ data })=>
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
|
+
try {
|
|
9
|
+
return serialise(await getAdminBylineClient().singleton(data.singleton).restoreVersion(data.versionId));
|
|
10
|
+
} catch (error) {
|
|
11
|
+
const committedFailure = toCommittedDocumentHookFailureResponse(error);
|
|
12
|
+
if (null != committedFailure) return committedFailure;
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
7
16
|
export { restoreSingletonVersion };
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { getAdminBylineClient } from "@byline/client/server";
|
|
3
|
+
import { toCommittedDocumentHookFailureResponse } from "../collections/save-outcome.js";
|
|
3
4
|
import { serialise } from "../serialise.js";
|
|
4
5
|
const updateSingleton = createServerFn({
|
|
5
6
|
method: 'POST'
|
|
6
7
|
}).validator((input)=>input).handler(async ({ data })=>{
|
|
7
8
|
const { singleton, data: fields, locale, expectedVersionId } = data;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
try {
|
|
10
|
+
const result = await getAdminBylineClient().singleton(singleton).update(fields, {
|
|
11
|
+
locale,
|
|
12
|
+
expectedVersionId
|
|
13
|
+
});
|
|
14
|
+
return serialise(result);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
const committedFailure = toCommittedDocumentHookFailureResponse(error);
|
|
17
|
+
if (null != committedFailure) return committedFailure;
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
13
20
|
});
|
|
14
21
|
export { updateSingleton };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"private": false,
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
|
-
"version": "4.
|
|
6
|
+
"version": "4.19.0",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=20.9.0"
|
|
9
9
|
},
|
|
@@ -125,15 +125,15 @@
|
|
|
125
125
|
"react-json-view-lite": "^2.5.0",
|
|
126
126
|
"react-swipeable": "^7.0.2",
|
|
127
127
|
"zod": "^4.4.3",
|
|
128
|
-
"@byline/admin": "4.
|
|
129
|
-
"@byline/
|
|
130
|
-
"@byline/analytics-agent": "4.
|
|
131
|
-
"@byline/
|
|
132
|
-
"@byline/
|
|
133
|
-
"@byline/
|
|
134
|
-
"@byline/
|
|
135
|
-
"@byline/
|
|
136
|
-
"@byline/ui": "4.
|
|
128
|
+
"@byline/admin": "4.19.0",
|
|
129
|
+
"@byline/analytics": "4.19.0",
|
|
130
|
+
"@byline/analytics-agent": "4.19.0",
|
|
131
|
+
"@byline/ai": "4.19.0",
|
|
132
|
+
"@byline/core": "4.19.0",
|
|
133
|
+
"@byline/client": "4.19.0",
|
|
134
|
+
"@byline/auth": "4.19.0",
|
|
135
|
+
"@byline/i18n": "4.19.0",
|
|
136
|
+
"@byline/ui": "4.19.0"
|
|
137
137
|
},
|
|
138
138
|
"peerDependencies": {
|
|
139
139
|
"@tanstack/react-router": "^1.167.0",
|
|
@@ -15,7 +15,10 @@ import { Container, Section, useToastManager } from '@byline/ui/react'
|
|
|
15
15
|
|
|
16
16
|
import { getAdminRoutePath } from '../../routes/admin-path.js'
|
|
17
17
|
import { decodeListReturnState } from '../../routes/list-return-state.js'
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
createCollectionDocument,
|
|
20
|
+
hasCommittedDocumentHookFailure,
|
|
21
|
+
} from '../../server-fns/collections/index.js'
|
|
19
22
|
import { useNavigate } from '../chrome/loose-router.js'
|
|
20
23
|
import { useTanStackNavigationGuard } from './tanstack-navigation-guard.js'
|
|
21
24
|
|
|
@@ -65,6 +68,14 @@ export const CreateView = ({
|
|
|
65
68
|
...(systemAvailableLocales ? { availableLocales: systemAvailableLocales } : {}),
|
|
66
69
|
},
|
|
67
70
|
})
|
|
71
|
+
const hookFailed = hasCommittedDocumentHookFailure(result)
|
|
72
|
+
if (hookFailed) {
|
|
73
|
+
toastManager.add({
|
|
74
|
+
title: t('collections.save.hookFailedToast'),
|
|
75
|
+
description: t('collections.save.hookFailedDescription'),
|
|
76
|
+
data: { intent: 'warning', iconType: 'warning', icon: true, close: true },
|
|
77
|
+
})
|
|
78
|
+
}
|
|
68
79
|
// Create → edit: land the editor on the new document, where the rest
|
|
69
80
|
// of the work (content, status, relations) happens. `from` threads
|
|
70
81
|
// forward so closing the brand-new document also returns to the
|
|
@@ -75,13 +86,21 @@ export const CreateView = ({
|
|
|
75
86
|
navigate({
|
|
76
87
|
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
77
88
|
params: { collection: path, id: result.documentId } as never,
|
|
78
|
-
search: { action: 'created', from },
|
|
89
|
+
search: { ...(hookFailed ? {} : { action: 'created' as const }), from },
|
|
90
|
+
// Persistence has succeeded, but FormRenderer cannot commit its
|
|
91
|
+
// clean baseline until this handler returns. Do not let that brief
|
|
92
|
+
// dirty-state overlap block the intentional create → edit redirect.
|
|
93
|
+
ignoreBlocker: true,
|
|
79
94
|
})
|
|
80
95
|
} else {
|
|
81
96
|
navigate({
|
|
82
97
|
to: getAdminRoutePath('collections', '$collection'),
|
|
83
98
|
params: { collection: path },
|
|
84
|
-
search: {
|
|
99
|
+
search: {
|
|
100
|
+
...decodeListReturnState(from),
|
|
101
|
+
...(hookFailed ? {} : { action: 'created' as const }),
|
|
102
|
+
},
|
|
103
|
+
ignoreBlocker: true,
|
|
85
104
|
})
|
|
86
105
|
}
|
|
87
106
|
} catch (err) {
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
deleteDocument,
|
|
30
30
|
deleteDocumentLocale,
|
|
31
31
|
duplicateCollectionDocument,
|
|
32
|
+
hasCommittedDocumentHookFailure,
|
|
32
33
|
hasDeleteSideEffectFailures,
|
|
33
34
|
scheduleCollectionDocumentPublish,
|
|
34
35
|
unpublishDocument,
|
|
@@ -43,7 +44,7 @@ import type { SerializedDocumentPublishSchedule } from '../../server-fns/collect
|
|
|
43
44
|
import type { ContentLocaleOption } from './view-menu.js'
|
|
44
45
|
|
|
45
46
|
type EditState = {
|
|
46
|
-
status: 'success' | 'failed' | 'busy' | 'idle'
|
|
47
|
+
status: 'success' | 'warning' | 'failed' | 'busy' | 'idle'
|
|
47
48
|
message: string
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -110,6 +111,16 @@ export const EditView = ({
|
|
|
110
111
|
})
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
const notifyCommittedHookFailure = () => {
|
|
115
|
+
const description = t('collections.save.hookFailedDescription')
|
|
116
|
+
toastManager.add({
|
|
117
|
+
title: t('collections.save.hookFailedToast'),
|
|
118
|
+
description,
|
|
119
|
+
data: { intent: 'warning', iconType: 'warning', icon: true, close: true },
|
|
120
|
+
})
|
|
121
|
+
setEditState({ status: 'warning', message: description })
|
|
122
|
+
}
|
|
123
|
+
|
|
113
124
|
const handleLocaleChange = (newLocale: string) => {
|
|
114
125
|
navigate({
|
|
115
126
|
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
@@ -306,6 +317,15 @@ export const EditView = ({
|
|
|
306
317
|
const result = await duplicateCollectionDocument({
|
|
307
318
|
data: { collection: path, id: String(initialData.id) },
|
|
308
319
|
})
|
|
320
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
321
|
+
notifyCommittedHookFailure()
|
|
322
|
+
navigate({
|
|
323
|
+
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
324
|
+
params: { collection: path, id: result.documentId },
|
|
325
|
+
search: (prev: Record<string, unknown>) => ({ ...prev }),
|
|
326
|
+
})
|
|
327
|
+
return
|
|
328
|
+
}
|
|
309
329
|
const description = result.pathRetried
|
|
310
330
|
? t('collections.edit.duplicatedAutoPathDescription', { path: result.newPath })
|
|
311
331
|
: t('collections.edit.duplicatedPathDescription', { path: result.newPath })
|
|
@@ -367,6 +387,16 @@ export const EditView = ({
|
|
|
367
387
|
overwrite,
|
|
368
388
|
},
|
|
369
389
|
})
|
|
390
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
391
|
+
notifyCommittedHookFailure()
|
|
392
|
+
notifyScheduleSuspended()
|
|
393
|
+
navigate({
|
|
394
|
+
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
395
|
+
params: { collection: path, id: String(initialData.id) },
|
|
396
|
+
search: (prev: Record<string, unknown>) => ({ ...prev, locale: targetLocale }),
|
|
397
|
+
})
|
|
398
|
+
return
|
|
399
|
+
}
|
|
370
400
|
const sourceLabel =
|
|
371
401
|
contentLocales.find((l) => l.code === result.sourceLocale)?.label ?? result.sourceLocale
|
|
372
402
|
const targetLabel =
|
|
@@ -435,6 +465,16 @@ export const EditView = ({
|
|
|
435
465
|
locale: targetLocale,
|
|
436
466
|
},
|
|
437
467
|
})
|
|
468
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
469
|
+
notifyCommittedHookFailure()
|
|
470
|
+
notifyScheduleSuspended()
|
|
471
|
+
navigate({
|
|
472
|
+
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
473
|
+
params: { collection: path, id: String(initialData.id) },
|
|
474
|
+
search: (prev: Record<string, unknown>) => ({ ...prev, locale: defaultContentLocale }),
|
|
475
|
+
})
|
|
476
|
+
return
|
|
477
|
+
}
|
|
438
478
|
const targetLabel =
|
|
439
479
|
contentLocales.find((l) => l.code === result.locale)?.label ?? result.locale
|
|
440
480
|
const description = t('collections.edit.deletedLocaleDescription', {
|
|
@@ -498,7 +538,10 @@ export const EditView = ({
|
|
|
498
538
|
close: true,
|
|
499
539
|
},
|
|
500
540
|
})
|
|
501
|
-
setEditState({
|
|
541
|
+
setEditState({
|
|
542
|
+
status: hasSideEffectFailures ? 'warning' : 'success',
|
|
543
|
+
message: description,
|
|
544
|
+
})
|
|
502
545
|
// Navigate back to the collection list after deletion. The return
|
|
503
546
|
// target has now been consumed — clear the stored fallback so a later
|
|
504
547
|
// visit doesn't resurrect a stale list position.
|
|
@@ -550,6 +593,7 @@ export const EditView = ({
|
|
|
550
593
|
systemAvailableLocales?: string[]
|
|
551
594
|
}) => {
|
|
552
595
|
try {
|
|
596
|
+
let hookFailed = false
|
|
553
597
|
// Document-grain system fields write first via their own non-versioned
|
|
554
598
|
// path — so a path conflict surfaces before we mint a content version,
|
|
555
599
|
// and these immediate writes never reset workflow status. See
|
|
@@ -571,7 +615,7 @@ export const EditView = ({
|
|
|
571
615
|
// fields changed, so a path/advertising edit never creates an empty
|
|
572
616
|
// content version.
|
|
573
617
|
if (contentDirty) {
|
|
574
|
-
await updateCollectionDocumentWithPatches({
|
|
618
|
+
const result = await updateCollectionDocumentWithPatches({
|
|
575
619
|
data: {
|
|
576
620
|
collection: path,
|
|
577
621
|
id: String(initialData.id),
|
|
@@ -580,33 +624,42 @@ export const EditView = ({
|
|
|
580
624
|
locale,
|
|
581
625
|
},
|
|
582
626
|
})
|
|
627
|
+
hookFailed = hasCommittedDocumentHookFailure(result)
|
|
583
628
|
}
|
|
584
629
|
|
|
585
630
|
if (contentDirty && scheduledPublication?.state === 'armed') {
|
|
586
631
|
notifyScheduleSuspended()
|
|
587
632
|
}
|
|
588
633
|
|
|
589
|
-
const description =
|
|
634
|
+
const description = hookFailed
|
|
635
|
+
? t('collections.save.hookFailedDescription')
|
|
636
|
+
: t('collections.edit.updatedDescription', { label: singularLower })
|
|
590
637
|
toastManager.add({
|
|
591
|
-
title:
|
|
638
|
+
title: hookFailed
|
|
639
|
+
? t('collections.save.hookFailedToast')
|
|
640
|
+
: t('collections.edit.updateTitle', { label: singular }),
|
|
592
641
|
description,
|
|
593
642
|
data: {
|
|
594
|
-
intent: 'success',
|
|
595
|
-
iconType: 'success',
|
|
643
|
+
intent: hookFailed ? 'warning' : 'success',
|
|
644
|
+
iconType: hookFailed ? 'warning' : 'success',
|
|
596
645
|
icon: true,
|
|
597
646
|
close: true,
|
|
598
647
|
},
|
|
599
648
|
})
|
|
600
649
|
|
|
601
|
-
setEditState({ status: 'success', message: description })
|
|
650
|
+
setEditState({ status: hookFailed ? 'warning' : 'success', message: description })
|
|
602
651
|
|
|
603
652
|
// Re-navigate to the same route so the loader re-fetches the document.
|
|
604
|
-
// The new version will have a fresh version ID,
|
|
605
|
-
// updated publishedVersion metadata.
|
|
653
|
+
// The new version will have a fresh version ID, the collection's default
|
|
654
|
+
// workflow status, and updated publishedVersion metadata.
|
|
606
655
|
navigate({
|
|
607
656
|
to: getAdminRoutePath('collections', '$collection', '$id'),
|
|
608
657
|
params: { collection: path, id: String(initialData.id) },
|
|
609
658
|
search: (prev: Record<string, unknown>) => ({ ...prev }),
|
|
659
|
+
// Every write above has succeeded. FormRenderer clears its dirty
|
|
660
|
+
// baseline after this handler returns, so bypass the guard during the
|
|
661
|
+
// intentional post-save refresh rather than racing that state update.
|
|
662
|
+
ignoreBlocker: true,
|
|
610
663
|
})
|
|
611
664
|
} catch (err) {
|
|
612
665
|
console.error('Network error:', err)
|
|
@@ -19,9 +19,10 @@
|
|
|
19
19
|
import { useState } from 'react'
|
|
20
20
|
|
|
21
21
|
import { useTranslation } from '@byline/i18n/react'
|
|
22
|
-
import { Alert, Button, LoaderEllipsis, Modal } from '@byline/ui/react'
|
|
22
|
+
import { Alert, Button, LoaderEllipsis, Modal, useToastManager } from '@byline/ui/react'
|
|
23
23
|
import cx from 'clsx'
|
|
24
24
|
|
|
25
|
+
import { hasCommittedDocumentHookFailure } from '../../server-fns/collections/save-outcome.js'
|
|
25
26
|
import styles from './restore-version-modal.module.css'
|
|
26
27
|
|
|
27
28
|
interface RestoreVersionModalProps {
|
|
@@ -42,6 +43,7 @@ export function RestoreVersionModal({
|
|
|
42
43
|
onRestoreComplete,
|
|
43
44
|
}: RestoreVersionModalProps) {
|
|
44
45
|
const { t } = useTranslation('byline-admin')
|
|
46
|
+
const toastManager = useToastManager()
|
|
45
47
|
const [error, setError] = useState<string | null>(null)
|
|
46
48
|
const [pending, setPending] = useState(false)
|
|
47
49
|
|
|
@@ -50,7 +52,14 @@ export function RestoreVersionModal({
|
|
|
50
52
|
setPending(true)
|
|
51
53
|
setError(null)
|
|
52
54
|
try {
|
|
53
|
-
await restoreVersion()
|
|
55
|
+
const result = await restoreVersion()
|
|
56
|
+
if (hasCommittedDocumentHookFailure(result)) {
|
|
57
|
+
toastManager.add({
|
|
58
|
+
title: t('collections.save.hookFailedToast'),
|
|
59
|
+
description: t('collections.save.hookFailedDescription'),
|
|
60
|
+
data: { intent: 'warning', iconType: 'warning', icon: true, close: true },
|
|
61
|
+
})
|
|
62
|
+
}
|
|
54
63
|
onClose()
|
|
55
64
|
await onRestoreComplete()
|
|
56
65
|
} catch (err) {
|