@byline/admin 4.18.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { getAdminConfig } from "@byline/core";
5
5
  import { useTranslation } from "@byline/i18n/react";
6
- import { Alert, Button, ComboButton } from "@byline/ui/react";
6
+ import { Alert, Button, ComboButton, LoaderEllipsis } from "@byline/ui/react";
7
7
  import clsx from "clsx";
8
8
  import { sliceFieldAdmin } from "../fields/field-admin.js";
9
9
  import { FieldRenderer } from "../fields/field-renderer.js";
@@ -24,7 +24,7 @@ import { computeStatusTransitions } from "./status-transitions.js";
24
24
  import { TreePlacementWidget } from "./tree-placement-widget.js";
25
25
  import { executeUploadsWithProgress } from "./upload-executor.js";
26
26
  import { useFormLayout } from "./use-form-layout.js";
27
- const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpublish, scheduledPublication, onSchedulePublication, onConfirmScheduledPublication, onCancelScheduledPublication, onDelete, onDuplicate, onCopyToLocale, onDeleteLocale, contentLocales, nextStatus, workflowStatuses, publishedVersion, initialData, adminConfig, useAsTitle, useAsPath, showPath = true, heading, advertiseLocales, tree, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale = 'en', useNavigationGuard: useNavigationGuardProp, restoreWarnings, _activeTabBySet, _onTabChange })=>{
27
+ const FormContent = ({ mode, mutationIssue, mutationsBlocked = false, observedRevision, onMutationError, onTreeMutationCommitted, scheduledPublicationsNeedReconfirmation = false, scheduledPublicationsHref, onReloadDocument, fields, onSubmit, onCancel, onStatusChange, onUnpublish, scheduledPublication, onSchedulePublication, onConfirmScheduledPublication, onCancelScheduledPublication, onDelete, onDuplicate, onCopyToLocale, onDeleteLocale, contentLocales, nextStatus, workflowStatuses, publishedVersion, initialData, adminConfig, useAsTitle, useAsPath, showPath = true, heading, advertiseLocales, tree, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale = 'en', useNavigationGuard: useNavigationGuardProp, restoreWarnings, _activeTabBySet, _onTabChange })=>{
28
28
  const { getFieldValues, runFieldHooks, validateForm, errors: initialErrors, hasChanges: hasChangesFn, resetHasChanges, getPatches, getDirtyBreakdown, getSystemPath, getSystemAvailableLocales, subscribeErrors, subscribeMeta, setFieldValue, setFieldError, getPendingUploads, clearPendingUploads, setFieldUploading } = useFormContext();
29
29
  const { t } = useTranslation('byline-admin');
30
30
  const [errors, setErrors] = useState(initialErrors);
@@ -33,10 +33,15 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
33
33
  const [isUploading, setIsUploading] = useState(false);
34
34
  const submittingRef = useRef(false);
35
35
  const [isSubmitting, setIsSubmitting] = useState(false);
36
+ const isBusy = isUploading || isSubmitting;
37
+ const formRef = useRef(null);
38
+ const focusBeforeBusyRef = useRef(null);
39
+ const restoreFocusAfterBusyRef = useRef(false);
36
40
  const [showUnsavedModal, setShowUnsavedModal] = useState(false);
37
41
  const [pendingSystemFieldsSubmit, setPendingSystemFieldsSubmit] = useState(null);
38
42
  const [contentLocale, setContentLocale] = useState(initialLocale ?? defaultLocale);
39
43
  const scheduling = useScheduledPublication({
44
+ disabled: mutationsBlocked,
40
45
  schedule: scheduledPublication ?? null,
41
46
  onSchedule: onSchedulePublication,
42
47
  onConfirm: onConfirmScheduledPublication,
@@ -92,7 +97,27 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
92
97
  }) : 'create' === mode ? t('forms.heading.create') : t('forms.heading.edit'));
93
98
  const guardFromContext = useNavigationGuardAdapter();
94
99
  const useGuard = useNavigationGuardProp ?? guardFromContext;
95
- const guard = useGuard(hasChanges);
100
+ const [discarding, setDiscarding] = useState(false);
101
+ const [reloadFailed, setReloadFailed] = useState(false);
102
+ const warningRef = useRef(null);
103
+ const mutationBlockedRef = useRef(mutationsBlocked);
104
+ mutationBlockedRef.current = mutationsBlocked || discarding;
105
+ const guard = useGuard(hasChanges && !discarding);
106
+ useEffect(()=>{
107
+ if (mutationIssue) warningRef.current?.focus();
108
+ }, [
109
+ mutationIssue
110
+ ]);
111
+ useEffect(()=>{
112
+ if (!discarding) return;
113
+ Promise.resolve().then(()=>onReloadDocument ? onReloadDocument() : window.location.reload()).catch(()=>{
114
+ setDiscarding(false);
115
+ setReloadFailed(true);
116
+ });
117
+ }, [
118
+ discarding,
119
+ onReloadDocument
120
+ ]);
96
121
  const currentStatus = initialData?.status;
97
122
  const { primaryStatus, secondaryStatuses, isTerminal } = computeStatusTransitions(currentStatus, workflowStatuses, nextStatus);
98
123
  useEffect(()=>subscribeErrors((newErrors)=>setErrors(newErrors)), [
@@ -106,13 +131,40 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
106
131
  subscribeMeta,
107
132
  getFieldValues
108
133
  ]);
134
+ useEffect(()=>{
135
+ if (isBusy || !restoreFocusAfterBusyRef.current) return;
136
+ restoreFocusAfterBusyRef.current = false;
137
+ if (mutationIssue) {
138
+ warningRef.current?.focus();
139
+ focusBeforeBusyRef.current = null;
140
+ return;
141
+ }
142
+ const original = focusBeforeBusyRef.current;
143
+ focusBeforeBusyRef.current = null;
144
+ const originalCanReceiveFocus = original?.isConnected === true && !original.matches(':disabled, [aria-disabled="true"]');
145
+ const target = originalCanReceiveFocus ? original : formRef.current?.querySelector('input:not(:disabled), textarea:not(:disabled), select:not(:disabled), button:not(:disabled), [tabindex]:not([tabindex="-1"])');
146
+ target?.focus({
147
+ preventScroll: true
148
+ });
149
+ }, [
150
+ isBusy,
151
+ mutationIssue
152
+ ]);
153
+ const captureFocusBeforeBusy = useCallback(()=>{
154
+ if (null != focusBeforeBusyRef.current) return;
155
+ const activeElement = document.activeElement;
156
+ if (!(activeElement instanceof HTMLElement) || !formRef.current?.contains(activeElement)) return;
157
+ focusBeforeBusyRef.current = activeElement;
158
+ restoreFocusAfterBusyRef.current = true;
159
+ }, []);
109
160
  const handleCancel = ()=>{
110
161
  if (onCancel && 'function' == typeof onCancel) onCancel();
111
162
  };
112
163
  const submitPayload = useCallback(async (payload)=>{
113
- if ('function' != typeof onSubmit) return;
164
+ if (mutationBlockedRef.current || 'function' != typeof onSubmit) return;
114
165
  if (submittingRef.current) return;
115
166
  submittingRef.current = true;
167
+ captureFocusBeforeBusy();
116
168
  setIsSubmitting(true);
117
169
  try {
118
170
  await onSubmit(payload);
@@ -122,10 +174,12 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
122
174
  setIsSubmitting(false);
123
175
  }
124
176
  }, [
177
+ captureFocusBeforeBusy,
125
178
  onSubmit,
126
179
  resetHasChanges
127
180
  ]);
128
181
  const handleSubmit = (e)=>{
182
+ if (mutationBlockedRef.current) return void e.preventDefault();
129
183
  e.preventDefault();
130
184
  (async ()=>{
131
185
  const hookErrors = await runFieldHooks(fields);
@@ -135,8 +189,10 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
135
189
  ...formErrors
136
190
  ];
137
191
  if (allErrors.length > 0) return void console.error('Form validation failed:', allErrors);
192
+ if (mutationBlockedRef.current) return;
138
193
  const pendingUploads = getPendingUploads();
139
194
  if (pendingUploads.size > 0) {
195
+ captureFocusBeforeBusy();
140
196
  setIsUploading(true);
141
197
  try {
142
198
  const uploadResult = await executeUploadsWithProgress(pendingUploads, uploadField, ({ fieldPath, status })=>{
@@ -245,196 +301,287 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
245
301
  ]
246
302
  }, `tabset:${set.name}`);
247
303
  };
248
- return /*#__PURE__*/ jsxs("form", {
249
- method: "post",
250
- noValidate: true,
251
- onSubmit: handleSubmit,
252
- className: clsx('byline-form', form_renderer_module.form),
253
- inert: isUploading ? true : void 0,
254
- "aria-busy": isUploading,
304
+ const busyAnnouncement = isUploading ? t('forms.actions.uploading') : isSubmitting ? t('forms.actions.saving') : '';
305
+ return /*#__PURE__*/ jsxs(Fragment, {
255
306
  children: [
256
- /*#__PURE__*/ jsxs("div", {
257
- className: clsx('byline-form-heading-row', form_renderer_module["heading-row"]),
258
- children: [
259
- /*#__PURE__*/ jsx("h1", {
260
- className: clsx('byline-form-heading', form_renderer_module.heading),
261
- children: computedHeading
262
- }),
263
- headerSlot
264
- ]
307
+ /*#__PURE__*/ jsx("span", {
308
+ className: clsx('byline-form-busy-status', form_renderer_module["busy-status"]),
309
+ role: "status",
310
+ "aria-live": "polite",
311
+ children: busyAnnouncement
265
312
  }),
266
- /*#__PURE__*/ jsxs("div", {
267
- className: clsx('byline-form-status-bar', form_renderer_module["status-bar"]),
268
- children: [
269
- /*#__PURE__*/ jsx("div", {
270
- className: clsx('byline-form-status-details', form_renderer_module["status-details"]),
271
- children: /*#__PURE__*/ jsx(FormStatusDisplay, {
272
- initialData: initialData,
273
- workflowStatuses: workflowStatuses,
274
- publishedVersion: publishedVersion,
275
- onUnpublish: onUnpublish,
276
- afterStatusCells: /*#__PURE__*/ jsx(ScheduledPublicationCell, {
277
- state: scheduling.state,
278
- timeZone: scheduling.timeZone
279
- })
280
- })
281
- }),
282
- /*#__PURE__*/ jsxs("div", {
283
- className: clsx('byline-form-actions', form_renderer_module.actions),
284
- children: [
285
- /*#__PURE__*/ jsx(Button, {
286
- className: clsx('byline-form-actions-button', form_renderer_module["actions-button"]),
287
- size: "sm",
288
- intent: "noeffect",
289
- type: "button",
290
- onClick: handleCancel,
291
- children: false === hasChanges ? t('common.actions.close') : t('common.actions.cancel')
292
- }),
293
- /*#__PURE__*/ jsx(Button, {
294
- className: clsx('byline-form-actions-button', form_renderer_module["actions-button"]),
295
- size: "sm",
296
- type: "submit",
297
- disabled: false === hasChanges || isUploading || isSubmitting,
298
- children: isUploading ? t('forms.actions.uploading') : t('common.actions.save')
299
- }),
300
- primaryStatus && onStatusChange && /*#__PURE__*/ jsx("div", {
301
- className: clsx('byline-form-actions-status-wrap', form_renderer_module["actions-status-wrap"]),
302
- children: /*#__PURE__*/ jsx(ComboButton, {
303
- buttonClassName: clsx('byline-form-actions-combo-button', form_renderer_module["actions-combo-button"]),
304
- triggerClassName: clsx('byline-form-actions-combo-trigger', form_renderer_module["actions-combo-trigger"]),
305
- options: secondaryStatuses.map((s)=>({
306
- label: isTerminal ? t('forms.actions.revertTo', {
307
- label: s.label ?? s.name
308
- }) : s.verb ?? s.label ?? s.name,
309
- value: s.name
310
- })),
311
- sideOffset: 5,
312
- size: "sm",
313
- type: "button",
314
- intent: isTerminal ? 'info' : 'success',
315
- disabled: statusBusy,
316
- onOptionSelect: async (value)=>{
317
- if (hasChanges) return void setShowUnsavedModal(true);
318
- setStatusBusy(true);
319
- try {
320
- await onStatusChange(value);
321
- } finally{
322
- setStatusBusy(false);
323
- }
324
- },
325
- onButtonClick: isTerminal ? void 0 : async ()=>{
326
- if (hasChanges) return void setShowUnsavedModal(true);
327
- setStatusBusy(true);
328
- try {
329
- await onStatusChange(primaryStatus.name);
330
- } finally{
331
- setStatusBusy(false);
332
- }
333
- },
334
- children: statusBusy ? '...' : isTerminal ? primaryStatus.label ?? primaryStatus.name : primaryStatus.verb ?? primaryStatus.label ?? primaryStatus.name
313
+ /*#__PURE__*/ jsx("div", {
314
+ "aria-busy": isBusy,
315
+ children: /*#__PURE__*/ jsxs("form", {
316
+ ref: formRef,
317
+ method: "post",
318
+ noValidate: true,
319
+ onSubmit: handleSubmit,
320
+ className: clsx('byline-form', form_renderer_module.form),
321
+ inert: isBusy ? true : void 0,
322
+ children: [
323
+ /*#__PURE__*/ jsxs("div", {
324
+ className: clsx('byline-form-heading-row', form_renderer_module["heading-row"]),
325
+ children: [
326
+ /*#__PURE__*/ jsx("h1", {
327
+ className: clsx('byline-form-heading', form_renderer_module.heading),
328
+ children: computedHeading
329
+ }),
330
+ headerSlot
331
+ ]
332
+ }),
333
+ /*#__PURE__*/ jsxs("div", {
334
+ className: clsx('byline-form-status-bar', form_renderer_module["status-bar"]),
335
+ children: [
336
+ /*#__PURE__*/ jsx("div", {
337
+ className: clsx('byline-form-status-details', form_renderer_module["status-details"]),
338
+ children: /*#__PURE__*/ jsx(FormStatusDisplay, {
339
+ disabled: mutationsBlocked || discarding,
340
+ initialData: initialData,
341
+ workflowStatuses: workflowStatuses,
342
+ publishedVersion: publishedVersion,
343
+ onUnpublish: onUnpublish,
344
+ afterStatusCells: /*#__PURE__*/ jsx(ScheduledPublicationCell, {
345
+ state: scheduling.state,
346
+ timeZone: scheduling.timeZone
347
+ })
348
+ })
349
+ }),
350
+ /*#__PURE__*/ jsxs("div", {
351
+ className: clsx('byline-form-actions', form_renderer_module.actions),
352
+ children: [
353
+ /*#__PURE__*/ jsx(Button, {
354
+ className: clsx('byline-form-actions-button', form_renderer_module["actions-button"]),
355
+ size: "sm",
356
+ intent: "noeffect",
357
+ type: "button",
358
+ onClick: handleCancel,
359
+ children: false === hasChanges ? t('common.actions.close') : t('common.actions.cancel')
360
+ }),
361
+ /*#__PURE__*/ jsx(Button, {
362
+ className: clsx('byline-form-actions-button', form_renderer_module["actions-button"]),
363
+ size: "sm",
364
+ type: "submit",
365
+ disabled: mutationsBlocked || discarding || false === hasChanges || isUploading || isSubmitting,
366
+ "aria-label": isSubmitting ? t('common.actions.save') : void 0,
367
+ children: isUploading ? t('forms.actions.uploading') : /*#__PURE__*/ jsxs("span", {
368
+ className: clsx('byline-form-save-content', form_renderer_module["save-content"]),
369
+ children: [
370
+ /*#__PURE__*/ jsx("span", {
371
+ className: clsx('byline-form-save-label', form_renderer_module["save-label"], isSubmitting && form_renderer_module["save-label-hidden"]),
372
+ children: t('common.actions.save')
373
+ }),
374
+ isSubmitting ? /*#__PURE__*/ jsx("span", {
375
+ className: clsx('byline-form-save-loader', form_renderer_module["save-loader"]),
376
+ children: /*#__PURE__*/ jsx(LoaderEllipsis, {
377
+ size: 28,
378
+ "aria-hidden": "true"
379
+ })
380
+ }) : null
381
+ ]
382
+ })
383
+ }),
384
+ primaryStatus && onStatusChange && /*#__PURE__*/ jsx("div", {
385
+ className: clsx('byline-form-actions-status-wrap', form_renderer_module["actions-status-wrap"]),
386
+ children: /*#__PURE__*/ jsx(ComboButton, {
387
+ buttonClassName: clsx('byline-form-actions-combo-button', form_renderer_module["actions-combo-button"]),
388
+ triggerClassName: clsx('byline-form-actions-combo-trigger', form_renderer_module["actions-combo-trigger"]),
389
+ options: secondaryStatuses.map((s)=>({
390
+ label: isTerminal ? t('forms.actions.revertTo', {
391
+ label: s.label ?? s.name
392
+ }) : s.verb ?? s.label ?? s.name,
393
+ value: s.name
394
+ })),
395
+ sideOffset: 5,
396
+ size: "sm",
397
+ type: "button",
398
+ intent: isTerminal ? 'info' : 'success',
399
+ disabled: mutationsBlocked || discarding || statusBusy,
400
+ onOptionSelect: async (value)=>{
401
+ if (mutationBlockedRef.current) return;
402
+ if (hasChanges) return void setShowUnsavedModal(true);
403
+ setStatusBusy(true);
404
+ try {
405
+ await onStatusChange(value);
406
+ } catch (error) {
407
+ onMutationError?.(error);
408
+ } finally{
409
+ setStatusBusy(false);
410
+ }
411
+ },
412
+ onButtonClick: isTerminal ? void 0 : async ()=>{
413
+ if (mutationBlockedRef.current) return;
414
+ if (hasChanges) return void setShowUnsavedModal(true);
415
+ setStatusBusy(true);
416
+ try {
417
+ await onStatusChange(primaryStatus.name);
418
+ } catch (error) {
419
+ onMutationError?.(error);
420
+ } finally{
421
+ setStatusBusy(false);
422
+ }
423
+ },
424
+ children: statusBusy ? '...' : isTerminal ? primaryStatus.label ?? primaryStatus.name : primaryStatus.verb ?? primaryStatus.label ?? primaryStatus.name
425
+ })
426
+ }),
427
+ /*#__PURE__*/ jsx(DocumentActions, {
428
+ disabled: mutationsBlocked || discarding,
429
+ publishedVersion: publishedVersion,
430
+ onUnpublish: onUnpublish,
431
+ onDelete: onDelete,
432
+ onDuplicate: onDuplicate,
433
+ sourceTitle: null != useAsTitle && null != initialData ? initialData[useAsTitle] : null,
434
+ onCopyToLocale: onCopyToLocale,
435
+ sourceLocale: contentLocale,
436
+ contentLocales: contentLocales,
437
+ hasUnsavedChanges: hasChanges,
438
+ onUnsavedChanges: ()=>setShowUnsavedModal(true),
439
+ onDeleteLocale: onDeleteLocale,
440
+ defaultLocale: defaultLocale,
441
+ availableLocales: initialData?._availableVersionLocales,
442
+ scheduledPublicationState: scheduling.state,
443
+ onSchedulePublication: scheduling.openSchedule,
444
+ onConfirmScheduledPublication: scheduling.confirm,
445
+ onCancelScheduledPublication: scheduling.cancel
446
+ })
447
+ ]
335
448
  })
336
- }),
337
- /*#__PURE__*/ jsx(DocumentActions, {
338
- publishedVersion: publishedVersion,
339
- onUnpublish: onUnpublish,
340
- onDelete: onDelete,
341
- onDuplicate: onDuplicate,
342
- sourceTitle: null != useAsTitle && null != initialData ? initialData[useAsTitle] : null,
343
- onCopyToLocale: onCopyToLocale,
344
- sourceLocale: contentLocale,
345
- contentLocales: contentLocales,
346
- hasUnsavedChanges: hasChanges,
347
- onUnsavedChanges: ()=>setShowUnsavedModal(true),
348
- onDeleteLocale: onDeleteLocale,
349
- defaultLocale: defaultLocale,
350
- availableLocales: initialData?._availableVersionLocales,
351
- scheduledPublicationState: scheduling.state,
352
- onSchedulePublication: scheduling.openSchedule,
353
- onConfirmScheduledPublication: scheduling.confirm,
354
- onCancelScheduledPublication: scheduling.cancel
355
- })
356
- ]
357
- })
358
- ]
359
- }),
360
- /*#__PURE__*/ jsx(ScheduledPublicationNotice, {
361
- state: scheduling.state,
362
- timeZone: scheduling.timeZone,
363
- busy: scheduling.busy,
364
- onConfirm: scheduling.confirm,
365
- onReschedule: scheduling.openSchedule,
366
- onCancel: scheduling.cancel
367
- }),
368
- scheduling.modal,
369
- restoreWarnings && restoreWarnings.length > 0 && /*#__PURE__*/ jsxs(Alert, {
370
- className: "m-0 mt-4",
371
- intent: "warning",
372
- icon: true,
373
- close: false,
374
- title: t('forms.restoreWarnings.title'),
375
- children: [
376
- /*#__PURE__*/ jsx("p", {
377
- children: t('forms.restoreWarnings.body', {
378
- count: restoreWarnings.length
449
+ ]
450
+ }),
451
+ (mutationIssue || scheduledPublicationsNeedReconfirmation) && /*#__PURE__*/ jsxs("div", {
452
+ ref: warningRef,
453
+ tabIndex: -1,
454
+ role: "alert",
455
+ "aria-live": "assertive",
456
+ className: clsx('byline-document-concurrency', form_renderer_module.concurrency),
457
+ children: [
458
+ mutationIssue && /*#__PURE__*/ jsxs(Alert, {
459
+ intent: "warning",
460
+ icon: true,
461
+ close: false,
462
+ title: t(`documentConcurrency.${mutationIssue}Title`),
463
+ children: [
464
+ /*#__PURE__*/ jsx("p", {
465
+ children: t(`documentConcurrency.${mutationIssue}`)
466
+ }),
467
+ 'committed' !== mutationIssue && /*#__PURE__*/ jsx(Button, {
468
+ type: "button",
469
+ disabled: discarding,
470
+ onClick: ()=>{
471
+ setReloadFailed(false);
472
+ setDiscarding(true);
473
+ },
474
+ children: t('documentConcurrency.reloadAction')
475
+ }),
476
+ reloadFailed && /*#__PURE__*/ jsx("p", {
477
+ children: t('documentConcurrency.reloadFailed')
478
+ })
479
+ ]
480
+ }),
481
+ scheduledPublicationsNeedReconfirmation && /*#__PURE__*/ jsxs(Alert, {
482
+ intent: "warning",
483
+ icon: true,
484
+ close: false,
485
+ title: t('documentConcurrency.schedulesTitle'),
486
+ children: [
487
+ /*#__PURE__*/ jsx("p", {
488
+ children: t('documentConcurrency.schedules')
489
+ }),
490
+ scheduledPublicationsHref && /*#__PURE__*/ jsx("a", {
491
+ href: scheduledPublicationsHref,
492
+ children: t('documentConcurrency.reviewSchedules')
493
+ })
494
+ ]
495
+ })
496
+ ]
497
+ }),
498
+ /*#__PURE__*/ jsx(ScheduledPublicationNotice, {
499
+ state: scheduling.state,
500
+ timeZone: scheduling.timeZone,
501
+ busy: mutationsBlocked || discarding || scheduling.busy,
502
+ onConfirm: scheduling.confirm,
503
+ onReschedule: scheduling.openSchedule,
504
+ onCancel: scheduling.cancel
505
+ }),
506
+ scheduling.modal,
507
+ restoreWarnings && restoreWarnings.length > 0 && /*#__PURE__*/ jsxs(Alert, {
508
+ className: "m-0 mt-4",
509
+ intent: "warning",
510
+ icon: true,
511
+ close: false,
512
+ title: t('forms.restoreWarnings.title'),
513
+ children: [
514
+ /*#__PURE__*/ jsx("p", {
515
+ children: t('forms.restoreWarnings.body', {
516
+ count: restoreWarnings.length
517
+ })
518
+ }),
519
+ /*#__PURE__*/ jsx("ul", {
520
+ children: restoreWarnings.map((w)=>/*#__PURE__*/ jsx("li", {
521
+ children: w
522
+ }, w))
523
+ })
524
+ ]
525
+ }),
526
+ /*#__PURE__*/ jsxs("div", {
527
+ className: clsx('byline-form-layout', form_renderer_module.layout),
528
+ children: [
529
+ /*#__PURE__*/ jsx("div", {
530
+ className: clsx('byline-form-content', form_renderer_module.content),
531
+ children: layout.main.map((name)=>renderItem(name))
532
+ }),
533
+ /*#__PURE__*/ jsxs("div", {
534
+ className: clsx('byline-form-sidebar', form_renderer_module.sidebar),
535
+ children: [
536
+ showPath && (useAsPath || 'string' == typeof initialData?.path && initialData.path.length > 0) && /*#__PURE__*/ jsx(PathWidget, {
537
+ disabled: mutationsBlocked || discarding,
538
+ useAsPath: useAsPath,
539
+ collectionPath: collectionPath ?? '',
540
+ defaultLocale: defaultLocale,
541
+ activeLocale: contentLocale,
542
+ mode: mode,
543
+ slugifier: pathSlugifier,
544
+ sourceLocked: pathSourceLocked
545
+ }),
546
+ tree && 'edit' === mode && 'string' == typeof initialData?.id && /*#__PURE__*/ jsx(TreePlacementWidget, {
547
+ disabled: mutationsBlocked || discarding,
548
+ onMutationError: onMutationError,
549
+ onCommitted: onTreeMutationCommitted,
550
+ expectedRevision: observedRevision ?? initialData.revision,
551
+ collectionPath: collectionPath ?? '',
552
+ documentId: initialData.id,
553
+ useAsTitle: useAsTitle
554
+ }),
555
+ advertiseLocales && /*#__PURE__*/ jsx(AvailableLocalesWidget, {
556
+ disabled: mutationsBlocked || discarding,
557
+ contentLocales: contentLocales ?? [],
558
+ availableVersionLocales: initialData?._availableVersionLocales ?? []
559
+ }),
560
+ (layout.sidebar ?? []).map((name)=>renderItem(name))
561
+ ]
562
+ })
563
+ ]
564
+ }),
565
+ showUnsavedModal && /*#__PURE__*/ jsx(UnsavedChangesModal, {
566
+ onClose: ()=>setShowUnsavedModal(false)
567
+ }),
568
+ !mutationsBlocked && !discarding && null != pendingSystemFieldsSubmit && /*#__PURE__*/ jsx(SystemFieldsConfirmModal, {
569
+ contentDirty: pendingSystemFieldsSubmit.contentDirty,
570
+ pathDirty: pendingSystemFieldsSubmit.pathDirty,
571
+ availableLocalesDirty: pendingSystemFieldsSubmit.availableLocalesDirty,
572
+ onCancel: ()=>setPendingSystemFieldsSubmit(null),
573
+ onConfirm: ()=>{
574
+ const payload = pendingSystemFieldsSubmit;
575
+ setPendingSystemFieldsSubmit(null);
576
+ submitPayload(payload);
577
+ }
578
+ }),
579
+ guard.isBlocked && /*#__PURE__*/ jsx(NavigationGuardModal, {
580
+ onStay: guard.stay,
581
+ onProceed: guard.proceed
379
582
  })
380
- }),
381
- /*#__PURE__*/ jsx("ul", {
382
- children: restoreWarnings.map((w)=>/*#__PURE__*/ jsx("li", {
383
- children: w
384
- }, w))
385
- })
386
- ]
387
- }),
388
- /*#__PURE__*/ jsxs("div", {
389
- className: clsx('byline-form-layout', form_renderer_module.layout),
390
- children: [
391
- /*#__PURE__*/ jsx("div", {
392
- className: clsx('byline-form-content', form_renderer_module.content),
393
- children: layout.main.map((name)=>renderItem(name))
394
- }),
395
- /*#__PURE__*/ jsxs("div", {
396
- className: clsx('byline-form-sidebar', form_renderer_module.sidebar),
397
- children: [
398
- showPath && (useAsPath || 'string' == typeof initialData?.path && initialData.path.length > 0) && /*#__PURE__*/ jsx(PathWidget, {
399
- useAsPath: useAsPath,
400
- collectionPath: collectionPath ?? '',
401
- defaultLocale: defaultLocale,
402
- activeLocale: contentLocale,
403
- mode: mode,
404
- slugifier: pathSlugifier,
405
- sourceLocked: pathSourceLocked
406
- }),
407
- tree && 'edit' === mode && 'string' == typeof initialData?.id && /*#__PURE__*/ jsx(TreePlacementWidget, {
408
- collectionPath: collectionPath ?? '',
409
- documentId: initialData.id,
410
- useAsTitle: useAsTitle
411
- }),
412
- advertiseLocales && /*#__PURE__*/ jsx(AvailableLocalesWidget, {
413
- contentLocales: contentLocales ?? [],
414
- availableVersionLocales: initialData?._availableVersionLocales ?? []
415
- }),
416
- (layout.sidebar ?? []).map((name)=>renderItem(name))
417
- ]
418
- })
419
- ]
420
- }),
421
- showUnsavedModal && /*#__PURE__*/ jsx(UnsavedChangesModal, {
422
- onClose: ()=>setShowUnsavedModal(false)
423
- }),
424
- null != pendingSystemFieldsSubmit && /*#__PURE__*/ jsx(SystemFieldsConfirmModal, {
425
- contentDirty: pendingSystemFieldsSubmit.contentDirty,
426
- pathDirty: pendingSystemFieldsSubmit.pathDirty,
427
- availableLocalesDirty: pendingSystemFieldsSubmit.availableLocalesDirty,
428
- onCancel: ()=>setPendingSystemFieldsSubmit(null),
429
- onConfirm: ()=>{
430
- const payload = pendingSystemFieldsSubmit;
431
- setPendingSystemFieldsSubmit(null);
432
- submitPayload(payload);
433
- }
434
- }),
435
- guard.isBlocked && /*#__PURE__*/ jsx(NavigationGuardModal, {
436
- onStay: guard.stay,
437
- onProceed: guard.proceed
583
+ ]
584
+ })
438
585
  })
439
586
  ]
440
587
  });
@@ -24,12 +24,23 @@ const form_renderer_module = {
24
24
  actions: "actions-AZBIdR",
25
25
  "actions-button": "actions-button-VIwbST",
26
26
  actionsButton: "actions-button-VIwbST",
27
+ "busy-status": "busy-status-kzSMVH",
28
+ busyStatus: "busy-status-kzSMVH",
29
+ "save-content": "save-content-bc8XeC",
30
+ saveContent: "save-content-bc8XeC",
31
+ "save-label": "save-label-iJw9DA",
32
+ saveLabel: "save-label-iJw9DA",
33
+ "save-label-hidden": "save-label-hidden-Wct46I",
34
+ saveLabelHidden: "save-label-hidden-Wct46I",
35
+ "save-loader": "save-loader-g2wcnV",
36
+ saveLoader: "save-loader-g2wcnV",
27
37
  "actions-status-wrap": "actions-status-wrap-hSvlps",
28
38
  actionsStatusWrap: "actions-status-wrap-hSvlps",
29
39
  "actions-combo-button": "actions-combo-button-XvqHCC",
30
40
  actionsComboButton: "actions-combo-button-XvqHCC",
31
41
  "actions-combo-trigger": "actions-combo-trigger-bmXUzc",
32
42
  actionsComboTrigger: "actions-combo-trigger-bmXUzc",
43
+ concurrency: "concurrency-UT6bX5",
33
44
  layout: "layout-WTbLYr",
34
45
  content: "content-_P5cdJ",
35
46
  sidebar: "sidebar-WsxX88",