@griddo/ax 1.49.42 → 1.51.2

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 (51) hide show
  1. package/README.md +6 -0
  2. package/config/griddo-config.js +2 -2
  3. package/config/webpack.config.js +0 -3
  4. package/config/webpackSchemas.config.js +18 -0
  5. package/package.json +41 -24
  6. package/scripts/griddo-sync-schemas.js +28 -6
  7. package/scripts/griddo.js +0 -1
  8. package/src/api/sites.tsx +2 -2
  9. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +2 -1
  10. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +8 -2
  11. package/src/components/Fields/ArrayFieldGroup/ArrayFieldInline/index.tsx +43 -0
  12. package/src/components/Fields/ArrayFieldGroup/ArrayFieldInline/style.tsx +30 -0
  13. package/src/components/Fields/ArrayFieldGroup/ArrayFieldItem/index.tsx +55 -0
  14. package/src/components/Fields/ArrayFieldGroup/ArrayFieldItem/style.tsx +48 -0
  15. package/src/components/Fields/ArrayFieldGroup/index.tsx +91 -0
  16. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +12 -6
  17. package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +13 -5
  18. package/src/components/Fields/ComponentArray/helpers.tsx +13 -1
  19. package/src/components/Fields/ComponentContainer/index.tsx +5 -3
  20. package/src/components/Fields/FieldsDivider/index.tsx +21 -0
  21. package/src/components/Fields/FieldsDivider/style.tsx +19 -0
  22. package/src/components/Fields/RadioGroup/index.tsx +1 -1
  23. package/src/components/Fields/VisualUniqueSelection/ScrollableSelection/index.tsx +4 -11
  24. package/src/components/Fields/index.tsx +4 -0
  25. package/src/components/MainWrapper/AppBar/index.tsx +3 -1
  26. package/src/components/MainWrapper/index.tsx +1 -0
  27. package/src/components/index.tsx +4 -0
  28. package/src/containers/Navigation/Defaults/actions.tsx +32 -27
  29. package/src/containers/PageEditor/actions.tsx +44 -22
  30. package/src/containers/PageEditor/constants.tsx +1 -0
  31. package/src/containers/PageEditor/interfaces.tsx +6 -0
  32. package/src/containers/PageEditor/reducer.tsx +4 -0
  33. package/src/containers/Sites/actions.tsx +22 -0
  34. package/src/containers/Sites/constants.tsx +7 -7
  35. package/src/containers/Sites/interfaces.tsx +6 -0
  36. package/src/containers/Sites/reducer.tsx +4 -0
  37. package/src/forms/editor.tsx +17 -9
  38. package/src/forms/elements.tsx +8 -14
  39. package/src/forms/fields.tsx +1 -1
  40. package/src/forms/index.tsx +2 -0
  41. package/src/hooks/bulk.tsx +12 -3
  42. package/src/modules/Content/PageImporter/index.tsx +1 -0
  43. package/src/modules/Content/index.tsx +5 -1
  44. package/src/modules/GlobalEditor/Editor/index.tsx +6 -6
  45. package/src/modules/GlobalEditor/index.tsx +33 -0
  46. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +5 -5
  47. package/src/modules/PageEditor/Editor/index.tsx +11 -6
  48. package/src/modules/PageEditor/index.tsx +1 -0
  49. package/src/modules/StructuredData/Form/index.tsx +1 -0
  50. package/src/modules/StructuredData/StructuredDataList/index.tsx +9 -2
  51. package/src/types/index.tsx +1 -0
package/README.md CHANGED
@@ -1 +1,7 @@
1
1
  # Griddo AX
2
+
3
+ Panel de Administración de Griddo.
4
+
5
+ # Arrancar el entorno de desarrollo
6
+
7
+ Ejecuta `yarn start:dev` en la raíz de este paquete o en la raíz del monorepo.
@@ -3,12 +3,12 @@ const findUp = require("find-up");
3
3
 
4
4
  const pkgDir = require("pkg-dir");
5
5
 
6
- const isComponentLibraryEnv = process.env.IS_COMPONENT_LIBRARY;
6
+ const isComponentLibraryEnv = __dirname.includes("node_modules");
7
7
 
8
8
  const resolveComponentsPath = (customPath = "") =>
