@griddo/ax 1.66.13 → 1.67.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 (76) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Fields/ConditionalField/ConditionalField.test.tsx +95 -0
  3. package/src/api/pages.tsx +15 -3
  4. package/src/api/redirects.tsx +4 -2
  5. package/src/api/sites.tsx +12 -4
  6. package/src/components/Browser/index.tsx +9 -22
  7. package/src/components/Browser/style.tsx +1 -6
  8. package/src/components/ErrorCenter/index.tsx +8 -5
  9. package/src/components/ErrorCenter/style.tsx +21 -8
  10. package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +3 -3
  11. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +60 -25
  12. package/src/components/Fields/ComponentContainer/index.tsx +21 -7
  13. package/src/components/Fields/ConditionalField/index.tsx +1 -1
  14. package/src/components/Fields/LinkField/index.tsx +111 -0
  15. package/src/components/Fields/ReferenceField/ItemList/index.tsx +4 -0
  16. package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +12 -2
  17. package/src/components/Fields/ReferenceField/index.tsx +24 -12
  18. package/src/components/Fields/ReferenceField/style.tsx +12 -1
  19. package/src/components/Fields/UrlField/index.tsx +13 -1
  20. package/src/components/Fields/VisualUniqueSelection/utils.tsx +1 -6
  21. package/src/components/Fields/index.tsx +2 -0
  22. package/src/components/FieldsBehavior/index.tsx +14 -1
  23. package/src/components/Icon/components/Copy.js +14 -0
  24. package/src/components/Icon/components/Copy2.js +14 -0
  25. package/src/components/Icon/components/Duplicate.js +3 -5
  26. package/src/components/Icon/components/Page.js +12 -0
  27. package/src/components/Icon/svgs/Copy.svg +3 -0
  28. package/src/components/Icon/svgs/Copy2.svg +3 -0
  29. package/src/components/Icon/svgs/Duplicate.svg +1 -1
  30. package/src/components/Icon/svgs/page.svg +3 -0
  31. package/src/components/MainWrapper/AppBar/index.tsx +21 -10
  32. package/src/components/MainWrapper/AppBar/style.tsx +11 -3
  33. package/src/components/MainWrapper/index.tsx +2 -0
  34. package/src/components/Notification/index.tsx +1 -3
  35. package/src/components/SearchField/index.tsx +37 -4
  36. package/src/components/SearchField/style.tsx +23 -10
  37. package/src/components/index.tsx +2 -0
  38. package/src/containers/Navigation/Defaults/actions.tsx +2 -0
  39. package/src/containers/PageEditor/actions.tsx +101 -19
  40. package/src/containers/PageEditor/utils.tsx +2 -1
  41. package/src/containers/Sites/actions.tsx +53 -24
  42. package/src/containers/Sites/constants.tsx +2 -0
  43. package/src/containers/Sites/interfaces.tsx +12 -5
  44. package/src/containers/Sites/reducer.tsx +8 -0
  45. package/src/containers/StructuredData/actions.tsx +5 -8
  46. package/src/forms/errors.tsx +1 -0
  47. package/src/forms/index.tsx +13 -1
  48. package/src/forms/validators.tsx +181 -13
  49. package/src/helpers/dataPacks.tsx +8 -1
  50. package/src/helpers/index.tsx +4 -1
  51. package/src/helpers/objects.tsx +10 -2
  52. package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +3 -1
  53. package/src/modules/Categories/CategoriesList/CategoryPanel/index.tsx +15 -9
  54. package/src/modules/Categories/CategoriesList/index.tsx +2 -1
  55. package/src/modules/Content/PageItem/index.tsx +52 -2
  56. package/src/modules/Content/atoms.tsx +41 -3
  57. package/src/modules/Content/index.tsx +44 -2
  58. package/src/modules/Content/style.tsx +8 -1
  59. package/src/modules/FramePreview/index.tsx +85 -0
  60. package/src/modules/FramePreview/style.tsx +18 -0
  61. package/src/modules/GlobalEditor/Editor/index.tsx +3 -1
  62. package/src/modules/GlobalEditor/PageBrowser/index.tsx +3 -0
  63. package/src/modules/GlobalEditor/index.tsx +22 -6
  64. package/src/modules/PageEditor/Editor/index.tsx +5 -1
  65. package/src/modules/PageEditor/PageBrowser/index.tsx +4 -5
  66. package/src/modules/PageEditor/index.tsx +40 -12
  67. package/src/modules/Redirects/index.tsx +40 -10
  68. package/src/modules/Settings/Globals/index.tsx +1 -1
  69. package/src/modules/Sites/index.tsx +2 -2
  70. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
  71. package/src/modules/StructuredData/StructuredDataList/index.tsx +19 -2
  72. package/src/modules/Users/Profile/index.tsx +3 -3
  73. package/src/routes/multisite.tsx +12 -4
  74. package/src/routes/site.tsx +1 -1
  75. package/src/types/index.tsx +13 -4
  76. package/tsconfig.paths.json +2 -1
