@strapi/review-workflows 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6 → 0.0.0-experimental.f49f46a1c17445a39e8af3f63124bcccf73842e6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{Layout-Cwbb9usb.js → Layout-B4fpKB9J.js} +8 -9
- package/dist/_chunks/Layout-B4fpKB9J.js.map +1 -0
- package/dist/_chunks/{Layout-BpMLb-Oo.mjs → Layout-Dko22Aly.mjs} +8 -9
- package/dist/_chunks/Layout-Dko22Aly.mjs.map +1 -0
- package/dist/_chunks/{en-xcewH2pC.js → en-CYgjfSep.js} +5 -2
- package/dist/_chunks/en-CYgjfSep.js.map +1 -0
- package/dist/_chunks/{en-D9ZrQAV6.mjs → en-D9dxziEb.mjs} +5 -2
- package/dist/_chunks/en-D9dxziEb.mjs.map +1 -0
- package/dist/_chunks/{_id-p9NnvlMP.js → id-BKq7JAqZ.js} +82 -49
- package/dist/_chunks/id-BKq7JAqZ.js.map +1 -0
- package/dist/_chunks/{_id-KpezMzxO.mjs → id-DINFSsrh.mjs} +82 -49
- package/dist/_chunks/id-DINFSsrh.mjs.map +1 -0
- package/dist/_chunks/{index-DqT_oXGP.js → index-BpIILEs0.js} +9 -29
- package/dist/_chunks/index-BpIILEs0.js.map +1 -0
- package/dist/_chunks/{index-BTr8zF-9.js → index-BpL7C1EG.js} +54 -71
- package/dist/_chunks/index-BpL7C1EG.js.map +1 -0
- package/dist/_chunks/{index-DtJI5ZoC.mjs → index-DAcEdoqJ.mjs} +55 -72
- package/dist/_chunks/index-DAcEdoqJ.mjs.map +1 -0
- package/dist/_chunks/{index-BxkGN0Yj.mjs → index-ZcZKwmTD.mjs} +11 -31
- package/dist/_chunks/index-ZcZKwmTD.mjs.map +1 -0
- package/dist/_chunks/{router-B8G2sh6V.mjs → router-BPH_u176.mjs} +3 -3
- package/dist/_chunks/router-BPH_u176.mjs.map +1 -0
- package/dist/_chunks/{router-Bqj-105s.js → router-DeEgX8Ao.js} +3 -3
- package/dist/_chunks/router-DeEgX8Ao.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/services/settings.d.ts +1737 -7
- package/dist/server/index.js +180 -108
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +180 -108
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/constants/workflows.d.ts +1 -0
- package/dist/server/src/constants/workflows.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +6 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/workflow/index.d.ts +6 -0
- package/dist/server/src/content-types/workflow/index.d.ts.map +1 -1
- package/dist/server/src/controllers/assignees.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +0 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/stages.d.ts.map +1 -1
- package/dist/server/src/controllers/workflows.d.ts +0 -7
- package/dist/server/src/controllers/workflows.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +28 -7
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/review-workflows.d.ts.map +1 -1
- package/dist/server/src/services/assignees.d.ts +8 -4
- package/dist/server/src/services/assignees.d.ts.map +1 -1
- package/dist/server/src/services/document-service-middleware.d.ts +1 -0
- package/dist/server/src/services/document-service-middleware.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +16 -6
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics/index.d.ts +4 -4
- package/dist/server/src/services/metrics/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics/weekly-metrics.d.ts.map +1 -1
- package/dist/server/src/services/stages.d.ts +7 -7
- package/dist/server/src/services/stages.d.ts.map +1 -1
- package/dist/server/src/services/workflows.d.ts.map +1 -1
- package/dist/server/src/validation/review-workflows.d.ts +4 -0
- package/dist/server/src/validation/review-workflows.d.ts.map +1 -1
- package/dist/shared/contracts/review-workflows.d.ts +9 -17
- package/dist/shared/contracts/review-workflows.d.ts.map +1 -1
- package/package.json +12 -12
- package/dist/_chunks/Layout-BpMLb-Oo.mjs.map +0 -1
- package/dist/_chunks/Layout-Cwbb9usb.js.map +0 -1
- package/dist/_chunks/_id-KpezMzxO.mjs.map +0 -1
- package/dist/_chunks/_id-p9NnvlMP.js.map +0 -1
- package/dist/_chunks/en-D9ZrQAV6.mjs.map +0 -1
- package/dist/_chunks/en-xcewH2pC.js.map +0 -1
- package/dist/_chunks/index-BTr8zF-9.js.map +0 -1
- package/dist/_chunks/index-BxkGN0Yj.mjs.map +0 -1
- package/dist/_chunks/index-DqT_oXGP.js.map +0 -1
- package/dist/_chunks/index-DtJI5ZoC.mjs.map +0 -1
- package/dist/_chunks/router-B8G2sh6V.mjs.map +0 -1
- package/dist/_chunks/router-Bqj-105s.js.map +0 -1
- package/strapi-server.js +0 -3
- /package/dist/admin/src/routes/settings/{:id.d.ts → id.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-DINFSsrh.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={!stage.id}\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 SingleSelect,\n SingleSelectOption,\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\nimport type { WorkflowStage } from './Stages';\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.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <StageSelector 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\n/* -------------------------------------------------------------------------------------------------\n * StageSelector\n * -----------------------------------------------------------------------------------------------*/\ninterface StageSelectorProps {\n disabled?: boolean;\n}\n\nconst StageSelector = ({ disabled }: StageSelectorProps) => {\n const { value: stages = [] } = useField<WorkflowStage[]>('stages');\n const { formatMessage } = useIntl();\n\n const { error, value, onChange } = useField('stageRequiredToPublish');\n\n // stages with empty names are not valid, so we avoid them from being used to avoid errors\n const validStages = stages.filter((stage) => stage.name);\n\n return (\n <Field.Root\n error={error}\n name=\"stageRequiredToPublish\"\n hint={formatMessage({\n id: 'settings.review-workflows.workflow.stageRequiredToPublish.hint',\n defaultMessage:\n 'Prevents entries from being published if they are not at the required stage.',\n })}\n >\n <Field.Label>\n {formatMessage({\n id: 'settings.review-workflows.workflow.stageRequiredToPublish.label',\n defaultMessage: 'Required stage for publishing',\n })}\n </Field.Label>\n <SingleSelect\n disabled={disabled}\n onChange={(value) => {\n onChange('stageRequiredToPublish', value);\n }}\n value={value}\n >\n <SingleSelectOption value={''}>\n {formatMessage({\n id: 'settings.review-workflows.workflow.stageRequiredToPublish.any',\n defaultMessage: 'Any stage',\n })}\n </SingleSelectOption>\n {validStages.map((stage, i) => (\n <SingleSelectOption\n key={`requiredToPublishStage-${stage.id || stage.__temp_key__}`}\n value={stage.id?.toString() || stage.__temp_key__}\n >\n {stage.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n <Field.Hint />\n </Field.Root>\n );\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 stageRequiredToPublish: yup.string().nullable(),\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 stageRequiredToPublish: string | null;\n }\n\n const submitForm = async (data: FormValues, helpers: Pick<FormHelpers, 'setErrors'>) => {\n try {\n const { stageRequiredToPublish, ...rest } = data;\n const stageRequiredToPublishName =\n stageRequiredToPublish === ''\n ? null\n : rest.stages.find(\n (stage) =>\n stage.id === Number(stageRequiredToPublish) ||\n stage.__temp_key__ === stageRequiredToPublish\n )?.name;\n\n if (!isCreatingWorkflow) {\n const res = await update(id, {\n ...rest,\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: rest.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 stageRequiredToPublishName,\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({\n ...rest,\n stageRequiredToPublishName,\n });\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 stageRequiredToPublish: '',\n };\n } else {\n return {\n name: currentWorkflow.name,\n stages: addTmpKeysToStages(currentWorkflow.stages),\n contentTypes: currentWorkflow.contentTypes,\n stageRequiredToPublish: currentWorkflow.stageRequiredToPublish?.id.toString() ?? '',\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 fallback=\"..\" />}\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":"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"}
|
|
@@ -8,9 +8,8 @@ const designSystem = require("@strapi/design-system");
|
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const reactIntl = require("react-intl");
|
|
10
10
|
const reactRouterDom = require("react-router-dom");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const Layout = require("./Layout-Cwbb9usb.js");
|
|
11
|
+
const index = require("./index-BpL7C1EG.js");
|
|
12
|
+
const Layout = require("./Layout-B4fpKB9J.js");
|
|
14
13
|
function _interopNamespace(e) {
|
|
15
14
|
if (e && e.__esModule)
|
|
16
15
|
return e;
|
|
@@ -164,16 +163,18 @@ const ReviewWorkflowsListView = () => {
|
|
|
164
163
|
}).join(", ") }) }),
|
|
165
164
|
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", justifyContent: "end", children: [
|
|
166
165
|
canRead || canUpdate ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
167
|
-
|
|
166
|
+
designSystem.IconButton,
|
|
168
167
|
{
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
tag: reactRouterDom.Link,
|
|
169
|
+
to: workflow.id.toString(),
|
|
170
|
+
label: formatMessage(
|
|
171
171
|
{
|
|
172
172
|
id: "Settings.review-workflows.list.page.list.column.actions.edit.label",
|
|
173
173
|
defaultMessage: "Edit {name}"
|
|
174
174
|
},
|
|
175
175
|
{ name: workflow.name }
|
|
176
176
|
),
|
|
177
|
+
variant: "ghost",
|
|
177
178
|
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
|
|
178
179
|
}
|
|
179
180
|
) : null,
|
|
@@ -188,7 +189,7 @@ const ReviewWorkflowsListView = () => {
|
|
|
188
189
|
},
|
|
189
190
|
{ name: "Default workflow" }
|
|
190
191
|
),
|
|
191
|
-
|
|
192
|
+
variant: "ghost",
|
|
192
193
|
onClick: (e) => {
|
|
193
194
|
e.stopPropagation();
|
|
194
195
|
handleDeleteWorkflow(String(workflow.id));
|
|
@@ -221,27 +222,6 @@ const ReviewWorkflowsListView = () => {
|
|
|
221
222
|
] })
|
|
222
223
|
] });
|
|
223
224
|
};
|
|
224
|
-
const ActionLink = styledComponents.styled(designSystem.Link)`
|
|
225
|
-
align-items: center;
|
|
226
|
-
display: flex;
|
|
227
|
-
justify-content: center;
|
|
228
|
-
padding: ${({ theme }) => `${theme.spaces[2]}}`};
|
|
229
|
-
& > span {
|
|
230
|
-
line-height: 1rem;
|
|
231
|
-
font-size: 1rem;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
& svg > path {
|
|
235
|
-
fill: ${({ theme }) => theme.colors.neutral500};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
&:hover,
|
|
239
|
-
&:focus {
|
|
240
|
-
svg > path {
|
|
241
|
-
fill: ${({ theme }) => theme.colors.neutral800};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
`;
|
|
245
225
|
const ProtectedListPage = () => {
|
|
246
226
|
const permissions = index.useTypedSelector(
|
|
247
227
|
(state) => state.admin_app.permissions.settings?.["review-workflows"]?.main
|
|
@@ -250,4 +230,4 @@ const ProtectedListPage = () => {
|
|
|
250
230
|
};
|
|
251
231
|
exports.ProtectedListPage = ProtectedListPage;
|
|
252
232
|
exports.ReviewWorkflowsListView = ReviewWorkflowsListView;
|
|
253
|
-
//# sourceMappingURL=index-
|
|
233
|
+
//# sourceMappingURL=index-BpIILEs0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BpIILEs0.js","sources":["../../admin/src/routes/settings/index.tsx"],"sourcesContent":["/* eslint-disable check-file/no-index */\n/* eslint-disable check-file/filename-naming-convention */\nimport * as React from 'react';\n\nimport { Page, useTracking, ConfirmDialog, useRBAC, Table } from '@strapi/admin/strapi-admin';\nimport { useLicenseLimits } from '@strapi/admin/strapi-admin/ee';\nimport { Flex, IconButton, TFooter, Typography, LinkButton, Dialog } from '@strapi/design-system';\nimport { Pencil, Plus, Trash } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { NavLink, Link, useNavigate } from 'react-router-dom';\n\nimport { LimitsModal } from '../../components/LimitsModal';\nimport { CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME } from '../../constants';\nimport { useTypedSelector } from '../../modules/hooks';\nimport { ContentType, useGetContentTypesQuery } from '../../services/content-manager';\n\nimport * as Layout from './components/Layout';\nimport { useReviewWorkflows } from './hooks/useReviewWorkflows';\n\nexport const ReviewWorkflowsListView = () => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n const { trackUsage } = useTracking();\n const [workflowToDelete, setWorkflowToDelete] = React.useState<string | null>(null);\n const [showLimitModal, setShowLimitModal] = React.useState<boolean>(false);\n const { data, isLoading: isLoadingModels } = useGetContentTypesQuery();\n const { meta, workflows, isLoading, delete: deleteAction } = useReviewWorkflows();\n const { getFeature, isLoading: isLicenseLoading } = useLicenseLimits();\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions.settings?.['review-workflows']\n );\n const {\n allowedActions: { canCreate, canRead, canUpdate, canDelete },\n } = useRBAC(permissions);\n\n const limits = getFeature('review-workflows');\n const numberOfWorkflows = limits?.[CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME] as string;\n\n const handleDeleteWorkflow = (workflowId: string) => {\n setWorkflowToDelete(workflowId);\n };\n\n const toggleConfirmDeleteDialog = () => {\n setWorkflowToDelete(null);\n };\n\n const handleConfirmDeleteDialog = async () => {\n if (!workflowToDelete) return;\n\n await deleteAction(workflowToDelete);\n\n setWorkflowToDelete(null);\n };\n\n const handleCreateClick: React.MouseEventHandler<HTMLAnchorElement> &\n ((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void) = (event) => {\n event.preventDefault();\n /**\n * If the current license has a workflow limit:\n * check if the total count of workflows exceeds that limit. If so,\n * prevent the navigation and show the limits overlay.\n *\n * If the current license does not have a limit (e.g. offline license):\n * allow the user to navigate to the create-view. In case they exceed the\n * current hard-limit of 200 they will see an error thrown by the API.\n */\n\n if (numberOfWorkflows && meta && meta?.workflowCount >= parseInt(numberOfWorkflows, 10)) {\n event.preventDefault();\n setShowLimitModal(true);\n } else {\n navigate('create');\n trackUsage('willCreateWorkflow');\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 (!isLoading && !isLicenseLoading) {\n if (numberOfWorkflows && meta && meta?.workflowCount > parseInt(numberOfWorkflows, 10)) {\n setShowLimitModal(true);\n }\n }\n }, [isLicenseLoading, isLoading, meta, meta?.workflowCount, numberOfWorkflows]);\n\n const headers = [\n {\n label: formatMessage({\n id: 'Settings.review-workflows.list.page.list.column.name.title',\n defaultMessage: 'Name',\n }),\n name: 'name',\n },\n {\n label: formatMessage({\n id: 'Settings.review-workflows.list.page.list.column.stages.title',\n defaultMessage: 'Stages',\n }),\n name: 'stages',\n },\n {\n label: formatMessage({\n id: 'Settings.review-workflows.list.page.list.column.contentTypes.title',\n defaultMessage: 'Content Types',\n }),\n name: 'content-types',\n },\n ];\n\n if (isLoading || isLoadingModels) {\n return <Page.Loading />;\n }\n\n const contentTypes = Object.values(data ?? {}).reduce<ContentType[]>((acc, curr) => {\n acc.push(...curr);\n return acc;\n }, []);\n\n return (\n <>\n <Layout.Header\n primaryAction={\n canCreate ? (\n <LinkButton\n startIcon={<Plus />}\n size=\"S\"\n tag={NavLink}\n to=\"create\"\n onClick={handleCreateClick}\n >\n {formatMessage({\n id: 'Settings.review-workflows.list.page.create',\n defaultMessage: 'Create new workflow',\n })}\n </LinkButton>\n ) : null\n }\n subtitle={formatMessage({\n id: 'Settings.review-workflows.list.page.subtitle',\n defaultMessage: 'Manage your content review process',\n })}\n title={formatMessage({\n id: 'Settings.review-workflows.list.page.title',\n defaultMessage: 'Review Workflows',\n })}\n />\n\n <Layout.Root>\n <Table.Root\n isLoading={isLoading}\n rows={workflows}\n footer={\n canCreate ? (\n <TFooter icon={<Plus />} onClick={handleCreateClick}>\n {formatMessage({\n id: 'Settings.review-workflows.list.page.create',\n defaultMessage: 'Create new workflow',\n })}\n </TFooter>\n ) : null\n }\n headers={headers}\n >\n <Table.Content>\n <Table.Head>\n {headers.map((head) => (\n <Table.HeaderCell key={head.name} {...head} />\n ))}\n </Table.Head>\n\n <Table.Body>\n {workflows.map((workflow) => (\n <Table.Row\n onClick={() => {\n navigate(`${workflow.id}`);\n }}\n key={workflow.id}\n >\n <Table.Cell width=\"25rem\">\n <Typography textColor=\"neutral800\" fontWeight=\"bold\" ellipsis>\n {workflow.name}\n </Typography>\n </Table.Cell>\n <Table.Cell>\n <Typography textColor=\"neutral800\">{workflow.stages.length}</Typography>\n </Table.Cell>\n <Table.Cell>\n <Typography textColor=\"neutral800\">\n {workflow.contentTypes\n .map((uid: string) => {\n const contentType = contentTypes.find(\n (contentType) => contentType.uid === uid\n );\n\n return contentType?.info.displayName ?? '';\n })\n .join(', ')}\n </Typography>\n </Table.Cell>\n <Table.Cell>\n <Flex alignItems=\"center\" justifyContent=\"end\">\n {canRead || canUpdate ? (\n <IconButton\n tag={Link}\n to={workflow.id.toString()}\n label={formatMessage(\n {\n id: 'Settings.review-workflows.list.page.list.column.actions.edit.label',\n defaultMessage: 'Edit {name}',\n },\n { name: workflow.name }\n )}\n variant=\"ghost\"\n >\n <Pencil />\n </IconButton>\n ) : null}\n {workflows.length > 1 && canDelete ? (\n <IconButton\n withTooltip={false}\n label={formatMessage(\n {\n id: 'Settings.review-workflows.list.page.list.column.actions.delete.label',\n defaultMessage: 'Delete {name}',\n },\n { name: 'Default workflow' }\n )}\n variant=\"ghost\"\n onClick={(e) => {\n e.stopPropagation();\n handleDeleteWorkflow(String(workflow.id));\n }}\n >\n <Trash />\n </IconButton>\n ) : null}\n </Flex>\n </Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table.Content>\n </Table.Root>\n\n <Dialog.Root open={!!workflowToDelete} onOpenChange={toggleConfirmDeleteDialog}>\n <ConfirmDialog onConfirm={handleConfirmDeleteDialog}>\n {formatMessage({\n id: 'Settings.review-workflows.list.page.delete.confirm.body',\n defaultMessage:\n 'If you remove this worfklow, all stage-related information will be removed for this content-type. Are you sure you want to remove it?',\n })}\n </ConfirmDialog>\n </Dialog.Root>\n\n <LimitsModal.Root open={showLimitModal} onOpenChange={() => setShowLimitModal(false)}>\n <LimitsModal.Title>\n {formatMessage({\n id: 'Settings.review-workflows.list.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: 'Settings.review-workflows.list.page.workflows.limit.body',\n defaultMessage: 'Delete a workflow or contact Sales to enable more workflows.',\n })}\n </LimitsModal.Body>\n </LimitsModal.Root>\n </Layout.Root>\n </>\n );\n};\n\nconst ProtectedListPage = () => {\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions.settings?.['review-workflows']?.main\n );\n\n return (\n <Page.Protect permissions={permissions}>\n <ReviewWorkflowsListView />\n </Page.Protect>\n );\n};\n\nexport { ProtectedListPage };\n"],"names":["useIntl","useNavigate","useTracking","React","useGetContentTypesQuery","useReviewWorkflows","useLicenseLimits","useTypedSelector","useRBAC","CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME","jsx","Page","jsxs","Fragment","Layout.Header","LinkButton","Plus","NavLink","Layout.Root","Table","TFooter","Typography","contentType","Flex","IconButton","Link","Pencil","Trash","Dialog","ConfirmDialog","LimitsModal"],"mappings":"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"}
|
|
@@ -82,7 +82,8 @@ const contentManagerApi = reviewWorkflowsApi.injectEndpoints({
|
|
|
82
82
|
type: "Document",
|
|
83
83
|
id: slug !== SINGLE_TYPES ? `${model}_${id}` : model
|
|
84
84
|
},
|
|
85
|
-
{ type: "Document", id: `${model}_LIST` }
|
|
85
|
+
{ type: "Document", id: `${model}_LIST` },
|
|
86
|
+
"ReviewWorkflowStages"
|
|
86
87
|
];
|
|
87
88
|
}
|
|
88
89
|
}),
|
|
@@ -175,7 +176,6 @@ const AssigneeSelect = () => {
|
|
|
175
176
|
id,
|
|
176
177
|
slug: model = ""
|
|
177
178
|
} = reactRouterDom.useParams();
|
|
178
|
-
const dispatch = reactRedux.useDispatch();
|
|
179
179
|
const permissions = useTypedSelector((state) => state.admin_app.permissions);
|
|
180
180
|
const { formatMessage } = reactIntl.useIntl();
|
|
181
181
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
|
@@ -196,13 +196,13 @@ const AssigneeSelect = () => {
|
|
|
196
196
|
documentId: id
|
|
197
197
|
},
|
|
198
198
|
{
|
|
199
|
-
skip: !id
|
|
199
|
+
skip: !id && collectionType !== "single-types"
|
|
200
200
|
}
|
|
201
201
|
);
|
|
202
202
|
const users = data?.users || [];
|
|
203
203
|
const currentAssignee = document ? document[ASSIGNEE_ATTRIBUTE_NAME] : null;
|
|
204
204
|
const [updateAssignee, { error, isLoading: isMutating }] = useUpdateAssigneeMutation();
|
|
205
|
-
if (!collectionType || !model || !
|
|
205
|
+
if (!collectionType || !model || !document?.documentId) {
|
|
206
206
|
return null;
|
|
207
207
|
}
|
|
208
208
|
const handleChange = async (assigneeId) => {
|
|
@@ -212,22 +212,13 @@ const AssigneeSelect = () => {
|
|
|
212
212
|
const res = await updateAssignee({
|
|
213
213
|
slug: collectionType,
|
|
214
214
|
model,
|
|
215
|
-
id,
|
|
215
|
+
id: document.documentId,
|
|
216
216
|
params,
|
|
217
217
|
data: {
|
|
218
218
|
id: assigneeId ? parseInt(assigneeId, 10) : null
|
|
219
219
|
}
|
|
220
220
|
});
|
|
221
221
|
if ("data" in res) {
|
|
222
|
-
dispatch({
|
|
223
|
-
type: "contentManagerApi/invalidateTags",
|
|
224
|
-
payload: [
|
|
225
|
-
{
|
|
226
|
-
type: "Document",
|
|
227
|
-
id: `${model}_${id}`
|
|
228
|
-
}
|
|
229
|
-
]
|
|
230
|
-
});
|
|
231
222
|
toggleNotification({
|
|
232
223
|
type: "success",
|
|
233
224
|
message: formatMessage({
|
|
@@ -258,7 +249,7 @@ const AssigneeSelect = () => {
|
|
|
258
249
|
id: "content-manager.reviewWorkflows.assignee.clear",
|
|
259
250
|
defaultMessage: "Clear assignee"
|
|
260
251
|
}),
|
|
261
|
-
disabled: !isLoadingPermissions && !isLoading && users.length === 0 || !
|
|
252
|
+
disabled: !isLoadingPermissions && !isLoading && users.length === 0 || !document.documentId,
|
|
262
253
|
value: currentAssignee ? currentAssignee.id.toString() : null,
|
|
263
254
|
onChange: handleChange,
|
|
264
255
|
onClear: () => handleChange(null),
|
|
@@ -395,31 +386,31 @@ const StageSelect = () => {
|
|
|
395
386
|
slug: model = "",
|
|
396
387
|
id = ""
|
|
397
388
|
} = reactRouterDom.useParams();
|
|
398
|
-
const dispatch = reactRedux.useDispatch();
|
|
399
389
|
const { formatMessage } = reactIntl.useIntl();
|
|
400
390
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
|
401
391
|
const { toggleNotification } = strapiAdmin.useNotification();
|
|
402
392
|
const [{ query }] = strapiAdmin.useQueryParams();
|
|
403
393
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
|
404
|
-
const {
|
|
394
|
+
const { document, isLoading: isLoadingDocument } = strapiAdmin$1.unstable_useDocument(
|
|
405
395
|
{
|
|
406
|
-
|
|
396
|
+
collectionType,
|
|
407
397
|
model,
|
|
408
|
-
id
|
|
409
|
-
params
|
|
398
|
+
documentId: id
|
|
410
399
|
},
|
|
411
400
|
{
|
|
412
|
-
skip: !id
|
|
401
|
+
skip: !id && collectionType !== "single-types"
|
|
413
402
|
}
|
|
414
403
|
);
|
|
415
|
-
const {
|
|
404
|
+
const { data, isLoading: isLoadingStages } = useGetStagesQuery(
|
|
416
405
|
{
|
|
417
|
-
collectionType,
|
|
406
|
+
slug: collectionType,
|
|
418
407
|
model,
|
|
419
|
-
|
|
408
|
+
// @ts-expect-error – `id` is not correctly typed in the DS.
|
|
409
|
+
id: document?.documentId,
|
|
410
|
+
params
|
|
420
411
|
},
|
|
421
412
|
{
|
|
422
|
-
skip: !
|
|
413
|
+
skip: !document?.documentId
|
|
423
414
|
}
|
|
424
415
|
);
|
|
425
416
|
const { meta, stages = [] } = data ?? {};
|
|
@@ -435,24 +426,15 @@ const StageSelect = () => {
|
|
|
435
426
|
} else if (limits?.[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME] && parseInt(limits[CHARGEBEE_STAGES_PER_WORKFLOW_ENTITLEMENT_NAME], 10) < stages.length) {
|
|
436
427
|
setShowLimitModal("stage");
|
|
437
428
|
} else {
|
|
438
|
-
if (
|
|
429
|
+
if (document?.documentId) {
|
|
439
430
|
const res = await updateStage({
|
|
440
431
|
model,
|
|
441
|
-
id,
|
|
432
|
+
id: document.documentId,
|
|
442
433
|
slug: collectionType,
|
|
443
434
|
params,
|
|
444
435
|
data: { id: stageId }
|
|
445
436
|
});
|
|
446
437
|
if ("data" in res) {
|
|
447
|
-
dispatch({
|
|
448
|
-
type: "contentManagerApi/invalidateTags",
|
|
449
|
-
payload: [
|
|
450
|
-
{
|
|
451
|
-
type: "Document",
|
|
452
|
-
id: `${model}_${id}`
|
|
453
|
-
}
|
|
454
|
-
]
|
|
455
|
-
});
|
|
456
438
|
toggleNotification({
|
|
457
439
|
type: "success",
|
|
458
440
|
message: formatMessage({
|
|
@@ -474,6 +456,7 @@ const StageSelect = () => {
|
|
|
474
456
|
}
|
|
475
457
|
};
|
|
476
458
|
const { themeColorName } = getStageColorByHex(activeWorkflowStage?.color) ?? {};
|
|
459
|
+
const isLoading = isLoadingStages || isLoadingDocument;
|
|
477
460
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
478
461
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
479
462
|
designSystem.Field.Root,
|
|
@@ -586,12 +569,16 @@ const StageSelect = () => {
|
|
|
586
569
|
] });
|
|
587
570
|
};
|
|
588
571
|
const Panel = () => {
|
|
589
|
-
const {
|
|
572
|
+
const {
|
|
573
|
+
slug = "",
|
|
574
|
+
id,
|
|
575
|
+
collectionType
|
|
576
|
+
} = reactRouterDom.useParams();
|
|
590
577
|
const {
|
|
591
578
|
edit: { options }
|
|
592
579
|
} = strapiAdmin$1.unstable_useDocumentLayout(slug);
|
|
593
580
|
const { formatMessage } = reactIntl.useIntl();
|
|
594
|
-
if (!window.strapi.isEE || !options?.reviewWorkflows || !id || id === "create") {
|
|
581
|
+
if (!window.strapi.isEE || !options?.reviewWorkflows || collectionType !== "single-types" && !id || id === "create") {
|
|
595
582
|
return null;
|
|
596
583
|
}
|
|
597
584
|
return {
|
|
@@ -610,36 +597,25 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
|
|
|
610
597
|
endpoints: (builder) => ({
|
|
611
598
|
getWorkflows: builder.query({
|
|
612
599
|
query: (args) => {
|
|
613
|
-
const { id, ...params } = args ?? {};
|
|
614
600
|
return {
|
|
615
|
-
url:
|
|
601
|
+
url: "/review-workflows/workflows",
|
|
616
602
|
method: "GET",
|
|
617
603
|
config: {
|
|
618
|
-
params
|
|
604
|
+
params: args ?? {}
|
|
619
605
|
}
|
|
620
606
|
};
|
|
621
607
|
},
|
|
622
608
|
transformResponse: (res) => {
|
|
623
|
-
let workflows = [];
|
|
624
|
-
if (Array.isArray(res.data)) {
|
|
625
|
-
workflows = res.data;
|
|
626
|
-
} else {
|
|
627
|
-
workflows = [res.data];
|
|
628
|
-
}
|
|
629
609
|
return {
|
|
630
|
-
workflows,
|
|
610
|
+
workflows: res.data,
|
|
631
611
|
meta: "meta" in res ? res.meta : void 0
|
|
632
612
|
};
|
|
633
613
|
},
|
|
634
|
-
providesTags: (res
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
...res?.workflows.map(({ id }) => ({ type: "ReviewWorkflow", id })) ?? [],
|
|
640
|
-
{ type: "ReviewWorkflow", id: "LIST" }
|
|
641
|
-
];
|
|
642
|
-
}
|
|
614
|
+
providesTags: (res) => {
|
|
615
|
+
return [
|
|
616
|
+
...res?.workflows.map(({ id }) => ({ type: "ReviewWorkflow", id })) ?? [],
|
|
617
|
+
{ type: "ReviewWorkflow", id: "LIST" }
|
|
618
|
+
];
|
|
643
619
|
}
|
|
644
620
|
}),
|
|
645
621
|
createWorkflow: builder.mutation({
|
|
@@ -649,12 +625,18 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
|
|
|
649
625
|
data
|
|
650
626
|
}),
|
|
651
627
|
transformResponse: (res) => res.data,
|
|
652
|
-
invalidatesTags
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
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
|
+
}
|
|
658
640
|
}),
|
|
659
641
|
updateWorkflow: builder.mutation({
|
|
660
642
|
query: ({ id, ...data }) => ({
|
|
@@ -666,8 +648,12 @@ const settingsApi = reviewWorkflowsApi.injectEndpoints({
|
|
|
666
648
|
invalidatesTags: (res, _err, arg) => [
|
|
667
649
|
{ type: "ReviewWorkflow", id: arg.id },
|
|
668
650
|
"ReviewWorkflowStages",
|
|
669
|
-
{ type: "Document", id:
|
|
670
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
|
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
|
+
})) ?? []
|
|
671
657
|
]
|
|
672
658
|
}),
|
|
673
659
|
deleteWorkflow: builder.mutation({
|
|
@@ -765,9 +751,6 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
|
|
765
751
|
};
|
|
766
752
|
};
|
|
767
753
|
const prefixPluginTranslations = (trad, pluginId) => {
|
|
768
|
-
if (!pluginId) {
|
|
769
|
-
throw new TypeError("pluginId can't be empty");
|
|
770
|
-
}
|
|
771
754
|
return Object.keys(trad).reduce((acc, current) => {
|
|
772
755
|
acc[`${pluginId}.${current}`] = trad[current];
|
|
773
756
|
return acc;
|
|
@@ -790,7 +773,7 @@ const admin = {
|
|
|
790
773
|
},
|
|
791
774
|
permissions: [],
|
|
792
775
|
async Component() {
|
|
793
|
-
const { Router } = await Promise.resolve().then(() => require("./router-
|
|
776
|
+
const { Router } = await Promise.resolve().then(() => require("./router-DeEgX8Ao.js"));
|
|
794
777
|
return { default: Router };
|
|
795
778
|
}
|
|
796
779
|
});
|
|
@@ -814,7 +797,7 @@ const admin = {
|
|
|
814
797
|
async registerTrads({ locales }) {
|
|
815
798
|
const importedTrads = await Promise.all(
|
|
816
799
|
locales.map((locale) => {
|
|
817
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-
|
|
800
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-CYgjfSep.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
|
|
818
801
|
return {
|
|
819
802
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
|
820
803
|
locale
|
|
@@ -844,4 +827,4 @@ exports.useGetContentTypesQuery = useGetContentTypesQuery;
|
|
|
844
827
|
exports.useGetWorkflowsQuery = useGetWorkflowsQuery;
|
|
845
828
|
exports.useTypedSelector = useTypedSelector;
|
|
846
829
|
exports.useUpdateWorkflowMutation = useUpdateWorkflowMutation;
|
|
847
|
-
//# sourceMappingURL=index-
|
|
830
|
+
//# sourceMappingURL=index-BpL7C1EG.js.map
|