@byline/admin 4.14.0 → 4.15.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.
Files changed (34) hide show
  1. package/dist/forms/document-actions.d.ts +16 -1
  2. package/dist/forms/document-actions.js +43 -1
  3. package/dist/forms/form-renderer.d.ts +6 -1
  4. package/dist/forms/form-renderer.js +39 -36
  5. package/dist/forms/form-renderer.module.js +2 -0
  6. package/dist/forms/form-renderer_module.css +7 -1
  7. package/dist/forms/form-status-display.d.ts +10 -1
  8. package/dist/forms/form-status-display.js +4 -2
  9. package/dist/forms/scheduled-publication-control.d.ts +56 -0
  10. package/dist/forms/scheduled-publication-control.js +376 -0
  11. package/dist/forms/scheduled-publication-control.module.js +25 -0
  12. package/dist/forms/scheduled-publication-control_module.css +95 -0
  13. package/dist/forms/scheduled-publication-state.d.ts +83 -0
  14. package/dist/forms/scheduled-publication-state.js +41 -0
  15. package/dist/forms/scheduled-publication-state.test.node.d.ts +8 -0
  16. package/dist/forms/scheduled-publication-time.d.ts +57 -0
  17. package/dist/forms/scheduled-publication-time.js +113 -0
  18. package/dist/forms/scheduled-publication-time.test.node.d.ts +8 -0
  19. package/dist/react.d.ts +1 -0
  20. package/dist/react.js +1 -0
  21. package/package.json +11 -7
  22. package/src/forms/document-actions.tsx +73 -0
  23. package/src/forms/form-renderer.module.css +15 -0
  24. package/src/forms/form-renderer.tsx +59 -64
  25. package/src/forms/form-status-display.tsx +12 -0
  26. package/src/forms/path-widget.test.tsx +20 -8
  27. package/src/forms/scheduled-publication-control.module.css +149 -0
  28. package/src/forms/scheduled-publication-control.tsx +590 -0
  29. package/src/forms/scheduled-publication-datepicker.test.tsx +89 -0
  30. package/src/forms/scheduled-publication-state.test.node.ts +190 -0
  31. package/src/forms/scheduled-publication-state.ts +146 -0
  32. package/src/forms/scheduled-publication-time.test.node.ts +86 -0
  33. package/src/forms/scheduled-publication-time.ts +218 -0
  34. package/src/react.ts +3 -0
@@ -1,4 +1,5 @@
1
1
  import type { PublishedVersionInfo } from './form-renderer';
2
+ import type { ScheduledPublicationState } from './scheduled-publication-state.js';
2
3
  /**
3
4
  * Shape of a content-locale option as consumed by the Copy-to-Locale
4
5
  * modal. Matches the host adapter's `ContentLocaleOption`; declared
@@ -8,7 +9,7 @@ export interface DocumentActionsLocaleOption {
8
9
  code: string;
9
10
  label: string;
10
11
  }
11
- export declare function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate, sourceTitle, onCopyToLocale, sourceLocale, contentLocales, hasUnsavedChanges, onUnsavedChanges, onDeleteLocale, defaultLocale, availableLocales, }: {
12
+ export declare function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate, sourceTitle, onCopyToLocale, sourceLocale, contentLocales, hasUnsavedChanges, onUnsavedChanges, onDeleteLocale, defaultLocale, availableLocales, scheduledPublicationState, onSchedulePublication, onConfirmScheduledPublication, onCancelScheduledPublication, }: {
12
13
  publishedVersion?: PublishedVersionInfo | null;
13
14
  onUnpublish?: () => Promise<void>;
14
15
  onDelete?: () => Promise<void>;
@@ -78,4 +79,18 @@ export declare function DocumentActions({ publishedVersion, onUnpublish, onDelet
78
79
  * minus the default locale and the `'all'` sentinel.
79
80
  */
80
81
  availableLocales?: string[];
