@strapi/review-workflows 0.0.0-experimental.d23c1d5b0e45dd06ef09977f526c85468be05403 → 0.0.0-experimental.d3cdf79a0d5f803dfeb6d0f055bb2f3b913bb015

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 (96) hide show
  1. package/LICENSE +12 -17
  2. package/dist/_chunks/{Layout-dGg4FA1R.js → Layout-C3IORH2n.js} +14 -24
  3. package/dist/_chunks/Layout-C3IORH2n.js.map +1 -0
  4. package/dist/_chunks/{Layout-facLKucY.mjs → Layout-DNKR5bym.mjs} +16 -23
  5. package/dist/_chunks/Layout-DNKR5bym.mjs.map +1 -0
  6. package/dist/_chunks/{en-xcewH2pC.js → en-CYgjfSep.js} +5 -2
  7. package/dist/_chunks/en-CYgjfSep.js.map +1 -0
  8. package/dist/_chunks/{en-D9ZrQAV6.mjs → en-D9dxziEb.mjs} +5 -2
  9. package/dist/_chunks/en-D9dxziEb.mjs.map +1 -0
  10. package/dist/_chunks/{_id-D4CXKOqG.mjs → id-C9Ku9Br9.mjs} +390 -427
  11. package/dist/_chunks/id-C9Ku9Br9.mjs.map +1 -0
  12. package/dist/_chunks/{_id-B6DgrtpA.js → id-oOE1bYls.js} +395 -435
  13. package/dist/_chunks/id-oOE1bYls.js.map +1 -0
  14. package/dist/_chunks/{index-D7Y0ofdg.mjs → index-ByXbOW-R.mjs} +196 -232
  15. package/dist/_chunks/index-ByXbOW-R.mjs.map +1 -0
  16. package/dist/_chunks/{index-BuKZWpJw.js → index-CmHHjN95.js} +24 -61
  17. package/dist/_chunks/index-CmHHjN95.js.map +1 -0
  18. package/dist/_chunks/{index-QbWLXdZR.mjs → index-CyhaJuJG.mjs} +24 -58
  19. package/dist/_chunks/index-CyhaJuJG.mjs.map +1 -0
  20. package/dist/_chunks/{index-DX8AGcIP.js → index-DMT27jNE.js} +196 -235
  21. package/dist/_chunks/index-DMT27jNE.js.map +1 -0
  22. package/dist/_chunks/{purchase-review-workflows-Ds61D_tk.js → purchase-review-workflows-BxoDFxQ5.js} +8 -7
  23. package/dist/_chunks/purchase-review-workflows-BxoDFxQ5.js.map +1 -0
  24. package/dist/_chunks/{purchase-review-workflows-B-V0sA2I.mjs → purchase-review-workflows-DyFV_H0I.mjs} +9 -8
  25. package/dist/_chunks/purchase-review-workflows-DyFV_H0I.mjs.map +1 -0
  26. package/dist/_chunks/{router-ylD0eA48.mjs → router-BPl2HZMq.mjs} +3 -3
  27. package/dist/_chunks/router-BPl2HZMq.mjs.map +1 -0
  28. package/dist/_chunks/{router-CL62NScV.js → router-vDfGt9bq.js} +3 -3
  29. package/dist/_chunks/router-vDfGt9bq.js.map +1 -0
  30. package/dist/admin/index.js +1 -1
  31. package/dist/admin/index.mjs +1 -1
  32. package/dist/admin/src/components/LimitsModal.d.ts +2 -4
  33. package/dist/admin/src/routes/content-manager/[model]/[id]/components/Panel.d.ts +1 -1
  34. package/dist/admin/src/routes/settings/hooks/useDragAndDrop.d.ts +4 -4
  35. package/dist/admin/src/routes/settings/hooks/useKeyboardDragAndDrop.d.ts +1 -1
  36. package/dist/admin/src/routes/settings/hooks/useReviewWorkflows.d.ts +3 -3
  37. package/dist/admin/src/services/admin.d.ts +2 -2
  38. package/dist/admin/src/services/api.d.ts +2 -3
  39. package/dist/admin/src/services/content-manager.d.ts +7 -7
  40. package/dist/admin/src/services/settings.d.ts +1740 -10
  41. package/dist/admin/src/utils/api.d.ts +4 -19
  42. package/dist/admin/src/utils/cm-hooks.d.ts +1 -1
  43. package/dist/server/index.js +455 -628
  44. package/dist/server/index.js.map +1 -1
  45. package/dist/server/index.mjs +455 -628
  46. package/dist/server/index.mjs.map +1 -1
  47. package/dist/server/src/bootstrap.d.ts.map +1 -1
  48. package/dist/server/src/constants/workflows.d.ts +1 -0
  49. package/dist/server/src/constants/workflows.d.ts.map +1 -1
  50. package/dist/server/src/content-types/index.d.ts +6 -0
  51. package/dist/server/src/content-types/index.d.ts.map +1 -1
  52. package/dist/server/src/content-types/workflow/index.d.ts +6 -0
  53. package/dist/server/src/content-types/workflow/index.d.ts.map +1 -1
  54. package/dist/server/src/controllers/assignees.d.ts.map +1 -1
  55. package/dist/server/src/controllers/index.d.ts +0 -1
  56. package/dist/server/src/controllers/index.d.ts.map +1 -1
  57. package/dist/server/src/controllers/stages.d.ts.map +1 -1
  58. package/dist/server/src/controllers/workflows.d.ts +0 -7
  59. package/dist/server/src/controllers/workflows.d.ts.map +1 -1
  60. package/dist/server/src/index.d.ts +28 -7
  61. package/dist/server/src/index.d.ts.map +1 -1
  62. package/dist/server/src/register.d.ts.map +1 -1
  63. package/dist/server/src/routes/review-workflows.d.ts.map +1 -1
  64. package/dist/server/src/services/assignees.d.ts +8 -4
  65. package/dist/server/src/services/assignees.d.ts.map +1 -1
  66. package/dist/server/src/services/document-service-middleware.d.ts +1 -0
  67. package/dist/server/src/services/document-service-middleware.d.ts.map +1 -1
  68. package/dist/server/src/services/index.d.ts +16 -6
  69. package/dist/server/src/services/index.d.ts.map +1 -1
  70. package/dist/server/src/services/metrics/index.d.ts +4 -4
  71. package/dist/server/src/services/metrics/index.d.ts.map +1 -1
  72. package/dist/server/src/services/metrics/weekly-metrics.d.ts.map +1 -1
  73. package/dist/server/src/services/stages.d.ts +7 -7
  74. package/dist/server/src/services/stages.d.ts.map +1 -1
  75. package/dist/server/src/services/workflows.d.ts.map +1 -1
  76. package/dist/server/src/validation/review-workflows.d.ts +4 -0
  77. package/dist/server/src/validation/review-workflows.d.ts.map +1 -1
  78. package/dist/shared/contracts/review-workflows.d.ts +9 -17
  79. package/dist/shared/contracts/review-workflows.d.ts.map +1 -1
  80. package/package.json +17 -20
  81. package/dist/_chunks/Layout-dGg4FA1R.js.map +0 -1
  82. package/dist/_chunks/Layout-facLKucY.mjs.map +0 -1
  83. package/dist/_chunks/_id-B6DgrtpA.js.map +0 -1
  84. package/dist/_chunks/_id-D4CXKOqG.mjs.map +0 -1
  85. package/dist/_chunks/en-D9ZrQAV6.mjs.map +0 -1
  86. package/dist/_chunks/en-xcewH2pC.js.map +0 -1
  87. package/dist/_chunks/index-BuKZWpJw.js.map +0 -1
  88. package/dist/_chunks/index-D7Y0ofdg.mjs.map +0 -1
  89. package/dist/_chunks/index-DX8AGcIP.js.map +0 -1
  90. package/dist/_chunks/index-QbWLXdZR.mjs.map +0 -1
  91. package/dist/_chunks/purchase-review-workflows-B-V0sA2I.mjs.map +0 -1
  92. package/dist/_chunks/purchase-review-workflows-Ds61D_tk.js.map +0 -1
  93. package/dist/_chunks/router-CL62NScV.js.map +0 -1
  94. package/dist/_chunks/router-ylD0eA48.mjs.map +0 -1
  95. package/strapi-server.js +0 -3
  96. /package/dist/admin/src/routes/settings/{:id.d.ts → id.d.ts} +0 -0
