@griddo/ax 1.66.3 → 1.66.4

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 (71) hide show
  1. package/package.json +2 -2
  2. package/src/api/pages.tsx +15 -3
  3. package/src/api/redirects.tsx +4 -2
  4. package/src/api/sites.tsx +4 -2
  5. package/src/components/Browser/index.tsx +3 -1
  6. package/src/components/Browser/style.tsx +2 -2
  7. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +0 -1
  8. package/src/components/ErrorCenter/index.tsx +8 -5
  9. package/src/components/ErrorCenter/style.tsx +21 -8
  10. package/src/components/Fields/ColorPicker/index.tsx +1 -0
  11. package/src/components/Fields/LinkField/index.tsx +85 -0
  12. package/src/components/Fields/ReferenceField/ItemList/index.tsx +5 -1
  13. package/src/components/Fields/ReferenceField/index.tsx +18 -14
  14. package/src/components/Fields/UrlField/index.tsx +13 -1
  15. package/src/components/Fields/index.tsx +2 -0
  16. package/src/components/FieldsBehavior/index.tsx +14 -1
  17. package/src/components/Icon/components/Copy.js +14 -0
  18. package/src/components/Icon/svgs/Copy2.svg +3 -0
  19. package/src/components/MainWrapper/AppBar/index.tsx +21 -10
  20. package/src/components/MainWrapper/AppBar/style.tsx +11 -3
  21. package/src/components/MainWrapper/index.tsx +2 -0
  22. package/src/components/Modal/style.tsx +0 -1
  23. package/src/components/SearchField/index.tsx +36 -4
  24. package/src/components/SearchField/style.tsx +23 -10
  25. package/src/components/SideModal/style.tsx +6 -6
  26. package/src/components/TableFilters/StatusFilter/index.tsx +2 -2
  27. package/src/components/index.tsx +2 -0
  28. package/src/containers/App/actions.tsx +3 -7
  29. package/src/containers/PageEditor/actions.tsx +91 -22
  30. package/src/containers/PageEditor/constants.tsx +1 -1
  31. package/src/containers/PageEditor/interfaces.tsx +6 -6
  32. package/src/containers/PageEditor/reducer.tsx +4 -4
  33. package/src/containers/PageEditor/utils.tsx +2 -1
  34. package/src/containers/Sites/actions.tsx +35 -23
  35. package/src/containers/Sites/constants.tsx +1 -0
  36. package/src/containers/Sites/interfaces.tsx +6 -0
  37. package/src/containers/Sites/reducer.tsx +4 -0
  38. package/src/forms/editor.tsx +34 -1
  39. package/src/forms/errors.tsx +1 -0
  40. package/src/forms/index.tsx +15 -1
  41. package/src/forms/validators.tsx +168 -9
  42. package/src/guards/error/index.tsx +1 -1
  43. package/src/helpers/dataPacks.tsx +8 -1
  44. package/src/helpers/index.tsx +2 -1
  45. package/src/modules/Content/PageItem/index.tsx +54 -4
  46. package/src/modules/Content/atoms.tsx +41 -3
  47. package/src/modules/Content/index.tsx +111 -64
  48. package/src/modules/Content/style.tsx +8 -1
  49. package/src/modules/GlobalEditor/Editor/index.tsx +3 -1
  50. package/src/modules/GlobalEditor/PageBrowser/index.tsx +3 -0
  51. package/src/modules/GlobalEditor/index.tsx +8 -6
  52. package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +8 -0
  53. package/src/modules/PageEditor/Editor/index.tsx +6 -2
  54. package/src/modules/PageEditor/PageBrowser/index.tsx +3 -0
  55. package/src/modules/PageEditor/index.tsx +29 -15
  56. package/src/modules/Redirects/index.tsx +40 -10
  57. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +1 -1
  58. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +1 -1
  59. package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +1 -1
  60. package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +1 -1
  61. package/src/modules/Sites/index.tsx +3 -3
  62. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
  63. package/src/modules/StructuredData/StructuredDataList/atoms.tsx +1 -1
  64. package/src/modules/Users/Profile/index.tsx +3 -4
  65. package/src/modules/Users/UserCreate/SiteItem/index.tsx +1 -1
  66. package/src/modules/Users/UserCreate/SiteItem/style.tsx +1 -1
  67. package/src/modules/Users/UserForm/style.tsx +3 -3
  68. package/src/modules/Users/UserList/UserItem/index.tsx +3 -1
  69. package/src/modules/Users/UserList/hooks.tsx +1 -1
  70. package/src/modules/Users/UserList/index.tsx +2 -2
  71. package/src/types/index.tsx +16 -3
