@strapi/review-workflows 0.0.0-experimental.fdacf4285d1cada9d94ab4dcd756c5362cba1b54 → 0.0.0-next.185e16fdc3e6f1895610ab73932bc3f044bb59e9

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 (49) hide show
  1. package/dist/_chunks/{Layout-CefL-rfa.mjs → Layout-BmKilx1K.mjs} +2 -2
  2. package/dist/_chunks/{Layout-CefL-rfa.mjs.map → Layout-BmKilx1K.mjs.map} +1 -1
  3. package/dist/_chunks/{Layout-COeOgRsc.js → Layout-Bv8Nx1fv.js} +2 -2
  4. package/dist/_chunks/{Layout-COeOgRsc.js.map → Layout-Bv8Nx1fv.js.map} +1 -1
  5. package/dist/_chunks/{_id-PmPKIqUm.js → id-CsSxw398.js} +4 -5
  6. package/dist/_chunks/id-CsSxw398.js.map +1 -0
  7. package/dist/_chunks/{_id-Dt2oEiro.mjs → id-DEppSbOE.mjs} +4 -5
  8. package/dist/_chunks/id-DEppSbOE.mjs.map +1 -0
  9. package/dist/_chunks/{index-IZXxuQ4h.mjs → index-B40EWubS.mjs} +2 -5
  10. package/dist/_chunks/{index-IZXxuQ4h.mjs.map → index-B40EWubS.mjs.map} +1 -1
  11. package/dist/_chunks/{index-p25R0AkB.js → index-BxrwA-_0.js} +4 -4
  12. package/dist/_chunks/index-BxrwA-_0.js.map +1 -0
  13. package/dist/_chunks/{index-DiWo3Pu2.js → index-C_J52ViX.js} +2 -5
  14. package/dist/_chunks/{index-DiWo3Pu2.js.map → index-C_J52ViX.js.map} +1 -1
  15. package/dist/_chunks/{index-DJtnx2X1.mjs → index-YTnpzhNo.mjs} +4 -4
  16. package/dist/_chunks/index-YTnpzhNo.mjs.map +1 -0
  17. package/dist/_chunks/{router-C8mPPFJk.js → router-8E0pDcC7.js} +3 -3
  18. package/dist/_chunks/router-8E0pDcC7.js.map +1 -0
  19. package/dist/_chunks/{router-DJCVv74P.mjs → router-BKGmmyPp.mjs} +3 -3
  20. package/dist/_chunks/router-BKGmmyPp.mjs.map +1 -0
  21. package/dist/admin/index.js +1 -1
  22. package/dist/admin/index.mjs +1 -1
  23. package/dist/server/index.js +90 -49
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/index.mjs +90 -49
  26. package/dist/server/index.mjs.map +1 -1
  27. package/dist/server/src/controllers/assignees.d.ts.map +1 -1
  28. package/dist/server/src/controllers/stages.d.ts.map +1 -1
  29. package/dist/server/src/index.d.ts +15 -6
  30. package/dist/server/src/index.d.ts.map +1 -1
  31. package/dist/server/src/register.d.ts.map +1 -1
  32. package/dist/server/src/services/assignees.d.ts +8 -4
  33. package/dist/server/src/services/assignees.d.ts.map +1 -1
  34. package/dist/server/src/services/index.d.ts +15 -6
  35. package/dist/server/src/services/index.d.ts.map +1 -1
  36. package/dist/server/src/services/metrics/index.d.ts +4 -4
  37. package/dist/server/src/services/metrics/index.d.ts.map +1 -1
  38. package/dist/server/src/services/metrics/weekly-metrics.d.ts.map +1 -1
  39. package/dist/server/src/services/stages.d.ts +6 -1
  40. package/dist/server/src/services/stages.d.ts.map +1 -1
  41. package/dist/server/src/services/workflows.d.ts.map +1 -1
  42. package/package.json +11 -11
  43. package/dist/_chunks/_id-Dt2oEiro.mjs.map +0 -1
  44. package/dist/_chunks/_id-PmPKIqUm.js.map +0 -1
  45. package/dist/_chunks/index-DJtnx2X1.mjs.map +0 -1
  46. package/dist/_chunks/index-p25R0AkB.js.map +0 -1
  47. package/dist/_chunks/router-C8mPPFJk.js.map +0 -1
  48. package/dist/_chunks/router-DJCVv74P.mjs.map +0 -1
  49. /package/dist/admin/src/routes/settings/{:id.d.ts → id.d.ts} +0 -0