@@ -2,23 +2,21 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { useTracking, useForm, useField, InputRenderer as InputRenderer$1, useNotification, ConfirmDialog, Page, useAPIErrorHandler, useRBAC, Form, BackButton } from "@strapi/admin/strapi-admin";
4
4
  import { useLicenseLimits } from "@strapi/admin/strapi-admin/ee";
5
- import { Box, Typography, Flex, IconButton, MultiSelectOption, useComposedRefs, VisuallyHidden, Accordion, AccordionToggle, AccordionContent, Grid, GridItem, SingleSelect, SingleSelectOption, TextInput, MultiSelect, MultiSelectGroup, useCollator, Button } from "@strapi/design-system";
6
- import { PlusCircle, EyeStriked, More, Drag, Duplicate, Check } from "@strapi/icons";
5
+ import { Box, Typography, Flex, Accordion, MenuItem, Menu, MultiSelectOption, useComposedRefs, VisuallyHidden, IconButton, Grid, Field, SingleSelect, SingleSelectOption, TextInput, MultiSelect, MultiSelectGroup, Dialog, useCollator, Button } from "@strapi/design-system";
6
+ import { PlusCircle, More, Drag, EyeStriked, Duplicate, Check } from "@strapi/icons";
7
7
  import { generateNKeysBetween } from "fractional-indexing";
8
8
  import { useIntl } from "react-intl";
9
- import { useDispatch } from "react-redux";
10
9
  import { useParams, useNavigate } from "react-router-dom";
11
10
  import * as yup from "yup";
12
- import { r as reviewWorkflowsApi, A as AVAILABLE_COLORS, g as getStageColorByHex, u as useGetContentTypesQuery, a as useTypedSelector, C as CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME, b as CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME, L as LimitsModal, i as isBaseQueryError } from "./index-D7Y0ofdg.mjs";
13
- import { D as DRAG_DROP_TYPES, u as useReviewWorkflows, a as DragLayerRendered, H as Header, R as Root } from "./Layout-facLKucY.mjs";
14
- import { MenuItem, Menu } from "@strapi/design-system/v2";
11
+ import { r as reviewWorkflowsApi, A as AVAILABLE_COLORS, g as getStageColorByHex, u as useGetContentTypesQuery, a as useTypedSelector, C as CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME, b as CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME, L as LimitsModal, i as isBaseQueryError } from "./index-ByXbOW-R.mjs";
12
+ import { D as DRAG_DROP_TYPES, u as useReviewWorkflows, a as DragLayerRendered, H as Header, R as Root } from "./Layout-DNKR5bym.mjs";
15
13
  import { getEmptyImage } from "react-dnd-html5-backend";
16
- import styled from "styled-components";
14
+ import { styled } from "styled-components";
17
15
  import { useDrop, useDrag } from "react-dnd";
