mirror of
https://github.com/strapi/strapi.git
synced 2025-08-05 15:29:04 +00:00
Merge branch 'custom-fields/add-custom-field-attribute' of github.com:strapi/strapi into add-custom-field-attribute/error-handling
This commit is contained in:
commit
b3384fb6e8
@ -49,10 +49,21 @@ export default {
|
||||
id: 'color-picker.color.format.label',
|
||||
defaultMessage: 'Color format',
|
||||
},
|
||||
name: 'options.color-picker.format',
|
||||
name: 'options.format',
|
||||
type: 'select',
|
||||
value: 'hex',
|
||||
options: [
|
||||
{
|
||||
key: '__null_reset_value__',
|
||||
value: '',
|
||||
metadatas: {
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.placeholder',
|
||||
defaultMessage: 'Select a format',
|
||||
},
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'hex',
|
||||
value: 'hex',
|
||||
@ -111,11 +122,9 @@ export default {
|
||||
},
|
||||
],
|
||||
validator: args => ({
|
||||
'color-picker': yup.object().shape({
|
||||
format: yup.string().required({
|
||||
id: 'options.color-picker.format.error',
|
||||
defaultMessage: 'The color format is required',
|
||||
}),
|
||||
format: yup.string().required({
|
||||
id: 'options.color-picker.format.error',
|
||||
defaultMessage: 'The color format is required',
|
||||
}),
|
||||
}),
|
||||
},
|
||||
|
@ -173,17 +173,19 @@ const DataManagerProvider = ({
|
||||
});
|
||||
};
|
||||
|
||||
const addCustomFieldAttribute = (
|
||||
attributeToSet,
|
||||
forTarget,
|
||||
targetUid,
|
||||
isEditing = false,
|
||||
initialAttribute
|
||||
) => {
|
||||
const actionType = isEditing ? EDIT_CUSTOM_FIELD_ATTRIBUTE : ADD_CUSTOM_FIELD_ATTRIBUTE;
|
||||
|
||||
const addCustomFieldAttribute = ({ attributeToSet, forTarget, targetUid, initialAttribute }) => {
|
||||
dispatch({
|
||||
type: actionType,
|
||||
type: ADD_CUSTOM_FIELD_ATTRIBUTE,
|
||||
attributeToSet,
|
||||
forTarget,
|
||||
targetUid,
|
||||
initialAttribute,
|
||||
});
|
||||
};
|
||||
|
||||
const editCustomFieldAttribute = ({ attributeToSet, forTarget, targetUid, initialAttribute }) => {
|
||||
dispatch({
|
||||
type: EDIT_CUSTOM_FIELD_ATTRIBUTE,
|
||||
attributeToSet,
|
||||
forTarget,
|
||||
targetUid,
|
||||
@ -573,6 +575,7 @@ const DataManagerProvider = ({
|
||||
deleteCategory,
|
||||
deleteData,
|
||||
editCategory,
|
||||
editCustomFieldAttribute,
|
||||
isInDevelopmentMode,
|
||||
initialData,
|
||||
isInContentTypeView,
|
||||
|
@ -36,65 +36,58 @@ const findAttributeIndex = (schema, attributeToFind) => {
|
||||
return schema.schema.attributes.findIndex(({ name }) => name === attributeToFind);
|
||||
};
|
||||
|
||||
const getAddAttributeUpdate = (action, state) => {
|
||||
const {
|
||||
attributeToSet: { name, ...rest },
|
||||
forTarget,
|
||||
targetUid,
|
||||
} = action;
|
||||
delete rest.createComponent;
|
||||
|
||||
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const currentAttributes = get(
|
||||
state,
|
||||
['modifiedData', ...pathToDataToEdit, 'schema', 'attributes'],
|
||||
[]
|
||||
).slice();
|
||||
|
||||
// Add the createdAttribute
|
||||
const updatedAttributes = [...currentAttributes, { ...rest, name }];
|
||||
|
||||
return { pathToDataToEdit, updatedAttributes, attributeToSet: { ...rest, name } };
|
||||
};
|
||||
|
||||
const getEditAttributeUpdate = (action, state) => {
|
||||
const { forTarget, targetUid, initialAttribute } = action;
|
||||
|
||||
const initialAttributeName = initialAttribute.name;
|
||||
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const initialAttributeIndex = findAttributeIndex(
|
||||
get(state, ['modifiedData', ...pathToDataToEdit]),
|
||||
initialAttributeName
|
||||
);
|
||||
|
||||
return { pathToDataToEdit, initialAttributeIndex };
|
||||
};
|
||||
|
||||
const reducer = (state = initialState, action) =>
|
||||
// eslint-disable-next-line consistent-return
|
||||
produce(state, draftState => {
|
||||
switch (action.type) {
|
||||
case actions.ADD_CUSTOM_FIELD_ATTRIBUTE: {
|
||||
const { pathToDataToEdit, updatedAttributes } = getAddAttributeUpdate(action, state);
|
||||
const {
|
||||
attributeToSet: { name, ...rest },
|
||||
forTarget,
|
||||
targetUid,
|
||||
} = action;
|
||||
|
||||
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const currentAttributes = get(
|
||||
state,
|
||||
['modifiedData', ...pathToDataToEdit, 'schema', 'attributes'],
|
||||
[]
|
||||
).slice();
|
||||
|
||||
// Add the createdAttribute
|
||||
const updatedAttributes = [...currentAttributes, { ...rest, name }];
|
||||
|
||||
set(
|
||||
draftState,
|
||||
['modifiedData', ...pathToDataToEdit, 'schema', 'attributes'],
|
||||
updatedAttributes
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case actions.ADD_ATTRIBUTE: {
|
||||
const {
|
||||
pathToDataToEdit,
|
||||
updatedAttributes,
|
||||
attributeToSet: { name, ...rest },
|
||||
} = getAddAttributeUpdate(action, state);
|
||||
forTarget,
|
||||
targetUid,
|
||||
} = action;
|
||||
delete rest.createComponent;
|
||||
|
||||
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const currentAttributes = get(
|
||||
state,
|
||||
['modifiedData', ...pathToDataToEdit, 'schema', 'attributes'],
|
||||
[]
|
||||
).slice();
|
||||
|
||||
// Add the createdAttribute
|
||||
const updatedAttributes = [...currentAttributes, { ...rest, name }];
|
||||
|
||||
set(
|
||||
draftState,
|
||||
@ -270,9 +263,17 @@ const reducer = (state = initialState, action) =>
|
||||
break;
|
||||
}
|
||||
case actions.EDIT_CUSTOM_FIELD_ATTRIBUTE: {
|
||||
const { attributeToSet } = action;
|
||||
const { forTarget, targetUid, initialAttribute, attributeToSet } = action;
|
||||
|
||||
const { pathToDataToEdit, initialAttributeIndex } = getEditAttributeUpdate(action, state);
|
||||
const initialAttributeName = initialAttribute.name;
|
||||
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const initialAttributeIndex = findAttributeIndex(
|
||||
get(state, ['modifiedData', ...pathToDataToEdit]),
|
||||
initialAttributeName
|
||||
);
|
||||
|
||||
set(
|
||||
draftState,
|
||||
@ -285,10 +286,20 @@ const reducer = (state = initialState, action) =>
|
||||
case actions.EDIT_ATTRIBUTE: {
|
||||
const {
|
||||
attributeToSet: { name, ...rest },
|
||||
forTarget,
|
||||
targetUid,
|
||||
initialAttribute,
|
||||
} = action;
|
||||
|
||||
const { pathToDataToEdit, initialAttributeIndex } = getEditAttributeUpdate(action, state);
|
||||
const initialAttributeName = initialAttribute.name;
|
||||
const pathToDataToEdit = ['component', 'contentType'].includes(forTarget)
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const initialAttributeIndex = findAttributeIndex(
|
||||
get(state, ['modifiedData', ...pathToDataToEdit]),
|
||||
initialAttributeName
|
||||
);
|
||||
|
||||
const isEditingRelation = rest.type === 'relation';
|
||||
|
||||
|
@ -7,16 +7,9 @@ import { createComponentSchema, componentForm } from '../component';
|
||||
import { dynamiczoneForm } from '../dynamicZone';
|
||||
import { nameField } from '../attributes/nameField';
|
||||
import addItemsToFormSection from './utils/addItemsToFormSection';
|
||||
import getUsedAttributeNames from './utils/getUsedAttributeNames';
|
||||
import getTrad from '../../../utils/getTrad';
|
||||
|
||||
const getUsedAttributeNames = (attributes, schemaData) => {
|
||||
return attributes
|
||||
.filter(({ name }) => {
|
||||
return name !== schemaData.initialData.name;
|
||||
})
|
||||
.map(({ name }) => name);
|
||||
};
|
||||
|
||||
const forms = {
|
||||
customField: {
|
||||
schema({
|
||||
@ -68,7 +61,6 @@ const forms = {
|
||||
}
|
||||
|
||||
if (injectedInputs) {
|
||||
// TODO: Discuss how to handle settings from other plugins
|
||||
const extendedSettings = {
|
||||
sectionTitle: {
|
||||
id: getTrad('modalForm.custom-fields.advanced.settings.extended'),
|
||||
|
@ -15,7 +15,7 @@ const addItemsToFormSection = (formTypeOptions, sections) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, when no sectionTitle is present or sectionTitle has a value (including null),
|
||||
// Otherwise, when sectionTitle has a value (including null),
|
||||
// add the item as a new section
|
||||
sections.push(item);
|
||||
});
|
||||
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
*
|
||||
* @param {array} attributes The attributes found on the dataManager's modifiedData object
|
||||
* @param {object} schemaData The modifiedData and SchemaData objects from the reducer state
|
||||
* @returns A list of names already being used
|
||||
*/
|
||||
const getUsedAttributeNames = (attributes, schemaData) => {
|
||||
return attributes
|
||||
.filter(({ name }) => {
|
||||
return name !== schemaData.initialData.name;
|
||||
})
|
||||
.map(({ name }) => name);
|
||||
};
|
||||
|
||||
export default getUsedAttributeNames;
|
@ -116,6 +116,7 @@ const FormModal = () => {
|
||||
deleteCategory,
|
||||
deleteData,
|
||||
editCategory,
|
||||
editCustomFieldAttribute,
|
||||
submitData,
|
||||
modifiedData: allDataSchema,
|
||||
nestedComponents,
|
||||
@ -347,7 +348,6 @@ const FormModal = () => {
|
||||
ctbFormsAPI,
|
||||
customFieldValidator: customField.options.validator,
|
||||
});
|
||||
|
||||
// Check for validity for creating a component
|
||||
// This is happening when the user creates a component "on the fly"
|
||||
// Since we temporarily store the component info in another object
|
||||
@ -550,13 +550,18 @@ const FormModal = () => {
|
||||
// Add/edit a field to a content type
|
||||
// Add/edit a field to a created component (the end modal is not step 2)
|
||||
} else if (isCreatingCustomFieldAttribute) {
|
||||
addCustomFieldAttribute(
|
||||
{ ...modifiedData, customField: customFieldUid },
|
||||
const customFieldAttributeUpdate = {
|
||||
attributeToSet: { ...modifiedData, customField: customFieldUid },
|
||||
forTarget,
|
||||
targetUid,
|
||||
actionType === 'edit',
|
||||
initialData
|
||||
);
|
||||
initialAttribute: initialData,
|
||||
};
|
||||
|
||||
if (actionType === 'edit') {
|
||||
editCustomFieldAttribute(customFieldAttributeUpdate);
|
||||
} else {
|
||||
addCustomFieldAttribute(customFieldAttributeUpdate);
|
||||
}
|
||||
|
||||
if (shouldContinue) {
|
||||
onNavigateToChooseAttributeModal({
|
||||
@ -1050,10 +1055,10 @@ const FormModal = () => {
|
||||
onSubmitCreateContentType={handleSubmit}
|
||||
onSubmitCreateDz={handleSubmit}
|
||||
onSubmitEditAttribute={handleSubmit}
|
||||
onSubmitEditCusomFieldAttribute={handleSubmit}
|
||||
onSubmitEditCategory={handleSubmit}
|
||||
onSubmitEditComponent={handleSubmit}
|
||||
onSubmitEditContentType={handleSubmit}
|
||||
onSubmitEditCustomFieldAttribute={handleSubmit}
|
||||
onSubmitEditDz={handleSubmit}
|
||||
/>
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
import addItemsToFormSections from '../forms/utils/addItemsToFormSection';
|
||||
|
||||
describe('addItemsToFormSection', () => {
|
||||
it('adds items to the default section', () => {
|
||||
const sections = [{ sectionTitle: null, items: [] }];
|
||||
const itemsToAdd = [
|
||||
{
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.label',
|
||||
defaultMessage: 'Color format',
|
||||
},
|
||||
name: 'options.color-picker.format',
|
||||
type: 'select',
|
||||
value: 'hex',
|
||||
options: [
|
||||
{
|
||||
key: 'hex',
|
||||
value: 'hex',
|
||||
metadatas: {
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.hex',
|
||||
defaultMessage: 'Hexadecimal',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'rgba',
|
||||
value: 'rgba',
|
||||
metadatas: {
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.rgba',
|
||||
defaultMessage: 'RGBA',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
addItemsToFormSections(itemsToAdd, sections);
|
||||
|
||||
expect(sections.length).toBe(1);
|
||||
expect(sections[0].items.length).toBe(1);
|
||||
});
|
||||
|
||||
it('adds the item as a new section', () => {
|
||||
const sections = [{ sectionTitle: null, items: [] }];
|
||||
const itemsToAdd = [
|
||||
{
|
||||
sectionTitle: null,
|
||||
items: [
|
||||
{
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.label',
|
||||
defaultMessage: 'Color format',
|
||||
},
|
||||
name: 'options.color-picker.format',
|
||||
type: 'select',
|
||||
value: 'hex',
|
||||
options: [
|
||||
{
|
||||
key: 'hex',
|
||||
value: 'hex',
|
||||
metadatas: {
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.hex',
|
||||
defaultMessage: 'Hexadecimal',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'rgba',
|
||||
value: 'rgba',
|
||||
metadatas: {
|
||||
intlLabel: {
|
||||
id: 'color-picker.color.format.rgba',
|
||||
defaultMessage: 'RGBA',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
addItemsToFormSections(itemsToAdd, sections);
|
||||
|
||||
expect(sections.length).toBe(2);
|
||||
});
|
||||
});
|
@ -38,10 +38,10 @@ const FormModalEndActions = ({
|
||||
onSubmitCreateComponent,
|
||||
onSubmitCreateDz,
|
||||
onSubmitEditAttribute,
|
||||
onSubmitEditCusomFieldAttribute,
|
||||
onSubmitEditCategory,
|
||||
onSubmitEditComponent,
|
||||
onSubmitEditContentType,
|
||||
onSubmitEditCustomFieldAttribute,
|
||||
onSubmitEditDz,
|
||||
}) => {
|
||||
const { formatMessage } = useIntl();
|
||||
@ -394,7 +394,7 @@ const FormModalEndActions = ({
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
|
||||
onSubmitEditCusomFieldAttribute(e, true);
|
||||
onSubmitEditCustomFieldAttribute(e, true);
|
||||
}}
|
||||
startIcon={<Plus />}
|
||||
>
|
||||
@ -409,7 +409,7 @@ const FormModalEndActions = ({
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
|
||||
onSubmitEditCusomFieldAttribute(e, false);
|
||||
onSubmitEditCustomFieldAttribute(e, false);
|
||||
}}
|
||||
>
|
||||
{formatMessage({
|
||||
@ -455,10 +455,10 @@ FormModalEndActions.propTypes = {
|
||||
onSubmitCreateComponent: PropTypes.func.isRequired,
|
||||
onSubmitCreateDz: PropTypes.func.isRequired,
|
||||
onSubmitEditAttribute: PropTypes.func.isRequired,
|
||||
onSubmitEditCusomFieldAttribute: PropTypes.func.isRequired,
|
||||
onSubmitEditCategory: PropTypes.func.isRequired,
|
||||
onSubmitEditComponent: PropTypes.func.isRequired,
|
||||
onSubmitEditContentType: PropTypes.func.isRequired,
|
||||
onSubmitEditCustomFieldAttribute: PropTypes.func.isRequired,
|
||||
onSubmitEditDz: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,6 @@ const FormModalNavigationProvider = ({ children }) => {
|
||||
return {
|
||||
...prevState,
|
||||
actionType: 'create',
|
||||
// TODO: Create a new modalType on EXPANSION-245
|
||||
modalType: 'customField',
|
||||
attributeType,
|
||||
customFieldUid,
|
||||
|
@ -17,14 +17,6 @@ const FormModalSubHeader = ({
|
||||
customField,
|
||||
}) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const type =
|
||||
modalType === 'customField'
|
||||
? upperFirst(formatMessage(customField.intlLabel))
|
||||
: upperFirst(
|
||||
formatMessage({
|
||||
id: getTrad(`attribute.${attributeType}`),
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<Typography as="h2" variant="beta">
|
||||
@ -40,7 +32,9 @@ const FormModalSubHeader = ({
|
||||
defaultMessage: 'Add new field',
|
||||
},
|
||||
{
|
||||
type,
|
||||
type: upperFirst(
|
||||
formatMessage(customField?.intlLabel ?? { id: getTrad(`attribute.${attributeType}`) })
|
||||
),
|
||||
name: upperFirst(attributeName),
|
||||
step,
|
||||
}
|
||||
|
@ -88,8 +88,12 @@ const formsAPI = {
|
||||
return sectionsToAdd;
|
||||
},
|
||||
|
||||
makeCustomFieldValidator(initShape, validator, ...validatorArgs) {
|
||||
return initShape.shape({ options: yup.object().shape(validator(validatorArgs)) });
|
||||
makeCustomFieldValidator(attributeShape, validator, ...validatorArgs) {
|
||||
// When no validator, return the attribute shape
|
||||
if (!validator) return attributeShape;
|
||||
|
||||
// Otherwise extend the shape with the provided validator
|
||||
return attributeShape.shape({ options: yup.object().shape(validator(validatorArgs)) });
|
||||
},
|
||||
|
||||
makeValidator(target, initShape, ...args) {
|
||||
|
@ -4,7 +4,6 @@ const _ = require('lodash');
|
||||
|
||||
const { formatAttributes, replaceTemporaryUIDs } = require('../utils/attributes');
|
||||
const createBuilder = require('./schema-builder');
|
||||
const convertCustomFieldType = require('./utils/convert-custom-field-type');
|
||||
|
||||
/**
|
||||
* Formats a component attributes
|
||||
@ -42,11 +41,9 @@ const createComponent = async ({ component, components = [] }) => {
|
||||
const uidMap = builder.createNewComponentUIDMap(components);
|
||||
const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);
|
||||
|
||||
convertCustomFieldType(component.attributes);
|
||||
const newComponent = builder.createComponent(replaceTmpUIDs(component));
|
||||
|
||||
components.forEach(component => {
|
||||
convertCustomFieldType(component.attributes);
|
||||
if (!_.has(component, 'uid')) {
|
||||
return builder.createComponent(replaceTmpUIDs(component));
|
||||
}
|
||||
@ -70,14 +67,12 @@ const editComponent = async (uid, { component, components = [] }) => {
|
||||
const uidMap = builder.createNewComponentUIDMap(components);
|
||||
const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);
|
||||
|
||||
convertCustomFieldType(component.attributes);
|
||||
const updatedComponent = builder.editComponent({
|
||||
uid,
|
||||
...replaceTmpUIDs(component),
|
||||
});
|
||||
|
||||
components.forEach(component => {
|
||||
convertCustomFieldType(component.attributes);
|
||||
if (!_.has(component, 'uid')) {
|
||||
return builder.createComponent(replaceTmpUIDs(component));
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ const { ApplicationError } = require('@strapi/utils').errors;
|
||||
const { formatAttributes, replaceTemporaryUIDs } = require('../utils/attributes');
|
||||
const createBuilder = require('./schema-builder');
|
||||
const { coreUids, pluginsUids } = require('./constants');
|
||||
const convertCustomFieldType = require('./utils/convert-custom-field-type');
|
||||
|
||||
const isContentTypeVisible = model =>
|
||||
getOr(true, 'pluginOptions.content-type-builder.visible', model) === true;
|
||||
@ -85,7 +84,6 @@ const createContentType = async ({ contentType, components = [] }, options = {})
|
||||
|
||||
const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);
|
||||
|
||||
convertCustomFieldType(contentType.attributes);
|
||||
const newContentType = builder.createContentType(replaceTmpUIDs(contentType));
|
||||
|
||||
// allow components to target the new contentType
|
||||
@ -101,7 +99,6 @@ const createContentType = async ({ contentType, components = [] }, options = {})
|
||||
};
|
||||
|
||||
components.forEach(component => {
|
||||
convertCustomFieldType(component.attributes);
|
||||
const options = replaceTmpUIDs(targetContentType(component));
|
||||
|
||||
if (!_.has(component, 'uid')) {
|
||||
@ -173,15 +170,12 @@ const editContentType = async (uid, { contentType, components = [] }) => {
|
||||
const uidMap = builder.createNewComponentUIDMap(components);
|
||||
const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);
|
||||
|
||||
convertCustomFieldType(contentType.attributes);
|
||||
const updatedContentType = builder.editContentType({
|
||||
uid,
|
||||
...replaceTmpUIDs(contentType),
|
||||
});
|
||||
|
||||
components.forEach(component => {
|
||||
convertCustomFieldType(component.attributes);
|
||||
|
||||
if (!_.has(component, 'uid')) {
|
||||
return builder.createComponent(replaceTmpUIDs(component));
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ const { nameToSlug, nameToCollectionName } = require('@strapi/utils');
|
||||
const { ApplicationError } = require('@strapi/utils').errors;
|
||||
const { isConfigurable } = require('../../utils/attributes');
|
||||
const createSchemaHandler = require('./schema-handler');
|
||||
const convertCustomFieldType = require('./utils/convert-custom-field-type');
|
||||
|
||||
module.exports = function createComponentBuilder() {
|
||||
return {
|
||||
@ -32,12 +33,15 @@ module.exports = function createComponentBuilder() {
|
||||
* create a component in the tmpComponent map
|
||||
*/
|
||||
createComponent(infos) {
|
||||
const { attributes } = infos;
|
||||
const uid = this.createComponentUID(infos);
|
||||
|
||||
if (this.components.has(uid)) {
|
||||
throw new ApplicationError('component.alreadyExists');
|
||||
}
|
||||
|
||||
convertCustomFieldType(attributes);
|
||||
|
||||
const handler = createSchemaHandler({
|
||||
dir: path.join(strapi.dirs.components, nameToSlug(infos.category)),
|
||||
filename: `${nameToSlug(infos.displayName)}.json`,
|
||||
@ -72,12 +76,13 @@ module.exports = function createComponentBuilder() {
|
||||
* create a component in the tmpComponent map
|
||||
*/
|
||||
editComponent(infos) {
|
||||
const { uid } = infos;
|
||||
const { uid, attributes } = infos;
|
||||
|
||||
if (!this.components.has(uid)) {
|
||||
throw new ApplicationError('component.notFound');
|
||||
}
|
||||
|
||||
convertCustomFieldType(attributes);
|
||||
const component = this.components.get(uid);
|
||||
|
||||
const [, nameUID] = uid.split('.');
|
||||
|
@ -8,6 +8,7 @@ const { ApplicationError } = require('@strapi/utils').errors;
|
||||
const { isRelation, isConfigurable } = require('../../utils/attributes');
|
||||
const { typeKinds } = require('../constants');
|
||||
const createSchemaHandler = require('./schema-handler');
|
||||
const convertCustomFieldType = require('./utils/convert-custom-field-type');
|
||||
|
||||
const reuseUnsetPreviousProperties = (newAttribute, oldAttribute) => {
|
||||
_.defaults(
|
||||
@ -71,12 +72,15 @@ module.exports = function createComponentBuilder() {
|
||||
* @returns {object} new content type
|
||||
*/
|
||||
createContentType(infos) {
|
||||
const { attributes } = infos;
|
||||
const uid = createContentTypeUID(infos);
|
||||
|
||||
if (this.contentTypes.has(uid)) {
|
||||
throw new ApplicationError('contentType.alreadyExists');
|
||||
}
|
||||
|
||||
convertCustomFieldType(attributes);
|
||||
|
||||
const contentType = createSchemaHandler({
|
||||
modelName: infos.singularName,
|
||||
dir: path.join(strapi.dirs.api, infos.singularName, 'content-types', infos.singularName),
|
||||
@ -124,12 +128,14 @@ module.exports = function createComponentBuilder() {
|
||||
},
|
||||
|
||||
editContentType(infos) {
|
||||
const { uid } = infos;
|
||||
const { uid, attributes } = infos;
|
||||
|
||||
if (!this.contentTypes.has(uid)) {
|
||||
throw new ApplicationError('contentType.notFound');
|
||||
}
|
||||
|
||||
convertCustomFieldType(attributes);
|
||||
|
||||
const contentType = this.contentTypes.get(uid);
|
||||
|
||||
const oldAttributes = contentType.schema.attributes;
|
||||
|
@ -26,6 +26,16 @@ describe('format attributes', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
'default.test': {
|
||||
attributes: {
|
||||
color: {
|
||||
type: 'customField',
|
||||
customField: 'plugin::mycustomfields.color',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
convertCustomFieldType(global.strapi);
|
||||
@ -42,6 +52,16 @@ describe('format attributes', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
'default.test': {
|
||||
attributes: {
|
||||
color: {
|
||||
type: 'text',
|
||||
customField: 'plugin::mycustomfields.color',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(global.strapi).toEqual(expected);
|
||||
|
@ -1,7 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const convertCustomFieldType = strapi => {
|
||||
const allSchemasAttributes = Object.values(strapi.contentTypes).map(schema => schema.attributes);
|
||||
const allContentTypeSchemaAttributes = Object.values(strapi.contentTypes).map(
|
||||
schema => schema.attributes
|
||||
);
|
||||
const allComponentSchemaAttributes = Object.values(strapi.components).map(
|
||||
schema => schema.attributes
|
||||
);
|
||||
const allSchemasAttributes = [...allContentTypeSchemaAttributes, ...allComponentSchemaAttributes];
|
||||
|
||||
for (const schemaAttrbutes of allSchemasAttributes) {
|
||||
for (const attribute of Object.values(schemaAttrbutes)) {
|
||||
if (attribute.type === 'customField') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user