@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.
- package/admin/src/constants.js +83 -83
- package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +8 -5
- package/admin/src/content-manager/components/Inputs/index.js +3 -47
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +34 -37
- package/admin/src/content-manager/pages/EditSettingsView/components/ModalForm.js +0 -27
- package/admin/src/content-manager/pages/EditView/Information/index.js +1 -1
- package/admin/src/content-manager/pages/EditView/InformationBox/InformationBoxCE.js +1 -2
- package/admin/src/content-manager/pages/EditView/InformationBox/index.js +1 -3
- package/admin/src/content-manager/pages/EditView/index.js +14 -2
- package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +93 -14
- package/admin/src/content-manager/pages/ListView/index.js +65 -59
- package/admin/src/content-manager/pages/ListView/utils/buildValidGetParams.js +30 -0
- package/admin/src/content-manager/pages/ListView/utils/index.js +1 -1
- package/admin/src/content-manager/utils/mergeMetasWithSchema.js +5 -1
- package/admin/src/hooks/index.js +0 -1
- package/admin/src/hooks/useAdminUsers/useAdminUsers.js +3 -3
- package/admin/src/hooks/useEnterprise/useEnterprise.js +4 -4
- package/admin/src/hooks/useSettingsMenu/index.js +35 -21
- package/admin/src/pages/App/index.js +28 -23
- package/admin/src/pages/AuthPage/components/Login/index.js +3 -5
- package/admin/src/pages/AuthPage/components/Register/index.js +5 -1
- package/admin/src/pages/AuthPage/constants.js +3 -2
- package/admin/src/pages/AuthPage/index.js +18 -1
- package/admin/src/pages/HomePage/index.js +19 -7
- package/admin/src/pages/ProfilePage/index.js +12 -12
- package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +13 -11
- package/admin/src/pages/SettingsPage/components/Tokens/TokenBox/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +17 -1
- package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +16 -3
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +2 -4
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +15 -1
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +36 -5
- package/admin/src/pages/SettingsPage/pages/Users/components/MagicLink/index.js +3 -5
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +1 -3
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +16 -1
- package/admin/src/translations/zh-Hans.json +1 -1
- package/build/0cd5f8915b265d5b1856.png +0 -0
- package/build/1049.758a01f5.chunk.js +1 -0
- package/build/{3528.4845cf92.chunk.js → 1386.762d6eb8.chunk.js} +1 -1
- package/build/1727.b49f0713.chunk.js +1 -0
- package/build/190.66d89241.chunk.js +117 -0
- package/build/{5563.86f9aa9c.chunk.js → 2225.15d1df72.chunk.js} +3 -3
- package/build/2379.d33a2e16.chunk.js +1 -0
- package/build/2395.b0419a54.chunk.js +26 -0
- package/build/2801.18ac397d.chunk.js +1 -0
- package/build/{7394.423886bd.chunk.js → 3100.21c343fa.chunk.js} +1 -1
- package/build/311.cb0884bb.chunk.js +1 -0
- package/build/3483.e182b190.chunk.js +1 -0
- package/build/3984.ea7b8036.chunk.js +1 -0
- package/build/4546.ff9fdf30.chunk.js +1 -0
- package/build/502.ccb38223.chunk.js +1 -0
- package/build/5483.ed2c7efa.chunk.js +6 -0
- package/build/{5542.c62d0daf.chunk.js → 5542.2415a393.chunk.js} +6 -6
- package/build/6158.f9d82db9.chunk.js +1 -0
- package/build/7030.b98dcedf.chunk.js +1 -0
- package/build/7464.c6d0565c.chunk.js +1 -0
- package/build/8276.23e0763b.chunk.js +26 -0
- package/build/918.54414509.chunk.js +1 -0
- package/build/{9932.7e2b71de.chunk.js → 9932.b5a3bb3a.chunk.js} +81 -81
- package/build/9944.7af075a5.chunk.js +26 -0
- package/build/{Admin-authenticatedApp.cb649fc1.chunk.js → Admin-authenticatedApp.2ffa318a.chunk.js} +5 -5
- package/build/Admin_InternalErrorPage.f45f2462.chunk.js +1 -0
- package/build/{Admin_homePage.be30ef4e.chunk.js → Admin_homePage.ac9dfb86.chunk.js} +23 -15
- package/build/{Admin_marketplace.74a58e20.chunk.js → Admin_marketplace.f0b87fce.chunk.js} +1 -1
- package/build/{Admin_pluginsPage.ce464189.chunk.js → Admin_pluginsPage.8728ff6e.chunk.js} +1 -1
- package/build/{Admin_profilePage.2131eb68.chunk.js → Admin_profilePage.a968035f.chunk.js} +2 -2
- package/build/Admin_settingsPage.3ad19487.chunk.js +79 -0
- package/build/Upload_ConfigureTheView.345ac1e0.chunk.js +1 -0
- package/build/admin-app.088bcd33.chunk.js +36 -0
- package/build/{admin-edit-roles-page.3fdd6b9d.chunk.js → admin-edit-roles-page.a49b9f4f.chunk.js} +4 -4
- package/build/admin-edit-users.67704088.chunk.js +10 -0
- package/build/{admin-roles-list.e17b00d7.chunk.js → admin-roles-list.0c129e98.chunk.js} +1 -1
- package/build/admin-users.3279ffb0.chunk.js +11 -0
- package/build/api-tokens-create-page.46c2ea84.chunk.js +1 -0
- package/build/{api-tokens-edit-page.9a1dd2fa.chunk.js → api-tokens-edit-page.58139df9.chunk.js} +1 -1
- package/build/{api-tokens-list-page.a103f526.chunk.js → api-tokens-list-page.505bf7e0.chunk.js} +2 -2
- package/build/audit-logs-settings-page.4b422831.chunk.js +1 -0
- package/build/content-manager.9b569036.chunk.js +1094 -0
- package/build/{content-type-builder-list-view.a200a358.chunk.js → content-type-builder-list-view.bf9be456.chunk.js} +9 -9
- package/build/content-type-builder-translation-en-json.38e20391.chunk.js +1 -0
- package/build/{content-type-builder-translation-zh-json.ad24dbeb.chunk.js → content-type-builder-translation-zh-json.958d90e1.chunk.js} +1 -1
- package/build/content-type-builder.3963fb2d.chunk.js +166 -0
- package/build/{email-settings-page.45695daa.chunk.js → email-settings-page.d494d1eb.chunk.js} +2 -2
- package/build/{i18n-settings-page.29308d0b.chunk.js → i18n-settings-page.47f78016.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/main.98c989b0.js +2908 -0
- package/build/review-workflows-settings-create-view.60bc516c.chunk.js +1 -0
- package/build/review-workflows-settings-edit-view.898ea409.chunk.js +1 -0
- package/build/review-workflows-settings-list-view.240cacdf.chunk.js +56 -0
- package/build/runtime~main.44bf2a37.js +2 -0
- package/build/sso-settings-page.ed6f3f15.chunk.js +1 -0
- package/build/transfer-tokens-create-page.1597e6ab.chunk.js +1 -0
- package/build/transfer-tokens-edit-page.8741529f.chunk.js +1 -0
- package/build/{transfer-tokens-list-page.7237443d.chunk.js → transfer-tokens-list-page.22147d2c.chunk.js} +2 -2
- package/build/upload-settings.cac210a0.chunk.js +14 -0
- package/build/upload.8d01c525.chunk.js +26 -0
- package/build/{users-advanced-settings-page.750b1f76.chunk.js → users-advanced-settings-page.18379a56.chunk.js} +1 -1
- package/build/users-email-settings-page.a87978e5.chunk.js +9 -0
- package/build/users-providers-settings-page.8876c1ee.chunk.js +14 -0
- package/build/{users-roles-settings-page.1f505119.chunk.js → users-roles-settings-page.0431f48c.chunk.js} +2 -2
- package/build/webhook-edit-page.a91f27a1.chunk.js +33 -0
- package/build/{webhook-list-page.940a40f1.chunk.js → webhook-list-page.65e1b5bb.chunk.js} +1 -1
- package/build/{zh-Hans-json.4cfef87d.chunk.js → zh-Hans-json.fada6f40.chunk.js} +1 -1
- package/ee/admin/constants.js +14 -14
- package/ee/admin/content-manager/pages/EditView/InformationBox/InformationBoxEE.js +88 -31
- package/ee/admin/content-manager/pages/EditView/InformationBox/index.js +1 -3
- package/ee/admin/content-manager/{components/DynamicTable/CellContent/ReviewWorkflowsStage → pages/ListView/ReviewWorkflowsColumn}/ReviewWorkflowsStageEE.js +7 -2
- package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/constants.js +24 -0
- package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/index.js +1 -0
- package/ee/admin/hooks/useLicenseLimitNotification/index.js +17 -6
- package/ee/admin/hooks/useLicenseLimits/index.js +1 -32
- package/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js +44 -0
- package/ee/admin/pages/AuthPage/components/Login/index.js +3 -5
- package/ee/admin/pages/HomePage/index.js +11 -0
- package/ee/admin/pages/SettingsPage/constants.js +25 -1
- package/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +7 -7
- package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +6 -4
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/actions/index.js +19 -4
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Layout/Layout.js +65 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Layout/index.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal/LimitsModal.js +111 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal/assets/balloon.png +0 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/LimitsModal/index.js +3 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/ProtectedPage.js +21 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/ProtectedPage/index.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js +5 -5
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/WorkflowAttributes.js +110 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/WorkflowAttributes/index.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/constants.js +3 -1
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +13 -19
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js +246 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/index.js +13 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js +287 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/index.js +13 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js +382 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/index.js +13 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/reducer/index.js +53 -23
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/utils/getWorkflowValidationSchema.js +43 -28
- package/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +11 -6
- package/ee/admin/pages/SettingsPage/pages/Users/ListPage/index.js +13 -0
- package/ee/admin/pages/SettingsPage/pages/Users/components/MagicLink/index.js +3 -5
- package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +1 -3
- package/ee/server/config/admin-actions.js +24 -0
- package/ee/server/constants/default-stages.json +8 -4
- package/ee/server/constants/default-workflow.json +3 -1
- package/ee/server/constants/workflows.js +10 -1
- package/ee/server/content-types/workflow/index.js +10 -0
- package/ee/server/content-types/workflow-stage/index.js +3 -1
- package/ee/server/controllers/admin.js +1 -0
- package/ee/server/controllers/workflows/index.js +135 -8
- package/ee/server/controllers/workflows/stages/index.js +38 -38
- package/ee/server/migrations/review-workflows-content-types.js +29 -0
- package/ee/server/migrations/review-workflows-deleted-ct-in-workflows.js +39 -0
- package/ee/server/migrations/review-workflows-stage-attribute.js +49 -0
- package/ee/server/migrations/review-workflows-stages-color.js +2 -2
- package/ee/server/migrations/review-workflows-workflow-name.js +21 -0
- package/ee/server/register.js +12 -2
- package/ee/server/routes/review-workflows.js +44 -10
- package/ee/server/services/index.js +1 -0
- package/ee/server/services/review-workflows/entity-service-decorator.js +8 -13
- package/ee/server/services/review-workflows/review-workflows.js +45 -53
- package/ee/server/services/review-workflows/stages.js +84 -46
- package/ee/server/services/review-workflows/validation.js +60 -0
- package/ee/server/services/review-workflows/workflows/content-types.js +80 -0
- package/ee/server/services/review-workflows/workflows/index.js +207 -0
- package/ee/server/utils/review-workflows.js +30 -25
- package/ee/server/validation/review-workflows.js +49 -10
- package/index.js +0 -14
- package/package.json +12 -21
- package/webpack.alias.js +0 -3
- package/webpack.config.js +1 -75
- package/admin/src/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -2
- package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +0 -36
- package/admin/src/content-manager/pages/ListView/utils/createPluginsFilter.js +0 -4
- package/admin/src/hooks/useLicenseLimits/index.js +0 -3
- package/admin/src/pages/App/utils/index.js +0 -3
- package/admin/src/pages/App/utils/unique-identifier.js +0 -12
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +0 -5
- package/build/1386.3b2aa6a7.chunk.js +0 -3
- package/build/1799.44d2e264.chunk.js +0 -33
- package/build/1970.39a2d75e.chunk.js +0 -1
- package/build/3269.1ea0f5a6.chunk.js +0 -1
- package/build/5932.6a23b88c.chunk.js +0 -1
- package/build/7018.98feed67.chunk.js +0 -1
- package/build/7259.fb69d4bf.chunk.js +0 -1
- package/build/Admin_InternalErrorPage.8911cb49.chunk.js +0 -1
- package/build/Admin_settingsPage.4069bb8a.chunk.js +0 -79
- package/build/Upload_ConfigureTheView.7a1cb9c9.chunk.js +0 -1
- package/build/admin-app.fea867af.chunk.js +0 -61
- package/build/admin-edit-users.200551e3.chunk.js +0 -10
- package/build/admin-users.3b12dca2.chunk.js +0 -11
- package/build/api-tokens-create-page.3dd4e921.chunk.js +0 -1
- package/build/audit-logs-settings-page.f538490f.chunk.js +0 -1
- package/build/content-manager.c40f5ff9.chunk.js +0 -1088
- package/build/content-type-builder-translation-en-json.f592325b.chunk.js +0 -1
- package/build/content-type-builder.bd1bbff1.chunk.js +0 -166
- package/build/main.ee36abd9.js +0 -2927
- package/build/review-workflows-settings.93808ae0.chunk.js +0 -110
- package/build/runtime~main.efd966f6.js +0 -2
- package/build/sso-settings-page.0cdb96a6.chunk.js +0 -1
- package/build/transfer-tokens-create-page.de14cad4.chunk.js +0 -1
- package/build/transfer-tokens-edit-page.4f5e39af.chunk.js +0 -1
- package/build/upload-settings.cb6c14c3.chunk.js +0 -14
- package/build/upload.7e629643.chunk.js +0 -26
- package/build/users-email-settings-page.e9bcd865.chunk.js +0 -9
- package/build/users-providers-settings-page.a94253e9.chunk.js +0 -14
- package/build/webhook-edit-page.77ef4f1a.chunk.js +0 -33
- package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -58
- package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/index.js +0 -3
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ProtectedPage.js +0 -20
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js +0 -204
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/index.js +0 -3
- package/ee/server/services/review-workflows/workflows.js +0 -25
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { mapAsync } = require('@strapi/utils');
|
|
4
4
|
const { getService } = require('../../../utils');
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const { validateUpdateStageOnEntity } = require('../../../validation/review-workflows');
|
|
6
|
+
const { STAGE_MODEL_UID } = require('../../../constants/workflows');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param { Strapi } strapi - Strapi instance
|
|
11
|
+
* @param userAbility
|
|
12
|
+
* @return { (Stage) => SanitizedStage }
|
|
13
|
+
*/
|
|
14
|
+
function sanitizeStage({ strapi }, userAbility) {
|
|
15
|
+
const permissionChecker = strapi
|
|
16
|
+
.plugin('content-manager')
|
|
17
|
+
.service('permission-checker')
|
|
18
|
+
.create({ userAbility, model: STAGE_MODEL_UID });
|
|
19
|
+
|
|
20
|
+
return (entity) => permissionChecker.sanitizeOutput(entity);
|
|
21
|
+
}
|
|
10
22
|
|
|
11
23
|
module.exports = {
|
|
12
24
|
/**
|
|
@@ -17,14 +29,15 @@ module.exports = {
|
|
|
17
29
|
const { workflow_id: workflowId } = ctx.params;
|
|
18
30
|
const { populate } = ctx.query;
|
|
19
31
|
const stagesService = getService('stages');
|
|
32
|
+
const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);
|
|
20
33
|
|
|
21
|
-
const
|
|
34
|
+
const stages = await stagesService.find({
|
|
22
35
|
workflowId,
|
|
23
36
|
populate,
|
|
24
37
|
});
|
|
25
38
|
|
|
26
39
|
ctx.body = {
|
|
27
|
-
data,
|
|
40
|
+
data: await mapAsync(stages, sanitizer),
|
|
28
41
|
};
|
|
29
42
|
},
|
|
30
43
|
/**
|
|
@@ -35,36 +48,18 @@ module.exports = {
|
|
|
35
48
|
const { id, workflow_id: workflowId } = ctx.params;
|
|
36
49
|
const { populate } = ctx.query;
|
|
37
50
|
const stagesService = getService('stages');
|
|
51
|
+
const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);
|
|
38
52
|
|
|
39
|
-
const
|
|
53
|
+
const stage = await stagesService.findById(id, {
|
|
40
54
|
workflowId,
|
|
41
55
|
populate,
|
|
42
56
|
});
|
|
43
57
|
|
|
44
58
|
ctx.body = {
|
|
45
|
-
data,
|
|
59
|
+
data: await sanitizer(stage),
|
|
46
60
|
};
|
|
47
61
|
},
|
|
48
62
|
|
|
49
|
-
/**
|
|
50
|
-
* Replace all stages in a workflow
|
|
51
|
-
* @param {import('koa').BaseContext} ctx - koa context
|
|
52
|
-
*
|
|
53
|
-
*/
|
|
54
|
-
async replace(ctx) {
|
|
55
|
-
const { workflow_id: workflowId } = ctx.params;
|
|
56
|
-
const stagesService = getService('stages');
|
|
57
|
-
const {
|
|
58
|
-
body: { data: stages },
|
|
59
|
-
} = ctx.request;
|
|
60
|
-
|
|
61
|
-
const stagesValidated = await validateUpdateStages(stages);
|
|
62
|
-
|
|
63
|
-
const data = await stagesService.replaceWorkflowStages(workflowId, stagesValidated);
|
|
64
|
-
|
|
65
|
-
ctx.body = { data };
|
|
66
|
-
},
|
|
67
|
-
|
|
68
63
|
/**
|
|
69
64
|
* Updates an entity's stage.
|
|
70
65
|
* @async
|
|
@@ -80,23 +75,28 @@ module.exports = {
|
|
|
80
75
|
*/
|
|
81
76
|
async updateEntity(ctx) {
|
|
82
77
|
const stagesService = getService('stages');
|
|
78
|
+
const workflowService = getService('workflows');
|
|
79
|
+
|
|
83
80
|
const { model_uid: modelUID, id: entityIdString } = ctx.params;
|
|
81
|
+
const { body } = ctx.request;
|
|
82
|
+
|
|
84
83
|
const entityId = Number(entityIdString);
|
|
85
84
|
|
|
85
|
+
const { sanitizeOutput } = strapi
|
|
86
|
+
.plugin('content-manager')
|
|
87
|
+
.service('permission-checker')
|
|
88
|
+
.create({ userAbility: ctx.state.userAbility, model: modelUID });
|
|
89
|
+
|
|
86
90
|
const { id: stageId } = await validateUpdateStageOnEntity(
|
|
87
|
-
|
|
91
|
+
{ id: Number(body?.data?.id) },
|
|
88
92
|
'You should pass an id to the body of the put request.'
|
|
89
93
|
);
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// TODO When multiple workflows are possible, check if the stage is part of the right one
|
|
96
|
-
// Didn't need this today as their can only be one workflow
|
|
95
|
+
const workflow = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);
|
|
96
|
+
workflowService.assertStageBelongsToWorkflow(stageId, workflow);
|
|
97
97
|
|
|
98
|
-
const
|
|
98
|
+
const entity = await stagesService.updateEntity({ id: entityId, modelUID }, stageId);
|
|
99
99
|
|
|
100
|
-
ctx.body = { data };
|
|
100
|
+
ctx.body = { data: await sanitizeOutput(entity) };
|
|
101
101
|
},
|
|
102
102
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { get, keys, pickBy, pipe } = require('lodash/fp');
|
|
4
|
+
const { WORKFLOW_MODEL_UID } = require('../constants/workflows');
|
|
5
|
+
|
|
6
|
+
async function migrateWorkflowsContentTypes({ oldContentTypes, contentTypes }) {
|
|
7
|
+
// Look for RW contentTypes attribute
|
|
8
|
+
const hadContentTypes = !!oldContentTypes?.[WORKFLOW_MODEL_UID]?.attributes?.contentTypes;
|
|
9
|
+
const hasContentTypes = !!contentTypes?.[WORKFLOW_MODEL_UID]?.attributes?.contentTypes;
|
|
10
|
+
|
|
11
|
+
if (!hadContentTypes && hasContentTypes) {
|
|
12
|
+
// Initialize contentTypes with an empty array and assign only to one
|
|
13
|
+
// workflow the Content Types which were using Review Workflow before.
|
|
14
|
+
await strapi.query(WORKFLOW_MODEL_UID).updateMany({ data: { contentTypes: [] } });
|
|
15
|
+
|
|
16
|
+
// Find Content Types which were using Review Workflow before
|
|
17
|
+
const contentTypes = pipe([pickBy(get('options.reviewWorkflows')), keys])(oldContentTypes);
|
|
18
|
+
|
|
19
|
+
if (contentTypes.length) {
|
|
20
|
+
// Update only one workflow with the contentTypes
|
|
21
|
+
// Before this release there was only one workflow, so this operation is safe.
|
|
22
|
+
await strapi
|
|
23
|
+
.query(WORKFLOW_MODEL_UID)
|
|
24
|
+
.update({ where: { id: { $notNull: true } }, data: { contentTypes } });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = migrateWorkflowsContentTypes;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { difference, keys } = require('lodash/fp');
|
|
4
|
+
const { mapAsync } = require('@strapi/utils');
|
|
5
|
+
const { WORKFLOW_MODEL_UID } = require('../constants/workflows');
|
|
6
|
+
const { getWorkflowContentTypeFilter } = require('../utils/review-workflows');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {Object} oldContentTypes
|
|
10
|
+
* @param {Object} contentTypes
|
|
11
|
+
* @return {Promise<void>}
|
|
12
|
+
*/
|
|
13
|
+
async function migrateDeletedCTInWorkflows({ oldContentTypes, contentTypes }) {
|
|
14
|
+
const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];
|
|
15
|
+
|
|
16
|
+
if (deletedContentTypes.length) {
|
|
17
|
+
await mapAsync(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
18
|
+
const workflow = await strapi.query(WORKFLOW_MODEL_UID).findOne({
|
|
19
|
+
select: ['id', 'contentTypes'],
|
|
20
|
+
where: {
|
|
21
|
+
contentTypes: getWorkflowContentTypeFilter({ strapi }, deletedContentTypeUID),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (workflow) {
|
|
26
|
+
await strapi.query(WORKFLOW_MODEL_UID).update({
|
|
27
|
+
where: { id: workflow.id },
|
|
28
|
+
data: {
|
|
29
|
+
contentTypes: workflow.contentTypes.filter(
|
|
30
|
+
(contentTypeUID) => contentTypeUID !== deletedContentTypeUID
|
|
31
|
+
),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = migrateDeletedCTInWorkflows;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const semver = require('semver');
|
|
4
|
+
const { getOr } = require('lodash/fp');
|
|
5
|
+
const { mapAsync } = require('@strapi/utils');
|
|
6
|
+
const { STAGE_MODEL_UID } = require('../constants/workflows');
|
|
7
|
+
const { findTables } = require('../utils/persisted-tables');
|
|
8
|
+
|
|
9
|
+
function checkVersionThreshold(startVersion, currentVersion, thresholdVersion) {
|
|
10
|
+
return semver.gte(currentVersion, thresholdVersion) && semver.lt(startVersion, thresholdVersion);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function migrateStageAttribute({ oldContentTypes, contentTypes }) {
|
|
14
|
+
const getRWVersion = getOr('0.0.0', `${STAGE_MODEL_UID}.options.version`);
|
|
15
|
+
const oldRWVersion = getRWVersion(oldContentTypes);
|
|
16
|
+
const currentRWVersion = getRWVersion(contentTypes);
|
|
17
|
+
|
|
18
|
+
const migrationNeeded = checkVersionThreshold(oldRWVersion, currentRWVersion, '1.1.0');
|
|
19
|
+
|
|
20
|
+
if (migrationNeeded) {
|
|
21
|
+
const oldAttributeTableName = 'strapi_review_workflows_stage';
|
|
22
|
+
const newAttributeTableName = 'strapi_stage';
|
|
23
|
+
const tables = await findTables({ strapi }, new RegExp(oldAttributeTableName));
|
|
24
|
+
|
|
25
|
+
await mapAsync(tables, async (tableName) => {
|
|
26
|
+
const newTableName = tableName.replace(oldAttributeTableName, newAttributeTableName);
|
|
27
|
+
const alreadyHasNextTable = await strapi.db.connection.schema.hasTable(newTableName);
|
|
28
|
+
|
|
29
|
+
// The table can be already created but empty. In order to rename the old one, we need to drop the previously created empty one.
|
|
30
|
+
if (alreadyHasNextTable) {
|
|
31
|
+
const dataInTable = await strapi.db.connection(newTableName).select().limit(1);
|
|
32
|
+
if (!dataInTable.length) {
|
|
33
|
+
await strapi.db.connection.schema.dropTable(newTableName);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
await strapi.db.connection.schema.renameTable(tableName, newTableName);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
strapi.log.warn(
|
|
41
|
+
`An error occurred during the migration of ${tableName} table to ${newTableName}.\nIf ${newTableName} already exists, migration can't be done automatically.`
|
|
42
|
+
);
|
|
43
|
+
strapi.log.warn(e.message);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = migrateStageAttribute;
|
|
@@ -5,10 +5,10 @@ const { STAGE_DEFAULT_COLOR } = require('../constants/workflows');
|
|
|
5
5
|
async function migrateReviewWorkflowStagesColor({ oldContentTypes, contentTypes }) {
|
|
6
6
|
// Look for CT's color attribute
|
|
7
7
|
const hadColor = !!oldContentTypes?.['admin::workflow-stage']?.attributes?.color;
|
|
8
|
-
const hasColor = !!contentTypes['admin::workflow-stage']?.attributes?.color;
|
|
8
|
+
const hasColor = !!contentTypes?.['admin::workflow-stage']?.attributes?.color;
|
|
9
9
|
|
|
10
10
|
// Add the default stage color if color attribute was added
|
|
11
|
-
if (!hadColor
|
|
11
|
+
if (!hadColor && hasColor) {
|
|
12
12
|
await strapi.query('admin::workflow-stage').updateMany({
|
|
13
13
|
data: {
|
|
14
14
|
color: STAGE_DEFAULT_COLOR,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { WORKFLOW_MODEL_UID } = require('../constants/workflows');
|
|
4
|
+
const defaultWorkflow = require('../constants/default-workflow.json');
|
|
5
|
+
|
|
6
|
+
async function migrateReviewWorkflowName({ oldContentTypes, contentTypes }) {
|
|
7
|
+
// Look for RW name attribute
|
|
8
|
+
const hadName = !!oldContentTypes?.[WORKFLOW_MODEL_UID]?.attributes?.name;
|
|
9
|
+
const hasName = !!contentTypes?.[WORKFLOW_MODEL_UID]?.attributes?.name;
|
|
10
|
+
|
|
11
|
+
// Add the default workflow name if name attribute was added
|
|
12
|
+
if (!hadName && hasName) {
|
|
13
|
+
await strapi.query(WORKFLOW_MODEL_UID).updateMany({
|
|
14
|
+
data: {
|
|
15
|
+
name: defaultWorkflow.name,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = migrateReviewWorkflowName;
|
package/ee/server/register.js
CHANGED
|
@@ -4,6 +4,10 @@ const { features } = require('@strapi/strapi/lib/utils/ee');
|
|
|
4
4
|
const executeCERegister = require('../../server/register');
|
|
5
5
|
const migrateAuditLogsTable = require('./migrations/audit-logs-table');
|
|
6
6
|
const migrateReviewWorkflowStagesColor = require('./migrations/review-workflows-stages-color');
|
|
7
|
+
const migrateReviewWorkflowName = require('./migrations/review-workflows-workflow-name');
|
|
8
|
+
const migrateWorkflowsContentTypes = require('./migrations/review-workflows-content-types');
|
|
9
|
+
const migrateStageAttribute = require('./migrations/review-workflows-stage-attribute');
|
|
10
|
+
const migrateDeletedCTInWorkflows = require('./migrations/review-workflows-deleted-ct-in-workflows');
|
|
7
11
|
const createAuditLogsService = require('./services/audit-logs');
|
|
8
12
|
const reviewWorkflowsMiddlewares = require('./middlewares/review-workflows');
|
|
9
13
|
const { getService } = require('./utils');
|
|
@@ -18,11 +22,17 @@ module.exports = async ({ strapi }) => {
|
|
|
18
22
|
await auditLogsService.register();
|
|
19
23
|
}
|
|
20
24
|
if (features.isEnabled('review-workflows')) {
|
|
21
|
-
strapi.hook('strapi::content-types.
|
|
25
|
+
strapi.hook('strapi::content-types.beforeSync').register(migrateStageAttribute);
|
|
26
|
+
strapi
|
|
27
|
+
.hook('strapi::content-types.afterSync')
|
|
28
|
+
.register(migrateReviewWorkflowStagesColor)
|
|
29
|
+
.register(migrateReviewWorkflowName)
|
|
30
|
+
.register(migrateWorkflowsContentTypes)
|
|
31
|
+
.register(migrateDeletedCTInWorkflows);
|
|
22
32
|
const reviewWorkflowService = getService('review-workflows');
|
|
23
33
|
|
|
24
34
|
reviewWorkflowsMiddlewares.contentTypeMiddleware(strapi);
|
|
25
|
-
await reviewWorkflowService.register();
|
|
35
|
+
await reviewWorkflowService.register(features.get('review-workflows'));
|
|
26
36
|
}
|
|
27
37
|
await executeCERegister({ strapi });
|
|
28
38
|
};
|
|
@@ -7,9 +7,9 @@ module.exports = {
|
|
|
7
7
|
routes: [
|
|
8
8
|
// Review workflow
|
|
9
9
|
{
|
|
10
|
-
method: '
|
|
10
|
+
method: 'POST',
|
|
11
11
|
path: '/review-workflows/workflows',
|
|
12
|
-
handler: 'workflows.
|
|
12
|
+
handler: 'workflows.create',
|
|
13
13
|
config: {
|
|
14
14
|
middlewares: [enableFeatureMiddleware('review-workflows')],
|
|
15
15
|
policies: [
|
|
@@ -17,16 +17,50 @@ module.exports = {
|
|
|
17
17
|
{
|
|
18
18
|
name: 'admin::hasPermissions',
|
|
19
19
|
config: {
|
|
20
|
-
actions: ['admin::review-workflows.
|
|
20
|
+
actions: ['admin::review-workflows.create'],
|
|
21
21
|
},
|
|
22
22
|
},
|
|
23
23
|
],
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
|
-
method: '
|
|
27
|
+
method: 'PUT',
|
|
28
28
|
path: '/review-workflows/workflows/:id',
|
|
29
|
-
handler: 'workflows.
|
|
29
|
+
handler: 'workflows.update',
|
|
30
|
+
config: {
|
|
31
|
+
middlewares: [enableFeatureMiddleware('review-workflows')],
|
|
32
|
+
policies: [
|
|
33
|
+
'admin::isAuthenticatedAdmin',
|
|
34
|
+
{
|
|
35
|
+
name: 'admin::hasPermissions',
|
|
36
|
+
config: {
|
|
37
|
+
actions: ['admin::review-workflows.update'],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
method: 'DELETE',
|
|
45
|
+
path: '/review-workflows/workflows/:id',
|
|
46
|
+
handler: 'workflows.delete',
|
|
47
|
+
config: {
|
|
48
|
+
middlewares: [enableFeatureMiddleware('review-workflows')],
|
|
49
|
+
policies: [
|
|
50
|
+
'admin::isAuthenticatedAdmin',
|
|
51
|
+
{
|
|
52
|
+
name: 'admin::hasPermissions',
|
|
53
|
+
config: {
|
|
54
|
+
actions: ['admin::review-workflows.delete'],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
method: 'GET',
|
|
62
|
+
path: '/review-workflows/workflows',
|
|
63
|
+
handler: 'workflows.find',
|
|
30
64
|
config: {
|
|
31
65
|
middlewares: [enableFeatureMiddleware('review-workflows')],
|
|
32
66
|
policies: [
|
|
@@ -42,8 +76,8 @@ module.exports = {
|
|
|
42
76
|
},
|
|
43
77
|
{
|
|
44
78
|
method: 'GET',
|
|
45
|
-
path: '/review-workflows/workflows/:
|
|
46
|
-
handler: '
|
|
79
|
+
path: '/review-workflows/workflows/:id',
|
|
80
|
+
handler: 'workflows.findById',
|
|
47
81
|
config: {
|
|
48
82
|
middlewares: [enableFeatureMiddleware('review-workflows')],
|
|
49
83
|
policies: [
|
|
@@ -58,9 +92,9 @@ module.exports = {
|
|
|
58
92
|
},
|
|
59
93
|
},
|
|
60
94
|
{
|
|
61
|
-
method: '
|
|
95
|
+
method: 'GET',
|
|
62
96
|
path: '/review-workflows/workflows/:workflow_id/stages',
|
|
63
|
-
handler: 'stages.
|
|
97
|
+
handler: 'stages.find',
|
|
64
98
|
config: {
|
|
65
99
|
middlewares: [enableFeatureMiddleware('review-workflows')],
|
|
66
100
|
policies: [
|
|
@@ -102,7 +136,7 @@ module.exports = {
|
|
|
102
136
|
{
|
|
103
137
|
name: 'admin::hasPermissions',
|
|
104
138
|
config: {
|
|
105
|
-
actions: ['admin::review-workflows.
|
|
139
|
+
actions: ['admin::review-workflows.update'],
|
|
106
140
|
},
|
|
107
141
|
},
|
|
108
142
|
],
|
|
@@ -9,6 +9,7 @@ module.exports = {
|
|
|
9
9
|
workflows: require('./review-workflows/workflows'),
|
|
10
10
|
stages: require('./review-workflows/stages'),
|
|
11
11
|
'review-workflows': require('./review-workflows/review-workflows'),
|
|
12
|
+
'review-workflows-validation': require('./review-workflows/validation'),
|
|
12
13
|
'review-workflows-decorator': require('./review-workflows/entity-service-decorator'),
|
|
13
14
|
'review-workflows-metrics': require('./review-workflows/metrics'),
|
|
14
15
|
};
|
|
@@ -3,17 +3,16 @@
|
|
|
3
3
|
const { isNil, isNull } = require('lodash/fp');
|
|
4
4
|
const { ENTITY_STAGE_ATTRIBUTE } = require('../../constants/workflows');
|
|
5
5
|
const { WORKFLOW_UPDATE_STAGE } = require('../../constants/webhookEvents');
|
|
6
|
-
const {
|
|
6
|
+
const { getService } = require('../../utils');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Assigns the entity data to the default workflow stage if no stage is present in the data
|
|
10
10
|
* @param {Object} data
|
|
11
11
|
* @returns
|
|
12
12
|
*/
|
|
13
|
-
const getDataWithStage = async (data) => {
|
|
13
|
+
const getDataWithStage = async (workflow, data) => {
|
|
14
14
|
if (!isNil(ENTITY_STAGE_ATTRIBUTE, data)) {
|
|
15
|
-
|
|
16
|
-
return { ...data, [ENTITY_STAGE_ATTRIBUTE]: defaultWorkflow.stages[0].id };
|
|
15
|
+
return { ...data, [ENTITY_STAGE_ATTRIBUTE]: workflow.stages[0].id };
|
|
17
16
|
}
|
|
18
17
|
return data;
|
|
19
18
|
};
|
|
@@ -43,22 +42,18 @@ const getEntityStage = async (uid, id) => {
|
|
|
43
42
|
*/
|
|
44
43
|
const decorator = (service) => ({
|
|
45
44
|
async create(uid, opts = {}) {
|
|
46
|
-
const
|
|
45
|
+
const workflow = await getService('workflows').getAssignedWorkflow(uid, {
|
|
46
|
+
populate: 'stages',
|
|
47
|
+
});
|
|
47
48
|
|
|
48
|
-
if (!
|
|
49
|
+
if (!workflow) {
|
|
49
50
|
return service.create.call(this, uid, opts);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
const data = await getDataWithStage(opts.data);
|
|
53
|
+
const data = await getDataWithStage(workflow, opts.data);
|
|
53
54
|
return service.create.call(this, uid, { ...opts, data });
|
|
54
55
|
},
|
|
55
56
|
async update(uid, entityId, opts = {}) {
|
|
56
|
-
const hasRW = hasReviewWorkflow({ strapi }, uid);
|
|
57
|
-
|
|
58
|
-
if (!hasRW) {
|
|
59
|
-
return service.update.call(this, uid, entityId, opts);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
57
|
// Prevents the stage from being set to null
|
|
63
58
|
const data = { ...opts.data };
|
|
64
59
|
if (isNull(data[ENTITY_STAGE_ATTRIBUTE])) {
|
|
@@ -1,41 +1,57 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { set, forEach, pipe, map } = require('lodash/fp');
|
|
4
|
-
const { mapAsync } = require('@strapi/utils');
|
|
3
|
+
const { filter, set, forEach, pipe, map, stubTrue, cond, defaultsDeep } = require('lodash/fp');
|
|
5
4
|
const { getService } = require('../../utils');
|
|
6
|
-
const {
|
|
5
|
+
const { getVisibleContentTypesUID, hasStageAttribute } = require('../../utils/review-workflows');
|
|
7
6
|
|
|
8
7
|
const defaultStages = require('../../constants/default-stages.json');
|
|
9
8
|
const defaultWorkflow = require('../../constants/default-workflow.json');
|
|
10
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
ENTITY_STAGE_ATTRIBUTE,
|
|
11
|
+
MAX_WORKFLOWS,
|
|
12
|
+
MAX_STAGES_PER_WORKFLOW,
|
|
13
|
+
} = require('../../constants/workflows');
|
|
11
14
|
|
|
12
|
-
const { getDefaultWorkflow } = require('../../utils/review-workflows');
|
|
13
15
|
const { persistTables, removePersistedTablesWithSuffix } = require('../../utils/persisted-tables');
|
|
14
16
|
const webhookEvents = require('../../constants/webhookEvents');
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
const MAX_DB_TABLE_NAME_LEN = 63; // Postgres limit
|
|
19
|
+
// The longest index name that Strapi can create is prefixed with '_strapi_stage_links_inv_fk', so the content type name should be no longer than this.
|
|
20
|
+
const MAX_JOIN_TABLE_NAME_SUFFIX =
|
|
21
|
+
1 /* _ */ + ENTITY_STAGE_ATTRIBUTE.length + '_links_inv_fk'.length;
|
|
22
|
+
const MAX_CONTENT_TYPE_NAME_LEN = MAX_DB_TABLE_NAME_LEN - MAX_JOIN_TABLE_NAME_SUFFIX;
|
|
23
|
+
|
|
24
|
+
const DEFAULT_OPTIONS = {
|
|
25
|
+
workflows: MAX_WORKFLOWS,
|
|
26
|
+
stagesPerWorkflow: MAX_STAGES_PER_WORKFLOW,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
async function initDefaultWorkflow({ workflowsService, stagesService }) {
|
|
17
30
|
const wfCount = await workflowsService.count();
|
|
18
31
|
const stagesCount = await stagesService.count();
|
|
19
32
|
|
|
20
33
|
// Check if there is nothing about review-workflow in DB
|
|
21
34
|
// If any, the feature has already been initialized with a workflow and stages
|
|
22
35
|
if (wfCount === 0 && stagesCount === 0) {
|
|
23
|
-
const stages = await stagesService.createMany(defaultStages, { fields: ['id'] });
|
|
24
36
|
const workflow = {
|
|
25
37
|
...defaultWorkflow,
|
|
26
|
-
stages:
|
|
27
|
-
connect: stages.map((stage) => stage.id),
|
|
28
|
-
},
|
|
38
|
+
stages: defaultStages,
|
|
29
39
|
};
|
|
30
40
|
|
|
31
|
-
await workflowsService.create(workflow);
|
|
32
|
-
// If there is any manually activated RW on content-types, we want to migrate the related entities
|
|
33
|
-
await enableReviewWorkflow({ strapi })({ contentTypes: strapi.contentTypes });
|
|
41
|
+
await workflowsService.create({ data: workflow });
|
|
34
42
|
}
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
function extendReviewWorkflowContentTypes({ strapi }) {
|
|
38
46
|
const extendContentType = (contentTypeUID) => {
|
|
47
|
+
const assertContentTypeCompatibility = (contentType) =>
|
|
48
|
+
contentType.collectionName.length <= MAX_CONTENT_TYPE_NAME_LEN;
|
|
49
|
+
const incompatibleContentTypeAlert = (contentType) => {
|
|
50
|
+
strapi.log.warn(
|
|
51
|
+
`Review Workflow cannot be activated for the content type with the name '${contentType.info.displayName}' because the name exceeds the maximum length of ${MAX_CONTENT_TYPE_NAME_LEN} characters.`
|
|
52
|
+
);
|
|
53
|
+
return contentType;
|
|
54
|
+
};
|
|
39
55
|
const setStageAttribute = set(`attributes.${ENTITY_STAGE_ATTRIBUTE}`, {
|
|
40
56
|
writable: true,
|
|
41
57
|
private: false,
|
|
@@ -46,49 +62,21 @@ function extendReviewWorkflowContentTypes({ strapi }) {
|
|
|
46
62
|
relation: 'oneToOne',
|
|
47
63
|
target: 'admin::workflow-stage',
|
|
48
64
|
});
|
|
49
|
-
|
|
65
|
+
|
|
66
|
+
const extendContentTypeIfCompatible = cond([
|
|
67
|
+
[assertContentTypeCompatibility, setStageAttribute],
|
|
68
|
+
[stubTrue, incompatibleContentTypeAlert],
|
|
69
|
+
]);
|
|
70
|
+
strapi.container.get('content-types').extend(contentTypeUID, extendContentTypeIfCompatible);
|
|
50
71
|
};
|
|
72
|
+
|
|
51
73
|
pipe([
|
|
52
|
-
|
|
74
|
+
getVisibleContentTypesUID,
|
|
53
75
|
// Iterate over UIDs to extend the content-type
|
|
54
76
|
forEach(extendContentType),
|
|
55
77
|
])(strapi.contentTypes);
|
|
56
78
|
}
|
|
57
79
|
|
|
58
|
-
/**
|
|
59
|
-
* Enables the review workflow for the given content types.
|
|
60
|
-
* @param {Object} strapi - Strapi instance
|
|
61
|
-
*/
|
|
62
|
-
function enableReviewWorkflow({ strapi }) {
|
|
63
|
-
/**
|
|
64
|
-
* @param {Array<string>} contentTypes - Content type UIDs to enable the review workflow for.
|
|
65
|
-
* @returns {Promise<void>} - Promise that resolves when the review workflow is enabled.
|
|
66
|
-
*/
|
|
67
|
-
return async ({ contentTypes }) => {
|
|
68
|
-
const defaultWorkflow = await getDefaultWorkflow({ strapi });
|
|
69
|
-
// This is possible if this is the first start of EE, there won't be any workflow in DB before bootstrap
|
|
70
|
-
if (!defaultWorkflow) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
const firstStage = defaultWorkflow.stages[0];
|
|
74
|
-
const stagesService = getService('stages', { strapi });
|
|
75
|
-
|
|
76
|
-
const updateEntitiesStage = async (contentTypeUID) => {
|
|
77
|
-
// Update CT entities stage
|
|
78
|
-
return stagesService.updateEntitiesStage(contentTypeUID, {
|
|
79
|
-
fromStageId: null,
|
|
80
|
-
toStageId: firstStage.id,
|
|
81
|
-
});
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
return pipe([
|
|
85
|
-
getContentTypeUIDsWithActivatedReviewWorkflows,
|
|
86
|
-
// Iterate over UIDs to extend the content-type
|
|
87
|
-
(contentTypesUIDs) => mapAsync(contentTypesUIDs, updateEntitiesStage),
|
|
88
|
-
])(contentTypes);
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
80
|
function persistStagesJoinTables({ strapi }) {
|
|
93
81
|
return async ({ contentTypes }) => {
|
|
94
82
|
const getStageTableToPersist = (contentTypeUID) => {
|
|
@@ -99,12 +87,13 @@ function persistStagesJoinTables({ strapi }) {
|
|
|
99
87
|
};
|
|
100
88
|
|
|
101
89
|
const joinTablesToPersist = pipe([
|
|
102
|
-
|
|
90
|
+
getVisibleContentTypesUID,
|
|
91
|
+
filter((uid) => hasStageAttribute(contentTypes[uid])),
|
|
103
92
|
map(getStageTableToPersist),
|
|
104
93
|
])(contentTypes);
|
|
105
94
|
|
|
106
95
|
// TODO: Instead of removing all the tables, we should only remove the ones that are not in the joinTablesToPersist
|
|
107
|
-
await removePersistedTablesWithSuffix('
|
|
96
|
+
await removePersistedTablesWithSuffix('_strapi_stage_links');
|
|
108
97
|
await persistTables(joinTablesToPersist);
|
|
109
98
|
};
|
|
110
99
|
}
|
|
@@ -117,16 +106,19 @@ const registerWebhookEvents = async ({ strapi }) =>
|
|
|
117
106
|
module.exports = ({ strapi }) => {
|
|
118
107
|
const workflowsService = getService('workflows', { strapi });
|
|
119
108
|
const stagesService = getService('stages', { strapi });
|
|
109
|
+
const workflowsValidationService = getService('review-workflows-validation', { strapi });
|
|
120
110
|
|
|
121
111
|
return {
|
|
122
112
|
async bootstrap() {
|
|
123
113
|
await registerWebhookEvents({ strapi });
|
|
124
114
|
await initDefaultWorkflow({ workflowsService, stagesService, strapi });
|
|
125
115
|
},
|
|
126
|
-
async register() {
|
|
116
|
+
async register({ options } = { options: {} }) {
|
|
127
117
|
extendReviewWorkflowContentTypes({ strapi });
|
|
128
|
-
strapi.hook('strapi::content-types.afterSync').register(enableReviewWorkflow({ strapi }));
|
|
129
118
|
strapi.hook('strapi::content-types.afterSync').register(persistStagesJoinTables({ strapi }));
|
|
119
|
+
|
|
120
|
+
const reviewWorkflowsOptions = defaultsDeep(DEFAULT_OPTIONS, options);
|
|
121
|
+
workflowsValidationService.register(reviewWorkflowsOptions);
|
|
130
122
|
},
|
|
131
123
|
};
|
|
132
124
|
};
|