18
16
  const adminApi = reviewWorkflowsApi.injectEndpoints({
19
17
  endpoints(builder) {
20
18
  return {
21
- getRoles: builder.query({
19
+ getAdminRoles: builder.query({
22
20
  query: () => ({
23
21
  url: `/admin/roles`,
24
22
  method: "GET"
@@ -30,7 +28,7 @@ const adminApi = reviewWorkflowsApi.injectEndpoints({
30
28
  };
31
29
  }
32
30
  });
33
- const { useGetRolesQuery } = adminApi;
31
+ const { useGetAdminRolesQuery } = adminApi;
34
32
  const useKeyboardDragAndDrop = (active, index, { onCancel, onDropItem, onGrabItem, onMoveItem }) => {
35
33
  const [isSelected, setIsSelected] = React.useState(false);
36
34
  const handleMove = (movement) => {
@@ -139,8 +137,7 @@ const useDragAndDrop = (active, {
139
137
  const hoverBoundingRect = objectRef.current?.getBoundingClientRect();
140
138
  const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
141
139
  const clientOffset = monitor.getClientOffset();
142
- if (!clientOffset)
143
- return;
140
+ if (!clientOffset) return;
144
141
  const hoverClientY = clientOffset && clientOffset.y - hoverBoundingRect.top;
145
142
  if (typeof dragIndex === "number" && typeof newIndex === "number") {
146
143
  if (dragIndex === newIndex) {
@@ -193,10 +190,8 @@ const useDragAndDrop = (active, {
193
190
  const getDragDirection = (monitor) => {
194
191
  if (monitor && monitor.isDragging() && !monitor.didDrop() && monitor.getInitialClientOffset() && monitor.getClientOffset()) {
195
192
  const deltaY = monitor.getInitialClientOffset().y - monitor.getClientOffset().y;
196
- if (deltaY > 0)
197
- return DIRECTIONS.UPWARD;
198
- if (deltaY < 0)
199
- return DIRECTIONS.DOWNWARD;
193
+ if (deltaY > 0) return DIRECTIONS.UPWARD;
194
+ if (deltaY < 0) return DIRECTIONS.DOWNWARD;
200
195
  return null;
201
196
  }
202
197
  return null;
@@ -249,74 +244,35 @@ const AddStage = ({ children, ...props }) => {
249
244
  return /* @__PURE__ */ jsx(
250
245
  StyledButton,
251
246
  {
252
- as: "button",
247
+ tag: "button",
253
248
  background: "neutral0",
254
- border: "neutral150",
249
+ borderColor: "neutral150",
255
250
  paddingBottom: 3,
256
251
  paddingLeft: 4,
257
252
  paddingRight: 4,
258
253
  paddingTop: 3,
259
254
  shadow: "filterShadow",
260
255
  ...props,
261
- children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
262
- /* @__PURE__ */ jsx(StyledAddIcon, { "aria-hidden": true }),
263
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral500", children })
264
- ] })
256
+ children: /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: /* @__PURE__ */ jsxs(Flex, { tag: "span", gap: 2, children: [
257
+ /* @__PURE__ */ jsx(PlusCircle, { width: "2.4rem", height: "2.4rem", "aria-hidden": true }),
258
+ children
259
+ ] }) })
265
260
  }
266
261
  );
267
262
  };
268
- const StyledAddIcon = styled(PlusCircle)`
269
- > circle {
270
- fill: ${({ theme }) => theme.colors.neutral150};
271
- }
272
- > path {
273
- fill: ${({ theme }) => theme.colors.neutral600};
274
- }
275
- `;
276
263
  const StyledButton = styled(Box)`
277
264
  border-radius: 26px;
278
-
279
- svg {
280
- height: ${({ theme }) => theme.spaces[6]};
281
- width: ${({ theme }) => theme.spaces[6]};
282
-
283
- > path {
284
- fill: ${({ theme }) => theme.colors.neutral600};
285
- }
286
- }
265
+ color: ${({ theme }) => theme.colors.neutral500};
287
266
 
288
267
  &:hover {
289
- color: ${({ theme }) => theme.colors.primary600} !important;
290
- ${Typography} {
291
- color: ${({ theme }) => theme.colors.primary600} !important;
292
- }
293
-
294
- ${StyledAddIcon} {
295
- > circle {
296
- fill: ${({ theme }) => theme.colors.primary600};
297
- }
298
- > path {
299
- fill: ${({ theme }) => theme.colors.neutral100};
300
- }
301
- }
268
+ color: ${({ theme }) => theme.colors.primary600};
302
269
  }
303
270
 
304
271
  &:active {
305
- ${Typography} {
306
- color: ${({ theme }) => theme.colors.primary600};
307
- }
308
-
309
- ${StyledAddIcon} {
310
- > circle {
311
- fill: ${({ theme }) => theme.colors.primary600};
312
- }
313
- > path {
314
- fill: ${({ theme }) => theme.colors.neutral100};
315
- }
316
- }
272
+ color: ${({ theme }) => theme.colors.primary600};
317
273
  }
318
274
  `;
319
- const Stages = ({ canDelete = true, canUpdate = true, isCreating = false }) => {
275
+ const Stages = ({ canDelete = true, canUpdate = true, isCreating }) => {
320
276
  const { formatMessage } = useIntl();
321
277
  const { trackUsage } = useTracking();
322
278
  const addFieldRow = useForm("Stages", (state) => state.addFieldRow);
@@ -331,35 +287,23 @@ const Stages = ({ canDelete = true, canUpdate = true, isCreating = false }) => {
331
287
  left: "50%",
332
288
  position: "absolute",
333
289
  top: "0",
334
- width: 2,
335
- zIndex: 1
290
+ width: 2
336
291
  }
337
292
  ),
338
- /* @__PURE__ */ jsx(
339
- Flex,
340
- {
341
- direction: "column",
342
- alignItems: "stretch",
343
- gap: 6,
344
- zIndex: 2,
345
- position: "relative",
346
- as: "ol",
347
- children: stages.map((stage, index) => {
348
- return /* @__PURE__ */ jsx(Box, { as: "li", children: /* @__PURE__ */ jsx(
349
- Stage,
350
- {
351
- index,
352
- canDelete: stages.length > 1 && canDelete,
353
- canReorder: stages.length > 1,
354
- canUpdate,
355
- stagesCount: stages.length,
356
- isOpen: isCreating,
357
- ...stage
358
- }
359
- ) }, stage.__temp_key__);
360
- })
361
- }
362
- )
293
+ /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, position: "relative", tag: "ol", children: stages.map((stage, index) => {
294
+ return /* @__PURE__ */ jsx(Box, { tag: "li", children: /* @__PURE__ */ jsx(
295
+ Stage,
296
+ {
297
+ index,
298
+ canDelete: stages.length > 1 && canDelete,
299
+ canReorder: stages.length > 1,
300
+ canUpdate,
301
+ stagesCount: stages.length,
302
+ defaultOpen: !stage.id,
303
+ ...stage
304
+ }
305
+ ) }, stage.__temp_key__);
306
+ }) })
363
307
  ] }),
364
308
  canUpdate && /* @__PURE__ */ jsx(
365
309
  AddStage,
@@ -385,16 +329,15 @@ const Stage = ({
385
329
  canDelete = false,
386
330
  canReorder = false,
387
331
  canUpdate = false,
388
- isOpen: isOpenDefault = false,
389
332
  stagesCount,
390
333
  name,
391
334
  permissions,
392
- color
335
+ color,
336
+ defaultOpen
393
337
  }) => {
394
338
  const [liveText, setLiveText] = React.useState();
395
339
  const { formatMessage } = useIntl();
396
340
  const { trackUsage } = useTracking();
397
- const [isOpen, setIsOpen] = React.useState(isOpenDefault);
398
341
  const stageErrors = useForm("Stages", (state) => state.errors.stages);
399
342
  const error = stageErrors?.[index];
400
343
  const addFieldRow = useForm("Stage", (state) => state.addFieldRow);
@@ -476,7 +419,8 @@ const Stage = ({
476
419
  const handleCloneClick = () => {
477
420
  addFieldRow("stages", { name, color, permissions });
478
421
  };
479
- return /* @__PURE__ */ jsxs(Box, { ref: (ref) => composedRef(ref), children: [
422
+ const id = React.useId();
423
+ return /* @__PURE__ */ jsxs(Box, { ref: composedRef, shadow: "tableShadow", children: [
480
424
  liveText && /* @__PURE__ */ jsx(VisuallyHidden, { "aria-live": "assertive", children: liveText }),
481
425
  isDragging ? /* @__PURE__ */ jsx(
482
426
  Box,
@@ -487,74 +431,61 @@ const Stage = ({
487
431
  borderWidth: "1px",
488
432
  display: "block",
489
433
  hasRadius: true,
490
- padding: 6,
491
- shadow: "tableShadow"
434
+ padding: 6
492
435
  }
493
- ) : /* @__PURE__ */ jsxs(
494
- Accordion,
436
+ ) : /* @__PURE__ */ jsx(
437
+ AccordionRoot,
495
438
  {
496
- size: "S",
497
- variant: "primary",
498
- onToggle: () => {
499
- setIsOpen(!isOpen);
500
- if (!isOpen) {
439
+ onValueChange: (value) => {
440
+ if (value) {
501
441
  trackUsage("willEditStage");
502
442
  }
503
443
  },
504
- expanded: isOpen,
505
- shadow: "tableShadow",
506
- error: Object.values(error ?? {})[0],
507
- hasErrorMessage: false,
508
- children: [
509
- /* @__PURE__ */ jsx(
510
- AccordionToggle,
511
- {
512
- title: name,
513
- togglePosition: "left",
514
- action: (canDelete || canUpdate) && /* @__PURE__ */ jsxs(Flex, { children: [
515
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
516
- /* @__PURE__ */ jsxs(ContextMenuTrigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
517
- /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
518
- /* @__PURE__ */ jsx(VisuallyHidden, { as: "span", children: formatMessage({
519
- id: "[tbdb].components.DynamicZone.more-actions",
520
- defaultMessage: "More actions"
521
- }) })
522
- ] }),
523
- /* @__PURE__ */ jsx(Menu.Content, { popoverPlacement: "bottom-end", zIndex: 2, children: /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
524
- canUpdate && /* @__PURE__ */ jsx(MenuItem, { onClick: handleCloneClick, children: formatMessage({
525
- id: "Settings.review-workflows.stage.delete",
526
- defaultMessage: "Duplicate stage"
527
- }) }),
528
- canDelete && /* @__PURE__ */ jsx(DeleteMenuItem, { onClick: () => removeFieldRow("stages", index), children: formatMessage({
529
- id: "Settings.review-workflows.stage.delete",
530
- defaultMessage: "Delete"
531
- }) })
532
- ] }) })
444
+ defaultValue: defaultOpen ? id : void 0,
445
+ $error: Object.values(error ?? {}).length > 0,
446
+ children: /* @__PURE__ */ jsxs(Accordion.Item, { value: id, children: [
447
+ /* @__PURE__ */ jsxs(Accordion.Header, { children: [
448
+ /* @__PURE__ */ jsx(Accordion.Trigger, { children: name }),
449
+ /* @__PURE__ */ jsx(Accordion.Actions, { children: canDelete || canUpdate ? /* @__PURE__ */ jsxs(Fragment, { children: [
450
+ /* @__PURE__ */ jsxs(Menu.Root, { children: [
451
+ /* @__PURE__ */ jsxs(ContextMenuTrigger, { size: "S", endIcon: null, paddingLeft: 2, paddingRight: 2, children: [
452
+ /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
453
+ /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage({
454
+ id: "[tbdb].components.DynamicZone.more-actions",
455
+ defaultMessage: "More actions"
456
+ }) })
533
457
  ] }),
534
- canUpdate && /* @__PURE__ */ jsx(
535
- DragIconButton,
536
- {
537
- background: "transparent",
538
- forwardedAs: "div",
539
- hasRadius: true,
540
- role: "button",
541
- noBorder: true,
542
- tabIndex: 0,
543
- "data-handler-id": handlerId,
544
- ref: dragRef,
545
- label: formatMessage({
546
- id: "Settings.review-workflows.stage.drag",
547
- defaultMessage: "Drag"
548
- }),
549
- onClick: (e) => e.stopPropagation(),
550
- onKeyDown: handleKeyDown,
551
- children: /* @__PURE__ */ jsx(Drag, {})
552
- }
553
- )
554
- ] })
555
- }
556
- ),
557
- /* @__PURE__ */ jsx(AccordionContent, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsx(Grid, { gap: 4, children: [
458
+ /* @__PURE__ */ jsx(Menu.Content, { popoverPlacement: "bottom-end", zIndex: 2, children: /* @__PURE__ */ jsxs(Menu.SubRoot, { children: [
459
+ canUpdate && /* @__PURE__ */ jsx(MenuItem, { onClick: handleCloneClick, children: formatMessage({
460
+ id: "Settings.review-workflows.stage.delete",
461
+ defaultMessage: "Duplicate stage"
462
+ }) }),
463
+ canDelete && /* @__PURE__ */ jsx(DeleteMenuItem, { onClick: () => removeFieldRow("stages", index), children: formatMessage({
464
+ id: "Settings.review-workflows.stage.delete",
465
+ defaultMessage: "Delete"
466
+ }) })
467
+ ] }) })
468
+ ] }),
469
+ canUpdate && /* @__PURE__ */ jsx(
470
+ IconButton,
471
+ {
472
+ background: "transparent",
473
+ hasRadius: true,
474
+ variant: "ghost",
475
+ "data-handler-id": handlerId,
476
+ ref: dragRef,
477
+ label: formatMessage({
478
+ id: "Settings.review-workflows.stage.drag",
479
+ defaultMessage: "Drag"
480
+ }),
481
+ onClick: (e) => e.stopPropagation(),
482
+ onKeyDown: handleKeyDown,
483
+ children: /* @__PURE__ */ jsx(Drag, {})
484
+ }
485
+ )
486
+ ] }) : null })
487
+ ] }),
488
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsx(Grid.Root, { gap: 4, padding: 6, children: [
558
489
  {
559
490
  disabled: !canUpdate,
560
491
  label: formatMessage({
@@ -592,12 +523,16 @@ const Stage = ({
592
523
  size: 6,
593
524
  type: "permissions"
594
525
  }
595
- ].map(({ size, ...field }) => /* @__PURE__ */ jsx(GridItem, { col: size, children: /* @__PURE__ */ jsx(InputRenderer, { ...field }) }, field.name)) }) })
596
- ]
526
+ ].map(({ size, ...field }) => /* @__PURE__ */ jsx(Grid.Item, { col: size, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(InputRenderer, { ...field }) }, field.name)) }) })
527
+ ] })
597
528
  }
598
529
  )
599
530
  ] });
600
531
  };
532
+ const AccordionRoot = styled(Accordion.Root)`
533
+ border: 1px solid
534
+ ${({ theme, $error }) => $error ? theme.colors.danger600 : theme.colors.neutral200};
535
+ `;
601
536
  const DeleteMenuItem = styled(MenuItem)`
602
537
  color: ${({ theme }) => theme.colors.danger600};
603
538
  `;
@@ -611,22 +546,6 @@ const ContextMenuTrigger = styled(Menu.Trigger)`
611
546
  font-size: 0;
612
547
  }
613
548
  `;
614
- const DragIconButton = styled(IconButton)`
615
- align-items: center;
616
- border-radius: ${({ theme }) => theme.borderRadius};
617
- display: flex;
618
- justify-content: center;
619
-
620
- &:hover,
621
- &:focus {
622
- background-color: ${({ theme }) => theme.colors.neutral100};
623
- }
624
-
625
- svg {
626
- height: auto;
627
- width: ${({ theme }) => theme.spaces[3]};
628
- }
629
- `;
630
549
  const InputRenderer = (props) => {
631
550
  switch (props.type) {
632
551
  case "color":
@@ -652,54 +571,55 @@ const ColorSelector = ({ disabled, label, name, required }) => {
652
571
  color: hex
653
572
  }));
654
573
  const { themeColorName } = getStageColorByHex(value) ?? {};
655
- return /* @__PURE__ */ jsx(
656
- SingleSelect,
657
- {
658
- disabled,
659
- error,
660
- required,
661
- label,
662
- onChange: (v) => {
663
- onChange(name, v.toString());
664
- },
665
- value: value?.toUpperCase(),
666
- startIcon: /* @__PURE__ */ jsx(
667
- Flex,
668
- {
669
- as: "span",
670
- height: 2,
671
- background: value,
672
- borderColor: themeColorName === "neutral0" ? "neutral150" : "transparent",
673
- hasRadius: true,
674
- shrink: 0,
675
- width: 2
676
- }
677
- ),
678
- children: colorOptions.map(({ value: value2, label: label2, color }) => {
679
- const { themeColorName: themeColorName2 } = getStageColorByHex(color) || {};
680
- return /* @__PURE__ */ jsx(
681
- SingleSelectOption,
574
+ return /* @__PURE__ */ jsxs(Field.Root, { error, name, required, children: [
575
+ /* @__PURE__ */ jsx(Field.Label, { children: label }),
576
+ /* @__PURE__ */ jsx(
577
+ SingleSelect,
578
+ {
579
+ disabled,
580
+ onChange: (v) => {
581
+ onChange(name, v.toString());
582
+ },
583
+ value: value?.toUpperCase(),
584
+ startIcon: /* @__PURE__ */ jsx(
585
+ Flex,
682
586
  {
683
- value: value2,
684
- startIcon: /* @__PURE__ */ jsx(
685
- Flex,
686
- {
687
- as: "span",
688
- height: 2,
689
- background: color,
690
- borderColor: themeColorName2 === "neutral0" ? "neutral150" : "transparent",
691
- hasRadius: true,
692
- shrink: 0,
693
- width: 2
694
- }
695
- ),
696
- children: label2
697
- },
698
- value2
699
- );
700
- })
701
- }
702
- );
587
+ tag: "span",
588
+ height: 2,
589
+ background: value,
590
+ borderColor: themeColorName === "neutral0" ? "neutral150" : "transparent",
591
+ hasRadius: true,
592
+ shrink: 0,
593
+ width: 2
594
+ }
595
+ ),
596
+ children: colorOptions.map(({ value: value2, label: label2, color }) => {
597
+ const { themeColorName: themeColorName2 } = getStageColorByHex(color) || {};
598
+ return /* @__PURE__ */ jsx(
599
+ SingleSelectOption,
600
+ {
601
+ value: value2,
602
+ startIcon: /* @__PURE__ */ jsx(
603
+ Flex,
604
+ {
605
+ tag: "span",
606
+ height: 2,
607
+ background: color,
608
+ borderColor: themeColorName2 === "neutral0" ? "neutral150" : "transparent",
609
+ hasRadius: true,
610
+ shrink: 0,
611
+ width: 2
612
+ }
613
+ ),
614
+ children: label2
615
+ },
616
+ value2
617
+ );
618
+ })
619
+ }
620
+ ),
621
+ /* @__PURE__ */ jsx(Field.Error, {})
622
+ ] });
703
623
  };
704
624
  const PermissionsField = ({ disabled, name, placeholder, required }) => {
705
625
  const { formatMessage } = useIntl();
@@ -708,57 +628,65 @@ const PermissionsField = ({ disabled, name, placeholder, required }) => {
708
628
  const { value = [], error, onChange } = useField(name);
709
629
  const allStages = useForm("PermissionsField", (state) => state.values.stages);
710
630
  const onFormValueChange = useForm("PermissionsField", (state) => state.onChange);
711
- const { data: roles = [], isLoading } = useGetRolesQuery();
631
+ const rolesErrorCount = React.useRef(0);
632
+ const { data: roles = [], isLoading, error: getRolesError } = useGetAdminRolesQuery();
712
633
  const filteredRoles = roles?.filter((role) => role.code !== "strapi-super-admin") ?? [];
713
634
  React.useEffect(() => {
714
- if (!isLoading && roles.length === 0) {
635
+ if (!isLoading && getRolesError && "status" in getRolesError && getRolesError.status == 403 && rolesErrorCount.current === 0) {
636
+ rolesErrorCount.current = 1;
715
637
  toggleNotification({
716
638
  blockTransition: true,
717
639
  type: "danger",
718
640
  message: formatMessage({
719
641
  id: "review-workflows.stage.permissions.noPermissions.description",
720
- defaultMessage: "You don’t have the permission to see roles"
642
+ defaultMessage: "You don’t have the permission to see roles. Contact your administrator."
721
643
  })
722
644
  });
723
645
  }
724
- }, [formatMessage, isLoading, roles, toggleNotification]);
646
+ }, [formatMessage, isLoading, roles, toggleNotification, getRolesError]);
725
647
  if (!isLoading && filteredRoles.length === 0) {
726
- return /* @__PURE__ */ jsx(
727
- TextInput,
648
+ return /* @__PURE__ */ jsxs(
649
+ Field.Root,
728
650
  {
729
- disabled: true,
730
651
  name,
731
652
  hint: formatMessage({
732
653
  id: "Settings.review-workflows.stage.permissions.noPermissions.description",
733
654
  defaultMessage: "You don’t have the permission to see roles"
734
655
  }),
735
- label: formatMessage({
736
- id: "Settings.review-workflows.stage.permissions.label",
737
- defaultMessage: "Roles that can change this stage"
738
- }),
739
- placeholder: formatMessage({
740
- id: "components.NotAllowedInput.text",
741
- defaultMessage: "No permissions to see this field"
742
- }),
743
656
  required,
744
- startAction: /* @__PURE__ */ jsx(StyledIcon, {}),
745
- type: "text",
746
- value: ""
657
+ children: [
658
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
659
+ id: "Settings.review-workflows.stage.permissions.label",
660
+ defaultMessage: "Roles that can change this stage"
661
+ }) }),
662
+ /* @__PURE__ */ jsx(
663
+ TextInput,
664
+ {
665
+ disabled: true,
666
+ placeholder: formatMessage({
667
+ id: "components.NotAllowedInput.text",
668
+ defaultMessage: "No permissions to see this field"
669
+ }),
670
+ startAction: /* @__PURE__ */ jsx(EyeStriked, { fill: "neutral600" }),
671
+ type: "text",
672
+ value: ""
673
+ }
674
+ ),
675
+ /* @__PURE__ */ jsx(Field.Hint, {})
676
+ ]
747
677
  }
748
678
  );
749
679
  }
750
- return /* @__PURE__ */ jsxs(Fragment, { children: [
751
- /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-end", gap: 3, children: [
752
- /* @__PURE__ */ jsx(PermissionWrapper, { grow: 1, children: /* @__PURE__ */ jsx(
680
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-end", gap: 3, children: [
681
+ /* @__PURE__ */ jsx(PermissionWrapper, { grow: 1, children: /* @__PURE__ */ jsxs(Field.Root, { error, name, required: true, children: [
682
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
683
+ id: "Settings.review-workflows.stage.permissions.label",
684
+ defaultMessage: "Roles that can change this stage"
685
+ }) }),
686
+ /* @__PURE__ */ jsx(
753
687
  MultiSelect,
754
688
  {
755
689
  disabled,
756
- error,
757
- id: name,
758
- label: formatMessage({
759
- id: "Settings.review-workflows.stage.permissions.label",
760
- defaultMessage: "Roles that can change this stage"
761
- }),
762
690
  onChange: (values) => {
763
691
  const permissions = values.map((value2) => ({
764
692
  role: parseInt(value2, 10),
@@ -767,7 +695,6 @@ const PermissionsField = ({ disabled, name, placeholder, required }) => {
767
695
  onChange(name, permissions);
768
696
  },
769
697
  placeholder,
770
- required: true,
771
698
  value: value.map((permission) => `${permission.role}`),
772
699
  withTags: true,
773
700
  children: /* @__PURE__ */ jsx(
@@ -784,58 +711,52 @@ const PermissionsField = ({ disabled, name, placeholder, required }) => {
784
711
  }
785
712
  )
786
713
  }
787
- ) }),
788
- /* @__PURE__ */ jsx(
714
+ ),
715
+ /* @__PURE__ */ jsx(Field.Error, {})
716
+ ] }) }),
717
+ /* @__PURE__ */ jsxs(Dialog.Root, { open: isApplyAllConfirmationOpen, onOpenChange: setIsApplyAllConfirmationOpen, children: [
718
+ /* @__PURE__ */ jsx(Dialog.Trigger, { children: /* @__PURE__ */ jsx(
789
719
  IconButton,
790
720
  {
791
721
  disabled,
792
- icon: /* @__PURE__ */ jsx(Duplicate, {}),
793
722
  label: formatMessage({
794
723
  id: "Settings.review-workflows.stage.permissions.apply.label",
795
724
  defaultMessage: "Apply to all stages"
796
725
  }),
797
726
  size: "L",
798
- variant: "secondary",
799
- onClick: () => setIsApplyAllConfirmationOpen(true)
727
+ children: /* @__PURE__ */ jsx(Duplicate, {})
728
+ }
729
+ ) }),
730
+ /* @__PURE__ */ jsx(
731
+ ConfirmDialog,
732
+ {
733
+ onConfirm: () => {
734
+ onFormValueChange(
735
+ "stages",
736
+ allStages.map((stage) => ({
737
+ ...stage,
738
+ permissions: value
739
+ }))
740
+ );
741
+ setIsApplyAllConfirmationOpen(false);
742
+ toggleNotification({
743
+ type: "success",
744
+ message: formatMessage({
745
+ id: "Settings.review-workflows.page.edit.confirm.stages.permissions.copy.success",
746
+ defaultMessage: "Applied roles to all other stages of the workflow"
747
+ })
748
+ });
749
+ },
750
+ variant: "default",
751
+ children: formatMessage({
752
+ id: "Settings.review-workflows.page.edit.confirm.stages.permissions.copy",
753
+ defaultMessage: "Roles that can change that stage will be applied to all the other stages."
754
+ })
800
755
  }
801
756
  )
802
- ] }),
803
- /* @__PURE__ */ jsx(
804
- ConfirmDialog,
805
- {
806
- isOpen: isApplyAllConfirmationOpen,
807
- onClose: () => setIsApplyAllConfirmationOpen(false),
808
- onConfirm: () => {
809
- onFormValueChange(
810
- "stages",
811
- allStages.map((stage) => ({
812
- ...stage,
813
- permissions: value
814
- }))
815
- );
816
- setIsApplyAllConfirmationOpen(false);
817
- toggleNotification({
818
- type: "success",
819
- message: formatMessage({
820
- id: "Settings.review-workflows.page.edit.confirm.stages.permissions.copy.success",
821
- defaultMessage: "Applied roles to all other stages of the workflow"
822
- })
823
- });
824
- },
825
- variant: "default",
826
- children: formatMessage({
827
- id: "Settings.review-workflows.page.edit.confirm.stages.permissions.copy",
828
- defaultMessage: "Roles that can change that stage will be applied to all the other stages."
829
- })
830
- }
831
- )
832
- ] });
757
+ ] })
758
+ ] }) });
833
759
  };
