@byline/admin 4.14.1 → 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.
- package/dist/forms/document-actions.d.ts +16 -1
- package/dist/forms/document-actions.js +43 -1
- package/dist/forms/form-renderer.d.ts +6 -1
- package/dist/forms/form-renderer.js +39 -36
- package/dist/forms/form-renderer.module.js +2 -0
- package/dist/forms/form-renderer_module.css +7 -1
- package/dist/forms/form-status-display.d.ts +10 -1
- package/dist/forms/form-status-display.js +4 -2
- package/dist/forms/scheduled-publication-control.d.ts +56 -0
- package/dist/forms/scheduled-publication-control.js +376 -0
- package/dist/forms/scheduled-publication-control.module.js +25 -0
- package/dist/forms/scheduled-publication-control_module.css +95 -0
- package/dist/forms/scheduled-publication-state.d.ts +83 -0
- package/dist/forms/scheduled-publication-state.js +41 -0
- package/dist/forms/scheduled-publication-state.test.node.d.ts +8 -0
- package/dist/forms/scheduled-publication-time.d.ts +57 -0
- package/dist/forms/scheduled-publication-time.js +113 -0
- package/dist/forms/scheduled-publication-time.test.node.d.ts +8 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +1 -0
- package/package.json +11 -7
- package/src/forms/document-actions.tsx +73 -0
- package/src/forms/form-renderer.module.css +15 -0
- package/src/forms/form-renderer.tsx +59 -64
- package/src/forms/form-status-display.tsx +12 -0
- package/src/forms/path-widget.test.tsx +20 -8
- package/src/forms/scheduled-publication-control.module.css +149 -0
- package/src/forms/scheduled-publication-control.tsx +590 -0
- package/src/forms/scheduled-publication-datepicker.test.tsx +89 -0
- package/src/forms/scheduled-publication-state.test.node.ts +190 -0
- package/src/forms/scheduled-publication-state.ts +146 -0
- package/src/forms/scheduled-publication-time.test.node.ts +86 -0
- package/src/forms/scheduled-publication-time.ts +218 -0
- 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: (
|
|
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(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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 = (
|
|
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
|
-
|
|
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-
|
|
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;
|