This commit is contained in:
Pierre Noël 2021-04-02 15:13:23 +02:00
parent 92a9ecb38d
commit 9cd6e158ff
3 changed files with 47 additions and 28 deletions

View File

@ -1,6 +1,6 @@
'use strict';
const { pick, uniq, prop, getOr, flatten, pipe } = require('lodash/fp');
const { pick, uniq, prop, getOr, flatten, pipe, map } = require('lodash/fp');
const { contentTypes: contentTypesUtils } = require('strapi-utils');
const { getService } = require('../utils');
const { validateGetNonLocalizedAttributesInput } = require('../validation/content-types');
@ -10,6 +10,8 @@ const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;
const getLocalesProperty = getOr([], 'properties.locales');
const getFieldsProperty = prop('properties.fields');
const getFirstLevelPath = map(path => path.split('.')[0]);
module.exports = {
async getNonLocalizedAttributes(ctx) {
const { user } = ctx.state;
@ -46,7 +48,8 @@ module.exports = {
const localePermissions = permissions
.filter(perm => getLocalesProperty(perm).includes(locale))
.map(getFieldsProperty);
const permittedFields = pipe(flatten, uniq)(localePermissions);
const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);
const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);
const sanitizedNonLocalizedFields = pick(permittedFields, nonLocalizedFields);

View File

@ -1,7 +1,7 @@
'use strict';
const _ = require('lodash');
const { pick, pipe, has, prop, isNil, cloneDeepWith } = require('lodash/fp');
const { pick, pipe, has, prop, isNil, cloneDeep, isArray } = require('lodash/fp');
const {
isRelationalAttribute,
getVisibleAttributes,
@ -97,25 +97,41 @@ const getNonLocalizedAttributes = model => {
);
};
const cleanIds = (model, { output = true }) => entry => {
// remove ids
const processedEntry = cloneDeepWith(value => {
if (typeof value === 'object' && has('id', value)) {
delete value.id;
}
}, entry);
const removeId = value => {
if (typeof value === 'object' && has('id', value)) {
delete value.id;
}
};
// set media ids back
if (!output) {
_.forIn(entry, (value, attrName) => {
const attr = model.attributes[attrName];
if (isMediaAttribute(attr) && value) {
processedEntry[attrName] = has('collection', attr) ? value : value.id;
}
});
const removeIds = model => entry => removeIdsMut(model, cloneDeep(entry));
const removeIdsMut = (model, entry) => {
if (isNil(entry)) {
return entry;
}
return processedEntry;
removeId(entry);
_.forEach(model.attributes, (attr, attrName) => {
const value = entry[attrName];
if (attr.type === 'dynamiczone' && isArray(value)) {
value.forEach(compo => {
if (has('__component', compo)) {
const model = strapi.components[compo.__component];
removeIdsMut(model, compo);
}
});
} else if (attr.type === 'component') {
const [model] = strapi.db.getModelsByAttribute(attr);
if (isArray(value)) {
value.forEach(compo => removeIdsMut(model, compo));
} else {
removeIdsMut(model, value);
}
}
});
return entry;
};
/**
@ -124,10 +140,11 @@ const cleanIds = (model, { output = true }) => entry => {
* @param {object} entry
* @returns {object}
*/
const copyNonLocalizedAttributes = (model, entry, { output = true } = {}) => {
const copyNonLocalizedAttributes = (model, entry) => {
const nonLocalizedAttributes = getNonLocalizedAttributes(model);
return pipe(pick(nonLocalizedAttributes), cleanIds(model, { output }))(entry);
const res = pipe(pick(nonLocalizedAttributes), removeIds(model))(entry);
return res;
};
/**
@ -154,7 +171,7 @@ const fillNonLocalizedAttributes = (entry, relatedEntry, { model }) => {
}
const modelDef = strapi.getModel(model);
const relatedEntryCopy = copyNonLocalizedAttributes(modelDef, relatedEntry, { output: false });
const relatedEntryCopy = copyNonLocalizedAttributes(modelDef, relatedEntry);
_.forEach(relatedEntryCopy, (value, field) => {
if (isNil(entry[field])) {

View File

@ -1,6 +1,6 @@
'use strict';
const { pick, prop, isNil } = require('lodash/fp');
const { prop, isNil, isEmpty } = require('lodash/fp');
const { getService } = require('../utils');
@ -43,17 +43,16 @@ const syncLocalizations = async (entry, { model }) => {
* @param {Object} options.model corresponding model
*/
const syncNonLocalizedAttributes = async (entry, { model }) => {
const { getNonLocalizedAttributes } = getService('content-types');
const { copyNonLocalizedAttributes } = getService('content-types');
if (Array.isArray(entry.localizations)) {
const nonLocalizedFields = getNonLocalizedAttributes(model);
const nonLocalizedAttributes = copyNonLocalizedAttributes(model, entry);
if (nonLocalizedFields.length === 0) {
if (isEmpty(nonLocalizedAttributes)) {
return;
}
const fieldsToUpdate = pick(nonLocalizedFields, entry);
const updateLocalization = id => strapi.query(model.uid).update({ id }, fieldsToUpdate);
const updateLocalization = id => strapi.query(model.uid).update({ id }, nonLocalizedAttributes);
await Promise.all(entry.localizations.map(({ id }) => updateLocalization(id)));
}