834
- const StyledIcon = styled(EyeStriked)`
835
- & > path {
836
- fill: ${({ theme }) => theme.colors.neutral600};
837
- }
838
- `;
839
760
  const NestedOption$1 = styled(MultiSelectOption)`
840
761
  padding-left: ${({ theme }) => theme.spaces[7]};
841
762
  `;
@@ -846,8 +767,8 @@ const PermissionWrapper = styled(Flex)`
846
767
  `;
847
768
  const WorkflowAttributes = ({ canUpdate = true }) => {
848
769
  const { formatMessage } = useIntl();
849
- return /* @__PURE__ */ jsxs(Grid, { background: "neutral0", hasRadius: true, gap: 4, padding: 6, shadow: "tableShadow", children: [
850
- /* @__PURE__ */ jsx(GridItem, { col: 6, children: /* @__PURE__ */ jsx(
770
+ return /* @__PURE__ */ jsxs(Grid.Root, { background: "neutral0", hasRadius: true, gap: 4, padding: 6, shadow: "tableShadow", children: [
771
+ /* @__PURE__ */ jsx(Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(
851
772
  InputRenderer$1,
852
773
  {
853
774
  disabled: !canUpdate,
@@ -860,7 +781,8 @@ const WorkflowAttributes = ({ canUpdate = true }) => {
860
781
  type: "string"
861
782
  }
862
783
  ) }),
863
- /* @__PURE__ */ jsx(GridItem, { col: 6, children: /* @__PURE__ */ jsx(ContentTypesSelector, { disabled: !canUpdate }) })
784
+ /* @__PURE__ */ jsx(Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(ContentTypesSelector, { disabled: !canUpdate }) }),
785
+ /* @__PURE__ */ jsx(Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(StageSelector, { disabled: !canUpdate }) })
864
786
  ] });
865
787
  };
866
788
  const ContentTypesSelector = ({ disabled }) => {
@@ -881,81 +803,82 @@ const ContentTypesSelector = ({ disabled }) => {
881
803
  label: contentType.info.displayName,
882
804
  value: contentType.uid
883
805
  }));
884
- return /* @__PURE__ */ jsx(
885
- MultiSelect,
886
- {
887
- customizeContent: (value2) => formatMessage(
888
- {
889
- id: "Settings.review-workflows.workflow.contentTypes.displayValue",
890
- defaultMessage: "{count} {count, plural, one {content type} other {content types}} selected"
891
- },
892
- { count: value2?.length }
893
- ),
894
- disabled: isDisabled,
895
- error,
896
- label: formatMessage({
897
- id: "Settings.review-workflows.workflow.contentTypes.label",
898
- defaultMessage: "Associated to"
899
- }),
900
- onChange: (values) => {
901
- onChange("contentTypes", values);
902
- },
903
- value,
904
- placeholder: formatMessage({
905
- id: "Settings.review-workflows.workflow.contentTypes.placeholder",
906
- defaultMessage: "Select"
907
- }),
908
- children: [
909
- ...collectionTypes.length > 0 ? [
910
- {
911
- label: formatMessage({
912
- id: "Settings.review-workflows.workflow.contentTypes.collectionTypes.label",
913
- defaultMessage: "Collection Types"
914
- }),
915
- children: collectionTypes
916
- }
917
- ] : [],
918
- ...singleTypes.length > 0 ? [
919
- {
920
- label: formatMessage({
921
- id: "Settings.review-workflows.workflow.contentTypes.singleTypes.label",
922
- defaultMessage: "Single Types"
923
- }),
924
- children: singleTypes
925
- }
926
- ] : []
927
- ].map((opt) => {
928
- return /* @__PURE__ */ jsx(
929
- MultiSelectGroup,
806
+ return /* @__PURE__ */ jsxs(Field.Root, { error, name: "contentTypes", children: [
807
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
808
+ id: "Settings.review-workflows.workflow.contentTypes.label",
809
+ defaultMessage: "Associated to"
810
+ }) }),
811
+ /* @__PURE__ */ jsx(
812
+ MultiSelect,
813
+ {
814
+ customizeContent: (value2) => formatMessage(
930
815
  {
931
- label: opt.label,
932
- values: opt.children.map((child) => child.value.toString()),
933
- children: opt.children.map((child) => {
934
- const { name: assignedWorkflowName } = workflows?.find(
935
- (workflow) => (currentWorkflow && workflow.id !== currentWorkflow.id || !currentWorkflow) && workflow.contentTypes.includes(child.value)
936
- ) ?? {};
937
- return /* @__PURE__ */ jsx(NestedOption, { value: child.value, children: /* @__PURE__ */ jsx(Typography, {
938
- // @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
939
- children: formatMessage(
940
- {
941
- id: "Settings.review-workflows.workflow.contentTypes.assigned.notice",
942
- defaultMessage: "{label} {name, select, undefined {} other {<i>(assigned to <em>{name}</em> workflow)</i>}}"
943
- },
944
- {
945
- label: child.label,
946
- name: assignedWorkflowName,
947
- em: (...children) => /* @__PURE__ */ jsx(Typography, { as: "em", fontWeight: "bold", children }),
948
- i: (...children) => /* @__PURE__ */ jsx(ContentTypeTakeNotice, { children })
949
- }
950
- )
951
- }) }, child.value);
952
- })
816
+ id: "Settings.review-workflows.workflow.contentTypes.displayValue",
817
+ defaultMessage: "{count} {count, plural, one {content type} other {content types}} selected"
953
818
  },
954
- opt.label
955
- );
956
- })
957
- }
958
- );
819
+ { count: value2?.length }
820
+ ),
821
+ disabled: isDisabled,
822
+ onChange: (values) => {
823
+ onChange("contentTypes", values);
824
+ },
825
+ value,
826
+ placeholder: formatMessage({
827
+ id: "Settings.review-workflows.workflow.contentTypes.placeholder",
828
+ defaultMessage: "Select"
829
+ }),
830
+ children: [
831
+ ...collectionTypes.length > 0 ? [
832
+ {
833
+ label: formatMessage({
834
+ id: "Settings.review-workflows.workflow.contentTypes.collectionTypes.label",
835
+ defaultMessage: "Collection Types"
836
+ }),
837
+ children: collectionTypes
838
+ }
839
+ ] : [],
840
+ ...singleTypes.length > 0 ? [
841
+ {
842
+ label: formatMessage({
843
+ id: "Settings.review-workflows.workflow.contentTypes.singleTypes.label",
844
+ defaultMessage: "Single Types"
845
+ }),
846
+ children: singleTypes
847
+ }
848
+ ] : []
849
+ ].map((opt) => {
850
+ return /* @__PURE__ */ jsx(
851
+ MultiSelectGroup,
852
+ {
853
+ label: opt.label,
854
+ values: opt.children.map((child) => child.value.toString()),
855
+ children: opt.children.map((child) => {
856
+ const { name: assignedWorkflowName } = workflows?.find(
857
+ (workflow) => (currentWorkflow && workflow.id !== currentWorkflow.id || !currentWorkflow) && workflow.contentTypes.includes(child.value)
858
+ ) ?? {};
859
+ return /* @__PURE__ */ jsx(NestedOption, { value: child.value, children: /* @__PURE__ */ jsx(Typography, {
860
+ // @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
861
+ children: formatMessage(
862
+ {
863
+ id: "Settings.review-workflows.workflow.contentTypes.assigned.notice",
864
+ defaultMessage: "{label} {name, select, undefined {} other {<i>(assigned to <em>{name}</em> workflow)</i>}}"
865
+ },
866
+ {
867
+ label: child.label,
868
+ name: assignedWorkflowName,
869
+ em: (...children) => /* @__PURE__ */ jsx(Typography, { tag: "em", fontWeight: "bold", children }),
870
+ i: (...children) => /* @__PURE__ */ jsx(ContentTypeTakeNotice, { children })
871
+ }
872
+ )
873
+ }) }, child.value);
874
+ })
875
+ },
876
+ opt.label
877
+ );
878
+ })
879
+ }
880
+ )
881
+ ] });
959
882
  };
