@griddo/ax 11.2.12 → 11.3.0

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 (106) hide show
  1. package/package.json +3 -2
  2. package/src/__tests__/components/SideModal/SideModal.test.tsx +15 -11
  3. package/src/api/images.tsx +17 -2
  4. package/src/api/pages.tsx +49 -2
  5. package/src/api/selects.tsx +7 -5
  6. package/src/components/Browser/index.tsx +8 -1
  7. package/src/components/Button/style.tsx +7 -2
  8. package/src/components/ConfigPanel/Form/ConnectedField/NavConnectedField/index.tsx +6 -3
  9. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/TemplateManager/index.tsx +8 -3
  10. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +20 -6
  11. package/src/components/ConfigPanel/NavigationForm/Field/index.tsx +1 -1
  12. package/src/components/ErrorCenter/index.tsx +6 -5
  13. package/src/components/Fields/AsyncSelect/index.tsx +3 -1
  14. package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +1 -1
  15. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +18 -15
  16. package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +6 -7
  17. package/src/components/Fields/ComponentArray/helpers.tsx +19 -11
  18. package/src/components/Fields/ComponentContainer/EmptyContainer/index.tsx +10 -3
  19. package/src/components/Fields/ComponentContainer/index.tsx +15 -3
  20. package/src/components/Fields/FormContainer/FormModal/index.tsx +217 -0
  21. package/src/components/Fields/FormContainer/FormModal/style.tsx +129 -0
  22. package/src/components/Fields/FormContainer/index.tsx +96 -0
  23. package/src/components/Fields/FormContainer/style.tsx +74 -0
  24. package/src/components/Fields/HiddenField/index.tsx +8 -5
  25. package/src/components/Fields/HiddenField/style.tsx +28 -18
  26. package/src/components/Fields/IntegrationsField/index.tsx +8 -2
  27. package/src/components/Fields/LinkField/index.tsx +1 -1
  28. package/src/components/Fields/TextField/index.tsx +3 -3
  29. package/src/components/Fields/UrlField/utils.tsx +2 -2
  30. package/src/components/Fields/index.tsx +2 -0
  31. package/src/components/FieldsBehavior/index.tsx +7 -4
  32. package/src/components/FileGallery/index.tsx +5 -5
  33. package/src/components/FloatingButton/index.tsx +34 -0
  34. package/src/components/FloatingButton/style.tsx +76 -0
  35. package/src/components/FloatingPanel/style.tsx +1 -2
  36. package/src/components/Gallery/index.tsx +1 -1
  37. package/src/components/MainWrapper/AppBar/index.tsx +2 -2
  38. package/src/components/MainWrapper/index.tsx +2 -2
  39. package/src/components/MainWrapper/style.tsx +1 -0
  40. package/src/components/Modal/index.tsx +3 -3
  41. package/src/components/OcassionalToast/index.tsx +25 -0
  42. package/src/components/OcassionalToast/style.tsx +33 -0
  43. package/src/components/SearchField/index.tsx +4 -3
  44. package/src/components/SideModal/SideModalOption/index.tsx +1 -3
  45. package/src/components/SideModal/index.tsx +67 -44
  46. package/src/components/SideModal/style.tsx +67 -23
  47. package/src/components/TableFilters/CategoryFilter/index.tsx +14 -3
  48. package/src/components/TableFilters/CategoryFilter/style.tsx +2 -2
  49. package/src/components/Toast/index.tsx +6 -4
  50. package/src/components/index.tsx +8 -0
  51. package/src/containers/Forms/actions.tsx +92 -51
  52. package/src/containers/Gallery/actions.tsx +2 -5
  53. package/src/containers/Navigation/Defaults/actions.tsx +6 -4
  54. package/src/containers/Navigation/Defaults/utils.tsx +1 -43
  55. package/src/containers/PageEditor/actions.tsx +53 -34
  56. package/src/containers/PageEditor/reducer.tsx +1 -1
  57. package/src/containers/PageEditor/utils.tsx +22 -9
  58. package/src/forms/editor.tsx +20 -1
  59. package/src/forms/elements.tsx +3 -0
  60. package/src/forms/index.tsx +2 -0
  61. package/src/forms/validators.tsx +56 -33
  62. package/src/helpers/containerEvaluations.tsx +1 -1
  63. package/src/helpers/fields.tsx +1 -1
  64. package/src/helpers/images.tsx +71 -1
  65. package/src/helpers/index.tsx +5 -1
  66. package/src/helpers/schemas.tsx +10 -7
  67. package/src/helpers/themes.tsx +2 -2
  68. package/src/hooks/forms.tsx +2 -2
  69. package/src/hooks/modals.tsx +2 -2
  70. package/src/modules/Categories/CategoriesList/CategoryPanel/index.tsx +4 -7
  71. package/src/modules/Categories/CategoriesList/index.tsx +1 -3
  72. package/src/modules/FileDrive/atoms.tsx +2 -2
  73. package/src/modules/FileDrive/index.tsx +9 -9
  74. package/src/modules/Forms/FormCategoriesList/CategoryItem/index.tsx +30 -10
  75. package/src/modules/Forms/FormCategoriesList/CategoryPanel/index.tsx +1 -0
  76. package/src/modules/Forms/FormCategoriesList/index.tsx +45 -21
  77. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/Field/index.tsx +3 -0
  78. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/TemplateManager/index.tsx +9 -6
  79. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/index.tsx +20 -4
  80. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/index.tsx +17 -2
  81. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/index.tsx +7 -1
  82. package/src/modules/Forms/FormEditor/Editor/index.tsx +8 -2
  83. package/src/modules/Forms/FormEditor/PageBrowser/index.tsx +20 -16
  84. package/src/modules/Forms/FormEditor/PageBrowser/style.tsx +9 -0
  85. package/src/modules/Forms/FormEditor/index.tsx +126 -30
  86. package/src/modules/Forms/FormEditor/style.tsx +1 -1
  87. package/src/modules/Forms/FormList/FormItem/index.tsx +114 -36
  88. package/src/modules/Forms/FormList/FormItem/style.tsx +4 -2
  89. package/src/modules/Forms/FormList/TemplateModal/index.tsx +67 -20
  90. package/src/modules/Forms/FormList/TemplateModal/style.tsx +28 -2
  91. package/src/modules/Forms/FormList/index.tsx +114 -34
  92. package/src/modules/Forms/FormList/style.tsx +10 -2
  93. package/src/modules/Forms/FormUseModal/index.tsx +219 -0
  94. package/src/modules/Forms/FormUseModal/style.tsx +81 -0
  95. package/src/modules/Forms/FormUseModal/utils.tsx +39 -0
  96. package/src/modules/Forms/atoms.tsx +38 -3
  97. package/src/modules/PageEditor/index.tsx +2 -2
  98. package/src/modules/Redirects/index.tsx +10 -12
  99. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/NavigationField/index.tsx +1 -1
  100. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
  101. package/src/modules/Users/UserCreate/index.tsx +5 -4
  102. package/src/routes/multisite.tsx +18 -0
  103. package/src/routes/site.tsx +5 -0
  104. package/src/schemas/pages/FormPage.tsx +3 -2
  105. package/src/types/forms.tsx +4 -2
  106. package/src/types/index.tsx +20 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "11.2.12",