9
9
  isComponentLibraryEnv
10
10
  ? path.resolve(pkgDir.sync(process.cwd()), customPath)
11
- : path.resolve(pkgDir.sync(__dirname), "../../components", customPath);
11
+ : path.resolve(pkgDir.sync(__dirname), "../griddo-components", customPath);
12
12
 
13
13
  const getComponentsJSConfig = () => {
14
14
  const jsConfigPath = findUp.sync("jsconfig.json", { cwd: resolveComponentsPath() });
@@ -39,9 +39,6 @@ const reactRefreshOverlayEntry = require.resolve("react-dev-utils/refreshOverlay
39
39
  // makes for a smoother build process.
40
40
  const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== "false";
41
41
 
42
- const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === "true";
43
- const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === "true";
44
-
45
42
  const imageInlineSizeLimit = parseInt(process.env.IMAGE_INLINE_SIZE_LIMIT || "10000");
46
43
 
47
44
  // Check if TypeScript is setup
@@ -15,6 +15,20 @@ const createConfig = ({ input, output }) => ({
15
15
  },
16
16
  },
17
17
  plugins: [new webpack.ProgressPlugin()],
18
+ module: {
19
+ rules: [
20
+ {
21
+ test: /\.m?js$/,
22
+ exclude: /(node_modules|bower_components)/,
23
+ use: {
24
+ loader: "babel-loader",
25
+ options: {
26
+ presets: ["@babel/preset-env"],
27
+ },
28
+ },
29
+ },
30
+ ],
31
+ },
18
32
  });
19
33
 
20
34
  module.exports = (withExternalConfig) => {
@@ -29,6 +43,10 @@ module.exports = (withExternalConfig) => {
29
43
  return reject(err);
30
44
  }
31
45
 
46
+ if (stats.compilation.errors && stats.compilation.errors.length) {
47
+ return reject(stats.compilation.errors[0]);
48
+ }
49
+
32
50
  return resolve({
33
51
  stats,
34
52
  });
package/package.json CHANGED
@@ -1,14 +1,25 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "1.49.42",
4
+ "version": "1.51.2",
5
+ "authors": [
6
+ "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
+ "Carlos Torres <carlos.torres@secuoyas.com>",
8
+ "Diego Béjar <diego.bejar@secuoyas.com>",
9
+ "Francis Vega <francis.vega@secuoyas.com>",
10
+ "Gonzalo Hernández <gonzalo.hernandez@secuoyas.com>",
11
+ "Sergio Ródenas <sergio.rodenas@secuoyas.com>",
12
+ "Txema León <txema.leon@secuoyas.com>"
13
+ ],
14
+ "homepage": "https://griddo.io",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/griddo/griddo"
18
+ },
5
19
  "bin": {
6
20
  "griddo": "./scripts/griddo.js",
7
21
  "griddo-sync-schemas": "./scripts/griddo-sync-schemas.js"
8
22
  },
9
- "publishConfig": {
10
- "access": "public"
11
- },
12
23
  "scripts": {
13
24
  "start": "npm run start:dev",
14
25
  "start:local": "env-cmd -f env/.env.local node scripts/start.js",
@@ -22,17 +33,10 @@
22
33
  "format": "prettier -w .",
23
34
  "start:test": "env-cmd -f env/.env.development node scripts/dev.js"
24
35
  },