960
883
  const NestedOption = styled(MultiSelectOption)`
961
884
  padding-left: ${({ theme }) => theme.spaces[7]};
@@ -963,15 +886,63 @@ const NestedOption = styled(MultiSelectOption)`
963
886
  const ContentTypeTakeNotice = styled(Typography)`
964
887
  font-style: italic;
965
888
  `;
889
+ const StageSelector = ({ disabled }) => {
890
+ const { value: stages = [] } = useField("stages");
891
+ const { formatMessage } = useIntl();
892
+ const { error, value, onChange } = useField("stageRequiredToPublish");
893
+ const validStages = stages.filter((stage) => stage.name);
894
+ return /* @__PURE__ */ jsxs(
895
+ Field.Root,
896
+ {
897
+ error,
898
+ name: "stageRequiredToPublish",
899
+ hint: formatMessage({
900
+ id: "settings.review-workflows.workflow.stageRequiredToPublish.hint",
901
+ defaultMessage: "Prevents entries from being published if they are not at the required stage."
902
+ }),
903
+ children: [
904
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
905
+ id: "settings.review-workflows.workflow.stageRequiredToPublish.label",
906
+ defaultMessage: "Required stage for publishing"
907
+ }) }),
908
+ /* @__PURE__ */ jsxs(
909
+ SingleSelect,
910
+ {
911
+ disabled,
912
+ onChange: (value2) => {
913
+ onChange("stageRequiredToPublish", value2);
914
+ },
915
+ value,
916
+ children: [
917
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "", children: formatMessage({
918
+ id: "settings.review-workflows.workflow.stageRequiredToPublish.any",
919
+ defaultMessage: "Any stage"
920
+ }) }),
921
+ validStages.map((stage, i) => /* @__PURE__ */ jsx(
922
+ SingleSelectOption,
923
+ {
924
+ value: stage.id?.toString() || stage.__temp_key__,
925
+ children: stage.name
926
+ },
927
+ `requiredToPublishStage-${stage.id || stage.__temp_key__}`
928
+ ))
929
+ ]
930
+ }
931
+ ),
932
+ /* @__PURE__ */ jsx(Field.Hint, {})
933
+ ]
934
+ }
935
+ );
936
+ };
966
937
  const WORKFLOW_SCHEMA = yup.object({
967
938
  contentTypes: yup.array().of(yup.string()),
968
939
  name: yup.string().max(255, {
969
940
  id: "review-workflows.validation.name.max-length",
970
941
  defaultMessage: "Name can not be longer than 255 characters"
971
- }).required(),
942
+ }).required().nullable(),
972
943
  stages: yup.array().of(
973
944
  yup.object().shape({
974
- name: yup.string().required({
945
+ name: yup.string().nullable().required({
975
946
  id: "review-workflows.validation.stage.name",
976
947
  defaultMessage: "Name is required"
977
948
  }).max(255, {
@@ -988,7 +959,7 @@ const WORKFLOW_SCHEMA = yup.object({
988
959
  return stages.filter((stage) => stage.name === stageName).length === 1;
989
960
  }
990
961
  ),
991
- color: yup.string().required({
962
+ color: yup.string().nullable().required({
992
963
  id: "review-workflows.validation.stage.color",
993
964
  defaultMessage: "Color is required"
994
965
  }).matches(/^#(?:[0-9a-fA-F]{3}){1,2}$/i),
@@ -1005,7 +976,8 @@ const WORKFLOW_SCHEMA = yup.object({
1005
976
  })
1006
977
  ).strict()
1007
978
  })
1008
- ).min(1)
979
+ ).min(1),
980
+ stageRequiredToPublish: yup.string().nullable()
1009
981
  });
1010
982
  const EditPage = () => {
1011
983
  const { id = "" } = useParams();
@@ -1014,7 +986,6 @@ const EditPage = () => {
1014
986
  const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
1015
987
  const navigate = useNavigate();
1016
988
  const { toggleNotification } = useNotification();
1017
- const dispatch = useDispatch();
1018
989
  const {
1019
990
  isLoading: isLoadingWorkflow,
1020
991
  meta,
@@ -1022,7 +993,7 @@ const EditPage = () => {
1022
993
  error,
1023
994
  update,
1024
995
  create
1025
- } = useReviewWorkflows({ id: isCreatingWorkflow ? void 0 : id });
996
+ } = useReviewWorkflows();
1026
997
  const permissions = useTypedSelector(
1027
998
  (state) => state.admin_app.permissions["settings"]?.["review-workflows"]
1028
999
  );
@@ -1039,13 +1010,17 @@ const EditPage = () => {
1039
1010
  const stagesPerWorkflow = limits?.[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME];
1040
1011
  const submitForm = async (data, helpers) => {
1041
1012
  try {
1013
+ const { stageRequiredToPublish, ...rest } = data;
1014
+ const stageRequiredToPublishName = stageRequiredToPublish === "" ? null : rest.stages.find(
1015
+ (stage) => stage.id === Number(stageRequiredToPublish) || stage.__temp_key__ === stageRequiredToPublish
1016
+ )?.name;
1042
1017
  if (!isCreatingWorkflow) {
1043
1018
  const res = await update(id, {
1044
- ...data,
1019
+ ...rest,
1045
1020
  // compare permissions of stages and only submit them if at least one has
1046
1021
  // changed; this enables partial updates e.g. for users who don't have
1047
1022
  // permissions to see roles
1048
- stages: data.stages.map((stage) => {
1023
+ stages: rest.stages.map((stage) => {
1049
1024
  let hasUpdatedPermissions = true;
1050
1025
  const serverStage = currentWorkflow?.stages?.find(
1051
1026
  (serverStage2) => serverStage2.id === stage?.id
@@ -1061,40 +1036,21 @@ const EditPage = () => {
1061
1036
  ...stage,
1062
1037
  permissions: hasUpdatedPermissions ? stage.permissions : void 0
1063
1038
  };
1064
- })
1039
+ }),
1040
+ stageRequiredToPublishName
1065
1041
  });
1066
1042
  if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1067
1043
  helpers.setErrors(formatValidationErrors(res.error));
1068
- } else if ("data" in res) {
1069
- for (const uid of res.data.contentTypes) {
1070
- dispatch({
1071
- type: "contentManagerApi/invalidateTags",
1072
- payload: [
1073
- {
1074
- type: "ContentTypesConfiguration",
1075
- id: uid
1076
- }
1077
- ]
1078
- });
1079
- }
1080
1044
  }
1081
1045
  } else {
1082
- const res = await create(data);
1046
+ const res = await create({
1047
+ ...rest,
1048
+ stageRequiredToPublishName
1049
+ });
1083
1050
  if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1084
1051
  helpers.setErrors(formatValidationErrors(res.error));
1085
1052
  } else if ("data" in res) {
1086
- for (const uid of res.data.contentTypes) {
1087
- dispatch({
1088
- type: "contentManagerApi/invalidateTags",
1089
- payload: [
1090
- {
1091
- type: "ContentTypesConfiguration",
1092
- id: uid
1093
- }
1094
- ]
1095
- });
1096
- }
1097
- navigate(`../${res.data.id}`);
1053
+ navigate(`../${res.data.id}`, { replace: true });
1098
1054
  }
1099
1055
  }
1100
1056
  } catch (error2) {
@@ -1158,13 +1114,15 @@ const EditPage = () => {
1158
1114
  return {
1159
1115
  name: "",
1160
1116
  stages: [],
1161
- contentTypes: []
1117
+ contentTypes: [],
1118
+ stageRequiredToPublish: ""
1162
1119
  };
1163
1120
  } else {
1164
1121
  return {
1165
1122
  name: currentWorkflow.name,
1166
1123
  stages: addTmpKeysToStages(currentWorkflow.stages),
1167
- contentTypes: currentWorkflow.contentTypes
1124
+ contentTypes: currentWorkflow.contentTypes,
1125
+ stageRequiredToPublish: currentWorkflow.stageRequiredToPublish?.id.toString() ?? ""
1168
1126
  };
1169
1127
  }
1170
1128
  }, [currentWorkflow, isCreatingWorkflow]);
@@ -1187,13 +1145,12 @@ const EditPage = () => {
1187
1145
  /* @__PURE__ */ jsx(
1188
1146
  Header,
1189
1147
  {
1190
- navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
1148
+ navigationAction: /* @__PURE__ */ jsx(BackButton, { fallback: ".." }),
1191
1149
  primaryAction: canUpdate || canCreate ? /* @__PURE__ */ jsx(
1192
1150
  Button,
1193
1151
  {
1194
1152
  startIcon: /* @__PURE__ */ jsx(Check, {}),
1195
1153
  type: "submit",
1196
- size: "M",
1197
1154
  disabled: !modified || isSubmitting || values.stages.length === 0,
1198
1155
  loading: !Boolean(Object.keys(savePrompts).length > 0) && isSubmitting,
1199
1156
  children: formatMessage({
@@ -1216,23 +1173,22 @@ const EditPage = () => {
1216
1173
  }
1217
1174
  ),
1218
1175
  /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsxs(Flex, { alignItems: "stretch", direction: "column", gap: 7, children: [
1219
- /* @__PURE__ */ jsx(WorkflowAttributes, { canUpdate }),
1176
+ /* @__PURE__ */ jsx(WorkflowAttributes, { canUpdate: canUpdate || canCreate }),
1220
1177
  /* @__PURE__ */ jsx(
1221
1178
  Stages,
1222
1179
  {
1223
1180
  canDelete,
1224
- canUpdate,
1181
+ canUpdate: canUpdate || canCreate,
1225
1182
  isCreating: isCreatingWorkflow
1226
1183
  }
1227
1184
  )
1228
1185
  ] }) }),
1229
1186
  /* @__PURE__ */ jsx(
1230
- ConfirmDialog,
1187
+ Dialog.Root,
1231
1188
  {
1232
- isOpen: Object.keys(savePrompts).length > 0,
1233
- onClose: handleConfirmClose,
1234
- onConfirm: handleConfirmDeleteDialog(values, { setErrors }),
1235
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 5, children: [
1189
+ open: Object.keys(savePrompts).length > 0,
1190
+ onOpenChange: handleConfirmClose,
1191
+ children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleConfirmDeleteDialog(values, { setErrors }), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 5, children: [
1236
1192
  savePrompts.hasDeletedServerStages && /* @__PURE__ */ jsx(Typography, { textAlign: "center", variant: "omega", children: formatMessage({
1237
1193
  id: "review-workflows.page.delete.confirm.stages.body",
1238
1194
  defaultMessage: "All entries assigned to deleted stages will be moved to the previous stage."
@@ -1244,7 +1200,7 @@ const EditPage = () => {
1244
1200
  },
1245
1201
  {
1246
1202
  count: contentTypesFromOtherWorkflows?.filter(
1247
- (contentType) => currentWorkflow?.contentTypes?.includes(contentType)
1203
+ (contentType) => values.contentTypes.includes(contentType)
1248
1204
  ).length ?? 0
1249
1205
  }
1250
1206
  ) }),
@@ -1252,7 +1208,7 @@ const EditPage = () => {
1252
1208
  id: "review-workflows.page.delete.confirm.confirm",
1253
1209
  defaultMessage: "Are you sure you want to save?"
1254
1210
  }) })
1255
- ] })
1211
+ ] }) })
1256
1212
  }
1257
1213
  )
1258
1214
  ] })
