@strapi/admin 4.11.4 → 4.12.0-beta.1

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 (213) hide show
  1. package/admin/src/constants.js +83 -83
  2. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +8 -5
  3. package/admin/src/content-manager/components/Inputs/index.js +3 -47
  4. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +34 -37
  5. package/admin/src/content-manager/pages/EditSettingsView/components/ModalForm.js +0 -27
  6. package/admin/src/content-manager/pages/EditView/Information/index.js +1 -1
  7. package/admin/src/content-manager/pages/EditView/InformationBox/InformationBoxCE.js +1 -2
  8. package/admin/src/content-manager/pages/EditView/InformationBox/index.js +1 -3
  9. package/admin/src/content-manager/pages/EditView/index.js +14 -2
  10. package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +93 -14
  11. package/admin/src/content-manager/pages/ListView/index.js +65 -59
  12. package/admin/src/content-manager/pages/ListView/utils/buildValidGetParams.js +30 -0
  13. package/admin/src/content-manager/pages/ListView/utils/index.js +1 -1
  14. package/admin/src/content-manager/utils/mergeMetasWithSchema.js +5 -1
  15. package/admin/src/hooks/index.js +0 -1
  16. package/admin/src/hooks/useAdminUsers/useAdminUsers.js +3 -3
  17. package/admin/src/hooks/useEnterprise/useEnterprise.js +4 -4
  18. package/admin/src/hooks/useSettingsMenu/index.js +35 -21
  19. package/admin/src/pages/App/index.js +28 -23
  20. package/admin/src/pages/AuthPage/components/Login/index.js +3 -5
  21. package/admin/src/pages/AuthPage/components/Register/index.js +5 -1
  22. package/admin/src/pages/AuthPage/constants.js +3 -2
  23. package/admin/src/pages/AuthPage/index.js +18 -1
  24. package/admin/src/pages/HomePage/index.js +19 -7
  25. package/admin/src/pages/ProfilePage/index.js +12 -12
  26. package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +13 -11
  27. package/admin/src/pages/SettingsPage/components/Tokens/TokenBox/index.js +1 -1
  28. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +17 -1
  29. package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +16 -3
  30. package/admin/src/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +2 -4
  31. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +15 -1
  32. package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +36 -5
  33. package/admin/src/pages/SettingsPage/pages/Users/components/MagicLink/index.js +3 -5
  34. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +1 -3
  35. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +16 -1
  36. package/admin/src/translations/zh-Hans.json +1 -1
  37. package/build/0cd5f8915b265d5b1856.png +0 -0
  38. package/build/1049.758a01f5.chunk.js +1 -0
  39. package/build/{3528.4845cf92.chunk.js → 1386.762d6eb8.chunk.js} +1 -1
  40. package/build/1727.b49f0713.chunk.js +1 -0
  41. package/build/190.66d89241.chunk.js +117 -0
  42. package/build/{5563.86f9aa9c.chunk.js → 2225.15d1df72.chunk.js} +3 -3
  43. package/build/2379.d33a2e16.chunk.js +1 -0
  44. package/build/2395.b0419a54.chunk.js +26 -0
  45. package/build/2801.18ac397d.chunk.js +1 -0
  46. package/build/{7394.423886bd.chunk.js → 3100.21c343fa.chunk.js} +1 -1
  47. package/build/311.cb0884bb.chunk.js +1 -0
  48. package/build/3483.e182b190.chunk.js +1 -0
  49. package/build/3984.ea7b8036.chunk.js +1 -0
  50. package/build/4546.ff9fdf30.chunk.js +1 -0
  51. package/build/502.ccb38223.chunk.js +1 -0
  52. package/build/5483.ed2c7efa.chunk.js +6 -0
  53. package/build/{5542.c62d0daf.chunk.js → 5542.2415a393.chunk.js} +6 -6
  54. package/build/6158.f9d82db9.chunk.js +1 -0
  55. package/build/7030.b98dcedf.chunk.js +1 -0
  56. package/build/7464.c6d0565c.chunk.js +1 -0
  57. package/build/8276.23e0763b.chunk.js +26 -0
  58. package/build/918.54414509.chunk.js +1 -0
  59. package/build/{9932.7e2b71de.chunk.js → 9932.b5a3bb3a.chunk.js} +81 -81
  60. package/build/9944.7af075a5.chunk.js +26 -0
  61. package/build/{Admin-authenticatedApp.cb649fc1.chunk.js → Admin-authenticatedApp.2ffa318a.chunk.js} +5 -5
  62. package/build/Admin_InternalErrorPage.f45f2462.chunk.js +1 -0
  63. package/build/{Admin_homePage.be30ef4e.chunk.js → Admin_homePage.ac9dfb86.chunk.js} +23 -15
  64. package/build/{Admin_marketplace.74a58e20.chunk.js → Admin_marketplace.f0b87fce.chunk.js} +1 -1
  65. package/build/{Admin_pluginsPage.ce464189.chunk.js → Admin_pluginsPage.8728ff6e.chunk.js} +1 -1
  66. package/build/{Admin_profilePage.2131eb68.chunk.js → Admin_profilePage.a968035f.chunk.js} +2 -2
  67. package/build/Admin_settingsPage.3ad19487.chunk.js +79 -0
  68. package/build/Upload_ConfigureTheView.345ac1e0.chunk.js +1 -0
  69. package/build/admin-app.088bcd33.chunk.js +36 -0
  70. package/build/{admin-edit-roles-page.3fdd6b9d.chunk.js → admin-edit-roles-page.a49b9f4f.chunk.js} +4 -4
  71. package/build/admin-edit-users.67704088.chunk.js +10 -0
  72. package/build/{admin-roles-list.e17b00d7.chunk.js → admin-roles-list.0c129e98.chunk.js} +1 -1
  73. package/build/admin-users.3279ffb0.chunk.js +11 -0
  74. package/build/api-tokens-create-page.46c2ea84.chunk.js +1 -0
  75. package/build/{api-tokens-edit-page.9a1dd2fa.chunk.js → api-tokens-edit-page.58139df9.chunk.js} +1 -1
  76. package/build/{api-tokens-list-page.a103f526.chunk.js → api-tokens-list-page.505bf7e0.chunk.js} +2 -2
  77. package/build/audit-logs-settings-page.4b422831.chunk.js +1 -0
  78. package/build/content-manager.9b569036.chunk.js +1094 -0
  79. package/build/{content-type-builder-list-view.a200a358.chunk.js → content-type-builder-list-view.bf9be456.chunk.js} +9 -9
  80. package/build/content-type-builder-translation-en-json.38e20391.chunk.js +1 -0
  81. package/build/{content-type-builder-translation-zh-json.ad24dbeb.chunk.js → content-type-builder-translation-zh-json.958d90e1.chunk.js} +1 -1
  82. package/build/content-type-builder.3963fb2d.chunk.js +166 -0
  83. package/build/{email-settings-page.45695daa.chunk.js → email-settings-page.d494d1eb.chunk.js} +2 -2
  84. package/build/{i18n-settings-page.29308d0b.chunk.js → i18n-settings-page.47f78016.chunk.js} +1 -1
  85. package/build/index.html +1 -1
  86. package/build/main.98c989b0.js +2908 -0
  87. package/build/review-workflows-settings-create-view.60bc516c.chunk.js +1 -0
  88. package/build/review-workflows-settings-edit-view.898ea409.chunk.js +1 -0
  89. package/build/review-workflows-settings-list-view.240cacdf.chunk.js +56 -0
  90. package/build/runtime~main.44bf2a37.js +2 -0
  91. package/build/sso-settings-page.ed6f3f15.chunk.js +1 -0
  92. package/build/transfer-tokens-create-page.1597e6ab.chunk.js +1 -0
  93. package/build/transfer-tokens-edit-page.8741529f.chunk.js +1 -0
  94. package/build/{transfer-tokens-list-page.7237443d.chunk.js → transfer-tokens-list-page.22147d2c.chunk.js} +2 -2
  95. package/build/upload-settings.cac210a0.chunk.js +14 -0
  96. package/build/upload.8d01c525.chunk.js +26 -0
  97. package/build/{users-advanced-settings-page.750b1f76.chunk.js → users-advanced-settings-page.18379a56.chunk.js} +1 -1
  98. package/build/users-email-settings-page.a87978e5.chunk.js +9 -0
  99. package/build/users-providers-settings-page.8876c1ee.chunk.js +14 -0
  100. package/build/{users-roles-settings-page.1f505119.chunk.js → users-roles-settings-page.0431f48c.chunk.js} +2 -2
  101. package/build/webhook-edit-page.a91f27a1.chunk.js +33 -0
  102. package/build/{webhook-list-page.940a40f1.chunk.js → webhook-list-page.65e1b5bb.chunk.js} +1 -1
  103. package/build/{zh-Hans-json.4cfef87d.chunk.js → zh-Hans-json.fada6f40.chunk.js} +1 -1
  104. package/ee/admin/constants.js +14 -14
  105. package/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js +88 -31
  106. package/ee/admin/content-manager/pages/EditView/InformationBox/index.js +1 -3
  107. package/ee/admin/content-manager/{components/DynamicTable/CellContent/ReviewWorkflowsStage → pages/ListView/ReviewWorkflowsColumn}/ReviewWorkflowsStageEE.js +7 -2
  108. package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/constants.js +24 -0
  109. package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/index.js +1 -0
  110. package/ee/admin/hooks/useLicenseLimitNotification/index.js +17 -6
  111. package/ee/admin/hooks/useLicenseLimits/index.js +1 -32
  112. package/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js +44 -0
  113. package/ee/admin/pages/AuthPage/components/Login/index.js +3 -5
  114. package/ee/admin/pages/HomePage/index.js +11 -0
  115. package/ee/admin/pages/SettingsPage/constants.js +25 -1
  116. package/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +7 -7
  117. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +6 -4
  118. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/actions/index.js +19 -4
  119. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Layout/Layout.js +65 -0
  120. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Layout/index.js +1 -0
  121. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal/LimitsModal.js +111 -0
  122. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal/assets/balloon.png +0 -0
  123. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal/index.js +3 -0
  124. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/ProtectedPage.js +21 -0
  125. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/index.js +1 -0
  126. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js +5 -5
  127. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js +110 -0
  128. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/index.js +1 -0
  129. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/constants.js +3 -1
  130. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +13 -19
  131. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js +246 -0
  132. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js +13 -0
  133. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js +287 -0
  134. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js +13 -0
  135. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js +382 -0
  136. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js +13 -0
  137. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/reducer/index.js +53 -23
  138. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/utils/getWorkflowValidationSchema.js +43 -28
  139. package/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +11 -6
  140. package/ee/admin/pages/SettingsPage/pages/Users/ListPage/index.js +13 -0
  141. package/ee/admin/pages/SettingsPage/pages/Users/components/MagicLink/index.js +3 -5
  142. package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +1 -3
  143. package/ee/server/config/admin-actions.js +24 -0
  144. package/ee/server/constants/default-stages.json +8 -4
  145. package/ee/server/constants/default-workflow.json +3 -1
  146. package/ee/server/constants/workflows.js +10 -1
  147. package/ee/server/content-types/workflow/index.js +10 -0
  148. package/ee/server/content-types/workflow-stage/index.js +3 -1
  149. package/ee/server/controllers/admin.js +1 -0
  150. package/ee/server/controllers/workflows/index.js +135 -8
  151. package/ee/server/controllers/workflows/stages/index.js +38 -38
  152. package/ee/server/migrations/review-workflows-content-types.js +29 -0
  153. package/ee/server/migrations/review-workflows-deleted-ct-in-workflows.js +39 -0
  154. package/ee/server/migrations/review-workflows-stage-attribute.js +49 -0
  155. package/ee/server/migrations/review-workflows-stages-color.js +2 -2
  156. package/ee/server/migrations/review-workflows-workflow-name.js +21 -0
  157. package/ee/server/register.js +12 -2
  158. package/ee/server/routes/review-workflows.js +44 -10
  159. package/ee/server/services/index.js +1 -0
  160. package/ee/server/services/review-workflows/entity-service-decorator.js +8 -13
  161. package/ee/server/services/review-workflows/review-workflows.js +45 -53
  162. package/ee/server/services/review-workflows/stages.js +84 -46
  163. package/ee/server/services/review-workflows/validation.js +60 -0
  164. package/ee/server/services/review-workflows/workflows/content-types.js +80 -0
  165. package/ee/server/services/review-workflows/workflows/index.js +207 -0
  166. package/ee/server/utils/review-workflows.js +30 -25
  167. package/ee/server/validation/review-workflows.js +49 -10
  168. package/index.js +0 -14
  169. package/package.json +12 -21
  170. package/webpack.alias.js +0 -3
  171. package/webpack.config.js +1 -75
  172. package/admin/src/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -2
  173. package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +0 -36
  174. package/admin/src/content-manager/pages/ListView/utils/createPluginsFilter.js +0 -4
  175. package/admin/src/hooks/useLicenseLimits/index.js +0 -3
  176. package/admin/src/pages/App/utils/index.js +0 -3
  177. package/admin/src/pages/App/utils/unique-identifier.js +0 -12
  178. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +0 -5
  179. package/build/1386.3b2aa6a7.chunk.js +0 -3
  180. package/build/1799.44d2e264.chunk.js +0 -33
  181. package/build/1970.39a2d75e.chunk.js +0 -1
  182. package/build/3269.1ea0f5a6.chunk.js +0 -1
  183. package/build/5932.6a23b88c.chunk.js +0 -1
  184. package/build/7018.98feed67.chunk.js +0 -1
  185. package/build/7259.fb69d4bf.chunk.js +0 -1
  186. package/build/Admin_InternalErrorPage.8911cb49.chunk.js +0 -1
  187. package/build/Admin_settingsPage.4069bb8a.chunk.js +0 -79
  188. package/build/Upload_ConfigureTheView.7a1cb9c9.chunk.js +0 -1
  189. package/build/admin-app.fea867af.chunk.js +0 -61
  190. package/build/admin-edit-users.200551e3.chunk.js +0 -10
  191. package/build/admin-users.3b12dca2.chunk.js +0 -11
  192. package/build/api-tokens-create-page.3dd4e921.chunk.js +0 -1
  193. package/build/audit-logs-settings-page.f538490f.chunk.js +0 -1
  194. package/build/content-manager.c40f5ff9.chunk.js +0 -1088
  195. package/build/content-type-builder-translation-en-json.f592325b.chunk.js +0 -1
  196. package/build/content-type-builder.bd1bbff1.chunk.js +0 -166
  197. package/build/main.ee36abd9.js +0 -2927
  198. package/build/review-workflows-settings.93808ae0.chunk.js +0 -110
  199. package/build/runtime~main.efd966f6.js +0 -2
  200. package/build/sso-settings-page.0cdb96a6.chunk.js +0 -1
  201. package/build/transfer-tokens-create-page.de14cad4.chunk.js +0 -1
  202. package/build/transfer-tokens-edit-page.4f5e39af.chunk.js +0 -1
  203. package/build/upload-settings.cb6c14c3.chunk.js +0 -14
  204. package/build/upload.7e629643.chunk.js +0 -26
  205. package/build/users-email-settings-page.e9bcd865.chunk.js +0 -9
  206. package/build/users-providers-settings-page.a94253e9.chunk.js +0 -14
  207. package/build/webhook-edit-page.77ef4f1a.chunk.js +0 -33
  208. package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -58
  209. package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/index.js +0 -3
  210. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ProtectedPage.js +0 -20
  211. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js +0 -204
  212. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/index.js +0 -3
  213. package/ee/server/services/review-workflows/workflows.js +0 -25
