@byline/ui 2.5.2 → 2.6.1

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.
Files changed (218) hide show
  1. package/dist/components/shimmer/shimmer.d.ts +13 -1
  2. package/dist/components/shimmer/shimmer.js +29 -20
  3. package/dist/components/shimmer/shimmer_module.css +4 -4
  4. package/dist/dnd/draggable-sortable/demo/draggable-list-demo.js +1 -1
  5. package/dist/react.d.ts +18 -54
  6. package/dist/react.js +0 -35
  7. package/dist/styles/styles.css +3 -0
  8. package/dist/uikit.d.ts +1 -0
  9. package/dist/uikit.js +1 -0
  10. package/package.json +2 -8
  11. package/src/components/shimmer/shimmer.module.css +8 -4
  12. package/src/components/shimmer/shimmer.tsx +34 -9
  13. package/src/dnd/draggable-sortable/demo/draggable-list-demo.tsx +1 -1
  14. package/src/react.ts +20 -68
  15. package/src/styles/functional/surfaces.css +13 -1
  16. package/src/uikit.ts +1 -0
  17. package/dist/admin/group.d.ts +0 -27
  18. package/dist/admin/group.js +0 -14
  19. package/dist/admin/group.module.js +0 -6
  20. package/dist/admin/group_module.css +0 -19
  21. package/dist/admin/row.d.ts +0 -25
  22. package/dist/admin/row.js +0 -8
  23. package/dist/admin/row.module.js +0 -5
  24. package/dist/admin/row_module.css +0 -18
  25. package/dist/admin/tabs.d.ts +0 -25
  26. package/dist/admin/tabs.js +0 -35
  27. package/dist/admin/tabs.module.js +0 -10
  28. package/dist/admin/tabs_module.css +0 -68
  29. package/dist/fields/array/array-field.d.ts +0 -14
  30. package/dist/fields/array/array-field.js +0 -176
  31. package/dist/fields/array/array-field.module.js +0 -11
  32. package/dist/fields/array/array-field_module.css +0 -32
  33. package/dist/fields/blocks/blocks-field.d.ts +0 -13
  34. package/dist/fields/blocks/blocks-field.js +0 -244
  35. package/dist/fields/blocks/blocks-field.module.js +0 -26
  36. package/dist/fields/blocks/blocks-field_module.css +0 -107
  37. package/dist/fields/checkbox/checkbox-field.d.ts +0 -16
  38. package/dist/fields/checkbox/checkbox-field.js +0 -28
  39. package/dist/fields/checkbox/checkbox-field.module.js +0 -6
  40. package/dist/fields/checkbox/checkbox-field_module.css +0 -4
  41. package/dist/fields/column-formatter.d.ts +0 -20
  42. package/dist/fields/column-formatter.js +0 -15
  43. package/dist/fields/date-time-formatter.d.ts +0 -16
  44. package/dist/fields/date-time-formatter.js +0 -8
  45. package/dist/fields/datetime/datetime-field.d.ts +0 -16
  46. package/dist/fields/datetime/datetime-field.js +0 -37
  47. package/dist/fields/datetime/datetime-field.module.js +0 -5
  48. package/dist/fields/datetime/datetime-field_module.css +0 -4
  49. package/dist/fields/draggable-context-menu.d.ts +0 -6
  50. package/dist/fields/draggable-context-menu.js +0 -83
  51. package/dist/fields/draggable-context-menu.module.js +0 -15
  52. package/dist/fields/draggable-context-menu_module.css +0 -91
  53. package/dist/fields/field-helpers.d.ts +0 -26
  54. package/dist/fields/field-helpers.js +0 -50
  55. package/dist/fields/field-renderer.d.ts +0 -37
  56. package/dist/fields/field-renderer.js +0 -206
  57. package/dist/fields/field-renderer.module.js +0 -8
  58. package/dist/fields/field-renderer_module.css +0 -11
  59. package/dist/fields/file/file-field.d.ts +0 -19
  60. package/dist/fields/file/file-field.js +0 -226
  61. package/dist/fields/file/file-field.module.js +0 -18
  62. package/dist/fields/file/file-field_module.css +0 -131
  63. package/dist/fields/file/file-upload-field.d.ts +0 -21
  64. package/dist/fields/file/file-upload-field.js +0 -128
  65. package/dist/fields/file/file-upload-field.module.js +0 -15
  66. package/dist/fields/file/file-upload-field_module.css +0 -74
  67. package/dist/fields/group/group-field.d.ts +0 -15
  68. package/dist/fields/group/group-field.js +0 -59
  69. package/dist/fields/group/group-field.module.js +0 -9
  70. package/dist/fields/group/group-field_module.css +0 -27
  71. package/dist/fields/image/image-field.d.ts +0 -19
  72. package/dist/fields/image/image-field.js +0 -242
  73. package/dist/fields/image/image-field.module.js +0 -22
  74. package/dist/fields/image/image-field_module.css +0 -121
  75. package/dist/fields/image/image-upload-field.d.ts +0 -21
  76. package/dist/fields/image/image-upload-field.js +0 -187
  77. package/dist/fields/image/image-upload-field.module.js +0 -19
  78. package/dist/fields/image/image-upload-field_module.css +0 -92
  79. package/dist/fields/local-date-time.d.ts +0 -27
  80. package/dist/fields/local-date-time.js +0 -49
  81. package/dist/fields/locale-badge.d.ts +0 -18
  82. package/dist/fields/locale-badge.js +0 -10
  83. package/dist/fields/locale-badge.module.js +0 -5
  84. package/dist/fields/locale-badge_module.css +0 -27
  85. package/dist/fields/numerical/numerical-field.d.ts +0 -18
  86. package/dist/fields/numerical/numerical-field.js +0 -74
  87. package/dist/fields/relation/relation-display.d.ts +0 -40
  88. package/dist/fields/relation/relation-display.js +0 -58
  89. package/dist/fields/relation/relation-display.module.js +0 -9
  90. package/dist/fields/relation/relation-display_module.css +0 -21
  91. package/dist/fields/relation/relation-field.d.ts +0 -18
  92. package/dist/fields/relation/relation-field.js +0 -146
  93. package/dist/fields/relation/relation-field.module.js +0 -13
  94. package/dist/fields/relation/relation-field_module.css +0 -62
  95. package/dist/fields/relation/relation-picker.d.ts +0 -49
  96. package/dist/fields/relation/relation-picker.js +0 -233
  97. package/dist/fields/relation/relation-picker.module.js +0 -26
  98. package/dist/fields/relation/relation-picker_module.css +0 -124
  99. package/dist/fields/relation/relation-summary.d.ts +0 -31
  100. package/dist/fields/relation/relation-summary.js +0 -50
  101. package/dist/fields/relation/relation-summary.module.js +0 -11
  102. package/dist/fields/relation/relation-summary_module.css +0 -37
  103. package/dist/fields/select/select-field.d.ts +0 -16
  104. package/dist/fields/select/select-field.js +0 -50
  105. package/dist/fields/select/select-field.module.js +0 -5
  106. package/dist/fields/select/select-field_module.css +0 -4
  107. package/dist/fields/sortable-item.d.ts +0 -15
  108. package/dist/fields/sortable-item.js +0 -80
  109. package/dist/fields/sortable-item.module.js +0 -22
  110. package/dist/fields/sortable-item_module.css +0 -124
  111. package/dist/fields/text/text-field.d.ts +0 -20
  112. package/dist/fields/text/text-field.js +0 -104
  113. package/dist/fields/text/text-field.module.js +0 -6
  114. package/dist/fields/text/text-field_module.css +0 -5
  115. package/dist/fields/text-area/text-area-field.d.ts +0 -20
  116. package/dist/fields/text-area/text-area-field.js +0 -105
  117. package/dist/fields/text-area/text-area-field.module.js +0 -6
  118. package/dist/fields/text-area/text-area-field_module.css +0 -5
  119. package/dist/fields/use-field-change-handler.d.ts +0 -23
  120. package/dist/fields/use-field-change-handler.js +0 -52
  121. package/dist/forms/document-actions.d.ts +0 -48
  122. package/dist/forms/document-actions.js +0 -469
  123. package/dist/forms/document-actions.module.js +0 -34
  124. package/dist/forms/document-actions_module.css +0 -118
  125. package/dist/forms/form-context.d.ts +0 -89
  126. package/dist/forms/form-context.js +0 -466
  127. package/dist/forms/form-renderer.d.ts +0 -98
  128. package/dist/forms/form-renderer.js +0 -591
  129. package/dist/forms/form-renderer.module.js +0 -46
  130. package/dist/forms/form-renderer_module.css +0 -245
  131. package/dist/forms/navigation-guard.d.ts +0 -54
  132. package/dist/forms/navigation-guard.js +0 -22
  133. package/dist/forms/path-widget.d.ts +0 -36
  134. package/dist/forms/path-widget.js +0 -107
  135. package/dist/forms/path-widget.module.js +0 -8
  136. package/dist/forms/path-widget_module.css +0 -29
  137. package/dist/forms/upload-executor.d.ts +0 -57
  138. package/dist/forms/upload-executor.js +0 -92
  139. package/dist/services/field-services-context.d.ts +0 -16
  140. package/dist/services/field-services-context.js +0 -13
  141. package/dist/services/field-services-types.d.ts +0 -63
  142. package/dist/services/field-services-types.js +0 -1
  143. package/dist/widgets/diff-viewer/diff-modal.d.ts +0 -22
  144. package/dist/widgets/diff-viewer/diff-modal.js +0 -146
  145. package/dist/widgets/diff-viewer/diff-modal.module.js +0 -14
  146. package/dist/widgets/diff-viewer/diff-modal_module.css +0 -56
  147. package/dist/widgets/status-badge/status-badge.d.ts +0 -25
  148. package/dist/widgets/status-badge/status-badge.js +0 -35
  149. package/dist/widgets/status-badge/status-badge.module.js +0 -7
  150. package/dist/widgets/status-badge/status-badge_module.css +0 -20
  151. package/src/admin/group.module.css +0 -41
  152. package/src/admin/group.tsx +0 -40
  153. package/src/admin/row.module.css +0 -32
  154. package/src/admin/row.tsx +0 -33
  155. package/src/admin/tabs.module.css +0 -107
  156. package/src/admin/tabs.tsx +0 -82
  157. package/src/fields/array/array-field.module.css +0 -48
  158. package/src/fields/array/array-field.tsx +0 -266
  159. package/src/fields/blocks/blocks-field.module.css +0 -148
  160. package/src/fields/blocks/blocks-field.tsx +0 -312
  161. package/src/fields/checkbox/checkbox-field.module.css +0 -4
  162. package/src/fields/checkbox/checkbox-field.tsx +0 -54
  163. package/src/fields/column-formatter.tsx +0 -31
  164. package/src/fields/date-time-formatter.tsx +0 -22
  165. package/src/fields/datetime/datetime-field.module.css +0 -13
  166. package/src/fields/datetime/datetime-field.tsx +0 -54
  167. package/src/fields/draggable-context-menu.module.css +0 -127
  168. package/src/fields/draggable-context-menu.tsx +0 -85
  169. package/src/fields/field-helpers.ts +0 -69
  170. package/src/fields/field-renderer.module.css +0 -22
  171. package/src/fields/field-renderer.tsx +0 -288
  172. package/src/fields/file/file-field.module.css +0 -153
  173. package/src/fields/file/file-field.tsx +0 -271
  174. package/src/fields/file/file-upload-field.module.css +0 -101
  175. package/src/fields/file/file-upload-field.tsx +0 -183
  176. package/src/fields/group/group-field.module.css +0 -43
  177. package/src/fields/group/group-field.tsx +0 -84
  178. package/src/fields/image/image-field.module.css +0 -155
  179. package/src/fields/image/image-field.tsx +0 -291
  180. package/src/fields/image/image-upload-field.module.css +0 -123
  181. package/src/fields/image/image-upload-field.tsx +0 -270
  182. package/src/fields/local-date-time.tsx +0 -88
  183. package/src/fields/locale-badge.module.css +0 -37
  184. package/src/fields/locale-badge.tsx +0 -32
  185. package/src/fields/numerical/numerical-field.tsx +0 -114
  186. package/src/fields/relation/relation-display.module.css +0 -36
  187. package/src/fields/relation/relation-display.tsx +0 -130
  188. package/src/fields/relation/relation-field.module.css +0 -83
  189. package/src/fields/relation/relation-field.tsx +0 -206
  190. package/src/fields/relation/relation-picker.module.css +0 -168
  191. package/src/fields/relation/relation-picker.tsx +0 -325
  192. package/src/fields/relation/relation-summary.module.css +0 -55
  193. package/src/fields/relation/relation-summary.tsx +0 -123
  194. package/src/fields/select/select-field.module.css +0 -13
  195. package/src/fields/select/select-field.tsx +0 -61
  196. package/src/fields/sortable-item.module.css +0 -167
  197. package/src/fields/sortable-item.tsx +0 -101
  198. package/src/fields/text/text-field.module.css +0 -13
  199. package/src/fields/text/text-field.tsx +0 -146
  200. package/src/fields/text-area/text-area-field.module.css +0 -13
  201. package/src/fields/text-area/text-area-field.tsx +0 -147
  202. package/src/fields/use-field-change-handler.ts +0 -112
  203. package/src/forms/document-actions.module.css +0 -160
  204. package/src/forms/document-actions.tsx +0 -487
  205. package/src/forms/form-context.tsx +0 -704
  206. package/src/forms/form-renderer.module.css +0 -321
  207. package/src/forms/form-renderer.tsx +0 -888
  208. package/src/forms/navigation-guard.tsx +0 -98
  209. package/src/forms/path-widget.module.css +0 -41
  210. package/src/forms/path-widget.test.tsx +0 -217
  211. package/src/forms/path-widget.tsx +0 -181
  212. package/src/forms/upload-executor.ts +0 -190
  213. package/src/services/field-services-context.tsx +0 -35
  214. package/src/services/field-services-types.ts +0 -68
  215. package/src/widgets/diff-viewer/diff-modal.module.css +0 -79
  216. package/src/widgets/diff-viewer/diff-modal.tsx +0 -184
  217. package/src/widgets/status-badge/status-badge.module.css +0 -31
  218. package/src/widgets/status-badge/status-badge.tsx +0 -69
