@strapi/review-workflows 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6 → 0.0.0-experimental.f49f46a1c17445a39e8af3f63124bcccf73842e6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{Layout-Cwbb9usb.js → Layout-B4fpKB9J.js} +8 -9
- package/dist/_chunks/Layout-B4fpKB9J.js.map +1 -0
- package/dist/_chunks/{Layout-BpMLb-Oo.mjs → Layout-Dko22Aly.mjs} +8 -9
- package/dist/_chunks/Layout-Dko22Aly.mjs.map +1 -0
- package/dist/_chunks/{en-xcewH2pC.js → en-CYgjfSep.js} +5 -2
- package/dist/_chunks/en-CYgjfSep.js.map +1 -0
- package/dist/_chunks/{en-D9ZrQAV6.mjs → en-D9dxziEb.mjs} +5 -2
- package/dist/_chunks/en-D9dxziEb.mjs.map +1 -0
- package/dist/_chunks/{_id-p9NnvlMP.js → id-BKq7JAqZ.js} +82 -49
- package/dist/_chunks/id-BKq7JAqZ.js.map +1 -0
- package/dist/_chunks/{_id-KpezMzxO.mjs → id-DINFSsrh.mjs} +82 -49
- package/dist/_chunks/id-DINFSsrh.mjs.map +1 -0
- package/dist/_chunks/{index-DqT_oXGP.js → index-BpIILEs0.js} +9 -29
- package/dist/_chunks/index-BpIILEs0.js.map +1 -0
- package/dist/_chunks/{index-BTr8zF-9.js → index-BpL7C1EG.js} +54 -71
- package/dist/_chunks/index-BpL7C1EG.js.map +1 -0
- package/dist/_chunks/{index-DtJI5ZoC.mjs → index-DAcEdoqJ.mjs} +55 -72
- package/dist/_chunks/index-DAcEdoqJ.mjs.map +1 -0
- package/dist/_chunks/{index-BxkGN0Yj.mjs → index-ZcZKwmTD.mjs} +11 -31
- package/dist/_chunks/index-ZcZKwmTD.mjs.map +1 -0
- package/dist/_chunks/{router-B8G2sh6V.mjs → router-BPH_u176.mjs} +3 -3
- package/dist/_chunks/router-BPH_u176.mjs.map +1 -0
- package/dist/_chunks/{router-Bqj-105s.js → router-DeEgX8Ao.js} +3 -3
- package/dist/_chunks/router-DeEgX8Ao.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/services/settings.d.ts +1737 -7
- package/dist/server/index.js +180 -108
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +180 -108
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/constants/workflows.d.ts +1 -0
- package/dist/server/src/constants/workflows.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +6 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/workflow/index.d.ts +6 -0
- package/dist/server/src/content-types/workflow/index.d.ts.map +1 -1
- package/dist/server/src/controllers/assignees.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +0 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/stages.d.ts.map +1 -1
- package/dist/server/src/controllers/workflows.d.ts +0 -7
- package/dist/server/src/controllers/workflows.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +28 -7
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/review-workflows.d.ts.map +1 -1
- package/dist/server/src/services/assignees.d.ts +8 -4
- package/dist/server/src/services/assignees.d.ts.map +1 -1
- package/dist/server/src/services/document-service-middleware.d.ts +1 -0
- package/dist/server/src/services/document-service-middleware.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +16 -6
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics/index.d.ts +4 -4
- package/dist/server/src/services/metrics/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics/weekly-metrics.d.ts.map +1 -1
- package/dist/server/src/services/stages.d.ts +7 -7
- package/dist/server/src/services/stages.d.ts.map +1 -1
- package/dist/server/src/services/workflows.d.ts.map +1 -1
- package/dist/server/src/validation/review-workflows.d.ts +4 -0
- package/dist/server/src/validation/review-workflows.d.ts.map +1 -1
- package/dist/shared/contracts/review-workflows.d.ts +9 -17
- package/dist/shared/contracts/review-workflows.d.ts.map +1 -1
- package/package.json +12 -12
- package/dist/_chunks/Layout-BpMLb-Oo.mjs.map +0 -1
- package/dist/_chunks/Layout-Cwbb9usb.js.map +0 -1
- package/dist/_chunks/_id-KpezMzxO.mjs.map +0 -1
- package/dist/_chunks/_id-p9NnvlMP.js.map +0 -1
- package/dist/_chunks/en-D9ZrQAV6.mjs.map +0 -1
- package/dist/_chunks/en-xcewH2pC.js.map +0 -1
- package/dist/_chunks/index-BTr8zF-9.js.map +0 -1
- package/dist/_chunks/index-BxkGN0Yj.mjs.map +0 -1
- package/dist/_chunks/index-DqT_oXGP.js.map +0 -1
- package/dist/_chunks/index-DtJI5ZoC.mjs.map +0 -1
- package/dist/_chunks/router-B8G2sh6V.mjs.map +0 -1
- package/dist/_chunks/router-Bqj-105s.js.map +0 -1
- package/strapi-server.js +0 -3
- /package/dist/admin/src/routes/settings/{:id.d.ts → id.d.ts} +0 -0
package/dist/server/index.js
CHANGED
|
@@ -6387,7 +6387,8 @@ const WORKFLOW_POPULATE = {
|
|
|
6387
6387
|
}
|
|
6388
6388
|
}
|
|
6389
6389
|
}
|
|
6390
|
-
}
|
|
6390
|
+
},
|
|
6391
|
+
stageRequiredToPublish: true
|
|
6391
6392
|
};
|
|
6392
6393
|
function checkVersionThreshold(startVersion, currentVersion, thresholdVersion) {
|
|
6393
6394
|
return semver$1.gte(currentVersion, thresholdVersion) && semver$1.lt(startVersion, thresholdVersion);
|
|
@@ -6562,8 +6563,40 @@ function extendReviewWorkflowContentTypes({ strapi: strapi2 }) {
|
|
|
6562
6563
|
});
|
|
6563
6564
|
}
|
|
6564
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
|
+
}
|
|
6565
6597
|
const register = async ({ strapi: strapi2 }) => {
|
|
6566
6598
|
strapi2.hook("strapi::content-types.beforeSync").register(migrateStageAttribute);
|
|
6599
|
+
strapi2.hook("strapi::content-types.afterSync").register(persistRWOnDowngrade({ strapi: strapi2 }));
|
|
6567
6600
|
strapi2.hook("strapi::content-types.afterSync").register(migrateReviewWorkflowStagesColor).register(migrateReviewWorkflowStagesRoles).register(migrateReviewWorkflowName).register(migrateWorkflowsContentTypes).register(migrateDeletedCTInWorkflows);
|
|
6568
6601
|
reviewWorkflowsMiddlewares.contentTypeMiddleware(strapi2);
|
|
6569
6602
|
extendReviewWorkflowContentTypes({ strapi: strapi2 });
|
|
@@ -6608,6 +6641,12 @@ const workflow = {
|
|
|
6608
6641
|
relation: "oneToMany",
|
|
6609
6642
|
mappedBy: "workflow"
|
|
6610
6643
|
},
|
|
6644
|
+
stageRequiredToPublish: {
|
|
6645
|
+
type: "relation",
|
|
6646
|
+
target: "plugin::review-workflows.workflow-stage",
|
|
6647
|
+
relation: "oneToOne",
|
|
6648
|
+
required: false
|
|
6649
|
+
},
|
|
6611
6650
|
contentTypes: {
|
|
6612
6651
|
type: "json",
|
|
6613
6652
|
required: true,
|
|
@@ -6757,6 +6796,7 @@ const bootstrap = async (args) => {
|
|
|
6757
6796
|
const docsMiddlewares = getService("document-service-middlewares");
|
|
6758
6797
|
strapi.documents.use(docsMiddlewares.assignStageOnCreate);
|
|
6759
6798
|
strapi.documents.use(docsMiddlewares.handleStageOnUpdate);
|
|
6799
|
+
strapi.documents.use(docsMiddlewares.checkStageBeforePublish);
|
|
6760
6800
|
};
|
|
6761
6801
|
const destroy = async ({ strapi: strapi2 }) => {
|
|
6762
6802
|
};
|
|
@@ -6838,23 +6878,6 @@ const reviewWorkflows = {
|
|
|
6838
6878
|
]
|
|
6839
6879
|
}
|
|
6840
6880
|
},
|
|
6841
|
-
{
|
|
6842
|
-
method: "GET",
|
|
6843
|
-
path: "/workflows/:id",
|
|
6844
|
-
handler: "workflows.findById",
|
|
6845
|
-
config: {
|
|
6846
|
-
middlewares: [enableFeatureMiddleware("review-workflows")],
|
|
6847
|
-
policies: [
|
|
6848
|
-
"admin::isAuthenticatedAdmin",
|
|
6849
|
-
{
|
|
6850
|
-
name: "admin::hasPermissions",
|
|
6851
|
-
config: {
|
|
6852
|
-
actions: ["admin::review-workflows.read"]
|
|
6853
|
-
}
|
|
6854
|
-
}
|
|
6855
|
-
]
|
|
6856
|
-
}
|
|
6857
|
-
},
|
|
6858
6881
|
{
|
|
6859
6882
|
method: "GET",
|
|
6860
6883
|
path: "/workflows/:workflow_id/stages",
|
|
@@ -6918,7 +6941,7 @@ const reviewWorkflows = {
|
|
|
6918
6941
|
{
|
|
6919
6942
|
name: "admin::hasPermissions",
|
|
6920
6943
|
config: {
|
|
6921
|
-
actions: ["admin::users.read"
|
|
6944
|
+
actions: ["admin::users.read"]
|
|
6922
6945
|
}
|
|
6923
6946
|
}
|
|
6924
6947
|
]
|
|
@@ -7006,9 +7029,9 @@ const processFilters = ({ strapi: strapi2 }, filters = {}) => {
|
|
|
7006
7029
|
};
|
|
7007
7030
|
const processPopulate = (populate) => {
|
|
7008
7031
|
if (!populate) {
|
|
7009
|
-
return
|
|
7032
|
+
return WORKFLOW_POPULATE;
|
|
7010
7033
|
}
|
|
7011
|
-
return
|
|
7034
|
+
return populate;
|
|
7012
7035
|
};
|
|
7013
7036
|
const workflows$1 = ({ strapi: strapi2 }) => {
|
|
7014
7037
|
const workflowsContentTypes = workflowsContentTypesFactory({ strapi: strapi2 });
|
|
@@ -7059,14 +7082,27 @@ const workflows$1 = ({ strapi: strapi2 }) => {
|
|
|
7059
7082
|
const stages2 = await getService("stages", { strapi: strapi2 }).createMany(opts.data.stages);
|
|
7060
7083
|
const mapIds = fp.map(fp.get("id"));
|
|
7061
7084
|
createOpts = fp.set("data.stages", mapIds(stages2), createOpts);
|
|
7085
|
+
if (opts.data.stageRequiredToPublishName) {
|
|
7086
|
+
const stageRequiredToPublish = stages2.find(
|
|
7087
|
+
(stage) => stage.name === opts.data.stageRequiredToPublishName
|
|
7088
|
+
);
|
|
7089
|
+
if (!stageRequiredToPublish) {
|
|
7090
|
+
throw new utils.errors.ApplicationError("Stage required to publish does not exist");
|
|
7091
|
+
}
|
|
7092
|
+
createOpts = fp.set("data.stageRequiredToPublish", stageRequiredToPublish.id, createOpts);
|
|
7093
|
+
}
|
|
7062
7094
|
if (opts.data.contentTypes) {
|
|
7063
7095
|
await workflowsContentTypes.migrate({
|
|
7064
7096
|
destContentTypes: opts.data.contentTypes,
|
|
7065
7097
|
stageId: stages2[0].id
|
|
7066
7098
|
});
|
|
7067
7099
|
}
|
|
7068
|
-
|
|
7069
|
-
|
|
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
|
/**
|
|
@@ -7079,6 +7115,7 @@ const workflows$1 = ({ strapi: strapi2 }) => {
|
|
|
7079
7115
|
async update(workflow2, opts) {
|
|
7080
7116
|
const stageService = getService("stages", { strapi: strapi2 });
|
|
7081
7117
|
let updateOpts = { ...opts, populate: { ...WORKFLOW_POPULATE } };
|
|
7118
|
+
let updatedStages = [];
|
|
7082
7119
|
let updatedStageIds;
|
|
7083
7120
|
await workflowValidator.validateWorkflowCount();
|
|
7084
7121
|
return strapi2.db.transaction(async () => {
|
|
@@ -7087,9 +7124,28 @@ const workflows$1 = ({ strapi: strapi2 }) => {
|
|
|
7087
7124
|
opts.data.stages.forEach(
|
|
7088
7125
|
(stage) => this.assertStageBelongsToWorkflow(stage.id, workflow2)
|
|
7089
7126
|
);
|
|
7090
|
-
|
|
7127
|
+
updatedStages = await stageService.replaceStages(
|
|
7128
|
+
workflow2.stages,
|
|
7129
|
+
opts.data.stages,
|
|
7130
|
+
workflow2.contentTypes
|
|
7131
|
+
);
|
|
7132
|
+
updatedStageIds = updatedStages.map((stage) => stage.id);
|
|
7091
7133
|
updateOpts = fp.set("data.stages", updatedStageIds, updateOpts);
|
|
7092
7134
|
}
|
|
7135
|
+
if (opts.data.stageRequiredToPublishName !== void 0) {
|
|
7136
|
+
const stages2 = updatedStages ?? workflow2.stages;
|
|
7137
|
+
if (opts.data.stageRequiredToPublishName === null) {
|
|
7138
|
+
updateOpts = fp.set("data.stageRequiredToPublish", null, updateOpts);
|
|
7139
|
+
} else {
|
|
7140
|
+
const stageRequiredToPublish = stages2.find(
|
|
7141
|
+
(stage) => stage.name === opts.data.stageRequiredToPublishName
|
|
7142
|
+
);
|
|
7143
|
+
if (!stageRequiredToPublish) {
|
|
7144
|
+
throw new utils.errors.ApplicationError("Stage required to publish does not exist");
|
|
7145
|
+
}
|
|
7146
|
+
updateOpts = fp.set("data.stageRequiredToPublish", stageRequiredToPublish.id, updateOpts);
|
|
7147
|
+
}
|
|
7148
|
+
}
|
|
7093
7149
|
if (opts.data.contentTypes) {
|
|
7094
7150
|
await workflowsContentTypes.migrate({
|
|
7095
7151
|
srcContentTypes: workflow2.contentTypes,
|
|
@@ -7097,12 +7153,17 @@ const workflows$1 = ({ strapi: strapi2 }) => {
|
|
|
7097
7153
|
stageId: updatedStageIds ? updatedStageIds[0] : workflow2.stages[0].id
|
|
7098
7154
|
});
|
|
7099
7155
|
}
|
|
7100
|
-
metrics.sendDidEditWorkflow();
|
|
7156
|
+
metrics.sendDidEditWorkflow(workflow2.id, !!opts.data.stageRequiredToPublishName);
|
|
7101
7157
|
const query = strapi2.get("query-params").transform(WORKFLOW_MODEL_UID, updateOpts);
|
|
7102
|
-
|
|
7158
|
+
const updatedWorkflow = await strapi2.db.query(WORKFLOW_MODEL_UID).update({
|
|
7103
7159
|
...query,
|
|
7104
7160
|
where: { id: workflow2.id }
|
|
7105
7161
|
});
|
|
7162
|
+
await strapi2.plugin("content-releases").service("release-action").validateActionsByContentTypes([
|
|
7163
|
+
...workflow2.contentTypes,
|
|
7164
|
+
...opts.data.contentTypes || []
|
|
7165
|
+
]);
|
|
7166
|
+
return updatedWorkflow;
|
|
7106
7167
|
});
|
|
7107
7168
|
},
|
|
7108
7169
|
/**
|
|
@@ -7125,10 +7186,12 @@ const workflows$1 = ({ strapi: strapi2 }) => {
|
|
|
7125
7186
|
destContentTypes: []
|
|
7126
7187
|
});
|
|
7127
7188
|
const query = strapi2.get("query-params").transform(WORKFLOW_MODEL_UID, opts);
|
|
7128
|
-
|
|
7189
|
+
const deletedWorkflow = await strapi2.db.query(WORKFLOW_MODEL_UID).delete({
|
|
7129
7190
|
...query,
|
|
7130
7191
|
where: { id: workflow2.id }
|
|
7131
7192
|
});
|
|
7193
|
+
await strapi2.plugin("content-releases").service("release-action").validateActionsByContentTypes(workflow2.contentTypes);
|
|
7194
|
+
return deletedWorkflow;
|
|
7132
7195
|
});
|
|
7133
7196
|
},
|
|
7134
7197
|
/**
|
|
@@ -7339,25 +7402,26 @@ const stages$1 = ({ strapi: strapi2 }) => {
|
|
|
7339
7402
|
},
|
|
7340
7403
|
/**
|
|
7341
7404
|
* Update the stage of an entity
|
|
7342
|
-
*
|
|
7343
|
-
* @param {object} entityInfo
|
|
7344
|
-
* @param {number} entityInfo.id - Entity id
|
|
7345
|
-
* @param {string} entityInfo.modelUID - the content-type of the entity
|
|
7346
|
-
* @param {number} stageId - The id of the stage to assign to the entity
|
|
7347
7405
|
*/
|
|
7348
|
-
async updateEntity(
|
|
7406
|
+
async updateEntity(entityToUpdate, model, stageId) {
|
|
7349
7407
|
const stage = await this.findById(stageId);
|
|
7408
|
+
const { documentId, locale } = entityToUpdate;
|
|
7350
7409
|
await workflowValidator.validateWorkflowCount();
|
|
7351
7410
|
if (!stage) {
|
|
7352
7411
|
throw new ApplicationError$2(`Selected stage does not exist`);
|
|
7353
7412
|
}
|
|
7354
|
-
const entity = await strapi2.
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7413
|
+
const entity = await strapi2.documents(model).update({
|
|
7414
|
+
documentId,
|
|
7415
|
+
locale,
|
|
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) },
|
|
7359
7419
|
populate: [ENTITY_STAGE_ATTRIBUTE]
|
|
7360
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
|
+
});
|
|
7361
7425
|
metrics.sendDidChangeEntryStage();
|
|
7362
7426
|
return entity;
|
|
7363
7427
|
},
|
|
@@ -7504,32 +7568,28 @@ const assignees$1 = ({ strapi: strapi2 }) => {
|
|
|
7504
7568
|
/**
|
|
7505
7569
|
* Update the assignee of an entity
|
|
7506
7570
|
*/
|
|
7507
|
-
async updateEntityAssignee(
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
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
|
+
}
|
|
7514
7578
|
}
|
|
7515
|
-
|
|
7516
|
-
|
|
7579
|
+
const oldAssigneeId = await this.findEntityAssigneeId(entityToUpdate.id, model);
|
|
7580
|
+
metrics.sendDidEditAssignee(oldAssigneeId, assigneeId || null);
|
|
7581
|
+
const entity = await strapi2.documents(model).update({
|
|
7517
7582
|
documentId,
|
|
7518
7583
|
locale,
|
|
7519
|
-
data: { [ENTITY_ASSIGNEE_ATTRIBUTE]: assigneeId },
|
|
7584
|
+
data: { [ENTITY_ASSIGNEE_ATTRIBUTE]: assigneeId || null },
|
|
7520
7585
|
populate: [ENTITY_ASSIGNEE_ATTRIBUTE],
|
|
7521
7586
|
fields: []
|
|
7522
7587
|
});
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
return strapi2.documents(model).update({
|
|
7527
|
-
documentId,
|
|
7528
|
-
locale,
|
|
7529
|
-
data: { [ENTITY_ASSIGNEE_ATTRIBUTE]: null },
|
|
7530
|
-
populate: [ENTITY_ASSIGNEE_ATTRIBUTE],
|
|
7531
|
-
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)
|
|
7532
7591
|
});
|
|
7592
|
+
return entity;
|
|
7533
7593
|
}
|
|
7534
7594
|
};
|
|
7535
7595
|
};
|
|
@@ -7602,11 +7662,11 @@ const sendDidDeleteStage = async () => {
|
|
|
7602
7662
|
const sendDidChangeEntryStage = async () => {
|
|
7603
7663
|
strapi.telemetry.send("didChangeEntryStage", {});
|
|
7604
7664
|
};
|
|
7605
|
-
const sendDidCreateWorkflow = async () => {
|
|
7606
|
-
strapi.telemetry.send("didCreateWorkflow", {});
|
|
7665
|
+
const sendDidCreateWorkflow = async (workflowId, hasRequiredStageToPublish) => {
|
|
7666
|
+
strapi.telemetry.send("didCreateWorkflow", { workflowId, hasRequiredStageToPublish });
|
|
7607
7667
|
};
|
|
7608
|
-
const sendDidEditWorkflow = async () => {
|
|
7609
|
-
strapi.telemetry.send("didEditWorkflow", {});
|
|
7668
|
+
const sendDidEditWorkflow = async (workflowId, hasRequiredStageToPublish) => {
|
|
7669
|
+
strapi.telemetry.send("didEditWorkflow", { workflowId, hasRequiredStageToPublish });
|
|
7610
7670
|
};
|
|
7611
7671
|
const sendDidEditAssignee = async (fromId, toId) => {
|
|
7612
7672
|
strapi.telemetry.send("didEditAssignee", { from: fromId, to: toId });
|
|
@@ -7631,13 +7691,13 @@ const reviewWorkflowsMetrics = {
|
|
|
7631
7691
|
sendDidSendReviewWorkflowPropertiesOnceAWeek,
|
|
7632
7692
|
sendDidEditAssignee
|
|
7633
7693
|
};
|
|
7634
|
-
function _typeof(
|
|
7694
|
+
function _typeof(o) {
|
|
7635
7695
|
"@babel/helpers - typeof";
|
|
7636
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(
|
|
7637
|
-
return typeof
|
|
7638
|
-
} : function(
|
|
7639
|
-
return
|
|
7640
|
-
}, _typeof(
|
|
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);
|
|
7641
7701
|
}
|
|
7642
7702
|
function toInteger(dirtyNumber) {
|
|
7643
7703
|
if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
|
|
@@ -7772,7 +7832,12 @@ const reviewWorkflowsWeeklyMetrics = ({ strapi: strapi2 }) => {
|
|
|
7772
7832
|
},
|
|
7773
7833
|
async registerCron() {
|
|
7774
7834
|
const weeklySchedule = await this.ensureWeeklyStoredCronSchedule();
|
|
7775
|
-
strapi2.cron.add({
|
|
7835
|
+
strapi2.cron.add({
|
|
7836
|
+
reviewWorkflowsWeekly: {
|
|
7837
|
+
task: this.sendMetrics.bind(this),
|
|
7838
|
+
options: weeklySchedule
|
|
7839
|
+
}
|
|
7840
|
+
});
|
|
7776
7841
|
}
|
|
7777
7842
|
};
|
|
7778
7843
|
};
|
|
@@ -7828,6 +7893,7 @@ const handleStageOnUpdate = async (ctx, next) => {
|
|
|
7828
7893
|
strapi.eventHub.emit(WORKFLOW_UPDATE_STAGE, {
|
|
7829
7894
|
model: model.modelName,
|
|
7830
7895
|
uid: model.uid,
|
|
7896
|
+
// TODO v6: Rename to "entry", which is what is used for regular CRUD updates
|
|
7831
7897
|
entity: {
|
|
7832
7898
|
// @ts-expect-error
|
|
7833
7899
|
id: result?.id,
|
|
@@ -7853,9 +7919,27 @@ const handleStageOnUpdate = async (ctx, next) => {
|
|
|
7853
7919
|
}
|
|
7854
7920
|
return next();
|
|
7855
7921
|
};
|
|
7922
|
+
const checkStageBeforePublish = async (ctx, next) => {
|
|
7923
|
+
if (ctx.action !== "publish") {
|
|
7924
|
+
return next();
|
|
7925
|
+
}
|
|
7926
|
+
const workflow2 = await getService("workflows").getAssignedWorkflow(ctx.contentType.uid, {
|
|
7927
|
+
populate: "stageRequiredToPublish"
|
|
7928
|
+
});
|
|
7929
|
+
if (!workflow2 || !workflow2.stageRequiredToPublish) {
|
|
7930
|
+
return next();
|
|
7931
|
+
}
|
|
7932
|
+
const { documentId } = ctx.params;
|
|
7933
|
+
const entryStage = await getEntityStage(ctx.contentType.uid, documentId, ctx.params);
|
|
7934
|
+
if (entryStage.id !== workflow2.stageRequiredToPublish.id) {
|
|
7935
|
+
throw new utils.errors.ValidationError("Entry is not at the required stage to publish");
|
|
7936
|
+
}
|
|
7937
|
+
return next();
|
|
7938
|
+
};
|
|
7856
7939
|
const documentServiceMiddleware = () => ({
|
|
7857
7940
|
assignStageOnCreate,
|
|
7858
|
-
handleStageOnUpdate
|
|
7941
|
+
handleStageOnUpdate,
|
|
7942
|
+
checkStageBeforePublish
|
|
7859
7943
|
});
|
|
7860
7944
|
const services = {
|
|
7861
7945
|
workflows: workflows$1,
|
|
@@ -7905,12 +7989,14 @@ const validateContentTypes = utils.yup.array().of(
|
|
|
7905
7989
|
const validateWorkflowCreateSchema = utils.yup.object().shape({
|
|
7906
7990
|
name: utils.yup.string().max(255).min(1, "Workflow name can not be empty").required(),
|
|
7907
7991
|
stages: utils.yup.array().of(stageObject).uniqueProperty("name", "Stage name must be unique").min(1, "Can not create a workflow without stages").max(200, "Can not have more than 200 stages").required("Can not create a workflow without stages"),
|
|
7908
|
-
contentTypes: validateContentTypes
|
|
7992
|
+
contentTypes: validateContentTypes,
|
|
7993
|
+
stageRequiredToPublishName: utils.yup.string().min(1).nullable()
|
|
7909
7994
|
});
|
|
7910
7995
|
const validateWorkflowUpdateSchema = utils.yup.object().shape({
|
|
7911
7996
|
name: utils.yup.string().max(255).min(1, "Workflow name can not be empty"),
|
|
7912
7997
|
stages: utils.yup.array().of(stageObject).uniqueProperty("name", "Stage name must be unique").min(1, "Can not update a workflow without stages").max(200, "Can not have more than 200 stages"),
|
|
7913
|
-
contentTypes: validateContentTypes
|
|
7998
|
+
contentTypes: validateContentTypes,
|
|
7999
|
+
stageRequiredToPublishName: utils.yup.string().min(1).nullable()
|
|
7914
8000
|
});
|
|
7915
8001
|
const validateUpdateAssigneeOnEntitySchema = utils.yup.object().shape({
|
|
7916
8002
|
id: utils.yup.number().integer().min(1).nullable()
|
|
@@ -8029,30 +8115,6 @@ const workflows = {
|
|
|
8029
8115
|
workflowCount
|
|
8030
8116
|
}
|
|
8031
8117
|
};
|
|
8032
|
-
},
|
|
8033
|
-
/**
|
|
8034
|
-
* Get one workflow based on its id contained in request parameters
|
|
8035
|
-
* Returns count of workflows in meta, used to prevent workflow edition when
|
|
8036
|
-
* max workflow count is reached for the current plan
|
|
8037
|
-
* @param {import('koa').BaseContext} ctx - koa context
|
|
8038
|
-
*/
|
|
8039
|
-
async findById(ctx) {
|
|
8040
|
-
const { id } = ctx.params;
|
|
8041
|
-
const { query } = ctx.request;
|
|
8042
|
-
const { sanitizeOutput, sanitizedQuery } = getWorkflowsPermissionChecker(
|
|
8043
|
-
{ strapi },
|
|
8044
|
-
ctx.state.userAbility
|
|
8045
|
-
);
|
|
8046
|
-
const { populate } = await sanitizedQuery.read(query);
|
|
8047
|
-
const workflowService = getService("workflows");
|
|
8048
|
-
const [workflow2, workflowCount] = await Promise.all([
|
|
8049
|
-
workflowService.findById(id, { populate }).then(formatWorkflowToAdmin),
|
|
8050
|
-
workflowService.count()
|
|
8051
|
-
]);
|
|
8052
|
-
ctx.body = {
|
|
8053
|
-
data: await sanitizeOutput(workflow2),
|
|
8054
|
-
meta: { workflowCount }
|
|
8055
|
-
};
|
|
8056
8118
|
}
|
|
8057
8119
|
};
|
|
8058
8120
|
function sanitizeStage({ strapi: strapi2 }, userAbility) {
|
|
@@ -8137,7 +8199,7 @@ const stages = {
|
|
|
8137
8199
|
);
|
|
8138
8200
|
const workflow2 = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);
|
|
8139
8201
|
workflowService.assertStageBelongsToWorkflow(stageId, workflow2);
|
|
8140
|
-
const updatedEntity = await stagesService.updateEntity(
|
|
8202
|
+
const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);
|
|
8141
8203
|
ctx.body = { data: await sanitizeOutput(updatedEntity) };
|
|
8142
8204
|
},
|
|
8143
8205
|
/**
|
|
@@ -8157,10 +8219,9 @@ const stages = {
|
|
|
8157
8219
|
if (strapi.plugin("content-manager").service("permission-checker").create({ userAbility: ctx.state.userAbility, model: modelUID }).cannot.read()) {
|
|
8158
8220
|
return ctx.forbidden();
|
|
8159
8221
|
}
|
|
8160
|
-
const locale = await validateLocale(query?.locale);
|
|
8222
|
+
const locale = await validateLocale(query?.locale) ?? void 0;
|
|
8161
8223
|
const entity = await strapi.documents(modelUID).findOne({
|
|
8162
8224
|
documentId,
|
|
8163
|
-
// @ts-expect-error - locale should be also null in the doc service types
|
|
8164
8225
|
locale,
|
|
8165
8226
|
populate: [ENTITY_STAGE_ATTRIBUTE]
|
|
8166
8227
|
});
|
|
@@ -8169,12 +8230,13 @@ const stages = {
|
|
|
8169
8230
|
}
|
|
8170
8231
|
const entityStageId = entity[ENTITY_STAGE_ATTRIBUTE]?.id;
|
|
8171
8232
|
const canTransition = stagePermissions2.can(STAGE_TRANSITION_UID, entityStageId);
|
|
8172
|
-
const [workflowCount,
|
|
8233
|
+
const [workflowCount, workflowResult] = await Promise.all([
|
|
8173
8234
|
workflowService.count(),
|
|
8174
8235
|
workflowService.getAssignedWorkflow(modelUID, {
|
|
8175
8236
|
populate: "stages"
|
|
8176
8237
|
})
|
|
8177
8238
|
]);
|
|
8239
|
+
const workflowStages = workflowResult ? workflowResult.stages : [];
|
|
8178
8240
|
const meta = {
|
|
8179
8241
|
stageCount: workflowStages.length,
|
|
8180
8242
|
workflowCount
|
|
@@ -8210,22 +8272,32 @@ const assignees = {
|
|
|
8210
8272
|
async updateEntity(ctx) {
|
|
8211
8273
|
const assigneeService = getService("assignees");
|
|
8212
8274
|
const workflowService = getService("workflows");
|
|
8275
|
+
const stagePermissions2 = getService("stage-permissions");
|
|
8213
8276
|
const { model_uid: model, id: documentId } = ctx.params;
|
|
8214
|
-
const
|
|
8277
|
+
const locale = await validateLocale(ctx.request.query?.locale) ?? void 0;
|
|
8215
8278
|
const { sanitizeOutput } = strapi.plugin("content-manager").service("permission-checker").create({ userAbility: ctx.state.userAbility, model });
|
|
8279
|
+
const entity = await strapi.documents(model).findOne({
|
|
8280
|
+
documentId,
|
|
8281
|
+
locale,
|
|
8282
|
+
populate: [ENTITY_STAGE_ATTRIBUTE]
|
|
8283
|
+
});
|
|
8284
|
+
if (!entity) {
|
|
8285
|
+
ctx.throw(404, "Entity not found");
|
|
8286
|
+
}
|
|
8287
|
+
const canTransitionStage = stagePermissions2.can(
|
|
8288
|
+
STAGE_TRANSITION_UID,
|
|
8289
|
+
entity[ENTITY_STAGE_ATTRIBUTE]?.id
|
|
8290
|
+
);
|
|
8291
|
+
if (!canTransitionStage) {
|
|
8292
|
+
ctx.throw(403, "Stage transition permission is required");
|
|
8293
|
+
}
|
|
8216
8294
|
const { id: assigneeId } = await validateUpdateAssigneeOnEntity(
|
|
8217
8295
|
ctx.request?.body?.data,
|
|
8218
8296
|
"You should pass a valid id to the body of the put request."
|
|
8219
8297
|
);
|
|
8220
|
-
await validateLocale(locale);
|
|
8221
8298
|
await workflowService.assertContentTypeBelongsToWorkflow(model);
|
|
8222
|
-
const
|
|
8223
|
-
|
|
8224
|
-
locale || null,
|
|
8225
|
-
model,
|
|
8226
|
-
assigneeId
|
|
8227
|
-
);
|
|
8228
|
-
ctx.body = { data: await sanitizeOutput(entity) };
|
|
8299
|
+
const updatedEntity = await assigneeService.updateEntityAssignee(entity, model, assigneeId);
|
|
8300
|
+
ctx.body = { data: await sanitizeOutput(updatedEntity) };
|
|
8229
8301
|
}
|
|
8230
8302
|
};
|
|
8231
8303
|
const controllers = {
|