@@ -10,17 +10,19 @@ import {
10
10
  import { useIntl } from 'react-intl';
11
11
  import { useMutation } from 'react-query';
12
12
 
13
- import Information from '../../../../../../admin/src/content-manager/pages/EditView/Information';
13
+ import { Information } from '../../../../../../admin/src/content-manager/pages/EditView/Information';
14
+ import useLicenseLimits from '../../../../hooks/useLicenseLimits';
15
+ import * as LimitsModal from '../../../../pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal';
14
16
  import { useReviewWorkflows } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows';
15
17
  import { getStageColorByHex } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/utils/colors';
16
18
 
17
- const ATTRIBUTE_NAME = 'strapi_reviewWorkflows_stage';
19
+ const ATTRIBUTE_NAME = 'strapi_stage';
18
20
 
19
21
  export function InformationBoxEE() {
20
22
  const {
21
23
  initialData,
22
24
  isCreatingEntry,
23
- layout: { uid },
25
+ layout: { uid, options },
24
26
  isSingleType,
25
27
  onChange,
26
28
  } = useCMEditViewDataManager();
@@ -29,17 +31,18 @@ export function InformationBoxEE() {
29
31
  // be updated at the same time when modifiedData is updated, otherwise
30
32
  // the entity is flagged as modified
31
33
  const activeWorkflowStage = initialData?.[ATTRIBUTE_NAME] ?? null;
32
- const hasReviewWorkflowsEnabled = Object.prototype.hasOwnProperty.call(
33
- initialData,
34
- ATTRIBUTE_NAME
35
- );
34
+ const hasReviewWorkflowsEnabled = options?.reviewWorkflows ?? false;
36
35
  const { formatMessage } = useIntl();
37
36
  const { formatAPIError } = useAPIErrorHandler();
38
37
  const toggleNotification = useNotification();
38
+ const { getFeature } = useLicenseLimits();
39
+ const [showLimitModal, setShowLimitModal] = React.useState(false);
39
40
 
40
- const { workflows, isLoading: workflowIsLoading } = useReviewWorkflows();
41
- // TODO: this works only as long as we support one workflow
42
- const workflow = workflows?.[0] ?? null;
41
+ const {
42
+ meta,
43
+ workflows: [workflow],
44
+ isLoading: isWorkflowLoading,
45
+ } = useReviewWorkflows({ filters: { contentTypes: uid } });
43
46
 
44
47
  const { error, isLoading, mutateAsync } = useMutation(
45
48
  async ({ entityId, stageId, uid }) => {
@@ -70,29 +73,45 @@ export function InformationBoxEE() {
70
73
  }
71
74
  );
72
75
 
73
- // if entities are created e.g. through lifecycle methods
74
- // they may not have a stage assigned. Updating the entity won't
75
- // set the default stage either which may lead to entities that
76
- // do not have a stage assigned for a while. By displaying an
77
- // error by default we are trying to nudge users into assigning a stage.
78
- const initialStageNullError =
79
- activeWorkflowStage === null &&
80
- !workflowIsLoading &&
81
- !isCreatingEntry &&
82
- formatMessage({
83
- id: 'content-manager.reviewWorkflows.stage.select.placeholder',
84
- defaultMessage: 'Select a stage',
85
- });
86
- const formattedMutationError = error && formatAPIError(error);
87
- const formattedError = formattedMutationError || initialStageNullError || null;
76
+ const limits = getFeature('review-workflows');
77
+ const formattedError = (error && formatAPIError(error)) || null;
88
78
 
89
79
  const handleStageChange = async ({ value: stageId }) => {
90
80
  try {
91
- await mutateAsync({
92
- entityId: initialData.id,
93
- stageId,
94
- uid,
95
- });
81
+ /**
82
+ * If the current license has a limit:
83
+ * check if the total count of workflows exceeds that limit and display
84
+ * the limits modal.
85
+ *
86
+ * If the current license does not have a limit (e.g. offline license):
87
+ * do nothing (for now).
88
+ *
89
+ */
90
+
91
+ if (limits?.workflows && parseInt(limits.workflows, 10) > meta.workflowCount) {
92
+ setShowLimitModal('workflow');
93
+
94
+ /**
95
+ * If the current license has a limit:
96
+ * check if the total count of stages exceeds that limit and display
97
+ * the limits modal.
98
+ *
99
+ * If the current license does not have a limit (e.g. offline license):
100
+ * do nothing (for now).
101
+ *
102
+ */
103
+ } else if (
104
+ limits?.stagesPerWorkflow &&
105
+ parseInt(limits.stagesPerWorkflow, 10) > workflow.stages.length
106
+ ) {
107
+ setShowLimitModal('stage');
108
+ } else {
109
+ await mutateAsync({
110
+ entityId: initialData.id,
111
+ stageId,
112
+ uid,
113
+ });
114
+ }
96
115
  } catch (error) {
97
116
  // react-query@v3: the error doesn't have to be handled here
98
117
  // see: https://github.com/TanStack/query/issues/121
@@ -136,7 +155,7 @@ export function InformationBoxEE() {
136
155
  <Typography textColor="neutral800" ellipsis>
137
156
  {activeWorkflowStage?.name}
138
157
  </Typography>
139
- {isLoading ? <Loader small style={{ display: 'flex' }} /> : null}
158
+ {isWorkflowLoading || isLoading ? <Loader small style={{ display: 'flex' }} /> : null}
140
159
  </Flex>
141
160
  )}
142
161
  >
@@ -168,6 +187,44 @@ export function InformationBoxEE() {
168
187
  )}
169
188
 
170
189
  <Information.Body />
190
+
191
+ <LimitsModal.Root
192
+ isOpen={showLimitModal === 'workflow'}
193
+ onClose={() => setShowLimitModal(false)}
194
+ >
195
+ <LimitsModal.Title>
196
+ {formatMessage({
197
+ id: 'content-manager.reviewWorkflows.workflows.limit.title',
198
+ defaultMessage: 'You’ve reached the limit of workflows in your plan',
199
+ })}
200
+ </LimitsModal.Title>
201
+
202
+ <LimitsModal.Body>
203
+ {formatMessage({
204
+ id: 'content-manager.reviewWorkflows.workflows.limit.body',
205
+ defaultMessage: 'Delete a workflow or contact Sales to enable more workflows.',
206
+ })}
207
+ </LimitsModal.Body>
208
+ </LimitsModal.Root>
209
+
210
+ <LimitsModal.Root
211
+ isOpen={showLimitModal === 'stage'}
212
+ onClose={() => setShowLimitModal(false)}
213
+ >
214
+ <LimitsModal.Title>
215
+ {formatMessage({
216
+ id: 'content-manager.reviewWorkflows.stages.limit.title',
217
+ defaultMessage: 'You have reached the limit of stages for this workflow in your plan',
218
+ })}
219
+ </LimitsModal.Title>
220
+
221
+ <LimitsModal.Body>
222
+ {formatMessage({
223
+ id: 'content-manager.reviewWorkflows.stages.limit.body',
224
+ defaultMessage: 'Try deleting some stages or contact Sales to enable more stages.',
225
+ })}
226
+ </LimitsModal.Body>
227
+ </LimitsModal.Root>
171
228
  </Information.Root>
172
229
  );
173
230
  }
@@ -1,3 +1 @@
1
- import { InformationBoxEE } from './InformationBoxEE';
2
-
3
- export default InformationBoxEE;
1
+ export * from './InformationBoxEE';
@@ -4,7 +4,8 @@ import { Box, Flex, Typography } from '@strapi/design-system';
4
4
  import { pxToRem } from '@strapi/helper-plugin';
5
5
  import PropTypes from 'prop-types';
6
6
 
7
- import { getStageColorByHex } from '../../../../../pages/SettingsPage/pages/ReviewWorkflows/utils/colors';
7
+ import { STAGE_COLOR_DEFAULT } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/constants';
8
+ import { getStageColorByHex } from '../../../../pages/SettingsPage/pages/ReviewWorkflows/utils/colors';
8
9
 
9
10
  export function ReviewWorkflowsStageEE({ color, name }) {
10
11
  const { themeColorName } = getStageColorByHex(color);
@@ -27,7 +28,11 @@ export function ReviewWorkflowsStageEE({ color, name }) {
27
28
  );
28
29
  }
29
30
 
31
+ ReviewWorkflowsStageEE.defaultProps = {
32
+ color: STAGE_COLOR_DEFAULT,
33
+ };
34
+
30
35
  ReviewWorkflowsStageEE.propTypes = {
31
- color: PropTypes.string.isRequired,
36
+ color: PropTypes.string,
32
37
  name: PropTypes.string.isRequired,
33
38
  };
@@ -0,0 +1,24 @@
1
+ import getTrad from '../../../../../../admin/src/content-manager/utils/getTrad';
2
+
3
+ export const REVIEW_WORKFLOW_COLUMNS_EE = {
4
+ key: '__strapi_reviewWorkflows_stage_temp_key__',
5
+ name: 'strapi_reviewWorkflows_stage',
6
+ fieldSchema: {
7
+ type: 'relation',
8
+ },
9
+ metadatas: {
10
+ // formatMessage() will be applied when the column is rendered
11
+ label: {
12
+ id: getTrad(`containers.ListPage.table-headers.reviewWorkflows.stage`),
13
+ defaultMessage: 'Review stage',
14
+ },
15
+ searchable: false,
16
+ sortable: true,
17
+ mainField: {
18
+ name: 'name',
19
+ schema: {
20
+ type: 'string',
21
+ },
22
+ },
23
+ },
24
+ };
@@ -0,0 +1 @@
1
+ export * from './ReviewWorkflowsStageEE';
@@ -19,18 +19,18 @@ const BILLING_SELF_HOSTED_URL = 'https://strapi.io/billing/request-seats';
19
19
 
20
20
  const useLicenseLimitNotification = () => {
21
21
  const { formatMessage } = useIntl();
22
- let { license } = useLicenseLimits();
22
+ let { license, isError, isLoading } = useLicenseLimits();
23
23
  const toggleNotification = useNotification();
24
24
  const { pathname } = useLocation();
25
25
 
26
+ const { enforcementUserCount, permittedSeats, licenseLimitStatus, isHostedOnStrapiCloud } =
27
+ license;
28
+
26
29
  useEffect(() => {
27
- if (!license?.data) {
30
+ if (isError || isLoading) {
28
31
  return;
29
32
  }
30
33
 
31
- const { enforcementUserCount, permittedSeats, licenseLimitStatus, isHostedOnStrapiCloud } =
32
- license?.data ?? {};
33
-
34
34
  const shouldDisplayNotification =
35
35
  !isNil(permittedSeats) &&
36
36
  !window.sessionStorage.getItem(`${STORAGE_KEY_PREFIX}-${pathname}`) &&
@@ -84,7 +84,18 @@ const useLicenseLimitNotification = () => {
84
84
  },
85
85
  });
86
86
  }
87
- }, [toggleNotification, license.data, pathname, formatMessage]);
87
+ }, [
88
+ toggleNotification,
89
+ license,
90
+ pathname,
91
+ formatMessage,
92
+ isLoading,
93
+ permittedSeats,
94
+ licenseLimitStatus,
95
+ enforcementUserCount,
96
+ isHostedOnStrapiCloud,
97
+ isError,
98
+ ]);
88
99
  };
