@strapi/review-workflows 5.9.0 → 5.10.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 (77) hide show
  1. package/dist/admin/chunks/Layout-27uslS7w.mjs +265 -0
  2. package/dist/admin/chunks/Layout-27uslS7w.mjs.map +1 -0
  3. package/dist/admin/chunks/Layout-B4l91S3p.js +290 -0
  4. package/dist/admin/chunks/Layout-B4l91S3p.js.map +1 -0
  5. package/dist/admin/chunks/en-BixG7IBu.mjs +14 -0
  6. package/dist/admin/chunks/en-BixG7IBu.mjs.map +1 -0
  7. package/dist/admin/chunks/en-C6SESe-Y.js +16 -0
  8. package/dist/admin/chunks/en-C6SESe-Y.js.map +1 -0
  9. package/dist/admin/chunks/id-DnRGfGvc.js +1442 -0
  10. package/dist/admin/chunks/id-DnRGfGvc.js.map +1 -0
  11. package/dist/admin/chunks/id-LAMc9ydb.mjs +1420 -0
  12. package/dist/admin/chunks/id-LAMc9ydb.mjs.map +1 -0
  13. package/dist/admin/chunks/index-BiGArvbK.mjs +271 -0
  14. package/dist/admin/chunks/index-BiGArvbK.mjs.map +1 -0
  15. package/dist/admin/chunks/index-C5IeISWp.js +960 -0
  16. package/dist/admin/chunks/index-C5IeISWp.js.map +1 -0
  17. package/dist/admin/chunks/index-CSYOmjZt.mjs +926 -0
  18. package/dist/admin/chunks/index-CSYOmjZt.mjs.map +1 -0
  19. package/dist/admin/chunks/index-DZpcSUvc.js +293 -0
  20. package/dist/admin/chunks/index-DZpcSUvc.js.map +1 -0
  21. package/dist/admin/chunks/purchase-review-workflows-CEP8kvxZ.mjs +53 -0
  22. package/dist/admin/chunks/purchase-review-workflows-CEP8kvxZ.mjs.map +1 -0
  23. package/dist/admin/chunks/purchase-review-workflows-Drlxm8yP.js +55 -0
  24. package/dist/admin/chunks/purchase-review-workflows-Drlxm8yP.js.map +1 -0
  25. package/dist/admin/chunks/router-CrN8UbpP.js +30 -0
  26. package/dist/admin/chunks/router-CrN8UbpP.js.map +1 -0
  27. package/dist/admin/chunks/router-Z3AR7XZ7.mjs +28 -0
  28. package/dist/admin/chunks/router-Z3AR7XZ7.mjs.map +1 -0
  29. package/dist/admin/index.js +17 -2
  30. package/dist/admin/index.js.map +1 -1
  31. package/dist/admin/index.mjs +12 -4
  32. package/dist/admin/index.mjs.map +1 -1
  33. package/dist/server/index.js +2109 -7839
  34. package/dist/server/index.js.map +1 -1
  35. package/dist/server/index.mjs +2114 -7847
  36. package/dist/server/index.mjs.map +1 -1
  37. package/dist/server/src/services/document-service-middleware.d.ts +1 -1
  38. package/dist/server/src/services/document-service-middleware.d.ts.map +1 -1
  39. package/dist/shared/contracts/review-workflows.d.ts +0 -1
  40. package/package.json +14 -10
  41. package/dist/_chunks/Layout-C3IORH2n.js +0 -250
  42. package/dist/_chunks/Layout-C3IORH2n.js.map +0 -1
  43. package/dist/_chunks/Layout-DNKR5bym.mjs +0 -233
  44. package/dist/_chunks/Layout-DNKR5bym.mjs.map +0 -1
  45. package/dist/_chunks/en-CYgjfSep.js +0 -15
  46. package/dist/_chunks/en-CYgjfSep.js.map +0 -1
  47. package/dist/_chunks/en-D9dxziEb.mjs +0 -15
  48. package/dist/_chunks/en-D9dxziEb.mjs.map +0 -1
  49. package/dist/_chunks/id-C9Ku9Br9.mjs +0 -1274
  50. package/dist/_chunks/id-C9Ku9Br9.mjs.map +0 -1
  51. package/dist/_chunks/id-oOE1bYls.js +0 -1293
  52. package/dist/_chunks/id-oOE1bYls.js.map +0 -1
  53. package/dist/_chunks/index-ByXbOW-R.mjs +0 -815
  54. package/dist/_chunks/index-ByXbOW-R.mjs.map +0 -1
  55. package/dist/_chunks/index-CmHHjN95.js +0 -231
  56. package/dist/_chunks/index-CmHHjN95.js.map +0 -1
  57. package/dist/_chunks/index-CyhaJuJG.mjs +0 -213
  58. package/dist/_chunks/index-CyhaJuJG.mjs.map +0 -1
  59. package/dist/_chunks/index-DMT27jNE.js +0 -832
  60. package/dist/_chunks/index-DMT27jNE.js.map +0 -1
  61. package/dist/_chunks/purchase-review-workflows-BxoDFxQ5.js +0 -52
  62. package/dist/_chunks/purchase-review-workflows-BxoDFxQ5.js.map +0 -1
  63. package/dist/_chunks/purchase-review-workflows-DyFV_H0I.mjs +0 -52
  64. package/dist/_chunks/purchase-review-workflows-DyFV_H0I.mjs.map +0 -1
  65. package/dist/_chunks/router-BPl2HZMq.mjs +0 -24
  66. package/dist/_chunks/router-BPl2HZMq.mjs.map +0 -1
  67. package/dist/_chunks/router-vDfGt9bq.js +0 -24
  68. package/dist/_chunks/router-vDfGt9bq.js.map +0 -1
  69. /package/dist/admin/src/routes/content-manager/{[model] → model}/components/AssigneeFilter.d.ts +0 -0
  70. /package/dist/admin/src/routes/content-manager/{[model] → model}/components/StageFilter.d.ts +0 -0
  71. /package/dist/admin/src/routes/content-manager/{[model] → model}/components/TableColumns.d.ts +0 -0
  72. /package/dist/admin/src/routes/content-manager/{[model] → model}/configure/constants.d.ts +0 -0
  73. /package/dist/admin/src/routes/content-manager/{[model] → model}/constants.d.ts +0 -0
  74. /package/dist/admin/src/routes/content-manager/{[model]/[id] → model/id}/components/AssigneeSelect.d.ts +0 -0
  75. /package/dist/admin/src/routes/content-manager/{[model]/[id] → model/id}/components/Panel.d.ts +0 -0
  76. /package/dist/admin/src/routes/content-manager/{[model]/[id] → model/id}/components/StageSelect.d.ts +0 -0
  77. /package/dist/admin/src/routes/content-manager/{[model]/[id] → model/id}/components/constants.d.ts +0 -0
