diff --git a/api-tests/core/content-manager/api/relations.test.api.js b/api-tests/core/content-manager/api/relations.test.api.js index 252d0d3e80..0584bbd397 100644 --- a/api-tests/core/content-manager/api/relations.test.api.js +++ b/api-tests/core/content-manager/api/relations.test.api.js @@ -921,7 +921,7 @@ describe('Relations', () => { }); describe('Clone entity with relations', () => { - test('Clone entity with relations', async () => { + test('Auto cloning entity with relations should fail', async () => { const createdShop = await createEntry( 'shop', { @@ -943,7 +943,7 @@ describe('Relations', () => { // Clone with empty data const res = await rq({ method: 'POST', - url: `/content-manager/collection-types/api::shop.shop/clone/${createdShop.id}`, + url: `/content-manager/collection-types/api::shop.shop/auto-clone/${createdShop.id}`, body: {}, }); diff --git a/packages/core/admin/admin/src/content-manager/pages/ListView/components/TableRows/index.js b/packages/core/admin/admin/src/content-manager/pages/ListView/components/TableRows/index.js index 9ef5598af7..f0da516370 100644 --- a/packages/core/admin/admin/src/content-manager/pages/ListView/components/TableRows/index.js +++ b/packages/core/admin/admin/src/content-manager/pages/ListView/components/TableRows/index.js @@ -53,7 +53,7 @@ export const TableRows = ({ const handleCloneClick = (id) => async () => { try { const { data } = await post( - `/content-manager/collection-types/${contentType.uid}/clone/${id}?${pluginsQueryParams}` + `/content-manager/collection-types/${contentType.uid}/auto-clone/${id}?${pluginsQueryParams}` ); if ('id' in data) { diff --git a/packages/core/content-manager/server/controllers/collection-types.js b/packages/core/content-manager/server/controllers/collection-types.js index 0f29a661ee..db428c499b 100644 --- a/packages/core/content-manager/server/controllers/collection-types.js +++ b/packages/core/content-manager/server/controllers/collection-types.js @@ -1,7 +1,6 @@ 'use strict'; const { setCreatorFields, pipeAsync } = require('@strapi/utils'); -const { isEmpty } = require('lodash/fp'); const { ApplicationError } = require('@strapi/utils').errors; const { getService, pickWritableAttributes } = require('../utils'); @@ -165,14 +164,6 @@ module.exports = { return ctx.forbidden(); } - // Trying to automatically clone the entity - // and model has unique or relational fields - if (isEmpty(body) && hasProhibitedCloningFields(model)) { - throw new ApplicationError( - 'Entity could not be cloned as it has unique and/or relational fields. Please edit those fields manually and save to complete the cloning.' - ); - } - const entity = await entityManager.findOneWithCreatorRoles(id, model); if (!entity) { @@ -198,6 +189,20 @@ module.exports = { ctx.body = await permissionChecker.sanitizeOutput(clonedEntity); }, + async autoClone(ctx) { + const { model } = ctx.params; + + // Trying to automatically clone the entity and model has unique or relational fields + if (hasProhibitedCloningFields(model)) { + throw new ApplicationError( + 'Entity could not be cloned as it has unique and/or relational fields. ' + + 'Please edit those fields manually and save to complete the cloning.' + ); + } + + this.clone(ctx); + }, + async delete(ctx) { const { userAbility } = ctx.state; const { id, model } = ctx.params; diff --git a/packages/core/content-manager/server/controllers/utils/clone.js b/packages/core/content-manager/server/controllers/utils/clone.js index dad3bf13e9..99f67de3e6 100644 --- a/packages/core/content-manager/server/controllers/utils/clone.js +++ b/packages/core/content-manager/server/controllers/utils/clone.js @@ -29,6 +29,8 @@ const hasProhibitedCloningFields = (uid) => { return (attribute.components || []).some((componentUID) => hasProhibitedCloningFields(componentUID) ); + case 'uid': + return true; default: return attribute?.unique ?? false; } diff --git a/packages/core/content-manager/server/routes/admin.js b/packages/core/content-manager/server/routes/admin.js index d0f2e73c00..18fcef576b 100644 --- a/packages/core/content-manager/server/routes/admin.js +++ b/packages/core/content-manager/server/routes/admin.js @@ -246,6 +246,21 @@ module.exports = { ], }, }, + { + method: 'POST', + path: '/collection-types/:model/auto-clone/:sourceId', + handler: 'collection-types.autoClone', + config: { + middlewares: [routing], + policies: [ + 'admin::isAuthenticatedAdmin', + { + name: 'plugin::content-manager.hasPermissions', + config: { actions: ['plugin::content-manager.explorer.create'] }, + }, + ], + }, + }, { method: 'GET', path: '/collection-types/:model/:id',