@griddo/ax 11.0.29-rc.0 → 11.0.30-rc.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 (141) hide show
  1. package/config/griddo-config/cx-polyfills/componentsBundle.js +1 -1
  2. package/package.json +2 -2
  3. package/scripts/griddo-sync-schemas.js +49 -42
  4. package/src/GlobalStore.tsx +3 -0
  5. package/src/__tests__/components/TableFilters/LiveFilter/LiveFilter.test.tsx +6 -0
  6. package/src/api/forms.tsx +191 -0
  7. package/src/api/index.tsx +2 -0
  8. package/src/components/Browser/index.tsx +42 -37
  9. package/src/components/Browser/style.tsx +3 -3
  10. package/src/components/BrowserContent/index.tsx +1 -1
  11. package/src/components/ConfigPanel/Form/index.tsx +6 -5
  12. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +3 -1
  13. package/src/components/ConfigPanel/Header/index.tsx +1 -0
  14. package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +4 -5
  15. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +4 -4
  16. package/src/components/Fields/ComponentArray/helpers.tsx +1 -1
  17. package/src/components/Fields/FormFieldArray/index.tsx +13 -0
  18. package/src/components/Fields/ReferenceField/AutoPanel/index.tsx +1 -2
  19. package/src/components/Fields/ReferenceField/Context/index.tsx +0 -2
  20. package/src/components/Fields/ReferenceField/ItemList/index.tsx +1 -2
  21. package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +2 -2
  22. package/src/components/Fields/ReferenceField/index.tsx +1 -5
  23. package/src/components/Fields/TranslateButton/index.tsx +48 -10
  24. package/src/components/Fields/Wysiwyg/helpers.tsx +2 -2
  25. package/src/components/Fields/Wysiwyg/index.tsx +4 -11
  26. package/src/components/Fields/index.tsx +2 -0
  27. package/src/components/FieldsBehavior/index.tsx +8 -2
  28. package/src/components/Icon/components/Form.js +12 -0
  29. package/src/components/Icon/svgs/Form.svg +3 -0
  30. package/src/components/LanguageMenu/index.tsx +30 -27
  31. package/src/components/MainWrapper/AppBar/index.tsx +23 -68
  32. package/src/components/MainWrapper/index.tsx +4 -9
  33. package/src/components/MenuItem/index.tsx +2 -2
  34. package/src/components/ResizePanel/index.tsx +3 -2
  35. package/src/components/ResizePanel/style.tsx +11 -9
  36. package/src/components/SearchField/style.tsx +2 -2
  37. package/src/components/SideModal/SideModalOption/index.tsx +3 -2
  38. package/src/components/SideModal/SideModalOption/style.tsx +2 -2
  39. package/src/components/SideModal/index.tsx +11 -4
  40. package/src/components/SideModal/style.tsx +9 -7
  41. package/src/components/TableFilters/LiveFilter/index.tsx +4 -3
  42. package/src/components/index.tsx +4 -0
  43. package/src/containers/App/reducer.tsx +4 -1
  44. package/src/containers/Forms/actions.tsx +853 -0
  45. package/src/containers/Forms/constants.tsx +46 -0
  46. package/src/containers/Forms/index.tsx +4 -0
  47. package/src/containers/Forms/interfaces.tsx +95 -0
  48. package/src/containers/Forms/reducer.tsx +81 -0
  49. package/src/containers/Forms/utils.tsx +42 -0
  50. package/src/containers/Navigation/Menu/actions.tsx +6 -13
  51. package/src/containers/Navigation/Menu/reducer.tsx +0 -4
  52. package/src/containers/PageEditor/actions.tsx +3 -2
  53. package/src/containers/PageEditor/reducer.tsx +2 -2
  54. package/src/forms/editor.tsx +3 -1
  55. package/src/helpers/index.tsx +12 -1
  56. package/src/helpers/schemas.tsx +35 -9
  57. package/src/helpers/structuredData.tsx +3 -1
  58. package/src/helpers/themes.tsx +3 -1
  59. package/src/helpers/thumbnails.tsx +20 -2
  60. package/src/modules/Analytics/GroupPanel/utils.tsx +3 -1
  61. package/src/modules/App/Routing/NavMenu/index.tsx +16 -6
  62. package/src/modules/App/Routing/index.tsx +26 -9
  63. package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +4 -4
  64. package/src/modules/Categories/CategoriesList/index.tsx +16 -16
  65. package/src/modules/Content/BulkHeader/TableHeader/index.tsx +1 -5
  66. package/src/modules/Content/PageItem/index.tsx +34 -33
  67. package/src/modules/Content/index.tsx +23 -36
  68. package/src/modules/Content/utils.tsx +3 -1
  69. package/src/modules/Forms/FormCategoriesList/BulkHeader/TableHeader/index.tsx +42 -0
  70. package/src/modules/Forms/FormCategoriesList/BulkHeader/TableHeader/style.tsx +36 -0
  71. package/src/modules/Forms/FormCategoriesList/BulkHeader/index.tsx +37 -0
  72. package/src/modules/Forms/FormCategoriesList/BulkHeader/style.tsx +9 -0
  73. package/src/modules/Forms/FormCategoriesList/CategoryItem/index.tsx +125 -0
  74. package/src/modules/Forms/FormCategoriesList/CategoryItem/style.tsx +91 -0
  75. package/src/modules/Forms/FormCategoriesList/CategoryPanel/Form/index.tsx +50 -0
  76. package/src/modules/Forms/FormCategoriesList/CategoryPanel/index.tsx +112 -0
  77. package/src/modules/Forms/FormCategoriesList/CategoryPanel/style.tsx +31 -0
  78. package/src/modules/Forms/FormCategoriesList/atoms.tsx +33 -0
  79. package/src/modules/Forms/FormCategoriesList/hooks.tsx +61 -0
  80. package/src/modules/Forms/FormCategoriesList/index.tsx +245 -0
  81. package/src/modules/Forms/FormCategoriesList/style.tsx +82 -0
  82. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/Field/index.tsx +95 -0
  83. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/TemplateManager/index.tsx +102 -0
  84. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/TemplateManager/style.tsx +9 -0
  85. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/ConnectedField/index.tsx +109 -0
  86. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/index.tsx +76 -0
  87. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/style.tsx +28 -0
  88. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Header/index.tsx +132 -0
  89. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Header/style.tsx +30 -0
  90. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/index.tsx +86 -0
  91. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/style.tsx +7 -0
  92. package/src/modules/Forms/FormEditor/Editor/index.tsx +106 -0
  93. package/src/modules/Forms/FormEditor/PageBrowser/index.tsx +96 -0
  94. package/src/modules/Forms/FormEditor/index.tsx +295 -0
  95. package/src/modules/Forms/FormEditor/style.tsx +32 -0
  96. package/src/modules/Forms/FormList/BulkHeader/TableHeader/index.tsx +61 -0
  97. package/src/modules/Forms/FormList/BulkHeader/TableHeader/style.tsx +47 -0
  98. package/src/modules/Forms/FormList/BulkHeader/index.tsx +60 -0
  99. package/src/modules/Forms/FormList/FormItem/index.tsx +218 -0
  100. package/src/modules/Forms/FormList/FormItem/style.tsx +87 -0
  101. package/src/modules/Forms/FormList/Summary/index.tsx +51 -0
  102. package/src/modules/Forms/FormList/Summary/style.tsx +46 -0
  103. package/src/modules/Forms/FormList/TemplateModal/index.tsx +67 -0
  104. package/src/modules/Forms/FormList/TemplateModal/style.tsx +54 -0
  105. package/src/modules/Forms/FormList/index.tsx +266 -0
  106. package/src/modules/Forms/FormList/style.tsx +31 -0
  107. package/src/modules/Forms/FormsMenu/MenuGroup/index.tsx +57 -0
  108. package/src/modules/Forms/FormsMenu/MenuGroup/style.tsx +55 -0
  109. package/src/modules/Forms/FormsMenu/index.tsx +78 -0
  110. package/src/modules/Forms/FormsMenu/style.tsx +9 -0
  111. package/src/modules/Forms/atoms.tsx +111 -0
  112. package/src/modules/Forms/style.tsx +11 -0
  113. package/src/modules/FramePreview/index.tsx +26 -12
  114. package/src/modules/GlobalEditor/index.tsx +52 -21
  115. package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +32 -15
  116. package/src/modules/Navigation/Defaults/Item/atoms.tsx +6 -5
  117. package/src/modules/Navigation/Defaults/Item/index.tsx +10 -10
  118. package/src/modules/Navigation/Defaults/index.tsx +7 -6
  119. package/src/modules/Navigation/Menus/List/Nav/index.tsx +2 -10
  120. package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +14 -11
  121. package/src/modules/Navigation/Menus/List/index.tsx +15 -16
  122. package/src/modules/Navigation/Menus/index.tsx +9 -17
  123. package/src/modules/PageEditor/index.tsx +54 -31
  124. package/src/modules/Settings/Globals/index.tsx +3 -1
  125. package/src/modules/Settings/Languages/Table/Item/index.tsx +11 -9
  126. package/src/modules/Sites/SitesList/ListView/BulkHeader/TableHeader/index.tsx +1 -1
  127. package/src/modules/StructuredData/Form/index.tsx +41 -28
  128. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +1 -5
  129. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +6 -8
  130. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +5 -7
  131. package/src/modules/StructuredData/StructuredDataList/index.tsx +13 -10
  132. package/src/modules/StructuredData/StructuredDataList/utils.tsx +2 -1
  133. package/src/routes/multisite.tsx +53 -16
  134. package/src/routes/site.tsx +1 -0
  135. package/src/schemas/pages/FormPage.tsx +49 -0
  136. package/src/schemas/pages/GlobalPage.tsx +1 -0
  137. package/src/schemas/pages/Page.tsx +4 -1
  138. package/src/schemas/pages/index.tsx +2 -1
  139. package/src/types/forms.tsx +87 -0
  140. package/src/types/index.tsx +43 -7
  141. /package/src/modules/Navigation/Menus/{helpers.tsx → List/helpers.tsx} +0 -0
