From 22aa00f959dbe0a6a7e0b399dce834d57c1cb4c5 Mon Sep 17 00:00:00 2001 From: david-vaclavek Date: Tue, 5 Sep 2023 18:36:06 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20feat:=20fix=20download=20issues?= =?UTF-8?q?=20with=20Dynamic=20Zones?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../localazy-transfer-controller.js | 19 ++- server/services/strapi-i18n-service.js | 7 +- .../services/strapi-localazy-i18n-service.js | 53 +++++-- .../parsed-localazy-entry-to-create-entry.js | 133 +++++++++++++----- 4 files changed, 158 insertions(+), 54 deletions(-) diff --git a/server/controllers/localazy-transfer-controller.js b/server/controllers/localazy-transfer-controller.js index 1f57386..288fc2e 100644 --- a/server/controllers/localazy-transfer-controller.js +++ b/server/controllers/localazy-transfer-controller.js @@ -395,15 +395,17 @@ module.exports = { ); if (typeof modelContentTransferSetup !== "undefined" && shouldSetDownloadedProperty(modelContentTransferSetup, parsedKey.rest)) { - const parsedKeyRestWithoutComponents = parsedKey.rest.map((segment) => { - const semicolonIndex = segment.indexOf(";"); + const parsedKeyRestWithoutComponents = parsedKey.rest; + // TODO: component needs to be included in the key for dynamic zones (otherwise we loose data - only the last item of each unique entry id is set) + // .map((segment) => { + // const semicolonIndex = segment.indexOf(";"); - if (semicolonIndex === -1) { - return segment; - } + // if (semicolonIndex === -1) { + // return segment; + // } - return segment.substring(0, semicolonIndex); - }); + // return segment.substring(0, semicolonIndex); + // }); const setKey = [ isoStrapi, @@ -412,6 +414,8 @@ module.exports = { ...parsedKeyRestWithoutComponents, ]; + // ? TODO: Should be set as object instead of array? + // ? TODO: Should such thing be done only for dynamic zones? set(parsedLocalazyContent, setKey, value); } } @@ -486,6 +490,7 @@ module.exports = { } catch (e) { success = false; strapi.log.error(e.message); + strapi.log.error(JSON.stringify(e.details?.errors || {})); messageReport.push( `Cannot create an entry in ${isoStrapi} for ${uid}[${baseEntry.id}]: ${e.message}` ); diff --git a/server/services/strapi-i18n-service.js b/server/services/strapi-i18n-service.js index ec8a0ea..219e270 100644 --- a/server/services/strapi-i18n-service.js +++ b/server/services/strapi-i18n-service.js @@ -105,9 +105,12 @@ module.exports = ({ strapi }) => ({ baseEntry.id, newEntryLocale ); - const mergedEntry = merge(cloneDeep(baseEntry), insertedEntry); - return mergedEntry; + return insertedEntry + + // const mergedEntry = merge(cloneDeep(baseEntry), insertedEntry); + + // return mergedEntry; } catch (e) { strapi.log.error(e); throw e; diff --git a/server/services/strapi-localazy-i18n-service.js b/server/services/strapi-localazy-i18n-service.js index 9e5af97..44f8c36 100644 --- a/server/services/strapi-localazy-i18n-service.js +++ b/server/services/strapi-localazy-i18n-service.js @@ -2,6 +2,8 @@ const parsedLocalazyEntryToCreateEntry = require("../utils/parsed-localazy-entry-to-create-entry"); const parsedLocalazyEntryToUpdateEntry = require("../utils/parsed-localazy-entry-to-update-entry"); +const omitDeep = require("../utils/omit-deep"); +const { set, merge } = require("lodash"); module.exports = ({ strapi }) => ({ async createEntry( @@ -15,12 +17,13 @@ module.exports = ({ strapi }) => ({ // * The entry will be created and then updated as the structures differ // * It's one extra database call, but the complexity of recursive code to maintain does worth it + // Strapi i18n Service const StrapiI18nService = strapi .plugin("localazy") .service("strapiI18nService"); - const { createEntry } = parsedLocalazyEntryToCreateEntry( + const { createEntry, dynamicZoneComponentKeys } = parsedLocalazyEntryToCreateEntry( strapiContentTypesModels, translatedModel, baseEntry, @@ -28,22 +31,52 @@ module.exports = ({ strapi }) => ({ isoStrapi, ); + // ? TODO do not omit the __component from Dynamic Zones + const filteredBaseEntry = omitDeep(baseEntry, [ + // "__component", // do not omit the __component + "locale", + "localizations", + "createdAt", + "createdBy", + "updatedAt", + "updatedBy", + "publishedAt", + ]); + + let mergedCreateEntry = {}; + merge(mergedCreateEntry, filteredBaseEntry, createEntry); + mergedCreateEntry = omitDeep(mergedCreateEntry, [ + // "__component", + "locale", + "localizations", + "createdAt", + "createdBy", + "updatedAt", + "updatedBy", + "publishedAt", + ]); + // set dynamic zone compoonent keys again + // dynamicZoneComponentKeys.forEach((v) => { + // set(mergedCreateEntry, v.key, v.component); + // }); + + mergedCreateEntry.locale = isoStrapi; const createdEntry = await StrapiI18nService.createLocalizationForAnExistingEntry( ctx, uid, baseEntry, - createEntry, + mergedCreateEntry, ); - await this.updateEntry( - uid, - createdEntry.id, - strapiContentTypesModels, - translatedModel, - baseEntry, - isoStrapi, - ); + // await this.updateEntry( + // uid, + // createdEntry.id, + // strapiContentTypesModels, + // translatedModel, + // baseEntry, + // isoStrapi, + // ); return createdEntry; }, diff --git a/server/utils/parsed-localazy-entry-to-create-entry.js b/server/utils/parsed-localazy-entry-to-create-entry.js index e63c931..5d23a81 100644 --- a/server/utils/parsed-localazy-entry-to-create-entry.js +++ b/server/utils/parsed-localazy-entry-to-create-entry.js @@ -19,13 +19,14 @@ const parsedLocalazyEntryToCreateEntry = ( const toCreateEntry = ( entry, model, - baseEntry, + baseEntry, // this does not need to be passed, can be referenced from the closure // eslint-disable-next-line no-unused-vars key = "", prefix = "", component = "", isRepeatableComponent = false, isDZ = false, + isInsideDZ = false, ) => { if (Array.isArray(entry)) { // is array @@ -78,6 +79,28 @@ const parsedLocalazyEntryToCreateEntry = ( } } }); + } else if (isDZ) { + // TODO: implement DZ functionality + Object.entries(entry).forEach(([dzEntryIdWithComponent, value]) => { + let [dzEntryId, dzEntryComponent] = dzEntryIdWithComponent.split(";"); + dzEntryId = parseInt(dzEntryId); + const baseEntryDZEntry = get(baseEntry, prefix).find((v) => (v.id === dzEntryId) && (v.__component === dzEntryComponent)); + if (baseEntryDZEntry !== undefined) { + const dzEntryComponentModel = findModel(models, dzEntryComponent); + toCreateEntry( + value, + dzEntryComponentModel, + baseEntry, + dzEntryId, + `${prefix}.${dzEntryId}`, + dzEntryComponent, + true, + false, // we're already inside, so it's falsy + true, + ); + } + // ? don't do anything if baseEntryDZEntry is undefined - it means that the entry was deleted + }); } else { // is object Object.entries(entry).forEach(([objectKey, value]) => { @@ -86,38 +109,70 @@ const parsedLocalazyEntryToCreateEntry = ( // logicaly don't anything, skip... } else if (isComponent(attribute)) { // is component - const component = attribute.component; - const componentModel = findModel(models, component); - if (isRepeatable(attribute)) { - // is repeatable - array - const newPrefix = prefix - ? `${prefix}.${objectKey}` - : `${objectKey}`; - toCreateEntry( - value, - componentModel, - baseEntry, - objectKey, - newPrefix, - component, - true - ); - } else { - // is no repeatable - object - const newPrefix = prefix - ? `${prefix}.${objectKey}` - : `${objectKey}`; - set(createEntry, `${newPrefix}.__component`, component); - toCreateEntry( - value, - componentModel, - baseEntry, - objectKey, - newPrefix, - component, - false - ); + console.log("func key", key); + console.log("func comp", component); + const innerComponent = attribute.component; + const componentModel = findModel(models, innerComponent); + + let newPrefixBase = prefix; + let newPrefix = newPrefixBase + ? `${newPrefixBase}.${objectKey}` + : `${objectKey}`; + if (isInsideDZ) { + let [dzParamKey, dzEntryId] = newPrefixBase.split("."); + dzEntryId = parseInt(dzEntryId); + const baseEntryDZIndex = get(baseEntry, dzParamKey).findIndex((v) => (v.__component === component) && (v.id === dzEntryId)); // ? TODO: what if it's not found? + newPrefixBase = `${dzParamKey}.${baseEntryDZIndex}`; + newPrefix = `${newPrefixBase}.${objectKey}`; + } + const isRepeatableComponent = isRepeatable(attribute); + if (!isRepeatableComponent) { + set(createEntry, `${newPrefix}.__component`, innerComponent); } + toCreateEntry( + value, + componentModel, + baseEntry, + objectKey, + newPrefix, + innerComponent, + isRepeatableComponent, + false, + isInsideDZ, + ); + // if (isRepeatable(attribute)) { + // // TODO: need to count with possible inner-DZ components + // // is repeatable - array + // // const newPrefix = prefix + // // ? `${prefix}.${objectKey}` + // // : `${objectKey}`; + // toCreateEntry( + // value, + // componentModel, + // baseEntry, + // objectKey, + // newPrefix, + // innerComponent, + // true, + // false, + // isInsideDZ, + // ); + // } else { + // // TODO: need to count with possible inner-DZ components + // // is no repeatable - object + // set(createEntry, `${newPrefix}.__component`, innerComponent); + // toCreateEntry( + // value, + // componentModel, + // baseEntry, + // objectKey, + // newPrefix, + // innerComponent, + // false, + // false, + // isInsideDZ, + // ); + // } } else if (isDynamicZone(attribute)) { // behaves sort of like repeatable component const newPrefix = prefix @@ -134,14 +189,22 @@ const parsedLocalazyEntryToCreateEntry = ( true, ); } else { - const newPrefix = prefix ? `${prefix}.${objectKey}` : `${objectKey}`; + let newPrefixBase = prefix; + let newPrefix = newPrefixBase ? `${newPrefixBase}.${objectKey}` : `${objectKey}`; + if (isInsideDZ) { + let [dzParamKey, dzEntryId] = newPrefixBase.split("."); + dzEntryId = parseInt(dzEntryId); + const baseEntryDZIndex = get(baseEntry, dzParamKey).findIndex((v) => (v.__component === component) && (v.id === dzEntryId)); // ? TODO: what if it's not found? + newPrefixBase = `${dzParamKey}.${baseEntryDZIndex}`; + newPrefix = `${newPrefixBase}.${objectKey}`; + } set(createEntry, newPrefix, value); if (component) { - const componentKeyToSet = `${prefix}.__component`; + const componentKeyToSet = `${newPrefixBase}.__component`; set(createEntry, componentKeyToSet, component); - if (isDZ) { + if (isInsideDZ) { const isKeyAdded = (typeof dynamicZoneComponentKeys.find((v) => v.key === componentKeyToSet) !== "undefined"); if (!isKeyAdded) dynamicZoneComponentKeys.push({