@@ -5,15 +5,9 @@ const Wrapper = styled.div`
5
5
  width: 100%;
6
6
  `;
7
7
 
8
- const FieldWrapper = styled.div``;
9
-
10
- const Input = styled.input<{ closeOnInactive: boolean; disabled: boolean }>`
11
- ${(p) => p.theme.textStyle.fieldContent};
12
- color: ${(p) => p.theme.color.textHighEmphasis};
13
- background-color: ${(p) => p.theme.color.interactiveBackground};
14
- width: 100%;
15
- height: ${(p) => p.theme.spacing.l};
16
- padding-left: ${(p) => p.theme.spacing.xs};
8
+ const FieldWrapper = styled.div<{ closeOnInactive: boolean; disabled: boolean }>`
9
+ display: flex;
10
+ align-items: center;
17
11
  border-color: ${(p) =>
18
12
  p.disabled
19
13
  ? p.theme.color.interactiveDisabled
@@ -23,6 +17,16 @@ const Input = styled.input<{ closeOnInactive: boolean; disabled: boolean }>`
23
17
  border-width: ${(p) => (p.closeOnInactive ? "0 0 1px" : "1px")};
24
18
  border-style: solid;
25
19
  border-radius: ${(p) => (p.closeOnInactive ? 0 : p.theme.radii.s)};
20
+ `;
21
+
22
+ const Input = styled.input<{ closeOnInactive: boolean; disabled: boolean }>`
23
+ ${(p) => p.theme.textStyle.fieldContent};
24
+ color: ${(p) => p.theme.color.textHighEmphasis};
25
+ background-color: ${(p) => p.theme.color.interactiveBackground};
26
+ flex: 1 1 auto;
27
+ height: ${(p) => p.theme.spacing.l};
28
+ padding-left: ${(p) => p.theme.spacing.xs};
29
+ border: none;
26
30
 
27
31
  &:active,
28
32
  &:focus {
@@ -66,4 +70,13 @@ const IconCloseWrapper = styled.div`
66
70
  transform: translateY(-50%);
67
71
  `;
68
72
 
69
- export { Wrapper, IconSearchWrapper, FieldWrapper, Input, HelpText, IconCloseWrapper };
73
+ const FilterWrapper = styled.div``;
74
+
75
+ const Separator = styled.div`
76
+ border-right: 1px solid ${(p) => p.theme.color.uiLine};
77
+ height: ${(p) => p.theme.spacing.m};
78
+ margin-right: ${(p) => p.theme.spacing.xs};
79
+ margin-left: ${(p) => p.theme.spacing.s};
80
+ `;
81
+
82
+ export { Wrapper, IconSearchWrapper, FieldWrapper, Input, HelpText, IconCloseWrapper, FilterWrapper, Separator };
@@ -13,6 +13,7 @@ import {
13
13
  HeadingField,
14
14
  HiddenField,
15
15
  ImageField,
16
+ LinkField,
16
17
  NoteField,
17
18
  NumberField,
18
19
  RadioField,
@@ -105,6 +106,7 @@ export {
105
106
  HeadingField,
106
107
  HiddenField,
107
108
  ImageField,
109
+ LinkField,
108
110
  NoteField,
109
111
  NumberField,
110
112
  RadioField,
@@ -275,6 +275,8 @@ function updateNavigation(
275
275
  const successAction = async (response: any) => {
276
276
  if (fromEditor) {
277
277
  generateContent(response, dispatch, getState);
278
+ } else {
279
+ getNavigationByType(data.type)(dispatch, getState);
278
280
  }
279
281
  };
280
282
  const responseActions = {
@@ -26,10 +26,14 @@ import {
26
26
  replaceElements,
27
27
  findFieldsErrors,
28
28
  getParentKey,
29
+ checkH1content,
30
+ parseValidationErrors,
31
+ findPackagesActivationErrors,
29
32
  } from "@ax/forms";
30
33
  import { appActions } from "@ax/containers/App";
31
34
  import { navigationActions } from "@ax/containers/Navigation";
32
- import { pages, structuredData } from "@ax/api";
35
+ import { setCurrentSiteErrorPages } from "@ax/containers/Sites/actions";
36
+ import { pages, sites, structuredData } from "@ax/api";
33
37
  import { getPageData, getPageNavigation, getStateValues } from "./utils";
34
38
  import {
35
39
  SET_BREADCRUMB,
@@ -89,7 +93,7 @@ import {
89
93
  ISetCopyModule,
90
94
  } from "./interfaces";
91
95
 
92
- const { setIsLoading, setIsSaving } = appActions;
96
+ const { setIsLoading, setIsSaving, handleError } = appActions;
93
97
  const { getSiteDefaults, getDefaults } = navigationActions;
94
98
 
95
99
  // AUDIT: THIS FILE IS WAY TOO LONG - LOOK FOR A REFACTOR SOLUTION
@@ -197,7 +201,7 @@ function setTranslatedParent(): (dispatch: Dispatch, getState: any) => void {
197
201
  const translatedParentId = translatedParent && translatedParent[0] ? translatedParent[0].pageId : null;
198
202
  updateEditorContent(selectedEditorID, "parent", translatedParentId)(dispatch, getState);
199
203
  },
200
- handleError: (response: any) => appActions.handleError(response)(dispatch),
204
+ handleError: (response: any) => handleError(response)(dispatch),
201
205
  };
202
206
 
203
207
  const callback = async () => pages.getPageLanguages(parent, site, entity);
@@ -514,8 +518,30 @@ function updatePageStatus(
514
518
  pageEditor: {
515
519
  editorContent: { header, footer },
516
520
  },
521
+ sites: { currentSiteInfo },
517
522
  } = getState();
518
- const response = await pages.setPageStatus(status, ids);
523
+
524
+ const pagesWithErrors: number[] = [];
525
+ if (status === pageStatus.UPLOAD_PENDING && updatedFromList) {
526
+ const getPagesParams = {
527
+ siteID: currentSiteInfo?.id,
528
+ filterPages: ids,
529
+ deleted: false,
530
+ };
531
+ const { data } = await sites.getSitePages(getPagesParams);
532
+
533
+ data.items.forEach((page: any) => {
534
+ const errors = findFieldsErrors(page);
535
+ if (errors.length) pagesWithErrors.push(page.id);
536
+ });
537
+
538
+ dispatch(setCurrentSiteErrorPages(pagesWithErrors));
539
+ }
540
+
541
+ const validIds = ids.filter((id) => !pagesWithErrors.includes(id));
542
+ if (!validIds.length) return false;
543
+
544
+ const response = await pages.setPageStatus(status, validIds);
519
545
  const isUpdatingFromPageEditor = isReqOk(response.status) && !updatedFromList;
520
546
  if (isUpdatingFromPageEditor) {
521
547
  const currentPageID = ids[0];
@@ -551,18 +577,29 @@ function getPageLanguages(pageID: number, siteID: number | null, entity?: string
551
577
  };
552
578
  }
553
579
 
554
- function duplicatePage(pageID: number, data: any): (dispatch: any) => Promise<void> {
580
+ function duplicatePage(pageID: number, data: any, siteID?: number): (dispatch: Dispatch) => Promise<boolean> {
555
581
  return async (dispatch) => {
556
582
  try {
557
- const response: { status: number; data: IPage } = await pages.duplicatePage(pageID, data);
558
- if (isReqOk(response.status)) {
559
- dispatch(setCurrentPageID(response.data.id));
560
- dispatch(setCurrentPageStatus("offline"));
561
- } else {
562
- console.log("Error en duplicate Page"); // FIXME: capturar errores mejor
563
- }
583
+ const responseActions = {
584
+ handleSuccess: (data: any) => {
585
+ if (!siteID) {
586
+ dispatch(setCurrentPageID(data.id));
587
+ dispatch(setCurrentPageStatus("offline"));
588
+ }
589
+ return true;
590
+ },
591
+ handleError: (response: any) => {
592
+ appActions.handleError(response)(dispatch);
593
+ return false;
594
+ },
595
+ };
596
+
597
+ const callback = async () => pages.duplicatePage(pageID, data, siteID);
598
+
599
+ return await handleRequest(callback, responseActions, [])(dispatch);
564
600
  } catch (e) {
565
- console.log(e); // FIXME: capturar errores mejor
601
+ console.log(e);
602
+ return false;
566
603
  }
567
604
  };
568
605
  }
@@ -656,8 +693,11 @@ function addModule(
656
693
  function replaceModule(module: any, parent: any, objKey: string): (dispatch: Dispatch, getState: any) => void {
657
694
  return async (dispatch, getState) => {
658
695
  const { editorContent } = getStateValues(getState);
696
+
697
+ const [parentKey, childKey] = objKey.split(".");
698
+ const value = childKey ? parent[parentKey][childKey] : parent[parentKey];
659
699
  const updatedVal = {
660
- ...getNullValue(parent[objKey], true),
700
+ ...getNullValue(value, true),
661
701
  };
662
702
 
663
703
  Object.keys(updatedVal).forEach((key: string) => {
@@ -691,7 +731,7 @@ function replaceElementsInCollection(newValue: string, reference: string): (disp
691
731
 
692
732
  function deleteModule(editorID: number, key?: string): (dispatch: Dispatch, getState: any) => void {
693
733
  return (dispatch, getState) => {
694
- const { sections, editorContent } = getStateValues(getState);
734
+ const { sections, editorContent, errors } = getStateValues(getState);
695
735
 
696
736
  const updatedSections: any = [...sections];
697
737
  const { parent, grandParent } = findByEditorID(updatedSections, editorID);
@@ -707,6 +747,10 @@ function deleteModule(editorID: number, key?: string): (dispatch: Dispatch, getS
707
747
  ...editorContent,
708
748
  };
709
749
 
750
+ if (errors.length) {
751
+ validatePage()(dispatch, getState);
752
+ }
753
+
710
754
  generatePageContent(updatedPageContent, dispatch, getState);
711
755
 
712
756
  dispatch(setLastElementAddedId(null));
@@ -1025,16 +1069,54 @@ function getTemplateConfig(template: string): (dispatch: Dispatch, getState: any
1025
1069
  };
1026
1070
  }
1027
1071
 
1028
- function validatePage(publish: boolean): (dispatch: Dispatch, getState: any) => Promise<boolean> {
1072
+ function validatePage(publish?: boolean, browserRef?: any): (dispatch: Dispatch, getState: any) => Promise<boolean> {
1029
1073
  return async (dispatch, getState) => {
1030
1074
  try {
1031
1075
  const { editorContent } = getStateValues(getState);
1076
+ const content = deepClone(editorContent);
1077
+
1078
+ const {
1079
+ dataPacks: { modules, templates },
1080
+ pageEditor,
1081
+ } = getState();
1082
+
1083
+ const page = getPageData(getState, false);
1084
+ const { values } = parseData(page, false);
1085
+
1086
+ let errors: IErrorItem[] = [];
1087
+
1088
+ const responseActions = {
1089
+ handleSuccess: (data: any) => {
1090
+ const apiErrors = parseValidationErrors(data, content);
1091
+ errors = [...errors, ...apiErrors];
1092
+ },
1093
+ handleError: () => console.log("Error en page check"),
1094
+ };
1095
+
1096
+ const callback = async () => pages.pageCheck(values);
1097
+
1098
+ await handleRequest(callback, responseActions, [])(dispatch);
1032
1099
 
1033
- const errors = findFieldsErrors(editorContent);
1034
- dispatch(setErrors(errors));
1035
- if (errors.length === 0) {
1100
+ const fieldErrors = findFieldsErrors(content);
1101
+
1102
+ errors = [...errors, ...fieldErrors];
1103
+ const packagesActivationErrors = findPackagesActivationErrors(pageEditor, modules, templates);
1104
+ errors = packagesActivationErrors ? [...errors, packagesActivationErrors] : errors;
1105
+
1106
+ let warnings: IErrorItem[] = [];
1107
+ if (browserRef && browserRef.current) {
1108
+ const h1Warning = checkH1content(browserRef.current);
1109
+ warnings = h1Warning ? [...warnings, h1Warning] : warnings;
1110
+ }
1111
+
1112
+ const allErrors = [...errors, ...warnings];
1113
+
1114
+ dispatch(setErrors(allErrors));
1115
+ if (!allErrors.length) {
1036
1116
  !publish && dispatch(setValidated(true));
1037
1117
  return true;
1118
+ } else if (publish && !errors.length) {
1119
+ return true;
1038
1120
  } else {
1039
1121
  dispatch(setValidated(false));
1040
1122
  return false;
@@ -38,7 +38,7 @@ const getTemplateValues = (template: any) => {
38
38
 
39
39
  export const getStateValues = (getState: any) => {
40
40
  const {
41
- pageEditor: { editorContent: pageContent, selectedEditorID, selectedContent, template },
41
+ pageEditor: { editorContent: pageContent, selectedEditorID, selectedContent, template, errors },
42
42
  } = getState();
43
43
  const { editorContent, header, footer } = pageContent;
44
44
 
@@ -53,6 +53,7 @@ export const getStateValues = (getState: any) => {
53
53
  editorID,
54
54
  template,
55
55
  selectedContent,
56
+ errors,
56
57
  };
57
58
  };
58
59
 
@@ -1,6 +1,7 @@
1
1
  import { Dispatch } from "redux";
2
2
  import {
3
3
  SET_SITES,
4
+ SET_SITES_BY_LANG,
4
5
  SET_CURRENT_SITE_INFO,
5
6
  SET_CURRENT_SITE_PAGES,
6
7
  SET_FILTER,
@@ -8,15 +9,18 @@ import {
8
9
  SET_CURRENT_SITE_LANGUAGES,
9
10
  SET_SAVED_SITE_INFO,
10
11
  DEFAULT_PARAMS,
12
+ SET_CURRENT_SITE_ERROR_PAGES,
11
13
  } from "./constants";
12
14
  import {
13
15
  ISetSitesAction,
16
+ ISetSitesByLangAction,
14
17
  ISetCurrentSiteInfoAction,
15
18
  ISetCurrentSitePagesAction,
16
19
  ISetFilter,
17
20
  ISetTotalItems,
18
21
  ISetCurrentSiteLanguagesAction,
19
22
  ISetSavedSiteInfoAction,
23
+ ISetCurrentSiteErrorPages,
20
24
  } from "./interfaces";
21
25
 
22
26
  import { ISite, IGetSitePagesParams, ISettingsForm, IGetGlobalPagesParams, IPage } from "@ax/types";
@@ -24,7 +28,7 @@ import { sites, languages, dataPack, social, structuredData, analytics } from "@
24
28
  import { appActions } from "@ax/containers/App";
25
29
  import { structuredDataActions } from "@ax/containers/StructuredData";
26
30
  import { navigationActions, menuActions } from "@ax/containers/Navigation";
27
- import { pageEditorActions } from "@ax/containers/PageEditor";
31
+ import { resetPageEditor } from "@ax/containers/PageEditor/actions";
28
32
  import { analyticsActions } from "@ax/containers/Analytics";
29
33
  import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
30
34
  import { socialActions } from "@ax/containers/Settings/Social";
@@ -33,7 +37,6 @@ import { usersActions } from "@ax/containers/Users";
33
37
 
34
38
  const { setIsLoading, setIsSaving, setLanguage } = appActions;
35
39
  const { resetDefaultsValues } = navigationActions;
36
- const { resetPageEditor } = pageEditorActions;
37
40
  const { resetMenuValues } = menuActions;
38
41
  const { getAnalytics } = analyticsActions;
39
42
  const { getUsers } = usersActions;
@@ -42,6 +45,10 @@ function setSites(sitesList: ISite[]): ISetSitesAction {
42
45
  return { type: SET_SITES, payload: { sites: sitesList } };
43
46
  }
44
47
 
48
+ function setSitesByLang(sitesList: ISite[]): ISetSitesByLangAction {
49
+ return { type: SET_SITES_BY_LANG, payload: { sitesByLang: sitesList } };
50
+ }
51
+
45
52
  function setCurrentSiteInfo(currentSiteInfo: ISite): ISetCurrentSiteInfoAction {
46
53
  return { type: SET_CURRENT_SITE_INFO, payload: { currentSiteInfo } };
47
54
  }
@@ -66,25 +73,43 @@ function setSavedSiteInfo(savedSiteInfo: ISite): ISetSavedSiteInfoAction {
66
73
  return { type: SET_SAVED_SITE_INFO, payload: { savedSiteInfo } };
67
74
  }
68
75
 
76
+ function setCurrentSiteErrorPages(currentSiteErrorPages: number[]): ISetCurrentSiteErrorPages {
77
+ return { type: SET_CURRENT_SITE_ERROR_PAGES, payload: { currentSiteErrorPages } };
78
+ }
79
+
69
80
  // TODO: hay que controlar que cuando da error la API borrar los sites ya guardados y sacar el error (ver los siguientes FIXME)
70
- function getSites(token: string): (dispatch: Dispatch) => Promise<void> {
81
+ function getSites(): (dispatch: Dispatch) => Promise<void> {
71
82
  return async (dispatch) => {
72
83
  try {
73
- dispatch(setIsLoading(true));
74
- const sitesResponse: { status: number; data: ISite[] } = await sites.getAllSites(token); // FIXME: establecer type
75
- if (isReqOk(sitesResponse.status)) {
76
- dispatch(setSites(sitesResponse.data));
77
- } else {
78
- console.log("Error en getSites"); // TODO: capturar errores mejor
79
- }
80
- dispatch(setIsLoading(false));
84
+ const responseActions = {
85
+ handleSuccess: (data: any) => dispatch(setSites(data)),
86
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
87
+ };
88
+ const callback = async () => sites.getAllSites();
89
+
90
+ await handleRequest(callback, responseActions, [])(dispatch);
81
91
  } catch (e) {
82
- dispatch(setIsLoading(false));
83
92
  console.log(e); // TODO: capturar errores mejor
84
93
  }
85
94
  };
86
95
  }
87
96
 
97
+ function getSitesByLang(language: number): (dispatch: Dispatch) => Promise<void> {
98
+ return async (dispatch) => {
99
+ try {
100
+ const responseActions = {
101
+ handleSuccess: (data: any) => dispatch(setSitesByLang(data)),
102
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
103
+ };
104
+ const callback = async () => sites.getAllSites(language);
105
+
106
+ await handleRequest(callback, responseActions, [])(dispatch);
107
+ } catch (e) {
108
+ console.log(e);
109
+ }
110
+ };
111
+ }
112
+
88
113
  function saveSettings(form: ISettingsForm): (dispatch: Dispatch, getState: any) => Promise<boolean> {
89
114
  return async (dispatch, getState) => {
90
115
  try {
@@ -306,10 +331,7 @@ function deleteSite(siteID: number): (dispatch: Dispatch, getState: any) => Prom
306
331
  try {
307
332
  const response = await sites.deleteSite(siteID);
308
333
  if (isReqOk(response.status)) {
309
- const {
310
- app: { token },
311
- } = getState();
312
- getSites(token)(dispatch);
334
+ getSites()(dispatch);
313
335
  }
314
336
  } catch (e) {
315
337
  console.log(e); // TODO: capturar error bien
@@ -322,10 +344,7 @@ function publishSite(siteID: number): (dispatch: Dispatch, getState: any) => Pro
322
344
  try {
323
345
  const response = await sites.publishSite(siteID);
324
346
  if (isReqOk(response.status)) {
325
- const {
326
- app: { token },
327
- } = getState();
328
- getSites(token)(dispatch);
347
+ getSites()(dispatch);
329
348
  }
330
349
  } catch (e) {
331
350
  console.log(e); // TODO: capturar error bien
@@ -338,10 +357,7 @@ function unpublishSite(siteID: number): (dispatch: Dispatch, getState: any) => P
338
357
  try {
339
358
  const response = await sites.unpublishSite(siteID);
340
359
  if (isReqOk(response.status)) {
341
- const {
342
- app: { token },
343
- } = getState();
344
- getSites(token)(dispatch);
360
+ getSites()(dispatch);
345
361
  }
346
362
  } catch (e) {
347
363
  console.log(e); // TODO: capturar error bien
@@ -457,6 +473,16 @@ function removePageFromSite(
457
473
  };
458
474
  }
459
475
 
476
+ function resetCurrentSiteErrorPages(): (dispatch: Dispatch) => Promise<void> {
477
+ return async (dispatch) => {
478
+ try {
479
+ dispatch(setCurrentSiteErrorPages([]));
480
+ } catch (e) {
481
+ console.log(e);
482
+ }
483
+ };
484
+ }
485
+
460
486
  export {
461
487
  setCurrentSiteInfo,
462
488
  setCurrentSitePages,
@@ -464,6 +490,7 @@ export {
464
490
  setTotalItems,
465
491
  setCurrentSiteLanguages,
466
492
  getSites,
493
+ getSitesByLang,
467
494
  setSiteInfo,
468
495
  getFilteredContent,
469
496
  getSitePages,
@@ -478,4 +505,6 @@ export {
478
505
  importPageFromGlobal,
479
506
  removePageFromSite,
480
507
  removeUsersBulk,
508
+ setCurrentSiteErrorPages,
509
+ resetCurrentSiteErrorPages,
481
510
  };
@@ -1,6 +1,7 @@
1
1
  export const NAME = "sites";
2
2
 
3
3
  export const SET_SITES = `${NAME}/SET_SITES`;
4
+ export const SET_SITES_BY_LANG = `${NAME}/SET_SITES_BY_LANG`;
4
5
  export const SET_CURRENT_SITE_INFO = `${NAME}/SET_CURRENT_SITE_INFO`;
5
6
  export const SET_CURRENT_SITE_PAGES = `${NAME}/SET_CURRENT_SITE_PAGES`;
6
7
  export const SET_FILTER: string | null = `${NAME}/SET_FILTER`;
@@ -8,6 +9,7 @@ export const SET_TOTAL_ITEMS: string | null = `${NAME}/SET_TOTAL_ITEMS`;
8
9
  export const SET_CURRENT_SITE_LANGUAGES: string | null = `${NAME}/SET_CURRENT_SITE_LANGUAGES`;
9
10
  export const SET_INITIAL_VALUES = `${NAME}/SET_INITIAL_VALUES`;
10
11
  export const SET_SAVED_SITE_INFO = `${NAME}/SET_SAVED_SITE_INFO`;
12
+ export const SET_CURRENT_SITE_ERROR_PAGES = `${NAME}/SET_CURRENT_SITE_ERROR_PAGES`;
11
13
 
12
14
  export const ITEMS_PER_PAGE = 50;
13
15
 
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  SET_SITES,
3
+ SET_SITES_BY_LANG,
3
4
  SET_CURRENT_SITE_INFO,
4
5
  SET_CURRENT_SITE_PAGES,
5
6
  SET_FILTER,
@@ -7,6 +8,7 @@ import {
7
8
  SET_CURRENT_SITE_LANGUAGES,
8
9
  SET_INITIAL_VALUES,
9
10
  SET_SAVED_SITE_INFO,
11
+ SET_CURRENT_SITE_ERROR_PAGES,
10
12
  } from "./constants";
11
13
  import { ISite } from "@ax/types";
12
14
 
@@ -20,6 +22,11 @@ export interface ISetSitesAction {
20
22
  payload: { sites: ISite[] };
21
23
  }
22
24
 
25
+ export interface ISetSitesByLangAction {
26
+ type: typeof SET_SITES_BY_LANG;
27
+ payload: { sitesByLang: ISite[] };
28
+ }
29
+
23
30
  export interface ISetCurrentSiteInfoAction {
24
31
  type: typeof SET_CURRENT_SITE_INFO;
25
32
  payload: { currentSiteInfo: ISite };
@@ -40,11 +47,6 @@ export interface ISetCurrentSiteLanguagesAction {
40
47
  payload: { currentSiteLanguages: any[] }; // FIXME: establecer type
41
48
  }
42
49
 
43
- export interface ISetCurrentSiteLanguagesAction {
44
- type: typeof SET_CURRENT_SITE_LANGUAGES;
45
- payload: { currentSiteLanguages: any[] }; // FIXME: establecer type
46
- }
47
-
48
50
  export interface ISetInitialValuesAction {
49
51
  type: typeof SET_INITIAL_VALUES;
50
52
  payload: { initialValues: any };
@@ -55,4 +57,9 @@ export interface ISetSavedSiteInfoAction {
55
57
  payload: { savedSiteInfo: ISite };
56
58
  }
57
59
 
60
+ export interface ISetCurrentSiteErrorPages {
61
+ type: typeof SET_CURRENT_SITE_ERROR_PAGES;
62
+ payload: { currentSiteErrorPages: number[] };
63
+ }
64
+
58
65
  export type SitesActionsCreators = ISetSitesAction & ISetCurrentSiteInfoAction;
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  SET_SITES,
3
+ SET_SITES_BY_LANG,
3
4
  SET_CURRENT_SITE_INFO,
4
5
  SET_CURRENT_SITE_PAGES,
5
6
  SET_FILTER,
@@ -7,6 +8,7 @@ import {
7
8
  SET_CURRENT_SITE_LANGUAGES,
8
9
  SET_INITIAL_VALUES,
9
10
  SET_SAVED_SITE_INFO,
11
+ SET_CURRENT_SITE_ERROR_PAGES,
10
12
  } from "./constants";
11
13
 
12
14
  import { ISite, IPage, ILanguage } from "@ax/types";
@@ -17,34 +19,40 @@ export interface ISitesState {
17
19
  currentSiteName: string | null;
18
20
  currentSitePages: IPage[];
19
21
  sites: ISite[];
22
+ sitesByLang: ISite[];
20
23
  currentSiteInfo: any;
21
24
  currentFilter: string | null;
22
25
  totalItems: number;
23
26
  currentSiteLanguages: ILanguage[];
24
27
  savedSiteInfo: any;
28
+ currentSiteErrorPages: number[];
25
29
  }
26
30
 
27
31
  export const initialState = {
28
32
  currentSiteName: null,
29
33
  currentSitePages: [],
30
34
  sites: [],
35
+ sitesByLang: [],
31
36
  currentSiteInfo: null,
32
37
  currentFilter: "unique-pages",
33
38
  totalItems: 0,
34
39
  currentSiteLanguages: [],
35
40
  savedSiteInfo: null,
41
+ currentSiteErrorPages: [],
36
42
  };
37
43
 
38
44
  export function reducer(state = initialState, action: SitesActionsCreators): ISitesState {
39
45
  switch (action.type) {
40
46
  case SET_FILTER:
41
47
  case SET_SITES:
48
+ case SET_SITES_BY_LANG:
42
49
  case SET_CURRENT_SITE_INFO:
43
50
  case SET_CURRENT_SITE_PAGES:
44
51
  case SET_TOTAL_ITEMS:
45
52
  case SET_CURRENT_SITE_LANGUAGES:
46
53
  case SET_INITIAL_VALUES:
47
54
  case SET_SAVED_SITE_INFO:
55
+ case SET_CURRENT_SITE_ERROR_PAGES:
48
56
  return { ...state, ...action.payload };
49
57
  default:
50
58
  return state;
@@ -36,7 +36,7 @@ import { IStructuredData, IStructuredDataContent, ICategory, IGetStructuredDataP
36
36
  import { structuredData } from "@ax/api";
37
37
  import { setTotalItems } from "@ax/containers/Sites/actions";
38
38
  import { appActions } from "@ax/containers/App";
39
- import { handleRequest, isEmptyArray } from "@ax/helpers";
39
+ import { deepClone, handleRequest, isEmptyArray } from "@ax/helpers";
40
40
  import { findMandatoryStructuredDataErrors } from "@ax/forms";
41
41
 
42
42
  const { setIsLoading, setIsSaving } = appActions;
@@ -116,16 +116,12 @@ function resetForm(): (dispatch: Dispatch, getState: any) => void {
116
116
  return (dispatch, getState) => {
117
117
  const {
118
118
  structuredData: {
119
- form,
120
119
  currentStructuredData: { defaultValues },
121
120
  },
122
121
  } = getState();
123
122
 
124
- form.content &&
125
- Object.keys(form.content).forEach((key: string) => {
126
- defaultValues && defaultValues[key] ? (form.content[key] = defaultValues[key]) : (form.content[key] = "");
127
- });
128
- const updatedForm = { content: form.content };
123
+ const updatedForm = { content: defaultValues };
124
+
129
125
  dispatch(setEntity(null));
130
126
  dispatch(updateForm(updatedForm));
131
127
  dispatch(setErrors([]));
@@ -499,7 +495,8 @@ function validateForm(publish?: boolean): (dispatch: Dispatch, getState: any) =>
499
495
  },
500
496
  } = getState();
501
497
 
502
- const errors = findMandatoryStructuredDataErrors(content, schema);
498
+ const formContent = deepClone(content);
499
+ const errors = findMandatoryStructuredDataErrors(formContent, schema);
503
500
  dispatch(setErrors(errors));
504
501
  if (errors.length === 0) {
505
502
  !publish && dispatch(setValidated(true));
@@ -40,6 +40,7 @@ const ERRORS: Record<string, string> = {
40
40
  ERR039: "Sorry, this color doesn't exist. Please add new one.",
41
41
  ERR040: "Sorry, the file is not in a valid format.",
42
42
  ERR041: "Sorry, the password doesn’t match.",
43
+ ERR042: "This content is part of disabled content type package. To publish it, you must first activate it.",
43
44
  };
44
45
 
45
46
  export { ERRORS };
@@ -23,7 +23,15 @@ import {
23
23
  replaceElements,
24
24
  } from "./elements";
25
25
  import { getInnerFields, getStructuredDataInnerFields } from "./fields";
26
- import { getValidity, findFieldsErrors, findMandatoryStructuredDataErrors } from "./validators";
26
+ import {
27
+ getValidity,
28
+ findPackagesActivationErrors,
29
+ findFieldsErrors,
30
+ isTemplateActivated,
31
+ findMandatoryStructuredDataErrors,
32
+ checkH1content,
33
+ parseValidationErrors,
34
+ } from "./validators";
27
35
 
28
36
  export {
29
37
  parseData,
@@ -49,6 +57,10 @@ export {
49
57
  getLastComponentEditorID,
50
58
  getParentKey,
51
59
  getValidity,
60
+ findPackagesActivationErrors,
52
61
  findFieldsErrors,
62
+ isTemplateActivated,
53
63
  findMandatoryStructuredDataErrors,
64
+ checkH1content,
65
+ parseValidationErrors,
54
66
  };