@strapi/review-workflows 5.60.0 → 5.61.0

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 (61) hide show
  1. package/dist/admin/components/Widgets.js +5 -1
  2. package/dist/admin/components/Widgets.js.map +1 -1
  3. package/dist/admin/components/Widgets.mjs +5 -1
  4. package/dist/admin/components/Widgets.mjs.map +1 -1
  5. package/dist/admin/routes/content-manager/model/components/StageFilter.js +1 -1
  6. package/dist/admin/routes/content-manager/model/components/StageFilter.js.map +1 -1
  7. package/dist/admin/routes/content-manager/model/components/StageFilter.mjs +1 -1
  8. package/dist/admin/routes/content-manager/model/components/StageFilter.mjs.map +1 -1
  9. package/dist/admin/routes/content-manager/model/components/TableColumns.js.map +1 -1
  10. package/dist/admin/routes/content-manager/model/components/TableColumns.mjs.map +1 -1
  11. package/dist/admin/routes/content-manager/model/constants.js +2 -2
  12. package/dist/admin/routes/content-manager/model/constants.js.map +1 -1
  13. package/dist/admin/routes/content-manager/model/constants.mjs +2 -2
  14. package/dist/admin/routes/content-manager/model/constants.mjs.map +1 -1
  15. package/dist/admin/routes/settings/index.js +1 -1
  16. package/dist/admin/routes/settings/index.js.map +1 -1
  17. package/dist/admin/routes/settings/index.mjs +1 -1
  18. package/dist/admin/routes/settings/index.mjs.map +1 -1
  19. package/dist/admin/src/routes/content-manager/model/components/TableColumns.d.ts +1 -6
  20. package/dist/server/constants/workflows.js +2 -1
  21. package/dist/server/constants/workflows.js.map +1 -1
  22. package/dist/server/constants/workflows.mjs +2 -1
  23. package/dist/server/constants/workflows.mjs.map +1 -1
  24. package/dist/server/controllers/stages.js +3 -0
  25. package/dist/server/controllers/stages.js.map +1 -1
  26. package/dist/server/controllers/stages.mjs +3 -0
  27. package/dist/server/controllers/stages.mjs.map +1 -1
  28. package/dist/server/services/document-service-middleware.js +28 -1
  29. package/dist/server/services/document-service-middleware.js.map +1 -1
  30. package/dist/server/services/document-service-middleware.mjs +28 -1
  31. package/dist/server/services/document-service-middleware.mjs.map +1 -1
  32. package/dist/server/services/stages.js +32 -14
  33. package/dist/server/services/stages.js.map +1 -1
  34. package/dist/server/services/stages.mjs +32 -14
  35. package/dist/server/services/stages.mjs.map +1 -1
  36. package/dist/server/services/workflow-content-types.js +7 -1
  37. package/dist/server/services/workflow-content-types.js.map +1 -1
  38. package/dist/server/services/workflow-content-types.mjs +7 -1
  39. package/dist/server/services/workflow-content-types.mjs.map +1 -1
  40. package/dist/server/services/workflows.js +44 -1
  41. package/dist/server/services/workflows.js.map +1 -1
  42. package/dist/server/services/workflows.mjs +45 -2
  43. package/dist/server/services/workflows.mjs.map +1 -1
  44. package/dist/server/src/constants/workflows.d.ts +1 -0
  45. package/dist/server/src/constants/workflows.d.ts.map +1 -1
  46. package/dist/server/src/controllers/index.d.ts +1 -1
  47. package/dist/server/src/controllers/stages.d.ts +1 -1
  48. package/dist/server/src/controllers/stages.d.ts.map +1 -1
  49. package/dist/server/src/index.d.ts +4 -4
  50. package/dist/server/src/index.d.ts.map +1 -1
  51. package/dist/server/src/services/document-service-middleware.d.ts.map +1 -1
  52. package/dist/server/src/services/index.d.ts +3 -3
  53. package/dist/server/src/services/index.d.ts.map +1 -1
  54. package/dist/server/src/services/stages.d.ts +3 -4
  55. package/dist/server/src/services/stages.d.ts.map +1 -1
  56. package/dist/server/src/services/workflow-content-types.d.ts.map +1 -1
  57. package/dist/server/src/services/workflows.d.ts +2 -1
  58. package/dist/server/src/services/workflows.d.ts.map +1 -1
  59. package/dist/shared/contracts/homepage.d.ts +5 -1
  60. package/dist/shared/contracts/homepage.d.ts.map +1 -1
  61. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","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 fullWidth\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 cursor=\"pointer\" 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 onClick={(e) => e.stopPropagation()}\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: 'review-workflows.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.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":["ReviewWorkflowsListView","formatMessage","useIntl","navigate","useNavigate","trackUsage","useTracking","workflowToDelete","setWorkflowToDelete","React","useState","showLimitModal","setShowLimitModal","data","isLoading","isLoadingModels","useGetContentTypesQuery","meta","workflows","delete","deleteAction","useReviewWorkflows","getFeature","isLicenseLoading","useLicenseLimits","permissions","useTypedSelector","state","admin_app","settings","allowedActions","canCreate","canRead","canUpdate","canDelete","useRBAC","limits","numberOfWorkflows","CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME","handleDeleteWorkflow","workflowId","toggleConfirmDeleteDialog","handleConfirmDeleteDialog","handleCreateClick","event","preventDefault","workflowCount","parseInt","useEffect","headers","label","id","defaultMessage","name","_jsx","Page","Loading","contentTypes","Object","values","reduce","acc","curr","push","_jsxs","_Fragment","Layout","primaryAction","LinkButton","startIcon","Plus","size","tag","NavLink","to","onClick","fullWidth","subtitle","title","Table","Root","rows","footer","TFooter","cursor","icon","Content","Head","map","head","HeaderCell","Body","workflow","Row","Cell","width","Typography","textColor","fontWeight","ellipsis","stages","length","uid","contentType","find","info","displayName","join","Flex","alignItems","justifyContent","IconButton","Link","e","stopPropagation","toString","variant","Pencil","withTooltip","String","Trash","Dialog","open","onOpenChange","ConfirmDialog","onConfirm","LimitsModal","Title","ProtectedListPage","main","Protect"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","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 fullWidth\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 cursor=\"pointer\" 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 onClick={(e) => e.stopPropagation()}\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 workflow, 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: 'review-workflows.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.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":["ReviewWorkflowsListView","formatMessage","useIntl","navigate","useNavigate","trackUsage","useTracking","workflowToDelete","setWorkflowToDelete","React","useState","showLimitModal","setShowLimitModal","data","isLoading","isLoadingModels","useGetContentTypesQuery","meta","workflows","delete","deleteAction","useReviewWorkflows","getFeature","isLicenseLoading","useLicenseLimits","permissions","useTypedSelector","state","admin_app","settings","allowedActions","canCreate","canRead","canUpdate","canDelete","useRBAC","limits","numberOfWorkflows","CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME","handleDeleteWorkflow","workflowId","toggleConfirmDeleteDialog","handleConfirmDeleteDialog","handleCreateClick","event","preventDefault","workflowCount","parseInt","useEffect","headers","label","id","defaultMessage","name","_jsx","Page","Loading","contentTypes","Object","values","reduce","acc","curr","push","_jsxs","_Fragment","Layout","primaryAction","LinkButton","startIcon","Plus","size","tag","NavLink","to","onClick","fullWidth","subtitle","title","Table","Root","rows","footer","TFooter","cursor","icon","Content","Head","map","head","HeaderCell","Body","workflow","Row","Cell","width","Typography","textColor","fontWeight","ellipsis","stages","length","uid","contentType","find","info","displayName","join","Flex","alignItems","justifyContent","IconButton","Link","e","stopPropagation","toString","variant","Pencil","withTooltip","String","Trash","Dialog","open","onOpenChange","ConfirmDialog","onConfirm","LimitsModal","Title","ProtectedListPage","main","Protect"],"mappings":"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"}
@@ -1,17 +1,12 @@
1
1
  import { SanitizedAdminUser } from '@strapi/admin/strapi-admin';
2
- import { Data } from '@strapi/types';
3
2
  interface StageColumnProps {
4
- documentId?: string;
5
- id?: Data.ID;
6
3
  strapi_stage?: {
7
4
  color?: string;
8
5
  name: string;
9
- };
6
+ } | null;
10
7
  }
11
8
  declare const StageColumn: (props: StageColumnProps) => import("react/jsx-runtime").JSX.Element;
12
9
  interface AssigneeColumnProps {
13
- documentId?: string;
14
- id?: Data.ID;
15
10
  strapi_assignee?: Pick<SanitizedAdminUser, 'firstname' | 'lastname' | 'username' | 'email'> | null;
16
11
  }
17
12
  declare const AssigneeColumn: (props: AssigneeColumnProps) => import("react/jsx-runtime").JSX.Element;
@@ -16,7 +16,8 @@ const ERRORS = {
16
16
  WORKFLOW_WITHOUT_STAGES: 'A workflow must have at least one stage.',
17
17
  WORKFLOWS_LIMIT: 'You’ve reached the limit of workflows in your plan. Delete a workflow or contact Sales to enable more workflows.',
18
18
  STAGES_LIMIT: 'You’ve reached the limit of stages for this workflow in your plan. Try deleting some stages or contact Sales to enable more stages.',
19
- DUPLICATED_STAGE_NAME: 'Stage names must be unique.'
19
+ DUPLICATED_STAGE_NAME: 'Stage names must be unique.',
20
+ DUPLICATED_WORKFLOW_NAME: 'A workflow with this name already exists.'
20
21
  };
