diff --git a/packages/strapi-plugin-content-manager/admin/src/utils/index.js b/packages/strapi-plugin-content-manager/admin/src/utils/index.js index f5f20f88cd..7f827db09c 100644 --- a/packages/strapi-plugin-content-manager/admin/src/utils/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/utils/index.js @@ -11,3 +11,4 @@ export { default as getTrad } from './getTrad'; export { default as ItemTypes } from './ItemTypes'; export { default as removeKeyInObject } from './removeKeyInObject'; export { default as removePasswordFieldsFromData } from './removePasswordFieldsFromData'; +export { default as removeFieldsFromClonedData } from './removeFieldsFromClonedData'; diff --git a/packages/strapi-plugin-content-manager/admin/src/utils/removeFieldsFromClonedData.js b/packages/strapi-plugin-content-manager/admin/src/utils/removeFieldsFromClonedData.js new file mode 100644 index 0000000000..c615d16bb5 --- /dev/null +++ b/packages/strapi-plugin-content-manager/admin/src/utils/removeFieldsFromClonedData.js @@ -0,0 +1,76 @@ +import { get } from 'lodash'; +import { getType, getOtherInfos } from './getAttributeInfos'; + +const defaultFields = [ + 'created_at', + 'createdAt', + 'created_by', + 'createdBy', + 'updated_at', + 'updatedAt', + 'updated_by', + 'updatedBy', + 'id', + '_id', +]; + +const removeFieldsFromClonedData = ( + data, + contentTypeSchema, + componentSchema, + fields = defaultFields +) => { + const recursiveCleanData = (data, schema) => { + return Object.keys(data).reduce((acc, current) => { + const attrType = getType(schema.schema, current); + const value = get(data, current); + const component = getOtherInfos(schema.schema, [current, 'component']); + const isRepeatable = getOtherInfos(schema.schema, [current, 'repeatable']); + + if (fields.indexOf(current) !== -1) { + delete acc[current]; + + return acc; + } + + if (attrType === 'dynamiczone') { + acc[current] = value.map(componentValue => { + const subCleanedData = recursiveCleanData( + componentValue, + componentSchema[componentValue.__component] + ); + + return subCleanedData; + }); + + return acc; + } + + if (attrType === 'component') { + if (isRepeatable) { + /* eslint-disable indent */ + acc[current] = value + ? value.map(compoData => { + const subCleanedData = recursiveCleanData(compoData, componentSchema[component]); + + return subCleanedData; + }) + : value; + /* eslint-enable indent */ + } else { + acc[current] = value ? recursiveCleanData(value, componentSchema[component]) : value; + } + + return acc; + } + + acc[current] = value; + + return acc; + }, {}); + }; + + return recursiveCleanData(data, contentTypeSchema); +}; + +export default removeFieldsFromClonedData; diff --git a/packages/strapi-plugin-content-manager/admin/src/utils/tests/removeFieldsFromClonedData.test.js b/packages/strapi-plugin-content-manager/admin/src/utils/tests/removeFieldsFromClonedData.test.js new file mode 100644 index 0000000000..7630623e31 --- /dev/null +++ b/packages/strapi-plugin-content-manager/admin/src/utils/tests/removeFieldsFromClonedData.test.js @@ -0,0 +1,39 @@ +import { testData } from '../../testUtils'; +import removeFieldsFromClonedData from '../removeFieldsFromClonedData'; + +describe('CONTENT MANAGER | containers | EditViewDataManager | utils', () => { + describe('removeFieldsFromClonedData', () => { + it('should return an empty object', () => { + const { components, contentType } = testData; + + expect(removeFieldsFromClonedData({}, contentType, components)).toEqual({}); + }); + + it('should return the initial data if there is no field with the specified key', () => { + const { components, contentType } = testData; + + expect( + removeFieldsFromClonedData({ name: 'test' }, contentType, components, ['_id']) + ).toEqual({ + name: 'test', + }); + }); + + it('should remove the specified field for a simple data structure', () => { + const { components, contentType } = testData; + const data = { _id: 'test', name: 'test' }; + const expected = { name: 'test' }; + + expect(removeFieldsFromClonedData(data, contentType, components, ['_id'])).toEqual(expected); + }); + + it('should remove all password fields', () => { + const { components, contentType, modifiedData, expectedNoFieldsModifiedData } = testData; + const fields = ['id', 'created_at', 'updated_at']; + + expect(removeFieldsFromClonedData(modifiedData, contentType, components, fields)).toEqual( + expectedNoFieldsModifiedData + ); + }); + }); +});