89
100
 
90
101
  export default useLicenseLimitNotification;
@@ -1,34 +1,3 @@
1
- import { useFetchClient, useRBAC } from '@strapi/helper-plugin';
2
- import { useQuery } from 'react-query';
3
- import { useSelector } from 'react-redux';
4
-
5
- import { selectAdminPermissions } from '../../../../admin/src/pages/App/selectors';
6
-
7
- const useLicenseLimits = () => {
8
- const permissions = useSelector(selectAdminPermissions);
9
- const rbac = useRBAC(permissions.settings.users);
10
-
11
- const {
12
- isLoading: isRBACLoading,
13
- allowedActions: { canRead, canCreate, canUpdate, canDelete },
14
- } = rbac;
15
-
16
- const isRBACAllowed = canRead && canCreate && canUpdate && canDelete;
17
-
18
- const { get } = useFetchClient();
19
- const fetchLicenseLimitInfo = async () => {
20
- const {
21
- data: { data },
22
- } = await get('/admin/license-limit-information');
23
-
24
- return data;
25
- };
26
-
27
- const license = useQuery(['ee', 'license-limit-info'], fetchLicenseLimitInfo, {
28
- enabled: !isRBACLoading && isRBACAllowed,
29
- });
30
-
31
- return { license };
32
- };
1
+ import { useLicenseLimits } from './useLicenseLimits';
33
2
 