@@ -1,591 +0,0 @@
1
- "use client";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
- import classnames from "classnames";
5
- import { AdminGroup } from "../admin/group.js";
6
- import { AdminRow } from "../admin/row.js";
7
- import { AdminTabs } from "../admin/tabs.js";
8
- import { FieldRenderer } from "../fields/field-renderer.js";
9
- import { LocalDateTime } from "../fields/local-date-time.js";
10
- import { useBylineFieldServices } from "../services/field-services-context.js";
11
- import { Alert, Button, ComboButton, Modal } from "../uikit.js";
12
- import { DocumentActions } from "./document-actions.js";
13
- import { FormProvider, useFieldValue, useFormContext } from "./form-context.js";
14
- import form_renderer_module from "./form-renderer.module.js";
15
- import { useNavigationGuardAdapter } from "./navigation-guard.js";
16
- import { PathWidget } from "./path-widget.js";
17
- import { executeUploadsWithProgress } from "./upload-executor.js";
18
- const FormStatusDisplay = ({ initialData, workflowStatuses, publishedVersion, onUnpublish })=>{
19
- const statusCode = initialData?.status;
20
- const statusLabel = workflowStatuses?.find((s)=>s.name === statusCode)?.label ?? statusCode;
21
- const showStatusCell = (workflowStatuses?.length ?? 0) > 1;
22
- return /*#__PURE__*/ jsxs("div", {
23
- className: classnames('byline-form-status', form_renderer_module.status),
24
- children: [
25
- /*#__PURE__*/ jsxs("div", {
26
- className: classnames('byline-form-status-meta', form_renderer_module["status-meta"]),
27
- children: [
28
- showStatusCell && /*#__PURE__*/ jsxs("div", {
29
- className: classnames('byline-form-status-cell', form_renderer_module["status-cell"]),
30
- children: [
31
- /*#__PURE__*/ jsx("span", {
32
- className: classnames('byline-form-status-muted', form_renderer_module["status-muted"]),
33
- children: "Status:"
34
- }),
35
- /*#__PURE__*/ jsx("span", {
36
- className: classnames('byline-form-status-trunc', form_renderer_module["status-trunc"]),
37
- children: statusLabel
38
- })
39
- ]
40
- }),
41
- initialData?.updatedAt != null && /*#__PURE__*/ jsxs("div", {
42
- className: classnames('byline-form-status-cell', form_renderer_module["status-cell"]),
43
- children: [
44
- /*#__PURE__*/ jsx("span", {
45
- className: classnames('byline-form-status-muted', form_renderer_module["status-muted"]),
46
- children: "Last modified:"
47
- }),
48
- /*#__PURE__*/ jsx("span", {
49
- className: classnames('byline-form-status-trunc', form_renderer_module["status-trunc"]),
50
- children: /*#__PURE__*/ jsx(LocalDateTime, {
51
- value: initialData.updatedAt
52
- })
53
- })
54
- ]
55
- }),
56
- initialData?.createdAt != null && /*#__PURE__*/ jsxs("div", {
57
- className: classnames('byline-form-status-cell', form_renderer_module["status-cell"]),
58
- children: [
59
- /*#__PURE__*/ jsx("span", {
60
- className: classnames('byline-form-status-muted', form_renderer_module["status-muted"]),
61
- children: "Created:"
62
- }),
63
- /*#__PURE__*/ jsx("span", {
64
- className: classnames('byline-form-status-trunc', form_renderer_module["status-trunc"]),
65
- children: /*#__PURE__*/ jsx(LocalDateTime, {
66
- value: initialData.createdAt
67
- })
68
- })
69
- ]
70
- })
71
- ]
72
- }),
73
- null != publishedVersion && /*#__PURE__*/ jsxs("div", {
74
- className: classnames('byline-form-status-published', form_renderer_module["status-published"]),
75
- children: [
76
- /*#__PURE__*/ jsxs("span", {
77
- className: classnames('byline-form-status-muted', form_renderer_module["status-muted"]),
78
- children: [
79
- "A published version is currently live.",
80
- ' ',
81
- publishedVersion.updatedAt ? /*#__PURE__*/ jsxs("span", {
82
- children: [
83
- "Published on ",
84
- /*#__PURE__*/ jsx(LocalDateTime, {
85
- value: publishedVersion.updatedAt
86
- })
87
- ]
88
- }) : ''
89
- ]
90
- }),
91
- onUnpublish && /*#__PURE__*/ jsxs(Fragment, {
92
- children: [
93
- ' ',
94
- /*#__PURE__*/ jsx("button", {
95
- type: "button",
96
- onClick: onUnpublish,
97
- className: classnames('byline-form-status-unpublish', form_renderer_module["status-unpublish"]),
98
- children: "Unpublish"
99
- })
100
- ]
101
- })
102
- ]
103
- })
104
- ]
105
- });
106
- };
107
- function computeStatusTransitions(currentStatus, workflowStatuses, nextStatus) {
108
- if (!workflowStatuses || 0 === workflowStatuses.length || !currentStatus) return {
109
- primaryStatus: nextStatus,
110
- secondaryStatuses: [],
111
- isTerminal: false
112
- };
113
- if (workflowStatuses.length <= 1) return {
114
- primaryStatus: void 0,
115
- secondaryStatuses: [],
116
- isTerminal: false
117
- };
118
- const currentIndex = workflowStatuses.findIndex((s)=>s.name === currentStatus);
119
- if (-1 === currentIndex) return {
120
- primaryStatus: nextStatus,
121
- secondaryStatuses: [],
122
- isTerminal: false
123
- };
124
- const isAtEnd = currentIndex === workflowStatuses.length - 1;
125
- const isAtStart = 0 === currentIndex;
126
- const availableTargets = [];
127
- if (!isAtStart && workflowStatuses[0]) availableTargets.push(workflowStatuses[0]);
128
- if (currentIndex > 1 && workflowStatuses[currentIndex - 1]) availableTargets.push(workflowStatuses[currentIndex - 1]);
129
- if (!isAtEnd && workflowStatuses[currentIndex + 1]) availableTargets.push(workflowStatuses[currentIndex + 1]);
130
- if (isAtEnd) return {
131
- primaryStatus: workflowStatuses[currentIndex],
132
- secondaryStatuses: availableTargets,
133
- isTerminal: true
134
- };
135
- return {
136
- primaryStatus: nextStatus,
137
- secondaryStatuses: availableTargets.filter((s)=>s.name !== nextStatus?.name),
138
- isTerminal: false
139
- };
140
- }
141
- const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpublish, onDelete, onDuplicate, onCopyToLocale, contentLocales, nextStatus, workflowStatuses, publishedVersion, initialData, adminConfig, useAsTitle, useAsPath, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale = 'en', useNavigationGuard: useNavigationGuardProp, restoreWarnings, _activeTabBySet, _onTabChange })=>{
142
- const { getFieldValues, runFieldHooks, validateForm, errors: initialErrors, hasChanges: hasChangesFn, resetHasChanges, getPatches, getSystemPath, subscribeErrors, subscribeMeta, setFieldValue, setFieldError, getPendingUploads, clearPendingUploads, setFieldUploading } = useFormContext();
143
- const [errors, setErrors] = useState(initialErrors);
144
- const [hasChanges, setHasChanges] = useState(hasChangesFn());
145
- const [statusBusy, setStatusBusy] = useState(false);
146
- const [isUploading, setIsUploading] = useState(false);
147
- const [contentLocale, setContentLocale] = useState(initialLocale ?? defaultLocale);
148
- const { uploadField } = useBylineFieldServices();
149
- useEffect(()=>{
150
- if (initialLocale) setContentLocale(initialLocale);
151
- }, [
152
- initialLocale
153
- ]);
154
- const fieldByName = useMemo(()=>{
155
- const map = new Map();
156
- for (const field of fields)if ('name' in field) map.set(field.name, field);
157
- return map;
158
- }, [
159
- fields
160
- ]);
161
- const tabSetByName = useMemo(()=>{
162
- const map = new Map();
163
- for (const set of adminConfig?.tabSets ?? [])map.set(set.name, set);
164
- return map;
165
- }, [
166
- adminConfig
167
- ]);
168
- const rowByName = useMemo(()=>{
169
- const map = new Map();
170
- for (const row of adminConfig?.rows ?? [])map.set(row.name, row);
171
- return map;
172
- }, [
173
- adminConfig
174
- ]);
175
- const groupByName = useMemo(()=>{
176
- const map = new Map();
177
- for (const group of adminConfig?.groups ?? [])map.set(group.name, group);
178
- return map;
179
- }, [
180
- adminConfig
181
- ]);
182
- const layout = useMemo(()=>{
183
- if (adminConfig?.layout) return adminConfig.layout;
184
- return {
185
- main: fields.filter((f)=>'name' in f).map((f)=>f.name)
186
- };
187
- }, [
188
- adminConfig,
189
- fields
190
- ]);
191
- const fieldToTabPath = useMemo(()=>{
192
- const map = new Map();
193
- const visit = (names, tabSetName, tabName, seen)=>{
194
- for (const name of names)if (fieldByName.has(name)) map.set(name, {
195
- tabSetName,
196
- tabName
197
- });
198
- else if (seen.has(name)) ;
199
- else if (rowByName.has(name)) {
200
- const row = rowByName.get(name);
201
- const next = new Set(seen).add(name);
202
- visit(row.fields, tabSetName, tabName, next);
203
- } else if (groupByName.has(name)) {
204
- const group = groupByName.get(name);
205
- const next = new Set(seen).add(name);
206
- visit(group.fields, tabSetName, tabName, next);
207
- }
208
- };
209
- for (const set of adminConfig?.tabSets ?? [])for (const tab of set.tabs)visit(tab.fields, set.name, tab.name, new Set());
210
- return map;
211
- }, [
212
- adminConfig,
213
- fieldByName,
214
- rowByName,
215
- groupByName
216
- ]);
217
- const tabSets = adminConfig?.tabSets ?? [];
218
- const initialActiveTabBySet = useMemo(()=>{
219
- const result = {};
220
- for (const set of tabSets){
221
- const saved = _activeTabBySet?.[set.name];
222
- if (saved && set.tabs.some((t)=>t.name === saved)) result[set.name] = saved;
223
- else result[set.name] = set.tabs[0]?.name ?? '';
224
- }
225
- return result;
226
- }, [
227
- tabSets,
228
- _activeTabBySet
229
- ]);
230
- const [activeTabBySet, setActiveTabBySet] = useState(initialActiveTabBySet);
231
- const handleTabChange = useCallback((tabSetName, tabName)=>{
232
- setActiveTabBySet((prev)=>({
233
- ...prev,
234
- [tabSetName]: tabName
235
- }));
236
- _onTabChange?.(tabSetName, tabName);
237
- }, [
238
- _onTabChange
239
- ]);
240
- const [formData, setFormData] = useState(()=>getFieldValues());
241
- const liveTitle = useFieldValue(useAsTitle ?? '');
242
- const heading = liveTitle || (headingLabel ? `${'create' === mode ? 'Create' : 'Edit'} ${headingLabel}` : 'create' === mode ? 'Create' : 'Edit');
243
- const guardFromContext = useNavigationGuardAdapter();
244
- const useGuard = useNavigationGuardProp ?? guardFromContext;
245
- const guard = useGuard(hasChanges);
246
- const currentStatus = initialData?.status;
247
- const { primaryStatus, secondaryStatuses, isTerminal } = computeStatusTransitions(currentStatus, workflowStatuses, nextStatus);
248
- useEffect(()=>subscribeErrors((newErrors)=>setErrors(newErrors)), [
249
- subscribeErrors
250
- ]);
251
- useEffect(()=>subscribeMeta(()=>setHasChanges(hasChangesFn())), [
252
- subscribeMeta,
253
- hasChangesFn
254
- ]);
255
- useEffect(()=>subscribeMeta(()=>setFormData(getFieldValues())), [
256
- subscribeMeta,
257
- getFieldValues
258
- ]);
259
- const handleCancel = ()=>{
260
- if (onCancel && 'function' == typeof onCancel) onCancel();
261
- };
262
- const handleSubmit = (e)=>{
263
- e.preventDefault();
264
- (async ()=>{
265
- const hookErrors = await runFieldHooks(fields);
266
- const formErrors = validateForm(fields);
267
- const allErrors = [
268
- ...hookErrors,
269
- ...formErrors
270
- ];
271
- if (allErrors.length > 0) return void console.error('Form validation failed:', allErrors);
272
- const pendingUploads = getPendingUploads();
273
- if (pendingUploads.size > 0) {
274
- setIsUploading(true);
275
- try {
276
- const uploadResult = await executeUploadsWithProgress(pendingUploads, uploadField, ({ fieldPath, status })=>{
277
- setFieldUploading(fieldPath, 'uploading' === status);
278
- });
279
- if (!uploadResult.allSucceeded) {
280
- for (const [fieldPath, errorMessage] of uploadResult.errors.entries())setFieldError(fieldPath, `Upload failed: ${errorMessage}`);
281
- console.error('One or more uploads failed:', uploadResult.errors);
282
- setIsUploading(false);
283
- return;
284
- }
285
- for (const [fieldPath, storedFile] of uploadResult.successful.entries())setFieldValue(fieldPath, storedFile);
286
- clearPendingUploads();
287
- } catch (err) {
288
- console.error('Upload execution error:', err);
289
- setIsUploading(false);
290
- return;
291
- }
292
- setIsUploading(false);
293
- }
294
- const data = getFieldValues();
295
- const patches = getPatches();
296
- const systemPath = getSystemPath();
297
- if (onSubmit && 'function' == typeof onSubmit) {
298
- onSubmit({
299
- data,
300
- patches,
301
- systemPath
302
- });
303
- resetHasChanges();
304
- }
305
- })();
306
- };
307
- const tabErrorCountsBySet = useMemo(()=>{
308
- const result = {};
309
- for (const err of errors){
310
- const path = fieldToTabPath.get(err.field);
311
- if (path) {
312
- result[path.tabSetName] ??= {};
313
- result[path.tabSetName][path.tabName] = (result[path.tabSetName]?.[path.tabName] ?? 0) + 1;
314
- }
315
- }
316
- return result;
317
- }, [
318
- errors,
319
- fieldToTabPath
320
- ]);
321
- const renderField = (fieldName)=>{
322
- const field = fieldByName.get(fieldName);
323
- if (!field) return null;
324
- return /*#__PURE__*/ jsx(FieldRenderer, {
325
- field: field,
326
- defaultValue: initialData?.fields?.[field.name],
327
- collectionPath: collectionPath,
328
- contentLocale: contentLocale,
329
- components: adminConfig?.fields?.[field.name]?.components,
330
- editor: adminConfig?.fields?.[field.name]?.editor
331
- }, field.name);
332
- };
333
- const renderItem = (name)=>{
334
- const tabSet = tabSetByName.get(name);
335
- if (tabSet) return renderTabSet(tabSet);
336
- const group = groupByName.get(name);
337
- if (group) return renderGroup(group);
338
- const row = rowByName.get(name);
339
- if (row) return renderRow(row);
340
- return renderField(name);
341
- };
342
- const renderRow = (row)=>/*#__PURE__*/ jsx(AdminRow, {
343
- children: row.fields.map((name)=>renderField(name))
344
- }, `row:${row.name}`);
345
- const renderGroup = (group)=>/*#__PURE__*/ jsx(AdminGroup, {
346
- label: group.label,
347
- children: group.fields.map((name)=>renderItem(name))
348
- }, `group:${group.name}`);
349
- const renderTabSet = (set)=>{
350
- const visibleTabs = set.tabs.filter((tab)=>!tab.condition || tab.condition(formData));
351
- const requested = activeTabBySet[set.name] ?? '';
352
- const resolvedActive = visibleTabs.length > 0 && !visibleTabs.some((t)=>t.name === requested) ? visibleTabs[0]?.name ?? requested : requested;
353
- const activeTab = visibleTabs.find((t)=>t.name === resolvedActive);
354
- return /*#__PURE__*/ jsxs("div", {
355
- className: classnames('byline-form-tabset', form_renderer_module.tabset),
356
- children: [
357
- visibleTabs.length > 0 && /*#__PURE__*/ jsx(AdminTabs, {
358
- tabs: visibleTabs,
359
- activeTab: resolvedActive,
360
- onChange: (tabName)=>handleTabChange(set.name, tabName),
361
- errorCounts: tabErrorCountsBySet[set.name],
362
- className: classnames('byline-form-tabset-tabs', form_renderer_module["tabset-tabs"])
363
- }),
364
- activeTab && /*#__PURE__*/ jsx("div", {
365
- className: classnames('byline-form-tabset-fields', form_renderer_module["tabset-fields"]),
366
- children: activeTab.fields.map((name)=>renderItem(name))
367
- })
368
- ]
369
- }, `tabset:${set.name}`);
370
- };
371
- return /*#__PURE__*/ jsxs("form", {
372
- noValidate: true,
373
- onSubmit: handleSubmit,
374
- className: classnames('byline-form', form_renderer_module.form),
375
- children: [
376
- /*#__PURE__*/ jsxs("div", {
377
- className: classnames('byline-form-heading-row', form_renderer_module["heading-row"]),
378
- children: [
379
- /*#__PURE__*/ jsx("h1", {
380
- className: classnames('byline-form-heading', form_renderer_module.heading),
381
- children: heading
382
- }),
383
- headerSlot
384
- ]
385
- }),
386
- /*#__PURE__*/ jsxs("div", {
387
- className: classnames('byline-form-status-bar', form_renderer_module["status-bar"]),
388
- children: [
389
- /*#__PURE__*/ jsx(FormStatusDisplay, {
390
- initialData: initialData,
391
- workflowStatuses: workflowStatuses,
392
- publishedVersion: publishedVersion,
393
- onUnpublish: onUnpublish
394
- }),
395
- /*#__PURE__*/ jsxs("div", {
396
- className: classnames('byline-form-actions', form_renderer_module.actions),
397
- children: [
398
- /*#__PURE__*/ jsx(Button, {
399
- className: classnames('byline-form-actions-button', form_renderer_module["actions-button"]),
400
- size: "sm",
401
- intent: "noeffect",
402
- type: "button",
403
- onClick: handleCancel,
404
- children: false === hasChanges ? 'Close' : 'Cancel'
405
- }),
406
- /*#__PURE__*/ jsx(Button, {
407
- className: classnames('byline-form-actions-button', form_renderer_module["actions-button"]),
408
- size: "sm",
409
- type: "submit",
410
- disabled: false === hasChanges || isUploading,
411
- children: isUploading ? 'Uploading…' : 'Save'
412
- }),
413
- primaryStatus && onStatusChange && /*#__PURE__*/ jsx("div", {
414
- className: classnames('byline-form-actions-status-wrap', form_renderer_module["actions-status-wrap"]),
415
- children: /*#__PURE__*/ jsx(ComboButton, {
416
- buttonClassName: classnames('byline-form-actions-combo-button', form_renderer_module["actions-combo-button"]),
417
- triggerClassName: classnames('byline-form-actions-combo-trigger', form_renderer_module["actions-combo-trigger"]),
418
- options: secondaryStatuses.map((s)=>({
419
- label: isTerminal ? `Revert to ${s.label ?? s.name}` : s.verb ?? s.label ?? s.name,
420
- value: s.name
421
- })),
422
- sideOffset: 5,
423
- size: "sm",
424
- type: "button",
425
- intent: isTerminal ? 'info' : 'success',
426
- disabled: statusBusy,
427
- onOptionSelect: async (value)=>{
428
- setStatusBusy(true);
429
- try {
430
- await onStatusChange(value);
431
- } finally{
432
- setStatusBusy(false);
433
- }
434
- },
435
- onButtonClick: isTerminal ? void 0 : async ()=>{
436
- setStatusBusy(true);
437
- try {
438
- await onStatusChange(primaryStatus.name);
439
- } finally{
440
- setStatusBusy(false);
441
- }
442
- },
443
- children: statusBusy ? '...' : isTerminal ? primaryStatus.label ?? primaryStatus.name : primaryStatus.verb ?? primaryStatus.label ?? primaryStatus.name
444
- })
445
- }),
446
- /*#__PURE__*/ jsx(DocumentActions, {
447
- publishedVersion: publishedVersion,
448
- onUnpublish: onUnpublish,
449
- onDelete: onDelete,
450
- onDuplicate: onDuplicate,
451
- sourceTitle: null != useAsTitle && null != initialData ? initialData[useAsTitle] : null,
452
- onCopyToLocale: onCopyToLocale,
453
- sourceLocale: contentLocale,
454
- contentLocales: contentLocales
455
- })
456
- ]
457
- })
458
- ]
459
- }),
460
- restoreWarnings && restoreWarnings.length > 0 && /*#__PURE__*/ jsxs(Alert, {
461
- className: "m-0 mt-4",
462
- intent: "warning",
463
- icon: true,
464
- close: false,
465
- title: "This document was loaded with a best-effort reconstruction",
466
- children: [
467
- /*#__PURE__*/ jsxs("p", {
468
- children: [
469
- "The collection schema has changed since this document was last saved, and",
470
- ' ',
471
- 1 === restoreWarnings.length ? '1 field could not be restored against the current shape.' : `${restoreWarnings.length} fields could not be restored against the current shape.`,
472
- ' ',
473
- "The form below shows only the fields that match the new schema. Saving will overwrite the document with the new shape — any data that did not match will be lost. To preserve it, copy what you need before saving, or delete this document and recreate it. Errors:"
474
- ]
475
- }),
476
- /*#__PURE__*/ jsx("ul", {
477
- children: restoreWarnings.map((w)=>/*#__PURE__*/ jsx("li", {
478
- children: w
479
- }, w))
480
- })
481
- ]
482
- }),
483
- /*#__PURE__*/ jsxs("div", {
484
- className: classnames('byline-form-layout', form_renderer_module.layout),
485
- children: [
486
- /*#__PURE__*/ jsx("div", {
487
- className: classnames('byline-form-content', form_renderer_module.content),
488
- children: layout.main.map((name)=>renderItem(name))
489
- }),
490
- /*#__PURE__*/ jsxs("div", {
491
- className: classnames('byline-form-sidebar', form_renderer_module.sidebar),
492
- children: [
493
- (useAsPath || 'string' == typeof initialData?.path && initialData.path.length > 0) && /*#__PURE__*/ jsx(PathWidget, {
494
- useAsPath: useAsPath,
495
- collectionPath: collectionPath ?? '',
496
- defaultLocale: defaultLocale,
497
- activeLocale: contentLocale,
498
- mode: mode
499
- }),
500
- (layout.sidebar ?? []).map((name)=>renderItem(name))
501
- ]
502
- })
503
- ]
504
- }),
505
- guard.isBlocked && /*#__PURE__*/ jsx(Modal, {
506
- isOpen: true,
507
- closeOnOverlayClick: false,
508
- onDismiss: guard.stay,
509
- children: /*#__PURE__*/ jsxs(Modal.Container, {
510
- style: {
511
- maxWidth: '460px'
512
- },
513
- children: [
514
- /*#__PURE__*/ jsx(Modal.Header, {
515
- className: classnames('byline-form-guard-modal-head', form_renderer_module["guard-modal-head"]),
516
- children: /*#__PURE__*/ jsx("h3", {
517
- className: classnames('byline-form-guard-modal-title', form_renderer_module["guard-modal-title"]),
518
- children: "Leave without saving?"
519
- })
520
- }),
521
- /*#__PURE__*/ jsx(Modal.Content, {
522
- children: /*#__PURE__*/ jsx("p", {
523
- className: classnames('byline-form-guard-modal-text', form_renderer_module["guard-modal-text"]),
524
- children: "Your changes have not been saved. If you leave now, you will lose your changes."
525
- })
526
- }),
527
- /*#__PURE__*/ jsxs(Modal.Actions, {
528
- children: [
529
- /*#__PURE__*/ jsx(Button, {
530
- size: "sm",
531
- intent: "noeffect",
532
- type: "button",
533
- onClick: guard.stay,
534
- children: "Stay on this page"
535
- }),
536
- /*#__PURE__*/ jsx(Button, {
537
- size: "sm",
538
- intent: "danger",
539
- type: "button",
540
- onClick: guard.proceed,
541
- children: "Leave anyway"
542
- })
543
- ]
544
- })
545
- ]
546
- })
547
- })
548
- ]
549
- });
550
- };
551
- const FormRenderer = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpublish, onDelete, onDuplicate, onCopyToLocale, contentLocales, nextStatus, workflowStatuses, publishedVersion, initialData, adminConfig, useAsTitle, useAsPath, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale, useNavigationGuard, restoreWarnings })=>{
552
- const savedTabsRef = useRef({});
553
- return /*#__PURE__*/ jsx(FormProvider, {
554
- initialData: initialData,
555
- children: /*#__PURE__*/ jsx(FormContent, {
556
- mode: mode,
557
- fields: fields,
558
- onSubmit: onSubmit,
559
- onCancel: onCancel,
560
- onStatusChange: onStatusChange,
561
- onUnpublish: onUnpublish,
562
- onDelete: onDelete,
563
- onDuplicate: onDuplicate,
564
- onCopyToLocale: onCopyToLocale,
565
- contentLocales: contentLocales,
566
- nextStatus: nextStatus,
567
- workflowStatuses: workflowStatuses,
568
- publishedVersion: publishedVersion,
569
- initialData: initialData,
570
- adminConfig: adminConfig,
571
- useAsTitle: useAsTitle,
572
- useAsPath: useAsPath,
573
- headingLabel: headingLabel,
574
- headerSlot: headerSlot,
575
- collectionPath: collectionPath,
576
- initialLocale: initialLocale,
577
- onLocaleChange: onLocaleChange,
578
- defaultLocale: defaultLocale,
579
- useNavigationGuard: useNavigationGuard,
580
- restoreWarnings: restoreWarnings,
581
- _activeTabBySet: savedTabsRef.current,
582
- _onTabChange: (tabSetName, tabName)=>{
583
- savedTabsRef.current = {
584
- ...savedTabsRef.current,
585
- [tabSetName]: tabName
586
- };
587
- }
588
- })
589
- }, `${initialLocale ?? 'default'}-${initialData?.versionId ?? ''}`);
590
- };
591
- export { FormRenderer };
@@ -1,46 +0,0 @@
1
- import "./form-renderer_module.css";
2
- const form_renderer_module = {
3
- form: "form-MVxxVb",
4
- "heading-row": "heading-row-qw_UYh",
5
- headingRow: "heading-row-qw_UYh",
6
- heading: "heading-wnLlb_",
7
- "status-bar": "status-bar-kQCXLT",
8
- statusBar: "status-bar-kQCXLT",
9
- status: "status-XbhkJR",
10
- "status-meta": "status-meta-gppNXX",
11
- statusMeta: "status-meta-gppNXX",
12
- "status-cell": "status-cell-Tr3QHl",
13
- statusCell: "status-cell-Tr3QHl",
14
- "status-muted": "status-muted-vHn34O",
15
- statusMuted: "status-muted-vHn34O",
16
- "status-trunc": "status-trunc-jGiHWf",
17
- statusTrunc: "status-trunc-jGiHWf",
18
- "status-published": "status-published-hqosWb",
19
- statusPublished: "status-published-hqosWb",
20
- "status-unpublish": "status-unpublish-DiCNI0",
21
- statusUnpublish: "status-unpublish-DiCNI0",
22
- actions: "actions-AZBIdR",
23
- "actions-button": "actions-button-VIwbST",
24
- actionsButton: "actions-button-VIwbST",
25
- "actions-status-wrap": "actions-status-wrap-hSvlps",
26
- actionsStatusWrap: "actions-status-wrap-hSvlps",
27
- "actions-combo-button": "actions-combo-button-XvqHCC",
28
- actionsComboButton: "actions-combo-button-XvqHCC",
29
- "actions-combo-trigger": "actions-combo-trigger-bmXUzc",
30
- actionsComboTrigger: "actions-combo-trigger-bmXUzc",
31
- layout: "layout-WTbLYr",
32
- content: "content-_P5cdJ",
33
- sidebar: "sidebar-WsxX88",
34
- tabset: "tabset-xfaMkP",
35
- "tabset-tabs": "tabset-tabs-jZpqd_",
36
- tabsetTabs: "tabset-tabs-jZpqd_",
37
- "tabset-fields": "tabset-fields-JJefdw",
38
- tabsetFields: "tabset-fields-JJefdw",
39
- "guard-modal-head": "guard-modal-head-r2TApi",
40
- guardModalHead: "guard-modal-head-r2TApi",
41
- "guard-modal-title": "guard-modal-title-p9dFJ9",
42
- guardModalTitle: "guard-modal-title-p9dFJ9",
43
- "guard-modal-text": "guard-modal-text-uW56HS",
44
- guardModalText: "guard-modal-text-uW56HS"
45
- };
46
- export default form_renderer_module;