@@ -1261,8 +1217,8 @@ const EditPage = () => {
1261
1217
  /* @__PURE__ */ jsxs(
1262
1218
  LimitsModal.Root,
1263
1219
  {
1264
- isOpen: showLimitModal === "workflow",
1265
- onClose: () => setShowLimitModal(null),
1220
+ open: showLimitModal === "workflow",
1221
+ onOpenChange: () => setShowLimitModal(null),
1266
1222
  children: [
1267
1223
  /* @__PURE__ */ jsx(LimitsModal.Title, { children: formatMessage({
1268
1224
  id: "review-workflows.edit.page.workflows.limit.title",
@@ -1275,16 +1231,23 @@ const EditPage = () => {
1275
1231
  ]
1276
1232
  }
1277
1233
  ),
1278
- /* @__PURE__ */ jsxs(LimitsModal.Root, { isOpen: showLimitModal === "stage", onClose: () => setShowLimitModal(null), children: [
1279
- /* @__PURE__ */ jsx(LimitsModal.Title, { children: formatMessage({
1280
- id: "review-workflows.edit.page.stages.limit.title",
1281
- defaultMessage: "You have reached the limit of stages for this workflow in your plan"
1282
- }) }),
1283
- /* @__PURE__ */ jsx(LimitsModal.Body, { children: formatMessage({
1284
- id: "review-workflows.edit.page.stages.limit.body",
1285
- defaultMessage: "Try deleting some stages or contact Sales to enable more stages."
1286
- }) })
1287
- ] })
1234
+ /* @__PURE__ */ jsxs(
1235
+ LimitsModal.Root,
1236
+ {
1237
+ open: showLimitModal === "stage",
1238
+ onOpenChange: () => setShowLimitModal(null),
1239
+ children: [
1240
+ /* @__PURE__ */ jsx(LimitsModal.Title, { children: formatMessage({
1241
+ id: "review-workflows.edit.page.stages.limit.title",
1242
+ defaultMessage: "You have reached the limit of stages for this workflow in your plan"
1243
+ }) }),
1244
+ /* @__PURE__ */ jsx(LimitsModal.Body, { children: formatMessage({
1245
+ id: "review-workflows.edit.page.stages.limit.body",
1246
+ defaultMessage: "Try deleting some stages or contact Sales to enable more stages."
1247
+ }) })
1248
+ ]
1249
+ }
1250
+ )
1288
1251
  ] });
1289
1252
  };
1290
1253
  const addTmpKeysToStages = (data) => {
@@ -1308,4 +1271,4 @@ const ProtectedEditPage = () => {
1308
1271
  export {
1309
1272
  ProtectedEditPage
1310
1273
  };
1311
- //# sourceMappingURL=_id-D4CXKOqG.mjs.map
1274
+ //# sourceMappingURL=id-C9Ku9Br9.mjs.map