@@ -1,13 +1,24 @@
1
1
  import { Icon } from "@ax/components";
2
2
  import React, { useState } from "react";
3
+ import { Select } from "../Fields";
3
4
 
4
5
  import * as S from "./style";
5
6
 
6
7
  const SearchField = (props: IProps): JSX.Element => {
7
- const { onChange, placeholder, closeOnInactive = false, searchOnEnter = true, disabled = false } = props;
8
+ const {
9
+ onChange,
10
+ placeholder,
11
+ closeOnInactive = false,
12
+ searchOnEnter = true,
13
+ disabled = false,
14
+ searchFilters,
15
+ onFilterChange,
16
+ } = props;
8
17
 
9
18
  const [isOpen, setIsOpen] = useState(false);
10
19
  const [inputValue, setInputValue] = useState("");
20
+ const initState = searchFilters && searchFilters[0] ? searchFilters[0].value : "";
21
+ const [selectValue, setSelectValue] = useState<string>(initState);
11
22
 
12
23
  const toggleField = () => setIsOpen(!isOpen);
13
24
 
@@ -36,12 +47,32 @@ const SearchField = (props: IProps): JSX.Element => {
36
47
  }
37
48
  };
38
49
 
50
+ const handleSelectChange = (value: string) => {
51
+ setSelectValue(value);
52
+ onFilterChange && onFilterChange(value);
53
+ };
54
+
39
55
  const showField = isOpen || !closeOnInactive;
40
56
 