@@ -6,8 +6,8 @@ import { LinkButton, TFooter, Typography, Flex, IconButton, Dialog } from "@stra
6
6
  import { Plus, Pencil, Trash } from "@strapi/icons";
7
7
  import { useIntl } from "react-intl";
8
8
  import { useNavigate, NavLink, Link } from "react-router-dom";
9
- import { u as useGetContentTypesQuery, a as useTypedSelector, C as CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME, L as LimitsModal } from "./index-IZXxuQ4h.mjs";
10
- import { u as useReviewWorkflows, H as Header, R as Root } from "./Layout-CefL-rfa.mjs";
9
+ import { u as useGetContentTypesQuery, a as useTypedSelector, C as CHARGEBEE_WORKFLOW_ENTITLEMENT_NAME, L as LimitsModal } from "./index-B40EWubS.mjs";
10
+ import { u as useReviewWorkflows, H as Header, R as Root } from "./Layout-BmKilx1K.mjs";
11
11
  const ReviewWorkflowsListView = () => {
12
12
  const { formatMessage } = useIntl();
13
13
  const navigate = useNavigate();
@@ -118,7 +118,7 @@ const ReviewWorkflowsListView = () => {
118
118
  {
119
119
  isLoading,
120
120
  rows: workflows,
121
- footer: canCreate ? /* @__PURE__ */ jsx(TFooter, { icon: /* @__PURE__ */ jsx(Plus, {}), onClick: handleCreateClick, children: formatMessage({
121
+ footer: canCreate ? /* @__PURE__ */ jsx(TFooter, { cursor: "pointer", icon: /* @__PURE__ */ jsx(Plus, {}), onClick: handleCreateClick, children: formatMessage({
122
122
  id: "Settings.review-workflows.list.page.create",
123
123
  defaultMessage: "Create new workflow"
124
124
  }) }) : null,
@@ -211,4 +211,4 @@ export {
211
211
  ProtectedListPage,
212
212
  ReviewWorkflowsListView
213
213
  };
214
- //# sourceMappingURL=index-DJtnx2X1.mjs.map
214
+ //# sourceMappingURL=index-YTnpzhNo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-YTnpzhNo.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 >\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 to={workflow.id.toString()}\n label={formatMessage(\n {\n id: 'Settings.review-workflows.list.page.list.column.actions.edit.label',\n defaultMessage: 'Edit {name}',\n },\n { name: workflow.name }\n )}\n variant=\"ghost\"\n >\n <Pencil />\n </IconButton>\n ) : null}\n {workflows.length > 1 && canDelete ? (\n <IconButton\n withTooltip={false}\n label={formatMessage(\n {\n id: 'Settings.review-workflows.list.page.list.column.actions.delete.label',\n defaultMessage: 'Delete {name}',\n },\n { name: 'Default workflow' }\n )}\n variant=\"ghost\"\n onClick={(e) => {\n e.stopPropagation();\n handleDeleteWorkflow(String(workflow.id));\n }}\n >\n <Trash />\n </IconButton>\n ) : null}\n </Flex>\n </Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table.Content>\n </Table.Root>\n\n <Dialog.Root open={!!workflowToDelete} onOpenChange={toggleConfirmDeleteDialog}>\n <ConfirmDialog onConfirm={handleConfirmDeleteDialog}>\n {formatMessage({\n id: 'Settings.review-workflows.list.page.delete.confirm.body',\n defaultMessage:\n 'If you remove this worfklow, all stage-related information will be removed for this content-type. Are you sure you want to remove it?',\n })}\n </ConfirmDialog>\n </Dialog.Root>\n\n <LimitsModal.Root open={showLimitModal} onOpenChange={() => setShowLimitModal(false)}>\n <LimitsModal.Title>\n {formatMessage({\n id: 'Settings.review-workflows.list.page.workflows.limit.title',\n defaultMessage: 'You’ve reached the limit of workflows in your plan',\n })}\n </LimitsModal.Title>\n\n <LimitsModal.Body>\n {formatMessage({\n id: 'Settings.review-workflows.list.page.workflows.limit.body',\n defaultMessage: 'Delete a workflow or contact Sales to enable more workflows.',\n })}\n </LimitsModal.Body>\n </LimitsModal.Root>\n </Layout.Root>\n </>\n );\n};\n\nconst ProtectedListPage = () => {\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions.settings?.['review-workflows']?.main\n );\n\n return (\n <Page.Protect permissions={permissions}>\n <ReviewWorkflowsListView />\n </Page.Protect>\n );\n};\n\nexport { ProtectedListPage };\n"],"names":["Layout.Header","Layout.Root","contentType"],"mappings":"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"}
@@ -4,10 +4,10 @@ const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
5
  const reactRouterDom = require("react-router-dom");
6
6
  const ProtectedListPage = React.lazy(
7
- () => Promise.resolve().then(() => require("./index-p25R0AkB.js")).then((mod) => ({ default: mod.ProtectedListPage }))
7
+ () => Promise.resolve().then(() => require("./index-BxrwA-_0.js")).then((mod) => ({ default: mod.ProtectedListPage }))
8
8
  );
9
9
  const ProtectedEditPage = React.lazy(
10
- () => Promise.resolve().then(() => require("./_id-PmPKIqUm.js")).then((mod) => ({ default: mod.ProtectedEditPage }))
10
+ () => Promise.resolve().then(() => require("./id-CsSxw398.js")).then((mod) => ({ default: mod.ProtectedEditPage }))
11
11
  );
12
12
  const routes = [
13
13
  {
@@ -21,4 +21,4 @@ const routes = [
21
21
  ];
22
22
  const Router = () => /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Routes, { children: routes.map((route) => /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { ...route }, route.path)) });
23
23
  exports.Router = Router;
24
- //# sourceMappingURL=router-C8mPPFJk.js.map
24
+ //# sourceMappingURL=router-8E0pDcC7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-8E0pDcC7.js","sources":["../../admin/src/router.tsx"],"sourcesContent":["/* eslint-disable check-file/filename-naming-convention */\nimport { lazy } from 'react';\n\nimport { Routes, Route, PathRouteProps } from 'react-router-dom';\n\nconst ProtectedListPage = lazy(() =>\n import('./routes/settings').then((mod) => ({ default: mod.ProtectedListPage }))\n);\nconst ProtectedEditPage = lazy(() =>\n import('./routes/settings/id').then((mod) => ({ default: mod.ProtectedEditPage }))\n);\n\nconst routes: PathRouteProps[] = [\n {\n path: '/',\n Component: ProtectedListPage,\n },\n {\n path: ':id',\n Component: ProtectedEditPage,\n },\n];\n\nconst Router = () => (\n <Routes>\n {routes.map((route) => (\n <Route key={route.path} {...route} />\n ))}\n </Routes>\n);\n\nexport { Router };\n"],"names":["lazy","jsx","Routes","Route"],"mappings":";;;;;AAKA,MAAM,oBAAoBA,MAAA;AAAA,EAAK,MAC7B,QAAO,QAAA,EAAA,KAAA,MAAA,QAAA,qBAAmB,GAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,kBAAA,EAAoB;AAChF;AACA,MAAM,oBAAoBA,MAAA;AAAA,EAAK,MAC7B,QAAO,QAAA,EAAA,KAAA,MAAA,QAAA,kBAAsB,GAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,kBAAA,EAAoB;AACnF;AAEA,MAAM,SAA2B;AAAA,EAC/B;AAAA,IACE,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AACF;AAEA,MAAM,SAAS,MACZC,2BAAAA,IAAAC,eAAAA,QAAA,EACE,iBAAO,IAAI,CAAC,UACXD,2BAAA,IAACE,wBAAwB,GAAG,MAAA,GAAhB,MAAM,IAAiB,CACpC,EACH,CAAA;;"}
@@ -2,10 +2,10 @@ import { jsx } from "react/jsx-runtime";
2
2
  import { lazy } from "react";
3
3
  import { Routes, Route } from "react-router-dom";
4
4
  const ProtectedListPage = lazy(
5
- () => import("./index-DJtnx2X1.mjs").then((mod) => ({ default: mod.ProtectedListPage }))
5
+ () => import("./index-YTnpzhNo.mjs").then((mod) => ({ default: mod.ProtectedListPage }))
6
6
  );
7
7
  const ProtectedEditPage = lazy(
8
- () => import("./_id-Dt2oEiro.mjs").then((mod) => ({ default: mod.ProtectedEditPage }))
8
+ () => import("./id-DEppSbOE.mjs").then((mod) => ({ default: mod.ProtectedEditPage }))
9
9
  );
10
10
  const routes = [
11
11
  {
@@ -21,4 +21,4 @@ const Router = () => /* @__PURE__ */ jsx(Routes, { children: routes.map((route)
21
21
  export {
22
22
  Router
23
23
  };
24
- //# sourceMappingURL=router-DJCVv74P.mjs.map
24
+ //# sourceMappingURL=router-BKGmmyPp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-BKGmmyPp.mjs","sources":["../../admin/src/router.tsx"],"sourcesContent":["/* eslint-disable check-file/filename-naming-convention */\nimport { lazy } from 'react';\n\nimport { Routes, Route, PathRouteProps } from 'react-router-dom';\n\nconst ProtectedListPage = lazy(() =>\n import('./routes/settings').then((mod) => ({ default: mod.ProtectedListPage }))\n);\nconst ProtectedEditPage = lazy(() =>\n import('./routes/settings/id').then((mod) => ({ default: mod.ProtectedEditPage }))\n);\n\nconst routes: PathRouteProps[] = [\n {\n path: '/',\n Component: ProtectedListPage,\n },\n {\n path: ':id',\n Component: ProtectedEditPage,\n },\n];\n\nconst Router = () => (\n <Routes>\n {routes.map((route) => (\n <Route key={route.path} {...route} />\n ))}\n </Routes>\n);\n\nexport { Router };\n"],"names":[],"mappings":";;;AAKA,MAAM,oBAAoB;AAAA,EAAK,MAC7B,OAAO,sBAAmB,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,kBAAA,EAAoB;AAChF;AACA,MAAM,oBAAoB;AAAA,EAAK,MAC7B,OAAO,mBAAsB,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,kBAAA,EAAoB;AACnF;AAEA,MAAM,SAA2B;AAAA,EAC/B;AAAA,IACE,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AACF;AAEA,MAAM,SAAS,MACZ,oBAAA,QAAA,EACE,iBAAO,IAAI,CAAC,UACX,oBAAC,SAAwB,GAAG,MAAA,GAAhB,MAAM,IAAiB,CACpC,EACH,CAAA;"}
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-DiWo3Pu2.js");
2
+ const index = require("../_chunks/index-C_J52ViX.js");
3
3
  module.exports = index.admin;
4
4
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { h } from "../_chunks/index-IZXxuQ4h.mjs";
1
+ import { h } from "../_chunks/index-B40EWubS.mjs";
2
2
  export {
3
3
  h as default
4
4
  };
@@ -6563,8 +6563,40 @@ function extendReviewWorkflowContentTypes({ strapi: strapi2 }) {
6563
6563
  });
6564
6564
  }
6565
6565
  }
6566
+ function persistRWOnDowngrade({ strapi: strapi2 }) {
6567
+ const { removePersistedTablesWithSuffix, persistTables } = getAdminService("persist-tables");
6568
+ return async ({ contentTypes: contentTypes2 }) => {
6569
+ const getStageTableToPersist = (contentTypeUID) => {
6570
+ const { attributes, tableName } = strapi2.db.metadata.get(contentTypeUID);
6571
+ const joinTableName = attributes[ENTITY_STAGE_ATTRIBUTE].joinTable.name;
6572
+ return {
6573
+ name: joinTableName,
6574
+ dependsOn: [{ name: tableName }]
6575
+ };
6576
+ };
6577
+ const getAssigneeTableToPersist = (contentTypeUID) => {
6578
+ const { attributes, tableName } = strapi2.db.metadata.get(contentTypeUID);
6579
+ const joinTableName = attributes[ENTITY_ASSIGNEE_ATTRIBUTE].joinTable.name;
6580
+ return {
6581
+ name: joinTableName,
6582
+ dependsOn: [{ name: tableName }]
6583
+ };
6584
+ };
6585
+ const enabledRWContentTypes = fp.pipe([
6586
+ getVisibleContentTypesUID,
6587
+ fp.filter((uid) => hasStageAttribute(contentTypes2[uid]))
6588
+ ])(contentTypes2);
6589
+ const stageJoinTablesToPersist = enabledRWContentTypes.map(getStageTableToPersist);
6590
+ await removePersistedTablesWithSuffix("_strapi_stage_lnk");
6591
+ await persistTables(stageJoinTablesToPersist);
6592
+ const assigneeJoinTablesToPersist = enabledRWContentTypes.map(getAssigneeTableToPersist);
6593
+ await removePersistedTablesWithSuffix("_strapi_assignee_lnk");
6594
+ await persistTables(assigneeJoinTablesToPersist);
6595
+ };
6596
+ }
6566
6597
  const register = async ({ strapi: strapi2 }) => {
6567
6598
  strapi2.hook("strapi::content-types.beforeSync").register(migrateStageAttribute);
6599
+ strapi2.hook("strapi::content-types.afterSync").register(persistRWOnDowngrade({ strapi: strapi2 }));
6568
6600
  strapi2.hook("strapi::content-types.afterSync").register(migrateReviewWorkflowStagesColor).register(migrateReviewWorkflowStagesRoles).register(migrateReviewWorkflowName).register(migrateWorkflowsContentTypes).register(migrateDeletedCTInWorkflows);
6569
6601
  reviewWorkflowsMiddlewares.contentTypeMiddleware(strapi2);
6570
6602
  extendReviewWorkflowContentTypes({ strapi: strapi2 });
@@ -7065,8 +7097,12 @@ const workflows$1 = ({ strapi: strapi2 }) => {
7065
7097
  stageId: stages2[0].id
7066
7098
  });
7067
7099
  }
7068
- metrics.sendDidCreateWorkflow();
7069
- return strapi2.db.query(WORKFLOW_MODEL_UID).create(strapi2.get("query-params").transform(WORKFLOW_MODEL_UID, createOpts));
7100
+ const createdWorkflow = await strapi2.db.query(WORKFLOW_MODEL_UID).create(strapi2.get("query-params").transform(WORKFLOW_MODEL_UID, createOpts));
7101
+ metrics.sendDidCreateWorkflow(createdWorkflow.id, !!opts.data.stageRequiredToPublishName);
7102
+ if (opts.data.stageRequiredToPublishName) {
7103
+ await strapi2.plugin("content-releases").service("release-action").validateActionsByContentTypes(opts.data.contentTypes);
7104
+ }
7105
+ return createdWorkflow;
7070
7106
  });
7071
7107
  },
7072
7108
  /**
@@ -7117,12 +7153,17 @@ const workflows$1 = ({ strapi: strapi2 }) => {
7117
7153
  stageId: updatedStageIds ? updatedStageIds[0] : workflow2.stages[0].id
7118
7154
  });
7119
7155
  }
7120
- metrics.sendDidEditWorkflow();
7156
+ metrics.sendDidEditWorkflow(workflow2.id, !!opts.data.stageRequiredToPublishName);
7121
7157
  const query = strapi2.get("query-params").transform(WORKFLOW_MODEL_UID, updateOpts);
7122
- return strapi2.db.query(WORKFLOW_MODEL_UID).update({
7158
+ const updatedWorkflow = await strapi2.db.query(WORKFLOW_MODEL_UID).update({
7123
7159
  ...query,
7124
7160
  where: { id: workflow2.id }
7125
7161
  });
7162
+ await strapi2.plugin("content-releases").service("release-action").validateActionsByContentTypes([
7163
+ ...workflow2.contentTypes,
7164
+ ...opts.data.contentTypes || []
7165
+ ]);
7166
+ return updatedWorkflow;
7126
7167
  });
7127
7168
  },
7128
7169
  /**
@@ -7145,10 +7186,12 @@ const workflows$1 = ({ strapi: strapi2 }) => {
7145
7186
  destContentTypes: []
7146
7187
  });
7147
7188
  const query = strapi2.get("query-params").transform(WORKFLOW_MODEL_UID, opts);
7148
- return strapi2.db.query(WORKFLOW_MODEL_UID).delete({
7189
+ const deletedWorkflow = await strapi2.db.query(WORKFLOW_MODEL_UID).delete({
7149
7190
  ...query,
7150
7191
  where: { id: workflow2.id }
7151
7192
  });
7193
+ await strapi2.plugin("content-releases").service("release-action").validateActionsByContentTypes(workflow2.contentTypes);
7194
+ return deletedWorkflow;
7152
7195
  });
7153
7196
  },
7154
7197
  /**
@@ -7360,8 +7403,9 @@ const stages$1 = ({ strapi: strapi2 }) => {
7360
7403
  /**
7361
7404
  * Update the stage of an entity
7362
7405
  */
7363
- async updateEntity(documentId, locale, model, stageId) {
7406
+ async updateEntity(entityToUpdate, model, stageId) {
7364
7407
  const stage = await this.findById(stageId);
7408
+ const { documentId, locale } = entityToUpdate;
7365
7409
  await workflowValidator.validateWorkflowCount();
7366
7410
  if (!stage) {
7367
7411
  throw new ApplicationError$2(`Selected stage does not exist`);
@@ -7369,9 +7413,15 @@ const stages$1 = ({ strapi: strapi2 }) => {
7369
7413
  const entity = await strapi2.documents(model).update({
7370
7414
  documentId,
7371
7415
  locale,
7372
- data: { [ENTITY_STAGE_ATTRIBUTE]: stage },
7416
+ // Stage doesn't have DP or i18n enabled, connecting it through the `id`
7417
+ // will be safer than relying on the `documentId` + `locale` + `status` transformation
7418
+ data: { [ENTITY_STAGE_ATTRIBUTE]: fp.pick(["id"], stage) },
7373
7419
  populate: [ENTITY_STAGE_ATTRIBUTE]
7374
7420
  });
7421
+ const { tableName } = strapi2.db.metadata.get(model);
7422
+ await strapi2.db.connection(tableName).where({ id: entityToUpdate.id }).update({
7423
+ updated_at: new Date(entityToUpdate.updatedAt)
7424
+ });
7375
7425
  metrics.sendDidChangeEntryStage();
7376
7426
  return entity;
7377
7427
  },
@@ -7518,32 +7568,28 @@ const assignees$1 = ({ strapi: strapi2 }) => {
7518
7568
  /**
7519
7569
  * Update the assignee of an entity
7520
7570
  */
7521
- async updateEntityAssignee(documentId, locale, model, assigneeId) {
7522
- if (fp.isNil(assigneeId)) {
7523
- return this.deleteEntityAssignee(documentId, locale, model);
7524
- }
7525
- const userExists = await getAdminService("user", { strapi: strapi2 }).exists({ id: assigneeId });
7526
- if (!userExists) {
7527
- throw new ApplicationError(`Selected user does not exist`);
7571
+ async updateEntityAssignee(entityToUpdate, model, assigneeId) {
7572
+ const { documentId, locale } = entityToUpdate;
7573
+ if (!fp.isNil(assigneeId)) {
7574
+ const userExists = await getAdminService("user", { strapi: strapi2 }).exists({ id: assigneeId });
7575
+ if (!userExists) {
7576
+ throw new ApplicationError(`Selected user does not exist`);
7577
+ }
7528
7578
  }
7529
- metrics.sendDidEditAssignee(await this.findEntityAssigneeId(documentId, model), assigneeId);
7530
- return strapi2.documents(model).update({
7579
+ const oldAssigneeId = await this.findEntityAssigneeId(entityToUpdate.id, model);
7580
+ metrics.sendDidEditAssignee(oldAssigneeId, assigneeId || null);
7581
+ const entity = await strapi2.documents(model).update({
7531
7582
  documentId,
7532
7583
  locale,
7533
- data: { [ENTITY_ASSIGNEE_ATTRIBUTE]: assigneeId },
7584
+ data: { [ENTITY_ASSIGNEE_ATTRIBUTE]: assigneeId || null },
7534
7585
  populate: [ENTITY_ASSIGNEE_ATTRIBUTE],
7535
7586
  fields: []
7536
7587
  });
7537
- },
7538
- async deleteEntityAssignee(documentId, locale, model) {
7539
- metrics.sendDidEditAssignee(await this.findEntityAssigneeId(documentId, model), null);
7540
- return strapi2.documents(model).update({
7541
- documentId,
7542
- locale,
7543
- data: { [ENTITY_ASSIGNEE_ATTRIBUTE]: null },
7544
- populate: [ENTITY_ASSIGNEE_ATTRIBUTE],
7545
- fields: []
7588
+ const { tableName } = strapi2.db.metadata.get(model);
7589
+ await strapi2.db.connection(tableName).where({ id: entityToUpdate.id }).update({
7590
+ updated_at: new Date(entityToUpdate.updatedAt)
7546
7591
  });
7592
+ return entity;
7547
7593
  }
7548
7594
  };
7549
7595
  };
@@ -7616,11 +7662,11 @@ const sendDidDeleteStage = async () => {
7616
7662
  const sendDidChangeEntryStage = async () => {
7617
7663
  strapi.telemetry.send("didChangeEntryStage", {});
7618
7664
  };
7619
- const sendDidCreateWorkflow = async () => {
7620
- strapi.telemetry.send("didCreateWorkflow", {});
7665
+ const sendDidCreateWorkflow = async (workflowId, hasRequiredStageToPublish) => {
7666
+ strapi.telemetry.send("didCreateWorkflow", { workflowId, hasRequiredStageToPublish });
7621
7667
  };
7622
- const sendDidEditWorkflow = async () => {
7623
- strapi.telemetry.send("didEditWorkflow", {});
7668
+ const sendDidEditWorkflow = async (workflowId, hasRequiredStageToPublish) => {
7669
+ strapi.telemetry.send("didEditWorkflow", { workflowId, hasRequiredStageToPublish });
7624
7670
  };
7625
7671
  const sendDidEditAssignee = async (fromId, toId) => {
7626
7672
  strapi.telemetry.send("didEditAssignee", { from: fromId, to: toId });
@@ -7645,13 +7691,13 @@ const reviewWorkflowsMetrics = {
7645
7691
  sendDidSendReviewWorkflowPropertiesOnceAWeek,
7646
7692
  sendDidEditAssignee
7647
7693
  };
7648
- function _typeof(obj) {
7694
+ function _typeof(o) {
7649
7695
  "@babel/helpers - typeof";
7650
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj2) {
7651
- return typeof obj2;
7652
- } : function(obj2) {
7653
- return obj2 && "function" == typeof Symbol && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
7654
- }, _typeof(obj);
7696
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o2) {
7697
+ return typeof o2;
7698
+ } : function(o2) {
7699
+ return o2 && "function" == typeof Symbol && o2.constructor === Symbol && o2 !== Symbol.prototype ? "symbol" : typeof o2;
7700
+ }, _typeof(o);
7655
7701
  }
7656
7702
  function toInteger(dirtyNumber) {
7657
7703
  if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
@@ -7786,7 +7832,12 @@ const reviewWorkflowsWeeklyMetrics = ({ strapi: strapi2 }) => {
7786
7832
  },
7787
7833
  async registerCron() {
7788
7834
  const weeklySchedule = await this.ensureWeeklyStoredCronSchedule();
7789
- strapi2.cron.add({ [weeklySchedule]: this.sendMetrics.bind(this) });
7835
+ strapi2.cron.add({
7836
+ reviewWorkflowsWeekly: {
7837
+ task: this.sendMetrics.bind(this),
7838
+ options: weeklySchedule
7839
+ }
7840
+ });
7790
7841
  }
7791
7842
  };
7792
7843
  };
@@ -8148,12 +8199,7 @@ const stages = {
8148
8199
  );
8149
8200
  const workflow2 = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);
8150
8201
  workflowService.assertStageBelongsToWorkflow(stageId, workflow2);
8151
- const updatedEntity = await stagesService.updateEntity(
8152
- entity.documentId,
8153
- entity.locale,
8154
- modelUID,
8155
- stageId
8156
- );
8202
+ const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);
8157
8203
  ctx.body = { data: await sanitizeOutput(updatedEntity) };
8158
8204
  },
8159
8205
  /**
@@ -8250,12 +8296,7 @@ const assignees = {
8250
8296
  "You should pass a valid id to the body of the put request."
8251
8297
  );
8252
8298
  await workflowService.assertContentTypeBelongsToWorkflow(model);
8253
- const updatedEntity = await assigneeService.updateEntityAssignee(
8254
- documentId,
8255
- locale || null,
8256
- model,
8257
- assigneeId
8258
- );
8299
+ const updatedEntity = await assigneeService.updateEntityAssignee(entity, model, assigneeId);
8259
8300
  ctx.body = { data: await sanitizeOutput(updatedEntity) };
8260
8301
  }
8261
8302
  };