@byline/admin 3.12.1 → 3.13.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/fields/field-services-types.d.ts +50 -0
- package/dist/forms/form-context.js +30 -60
- package/dist/forms/form-modals.d.ts +30 -0
- package/dist/forms/form-modals.js +189 -0
- package/dist/forms/form-renderer.d.ts +8 -1
- package/dist/forms/form-renderer.js +31 -365
- package/dist/forms/form-status-display.d.ts +21 -0
- package/dist/forms/form-status-display.js +94 -0
- package/dist/forms/status-transitions.d.ts +23 -0
- package/dist/forms/status-transitions.js +37 -0
- package/dist/forms/status-transitions.test.node.d.ts +8 -0
- package/dist/forms/tree-placement-widget.d.ts +23 -0
- package/dist/forms/tree-placement-widget.js +176 -0
- package/dist/forms/tree-placement-widget.module.js +15 -0
- package/dist/forms/tree-placement-widget_module.css +69 -0
- package/dist/forms/use-form-layout.d.ts +35 -0
- package/dist/forms/use-form-layout.js +77 -0
- package/dist/forms/use-form-layout.test.node.d.ts +8 -0
- package/dist/forms/use-tracked-slot.d.ts +45 -0
- package/dist/forms/use-tracked-slot.js +46 -0
- package/dist/react.d.ts +1 -1
- package/package.json +5 -5
- package/src/fields/field-services-types.ts +50 -0
- package/src/forms/form-context.tsx +36 -92
- package/src/forms/form-modals.tsx +186 -0
- package/src/forms/form-renderer.tsx +42 -387
- package/src/forms/form-status-display.tsx +108 -0
- package/src/forms/status-transitions.test.node.ts +87 -0
- package/src/forms/status-transitions.ts +86 -0
- package/src/forms/tree-placement-widget.module.css +87 -0
- package/src/forms/tree-placement-widget.tsx +202 -0
- package/src/forms/use-form-layout.test.node.ts +82 -0
- package/src/forms/use-form-layout.ts +134 -0
- package/src/forms/use-tracked-slot.ts +101 -0
- package/src/react.ts +6 -0
|
@@ -57,7 +57,57 @@ export interface UploadedFileResult {
|
|
|
57
57
|
storedFile: StoredFileValue;
|
|
58
58
|
}
|
|
59
59
|
export type UploadFieldFn = (collection: string, formData: FormData, createDocument?: boolean) => Promise<UploadedFileResult>;
|
|
60
|
+
/** One hydrated ancestor in a document's breadcrumb trail (root-first). */
|
|
61
|
+
export interface TreeAncestor {
|
|
62
|
+
id: string;
|
|
63
|
+
title: string;
|
|
64
|
+
path?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface PlaceTreeNodeInput {
|
|
67
|
+
collection: string;
|
|
68
|
+
documentId: string;
|
|
69
|
+
/** The new parent; `null` makes the document a root node. */
|
|
70
|
+
parentDocumentId: string | null;
|
|
71
|
+
/** Optional sibling neighbours (left = land after, right = land before). */
|
|
72
|
+
beforeDocumentId?: string | null;
|
|
73
|
+
afterDocumentId?: string | null;
|
|
74
|
+
}
|
|
75
|
+
/** Place / move a document within its collection's tree. */
|
|
76
|
+
export type PlaceTreeNodeFn = (input: PlaceTreeNodeInput) => Promise<{
|
|
77
|
+
orderKey: string;
|
|
78
|
+
}>;
|
|
79
|
+
/** Remove a document from the tree (back to the unplaced state). */
|
|
80
|
+
export type RemoveFromTreeFn = (input: {
|
|
81
|
+
collection: string;
|
|
82
|
+
documentId: string;
|
|
83
|
+
}) => Promise<void>;
|
|
84
|
+
/** Resolve a document's ancestor chain, root-first, hydrated with titles. */
|
|
85
|
+
export type GetTreeAncestorsFn = (input: {
|
|
86
|
+
collection: string;
|
|
87
|
+
documentId: string;
|
|
88
|
+
}) => Promise<TreeAncestor[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Resolve a document's placement state — the tri-state (unplaced / root / child)
|
|
91
|
+
* that `getTreeAncestors` cannot express (it returns `[]` for both root and
|
|
92
|
+
* unplaced). `placed: false` = unplaced; `placed: true` + null parent = root.
|
|
93
|
+
*/
|
|
94
|
+
export type GetTreeParentFn = (input: {
|
|
95
|
+
collection: string;
|
|
96
|
+
documentId: string;
|
|
97
|
+
}) => Promise<{
|
|
98
|
+
placed: boolean;
|
|
99
|
+
parentDocumentId: string | null;
|
|
100
|
+
}>;
|
|
60
101
|
export interface BylineFieldServices {
|
|
61
102
|
getCollectionDocuments: GetCollectionDocumentsFn;
|
|
62
103
|
uploadField: UploadFieldFn;
|
|
104
|
+
/**
|
|
105
|
+
* Document-tree operations, consumed by the sidebar tree-placement widget.
|
|
106
|
+
* Optional — only hosts that serve `tree: true` collections need to wire
|
|
107
|
+
* them; the widget guards on their presence.
|
|
108
|
+
*/
|
|
109
|
+
placeTreeNode?: PlaceTreeNodeFn;
|
|
110
|
+
removeFromTree?: RemoveFromTreeFn;
|
|
111
|
+
getTreeAncestors?: GetTreeAncestorsFn;
|
|
112
|
+
getTreeParent?: GetTreeParentFn;
|
|
63
113
|
}
|
|
@@ -3,6 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { normalizeHooks } from "@byline/core";
|
|
5
5
|
import { get, set as external_nested_path_js_set } from "./nested-path.js";
|
|
6
|
+
import { useTrackedSlot } from "./use-tracked-slot.js";
|
|
6
7
|
const sameLocaleSet = (a, b)=>{
|
|
7
8
|
if (a.length !== b.length) return false;
|
|
8
9
|
const sa = [
|
|
@@ -33,16 +34,6 @@ const FormProvider = ({ children, initialData = {} })=>{
|
|
|
33
34
|
const fieldListeners = useRef(new Map());
|
|
34
35
|
const errorListeners = useRef(new Set());
|
|
35
36
|
const metaListeners = useRef(new Set());
|
|
36
|
-
const systemPathRef = useRef('string' == typeof initialData?.path && initialData.path.length > 0 ? initialData.path : null);
|
|
37
|
-
const initialSystemPath = useRef(systemPathRef.current);
|
|
38
|
-
const systemPathListeners = useRef(new Set());
|
|
39
|
-
const systemAvailableLocalesRef = useRef(Array.isArray(initialData?.availableLocales) ? [
|
|
40
|
-
...initialData.availableLocales
|
|
41
|
-
] : []);
|
|
42
|
-
const initialSystemAvailableLocales = useRef([
|
|
43
|
-
...systemAvailableLocalesRef.current
|
|
44
|
-
]);
|
|
45
|
-
const systemAvailableLocalesListeners = useRef(new Set());
|
|
46
37
|
const subscribeField = useCallback((name, listener)=>{
|
|
47
38
|
if (!fieldListeners.current.has(name)) fieldListeners.current.set(name, new Set());
|
|
48
39
|
fieldListeners.current.get(name)?.add(listener);
|
|
@@ -82,6 +73,24 @@ const FormProvider = ({ children, initialData = {} })=>{
|
|
|
82
73
|
listener();
|
|
83
74
|
});
|
|
84
75
|
}, []);
|
|
76
|
+
const pathSlot = useTrackedSlot({
|
|
77
|
+
initial: 'string' == typeof initialData?.path && initialData.path.length > 0 ? initialData.path : null,
|
|
78
|
+
dirtyKey: SYSTEM_PATH_DIRTY_KEY,
|
|
79
|
+
dirtyFields,
|
|
80
|
+
notifyMeta: notifyMetaListeners
|
|
81
|
+
});
|
|
82
|
+
const availableLocalesSlot = useTrackedSlot({
|
|
83
|
+
initial: Array.isArray(initialData?.availableLocales) ? [
|
|
84
|
+
...initialData.availableLocales
|
|
85
|
+
] : [],
|
|
86
|
+
dirtyKey: SYSTEM_AVAILABLE_LOCALES_DIRTY_KEY,
|
|
87
|
+
dirtyFields,
|
|
88
|
+
notifyMeta: notifyMetaListeners,
|
|
89
|
+
isEqual: sameLocaleSet,
|
|
90
|
+
clone: (value)=>[
|
|
91
|
+
...value
|
|
92
|
+
]
|
|
93
|
+
});
|
|
85
94
|
const updateFieldStoreInternal = useCallback((name, value)=>{
|
|
86
95
|
const newFieldValues = {
|
|
87
96
|
...fieldValues.current
|
|
@@ -152,13 +161,13 @@ const FormProvider = ({ children, initialData = {} })=>{
|
|
|
152
161
|
const resetHasChanges = useCallback(()=>{
|
|
153
162
|
dirtyFields.current.clear();
|
|
154
163
|
patchesRef.current = [];
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
...systemAvailableLocalesRef.current
|
|
158
|
-
];
|
|
164
|
+
pathSlot.commitInitial();
|
|
165
|
+
availableLocalesSlot.commitInitial();
|
|
159
166
|
notifyMetaListeners();
|
|
160
167
|
}, [
|
|
161
|
-
notifyMetaListeners
|
|
168
|
+
notifyMetaListeners,
|
|
169
|
+
pathSlot.commitInitial,
|
|
170
|
+
availableLocalesSlot.commitInitial
|
|
162
171
|
]);
|
|
163
172
|
const isDirty = useCallback((fieldName)=>dirtyFields.current.has(fieldName), []);
|
|
164
173
|
const getDirtyBreakdown = useCallback(()=>{
|
|
@@ -179,45 +188,6 @@ const FormProvider = ({ children, initialData = {} })=>{
|
|
|
179
188
|
availableLocalesDirty
|
|
180
189
|
};
|
|
181
190
|
}, []);
|
|
182
|
-
const getSystemPath = useCallback(()=>systemPathRef.current, []);
|
|
183
|
-
const setSystemPath = useCallback((value)=>{
|
|
184
|
-
systemPathRef.current = value;
|
|
185
|
-
if (value !== initialSystemPath.current) dirtyFields.current.add(SYSTEM_PATH_DIRTY_KEY);
|
|
186
|
-
else dirtyFields.current.delete(SYSTEM_PATH_DIRTY_KEY);
|
|
187
|
-
systemPathListeners.current.forEach((listener)=>{
|
|
188
|
-
listener(value);
|
|
189
|
-
});
|
|
190
|
-
notifyMetaListeners();
|
|
191
|
-
}, [
|
|
192
|
-
notifyMetaListeners
|
|
193
|
-
]);
|
|
194
|
-
const subscribeSystemPath = useCallback((listener)=>{
|
|
195
|
-
systemPathListeners.current.add(listener);
|
|
196
|
-
return ()=>{
|
|
197
|
-
systemPathListeners.current.delete(listener);
|
|
198
|
-
};
|
|
199
|
-
}, []);
|
|
200
|
-
const getSystemAvailableLocales = useCallback(()=>systemAvailableLocalesRef.current, []);
|
|
201
|
-
const setSystemAvailableLocales = useCallback((value)=>{
|
|
202
|
-
const next = [
|
|
203
|
-
...value
|
|
204
|
-
];
|
|
205
|
-
systemAvailableLocalesRef.current = next;
|
|
206
|
-
if (sameLocaleSet(next, initialSystemAvailableLocales.current)) dirtyFields.current.delete(SYSTEM_AVAILABLE_LOCALES_DIRTY_KEY);
|
|
207
|
-
else dirtyFields.current.add(SYSTEM_AVAILABLE_LOCALES_DIRTY_KEY);
|
|
208
|
-
systemAvailableLocalesListeners.current.forEach((listener)=>{
|
|
209
|
-
listener(next);
|
|
210
|
-
});
|
|
211
|
-
notifyMetaListeners();
|
|
212
|
-
}, [
|
|
213
|
-
notifyMetaListeners
|
|
214
|
-
]);
|
|
215
|
-
const subscribeSystemAvailableLocales = useCallback((listener)=>{
|
|
216
|
-
systemAvailableLocalesListeners.current.add(listener);
|
|
217
|
-
return ()=>{
|
|
218
|
-
systemAvailableLocalesListeners.current.delete(listener);
|
|
219
|
-
};
|
|
220
|
-
}, []);
|
|
221
191
|
const addPendingUpload = useCallback((fieldPath, upload)=>{
|
|
222
192
|
const existing = pendingUploadsRef.current.get(fieldPath);
|
|
223
193
|
if (existing) URL.revokeObjectURL(existing.previewUrl);
|
|
@@ -438,12 +408,12 @@ const FormProvider = ({ children, initialData = {} })=>{
|
|
|
438
408
|
setFieldUploading,
|
|
439
409
|
getIsFieldUploading,
|
|
440
410
|
subscribeFieldUploading,
|
|
441
|
-
getSystemPath,
|
|
442
|
-
setSystemPath,
|
|
443
|
-
subscribeSystemPath,
|
|
444
|
-
getSystemAvailableLocales,
|
|
445
|
-
setSystemAvailableLocales,
|
|
446
|
-
subscribeSystemAvailableLocales
|
|
411
|
+
getSystemPath: pathSlot.get,
|
|
412
|
+
setSystemPath: pathSlot.set,
|
|
413
|
+
subscribeSystemPath: pathSlot.subscribe,
|
|
414
|
+
getSystemAvailableLocales: availableLocalesSlot.get,
|
|
415
|
+
setSystemAvailableLocales: availableLocalesSlot.set,
|
|
416
|
+
subscribeSystemAvailableLocales: availableLocalesSlot.subscribe
|
|
447
417
|
},
|
|
448
418
|
children: children
|
|
449
419
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shown when the editor triggers a guarded action (status change, duplicate,
|
|
3
|
+
* copy-to-locale) while the form is dirty. Those actions operate on the saved
|
|
4
|
+
* version, so the editor must save first.
|
|
5
|
+
*/
|
|
6
|
+
export declare const UnsavedChangesModal: ({ onClose }: {
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
}) => import("react").JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Confirms an immediate, non-versioned write of the document-grain system
|
|
11
|
+
* fields (path / advertised locales) — which does NOT reset workflow status.
|
|
12
|
+
* When content is also dirty, the copy reassures that content edits still
|
|
13
|
+
* follow the normal revision + publish workflow. See docs/I18N.md.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SystemFieldsConfirmModal: ({ contentDirty, pathDirty, availableLocalesDirty, onCancel, onConfirm, }: {
|
|
16
|
+
contentDirty: boolean;
|
|
17
|
+
pathDirty: boolean;
|
|
18
|
+
availableLocalesDirty: boolean;
|
|
19
|
+
onCancel: () => void;
|
|
20
|
+
onConfirm: () => void;
|
|
21
|
+
}) => import("react").JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* Blocks router navigation / browser unload while the form is dirty. Driven by
|
|
24
|
+
* the navigation-guard adapter's `isBlocked` state; `onStay` keeps the editor
|
|
25
|
+
* on the page, `onProceed` discards and continues.
|
|
26
|
+
*/
|
|
27
|
+
export declare const NavigationGuardModal: ({ onStay, onProceed, }: {
|
|
28
|
+
onStay: () => void;
|
|
29
|
+
onProceed: () => void;
|
|
30
|
+
}) => import("react").JSX.Element;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
4
|
+
import { Button, CloseIcon, IconButton, Modal } from "@byline/ui/react";
|
|
5
|
+
import classnames from "classnames";
|
|
6
|
+
import form_renderer_module from "./form-renderer.module.js";
|
|
7
|
+
const UnsavedChangesModal = ({ onClose })=>{
|
|
8
|
+
const { t } = useTranslation('byline-admin');
|
|
9
|
+
return /*#__PURE__*/ jsx(Modal, {
|
|
10
|
+
isOpen: true,
|
|
11
|
+
closeOnOverlayClick: true,
|
|
12
|
+
onDismiss: onClose,
|
|
13
|
+
children: /*#__PURE__*/ jsxs(Modal.Container, {
|
|
14
|
+
style: {
|
|
15
|
+
maxWidth: '460px'
|
|
16
|
+
},
|
|
17
|
+
children: [
|
|
18
|
+
/*#__PURE__*/ jsx(Modal.Header, {
|
|
19
|
+
className: classnames('byline-form-guard-modal-head', form_renderer_module["guard-modal-head"]),
|
|
20
|
+
children: /*#__PURE__*/ jsx("h3", {
|
|
21
|
+
className: classnames('byline-form-guard-modal-title', form_renderer_module["guard-modal-title"]),
|
|
22
|
+
children: t('forms.unsavedChanges.title')
|
|
23
|
+
})
|
|
24
|
+
}),
|
|
25
|
+
/*#__PURE__*/ jsx(Modal.Content, {
|
|
26
|
+
children: /*#__PURE__*/ jsx("p", {
|
|
27
|
+
className: classnames('byline-form-guard-modal-text', form_renderer_module["guard-modal-text"]),
|
|
28
|
+
children: t('forms.unsavedChanges.message')
|
|
29
|
+
})
|
|
30
|
+
}),
|
|
31
|
+
/*#__PURE__*/ jsx(Modal.Actions, {
|
|
32
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
33
|
+
size: "sm",
|
|
34
|
+
style: {
|
|
35
|
+
minWidth: '60px'
|
|
36
|
+
},
|
|
37
|
+
intent: "primary",
|
|
38
|
+
type: "button",
|
|
39
|
+
onClick: onClose,
|
|
40
|
+
children: t('forms.unsavedChanges.okButton')
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
]
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
const SystemFieldsConfirmModal = ({ contentDirty, pathDirty, availableLocalesDirty, onCancel, onConfirm })=>{
|
|
48
|
+
const { t } = useTranslation('byline-admin');
|
|
49
|
+
return /*#__PURE__*/ jsx(Modal, {
|
|
50
|
+
isOpen: true,
|
|
51
|
+
closeOnOverlayClick: true,
|
|
52
|
+
onDismiss: onCancel,
|
|
53
|
+
children: /*#__PURE__*/ jsxs(Modal.Container, {
|
|
54
|
+
style: {
|
|
55
|
+
maxWidth: '520px'
|
|
56
|
+
},
|
|
57
|
+
children: [
|
|
58
|
+
/*#__PURE__*/ jsxs(Modal.Header, {
|
|
59
|
+
className: classnames('byline-form-guard-modal-head', form_renderer_module["guard-modal-head"]),
|
|
60
|
+
children: [
|
|
61
|
+
/*#__PURE__*/ jsx("h3", {
|
|
62
|
+
className: classnames('byline-form-guard-modal-title', form_renderer_module["guard-modal-title"]),
|
|
63
|
+
children: contentDirty ? t('forms.systemFieldsConfirm.bothTitle') : t('forms.systemFieldsConfirm.title')
|
|
64
|
+
}),
|
|
65
|
+
/*#__PURE__*/ jsx(IconButton, {
|
|
66
|
+
"aria-label": t('common.actions.close'),
|
|
67
|
+
size: "xs",
|
|
68
|
+
onClick: onCancel,
|
|
69
|
+
children: /*#__PURE__*/ jsx(CloseIcon, {
|
|
70
|
+
width: "16px",
|
|
71
|
+
height: "16px",
|
|
72
|
+
svgClassName: "white-icon"
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
}),
|
|
77
|
+
/*#__PURE__*/ jsxs(Modal.Content, {
|
|
78
|
+
className: "prose",
|
|
79
|
+
children: [
|
|
80
|
+
contentDirty && /*#__PURE__*/ jsx("p", {
|
|
81
|
+
className: classnames('byline-form-system-fields-content-note', 'm-0 mt-2'),
|
|
82
|
+
children: t('forms.systemFieldsConfirm.contentNote')
|
|
83
|
+
}),
|
|
84
|
+
/*#__PURE__*/ jsx("p", {
|
|
85
|
+
className: "m-0 mt-2",
|
|
86
|
+
style: contentDirty ? {
|
|
87
|
+
marginTop: 'var(--spacing-8)',
|
|
88
|
+
paddingTop: 'var(--spacing-12)',
|
|
89
|
+
borderTop: '1px solid var(--border-color)'
|
|
90
|
+
} : void 0,
|
|
91
|
+
children: t('forms.systemFieldsConfirm.intro')
|
|
92
|
+
}),
|
|
93
|
+
/*#__PURE__*/ jsxs("ul", {
|
|
94
|
+
className: classnames('byline-form-system-fields-list', form_renderer_module["guard-modal-text"], 'm-0'),
|
|
95
|
+
children: [
|
|
96
|
+
pathDirty && /*#__PURE__*/ jsx("li", {
|
|
97
|
+
children: t('forms.systemFieldsConfirm.bulletPath')
|
|
98
|
+
}),
|
|
99
|
+
availableLocalesDirty && /*#__PURE__*/ jsx("li", {
|
|
100
|
+
children: t('forms.systemFieldsConfirm.bulletLocales')
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
}),
|
|
104
|
+
/*#__PURE__*/ jsx("p", {
|
|
105
|
+
className: classnames('byline-form-system-fields-effect', form_renderer_module["guard-modal-text"]),
|
|
106
|
+
style: {
|
|
107
|
+
marginTop: 'var(--spacing-4)',
|
|
108
|
+
marginBottom: 0,
|
|
109
|
+
color: 'var(--text-subtle)'
|
|
110
|
+
},
|
|
111
|
+
children: t('forms.systemFieldsConfirm.effectLine')
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
}),
|
|
115
|
+
/*#__PURE__*/ jsxs(Modal.Actions, {
|
|
116
|
+
children: [
|
|
117
|
+
/*#__PURE__*/ jsx(Button, {
|
|
118
|
+
size: "sm",
|
|
119
|
+
style: {
|
|
120
|
+
minWidth: '80px'
|
|
121
|
+
},
|
|
122
|
+
intent: "noeffect",
|
|
123
|
+
type: "button",
|
|
124
|
+
onClick: onCancel,
|
|
125
|
+
children: t('common.actions.cancel')
|
|
126
|
+
}),
|
|
127
|
+
/*#__PURE__*/ jsx(Button, {
|
|
128
|
+
size: "sm",
|
|
129
|
+
style: {
|
|
130
|
+
minWidth: '80px'
|
|
131
|
+
},
|
|
132
|
+
intent: "primary",
|
|
133
|
+
type: "button",
|
|
134
|
+
onClick: onConfirm,
|
|
135
|
+
children: t('forms.systemFieldsConfirm.confirmButton')
|
|
136
|
+
})
|
|
137
|
+
]
|
|
138
|
+
})
|
|
139
|
+
]
|
|
140
|
+
})
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
const NavigationGuardModal = ({ onStay, onProceed })=>{
|
|
144
|
+
const { t } = useTranslation('byline-admin');
|
|
145
|
+
return /*#__PURE__*/ jsx(Modal, {
|
|
146
|
+
isOpen: true,
|
|
147
|
+
closeOnOverlayClick: false,
|
|
148
|
+
onDismiss: onStay,
|
|
149
|
+
children: /*#__PURE__*/ jsxs(Modal.Container, {
|
|
150
|
+
style: {
|
|
151
|
+
maxWidth: '460px'
|
|
152
|
+
},
|
|
153
|
+
children: [
|
|
154
|
+
/*#__PURE__*/ jsx(Modal.Header, {
|
|
155
|
+
className: classnames('byline-form-guard-modal-head', form_renderer_module["guard-modal-head"]),
|
|
156
|
+
children: /*#__PURE__*/ jsx("h3", {
|
|
157
|
+
className: classnames('byline-form-guard-modal-title', form_renderer_module["guard-modal-title"]),
|
|
158
|
+
children: t('forms.navigationGuard.title')
|
|
159
|
+
})
|
|
160
|
+
}),
|
|
161
|
+
/*#__PURE__*/ jsx(Modal.Content, {
|
|
162
|
+
children: /*#__PURE__*/ jsx("p", {
|
|
163
|
+
className: classnames('byline-form-guard-modal-text', form_renderer_module["guard-modal-text"]),
|
|
164
|
+
children: t('forms.navigationGuard.message')
|
|
165
|
+
})
|
|
166
|
+
}),
|
|
167
|
+
/*#__PURE__*/ jsxs(Modal.Actions, {
|
|
168
|
+
children: [
|
|
169
|
+
/*#__PURE__*/ jsx(Button, {
|
|
170
|
+
size: "sm",
|
|
171
|
+
intent: "noeffect",
|
|
172
|
+
type: "button",
|
|
173
|
+
onClick: onStay,
|
|
174
|
+
children: t('forms.navigationGuard.stayButton')
|
|
175
|
+
}),
|
|
176
|
+
/*#__PURE__*/ jsx(Button, {
|
|
177
|
+
size: "sm",
|
|
178
|
+
intent: "danger",
|
|
179
|
+
type: "button",
|
|
180
|
+
onClick: onProceed,
|
|
181
|
+
children: t('forms.navigationGuard.leaveButton')
|
|
182
|
+
})
|
|
183
|
+
]
|
|
184
|
+
})
|
|
185
|
+
]
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
export { NavigationGuardModal, SystemFieldsConfirmModal, UnsavedChangesModal };
|
|
@@ -100,6 +100,13 @@ export interface FormRendererProps {
|
|
|
100
100
|
* against the document's `_availableVersionLocales` ledger fact.
|
|
101
101
|
*/
|
|
102
102
|
advertiseLocales?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Opts the document-tree placement widget into the sidebar (above the
|
|
105
|
+
* available-locales widget). Sourced from `CollectionDefinition.tree` by the
|
|
106
|
+
* caller. Renders only in edit mode (placement needs a persisted document)
|
|
107
|
+
* and only when the host wires the tree services. See docs/DOCUMENT-TREE.md.
|
|
108
|
+
*/
|
|
109
|
+
tree?: boolean;
|
|
103
110
|
headingLabel?: string;
|
|
104
111
|
headerSlot?: ReactNode;
|
|
105
112
|
/** Collection path forwarded to upload-capable fields (e.g. `'media'`). */
|
|
@@ -129,4 +136,4 @@ export interface FormRendererProps {
|
|
|
129
136
|
*/
|
|
130
137
|
useNavigationGuard?: UseNavigationGuard;
|
|
131
138
|
}
|
|
132
|
-
export declare const FormRenderer: ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpublish, onDelete, onDuplicate, onCopyToLocale, onDeleteLocale, contentLocales, nextStatus, workflowStatuses, publishedVersion, initialData, adminConfig, useAsTitle, useAsPath, advertiseLocales, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale, useNavigationGuard, restoreWarnings, }: FormRendererProps) => import("react").JSX.Element;
|
|
139
|
+
export declare const FormRenderer: ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpublish, onDelete, onDuplicate, onCopyToLocale, onDeleteLocale, contentLocales, nextStatus, workflowStatuses, publishedVersion, initialData, adminConfig, useAsTitle, useAsPath, advertiseLocales, tree, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale, useNavigationGuard, restoreWarnings, }: FormRendererProps) => import("react").JSX.Element;
|