@@ -1,1293 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
- const React = require("react");
5
- const strapiAdmin = require("@strapi/admin/strapi-admin");
6
- const ee = require("@strapi/admin/strapi-admin/ee");
7
- const designSystem = require("@strapi/design-system");
8
- const icons = require("@strapi/icons");
9
- const fractionalIndexing = require("fractional-indexing");
10
- const reactIntl = require("react-intl");
11
- const reactRouterDom = require("react-router-dom");
12
- const yup = require("yup");
13
- const index = require("./index-DMT27jNE.js");
14
- const Layout = require("./Layout-C3IORH2n.js");
15
- const reactDndHtml5Backend = require("react-dnd-html5-backend");
16
- const styledComponents = require("styled-components");
17
- const reactDnd = require("react-dnd");
18
- function _interopNamespace(e) {
19
- if (e && e.__esModule) return e;
20
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
21
- if (e) {
22
- for (const k in e) {
23
- if (k !== "default") {
24
- const d = Object.getOwnPropertyDescriptor(e, k);
25
- Object.defineProperty(n, k, d.get ? d : {
26
- enumerable: true,
27
- get: () => e[k]
28
- });
29
- }
30
- }
31
- }
32
- n.default = e;
33
- return Object.freeze(n);
34
- }
35
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
36
- const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
37
- const adminApi = index.reviewWorkflowsApi.injectEndpoints({
38
- endpoints(builder) {
39
- return {
40
- getAdminRoles: builder.query({
41
- query: () => ({
42
- url: `/admin/roles`,
43
- method: "GET"
44
- }),
45
- transformResponse: (res) => {
46
- return res.data;
47
- }
48
- })
49
- };
50
- }
51
- });
52
- const { useGetAdminRolesQuery } = adminApi;
53
- const useKeyboardDragAndDrop = (active, index2, { onCancel, onDropItem, onGrabItem, onMoveItem }) => {
54
- const [isSelected, setIsSelected] = React__namespace.useState(false);
55
- const handleMove = (movement) => {
56
- if (!isSelected) {
57
- return;
58
- }
59
- if (typeof index2 === "number" && onMoveItem) {
60
- if (movement === "UP") {
61
- onMoveItem(index2 - 1, index2);
62
- } else if (movement === "DOWN") {
63
- onMoveItem(index2 + 1, index2);
64
- }
65
- }
66
- };
67
- const handleDragClick = () => {
68
- if (isSelected) {
69
- if (onDropItem) {
70
- onDropItem(index2);
71
- }
72
- setIsSelected(false);
73
- } else {
74
- if (onGrabItem) {
75
- onGrabItem(index2);
76
- }
77
- setIsSelected(true);
78
- }
79
- };
80
- const handleCancel = () => {
81
- if (isSelected) {
82
- setIsSelected(false);
83
- if (onCancel) {
84
- onCancel(index2);
85
- }
86
- }
87
- };
88
- const handleKeyDown = (e) => {
89
- if (!active) {
90
- return;
91
- }
92
- if (e.key === "Tab" && !isSelected) {
93
- return;
94
- }
95
- e.preventDefault();
96
- switch (e.key) {
97
- case " ":
98
- case "Enter":
99
- handleDragClick();
100
- break;
101
- case "Escape":
102
- handleCancel();
103
- break;
104
- case "ArrowDown":
105
- case "ArrowRight":
106
- handleMove("DOWN");
107
- break;
108
- case "ArrowUp":
109
- case "ArrowLeft":
110
- handleMove("UP");
111
- break;
112
- }
113
- };
114
- return handleKeyDown;
115
- };
116
- const DIRECTIONS = {
117
- UPWARD: "upward",
118
- DOWNWARD: "downward"
119
- };
120
- const DROP_SENSITIVITY = {
121
- REGULAR: "regular",
122
- IMMEDIATE: "immediate"
123
- };
124
- const useDragAndDrop = (active, {
125
- type = "STRAPI_DND",
126
- index: index2,
127
- item,
128
- onStart,
129
- onEnd,
130
- onGrabItem,
131
- onDropItem,
132
- onCancel,
133
- onMoveItem,
134
- dropSensitivity = DROP_SENSITIVITY.REGULAR
135
- }) => {
136
- const objectRef = React__namespace.useRef(null);
137
- const [{ handlerId, isOver }, dropRef] = reactDnd.useDrop({
138
- accept: type,
139
- collect(monitor) {
140
- return {
141
- handlerId: monitor.getHandlerId(),
142
- isOver: monitor.isOver({ shallow: true })
143
- };
144
- },
145
- drop(item2) {
146
- const draggedIndex = item2.index;
147
- const newIndex = index2;
148
- if (isOver && onDropItem) {
149
- onDropItem(draggedIndex, newIndex);
150
- }
151
- },
152
- hover(item2, monitor) {
153
- if (!objectRef.current || !onMoveItem) {
154
- return;
155
- }
156
- const dragIndex = item2.index;
157
- const newIndex = index2;
158
- const hoverBoundingRect = objectRef.current?.getBoundingClientRect();
159
- const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
160
- const clientOffset = monitor.getClientOffset();
161
- if (!clientOffset) return;
162
- const hoverClientY = clientOffset && clientOffset.y - hoverBoundingRect.top;
163
- if (typeof dragIndex === "number" && typeof newIndex === "number") {
164
- if (dragIndex === newIndex) {
165
- return;
166
- }
167
- if (dropSensitivity === DROP_SENSITIVITY.REGULAR) {
168
- if (dragIndex < newIndex && hoverClientY < hoverMiddleY) {
169
- return;
170
- }
171
- if (dragIndex > newIndex && hoverClientY > hoverMiddleY) {
172
- return;
173
- }
174
- }
175
- onMoveItem(newIndex, dragIndex);
176
- item2.index = newIndex;
177
- } else {
178
- if (Array.isArray(dragIndex) && Array.isArray(newIndex)) {
179
- const minLength = Math.min(dragIndex.length, newIndex.length);
180
- let areEqual = true;
181
- let isLessThan = false;
182
- let isGreaterThan = false;
183
- for (let i = 0; i < minLength; i++) {
184
- if (dragIndex[i] < newIndex[i]) {
185
- isLessThan = true;
186
- areEqual = false;
187
- break;
188
- } else if (dragIndex[i] > newIndex[i]) {
189
- isGreaterThan = true;
190
- areEqual = false;
191
- break;
192
- }
193
- }
194
- if (areEqual && dragIndex.length === newIndex.length) {
195
- return;
196
- }
197
- if (dropSensitivity === DROP_SENSITIVITY.REGULAR) {
198
- if (isLessThan && !isGreaterThan && hoverClientY < hoverMiddleY) {
199
- return;
200
- }
201
- if (isGreaterThan && !isLessThan && hoverClientY > hoverMiddleY) {
202
- return;
203
- }
204
- }
205
- }
206
- onMoveItem(newIndex, dragIndex);
207
- item2.index = newIndex;
208
- }
209
- }
210
- });
211
- const getDragDirection = (monitor) => {
212
- if (monitor && monitor.isDragging() && !monitor.didDrop() && monitor.getInitialClientOffset() && monitor.getClientOffset()) {
213
- const deltaY = monitor.getInitialClientOffset().y - monitor.getClientOffset().y;
214
- if (deltaY > 0) return DIRECTIONS.UPWARD;
215
- if (deltaY < 0) return DIRECTIONS.DOWNWARD;
216
- return null;
217
- }
218
- return null;
219
- };
220
- const [{ isDragging, direction }, dragRef, dragPreviewRef] = reactDnd.useDrag({
221
- type,
222
- item() {
223
- if (onStart) {
224
- onStart();
225
- }
226
- const { width } = objectRef.current?.getBoundingClientRect() ?? {};
227
- return { index: index2, width, ...item };
228
- },
229
- end() {
230
- if (onEnd) {
231
- onEnd();
232
- }
233
- },
234
- canDrag: active,
235
- /**
236
- * This is useful when the item is in a virtualized list.
237
- * However, if we don't have an ID then we want the libraries
238
- * defaults to take care of this.
239
- */
240
- isDragging: item?.id ? (monitor) => {
241
- return item.id === monitor.getItem().id;
242
- } : void 0,
243
- collect: (monitor) => ({
244
- isDragging: monitor.isDragging(),
245
- initialOffset: monitor.getInitialClientOffset(),
246
- currentOffset: monitor.getClientOffset(),
247
- direction: getDragDirection(monitor)
248
- })
249
- });
250
- const handleKeyDown = useKeyboardDragAndDrop(active, index2, {
251
- onGrabItem,
252
- onDropItem,
253
- onCancel,
254
- onMoveItem
255
- });
256
- return [
257
- { handlerId, isDragging, handleKeyDown, isOverDropTarget: isOver, direction },
258
- objectRef,
259
- dropRef,
260
- dragRef,
261
- dragPreviewRef
262
- ];
263
- };
264
- const AddStage = ({ children, ...props }) => {
265
- return /* @__PURE__ */ jsxRuntime.jsx(
266
- StyledButton,
267
- {
268
- tag: "button",
269
- background: "neutral0",
270
- borderColor: "neutral150",
271
- paddingBottom: 3,
272
- paddingLeft: 4,
273
- paddingRight: 4,
274
- paddingTop: 3,
275
- shadow: "filterShadow",
276
- ...props,
277
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { tag: "span", gap: 2, children: [
278
- /* @__PURE__ */ jsxRuntime.jsx(icons.PlusCircle, { width: "2.4rem", height: "2.4rem", "aria-hidden": true }),
279
- children
280
- ] }) })
281
- }
282
- );
283
- };
284
- const StyledButton = styledComponents.styled(designSystem.Box)`
285
- border-radius: 26px;
286
- color: ${({ theme }) => theme.colors.neutral500};
287
-
288
- &:hover {
289
- color: ${({ theme }) => theme.colors.primary600};
290
- }
291
-
292
- &:active {
293
- color: ${({ theme }) => theme.colors.primary600};
294
- }
295
- `;
296
- const Stages = ({ canDelete = true, canUpdate = true, isCreating }) => {
297
- const { formatMessage } = reactIntl.useIntl();
298
- const { trackUsage } = strapiAdmin.useTracking();
299
- const addFieldRow = strapiAdmin.useForm("Stages", (state) => state.addFieldRow);
300
- const { value: stages = [] } = strapiAdmin.useField("stages");
301
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 6, width: "100%", children: [
302
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { position: "relative", width: "100%", children: [
303
- /* @__PURE__ */ jsxRuntime.jsx(
304
- Background,
305
- {
306
- background: "neutral200",
307
- height: "100%",
308
- left: "50%",
309
- position: "absolute",
310
- top: "0",
311
- width: 2
312
- }
313
- ),
314
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, position: "relative", tag: "ol", children: stages.map((stage, index2) => {
315
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { tag: "li", children: /* @__PURE__ */ jsxRuntime.jsx(
316
- Stage,
317
- {
318
- index: index2,
319
- canDelete: stages.length > 1 && canDelete,
320
- canReorder: stages.length > 1,
321
- canUpdate,
322
- stagesCount: stages.length,
323
- defaultOpen: !stage.id,
324
- ...stage
325
- }
326
- ) }, stage.__temp_key__);
327
- }) })
328
- ] }),
329
- canUpdate && /* @__PURE__ */ jsxRuntime.jsx(
330
- AddStage,
331
- {
332
- type: "button",
333
- onClick: () => {
334
- addFieldRow("stages", { name: "" });
335
- trackUsage("willCreateStage");
336
- },
337
- children: formatMessage({
338
- id: "Settings.review-workflows.stage.add",
339
- defaultMessage: "Add new stage"
340
- })
341
- }
342
- )
343
- ] });
344
- };
345
- const Background = styledComponents.styled(designSystem.Box)`
346
- transform: translateX(-50%);
347
- `;
348
- const Stage = ({
349
- index: index2,
350
- canDelete = false,
351
- canReorder = false,
352
- canUpdate = false,
353
- stagesCount,
354
- name,
355
- permissions,
356
- color,
357
- defaultOpen
358
- }) => {
359
- const [liveText, setLiveText] = React__namespace.useState();
360
- const { formatMessage } = reactIntl.useIntl();
361
- const { trackUsage } = strapiAdmin.useTracking();
362
- const stageErrors = strapiAdmin.useForm("Stages", (state) => state.errors.stages);
363
- const error = stageErrors?.[index2];
364
- const addFieldRow = strapiAdmin.useForm("Stage", (state) => state.addFieldRow);
365
- const moveFieldRow = strapiAdmin.useForm("Stage", (state) => state.moveFieldRow);
366
- const removeFieldRow = strapiAdmin.useForm("Stage", (state) => state.removeFieldRow);
367
- const getItemPos = (index22) => `${index22 + 1} of ${stagesCount}`;
368
- const handleGrabStage = (index22) => {
369
- setLiveText(
370
- formatMessage(
371
- {
372
- id: "dnd.grab-item",
373
- defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
374
- },
375
- {
376
- item: name,
377
- position: getItemPos(index22)
378
- }
379
- )
380
- );
381
- };
382
- const handleDropStage = (index22) => {
383
- setLiveText(
384
- formatMessage(
385
- {
386
- id: "dnd.drop-item",
387
- defaultMessage: `{item}, dropped. Final position in list: {position}.`
388
- },
389
- {
390
- item: name,
391
- position: getItemPos(index22)
392
- }
393
- )
394
- );
395
- };
396
- const handleCancelDragStage = () => {
397
- setLiveText(
398
- formatMessage(
399
- {
400
- id: "dnd.cancel-item",
401
- defaultMessage: "{item}, dropped. Re-order cancelled."
402
- },
403
- {
404
- item: name
405
- }
406
- )
407
- );
408
- };
409
- const handleMoveStage = (newIndex, oldIndex) => {
410
- setLiveText(
411
- formatMessage(
412
- {
413
- id: "dnd.reorder",
414
- defaultMessage: "{item}, moved. New position in list: {position}."
415
- },
416
- {
417
- item: name,
418
- position: getItemPos(newIndex)
419
- }
420
- )
421
- );
422
- moveFieldRow("stages", oldIndex, newIndex);
423
- };
424
- const [{ handlerId, isDragging, handleKeyDown }, stageRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(canReorder, {
425
- index: index2,
426
- item: {
427
- index: index2,
428
- name
429
- },
430
- onGrabItem: handleGrabStage,
431
- onDropItem: handleDropStage,
432
- onMoveItem: handleMoveStage,
433
- onCancel: handleCancelDragStage,
434
- type: Layout.DRAG_DROP_TYPES.STAGE
435
- });
436
- const composedRef = designSystem.useComposedRefs(stageRef, dropRef);
437
- React__namespace.useEffect(() => {
438
- dragPreviewRef(reactDndHtml5Backend.getEmptyImage(), { captureDraggingState: false });
439
- }, [dragPreviewRef, index2]);
440
- const handleCloneClick = () => {
441
- addFieldRow("stages", { name, color, permissions });
442
- };
443
- const id = React__namespace.useId();
444
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { ref: composedRef, shadow: "tableShadow", children: [
445
- liveText && /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { "aria-live": "assertive", children: liveText }),
446
- isDragging ? /* @__PURE__ */ jsxRuntime.jsx(
447
- designSystem.Box,
448
- {
449
- background: "primary100",
450
- borderStyle: "dashed",
451
- borderColor: "primary600",
452
- borderWidth: "1px",
453
- display: "block",
454
- hasRadius: true,
455
- padding: 6
456
- }
457
- ) : /* @__PURE__ */ jsxRuntime.jsx(
458
- AccordionRoot,
459
- {
460
- onValueChange: (value) => {
461
- if (value) {
462
- trackUsage("willEditStage");
463
- }
464
- },
465
- defaultValue: defaultOpen ? id : void 0,
466
- $error: Object.values(error ?? {}).length > 0,
467
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: id, children: [
468
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Header, { children: [
469
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { children: name }),
470
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Actions, { children: canDelete || canUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
471
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { children: [
472
- /* @__PURE__ */ jsxRuntime.jsxs(ContextMenuTrigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
473
- /* @__PURE__ */ jsxRuntime.jsx(icons.More, { "aria-hidden": true, focusable: false }),
474
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage({
475
- id: "[tbdb].components.DynamicZone.more-actions",
476
- defaultMessage: "More actions"
477
- }) })
478
- ] }),
479
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Menu.Content, { popoverPlacement: "bottom-end", zIndex: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.SubRoot, { children: [
480
- canUpdate && /* @__PURE__ */ jsxRuntime.jsx(designSystem.MenuItem, { onClick: handleCloneClick, children: formatMessage({
481
- id: "Settings.review-workflows.stage.delete",
482
- defaultMessage: "Duplicate stage"
483
- }) }),
484
- canDelete && /* @__PURE__ */ jsxRuntime.jsx(DeleteMenuItem, { onClick: () => removeFieldRow("stages", index2), children: formatMessage({
485
- id: "Settings.review-workflows.stage.delete",
486
- defaultMessage: "Delete"
487
- }) })
488
- ] }) })
489
- ] }),
490
- canUpdate && /* @__PURE__ */ jsxRuntime.jsx(
491
- designSystem.IconButton,
492
- {
493
- background: "transparent",
494
- hasRadius: true,
495
- variant: "ghost",
496
- "data-handler-id": handlerId,
497
- ref: dragRef,
498
- label: formatMessage({
499
- id: "Settings.review-workflows.stage.drag",
500
- defaultMessage: "Drag"
501
- }),
502
- onClick: (e) => e.stopPropagation(),
503
- onKeyDown: handleKeyDown,
504
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Drag, {})
505
- }
506
- )
507
- ] }) : null })
508
- ] }),
509
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, padding: 6, children: [
510
- {
511
- disabled: !canUpdate,
512
- label: formatMessage({
513
- id: "Settings.review-workflows.stage.name.label",
514
- defaultMessage: "Stage name"
515
- }),
516
- name: `stages.${index2}.name`,
517
- required: true,
518
- size: 6,
519
- type: "string"
520
- },
521
- {
522
- disabled: !canUpdate,
523
- label: formatMessage({
524
- id: "content-manager.reviewWorkflows.stage.color",
525
- defaultMessage: "Color"
526
- }),
527
- name: `stages.${index2}.color`,
528
- required: true,
529
- size: 6,
530
- type: "color"
531
- },
532
- {
533
- disabled: !canUpdate,
534
- label: formatMessage({
535
- id: "Settings.review-workflows.stage.permissions.label",
536
- defaultMessage: "Roles that can change this stage"
537
- }),
538
- name: `stages.${index2}.permissions`,
539
- placeholder: formatMessage({
540
- id: "Settings.review-workflows.stage.permissions.placeholder",
541
- defaultMessage: "Select a role"
542
- }),
543
- required: true,
544
- size: 6,
545
- type: "permissions"
546
- }
547
- ].map(({ size, ...field }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: size, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsxRuntime.jsx(InputRenderer, { ...field }) }, field.name)) }) })
548
- ] })
549
- }
550
- )
551
- ] });
552
- };
553
- const AccordionRoot = styledComponents.styled(designSystem.Accordion.Root)`
554
- border: 1px solid
555
- ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
556
- `;
557
- const DeleteMenuItem = styledComponents.styled(designSystem.MenuItem)`
558
- color: ${({ theme }) => theme.colors.danger600};
559
- `;
560
- const ContextMenuTrigger = styledComponents.styled(designSystem.Menu.Trigger)`
561
- :hover,
562
- :focus {
563
- background-color: ${({ theme }) => theme.colors.neutral100};
564
- }
565
-
566
- > span {
567
- font-size: 0;
568
- }
569
- `;
570
- const InputRenderer = (props) => {
571
- switch (props.type) {
572
- case "color":
573
- return /* @__PURE__ */ jsxRuntime.jsx(ColorSelector, { ...props });
574
- case "permissions":
575
- return /* @__PURE__ */ jsxRuntime.jsx(PermissionsField, { ...props });
576
- default:
577
- return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.InputRenderer, { ...props });
578
- }
579
- };
580
- const ColorSelector = ({ disabled, label, name, required }) => {
581
- const { formatMessage } = reactIntl.useIntl();
582
- const { value, error, onChange } = strapiAdmin.useField(name);
583
- const colorOptions = index.AVAILABLE_COLORS.map(({ hex, name: name2 }) => ({
584
- value: hex,
585
- label: formatMessage(
586
- {
587
- id: "Settings.review-workflows.stage.color.name",
588
- defaultMessage: "{name}"
589
- },
590
- { name: name2 }
591
- ),
592
- color: hex
593
- }));
594
- const { themeColorName } = index.getStageColorByHex(value) ?? {};
595
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error, name, required, children: [
596
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
597
- /* @__PURE__ */ jsxRuntime.jsx(
598
- designSystem.SingleSelect,
599
- {
600
- disabled,
601
- onChange: (v) => {
602
- onChange(name, v.toString());
603
- },
604
- value: value?.toUpperCase(),
605
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(
606
- designSystem.Flex,
607
- {
608
- tag: "span",
609
- height: 2,
610
- background: value,
611
- borderColor: themeColorName === "neutral0" ? "neutral150" : "transparent",
612
- hasRadius: true,
613
- shrink: 0,
614
- width: 2
615
- }
616
- ),
617
- children: colorOptions.map(({ value: value2, label: label2, color }) => {
618
- const { themeColorName: themeColorName2 } = index.getStageColorByHex(color) || {};
619
- return /* @__PURE__ */ jsxRuntime.jsx(
620
- designSystem.SingleSelectOption,
621
- {
622
- value: value2,
623
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(
624
- designSystem.Flex,
625
- {
626
- tag: "span",
627
- height: 2,
628
- background: color,
629
- borderColor: themeColorName2 === "neutral0" ? "neutral150" : "transparent",
630
- hasRadius: true,
631
- shrink: 0,
632
- width: 2
633
- }
634
- ),
635
- children: label2
636
- },
637
- value2
638
- );
639
- })
640
- }
641
- ),
642
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
643
- ] });
644
- };
645
- const PermissionsField = ({ disabled, name, placeholder, required }) => {
646
- const { formatMessage } = reactIntl.useIntl();
647
- const { toggleNotification } = strapiAdmin.useNotification();
648
- const [isApplyAllConfirmationOpen, setIsApplyAllConfirmationOpen] = React__namespace.useState(false);
649
- const { value = [], error, onChange } = strapiAdmin.useField(name);
650
- const allStages = strapiAdmin.useForm("PermissionsField", (state) => state.values.stages);
651
- const onFormValueChange = strapiAdmin.useForm("PermissionsField", (state) => state.onChange);
652
- const rolesErrorCount = React__namespace.useRef(0);
653
- const { data: roles = [], isLoading, error: getRolesError } = useGetAdminRolesQuery();
654
- const filteredRoles = roles?.filter((role) => role.code !== "strapi-super-admin") ?? [];
655
- React__namespace.useEffect(() => {
656
- if (!isLoading && getRolesError && "status" in getRolesError && getRolesError.status == 403 && rolesErrorCount.current === 0) {
657
- rolesErrorCount.current = 1;
658
- toggleNotification({
659
- blockTransition: true,
660
- type: "danger",
661
- message: formatMessage({
662
- id: "review-workflows.stage.permissions.noPermissions.description",
663
- defaultMessage: "You don’t have the permission to see roles. Contact your administrator."
664
- })
665
- });
666
- }
667
- }, [formatMessage, isLoading, roles, toggleNotification, getRolesError]);
668
- if (!isLoading && filteredRoles.length === 0) {
669
- return /* @__PURE__ */ jsxRuntime.jsxs(
670
- designSystem.Field.Root,
671
- {
672
- name,
673
- hint: formatMessage({
674
- id: "Settings.review-workflows.stage.permissions.noPermissions.description",
675
- defaultMessage: "You don’t have the permission to see roles"
676
- }),
677
- required,
678
- children: [
679
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
680
- id: "Settings.review-workflows.stage.permissions.label",
681
- defaultMessage: "Roles that can change this stage"
682
- }) }),
683
- /* @__PURE__ */ jsxRuntime.jsx(
684
- designSystem.TextInput,
685
- {
686
- disabled: true,
687
- placeholder: formatMessage({
688
- id: "components.NotAllowedInput.text",
689
- defaultMessage: "No permissions to see this field"
690
- }),
691
- startAction: /* @__PURE__ */ jsxRuntime.jsx(icons.EyeStriked, { fill: "neutral600" }),
692
- type: "text",
693
- value: ""
694
- }
695
- ),
696
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
697
- ]
698
- }
699
- );
700
- }
701
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-end", gap: 3, children: [
702
- /* @__PURE__ */ jsxRuntime.jsx(PermissionWrapper, { grow: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error, name, required: true, children: [
703
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
704
- id: "Settings.review-workflows.stage.permissions.label",
705
- defaultMessage: "Roles that can change this stage"
706
- }) }),
707
- /* @__PURE__ */ jsxRuntime.jsx(
708
- designSystem.MultiSelect,
709
- {
710
- disabled,
711
- onChange: (values) => {
712
- const permissions = values.map((value2) => ({
713
- role: parseInt(value2, 10),
714
- action: "admin::review-workflows.stage.transition"
715
- }));
716
- onChange(name, permissions);
717
- },
718
- placeholder,
719
- value: value.map((permission) => `${permission.role}`),
720
- withTags: true,
721
- children: /* @__PURE__ */ jsxRuntime.jsx(
722
- designSystem.MultiSelectGroup,
723
- {
724
- label: formatMessage({
725
- id: "Settings.review-workflows.stage.permissions.allRoles.label",
726
- defaultMessage: "All roles"
727
- }),
728
- values: filteredRoles.map((r) => `${r.id}`),
729
- children: filteredRoles.map((role) => {
730
- return /* @__PURE__ */ jsxRuntime.jsx(NestedOption$1, { value: `${role.id}`, children: role.name }, role.id);
731
- })
732
- }
733
- )
734
- }
735
- ),
736
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
737
- ] }) }),
738
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { open: isApplyAllConfirmationOpen, onOpenChange: setIsApplyAllConfirmationOpen, children: [
739
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
740
- designSystem.IconButton,
741
- {
742
- disabled,
743
- label: formatMessage({
744
- id: "Settings.review-workflows.stage.permissions.apply.label",
745
- defaultMessage: "Apply to all stages"
746
- }),
747
- size: "L",
748
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Duplicate, {})
749
- }
750
- ) }),
751
- /* @__PURE__ */ jsxRuntime.jsx(
752
- strapiAdmin.ConfirmDialog,
753
- {
754
- onConfirm: () => {
755
- onFormValueChange(
756
- "stages",
757
- allStages.map((stage) => ({
758
- ...stage,
759
- permissions: value
760
- }))
761
- );
762
- setIsApplyAllConfirmationOpen(false);
763
- toggleNotification({
764
- type: "success",
765
- message: formatMessage({
766
- id: "Settings.review-workflows.page.edit.confirm.stages.permissions.copy.success",
767
- defaultMessage: "Applied roles to all other stages of the workflow"
768
- })
769
- });
770
- },
771
- variant: "default",
772
- children: formatMessage({
773
- id: "Settings.review-workflows.page.edit.confirm.stages.permissions.copy",
774
- defaultMessage: "Roles that can change that stage will be applied to all the other stages."
775
- })
776
- }
777
- )
778
- ] })
779
- ] }) });
780
- };
781
- const NestedOption$1 = styledComponents.styled(designSystem.MultiSelectOption)`
782
- padding-left: ${({ theme }) => theme.spaces[7]};
783
- `;
784
- const PermissionWrapper = styledComponents.styled(designSystem.Flex)`
785
- > * {
786
- flex-grow: 1;
787
- }
788
- `;
789
- const WorkflowAttributes = ({ canUpdate = true }) => {
790
- const { formatMessage } = reactIntl.useIntl();
791
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { background: "neutral0", hasRadius: true, gap: 4, padding: 6, shadow: "tableShadow", children: [
792
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsxRuntime.jsx(
793
- strapiAdmin.InputRenderer,
794
- {
795
- disabled: !canUpdate,
796
- label: formatMessage({
797
- id: "Settings.review-workflows.workflow.name.label",
798
- defaultMessage: "Workflow Name"
799
- }),
800
- name: "name",
801
- required: true,
802
- type: "string"
803
- }
804
- ) }),
805
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsxRuntime.jsx(ContentTypesSelector, { disabled: !canUpdate }) }),
806
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsxRuntime.jsx(StageSelector, { disabled: !canUpdate }) })
807
- ] });
808
- };
809
- const ContentTypesSelector = ({ disabled }) => {
810
- const { formatMessage, locale } = reactIntl.useIntl();
811
- const { data: contentTypes, isLoading } = index.useGetContentTypesQuery();
812
- const { workflows } = Layout.useReviewWorkflows();
813
- const currentWorkflow = strapiAdmin.useForm("ContentTypesSelector", (state) => state.values);
814
- const { error, value, onChange } = strapiAdmin.useField("contentTypes");
815
- const formatter = designSystem.useCollator(locale, {
816
- sensitivity: "base"
817
- });
818
- const isDisabled = disabled || isLoading || !contentTypes || contentTypes.collectionType.length === 0 && contentTypes.singleType.length === 0;
819
- const collectionTypes = (contentTypes?.collectionType ?? []).toSorted((a, b) => formatter.compare(a.info.displayName, b.info.displayName)).map((contentType) => ({
820
- label: contentType.info.displayName,
821
- value: contentType.uid
822
- }));
823
- const singleTypes = (contentTypes?.singleType ?? []).map((contentType) => ({
824
- label: contentType.info.displayName,
825
- value: contentType.uid
826
- }));
827
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error, name: "contentTypes", children: [
828
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
829
- id: "Settings.review-workflows.workflow.contentTypes.label",
830
- defaultMessage: "Associated to"
831
- }) }),
832
- /* @__PURE__ */ jsxRuntime.jsx(
833
- designSystem.MultiSelect,
834
- {
835
- customizeContent: (value2) => formatMessage(
836
- {
837
- id: "Settings.review-workflows.workflow.contentTypes.displayValue",
838
- defaultMessage: "{count} {count, plural, one {content type} other {content types}} selected"
839
- },
840
- { count: value2?.length }
841
- ),
842
- disabled: isDisabled,
843
- onChange: (values) => {
844
- onChange("contentTypes", values);
845
- },
846
- value,
847
- placeholder: formatMessage({
848
- id: "Settings.review-workflows.workflow.contentTypes.placeholder",
849
- defaultMessage: "Select"
850
- }),
851
- children: [
852
- ...collectionTypes.length > 0 ? [
853
- {
854
- label: formatMessage({
855
- id: "Settings.review-workflows.workflow.contentTypes.collectionTypes.label",
856
- defaultMessage: "Collection Types"
857
- }),
858
- children: collectionTypes
859
- }
860
- ] : [],
861
- ...singleTypes.length > 0 ? [
862
- {
863
- label: formatMessage({
864
- id: "Settings.review-workflows.workflow.contentTypes.singleTypes.label",
865
- defaultMessage: "Single Types"
866
- }),
867
- children: singleTypes
868
- }
869
- ] : []
870
- ].map((opt) => {
871
- return /* @__PURE__ */ jsxRuntime.jsx(
872
- designSystem.MultiSelectGroup,
873
- {
874
- label: opt.label,
875
- values: opt.children.map((child) => child.value.toString()),
876
- children: opt.children.map((child) => {
877
- const { name: assignedWorkflowName } = workflows?.find(
878
- (workflow) => (currentWorkflow && workflow.id !== currentWorkflow.id || !currentWorkflow) && workflow.contentTypes.includes(child.value)
879
- ) ?? {};
880
- return /* @__PURE__ */ jsxRuntime.jsx(NestedOption, { value: child.value, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
881
- // @ts-expect-error - formatMessage options doesn't expect to be a React component but that's what we need actually for the <i> and <em> components
882
- children: formatMessage(
883
- {
884
- id: "Settings.review-workflows.workflow.contentTypes.assigned.notice",
885
- defaultMessage: "{label} {name, select, undefined {} other {<i>(assigned to <em>{name}</em> workflow)</i>}}"
886
- },
887
- {
888
- label: child.label,
889
- name: assignedWorkflowName,
890
- em: (...children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "em", fontWeight: "bold", children }),
891
- i: (...children) => /* @__PURE__ */ jsxRuntime.jsx(ContentTypeTakeNotice, { children })
892
- }
893
- )
894
- }) }, child.value);
895
- })
896
- },
897
- opt.label
898
- );
899
- })
900
- }
901
- )
902
- ] });
903
- };
904
- const NestedOption = styledComponents.styled(designSystem.MultiSelectOption)`
905
- padding-left: ${({ theme }) => theme.spaces[7]};
906
- `;
907
- const ContentTypeTakeNotice = styledComponents.styled(designSystem.Typography)`
908
- font-style: italic;
909
- `;
910
- const StageSelector = ({ disabled }) => {
911
- const { value: stages = [] } = strapiAdmin.useField("stages");
912
- const { formatMessage } = reactIntl.useIntl();
913
- const { error, value, onChange } = strapiAdmin.useField("stageRequiredToPublish");
914
- const validStages = stages.filter((stage) => stage.name);
915
- return /* @__PURE__ */ jsxRuntime.jsxs(
916
- designSystem.Field.Root,
917
- {
918
- error,
919
- name: "stageRequiredToPublish",
920
- hint: formatMessage({
921
- id: "settings.review-workflows.workflow.stageRequiredToPublish.hint",
922
- defaultMessage: "Prevents entries from being published if they are not at the required stage."
923
- }),
924
- children: [
925
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
926
- id: "settings.review-workflows.workflow.stageRequiredToPublish.label",
927
- defaultMessage: "Required stage for publishing"
928
- }) }),
929
- /* @__PURE__ */ jsxRuntime.jsxs(
930
- designSystem.SingleSelect,
931
- {
932
- disabled,
933
- onChange: (value2) => {
934
- onChange("stageRequiredToPublish", value2);
935
- },
936
- value,
937
- children: [
938
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: formatMessage({
939
- id: "settings.review-workflows.workflow.stageRequiredToPublish.any",
940
- defaultMessage: "Any stage"
941
- }) }),
942
- validStages.map((stage, i) => /* @__PURE__ */ jsxRuntime.jsx(
943
- designSystem.SingleSelectOption,
944
- {
945
- value: stage.id?.toString() || stage.__temp_key__,
946
- children: stage.name
947
- },
948
- `requiredToPublishStage-${stage.id || stage.__temp_key__}`
949
- ))
950
- ]
951
- }
952
- ),
953
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
954
- ]
955
- }
956
- );
957
- };
958
- const WORKFLOW_SCHEMA = yup__namespace.object({
959
- contentTypes: yup__namespace.array().of(yup__namespace.string()),
960
- name: yup__namespace.string().max(255, {
961
- id: "review-workflows.validation.name.max-length",
962
- defaultMessage: "Name can not be longer than 255 characters"
963
- }).required().nullable(),
964
- stages: yup__namespace.array().of(
965
- yup__namespace.object().shape({
966
- name: yup__namespace.string().nullable().required({
967
- id: "review-workflows.validation.stage.name",
968
- defaultMessage: "Name is required"
969
- }).max(255, {
970
- id: "review-workflows.validation.stage.max-length",
971
- defaultMessage: "Name can not be longer than 255 characters"
972
- }).test(
973
- "unique-name",
974
- {
975
- id: "review-workflows.validation.stage.duplicate",
976
- defaultMessage: "Stage name must be unique"
977
- },
978
- (stageName, context) => {
979
- const { stages } = context.from[1].value;
980
- return stages.filter((stage) => stage.name === stageName).length === 1;
981
- }
982
- ),
983
- color: yup__namespace.string().nullable().required({
984
- id: "review-workflows.validation.stage.color",
985
- defaultMessage: "Color is required"
986
- }).matches(/^#(?:[0-9a-fA-F]{3}){1,2}$/i),
987
- permissions: yup__namespace.array(
988
- yup__namespace.object({
989
- role: yup__namespace.number().strict().typeError({
990
- id: "review-workflows.validation.stage.permissions.role.number",
991
- defaultMessage: "Role must be of type number"
992
- }).required(),
993
- action: yup__namespace.string().required({
994
- id: "review-workflows.validation.stage.permissions.action.required",
995
- defaultMessage: "Action is a required argument"
996
- })
997
- })
998
- ).strict()
999
- })
1000
- ).min(1),
1001
- stageRequiredToPublish: yup__namespace.string().nullable()
1002
- });
1003
- const EditPage = () => {
1004
- const { id = "" } = reactRouterDom.useParams();
1005
- const isCreatingWorkflow = id === "create";
1006
- const { formatMessage } = reactIntl.useIntl();
1007
- const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
1008
- const navigate = reactRouterDom.useNavigate();
1009
- const { toggleNotification } = strapiAdmin.useNotification();
1010
- const {
1011
- isLoading: isLoadingWorkflow,
1012
- meta,
1013
- workflows,
1014
- error,
1015
- update,
1016
- create
1017
- } = Layout.useReviewWorkflows();
1018
- const permissions = index.useTypedSelector(
1019
- (state) => state.admin_app.permissions["settings"]?.["review-workflows"]
1020
- );
1021
- const {
1022
- allowedActions: { canDelete, canUpdate, canCreate }
1023
- } = strapiAdmin.useRBAC(permissions);
1024
- const [savePrompts, setSavePrompts] = React__namespace.useState({});
1025
- const { getFeature, isLoading: isLicenseLoading } = ee.useLicenseLimits();
1026
- const [showLimitModal, setShowLimitModal] = React__namespace.useState(null);
1027
- const currentWorkflow = workflows?.find((workflow) => workflow.id === parseInt(id, 10));
1028
- const contentTypesFromOtherWorkflows = workflows?.filter((workflow) => workflow.id !== parseInt(id, 10)).flatMap((workflow) => workflow.contentTypes);
1029
- const limits = getFeature("review-workflows");
1030
- const numberOfWorkflows = limits?.[index.CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME];
1031
- const stagesPerWorkflow = limits?.[index.CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME];
1032
- const submitForm = async (data, helpers) => {
1033
- try {
1034
- const { stageRequiredToPublish, ...rest } = data;
1035
- const stageRequiredToPublishName = stageRequiredToPublish === "" ? null : rest.stages.find(
1036
- (stage) => stage.id === Number(stageRequiredToPublish) || stage.__temp_key__ === stageRequiredToPublish
1037
- )?.name;
1038
- if (!isCreatingWorkflow) {
1039
- const res = await update(id, {
1040
- ...rest,
1041
- // compare permissions of stages and only submit them if at least one has
1042
- // changed; this enables partial updates e.g. for users who don't have
1043
- // permissions to see roles
1044
- stages: rest.stages.map((stage) => {
1045
- let hasUpdatedPermissions = true;
1046
- const serverStage = currentWorkflow?.stages?.find(
1047
- (serverStage2) => serverStage2.id === stage?.id
1048
- );
1049
- if (serverStage) {
1050
- hasUpdatedPermissions = serverStage.permissions?.length !== stage.permissions?.length || !serverStage.permissions?.every(
1051
- (serverPermission) => !!stage.permissions?.find(
1052
- (permission) => permission.role === serverPermission.role
1053
- )
1054
- );
1055
- }
1056
- return {
1057
- ...stage,
1058
- permissions: hasUpdatedPermissions ? stage.permissions : void 0
1059
- };
1060
- }),
1061
- stageRequiredToPublishName
1062
- });
1063
- if ("error" in res && index.isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1064
- helpers.setErrors(formatValidationErrors(res.error));
1065
- }
1066
- } else {
1067
- const res = await create({
1068
- ...rest,
1069
- stageRequiredToPublishName
1070
- });
1071
- if ("error" in res && index.isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1072
- helpers.setErrors(formatValidationErrors(res.error));
1073
- } else if ("data" in res) {
1074
- navigate(`../${res.data.id}`, { replace: true });
1075
- }
1076
- }
1077
- } catch (error2) {
1078
- toggleNotification({
1079
- type: "danger",
1080
- message: formatMessage({
1081
- id: "notification.error",
1082
- defaultMessage: "An error occurred"
1083
- })
1084
- });
1085
- }
1086
- setSavePrompts({});
1087
- };
1088
- const handleConfirmDeleteDialog = (data, helpers) => async () => {
1089
- await submitForm(data, helpers);
1090
- };
1091
- const handleConfirmClose = () => {
1092
- setSavePrompts({});
1093
- };
1094
- const handleSubmit = async (data, helpers) => {
1095
- const isContentTypeReassignment = data.contentTypes.some(
1096
- (contentType) => contentTypesFromOtherWorkflows?.includes(contentType)
1097
- );
1098
- const hasDeletedServerStages = !isCreatingWorkflow && !currentWorkflow?.stages.every(
1099
- (stage) => data.stages.some((newStage) => newStage.id === stage.id)
1100
- );
1101
- if (meta && numberOfWorkflows && meta?.workflowCount > parseInt(numberOfWorkflows, 10)) {
1102
- setShowLimitModal("workflow");
1103
- } else if (data.stages && stagesPerWorkflow && data.stages.length > parseInt(stagesPerWorkflow, 10)) {
1104
- setShowLimitModal("stage");
1105
- } else if (hasDeletedServerStages || isContentTypeReassignment) {
1106
- if (hasDeletedServerStages) {
1107
- setSavePrompts((prev) => ({ ...prev, hasDeletedServerStages: true }));
1108
- }
1109
- if (isContentTypeReassignment) {
1110
- setSavePrompts((prev) => ({ ...prev, hasReassignedContentTypes: true }));
1111
- }
1112
- } else {
1113
- await submitForm(data, helpers);
1114
- }
1115
- };
1116
- React__namespace.useEffect(() => {
1117
- if (!isLoadingWorkflow && !isLicenseLoading) {
1118
- if (meta && numberOfWorkflows && meta?.workflowCount > parseInt(numberOfWorkflows, 10)) {
1119
- setShowLimitModal("workflow");
1120
- } else if (currentWorkflow && currentWorkflow.stages && stagesPerWorkflow && currentWorkflow.stages.length > parseInt(stagesPerWorkflow, 10)) {
1121
- setShowLimitModal("stage");
1122
- }
1123
- }
1124
- }, [
1125
- currentWorkflow,
1126
- isLicenseLoading,
1127
- isLoadingWorkflow,
1128
- limits,
1129
- meta,
1130
- numberOfWorkflows,
1131
- stagesPerWorkflow
1132
- ]);
1133
- const initialValues = React__namespace.useMemo(() => {
1134
- if (isCreatingWorkflow || !currentWorkflow) {
1135
- return {
1136
- name: "",
1137
- stages: [],
1138
- contentTypes: [],
1139
- stageRequiredToPublish: ""
1140
- };
1141
- } else {
1142
- return {
1143
- name: currentWorkflow.name,
1144
- stages: addTmpKeysToStages(currentWorkflow.stages),
1145
- contentTypes: currentWorkflow.contentTypes,
1146
- stageRequiredToPublish: currentWorkflow.stageRequiredToPublish?.id.toString() ?? ""
1147
- };
1148
- }
1149
- }, [currentWorkflow, isCreatingWorkflow]);
1150
- if (isLoadingWorkflow) {
1151
- return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Loading, {});
1152
- }
1153
- if (error) {
1154
- return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Error, {});
1155
- }
1156
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1157
- /* @__PURE__ */ jsxRuntime.jsx(Layout.DragLayerRendered, {}),
1158
- /* @__PURE__ */ jsxRuntime.jsx(
1159
- strapiAdmin.Form,
1160
- {
1161
- method: isCreatingWorkflow ? "POST" : "PUT",
1162
- initialValues,
1163
- validationSchema: WORKFLOW_SCHEMA,
1164
- onSubmit: handleSubmit,
1165
- children: ({ modified, isSubmitting, values, setErrors }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1166
- /* @__PURE__ */ jsxRuntime.jsx(
1167
- Layout.Header,
1168
- {
1169
- navigationAction: /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, { fallback: ".." }),
1170
- primaryAction: canUpdate || canCreate ? /* @__PURE__ */ jsxRuntime.jsx(
1171
- designSystem.Button,
1172
- {
1173
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}),
1174
- type: "submit",
1175
- disabled: !modified || isSubmitting || values.stages.length === 0,
1176
- loading: !Boolean(Object.keys(savePrompts).length > 0) && isSubmitting,
1177
- children: formatMessage({
1178
- id: "global.save",
1179
- defaultMessage: "Save"
1180
- })
1181
- }
1182
- ) : null,
1183
- subtitle: formatMessage(
1184
- {
1185
- id: "review-workflows.page.subtitle",
1186
- defaultMessage: "{count, plural, one {# stage} other {# stages}}"
1187
- },
1188
- { count: currentWorkflow?.stages?.length ?? 0 }
1189
- ),
1190
- title: currentWorkflow?.name || formatMessage({
1191
- id: "Settings.review-workflows.create.page.title",
1192
- defaultMessage: "Create Review Workflow"
1193
- })
1194
- }
1195
- ),
1196
- /* @__PURE__ */ jsxRuntime.jsx(Layout.Root, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "stretch", direction: "column", gap: 7, children: [
1197
- /* @__PURE__ */ jsxRuntime.jsx(WorkflowAttributes, { canUpdate: canUpdate || canCreate }),
1198
- /* @__PURE__ */ jsxRuntime.jsx(
1199
- Stages,
1200
- {
1201
- canDelete,
1202
- canUpdate: canUpdate || canCreate,
1203
- isCreating: isCreatingWorkflow
1204
- }
1205
- )
1206
- ] }) }),
1207
- /* @__PURE__ */ jsxRuntime.jsx(
1208
- designSystem.Dialog.Root,
1209
- {
1210
- open: Object.keys(savePrompts).length > 0,
1211
- onOpenChange: handleConfirmClose,
1212
- children: /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.ConfirmDialog, { onConfirm: handleConfirmDeleteDialog(values, { setErrors }), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 5, children: [
1213
- savePrompts.hasDeletedServerStages && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", variant: "omega", children: formatMessage({
1214
- id: "review-workflows.page.delete.confirm.stages.body",
1215
- defaultMessage: "All entries assigned to deleted stages will be moved to the previous stage."
1216
- }) }),
1217
- savePrompts.hasReassignedContentTypes && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", variant: "omega", children: formatMessage(
1218
- {
1219
- id: "review-workflows.page.delete.confirm.contentType.body",
1220
- defaultMessage: "{count} {count, plural, one {content-type} other {content-types}} {count, plural, one {is} other {are}} already mapped to {count, plural, one {another workflow} other {other workflows}}. If you save changes, {count, plural, one {this} other {these}} {count, plural, one {content-type} other {{count} content-types}} will no more be mapped to the {count, plural, one {another workflow} other {other workflows}} and all corresponding information will be removed."
1221
- },
1222
- {
1223
- count: contentTypesFromOtherWorkflows?.filter(
1224
- (contentType) => values.contentTypes.includes(contentType)
1225
- ).length ?? 0
1226
- }
1227
- ) }),
1228
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", variant: "omega", children: formatMessage({
1229
- id: "review-workflows.page.delete.confirm.confirm",
1230
- defaultMessage: "Are you sure you want to save?"
1231
- }) })
1232
- ] }) })
1233
- }
1234
- )
1235
- ] })
1236
- }
1237
- ),
1238
- /* @__PURE__ */ jsxRuntime.jsxs(
1239
- index.LimitsModal.Root,
1240
- {
1241
- open: showLimitModal === "workflow",
1242
- onOpenChange: () => setShowLimitModal(null),
1243
- children: [
1244
- /* @__PURE__ */ jsxRuntime.jsx(index.LimitsModal.Title, { children: formatMessage({
1245
- id: "review-workflows.edit.page.workflows.limit.title",
1246
- defaultMessage: "You’ve reached the limit of workflows in your plan"
1247
- }) }),
1248
- /* @__PURE__ */ jsxRuntime.jsx(index.LimitsModal.Body, { children: formatMessage({
1249
- id: "review-workflows.edit.page.workflows.limit.body",
1250
- defaultMessage: "Delete a workflow or contact Sales to enable more workflows."
1251
- }) })
1252
- ]
1253
- }
1254
- ),
1255
- /* @__PURE__ */ jsxRuntime.jsxs(
1256
- index.LimitsModal.Root,
1257
- {
1258
- open: showLimitModal === "stage",
1259
- onOpenChange: () => setShowLimitModal(null),
1260
- children: [
1261
- /* @__PURE__ */ jsxRuntime.jsx(index.LimitsModal.Title, { children: formatMessage({
1262
- id: "review-workflows.edit.page.stages.limit.title",
1263
- defaultMessage: "You have reached the limit of stages for this workflow in your plan"
1264
- }) }),
1265
- /* @__PURE__ */ jsxRuntime.jsx(index.LimitsModal.Body, { children: formatMessage({
1266
- id: "review-workflows.edit.page.stages.limit.body",
1267
- defaultMessage: "Try deleting some stages or contact Sales to enable more stages."
1268
- }) })
1269
- ]
1270
- }
1271
- )
1272
- ] });
1273
- };
1274
- const addTmpKeysToStages = (data) => {
1275
- const keys = fractionalIndexing.generateNKeysBetween(void 0, void 0, data.length);
1276
- return data.map((datum, index2) => ({
1277
- ...datum,
1278
- __temp_key__: keys[index2]
1279
- }));
1280
- };
1281
- const ProtectedEditPage = () => {
1282
- const permissions = index.useTypedSelector((state) => {
1283
- const {
1284
- create = [],
1285
- update = [],
1286
- read = []
1287
- } = state.admin_app.permissions.settings?.["review-workflows"] ?? {};
1288
- return [...create, ...update, ...read];
1289
- });
1290
- return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Page.Protect, { permissions, children: /* @__PURE__ */ jsxRuntime.jsx(EditPage, {}) });
1291
- };
1292
- exports.ProtectedEditPage = ProtectedEditPage;
1293
- //# sourceMappingURL=id-oOE1bYls.js.map