@griddo/ax 1.75.92 → 1.75.93

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 (57) hide show
  1. package/package.json +2 -2
  2. package/src/__mocks__/store/SitesList.ts +24 -0
  3. package/src/__tests__/components/Avatar/__snapshots__/Avatar.test.tsx.snap +10 -10
  4. package/src/__tests__/modules/Sites/Sites.test.tsx +3 -0
  5. package/src/__tests__/modules/Sites/SitesList/SitesList.test.tsx +8 -1
  6. package/src/components/ErrorCenter/index.tsx +10 -1
  7. package/src/components/Fields/ComponentContainer/index.tsx +1 -1
  8. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +34 -19
  9. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/style.tsx +5 -0
  10. package/src/components/Notification/style.tsx +2 -2
  11. package/src/components/Tooltip/style.tsx +1 -1
  12. package/src/containers/App/actions.tsx +2 -0
  13. package/src/containers/Gallery/actions.tsx +19 -10
  14. package/src/containers/PageEditor/actions.tsx +19 -22
  15. package/src/containers/PageEditor/utils.tsx +5 -5
  16. package/src/containers/Sites/actions.tsx +35 -8
  17. package/src/containers/Sites/constants.tsx +1 -0
  18. package/src/containers/Sites/interfaces.tsx +8 -2
  19. package/src/containers/Sites/reducer.tsx +18 -1
  20. package/src/containers/Users/actions.tsx +23 -2
  21. package/src/forms/validators.tsx +1 -3
  22. package/src/helpers/requests.tsx +1 -1
  23. package/src/hooks/bulk.tsx +2 -1
  24. package/src/hooks/content.tsx +27 -2
  25. package/src/hooks/index.tsx +4 -1
  26. package/src/hooks/window.ts +16 -0
  27. package/src/modules/App/Routing/NavMenu/index.tsx +3 -2
  28. package/src/modules/App/Routing/NavMenu/style.tsx +2 -2
  29. package/src/modules/Content/PageItem/index.tsx +18 -10
  30. package/src/modules/Content/PageItem/style.tsx +26 -4
  31. package/src/modules/Content/index.tsx +41 -5
  32. package/src/modules/Content/utils.tsx +5 -2
  33. package/src/modules/CreatePass/index.tsx +8 -11
  34. package/src/modules/FramePreview/index.tsx +2 -6
  35. package/src/modules/GlobalEditor/PageBrowser/index.tsx +2 -4
  36. package/src/modules/GlobalEditor/index.tsx +13 -15
  37. package/src/modules/PageEditor/Editor/index.tsx +1 -3
  38. package/src/modules/PageEditor/PageBrowser/index.tsx +2 -6
  39. package/src/modules/PageEditor/index.tsx +23 -20
  40. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/index.tsx +1 -1
  41. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +3 -3
  42. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/index.tsx +17 -10
  43. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +23 -25
  44. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/style.tsx +3 -3
  45. package/src/modules/Sites/SitesList/GridView/GridHeaderFilter/index.tsx +2 -2
  46. package/src/modules/Sites/SitesList/GridView/GridSiteItem/index.tsx +1 -1
  47. package/src/modules/Sites/SitesList/atoms.tsx +1 -1
  48. package/src/modules/Sites/SitesList/hooks.tsx +3 -4
  49. package/src/modules/Sites/SitesList/index.tsx +47 -19
  50. package/src/modules/Sites/SitesList/style.tsx +7 -1
  51. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +11 -6
  52. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/style.tsx +10 -1
  53. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +1 -1
  54. package/src/modules/StructuredData/StructuredDataList/index.tsx +25 -1
  55. package/src/modules/StructuredData/StructuredDataList/utils.tsx +5 -3
  56. package/src/modules/Users/UserCreate/index.tsx +4 -1
  57. package/src/types/index.tsx +21 -2
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "1.75.92",
4
+ "version": "1.75.93",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -230,5 +230,5 @@
230
230
  "publishConfig": {
231
231
  "access": "public"
232
232
  },
233
- "gitHead": "ae192e87d36ac0db7f888c1cb4e9c3564a7a0ad7"
233
+ "gitHead": "971ac4c31bccc4aeb90f0f34e0309e3032e8618b"
234
234
  }
@@ -112,6 +112,18 @@ export const sitesDataMock = {
112
112
  navigationModules: null,
113
113
  },
114
114
  ],