25
- "files": [
26
- "config",
27
- "public",
28
- "scripts",
29
- "src",
30
- "tsconfig.json",
31
- "tsconfig.paths.json"
32
- ],
33
36
  "dependencies": {
34
37
  "@atlaskit/tree": "^8.2.0",
35
38
  "@babel/core": "7.14.2",
39
+ "@babel/preset-env": "^7.14.5",
36
40
  "@babel/preset-react": "^7.14.5",
37
41
  "@pmmmwh/react-refresh-webpack-plugin": "0.5.0-rc.0",
38
42
  "@styled-system/prop-types": "5.1.2",
@@ -54,6 +58,7 @@
54
58
  "@types/react-test-renderer": "16.9.1",
55
59
  "@types/react-textarea-autosize": "^4.3.5",
56
60
  "@types/styled-components": "4.1.19",
61
+ "@types/uuid": "^8.3.1",
57
62
  "@types/webpack-env": "^1.14.1",
58
63
  "@typescript-eslint/eslint-plugin": "^4.25.0",
59
64
  "@typescript-eslint/parser": "^4.25.0",
@@ -68,7 +73,7 @@
68
73
  "case-sensitive-paths-webpack-plugin": "2.4.0",
69
74
  "compress.js": "^1.1.2",
70
75
  "connected-react-router": "6.5.2",
71
- "css-loader": "4.3.0",
76
+ "css-loader": "^4.3.0",
72
77
  "css-minimizer-webpack-plugin": "3.0.2",
73
78
  "date-fns": "^2.21.3",
74
79
  "dotenv": "6.2.0",
@@ -114,17 +119,18 @@
114
119
  "reflect-metadata": "0.1.13",
115
120
  "resolve": "^1.20.0",
116
121
  "resolve-url-loader": "^4.0.0",
117
- "sass-loader": "^12.1.0",
122
+ "sass-loader": "^8.0.2",
118
123
  "semver": "^7.3.5",
119
124
  "source-map-loader": "^1.1.2",
120
125
  "string-replace-loader": "^3.0.1",
121
- "style-loader": "1.0.0",
126
+ "style-loader": "^1.2.1",
122
127
  "styled-components": "^4.4.1",
123
128
  "styled-reset": "4.0.1",
124
129
  "terser-webpack-plugin": "1.4.1",
125
130
  "ts-pnp": "1.1.4",
126
131
  "typescript": "~3.8",
127
132
  "url-loader": "^4.1.1",
133
+ "uuid": "^8.3.2",
128
134
  "webpack": "4.44.2",
129
135
  "webpack-dev-server": "3.11.1",
130
136
  "webpack-manifest-plugin": "2.2.0",
@@ -145,9 +151,11 @@
145
151
  "prettier": "^2.3.0",
146
152
  "react-test-render": "1.1.2"
147
153
  },
148
- "peerDependencies": {
149
- "react": "*",
150
- "react-dom": "*"
154
+ "babel": {
155
+ "presets": [
156
+ "react-app",
157
+ "@babel/preset-react"
158
+ ]
151
159
  },
152
160
  "browserslist": {
153
161
  "production": [
@@ -161,6 +169,14 @@
161
169
  "last 1 safari version"
162
170
  ]
163
171
  },
172
+ "files": [
173
+ "config",
174
+ "public",
175
+ "scripts",
176
+ "src",
177
+ "tsconfig.json",
178
+ "tsconfig.paths.json"
179
+ ],
164
180
  "jest": {
165
181
  "roots": [
166
182
  "<rootDir>/src"
@@ -209,11 +225,12 @@
209
225
  "jest-watch-typeahead/testname"
210
226
  ]
211
227
  },
212
- "babel": {
213
- "presets": [
214
- "react-app",
215
- "@babel/preset-react"
216
- ]
228
+ "peerDependencies": {
229
+ "react": "*",
230
+ "react-dom": "*"
231
+ },
232
+ "publishConfig": {
233
+ "access": "public"
217
234
  },
218
- "gitHead": "a601c4449b08e03c47e72248115633ea3267e9b7"
235
+ "gitHead": "137fb5810ec6523db7745a43f77e47484611441b"
219
236
  }
@@ -5,6 +5,7 @@ const axios = require("axios");
5
5
  const chalk = require("chalk");
6
6
  const dotenv = require("dotenv");
7
7
  const path = require("path");
8
+ const fs = require("fs");
8
9
  const compiler = require("../config/webpackSchemas.config");
9
10
 
10
11
  const { resolveComponentsPath } = require("../config/griddo-config");
@@ -21,10 +22,30 @@ async function main() {
21
22
  console.clear();
22
23
  const tempFile = "__griddo_config_parsed__.js";
23
24
 
24
- await compiler({
25
- input: resolveComponentsPath("griddo.config.js"),
26
- output: { filename: tempFile, path: __dirname },
27
- });
25
+ const inputFile = resolveComponentsPath("griddo.config.js");
26
+ const outputFile = `${__dirname}/${tempFile}`;
27
+
28
+ if (fs.existsSync(outputFile)) {
29
+ fs.unlinkSync(outputFile);
30
+ }
31
+
32
+ try {
33
+ if (!fs.existsSync(inputFile)) {
34
+ throw new Error(`Source schemas config not found: ${inputFile}`);
35
+ }
36
+
37
+ await compiler({
38
+ input: resolveComponentsPath("griddo.config.js"),
39
+ output: { filename: tempFile, path: __dirname },
40
+ });
41
+
42
+ if (!fs.existsSync(outputFile)) {
43
+ throw new Error(`Unknown error when parsing ${inputFile}`);
44
+ }
45
+ } catch (err) {
46
+ console.log(`\n${chalk.red("ERROR:")} ${err.message}\n`);
47
+ process.exit(1);
48
+ }
28
49
 
29
50
  const _griddoConfig = require(path.resolve(__dirname, `./${tempFile}`));
30
51
  const griddoConfig = _griddoConfig.default || _griddoConfig;
@@ -48,11 +69,12 @@ async function main() {
48
69
  method: API_METHOD,
49
70
  data: { version, ...emptySchemas, ...griddoConfig.schemas },
50
71
  });
51
- console.log(res);
72
+ // console.log(res);
52
73
  const data = await res?.json?.();
53
- console.log(data);
74
+ // console.log(data);
54
75
  } catch (e) {
55
76
  console.log(chalk.red("ERROR:"), e.response?.data?.message || e.response || e.message);
77
+ process.exit(1);
56
78
  }