@@ -0,0 +1,853 @@
1
+ import { Dispatch } from "redux";
2
+ import {
3
+ FormCategoriesList,
4
+ FormCategoriesOrderParams,
5
+ FormCategory,
6
+ FormContent,
7
+ FormState,
8
+ GetFormsParams,
9
+ IBreadcrumbItem,
10
+ IModule,
11
+ INotification,
12
+ IRootState,
13
+ ISchema,
14
+ ListForm,
15
+ } from "@ax/types";
16
+ import { deepClone, getDefaultFormTemplate, getDefaultSchema, getSchema, handleRequest, isReqOk } from "@ax/helpers";
17
+ import {
18
+ findByEditorID,
19
+ generateEditorIDs,
20
+ getLastComponentEditorID,
21
+ getNewBreadcrumb,
22
+ getParentKey,
23
+ moveElement,
24
+ parseData,
25
+ updateByEditorID,
26
+ updateComponent,
27
+ } from "@ax/forms";
28
+ import { appActions } from "@ax/containers/App";
29
+ import { forms } from "@ax/api";
30
+ import {
31
+ SET_BREADCRUMB,
32
+ SET_COPY_MODULE,
33
+ SET_CURRENT_FORM_ID,
34
+ SET_FORM_CONTENT,
35
+ SET_FORMS,
36
+ SET_SCHEMA,
37
+ SET_SELECTED_CONTENT,
38
+ SET_SELECTED_EDITOR_ID,
39
+ SET_SELECTED_PARENT,
40
+ SET_TAB,
41
+ SET_TEMPLATE,
42
+ SET_SUMMARY,
43
+ DEFAULT_PARAMS,
44
+ SET_CURRENT_FORM_CATEGORIES,
45
+ SET_IS_NEW_TRANSLATION,
46
+ SET_IS_IA_TRANSLATED,
47
+ } from "./constants";
48
+ import {
49
+ ISetBreadcrumb,
50
+ ISetCopyModule,
51
+ ISetCurrentFormID,
52
+ ISetFormContent,
53
+ ISetForms,
54
+ ISetSchema,
55
+ ISetSelectedContent,
56
+ ISetSelectedEditorID,
57
+ ISetSelectedParent,
58
+ ISetTab,
59
+ ISetTemplate,
60
+ ISetSummary,
61
+ ISetCurrentFormCategories,
62
+ ISetIsNewTranslation,
63
+ ISetIsIATranslated,
64
+ } from "./interfaces";
65
+ import { getUpdatedComponents } from "./utils";
66
+
67
+ const { setIsLoading, setIsSaving, handleError } = appActions;
68
+
69
+ function setForms(forms: FormContent[]): ISetForms {
70
+ return { type: SET_FORMS, payload: { forms } };
71
+ }
72
+
73
+ function setFormContent(formContent: FormContent | null): ISetFormContent {
74
+ const iframe = document.querySelector("iframe");
75
+ iframe?.contentWindow?.postMessage(
76
+ {
77
+ type: "content-update",
78
+ message: formContent,
79
+ },
80
+ "*"
81
+ );
82
+ return { type: SET_FORM_CONTENT, payload: { formContent } };
83
+ }
84
+
85
+ function setSchema(schema: ISchema | Record<string, never>): ISetSchema {
86
+ return { type: SET_SCHEMA, payload: { schema } };
87
+ }
88
+
89
+ function setTemplate(template: string): ISetTemplate {
90
+ return { type: SET_TEMPLATE, payload: { template } };
91
+ }
92
+
93
+ function setSelectedFormContent(selectedContent: Record<string, unknown>): ISetSelectedContent {
94
+ return { type: SET_SELECTED_CONTENT, payload: { selectedContent } };
95
+ }
96
+
97
+ function setSelectedParent(selectedParent: Record<string, unknown> | null): ISetSelectedParent {
98
+ return { type: SET_SELECTED_PARENT, payload: { selectedParent } };
99
+ }
100
+
101
+ function setSelectedEditorID(selectedEditorID: number): ISetSelectedEditorID {
102
+ return { type: SET_SELECTED_EDITOR_ID, payload: { selectedEditorID } };
103
+ }
104
+
105
+ function setTab(tab: string): ISetTab {
106
+ return { type: SET_TAB, payload: { tab } };
107
+ }
108
+
109
+ function setCurrentFormID(currentFormID: number | null): ISetCurrentFormID {
110
+ return { type: SET_CURRENT_FORM_ID, payload: { currentFormID } };
111
+ }
112
+
113
+ function setBreadcrumb(breadcrumb: IBreadcrumbItem[]): ISetBreadcrumb {
114
+ return { type: SET_BREADCRUMB, payload: { breadcrumb } };
115
+ }
116
+
117
+ function setCopyModule(moduleCopy: { date: Date; elements: IModule[] } | null): ISetCopyModule {
118
+ return { type: SET_COPY_MODULE, payload: { moduleCopy } };
119
+ }
120
+
121
+ function setSummary(summary: { total: number; active: number; inactive: number }): ISetSummary {
122
+ return { type: SET_SUMMARY, payload: { summary } };
123
+ }
124
+
125
+ function setCurrentFormCategories(currentFormCategories: FormCategory[]): ISetCurrentFormCategories {
126
+ return { type: SET_CURRENT_FORM_CATEGORIES, payload: { currentFormCategories } };
127
+ }
128
+
129
+ function setIsNewTranslation(isNewTranslation: boolean): ISetIsNewTranslation {
130
+ return { type: SET_IS_NEW_TRANSLATION, payload: { isNewTranslation } };
131
+ }
132
+
133
+ function setIsIATranslated(isIATranslated: boolean): ISetIsIATranslated {
134
+ return { type: SET_IS_IA_TRANSLATED, payload: { isIATranslated } };
135
+ }
136
+
137
+ function getForms(params?: GetFormsParams): (dispatch: Dispatch, getState: any) => Promise<void> {
138
+ return async (dispatch, getState) => {
139
+ try {
140
+ const {
141
+ sites: { currentSiteInfo },
142
+ }: IRootState = getState();
143
+
144
+ const getParams = { ...DEFAULT_PARAMS, ...params };
145
+
146
+ const siteID = currentSiteInfo ? currentSiteInfo.id : "global";
147
+
148
+ const responseActions = {
149
+ handleSuccess: (response: ListForm) => {
150
+ const { items, totalItems, active, inactive } = response;
151
+ dispatch(setForms(items));
152
+ dispatch(setSummary({ total: totalItems, active, inactive }));
153
+ },
154
+ handleError: (response: any) => handleError(response)(dispatch),
155
+ };
156
+
157
+ const callback = async () => forms.getForms(siteID, getParams);
158
+
159
+ await handleRequest(callback, responseActions, [setIsLoading])(dispatch);
160
+ } catch (e) {
161
+ console.log(e);
162
+ }
163
+ };
164
+ }
165
+
166
+ function getForm(formID: number | null): (dispatch: Dispatch, getState: any) => Promise<void> {
167
+ return async (dispatch, getState) => {
168
+ try {
169
+ dispatch(setIsLoading(true));
170
+ const {
171
+ forms: { isNewTranslation },
172
+ }: IRootState = getState();
173
+
174
+ if (formID) {
175
+ const response: { status: number; data: FormContent } = await forms.getForm(formID);
176
+
177
+ if (isReqOk(response.status)) {
178
+ addTemplate(response.data.template.templateType)(dispatch);
179
+ dispatch(setSelectedEditorID(0));
180
+ const formData: Partial<FormContent> = response.data;
181
+ if (isNewTranslation) {
182
+ delete formData.id;
183
+ formData["state"] = "inactive";
184
+ formData["canBeTranslated"] = true;
185
+ formData["originalLanguage"] = formData.language;
186
+ }
187
+ generateFormContent(formData)(dispatch, getState);
188
+ dispatch(setCurrentFormID(response.data.id));
189
+ }
190
+ } else {
191
+ generateNewForm()(dispatch, getState);
192
+ }
193
+ } catch (e) {
194
+ dispatch(setIsLoading(false));
195
+ console.log(e); // TODO: capturar error bien
196
+ }
197
+ };
198
+ }
199
+
200
+ function generateNewForm(): (dispatch: Dispatch, getState: any) => void {
201
+ return async (dispatch, getState) => {
202
+ const {
203
+ forms: { template },
204
+ app: { lang },
205
+ }: IRootState = getState();
206
+
207
+ let form = getDefaultSchema("FormPage");
208
+ const parsedPageData = parseData(form, true);
209
+ const currentTemplate = getDefaultFormTemplate(template);
210
+
211
+ form = { ...parsedPageData, template: currentTemplate, language: lang.id, dataLanguages: [] };
212
+
213
+ dispatch(setIsNewTranslation(false));
214
+
215
+ // SET PAGE AS ROOT WHEN NEW PAGE
216
+ dispatch(setSelectedEditorID(0));
217
+ generateFormContent(form)(dispatch, getState);
218
+ };
219
+ }
220
+
221
+ function generateFormContent(formContent: Partial<FormContent>): (dispatch: Dispatch, getState: any) => void {
222
+ return (dispatch, getState) => {
223
+ const {
224
+ forms: { selectedEditorID },
225
+ sites: { currentSiteInfo },
226
+ }: IRootState = getState();
227
+
228
+ const { pageContent } = generateEditorIDs({ ...formContent });
229
+ pageContent["site"] = currentSiteInfo ? currentSiteInfo.id : null;
230
+ const { element: selectedContent, parent: selectedParent } = findByEditorID(pageContent, selectedEditorID);
231
+ const { component } = selectedContent;
232
+ const schema = getSchema(component);
233
+
234
+ dispatch(setSchema(schema));
235
+ dispatch(setFormContent(pageContent));
236
+ updateBreadcrumb(selectedEditorID)(dispatch, getState);
237
+ dispatch(setSelectedFormContent(selectedContent));
238
+ dispatch(setSelectedParent(selectedParent));
239
+ dispatch(setIsLoading(false));
240
+ };
241
+ }
242
+
243
+ function setSelectedContent(editorID: number): (dispatch: Dispatch, getState: any) => Promise<void> {
244
+ return async (dispatch, getState) => {
245
+ const {
246
+ forms: { formContent, tab },
247
+ }: IRootState = getState();
248
+
249
+ dispatch(setIsLoading(true));
250
+
251
+ const iframe = document.querySelector("iframe");
252
+ iframe?.contentWindow?.postMessage(
253
+ {
254
+ type: "selected-content",
255
+ message: editorID,
256
+ },
257
+ "*"
258
+ );
259
+
260
+ if (editorID > 0) {
261
+ localStorage.setItem("selectedID", `${editorID}`);
262
+ }
263
+
264
+ const { element: selectedContent, parent: selectedParent } = findByEditorID({ formContent }, editorID);
265
+
266
+ const { component } = selectedContent;
267
+ const defaultSchema = getDefaultSchema(component);
268
+
269
+ // if schema default has new keys
270
+ const isUpdatedComponent = Object.keys(defaultSchema).length + 2 !== Object.keys(selectedContent).length;
271
+ isUpdatedComponent && updateComponent(selectedContent, defaultSchema);
272
+
273
+ const schema = getSchema(component);
274
+ const defaultTab = "content";
275
+ dispatch(setTab(tab || defaultTab));
276
+ dispatch(setSchema(schema));
277
+ dispatch(setSelectedEditorID(editorID));
278
+ updateBreadcrumb(editorID)(dispatch, getState);
279
+ dispatch(setSelectedFormContent({ ...selectedContent }));
280
+ dispatch(setSelectedParent(selectedParent));
281
+ dispatch(setIsLoading(false));
282
+ };
283
+ }
284
+
285
+ function updateFormContent(
286
+ selectedEditorID: number,
287
+ key: string,
288
+ value: any
289
+ ): (dispatch: Dispatch, getState: any) => void {
290
+ return (dispatch, getState) => {
291
+ const {
292
+ forms: { formContent, selectedContent },
293
+ }: IRootState = getState();
294
+
295
+ const clonedContent = deepClone(formContent);
296
+
297
+ const updatedSelectedContent = updateByEditorID(selectedContent, selectedEditorID, key, value);
298
+ const updatedFormContent = updateByEditorID(clonedContent, selectedEditorID, key, value);
299
+
300
+ dispatch(setSelectedFormContent(updatedSelectedContent));
301
+ dispatch(setFormContent(updatedFormContent));
302
+
303
+ if (value && typeof value === "object") {
304
+ generateFormContent(updatedFormContent)(dispatch, getState);
305
+ }
306
+ };
307
+ }
308
+
309
+ function updateBreadcrumb(editorID: number): (dispatch: Dispatch, getState: any) => void {
310
+ return (dispatch, getState) => {
311
+ const {
312
+ forms: { formContent },
313
+ }: IRootState = getState();
314
+
315
+ const newBreadcrumb = getNewBreadcrumb(formContent, editorID, false);
316
+
317
+ dispatch(setBreadcrumb(newBreadcrumb));
318
+ };
319
+ }
320
+
321
+ function saveForm(updateState?: FormState): (dispatch: Dispatch, getState: any) => Promise<boolean> {
322
+ return async (dispatch, getState) => {
323
+ try {
324
+ const {
325
+ forms: { formContent },
326
+ app: { lang },
327
+ }: IRootState = getState();
328
+
329
+ if (!formContent) {
330
+ return false;
331
+ }
332
+
333
+ const isNewForm = !formContent.id;
334
+ formContent["language"] = lang.id;
335
+
336
+ const callback = async () =>
337
+ isNewForm ? await forms.createForm(formContent) : await forms.updateForm(formContent.id, formContent);
338
+
339
+ const responseActions = {
340
+ handleSuccess: async (response: FormContent) => {
341
+ const { pageContent } = generateEditorIDs(response);
342
+ if (updateState) {
343
+ const isUpdated = await forms.updateFormState(pageContent.id, updateState);
344
+ if (isUpdated) {
345
+ pageContent["state"] = updateState;
346
+ }
347
+ }
348
+ if (isNewForm) {
349
+ dispatch(setCurrentFormID(pageContent.id));
350
+ }
351
+ dispatch(setFormContent(pageContent));
352
+ dispatch(setIsNewTranslation(false));
353
+ },
354
+ handleError: (response: any) => handleError(response)(dispatch),
355
+ };
356
+
357
+ return await handleRequest(callback, responseActions, [setIsSaving])(dispatch);
358
+ } catch (e) {
359
+ console.log(e);
360
+ return false;
361
+ }
362
+ };
363
+ }
364
+
365
+ function deleteForm(id: number | number[]): (dispatch: Dispatch, getState: any) => Promise<boolean> {
366
+ return async (dispatch, getState) => {
367
+ try {
368
+ const responseActions = {
369
+ handleSuccess: () => {
370
+ getForms()(dispatch, getState);
371
+ },
372
+ handleError: (response: any) => {
373
+ const {
374
+ data: { message },
375
+ } = response;
376
+ const isMultiple = Array.isArray(message) && message.length > 1;
377
+ const msg = isMultiple ? `The delete action failed due to ${message.length} errors.` : undefined;
378
+ appActions.handleError(response, isMultiple, msg)(dispatch);
379
+ },
380
+ };
381
+
382
+ const callback = async () => (Array.isArray(id) ? forms.deleteFormBulk(id) : forms.deleteForm(id));
383
+
384
+ return await handleRequest(callback, responseActions, [])(dispatch);
385
+ } catch (e) {
386
+ console.log(e);
387
+ return false;
388
+ }
389
+ };
390
+ }
391
+
392
+ function updateFormState(formID: number, state: FormState): (dispatch: Dispatch, getState: any) => Promise<boolean> {
393
+ return async (dispatch, getState) => {
394
+ try {
395
+ const callback = async () => await forms.updateFormState(formID, state);
396
+
397
+ const responseActions = {
398
+ handleSuccess: () => {
399
+ getForms()(dispatch, getState);
400
+ },
401
+ handleError: (response: any) => handleError(response)(dispatch),
402
+ };
403
+
404
+ return await handleRequest(callback, responseActions, [])(dispatch);
405
+ } catch (e) {
406
+ console.log(e);
407
+ return false;
408
+ }
409
+ };
410
+ }
411
+
412
+ function setSelectedTab(tab: string): (dispatch: Dispatch) => void {
413
+ return (dispatch) => {
414
+ try {
415
+ dispatch(setTab(tab));
416
+ } catch (e) {
417
+ console.log("Error", e);
418
+ }
419
+ };
420
+ }
421
+
422
+ function addModule(type: string, key: string): (dispatch: Dispatch, getState: any) => void {
423
+ return (dispatch, getState) => {
424
+ const {
425
+ forms: { formContent, selectedEditorID: editorID },
426
+ }: IRootState = getState();
427
+
428
+ if (!formContent) return;
429
+
430
+ const templateContent = formContent.template;
431
+
432
+ const component = {
433
+ editorID: editorID === 0 ? templateContent?.editorID : editorID,
434
+ type,
435
+ };
436
+
437
+ const updatedObj = getUpdatedComponents(templateContent, component, key);
438
+
439
+ const updatedPageContent = {
440
+ ...formContent,
441
+ template: {
442
+ ...templateContent,
443
+ ...updatedObj,
444
+ },
445
+ };
446
+
447
+ generateFormContent(updatedPageContent)(dispatch, getState);
448
+
449
+ const {
450
+ forms: { formContent: generatedFormContent },
451
+ }: IRootState = getState();
452
+
453
+ if (!generatedFormContent) return;
454
+
455
+ const lastElementEditorID = getLastComponentEditorID(generatedFormContent.template, component.editorID, key);
456
+ localStorage.setItem("selectedID", `${lastElementEditorID}`);
457
+ };
458
+ }
459
+
460
+ function deleteModule(editorID: number[], key?: string): (dispatch: Dispatch, getState: any) => void {
461
+ return (dispatch, getState) => {
462
+ const {
463
+ forms: { formContent },
464
+ }: IRootState = getState();
465
+
466
+ if (!formContent) return;
467
+
468
+ const templateContent = formContent.template;
469
+
470
+ const { parent, grandParent } = findByEditorID(templateContent, editorID[0]);
471
+ const parentModule = Array.isArray(parent) ? grandParent : parent;
472
+
473
+ const parentKey = key ? key : getParentKey(parentModule, editorID[0]);
474
+ const itemsArr = parentModule[parentKey];
475
+
476
+ editorID.forEach((moduleID) => {
477
+ const index = itemsArr.findIndex((module: IModule) => module.editorID === moduleID);
478
+ itemsArr.splice(index, 1);
479
+ });
480
+
481
+ const updatedContent = {
482
+ ...formContent,
483
+ template: {
484
+ ...templateContent,
485
+ },
486
+ };
487
+
488
+ generateFormContent(updatedContent)(dispatch, getState);
489
+ };
490
+ }
491
+
492
+ function duplicateModule(editorID: number[], key?: string): (dispatch: Dispatch, getState: any) => number {
493
+ return (dispatch, getState) => {
494
+ const {
495
+ forms: { formContent },
496
+ }: IRootState = getState();
497
+
498
+ if (!formContent) return;
499
+
500
+ const templateContent = formContent.template;
501
+
502
+ const { parent, grandParent } = findByEditorID(templateContent, editorID[0]);
503
+ const parentModule = Array.isArray(parent) ? grandParent : parent;
504
+
505
+ const parentKey = key ? key : getParentKey(parentModule, editorID[0]);
506
+ const itemsArr = parentModule[parentKey];
507
+ let duplicatedItemIndex = 0;
508
+
509
+ editorID.forEach((id) => {
510
+ const { element: originalItem } = findByEditorID(templateContent, id);
511
+ const originalItemIndex = itemsArr.findIndex((module: IModule) => module.editorID === id);
512
+ duplicatedItemIndex = originalItemIndex + 1;
513
+ itemsArr.splice(duplicatedItemIndex, 0, originalItem);
514
+ });
515
+
516
+ const updatedContent = {
517
+ ...formContent,
518
+ template: {
519
+ ...templateContent,
520
+ },
521
+ };
522
+
523
+ generateFormContent(updatedContent)(dispatch, getState);
524
+
525
+ const {
526
+ forms: { formContent: generatedFormContent },
527
+ }: IRootState = getState();
528
+
529
+ const { parent: generatedParent, grandParent: generatedGrandParent } = findByEditorID(
530
+ generatedFormContent,
531
+ editorID[0]
532
+ );
533
+ const module = Array.isArray(generatedParent) ? generatedGrandParent : generatedParent;
534
+ const duplicatedEditorID = module[parentKey][duplicatedItemIndex].editorID;
535
+
536
+ localStorage.setItem("selectedID", `${duplicatedEditorID}`);
537
+
538
+ return duplicatedEditorID;
539
+ };
540
+ }
541
+
542
+ function moveModule(
543
+ elementID: number[],
544
+ content: any,
545
+ newIndex: number,
546
+ key: string
547
+ ): (dispatch: Dispatch, getState: any) => void {
548
+ return async (dispatch, getState) => {
549
+ const {
550
+ forms: { formContent, selectedContent },
551
+ }: IRootState = getState();
552
+
553
+ if (!formContent) return;
554
+
555
+ const templateContent = formContent.template;
556
+
557
+ const contentElements = [...(selectedContent as any).template[key]];
558
+ const { element: selectedModule } = findByEditorID(templateContent, templateContent.editorID);
559
+ selectedModule[key] = moveElement(elementID, contentElements, newIndex);
560
+
561
+ const updatedContent = {
562
+ ...formContent,
563
+ template: {
564
+ ...templateContent,
565
+ },
566
+ };
567
+
568
+ dispatch(setFormContent(updatedContent));
569
+ dispatch(setSelectedFormContent(updatedContent));
570
+ };
571
+ }
572
+
573
+ function copyModule(editorID: number[]): (dispatch: Dispatch, getState: any) => boolean | number {
574
+ return (dispatch, getState) => {
575
+ const {
576
+ forms: { formContent },
577
+ }: IRootState = getState();
578
+
579
+ if (!formContent) return false;
580
+
581
+ const templateContent: any = formContent.template;
582
+ const modulesToCopy: IModule[] = [];
583
+
584
+ editorID.forEach((id) => {
585
+ const { element: originalElement } = findByEditorID(templateContent, id);
586
+ if (originalElement) {
587
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
588
+ const { editorID, parentEditorID, ...element } = originalElement;
589
+ modulesToCopy.push(element);
590
+ }
591
+ });
592
+
593
+ if (modulesToCopy.length) {
594
+ const payload = {
595
+ date: new Date(),
596
+ elements: modulesToCopy,
597
+ };
598
+
599
+ dispatch(setCopyModule(payload));
600
+ return payload.elements.length;
601
+ } else {
602
+ return false;
603
+ }
604
+ };
605
+ }
606
+
607
+ function pasteModule(
608
+ editorID: number,
609
+ key: string,
610
+ modulesToPaste: IModule[]
611
+ ): (dispatch: Dispatch, getState: any) => Promise<{ error?: INotification }> {
612
+ return async (dispatch, getState) => {
613
+ const {
614
+ forms: { formContent },
615
+ }: IRootState = getState();
616
+
617
+ if (!formContent) return { error: undefined };
618
+
619
+ const templateContent = formContent.template;
620
+ const { element: originalElement } = findByEditorID(templateContent, editorID);
621
+ const itemsArr = originalElement[key];
622
+
623
+ modulesToPaste.forEach((element) => {
624
+ const validatedModuleCopy = deepClone(element);
625
+ itemsArr.push(validatedModuleCopy);
626
+ });
627
+
628
+ const updatedPageContent = {
629
+ ...formContent,
630
+ };
631
+
632
+ generateFormContent(updatedPageContent)(dispatch, getState);
633
+
634
+ return { error: undefined };
635
+ };
636
+ }
637
+
638
+ function addTemplate(template: string): (dispatch: Dispatch) => Promise<void> {
639
+ return async (dispatch) => {
640
+ try {
641
+ dispatch(setTemplate(template));
642
+ } catch (e) {
643
+ console.log("Error", e);
644
+ }
645
+ };
646
+ }
647
+
648
+ function resetForm(): (dispatch: Dispatch) => void {
649
+ return async (dispatch) => {
650
+ dispatch(setCurrentFormID(null));
651
+ dispatch(setFormContent(null));
652
+ dispatch(setSchema({}));
653
+ };
654
+ }
655
+
656
+ function getFormCategories(type: string): (dispatch: Dispatch, getState: any) => Promise<void> {
657
+ return async (dispatch, getState) => {
658
+ try {
659
+ const {
660
+ sites: { currentSiteInfo },
661
+ }: IRootState = getState();
662
+
663
+ const siteID = currentSiteInfo ? currentSiteInfo.id : "global";
664
+
665
+ const responseActions = {
666
+ handleSuccess: (response: FormCategoriesList) => {
667
+ const { items } = response;
668
+ dispatch(setCurrentFormCategories(items));
669
+ },
670
+ handleError: (response: any) => handleError(response)(dispatch),
671
+ };
672
+
673
+ const callback = async () => forms.getFormCategories(siteID, type);
674
+
675
+ await handleRequest(callback, responseActions, [setIsLoading])(dispatch);
676
+ } catch (e) {
677
+ console.log(e);
678
+ }
679
+ };
680
+ }
681
+
682
+ function createFormCategory(
683
+ content: { title: string; code: string },
684
+ categoryType: string
685
+ ): (dispatch: Dispatch, getState: any) => Promise<boolean> {
686
+ return async (dispatch, getState) => {
687
+ try {
688
+ const {
689
+ sites: { currentSiteInfo },
690
+ }: IRootState = getState();
691
+
692
+ const relatedSite = currentSiteInfo ? currentSiteInfo.id : null;
693
+
694
+ const callback = async () =>
695
+ await forms.createFormCategory({
696
+ categoryType,
697
+ content,
698
+ relatedSite,
699
+ });
700
+
701
+ const responseActions = {
702
+ handleSuccess: () => {
703
+ getFormCategories(categoryType)(dispatch, getState);
704
+ },
705
+ handleError: (response: any) => handleError(response)(dispatch),
706
+ };
707
+
708
+ return await handleRequest(callback, responseActions, [setIsSaving])(dispatch);
709
+ } catch (e) {
710
+ console.log(e);
711
+ return false;
712
+ }
713
+ };
714
+ }
715
+
716
+ function updateFormCategory(
717
+ id: number,
718
+ content: { title: string; code: string }
719
+ ): (dispatch: Dispatch, getState: any) => Promise<boolean> {
720
+ return async (dispatch, getState) => {
721
+ try {
722
+ const callback = async () => await forms.updateFormCategory(id, { content });
723
+
724
+ const responseActions = {
725
+ handleSuccess: (result: FormCategory) => {
726
+ getFormCategories(result.categoryType)(dispatch, getState);
727
+ },
728
+ handleError: (response: any) => handleError(response)(dispatch),
729
+ };
730
+
731
+ return await handleRequest(callback, responseActions, [setIsSaving])(dispatch);
732
+ } catch (e) {
733
+ console.log(e);
734
+ return false;
735
+ }
736
+ };
737
+ }
738
+
739
+ function deleteFormCategory(
740
+ id: number | number[],
741
+ categoryType: string
742
+ ): (dispatch: Dispatch, getState: any) => Promise<boolean> {
743
+ return async (dispatch, getState) => {
744
+ try {
745
+ const responseActions = {
746
+ handleSuccess: () => {
747
+ getFormCategories(categoryType)(dispatch, getState);
748
+ },
749
+ handleError: (response: any) => {
750
+ const {
751
+ data: { message },
752
+ } = response;
753
+ const isMultiple = Array.isArray(message) && message.length > 1;
754
+ const msg = isMultiple ? `The delete action failed due to ${message.length} errors.` : undefined;
755
+ appActions.handleError(response, isMultiple, msg)(dispatch);
756
+ },
757
+ };
758
+
759
+ const callback = async () =>
760
+ Array.isArray(id) ? forms.deleteFormCategoryBulk(id) : forms.deleteFormCategory(id);
761
+
762
+ return await handleRequest(callback, responseActions, [])(dispatch);
763
+ } catch (e) {
764
+ console.log(e);
765
+ return false;
766
+ }
767
+ };
768
+ }
769
+
770
+ function orderFormCategory(data: FormCategoriesOrderParams): (dispatch: Dispatch, getState: any) => Promise<boolean> {
771
+ return async (dispatch, getState) => {
772
+ try {
773
+ dispatch(setIsLoading(true));
774
+
775
+ const responseActions = {
776
+ handleSuccess: () => getFormCategories(data.categoryType)(dispatch, getState),
777
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
778
+ };
779
+
780
+ const callback = async () => forms.orderFormCategory(data);
781
+
782
+ return await handleRequest(callback, responseActions, [])(dispatch);
783
+ } catch (e) {
784
+ console.log(e);
785
+ return false;
786
+ }
787
+ };
788
+ }
789
+
790
+ function createNewTranslation(isNewTranslation: boolean): (dispatch: Dispatch) => void {
791
+ return async (dispatch) => {
792
+ try {
793
+ dispatch(setIsNewTranslation(isNewTranslation));
794
+ } catch (e) {
795
+ console.log(e);
796
+ }
797
+ };
798
+ }
799
+
800
+ function getFormTranslation(langID: number): (dispatch: Dispatch, getState: any) => Promise<boolean> {
801
+ return async (dispatch, getState) => {
802
+ try {
803
+ const {
804
+ forms: { formContent },
805
+ }: IRootState = getState();
806
+
807
+ const responseActions = {
808
+ handleSuccess: (data: FormContent) => {
809
+ data["canBeTranslated"] = false;
810
+ generateFormContent(data)(dispatch, getState);
811
+ dispatch(setIsIATranslated(true));
812
+ },
813
+ handleError: () => console.log("Error en GetFormTranslation"),
814
+ };
815
+
816
+ const callback = async () => formContent && forms.getFormTranslation(formContent, langID);
817
+
818
+ return await handleRequest(callback, responseActions, [])(dispatch);
819
+ } catch (e) {
820
+ console.log(e);
821
+ return false;
822
+ }
823
+ };
824
+ }
825
+
826
+ export {
827
+ setSelectedTab,
828
+ setFormContent,
829
+ setCurrentFormID,
830
+ getForms,
831
+ getForm,
832
+ updateFormContent,
833
+ setSelectedContent,
834
+ addModule,
835
+ deleteModule,
836
+ duplicateModule,
837
+ moveModule,
838
+ copyModule,
839
+ pasteModule,
840
+ addTemplate,
841
+ saveForm,
842
+ resetForm,
843
+ deleteForm,
844
+ getFormCategories,
845
+ createFormCategory,
846
+ updateFormCategory,
847
+ deleteFormCategory,
848
+ orderFormCategory,
849
+ updateFormState,
850
+ createNewTranslation,
851
+ getFormTranslation,
852
+ setIsIATranslated,
853
+ };