From 8abf651a46c60429a4e04b0a341c0a2e675ec6a5 Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Fri, 21 Jan 2022 16:21:00 +0100 Subject: [PATCH 1/3] feat: Sort relations on more than 1 field --- server/config/type.js | 22 ++++++++++++++-------- server/config/types.js | 4 ++-- server/utils/index.js | 14 +++++++++----- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index ff82ed8..a7b9ea1 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -99,18 +99,22 @@ const ConfigType = class ConfigType { const entity = await queryAPI.update({ where: combinedUidWhereFilter, data: query }); // Delete/create relations. - await Promise.all(this.relations.map(async ({ queryString, relationName, parentName, relationSortField }) => { + await Promise.all(this.relations.map(async ({ queryString, relationName, parentName, relationSortFields }) => { const relationQueryApi = strapi.query(queryString); - existingConfig = sanitizeConfig(existingConfig, relationName, relationSortField); - configContent = sanitizeConfig(configContent, relationName, relationSortField); + existingConfig = sanitizeConfig(existingConfig, relationName, relationSortFields); + configContent = sanitizeConfig(configContent, relationName, relationSortFields); - const configToAdd = difference(configContent[relationName], existingConfig[relationName], relationSortField); - const configToDelete = difference(existingConfig[relationName], configContent[relationName], relationSortField); + const configToAdd = difference(configContent[relationName], existingConfig[relationName], relationSortFields[0]); + const configToDelete = difference(existingConfig[relationName], configContent[relationName], relationSortFields[0]); await Promise.all(configToDelete.map(async (config) => { + const whereClause = {}; + relationSortFields.map((sortField) => { + whereClause[sortField] = config[sortField]; + }); await relationQueryApi.delete({ where: { - [relationSortField]: config[relationSortField], + ...whereClause, [parentName]: entity.id, }, }); @@ -168,13 +172,15 @@ const ConfigType = class ConfigType { if (shouldExclude) return; const formattedConfig = { ...sanitizeConfig(config) }; - await Promise.all(this.relations.map(async ({ queryString, relationName, relationSortField, parentName }) => { + await Promise.all(this.relations.map(async ({ queryString, relationName, relationSortFields, parentName }) => { const relations = await noLimit(strapi.query(queryString), { where: { [parentName]: combinedUidWhereFilter }, }); relations.map((relation) => sanitizeConfig(relation)); - relations.sort(dynamicSort(relationSortField)); + relationSortFields.map((sortField) => { + relations.sort(dynamicSort(sortField)); + }); formattedConfig[relationName] = relations; })); diff --git a/server/config/types.js b/server/config/types.js index a4923bc..c337f20 100644 --- a/server/config/types.js +++ b/server/config/types.js @@ -17,7 +17,7 @@ const types = (strapi) => { queryString: 'admin::permission', relationName: 'permissions', parentName: 'role', - relationSortField: 'action', + relationSortFields: ['action', 'subject'], }], }, ]; @@ -32,7 +32,7 @@ const types = (strapi) => { queryString: 'plugin::users-permissions.permission', relationName: 'permissions', parentName: 'role', - relationSortField: 'action', + relationSortFields: ['action'], }], }); } diff --git a/server/utils/index.js b/server/utils/index.js index 3d8f440..7572fd4 100644 --- a/server/utils/index.js +++ b/server/utils/index.js @@ -37,14 +37,16 @@ const dynamicSort = (property) => { return (a, b) => { if (sortOrder === -1) { - return b[property].localeCompare(a[property]); - } else { + if (b[property]) { + return b[property].localeCompare(a[property]); + } + } else if (a[property]) { return a[property].localeCompare(b[property]); } }; }; -const sanitizeConfig = (config, relation, relationSortField) => { +const sanitizeConfig = (config, relation, relationSortFields) => { delete config._id; delete config.id; delete config.updatedAt; @@ -63,8 +65,10 @@ const sanitizeConfig = (config, relation, relationSortField) => { formattedRelations.push(relationEntity); }); - if (relationSortField) { - formattedRelations.sort(dynamicSort(relationSortField)); + if (relationSortFields) { + relationSortFields.map((sortField) => { + formattedRelations.sort(dynamicSort(sortField)); + }); } config[relation] = formattedRelations; From dbe3ea8c88157af267f47bdb6fbc4264cccd7798 Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Fri, 21 Jan 2022 17:33:14 +0100 Subject: [PATCH 2/3] fix: More specific selection of relation entities --- server/config/type.js | 4 ++-- server/utils/getArrayDiff.js | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index a7b9ea1..be9cba1 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -104,8 +104,8 @@ const ConfigType = class ConfigType { existingConfig = sanitizeConfig(existingConfig, relationName, relationSortFields); configContent = sanitizeConfig(configContent, relationName, relationSortFields); - const configToAdd = difference(configContent[relationName], existingConfig[relationName], relationSortFields[0]); - const configToDelete = difference(existingConfig[relationName], configContent[relationName], relationSortFields[0]); + const configToAdd = difference(configContent[relationName], existingConfig[relationName], relationSortFields); + const configToDelete = difference(existingConfig[relationName], configContent[relationName], relationSortFields); await Promise.all(configToDelete.map(async (config) => { const whereClause = {}; diff --git a/server/utils/getArrayDiff.js b/server/utils/getArrayDiff.js index 5dd2b38..3e6feeb 100644 --- a/server/utils/getArrayDiff.js +++ b/server/utils/getArrayDiff.js @@ -1,6 +1,12 @@ -const difference = (arrayOne, arrayTwo, compareKey) => { - return arrayOne.filter(({ [compareKey]: id1 }) => { - return !arrayTwo.some(({ [compareKey]: id2 }) => id2 === id1); +const difference = (arrayOne, arrayTwo, compareKeys) => { + return arrayOne.filter(({ + [compareKeys[0]]: id1, + [compareKeys[1]]: id2, + }) => { + return !arrayTwo.some(({ + [compareKeys[0]]: id3, + [compareKeys[1]]: id4, + }) => id1 === id3 && id2 === id4); }); }; From dbbdeb5f5b1efd5f6d80512c40c19388c82368ed Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Mon, 24 Jan 2022 20:48:59 +0100 Subject: [PATCH 3/3] feat: Update relations entities on import --- server/config/type.js | 18 +++++++++++++++++- server/utils/getArrayDiff.js | 21 ++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index be9cba1..06087e6 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -1,6 +1,6 @@ const { isEmpty } = require('lodash'); const { logMessage, sanitizeConfig, dynamicSort, noLimit, getCombinedUid, getCombinedUidWhereFilter, getUidParamsFromName } = require('../utils'); -const difference = require('../utils/getArrayDiff'); +const { difference, same } = require('../utils/getArrayDiff'); const ConfigType = class ConfigType { constructor({ queryString, configName, uid, jsonFields, relations }) { @@ -106,6 +106,7 @@ const ConfigType = class ConfigType { const configToAdd = difference(configContent[relationName], existingConfig[relationName], relationSortFields); const configToDelete = difference(existingConfig[relationName], configContent[relationName], relationSortFields); + const configToUpdate = same(configContent[relationName], existingConfig[relationName], relationSortFields); await Promise.all(configToDelete.map(async (config) => { const whereClause = {}; @@ -125,6 +126,21 @@ const ConfigType = class ConfigType { data: { ...config, [parentName]: entity.id }, }); })); + + await Promise.all(configToUpdate.map(async (config, index) => { + const whereClause = {}; + relationSortFields.map((sortField) => { + whereClause[sortField] = config[sortField]; + }); + + await relationQueryApi.update({ + where: { + ...whereClause, + [parentName]: entity.id, + }, + data: { ...config, [parentName]: entity.id }, + }); + })); })); } } diff --git a/server/utils/getArrayDiff.js b/server/utils/getArrayDiff.js index 3e6feeb..a1584a3 100644 --- a/server/utils/getArrayDiff.js +++ b/server/utils/getArrayDiff.js @@ -10,4 +10,23 @@ const difference = (arrayOne, arrayTwo, compareKeys) => { }); }; -module.exports = difference; +const same = (arrayOne, arrayTwo, compareKeys) => { + return arrayOne.filter(({ + [compareKeys[0]]: id1, + [compareKeys[1]]: id2, + ...restOne + }) => { + return !arrayTwo.some(({ + [compareKeys[0]]: id3, + [compareKeys[1]]: id4, + ...restTwo + }) => id1 === id3 + && id2 === id4 + && JSON.stringify(restOne) === JSON.stringify(restTwo)); + }); +}; + +module.exports = { + difference, + same, +};