57
79
  }
58
80
 
package/scripts/griddo.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- process.env.IS_COMPONENT_LIBRARY = true;
3
2
 
4
3
  // Makes the script crash on unhandled rejections instead of silently
5
4
  // ignoring them. In the future, promise rejections that are not handled will
package/src/api/sites.tsx CHANGED
@@ -156,9 +156,9 @@ const getGlobalPages = async (params: IGetGlobalPagesParams, filterQuery?: strin
156
156
  const getGlobalPagesLight = async (params: IGetGlobalPagesParams): Promise<AxiosResponse> => {
157
157
  const { host, endpoint } = SERVICES.GET_GLOBAL_PAGES_LIGHT;
158
158
 
159
- const { deleted, page, itemsPerPage, query, filterStructuredData, excludeSite } = params;
159
+ const { deleted, page, itemsPerPage, query, filterStructuredData, excludeSite, liveStatus } = params;
160
160
 
161
- SERVICES.GET_GLOBAL_PAGES_LIGHT.dynamicUrl = `${host}${endpoint}?deleted=${deleted}&page=${page}&itemsPerPage=${itemsPerPage}&excludeSite=${excludeSite}`;
161
+ SERVICES.GET_GLOBAL_PAGES_LIGHT.dynamicUrl = `${host}${endpoint}?deleted=${deleted}&page=${page}&itemsPerPage=${itemsPerPage}&excludeSite=${excludeSite}&liveStatus=${liveStatus}`;
162
162
 
163
163
  if (query && query.trim() !== "") SERVICES.GET_GLOBAL_PAGES_LIGHT.dynamicUrl += `&query=${query}`;
164
164
  if (filterStructuredData)
@@ -28,10 +28,11 @@ const Field = (props: IProps): JSX.Element => {
28
28
 
29
29
  const isGroup = field.type === "FieldGroup";
30
30
  const isConditional = field.type === "ConditionalField";
31
+ const isArrayGroup = field.type === "ArrayFieldGroup";
31
32
 
32
33
  let innerFields: JSX.Element[] = [];
33
34
 
34
- if (isGroup || isConditional) {
35
+ if (isGroup || isConditional || isArrayGroup) {
35
36
  const innerActions = { ...actions, updateValue, goTo };
36
37
  innerFields = getInnerFields(field.fields, innerActions, selectedContent, isTemplateActivated, errors, deleteError);
37
38
  }
@@ -13,7 +13,10 @@ const GlobalPageForm = (props: IProps): JSX.Element => {
13
13
  const { selectedTab, setSelectedTab, schema, pageTitle, setHistoryPush, actions } = props;
14
14
  const tabs = ["content", "config"];
15
15
 
16
- const handleGetGlobalPage = async () => await actions.getGlobalFromLocalPageAction();
16
+ const handleGetGlobalPage = async () => {
17
+ actions.saveCurrentSiteInfoAction();
18
+ await actions.getGlobalFromLocalPageAction();
19
+ };
17
20
 
18
21
  const handleClick = async () => {
19
22
  await handleGetGlobalPage();
@@ -67,7 +70,10 @@ interface IProps {
67
70
  schema: ISchema;
68
71
  pageTitle?: string;
69
72
  setHistoryPush?: (path: string, isEditor: boolean) => void;
70
- actions: { getGlobalFromLocalPageAction(): Promise<void> };
73
+ actions: {
74
+ getGlobalFromLocalPageAction(): Promise<void>;
75
+ saveCurrentSiteInfoAction(): Promise<void>;
76
+ };
71
77
  }
72
78
 
73
79
  export default GlobalPageForm;
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+
3
+ import { IconAction } from "@ax/components";
4
+
5
+ import * as S from "./style";
6
+
7
+ const ArrayFieldInline = (props: IProps): JSX.Element => {
8
+ const { fields, item, index, onChange, handleDelete } = props;
9
+
10
+ const deleteItem = () => {
11
+ handleDelete(index);
12
+ };
13
+
14
+ return (
15
+ <S.Wrapper>
16
+ <S.Content>
17
+ <S.IconWrapper>
18
+ <IconAction icon="delete" onClick={deleteItem} size="s" />
19
+ </S.IconWrapper>
20
+ {fields.map((field: any) => {
21
+ const key = field.props.objKey;
22
+ const handleChange = (newValue: any) => onChange({ [key]: newValue });
23
+
24
+ return {
25
+ ...field,
26
+ props: { ...field.props, value: item[key], objKey: key, onChange: handleChange },
27
+ key,
28
+ };
29
+ })}
30
+ </S.Content>
31
+ </S.Wrapper>
32
+ );
33
+ };
34
+
35
+ interface IProps {
36
+ fields: any[];
37
+ item: Record<string, unknown>;
38
+ index: number;
39
+ onChange: (value: Record<string, unknown>) => void;
40
+ handleDelete: (index: number) => void;
41
+ }
42
+
43
+ export default ArrayFieldInline;
@@ -0,0 +1,30 @@
1
+ import styled from "styled-components";
2
+
3
+ const Wrapper = styled.div`
4
+ margin-bottom: ${(p) => p.theme.spacing.xs};
5
+ `;
6
+
7
+ const Content = styled.div`
8
+ position: relative;
9
+ display: flex;
10
+
11
+ & > div {
12
+ margin-right: ${(p) => p.theme.spacing.m};
13
+
14
+ &:last-child,
15
+ &:first-child {
16
+ margin-right: 0;
17
+ }
18
+ }
19
+ `;
20
+
21
+ const IconWrapper = styled.div`
22
+ position: absolute;
23
+ top: -2px;
24
+ right: 10px;
25
+ width: ${(p) => p.theme.spacing.s};
26
+ height: ${(p) => p.theme.spacing.s};
27
+ z-index: 99;
28
+ `;
29
+
30
+ export { Wrapper, Content, IconWrapper };
@@ -0,0 +1,55 @@
1
+ import React, { useState } from "react";
2
+
3
+ import * as S from "./style";
4
+
5
+ const ArrayFieldItem = (props: IProps): JSX.Element => {
6
+ const { fields, item, name, index, onChange, handleDelete } = props;
7
+
8
+ const [isOpen, setIsOpen] = useState(false);
9
+
10
+ const handleClick = () => setIsOpen(!isOpen);
11
+
12
+ const deleteItem = () => {
13
+ handleDelete(index);
14
+ };
15
+
16
+ const menuOptions = [
17
+ {
18
+ label: "Delete",
19
+ icon: "delete",
20
+ action: deleteItem,
21
+ },
22
+ ];
23
+
24
+ return (
25
+ <S.Wrapper isOpen={isOpen}>
26
+ <S.Title onClick={handleClick} isOpen={isOpen}>
27
+ {`${name} ${index + 1}`}
28
+ <S.StyledActionMenu icon="more" options={menuOptions} />
29
+ </S.Title>
30
+ <S.Content isOpen={isOpen}>
31
+ {fields.map((field: any) => {
32
+ const key = field.props.objKey;
33
+ const handleChange = (newValue: any) => onChange({ [key]: newValue });
34
+
35
+ return {
36
+ ...field,
37
+ props: { ...field.props, value: item[key], objKey: key, onChange: handleChange },
38
+ key,
39
+ };
40
+ })}
41
+ </S.Content>
42
+ </S.Wrapper>
43
+ );
44
+ };
45
+
46
+ interface IProps {
47
+ name: string;
48
+ fields: any[];
49
+ item: Record<string, unknown>;
50
+ index: number;
51
+ onChange: (value: Record<string, unknown>) => void;
52
+ handleDelete: (index: number) => void;
53
+ }
54
+
55
+ export default ArrayFieldItem;
@@ -0,0 +1,48 @@
1
+ import styled from "styled-components";
2
+ import ActionMenu from "@ax/components/ActionMenu";
3
+
4
+ const Wrapper = styled.div<{ isOpen: boolean }>`
5
+ background-color: ${(p) => p.theme.color.uiBarBackground};
6
+ margin-bottom: ${(p) => p.theme.spacing.xs};
7
+ border: 1px solid ${(p) => (p.isOpen ? p.theme.color.interactive01 : p.theme.color.uiLine)};
8
+ border-radius: ${(p) => p.theme.radii.s};
9
+ `;
10
+
11
+ const StyledActionMenu = styled(ActionMenu)`
12
+ width: ${(p) => p.theme.spacing.m};
13
+ height: ${(p) => p.theme.spacing.m};
14
+ display: flex;
15
+ margin-left: auto;
16
+ `;
17
+
18
+ const Title = styled.div<{ isOpen: boolean }>`
19
+ position: relative;
20
+ display: flex;
21
+ ${(p) => p.theme.textStyle.fieldContent};
22
+ color: ${(p) => p.theme.colors.textHighEmphasis};
23
+ padding: ${(p) => p.theme.spacing.s};
24
+ cursor: pointer;
25
+ text-transform: capitalize;
26
+ align-items: center;
27
+ width: 100%;
28
+ :after {
29
+ position: absolute;
30
+ right: 55px;
31
+ top: ${(p) => (p.isOpen ? `28px` : `24px`)};
32
+ content: "";
33
+ border: solid ${(p) => p.theme.color.interactive01};
34
+ border-width: 0 2px 2px 0;
35
+ display: inline-block;
36
+ padding: 3px;
37
+ transform: ${(p) => (p.isOpen ? `rotate(-135deg)` : `rotate(45deg)`)};
38
+ }
39
+ `;
40
+
41
+ const Content = styled.div<{ isOpen: boolean }>`
42
+ overflow-y: hidden;
43
+ max-height: ${(p) => (p.isOpen ? `auto` : 0)};
44
+ transition: all 0.5s ease-in-out;
45
+ padding: ${(p) => `0 ${p.theme.spacing.s}`};
46
+ `;
47
+
48
+ export { Wrapper, Title, Content, StyledActionMenu };
@@ -0,0 +1,91 @@
1
+ import React, { useState } from "react";
2
+ import { v4 as uuidv4 } from "uuid";
3
+
4
+ import { Button, FieldsDivider } from "@ax/components";
5
+ import ArrayFieldItem from "./ArrayFieldItem";
6
+ import ArrayFieldInline from "./ArrayFieldInline";
7
+
8
+ const ArrayFieldGroup = (props: IProps): JSX.Element => {
9
+ const { value, name, innerFields, onChange, divider, arrayType } = props;
10
+
11
+ const initialValue = value ? Object.values(value) : [];
12
+ const initialValueMapped = initialValue.map((val: any) => {
13
+ return val.id ? val : { id: uuidv4(), ...val };
14
+ });
15
+
16
+ const [items, setItems] = useState(initialValueMapped);
17
+
18
+ const handleClick = () => {
19
+ const newItems = [...items, { id: uuidv4() }];
20
+ setItems(newItems);
21
+ onChange(newItems);
22
+ };
23
+
24
+ const handleChange = (newValue: Record<string, unknown>, index: number) => {
25
+ const updatedItems = [...items];
26
+ updatedItems[index] = {
27
+ ...updatedItems[index],
28
+ ...newValue,
29
+ };
30
+ setItems(updatedItems);
31
+ onChange(updatedItems);
32
+ };
33
+
34
+ const handleDelete = (index: number) => {
35
+ const updatedItems = [...items];
36
+ updatedItems.splice(index, 1);
37
+ setItems(updatedItems);
38
+ onChange(updatedItems);
39
+ };
40
+
41
+ const DividerComponent = () => (divider ? <FieldsDivider data={divider} /> : null);
42
+
43
+ return (
44
+ <div>
45
+ <DividerComponent />
46
+ <div>
47
+ {items &&
48
+ items.map((item: any, index: number) => {
49
+ const handleFieldChange = (newValue: Record<string, unknown>) => handleChange(newValue, index);
50
+
51
+ return arrayType === "inline" ? (
52
+ <ArrayFieldInline
53
+ key={item.id}
54
+ fields={innerFields}
55
+ item={item}
56
+ index={index}
57
+ onChange={handleFieldChange}
58
+ handleDelete={handleDelete}
59
+ />
60
+ ) : (
61
+ <ArrayFieldItem
62
+ key={item.id}
63
+ name={name}
64
+ fields={innerFields}
65
+ item={item}
66
+ index={index}
67
+ onChange={handleFieldChange}
68
+ handleDelete={handleDelete}
69
+ />
70
+ );
71
+ })}
72
+ </div>
73
+ <div>
74
+ <Button type="button" onClick={handleClick} buttonStyle="line">
75
+ {`Add ${name}`}
76
+ </Button>
77
+ </div>
78
+ </div>
79
+ );
80
+ };
81
+
82
+ interface IProps {
83
+ value: Record<string, unknown>[];
84
+ name: string;
85
+ onChange: (value: Record<string, unknown>[]) => void;
86
+ innerFields: any[];
87
+ divider: { title: string; text: string };
88
+ arrayType: string;
89
+ }
90
+
91
+ export default ArrayFieldGroup;
@@ -4,7 +4,7 @@ import { IModule } from "@ax/types";
4
4
  import { ComponentContainer } from "@ax/components";
5
5
 
6
6
  import AddItemButton from "./AddItemButton";
7
- import { getComponentProps, containerToComponentArray } from "../helpers";
7
+ import { getComponentProps, containerToComponentArray, getTypefromKey } from "../helpers";
8
8
 
9
9
  import * as S from "./style";
10
10
 
@@ -21,8 +21,13 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
21
21
  maxItems,
22
22
  disabled,
23
23
  activatedModules,
24
+ objKey,
25
+ field,
24
26
  } = props;
25
27
 
28
+ const type = getTypefromKey(objKey);
29
+ const { contentType = type } = field;
30
+
26
31
  let addModuleAction: any;
27
32
  let addComponentAction: any;
28
33
 
@@ -38,14 +43,12 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
38
43
  return fixedValue.length > 1 ? `#${index + 1} ${name}` : name;
39
44
  };
40
45
 
41
- const { elements, componentModules } = selectedContent;
42
-
43
- const isComponentModule = !!componentModules;
44
- const isModuleArr = !elements && !isComponentModule;
46
+ const isComponentModule = contentType === "components";
47
+ const isModuleArr = contentType === "modules";
45
48
 
46
49
  const handleAddModule = (moduleType: string) => addModuleAction(moduleType, editorID, isComponentModule);
47
50
 
48
- const handleAddComponent = (componentType: string) => addComponentAction && addComponentAction(componentType);
51
+ const handleAddComponent = (componentType: string) => addComponentAction && addComponentAction(componentType, objKey);
49
52
 
50
53
  const handleAdd = isModuleArr ? handleAddModule : handleAddComponent;
51
54
 
@@ -90,6 +93,7 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
90
93
  selectedContent={selectedContent}
91
94
  disabled={disabled}
92
95
  canDuplicate={showAddItemButton && !isModuleDeactivated}
96
+ parentKey={objKey}
93
97
  />
94
98
  );
95
99
  })}
@@ -109,6 +113,8 @@ export interface IMixableComponentArrayProps {
109
113
  categories?: any;
110
114
  disabled?: boolean;
111
115
  activatedModules: string[];
116
+ objKey: string;
117
+ field: any;
112
118
  }
113
119
 
114
120
  export default MixableComponentArray;