115
+ config: {
116
+ displayRecentSites: true,
117
+ mode: "grid",
118
+ filter: "&order=lastAccess-desc",
119
+ filterValues: { order: "desc", liveStatus: "all" },
120
+ sortedListStatus: {
121
+ isAscending: false,
122
+ sortedByDateCreated: false,
123
+ sortedByLastAccess: true,
124
+ sortedByTitle: false,
125
+ },
126
+ },
115
127
  };
116
128
 
117
129
  export const sitesDataNoThumbnailMock = {
@@ -228,6 +240,18 @@ export const sitesDataNoThumbnailMock = {
228
240
  navigationModules: null,
229
241
  },
230
242
  ],
243
+ config: {
244
+ displayRecentSites: true,
245
+ mode: "grid",
246
+ filter: "&order=lastAccess-desc",
247
+ filterValues: { order: "desc", liveStatus: "all" },
248
+ sortedListStatus: {
249
+ isAscending: false,
250
+ sortedByDateCreated: false,
251
+ sortedByLastAccess: true,
252
+ sortedByTitle: false,
253
+ },
254
+ },
231
255
  };
232
256
 
233
257
  export const userDataMock = {
@@ -2,11 +2,11 @@
2
2
 
3
3
  exports[`Avatar component rendering should render the component only with name 1`] = `
4
4
  <div
5
- className="sc-gScZFl gCBoym"
5
+ className="sc-gSAPjG jRkXjC"
6
6
  data-testid="avatar-wrapper"
7
7
  >
8
8
  <div
9
- className="sc-lbVpMG hOAqbs"
9
+ className="sc-lbxAil fkodDH"
10
10
  data-testid="avatar"
11
11
  />
12
12
  </div>
@@ -14,11 +14,11 @@ exports[`Avatar component rendering should render the component only with name 1
14
14
 
15
15
  exports[`Avatar component rendering should render the component with a wrong image url 1`] = `
16
16
  <div
17
- className="sc-gScZFl gCBoym"
17
+ className="sc-gSAPjG jRkXjC"
18
18
  data-testid="avatar-wrapper"
19
19
  >
20
20
  <div
21
- className="sc-lbVpMG kLnTvZ"
21
+ className="sc-lbxAil ejhcAS"
22
22
  data-testid="avatar"
23
23
  />
24
24
  </div>
@@ -26,11 +26,11 @@ exports[`Avatar component rendering should render the component with a wrong ima
26
26
 
27
27
  exports[`Avatar component rendering should render the component with an empty string as name 1`] = `
28
28
  <div
29
- className="sc-gScZFl gCBoym"
29
+ className="sc-gSAPjG jRkXjC"
30
30
  data-testid="avatar-wrapper"
31
31
  >
32
32
  <div
33
- className="sc-lbVpMG dbQJiT"
33
+ className="sc-lbxAil hilXDA"
34
34
  data-testid="avatar"
35
35
  />
36
36
  </div>
@@ -38,11 +38,11 @@ exports[`Avatar component rendering should render the component with an empty st
38
38
 
39
39
  exports[`Avatar component rendering should render the component with image null 1`] = `
40
40
  <div
41
- className="sc-gScZFl gCBoym"
41
+ className="sc-gSAPjG jRkXjC"
42
42
  data-testid="avatar-wrapper"
43
43
  >
44
44
  <div
45
- className="sc-lbVpMG jpmXvZ"
45
+ className="sc-lbxAil jDWEnq"
46
46
  data-testid="avatar"
47
47
  />
48
48
  </div>
@@ -50,11 +50,11 @@ exports[`Avatar component rendering should render the component with image null
50
50
 
51
51
  exports[`Avatar component rendering should render the component without name or image 1`] = `
52
52
  <div
53
- className="sc-gScZFl gCBoym"
53
+ className="sc-gSAPjG jRkXjC"
54
54
  data-testid="avatar-wrapper"
55
55
  >
56
56
  <div
57
- className="sc-lbVpMG dbQJiT"
57
+ className="sc-lbxAil hilXDA"
58
58
  data-testid="avatar"
59
59
  />
60
60
  </div>
@@ -39,6 +39,7 @@ describe("Sites module rendering", () => {
39
39
  totalItems: 0,
40
40
  sites: [],
41
41
  recentSites: [],
42
+ config: sitesDataMock.config,
42
43
  },
43
44
  structuredData: { global: [], sites: [] },
44
45
  };
@@ -186,6 +187,7 @@ describe("Sites module rendering", () => {
186
187
  totalItems: 2,
187
188
  sites: sitesDataMock.sites,
188
189
  recentSites: [],
190
+ config: sitesDataMock.config,
189
191
  },
190
192
  structuredData: { global: [], sites: [] },
191
193
  };
@@ -231,6 +233,7 @@ describe("Sites module rendering", () => {
231
233
  totalItems: 0,
232
234
  sites: [],
233
235
  recentSites: [],
236
+ config: sitesDataMock.config,
234
237
  },
235
238
  structuredData: { global: [], sites: [] },
236
239
  };
@@ -146,7 +146,7 @@ describe("Sites module rendering", () => {
146
146
  token: "eyJhbGciOiJIUzI",
147
147
  },
148
148
  users: userDataMock,
149
- sites: { totalItems: 2, sites: sitesDataMock.sites, recentSites: [] },
149
+ sites: { totalItems: 2, sites: sitesDataMock.sites, recentSites: [], config: sitesDataMock.config, },
150
150
  };
151
151
 
152
152
  const middlewares: any = [thunk];
@@ -187,6 +187,7 @@ describe("Sites module rendering", () => {
187
187
  totalItems: 0,
188
188
  sites: [],
189
189
  recentSites: [],
190
+ config: sitesDataMock.config,
190
191
  },
191
192
  };
192
193
 
@@ -280,6 +281,7 @@ describe("Sites module rendering", () => {
280
281
  },
281
282
  sitesDataMock.sites[1],
282
283
  ],
284
+ config: sitesDataMock.config,
283
285
  recentSites: sitesDataMock.recentSites,
284
286
  },
285
287
  };
@@ -399,6 +401,7 @@ describe("Sites module events", () => {
399
401
  });
400
402
 
401
403
  it("should go to site on click recent site item", async () => {
404
+ window.HTMLElement.prototype.scrollTo = jest.fn();
402
405
  const middlewares: any = [thunk];
403
406
  const mockStore = configureStore(middlewares);
404
407
  const store = mockStore(initialStore);
@@ -479,6 +482,7 @@ describe("Sites module events", () => {
479
482
  });
480
483
 
481
484
  it("should go to site on click list site item", async () => {
485
+ window.HTMLElement.prototype.scrollTo = jest.fn();
482
486
  const middlewares: any = [thunk];
483
487
  const mockStore = configureStore(middlewares);
484
488
  const store = mockStore(initialStore);
@@ -892,6 +896,9 @@ describe("Sites module events", () => {
892
896
  await act(async () => {
893
897
  render(Component, { store });
894
898
  });
899
+
900
+ const gridIconAction = screen.getByTestId("icon-action-Grid2");
901
+ fireEvent.click(gridIconAction);
895
902
 
896
903
  const gridItems = screen.getAllByTestId("grid-site-item");
897
904
  const moreInfoButton = screen.getAllByTestId("more-info-button");
@@ -9,8 +9,17 @@ const ErrorCenter = (props: IErrorCenterProps): JSX.Element => {
9
9
 
10
10
  const goToElement = (key: string) => {
11
11
  const element = document.getElementById(key);
12
+
12
13
  if (element) {
13
- element.scrollIntoView();
14
+ const pos = element.style.position;
15
+ const top = element.style.top;
16
+ element.style.position = "relative";
17
+ element.style.top = "-120px";
18
+ setTimeout(() => {
19
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
20
+ element.style.top = top;
21
+ element.style.position = pos;
22
+ }, 100);
14
23
  }
15
24
  };
16
25
 
@@ -54,7 +54,7 @@ const ComponentContainer = (props: IComponentContainerProps): JSX.Element => {
54
54
  parentKey && objKey ? selectedContent[parentKey][objKey] : objKey && selectedContent[objKey];
55
55
 
56
56
  let containerText: string = text ? text : getDisplayName(whiteListFirstItem);
57
- let componentID: number = editorID ? editorID : containerOptions.editorID;
57
+ let componentID: number = editorID ? editorID : containerOptions?.editorID;
58
58
 
59
59
  const containerInfo: any = !isArray && value && isEmptyContainer(value, hasMultipleOptions);
60
60
  const isEmpty: boolean = containerInfo?.isEmpty;
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
3
3
 
4
4
  import { galleryActions } from "@ax/containers/Gallery";
5
5
  import { IGetSiteImages, IImage, IRootState } from "@ax/types";
6
- import { Icon, DragAndDrop } from "@ax/components";
6
+ import { Icon, DragAndDrop, ProgressBar } from "@ax/components";
7
7
 
8
8
  import * as S from "./style";
9
9
 
@@ -28,6 +28,7 @@ const GalleryDragAndDrop = (props: IProps) => {
28
28
  const filesButtonRef = useRef<HTMLButtonElement>(null);
29
29
  const [inDropZone, setInDropZone] = useState(false);
30
30
  const [dropDepth, setDropDepth] = useState(0);
31
+ const [uploadingState, setUploadingState] = useState({ total: 0, ready: 0 });
31
32
 
32
33
  const handleDragEnter = () => {
33
34
  setDropDepth((depth) => depth + 1);
@@ -54,32 +55,43 @@ const GalleryDragAndDrop = (props: IProps) => {
54
55
  const handleDrop = async (e: React.DragEvent<HTMLDivElement>) => {
55
56
  const files = Array.from(e.dataTransfer.files);
56
57
  e.dataTransfer.clearData();
57
- await handleUploadFile(files);
58
+ await uploadFiles(files);
58
59
  setDropDepth(0);
59
60
  };
60
61
 
61
62
  const handleFilesUpload = (e: any) => {
62
- const files = Array.from(e.currentTarget.files);
63
- handleUploadFile(files);
63
+ const files: File[] = Array.from(e.currentTarget.files);
64
+ uploadFiles(files);
64
65
  };
65
66
 
66
- const handleUploadFile = async (files: Array<any>) => {
67
- if (files[0]) {
68
- if (!checkType(files[0].type)) {
67
+ const uploadFiles = async (files: File[]) => {
68
+ try {
69
+ if (!files.every((file) => checkType(file.type))) {
69
70
  uploadError(true, "Invalid format");
70
- } else {
71
- try {
72
- const newImage = await uploadImage(files[0], site);
73
- setInDropZone(false);
74
- await refreshImages();
75
- selectImage(newImage);
76
- } catch (error) {
77
- console.log(error);
78
- }
71
+ return;
79
72
  }
73
+
74
+ setUploadingState({ total: files.length, ready: 0 });
75
+ let lastImage;
76
+ while (files.length) {
77
+ const file = files.shift();
78
+ lastImage = file && (await uploadImage(file, site));
79
+ setUploadingState((state) => ({ total: state.total, ready: state.ready + 1 }));
80
+ }
81
+
82
+ setInDropZone(false);
83
+ await refreshImages();
84
+ lastImage && selectImage(lastImage);
85
+ setUploadingState({ total: 0, ready: 0 });
86
+ } catch (error) {
87
+ console.log(error);
80
88
  }
81
89
  };
82
90
 
91
+ const uploading = isUploading || uploadingState.total > uploadingState.ready;
92
+ const success = isSuccess && uploadingState.total === uploadingState.ready;
93
+ const uploadPercentage = (uploadingState.ready * 100) / uploadingState.total;
94
+
83
95
  const handleTryAgain = () => {
84
96
  setInDropZone(false);
85
97
  uploadError(false);
@@ -136,15 +148,18 @@ const GalleryDragAndDrop = (props: IProps) => {
136
148
 
137
149
  return (
138
150
  <S.Wrapper hidden={isImageSelected}>
139
- <S.DragAndDropWrapper inDropZone={inDropZone} uploading={isUploading} success={isSuccess} error={isError}>
151
+ <S.DragAndDropWrapper inDropZone={inDropZone} uploading={uploading} success={success} error={isError}>
140
152
  {allowUpload ? renderDragAndDrop() : renderPlaceholder()}
141
153
  </S.DragAndDropWrapper>
142
- <S.UploadingWrapper inDropZone={inDropZone} uploading={isUploading} success={isSuccess} error={isError}>
154
+ <S.UploadingWrapper inDropZone={inDropZone} uploading={uploading} success={success} error={isError}>
143
155
  <S.StatusWrapper>
144
156
  <S.UploadingStatus>
145
157
  <S.DragIcon>
146
158
  <Icon name="image" size="36" />
147
159
  </S.DragIcon>
160
+ <S.ProgressBar>
161
+ <ProgressBar percentage={uploadPercentage} />
162
+ </S.ProgressBar>
148
163
  <S.DragTitle>Uploading...</S.DragTitle>
149
164
  </S.UploadingStatus>
150
165
  <S.SuccessStatus>
@@ -192,7 +207,7 @@ interface IDispatchProps {
192
207
  getSiteImages(params: IGetSiteImages): Promise<void>;
193
208
  selectImage(item: IImage): void;
194
209
  uploadError: (error: boolean, msg?: string) => Promise<void>;
195
- uploadImage: (imageFile: File, site: number | string) => Promise<IImage>;
210
+ uploadImage: (imageFiles: File | File[], site: number | string) => Promise<IImage>;
196
211
  }
197
212
 
198
213
  const mapDispatchToProps = {
@@ -18,6 +18,11 @@ export const StatusWrapper = styled.div`
18
18
  left: 50%;
19
19
  transform: translate(-50%, -50%);
20
20
  text-align: center;
21
+ width: calc(100% - ${(p) => p.theme.spacing.m} * 4);
22
+ `;
23
+
24
+ export const ProgressBar = styled.div`
25
+ margin-bottom: ${(p) => p.theme.spacing.xs};
21
26
  `;
22
27
 
23
28
  export const DragStatus = styled.div`
@@ -24,7 +24,8 @@ const NotificationWrapper = styled.div`
24
24
  flex-direction: column;
25
25
  justify-content: center;
26
26
  align-items: center;
27
- padding: ${(p) => `0 ${p.theme.spacing.m}`};
27
+ padding: ${(p) => p.theme.spacing.s};
28
+ ${(p) => p.theme.spacing.m};
28
29
  color: ${(p) => p.theme.color.textHighEmphasisInverse};
29
30
  ${(p) => p.theme.textStyle.uiL};
30
31
  `;
@@ -33,7 +34,6 @@ const Row = styled.div`
33
34
  display: flex;
34
35
  align-items: center;
35
36
  width: 100%;
36
- min-height: ${(p) => p.theme.spacing.l};
37
37
  z-index: 2;
38
38
 
39
39
  svg {
@@ -4,7 +4,7 @@ const Tooltip = styled.div`
4
4
  position: relative;
5
5
  `;
6
6
 
7
- const Tip = styled.div<{
7
+ const Tip = styled.span<{
8
8
  active: boolean;
9
9
  childrenWidth: number;
10
10
  bottom?: boolean;
@@ -72,7 +72,9 @@ function setToken(token: string): ISetTokenAction {
72
72
  }
73
73
 
74
74
  function logout(): ILogoutAction {
75
+ const listConfig = localStorage.getItem("sitesConfig") || "";
75
76
  localStorage.clear();
77
+ localStorage.setItem("sitesConfig", listConfig);
76
78
  return { type: LOGOUT, payload: { token: "" } };
77
79
  }
78
80
 
@@ -94,21 +94,30 @@ function selectImage(item: IImage): (dispatch: Dispatch, getState: () => IRootSt
94
94
  };
95
95
  }
96
96
 
97
- function uploadImage(imageFile: File, site: number | string): (dispatch: Dispatch) => Promise<IImage> {
97
+ function uploadImage(imageFiles: File | File[], site: number | string): (dispatch: Dispatch) => Promise<IImage> {
98
98
  return async (dispatch) => {
99
99
  try {
100
100
  dispatch(setIsUploading(true));
101
- const imageSize = imageFile.size / (1024 * 1024);
102
- const image = imageSize >= maxSize ? await compressImage(imageFile, 9999, 9999, maxSize, false) : imageFile;
103
- const form = new FormData();
104
- form.append("file", image);
105
- site && form.append("site", JSON.stringify(site));
106
- const result = await images.createImage(form);
107
- if (isReqOk(result.status)) {
101
+
102
+ const imageFilesArr = Array.isArray(imageFiles) ? imageFiles : [imageFiles];
103
+ const uploadPromises = imageFilesArr.map(async (imageFile: File) => {
104
+ const imageSize = imageFile.size / (1024 * 1024);
105
+ const image = imageSize >= maxSize ? await compressImage(imageFile, 9999, 9999, maxSize, false) : imageFile;
106
+ const form = new FormData();
107
+ form.append("file", image);
108
+ site && form.append("site", JSON.stringify(site));
109
+ const createdImage = await images.createImage(form);
110
+ return { ...createdImage, image };
111
+ });
112
+ const results = await Promise.all(uploadPromises);
113
+ const lastUploadedImage = results.reduce((lastResult, result) =>
114
+ result.data.id > lastResult.data.id ? result : lastResult
115
+ );
116
+
117
+ if (isReqOk(lastUploadedImage?.status)) {
108
118
  dispatch(setIsUploading(false));
109
119
  dispatch(setUploadSuccess(true));
110
- // dispatch(setInDropZone(false));
111
- return { ...result.data, file: image };
120
+ return { ...lastUploadedImage.data, file: lastUploadedImage.image };
112
121
  } else {
113
122
  dispatch(setUploadError(true, "Error uploading image"));
114
123
  }
@@ -33,6 +33,7 @@ import {
33
33
  } from "@ax/forms";
34
34
  import { appActions } from "@ax/containers/App";
35
35
  import { navigationActions } from "@ax/containers/Navigation";
36
+ import { structuredDataActions } from "@ax/containers/StructuredData";
36
37
  import { setCurrentSiteErrorPages } from "@ax/containers/Sites/actions";
37
38
  import { pages, sites, structuredData } from "@ax/api";
38
39
  import { getDefaultPageNavigation, getPageData, getPageNavigation, getStateValues } from "./utils";
@@ -421,7 +422,7 @@ function savePage(
421
422
  const pageID = saveResponse.data.id;
422
423
  const updatedPage = await pages.getPageInfo(pageID);
423
424
  const mappedData = parseData(updatedPage.data, true);
424
- const { pageContent } = generateEditorIDs({ editorContent: mappedData, header, footer });
425
+ const { pageContent } = generateEditorIDs({ ...mappedData, header, footer });
425
426
 
426
427
  const isGlobalPage = saveResponse.data.component === "GlobalPage";
427
428
  !isGlobalPage && (await getPageLanguages(pageID, currentSiteInfo.id, saveResponse.data.entity)(dispatch));
@@ -574,7 +575,7 @@ function updatePageStatus(
574
575
  const currentPageID = ids[0];
575
576
  const updatedContent = await pages.getPageInfo(currentPageID);
576
577
  const mappedData = parseData(updatedContent.data, true);
577
- const { pageContent } = generateEditorIDs({ editorContent: mappedData, header, footer });
578
+ const { pageContent } = generateEditorIDs({ ...mappedData, header, footer });
578
579
  dispatch(setEditorContent(pageContent));
579
580
  dispatch(setCurrentPageStatus(status));
580
581
  }
@@ -937,20 +938,22 @@ function generatePageContent(editorContent: IPage, dispatch: Dispatch, getState:
937
938
  dataPacks: { configFormData },
938
939
  } = getState();
939
940
 
940
- const { header: headerID, footer: footerID, isGlobal } = editorContent;
941
+ const { header, footer, isGlobal } = editorContent;
941
942
  const { defaultHeader, defaultFooter } = (configFormData.templates && configFormData.templates[template]) || {};
942
943
 
943
- const header = headerID === null ? defaultHeader : headerID;
944
- const footer = footerID === null ? defaultFooter : footerID;
944
+ const headerID =
945
+ header === null || header === undefined ? defaultHeader : typeof header === "object" ? header.id : header;
946
+ const footerID =
947
+ footer === null || footer === undefined ? defaultFooter : typeof footer === "object" ? footer.id : footer;
945
948
 
946
949
  const { header: pageHeader, footer: pageFooter } = getPageNavigation(
947
- header,
948
- footer,
950
+ headerID,
951
+ footerID,
949
952
  currentDefaultsContent,
950
953
  isGlobal
951
954
  );
952
955
 
953
- const { pageContent } = generateEditorIDs({ editorContent, header: pageHeader, footer: pageFooter });
956
+ const { pageContent } = generateEditorIDs({ ...editorContent, header: pageHeader, footer: pageFooter });
954
957
  const { element: selectedContent, parent: selectedParent } = findByEditorID({ pageContent }, selectedEditorID);
955
958
  const { component } = selectedContent;
956
959
  const schema = getSchema(component);
@@ -984,7 +987,7 @@ function updateEditorContent(
984
987
 
985
988
  const isNavigation = ["header", "footer"].includes(key);
986
989
  if (isNavigation || (value && typeof value === "object")) {
987
- generatePageContent(updatedEditorContent.editorContent, dispatch, getState);
990
+ generatePageContent(updatedEditorContent, dispatch, getState);
988
991
  }
989
992
  };
990
993
  }
@@ -1109,7 +1112,7 @@ function moveElement(
1109
1112
  content,
1110
1113
  selectedContent,
1111
1114
  newIndex,
1112
- page: editorContent.editorContent,
1115
+ page: editorContent,
1113
1116
  key,
1114
1117
  });
1115
1118
 
@@ -1224,13 +1227,14 @@ function getGlobalFromLocalPage(): (dispatch: Dispatch, getState: any) => Promis
1224
1227
  dispatch(setIsLoading(true));
1225
1228
 
1226
1229
  const {
1227
- pageEditor: { editorContent: content, currentPageID },
1230
+ pageEditor: { editorContent, currentPageID },
1228
1231
  } = getState();
1229
1232
 
1230
- const { originalGlobalPage } = content.editorContent;
1233
+ const { originalGlobalPage, structuredData } = editorContent;
1231
1234
 
1232
1235
  dispatch(setSitePageID(currentPageID));
1233
1236
  dispatch(setCurrentPageID(originalGlobalPage));
1237
+ structuredDataActions.setSelectedStructuredData(structuredData, "global")(dispatch, getState);
1234
1238
  } catch (e) {
1235
1239
  console.log(e);
1236
1240
  }
@@ -1291,11 +1295,7 @@ function removeNavigationFromPage(key: string): (dispatch: Dispatch, getState: a
1291
1295
  pageEditor: { editorContent },
1292
1296
  } = getState();
1293
1297
 
1294
- const updatedEditorContent = {
1295
- ...editorContent,
1296
- editorContent: { ...editorContent.editorContent, [key]: 0 },
1297
- [key]: null,
1298
- };
1298
+ const updatedEditorContent = { ...editorContent, [key]: 0 };
1299
1299
 
1300
1300
  setSelectedContent(0)(dispatch, getState);
1301
1301
  dispatch(setEditorContent(updatedEditorContent));
@@ -1316,13 +1316,10 @@ function restorePageNavigation(key: string): (dispatch: Dispatch, getState: any)
1316
1316
  const pageHeader = key === "header" ? navigation : header;
1317
1317
  const pageFooter = key === "footer" ? navigation : footer;
1318
1318
 
1319
- const updatedEditorContent = {
1320
- ...editorContent,
1321
- editorContent: { ...editorContent.editorContent, [key]: navigation.id },
1322
- };
1319
+ const updatedEditorContent = { ...editorContent, [key]: navigation };
1323
1320
 
1324
1321
  const { pageContent } = generateEditorIDs({
1325
- editorContent: updatedEditorContent.editorContent,
1322
+ ...updatedEditorContent,
1326
1323
  header: pageHeader,
1327
1324
  footer: pageFooter,
1328
1325
  });
@@ -8,7 +8,7 @@ const getPageParams = (getState: any): ISavePageParams => {
8
8
  } = getState();
9
9
  return {
10
10
  site: currentSiteInfo,
11
- page: editorContent.editorContent,
11
+ page: editorContent,
12
12
  };
13
13
  };
14
14
 
@@ -38,9 +38,9 @@ const getTemplateValues = (template: any) => {
38
38
 
39
39
  const getStateValues = (getState: any) => {
40
40
  const {
41
- pageEditor: { editorContent: pageContent, selectedEditorID, selectedContent, template, errors },
41
+ pageEditor: { editorContent, selectedEditorID, selectedContent, template, errors },
42
42
  } = getState();
43
- const { editorContent, header, footer } = pageContent;
43
+ const { header, footer } = editorContent;
44
44
 
45
45
  const editorID = selectedEditorID;
46
46
  const sections = getTemplateValues(editorContent.template);
@@ -72,14 +72,14 @@ const getPageNavigation = (
72
72
 
73
73
  const header =
74
74
  headerID === 0
75
- ? null
75
+ ? headerID
76
76
  : headerID === undefined || headerID === null
77
77
  ? headers.find((content: any) => content.setAsDefault)
78
78
  : headers.find((content: any) => content.id === headerID);
79
79
 
80
80
  const footer =
81
81
  footerID === 0
82
- ? null
82
+ ? headerID
83
83
  : footerID === undefined || footerID === null
84
84
  ? footers.find((content: any) => content.setAsDefault)
85
85
  : footers.find((content: any) => content.id === footerID);
@@ -13,6 +13,7 @@ import {
13
13
  DEFAULT_PARAMS,
14
14
  SET_CURRENT_SITE_ERROR_PAGES,
15
15
  SET_CONTENT_FILTERS,
16
+ SET_CONFIG,
16
17
  } from "./constants";
17
18
 
18
19
  import {
@@ -28,9 +29,18 @@ import {
28
29
  ISetCurrentSiteErrorPages,
29
30
  ISetContentFilters,
30
31
  ISetSitesTotalItems,
32
+ ISetConfig,
31
33
  } from "./interfaces";
32
34
 
33
- import { ISite, IGetSitePagesParams, ISettingsForm, IGetGlobalPagesParams, IPage, IGetSitesParams } from "@ax/types";
35
+ import {
36
+ ISite,
37
+ IGetSitePagesParams,
38
+ ISettingsForm,
39
+ IGetGlobalPagesParams,
40
+ IPage,
41
+ IGetSitesParams,
42
+ ISiteListConfig,
43
+ } from "@ax/types";
34
44
  import { sites, languages, dataPack, social, structuredData, analytics, pages } from "@ax/api";
35
45
  import { appActions } from "@ax/containers/App";
36
46
  import { structuredDataActions } from "@ax/containers/StructuredData";
@@ -96,10 +106,12 @@ function setContentFilters(contentFilters: Record<string, string> | null): ISetC
96
106
  return { type: SET_CONTENT_FILTERS, payload: { contentFilters } };
97
107
  }
98
108
 
109
+ function setConfig(config: ISiteListConfig): ISetConfig {
110
+ return { type: SET_CONFIG, payload: { config } };
111
+ }
112
+
99
113
  // TODO: hay que controlar que cuando da error la API borrar los sites ya guardados y sacar el error (ver los siguientes FIXME)
100
- function getSites(
101
- params: IGetSitesParams = { recentSitesNumber: 7 }
102
- ): (dispatch: Dispatch) => Promise<void> {
114
+ function getSites(params: IGetSitesParams = { recentSitesNumber: 7 }): (dispatch: Dispatch) => Promise<void> {
103
115
  return async (dispatch) => {
104
116
  try {
105
117
  const responseActions = {
@@ -595,8 +607,10 @@ function deleteAndRemoveFromSiteBulk(
595
607
  responseErrorPages = {
596
608
  ...responseErrorPages,
597
609
  data: {
598
- code: responseErrorPages.data.code || response.data.code,
599
- message: [...responseErrorPages.data.message, ...response.data.message],
610
+ code: responseErrorPages.data?.code || response.data?.code,
611
+ message: response.data
612
+ ? [...responseErrorPages.data.message, ...response.data.message]
613
+ : responseErrorPages.data?.message,
600
614
  },
601
615
  };
602
616
 
@@ -604,8 +618,9 @@ function deleteAndRemoveFromSiteBulk(
604
618
  },
605
619
  };
606
620
 
607
- const callbackPages = async () => pages.bulkDelete(pageIds);
608
- const callbackGlobalPages = async () => sites.removePageBulk(currentSiteInfo.id, globalPageIds);
621
+ const callbackPages = async () => pageIds.length > 0 && pages.bulkDelete(pageIds);
622
+ const callbackGlobalPages = async () =>
623
+ globalPageIds.length > 0 && sites.removePageBulk(currentSiteInfo.id, globalPageIds);
609
624
 
610
625
  const resultPages = await handleRequest(callbackPages, responsePageActions, [])(dispatch);
611
626
  const resultGlobalPages = await handleRequest(callbackGlobalPages, responseGlobalPageActions, [])(dispatch);
@@ -628,6 +643,17 @@ function resetCurrentSiteErrorPages(): (dispatch: Dispatch) => Promise<void> {
628
643
  };
629
644
  }
630
645
 
646
+ function setListConfig(config: ISiteListConfig): (dispatch: Dispatch) => Promise<void> {
647
+ return async (dispatch) => {
648
+ try {
649
+ localStorage.setItem("sitesConfig", JSON.stringify(config));
650
+ dispatch(setConfig(config));
651
+ } catch (e) {
652
+ console.log(e);
653
+ }
654
+ };
655
+ }
656
+
631
657
  export {
632
658
  setCurrentSiteInfo,
633
659
  setCurrentSitePages,
@@ -656,4 +682,5 @@ export {
656
682
  resetCurrentSiteErrorPages,
657
683
  setContentFilters,
658
684
  deleteAndRemoveFromSiteBulk,
685
+ setListConfig,
659
686
  };