41
57
  return (
42
58
  <S.Wrapper>
43
59
  {showField ? (
44
- <S.FieldWrapper>
60
+ <S.FieldWrapper closeOnInactive={closeOnInactive} disabled={disabled}>
61
+ {searchFilters && searchFilters.length && (
62
+ <>
63
+ <S.FilterWrapper>
64
+ <Select
65
+ name="filterSelect"
66
+ value={selectValue}
67
+ options={searchFilters}
68
+ onChange={handleSelectChange}
69
+ type="inline"
70
+ placeholder="Filter by"
71
+ />
72
+ </S.FilterWrapper>
73
+ <S.Separator />
74
+ </>
75
+ )}
45
76
  <S.Input
46
77
  type="text"
47
78
  value={inputValue}
@@ -50,7 +81,6 @@ const SearchField = (props: IProps): JSX.Element => {
50
81
  placeholder={placeholder}
51
82
  closeOnInactive={closeOnInactive}
52
83
  disabled={disabled}
53
- autoFocus
54
84
  />
55
85
  {inputValue.trim() !== "" && searchOnEnter && <S.HelpText>Press ENTER</S.HelpText>}
56
86
  {closeOnInactive || inputValue.length > 0 ? (
@@ -78,6 +108,8 @@ interface IProps {
78
108
  closeOnInactive?: boolean;
79
109
  searchOnEnter?: boolean;
80
110
  disabled?: boolean;
111
+ searchFilters?: any;
112
+ onFilterChange?(filter: string): void;
81
113
  }
82
114
 
83
- export default SearchField;
115
+ export default SearchField;
@@ -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 };
@@ -11,7 +11,8 @@ const Wrapper = styled.div<{ optionsType?: string }>`
11
11
 
12
12
  height: 100vh;
13
13
  background: ${(p) => p.theme.colors.uiBackground01};
14
- box-shadow: ${(p) => (p.optionsType && placeRight.includes(p.optionsType) ? p.theme.shadow.rightPanel : p.theme.shadow.leftPanel)};
14
+ box-shadow: ${(p) =>
15
+ p.optionsType && placeRight.includes(p.optionsType) ? p.theme.shadow.rightPanel : p.theme.shadow.leftPanel};
15
16
  padding-bottom: calc(${(p) => p.theme.spacing.m} * 2);
16
17
  `;
17
18
 
@@ -31,11 +32,10 @@ const Header = styled.div`
31
32
  }
32
33
  `;
33
34
 
34
- const Title = styled.h6`
35
- `;
35
+ const Title = styled.h6``;
36
36
 
37
37
  const ColumnsWrapper = styled.div`
38
- display:flex;
38
+ display: flex;
39
39
  `;
40
40
 
41
41
  const Content = styled.div`
@@ -64,11 +64,11 @@ const FeaturedWrapper = styled.div`
64
64
  `;
65
65
 
66
66
  const SearchWrapper = styled.div`
67
- width: ${p => `calc(${p.theme.spacing.xl} * 4)`};
67
+ width: ${(p) => `calc(${p.theme.spacing.xl} * 4)`};
68
68
  `;
69
69
 
70
70
  const Link = styled.div<{ active: boolean }>`
71
- color: ${p => p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis};
71
+ color: ${(p) => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis)};
72
72
  `;
73
73
 
74
74
  const ButtonWrapper = styled.div`
@@ -4,7 +4,7 @@ import { Icon, FloatingMenu, ListTitle, ListItem } from "@ax/components";
4
4
 
5
5
  import * as S from "./style";
6
6
 
7
- const StatusFilter = (props: IStatusFilterProps) => {
7
+ const StatusFilter = (props: IStatusFilterProps): JSX.Element => {
8
8
  const { sortItems, sortedState, isStructuredData } = props;
9
9
  const { isAscending, sortedByDate } = sortedState;
10
10
  const value = isStructuredData ? "date" : "modified";
@@ -46,7 +46,7 @@ const StatusFilter = (props: IStatusFilterProps) => {
46
46
 
47
47
  interface IStatusFilterProps {
48
48
  sortedState: any;
49
- sortItems(orderPointer: string, isAscendent: boolean): any;
49
+ sortItems(orderPointer: string, isAscendent: boolean): void;
50
50
  isStructuredData?: boolean;
51
51
  }
52
52
 
@@ -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,
@@ -99,14 +99,10 @@ function resetError(): ISetErrorAction {
99
99
 
100
100
  function handleError(response: any): (dispatch: Dispatch) => Promise<void> {
101
101
  return async (dispatch) => {
102
- const {
103
- data: { code, message },
104
- btnText,
105
- actionsBelow,
106
- } = response;
102
+ const { data, btnText, actionsBelow, text } = response;
107
103
  const error = {
108
- code,
109
- text: message,
104
+ code: data?.code,
105
+ text: data?.message || text,
110
106
  btnText,
111
107
  actionsBelow,
112
108
  };
@@ -26,6 +26,10 @@ import {
26
26
  replaceElements,
27
27
  findFieldsErrors,
28
28
  getParentKey,
29
+ checkMaxModules,
30
+ checkH1content,
31
+ parseValidationErrors,
32
+ findPackagesActivationErrors,
29
33
  } from "@ax/forms";
30
34
  import { appActions } from "@ax/containers/App";
31
35
  import { navigationActions } from "@ax/containers/Navigation";
@@ -50,8 +54,8 @@ import {
50
54
  SET_VALIDATED,
51
55
  SET_SITE_PAGE_ID,
52
56
  SET_USER_EDITING,
53
- SET_LAST_ELEMENT_ADDED_ID,
54
57
  SET_COPY_MODULE,
58
+ SET_LAST_ELEMENT_ADDED_ID,
55
59
  } from "./constants";
56
60
 
57
61
  import {
@@ -85,11 +89,11 @@ import {
85
89
  ISetSitePageID,
86
90
  ISetUserEditing,
87
91
  pageStatus,
88
- ISetLastElementAddedId,
89
92
  ISetCopyModule,
93
+ ISetLastElementAddedId,
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
@@ -167,14 +171,14 @@ function setUserEditing(userEditing: IUserEditing | null): ISetUserEditing {
167
171
  return { type: SET_USER_EDITING, payload: { userEditing } };
168
172
  }
169
173
 
170
- function setLastElementAddedId(lastElementAddedId: null | number): ISetLastElementAddedId {
171
- return { type: SET_LAST_ELEMENT_ADDED_ID, payload: { lastElementAddedId } };
172
- }
173
-
174
174
  function setCopyModule(moduleCopy: Record<string, unknown> | null): ISetCopyModule {
175
175
  return { type: SET_COPY_MODULE, payload: { moduleCopy } };
176
176
  }
177
177
 
178
+ function setLastElementAddedId(lastElementAddedId: null | number): ISetLastElementAddedId {
179
+ return { type: SET_LAST_ELEMENT_ADDED_ID, payload: { lastElementAddedId } };
180
+ }
181
+
178
182
  function setTranslatedParent(): (dispatch: Dispatch, getState: any) => void {
179
183
  return async (dispatch, getState) => {
180
184
  try {
@@ -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);
@@ -551,18 +555,29 @@ function getPageLanguages(pageID: number, siteID: number | null, entity?: string
551
555
  };
552
556
  }
553
557
 
554
- function duplicatePage(pageID: number, data: any): (dispatch: any) => Promise<void> {
558
+ function duplicatePage(pageID: number, data: any, siteID?: number): (dispatch: Dispatch) => Promise<boolean> {
555
559
  return async (dispatch) => {
556
560
  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
- }
561
+ const responseActions = {
562
+ handleSuccess: (data: any) => {
563
+ if (!siteID) {
564
+ dispatch(setCurrentPageID(data.id));
565
+ dispatch(setCurrentPageStatus("offline"));
566
+ }
567
+ return true;
568
+ },
569
+ handleError: (response: any) => {
570
+ appActions.handleError(response)(dispatch);
571
+ return false;
572
+ },
573
+ };
574
+
575
+ const callback = async () => pages.duplicatePage(pageID, data, siteID);
576
+
577
+ return await handleRequest(callback, responseActions, [])(dispatch);
564
578
  } catch (e) {
565
- console.log(e); // FIXME: capturar errores mejor
579
+ console.log(e);
580
+ return false;
566
581
  }
567
582
  };
568
583
  }
@@ -617,6 +632,13 @@ function addModule(
617
632
  ): (dispatch: Dispatch, getState: any) => void {
618
633
  return (dispatch, getState) => {
619
634
  const { editorContent, sections, editorID } = getStateValues(getState);
635
+
636
+ const { isMaxModules, errorMessage } = checkMaxModules(editorContent, type);
637
+ if (isMaxModules) {
638
+ handleError({ text: errorMessage })(dispatch);
639
+ return;
640
+ }
641
+
620
642
  const componentModule = {
621
643
  editorID,
622
644
  type,
@@ -691,7 +713,7 @@ function replaceElementsInCollection(newValue: string, reference: string): (disp
691
713
 
692
714
  function deleteModule(editorID: number, key?: string): (dispatch: Dispatch, getState: any) => void {
693
715
  return (dispatch, getState) => {
694
- const { sections, editorContent } = getStateValues(getState);
716
+ const { sections, editorContent, errors } = getStateValues(getState);
695
717
 
696
718
  const updatedSections: any = [...sections];
697
719
  const { parent, grandParent } = findByEditorID(updatedSections, editorID);
@@ -707,6 +729,10 @@ function deleteModule(editorID: number, key?: string): (dispatch: Dispatch, getS
707
729
  ...editorContent,
708
730
  };
709
731
 
732
+ if (errors.length) {
733
+ validatePage()(dispatch, getState);
734
+ }
735
+
710
736
  generatePageContent(updatedPageContent, dispatch, getState);
711
737
 
712
738
  dispatch(setLastElementAddedId(null));
@@ -719,6 +745,13 @@ function duplicateModule(editorID: number, key?: string): (dispatch: Dispatch, g
719
745
 
720
746
  const updatedSections: any = [...sections];
721
747
  const { element: originalItem, parent, grandParent } = findByEditorID(updatedSections, editorID);
748
+
749
+ const { isMaxModules, errorMessage } = checkMaxModules(editorContent, originalItem.component);
750
+ if (isMaxModules) {
751
+ handleError({ text: errorMessage })(dispatch);
752
+ return;
753
+ }
754
+
722
755
  const parentModule = Array.isArray(parent) ? grandParent : parent;
723
756
 
724
757
  const parentKey = key ? key : getParentKey(parentModule, editorID);
@@ -1025,16 +1058,52 @@ function getTemplateConfig(template: string): (dispatch: Dispatch, getState: any
1025
1058
  };
1026
1059
  }
1027
1060
 
1028
- function validatePage(publish: boolean): (dispatch: Dispatch, getState: any) => Promise<boolean> {
1061
+ function validatePage(publish?: boolean, browserRef?: any): (dispatch: Dispatch, getState: any) => Promise<boolean> {
1029
1062
  return async (dispatch, getState) => {
1030
1063
  try {
1031
1064
  const { editorContent } = getStateValues(getState);
1032
1065
 
1033
- const errors = findFieldsErrors(editorContent);
1034
- dispatch(setErrors(errors));
1035
- if (errors.length === 0) {
1066
+ const {
1067
+ dataPacks: { modules, templates },
1068
+ pageEditor,
1069
+ } = getState();
1070
+
1071
+ const page = getPageData(getState, false);
1072
+ const { values } = parseData(page, false);
1073
+
1074
+ let errors: IErrorItem[] = [];
1075
+
1076
+ const responseActions = {
1077
+ handleSuccess: (data: any) => {
1078
+ const apiErrors = parseValidationErrors(data, editorContent);
1079
+ errors = [...errors, ...apiErrors];
1080
+ },
1081
+ handleError: () => console.log("Error en page check"),
1082
+ };
1083
+
1084
+ const callback = async () => pages.pageCheck(values);
1085
+
1086
+ await handleRequest(callback, responseActions, [])(dispatch);
1087
+
1088
+ const fieldErrors = findFieldsErrors(editorContent);
1089
+ errors = [...errors, ...fieldErrors];
1090
+ const packagesActivationErrors = findPackagesActivationErrors(pageEditor, modules, templates);
1091
+ errors = packagesActivationErrors ? [...errors, packagesActivationErrors] : errors;
1092
+
1093
+ let warnings: IErrorItem[] = [];
1094
+ if (browserRef && browserRef.current) {
1095
+ const h1Warning = checkH1content(browserRef.current);
1096
+ warnings = h1Warning ? [...warnings, h1Warning] : warnings;
1097
+ }
1098
+
1099
+ const allErrors = [...errors, ...warnings];
1100
+
1101
+ dispatch(setErrors(allErrors));
1102
+ if (!allErrors.length) {
1036
1103
  !publish && dispatch(setValidated(true));
1037
1104
  return true;
1105
+ } else if (publish && !errors.length) {
1106
+ return true;
1038
1107
  } else {
1039
1108
  dispatch(setValidated(false));
1040
1109
  return false;
@@ -18,8 +18,8 @@ export const SET_ERRORS = `${NAME}/SET_ERRORS`;
18
18
  export const SET_VALIDATED = `${NAME}/SET_VALIDATED`;
19
19
  export const SET_SITE_PAGE_ID = `${NAME}/SET_SITE_PAGE_ID`;
20
20
  export const SET_USER_EDITING = `${NAME}/SET_USER_EDITING`;
21
- export const SET_LAST_ELEMENT_ADDED_ID = `${NAME}/SET_LAST_ELEMENT_ADDED_ID`;
22
21
  export const SET_COPY_MODULE = `${NAME}/SET_COPY_MODULE`;
22
+ export const SET_LAST_ELEMENT_ADDED_ID = `${NAME}/SET_LAST_ELEMENT_ADDED_ID`;
23
23
 
24
24
  export const INITIAL_TEMPLATE = "BasicTemplate";
25
25
  export const MULTIMEDIA_COMPONENTS = ["LinkableImage", "Video"];
@@ -17,8 +17,8 @@ import {
17
17
  SET_VALIDATED,
18
18
  SET_SITE_PAGE_ID,
19
19
  SET_USER_EDITING,
20
- SET_LAST_ELEMENT_ADDED_ID,
21
20
  SET_COPY_MODULE,
21
+ SET_LAST_ELEMENT_ADDED_ID,
22
22
  } from "./constants";
23
23
  import { IBreadcrumbItem, ISchema, IPage, IErrorItem, IUserEditing } from "@ax/types";
24
24
 
@@ -112,16 +112,16 @@ export interface ISetUserEditing {
112
112
  payload: { userEditing: IUserEditing | null };
113
113
  }
114
114
 
115
- export interface ISetLastElementAddedId {
116
- type: typeof SET_LAST_ELEMENT_ADDED_ID;
117
- payload: { lastElementAddedId: null | number };
118
- }
119
-
120
115
  export interface ISetCopyModule {
121
116
  type: typeof SET_COPY_MODULE;
122
117
  payload: { moduleCopy: Record<string, unknown> | null };
123
118
  }
124
119
 
120
+ export interface ISetLastElementAddedId {
121
+ type: typeof SET_LAST_ELEMENT_ADDED_ID;
122
+ payload: { lastElementAddedId: null | number };
123
+ }
124
+
125
125
  export interface IFieldProps {
126
126
  id: number;
127
127
  key: string;
@@ -20,8 +20,8 @@ import {
20
20
  SET_VALIDATED,
21
21
  SET_SITE_PAGE_ID,
22
22
  SET_USER_EDITING,
23
- SET_LAST_ELEMENT_ADDED_ID,
24
23
  SET_COPY_MODULE,
24
+ SET_LAST_ELEMENT_ADDED_ID,
25
25
  } from "./constants";
26
26
 
27
27
  import { PageEditorActionsCreators } from "./interfaces";
@@ -45,8 +45,8 @@ export interface IPageEditorState {
45
45
  validated: boolean;
46
46
  sitePageID: number | null;
47
47
  userEditing: IUserEditing | null;
48
- lastElementAddedId: null | number;
49
48
  moduleCopy: { date: string; element: Record<string, unknown> } | null;
49
+ lastElementAddedId: null | number;
50
50
  }
51
51
 
52
52
  export const initialState = {
@@ -68,8 +68,8 @@ export const initialState = {
68
68
  validated: false,
69
69
  sitePageID: null,
70
70
  userEditing: null,
71
- lastElementAddedId: null,
72
71
  moduleCopy: null,
72
+ lastElementAddedId: null,
73
73
  };
74
74
 
75
75
  export function reducer(state = initialState, action: PageEditorActionsCreators): IPageEditorState {
@@ -93,8 +93,8 @@ export function reducer(state = initialState, action: PageEditorActionsCreators)
93
93
  case SET_VALIDATED:
94
94
  case SET_SITE_PAGE_ID:
95
95
  case SET_USER_EDITING:
96
- case SET_LAST_ELEMENT_ADDED_ID:
97
96
  case SET_COPY_MODULE:
97
+ case SET_LAST_ELEMENT_ADDED_ID:
98
98
  return { ...state, ...action.payload };
99
99
  default:
100
100
  return state;
@@ -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,
@@ -11,6 +12,7 @@ import {
11
12
  } from "./constants";
12
13
  import {
13
14
  ISetSitesAction,
15
+ ISetSitesByLangAction,
14
16
  ISetCurrentSiteInfoAction,
15
17
  ISetCurrentSitePagesAction,
16
18
  ISetFilter,
@@ -42,6 +44,10 @@ function setSites(sitesList: ISite[]): ISetSitesAction {
42
44
  return { type: SET_SITES, payload: { sites: sitesList } };
43
45
  }
44
46
 
47
+ function setSitesByLang(sitesList: ISite[]): ISetSitesByLangAction {
48
+ return { type: SET_SITES_BY_LANG, payload: { sitesByLang: sitesList } };
49
+ }
50
+
45
51
  function setCurrentSiteInfo(currentSiteInfo: ISite): ISetCurrentSiteInfoAction {
46
52
  return { type: SET_CURRENT_SITE_INFO, payload: { currentSiteInfo } };
47
53
  }
@@ -67,20 +73,34 @@ function setSavedSiteInfo(savedSiteInfo: ISite): ISetSavedSiteInfoAction {
67
73
  }
68
74
 
69
75
  // 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> {
76
+ function getSites(): (dispatch: Dispatch) => Promise<void> {
71
77
  return async (dispatch) => {
72
78
  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));
79
+ const responseActions = {
80
+ handleSuccess: (data: any) => dispatch(setSites(data)),
81
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
82
+ };
83
+ const callback = async () => sites.getAllSites();
84
+
85
+ await handleRequest(callback, responseActions, [])(dispatch);
81
86
  } catch (e) {
82
- dispatch(setIsLoading(false));
83
- console.log(e); // TODO: capturar errores mejor
87
+ console.log(e);
88
+ }
89
+ };
90
+ }
91
+
92
+ function getSitesByLang(language: number): (dispatch: Dispatch) => Promise<void> {
93
+ return async (dispatch) => {
94
+ try {
95
+ const responseActions = {
96
+ handleSuccess: (data: any) => dispatch(setSitesByLang(data)),
97
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
98
+ };
99
+ const callback = async () => sites.getAllSites(language);
100
+
101
+ await handleRequest(callback, responseActions, [])(dispatch);
102
+ } catch (e) {
103
+ console.log(e);
84
104
  }
85
105
  };
86
106
  }
@@ -306,10 +326,7 @@ function deleteSite(siteID: number): (dispatch: Dispatch, getState: any) => Prom
306
326
  try {
307
327
  const response = await sites.deleteSite(siteID);
308
328
  if (isReqOk(response.status)) {
309
- const {
310
- app: { token },
311
- } = getState();
312
- getSites(token)(dispatch);
329
+ getSites()(dispatch);
313
330
  }
314
331
  } catch (e) {
315
332
  console.log(e); // TODO: capturar error bien
@@ -322,10 +339,7 @@ function publishSite(siteID: number): (dispatch: Dispatch, getState: any) => Pro
322
339
  try {
323
340
  const response = await sites.publishSite(siteID);
324
341
  if (isReqOk(response.status)) {
325
- const {
326
- app: { token },
327
- } = getState();
328
- getSites(token)(dispatch);
342
+ getSites()(dispatch);
329
343
  }
330
344
  } catch (e) {
331
345
  console.log(e); // TODO: capturar error bien
@@ -338,10 +352,7 @@ function unpublishSite(siteID: number): (dispatch: Dispatch, getState: any) => P
338
352
  try {
339
353
  const response = await sites.unpublishSite(siteID);
340
354
  if (isReqOk(response.status)) {
341
- const {
342
- app: { token },
343
- } = getState();
344
- getSites(token)(dispatch);
355
+ getSites()(dispatch);
345
356
  }
346
357
  } catch (e) {
347
358
  console.log(e); // TODO: capturar error bien
@@ -464,6 +475,7 @@ export {
464
475
  setTotalItems,
465
476
  setCurrentSiteLanguages,
466
477
  getSites,
478
+ getSitesByLang,
467
479
  setSiteInfo,
468
480
  getFilteredContent,
469
481
  getSitePages,
@@ -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`;
@@ -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,
@@ -20,6 +21,11 @@ export interface ISetSitesAction {
20
21
  payload: { sites: ISite[] };
21
22
  }
22
23
 
24
+ export interface ISetSitesByLangAction {
25
+ type: typeof SET_SITES_BY_LANG;
26
+ payload: { sitesByLang: ISite[] };
27
+ }
28
+
23
29
  export interface ISetCurrentSiteInfoAction {
24
30
  type: typeof SET_CURRENT_SITE_INFO;
25
31
  payload: { currentSiteInfo: ISite };