@strapi/review-workflows 0.0.0-experimental.d53e940834bf72ddc725f1d2fd36dac9abec30cb → 0.0.0-experimental.d74a8e5e655230b243e2d61ab5bec2fcdb426993

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 (57) hide show
  1. package/LICENSE +12 -17
  2. package/dist/_chunks/{Layout-D292CXD6.mjs → Layout-C_uZ98Uf.mjs} +8 -9
  3. package/dist/_chunks/Layout-C_uZ98Uf.mjs.map +1 -0
  4. package/dist/_chunks/{Layout-BWzD-Tfe.js → Layout-b_msoxIP.js} +8 -9
  5. package/dist/_chunks/Layout-b_msoxIP.js.map +1 -0
  6. package/dist/_chunks/{_id-CoX9yljN.js → _id-4xBYY7wK.js} +36 -73
  7. package/dist/_chunks/_id-4xBYY7wK.js.map +1 -0
  8. package/dist/_chunks/{_id-DqEUzU_u.mjs → _id-mkPbu6GX.mjs} +36 -73
  9. package/dist/_chunks/_id-mkPbu6GX.mjs.map +1 -0
  10. package/dist/_chunks/{index-D-KMrml_.js → index-C5NgBQMb.js} +78 -67
  11. package/dist/_chunks/index-C5NgBQMb.js.map +1 -0
  12. package/dist/_chunks/{index-CDMcvtW9.js → index-CIGzoVfk.js} +9 -29
  13. package/dist/_chunks/index-CIGzoVfk.js.map +1 -0
  14. package/dist/_chunks/{index-udedGkii.mjs → index-DL8-Q4Q5.mjs} +79 -68
  15. package/dist/_chunks/index-DL8-Q4Q5.mjs.map +1 -0
  16. package/dist/_chunks/{index-2nkLt-AE.mjs → index-D_k4wfAN.mjs} +11 -31
  17. package/dist/_chunks/index-D_k4wfAN.mjs.map +1 -0
  18. package/dist/_chunks/{router-C19H1Rju.js → router-BFr5lHsE.js} +3 -3
  19. package/dist/_chunks/{router-C19H1Rju.js.map → router-BFr5lHsE.js.map} +1 -1
  20. package/dist/_chunks/{router-bmjk-Tpf.mjs → router-DnQKLQOJ.mjs} +3 -3
  21. package/dist/_chunks/{router-bmjk-Tpf.mjs.map → router-DnQKLQOJ.mjs.map} +1 -1
  22. package/dist/admin/index.js +1 -1
  23. package/dist/admin/index.mjs +1 -1
  24. package/dist/admin/src/services/admin.d.ts +1 -1
  25. package/dist/admin/src/services/api.d.ts +1 -1
  26. package/dist/admin/src/services/content-manager.d.ts +4 -4
  27. package/dist/admin/src/services/settings.d.ts +1733 -7
  28. package/dist/server/index.js +47 -68
  29. package/dist/server/index.js.map +1 -1
  30. package/dist/server/index.mjs +47 -68
  31. package/dist/server/index.mjs.map +1 -1
  32. package/dist/server/src/controllers/assignees.d.ts.map +1 -1
  33. package/dist/server/src/controllers/index.d.ts +0 -1
  34. package/dist/server/src/controllers/index.d.ts.map +1 -1
  35. package/dist/server/src/controllers/stages.d.ts.map +1 -1
  36. package/dist/server/src/controllers/workflows.d.ts +0 -7
  37. package/dist/server/src/controllers/workflows.d.ts.map +1 -1
  38. package/dist/server/src/index.d.ts +1 -2
  39. package/dist/server/src/index.d.ts.map +1 -1
  40. package/dist/server/src/routes/review-workflows.d.ts.map +1 -1
  41. package/dist/server/src/services/document-service-middleware.d.ts.map +1 -1
  42. package/dist/server/src/services/index.d.ts +1 -1
  43. package/dist/server/src/services/metrics/weekly-metrics.d.ts.map +1 -1
  44. package/dist/server/src/services/stages.d.ts +2 -7
  45. package/dist/server/src/services/stages.d.ts.map +1 -1
  46. package/dist/shared/contracts/review-workflows.d.ts +1 -14
  47. package/dist/shared/contracts/review-workflows.d.ts.map +1 -1
  48. package/package.json +9 -9
  49. package/dist/_chunks/Layout-BWzD-Tfe.js.map +0 -1
  50. package/dist/_chunks/Layout-D292CXD6.mjs.map +0 -1
  51. package/dist/_chunks/_id-CoX9yljN.js.map +0 -1
  52. package/dist/_chunks/_id-DqEUzU_u.mjs.map +0 -1
  53. package/dist/_chunks/index-2nkLt-AE.mjs.map +0 -1
  54. package/dist/_chunks/index-CDMcvtW9.js.map +0 -1
  55. package/dist/_chunks/index-D-KMrml_.js.map +0 -1
  56. package/dist/_chunks/index-udedGkii.mjs.map +0 -1
  57. package/strapi-server.js +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_id-mkPbu6GX.mjs","sources":["../../admin/src/services/admin.ts","../../admin/src/routes/settings/hooks/useKeyboardDragAndDrop.ts","../../admin/src/routes/settings/hooks/useDragAndDrop.ts","../../admin/src/routes/settings/components/AddStage.tsx","../../admin/src/routes/settings/components/Stages.tsx","../../admin/src/routes/settings/components/WorkflowAttributes.tsx","../../admin/src/routes/settings/:id.tsx"],"sourcesContent":["import { SanitizedAdminUser } from '@strapi/admin/strapi-admin';\n\nimport { reviewWorkflowsApi } from './api';\n\ntype Roles = SanitizedAdminUser['roles'];\ntype RolesResponse = { data: Roles };\n\nconst adminApi = reviewWorkflowsApi.injectEndpoints({\n endpoints(builder) {\n return {\n getAdminRoles: builder.query<Roles, void>({\n query: () => ({\n url: `/admin/roles`,\n method: 'GET',\n }),\n transformResponse: (res: RolesResponse) => {\n return res.data;\n },\n }),\n };\n },\n});\n\nconst { useGetAdminRolesQuery } = adminApi;\n\nexport { useGetAdminRolesQuery };\nexport type { SanitizedAdminUser, Roles };\n","import * as React from 'react';\n\nexport type UseKeyboardDragAndDropCallbacks<TIndex extends number | Array<number> = number> = {\n onCancel?: (index: TIndex) => void;\n onDropItem?: (currentIndex: TIndex, newIndex?: TIndex) => void;\n onGrabItem?: (index: TIndex) => void;\n onMoveItem?: (newIndex: TIndex, currentIndex: TIndex) => void;\n};\n\n/**\n * Utility hook designed to implement keyboard accessibile drag and drop by\n * returning an onKeyDown handler to be passed to the drag icon button.\n *\n * @internal - You should use `useDragAndDrop` instead.\n */\nexport const useKeyboardDragAndDrop = <TIndex extends number | Array<number> = number>(\n active: boolean,\n index: TIndex,\n { onCancel, onDropItem, onGrabItem, onMoveItem }: UseKeyboardDragAndDropCallbacks<TIndex>\n) => {\n const [isSelected, setIsSelected] = React.useState(false);\n\n const handleMove = (movement: 'UP' | 'DOWN') => {\n if (!isSelected) {\n return;\n }\n if (typeof index === 'number' && onMoveItem) {\n if (movement === 'UP') {\n onMoveItem((index - 1) as TIndex, index);\n } else if (movement === 'DOWN') {\n onMoveItem((index + 1) as TIndex, index);\n }\n }\n };\n\n const handleDragClick = () => {\n if (isSelected) {\n if (onDropItem) {\n onDropItem(index);\n }\n setIsSelected(false);\n } else {\n if (onGrabItem) {\n onGrabItem(index);\n }\n setIsSelected(true);\n }\n };\n\n const handleCancel = () => {\n if (isSelected) {\n setIsSelected(false);\n\n if (onCancel) {\n onCancel(index);\n }\n }\n };\n\n const handleKeyDown = <E extends Element>(e: React.KeyboardEvent<E>) => {\n if (!active) {\n return;\n }\n\n if (e.key === 'Tab' && !isSelected) {\n return;\n }\n\n e.preventDefault();\n\n switch (e.key) {\n case ' ':\n case 'Enter':\n handleDragClick();\n break;\n\n case 'Escape':\n handleCancel();\n break;\n\n case 'ArrowDown':\n case 'ArrowRight':\n handleMove('DOWN');\n break;\n\n case 'ArrowUp':\n case 'ArrowLeft':\n handleMove('UP');\n break;\n\n default:\n }\n };\n\n return handleKeyDown;\n};\n","import * as React from 'react';\n\nimport {\n useDrag,\n useDrop,\n type HandlerManager,\n type ConnectDragSource,\n type ConnectDropTarget,\n type ConnectDragPreview,\n type DragSourceMonitor,\n} from 'react-dnd';\n\nimport {\n useKeyboardDragAndDrop,\n type UseKeyboardDragAndDropCallbacks,\n} from './useKeyboardDragAndDrop';\n\nimport type { Data } from '@strapi/types';\n\nconst DIRECTIONS = {\n UPWARD: 'upward',\n DOWNWARD: 'downward',\n} as const;\n\nconst DROP_SENSITIVITY = {\n REGULAR: 'regular',\n IMMEDIATE: 'immediate',\n} as const;\n\ninterface UseDragAndDropOptions<\n TIndex extends number | Array<number> = number,\n TItem extends { index: TIndex } = { index: TIndex },\n> extends UseKeyboardDragAndDropCallbacks<TIndex> {\n type?: string;\n index: TIndex;\n item?: TItem;\n onStart?: () => void;\n onEnd?: () => void;\n dropSensitivity?: (typeof DROP_SENSITIVITY)[keyof typeof DROP_SENSITIVITY];\n}\n\ntype Identifier = ReturnType<HandlerManager['getHandlerId']>;\n\ntype UseDragAndDropReturn<E extends Element = HTMLElement> = [\n props: {\n handlerId: Identifier;\n isDragging: boolean;\n handleKeyDown: <E extends Element>(event: React.KeyboardEvent<E>) => void;\n isOverDropTarget: boolean;\n direction: (typeof DIRECTIONS)[keyof typeof DIRECTIONS] | null;\n },\n objectRef: React.RefObject<E>,\n dropRef: ConnectDropTarget,\n dragRef: ConnectDragSource,\n dragPreviewRef: ConnectDragPreview,\n];\n\ntype DropCollectedProps = {\n handlerId: Identifier;\n isOver: boolean;\n};\n\n/**\n * A utility hook abstracting the general drag and drop hooks from react-dnd.\n * Centralising the same behaviours and by default offering keyboard support.\n */\nconst useDragAndDrop = <\n TIndex extends number | Array<number>,\n TItem extends { index: TIndex; id?: Data.ID; [key: string]: unknown } = {\n index: TIndex;\n [key: string]: unknown;\n },\n E extends Element = HTMLElement,\n>(\n active: boolean,\n {\n type = 'STRAPI_DND',\n index,\n item,\n onStart,\n onEnd,\n onGrabItem,\n onDropItem,\n onCancel,\n onMoveItem,\n dropSensitivity = DROP_SENSITIVITY.REGULAR,\n }: UseDragAndDropOptions<TIndex, TItem>\n): UseDragAndDropReturn<E> => {\n const objectRef = React.useRef<E>(null);\n\n const [{ handlerId, isOver }, dropRef] = useDrop<TItem, void, DropCollectedProps>({\n accept: type,\n collect(monitor) {\n return {\n handlerId: monitor.getHandlerId(),\n isOver: monitor.isOver({ shallow: true }),\n };\n },\n drop(item) {\n const draggedIndex = item.index;\n const newIndex = index;\n\n if (isOver && onDropItem) {\n onDropItem(draggedIndex, newIndex);\n }\n },\n hover(item, monitor) {\n if (!objectRef.current || !onMoveItem) {\n return;\n }\n\n const dragIndex = item.index;\n const newIndex = index;\n\n const hoverBoundingRect = objectRef.current?.getBoundingClientRect();\n const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;\n const clientOffset = monitor.getClientOffset();\n if (!clientOffset) return;\n\n const hoverClientY = clientOffset && clientOffset.y - hoverBoundingRect.top;\n if (typeof dragIndex === 'number' && typeof newIndex === 'number') {\n if (dragIndex === newIndex) {\n // Don't replace items with themselves\n return;\n }\n\n if (dropSensitivity === DROP_SENSITIVITY.REGULAR) {\n // Dragging downwards\n if (dragIndex < newIndex && hoverClientY < hoverMiddleY) {\n return;\n }\n\n // Dragging upwards\n if (dragIndex > newIndex && hoverClientY > hoverMiddleY) {\n return;\n }\n }\n\n // Time to actually perform the action\n onMoveItem(newIndex, dragIndex);\n item.index = newIndex;\n } else {\n // Using numbers as indices doesn't work for nested list items with path like [1, 1, 0]\n if (Array.isArray(dragIndex) && Array.isArray(newIndex)) {\n // Indices comparison to find item position in nested list\n const minLength = Math.min(dragIndex.length, newIndex.length);\n let areEqual = true;\n let isLessThan = false;\n let isGreaterThan = false;\n\n for (let i = 0; i < minLength; i++) {\n if (dragIndex[i] < newIndex[i]) {\n isLessThan = true;\n areEqual = false;\n break;\n } else if (dragIndex[i] > newIndex[i]) {\n isGreaterThan = true;\n areEqual = false;\n break;\n }\n }\n\n // Don't replace items with themselves\n if (areEqual && dragIndex.length === newIndex.length) {\n return;\n }\n\n if (dropSensitivity === DROP_SENSITIVITY.REGULAR) {\n // Dragging downwards\n if (isLessThan && !isGreaterThan && hoverClientY < hoverMiddleY) {\n return;\n }\n\n // Dragging upwards\n if (isGreaterThan && !isLessThan && hoverClientY > hoverMiddleY) {\n return;\n }\n }\n }\n\n onMoveItem(newIndex, dragIndex);\n item.index = newIndex;\n }\n },\n });\n\n const getDragDirection = (monitor: DragSourceMonitor<TItem, void>) => {\n if (\n monitor &&\n monitor.isDragging() &&\n !monitor.didDrop() &&\n monitor.getInitialClientOffset() &&\n monitor.getClientOffset()\n ) {\n const deltaY = monitor.getInitialClientOffset()!.y - monitor.getClientOffset()!.y;\n\n if (deltaY > 0) return DIRECTIONS.UPWARD;\n\n if (deltaY < 0) return DIRECTIONS.DOWNWARD;\n\n return null;\n }\n\n return null;\n };\n\n const [{ isDragging, direction }, dragRef, dragPreviewRef] = useDrag({\n type,\n item() {\n if (onStart) {\n onStart();\n }\n\n /**\n * This will be attached and it helps define the preview sizes\n * when a component is flexy e.g. Relations\n */\n const { width } = objectRef.current?.getBoundingClientRect() ?? {};\n\n return { index, width, ...item };\n },\n end() {\n if (onEnd) {\n onEnd();\n }\n },\n canDrag: active,\n /**\n * This is useful when the item is in a virtualized list.\n * However, if we don't have an ID then we want the libraries\n * defaults to take care of this.\n */\n isDragging: item?.id\n ? (monitor) => {\n return item.id === monitor.getItem().id;\n }\n : undefined,\n collect: (monitor) => ({\n isDragging: monitor.isDragging(),\n initialOffset: monitor.getInitialClientOffset(),\n currentOffset: monitor.getClientOffset(),\n direction: getDragDirection(monitor),\n }),\n });\n\n const handleKeyDown = useKeyboardDragAndDrop(active, index, {\n onGrabItem,\n onDropItem,\n onCancel,\n onMoveItem,\n });\n\n return [\n { handlerId, isDragging, handleKeyDown, isOverDropTarget: isOver, direction },\n objectRef,\n dropRef,\n dragRef,\n dragPreviewRef,\n ];\n};\n\nexport {\n useDragAndDrop,\n UseDragAndDropReturn,\n UseDragAndDropOptions,\n DIRECTIONS,\n DROP_SENSITIVITY,\n};\n","import { Box, BoxComponent, ButtonProps, Flex, Typography } from '@strapi/design-system';\nimport { PlusCircle } from '@strapi/icons';\nimport { styled } from 'styled-components';\n\nexport const AddStage = ({ children, ...props }: ButtonProps) => {\n return (\n <StyledButton\n tag=\"button\"\n background=\"neutral0\"\n borderColor=\"neutral150\"\n paddingBottom={3}\n paddingLeft={4}\n paddingRight={4}\n paddingTop={3}\n shadow=\"filterShadow\"\n {...props}\n >\n <Typography variant=\"pi\" fontWeight=\"bold\">\n <Flex tag=\"span\" gap={2}>\n <PlusCircle width=\"2.4rem\" height=\"2.4rem\" aria-hidden />\n {children}\n </Flex>\n </Typography>\n </StyledButton>\n );\n};\n\nconst StyledButton = styled<BoxComponent<'button'>>(Box)`\n border-radius: 26px;\n color: ${({ theme }) => theme.colors.neutral500};\n\n &:hover {\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n &:active {\n color: ${({ theme }) => theme.colors.primary600};\n }\n`;\n","import * as React from 'react';\n\nimport {\n useField,\n useForm,\n useTracking,\n ConfirmDialog,\n useNotification,\n InputRenderer as AdminInputRenderer,\n InputProps,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Flex,\n MultiSelectOption,\n Accordion,\n Grid,\n IconButton,\n MultiSelect,\n MultiSelectGroup,\n SingleSelect,\n SingleSelectOption,\n TextInput,\n VisuallyHidden,\n useComposedRefs,\n Menu,\n MenuItem,\n Field,\n Dialog,\n} from '@strapi/design-system';\nimport { Duplicate, Drag, More, EyeStriked } from '@strapi/icons';\nimport { getEmptyImage } from 'react-dnd-html5-backend';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { Stage as IStage, StagePermission } from '../../../../../shared/contracts/review-workflows';\nimport { useGetAdminRolesQuery } from '../../../services/admin';\nimport { AVAILABLE_COLORS, getStageColorByHex } from '../../../utils/colors';\nimport { DRAG_DROP_TYPES } from '../constants';\nimport { useDragAndDrop } from '../hooks/useDragAndDrop';\n\nimport { AddStage } from './AddStage';\n\ninterface WorkflowStage extends Pick<IStage, 'id' | 'name' | 'permissions' | 'color'> {\n __temp_key__: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Stages\n * -----------------------------------------------------------------------------------------------*/\ninterface StagesProps {\n canDelete?: boolean;\n canUpdate?: boolean;\n isCreating?: boolean;\n}\n\nconst Stages = ({ canDelete = true, canUpdate = true, isCreating }: StagesProps) => {\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const addFieldRow = useForm('Stages', (state) => state.addFieldRow);\n const { value: stages = [] } = useField<WorkflowStage[]>('stages');\n\n return (\n <Flex direction=\"column\" gap={6} width=\"100%\">\n <Box position=\"relative\" width=\"100%\">\n <Background\n background=\"neutral200\"\n height=\"100%\"\n left=\"50%\"\n position=\"absolute\"\n top=\"0\"\n width={2}\n />\n\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6} position=\"relative\" tag=\"ol\">\n {stages.map((stage, index) => {\n return (\n <Box key={stage.__temp_key__} tag=\"li\">\n <Stage\n index={index}\n canDelete={stages.length > 1 && canDelete}\n canReorder={stages.length > 1}\n canUpdate={canUpdate}\n stagesCount={stages.length}\n defaultOpen={isCreating}\n {...stage}\n />\n </Box>\n );\n })}\n </Flex>\n </Box>\n\n {canUpdate && (\n <AddStage\n type=\"button\"\n onClick={() => {\n addFieldRow('stages', { name: '' });\n trackUsage('willCreateStage');\n }}\n >\n {formatMessage({\n id: 'Settings.review-workflows.stage.add',\n defaultMessage: 'Add new stage',\n })}\n </AddStage>\n )}\n </Flex>\n );\n};\n\nconst Background = styled(Box)`\n transform: translateX(-50%);\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Stage\n * -----------------------------------------------------------------------------------------------*/\ninterface StageProps extends WorkflowStage {\n canDelete?: boolean;\n canReorder?: boolean;\n canUpdate?: boolean;\n index: number;\n stagesCount: number;\n defaultOpen?: boolean;\n}\n\nconst Stage = ({\n index,\n canDelete = false,\n canReorder = false,\n canUpdate = false,\n stagesCount,\n name,\n permissions,\n color,\n defaultOpen,\n}: StageProps) => {\n const [liveText, setLiveText] = React.useState<string>();\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const stageErrors = useForm('Stages', (state) => state.errors.stages as object[]);\n const error = stageErrors?.[index];\n const addFieldRow = useForm('Stage', (state) => state.addFieldRow);\n const moveFieldRow = useForm('Stage', (state) => state.moveFieldRow);\n const removeFieldRow = useForm('Stage', (state) => state.removeFieldRow);\n\n const getItemPos = (index: number) => `${index + 1} of ${stagesCount}`;\n\n const handleGrabStage = (index: number) => {\n setLiveText(\n formatMessage(\n {\n id: 'dnd.grab-item',\n defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`,\n },\n {\n item: name,\n position: getItemPos(index),\n }\n )\n );\n };\n\n const handleDropStage = (index: number) => {\n setLiveText(\n formatMessage(\n {\n id: 'dnd.drop-item',\n defaultMessage: `{item}, dropped. Final position in list: {position}.`,\n },\n {\n item: name,\n position: getItemPos(index),\n }\n )\n );\n };\n\n const handleCancelDragStage = () => {\n setLiveText(\n formatMessage(\n {\n id: 'dnd.cancel-item',\n defaultMessage: '{item}, dropped. Re-order cancelled.',\n },\n {\n item: name,\n }\n )\n );\n };\n\n const handleMoveStage = (newIndex: number, oldIndex: number) => {\n setLiveText(\n formatMessage(\n {\n id: 'dnd.reorder',\n defaultMessage: '{item}, moved. New position in list: {position}.',\n },\n {\n item: name,\n position: getItemPos(newIndex),\n }\n )\n );\n\n moveFieldRow('stages', oldIndex, newIndex);\n };\n\n const [{ handlerId, isDragging, handleKeyDown }, stageRef, dropRef, dragRef, dragPreviewRef] =\n useDragAndDrop(canReorder, {\n index,\n item: {\n index,\n name,\n },\n onGrabItem: handleGrabStage,\n onDropItem: handleDropStage,\n onMoveItem: handleMoveStage,\n onCancel: handleCancelDragStage,\n type: DRAG_DROP_TYPES.STAGE,\n });\n\n // @ts-expect-error – the stageRef is incorrectly typed.\n const composedRef = useComposedRefs<HTMLDivElement>(stageRef, dropRef);\n\n React.useEffect(() => {\n dragPreviewRef(getEmptyImage(), { captureDraggingState: false });\n }, [dragPreviewRef, index]);\n\n const handleCloneClick = () => {\n addFieldRow('stages', { name, color, permissions });\n };\n\n const id = React.useId();\n\n return (\n <Box ref={composedRef} shadow=\"tableShadow\">\n {liveText && <VisuallyHidden aria-live=\"assertive\">{liveText}</VisuallyHidden>}\n\n {isDragging ? (\n <Box\n background=\"primary100\"\n borderStyle=\"dashed\"\n borderColor=\"primary600\"\n borderWidth=\"1px\"\n display=\"block\"\n hasRadius\n padding={6}\n />\n ) : (\n <AccordionRoot\n onValueChange={(value) => {\n if (value) {\n trackUsage('willEditStage');\n }\n }}\n defaultValue={defaultOpen ? id : undefined}\n $error={Object.values(error ?? {}).length > 0}\n >\n <Accordion.Item value={id}>\n <Accordion.Header>\n <Accordion.Trigger>{name}</Accordion.Trigger>\n <Accordion.Actions>\n {canDelete || canUpdate ? (\n <>\n <Menu.Root>\n <ContextMenuTrigger size=\"S\" endIcon={null} paddingLeft={2} paddingRight={2}>\n <More aria-hidden focusable={false} />\n <VisuallyHidden tag=\"span\">\n {formatMessage({\n id: '[tbdb].components.DynamicZone.more-actions',\n defaultMessage: 'More actions',\n })}\n </VisuallyHidden>\n </ContextMenuTrigger>\n {/* z-index needs to be as big as the one defined for the wrapper in Stages, otherwise the menu\n * disappears behind the accordion\n */}\n <Menu.Content popoverPlacement=\"bottom-end\" zIndex={2}>\n <Menu.SubRoot>\n {canUpdate && (\n <MenuItem onClick={handleCloneClick}>\n {formatMessage({\n id: 'Settings.review-workflows.stage.delete',\n defaultMessage: 'Duplicate stage',\n })}\n </MenuItem>\n )}\n\n {canDelete && (\n <DeleteMenuItem onClick={() => removeFieldRow('stages', index)}>\n {formatMessage({\n id: 'Settings.review-workflows.stage.delete',\n defaultMessage: 'Delete',\n })}\n </DeleteMenuItem>\n )}\n </Menu.SubRoot>\n </Menu.Content>\n </Menu.Root>\n\n {canUpdate && (\n <IconButton\n background=\"transparent\"\n hasRadius\n variant=\"ghost\"\n data-handler-id={handlerId}\n ref={dragRef}\n label={formatMessage({\n id: 'Settings.review-workflows.stage.drag',\n defaultMessage: 'Drag',\n })}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={handleKeyDown}\n >\n <Drag />\n </IconButton>\n )}\n </>\n ) : null}\n </Accordion.Actions>\n </Accordion.Header>\n <Accordion.Content>\n <Grid.Root gap={4} padding={6}>\n {[\n {\n disabled: !canUpdate,\n label: formatMessage({\n id: 'Settings.review-workflows.stage.name.label',\n defaultMessage: 'Stage name',\n }),\n name: `stages.${index}.name`,\n required: true,\n size: 6,\n type: 'string' as const,\n },\n {\n disabled: !canUpdate,\n label: formatMessage({\n id: 'content-manager.reviewWorkflows.stage.color',\n defaultMessage: 'Color',\n }),\n name: `stages.${index}.color`,\n required: true,\n size: 6,\n type: 'color' as const,\n },\n {\n disabled: !canUpdate,\n label: formatMessage({\n id: 'Settings.review-workflows.stage.permissions.label',\n defaultMessage: 'Roles that can change this stage',\n }),\n name: `stages.${index}.permissions`,\n placeholder: formatMessage({\n id: 'Settings.review-workflows.stage.permissions.placeholder',\n defaultMessage: 'Select a role',\n }),\n required: true,\n size: 6,\n type: 'permissions' as const,\n },\n ].map(({ size, ...field }) => (\n <Grid.Item key={field.name} col={size} direction=\"column\" alignItems=\"stretch\">\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Accordion.Content>\n </Accordion.Item>\n </AccordionRoot>\n )}\n </Box>\n );\n};\n\nconst AccordionRoot = styled(Accordion.Root)<{ $error?: boolean }>`\n border: 1px solid\n ${({ theme, $error }) => ($error ? theme.colors.danger600 : theme.colors.neutral200)};\n`;\n\nconst DeleteMenuItem = styled(MenuItem)`\n color: ${({ theme }) => theme.colors.danger600};\n`;\n\n// Removing the font-size from the child-span aligns the\n// more icon vertically\nconst ContextMenuTrigger = styled(Menu.Trigger)`\n :hover,\n :focus {\n background-color: ${({ theme }) => theme.colors.neutral100};\n }\n\n > span {\n font-size: 0;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * InputRenderer\n * -----------------------------------------------------------------------------------------------*/\n\ntype InputRendererProps = InputProps | ColorSelectorProps | PermissionsFieldProps;\n\nconst InputRenderer = (props: InputRendererProps) => {\n switch (props.type) {\n case 'color':\n return <ColorSelector {...props} />;\n case 'permissions':\n return <PermissionsField {...props} />;\n default:\n return <AdminInputRenderer {...props} />;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ColorSelector\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ColorSelectorProps\n extends Omit<Extract<InputProps, { type: 'enumeration' }>, 'type' | 'options'> {\n type: 'color';\n}\n\nconst ColorSelector = ({ disabled, label, name, required }: ColorSelectorProps) => {\n const { formatMessage } = useIntl();\n const { value, error, onChange } = useField<string>(name);\n\n const colorOptions = AVAILABLE_COLORS.map(({ hex, name }) => ({\n value: hex,\n label: formatMessage(\n {\n id: 'Settings.review-workflows.stage.color.name',\n defaultMessage: '{name}',\n },\n { name }\n ),\n color: hex,\n }));\n\n const { themeColorName } = getStageColorByHex(value) ?? {};\n\n return (\n <Field.Root error={error} name={name} required={required}>\n <Field.Label>{label}</Field.Label>\n <SingleSelect\n disabled={disabled}\n onChange={(v) => {\n onChange(name, v.toString());\n }}\n value={value?.toUpperCase()}\n startIcon={\n <Flex\n tag=\"span\"\n height={2}\n background={value}\n borderColor={themeColorName === 'neutral0' ? 'neutral150' : 'transparent'}\n hasRadius\n shrink={0}\n width={2}\n />\n }\n >\n {colorOptions.map(({ value, label, color }) => {\n const { themeColorName } = getStageColorByHex(color) || {};\n\n return (\n <SingleSelectOption\n value={value}\n key={value}\n startIcon={\n <Flex\n tag=\"span\"\n height={2}\n background={color}\n borderColor={themeColorName === 'neutral0' ? 'neutral150' : 'transparent'}\n hasRadius\n shrink={0}\n width={2}\n />\n }\n >\n {label}\n </SingleSelectOption>\n );\n })}\n </SingleSelect>\n <Field.Error />\n </Field.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * PermissionsField\n * -----------------------------------------------------------------------------------------------*/\ninterface PermissionsFieldProps\n extends Omit<Extract<InputProps, { type: 'enumeration' }>, 'type' | 'options'> {\n type: 'permissions';\n}\n\nconst PermissionsField = ({ disabled, name, placeholder, required }: PermissionsFieldProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const [isApplyAllConfirmationOpen, setIsApplyAllConfirmationOpen] = React.useState(false);\n const { value = [], error, onChange } = useField<StagePermission[]>(name);\n const allStages = useForm<WorkflowStage[]>('PermissionsField', (state) => state.values.stages);\n const onFormValueChange = useForm('PermissionsField', (state) => state.onChange);\n const rolesErrorCount = React.useRef(0);\n\n const { data: roles = [], isLoading, error: getRolesError } = useGetAdminRolesQuery();\n\n // Super admins always have permissions to do everything and therefore\n // there is no point for this role to show up in the role combobox\n const filteredRoles = roles?.filter((role) => role.code !== 'strapi-super-admin') ?? [];\n\n React.useEffect(() => {\n if (\n !isLoading &&\n getRolesError &&\n 'status' in getRolesError &&\n getRolesError.status == 403 &&\n rolesErrorCount.current === 0\n ) {\n rolesErrorCount.current = 1;\n\n toggleNotification({\n blockTransition: true,\n type: 'danger',\n message: formatMessage({\n id: 'review-workflows.stage.permissions.noPermissions.description',\n defaultMessage: 'You don’t have the permission to see roles. Contact your administrator.',\n }),\n });\n }\n }, [formatMessage, isLoading, roles, toggleNotification, getRolesError]);\n\n if (!isLoading && filteredRoles.length === 0) {\n return (\n <Field.Root\n name={name}\n hint={formatMessage({\n id: 'Settings.review-workflows.stage.permissions.noPermissions.description',\n defaultMessage: 'You don’t have the permission to see roles',\n })}\n required={required}\n >\n <Field.Label>\n {formatMessage({\n id: 'Settings.review-workflows.stage.permissions.label',\n defaultMessage: 'Roles that can change this stage',\n })}\n </Field.Label>\n <TextInput\n disabled\n placeholder={formatMessage({\n id: 'components.NotAllowedInput.text',\n defaultMessage: 'No permissions to see this field',\n })}\n startAction={<EyeStriked fill=\"neutral600\" />}\n type=\"text\"\n value=\"\"\n />\n <Field.Hint />\n </Field.Root>\n );\n }\n\n return (\n <>\n <Flex alignItems=\"flex-end\" gap={3}>\n <PermissionWrapper grow={1}>\n <Field.Root error={error} name={name} required>\n <Field.Label>\n {formatMessage({\n id: 'Settings.review-workflows.stage.permissions.label',\n defaultMessage: 'Roles that can change this stage',\n })}\n </Field.Label>\n <MultiSelect\n disabled={disabled}\n onChange={(values) => {\n // Because the select components expects strings for values, but\n // the yup schema validates we are sending full permission objects to the API,\n // we must coerce the string value back to an object\n const permissions = values.map((value) => ({\n role: parseInt(value, 10),\n action: 'admin::review-workflows.stage.transition',\n }));\n\n onChange(name, permissions);\n }}\n placeholder={placeholder}\n // The Select component expects strings for values\n value={value.map((permission) => `${permission.role}`)}\n withTags\n >\n <MultiSelectGroup\n label={formatMessage({\n id: 'Settings.review-workflows.stage.permissions.allRoles.label',\n defaultMessage: 'All roles',\n })}\n values={filteredRoles.map((r) => `${r.id}`)}\n >\n {filteredRoles.map((role) => {\n return (\n <NestedOption key={role.id} value={`${role.id}`}>\n {role.name}\n </NestedOption>\n );\n })}\n </MultiSelectGroup>\n </MultiSelect>\n <Field.Error />\n </Field.Root>\n </PermissionWrapper>\n <Dialog.Root open={isApplyAllConfirmationOpen} onOpenChange={setIsApplyAllConfirmationOpen}>\n <Dialog.Trigger>\n <IconButton\n disabled={disabled}\n label={formatMessage({\n id: 'Settings.review-workflows.stage.permissions.apply.label',\n defaultMessage: 'Apply to all stages',\n })}\n size=\"L\"\n >\n <Duplicate />\n </IconButton>\n </Dialog.Trigger>\n <ConfirmDialog\n onConfirm={() => {\n onFormValueChange(\n 'stages',\n allStages.map((stage) => ({\n ...stage,\n permissions: value,\n }))\n );\n\n setIsApplyAllConfirmationOpen(false);\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'Settings.review-workflows.page.edit.confirm.stages.permissions.copy.success',\n defaultMessage: 'Applied roles to all other stages of the workflow',\n }),\n });\n }}\n variant=\"default\"\n >\n {formatMessage({\n id: 'Settings.review-workflows.page.edit.confirm.stages.permissions.copy',\n defaultMessage:\n 'Roles that can change that stage will be applied to all the other stages.',\n })}\n </ConfirmDialog>\n </Dialog.Root>\n </Flex>\n </>\n );\n};\n\nconst NestedOption = styled(MultiSelectOption)`\n padding-left: ${({ theme }) => theme.spaces[7]};\n`;\n\n// Grow the size of the permission Select\nconst PermissionWrapper = styled(Flex)`\n > * {\n flex-grow: 1;\n }\n`;\n\nexport { Stages };\nexport type { StagesProps, WorkflowStage };\n","import { InputRenderer, useField, useForm } from '@strapi/admin/strapi-admin';\nimport {\n Field,\n Grid,\n MultiSelect,\n MultiSelectGroup,\n MultiSelectOption,\n Typography,\n useCollator,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useGetContentTypesQuery } from '../../../services/content-manager';\nimport { useReviewWorkflows } from '../hooks/useReviewWorkflows';\n\n/* -------------------------------------------------------------------------------------------------\n * WorkflowAttributes\n * -----------------------------------------------------------------------------------------------*/\ninterface WorkflowAttributesProps {\n canUpdate?: boolean;\n}\n\nconst WorkflowAttributes = ({ canUpdate = true }: WorkflowAttributesProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <Grid.Root background=\"neutral0\" hasRadius gap={4} padding={6} shadow=\"tableShadow\">\n <Grid.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <InputRenderer\n disabled={!canUpdate}\n label={formatMessage({\n id: 'Settings.review-workflows.workflow.name.label',\n defaultMessage: 'Workflow Name',\n })}\n name=\"name\"\n required\n type=\"string\"\n />\n </Grid.Item>\n <Grid.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <ContentTypesSelector disabled={!canUpdate} />\n </Grid.Item>\n </Grid.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ContentTypesSelector\n * -----------------------------------------------------------------------------------------------*/\ninterface ContentTypesSelectorProps {\n disabled?: boolean;\n}\n\nconst ContentTypesSelector = ({ disabled }: ContentTypesSelectorProps) => {\n const { formatMessage, locale } = useIntl();\n const { data: contentTypes, isLoading } = useGetContentTypesQuery();\n const { workflows } = useReviewWorkflows();\n const currentWorkflow = useForm('ContentTypesSelector', (state) => state.values);\n\n const { error, value, onChange } = useField('contentTypes');\n\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const isDisabled =\n disabled ||\n isLoading ||\n !contentTypes ||\n (contentTypes.collectionType.length === 0 && contentTypes.singleType.length === 0);\n\n const collectionTypes = (contentTypes?.collectionType ?? [])\n .toSorted((a, b) => formatter.compare(a.info.displayName, b.info.displayName))\n .map((contentType) => ({\n label: contentType.info.displayName,\n value: contentType.uid,\n }));\n\n const singleTypes = (contentTypes?.singleType ?? []).map((contentType) => ({\n label: contentType.info.displayName,\n value: contentType.uid,\n }));\n\n return (\n <Field.Root error={error} name={'contentTypes'}>\n <Field.Label>\n {formatMessage({\n id: 'Settings.review-workflows.workflow.contentTypes.label',\n defaultMessage: 'Associated to',\n })}\n </Field.Label>\n <MultiSelect\n customizeContent={(value) =>\n formatMessage(\n {\n id: 'Settings.review-workflows.workflow.contentTypes.displayValue',\n defaultMessage:\n '{count} {count, plural, one {content type} other {content types}} selected',\n },\n { count: value?.length }\n )\n }\n disabled={isDisabled}\n onChange={(values) => {\n onChange('contentTypes', values);\n }}\n value={value}\n placeholder={formatMessage({\n id: 'Settings.review-workflows.workflow.contentTypes.placeholder',\n defaultMessage: 'Select',\n })}\n >\n {[\n ...(collectionTypes.length > 0\n ? [\n {\n label: formatMessage({\n id: 'Settings.review-workflows.workflow.contentTypes.collectionTypes.label',\n defaultMessage: 'Collection Types',\n }),\n children: collectionTypes,\n },\n ]\n : []),\n\n ...(singleTypes.length > 0\n ? [\n {\n label: formatMessage({\n id: 'Settings.review-workflows.workflow.contentTypes.singleTypes.label',\n defaultMessage: 'Single Types',\n }),\n children: singleTypes,\n },\n ]\n : []),\n ].map((opt) => {\n return (\n <MultiSelectGroup\n key={opt.label}\n label={opt.label}\n values={opt.children.map((child) => child.value.toString())}\n >\n {opt.children.map((child) => {\n const { name: assignedWorkflowName } =\n workflows?.find(\n (workflow) =>\n ((currentWorkflow && workflow.id !== currentWorkflow.id) ||\n !currentWorkflow) &&\n workflow.contentTypes.includes(child.value)\n ) ?? {};\n\n return (\n <NestedOption key={child.value} value={child.value}>\n <Typography>\n {\n // @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\n formatMessage(\n {\n id: 'Settings.review-workflows.workflow.contentTypes.assigned.notice',\n defaultMessage:\n '{label} {name, select, undefined {} other {<i>(assigned to <em>{name}</em> workflow)</i>}}',\n },\n {\n label: child.label,\n name: assignedWorkflowName,\n em: (...children) => (\n <Typography tag=\"em\" fontWeight=\"bold\">\n {children}\n </Typography>\n ),\n i: (...children) => (\n <ContentTypeTakeNotice>{children}</ContentTypeTakeNotice>\n ),\n }\n )\n }\n </Typography>\n </NestedOption>\n );\n })}\n </MultiSelectGroup>\n );\n })}\n </MultiSelect>\n </Field.Root>\n );\n};\n\nconst NestedOption = styled(MultiSelectOption)`\n padding-left: ${({ theme }) => theme.spaces[7]};\n`;\n\nconst ContentTypeTakeNotice = styled(Typography)`\n font-style: italic;\n`;\n\nexport { WorkflowAttributes };\nexport type { WorkflowAttributesProps };\n","import * as React from 'react';\n\nimport {\n ConfirmDialog,\n BackButton,\n useNotification,\n useAPIErrorHandler,\n useRBAC,\n Form,\n Page,\n FormProps,\n FormHelpers,\n} from '@strapi/admin/strapi-admin';\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport { Button, Dialog, Flex, Typography } from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport { generateNKeysBetween } from 'fractional-indexing';\nimport { useIntl } from 'react-intl';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport * as yup from 'yup';\n\nimport { LimitsModal } from '../../components/LimitsModal';\nimport {\n CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME,\n CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME,\n} from '../../constants';\nimport { useTypedSelector } from '../../modules/hooks';\nimport { isBaseQueryError } from '../../utils/api';\n\nimport * as Layout from './components/Layout';\nimport { Stages, WorkflowStage } from './components/Stages';\nimport { WorkflowAttributes } from './components/WorkflowAttributes';\nimport { useReviewWorkflows } from './hooks/useReviewWorkflows';\n\nimport type { Stage, Workflow } from '../../../../shared/contracts/review-workflows';\n\n/* -------------------------------------------------------------------------------------------------\n * EditPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst WORKFLOW_SCHEMA = yup.object({\n contentTypes: yup.array().of(yup.string()),\n name: yup\n .string()\n .max(255, {\n id: 'review-workflows.validation.name.max-length',\n defaultMessage: 'Name can not be longer than 255 characters',\n })\n .required()\n .nullable(),\n stages: yup\n .array()\n .of(\n yup.object().shape({\n name: yup\n .string()\n .nullable()\n .required({\n id: 'review-workflows.validation.stage.name',\n defaultMessage: 'Name is required',\n })\n .max(255, {\n id: 'review-workflows.validation.stage.max-length',\n defaultMessage: 'Name can not be longer than 255 characters',\n })\n .test(\n 'unique-name',\n {\n id: 'review-workflows.validation.stage.duplicate',\n defaultMessage: 'Stage name must be unique',\n },\n (stageName, context) => {\n // @ts-expect-error it does exist.\n const { stages } = context.from[1].value;\n\n return stages.filter((stage: Stage) => stage.name === stageName).length === 1;\n }\n ),\n color: yup\n .string()\n .nullable()\n .required({\n id: 'review-workflows.validation.stage.color',\n defaultMessage: 'Color is required',\n })\n .matches(/^#(?:[0-9a-fA-F]{3}){1,2}$/i),\n\n permissions: yup\n .array(\n yup.object({\n role: yup\n .number()\n .strict()\n .typeError({\n id: 'review-workflows.validation.stage.permissions.role.number',\n defaultMessage: 'Role must be of type number',\n })\n .required(),\n action: yup.string().required({\n id: 'review-workflows.validation.stage.permissions.action.required',\n defaultMessage: 'Action is a required argument',\n }),\n })\n )\n .strict(),\n })\n )\n .min(1),\n});\n\nconst EditPage = () => {\n const { id = '' } = useParams<{ id: string }>();\n const isCreatingWorkflow = id === 'create';\n const { formatMessage } = useIntl();\n const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();\n const navigate = useNavigate();\n const { toggleNotification } = useNotification();\n const {\n isLoading: isLoadingWorkflow,\n meta,\n workflows,\n error,\n update,\n create,\n } = useReviewWorkflows();\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions['settings']?.['review-workflows']\n );\n const {\n allowedActions: { canDelete, canUpdate, canCreate },\n } = useRBAC(permissions);\n\n const [savePrompts, setSavePrompts] = React.useState<{\n hasDeletedServerStages?: boolean;\n hasReassignedContentTypes?: boolean;\n }>({});\n const { getFeature, isLoading: isLicenseLoading } = useLicenseLimits();\n const [showLimitModal, setShowLimitModal] = React.useState<'workflow' | 'stage' | null>(null);\n\n const currentWorkflow = workflows?.find((workflow) => workflow.id === parseInt(id, 10));\n const contentTypesFromOtherWorkflows = workflows\n ?.filter((workflow) => workflow.id !== parseInt(id, 10))\n .flatMap((workflow) => workflow.contentTypes);\n\n const limits = getFeature<string>('review-workflows');\n const numberOfWorkflows = limits?.[CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME];\n const stagesPerWorkflow = limits?.[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME];\n\n interface FormValues {\n name: string;\n stages: WorkflowStage[];\n contentTypes: string[];\n }\n\n const submitForm = async (data: FormValues, helpers: Pick<FormHelpers, 'setErrors'>) => {\n try {\n if (!isCreatingWorkflow) {\n const res = await update(id, {\n ...data,\n // compare permissions of stages and only submit them if at least one has\n // changed; this enables partial updates e.g. for users who don't have\n // permissions to see roles\n stages: data.stages.map((stage) => {\n let hasUpdatedPermissions = true;\n const serverStage = currentWorkflow?.stages?.find(\n (serverStage) => serverStage.id === stage?.id\n );\n if (serverStage) {\n hasUpdatedPermissions =\n serverStage.permissions?.length !== stage.permissions?.length ||\n !serverStage.permissions?.every(\n (serverPermission) =>\n !!stage.permissions?.find(\n (permission) => permission.role === serverPermission.role\n )\n );\n }\n return {\n ...stage,\n permissions: hasUpdatedPermissions ? stage.permissions : undefined,\n } satisfies Stage;\n }),\n });\n\n if ('error' in res && isBaseQueryError(res.error) && res.error.name === 'ValidationError') {\n helpers.setErrors(formatValidationErrors(res.error));\n }\n } else {\n const res = await create(data);\n\n if ('error' in res && isBaseQueryError(res.error) && res.error.name === 'ValidationError') {\n helpers.setErrors(formatValidationErrors(res.error));\n } else if ('data' in res) {\n navigate(`../${res.data.id}`, { replace: true });\n }\n }\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'notification.error',\n defaultMessage: 'An error occurred',\n }),\n });\n }\n setSavePrompts({});\n };\n\n const handleConfirmDeleteDialog =\n (data: FormValues, helpers: Pick<FormHelpers, 'setErrors'>) => async () => {\n await submitForm(data, helpers);\n };\n\n const handleConfirmClose = () => {\n setSavePrompts({});\n };\n\n const handleSubmit: FormProps<FormValues>['onSubmit'] = async (data, helpers) => {\n const isContentTypeReassignment = data.contentTypes.some((contentType) =>\n contentTypesFromOtherWorkflows?.includes(contentType)\n );\n const hasDeletedServerStages =\n !isCreatingWorkflow &&\n !currentWorkflow?.stages.every((stage) =>\n data.stages.some((newStage) => newStage.id === stage.id)\n );\n\n if (meta && numberOfWorkflows && meta?.workflowCount > parseInt(numberOfWorkflows, 10)) {\n /**\n * If the current license has a limit, check if the total count of workflows\n * exceeds that limit and display the limits modal instead of sending the\n * update, because it would throw an API error.\n */\n setShowLimitModal('workflow');\n\n /**\n * If the current license has a limit, check if the total count of stages\n * exceeds that limit and display the limits modal instead of sending the\n * update, because it would throw an API error.\n */\n } else if (\n data.stages &&\n stagesPerWorkflow &&\n data.stages.length > parseInt(stagesPerWorkflow, 10)\n ) {\n setShowLimitModal('stage');\n } else if (hasDeletedServerStages || isContentTypeReassignment) {\n if (hasDeletedServerStages) {\n setSavePrompts((prev) => ({ ...prev, hasDeletedServerStages: true }));\n }\n\n if (isContentTypeReassignment) {\n setSavePrompts((prev) => ({ ...prev, hasReassignedContentTypes: true }));\n }\n } else {\n await submitForm(data, helpers);\n }\n };\n\n /**\n * If the current license has a limit:\n * check if the total count of workflows or stages exceeds that limit and display\n * the limits modal on page load. It can be closed by the user, but the\n * API will throw an error in case they try to create a new workflow or update the\n * stages.\n *\n * If the current license does not have a limit (e.g. offline license):\n * do nothing (for now). In case they are trying to create the 201st workflow/ stage\n * the API will throw an error.\n *\n */\n React.useEffect(() => {\n if (!isLoadingWorkflow && !isLicenseLoading) {\n if (meta && numberOfWorkflows && meta?.workflowCount > parseInt(numberOfWorkflows, 10)) {\n setShowLimitModal('workflow');\n } else if (\n currentWorkflow &&\n currentWorkflow.stages &&\n stagesPerWorkflow &&\n currentWorkflow.stages.length > parseInt(stagesPerWorkflow, 10)\n ) {\n setShowLimitModal('stage');\n }\n }\n }, [\n currentWorkflow,\n isLicenseLoading,\n isLoadingWorkflow,\n limits,\n meta,\n numberOfWorkflows,\n stagesPerWorkflow,\n ]);\n\n const initialValues: FormValues = React.useMemo(() => {\n if (isCreatingWorkflow || !currentWorkflow) {\n return {\n name: '',\n stages: [],\n contentTypes: [],\n };\n } else {\n return {\n name: currentWorkflow.name,\n stages: addTmpKeysToStages(currentWorkflow.stages),\n contentTypes: currentWorkflow.contentTypes,\n };\n }\n }, [currentWorkflow, isCreatingWorkflow]);\n\n if (isLoadingWorkflow) {\n return <Page.Loading />;\n }\n\n if (error) {\n return <Page.Error />;\n }\n\n return (\n <>\n <Layout.DragLayerRendered />\n\n <Form\n method={isCreatingWorkflow ? 'POST' : 'PUT'}\n initialValues={initialValues}\n validationSchema={WORKFLOW_SCHEMA}\n onSubmit={handleSubmit}\n >\n {({ modified, isSubmitting, values, setErrors }) => (\n <>\n <Layout.Header\n navigationAction={<BackButton />}\n primaryAction={\n canUpdate || canCreate ? (\n <Button\n startIcon={<Check />}\n type=\"submit\"\n disabled={!modified || isSubmitting || values.stages.length === 0}\n // if the confirm dialog is open the loading state is on\n // the confirm button already\n loading={!Boolean(Object.keys(savePrompts).length > 0) && isSubmitting}\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n ) : null\n }\n subtitle={formatMessage(\n {\n id: 'review-workflows.page.subtitle',\n defaultMessage: '{count, plural, one {# stage} other {# stages}}',\n },\n { count: currentWorkflow?.stages?.length ?? 0 }\n )}\n title={\n currentWorkflow?.name ||\n formatMessage({\n id: 'Settings.review-workflows.create.page.title',\n defaultMessage: 'Create Review Workflow',\n })\n }\n />\n <Layout.Root>\n <Flex alignItems=\"stretch\" direction=\"column\" gap={7}>\n <WorkflowAttributes canUpdate={canUpdate || canCreate} />\n <Stages\n canDelete={canDelete}\n canUpdate={canUpdate || canCreate}\n isCreating={isCreatingWorkflow}\n />\n </Flex>\n </Layout.Root>\n <Dialog.Root\n open={Object.keys(savePrompts).length > 0}\n onOpenChange={handleConfirmClose}\n >\n <ConfirmDialog onConfirm={handleConfirmDeleteDialog(values, { setErrors })}>\n <Flex direction=\"column\" gap={5}>\n {savePrompts.hasDeletedServerStages && (\n <Typography textAlign=\"center\" variant=\"omega\">\n {formatMessage({\n id: 'review-workflows.page.delete.confirm.stages.body',\n defaultMessage:\n 'All entries assigned to deleted stages will be moved to the previous stage.',\n })}\n </Typography>\n )}\n\n {savePrompts.hasReassignedContentTypes && (\n <Typography textAlign=\"center\" variant=\"omega\">\n {formatMessage(\n {\n id: 'review-workflows.page.delete.confirm.contentType.body',\n defaultMessage:\n '{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.',\n },\n {\n count:\n contentTypesFromOtherWorkflows?.filter((contentType) =>\n values.contentTypes.includes(contentType)\n ).length ?? 0,\n }\n )}\n </Typography>\n )}\n\n <Typography textAlign=\"center\" variant=\"omega\">\n {formatMessage({\n id: 'review-workflows.page.delete.confirm.confirm',\n defaultMessage: 'Are you sure you want to save?',\n })}\n </Typography>\n </Flex>\n </ConfirmDialog>\n </Dialog.Root>\n </>\n )}\n </Form>\n\n <LimitsModal.Root\n open={showLimitModal === 'workflow'}\n onOpenChange={() => setShowLimitModal(null)}\n >\n <LimitsModal.Title>\n {formatMessage({\n id: 'review-workflows.edit.page.workflows.limit.title',\n defaultMessage: 'You’ve reached the limit of workflows in your plan',\n })}\n </LimitsModal.Title>\n\n <LimitsModal.Body>\n {formatMessage({\n id: 'review-workflows.edit.page.workflows.limit.body',\n defaultMessage: 'Delete a workflow or contact Sales to enable more workflows.',\n })}\n </LimitsModal.Body>\n </LimitsModal.Root>\n\n <LimitsModal.Root\n open={showLimitModal === 'stage'}\n onOpenChange={() => setShowLimitModal(null)}\n >\n <LimitsModal.Title>\n {formatMessage({\n id: 'review-workflows.edit.page.stages.limit.title',\n defaultMessage: 'You have reached the limit of stages for this workflow in your plan',\n })}\n </LimitsModal.Title>\n\n <LimitsModal.Body>\n {formatMessage({\n id: 'review-workflows.edit.page.stages.limit.body',\n defaultMessage: 'Try deleting some stages or contact Sales to enable more stages.',\n })}\n </LimitsModal.Body>\n </LimitsModal.Root>\n </>\n );\n};\n\nconst addTmpKeysToStages = (data: Workflow['stages']) => {\n const keys = generateNKeysBetween(undefined, undefined, data.length);\n\n return data.map((datum, index) => ({\n ...datum,\n __temp_key__: keys[index],\n }));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ProtectedEditPage\n * -----------------------------------------------------------------------------------------------*/\n\nconst ProtectedEditPage = () => {\n const permissions = useTypedSelector((state) => {\n const {\n create = [],\n update = [],\n read = [],\n } = state.admin_app.permissions.settings?.['review-workflows'] ?? {};\n\n return [...create, ...update, ...read];\n });\n\n return (\n <Page.Protect permissions={permissions}>\n <EditPage />\n </Page.Protect>\n );\n};\n\nexport { ProtectedEditPage };\n"],"names":["item","index","AdminInputRenderer","name","value","label","themeColorName","NestedOption","InputRenderer","serverStage","error","Layout.DragLayerRendered","Layout.Header","Layout.Root"],"mappings":";;;;;;;;;;;;;;;AAOA,MAAM,WAAW,mBAAmB,gBAAgB;AAAA,EAClD,UAAU,SAAS;AACV,WAAA;AAAA,MACL,eAAe,QAAQ,MAAmB;AAAA,QACxC,OAAO,OAAO;AAAA,UACZ,KAAK;AAAA,UACL,QAAQ;AAAA,QAAA;AAAA,QAEV,mBAAmB,CAAC,QAAuB;AACzC,iBAAO,IAAI;AAAA,QACb;AAAA,MAAA,CACD;AAAA,IAAA;AAAA,EAEL;AACF,CAAC;AAED,MAAM,EAAE,sBAA0B,IAAA;ACRrB,MAAA,yBAAyB,CACpC,QACA,OACA,EAAE,UAAU,YAAY,YAAY,iBACjC;AACH,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AAElD,QAAA,aAAa,CAAC,aAA4B;AAC9C,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AACI,QAAA,OAAO,UAAU,YAAY,YAAY;AAC3C,UAAI,aAAa,MAAM;AACT,mBAAA,QAAQ,GAAc,KAAK;AAAA,MAAA,WAC9B,aAAa,QAAQ;AAClB,mBAAA,QAAQ,GAAc,KAAK;AAAA,MACzC;AAAA,IACF;AAAA,EAAA;AAGF,QAAM,kBAAkB,MAAM;AAC5B,QAAI,YAAY;AACd,UAAI,YAAY;AACd,mBAAW,KAAK;AAAA,MAClB;AACA,oBAAc,KAAK;AAAA,IAAA,OACd;AACL,UAAI,YAAY;AACd,mBAAW,KAAK;AAAA,MAClB;AACA,oBAAc,IAAI;AAAA,IACpB;AAAA,EAAA;AAGF,QAAM,eAAe,MAAM;AACzB,QAAI,YAAY;AACd,oBAAc,KAAK;AAEnB,UAAI,UAAU;AACZ,iBAAS,KAAK;AAAA,MAChB;AAAA,IACF;AAAA,EAAA;AAGI,QAAA,gBAAgB,CAAoB,MAA8B;AACtE,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,QAAI,EAAE,QAAQ,SAAS,CAAC,YAAY;AAClC;AAAA,IACF;AAEA,MAAE,eAAe;AAEjB,YAAQ,EAAE,KAAK;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AACa;AAChB;AAAA,MAEF,KAAK;AACU;AACb;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,mBAAW,MAAM;AACjB;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,mBAAW,IAAI;AACf;AAAA,IAGJ;AAAA,EAAA;AAGK,SAAA;AACT;AC5EA,MAAM,aAAa;AAAA,EACjB,QAAQ;AAAA,EACR,UAAU;AACZ;AAEA,MAAM,mBAAmB;AAAA,EACvB,SAAS;AAAA,EACT,WAAW;AACb;AAuCA,MAAM,iBAAiB,CAQrB,QACA;AAAA,EACE,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB,iBAAiB;AACrC,MAC4B;AACtB,QAAA,YAAY,MAAM,OAAU,IAAI;AAEtC,QAAM,CAAC,EAAE,WAAW,OAAU,GAAA,OAAO,IAAI,QAAyC;AAAA,IAChF,QAAQ;AAAA,IACR,QAAQ,SAAS;AACR,aAAA;AAAA,QACL,WAAW,QAAQ,aAAa;AAAA,QAChC,QAAQ,QAAQ,OAAO,EAAE,SAAS,MAAM;AAAA,MAAA;AAAA,IAE5C;AAAA,IACA,KAAKA,OAAM;AACT,YAAM,eAAeA,MAAK;AAC1B,YAAM,WAAW;AAEjB,UAAI,UAAU,YAAY;AACxB,mBAAW,cAAc,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,IACA,MAAMA,OAAM,SAAS;AACnB,UAAI,CAAC,UAAU,WAAW,CAAC,YAAY;AACrC;AAAA,MACF;AAEA,YAAM,YAAYA,MAAK;AACvB,YAAM,WAAW;AAEX,YAAA,oBAAoB,UAAU,SAAS,sBAAsB;AACnE,YAAM,gBAAgB,kBAAkB,SAAS,kBAAkB,OAAO;AACpE,YAAA,eAAe,QAAQ;AAC7B,UAAI,CAAC;AAAc;AAEnB,YAAM,eAAe,gBAAgB,aAAa,IAAI,kBAAkB;AACxE,UAAI,OAAO,cAAc,YAAY,OAAO,aAAa,UAAU;AACjE,YAAI,cAAc,UAAU;AAE1B;AAAA,QACF;AAEI,YAAA,oBAAoB,iBAAiB,SAAS;AAE5C,cAAA,YAAY,YAAY,eAAe,cAAc;AACvD;AAAA,UACF;AAGI,cAAA,YAAY,YAAY,eAAe,cAAc;AACvD;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,UAAU,SAAS;AAC9BA,cAAK,QAAQ;AAAA,MAAA,OACR;AAEL,YAAI,MAAM,QAAQ,SAAS,KAAK,MAAM,QAAQ,QAAQ,GAAG;AAEvD,gBAAM,YAAY,KAAK,IAAI,UAAU,QAAQ,SAAS,MAAM;AAC5D,cAAI,WAAW;AACf,cAAI,aAAa;AACjB,cAAI,gBAAgB;AAEpB,mBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,gBAAI,UAAU,CAAC,IAAI,SAAS,CAAC,GAAG;AACjB,2BAAA;AACF,yBAAA;AACX;AAAA,uBACS,UAAU,CAAC,IAAI,SAAS,CAAC,GAAG;AACrB,8BAAA;AACL,yBAAA;AACX;AAAA,YACF;AAAA,UACF;AAGA,cAAI,YAAY,UAAU,WAAW,SAAS,QAAQ;AACpD;AAAA,UACF;AAEI,cAAA,oBAAoB,iBAAiB,SAAS;AAEhD,gBAAI,cAAc,CAAC,iBAAiB,eAAe,cAAc;AAC/D;AAAA,YACF;AAGA,gBAAI,iBAAiB,CAAC,cAAc,eAAe,cAAc;AAC/D;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,UAAU,SAAS;AAC9BA,cAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EAAA,CACD;AAEK,QAAA,mBAAmB,CAAC,YAA4C;AACpE,QACE,WACA,QAAQ,WAAW,KACnB,CAAC,QAAQ,QAAQ,KACjB,QAAQ,uBAAA,KACR,QAAQ,mBACR;AACA,YAAM,SAAS,QAAQ,yBAA0B,IAAI,QAAQ,gBAAmB,EAAA;AAEhF,UAAI,SAAS;AAAG,eAAO,WAAW;AAElC,UAAI,SAAS;AAAG,eAAO,WAAW;AAE3B,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EAAA;AAGH,QAAA,CAAC,EAAE,YAAY,UAAA,GAAa,SAAS,cAAc,IAAI,QAAQ;AAAA,IACnE;AAAA,IACA,OAAO;AACL,UAAI,SAAS;AACH;MACV;AAMA,YAAM,EAAE,MAAM,IAAI,UAAU,SAAS,2BAA2B;AAEhE,aAAO,EAAE,OAAO,OAAO,GAAG,KAAK;AAAA,IACjC;AAAA,IACA,MAAM;AACJ,UAAI,OAAO;AACH;MACR;AAAA,IACF;AAAA,IACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMT,YAAY,MAAM,KACd,CAAC,YAAY;AACX,aAAO,KAAK,OAAO,QAAQ,QAAA,EAAU;AAAA,IAEvC,IAAA;AAAA,IACJ,SAAS,CAAC,aAAa;AAAA,MACrB,YAAY,QAAQ,WAAW;AAAA,MAC/B,eAAe,QAAQ,uBAAuB;AAAA,MAC9C,eAAe,QAAQ,gBAAgB;AAAA,MACvC,WAAW,iBAAiB,OAAO;AAAA,IAAA;AAAA,EACrC,CACD;AAEK,QAAA,gBAAgB,uBAAuB,QAAQ,OAAO;AAAA,IAC1D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAEM,SAAA;AAAA,IACL,EAAE,WAAW,YAAY,eAAe,kBAAkB,QAAQ,UAAU;AAAA,IAC5E;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AC/PO,MAAM,WAAW,CAAC,EAAE,UAAU,GAAG,YAAyB;AAE7D,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAI;AAAA,MACJ,YAAW;AAAA,MACX,aAAY;AAAA,MACZ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,QAAO;AAAA,MACN,GAAG;AAAA,MAEJ,UAAA,oBAAC,YAAW,EAAA,SAAQ,MAAK,YAAW,QAClC,UAAA,qBAAC,MAAK,EAAA,KAAI,QAAO,KAAK,GACpB,UAAA;AAAA,QAAA,oBAAC,cAAW,OAAM,UAAS,QAAO,UAAS,eAAW,MAAC;AAAA,QACtD;AAAA,MAAA,EAAA,CACH,EACF,CAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,MAAM,eAAe,OAA+B,GAAG;AAAA;AAAA,WAE5C,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;AAAA,aAGpC,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,aAItC,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;ACoBnD,MAAM,SAAS,CAAC,EAAE,YAAY,MAAM,YAAY,MAAM,iBAA8B;AAC5E,QAAA,EAAE,kBAAkB;AACpB,QAAA,EAAE,eAAe;AACvB,QAAM,cAAc,QAAQ,UAAU,CAAC,UAAU,MAAM,WAAW;AAClE,QAAM,EAAE,OAAO,SAAS,CAAG,EAAA,IAAI,SAA0B,QAAQ;AAEjE,8BACG,MAAK,EAAA,WAAU,UAAS,KAAK,GAAG,OAAM,QACrC,UAAA;AAAA,IAAA,qBAAC,KAAI,EAAA,UAAS,YAAW,OAAM,QAC7B,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,YAAW;AAAA,UACX,QAAO;AAAA,UACP,MAAK;AAAA,UACL,UAAS;AAAA,UACT,KAAI;AAAA,UACJ,OAAO;AAAA,QAAA;AAAA,MACT;AAAA,0BAEC,MAAK,EAAA,WAAU,UAAS,YAAW,WAAU,KAAK,GAAG,UAAS,YAAW,KAAI,MAC3E,UAAA,OAAO,IAAI,CAAC,OAAO,UAAU;AAE1B,eAAA,oBAAC,KAA6B,EAAA,KAAI,MAChC,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA,WAAW,OAAO,SAAS,KAAK;AAAA,YAChC,YAAY,OAAO,SAAS;AAAA,YAC5B;AAAA,YACA,aAAa,OAAO;AAAA,YACpB,aAAa;AAAA,YACZ,GAAG;AAAA,UAAA;AAAA,QAAA,KARE,MAAM,YAUhB;AAAA,MAEH,CAAA,GACH;AAAA,IAAA,GACF;AAAA,IAEC,aACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAM;AACb,sBAAY,UAAU,EAAE,MAAM,GAAI,CAAA;AAClC,qBAAW,iBAAiB;AAAA,QAC9B;AAAA,QAEC,UAAc,cAAA;AAAA,UACb,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,MAAA;AAAA,IACH;AAAA,EAEJ,EAAA,CAAA;AAEJ;AAEA,MAAM,aAAa,OAAO,GAAG;AAAA;AAAA;AAgB7B,MAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAkB;AAChB,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAiB;AACjD,QAAA,EAAE,kBAAkB;AACpB,QAAA,EAAE,eAAe;AACvB,QAAM,cAAc,QAAQ,UAAU,CAAC,UAAU,MAAM,OAAO,MAAkB;AAC1E,QAAA,QAAQ,cAAc,KAAK;AACjC,QAAM,cAAc,QAAQ,SAAS,CAAC,UAAU,MAAM,WAAW;AACjE,QAAM,eAAe,QAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AACnE,QAAM,iBAAiB,QAAQ,SAAS,CAAC,UAAU,MAAM,cAAc;AAEvE,QAAM,aAAa,CAACC,WAAkB,GAAGA,SAAQ,CAAC,OAAO,WAAW;AAE9D,QAAA,kBAAkB,CAACA,WAAkB;AACzC;AAAA,MACE;AAAA,QACE;AAAA,UACE,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAClB;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,WAAWA,MAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IAAA;AAAA,EACF;AAGI,QAAA,kBAAkB,CAACA,WAAkB;AACzC;AAAA,MACE;AAAA,QACE;AAAA,UACE,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAClB;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,WAAWA,MAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IAAA;AAAA,EACF;AAGF,QAAM,wBAAwB,MAAM;AAClC;AAAA,MACE;AAAA,QACE;AAAA,UACE,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAClB;AAAA,QACA;AAAA,UACE,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IAAA;AAAA,EACF;AAGI,QAAA,kBAAkB,CAAC,UAAkB,aAAqB;AAC9D;AAAA,MACE;AAAA,QACE;AAAA,UACE,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAClB;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,WAAW,QAAQ;AAAA,QAC/B;AAAA,MACF;AAAA,IAAA;AAGW,iBAAA,UAAU,UAAU,QAAQ;AAAA,EAAA;AAG3C,QAAM,CAAC,EAAE,WAAW,YAAY,cAAc,GAAG,UAAU,SAAS,SAAS,cAAc,IACzF,eAAe,YAAY;AAAA,IACzB;AAAA,IACA,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,MAAM,gBAAgB;AAAA,EAAA,CACvB;AAGG,QAAA,cAAc,gBAAgC,UAAU,OAAO;AAErE,QAAM,UAAU,MAAM;AACpB,mBAAe,cAAc,GAAG,EAAE,sBAAsB,MAAO,CAAA;AAAA,EAAA,GAC9D,CAAC,gBAAgB,KAAK,CAAC;AAE1B,QAAM,mBAAmB,MAAM;AAC7B,gBAAY,UAAU,EAAE,MAAM,OAAO,YAAa,CAAA;AAAA,EAAA;AAG9C,QAAA,KAAK,MAAM;AAEjB,SACG,qBAAA,KAAA,EAAI,KAAK,aAAa,QAAO,eAC3B,UAAA;AAAA,IAAA,YAAa,oBAAA,gBAAA,EAAe,aAAU,aAAa,UAAS,UAAA;AAAA,IAE5D,aACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,YAAW;AAAA,QACX,aAAY;AAAA,QACZ,aAAY;AAAA,QACZ,aAAY;AAAA,QACZ,SAAQ;AAAA,QACR,WAAS;AAAA,QACT,SAAS;AAAA,MAAA;AAAA,IAAA,IAGX;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAe,CAAC,UAAU;AACxB,cAAI,OAAO;AACT,uBAAW,eAAe;AAAA,UAC5B;AAAA,QACF;AAAA,QACA,cAAc,cAAc,KAAK;AAAA,QACjC,QAAQ,OAAO,OAAO,SAAS,CAAE,CAAA,EAAE,SAAS;AAAA,QAE5C,UAAC,qBAAA,UAAU,MAAV,EAAe,OAAO,IACrB,UAAA;AAAA,UAAC,qBAAA,UAAU,QAAV,EACC,UAAA;AAAA,YAAC,oBAAA,UAAU,SAAV,EAAmB,UAAK,KAAA,CAAA;AAAA,gCACxB,UAAU,SAAV,EACE,UAAA,aAAa,YAEV,qBAAA,UAAA,EAAA,UAAA;AAAA,cAAC,qBAAA,KAAK,MAAL,EACC,UAAA;AAAA,gBAAC,qBAAA,oBAAA,EAAmB,MAAK,KAAI,SAAS,MAAM,aAAa,GAAG,cAAc,GACxE,UAAA;AAAA,kBAAA,oBAAC,MAAK,EAAA,eAAW,MAAC,WAAW,OAAO;AAAA,kBACnC,oBAAA,gBAAA,EAAe,KAAI,QACjB,UAAc,cAAA;AAAA,oBACb,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBACjB,CAAA,GACH;AAAA,gBAAA,GACF;AAAA,gBAIA,oBAAC,KAAK,SAAL,EAAa,kBAAiB,cAAa,QAAQ,GAClD,UAAA,qBAAC,KAAK,SAAL,EACE,UAAA;AAAA,kBAAA,aACE,oBAAA,UAAA,EAAS,SAAS,kBAChB,UAAc,cAAA;AAAA,oBACb,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBACjB,CAAA,GACH;AAAA,kBAGD,iCACE,gBAAe,EAAA,SAAS,MAAM,eAAe,UAAU,KAAK,GAC1D,UAAc,cAAA;AAAA,oBACb,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBACjB,CAAA,GACH;AAAA,gBAAA,EAAA,CAEJ,EACF,CAAA;AAAA,cAAA,GACF;AAAA,cAEC,aACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,YAAW;AAAA,kBACX,WAAS;AAAA,kBACT,SAAQ;AAAA,kBACR,mBAAiB;AAAA,kBACjB,KAAK;AAAA,kBACL,OAAO,cAAc;AAAA,oBACnB,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBAAA,CACjB;AAAA,kBACD,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,kBAClC,WAAW;AAAA,kBAEX,8BAAC,MAAK,EAAA;AAAA,gBAAA;AAAA,cACR;AAAA,YAAA,EAEJ,CAAA,IACE,MACN;AAAA,UAAA,GACF;AAAA,UACA,oBAAC,UAAU,SAAV,EACC,UAAA,oBAAC,KAAK,MAAL,EAAU,KAAK,GAAG,SAAS,GACzB,UAAA;AAAA,YACC;AAAA,cACE,UAAU,CAAC;AAAA,cACX,OAAO,cAAc;AAAA,gBACnB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAM,UAAU,KAAK;AAAA,cACrB,UAAU;AAAA,cACV,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,YACA;AAAA,cACE,UAAU,CAAC;AAAA,cACX,OAAO,cAAc;AAAA,gBACnB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAM,UAAU,KAAK;AAAA,cACrB,UAAU;AAAA,cACV,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,YACA;AAAA,cACE,UAAU,CAAC;AAAA,cACX,OAAO,cAAc;AAAA,gBACnB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,MAAM,UAAU,KAAK;AAAA,cACrB,aAAa,cAAc;AAAA,gBACzB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,UAAU;AAAA,cACV,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAChB,MAAA,oBAAC,KAAK,MAAL,EAA2B,KAAK,MAAM,WAAU,UAAS,YAAW,WACnE,UAAA,oBAAC,eAAe,EAAA,GAAG,OAAO,EAAA,GADZ,MAAM,IAEtB,CACD,EAAA,CACH,EACF,CAAA;AAAA,QAAA,GACF;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ,EAAA,CAAA;AAEJ;AAEA,MAAM,gBAAgB,OAAO,UAAU,IAAI;AAAA;AAAA,MAErC,CAAC,EAAE,OAAO,OAAO,MAAO,SAAS,MAAM,OAAO,YAAY,MAAM,OAAO,UAAW;AAAA;AAGxF,MAAM,iBAAiB,OAAO,QAAQ;AAAA,WAC3B,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,SAAS;AAAA;AAKhD,MAAM,qBAAqB,OAAO,KAAK,OAAO;AAAA;AAAA;AAAA,wBAGtB,CAAC,EAAE,MAAA,MAAY,MAAM,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc9D,MAAM,gBAAgB,CAAC,UAA8B;AACnD,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACI,aAAA,oBAAC,eAAe,EAAA,GAAG,MAAO,CAAA;AAAA,IACnC,KAAK;AACI,aAAA,oBAAC,kBAAkB,EAAA,GAAG,MAAO,CAAA;AAAA,IACtC;AACS,aAAA,oBAACC,iBAAoB,EAAA,GAAG,MAAO,CAAA;AAAA,EAC1C;AACF;AAWA,MAAM,gBAAgB,CAAC,EAAE,UAAU,OAAO,MAAM,eAAmC;AAC3E,QAAA,EAAE,kBAAkB;AAC1B,QAAM,EAAE,OAAO,OAAO,SAAS,IAAI,SAAiB,IAAI;AAElD,QAAA,eAAe,iBAAiB,IAAI,CAAC,EAAE,KAAK,MAAAC,aAAY;AAAA,IAC5D,OAAO;AAAA,IACP,OAAO;AAAA,MACL;AAAA,QACE,IAAI;AAAA,QACJ,gBAAgB;AAAA,MAClB;AAAA,MACA,EAAE,MAAAA,MAAK;AAAA,IACT;AAAA,IACA,OAAO;AAAA,EACP,EAAA;AAEF,QAAM,EAAE,eAAe,IAAI,mBAAmB,KAAK,KAAK,CAAA;AAExD,8BACG,MAAM,MAAN,EAAW,OAAc,MAAY,UACpC,UAAA;AAAA,IAAC,oBAAA,MAAM,OAAN,EAAa,UAAM,MAAA,CAAA;AAAA,IACpB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,UAAU,CAAC,MAAM;AACN,mBAAA,MAAM,EAAE,SAAU,CAAA;AAAA,QAC7B;AAAA,QACA,OAAO,OAAO,YAAY;AAAA,QAC1B,WACE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAI;AAAA,YACJ,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,aAAa,mBAAmB,aAAa,eAAe;AAAA,YAC5D,WAAS;AAAA,YACT,QAAQ;AAAA,YACR,OAAO;AAAA,UAAA;AAAA,QACT;AAAA,QAGD,UAAA,aAAa,IAAI,CAAC,EAAE,OAAAC,QAAO,OAAAC,QAAO,YAAY;AAC7C,gBAAM,EAAE,gBAAAC,gBAAAA,IAAmB,mBAAmB,KAAK,KAAK;AAGtD,iBAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAOF;AAAAA,cAEP,WACE;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,KAAI;AAAA,kBACJ,QAAQ;AAAA,kBACR,YAAY;AAAA,kBACZ,aAAaE,oBAAmB,aAAa,eAAe;AAAA,kBAC5D,WAAS;AAAA,kBACT,QAAQ;AAAA,kBACR,OAAO;AAAA,gBAAA;AAAA,cACT;AAAA,cAGD,UAAAD;AAAAA,YAAA;AAAA,YAbID;AAAAA,UAAA;AAAA,QAcP,CAEH;AAAA,MAAA;AAAA,IACH;AAAA,IACA,oBAAC,MAAM,OAAN,EAAY;AAAA,EACf,EAAA,CAAA;AAEJ;AAUA,MAAM,mBAAmB,CAAC,EAAE,UAAU,MAAM,aAAa,eAAsC;AACvF,QAAA,EAAE,kBAAkB;AACpB,QAAA,EAAE,uBAAuB;AAC/B,QAAM,CAAC,4BAA4B,6BAA6B,IAAI,MAAM,SAAS,KAAK;AAClF,QAAA,EAAE,QAAQ,IAAI,OAAO,aAAa,SAA4B,IAAI;AACxE,QAAM,YAAY,QAAyB,oBAAoB,CAAC,UAAU,MAAM,OAAO,MAAM;AAC7F,QAAM,oBAAoB,QAAQ,oBAAoB,CAAC,UAAU,MAAM,QAAQ;AACzE,QAAA,kBAAkB,MAAM,OAAO,CAAC;AAEhC,QAAA,EAAE,MAAM,QAAQ,IAAI,WAAW,OAAO,kBAAkB;AAIxD,QAAA,gBAAgB,OAAO,OAAO,CAAC,SAAS,KAAK,SAAS,oBAAoB,KAAK;AAErF,QAAM,UAAU,MAAM;AAElB,QAAA,CAAC,aACD,iBACA,YAAY,iBACZ,cAAc,UAAU,OACxB,gBAAgB,YAAY,GAC5B;AACA,sBAAgB,UAAU;AAEP,yBAAA;AAAA,QACjB,iBAAiB;AAAA,QACjB,MAAM;AAAA,QACN,SAAS,cAAc;AAAA,UACrB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,MAAA,CACF;AAAA,IACH;AAAA,EAAA,GACC,CAAC,eAAe,WAAW,OAAO,oBAAoB,aAAa,CAAC;AAEvE,MAAI,CAAC,aAAa,cAAc,WAAW,GAAG;AAE1C,WAAA;AAAA,MAAC,MAAM;AAAA,MAAN;AAAA,QACC;AAAA,QACA,MAAM,cAAc;AAAA,UAClB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,QACD;AAAA,QAEA,UAAA;AAAA,UAAC,oBAAA,MAAM,OAAN,EACE,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,UACA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,UAAQ;AAAA,cACR,aAAa,cAAc;AAAA,gBACzB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,aAAa,oBAAC,YAAW,EAAA,MAAK,aAAa,CAAA;AAAA,cAC3C,MAAK;AAAA,cACL,OAAM;AAAA,YAAA;AAAA,UACR;AAAA,UACA,oBAAC,MAAM,MAAN,EAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGlB;AAEA,yCAEI,UAAC,qBAAA,MAAA,EAAK,YAAW,YAAW,KAAK,GAC/B,UAAA;AAAA,IAAC,oBAAA,mBAAA,EAAkB,MAAM,GACvB,UAAC,qBAAA,MAAM,MAAN,EAAW,OAAc,MAAY,UAAQ,MAC5C,UAAA;AAAA,MAAC,oBAAA,MAAM,OAAN,EACE,UAAc,cAAA;AAAA,QACb,IAAI;AAAA,QACJ,gBAAgB;AAAA,MACjB,CAAA,GACH;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,UAAU,CAAC,WAAW;AAIpB,kBAAM,cAAc,OAAO,IAAI,CAACA,YAAW;AAAA,cACzC,MAAM,SAASA,QAAO,EAAE;AAAA,cACxB,QAAQ;AAAA,YACR,EAAA;AAEF,qBAAS,MAAM,WAAW;AAAA,UAC5B;AAAA,UACA;AAAA,UAEA,OAAO,MAAM,IAAI,CAAC,eAAe,GAAG,WAAW,IAAI,EAAE;AAAA,UACrD,UAAQ;AAAA,UAER,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,cAAc;AAAA,gBACnB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,QAAQ,cAAc,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,EAAE;AAAA,cAEzC,UAAA,cAAc,IAAI,CAAC,SAAS;AAEzB,uBAAA,oBAACG,gBAA2B,EAAA,OAAO,GAAG,KAAK,EAAE,IAC1C,UAAA,KAAK,KADW,GAAA,KAAK,EAExB;AAAA,cAAA,CAEH;AAAA,YAAA;AAAA,UACH;AAAA,QAAA;AAAA,MACF;AAAA,MACA,oBAAC,MAAM,OAAN,EAAY;AAAA,IAAA,EAAA,CACf,EACF,CAAA;AAAA,yBACC,OAAO,MAAP,EAAY,MAAM,4BAA4B,cAAc,+BAC3D,UAAA;AAAA,MAAC,oBAAA,OAAO,SAAP,EACC,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,OAAO,cAAc;AAAA,YACnB,IAAI;AAAA,YACJ,gBAAgB;AAAA,UAAA,CACjB;AAAA,UACD,MAAK;AAAA,UAEL,8BAAC,WAAU,EAAA;AAAA,QAAA;AAAA,MAAA,GAEf;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,MAAM;AACf;AAAA,cACE;AAAA,cACA,UAAU,IAAI,CAAC,WAAW;AAAA,gBACxB,GAAG;AAAA,gBACH,aAAa;AAAA,cAAA,EACb;AAAA,YAAA;AAGJ,0CAA8B,KAAK;AAChB,+BAAA;AAAA,cACjB,MAAM;AAAA,cACN,SAAS,cAAc;AAAA,gBACrB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,YAAA,CACF;AAAA,UACH;AAAA,UACA,SAAQ;AAAA,UAEP,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBACE;AAAA,UAAA,CACH;AAAA,QAAA;AAAA,MACH;AAAA,IAAA,GACF;AAAA,EAAA,EACF,CAAA,EACF,CAAA;AAEJ;AAEA,MAAMA,iBAAe,OAAO,iBAAiB;AAAA,kBAC3B,CAAC,EAAE,YAAY,MAAM,OAAO,CAAC,CAAC;AAAA;AAIhD,MAAM,oBAAoB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;ACroBrC,MAAM,qBAAqB,CAAC,EAAE,YAAY,WAAoC;AACtE,QAAA,EAAE,kBAAkB;AAE1B,SACG,qBAAA,KAAK,MAAL,EAAU,YAAW,YAAW,WAAS,MAAC,KAAK,GAAG,SAAS,GAAG,QAAO,eACpE,UAAA;AAAA,IAAC,oBAAA,KAAK,MAAL,EAAU,KAAK,GAAG,WAAU,UAAS,YAAW,WAC/C,UAAA;AAAA,MAACC;AAAAA,MAAA;AAAA,QACC,UAAU,CAAC;AAAA,QACX,OAAO,cAAc;AAAA,UACnB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,QACD,MAAK;AAAA,QACL,UAAQ;AAAA,QACR,MAAK;AAAA,MAAA;AAAA,IAAA,GAET;AAAA,IACC,oBAAA,KAAK,MAAL,EAAU,KAAK,GAAG,WAAU,UAAS,YAAW,WAC/C,UAAC,oBAAA,sBAAA,EAAqB,UAAU,CAAC,UAAW,CAAA,GAC9C;AAAA,EACF,EAAA,CAAA;AAEJ;AASA,MAAM,uBAAuB,CAAC,EAAE,eAA0C;AACxE,QAAM,EAAE,eAAe,OAAO,IAAI,QAAQ;AAC1C,QAAM,EAAE,MAAM,cAAc,cAAc,wBAAwB;AAC5D,QAAA,EAAE,cAAc;AACtB,QAAM,kBAAkB,QAAQ,wBAAwB,CAAC,UAAU,MAAM,MAAM;AAE/E,QAAM,EAAE,OAAO,OAAO,SAAS,IAAI,SAAS,cAAc;AAEpD,QAAA,YAAY,YAAY,QAAQ;AAAA,IACpC,aAAa;AAAA,EAAA,CACd;AAEK,QAAA,aACJ,YACA,aACA,CAAC,gBACA,aAAa,eAAe,WAAW,KAAK,aAAa,WAAW,WAAW;AAE5E,QAAA,mBAAmB,cAAc,kBAAkB,IACtD,SAAS,CAAC,GAAG,MAAM,UAAU,QAAQ,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,CAAC,EAC5E,IAAI,CAAC,iBAAiB;AAAA,IACrB,OAAO,YAAY,KAAK;AAAA,IACxB,OAAO,YAAY;AAAA,EACnB,EAAA;AAEJ,QAAM,eAAe,cAAc,cAAc,CAAA,GAAI,IAAI,CAAC,iBAAiB;AAAA,IACzE,OAAO,YAAY,KAAK;AAAA,IACxB,OAAO,YAAY;AAAA,EACnB,EAAA;AAEF,8BACG,MAAM,MAAN,EAAW,OAAc,MAAM,gBAC9B,UAAA;AAAA,IAAC,oBAAA,MAAM,OAAN,EACE,UAAc,cAAA;AAAA,MACb,IAAI;AAAA,MACJ,gBAAgB;AAAA,IACjB,CAAA,GACH;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,kBAAkB,CAACJ,WACjB;AAAA,UACE;AAAA,YACE,IAAI;AAAA,YACJ,gBACE;AAAA,UACJ;AAAA,UACA,EAAE,OAAOA,QAAO,OAAO;AAAA,QACzB;AAAA,QAEF,UAAU;AAAA,QACV,UAAU,CAAC,WAAW;AACpB,mBAAS,gBAAgB,MAAM;AAAA,QACjC;AAAA,QACA;AAAA,QACA,aAAa,cAAc;AAAA,UACzB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,QAEA,UAAA;AAAA,UACC,GAAI,gBAAgB,SAAS,IACzB;AAAA,YACE;AAAA,cACE,OAAO,cAAc;AAAA,gBACnB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,UAAU;AAAA,YACZ;AAAA,UAAA,IAEF,CAAC;AAAA,UAEL,GAAI,YAAY,SAAS,IACrB;AAAA,YACE;AAAA,cACE,OAAO,cAAc;AAAA,gBACnB,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,cACD,UAAU;AAAA,YACZ;AAAA,UAAA,IAEF,CAAC;AAAA,QAAA,EACL,IAAI,CAAC,QAAQ;AAEX,iBAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,OAAO,IAAI;AAAA,cACX,QAAQ,IAAI,SAAS,IAAI,CAAC,UAAU,MAAM,MAAM,UAAU;AAAA,cAEzD,UAAI,IAAA,SAAS,IAAI,CAAC,UAAU;AAC3B,sBAAM,EAAE,MAAM,qBAAqB,IACjC,WAAW;AAAA,kBACT,CAAC,cACG,mBAAmB,SAAS,OAAO,gBAAgB,MACnD,CAAC,oBACH,SAAS,aAAa,SAAS,MAAM,KAAK;AAAA,qBACzC;AAEP,uBACG,oBAAA,cAAA,EAA+B,OAAO,MAAM,OAC3C,UAAC,oBAAA,YAAA;AAAA;AAAA,kBAGG,UAAA;AAAA,oBACE;AAAA,sBACE,IAAI;AAAA,sBACJ,gBACE;AAAA,oBACJ;AAAA,oBACA;AAAA,sBACE,OAAO,MAAM;AAAA,sBACb,MAAM;AAAA,sBACN,IAAI,IAAI,aACN,oBAAC,cAAW,KAAI,MAAK,YAAW,QAC7B,SACH,CAAA;AAAA,sBAEF,GAAG,IAAI,aACL,oBAAC,yBAAuB,UAAS;AAAA,oBAErC;AAAA,kBACF;AAAA,gBAAA,CAEJ,EAAA,GAxBiB,MAAM,KAyBzB;AAAA,cAAA,CAEH;AAAA,YAAA;AAAA,YAzCI,IAAI;AAAA,UAAA;AAAA,QA0CX,CAEH;AAAA,MAAA;AAAA,IACH;AAAA,EACF,EAAA,CAAA;AAEJ;AAEA,MAAM,eAAe,OAAO,iBAAiB;AAAA,kBAC3B,CAAC,EAAE,YAAY,MAAM,OAAO,CAAC,CAAC;AAAA;AAGhD,MAAM,wBAAwB,OAAO,UAAU;AAAA;AAAA;AC1J/C,MAAM,kBAAkB,IAAI,OAAO;AAAA,EACjC,cAAc,IAAI,MAAA,EAAQ,GAAG,IAAI,QAAQ;AAAA,EACzC,MAAM,IACH,SACA,IAAI,KAAK;AAAA,IACR,IAAI;AAAA,IACJ,gBAAgB;AAAA,EAAA,CACjB,EACA,SAAS,EACT,SAAS;AAAA,EACZ,QAAQ,IACL,MAAA,EACA;AAAA,IACC,IAAI,OAAO,EAAE,MAAM;AAAA,MACjB,MAAM,IACH,OACA,EAAA,SAAA,EACA,SAAS;AAAA,QACR,IAAI;AAAA,QACJ,gBAAgB;AAAA,MAAA,CACjB,EACA,IAAI,KAAK;AAAA,QACR,IAAI;AAAA,QACJ,gBAAgB;AAAA,MACjB,CAAA,EACA;AAAA,QACC;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAClB;AAAA,QACA,CAAC,WAAW,YAAY;AAEtB,gBAAM,EAAE,OAAO,IAAI,QAAQ,KAAK,CAAC,EAAE;AAE5B,iBAAA,OAAO,OAAO,CAAC,UAAiB,MAAM,SAAS,SAAS,EAAE,WAAW;AAAA,QAC9E;AAAA,MACF;AAAA,MACF,OAAO,IACJ,OACA,EAAA,SAAA,EACA,SAAS;AAAA,QACR,IAAI;AAAA,QACJ,gBAAgB;AAAA,MAAA,CACjB,EACA,QAAQ,6BAA6B;AAAA,MAExC,aAAa,IACV;AAAA,QACC,IAAI,OAAO;AAAA,UACT,MAAM,IACH,OACA,EAAA,OAAA,EACA,UAAU;AAAA,YACT,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,EACA,SAAS;AAAA,UACZ,QAAQ,IAAI,OAAO,EAAE,SAAS;AAAA,YAC5B,IAAI;AAAA,YACJ,gBAAgB;AAAA,UAAA,CACjB;AAAA,QAAA,CACF;AAAA,QAEF,OAAO;AAAA,IAAA,CACX;AAAA,EAAA,EAEF,IAAI,CAAC;AACV,CAAC;AAED,MAAM,WAAW,MAAM;AACrB,QAAM,EAAE,KAAK,GAAG,IAAI,UAA0B;AAC9C,QAAM,qBAAqB,OAAO;AAC5B,QAAA,EAAE,kBAAkB;AAC1B,QAAM,EAAE,iCAAiC,uBAAuB,IAAI,mBAAmB;AACvF,QAAM,WAAW;AACX,QAAA,EAAE,uBAAuB;AACzB,QAAA;AAAA,IACJ,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,mBAAmB;AACvB,QAAM,cAAc;AAAA,IAClB,CAAC,UAAU,MAAM,UAAU,YAAY,UAAU,IAAI,kBAAkB;AAAA,EAAA;AAEnE,QAAA;AAAA,IACJ,gBAAgB,EAAE,WAAW,WAAW,UAAU;AAAA,EAAA,IAChD,QAAQ,WAAW;AAEvB,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAGzC,CAAA,CAAE;AACL,QAAM,EAAE,YAAY,WAAW,qBAAqB,iBAAiB;AACrE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAsC,IAAI;AAEtF,QAAA,kBAAkB,WAAW,KAAK,CAAC,aAAa,SAAS,OAAO,SAAS,IAAI,EAAE,CAAC;AACtF,QAAM,iCAAiC,WACnC,OAAO,CAAC,aAAa,SAAS,OAAO,SAAS,IAAI,EAAE,CAAC,EACtD,QAAQ,CAAC,aAAa,SAAS,YAAY;AAExC,QAAA,SAAS,WAAmB,kBAAkB;AAC9C,QAAA,oBAAoB,SAAS,mCAAmC;AAChE,QAAA,oBAAoB,SAAS,8CAA8C;AAQ3E,QAAA,aAAa,OAAO,MAAkB,YAA4C;AAClF,QAAA;AACF,UAAI,CAAC,oBAAoB;AACjB,cAAA,MAAM,MAAM,OAAO,IAAI;AAAA,UAC3B,GAAG;AAAA;AAAA;AAAA;AAAA,UAIH,QAAQ,KAAK,OAAO,IAAI,CAAC,UAAU;AACjC,gBAAI,wBAAwB;AACtB,kBAAA,cAAc,iBAAiB,QAAQ;AAAA,cAC3C,CAACK,iBAAgBA,aAAY,OAAO,OAAO;AAAA,YAAA;AAE7C,gBAAI,aAAa;AAEb,sCAAA,YAAY,aAAa,WAAW,MAAM,aAAa,UACvD,CAAC,YAAY,aAAa;AAAA,gBACxB,CAAC,qBACC,CAAC,CAAC,MAAM,aAAa;AAAA,kBACnB,CAAC,eAAe,WAAW,SAAS,iBAAiB;AAAA,gBACvD;AAAA,cAAA;AAAA,YAER;AACO,mBAAA;AAAA,cACL,GAAG;AAAA,cACH,aAAa,wBAAwB,MAAM,cAAc;AAAA,YAAA;AAAA,UAC3D,CACD;AAAA,QAAA,CACF;AAEG,YAAA,WAAW,OAAO,iBAAiB,IAAI,KAAK,KAAK,IAAI,MAAM,SAAS,mBAAmB;AACzF,kBAAQ,UAAU,uBAAuB,IAAI,KAAK,CAAC;AAAA,QACrD;AAAA,MAAA,OACK;AACC,cAAA,MAAM,MAAM,OAAO,IAAI;AAEzB,YAAA,WAAW,OAAO,iBAAiB,IAAI,KAAK,KAAK,IAAI,MAAM,SAAS,mBAAmB;AACzF,kBAAQ,UAAU,uBAAuB,IAAI,KAAK,CAAC;AAAA,QAAA,WAC1C,UAAU,KAAK;AACf,mBAAA,MAAM,IAAI,KAAK,EAAE,IAAI,EAAE,SAAS,MAAM;AAAA,QACjD;AAAA,MACF;AAAA,aACOC,QAAO;AACK,yBAAA;AAAA,QACjB,MAAM;AAAA,QACN,SAAS,cAAc;AAAA,UACrB,IAAI;AAAA,UACJ,gBAAgB;AAAA,QAAA,CACjB;AAAA,MAAA,CACF;AAAA,IACH;AACA,mBAAe,CAAE,CAAA;AAAA,EAAA;AAGnB,QAAM,4BACJ,CAAC,MAAkB,YAA4C,YAAY;AACnE,UAAA,WAAW,MAAM,OAAO;AAAA,EAAA;AAGlC,QAAM,qBAAqB,MAAM;AAC/B,mBAAe,CAAE,CAAA;AAAA,EAAA;AAGb,QAAA,eAAkD,OAAO,MAAM,YAAY;AACzE,UAAA,4BAA4B,KAAK,aAAa;AAAA,MAAK,CAAC,gBACxD,gCAAgC,SAAS,WAAW;AAAA,IAAA;AAEtD,UAAM,yBACJ,CAAC,sBACD,CAAC,iBAAiB,OAAO;AAAA,MAAM,CAAC,UAC9B,KAAK,OAAO,KAAK,CAAC,aAAa,SAAS,OAAO,MAAM,EAAE;AAAA,IAAA;AAG3D,QAAI,QAAQ,qBAAqB,MAAM,gBAAgB,SAAS,mBAAmB,EAAE,GAAG;AAMtF,wBAAkB,UAAU;AAAA,IAO9B,WACE,KAAK,UACL,qBACA,KAAK,OAAO,SAAS,SAAS,mBAAmB,EAAE,GACnD;AACA,wBAAkB,OAAO;AAAA,IAAA,WAChB,0BAA0B,2BAA2B;AAC9D,UAAI,wBAAwB;AAC1B,uBAAe,CAAC,UAAU,EAAE,GAAG,MAAM,wBAAwB,KAAO,EAAA;AAAA,MACtE;AAEA,UAAI,2BAA2B;AAC7B,uBAAe,CAAC,UAAU,EAAE,GAAG,MAAM,2BAA2B,KAAO,EAAA;AAAA,MACzE;AAAA,IAAA,OACK;AACC,YAAA,WAAW,MAAM,OAAO;AAAA,IAChC;AAAA,EAAA;AAeF,QAAM,UAAU,MAAM;AAChB,QAAA,CAAC,qBAAqB,CAAC,kBAAkB;AAC3C,UAAI,QAAQ,qBAAqB,MAAM,gBAAgB,SAAS,mBAAmB,EAAE,GAAG;AACtF,0BAAkB,UAAU;AAAA,MAC9B,WACE,mBACA,gBAAgB,UAChB,qBACA,gBAAgB,OAAO,SAAS,SAAS,mBAAmB,EAAE,GAC9D;AACA,0BAAkB,OAAO;AAAA,MAC3B;AAAA,IACF;AAAA,EAAA,GACC;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAEK,QAAA,gBAA4B,MAAM,QAAQ,MAAM;AAChD,QAAA,sBAAsB,CAAC,iBAAiB;AACnC,aAAA;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,CAAC;AAAA,QACT,cAAc,CAAC;AAAA,MAAA;AAAA,IACjB,OACK;AACE,aAAA;AAAA,QACL,MAAM,gBAAgB;AAAA,QACtB,QAAQ,mBAAmB,gBAAgB,MAAM;AAAA,QACjD,cAAc,gBAAgB;AAAA,MAAA;AAAA,IAElC;AAAA,EAAA,GACC,CAAC,iBAAiB,kBAAkB,CAAC;AAExC,MAAI,mBAAmB;AACd,WAAA,oBAAC,KAAK,SAAL,CAAa,CAAA;AAAA,EACvB;AAEA,MAAI,OAAO;AACF,WAAA,oBAAC,KAAK,OAAL,CAAW,CAAA;AAAA,EACrB;AAEA,SAEI,qBAAA,UAAA,EAAA,UAAA;AAAA,IAAC,oBAAAC,mBAAA,EAAyB;AAAA,IAE1B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,QAAQ,qBAAqB,SAAS;AAAA,QACtC;AAAA,QACA,kBAAkB;AAAA,QAClB,UAAU;AAAA,QAET,WAAC,EAAE,UAAU,cAAc,QAAQ,UAAA,MAEhC,qBAAA,UAAA,EAAA,UAAA;AAAA,UAAA;AAAA,YAACC;AAAAA,YAAA;AAAA,cACC,sCAAmB,YAAW,EAAA;AAAA,cAC9B,eACE,aAAa,YACX;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,+BAAY,OAAM,EAAA;AAAA,kBAClB,MAAK;AAAA,kBACL,UAAU,CAAC,YAAY,gBAAgB,OAAO,OAAO,WAAW;AAAA,kBAGhE,SAAS,CAAC,QAAQ,OAAO,KAAK,WAAW,EAAE,SAAS,CAAC,KAAK;AAAA,kBAEzD,UAAc,cAAA;AAAA,oBACb,IAAI;AAAA,oBACJ,gBAAgB;AAAA,kBAAA,CACjB;AAAA,gBAAA;AAAA,cAAA,IAED;AAAA,cAEN,UAAU;AAAA,gBACR;AAAA,kBACE,IAAI;AAAA,kBACJ,gBAAgB;AAAA,gBAClB;AAAA,gBACA,EAAE,OAAO,iBAAiB,QAAQ,UAAU,EAAE;AAAA,cAChD;AAAA,cACA,OACE,iBAAiB,QACjB,cAAc;AAAA,gBACZ,IAAI;AAAA,gBACJ,gBAAgB;AAAA,cAAA,CACjB;AAAA,YAAA;AAAA,UAEL;AAAA,UACA,oBAACC,MAAA,EACC,UAAA,qBAAC,MAAK,EAAA,YAAW,WAAU,WAAU,UAAS,KAAK,GACjD,UAAA;AAAA,YAAC,oBAAA,oBAAA,EAAmB,WAAW,aAAa,UAAW,CAAA;AAAA,YACvD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC;AAAA,gBACA,WAAW,aAAa;AAAA,gBACxB,YAAY;AAAA,cAAA;AAAA,YACd;AAAA,UAAA,EAAA,CACF,EACF,CAAA;AAAA,UACA;AAAA,YAAC,OAAO;AAAA,YAAP;AAAA,cACC,MAAM,OAAO,KAAK,WAAW,EAAE,SAAS;AAAA,cACxC,cAAc;AAAA,cAEd,UAAC,oBAAA,eAAA,EAAc,WAAW,0BAA0B,QAAQ,EAAE,UAAW,CAAA,GACvE,UAAC,qBAAA,MAAA,EAAK,WAAU,UAAS,KAAK,GAC3B,UAAA;AAAA,gBAAA,YAAY,0BACV,oBAAA,YAAA,EAAW,WAAU,UAAS,SAAQ,SACpC,UAAc,cAAA;AAAA,kBACb,IAAI;AAAA,kBACJ,gBACE;AAAA,gBACH,CAAA,GACH;AAAA,gBAGD,YAAY,6BACX,oBAAC,cAAW,WAAU,UAAS,SAAQ,SACpC,UAAA;AAAA,kBACC;AAAA,oBACE,IAAI;AAAA,oBACJ,gBACE;AAAA,kBACJ;AAAA,kBACA;AAAA,oBACE,OACE,gCAAgC;AAAA,sBAAO,CAAC,gBACtC,OAAO,aAAa,SAAS,WAAW;AAAA,sBACxC,UAAU;AAAA,kBAChB;AAAA,gBAAA,GAEJ;AAAA,oCAGD,YAAW,EAAA,WAAU,UAAS,SAAQ,SACpC,UAAc,cAAA;AAAA,kBACb,IAAI;AAAA,kBACJ,gBAAgB;AAAA,gBACjB,CAAA,GACH;AAAA,cAAA,EAAA,CACF,EACF,CAAA;AAAA,YAAA;AAAA,UACF;AAAA,QAAA,GACF;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA;AAAA,MAAC,YAAY;AAAA,MAAZ;AAAA,QACC,MAAM,mBAAmB;AAAA,QACzB,cAAc,MAAM,kBAAkB,IAAI;AAAA,QAE1C,UAAA;AAAA,UAAC,oBAAA,YAAY,OAAZ,EACE,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,UAEC,oBAAA,YAAY,MAAZ,EACE,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,IAEA;AAAA,MAAC,YAAY;AAAA,MAAZ;AAAA,QACC,MAAM,mBAAmB;AAAA,QACzB,cAAc,MAAM,kBAAkB,IAAI;AAAA,QAE1C,UAAA;AAAA,UAAC,oBAAA,YAAY,OAAZ,EACE,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,UAEC,oBAAA,YAAY,MAAZ,EACE,UAAc,cAAA;AAAA,YACb,IAAI;AAAA,YACJ,gBAAgB;AAAA,UACjB,CAAA,GACH;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EACF,EAAA,CAAA;AAEJ;AAEA,MAAM,qBAAqB,CAAC,SAA6B;AACvD,QAAM,OAAO,qBAAqB,QAAW,QAAW,KAAK,MAAM;AAEnE,SAAO,KAAK,IAAI,CAAC,OAAO,WAAW;AAAA,IACjC,GAAG;AAAA,IACH,cAAc,KAAK,KAAK;AAAA,EACxB,EAAA;AACJ;AAMA,MAAM,oBAAoB,MAAM;AACxB,QAAA,cAAc,iBAAiB,CAAC,UAAU;AACxC,UAAA;AAAA,MACJ,SAAS,CAAC;AAAA,MACV,SAAS,CAAC;AAAA,MACV,OAAO,CAAC;AAAA,IAAA,IACN,MAAM,UAAU,YAAY,WAAW,kBAAkB,KAAK;AAElE,WAAO,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI;AAAA,EAAA,CACtC;AAED,6BACG,KAAK,SAAL,EAAa,aACZ,UAAA,oBAAC,YAAS,EACZ,CAAA;AAEJ;"}
@@ -45,8 +45,9 @@ const CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME = "stagesPerWorkflow";
45
45
  const STAGE_COLOR_DEFAULT = designSystem.lightTheme.colors.primary600;
46
46
  const useTypedSelector = reactRedux.useSelector;
47
47
  const reviewWorkflowsApi = strapiAdmin.adminApi.enhanceEndpoints({
48
- addTagTypes: ["ReviewWorkflow", "ReviewWorkflowStages"]
48
+ addTagTypes: ["ReviewWorkflow", "ReviewWorkflowStages", "Document", "ContentTypeSettings"]
49
49
  });
50
+ const SINGLE_TYPES = "single-types";
50
51
  const contentManagerApi = reviewWorkflowsApi.injectEndpoints({
51
52
  endpoints: (builder) => ({
52
53
  getStages: builder.query({
@@ -74,7 +75,17 @@ const contentManagerApi = reviewWorkflowsApi.injectEndpoints({
74
75
  params
75
76
  }
76
77
  }),
77
- transformResponse: (res) => res.data
78
+ transformResponse: (res) => res.data,
79
+ invalidatesTags: (_result, _error, { slug, id, model }) => {
80
+ return [
81
+ {
82
+ type: "Document",
83
+ id: slug !== SINGLE_TYPES ? `${model}_${id}` : model
84
+ },
85
+ { type: "Document", id: `${model}_LIST` },
86
+ "ReviewWorkflowStages"
87
+ ];
88
+ }
78
89
  }),
79
90
  updateAssignee: builder.mutation({
80
91
  query: ({ model, slug, id, params, ...data }) => ({
@@ -85,7 +96,16 @@ const contentManagerApi = reviewWorkflowsApi.injectEndpoints({
85
96
  params
86
97
  }
87
98
  }),
88
- transformResponse: (res) => res.data
99
+ transformResponse: (res) => res.data,
100
+ invalidatesTags: (_result, _error, { slug, id, model }) => {
101
+ return [
102
+ {
103
+ type: "Document",
104
+ id: slug !== SINGLE_TYPES ? `${model}_${id}` : model
105
+ },
106
+ { type: "Document", id: `${model}_LIST` }
107
+ ];
108
+ }
89
109
  }),
90
110
  getContentTypes: builder.query({
91
111
  query: () => ({
@@ -156,7 +176,6 @@ const AssigneeSelect = () => {
156
176
  id,
157
177
  slug: model = ""
158
178
  } = reactRouterDom.useParams();
159
- const dispatch = reactRedux.useDispatch();
160
179
  const permissions = useTypedSelector((state) => state.admin_app.permissions);
161
180
  const { formatMessage } = reactIntl.useIntl();
162
181
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
@@ -177,13 +196,13 @@ const AssigneeSelect = () => {
177
196
  documentId: id
178
197
  },
179
198
  {
180
- skip: !id
199
+ skip: !id && collectionType !== "single-types"
181
200
  }
182
201
  );
183
202
  const users = data?.users || [];
184
203
  const currentAssignee = document ? document[ASSIGNEE_ATTRIBUTE_NAME] : null;
185
204
  const [updateAssignee, { error, isLoading: isMutating }] = useUpdateAssigneeMutation();
186
- if (!collectionType || !model || !id) {
205
+ if (!collectionType || !model || !document?.documentId) {
187
206
  return null;
188
207
  }
189
208
  const handleChange = async (assigneeId) => {
@@ -193,22 +212,13 @@ const AssigneeSelect = () => {
193
212
  const res = await updateAssignee({
194
213
  slug: collectionType,
195
214
  model,
196
- id,
215
+ id: document.documentId,
197
216
  params,
198
217
  data: {
199
218
  id: assigneeId ? parseInt(assigneeId, 10) : null
200
219
  }
201
220
  });
202
221
  if ("data" in res) {
203
- dispatch({
204
- type: "contentManagerApi/invalidateTags",
205
- payload: [
206
- {
207
- type: "Document",
208
- id: `${model}_${id}`
209
- }
210
- ]
211
- });
212
222
  toggleNotification({
213
223
  type: "success",
214
224
  message: formatMessage({
@@ -239,7 +249,7 @@ const AssigneeSelect = () => {
239
249
  id: "content-manager.reviewWorkflows.assignee.clear",
240
250
  defaultMessage: "Clear assignee"
241
251
  }),
242
- disabled: !isLoadingPermissions && !isLoading && users.length === 0 || !id,
252
+ disabled: !isLoadingPermissions && !isLoading && users.length === 0 || !document.documentId,
243
253
  value: currentAssignee ? currentAssignee.id.toString() : null,
244
254
  onChange: handleChange,
245
255
  onClear: () => handleChange(null),
@@ -376,31 +386,31 @@ const StageSelect = () => {
376
386
  slug: model = "",
377
387
  id = ""
378
388
  } = reactRouterDom.useParams();
379
- const dispatch = reactRedux.useDispatch();
380
389
  const { formatMessage } = reactIntl.useIntl();
381
390
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
382
391
  const { toggleNotification } = strapiAdmin.useNotification();
383
392
  const [{ query }] = strapiAdmin.useQueryParams();
384
393
  const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
385
- const { data, isLoading } = useGetStagesQuery(
394
+ const { document, isLoading: isLoadingDocument } = strapiAdmin$1.unstable_useDocument(
386
395
  {
387
- slug: collectionType,
396
+ collectionType,
388
397
  model,
389
- id,
390
- params
398
+ documentId: id
391
399
  },
392
400
  {
393
- skip: !id
401
+ skip: !id && collectionType !== "single-types"
394
402
  }
395
403
  );
396
- const { document } = strapiAdmin$1.unstable_useDocument(
404
+ const { data, isLoading: isLoadingStages } = useGetStagesQuery(
397
405
  {
398
- collectionType,
406
+ slug: collectionType,
399
407
  model,
400
- documentId: id
408
+ // @ts-expect-error – `id` is not correctly typed in the DS.
409
+ id: document?.documentId,
410
+ params
401
411
  },
402
412
  {
403
- skip: !id
413
+ skip: !document?.documentId
404
414
  }
405
415
  );
406
416
  const { meta, stages = [] } = data ?? {};
@@ -416,24 +426,15 @@ const StageSelect = () => {
416
426
  } else if (limits?.[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME] && parseInt(limits[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME], 10) < stages.length) {
417
427
  setShowLimitModal("stage");
418
428
  } else {
419
- if (id) {
429
+ if (document?.documentId) {
420
430
  const res = await updateStage({
421
431
  model,
422
- id,
432
+ id: document.documentId,
423
433
  slug: collectionType,
424
434
  params,
425
435
  data: { id: stageId }
426
436
  });
427
437
  if ("data" in res) {
428
- dispatch({
429
- type: "contentManagerApi/invalidateTags",
430
- payload: [
431
- {
432
- type: "Document",
433
- id: `${model}_${id}`
434
- }
435
- ]
436
- });
437
438
  toggleNotification({
438
439
  type: "success",
439
440
  message: formatMessage({
@@ -455,6 +456,7 @@ const StageSelect = () => {
455
456
  }
456
457
  };
457
458
  const { themeColorName } = getStageColorByHex(activeWorkflowStage?.color) ?? {};
459
+ const isLoading = isLoadingStages || isLoadingDocument;
458
460
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
459
461
  /* @__PURE__ */ jsxRuntime.jsxs(
460
462
  designSystem.Field.Root,
@@ -567,12 +569,16 @@ const StageSelect = () => {
567
569
  ] });
568
570
  };
569
571
  const Panel = () => {
570
- const { slug = "", id } = reactRouterDom.useParams();
572
+ const {
573
+ slug = "",
574
+ id,
575
+ collectionType
576
+ } = reactRouterDom.useParams();
571
577
  const {
572
578
  edit: { options }
573
579
  } = strapiAdmin$1.unstable_useDocumentLayout(slug);
574
580
  const { formatMessage } = reactIntl.useIntl();
575
- if (!window.strapi.isEE || !options?.reviewWorkflows || !id || id === "create") {
581
+ if (!window.strapi.isEE || !options?.reviewWorkflows || collectionType !== "single-types" && !id || id === "create") {
576
582
  return null;
577
583
  }
578
584
  return {
@@ -591,36 +597,25 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
591
597
  endpoints: (builder) => ({
592
598
  getWorkflows: builder.query({
593
599
  query: (args) => {
594
- const { id, ...params } = args ?? {};
595
600
  return {
596
- url: `/review-workflows/workflows${id ? `/${id}` : ""}`,
601
+ url: "/review-workflows/workflows",
597
602
  method: "GET",
598
603
  config: {
599
- params
604
+ params: args ?? {}
600
605
  }
601
606
  };
602
607
  },
603
608
  transformResponse: (res) => {
604
- let workflows = [];
605
- if (Array.isArray(res.data)) {
606
- workflows = res.data;
607
- } else {
608
- workflows = [res.data];
609
- }
610
609
  return {
611
- workflows,
610
+ workflows: res.data,
612
611
  meta: "meta" in res ? res.meta : void 0
613
612
  };
614
613
  },
615
- providesTags: (res, _err, arg) => {
616
- if (typeof arg === "object" && "id" in arg && arg.id !== "") {
617
- return [{ type: "ReviewWorkflow", id: arg.id }];
618
- } else {
619
- return [
620
- ...res?.workflows.map(({ id }) => ({ type: "ReviewWorkflow", id })) ?? [],
621
- { type: "ReviewWorkflow", id: "LIST" }
622
- ];
623
- }
614
+ providesTags: (res) => {
615
+ return [
616
+ ...res?.workflows.map(({ id }) => ({ type: "ReviewWorkflow", id })) ?? [],
617
+ { type: "ReviewWorkflow", id: "LIST" }
618
+ ];
624
619
  }
625
620
  }),
626
621
  createWorkflow: builder.mutation({
@@ -630,7 +625,18 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
630
625
  data
631
626
  }),
632
627
  transformResponse: (res) => res.data,
633
- invalidatesTags: [{ type: "ReviewWorkflow", id: "LIST" }, "ReviewWorkflowStages"]
628
+ invalidatesTags(res) {
629
+ return [
630
+ { type: "ReviewWorkflow", id: "LIST" },
631
+ "ReviewWorkflowStages",
632
+ { type: "Document", id: `ALL_LIST` },
633
+ { type: "ContentTypeSettings", id: "LIST" },
634
+ ...res?.contentTypes.map((uid) => ({
635
+ type: "Document",
636
+ id: `${uid}_ALL_ITEMS`
637
+ })) ?? []
638
+ ];
639
+ }
634
640
  }),
635
641
  updateWorkflow: builder.mutation({
636
642
  query: ({ id, ...data }) => ({
@@ -641,7 +647,13 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
641
647
  transformResponse: (res) => res.data,
642
648
  invalidatesTags: (res, _err, arg) => [
643
649
  { type: "ReviewWorkflow", id: arg.id },
644
- "ReviewWorkflowStages"
650
+ "ReviewWorkflowStages",
651
+ { type: "Document", id: "ALL_LIST" },
652
+ { type: "ContentTypeSettings", id: "LIST" },
653
+ ...res?.contentTypes.map((uid) => ({
654
+ type: "Document",
655
+ id: `${uid}_ALL_ITEMS`
656
+ })) ?? []
645
657
  ]
646
658
  }),
647
659
  deleteWorkflow: builder.mutation({
@@ -652,7 +664,9 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
652
664
  transformResponse: (res) => res.data,
653
665
  invalidatesTags: (res, _err, arg) => [
654
666
  { type: "ReviewWorkflow", id: arg.id },
655
- "ReviewWorkflowStages"
667
+ "ReviewWorkflowStages",
668
+ { type: "Document", id: `ALL_LIST` },
669
+ { type: "ContentTypeSettings", id: "LIST" }
656
670
  ]
657
671
  })
658
672
  }),
@@ -737,9 +751,6 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
737
751
  };
738
752
  };
739
753
  const prefixPluginTranslations = (trad, pluginId) => {
740
- if (!pluginId) {
741
- throw new TypeError("pluginId can't be empty");
742
- }
743
754
  return Object.keys(trad).reduce((acc, current) => {
744
755
  acc[`${pluginId}.${current}`] = trad[current];
745
756
  return acc;
@@ -762,7 +773,7 @@ const admin = {
762
773
  },
763
774
  permissions: [],
764
775
  async Component() {
765
- const { Router } = await Promise.resolve().then(() => require("./router-C19H1Rju.js"));
776
+ const { Router } = await Promise.resolve().then(() => require("./router-BFr5lHsE.js"));
766
777
  return { default: Router };
767
778
  }
768
779
  });
@@ -816,4 +827,4 @@ exports.useGetContentTypesQuery = useGetContentTypesQuery;
816
827
  exports.useGetWorkflowsQuery = useGetWorkflowsQuery;
817
828
  exports.useTypedSelector = useTypedSelector;
818
829
  exports.useUpdateWorkflowMutation = useUpdateWorkflowMutation;
819
- //# sourceMappingURL=index-D-KMrml_.js.map
830
+ //# sourceMappingURL=index-C5NgBQMb.js.map