mirror of
https://github.com/strapi/strapi.git
synced 2025-08-31 04:03:50 +00:00
delete old components in compos & dz
This commit is contained in:
parent
ac6716c21d
commit
c364a712b6
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const { has, pick, omit } = require('lodash/fp');
|
const { has, pick, omit, prop } = require('lodash/fp');
|
||||||
const delegate = require('delegates');
|
const delegate = require('delegates');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -369,6 +369,20 @@ const createComponent = async (uid, data) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// components can have nested compos so this must be recursive
|
||||||
|
const updateComponent = async (uid, componentToUpdate, data) => {
|
||||||
|
const model = strapi.getModel(uid);
|
||||||
|
|
||||||
|
const componentData = await updateComponents(uid, componentToUpdate, data);
|
||||||
|
|
||||||
|
return await strapi.query(uid).update({
|
||||||
|
where: {
|
||||||
|
id: componentToUpdate.id,
|
||||||
|
},
|
||||||
|
data: Object.assign(omitComponentData(model, data), componentData),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: we could generalize the logic to allow CRUD of relation directly in the DB layer
|
// NOTE: we could generalize the logic to allow CRUD of relation directly in the DB layer
|
||||||
const createComponents = async (uid, data) => {
|
const createComponents = async (uid, data) => {
|
||||||
const { attributes } = strapi.getModel(uid);
|
const { attributes } = strapi.getModel(uid);
|
||||||
@ -400,14 +414,10 @@ const createComponents = async (uid, data) => {
|
|||||||
componentValue.map(value => createComponent(componentUID, value))
|
componentValue.map(value => createComponent(componentUID, value))
|
||||||
);
|
);
|
||||||
|
|
||||||
componentBody[attributeName] = components.map(({ id }) => {
|
// TODO: add order
|
||||||
// TODO: Add order in the relation
|
componentBody[attributeName] = components.map(({ id }) => id);
|
||||||
// NOTE: add & support pivot data in DB
|
|
||||||
return id;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
const component = await createComponent(componentUID, data);
|
const component = await createComponent(componentUID, componentValue);
|
||||||
// NOTE: add & support pivot data in DB
|
|
||||||
componentBody[attributeName] = component.id;
|
componentBody[attributeName] = component.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,14 +446,18 @@ const createComponents = async (uid, data) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateOrCreateComponent = (componentUID, value) => {
|
const updateOrCreateComponent = (componentUID, value) => {
|
||||||
|
if (value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// update
|
// update
|
||||||
if (has('id', value)) {
|
if (has('id', value)) {
|
||||||
// TODO: verify the compo is associated with the entity
|
// TODO: verify the compo is associated with the entity
|
||||||
return strapi.query(componentUID).update({ where: { id: value.id }, data: value });
|
return updateComponent(componentUID, { id: value.id }, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create
|
// create
|
||||||
return strapi.query(componentUID).create({ data: value });
|
return createComponent(componentUID, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -462,37 +476,26 @@ const updateComponents = async (uid, entityToUpdate, data) => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: diff prev & new
|
|
||||||
|
|
||||||
if (attribute.type === 'component') {
|
if (attribute.type === 'component') {
|
||||||
const { component: componentUID, repeatable = false } = attribute;
|
const { component: componentUID, repeatable = false } = attribute;
|
||||||
|
|
||||||
const previousValue = await strapi.query(uid).load(entityToUpdate, attributeName);
|
|
||||||
const componentValue = data[attributeName];
|
const componentValue = data[attributeName];
|
||||||
|
|
||||||
// make diff between prev ids & data ids
|
await deleteOldComponents(uid, componentUID, entityToUpdate, attributeName, componentValue);
|
||||||
if (componentValue === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (repeatable === true) {
|
if (repeatable === true) {
|
||||||
if (!Array.isArray(componentValue)) {
|
if (!Array.isArray(componentValue)) {
|
||||||
throw new Error('Expected an array to create repeatable component');
|
throw new Error('Expected an array to create repeatable component');
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: returns null sometimes
|
|
||||||
const components = await Promise.all(
|
const components = await Promise.all(
|
||||||
componentValue.map(value => updateOrCreateComponent(componentUID, value))
|
componentValue.map(value => updateOrCreateComponent(componentUID, value))
|
||||||
);
|
);
|
||||||
|
|
||||||
componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }, idx) => {
|
// TODO: add order
|
||||||
// TODO: add & support pivot data in DB
|
componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => id);
|
||||||
return id;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
const component = await updateOrCreateComponent(componentUID, componentValue);
|
const component = await updateOrCreateComponent(componentUID, componentValue);
|
||||||
|
|
||||||
// TODO: add & support pivot data in DB
|
|
||||||
componentBody[attributeName] = component && component.id;
|
componentBody[attributeName] = component && component.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +505,8 @@ const updateComponents = async (uid, entityToUpdate, data) => {
|
|||||||
if (attribute.type === 'dynamiczone') {
|
if (attribute.type === 'dynamiczone') {
|
||||||
const dynamiczoneValues = data[attributeName];
|
const dynamiczoneValues = data[attributeName];
|
||||||
|
|
||||||
|
await deleteOldDZComponents(uid, entityToUpdate, attributeName, dynamiczoneValues);
|
||||||
|
|
||||||
if (!Array.isArray(dynamiczoneValues)) {
|
if (!Array.isArray(dynamiczoneValues)) {
|
||||||
throw new Error('Expected an array to create repeatable component');
|
throw new Error('Expected an array to create repeatable component');
|
||||||
}
|
}
|
||||||
@ -520,6 +525,86 @@ const updateComponents = async (uid, entityToUpdate, data) => {
|
|||||||
return componentBody;
|
return componentBody;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deleteOldComponents = async (
|
||||||
|
uid,
|
||||||
|
componentUID,
|
||||||
|
entityToUpdate,
|
||||||
|
attributeName,
|
||||||
|
componentValue
|
||||||
|
) => {
|
||||||
|
const previousValue = await strapi.query(uid).load(entityToUpdate, attributeName);
|
||||||
|
|
||||||
|
const idsToKeep = _.castArray(componentValue)
|
||||||
|
.filter(has('id'))
|
||||||
|
.map(prop('id'));
|
||||||
|
|
||||||
|
const allIds = _.castArray(previousValue).map(prop('id'));
|
||||||
|
|
||||||
|
idsToKeep.forEach(id => {
|
||||||
|
if (!allIds.includes(id)) {
|
||||||
|
const err = new Error(
|
||||||
|
`Some of the provided components in ${attributeName} are not related to the entity`
|
||||||
|
);
|
||||||
|
err.status = 400;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const idsToDelete = _.difference(allIds, idsToKeep);
|
||||||
|
|
||||||
|
if (idsToDelete.length > 0) {
|
||||||
|
for (const idToDelete of idsToDelete) {
|
||||||
|
await deleteComponent(componentUID, { id: idToDelete });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteOldDZComponents = async (uid, entityToUpdate, attributeName, dynamiczoneValues) => {
|
||||||
|
const previousValue = await strapi.query(uid).load(entityToUpdate, attributeName);
|
||||||
|
|
||||||
|
const idsToKeep = _.castArray(dynamiczoneValues)
|
||||||
|
.filter(has('id'))
|
||||||
|
.map(({ id, __component }) => ({
|
||||||
|
id,
|
||||||
|
__component,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const allIds = _.castArray(previousValue).map(({ id, __component }) => ({
|
||||||
|
id,
|
||||||
|
__component,
|
||||||
|
}));
|
||||||
|
|
||||||
|
idsToKeep.forEach(({ id, __component }) => {
|
||||||
|
if (!allIds.find(el => el.id === id && el.__component === __component)) {
|
||||||
|
const err = new Error(
|
||||||
|
`Some of the provided components in ${attributeName} are not related to the entity`
|
||||||
|
);
|
||||||
|
err.status = 400;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const idsToDelete = allIds.reduce((acc, { id, __component }) => {
|
||||||
|
if (!idsToKeep.find(el => el.id === id && el.__component === __component)) {
|
||||||
|
acc.push({ id, __component });
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (idsToDelete.length > 0) {
|
||||||
|
for (const idToDelete of idsToDelete) {
|
||||||
|
const { id, __component } = idToDelete;
|
||||||
|
await deleteComponent(__component, { id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteComponent = async (uid, componentToDelete) => {
|
||||||
|
await deleteComponents(uid, componentToDelete);
|
||||||
|
await strapi.query(uid).delete({ where: { id: componentToDelete.id } });
|
||||||
|
};
|
||||||
|
|
||||||
const deleteComponents = async (uid, entityToDelete) => {
|
const deleteComponents = async (uid, entityToDelete) => {
|
||||||
const { attributes } = strapi.getModel(uid);
|
const { attributes } = strapi.getModel(uid);
|
||||||
|
|
||||||
@ -538,13 +623,9 @@ const deleteComponents = async (uid, entityToDelete) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
await Promise.all(
|
await Promise.all(value.map(subValue => deleteComponent(componentUID, subValue)));
|
||||||
value.map(subValue => {
|
|
||||||
return strapi.query(componentUID).delete({ where: { id: subValue.id } });
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
await strapi.query(componentUID).delete({ where: { id: value.id } });
|
await deleteComponent(componentUID, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -558,11 +639,7 @@ const deleteComponents = async (uid, entityToDelete) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
await Promise.all(
|
await Promise.all(value.map(subValue => deleteComponent(subValue.__component, subValue)));
|
||||||
value.map(subValue => {
|
|
||||||
return strapi.query(subValue.__component).delete({ where: { id: subValue.id } });
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user