21
22
  const WORKFLOW_POPULATE = {
22
23
  stages: {
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","sources":["../../../server/src/constants/workflows.ts"],"sourcesContent":["export const WORKFLOW_MODEL_UID = 'plugin::review-workflows.workflow';\nexport const STAGE_MODEL_UID = 'plugin::review-workflows.workflow-stage';\n/**\n * TODO: For V4 compatibility, the old UID was kept, when review workflows was in the admin package\n *\n * NOTE!: if you change this string you need to change it here too: strapi/packages/core/review-workflows/admin/src/routes/settings/components/Stages.tsx\n */\nexport const STAGE_TRANSITION_UID = 'admin::review-workflows.stage.transition';\n\nexport const STAGE_DEFAULT_COLOR = '#4945FF';\nexport const ENTITY_STAGE_ATTRIBUTE = 'strapi_stage';\nexport const ENTITY_ASSIGNEE_ATTRIBUTE = 'strapi_assignee';\n\nexport const MAX_WORKFLOWS = 200;\nexport const MAX_STAGES_PER_WORKFLOW = 200;\n\nexport const ERRORS = {\n WORKFLOW_WITHOUT_STAGES: 'A workflow must have at least one stage.',\n WORKFLOWS_LIMIT:\n 'You’ve reached the limit of workflows in your plan. Delete a workflow or contact Sales to enable more workflows.',\n STAGES_LIMIT:\n 'You’ve reached the limit of stages for this workflow in your plan. Try deleting some stages or contact Sales to enable more stages.',\n DUPLICATED_STAGE_NAME: 'Stage names must be unique.',\n};\n\nexport const WORKFLOW_POPULATE = {\n stages: {\n populate: {\n permissions: {\n fields: ['action', 'actionParameters'],\n populate: {\n role: { fields: ['id', 'name'] },\n },\n },\n },\n },\n stageRequiredToPublish: true,\n};\n"],"names":["WORKFLOW_MODEL_UID","STAGE_MODEL_UID","STAGE_TRANSITION_UID","STAGE_DEFAULT_COLOR","ENTITY_STAGE_ATTRIBUTE","ENTITY_ASSIGNEE_ATTRIBUTE","MAX_WORKFLOWS","MAX_STAGES_PER_WORKFLOW","ERRORS","WORKFLOW_WITHOUT_STAGES","WORKFLOWS_LIMIT","STAGES_LIMIT","DUPLICATED_STAGE_NAME","WORKFLOW_POPULATE","stages","populate","permissions","fields","role","stageRequiredToPublish"],"mappings":";;AAAO,MAAMA,qBAAqB;AAC3B,MAAMC,kBAAkB;AAC/B;;;;IAKO,MAAMC,oBAAAA,GAAuB;AAE7B,MAAMC,sBAAsB;AAC5B,MAAMC,yBAAyB;AAC/B,MAAMC,4BAA4B;AAElC,MAAMC,gBAAgB;AACtB,MAAMC,0BAA0B;MAE1BC,MAAAA,GAAS;IACpBC,uBAAAA,EAAyB,0CAAA;IACzBC,eAAAA,EACE,kHAAA;IACFC,YAAAA,EACE,qIAAA;IACFC,qBAAAA,EAAuB;AACzB;MAEaC,iBAAAA,GAAoB;IAC/BC,MAAAA,EAAQ;QACNC,QAAAA,EAAU;YACRC,WAAAA,EAAa;gBACXC,MAAAA,EAAQ;AAAC,oBAAA,QAAA;AAAU,oBAAA;AAAmB,iBAAA;gBACtCF,QAAAA,EAAU;oBACRG,IAAAA,EAAM;wBAAED,MAAAA,EAAQ;AAAC,4BAAA,IAAA;AAAM,4BAAA;AAAO;AAAC;AACjC;AACF;AACF;AACF,KAAA;IACAE,sBAAAA,EAAwB;AAC1B;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"workflows.js","sources":["../../../server/src/constants/workflows.ts"],"sourcesContent":["export const WORKFLOW_MODEL_UID = 'plugin::review-workflows.workflow';\nexport const STAGE_MODEL_UID = 'plugin::review-workflows.workflow-stage';\n/**\n * TODO: For V4 compatibility, the old UID was kept, when review workflows was in the admin package\n *\n * NOTE!: if you change this string you need to change it here too: strapi/packages/core/review-workflows/admin/src/routes/settings/components/Stages.tsx\n */\nexport const STAGE_TRANSITION_UID = 'admin::review-workflows.stage.transition';\n\nexport const STAGE_DEFAULT_COLOR = '#4945FF';\nexport const ENTITY_STAGE_ATTRIBUTE = 'strapi_stage';\nexport const ENTITY_ASSIGNEE_ATTRIBUTE = 'strapi_assignee';\n\nexport const MAX_WORKFLOWS = 200;\nexport const MAX_STAGES_PER_WORKFLOW = 200;\n\nexport const ERRORS = {\n WORKFLOW_WITHOUT_STAGES: 'A workflow must have at least one stage.',\n WORKFLOWS_LIMIT:\n 'You’ve reached the limit of workflows in your plan. Delete a workflow or contact Sales to enable more workflows.',\n STAGES_LIMIT:\n 'You’ve reached the limit of stages for this workflow in your plan. Try deleting some stages or contact Sales to enable more stages.',\n DUPLICATED_STAGE_NAME: 'Stage names must be unique.',\n DUPLICATED_WORKFLOW_NAME: 'A workflow with this name already exists.',\n};\n\nexport const WORKFLOW_POPULATE = {\n stages: {\n populate: {\n permissions: {\n fields: ['action', 'actionParameters'],\n populate: {\n role: { fields: ['id', 'name'] },\n },\n },\n },\n },\n stageRequiredToPublish: true,\n};\n"],"names":["WORKFLOW_MODEL_UID","STAGE_MODEL_UID","STAGE_TRANSITION_UID","STAGE_DEFAULT_COLOR","ENTITY_STAGE_ATTRIBUTE","ENTITY_ASSIGNEE_ATTRIBUTE","MAX_WORKFLOWS","MAX_STAGES_PER_WORKFLOW","ERRORS","WORKFLOW_WITHOUT_STAGES","WORKFLOWS_LIMIT","STAGES_LIMIT","DUPLICATED_STAGE_NAME","DUPLICATED_WORKFLOW_NAME","WORKFLOW_POPULATE","stages","populate","permissions","fields","role","stageRequiredToPublish"],"mappings":";;AAAO,MAAMA,qBAAqB;AAC3B,MAAMC,kBAAkB;AAC/B;;;;IAKO,MAAMC,oBAAAA,GAAuB;AAE7B,MAAMC,sBAAsB;AAC5B,MAAMC,yBAAyB;AAC/B,MAAMC,4BAA4B;AAElC,MAAMC,gBAAgB;AACtB,MAAMC,0BAA0B;MAE1BC,MAAAA,GAAS;IACpBC,uBAAAA,EAAyB,0CAAA;IACzBC,eAAAA,EACE,kHAAA;IACFC,YAAAA,EACE,qIAAA;IACFC,qBAAAA,EAAuB,6BAAA;IACvBC,wBAAAA,EAA0B;AAC5B;MAEaC,iBAAAA,GAAoB;IAC/BC,MAAAA,EAAQ;QACNC,QAAAA,EAAU;YACRC,WAAAA,EAAa;gBACXC,MAAAA,EAAQ;AAAC,oBAAA,QAAA;AAAU,oBAAA;AAAmB,iBAAA;gBACtCF,QAAAA,EAAU;oBACRG,IAAAA,EAAM;wBAAED,MAAAA,EAAQ;AAAC,4BAAA,IAAA;AAAM,4BAAA;AAAO;AAAC;AACjC;AACF;AACF;AACF,KAAA;IACAE,sBAAAA,EAAwB;AAC1B;;;;;;;;;;;;;"}
@@ -14,7 +14,8 @@ const ERRORS = {
14
14
  WORKFLOW_WITHOUT_STAGES: 'A workflow must have at least one stage.',
15
15
  WORKFLOWS_LIMIT: 'You’ve reached the limit of workflows in your plan. Delete a workflow or contact Sales to enable more workflows.',
16
16
  STAGES_LIMIT: 'You’ve reached the limit of stages for this workflow in your plan. Try deleting some stages or contact Sales to enable more stages.',
17
- DUPLICATED_STAGE_NAME: 'Stage names must be unique.'
17
+ DUPLICATED_STAGE_NAME: 'Stage names must be unique.',
18
+ DUPLICATED_WORKFLOW_NAME: 'A workflow with this name already exists.'
18
19
  };
19
20
  const WORKFLOW_POPULATE = {
20
21
  stages: {
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.mjs","sources":["../../../server/src/constants/workflows.ts"],"sourcesContent":["export const WORKFLOW_MODEL_UID = 'plugin::review-workflows.workflow';\nexport const STAGE_MODEL_UID = 'plugin::review-workflows.workflow-stage';\n/**\n * TODO: For V4 compatibility, the old UID was kept, when review workflows was in the admin package\n *\n * NOTE!: if you change this string you need to change it here too: strapi/packages/core/review-workflows/admin/src/routes/settings/components/Stages.tsx\n */\nexport const STAGE_TRANSITION_UID = 'admin::review-workflows.stage.transition';\n\nexport const STAGE_DEFAULT_COLOR = '#4945FF';\nexport const ENTITY_STAGE_ATTRIBUTE = 'strapi_stage';\nexport const ENTITY_ASSIGNEE_ATTRIBUTE = 'strapi_assignee';\n\nexport const MAX_WORKFLOWS = 200;\nexport const MAX_STAGES_PER_WORKFLOW = 200;\n\nexport const ERRORS = {\n WORKFLOW_WITHOUT_STAGES: 'A workflow must have at least one stage.',\n WORKFLOWS_LIMIT:\n 'You’ve reached the limit of workflows in your plan. Delete a workflow or contact Sales to enable more workflows.',\n STAGES_LIMIT:\n 'You’ve reached the limit of stages for this workflow in your plan. Try deleting some stages or contact Sales to enable more stages.',\n DUPLICATED_STAGE_NAME: 'Stage names must be unique.',\n};\n\nexport const WORKFLOW_POPULATE = {\n stages: {\n populate: {\n permissions: {\n fields: ['action', 'actionParameters'],\n populate: {\n role: { fields: ['id', 'name'] },\n },\n },\n },\n },\n stageRequiredToPublish: true,\n};\n"],"names":["WORKFLOW_MODEL_UID","STAGE_MODEL_UID","STAGE_TRANSITION_UID","STAGE_DEFAULT_COLOR","ENTITY_STAGE_ATTRIBUTE","ENTITY_ASSIGNEE_ATTRIBUTE","MAX_WORKFLOWS","MAX_STAGES_PER_WORKFLOW","ERRORS","WORKFLOW_WITHOUT_STAGES","WORKFLOWS_LIMIT","STAGES_LIMIT","DUPLICATED_STAGE_NAME","WORKFLOW_POPULATE","stages","populate","permissions","fields","role","stageRequiredToPublish"],"mappings":"AAAO,MAAMA,qBAAqB;AAC3B,MAAMC,kBAAkB;AAC/B;;;;IAKO,MAAMC,oBAAAA,GAAuB;AAE7B,MAAMC,sBAAsB;AAC5B,MAAMC,yBAAyB;AAC/B,MAAMC,4BAA4B;AAElC,MAAMC,gBAAgB;AACtB,MAAMC,0BAA0B;MAE1BC,MAAAA,GAAS;IACpBC,uBAAAA,EAAyB,0CAAA;IACzBC,eAAAA,EACE,kHAAA;IACFC,YAAAA,EACE,qIAAA;IACFC,qBAAAA,EAAuB;AACzB;MAEaC,iBAAAA,GAAoB;IAC/BC,MAAAA,EAAQ;QACNC,QAAAA,EAAU;YACRC,WAAAA,EAAa;gBACXC,MAAAA,EAAQ;AAAC,oBAAA,QAAA;AAAU,oBAAA;AAAmB,iBAAA;gBACtCF,QAAAA,EAAU;oBACRG,IAAAA,EAAM;wBAAED,MAAAA,EAAQ;AAAC,4BAAA,IAAA;AAAM,4BAAA;AAAO;AAAC;AACjC;AACF;AACF;AACF,KAAA;IACAE,sBAAAA,EAAwB;AAC1B;;;;"}
1
+ {"version":3,"file":"workflows.mjs","sources":["../../../server/src/constants/workflows.ts"],"sourcesContent":["export const WORKFLOW_MODEL_UID = 'plugin::review-workflows.workflow';\nexport const STAGE_MODEL_UID = 'plugin::review-workflows.workflow-stage';\n/**\n * TODO: For V4 compatibility, the old UID was kept, when review workflows was in the admin package\n *\n * NOTE!: if you change this string you need to change it here too: strapi/packages/core/review-workflows/admin/src/routes/settings/components/Stages.tsx\n */\nexport const STAGE_TRANSITION_UID = 'admin::review-workflows.stage.transition';\n\nexport const STAGE_DEFAULT_COLOR = '#4945FF';\nexport const ENTITY_STAGE_ATTRIBUTE = 'strapi_stage';\nexport const ENTITY_ASSIGNEE_ATTRIBUTE = 'strapi_assignee';\n\nexport const MAX_WORKFLOWS = 200;\nexport const MAX_STAGES_PER_WORKFLOW = 200;\n\nexport const ERRORS = {\n WORKFLOW_WITHOUT_STAGES: 'A workflow must have at least one stage.',\n WORKFLOWS_LIMIT:\n 'You’ve reached the limit of workflows in your plan. Delete a workflow or contact Sales to enable more workflows.',\n STAGES_LIMIT:\n 'You’ve reached the limit of stages for this workflow in your plan. Try deleting some stages or contact Sales to enable more stages.',\n DUPLICATED_STAGE_NAME: 'Stage names must be unique.',\n DUPLICATED_WORKFLOW_NAME: 'A workflow with this name already exists.',\n};\n\nexport const WORKFLOW_POPULATE = {\n stages: {\n populate: {\n permissions: {\n fields: ['action', 'actionParameters'],\n populate: {\n role: { fields: ['id', 'name'] },\n },\n },\n },\n },\n stageRequiredToPublish: true,\n};\n"],"names":["WORKFLOW_MODEL_UID","STAGE_MODEL_UID","STAGE_TRANSITION_UID","STAGE_DEFAULT_COLOR","ENTITY_STAGE_ATTRIBUTE","ENTITY_ASSIGNEE_ATTRIBUTE","MAX_WORKFLOWS","MAX_STAGES_PER_WORKFLOW","ERRORS","WORKFLOW_WITHOUT_STAGES","WORKFLOWS_LIMIT","STAGES_LIMIT","DUPLICATED_STAGE_NAME","DUPLICATED_WORKFLOW_NAME","WORKFLOW_POPULATE","stages","populate","permissions","fields","role","stageRequiredToPublish"],"mappings":"AAAO,MAAMA,qBAAqB;AAC3B,MAAMC,kBAAkB;AAC/B;;;;IAKO,MAAMC,oBAAAA,GAAuB;AAE7B,MAAMC,sBAAsB;AAC5B,MAAMC,yBAAyB;AAC/B,MAAMC,4BAA4B;AAElC,MAAMC,gBAAgB;AACtB,MAAMC,0BAA0B;MAE1BC,MAAAA,GAAS;IACpBC,uBAAAA,EAAyB,0CAAA;IACzBC,eAAAA,EACE,kHAAA;IACFC,YAAAA,EACE,qIAAA;IACFC,qBAAAA,EAAuB,6BAAA;IACvBC,wBAAAA,EAA0B;AAC5B;MAEaC,iBAAAA,GAAoB;IAC/BC,MAAAA,EAAQ;QACNC,QAAAA,EAAU;YACRC,WAAAA,EAAa;gBACXC,MAAAA,EAAQ;AAAC,oBAAA,QAAA;AAAU,oBAAA;AAAmB,iBAAA;gBACtCF,QAAAA,EAAU;oBACRG,IAAAA,EAAM;wBAAED,MAAAA,EAAQ;AAAC,4BAAA,IAAA;AAAM,4BAAA;AAAO;AAAC;AACjC;AACF;AACF;AACF,KAAA;IACAE,sBAAAA,EAAwB;AAC1B;;;;"}
@@ -48,6 +48,9 @@ var stages = {
48
48
  workflowId,
49
49
  populate
50
50
  });
51
+ if (stage === null) {
52
+ return ctx.notFound("Stage doesn't exist");
53
+ }
51
54
  ctx.body = {
52
55
  data: await sanitizer(stage)
53
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"stages.js","sources":["../../../server/src/controllers/stages.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { async } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { validateUpdateStageOnEntity, validateLocale } from '../validation/review-workflows';\nimport {\n STAGE_MODEL_UID,\n ENTITY_STAGE_ATTRIBUTE,\n STAGE_TRANSITION_UID,\n} from '../constants/workflows';\n\n/**\n *\n * @param { Core.Strapi } strapi - Strapi instance\n * @param userAbility\n * @return { (Stage) => SanitizedStage }\n */\nfunction sanitizeStage({ strapi }: { strapi: Core.Strapi }, userAbility: unknown) {\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model: STAGE_MODEL_UID });\n\n return (entity: unknown) => permissionChecker.sanitizeOutput(entity);\n}\n\nexport default {\n /**\n * List all stages\n */\n async find(ctx: Context) {\n const { workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stages = await stagesService.find({\n workflowId,\n populate,\n });\n\n ctx.body = {\n data: await async.map(stages, sanitizer),\n };\n },\n /**\n * Get one stage\n */\n async findById(ctx: Context) {\n const { id, workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stage = await stagesService.findById(id, {\n workflowId,\n populate,\n });\n\n ctx.body = {\n data: await sanitizer(stage),\n };\n },\n\n /**\n * Updates an entity's stage.\n * @async\n * @param {Object} ctx - The Koa context object.\n * @param {Object} ctx.params - An object containing the parameters from the request URL.\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity to update.\n * @param {Object} ctx.request.body.data - Optional data object containing the new stage ID for the entity.\n * @param {string} ctx.request.body.data.id - The ID of the new stage for the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n * @throws {ValidationError} If the `data` object in the request body fails to pass validation.\n * @returns {Promise<void>} A promise that resolves when the entity's stage has been updated.\n */\n async updateEntity(ctx: Context) {\n const stagesService = getService('stages');\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const { sanitizeOutput } = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID });\n\n // Load entity\n const locale = await validateLocale(query?.locale);\n const entity = await strapi.documents(modelUID).findOne({\n documentId,\n // @ts-expect-error - locale should be also null in the doc service types\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n });\n\n if (!entity) {\n ctx.throw(404, 'Entity not found');\n }\n\n // Validate if entity stage can be updated\n const canTransition = stagePermissions.can(\n STAGE_TRANSITION_UID,\n entity[ENTITY_STAGE_ATTRIBUTE]?.id\n );\n\n if (!canTransition) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const { id: stageId } = await validateUpdateStageOnEntity(\n { id: Number(body?.data?.id) },\n 'You should pass an id to the body of the put request.'\n );\n\n const workflow = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);\n workflowService.assertStageBelongsToWorkflow(stageId, workflow);\n\n const canTransitionTo = await stagePermissions.canTransitionToStage(stageId);\n if (!canTransitionTo) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);\n\n ctx.body = { data: await sanitizeOutput(updatedEntity) };\n },\n\n /**\n * List all the stages that are available for a user to transition an entity to.\n * Stages are filtered by both \"from\" permission on the current stage AND \"to\" permission on each target stage.\n * @async\n * @param {*} ctx\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n */\n async listAvailableStages(ctx: Context) {\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { query = {} } = ctx.request;\n\n if (\n strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID })\n .cannot.read()\n ) {\n return ctx.forbidden();\n }\n\n // Load entity\n const locale = (await validateLocale(query?.locale)) ?? undefined;\n const [entity, workflowCount, workflowResult] = await Promise.all([\n strapi.documents(modelUID).findOne({\n documentId,\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n }),\n workflowService.count(),\n workflowService.getAssignedWorkflow(modelUID, {\n populate: { stages: { populate: { permissions: { populate: ['role'] } } } },\n }),\n ]);\n\n const workflowStages = workflowResult ? workflowResult.stages : [];\n const entityStageId = entity?.[ENTITY_STAGE_ATTRIBUTE]?.id;\n const canTransition = stagePermissions.can(STAGE_TRANSITION_UID, entityStageId);\n\n const meta = {\n stageCount: workflowStages.length,\n workflowCount,\n canTransition,\n };\n\n // The entity may not exist yet for the requested locale (e.g. switching to a\n // locale that has not been saved).\n if (!entity) {\n if (!workflowResult) {\n ctx.throw(404, 'Entity not found');\n }\n\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n if (!canTransition) {\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n const otherStages = workflowStages.filter(\n (stage: { id: number; permissions?: unknown[] }) => stage.id !== entityStageId\n );\n\n const data = otherStages.filter((stage: { id: number; permissions?: unknown[] }) =>\n stagePermissions.canTransitionToStageWithPermissions(stage)\n );\n\n ctx.body = {\n data,\n meta,\n };\n },\n};\n"],"names":["sanitizeStage","strapi","userAbility","permissionChecker","plugin","service","create","model","STAGE_MODEL_UID","entity","sanitizeOutput","find","ctx","workflow_id","workflowId","params","populate","query","stagesService","getService","sanitizer","state","stages","body","data","async","map","findById","id","stage","updateEntity","stagePermissions","workflowService","model_uid","modelUID","documentId","request","locale","validateLocale","documents","findOne","ENTITY_STAGE_ATTRIBUTE","throw","canTransition","can","STAGE_TRANSITION_UID","stageId","validateUpdateStageOnEntity","Number","workflow","assertContentTypeBelongsToWorkflow","assertStageBelongsToWorkflow","canTransitionTo","canTransitionToStage","updatedEntity","listAvailableStages","cannot","read","forbidden","undefined","workflowCount","workflowResult","Promise","all","count","getAssignedWorkflow","permissions","workflowStages","entityStageId","meta","stageCount","length","otherStages","filter","canTransitionToStageWithPermissions"],"mappings":"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"}
1
+ {"version":3,"file":"stages.js","sources":["../../../server/src/controllers/stages.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { async } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { validateUpdateStageOnEntity, validateLocale } from '../validation/review-workflows';\nimport {\n STAGE_MODEL_UID,\n ENTITY_STAGE_ATTRIBUTE,\n STAGE_TRANSITION_UID,\n} from '../constants/workflows';\n\n/**\n *\n * @param { Core.Strapi } strapi - Strapi instance\n * @param userAbility\n * @return { (Stage) => SanitizedStage }\n */\nfunction sanitizeStage({ strapi }: { strapi: Core.Strapi }, userAbility: unknown) {\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model: STAGE_MODEL_UID });\n\n return (entity: unknown) => permissionChecker.sanitizeOutput(entity);\n}\n\nexport default {\n /**\n * List all stages\n */\n async find(ctx: Context) {\n const { workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stages = await stagesService.find({\n workflowId,\n populate,\n });\n\n ctx.body = {\n data: await async.map(stages, sanitizer),\n };\n },\n /**\n * Get one stage\n */\n async findById(ctx: Context) {\n const { id, workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stage = await stagesService.findById(id, {\n workflowId,\n populate,\n });\n\n if (stage === null) {\n return ctx.notFound(\"Stage doesn't exist\");\n }\n\n ctx.body = {\n data: await sanitizer(stage),\n };\n },\n\n /**\n * Updates an entity's stage.\n * @async\n * @param {Object} ctx - The Koa context object.\n * @param {Object} ctx.params - An object containing the parameters from the request URL.\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity to update.\n * @param {Object} ctx.request.body.data - Optional data object containing the new stage ID for the entity.\n * @param {string} ctx.request.body.data.id - The ID of the new stage for the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n * @throws {ValidationError} If the `data` object in the request body fails to pass validation.\n * @returns {Promise<void>} A promise that resolves when the entity's stage has been updated.\n */\n async updateEntity(ctx: Context) {\n const stagesService = getService('stages');\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const { sanitizeOutput } = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID });\n\n // Load entity\n const locale = await validateLocale(query?.locale);\n const entity = await strapi.documents(modelUID).findOne({\n documentId,\n // @ts-expect-error - locale should be also null in the doc service types\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n });\n\n if (!entity) {\n ctx.throw(404, 'Entity not found');\n }\n\n // Validate if entity stage can be updated\n const canTransition = stagePermissions.can(\n STAGE_TRANSITION_UID,\n entity[ENTITY_STAGE_ATTRIBUTE]?.id\n );\n\n if (!canTransition) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const { id: stageId } = await validateUpdateStageOnEntity(\n { id: Number(body?.data?.id) },\n 'You should pass an id to the body of the put request.'\n );\n\n const workflow = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);\n workflowService.assertStageBelongsToWorkflow(stageId, workflow);\n\n const canTransitionTo = await stagePermissions.canTransitionToStage(stageId);\n if (!canTransitionTo) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);\n\n ctx.body = { data: await sanitizeOutput(updatedEntity) };\n },\n\n /**\n * List all the stages that are available for a user to transition an entity to.\n * Stages are filtered by both \"from\" permission on the current stage AND \"to\" permission on each target stage.\n * @async\n * @param {*} ctx\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n */\n async listAvailableStages(ctx: Context) {\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { query = {} } = ctx.request;\n\n if (\n strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID })\n .cannot.read()\n ) {\n return ctx.forbidden();\n }\n\n // Load entity\n const locale = (await validateLocale(query?.locale)) ?? undefined;\n const [entity, workflowCount, workflowResult] = await Promise.all([\n strapi.documents(modelUID).findOne({\n documentId,\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n }),\n workflowService.count(),\n workflowService.getAssignedWorkflow(modelUID, {\n populate: { stages: { populate: { permissions: { populate: ['role'] } } } },\n }),\n ]);\n\n const workflowStages = workflowResult ? workflowResult.stages : [];\n const entityStageId = entity?.[ENTITY_STAGE_ATTRIBUTE]?.id;\n const canTransition = stagePermissions.can(STAGE_TRANSITION_UID, entityStageId);\n\n const meta = {\n stageCount: workflowStages.length,\n workflowCount,\n canTransition,\n };\n\n // The entity may not exist yet for the requested locale (e.g. switching to a\n // locale that has not been saved).\n if (!entity) {\n if (!workflowResult) {\n ctx.throw(404, 'Entity not found');\n }\n\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n if (!canTransition) {\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n const otherStages = workflowStages.filter(\n (stage: { id: number; permissions?: unknown[] }) => stage.id !== entityStageId\n );\n\n const data = otherStages.filter((stage: { id: number; permissions?: unknown[] }) =>\n stagePermissions.canTransitionToStageWithPermissions(stage)\n );\n\n ctx.body = {\n data,\n meta,\n };\n },\n};\n"],"names":["sanitizeStage","strapi","userAbility","permissionChecker","plugin","service","create","model","STAGE_MODEL_UID","entity","sanitizeOutput","find","ctx","workflow_id","workflowId","params","populate","query","stagesService","getService","sanitizer","state","stages","body","data","async","map","findById","id","stage","notFound","updateEntity","stagePermissions","workflowService","model_uid","modelUID","documentId","request","locale","validateLocale","documents","findOne","ENTITY_STAGE_ATTRIBUTE","throw","canTransition","can","STAGE_TRANSITION_UID","stageId","validateUpdateStageOnEntity","Number","workflow","assertContentTypeBelongsToWorkflow","assertStageBelongsToWorkflow","canTransitionTo","canTransitionToStage","updatedEntity","listAvailableStages","cannot","read","forbidden","undefined","workflowCount","workflowResult","Promise","all","count","getAssignedWorkflow","permissions","workflowStages","entityStageId","meta","stageCount","length","otherStages","filter","canTransitionToStageWithPermissions"],"mappings":"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"}
@@ -46,6 +46,9 @@ var stages = {
46
46
  workflowId,
47
47
  populate
48
48
  });
49
+ if (stage === null) {
50
+ return ctx.notFound("Stage doesn't exist");
51
+ }
49
52
  ctx.body = {
50
53
  data: await sanitizer(stage)
51
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"stages.mjs","sources":["../../../server/src/controllers/stages.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { async } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { validateUpdateStageOnEntity, validateLocale } from '../validation/review-workflows';\nimport {\n STAGE_MODEL_UID,\n ENTITY_STAGE_ATTRIBUTE,\n STAGE_TRANSITION_UID,\n} from '../constants/workflows';\n\n/**\n *\n * @param { Core.Strapi } strapi - Strapi instance\n * @param userAbility\n * @return { (Stage) => SanitizedStage }\n */\nfunction sanitizeStage({ strapi }: { strapi: Core.Strapi }, userAbility: unknown) {\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model: STAGE_MODEL_UID });\n\n return (entity: unknown) => permissionChecker.sanitizeOutput(entity);\n}\n\nexport default {\n /**\n * List all stages\n */\n async find(ctx: Context) {\n const { workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stages = await stagesService.find({\n workflowId,\n populate,\n });\n\n ctx.body = {\n data: await async.map(stages, sanitizer),\n };\n },\n /**\n * Get one stage\n */\n async findById(ctx: Context) {\n const { id, workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stage = await stagesService.findById(id, {\n workflowId,\n populate,\n });\n\n ctx.body = {\n data: await sanitizer(stage),\n };\n },\n\n /**\n * Updates an entity's stage.\n * @async\n * @param {Object} ctx - The Koa context object.\n * @param {Object} ctx.params - An object containing the parameters from the request URL.\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity to update.\n * @param {Object} ctx.request.body.data - Optional data object containing the new stage ID for the entity.\n * @param {string} ctx.request.body.data.id - The ID of the new stage for the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n * @throws {ValidationError} If the `data` object in the request body fails to pass validation.\n * @returns {Promise<void>} A promise that resolves when the entity's stage has been updated.\n */\n async updateEntity(ctx: Context) {\n const stagesService = getService('stages');\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const { sanitizeOutput } = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID });\n\n // Load entity\n const locale = await validateLocale(query?.locale);\n const entity = await strapi.documents(modelUID).findOne({\n documentId,\n // @ts-expect-error - locale should be also null in the doc service types\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n });\n\n if (!entity) {\n ctx.throw(404, 'Entity not found');\n }\n\n // Validate if entity stage can be updated\n const canTransition = stagePermissions.can(\n STAGE_TRANSITION_UID,\n entity[ENTITY_STAGE_ATTRIBUTE]?.id\n );\n\n if (!canTransition) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const { id: stageId } = await validateUpdateStageOnEntity(\n { id: Number(body?.data?.id) },\n 'You should pass an id to the body of the put request.'\n );\n\n const workflow = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);\n workflowService.assertStageBelongsToWorkflow(stageId, workflow);\n\n const canTransitionTo = await stagePermissions.canTransitionToStage(stageId);\n if (!canTransitionTo) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);\n\n ctx.body = { data: await sanitizeOutput(updatedEntity) };\n },\n\n /**\n * List all the stages that are available for a user to transition an entity to.\n * Stages are filtered by both \"from\" permission on the current stage AND \"to\" permission on each target stage.\n * @async\n * @param {*} ctx\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n */\n async listAvailableStages(ctx: Context) {\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { query = {} } = ctx.request;\n\n if (\n strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID })\n .cannot.read()\n ) {\n return ctx.forbidden();\n }\n\n // Load entity\n const locale = (await validateLocale(query?.locale)) ?? undefined;\n const [entity, workflowCount, workflowResult] = await Promise.all([\n strapi.documents(modelUID).findOne({\n documentId,\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n }),\n workflowService.count(),\n workflowService.getAssignedWorkflow(modelUID, {\n populate: { stages: { populate: { permissions: { populate: ['role'] } } } },\n }),\n ]);\n\n const workflowStages = workflowResult ? workflowResult.stages : [];\n const entityStageId = entity?.[ENTITY_STAGE_ATTRIBUTE]?.id;\n const canTransition = stagePermissions.can(STAGE_TRANSITION_UID, entityStageId);\n\n const meta = {\n stageCount: workflowStages.length,\n workflowCount,\n canTransition,\n };\n\n // The entity may not exist yet for the requested locale (e.g. switching to a\n // locale that has not been saved).\n if (!entity) {\n if (!workflowResult) {\n ctx.throw(404, 'Entity not found');\n }\n\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n if (!canTransition) {\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n const otherStages = workflowStages.filter(\n (stage: { id: number; permissions?: unknown[] }) => stage.id !== entityStageId\n );\n\n const data = otherStages.filter((stage: { id: number; permissions?: unknown[] }) =>\n stagePermissions.canTransitionToStageWithPermissions(stage)\n );\n\n ctx.body = {\n data,\n meta,\n };\n },\n};\n"],"names":["sanitizeStage","strapi","userAbility","permissionChecker","plugin","service","create","model","STAGE_MODEL_UID","entity","sanitizeOutput","find","ctx","workflow_id","workflowId","params","populate","query","stagesService","getService","sanitizer","state","stages","body","data","async","map","findById","id","stage","updateEntity","stagePermissions","workflowService","model_uid","modelUID","documentId","request","locale","validateLocale","documents","findOne","ENTITY_STAGE_ATTRIBUTE","throw","canTransition","can","STAGE_TRANSITION_UID","stageId","validateUpdateStageOnEntity","Number","workflow","assertContentTypeBelongsToWorkflow","assertStageBelongsToWorkflow","canTransitionTo","canTransitionToStage","updatedEntity","listAvailableStages","cannot","read","forbidden","undefined","workflowCount","workflowResult","Promise","all","count","getAssignedWorkflow","permissions","workflowStages","entityStageId","meta","stageCount","length","otherStages","filter","canTransitionToStageWithPermissions"],"mappings":"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"}
1
+ {"version":3,"file":"stages.mjs","sources":["../../../server/src/controllers/stages.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { async } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { validateUpdateStageOnEntity, validateLocale } from '../validation/review-workflows';\nimport {\n STAGE_MODEL_UID,\n ENTITY_STAGE_ATTRIBUTE,\n STAGE_TRANSITION_UID,\n} from '../constants/workflows';\n\n/**\n *\n * @param { Core.Strapi } strapi - Strapi instance\n * @param userAbility\n * @return { (Stage) => SanitizedStage }\n */\nfunction sanitizeStage({ strapi }: { strapi: Core.Strapi }, userAbility: unknown) {\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model: STAGE_MODEL_UID });\n\n return (entity: unknown) => permissionChecker.sanitizeOutput(entity);\n}\n\nexport default {\n /**\n * List all stages\n */\n async find(ctx: Context) {\n const { workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stages = await stagesService.find({\n workflowId,\n populate,\n });\n\n ctx.body = {\n data: await async.map(stages, sanitizer),\n };\n },\n /**\n * Get one stage\n */\n async findById(ctx: Context) {\n const { id, workflow_id: workflowId } = ctx.params;\n const { populate } = ctx.query;\n const stagesService = getService('stages');\n const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n const stage = await stagesService.findById(id, {\n workflowId,\n populate,\n });\n\n if (stage === null) {\n return ctx.notFound(\"Stage doesn't exist\");\n }\n\n ctx.body = {\n data: await sanitizer(stage),\n };\n },\n\n /**\n * Updates an entity's stage.\n * @async\n * @param {Object} ctx - The Koa context object.\n * @param {Object} ctx.params - An object containing the parameters from the request URL.\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity to update.\n * @param {Object} ctx.request.body.data - Optional data object containing the new stage ID for the entity.\n * @param {string} ctx.request.body.data.id - The ID of the new stage for the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n * @throws {ValidationError} If the `data` object in the request body fails to pass validation.\n * @returns {Promise<void>} A promise that resolves when the entity's stage has been updated.\n */\n async updateEntity(ctx: Context) {\n const stagesService = getService('stages');\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const { sanitizeOutput } = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID });\n\n // Load entity\n const locale = await validateLocale(query?.locale);\n const entity = await strapi.documents(modelUID).findOne({\n documentId,\n // @ts-expect-error - locale should be also null in the doc service types\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n });\n\n if (!entity) {\n ctx.throw(404, 'Entity not found');\n }\n\n // Validate if entity stage can be updated\n const canTransition = stagePermissions.can(\n STAGE_TRANSITION_UID,\n entity[ENTITY_STAGE_ATTRIBUTE]?.id\n );\n\n if (!canTransition) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const { id: stageId } = await validateUpdateStageOnEntity(\n { id: Number(body?.data?.id) },\n 'You should pass an id to the body of the put request.'\n );\n\n const workflow = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);\n workflowService.assertStageBelongsToWorkflow(stageId, workflow);\n\n const canTransitionTo = await stagePermissions.canTransitionToStage(stageId);\n if (!canTransitionTo) {\n ctx.throw(403, 'Forbidden stage transition');\n }\n\n const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);\n\n ctx.body = { data: await sanitizeOutput(updatedEntity) };\n },\n\n /**\n * List all the stages that are available for a user to transition an entity to.\n * Stages are filtered by both \"from\" permission on the current stage AND \"to\" permission on each target stage.\n * @async\n * @param {*} ctx\n * @param {string} ctx.params.model_uid - The model UID of the entity.\n * @param {string} ctx.params.id - The ID of the entity.\n * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n */\n async listAvailableStages(ctx: Context) {\n const stagePermissions = getService('stage-permissions');\n const workflowService = getService('workflows');\n\n const { model_uid: modelUID, id: documentId } = ctx.params;\n const { query = {} } = ctx.request;\n\n if (\n strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility: ctx.state.userAbility, model: modelUID })\n .cannot.read()\n ) {\n return ctx.forbidden();\n }\n\n // Load entity\n const locale = (await validateLocale(query?.locale)) ?? undefined;\n const [entity, workflowCount, workflowResult] = await Promise.all([\n strapi.documents(modelUID).findOne({\n documentId,\n locale,\n populate: [ENTITY_STAGE_ATTRIBUTE],\n }),\n workflowService.count(),\n workflowService.getAssignedWorkflow(modelUID, {\n populate: { stages: { populate: { permissions: { populate: ['role'] } } } },\n }),\n ]);\n\n const workflowStages = workflowResult ? workflowResult.stages : [];\n const entityStageId = entity?.[ENTITY_STAGE_ATTRIBUTE]?.id;\n const canTransition = stagePermissions.can(STAGE_TRANSITION_UID, entityStageId);\n\n const meta = {\n stageCount: workflowStages.length,\n workflowCount,\n canTransition,\n };\n\n // The entity may not exist yet for the requested locale (e.g. switching to a\n // locale that has not been saved).\n if (!entity) {\n if (!workflowResult) {\n ctx.throw(404, 'Entity not found');\n }\n\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n if (!canTransition) {\n ctx.body = {\n data: [],\n meta,\n };\n\n return;\n }\n\n const otherStages = workflowStages.filter(\n (stage: { id: number; permissions?: unknown[] }) => stage.id !== entityStageId\n );\n\n const data = otherStages.filter((stage: { id: number; permissions?: unknown[] }) =>\n stagePermissions.canTransitionToStageWithPermissions(stage)\n );\n\n ctx.body = {\n data,\n meta,\n };\n },\n};\n"],"names":["sanitizeStage","strapi","userAbility","permissionChecker","plugin","service","create","model","STAGE_MODEL_UID","entity","sanitizeOutput","find","ctx","workflow_id","workflowId","params","populate","query","stagesService","getService","sanitizer","state","stages","body","data","async","map","findById","id","stage","notFound","updateEntity","stagePermissions","workflowService","model_uid","modelUID","documentId","request","locale","validateLocale","documents","findOne","ENTITY_STAGE_ATTRIBUTE","throw","canTransition","can","STAGE_TRANSITION_UID","stageId","validateUpdateStageOnEntity","Number","workflow","assertContentTypeBelongsToWorkflow","assertStageBelongsToWorkflow","canTransitionTo","canTransitionToStage","updatedEntity","listAvailableStages","cannot","read","forbidden","undefined","workflowCount","workflowResult","Promise","all","count","getAssignedWorkflow","permissions","workflowStages","entityStageId","meta","stageCount","length","otherStages","filter","canTransitionToStageWithPermissions"],"mappings":"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"}
@@ -1,9 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var lodash = require('lodash');
3
4
  var utils = require('@strapi/utils');
4
5
  var workflows = require('../constants/workflows.js');
5
6
  var webhookEvents = require('../constants/webhook-events.js');
6
7
  var index = require('../utils/index.js');
8
+ var reviewWorkflows = require('../utils/review-workflows.js');
7
9
 
8
10
  /**
9
11
  * Get the stage information of an entity
@@ -25,10 +27,35 @@ var index = require('../utils/index.js');
25
27
  });
26
28
  return entity?.[workflows.ENTITY_STAGE_ATTRIBUTE] ?? {};
27
29
  };
30
+ /**
31
+ * An update creates a new locale of a document when the requested locale has no entry yet
32
+ */ const isLocaleCreation = async (uid, params)=>{
33
+ const entry = await strapi.documents(uid).findOne({
34
+ documentId: params.documentId,
35
+ locale: params.locale,
36
+ status: 'draft',
37
+ fields: [
38
+ 'id'
39
+ ]
40
+ });
41
+ return entry === null;
42
+ };
28
43
  /**
29
44
  * Ensures the entity is assigned to the default workflow stage
30
45
  */ const assignStageOnCreate = async (ctx, next)=>{
31
- if (ctx.action !== 'create' && ctx.action !== 'clone') {
46
+ if (ctx.action === 'update') {
47
+ const data = ctx.params.data;
48
+ if (data?.[workflows.ENTITY_STAGE_ATTRIBUTE] != null) {
49
+ return next();
50
+ }
51
+ // Only a localized type with a stage attribute can get a new locale with a stage through an update
52
+ if (reviewWorkflows.hasStageAttribute(ctx.contentType) === false || lodash.get(ctx.contentType, 'pluginOptions.i18n.localized') !== true) {
53
+ return next();
54
+ }
55
+ if (await isLocaleCreation(ctx.contentType.uid, ctx.params) === false) {
56
+ return next();
57
+ }
58
+ } else if (ctx.action !== 'create' && ctx.action !== 'clone') {
32
59
  return next();
33
60
  }
34
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"document-service-middleware.js","sources":["../../../server/src/services/document-service-middleware.ts"],"sourcesContent":["import type { Modules } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nimport { ENTITY_STAGE_ATTRIBUTE } from '../constants/workflows';\nimport { WORKFLOW_UPDATE_STAGE } from '../constants/webhook-events';\nimport { getService } from '../utils';\n\ntype Middleware = Modules.Documents.Middleware.Middleware;\n\n/**\n * Get the stage information of an entity\n * @param {String} uid\n * @param {Number} id\n * @returns {Object}\n */\nconst getEntityStage = async (uid: any, id: any, params: any) => {\n const entity = await strapi.documents(uid).findOne({\n ...params,\n documentId: id,\n status: 'draft',\n populate: {\n [ENTITY_STAGE_ATTRIBUTE]: {\n populate: {\n workflow: true,\n },\n },\n },\n });\n\n return entity?.[ENTITY_STAGE_ATTRIBUTE] ?? {};\n};\n\n/**\n * Ensures the entity is assigned to the default workflow stage\n */\nconst assignStageOnCreate: Middleware = async (ctx, next) => {\n if (ctx.action !== 'create' && ctx.action !== 'clone') {\n return next();\n }\n\n /**\n * Content types can have assigned workflows,\n * if the CT has one, assign a default value to the stage attribute if it's not present\n */\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stages',\n });\n\n if (!workflow) {\n return next();\n }\n\n const data = ctx.params.data as Record<string, any>;\n\n // Assign the default stage if the entity doesn't have one\n if (ctx.params?.data && data[ENTITY_STAGE_ATTRIBUTE] == null) {\n data[ENTITY_STAGE_ATTRIBUTE] = { id: workflow.stages[0].id };\n }\n\n return next();\n};\n\nconst handleStageOnUpdate: Middleware = async (ctx, next) => {\n if (ctx.action !== 'update') {\n return next();\n }\n\n const { documentId } = ctx.params;\n const data = ctx.params.data as any;\n\n if (data?.[ENTITY_STAGE_ATTRIBUTE] == null) {\n delete data?.[ENTITY_STAGE_ATTRIBUTE];\n return next();\n }\n\n /**\n * Get last stage of the entity\n */\n const previousStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n const result = await next();\n\n if (!result) {\n return result;\n }\n\n // @ts-expect-error - Property 'strapi_stage' does not exist on type ...\n const updatedStage = result?.[ENTITY_STAGE_ATTRIBUTE];\n\n // Stage might be null if field is not populated\n if (updatedStage && previousStage?.id && previousStage.id !== updatedStage.id) {\n const model = strapi.getModel(ctx.contentType.uid);\n\n strapi.eventHub.emit(WORKFLOW_UPDATE_STAGE, {\n model: model.modelName,\n uid: model.uid,\n // TODO v6: Rename to \"entry\", which is what is used for regular CRUD updates\n entity: {\n // @ts-expect-error - Property 'id' does not exist on type 'number'\n id: result?.id,\n documentId,\n // @ts-expect-error - Property 'locale' does not exist on type 'number'\n locale: result?.locale,\n status: 'draft',\n },\n workflow: {\n id: previousStage.workflow.id,\n stages: {\n from: {\n id: previousStage.id,\n name: previousStage.name,\n },\n to: {\n id: updatedStage.id,\n name: updatedStage.name,\n },\n },\n },\n });\n }\n\n return result;\n};\n\n/**\n * Check if the entity is at the required stage before publish\n */\nconst checkStageBeforePublish: Middleware = async (ctx, next) => {\n if (ctx.action !== 'publish') {\n return next();\n }\n\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stageRequiredToPublish',\n });\n\n if (!workflow || !workflow.stageRequiredToPublish) {\n return next();\n }\n\n const { documentId } = ctx.params;\n const entryStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n if (entryStage.id !== workflow.stageRequiredToPublish.id) {\n throw new errors.ValidationError('Entry is not at the required stage to publish');\n }\n\n return next();\n};\n\nexport default () => ({\n assignStageOnCreate,\n handleStageOnUpdate,\n checkStageBeforePublish,\n});\n"],"names":["getEntityStage","uid","id","params","entity","strapi","documents","findOne","documentId","status","populate","ENTITY_STAGE_ATTRIBUTE","workflow","assignStageOnCreate","ctx","next","action","getService","getAssignedWorkflow","contentType","data","stages","handleStageOnUpdate","previousStage","result","updatedStage","model","getModel","eventHub","emit","WORKFLOW_UPDATE_STAGE","modelName","locale","from","name","to","checkStageBeforePublish","stageRequiredToPublish","entryStage","errors","ValidationError"],"mappings":"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"}
1
+ {"version":3,"file":"document-service-middleware.js","sources":["../../../server/src/services/document-service-middleware.ts"],"sourcesContent":["import { get } from 'lodash';\nimport type { Modules } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nimport { ENTITY_STAGE_ATTRIBUTE } from '../constants/workflows';\nimport { WORKFLOW_UPDATE_STAGE } from '../constants/webhook-events';\nimport { getService } from '../utils';\nimport { hasStageAttribute } from '../utils/review-workflows';\n\ntype Middleware = Modules.Documents.Middleware.Middleware;\n\n/**\n * Get the stage information of an entity\n * @param {String} uid\n * @param {Number} id\n * @returns {Object}\n */\nconst getEntityStage = async (uid: any, id: any, params: any) => {\n const entity = await strapi.documents(uid).findOne({\n ...params,\n documentId: id,\n status: 'draft',\n populate: {\n [ENTITY_STAGE_ATTRIBUTE]: {\n populate: {\n workflow: true,\n },\n },\n },\n });\n\n return entity?.[ENTITY_STAGE_ATTRIBUTE] ?? {};\n};\n\n/**\n * An update creates a new locale of a document when the requested locale has no entry yet\n */\nconst isLocaleCreation = async (uid: any, params: any) => {\n const entry = await strapi.documents(uid).findOne({\n documentId: params.documentId,\n locale: params.locale,\n status: 'draft',\n fields: ['id'],\n });\n\n return entry === null;\n};\n\n/**\n * Ensures the entity is assigned to the default workflow stage\n */\nconst assignStageOnCreate: Middleware = async (ctx, next) => {\n if (ctx.action === 'update') {\n const data = ctx.params.data as Record<string, any> | undefined;\n\n if (data?.[ENTITY_STAGE_ATTRIBUTE] != null) {\n return next();\n }\n\n // Only a localized type with a stage attribute can get a new locale with a stage through an update\n if (\n hasStageAttribute(ctx.contentType) === false ||\n get(ctx.contentType, 'pluginOptions.i18n.localized') !== true\n ) {\n return next();\n }\n\n if ((await isLocaleCreation(ctx.contentType.uid, ctx.params)) === false) {\n return next();\n }\n } else if (ctx.action !== 'create' && ctx.action !== 'clone') {\n return next();\n }\n\n /**\n * Content types can have assigned workflows,\n * if the CT has one, assign a default value to the stage attribute if it's not present\n */\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stages',\n });\n\n if (!workflow) {\n return next();\n }\n\n const data = ctx.params.data as Record<string, any>;\n\n // Assign the default stage if the entity doesn't have one\n if (ctx.params?.data && data[ENTITY_STAGE_ATTRIBUTE] == null) {\n data[ENTITY_STAGE_ATTRIBUTE] = { id: workflow.stages[0].id };\n }\n\n return next();\n};\n\nconst handleStageOnUpdate: Middleware = async (ctx, next) => {\n if (ctx.action !== 'update') {\n return next();\n }\n\n const { documentId } = ctx.params;\n const data = ctx.params.data as any;\n\n if (data?.[ENTITY_STAGE_ATTRIBUTE] == null) {\n delete data?.[ENTITY_STAGE_ATTRIBUTE];\n return next();\n }\n\n /**\n * Get last stage of the entity\n */\n const previousStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n const result = await next();\n\n if (!result) {\n return result;\n }\n\n // @ts-expect-error - Property 'strapi_stage' does not exist on type ...\n const updatedStage = result?.[ENTITY_STAGE_ATTRIBUTE];\n\n // Stage might be null if field is not populated\n if (updatedStage && previousStage?.id && previousStage.id !== updatedStage.id) {\n const model = strapi.getModel(ctx.contentType.uid);\n\n strapi.eventHub.emit(WORKFLOW_UPDATE_STAGE, {\n model: model.modelName,\n uid: model.uid,\n // TODO v6: Rename to \"entry\", which is what is used for regular CRUD updates\n entity: {\n // @ts-expect-error - Property 'id' does not exist on type 'number'\n id: result?.id,\n documentId,\n // @ts-expect-error - Property 'locale' does not exist on type 'number'\n locale: result?.locale,\n status: 'draft',\n },\n workflow: {\n id: previousStage.workflow.id,\n stages: {\n from: {\n id: previousStage.id,\n name: previousStage.name,\n },\n to: {\n id: updatedStage.id,\n name: updatedStage.name,\n },\n },\n },\n });\n }\n\n return result;\n};\n\n/**\n * Check if the entity is at the required stage before publish\n */\nconst checkStageBeforePublish: Middleware = async (ctx, next) => {\n if (ctx.action !== 'publish') {\n return next();\n }\n\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stageRequiredToPublish',\n });\n\n if (!workflow || !workflow.stageRequiredToPublish) {\n return next();\n }\n\n const { documentId } = ctx.params;\n const entryStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n if (entryStage.id !== workflow.stageRequiredToPublish.id) {\n throw new errors.ValidationError('Entry is not at the required stage to publish');\n }\n\n return next();\n};\n\nexport default () => ({\n assignStageOnCreate,\n handleStageOnUpdate,\n checkStageBeforePublish,\n});\n"],"names":["getEntityStage","uid","id","params","entity","strapi","documents","findOne","documentId","status","populate","ENTITY_STAGE_ATTRIBUTE","workflow","isLocaleCreation","entry","locale","fields","assignStageOnCreate","ctx","next","action","data","hasStageAttribute","contentType","get","getService","getAssignedWorkflow","stages","handleStageOnUpdate","previousStage","result","updatedStage","model","getModel","eventHub","emit","WORKFLOW_UPDATE_STAGE","modelName","from","name","to","checkStageBeforePublish","stageRequiredToPublish","entryStage","errors","ValidationError"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
+ import { get } from 'lodash';
1
2
  import { errors } from '@strapi/utils';
2
3
  import { ENTITY_STAGE_ATTRIBUTE } from '../constants/workflows.mjs';
3
4
  import { WORKFLOW_UPDATE_STAGE } from '../constants/webhook-events.mjs';
4
5
  import { getService } from '../utils/index.mjs';
6
+ import { hasStageAttribute } from '../utils/review-workflows.mjs';
5
7
 
6
8
  /**
7
9
  * Get the stage information of an entity
@@ -23,10 +25,35 @@ import { getService } from '../utils/index.mjs';
23
25
  });
24
26
  return entity?.[ENTITY_STAGE_ATTRIBUTE] ?? {};
25
27
  };
28
+ /**
29
+ * An update creates a new locale of a document when the requested locale has no entry yet
30
+ */ const isLocaleCreation = async (uid, params)=>{
31
+ const entry = await strapi.documents(uid).findOne({
32
+ documentId: params.documentId,
33
+ locale: params.locale,
34
+ status: 'draft',
35
+ fields: [
36
+ 'id'
37
+ ]
38
+ });
39
+ return entry === null;
40
+ };
26
41
  /**
27
42
  * Ensures the entity is assigned to the default workflow stage
28
43
  */ const assignStageOnCreate = async (ctx, next)=>{
29
- if (ctx.action !== 'create' && ctx.action !== 'clone') {
44
+ if (ctx.action === 'update') {
45
+ const data = ctx.params.data;
46
+ if (data?.[ENTITY_STAGE_ATTRIBUTE] != null) {
47
+ return next();
48
+ }
49
+ // Only a localized type with a stage attribute can get a new locale with a stage through an update
50
+ if (hasStageAttribute(ctx.contentType) === false || get(ctx.contentType, 'pluginOptions.i18n.localized') !== true) {
51
+ return next();
52
+ }
53
+ if (await isLocaleCreation(ctx.contentType.uid, ctx.params) === false) {
54
+ return next();
55
+ }
56
+ } else if (ctx.action !== 'create' && ctx.action !== 'clone') {
30
57
  return next();
31
58
  }
32
59
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"document-service-middleware.mjs","sources":["../../../server/src/services/document-service-middleware.ts"],"sourcesContent":["import type { Modules } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nimport { ENTITY_STAGE_ATTRIBUTE } from '../constants/workflows';\nimport { WORKFLOW_UPDATE_STAGE } from '../constants/webhook-events';\nimport { getService } from '../utils';\n\ntype Middleware = Modules.Documents.Middleware.Middleware;\n\n/**\n * Get the stage information of an entity\n * @param {String} uid\n * @param {Number} id\n * @returns {Object}\n */\nconst getEntityStage = async (uid: any, id: any, params: any) => {\n const entity = await strapi.documents(uid).findOne({\n ...params,\n documentId: id,\n status: 'draft',\n populate: {\n [ENTITY_STAGE_ATTRIBUTE]: {\n populate: {\n workflow: true,\n },\n },\n },\n });\n\n return entity?.[ENTITY_STAGE_ATTRIBUTE] ?? {};\n};\n\n/**\n * Ensures the entity is assigned to the default workflow stage\n */\nconst assignStageOnCreate: Middleware = async (ctx, next) => {\n if (ctx.action !== 'create' && ctx.action !== 'clone') {\n return next();\n }\n\n /**\n * Content types can have assigned workflows,\n * if the CT has one, assign a default value to the stage attribute if it's not present\n */\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stages',\n });\n\n if (!workflow) {\n return next();\n }\n\n const data = ctx.params.data as Record<string, any>;\n\n // Assign the default stage if the entity doesn't have one\n if (ctx.params?.data && data[ENTITY_STAGE_ATTRIBUTE] == null) {\n data[ENTITY_STAGE_ATTRIBUTE] = { id: workflow.stages[0].id };\n }\n\n return next();\n};\n\nconst handleStageOnUpdate: Middleware = async (ctx, next) => {\n if (ctx.action !== 'update') {\n return next();\n }\n\n const { documentId } = ctx.params;\n const data = ctx.params.data as any;\n\n if (data?.[ENTITY_STAGE_ATTRIBUTE] == null) {\n delete data?.[ENTITY_STAGE_ATTRIBUTE];\n return next();\n }\n\n /**\n * Get last stage of the entity\n */\n const previousStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n const result = await next();\n\n if (!result) {\n return result;\n }\n\n // @ts-expect-error - Property 'strapi_stage' does not exist on type ...\n const updatedStage = result?.[ENTITY_STAGE_ATTRIBUTE];\n\n // Stage might be null if field is not populated\n if (updatedStage && previousStage?.id && previousStage.id !== updatedStage.id) {\n const model = strapi.getModel(ctx.contentType.uid);\n\n strapi.eventHub.emit(WORKFLOW_UPDATE_STAGE, {\n model: model.modelName,\n uid: model.uid,\n // TODO v6: Rename to \"entry\", which is what is used for regular CRUD updates\n entity: {\n // @ts-expect-error - Property 'id' does not exist on type 'number'\n id: result?.id,\n documentId,\n // @ts-expect-error - Property 'locale' does not exist on type 'number'\n locale: result?.locale,\n status: 'draft',\n },\n workflow: {\n id: previousStage.workflow.id,\n stages: {\n from: {\n id: previousStage.id,\n name: previousStage.name,\n },\n to: {\n id: updatedStage.id,\n name: updatedStage.name,\n },\n },\n },\n });\n }\n\n return result;\n};\n\n/**\n * Check if the entity is at the required stage before publish\n */\nconst checkStageBeforePublish: Middleware = async (ctx, next) => {\n if (ctx.action !== 'publish') {\n return next();\n }\n\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stageRequiredToPublish',\n });\n\n if (!workflow || !workflow.stageRequiredToPublish) {\n return next();\n }\n\n const { documentId } = ctx.params;\n const entryStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n if (entryStage.id !== workflow.stageRequiredToPublish.id) {\n throw new errors.ValidationError('Entry is not at the required stage to publish');\n }\n\n return next();\n};\n\nexport default () => ({\n assignStageOnCreate,\n handleStageOnUpdate,\n checkStageBeforePublish,\n});\n"],"names":["getEntityStage","uid","id","params","entity","strapi","documents","findOne","documentId","status","populate","ENTITY_STAGE_ATTRIBUTE","workflow","assignStageOnCreate","ctx","next","action","getService","getAssignedWorkflow","contentType","data","stages","handleStageOnUpdate","previousStage","result","updatedStage","model","getModel","eventHub","emit","WORKFLOW_UPDATE_STAGE","modelName","locale","from","name","to","checkStageBeforePublish","stageRequiredToPublish","entryStage","errors","ValidationError"],"mappings":"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"}
1
+ {"version":3,"file":"document-service-middleware.mjs","sources":["../../../server/src/services/document-service-middleware.ts"],"sourcesContent":["import { get } from 'lodash';\nimport type { Modules } from '@strapi/types';\nimport { errors } from '@strapi/utils';\n\nimport { ENTITY_STAGE_ATTRIBUTE } from '../constants/workflows';\nimport { WORKFLOW_UPDATE_STAGE } from '../constants/webhook-events';\nimport { getService } from '../utils';\nimport { hasStageAttribute } from '../utils/review-workflows';\n\ntype Middleware = Modules.Documents.Middleware.Middleware;\n\n/**\n * Get the stage information of an entity\n * @param {String} uid\n * @param {Number} id\n * @returns {Object}\n */\nconst getEntityStage = async (uid: any, id: any, params: any) => {\n const entity = await strapi.documents(uid).findOne({\n ...params,\n documentId: id,\n status: 'draft',\n populate: {\n [ENTITY_STAGE_ATTRIBUTE]: {\n populate: {\n workflow: true,\n },\n },\n },\n });\n\n return entity?.[ENTITY_STAGE_ATTRIBUTE] ?? {};\n};\n\n/**\n * An update creates a new locale of a document when the requested locale has no entry yet\n */\nconst isLocaleCreation = async (uid: any, params: any) => {\n const entry = await strapi.documents(uid).findOne({\n documentId: params.documentId,\n locale: params.locale,\n status: 'draft',\n fields: ['id'],\n });\n\n return entry === null;\n};\n\n/**\n * Ensures the entity is assigned to the default workflow stage\n */\nconst assignStageOnCreate: Middleware = async (ctx, next) => {\n if (ctx.action === 'update') {\n const data = ctx.params.data as Record<string, any> | undefined;\n\n if (data?.[ENTITY_STAGE_ATTRIBUTE] != null) {\n return next();\n }\n\n // Only a localized type with a stage attribute can get a new locale with a stage through an update\n if (\n hasStageAttribute(ctx.contentType) === false ||\n get(ctx.contentType, 'pluginOptions.i18n.localized') !== true\n ) {\n return next();\n }\n\n if ((await isLocaleCreation(ctx.contentType.uid, ctx.params)) === false) {\n return next();\n }\n } else if (ctx.action !== 'create' && ctx.action !== 'clone') {\n return next();\n }\n\n /**\n * Content types can have assigned workflows,\n * if the CT has one, assign a default value to the stage attribute if it's not present\n */\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stages',\n });\n\n if (!workflow) {\n return next();\n }\n\n const data = ctx.params.data as Record<string, any>;\n\n // Assign the default stage if the entity doesn't have one\n if (ctx.params?.data && data[ENTITY_STAGE_ATTRIBUTE] == null) {\n data[ENTITY_STAGE_ATTRIBUTE] = { id: workflow.stages[0].id };\n }\n\n return next();\n};\n\nconst handleStageOnUpdate: Middleware = async (ctx, next) => {\n if (ctx.action !== 'update') {\n return next();\n }\n\n const { documentId } = ctx.params;\n const data = ctx.params.data as any;\n\n if (data?.[ENTITY_STAGE_ATTRIBUTE] == null) {\n delete data?.[ENTITY_STAGE_ATTRIBUTE];\n return next();\n }\n\n /**\n * Get last stage of the entity\n */\n const previousStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n const result = await next();\n\n if (!result) {\n return result;\n }\n\n // @ts-expect-error - Property 'strapi_stage' does not exist on type ...\n const updatedStage = result?.[ENTITY_STAGE_ATTRIBUTE];\n\n // Stage might be null if field is not populated\n if (updatedStage && previousStage?.id && previousStage.id !== updatedStage.id) {\n const model = strapi.getModel(ctx.contentType.uid);\n\n strapi.eventHub.emit(WORKFLOW_UPDATE_STAGE, {\n model: model.modelName,\n uid: model.uid,\n // TODO v6: Rename to \"entry\", which is what is used for regular CRUD updates\n entity: {\n // @ts-expect-error - Property 'id' does not exist on type 'number'\n id: result?.id,\n documentId,\n // @ts-expect-error - Property 'locale' does not exist on type 'number'\n locale: result?.locale,\n status: 'draft',\n },\n workflow: {\n id: previousStage.workflow.id,\n stages: {\n from: {\n id: previousStage.id,\n name: previousStage.name,\n },\n to: {\n id: updatedStage.id,\n name: updatedStage.name,\n },\n },\n },\n });\n }\n\n return result;\n};\n\n/**\n * Check if the entity is at the required stage before publish\n */\nconst checkStageBeforePublish: Middleware = async (ctx, next) => {\n if (ctx.action !== 'publish') {\n return next();\n }\n\n const workflow = await getService('workflows').getAssignedWorkflow(ctx.contentType.uid, {\n populate: 'stageRequiredToPublish',\n });\n\n if (!workflow || !workflow.stageRequiredToPublish) {\n return next();\n }\n\n const { documentId } = ctx.params;\n const entryStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);\n\n if (entryStage.id !== workflow.stageRequiredToPublish.id) {\n throw new errors.ValidationError('Entry is not at the required stage to publish');\n }\n\n return next();\n};\n\nexport default () => ({\n assignStageOnCreate,\n handleStageOnUpdate,\n checkStageBeforePublish,\n});\n"],"names":["getEntityStage","uid","id","params","entity","strapi","documents","findOne","documentId","status","populate","ENTITY_STAGE_ATTRIBUTE","workflow","isLocaleCreation","entry","locale","fields","assignStageOnCreate","ctx","next","action","data","hasStageAttribute","contentType","get","getService","getAssignedWorkflow","stages","handleStageOnUpdate","previousStage","result","updatedStage","model","getModel","eventHub","emit","WORKFLOW_UPDATE_STAGE","modelName","from","name","to","checkStageBeforePublish","stageRequiredToPublish","entryStage","errors","ValidationError"],"mappings":"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"}