34
3
  export default useLicenseLimits;
@@ -0,0 +1,44 @@
1
+ import * as React from 'react';
2
+
3
+ import { useFetchClient, useRBAC } from '@strapi/helper-plugin';
4
+ import { useQuery } from 'react-query';
5
+ import { useSelector } from 'react-redux';
6
+
7
+ import { selectAdminPermissions } from '../../../../admin/src/pages/App/selectors';
8
+
9
+ export function useLicenseLimits() {
10
+ const permissions = useSelector(selectAdminPermissions);
11
+ const { get } = useFetchClient();
12
+ const {
13
+ isLoading: isRBACLoading,
14
+ allowedActions: { canRead, canCreate, canUpdate, canDelete },
15
+ } = useRBAC(permissions.settings.users);
16
+ const hasPermissions = canRead && canCreate && canUpdate && canDelete;
17
+
18
+ const { data, isError, isLoading } = useQuery(
19
+ ['ee', 'license-limit-info'],
20
+ async () => {
21
+ const {
22
+ data: { data },
23
+ } = await get('/admin/license-limit-information');
24
+
25
+ return data;
26
+ },
27
+ {
28
+ enabled: !isRBACLoading && hasPermissions,
29
+ }
30
+ );
31
+
32
+ const license = data ?? {};
33
+
34
+ const getFeature = React.useCallback(
35
+ (name) => {
36
+ const feature = (license?.features ?? []).find((feature) => feature.name === name);
37
+
38
+ return feature?.options ?? {};
39
+ },
40
+ [license?.features]
41
+ );
42
+
43
+ return { license, getFeature, isError, isLoading };
44
+ }
@@ -14,7 +14,7 @@ const DividerFull = styled(Divider)`
14
14
  flex: 1;
15
15
  `;
