@localazy/strapi-plugin 0.1.11-rc.0 → 0.1.11-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/admin/src/modules/plugin-settings/components/ContentTransferSetup/index.js +5 -0
  2. package/admin/src/modules/plugin-settings/components/Tree/index.js +21 -6
  3. package/admin/src/modules/plugin-settings/functions/build-content-transfer-setup-schema.js +1 -1
  4. package/admin/src/modules/plugin-settings/functions/has-model-changed.js +1 -1
  5. package/admin/src/modules/plugin-settings/locale/en.js +1 -1
  6. package/admin/src/modules/plugin-settings/utils/get-filtered-models-schemas.js +1 -7
  7. package/admin/src/modules/plugin-settings/utils/get-models-tree.js +19 -3
  8. package/package.json +4 -4
  9. package/server/controllers/localazy-transfer-controller.js +27 -7
  10. package/server/functions/should-set-downloaded-property.js +48 -3
  11. package/server/services/strapi-i18n-service.js +1 -1
  12. package/server/services/strapi-localazy-i18n-service.js +1 -1
  13. package/server/tests/fixtures/parsed-localazy-entry-to-create-entry-lesson-dz.js +392 -0
  14. package/server/tests/fixtures/parsed-localazy-entry-to-create-entry-sample-json-dz.js +4675 -0
  15. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-lesson-dz.js +309 -0
  16. package/server/tests/fixtures/populate-create-update-entry-with-base-entry-sample-json-dz.js +884 -0
  17. package/server/tests/fixtures/strapi-plugin-all-models.js +844 -37
  18. package/server/utils/__tests__/parsed-localazy-entry-to-create-entry.test.js +211 -62
  19. package/server/utils/__tests__/pick-entries.test.js +936 -56
  20. package/server/utils/__tests__/populate-create-update-entry-with-base-entry.test.js +287 -0
  21. package/server/utils/build-populate.js +5 -0
  22. package/server/utils/model-utils.js +5 -0
  23. package/server/utils/omit-deep.js +7 -0
  24. package/server/utils/parsed-localazy-entry-to-create-entry.js +58 -4
  25. package/server/utils/parsed-localazy-entry-to-update-entry.js +6 -1
  26. package/server/utils/pick-deep.js +22 -0
  27. package/server/utils/pick-entries.js +90 -5
  28. package/server/utils/populate-create-update-entry-with-base-entry.js +51 -3
  29. package/server/tests/fixtures/collection-flattened.js +0 -76
  30. package/server/tests/fixtures/restaurant-flattened.js +0 -46
  31. package/server/tests/fixtures/restaurants-pick-paths.js +0 -15