4
+ "version": "11.3.0",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -110,6 +110,7 @@
110
110
  "jsdom-global": "^3.0.2",
111
111
  "lodash.isequal": "4.5.0",
112
112
  "markdown-draft-js": "^2.2.1",
113
+ "masonic": "^4.0.1",
113
114
  "mini-css-extract-plugin": "0.11.3",
114
115
  "optimize-css-assets-webpack-plugin": "^6.0.1",
115
116
  "pkg-dir": "^5.0.0",
@@ -225,5 +226,5 @@
225
226
  "publishConfig": {
226
227
  "access": "public"
227
228
  },
228
- "gitHead": "91ccea61b7695a0661c947f6f2570ca3c9ee52b3"
229
+ "gitHead": "a79d065e23c54d42f453f227571ed1e3482d4a2a"
229
230
  }
@@ -13,7 +13,7 @@ afterEach(cleanup);
13
13
  const defaultProps = mock<ISideModalProps>();
14
14
 
15
15
  describe("SideModal component rendering", () => {
16
- it("should render the component", () => {
16
+ it("should render the component visible if isOpen is true", () => {
17
17
  const handleClickMock = jest.fn();
18
18
  const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
19
19
  defaultProps.categories = [
@@ -23,7 +23,7 @@ describe("SideModal component rendering", () => {
23
23
  defaultProps.isOpen = true;
24
24
  defaultProps.theme = "default-theme";
25
25
  defaultProps.whiteList = ["EventsDistributor", "ArticlesDistributor"];
26
- defaultProps.handleClick = handleClickMock;
26
+ defaultProps.onClick = handleClickMock;
27
27
  defaultProps.toggleModal = toggleModalMock;
28
28
  defaultProps.optionsType = "modules";
29
29
 
@@ -35,9 +35,11 @@ describe("SideModal component rendering", () => {
35
35
 
36
36
  const sideModal = screen.getByTestId("side-modal");
37
37
  expect(sideModal).toBeTruthy();
38
+ const styles = getComputedStyle(sideModal);
39
+ expect(styles.left).toEqual("0px");
38
40
  });
39
41
 
40
- it("should not render the component if isOpen is false", () => {
42
+ it("should render the component hidden if isOpen is false", () => {
41
43
  const handleClickMock = jest.fn();
42
44
  const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
43
45
  defaultProps.categories = [
@@ -47,7 +49,7 @@ describe("SideModal component rendering", () => {
47
49
  defaultProps.isOpen = false;
48
50
  defaultProps.theme = "default-theme";
49
51
  defaultProps.whiteList = ["EventsDistributor", "ArticlesDistributor"];
50
- defaultProps.handleClick = handleClickMock;
52
+ defaultProps.onClick = handleClickMock;
51
53
  defaultProps.toggleModal = toggleModalMock;
52
54
  defaultProps.optionsType = "modules";
53
55
 
@@ -57,8 +59,10 @@ describe("SideModal component rendering", () => {
57
59
  </ThemeProvider>
58
60
  );
59
61
 
60
- const sideModal = screen.queryByTestId("side-modal");
61
- expect(sideModal).not.toBeTruthy();
62
+ const sideModal = screen.getByTestId("side-modal");
63
+ expect(sideModal).toBeTruthy();
64
+ const styles = getComputedStyle(sideModal);
65
+ expect(styles.left).toEqual("-999px");
62
66
  });
63
67
 
64
68
  it("should render optiontype as title", () => {
@@ -120,7 +124,7 @@ describe("SideModal component rendering", () => {
120
124
  defaultProps.isOpen = true;
121
125
  defaultProps.theme = "default-theme";
122
126
  defaultProps.whiteList = ["BasicContent", "CardCollection"];
123
- defaultProps.handleClick = handleClickMock;
127
+ defaultProps.onClick = handleClickMock;
124
128
  defaultProps.toggleModal = toggleModalMock;
125
129
  defaultProps.optionsType = "modules";
126
130
 
@@ -155,7 +159,7 @@ describe("SideModal component rendering", () => {
155
159
  defaultProps.isOpen = true;
156
160
  defaultProps.theme = "default-theme";
157
161
  defaultProps.whiteList = ["LinkableImage", "Video"];
158
- defaultProps.handleClick = handleClickMock;
162
+ defaultProps.onClick = handleClickMock;
159
163
  defaultProps.toggleModal = toggleModalMock;
160
164
  defaultProps.optionsType = "components";
161
165
 
@@ -182,7 +186,7 @@ describe("SideModal component events", () => {
182
186
  defaultProps.isOpen = true;
183
187
  defaultProps.theme = "default-theme";
184
188
  defaultProps.whiteList = ["Accordion", "AddressCollection"];
185
- defaultProps.handleClick = handleClickMock;
189
+ defaultProps.onClick = handleClickMock;
186
190
  defaultProps.toggleModal = toggleModalMock;
187
191
  defaultProps.optionsType = "modules";
188
192
 
@@ -212,7 +216,7 @@ describe("SideModal component events", () => {
212
216
  defaultProps.isOpen = true;
213
217
  defaultProps.theme = "default-theme";
214
218
  defaultProps.whiteList = ["BasicContent", "CardCollection"];
215
- defaultProps.handleClick = handleClickMock;
219
+ defaultProps.onClick = handleClickMock;
216
220
  defaultProps.toggleModal = toggleModalMock;
217
221
  defaultProps.optionsType = "modules";
218
222
 
@@ -251,7 +255,7 @@ describe("SideModal component events", () => {
251
255
  defaultProps.isOpen = true;
252
256
  defaultProps.theme = "default-theme";
253
257
  defaultProps.whiteList = ["BasicContent", "CardCollection"];
254
- defaultProps.handleClick = handleClickMock;
258
+ defaultProps.onClick = handleClickMock;
255
259
  defaultProps.toggleModal = toggleModalMock;
256
260
  defaultProps.optionsType = "modules";
257
261
 
@@ -22,9 +22,14 @@ const SERVICES: { [key: string]: IServiceConfig } = {
22
22
  endpoint: "/image/",
23
23
  method: "DELETE",
24
24
  },
25
+ CREATE_THUMBNAIL: {
26
+ ...template,
27
+ endpoint: ["/thumbnail/contentId/", "/contentType/"],
28
+ method: "POST",
29
+ },
25
30
  };
26
31
 
27
- const createImage = async (data: any, setProgress?: (progress: number) => void) => {
32
+ const createImage = async (data: FormData, setProgress?: (progress: number) => void) => {
28
33
  return sendUploadRequest(SERVICES.CREATE_IMAGE, data, setProgress);
29
34
  };
30
35
 
@@ -49,4 +54,14 @@ const deleteImage = async (imageID: number) => {
49
54
  return sendRequest(SERVICES.DELETE_IMAGE);
50
55
  };
51
56
 
52
- export default { createImage, getImageInfo, updateImage, deleteImage };
57
+ const createThumbnail = async (contentID: number, contentType: "form" | "navigation", data: FormData) => {
58
+ const {
59
+ host,
60
+ endpoint: [prefix, suffix],
61
+ } = SERVICES.CREATE_THUMBNAIL;
62
+ SERVICES.CREATE_THUMBNAIL.dynamicUrl = `${host}${prefix}${contentID}${suffix}${contentType}`;
63
+
64
+ return sendRequest(SERVICES.CREATE_THUMBNAIL, data);
65
+ };
66
+
67
+ export default { createImage, getImageInfo, updateImage, deleteImage, createThumbnail };
package/src/api/pages.tsx CHANGED
@@ -1,9 +1,16 @@
1
+ import { AxiosResponse } from "axios";
1
2
  import { template } from "./config";
2
3
  import { IServiceConfig, sendRequest } from "./utils";
4
+ import { IGetPagesParams } from "@ax/types";
3
5
 
4
6
  const PUBLIC_BASE_PATH = process.env.REACT_APP_PUBLIC_API_ENDPOINT;
5
7
 
6
8
  const SERVICES: { [key: string]: IServiceConfig } = {
9
+ GET_PAGES: {
10
+ ...template,
11
+ endpoint: "/pages",
12
+ method: "GET",
13
+ },
7
14
  GET_PAGE_INFO: {
8
15
  ...template,
9
16
  endpoint: "/page/",
@@ -92,6 +99,45 @@ const SERVICES: { [key: string]: IServiceConfig } = {
92
99
  },
93
100
  };
94
101
 
102
+ const getPages = async (params: IGetPagesParams, filterQuery = ""): Promise<AxiosResponse> => {
103
+ const { host, endpoint } = SERVICES.GET_PAGES;
104
+
105
+ const {
106
+ deleted,
107
+ page,
108
+ itemsPerPage,
109
+ query,
110
+ filterStructuredData,
111
+ lang,
112
+ format,
113
+ filterPages,
114
+ ignoreLang,
115
+ filterSites,
116
+ type,
117
+ } = params;
118
+
119
+ SERVICES.GET_PAGES.dynamicUrl = `${host}${endpoint}?deleted=${deleted}${filterQuery}`;
120
+
121
+ if (page && itemsPerPage)
122
+ SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&page=${page}&itemsPerPage=${itemsPerPage}`;
123
+ if (query && query.trim() !== "") SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&query=${query}`;
124
+ if (filterStructuredData)
125
+ SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&filterStructuredData=${filterStructuredData}`;
126
+ if (format) SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&format=${format}`;
127
+ if (type) SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&type=${type}`;
128
+ if (filterPages)
129
+ SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&filterPages=${filterPages.join(",")}`;
130
+ if (filterSites)
131
+ SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&filterSites=${filterSites.join(",")}`;
132
+ if (ignoreLang) SERVICES.GET_PAGES.dynamicUrl = SERVICES.GET_PAGES.dynamicUrl + `&ignoreLang=${ignoreLang}`;
133
+
134
+ const dataHeader = {
135
+ ...(lang && { lang }),
136
+ };
137
+
138
+ return sendRequest(SERVICES.GET_PAGES, null, dataHeader);
139
+ };
140
+
95
141
  const getPageInfo = async (pageID: number) => {
96
142
  const { host, endpoint } = SERVICES.GET_PAGE_INFO;
97
143
  SERVICES.GET_PAGE_INFO.dynamicUrl = `${host}${endpoint}${pageID}`;
@@ -184,7 +230,7 @@ const duplicatePage = async (pageID: number, data?: any, siteID?: number) => {
184
230
 
185
231
  const bulkDelete = async (ids: any) => sendRequest(SERVICES.DELETE_BULK, { ids });
186
232
 
187
- const getTemplateConfig = async (siteID: number, template: string) => {
233
+ const getTemplateConfig = async (siteID: number | null, template: string) => {
188
234
  const {
189
235
  host,
190
236
  endpoint: [prefix, middle, suffix],
@@ -232,6 +278,7 @@ const getPageTranslation = async (data: any, langID: number) => {
232
278
  };
233
279
 
234
280
  export default {
281
+ getPages,
235
282
  getPageInfo,
236
283
  updatePage,
237
284
  createPage,
@@ -248,5 +295,5 @@ export default {
248
295
  getPublicPage,
249
296
  pageCheck,
250
297
  getPageSummary,
251
- getPageTranslation
298
+ getPageTranslation,
252
299
  };
@@ -37,18 +37,20 @@ const getSelectSiteItems = async (siteId: number, entity: string, params: any, p
37
37
  return sendRequest(SERVICES.GET_SITE_ITEMS);
38
38
  };
39
39
 
40
- const getSelectItems = async (entity: string, entityId?: number | string) => {
40
+ const getSelectItems = async (entity: string, entityId?: number | string, lang?: number) => {
41
41
  const { host, endpoint } = SERVICES.GET_ITEMS;
42
+ const filter = lang ? `?filterByLanguage=${lang}` : "";
42
43
  SERVICES.GET_ITEMS.dynamicUrl = entityId
43
- ? `${host}${endpoint}/${entity}/${entityId}`
44
- : `${host}${endpoint}/${entity}/`;
44
+ ? `${host}${endpoint}/${entity}/${entityId}${filter}`
45
+ : `${host}${endpoint}/${entity}${filter}`;
45
46
 
46
47
  return sendRequest(SERVICES.GET_ITEMS);
47
48
  };
48
49
 
49
- const getSelectSites = async () => {
50
+ const getSelectSites = async (lang?: number) => {
50
51
  const { host, endpoint } = SERVICES.GET_SITES;
51
- SERVICES.GET_ITEMS.dynamicUrl = `${host}${endpoint}`;
52
+ const filter = lang ? `?filterByLanguage=${lang}` : "";
53
+ SERVICES.GET_ITEMS.dynamicUrl = `${host}${endpoint}${filter}`;
52
54
 
53
55
  return sendRequest(SERVICES.GET_SITES);
54
56
  };
@@ -147,7 +147,14 @@ const Browser = (props: IBrowserProps): JSX.Element => {
147
147
  )}
148
148
  {showIframe ? (
149
149
  <S.FrameWrapper hasBorder={isPageEditor} data-testid="navbar-iframe-wrapper">
150
- <iframe title="Preview" width={getWidth(resolution)} height="100%" src={urlPreview} loading="lazy" />
150
+ <iframe
151
+ title="Preview"
152
+ width={getWidth(resolution)}
153
+ height="100%"
154
+ src={urlPreview}
155
+ loading="lazy"
156
+ className="frame-content"
157
+ />
151
158
  </S.FrameWrapper>
152
159
  ) : (
153
160
  <S.Wrapper
@@ -25,13 +25,17 @@ const Button = styled.button<{ iconFill: boolean }>`
25
25
  transition: opacity 0.1s;
26
26
  }
27
27
  :focus {
28
- outline: 1px solid ${(p) => p.theme.color.interactive02};
28
+ outline: none;
29
+ }
30
+ :focus-visible {
31
+ outline: ${(p) => `1px solid ${p.theme.color.interactive02}`};
29
32
  }
30
33
  :hover:before {
31
34
  background-color: ${(p) => p.theme.color.overlayHoverDark};
32
35
  opacity: 1;
33
36
  }
34
- :focus:before {
37
+ :focus:before,
38
+ :focus-visible:before {
35
39
  background-color: ${(p) => p.theme.color.overlayFocusDark};
36
40
  opacity: 1;
37
41
  }
@@ -44,6 +48,7 @@ const Button = styled.button<{ iconFill: boolean }>`
44
48
  background-color: ${(p) => p.theme.color.interactiveDisabled};
45
49
  :hover:before,
46
50
  :focus:before,
51
+ :focus-visible:before,
47
52
  :active:before {
48
53
  background-color: transparent;
49
54
  }
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { memo } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
4
  import { FieldContainer } from "@ax/components";
@@ -7,7 +7,7 @@ import { getInnerFields } from "@ax/forms";
7
7
  import { IRootState } from "@ax/types";
8
8
  import { areEqual, filterThemeModules } from "@ax/helpers";
9
9
 
10
- const NavConnectedField = (props: any) => {
10
+ const NavConnectedField = (props: any): JSX.Element => {
11
11
  const {
12
12
  whiteList,
13
13
  objKey,
@@ -109,4 +109,7 @@ const mapDispatchToProps = {
109
109
  updateEditorContent: navigationActions.updateEditorContent,
110
110
  };
111
111
 
112
- export default connect(mapStateToProps, mapDispatchToProps)(React.memo(NavConnectedField, areEqual));
112
+ export default connect(
113
+ mapStateToProps,
114
+ mapDispatchToProps
115
+ )(memo(NavConnectedField, areEqual) as typeof NavConnectedField);
@@ -31,6 +31,7 @@ export const TemplateManager = (props: IProps): JSX.Element => {
31
31
  lang,
32
32
  themeElements,
33
33
  scrollEditorID,
34
+ isForm,
34
35
  } = props;
35
36
 
36
37
  const isConfig = selectedTab === "config";
@@ -46,7 +47,7 @@ export const TemplateManager = (props: IProps): JSX.Element => {
46
47
  const mappedField = !isArr ? { ...field, key: fieldObjKey } : field;
47
48
  const handleUpdate = (fieldKey: string, value: any) =>
48
49
  updateValue(fieldKey, value, templateContent.editorID, slugTo);
49
- const error = errors.find((err: any) => err.editorID === templateContent.editorID && err.key === key);
50
+ const error = errors.find((err) => err.editorID === templateContent.editorID && err.key === key);
50
51
  const isComputedField = Object.prototype.hasOwnProperty.call(field, "computed");
51
52
 
52
53
  const addedModules: string[] = modulesDataPacks.reduce((acc: string[], current: any) => {
@@ -81,10 +82,13 @@ export const TemplateManager = (props: IProps): JSX.Element => {
81
82
 
82
83
  return (
83
84
  <>
84
- {isConfig && templateFields && <S.Title>Template Options</S.Title>}
85
+ {isConfig && templateFields && !isForm && <S.Title>Template Options</S.Title>}
85
86
  {templateFields &&
86
87
  templateFields
87
- .filter((templateField: ISchemaField) => !templateField.hidden)
88
+ .filter((templateField: ISchemaField) => {
89
+ const isHidden = templateField.hidden || (isForm && !templateField.overwrite);
90
+ return !isHidden;
91
+ })
88
92
  .map((templateField: ISchemaField, index: number) => {
89
93
  const {
90
94
  whiteList,
@@ -156,6 +160,7 @@ interface IProps {
156
160
  lang: number;
157
161
  themeElements: IThemeElements | null;
158
162
  scrollEditorID: number | null;
163
+ isForm: boolean;
159
164
  }
160
165
 
161
166
  const mapStateToProps = (state: IRootState) => ({
@@ -8,6 +8,7 @@ import {
8
8
  areEqual,
9
9
  filterThemeModules,
10
10
  isTemplateExcludedFromTheme,
11
+ getFormTemplate,
11
12
  } from "@ax/helpers";
12
13
  import { IRootState } from "@ax/types";
13
14
  import { pageEditorActions } from "@ax/containers/PageEditor";
@@ -15,7 +16,7 @@ import { pageEditorActions } from "@ax/containers/PageEditor";
15
16
  import TemplateManager from "./TemplateManager";
16
17
  import Field from "./Field";
17
18
 
18
- const PageConnectedField = (props: any) => {
19
+ const PageConnectedField = (props: any): JSX.Element => {
19
20
  const {
20
21
  whiteList,
21
22
  objKey,
@@ -51,15 +52,18 @@ const PageConnectedField = (props: any) => {
51
52
  } = props;
52
53
 
53
54
  const isTemplate = field.type === "template";
55
+ const isFormTemplate = field.type === "formTemplate";
56
+
54
57
  const overrideableFields = ["header", "footer"];
55
58
  const isOverride = selectedContent.type && overrideableFields.includes(selectedContent.type);
56
59
  const isPageHome = componentType === "page" && selectedContent.isHome;
57
60
  const allowModifySlug = !selectedContent.id && !selectedContent.isHome;
58
61
  const isNewPage = componentType === "page" && !selectedContent.id;
59
62
  const error = errors.find((err: any) => err.editorID === selectedEditorID && err.key === objKey);
63
+ const isFormPage = selectedContent.component === "FormPage";
60
64
 
61
65
  let isTemplateActivated = true;
62
- if (selectedContent.template && !isGlobal) {
66
+ if (selectedContent.template && !isGlobal && !isFormTemplate) {
63
67
  isTemplateActivated =
64
68
  activatedTemplates.find((temp: any) => temp.id === selectedContent.template.templateType) &&
65
69
  !isTemplateExcludedFromTheme(themeElements, selectedContent.template.templateType)
@@ -143,7 +147,7 @@ const PageConnectedField = (props: any) => {
143
147
  };
144
148
 
145
149
  if (isOverride) {
146
- if (!field.modifiable) return null;
150
+ if (!field.modifiable) return <></>;
147
151
 
148
152
  updateValue = (key: string, value: any) => {
149
153
  updateEditorContent(selectedEditorID, key, value);
@@ -153,8 +157,10 @@ const PageConnectedField = (props: any) => {
153
157
  };
154
158
  }
155
159
 
156
- if (isTemplate) {
157
- const template = getTemplate(selectedContent[field.key].templateType);
160
+ if (isTemplate || isFormTemplate) {
161
+ const template = isFormTemplate
162
+ ? getFormTemplate(selectedContent[field.key].templateType)
163
+ : getTemplate(selectedContent[field.key].templateType);
158
164
 
159
165
  return (
160
166
  <TemplateManager
@@ -176,10 +182,15 @@ const PageConnectedField = (props: any) => {
176
182
  setHistoryPush={setHistoryPush}
177
183
  lang={lang.id}
178
184
  activatedModules={filteredActivatedModules}
185
+ isForm={isFormTemplate}
179
186
  />
180
187
  );
181
188
  }
182
189
 
190
+ if (isFormPage) {
191
+ return <></>;
192
+ }
193
+
183
194
  return (
184
195
  <Field
185
196
  whiteList={filteredWhiteList}
@@ -236,4 +247,7 @@ const mapDispatchToProps = {
236
247
  deleteError: pageEditorActions.deleteError,
237
248
  };
238
249
 
239
- export default connect(mapStateToProps, mapDispatchToProps)(memo(PageConnectedField, areEqual));
250
+ export default connect(
251
+ mapStateToProps,
252
+ mapDispatchToProps
253
+ )(memo(PageConnectedField, areEqual) as typeof PageConnectedField);
@@ -126,7 +126,7 @@ const Field = (props: IProps) => {
126
126
  <SideModal
127
127
  optionsType={optionsType}
128
128
  whiteList={orderedOptions}
129
- handleClick={handleReplace}
129
+ onClick={handleReplace}
130
130
  toggleModal={toggleModal}
131
131
  isOpen={isOpen}
132
132
  theme={theme}
@@ -6,6 +6,7 @@ import * as S from "./style";
6
6
 
7
7
  const ErrorCenter = (props: IErrorCenterProps): JSX.Element => {
8
8
  const { errors, actions } = props;
9
+ const { goToError, goToPackage } = actions || {};
9
10
 
10
11
  const goToElement = (key: string) => {
11
12
  const element = document.getElementById(`gdd_${key}`);
@@ -25,10 +26,10 @@ const ErrorCenter = (props: IErrorCenterProps): JSX.Element => {
25
26
 
26
27
  const getErrorItem = (item: IErrorItem): JSX.Element => {
27
28
  const handleClick = () => {
28
- if (item.hasDeactivatedPackage) {
29
- actions?.goToPackage();
29
+ if (item.hasDeactivatedPackage && goToPackage) {
30
+ goToPackage();
30
31
  } else {
31
- item.editorID !== null && actions?.goToError(item.editorID, item.tab, item.template);
32
+ item.editorID !== null && goToError && goToError(item.editorID, item.tab, item.template, item.parentEditorID);
32
33
  goToElement(item.key);
33
34
  }
34
35
  };
@@ -67,8 +68,8 @@ const ErrorCenter = (props: IErrorCenterProps): JSX.Element => {
67
68
  export interface IErrorCenterProps {
68
69
  errors: IErrorItem[];
69
70
  actions?: {
70
- goToError(editorID: number | null, tab: string, template: boolean): void;
71
- goToPackage(): void;
71
+ goToError(editorID: number | null, tab: string, template: boolean, parentEditorID?: number): void;
72
+ goToPackage?(): void;
72
73
  };
73
74
  }
74
75
 
@@ -26,6 +26,7 @@ const AsyncSelect = (props: IAsyncSelectProps): JSX.Element => {
26
26
  source,
27
27
  type,
28
28
  maxWidth,
29
+ filterLang,
29
30
  } = props;
30
31
 
31
32
  const initialState: IState = {
@@ -50,7 +51,7 @@ const AsyncSelect = (props: IAsyncSelectProps): JSX.Element => {
50
51
  ? await selects.getSelectSiteItems(site.id, entity, options, selectedContent.id)
51
52
  : await selects.getSelectSiteItems(site.id, entity, options);
52
53
  } else {
53
- result = await selects.getSelectItems(entity, entityId);
54
+ result = await selects.getSelectItems(entity, entityId, filterLang);
54
55
  }
55
56
 
56
57
  if (result && isReqOk(result.status)) {
@@ -184,6 +185,7 @@ export interface IAsyncSelectProps {
184
185
  source?: string;
185
186
  type?: string;
186
187
  maxWidth?: number;
188
+ filterLang?: number;
187
189
  }
188
190
 
189
191
  export default AsyncSelect;
@@ -18,7 +18,7 @@ const AddItemButton = (props: IProps) => {
18
18
  categories={categories}
19
19
  toggleModal={toggleModal}
20
20
  isOpen={isOpen}
21
- handleClick={handleClick}
21
+ onClick={handleClick}
22
22
  theme={theme}
23
23
  showSearch
24
24
  />
@@ -49,7 +49,7 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
49
49
 
50
50
  // fix for old not array values
51
51
  const fixedValue = Array.isArray(value) ? value : containerToComponentArray(value);
52
- const componentIDs: number[] = fixedValue.map((element: any) => element.editorID);
52
+ const componentIDs: number[] = fixedValue.map((element) => element.editorID);
53
53
 
54
54
  const type = getTypefromKey(objKey);
55
55
  const { contentType = type } = field;
@@ -63,8 +63,11 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
63
63
  );
64
64
 
65
65
  const selectedID = parseInt(localStorage.getItem("selectedID") || "0");
66
+ const isComponentModule = contentType === "components";
67
+ const isModuleArr = contentType === "modules" || contentType === "fields";
68
+ const isFormArr = contentType === "fields";
66
69
 
67
- const { isOpen, toggleModal } = useModal();
70
+ const { isOpen, toggleModal } = useModal(isFormArr, false);
68
71
  const [isBulkOpen, setIsBulkOpen] = useState(false);
69
72
  const [draggingId, setDraggingId] = useState<number | null>(null);
70
73
  const { isVisible, toggleToast, setIsVisible, state: toastState } = useToast();
@@ -83,9 +86,6 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
83
86
  return fixedValue.length > 1 ? `#${index + 1} ${name}` : name;
84
87
  };
85
88
 
86
- const isComponentModule = contentType === "components";
87
- const isModuleArr = contentType === "modules" || contentType === "fields";
88
-
89
89
  const handleAddModule = (moduleType: string) =>
90
90
  addModuleAction && addModuleAction(moduleType, objKey, editorID, isComponentModule);
91
91
 
@@ -121,18 +121,17 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
121
121
 
122
122
  const ComponentList = React.memo(function ComponentList({ components }: any) {
123
123
  return components.map((element: IModule, i: number) => {
124
- const { editorID } = element;
125
- const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
126
- element,
127
- activatedModules,
128
- isModuleArr
129
- );
124
+ const { editorID, fixed } = element;
125
+ const componentProps = getComponentProps(element, activatedModules, isModuleArr);
126
+ const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule, isModuleDisabled } =
127
+ componentProps;
130
128
  const text = getText(componentTitle || displayName, i);
131
129
  const isItemSelected = isSelected(editorID);
132
130
  const isDraggingSelected = selectedItems.all.includes(draggingId);
133
131
  const isGhosting = isItemSelected && !!draggingId && draggingId !== editorID && isDraggingSelected;
134
132
  const isMultiDragging = selectedItems.all.length > 1 && draggingId === editorID;
135
133
  const isActive = scrollEditorID === editorID;
134
+ const canDelete = !isFormArr || !fixed;
136
135
 
137
136
  return (
138
137
  <Draggable draggableId={`${editorID}`} index={i} key={editorID}>
@@ -150,8 +149,9 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
150
149
  categories={categories}
151
150
  actions={actions}
152
151
  selectedContent={selectedContent}
153
- disabled={disabled}
152
+ disabled={disabled || isModuleDisabled}
154
153
  canDuplicate={showAddItemButton && !isModuleDeactivated}
154
+ canDelete={canDelete}
155
155
  parentKey={objKey}
156
156
  theme={theme}
157
157
  arrayLength={components.length}
@@ -214,7 +214,10 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
214
214
  };
215
215
 
216
216
  const handleDelete = () => {
217
- deleteModuleAction && deleteModuleAction(selectedItems.all, objKey);
217
+ const modulesToDelete = fixedValue
218
+ .filter((element) => selectedItems.all.includes(element.editorID) && (!isFormArr || !element.fixed))
219
+ .map((element) => element.editorID);
220
+ deleteModuleAction && deleteModuleAction(modulesToDelete, objKey);
218
221
  resetBulkSelection();
219
222
  };
220
223
 
@@ -303,7 +306,7 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
303
306
  categories={categories}
304
307
  toggleModal={toggleModal}
305
308
  isOpen={isOpen}
306
- handleClick={handleModuleReplace}
309
+ onClick={handleModuleReplace}
307
310
  theme={theme}
308
311
  showSearch
309
312
  />
@@ -320,7 +323,7 @@ export interface IMixableComponentArrayProps {
320
323
  value?: IModule[];
321
324
  selectedContent: any;
322
325
  editorID: number;
323
- goTo: (editorID: string) => void;
326
+ goTo: (editorID: number) => void;
324
327
  actions?: {
325
328
  addComponentAction: (componentType: any, key?: string) => void;
326
329
  addModuleAction: (moduleType: string, key: string, selectedID: number, isComponentModule?: boolean) => void;
@@ -90,11 +90,10 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
90
90
  const ComponentList = React.memo(function ComponentList({ components }: any) {
91
91
  return components.map((element: any, i: number) => {
92
92
  const { editorID } = element;
93
- const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
94
- element,
95
- activatedModules,
96
- isModuleArr
97
- );
93
+ const componentProps = getComponentProps(element, activatedModules, isModuleArr);
94
+ if (!componentProps) return <></>;
95
+ const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule, isModuleDisabled } =
96
+ componentProps;
98
97
  const text = getText(componentTitle || displayName, i);
99
98
  const isItemSelected = isSelected(editorID);
100
99
  const isDraggingSelected = selectedItems.all.includes(draggingId);
@@ -115,7 +114,7 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
115
114
  categories={categories}
116
115
  actions={actions}
117
116
  selectedContent={selectedContent}
118
- disabled={disabled}
117
+ disabled={disabled || isModuleDisabled}
119
118
  canDuplicate={showAddItemButton && !isModuleDeactivated}
120
119
  parentKey={objKey}
121
120
  theme={theme}
@@ -219,7 +218,7 @@ export interface ISameComponentArrayProps {
219
218
  elementUniqueSelection: boolean;
220
219
  selectedContent: any;
221
220
  editorID: number;
222
- goTo: (editorID: string) => void;
221
+ goTo: (editorID: number) => void;
223
222
  actions: {
224
223
  addComponentAction: (componentType: any, key?: string) => void;
225
224
  addModuleAction: (moduleType: string, key: string, selectedID: number, isComponentModule?: boolean) => void;