16
16
 
17
- const Login = (loginProps) => {
17
+ export const LoginEE = (loginProps) => {
18
18
  const ssoEnabled = window.strapi.features.isEnabled(window.strapi.features.SSO);
19
19
  const { isLoading, data: providers } = useAuthProviders({ ssoEnabled });
20
20
  const { formatMessage } = useIntl();
@@ -49,17 +49,15 @@ const Login = (loginProps) => {
49
49
  );
50
50
  };
51
51
 
52
- Login.defaultProps = {
52
+ LoginEE.defaultProps = {
53
53
  onSubmit: (e) => e.preventDefault(),
54
54
  requestError: null,
55
55
  };
56
56
 
57
- Login.propTypes = {
57
+ LoginEE.propTypes = {
58
58
  formErrors: PropTypes.object.isRequired,
59
59
  modifiedData: PropTypes.object.isRequired,
60
60
  onChange: PropTypes.func.isRequired,
61
61
  onSubmit: PropTypes.func,
62
62
  requestError: PropTypes.object,
63
63
  };
64
-
65
- export default Login;
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+
3
+ // eslint-disable-next-line import/no-cycle
4
+ import { HomePageCE } from '../../../../admin/src/pages/HomePage';
5
+ import { useLicenseLimitNotification } from '../../hooks';
6
+
7
+ export function HomePageEE() {
8
+ useLicenseLimitNotification();
9
+
10
+ return <HomePageCE />;
11
+ }
@@ -20,7 +20,7 @@ export const ROUTES_EE = [
20
20
  {
21
21
  async Component() {
22
22
  const component = await import(
23
- /* webpackChunkName: "review-workflows-settings" */ './pages/ReviewWorkflows'
23
+ /* webpackChunkName: "review-workflows-settings-list-view" */ './pages/ReviewWorkflows/pages/ListView'
24
24
  );
25
25
 
26
26
  return component;
@@ -28,6 +28,30 @@ export const ROUTES_EE = [
28
28
  to: '/settings/review-workflows',
29
29
  exact: true,
30
30
  },
31
+
32
+ {
33
+ async Component() {
34
+ const component = await import(
35
+ /* webpackChunkName: "review-workflows-settings-create-view" */ './pages/ReviewWorkflows/pages/CreateView'
36
+ );
37
+
38
+ return component;
39
+ },
40
+ to: '/settings/review-workflows/create',
41
+ exact: true,
42
+ },
43
+
44
+ {
45
+ async Component() {
46
+ const component = await import(
47
+ /* webpackChunkName: "review-workflows-settings-edit-view" */ './pages/ReviewWorkflows/pages/EditView'
48
+ );
49
+
50
+ return component;
51
+ },
52
+ to: '/settings/review-workflows/:workflowId',
53
+ exact: true,
54
+ },
31
55
  ]
32
56
  : []),
33
57
 
@@ -11,13 +11,15 @@ import { useLicenseLimits } from '../../../../../../hooks';
11
11
  const BILLING_STRAPI_CLOUD_URL = 'https://cloud.strapi.io/profile/billing';
12
12
  const BILLING_SELF_HOSTED_URL = 'https://strapi.io/billing/request-seats';
13
13
 
14
- const AdminSeatInfo = () => {
14
+ export const AdminSeatInfoEE = () => {
15
15
  const { formatMessage } = useIntl();
16
- const { license } = useLicenseLimits();
17
- const { licenseLimitStatus, enforcementUserCount, permittedSeats, isHostedOnStrapiCloud } =
18
- license?.data ?? {};
16
+ const {
17
+ license: { licenseLimitStatus, enforcementUserCount, permittedSeats, isHostedOnStrapiCloud },
18
+ isError,
19
+ isLoading,
20
+ } = useLicenseLimits();
19
21
 
20
- if (!permittedSeats) {
22
+ if (isError || isLoading || !permittedSeats) {
21
23
  return null;
22
24
  }
23
25
 
@@ -86,5 +88,3 @@ const AdminSeatInfo = () => {
86
88
  </GridItem>
87
89
  );
88
90
  };
89
-
90
- export default AdminSeatInfo;
@@ -1,4 +1,4 @@
1
- import { useFetchClient, useNotification } from '@strapi/helper-plugin';
1
+ import { useFetchClient, useNotification, useQueryParams } from '@strapi/helper-plugin';
2
2
  import { useQuery } from 'react-query';
3
3
  import { useLocation } from 'react-router-dom';
4
4
 
@@ -8,6 +8,7 @@ const useAuditLogsData = ({ canReadAuditLogs, canReadUsers }) => {
8
8
  const { get } = useFetchClient();
9
9
  const { search } = useLocation();
10
10
  const toggleNotification = useNotification();
11
+ const [{ query }] = useQueryParams();
11
12
 
12
13
  const queryOptions = {
13
14
  keepPreviousData: true,
@@ -35,9 +36,10 @@ const useAuditLogsData = ({ canReadAuditLogs, canReadUsers }) => {
35
36
  isError: isAuditLogsError,
36
37
  } = useQuery(
37
38
  ['auditLogs', search],
38
- async ({ queryKey }) => {
39
- const search = queryKey[1];
40
- const { data } = await get(`/admin/audit-logs${search}`);
39
+ async () => {
40
+ const { data } = await get(`/admin/audit-logs`, {
41
+ params: query,
42
+ });
41
43
 
42
44
  return data;
43
45
  },
@@ -1,17 +1,19 @@
1
1
  import {
2
2
  ACTION_ADD_STAGE,
3
3
  ACTION_DELETE_STAGE,
4
- ACTION_SET_WORKFLOWS,
4
+ ACTION_RESET_WORKFLOW,
5
+ ACTION_SET_WORKFLOW,
5
6
  ACTION_UPDATE_STAGE,
6
7
  ACTION_UPDATE_STAGE_POSITION,
8
+ ACTION_UPDATE_WORKFLOW,
7
9
  } from '../constants';
8
10
 
9
- export function setWorkflows({ status, data }) {
11
+ export function setWorkflow({ status, data }) {
10
12
  return {
11
- type: ACTION_SET_WORKFLOWS,
13
+ type: ACTION_SET_WORKFLOW,
12
14
  payload: {
13
15
  status,
14
- workflows: data,
16
+ workflow: data,
15
17
  },
16
18
  };
17
19
  }
@@ -51,3 +53,16 @@ export function updateStagePosition(oldIndex, newIndex) {
51
53
  },
52
54
  };
53
55
  }
56
+
57
+ export function updateWorkflow(payload) {
58
+ return {
59
+ type: ACTION_UPDATE_WORKFLOW,
60
+ payload,
61
+ };
62
+ }
63
+
64
+ export function resetWorkflow() {
65
+ return {
66
+ type: ACTION_RESET_WORKFLOW,
67
+ };
68
+ }
@@ -0,0 +1,65 @@
1
+ /* eslint-disable react/prop-types */
2
+
3
+ import * as React from 'react';
4
+
5
+ import { ContentLayout, HeaderLayout, Layout, Main } from '@strapi/design-system';
6
+ import { Link, SettingsPageTitle } from '@strapi/helper-plugin';
7
+ import { ArrowLeft } from '@strapi/icons';
8
+ import { useIntl } from 'react-intl';
9
+
10
+ import { DragLayer } from '../../../../../../../../admin/src/components/DragLayer';
11
+ import { DRAG_DROP_TYPES } from '../../constants';
12
+ import { StageDragPreview } from '../StageDragPreview';
13
+
14
+ function renderDragLayerItem({ type, item }) {
15
+ switch (type) {
16
+ case DRAG_DROP_TYPES.STAGE:
17
+ return <StageDragPreview {...item} />;
18
+
19
+ default:
20
+ return null;
21
+ }
22
+ }
23
+
24
+ function DragLayerRendered() {
25
+ return <DragLayer renderItem={renderDragLayerItem} />;
26
+ }
27
+
28
+ function Root({ children }) {
29
+ return (
30
+ <Layout>
31
+ <Main tabIndex={-1}>
32
+ <ContentLayout>{children}</ContentLayout>
33
+ </Main>
34
+ </Layout>
35
+ );
36
+ }
37
+
38
+ function Back({ href }) {
39
+ const { formatMessage } = useIntl();
40
+
41
+ return (
42
+ <Link startIcon={<ArrowLeft />} to={href}>
43
+ {formatMessage({
44
+ id: 'global.back',
45
+ defaultMessage: 'Back',
46
+ })}
47
+ </Link>
48
+ );
49
+ }
50
+
51
+ function Header({ title, subtitle, navigationAction, primaryAction }) {
52
+ return (
53
+ <>
54
+ <SettingsPageTitle name={title} />
55
+ <HeaderLayout
56
+ navigationAction={navigationAction}
57
+ primaryAction={primaryAction}
58
+ title={title}
59
+ subtitle={subtitle}
60
+ />
61
+ </>
62
+ );
63
+ }
64
+
65
+ export { Back, DragLayerRendered, Header, Root };