From 7ad6ef6adfc5e06d0c28cd80f1a036f705020fa4 Mon Sep 17 00:00:00 2001 From: Fernando Chavez Date: Thu, 17 Aug 2023 14:54:28 +0200 Subject: [PATCH] move custom field size logic outside and tests --- .../core/content-manager/server/bootstrap.js | 2 +- .../server/services/field-sizes.js | 4 + .../configuration/__tests__/layouts.test.js | 88 +++++++++++++++++++ .../services/utils/configuration/layouts.js | 40 +++------ 4 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 packages/core/content-manager/server/services/utils/configuration/__tests__/layouts.test.js diff --git a/packages/core/content-manager/server/bootstrap.js b/packages/core/content-manager/server/bootstrap.js index 2addefd0e5..8f0fd7b138 100644 --- a/packages/core/content-manager/server/bootstrap.js +++ b/packages/core/content-manager/server/bootstrap.js @@ -8,8 +8,8 @@ module.exports = async () => { strapi.webhookStore.addAllowedEvent(key, value); }); + getService('field-sizes').setCustomFieldInputSizes(); await getService('components').syncConfigurations(); await getService('content-types').syncConfigurations(); await getService('permission').registerPermissions(); - getService('field-sizes').setCustomFieldInputSizes(); }; diff --git a/packages/core/content-manager/server/services/field-sizes.js b/packages/core/content-manager/server/services/field-sizes.js index 6f87781f45..d892c943b5 100644 --- a/packages/core/content-manager/server/services/field-sizes.js +++ b/packages/core/content-manager/server/services/field-sizes.js @@ -52,6 +52,10 @@ const createFieldSizesService = ({ strapi }) => { return fieldSizes; }, + hasFieldSize(type) { + return !!fieldSizes[type]; + }, + getFieldSize(type) { if (!type) { throw new ApplicationError('The type is required'); diff --git a/packages/core/content-manager/server/services/utils/configuration/__tests__/layouts.test.js b/packages/core/content-manager/server/services/utils/configuration/__tests__/layouts.test.js new file mode 100644 index 0000000000..74dd82decc --- /dev/null +++ b/packages/core/content-manager/server/services/utils/configuration/__tests__/layouts.test.js @@ -0,0 +1,88 @@ +'use strict'; + +const { syncLayouts } = require('../layouts'); + +jest.mock('../../../../utils', () => ({ + getService: jest.fn().mockReturnValue({ + getFieldSize: jest.fn().mockImplementation((type) => { + if (type === 'integer' || type === 'string') { + return { default: 6, isResizable: true }; + } + + if (type === 'json' || type === 'customField') { + return { default: 12, isResizable: false }; + } + }), + hasFieldSize: jest.fn().mockImplementation((type) => { + return type === 'customField'; + }), + }), +})); + +const createMockSchema = ({ attributes = {} }) => ({ + attributes: { + id: { type: 'integer' }, + title: { type: 'string' }, + nodes: { type: 'json' }, + ...attributes, + }, + config: { + attributes: { + title: {}, + nodes: {}, + }, + }, +}); + +describe('Layouts', () => { + it('should create default layouts with valid fields if no configuration is provided', async () => { + const configuration = { layouts: {} }; + + const layout = await syncLayouts(configuration, createMockSchema({})); + + expect(layout.list).toEqual(['id', 'title']); + expect(layout.edit).toEqual([[{ name: 'title', size: 6 }], [{ name: 'nodes', size: 12 }]]); + }); + + it('should append new fields at the end of the layouts', async () => { + const configuration = { + layouts: { + list: ['id', 'title'], + edit: [[{ name: 'title', size: 6 }], [{ name: 'nodes', size: 12 }]], + }, + metadatas: { id: {}, title: {}, nodes: {} }, + }; + const schema = createMockSchema({ attributes: { description: { type: 'string' } } }); + + const layout = await syncLayouts(configuration, schema); + + expect(layout.list).toEqual(['id', 'title', 'description']); + expect(layout.edit).toEqual([ + [{ name: 'title', size: 6 }], + [{ name: 'nodes', size: 12 }], + [{ name: 'description', size: 6 }], + ]); + }); + + it('should use the custom field size if the field is a custom field with custom size', async () => { + const configuration = { + layouts: { + list: ['id', 'title'], + edit: [[{ name: 'title', size: 6 }], [{ name: 'nodes', size: 12 }]], + }, + metadatas: { id: {}, title: {}, nodes: {} }, + }; + const schema = createMockSchema({ + attributes: { color: { type: 'string', customField: 'customField' } }, + }); + + const layout = await syncLayouts(configuration, schema); + + expect(layout.list).toEqual(['id', 'title', 'color']); + expect(layout.edit).toEqual([ + [{ name: 'title', size: 6 }], + [{ name: 'nodes', size: 12 }], + [{ name: 'color', size: 12 }], + ]); + }); +}); diff --git a/packages/core/content-manager/server/services/utils/configuration/layouts.js b/packages/core/content-manager/server/services/utils/configuration/layouts.js index 3572154ad0..796e78e795 100644 --- a/packages/core/content-manager/server/services/utils/configuration/layouts.js +++ b/packages/core/content-manager/server/services/utils/configuration/layouts.js @@ -7,16 +7,9 @@ const { isListable, hasEditableAttribute, hasRelationAttribute } = require('./at const DEFAULT_LIST_LENGTH = 4; const MAX_ROW_SIZE = 12; -const isAllowedFieldSize = (type, size, customFieldUid = null) => { +const isAllowedFieldSize = (type, size) => { const { getFieldSize } = getService('field-sizes'); - let fieldSize = getFieldSize(type); - - if (customFieldUid) { - const customField = strapi.container.get('custom-fields').get(customFieldUid); - if (customField.inputSize) { - fieldSize = customField.inputSize; - } - } + const fieldSize = getFieldSize(type); // Check if field was locked to another size if (!fieldSize.isResizable && size !== fieldSize.default) { @@ -28,17 +21,11 @@ const isAllowedFieldSize = (type, size, customFieldUid = null) => { }; const getDefaultFieldSize = (attribute) => { - // Check if it's a custom field with a custom size - if (attribute.customField) { - const customField = strapi.container.get('custom-fields').get(attribute.customField); - if (customField.inputSize) { - return customField.inputSize.default; - } - } + const { hasFieldSize, getFieldSize } = getService('field-sizes'); - // Get the default size for the field type - const { getFieldSize } = getService('field-sizes'); - return getFieldSize(attribute.type).default; + // Check if it's a custom field with a custom size and get the default size for the field type + return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type) + .default; }; async function createDefaultLayouts(schema) { @@ -85,16 +72,17 @@ function syncLayouts(configuration, schema) { for (const el of row) { if (!hasEditableAttribute(schema, el.name)) continue; + // Check if the field is a custom field with a custom size. + // If so, use the custom size instead of the type size + const { hasFieldSize } = getService('field-sizes'); + const fieldType = hasFieldSize(schema.attributes[el.name].customField) + ? schema.attributes[el.name].customField + : schema.attributes[el.name].type; + /* if the type of a field was changed (ex: string -> json) or a new field was added in the schema and the new type doesn't allow the size of the previous type, append the field at the end of layouts */ - if ( - !isAllowedFieldSize( - schema.attributes[el.name].type, - el.size, - schema.attributes[el.name].customField - ) - ) { + if (!isAllowedFieldSize(fieldType, el.size)) { elementsToReAppend.push(el.name); continue; }