@byline/ui 1.10.0 → 1.10.2
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.
|
@@ -371,9 +371,8 @@ function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate,
|
|
|
371
371
|
style: {
|
|
372
372
|
fontWeight: 500
|
|
373
373
|
},
|
|
374
|
-
children: "From
|
|
374
|
+
children: "From:\xa0"
|
|
375
375
|
}),
|
|
376
|
-
' ',
|
|
377
376
|
/*#__PURE__*/ jsx("span", {
|
|
378
377
|
className: classnames('byline-form-actions-copy-source', document_actions_module["copy-source"]),
|
|
379
378
|
children: sourceLocaleLabel
|
|
@@ -439,6 +438,9 @@ function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate,
|
|
|
439
438
|
}),
|
|
440
439
|
/*#__PURE__*/ jsx(Button, {
|
|
441
440
|
size: "sm",
|
|
441
|
+
style: {
|
|
442
|
+
minWidth: '80px'
|
|
443
|
+
},
|
|
442
444
|
intent: "noeffect",
|
|
443
445
|
onClick: ()=>{
|
|
444
446
|
if (!copyToLocaleBusy) setShowCopyToLocaleConfirm(false);
|
|
@@ -448,6 +450,9 @@ function DocumentActions({ publishedVersion, onUnpublish, onDelete, onDuplicate,
|
|
|
448
450
|
}),
|
|
449
451
|
/*#__PURE__*/ jsx(Button, {
|
|
450
452
|
size: "sm",
|
|
453
|
+
style: {
|
|
454
|
+
minWidth: '80px'
|
|
455
|
+
},
|
|
451
456
|
intent: "primary",
|
|
452
457
|
onClick: handleOnCopyToLocale,
|
|
453
458
|
disabled: copyToLocaleBusy || !copyTargetLocale,
|
|
@@ -107,16 +107,19 @@ const FormStatusDisplay = ({ initialData, workflowStatuses, publishedVersion, on
|
|
|
107
107
|
function computeStatusTransitions(currentStatus, workflowStatuses, nextStatus) {
|
|
108
108
|
if (!workflowStatuses || 0 === workflowStatuses.length || !currentStatus) return {
|
|
109
109
|
primaryStatus: nextStatus,
|
|
110
|
-
secondaryStatuses: []
|
|
110
|
+
secondaryStatuses: [],
|
|
111
|
+
isTerminal: false
|
|
111
112
|
};
|
|
112
113
|
if (workflowStatuses.length <= 1) return {
|
|
113
114
|
primaryStatus: void 0,
|
|
114
|
-
secondaryStatuses: []
|
|
115
|
+
secondaryStatuses: [],
|
|
116
|
+
isTerminal: false
|
|
115
117
|
};
|
|
116
118
|
const currentIndex = workflowStatuses.findIndex((s)=>s.name === currentStatus);
|
|
117
119
|
if (-1 === currentIndex) return {
|
|
118
120
|
primaryStatus: nextStatus,
|
|
119
|
-
secondaryStatuses: []
|
|
121
|
+
secondaryStatuses: [],
|
|
122
|
+
isTerminal: false
|
|
120
123
|
};
|
|
121
124
|
const isAtEnd = currentIndex === workflowStatuses.length - 1;
|
|
122
125
|
const isAtStart = 0 === currentIndex;
|
|
@@ -124,19 +127,15 @@ function computeStatusTransitions(currentStatus, workflowStatuses, nextStatus) {
|
|
|
124
127
|
if (!isAtStart && workflowStatuses[0]) availableTargets.push(workflowStatuses[0]);
|
|
125
128
|
if (currentIndex > 1 && workflowStatuses[currentIndex - 1]) availableTargets.push(workflowStatuses[currentIndex - 1]);
|
|
126
129
|
if (!isAtEnd && workflowStatuses[currentIndex + 1]) availableTargets.push(workflowStatuses[currentIndex + 1]);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
secondaryStatuses = availableTargets.filter((s)=>s.name !== prevStatus?.name);
|
|
133
|
-
} else {
|
|
134
|
-
primaryStatus = nextStatus;
|
|
135
|
-
secondaryStatuses = availableTargets.filter((s)=>s.name !== nextStatus?.name);
|
|
136
|
-
}
|
|
130
|
+
if (isAtEnd) return {
|
|
131
|
+
primaryStatus: workflowStatuses[currentIndex],
|
|
132
|
+
secondaryStatuses: availableTargets,
|
|
133
|
+
isTerminal: true
|
|
134
|
+
};
|
|
137
135
|
return {
|
|
138
|
-
primaryStatus,
|
|
139
|
-
secondaryStatuses
|
|
136
|
+
primaryStatus: nextStatus,
|
|
137
|
+
secondaryStatuses: availableTargets.filter((s)=>s.name !== nextStatus?.name),
|
|
138
|
+
isTerminal: false
|
|
140
139
|
};
|
|
141
140
|
}
|
|
142
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 })=>{
|
|
@@ -245,7 +244,7 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
|
|
|
245
244
|
const useGuard = useNavigationGuardProp ?? guardFromContext;
|
|
246
245
|
const guard = useGuard(hasChanges);
|
|
247
246
|
const currentStatus = initialData?.status;
|
|
248
|
-
const { primaryStatus, secondaryStatuses } = computeStatusTransitions(currentStatus, workflowStatuses, nextStatus);
|
|
247
|
+
const { primaryStatus, secondaryStatuses, isTerminal } = computeStatusTransitions(currentStatus, workflowStatuses, nextStatus);
|
|
249
248
|
useEffect(()=>subscribeErrors((newErrors)=>setErrors(newErrors)), [
|
|
250
249
|
subscribeErrors
|
|
251
250
|
]);
|
|
@@ -415,13 +414,13 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
|
|
|
415
414
|
buttonClassName: classnames('byline-form-actions-combo-button', form_renderer_module["actions-combo-button"]),
|
|
416
415
|
triggerClassName: classnames('byline-form-actions-combo-trigger', form_renderer_module["actions-combo-trigger"]),
|
|
417
416
|
options: secondaryStatuses.map((s)=>({
|
|
418
|
-
label: s.verb ?? s.label ?? s.name,
|
|
417
|
+
label: isTerminal ? `Revert to ${s.label ?? s.name}` : s.verb ?? s.label ?? s.name,
|
|
419
418
|
value: s.name
|
|
420
419
|
})),
|
|
421
420
|
sideOffset: 5,
|
|
422
421
|
size: "sm",
|
|
423
422
|
type: "button",
|
|
424
|
-
intent:
|
|
423
|
+
intent: isTerminal ? 'info' : 'success',
|
|
425
424
|
disabled: statusBusy,
|
|
426
425
|
onOptionSelect: async (value)=>{
|
|
427
426
|
setStatusBusy(true);
|
|
@@ -431,7 +430,7 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
|
|
|
431
430
|
setStatusBusy(false);
|
|
432
431
|
}
|
|
433
432
|
},
|
|
434
|
-
onButtonClick: async ()=>{
|
|
433
|
+
onButtonClick: isTerminal ? void 0 : async ()=>{
|
|
435
434
|
setStatusBusy(true);
|
|
436
435
|
try {
|
|
437
436
|
await onStatusChange(primaryStatus.name);
|
|
@@ -439,7 +438,7 @@ const FormContent = ({ mode, fields, onSubmit, onCancel, onStatusChange, onUnpub
|
|
|
439
438
|
setStatusBusy(false);
|
|
440
439
|
}
|
|
441
440
|
},
|
|
442
|
-
children: statusBusy ? '...' : primaryStatus.verb ?? primaryStatus.label ?? primaryStatus.name
|
|
441
|
+
children: statusBusy ? '...' : isTerminal ? primaryStatus.label ?? primaryStatus.name : primaryStatus.verb ?? primaryStatus.label ?? primaryStatus.name
|
|
443
442
|
})
|
|
444
443
|
}),
|
|
445
444
|
/*#__PURE__*/ jsx(DocumentActions, {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"private": false,
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
|
-
"version": "1.10.
|
|
6
|
+
"version": "1.10.2",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=20.9.0"
|
|
9
9
|
},
|
|
@@ -50,48 +50,48 @@
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@base-ui/react": "^1.4.
|
|
53
|
+
"@base-ui/react": "^1.4.1",
|
|
54
54
|
"@dnd-kit/core": "^6.3.1",
|
|
55
55
|
"@dnd-kit/modifiers": "^9.0.0",
|
|
56
56
|
"@dnd-kit/sortable": "^10.0.0",
|
|
57
57
|
"@dnd-kit/utilities": "^3.2.2",
|
|
58
|
-
"@tanstack/react-form-start": "^1.
|
|
58
|
+
"@tanstack/react-form-start": "^1.32.0",
|
|
59
59
|
"classnames": "^2.5.1",
|
|
60
60
|
"date-fns": "^4.1.0",
|
|
61
61
|
"lodash-es": "^4.18.1",
|
|
62
62
|
"motion": "^12.38.0",
|
|
63
63
|
"npm-run-all": "^4.1.5",
|
|
64
|
-
"react-day-picker": "^
|
|
64
|
+
"react-day-picker": "^10.0.0",
|
|
65
65
|
"react-diff-viewer-continued": "^4.2.2",
|
|
66
|
-
"zod": "^4.4.
|
|
66
|
+
"zod": "^4.4.3",
|
|
67
67
|
"zod-form-data": "^3.0.1",
|
|
68
|
-
"@byline/
|
|
69
|
-
"@byline/
|
|
70
|
-
"@byline/
|
|
68
|
+
"@byline/admin": "1.10.2",
|
|
69
|
+
"@byline/client": "1.10.2",
|
|
70
|
+
"@byline/core": "1.10.2"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"react": "^19.0.0",
|
|
74
74
|
"react-dom": "^19.0.0"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@biomejs/biome": "2.4.
|
|
77
|
+
"@biomejs/biome": "2.4.15",
|
|
78
78
|
"@rsbuild/plugin-react": "^2.0.0",
|
|
79
|
-
"@rslib/core": "^0.21.
|
|
79
|
+
"@rslib/core": "^0.21.4",
|
|
80
80
|
"@types/lodash": "^4.17.24",
|
|
81
81
|
"@types/lodash-es": "^4.17.12",
|
|
82
|
-
"@types/node": "^25.6.
|
|
82
|
+
"@types/node": "^25.6.2",
|
|
83
83
|
"@types/react": "19.2.14",
|
|
84
84
|
"@types/react-dom": "19.2.3",
|
|
85
85
|
"@vitejs/plugin-react": "^6.0.1",
|
|
86
86
|
"chokidar": "^5.0.0",
|
|
87
87
|
"lightningcss": "^1.32.0",
|
|
88
88
|
"lightningcss-cli": "^1.32.0",
|
|
89
|
-
"react": "19.2.
|
|
90
|
-
"react-dom": "19.2.
|
|
89
|
+
"react": "^19.2.6",
|
|
90
|
+
"react-dom": "^19.2.6",
|
|
91
91
|
"rimraf": "^6.1.3",
|
|
92
92
|
"typescript": "6.0.3",
|
|
93
93
|
"typescript-plugin-css-modules": "^5.2.0",
|
|
94
|
-
"vite": "^8.0.
|
|
94
|
+
"vite": "^8.0.12",
|
|
95
95
|
"vitest": "^4.1.5"
|
|
96
96
|
},
|
|
97
97
|
"publishConfig": {
|
|
@@ -403,8 +403,8 @@ export function DocumentActions({
|
|
|
403
403
|
className={cx('byline-form-actions-copy-label', styles['copy-label'])}
|
|
404
404
|
style={{ fontWeight: 500 }}
|
|
405
405
|
>
|
|
406
|
-
From
|
|
407
|
-
</span>
|
|
406
|
+
From:
|
|
407
|
+
</span>
|
|
408
408
|
<span className={cx('byline-form-actions-copy-source', styles['copy-source'])}>
|
|
409
409
|
{sourceLocaleLabel}
|
|
410
410
|
</span>
|
|
@@ -461,6 +461,7 @@ export function DocumentActions({
|
|
|
461
461
|
</button>
|
|
462
462
|
<Button
|
|
463
463
|
size="sm"
|
|
464
|
+
style={{ minWidth: '80px' }}
|
|
464
465
|
intent="noeffect"
|
|
465
466
|
onClick={() => {
|
|
466
467
|
if (!copyToLocaleBusy) setShowCopyToLocaleConfirm(false)
|
|
@@ -471,6 +472,7 @@ export function DocumentActions({
|
|
|
471
472
|
</Button>
|
|
472
473
|
<Button
|
|
473
474
|
size="sm"
|
|
475
|
+
style={{ minWidth: '80px' }}
|
|
474
476
|
intent="primary"
|
|
475
477
|
onClick={handleOnCopyToLocale}
|
|
476
478
|
disabled={copyToLocaleBusy || !copyTargetLocale}
|
|
@@ -202,8 +202,12 @@ const FormStatusDisplay = ({
|
|
|
202
202
|
|
|
203
203
|
/**
|
|
204
204
|
* Compute the primary and secondary status transitions for the ComboButton.
|
|
205
|
-
* - Primary: the main action (forward step, or
|
|
206
|
-
*
|
|
205
|
+
* - Primary: the main action (forward step), or the current status itself
|
|
206
|
+
* when the document has reached the final workflow step (terminal state).
|
|
207
|
+
* - Secondary: other available transitions to show as dropdown options.
|
|
208
|
+
* - isTerminal: true when the document is at the final workflow status —
|
|
209
|
+
* the primary button renders as a non-actionable indicator and all
|
|
210
|
+
* back-steps move into the dropdown.
|
|
207
211
|
*/
|
|
208
212
|
function computeStatusTransitions(
|
|
209
213
|
currentStatus: string | undefined,
|
|
@@ -212,20 +216,21 @@ function computeStatusTransitions(
|
|
|
212
216
|
): {
|
|
213
217
|
primaryStatus: WorkflowStatus | undefined
|
|
214
218
|
secondaryStatuses: WorkflowStatus[]
|
|
219
|
+
isTerminal: boolean
|
|
215
220
|
} {
|
|
216
221
|
if (!workflowStatuses || workflowStatuses.length === 0 || !currentStatus) {
|
|
217
|
-
return { primaryStatus: nextStatus, secondaryStatuses: [] }
|
|
222
|
+
return { primaryStatus: nextStatus, secondaryStatuses: [], isTerminal: false }
|
|
218
223
|
}
|
|
219
224
|
|
|
220
225
|
// Single-status workflows (e.g. SINGLE_STATUS_WORKFLOW for lookups) have
|
|
221
226
|
// no transitions — short-circuit so the form shows only Close / Save.
|
|
222
227
|
if (workflowStatuses.length <= 1) {
|
|
223
|
-
return { primaryStatus: undefined, secondaryStatuses: [] }
|
|
228
|
+
return { primaryStatus: undefined, secondaryStatuses: [], isTerminal: false }
|
|
224
229
|
}
|
|
225
230
|
|
|
226
231
|
const currentIndex = workflowStatuses.findIndex((s) => s.name === currentStatus)
|
|
227
232
|
if (currentIndex === -1) {
|
|
228
|
-
return { primaryStatus: nextStatus, secondaryStatuses: [] }
|
|
233
|
+
return { primaryStatus: nextStatus, secondaryStatuses: [], isTerminal: false }
|
|
229
234
|
}
|
|
230
235
|
|
|
231
236
|
const isAtEnd = currentIndex === workflowStatuses.length - 1
|
|
@@ -249,22 +254,23 @@ function computeStatusTransitions(
|
|
|
249
254
|
availableTargets.push(workflowStatuses[currentIndex + 1])
|
|
250
255
|
}
|
|
251
256
|
|
|
252
|
-
// Determine primary and secondary
|
|
253
|
-
let primaryStatus: WorkflowStatus | undefined
|
|
254
|
-
let secondaryStatuses: WorkflowStatus[]
|
|
255
|
-
|
|
256
257
|
if (isAtEnd) {
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
258
|
+
// Terminal state: the primary button is a non-actionable indicator of the
|
|
259
|
+
// current status; both back-steps (revert to previous / reset to first)
|
|
260
|
+
// are surfaced in the dropdown.
|
|
261
|
+
return {
|
|
262
|
+
primaryStatus: workflowStatuses[currentIndex],
|
|
263
|
+
secondaryStatuses: availableTargets,
|
|
264
|
+
isTerminal: true,
|
|
265
|
+
}
|
|
265
266
|
}
|
|
266
267
|
|
|
267
|
-
|
|
268
|
+
// Not at end: primary is the forward step (nextStatus)
|
|
269
|
+
return {
|
|
270
|
+
primaryStatus: nextStatus,
|
|
271
|
+
secondaryStatuses: availableTargets.filter((s) => s.name !== nextStatus?.name),
|
|
272
|
+
isTerminal: false,
|
|
273
|
+
}
|
|
268
274
|
}
|
|
269
275
|
|
|
270
276
|
const FormContent = ({
|
|
@@ -461,7 +467,7 @@ const FormContent = ({
|
|
|
461
467
|
|
|
462
468
|
// Compute available status transitions
|
|
463
469
|
const currentStatus = initialData?.status
|
|
464
|
-
const { primaryStatus, secondaryStatuses } = computeStatusTransitions(
|
|
470
|
+
const { primaryStatus, secondaryStatuses, isTerminal } = computeStatusTransitions(
|
|
465
471
|
currentStatus,
|
|
466
472
|
workflowStatuses,
|
|
467
473
|
nextStatus
|
|
@@ -673,13 +679,15 @@ const FormContent = ({
|
|
|
673
679
|
styles['actions-combo-trigger']
|
|
674
680
|
)}
|
|
675
681
|
options={secondaryStatuses.map((s) => ({
|
|
676
|
-
label:
|
|
682
|
+
label: isTerminal
|
|
683
|
+
? `Revert to ${s.label ?? s.name}`
|
|
684
|
+
: (s.verb ?? s.label ?? s.name),
|
|
677
685
|
value: s.name,
|
|
678
686
|
}))}
|
|
679
687
|
sideOffset={5}
|
|
680
688
|
size="sm"
|
|
681
689
|
type="button"
|
|
682
|
-
intent=
|
|
690
|
+
intent={isTerminal ? 'info' : 'success'}
|
|
683
691
|
disabled={statusBusy}
|
|
684
692
|
onOptionSelect={async (value: string) => {
|
|
685
693
|
setStatusBusy(true)
|
|
@@ -689,18 +697,24 @@ const FormContent = ({
|
|
|
689
697
|
setStatusBusy(false)
|
|
690
698
|
}
|
|
691
699
|
}}
|
|
692
|
-
onButtonClick={
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
+
onButtonClick={
|
|
701
|
+
isTerminal
|
|
702
|
+
? undefined
|
|
703
|
+
: async () => {
|
|
704
|
+
setStatusBusy(true)
|
|
705
|
+
try {
|
|
706
|
+
await onStatusChange(primaryStatus.name)
|
|
707
|
+
} finally {
|
|
708
|
+
setStatusBusy(false)
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
700
712
|
>
|
|
701
713
|
{statusBusy
|
|
702
714
|
? '...'
|
|
703
|
-
:
|
|
715
|
+
: isTerminal
|
|
716
|
+
? (primaryStatus.label ?? primaryStatus.name)
|
|
717
|
+
: (primaryStatus.verb ?? primaryStatus.label ?? primaryStatus.name)}
|
|
704
718
|
</ComboButton>
|
|
705
719
|
</div>
|
|
706
720
|
)}
|