@@ -111,6 +111,11 @@ function ContentTransferSetup() {
111
111
 
112
112
  const newState = cloneDeep(prevState);
113
113
  keys.forEach((key) => {
114
+ // * if there's a "__component__" in the key; skip
115
+ if (key.includes("__component__")) {
116
+ return;
117
+ }
118
+
114
119
  const isEditable = get(model, key) !== null;
115
120
 
116
121
  if (isEditable) {
@@ -1,8 +1,10 @@
1
1
  import React, { useState, useEffect } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { Box } from "@strapi/design-system/Box";
4
+ import { Flex } from "@strapi/design-system/Flex";
4
5
  import { Switch } from '@strapi/design-system/Switch';
5
6
  import { Checkbox } from '@strapi/design-system/Checkbox';
7
+ import DynamicZone from '@strapi/icons/DynamicZone';
6
8
  import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion';
7
9
  import TreeItem from "../TreeItem";
8
10
  import flattenObject from "../../../@common/utils/functions/flatten-deep";
@@ -25,14 +27,24 @@ function Tree(props) {
25
27
  <>
26
28
  {Object.entries(branch).map(([key, value]) => {
27
29
  const isSubbranchObject = typeof value === "object" && value !== null;
28
- const flattened = flattenObject(value);
30
+ let flattened = flattenObject(value)
31
+ flattened = Object.fromEntries(Object.entries(flattened).filter(([key]) => !key.includes("__component__")));
29
32
  const flattenedKeys = Object.keys(flattened).map((k) => `${path}.${key}.${k}`);
30
33
 
31
- const hasTruthyValue = Object.values(flattened).some(v => v);
32
- const hasFalsyValue = Object.values(flattened).some(v => !v && v !== null);
33
- const hasAllNullValue = Object.values(flattened).every(v => v === null);
34
+ // debugger;
35
+ const hasTruthyValue = Object
36
+ .values(flattened)
37
+ .some(v => v);
38
+ const hasFalsyValue = Object
39
+ .values(flattened)
40
+ .some(v => !v && v !== null);
41
+ const hasAllNullValue = Object
42
+ .values(flattened)
43
+ .every(v => v === null);
34
44
 
35
- if (key === "__model__") {
45
+ const RESERVED_KEYS_TO_SKIP = ["__model__", "__component__"];
46
+
47
+ if (RESERVED_KEYS_TO_SKIP.includes(key)) {
36
48
  return false;
37
49
  }
38
50
  const passedKey = `${path}.${key}`;
@@ -51,7 +63,10 @@ function Tree(props) {
51
63
  indeterminate={hasTruthyValue && hasFalsyValue}
52
64
  onChange={() => onTreeItemClick(flattenedKeys, hasTruthyValue && !hasFalsyValue)}
53
65
  >
54
- {key || "-"}
66
+ <Flex alignItems="center">
67
+ {!!value?.__component__ && (<Flex alignItems="center" marginRight={2}><DynamicZone width="1rem" height="1rem" /></Flex>)}
68
+ {value?.__component__ || key || "-"}
69
+ </Flex>
55
70
  </Checkbox>)
56
71
  }
57
72
  <TreeItem
@@ -1,6 +1,6 @@
1
1
  import set from "lodash-es/set";
2
2
  import get from "lodash-es/get";
3
- import deepKeys from "deep-keys";
3
+ import deepKeys from "@david-vaclavek/deep-keys";
4
4
  import sortByModelName from "../../@common/utils/sort-by-model-name";
5
5
  import arrayOfModelsToObject from "../utils/array-of-models-to-object";
6
6
  import findModelValueByKey from "../utils/find-model-value-by-key";
@@ -1,4 +1,4 @@
1
- import deepKeys from "deep-keys";
1
+ import deepKeys from "@david-vaclavek/deep-keys";
2
2
  import get from "lodash-es/get";
3
3
  import PluginSettingsService from "../services/plugin-settings-service";
4
4
  import StrapiModelService from "../services/strapi-model-service";
@@ -1,7 +1,7 @@
1
1
  export default {
2
2
  content_transfer_setup: "Content Transfer Setup",
3
3
  content_transfer_setup_description:
4
- "Setup what content type fields will be uploaded to Localazy",
4
+ "Select which content type fields will be uploaded to Localazy",
5
5
  save: "Save",
6
6
  cancel: "Cancel",
7
7
  close: "Close",
@@ -1,10 +1,4 @@
1
- import baseSupportedContentTypeFields from "../../@common/models/supported-content-type-fields";
2
-
3
- const SUPPORTED_CONTENT_TYPE_FIELDS = [
4
- ...baseSupportedContentTypeFields,
5
- "component",
6
- // "relation", // relation cannot be supported field type
7
- ];
1
+ import SUPPORTED_CONTENT_TYPE_FIELDS from "../../@common/models/supported-content-type-fields";
8
2
 
9
3
  export default (models) => {
10
4
  if (!models) {
@@ -28,9 +28,25 @@ const getModelsTree = (allModels, localizableModels = []) => {
28
28
  : isComponentAttributesObjectTranslatable
29
29
  ),
30
30
  };
31
- } else if (
32
- SUPPORTED_CONTENT_TYPE_FIELDS.includes(attributes[attribute].type)
33
- ) {
31
+ } else if (attributes[attribute].type === "dynamiczone") {
32
+ const components = attributes[attribute].components;
33
+ currentModelTree[attribute] = [];
34
+ components.forEach((c) => {
35
+ const nestedModel = allModels.find((model) => model.uid === c);
36
+
37
+ const modelTree = getModelTree(
38
+ nestedModel.__schema__.attributes,
39
+ true,
40
+ isComponentAttributesObjectTranslatable === null
41
+ ? attributes[attribute].pluginOptions?.i18n?.localized || false
42
+ : isComponentAttributesObjectTranslatable
43
+ );
44
+ currentModelTree[attribute].push({
45
+ "__component__": c,
46
+ ...modelTree,
47
+ });
48
+ });
49
+ } else if (SUPPORTED_CONTENT_TYPE_FIELDS.includes(attributes[attribute].type)) {
34
50
  // field might not be localizable
35
51
  if (isComponentAttributes) {
36
52
  if (isComponentAttributesObjectTranslatable) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@localazy/strapi-plugin",
3
- "version": "0.1.11-rc.0",
3
+ "version": "0.1.11-rc.1",
4
4
  "description": "The official Strapi Plugin by Localazy.",
5
5
  "strapi": {
6
6
  "name": "localazy",
@@ -27,8 +27,8 @@
27
27
  "test:watch": "jest --watch --config ./jest.config.js"
28
28
  },
29
29
  "dependencies": {
30
+ "@david-vaclavek/deep-keys": "^0.5.0",
30
31
  "@localazy/ts-api": "^1.0.6",
31
- "deep-keys": "^0.5.0",
32
32
  "i18next": "^21.6.13",
33
33
  "isomorphic-fetch": "^3.0.0",
34
34
  "js-cookie": "^3.0.1",
@@ -39,9 +39,9 @@
39
39
  "styled-components": "^5.3.3"
40
40
  },
41
41
  "peerDependencies": {
42
- "@strapi/strapi": "^4.0.0",
43
42
  "@strapi/design-system": "^1.0.0",
44
- "@strapi/icons": "^1.0.0"
43
+ "@strapi/icons": "^1.0.0",
44
+ "@strapi/strapi": "^4.0.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@babel/plugin-transform-modules-commonjs": "^7.17.7",
@@ -17,6 +17,7 @@ const {
17
17
  const shouldSetDownloadedProperty = require("../functions/should-set-downloaded-property");
18
18
  const set = require("lodash/set");
19
19
  const isEmpty = require("lodash/isEmpty");
20
+ const omitDeep = require("../utils/omit-deep");
20
21
 
21
22
  module.exports = {
22
23
  async upload(ctx) {
@@ -86,7 +87,8 @@ module.exports = {
86
87
  }
87
88
 
88
89
  // get only enabled fields paths
89
- const pickPaths = getPickPaths(transferSetupModel[collectionName]);
90
+ const currentTransferSetupModel = transferSetupModel[collectionName];
91
+ const pickPaths = getPickPaths(currentTransferSetupModel);
90
92
  if (!pickPaths.length) {
91
93
  const message = `No fields for collection ${collectionName} transfer are enabled.`;
92
94
  messageReport.push(message);
@@ -97,11 +99,19 @@ module.exports = {
97
99
  (pickPath) => `${modelUid}.${pickPath}`
98
100
  );
99
101
 
100
- const populate = await StrapiService.getPopulateObject(modelUid);
101
-
102
102
  let entries = await strapi.entityService.findMany(modelUid, {
103
- populate,
103
+ populate: "deep",
104
104
  });
105
+ entries = omitDeep(entries, [
106
+ // "__component",
107
+ "locale",
108
+ "localizations",
109
+ "createdAt",
110
+ "createdBy",
111
+ "updatedAt",
112
+ "updatedBy",
113
+ "publishedAt",
114
+ ]);
105
115
 
106
116
  if (!entries) {
107
117
  strapi.log.info(`No entries found for model ${modelUid}`);
@@ -116,8 +126,8 @@ module.exports = {
116
126
  const flatten = flattenObject({
117
127
  [modelUid]: entry,
118
128
  });
119
- // get only enabled fields
120
- const pickedFlatten = pickEntries(flatten, pickPathsWithUid);
129
+ // get only enabled fields; "__component" will be filtered out inside of the function
130
+ const pickedFlatten = pickEntries(flatten, pickPathsWithUid, currentTransferSetupModel);
121
131
 
122
132
  flattenContent = {
123
133
  ...flattenContent,
@@ -340,11 +350,21 @@ module.exports = {
340
350
  );
341
351
 
342
352
  if (shouldSetDownloadedProperty(modelContentTransferSetup, parsedKey.rest)) {
353
+ const parsedKeyRestWithoutComponents = parsedKey.rest.map((segment) => {
354
+ const semicolonIndex = segment.indexOf(";");
355
+
356
+ if (semicolonIndex === -1) {
357
+ return segment;
358
+ }
359
+
360
+ return segment.substring(0, semicolonIndex);
361
+ });
362
+
343
363
  const setKey = [
344
364
  isoStrapi,
345
365
  parsedKey.uid,
346
366
  parsedKey.id,
347
- ...parsedKey.rest,
367
+ ...parsedKeyRestWithoutComponents,
348
368
  ];
349
369
 
350
370
  set(parsedLocalazyContent, setKey, value);
@@ -1,5 +1,31 @@
1
1
  const get = require("lodash/get");
2
2
 
3
+ const getDynamicZoneKeySegment = (parsedKey) => {
4
+ return parsedKey.find((segment) => segment.includes(";"));
5
+ };
6
+
7
+ const isDynamicZone = (parsedKey) => {
8
+ return !!getDynamicZoneKeySegment(parsedKey);
9
+ };
10
+
11
+ const getComponentNameFromDynamicZoneKeySegment = (dynamicZoneKeySegment) => {
12
+ return dynamicZoneKeySegment.split(";")[1];
13
+ };
14
+
15
+ const getDynamicZoneKeySegmentIndex = (parsedKey) => {
16
+ return parsedKey.findIndex((segment) => segment.includes(";"));
17
+ }
18
+
19
+ const getDynamicZonePropertyName = (parsedKey) => {
20
+ const dynamicZoneKeySegmentIndex = getDynamicZoneKeySegmentIndex(parsedKey);
21
+
22
+ if (dynamicZoneKeySegmentIndex === -1) {
23
+ return undefined;
24
+ }
25
+
26
+ return parsedKey[dynamicZoneKeySegmentIndex - 1];
27
+ };
28
+
3
29
  const shouldSetDownloadedProperty = (
4
30
  modelContentTransferSetup,
5
31
  parsedKeyRest,
@@ -8,9 +34,28 @@ const shouldSetDownloadedProperty = (
8
34
  return false;
9
35
  }
10
36
 
11
- const filteredParsedKeyRest = parsedKeyRest
12
- .filter((partialKey) => isNaN(parseInt(partialKey)));
13
- return !!get(modelContentTransferSetup, filteredParsedKeyRest);
37
+ const dynamicZoneKeySegment = getDynamicZoneKeySegment(parsedKeyRest);
38
+ if (!!dynamicZoneKeySegment) {
39
+ const dynamicZonePropertyName = getDynamicZonePropertyName(parsedKeyRest);
40
+ const componentName = getComponentNameFromDynamicZoneKeySegment(dynamicZoneKeySegment);
41
+
42
+ const dzContentTransferSetupModel = get(modelContentTransferSetup, dynamicZonePropertyName);
43
+ const dzContentTransferSetupComponentModel = dzContentTransferSetupModel.find((c) => c.__component__ === componentName);
44
+
45
+ if (!dzContentTransferSetupComponentModel) {
46
+ return false;
47
+ }
48
+
49
+ const dynamicZoneKeySegmentIndex = getDynamicZoneKeySegmentIndex(parsedKeyRest);
50
+ const slicedParsedKeyRest = parsedKeyRest.slice(dynamicZoneKeySegmentIndex + 1);
51
+ const filteredSlicedParsedKeyRest = slicedParsedKeyRest.filter((segment) => isNaN(parseInt(segment)));
52
+
53
+ return !!get(dzContentTransferSetupComponentModel, filteredSlicedParsedKeyRest);
54
+ } else {
55
+ const filteredParsedKeyRest = parsedKeyRest
56
+ .filter((partialKey) => isNaN(parseInt(partialKey)));
57
+ return !!get(modelContentTransferSetup, filteredParsedKeyRest);
58
+ }
14
59
  };
15
60
 
16
61
  module.exports = shouldSetDownloadedProperty;
@@ -39,7 +39,7 @@ module.exports = ({ strapi }) => ({
39
39
  }
40
40
  },
41
41
  parseLocalazyKey(key) {
42
- const split = key.split(/\.|\[|\]/);
42
+ const split = key.split(/\.(?![^[]*])|\[|\]/);
43
43
  const filteredSplit = split.filter((item) => item !== "");
44
44
 
45
45
  return {
@@ -20,7 +20,7 @@ module.exports = ({ strapi }) => ({
20
20
  .plugin("localazy")
21
21
  .service("strapiI18nService");
22
22
 
23
- const createEntry = parsedLocalazyEntryToCreateEntry(
23
+ const { createEntry } = parsedLocalazyEntryToCreateEntry(
24
24
  strapiContentTypesModels,
25
25
  translatedModel,
26
26
  baseEntry,