feat(review-workflows): remove deleted content-types in assigned workflows (#17053)

* feat(review-workflows): migrate old to new stage attribute name

* feat(reviewWorkflows): remove ct from workflows when deleted

* fix(operators): re-add $jsonSupersetOf to available operators
This commit is contained in:
Nathan Pichon 2023-06-23 17:18:32 +02:00 committed by GitHub
parent 136f107436
commit b4ac2f90d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 12 deletions

View File

@ -0,0 +1,39 @@
'use strict';
const { difference, keys } = require('lodash/fp');
const { mapAsync } = require('@strapi/utils');
const { WORKFLOW_MODEL_UID } = require('../constants/workflows');
const { getWorkflowContentTypeFilter } = require('../utils/review-workflows');
/**
* @param {Object} oldContentTypes
* @param {Object} contentTypes
* @return {Promise<void>}
*/
async function migrateDeletedCTInWorkflows({ oldContentTypes, contentTypes }) {
const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];
if (deletedContentTypes.length) {
await mapAsync(deletedContentTypes, async (deletedContentTypeUID) => {
const workflow = await strapi.query(WORKFLOW_MODEL_UID).findOne({
select: ['id', 'contentTypes'],
where: {
contentTypes: getWorkflowContentTypeFilter({ strapi }, deletedContentTypeUID),
},
});
if (workflow) {
await strapi.query(WORKFLOW_MODEL_UID).update({
where: { id: workflow.id },
data: {
contentTypes: workflow.contentTypes.filter(
(contentTypeUID) => contentTypeUID !== deletedContentTypeUID
),
},
});
}
});
}
}
module.exports = migrateDeletedCTInWorkflows;

View File

@ -7,6 +7,7 @@ const migrateReviewWorkflowStagesColor = require('./migrations/review-workflows-
const migrateReviewWorkflowName = require('./migrations/review-workflows-workflow-name'); const migrateReviewWorkflowName = require('./migrations/review-workflows-workflow-name');
const migrateWorkflowsContentTypes = require('./migrations/review-workflows-content-types'); const migrateWorkflowsContentTypes = require('./migrations/review-workflows-content-types');
const migrateStageAttribute = require('./migrations/review-workflows-stage-attribute'); const migrateStageAttribute = require('./migrations/review-workflows-stage-attribute');
const migrateDeletedCTInWorkflows = require('./migrations/review-workflows-deleted-ct-in-workflows');
const createAuditLogsService = require('./services/audit-logs'); const createAuditLogsService = require('./services/audit-logs');
const reviewWorkflowsMiddlewares = require('./middlewares/review-workflows'); const reviewWorkflowsMiddlewares = require('./middlewares/review-workflows');
const { getService } = require('./utils'); const { getService } = require('./utils');
@ -22,9 +23,12 @@ module.exports = async ({ strapi }) => {
} }
if (features.isEnabled('review-workflows')) { if (features.isEnabled('review-workflows')) {
strapi.hook('strapi::content-types.beforeSync').register(migrateStageAttribute); strapi.hook('strapi::content-types.beforeSync').register(migrateStageAttribute);
strapi.hook('strapi::content-types.afterSync').register(migrateReviewWorkflowStagesColor); strapi
strapi.hook('strapi::content-types.afterSync').register(migrateReviewWorkflowName); .hook('strapi::content-types.afterSync')
strapi.hook('strapi::content-types.afterSync').register(migrateWorkflowsContentTypes); .register(migrateReviewWorkflowStagesColor)
.register(migrateReviewWorkflowName)
.register(migrateWorkflowsContentTypes)
.register(migrateDeletedCTInWorkflows);
const reviewWorkflowService = getService('review-workflows'); const reviewWorkflowService = getService('review-workflows');
reviewWorkflowsMiddlewares.contentTypeMiddleware(strapi); reviewWorkflowsMiddlewares.contentTypeMiddleware(strapi);

View File

@ -4,20 +4,14 @@ const { set, isString } = require('lodash/fp');
const { ApplicationError, ValidationError } = require('@strapi/utils').errors; const { ApplicationError, ValidationError } = require('@strapi/utils').errors;
const { WORKFLOW_MODEL_UID } = require('../../../constants/workflows'); const { WORKFLOW_MODEL_UID } = require('../../../constants/workflows');
const { getService } = require('../../../utils'); const { getService } = require('../../../utils');
const { getWorkflowContentTypeFilter } = require('../../../utils/review-workflows');
const workflowsContentTypesFactory = require('./content-types'); const workflowsContentTypesFactory = require('./content-types');
const getContentTypeFilter = ({ strapi }, contentType) => {
if (strapi.db.dialect.supportsOperator('$jsonSupersetOf')) {
return { $jsonSupersetOf: JSON.stringify([contentType]) };
}
return { $contains: `"${contentType}"` };
};
const processFilters = ({ strapi }, filters = {}) => { const processFilters = ({ strapi }, filters = {}) => {
const processedFilters = { ...filters }; const processedFilters = { ...filters };
if (isString(filters.contentTypes)) { if (isString(filters.contentTypes)) {
processedFilters.contentTypes = getContentTypeFilter({ strapi }, filters.contentTypes); processedFilters.contentTypes = getWorkflowContentTypeFilter({ strapi }, filters.contentTypes);
} }
return processedFilters; return processedFilters;
@ -169,7 +163,7 @@ module.exports = ({ strapi }) => {
async getAssignedWorkflow(uid, opts = {}) { async getAssignedWorkflow(uid, opts = {}) {
const workflows = await this.find({ const workflows = await this.find({
...opts, ...opts,
filters: { contentTypes: getContentTypeFilter({ strapi }, uid) }, filters: { contentTypes: getWorkflowContentTypeFilter({ strapi }, uid) },
}); });
return workflows.length > 0 ? workflows[0] : null; return workflows.length > 0 ? workflows[0] : null;
}, },

View File

@ -16,7 +16,15 @@ const getVisibleContentTypesUID = pipe([
const hasStageAttribute = has(['attributes', ENTITY_STAGE_ATTRIBUTE]); const hasStageAttribute = has(['attributes', ENTITY_STAGE_ATTRIBUTE]);
const getWorkflowContentTypeFilter = ({ strapi }, contentType) => {
if (strapi.db.dialect.supportsOperator('$jsonSupersetOf')) {
return { $jsonSupersetOf: JSON.stringify([contentType]) };
}
return { $contains: `"${contentType}"` };
};
module.exports = { module.exports = {
getVisibleContentTypesUID, getVisibleContentTypesUID,
hasStageAttribute, hasStageAttribute,
getWorkflowContentTypeFilter,
}; };

View File

@ -24,6 +24,7 @@ const WHERE_OPERATORS = [
'$notContains', '$notContains',
'$containsi', '$containsi',
'$notContainsi', '$notContainsi',
'$jsonSupersetOf',
]; ];
const CAST_OPERATORS = [ const CAST_OPERATORS = [