Dynamic zone support configurable prop on attributes (#4664)

* Add event on component creation

* Handle configurable attributes
This commit is contained in:
Alexandre BODIN 2019-12-06 14:42:05 +01:00 committed by GitHub
parent 6f7197f87a
commit d0d0942a14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 24 deletions

View File

@ -4,6 +4,7 @@ const path = require('path');
const _ = require('lodash');
const pluralize = require('pluralize');
const { isConfigurable } = require('../../utils/attributes');
const { nameToSlug, nameToCollectionName } = require('../../utils/helpers');
const createSchemaHandler = require('./schema-handler');
@ -58,7 +59,13 @@ module.exports = function createComponentBuilder() {
.set(['info', 'name'], infos.name)
.set(['info', 'icon'], infos.icon)
.set(['info', 'description'], infos.description)
.set('attributes', this.convertAttributes(infos.attributes));
.setAttributes(this.convertAttributes(infos.attributes));
if (this.components.size === 0) {
strapi.emit('didCreateFirstComponent');
} else {
strapi.emit('didCreateComponent');
}
this.components.set(uid, handler);
@ -75,7 +82,7 @@ module.exports = function createComponentBuilder() {
throw new Error('component.notFound');
}
const handler = this.components.get(uid);
const component = this.components.get(uid);
const [, nameUID] = uid.split('.');
@ -88,7 +95,13 @@ module.exports = function createComponentBuilder() {
const newDir = path.join(strapi.dir, 'components', newCategory);
handler
const oldAttributes = component.schema.attributes;
const newAttributes = _.omitBy(infos.attributes, (attr, key) => {
return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);
});
component
.setUID(newUID)
.setDir(newDir)
.set('connection', infos.connection)
@ -96,8 +109,7 @@ module.exports = function createComponentBuilder() {
.set(['info', 'name'], infos.name)
.set(['info', 'icon'], infos.icon)
.set(['info', 'description'], infos.description)
// TODO: keep configurable args etc...
.set('attributes', this.convertAttributes(infos.attributes));
.setAttributes(this.convertAttributes(newAttributes));
if (newUID !== uid) {
this.components.forEach(compo => {
@ -109,7 +121,7 @@ module.exports = function createComponentBuilder() {
});
}
return handler;
return component;
},
deleteComponent(uid) {

View File

@ -4,15 +4,15 @@ const path = require('path');
const _ = require('lodash');
const pluralize = require('pluralize');
const { isRelation, toUID } = require('../../utils/attributes');
const { isRelation, toUID, isConfigurable } = require('../../utils/attributes');
const { nameToSlug, nameToCollectionName } = require('../../utils/helpers');
const createSchemaHandler = require('./schema-handler');
module.exports = function createComponentBuilder() {
return {
setRelation({ key, modelName, attribute }) {
this.contentTypes.get(attribute.target).set(
['attributes', attribute.targetAttribute],
this.contentTypes.get(attribute.target).setAttribute(
attribute.targetAttribute,
generateRelation({
key,
attribute,
@ -28,14 +28,14 @@ module.exports = function createComponentBuilder() {
const uid = toUID(target, plugin);
const targetCT = this.contentTypes.get(uid);
const targetAttribute = targetCT.get(['attributes', attribute.via]);
const targetAttribute = targetCT.getAttribute(attribute.via);
// do not delete polymorphic relations
if (targetAttribute.collection === '*' || targetAttribute.model === '*') {
return;
}
return targetCT.unset(['attributes', attribute.via]);
return targetCT.deleteAttribute(attribute.via);
},
/**
@ -84,7 +84,7 @@ module.exports = function createComponentBuilder() {
increments: true,
timestamps: true,
})
.set('attributes', this.convertAttributes(infos.attributes));
.setAttributes(this.convertAttributes(infos.attributes));
Object.keys(infos.attributes).forEach(key => {
const attribute = infos.attributes[key];
@ -112,39 +112,48 @@ module.exports = function createComponentBuilder() {
const oldAttributes = contentType.schema.attributes;
const newAttributes = _.omitBy(infos.attributes, (attr, key) => {
return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);
});
const newKeys = _.difference(
Object.keys(infos.attributes),
Object.keys(newAttributes),
Object.keys(oldAttributes)
);
const deletedKeys = _.difference(
Object.keys(oldAttributes),
Object.keys(infos.attributes)
Object.keys(newAttributes)
);
const remainingKeys = _.intersection(
Object.keys(oldAttributes),
Object.keys(infos.attributes)
Object.keys(newAttributes)
);
// remove old relations
deletedKeys.forEach(key => {
const attribute = oldAttributes[key];
if (isRelation(attribute) && _.has(attribute, 'via')) {
// if the old relation has a target attribute. we need to remove it
if (
isConfigurable(attribute) &&
isRelation(attribute) &&
_.has(attribute, 'via')
) {
this.unsetRelation(attribute);
}
});
remainingKeys.forEach(key => {
const oldAttribute = oldAttributes[key];
const newAttribute = infos.attributes[key];
const newAttribute = newAttributes[key];
if (!isRelation(oldAttribute) && isRelation(newAttribute)) {
return this.setRelation({
key,
modelName: contentType.modelName,
attribute: infos.attributes[key],
attribute: newAttributes[key],
});
}
@ -153,7 +162,10 @@ module.exports = function createComponentBuilder() {
}
if (isRelation(oldAttribute) && isRelation(newAttribute)) {
if (oldAttribute.via !== newAttribute.targetAttribute) {
if (
_.has(oldAttribute, 'via') &&
oldAttribute.via !== newAttribute.targetAttribute
) {
this.unsetRelation(oldAttribute);
}
@ -167,7 +179,7 @@ module.exports = function createComponentBuilder() {
// add new relations
newKeys.forEach(key => {
const attribute = infos.attributes[key];
const attribute = newAttributes[key];
if (isRelation(attribute)) {
this.setRelation({
@ -183,7 +195,7 @@ module.exports = function createComponentBuilder() {
.set('collectionName', infos.collectionName)
.set(['info', 'name'], infos.name)
.set(['info', 'description'], infos.description)
.set('attributes', this.convertAttributes(infos.attributes));
.setAttributes(this.convertAttributes(newAttributes));
return contentType;
},

View File

@ -3,7 +3,7 @@
const path = require('path');
const fse = require('fs-extra');
const _ = require('lodash');
const { toUID } = require('../../utils/attributes');
const { toUID, isConfigurable } = require('../../utils/attributes');
module.exports = function createSchemaHandler(infos) {
const { category, modelName, plugin, uid, dir, filename, schema } = infos;
@ -96,6 +96,34 @@ module.exports = function createSchemaHandler(infos) {
return this;
},
getAttribute(key) {
return this.get(['attributes', key]);
},
setAttribute(key, attribute) {
return this.set(['attributes', key], attribute);
},
deleteAttribute(key) {
return this.unset(['attributes', key]);
},
setAttributes(newAttributes) {
// delete old configurable attributes
for (let key in this.schema.attributes) {
if (isConfigurable(this.schema.attributes[key])) {
this.deleteAttribute(key);
}
}
// set new Attributes
for (let key in newAttributes) {
this.setAttribute(key, newAttributes[key]);
}
return this;
},
removeContentType(uid) {
const { attributes } = state.schema;
@ -107,7 +135,7 @@ module.exports = function createSchemaHandler(infos) {
const relationUID = toUID(target, plugin);
if (relationUID === uid) {
this.unset(['attributes', key]);
this.deleteAttribute(key);
}
});
@ -122,7 +150,7 @@ module.exports = function createSchemaHandler(infos) {
const attr = attributes[key];
if (attr.type === 'component' && attr.component === uid) {
this.unset(['attributes', key]);
this.deleteAttribute(key);
}
if (

View File

@ -26,6 +26,8 @@ const hasComponent = model => {
return compoKeys.length > 0;
};
const isConfigurable = attribute => _.get(attribute, 'configurable', true);
const isRelation = attribute =>
_.has(attribute, 'target') ||
_.has(attribute, 'model') ||
@ -137,6 +139,7 @@ module.exports = {
toUID,
hasComponent,
isRelation,
isConfigurable,
replaceTemporaryUIDs,
formatAttributes,