82
+ /**
83
+ * Derived presentation state for the document's pending publication
84
+ * schedule. Decides which of the scheduling menu items appear; omit it (or
85
+ * pass a `none` state with no capabilities) and the group is hidden
86
+ * entirely — which is what an ineligible document, a single-status
87
+ * workflow, or an actor missing either ability all reduce to.
88
+ */
89
+ scheduledPublicationState?: ScheduledPublicationState;
90
+ /** Opens the schedule / reschedule modal. Save-gated by the caller. */
91
+ onSchedulePublication?: () => void;
92
+ /** Re-confirms a suspended schedule against the current version. Save-gated by the caller. */
93
+ onConfirmScheduledPublication?: () => void | Promise<void>;
94
+ /** Withdraws the pending schedule. Deliberately not save-gated. */
95
+ onCancelScheduledPublication?: () => void | Promise<void>;
81
96
  }): import("react").JSX.Element;
@@ -6,7 +6,7 @@ import { Button, Checkbox, CloseIcon, DeleteIcon, Dropdown, EllipsisIcon, IconBu
6
6
  import clsx from "clsx";
7
7
  import document_actions_module from "./document-actions.module.js";
8
8
  const DUPLICATE_TITLE_SUFFIX = ' (copy)';
9
- function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate, sourceTitle, onCopyToLocale, sourceLocale, contentLocales, hasUnsavedChanges, onUnsavedChanges, onDeleteLocale, defaultLocale, availableLocales }) {
9
+ function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate, sourceTitle, onCopyToLocale, sourceLocale, contentLocales, hasUnsavedChanges, onUnsavedChanges, onDeleteLocale, defaultLocale, availableLocales, scheduledPublicationState, onSchedulePublication, onConfirmScheduledPublication, onCancelScheduledPublication }) {
10
10
  const { t } = useTranslation('byline-admin');
11
11
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
12
12
  const [showDuplicateConfirm, setShowDuplicateConfirm] = useState(false);
@@ -25,6 +25,30 @@ function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate,
25
25
  const [showDeleteLocaleConfirm, setShowDeleteLocaleConfirm] = useState(false);
26
26
  const [deleteLocaleBusy, setDeleteLocaleBusy] = useState(false);
27
27
  const [deleteTargetLocale, setDeleteTargetLocale] = useState('');
28
+ const scheduling = scheduledPublicationState;
29
+ const schedulingActions = [];
30
+ if (null != scheduling) {
31
+ if (scheduling.actions.schedule && null != onSchedulePublication) schedulingActions.push({
32
+ key: 'schedule',
33
+ label: t('scheduledPublication.actions.scheduleMenuItem'),
34
+ onSelect: onSchedulePublication
35
+ });
36
+ if (scheduling.actions.confirm && null != onConfirmScheduledPublication) schedulingActions.push({
37
+ key: 'confirm',
38
+ label: t('scheduledPublication.actions.confirm'),
39
+ onSelect: ()=>void onConfirmScheduledPublication()
40
+ });
41
+ if (scheduling.actions.reschedule && null != onSchedulePublication) schedulingActions.push({
42
+ key: 'reschedule',
43
+ label: t('scheduledPublication.actions.reschedule'),
44
+ onSelect: onSchedulePublication
45
+ });
46
+ if (scheduling.actions.cancel && null != onCancelScheduledPublication) schedulingActions.push({
47
+ key: 'cancel',
48
+ label: t('scheduledPublication.actions.cancel'),
49
+ onSelect: ()=>void onCancelScheduledPublication()
50
+ });
51
+ }
28
52
  const handleOnDelete = ()=>{
29
53
  setShowDeleteConfirm(false);
30
54
  if (onDelete) onDelete();
@@ -106,6 +130,24 @@ function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate,
106
130
  "data-side": "top",
107
131
  sideOffset: 10,
108
132
  children: [
133
+ schedulingActions.length > 0 && /*#__PURE__*/ jsxs(Fragment, {
134
+ children: [
135
+ schedulingActions.map((action)=>/*#__PURE__*/ jsx(Dropdown.Item, {
136
+ onClick: action.onSelect,
137
+ children: /*#__PURE__*/ jsx("div", {
138
+ className: clsx('byline-form-actions-item', document_actions_module.item),
139
+ children: /*#__PURE__*/ jsx("span", {
140
+ className: clsx('byline-form-actions-item-text', document_actions_module["item-text"]),
141
+ children: /*#__PURE__*/ jsx("button", {
142
+ type: "button",
143
+ children: action.label
144
+ })
145
+ })
146
+ })
147
+ }, action.key)),
148
+ /*#__PURE__*/ jsx(Dropdown.Separator, {})
149
+ ]
150
+ }),
109
151
  copyToLocaleAvailable && /*#__PURE__*/ jsx(Dropdown.Item, {
110
152
  onClick: handleOpenCopyToLocale,
111
153
  children: /*#__PURE__*/ jsx("div", {
@@ -9,6 +9,7 @@ import { type ReactNode } from 'react';
9
9
  import type { CollectionAdminConfig, Field, WorkflowStatus } from '@byline/core';
10
10
  import type { DocumentPatch } from '@byline/core/patches';
11
11
  import { type DocumentActionsLocaleOption } from './document-actions';
12
+ import { type ScheduledPublicationInfo, type SchedulePublicationInput } from './scheduled-publication-control';
12
13
  import type { UseNavigationGuard } from './navigation-guard';
13
14
  /** Metadata about a previously published version that is still live. */
14
15
  export interface PublishedVersionInfo {
@@ -42,6 +43,10 @@ export interface FormRendererProps {
42
43
  onCancel: () => void;
43
44
  onStatusChange?: (nextStatus: string) => Promise<void>;
44
45
  onUnpublish?: () => Promise<void>;
46
+ scheduledPublication?: ScheduledPublicationInfo | null;
47
+ onSchedulePublication?: (input: SchedulePublicationInput) => Promise<void>;
48
+ onConfirmScheduledPublication?: () => Promise<void>;
49
+ onCancelScheduledPublication?: () => Promise<void>;
45
50
  onDelete?: () => Promise<void>;
46
51
  /**
47
52
  * Called when the editor confirms the duplicate modal in
@@ -136,4 +141,4 @@ export interface FormRendererProps {
136
141
  */
137
142
  useNavigationGuard?: UseNavigationGuard;
138
143
  }
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;
144
+ export declare const FormRenderer: (props: FormRendererProps) => import("react").JSX.Element;
@@ -19,11 +19,12 @@ import form_renderer_module from "./form-renderer.module.js";
19
19
  import { FormStatusDisplay } from "./form-status-display.js";
20
20
  import { useNavigationGuardAdapter } from "./navigation-guard.js";
21
21
  import { PathWidget } from "./path-widget.js";
22
+ import { ScheduledPublicationCell, ScheduledPublicationNotice, useScheduledPublication } from "./scheduled-publication-control.js";
22
23
  import { computeStatusTransitions } from "./status-transitions.js";
23
24
  import { TreePlacementWidget } from "./tree-placement-widget.js";
24
25
  import { executeUploadsWithProgress } from "./upload-executor.js";
25
26
  import { useFormLayout } from "./use-form-layout.js";
26
- const FormContent = ({ 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 = 'en', useNavigationGuard: useNavigationGuardProp, restoreWarnings, _activeTabBySet, _onTabChange })=>{
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, advertiseLocales, tree, headingLabel, headerSlot, collectionPath, initialLocale, onLocaleChange, defaultLocale = 'en', useNavigationGuard: useNavigationGuardProp, restoreWarnings, _activeTabBySet, _onTabChange })=>{
27
28
  const { getFieldValues, runFieldHooks, validateForm, errors: initialErrors, hasChanges: hasChangesFn, resetHasChanges, getPatches, getDirtyBreakdown, getSystemPath, getSystemAvailableLocales, subscribeErrors, subscribeMeta, setFieldValue, setFieldError, getPendingUploads, clearPendingUploads, setFieldUploading } = useFormContext();
28
29
  const { t } = useTranslation('byline-admin');
29
30
  const [errors, setErrors] = useState(initialErrors);
@@ -33,6 +34,14 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
33
34
  const [showUnsavedModal, setShowUnsavedModal] = useState(false);
34
35
  const [pendingSystemFieldsSubmit, setPendingSystemFieldsSubmit] = useState(null);
35
36
  const [contentLocale, setContentLocale] = useState(initialLocale ?? defaultLocale);
37
+ const scheduling = useScheduledPublication({
38
+ schedule: scheduledPublication ?? null,
39
+ onSchedule: onSchedulePublication,
40
+ onConfirm: onConfirmScheduledPublication,
41
+ onCancel: onCancelScheduledPublication,
42
+ hasUnsavedChanges: hasChanges,
43
+ onUnsavedChanges: ()=>setShowUnsavedModal(true)
44
+ });
36
45
  const { uploadField } = useBylineFieldServices();
37
46
  const pathSlugifier = getAdminConfig().slugifier;
38
47
  const pathSourceLocked = useMemo(()=>{
@@ -248,11 +257,18 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
248
257
  /*#__PURE__*/ jsxs("div", {
249
258
  className: clsx('byline-form-status-bar', form_renderer_module["status-bar"]),
250
259
  children: [
251
- /*#__PURE__*/ jsx(FormStatusDisplay, {
252
- initialData: initialData,
253
- workflowStatuses: workflowStatuses,
254
- publishedVersion: publishedVersion,
255
- onUnpublish: onUnpublish
260
+ /*#__PURE__*/ jsx("div", {
261
+ className: clsx('byline-form-status-details', form_renderer_module["status-details"]),
262
+ children: /*#__PURE__*/ jsx(FormStatusDisplay, {
263
+ initialData: initialData,
264
+ workflowStatuses: workflowStatuses,
265
+ publishedVersion: publishedVersion,
266
+ onUnpublish: onUnpublish,
267
+ afterStatusCells: /*#__PURE__*/ jsx(ScheduledPublicationCell, {
268
+ state: scheduling.state,
269
+ timeZone: scheduling.timeZone
270
+ })
271
+ })
256
272
  }),
257
273
  /*#__PURE__*/ jsxs("div", {
258
274
  className: clsx('byline-form-actions', form_renderer_module.actions),
@@ -322,12 +338,25 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
322
338
  onUnsavedChanges: ()=>setShowUnsavedModal(true),
323
339
  onDeleteLocale: onDeleteLocale,
324
340
  defaultLocale: defaultLocale,
325
- availableLocales: initialData?._availableVersionLocales
341
+ availableLocales: initialData?._availableVersionLocales,
342
+ scheduledPublicationState: scheduling.state,
343
+ onSchedulePublication: scheduling.openSchedule,
344
+ onConfirmScheduledPublication: scheduling.confirm,
345
+ onCancelScheduledPublication: scheduling.cancel
326
346
  })
327
347
  ]
328
348
  })
329
349
  ]
330
350
  }),
351
+ /*#__PURE__*/ jsx(ScheduledPublicationNotice, {
352
+ state: scheduling.state,
353
+ timeZone: scheduling.timeZone,
354
+ busy: scheduling.busy,
355
+ onConfirm: scheduling.confirm,
356
+ onReschedule: scheduling.openSchedule,
357
+ onCancel: scheduling.cancel
358
+ }),
359
+ scheduling.modal,
331
360
  restoreWarnings && restoreWarnings.length > 0 && /*#__PURE__*/ jsxs(Alert, {
332
361
  className: "m-0 mt-4",
333
362
  intent: "warning",
@@ -401,41 +430,15 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
401
430
  ]
402
431
  });
403
432
  };
404
- 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 })=>{
433
+ const FormRenderer = (props)=>{
434
+ const { mode, initialData, initialLocale, collectionPath } = props;
405
435
  const savedTabsRef = useRef({});
406
436
  return /*#__PURE__*/ jsx(FormProvider, {
407
437
  initialData: initialData,
408
438
  documentId: 'edit' === mode && 'string' == typeof initialData?.id ? initialData.id : null,
409
439
  collectionPath: collectionPath ?? null,
410
440
  children: /*#__PURE__*/ jsx(FormContent, {
411
- mode: mode,
412
- fields: fields,
413
- onSubmit: onSubmit,
414
- onCancel: onCancel,
415
- onStatusChange: onStatusChange,
416
- onUnpublish: onUnpublish,
417
- onDelete: onDelete,
418
- onDuplicate: onDuplicate,
419
- onCopyToLocale: onCopyToLocale,
420
- onDeleteLocale: onDeleteLocale,
421
- contentLocales: contentLocales,
422
- nextStatus: nextStatus,
423
- workflowStatuses: workflowStatuses,
424
- publishedVersion: publishedVersion,
425
- initialData: initialData,
426
- adminConfig: adminConfig,
427
- useAsTitle: useAsTitle,
428
- useAsPath: useAsPath,
429
- advertiseLocales: advertiseLocales,
430
- tree: tree,
431
- headingLabel: headingLabel,
432
- headerSlot: headerSlot,
433
- collectionPath: collectionPath,
434
- initialLocale: initialLocale,
435
- onLocaleChange: onLocaleChange,
436
- defaultLocale: defaultLocale,
437
- useNavigationGuard: useNavigationGuard,
438
- restoreWarnings: restoreWarnings,
441
+ ...props,
439
442
  _activeTabBySet: savedTabsRef.current,
440
443
  _onTabChange: (tabSetName, tabName)=>{
441
444
  savedTabsRef.current = {
@@ -7,6 +7,8 @@ const form_renderer_module = {
7
7
  "status-bar": "status-bar-kQCXLT",
8
8
  statusBar: "status-bar-kQCXLT",
9
9
  status: "status-XbhkJR",
10
+ "status-details": "status-details-lv5FA6",
11
+ statusDetails: "status-details-lv5FA6",
10
12
  "status-meta": "status-meta-gppNXX",
11
13
  statusMeta: "status-meta-gppNXX",
12
14
  "status-cell": "status-cell-Tr3QHl",
@@ -57,6 +57,10 @@
57
57
  display: flex;
58
58
  }
59
59
 
60
+ :is(.status-details-lv5FA6, .byline-form-status-details) {
61
+ min-width: 0;
62
+ }
63
+
60
64
  :is(.status-meta-gppNXX, .byline-form-status-meta) {
61
65
  flex-direction: column;
62
66
  font-size: .8rem;
@@ -73,8 +77,9 @@
73
77
 
74
78
  @media (min-width: 66rem) {
75
79
  :is(.status-meta-gppNXX, .byline-form-status-meta) {
76
- flex-direction: row;
80
+ flex-flow: wrap;
77
81
  align-items: center;
82
+ row-gap: .35rem;
78
83
  }
79
84
  }
80
85
 
@@ -85,6 +90,7 @@
85
90
  }
86
91
 
87
92
  :is(.status-cell-Tr3QHl, .byline-form-status-cell) {
93
+ flex-wrap: wrap;
88
94
  align-items: center;
89
95
  gap: .25rem;
90
96
  min-width: 0;
@@ -13,9 +13,18 @@ import type { PublishedVersionInfo } from './form-renderer';
13
13
  * created timestamps, and a "published live" indicator with an inline
14
14
  * Unpublish action when a previously-published version is still live.
15
15
  */
16
- export declare const FormStatusDisplay: ({ initialData, workflowStatuses, publishedVersion, onUnpublish, }: {
16
+ export declare const FormStatusDisplay: ({ initialData, workflowStatuses, publishedVersion, onUnpublish, afterStatusCells, }: {
17
17
  initialData?: Record<string, any>;
18
18
  workflowStatuses?: WorkflowStatus[];
19
19
  publishedVersion?: PublishedVersionInfo | null;
20
20
  onUnpublish?: () => Promise<void>;
21
+ /**
22
+ * Rendered inside the status cell, directly after the status value, so it
23
+ * reads as a continuation of the same sentence: "Status: Draft — Scheduled
24
+ * for …". Scheduled publication uses this because an armed schedule is a
25
+ * statement about the document's lifecycle, not a timestamp to file beside
26
+ * Created. Falls back to standing alone when the workflow is single-status
27
+ * and no status cell is drawn.
28
+ */
29
+ afterStatusCells?: React.ReactNode;
21
30
  }) => import("react").JSX.Element;
@@ -4,7 +4,7 @@ import { useTranslation } from "@byline/i18n/react";
4
4
  import clsx from "clsx";
5
5
  import { LocalDateTime } from "../fields/local-date-time.js";
6
6
  import form_renderer_module from "./form-renderer.module.js";
7
- const FormStatusDisplay = ({ initialData, workflowStatuses, publishedVersion, onUnpublish })=>{
7
+ const FormStatusDisplay = ({ initialData, workflowStatuses, publishedVersion, onUnpublish, afterStatusCells })=>{
8
8
  const { t } = useTranslation('byline-admin');
9
9
  const statusCode = initialData?.status;
10
10
  const statusLabel = workflowStatuses?.find((s)=>s.name === statusCode)?.label ?? statusCode;
@@ -25,9 +25,11 @@ const FormStatusDisplay = ({ initialData, workflowStatuses, publishedVersion, on
25
25
  /*#__PURE__*/ jsx("span", {
26
26
  className: clsx('byline-form-status-trunc', form_renderer_module["status-trunc"]),
27
27
  children: statusLabel
28
- })
28
+ }),
29
+ afterStatusCells
29
30
  ]
30
31
  }),
32
+ !showStatusCell && afterStatusCells,
31
33
  initialData?.updatedAt != null && /*#__PURE__*/ jsxs("div", {
32
34
  className: clsx('byline-form-status-cell', form_renderer_module["status-cell"]),
33
35
  children: [
@@ -0,0 +1,56 @@
1
+ import type { ScheduledPublicationState } from './scheduled-publication-state.js';
2
+ export type { ScheduledPublicationInfo } from './scheduled-publication-state.js';
3
+ import type { ScheduledPublicationInfo } from './scheduled-publication-state.js';
4
+ export interface SchedulePublicationInput {
5
+ publishAt: string;
6
+ }
7
+ export interface UseScheduledPublicationArgs {
8
+ schedule: ScheduledPublicationInfo | null;
9
+ onSchedule?: (input: SchedulePublicationInput) => Promise<void>;
10
+ onConfirm?: () => Promise<void>;
11
+ onCancel?: () => Promise<void>;
12
+ hasUnsavedChanges: boolean;
13
+ onUnsavedChanges: () => void;
14
+ }
15
+ export interface UseScheduledPublicationReturn {
16
+ state: ScheduledPublicationState;
17
+ timeZone: string;
18
+ busy: boolean;
19
+ /** True when any surface has something to render for this document. */
20
+ isActive: boolean;
21
+ openSchedule: () => void;
22
+ confirm: () => Promise<void>;
23
+ cancel: () => Promise<void>;
24
+ /** The schedule / reschedule modal. Render once, anywhere in the form. */
25
+ modal: React.ReactNode;
26
+ }
27
+ export declare function useScheduledPublication({ schedule, onSchedule, onConfirm, onCancel, hasUnsavedChanges, onUnsavedChanges, }: UseScheduledPublicationArgs): UseScheduledPublicationReturn;
28
+ /**
29
+ * One metadata cell for the form's status bar, matching the Status /
30
+ * Last modified / Created cells in scale, sitting immediately after the status
31
+ * cell — an armed schedule says where the document is headed, which continues
32
+ * what Status says about it rather than belonging with the timestamps.
33
+ *
34
+ * Written as a single phrase in the success colour rather than the label/value
35
+ * pair its neighbours use: it is the one cell reporting something pending
36
+ * rather than something already true, and it should read that way at a glance.
37
+ * Only an armed schedule appears here; every other state is carried by the
38
+ * notice instead, so the two never say the same thing twice.
39
+ */
40
+ export declare function ScheduledPublicationCell({ state, timeZone, }: {
41
+ state: ScheduledPublicationState;
42
+ timeZone: string;
43
+ }): import("react").JSX.Element | null;
44
+ /**
45
+ * The durable notice for a suspended, overdue or failing schedule. Not
46
+ * dismissible: `needs_reconfirm` has to stay on screen until an editor acts on
47
+ * it, long after the toast that announced the suspension has gone.
48
+ */
49
+ export declare function ScheduledPublicationNotice({ state, timeZone, busy, onConfirm, onReschedule, onCancel, }: {
50
+ state: ScheduledPublicationState;
51
+ timeZone: string;
52
+ busy: boolean;
53
+ onConfirm: () => void;
54
+ onReschedule: () => void;
55
+ onCancel: () => void;
56
+ }): import("react").JSX.Element | null;