@griddo/ax 10.3.9 → 10.3.11

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 (29) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Gallery/GalleryPanel/GalleryDragAndDrop/GalleryDragAndDrop.test.tsx +2 -1
  3. package/src/api/files.tsx +10 -5
  4. package/src/api/images.tsx +3 -3
  5. package/src/api/utils.tsx +30 -1
  6. package/src/components/DragAndDrop/index.tsx +5 -0
  7. package/src/components/Fields/UrlField/index.tsx +10 -2
  8. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +15 -10
  9. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/style.tsx +11 -10
  10. package/src/containers/FileDrive/actions.tsx +20 -7
  11. package/src/containers/Gallery/actions.tsx +6 -2
  12. package/src/containers/Sites/actions.tsx +30 -4
  13. package/src/containers/Sites/reducer.tsx +1 -1
  14. package/src/modules/App/Routing/NavMenu/index.tsx +1 -1
  15. package/src/modules/Content/index.tsx +30 -3
  16. package/src/modules/FileDrive/FileDragAndDrop/index.tsx +56 -21
  17. package/src/modules/FileDrive/FileDragAndDrop/style.tsx +69 -27
  18. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/Item/index.tsx +31 -0
  19. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/Item/style.tsx +43 -0
  20. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/ItemGroup/index.tsx +42 -0
  21. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/ItemGroup/style.tsx +34 -0
  22. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/index.tsx +138 -0
  23. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/style.tsx +21 -0
  24. package/src/modules/FileDrive/FileModal/DetailPanel/index.tsx +86 -68
  25. package/src/modules/FileDrive/FileModal/DetailPanel/style.tsx +1 -1
  26. package/src/modules/FileDrive/UploadItem/index.tsx +32 -0
  27. package/src/modules/FileDrive/UploadItem/style.tsx +40 -0
  28. package/src/modules/FileDrive/index.tsx +71 -30
  29. package/src/types/index.tsx +18 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "10.3.9",
4
+ "version": "10.3.11",
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": "cb7e232a3897ad08edf010dd96de7b99ef5c03ad"
233
+ "gitHead": "919cce1a8832b6839f0360db701dfbb1e69148ce"
234
234
  }
@@ -246,7 +246,8 @@ describe("GalleryDragAndDrop component actions", () => {
246
246
  clearData: clearDataMock,
247
247
  },
248
248
  });
249
+
249
250
  expect(clearDataMock).toBeCalled();
250
- await waitFor(() => expect(refreshImagesMock).toBeCalled());
251
+ await waitFor(() => expect(refreshImagesMock).toHaveBeenCalled(), { timeout: 3100 });
251
252
  });
252
253
  });
package/src/api/files.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import { IGetFolderParams } from "@ax/types";
2
2
  import { encodeData } from "@ax/helpers";
3
3
  import { template } from "./config";
4
- import { IServiceConfig, sendRequest } from "./utils";
4
+ import { IServiceConfig, sendRequest, sendUploadRequest } from "./utils";
5
5
 
6
6
  const SERVICES: { [key: string]: IServiceConfig } = {
7
7
  UPLOAD_FILE: {
@@ -72,8 +72,8 @@ const SERVICES: { [key: string]: IServiceConfig } = {
72
72
  },
73
73
  };
74
74
 
75
- const uploadFile = async (data: FormData) => {
76
- return sendRequest(SERVICES.UPLOAD_FILE, data as any);
75
+ const uploadFile = async (data: FormData, setProgress?: (progress: number) => void) => {
76
+ return sendUploadRequest(SERVICES.UPLOAD_FILE, data, setProgress);
77
77
  };
78
78
 
79
79
  const getFolderContent = async (params: IGetFolderParams) => {
@@ -162,7 +162,12 @@ const moveFilesBulk = async (ids: number[], folderID: number) => {
162
162
  return sendRequest(SERVICES.MOVE_FILES_BULK, { ids });
163
163
  };
164
164
 
165
- const replaceFile = async (data: FormData, fileID: number, keepUrl: boolean) => {
165
+ const replaceFile = async (
166
+ data: FormData,
167
+ fileID: number,
168
+ keepUrl: boolean,
169
+ setProgress?: (progress: number) => void
170
+ ) => {
166
171
  const {
167
172
  host,
168
173
  endpoint: [prefix, suffix],
@@ -172,7 +177,7 @@ const replaceFile = async (data: FormData, fileID: number, keepUrl: boolean) =>
172
177
 
173
178
  SERVICES.REPLACE_FILE.dynamicUrl = `${host}${prefix}${fileID}${suffix}${query}`;
174
179
 
175
- return sendRequest(SERVICES.REPLACE_FILE, data as any);
180
+ return sendUploadRequest(SERVICES.REPLACE_FILE, data, setProgress);
176
181
  };
177
182
 
178
183
  const downloadFiles = async (fileID: number | number[], zip: boolean) => {
@@ -1,5 +1,5 @@
1
1
  import { template } from "./config";
2
- import { IServiceConfig, sendRequest } from "./utils";
2
+ import { IServiceConfig, sendRequest, sendUploadRequest } from "./utils";
3
3
 
4
4
  const SERVICES: { [key: string]: IServiceConfig } = {
5
5
  CREATE_IMAGE: {
@@ -24,8 +24,8 @@ const SERVICES: { [key: string]: IServiceConfig } = {
24
24
  },
25
25
  };
26
26
 
27
- const createImage = async (data: any) => {
28
- return sendRequest(SERVICES.CREATE_IMAGE, data);
27
+ const createImage = async (data: any, setProgress?: (progress: number) => void) => {
28
+ return sendUploadRequest(SERVICES.CREATE_IMAGE, data, setProgress);
29
29
  };
30
30
 
31
31
  const getImageInfo = async (imageID: number) => {
package/src/api/utils.tsx CHANGED
@@ -9,6 +9,7 @@ export interface IServiceConfig {
9
9
  hasToken: boolean;
10
10
  dynamicUrl?: string;
11
11
  responseType?: ResponseType;
12
+ onUploadProgress?: any;
12
13
  }
13
14
 
14
15
  const getToken = (): Record<string, unknown> | null => {
@@ -113,7 +114,7 @@ export const sendInitialRequest = async (
113
114
 
114
115
  export const sendRequest = async (
115
116
  serviceConfig: IServiceConfig,
116
- data?: Record<string, unknown> | null,
117
+ data?: Record<string, unknown> | null | FormData,
117
118
  dataHeader?: Record<string, unknown>
118
119
  ): Promise<AxiosResponse> => {
119
120
  let config = wrapConfig(serviceConfig);
@@ -148,6 +149,34 @@ export const sendRequest = async (
148
149
  }
149
150
  };
150
151
 
152
+ export const sendUploadRequest = async (
153
+ serviceConfig: IServiceConfig,
154
+ data: FormData,
155
+ setProgress?: (progress: number) => void
156
+ ): Promise<AxiosResponse> => {
157
+ try {
158
+ const config = wrapConfig(serviceConfig);
159
+ let requestConfig = {
160
+ ...config,
161
+ data,
162
+ };
163
+
164
+ if (setProgress) {
165
+ requestConfig = {
166
+ ...requestConfig,
167
+ onUploadProgress: (progressEvent: any) => {
168
+ const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
169
+ setProgress(percentCompleted);
170
+ },
171
+ };
172
+ }
173
+
174
+ return await axios(requestConfig);
175
+ } catch (e) {
176
+ return e.response;
177
+ }
178
+ };
179
+
151
180
  function defaultErrorHandler(errorType: number) {
152
181
  // FIXME create DEFAULT ERROR
153
182
  return { type: SET_ERROR, payload: { errorType, errorText: "This is a generic error" } };
@@ -4,6 +4,10 @@ import * as S from "./style";
4
4
  const DragAndDrop = (props: any) => {
5
5
  const { onDrop, onDragOver, onDragEnter, onDragLeave, children }: IDragAndDropProps = props;
6
6
 
7
+ const _handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {
8
+ e.dataTransfer.clearData();
9
+ };
10
+
7
11
  const _handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {
8
12
  e.preventDefault();
9
13
  e.stopPropagation();
@@ -35,6 +39,7 @@ const DragAndDrop = (props: any) => {
35
39
  onDragOver={_handleDragOver}
36
40
  onDragEnter={_handleDragEnter}
37
41
  onDragLeave={_handleDragLeave}
42
+ onDragStart={_handleDragStart}
38
43
  >
39
44
  {children}
40
45
  </S.DragDropWrapper>
@@ -140,12 +140,20 @@ const UrlField = (props: IUrlFieldProps): JSX.Element => {
140
140
  );
141
141
  }
142
142
 
143
+ const titleValue = value && value.title ? value.title : internalPageName ? internalPageName : "";
144
+ const noFollowValue =
145
+ value && value.noFollow !== undefined
146
+ ? value.noFollow
147
+ : pageData && pageData.follow !== undefined
148
+ ? !pageData.follow
149
+ : false;
150
+
143
151
  const advancedFields = [
144
152
  {
145
153
  type: "TextField" as Field,
146
154
  name: "title",
147
155
  title: "Title",
148
- value: value && value.title ? value.title : internalPageName ? internalPageName : "",
156
+ value: titleValue,
149
157
  onChange: handleTitleChange,
150
158
  },
151
159
  {
@@ -159,7 +167,7 @@ const UrlField = (props: IUrlFieldProps): JSX.Element => {
159
167
  type: "UniqueCheck" as Field,
160
168
  name: "noFollow",
161
169
  options: [{ title: "Add nofollow" }],
162
- value: value ? value.noFollow || !pageData?.follow : false,
170
+ value: noFollowValue,
163
171
  onChange: handleNoFollowChange,
164
172
  },
165
173
  ];
@@ -29,6 +29,7 @@ const GalleryDragAndDrop = (props: IProps) => {
29
29
  const [inDropZone, setInDropZone] = useState(false);
30
30
  const [dropDepth, setDropDepth] = useState(0);
31
31
  const [uploadingState, setUploadingState] = useState({ total: 0, ready: 0 });
32
+ const [progress, setProgress] = useState(0);
32
33
 
33
34
  const handleDragEnter = () => {
34
35
  setDropDepth((depth) => depth + 1);
@@ -54,7 +55,6 @@ const GalleryDragAndDrop = (props: IProps) => {
54
55
 
55
56
  const handleDrop = async (e: React.DragEvent<HTMLDivElement>) => {
56
57
  const files = Array.from(e.dataTransfer.files);
57
- e.dataTransfer.clearData();
58
58
  await uploadFiles(files);
59
59
  setDropDepth(0);
60
60
  };
@@ -72,17 +72,19 @@ const GalleryDragAndDrop = (props: IProps) => {
72
72
  }
73
73
 
74
74
  setUploadingState({ total: files.length, ready: 0 });
75
- let lastImage;
75
+ let lastImage: IImage | undefined;
76
76
  while (files.length) {
77
77
  const file = files.shift();
78
- lastImage = file && (await uploadImage(file, site));
78
+ lastImage = file && (await uploadImage(file, site, setProgress));
79
79
  setUploadingState((state) => ({ total: state.total, ready: state.ready + 1 }));
80
80
  }
81
81
 
82
82
  setInDropZone(false);
83
- await refreshImages();
84
- lastImage && selectImage(lastImage);
85
83
  setUploadingState({ total: 0, ready: 0 });
84
+ setTimeout(async () => {
85
+ await refreshImages();
86
+ lastImage && selectImage(lastImage);
87
+ }, 3000);
86
88
  } catch (error) {
87
89
  console.log(error);
88
90
  }
@@ -90,7 +92,6 @@ const GalleryDragAndDrop = (props: IProps) => {
90
92
 
91
93
  const uploading = isUploading || uploadingState.total > uploadingState.ready;
92
94
  const success = isSuccess && uploadingState.total === uploadingState.ready;
93
- const uploadPercentage = (uploadingState.ready * 100) / uploadingState.total;
94
95
 
95
96
  const handleTryAgain = () => {
96
97
  uploadError(false);
@@ -124,7 +125,7 @@ const GalleryDragAndDrop = (props: IProps) => {
124
125
  Select files
125
126
  </S.FilesButton>
126
127
  <S.DragSubtitle>Valid formats: {validFormats.join(", ")}</S.DragSubtitle>
127
- <S.DragSubtitle>Max. size: 10MB</S.DragSubtitle>
128
+ <S.DragSubtitle>Max. size: 50MB</S.DragSubtitle>
128
129
  </S.DragStatus>
129
130
  <S.DragOverStatus onDragEnter={handleDragEnter} onDragLeave={handleDragLeave}>
130
131
  <S.DragIcon>
@@ -132,7 +133,7 @@ const GalleryDragAndDrop = (props: IProps) => {
132
133
  </S.DragIcon>
133
134
  <S.DragTitle>Drop your file</S.DragTitle>
134
135
  <S.DragSubtitle>Valid formats: {validFormats.join(", ")}</S.DragSubtitle>
135
- <S.DragSubtitle>Max. size: 10MB</S.DragSubtitle>
136
+ <S.DragSubtitle>Max. size: 50MB</S.DragSubtitle>
136
137
  </S.DragOverStatus>
137
138
  </S.StatusWrapper>
138
139
  </DragAndDrop>
@@ -159,7 +160,7 @@ const GalleryDragAndDrop = (props: IProps) => {
159
160
  <Icon name="image" size="36" />
160
161
  </S.DragIcon>
161
162
  <S.ProgressBar>
162
- <ProgressBar percentage={uploadPercentage} />
163
+ <ProgressBar percentage={progress} />
163
164
  </S.ProgressBar>
164
165
  <S.DragTitle>Uploading...</S.DragTitle>
165
166
  </S.UploadingStatus>
@@ -207,7 +208,11 @@ const mapStateToProps = (state: IRootState) => ({
207
208
  export interface IDispatchProps {
208
209
  selectImage(item: IImage | null): void;
209
210
  uploadError: (error: boolean, msg?: string) => Promise<void>;
210
- uploadImage: (imageFiles: File | File[], site: number | string) => Promise<IImage>;
211
+ uploadImage: (
212
+ imageFiles: File | File[],
213
+ site: number | string,
214
+ setProgress?: (progress: number) => void
215
+ ) => Promise<IImage>;
211
216
  }
212
217
 
213
218
  const mapDispatchToProps = {
@@ -46,16 +46,6 @@ export const DragIcon = styled.div`
46
46
  margin-bottom: ${(p) => p.theme.spacing.s};
47
47
  `;
48
48
 
49
- export const DragOverStatus = styled.div`
50
- transition: opacity 0.1s;
51
- ${DragIcon} {
52
- svg {
53
- path {
54
- fill: #ffffff;
55
- }
56
- }
57
- }
58
- `;
59
49
 
60
50
  export const UploadingStatus = styled.div`
61
51
  transition: opacity 0.1s;
@@ -89,6 +79,17 @@ export const ErrorStatus = styled.div`
89
79
  }
90
80
  `;
91
81
 
82
+ export const DragOverStatus = styled.div`
83
+ transition: opacity 0.1s;
84
+ ${DragIcon} {
85
+ svg {
86
+ path {
87
+ fill: #ffffff;
88
+ }
89
+ }
90
+ }
91
+ `;
92
+
92
93
  export const DragAndDropWrapper = styled.div<{
93
94
  inDropZone: boolean;
94
95
  uploading: boolean;
@@ -198,7 +198,8 @@ function deleteFolder(folder: IFolder): (dispatch: Dispatch, getState: any) => P
198
198
  function uploadFile(
199
199
  docFiles: File | File[],
200
200
  folderID: number | null,
201
- siteID: number | "global"
201
+ siteID: number | "global",
202
+ setProgress?: (progress: number) => void
202
203
  ): (dispatch: Dispatch) => Promise<IFile | null> {
203
204
  return async (dispatch) => {
204
205
  try {
@@ -210,7 +211,7 @@ function uploadFile(
210
211
  form.append("file", file);
211
212
  form.append("site", JSON.stringify(siteID));
212
213
  folderID && form.append("folder", JSON.stringify(folderID));
213
- const uploadedFile = await files.uploadFile(form);
214
+ const uploadedFile = await files.uploadFile(form, setProgress);
214
215
  return { ...uploadedFile, file };
215
216
  });
216
217
  const results = await Promise.all(uploadPromises);
@@ -337,7 +338,8 @@ function replaceFile(
337
338
  docFile: File,
338
339
  fileID: number,
339
340
  keepUrl: boolean,
340
- siteID: number | "global"
341
+ siteID: number | "global",
342
+ setProgress?: (progress: number) => void
341
343
  ): (dispatch: Dispatch, getState: any) => Promise<IFile | null> {
342
344
  return async (dispatch, getState) => {
343
345
  try {
@@ -350,7 +352,7 @@ function replaceFile(
350
352
  const form = new FormData();
351
353
  form.append("file", docFile);
352
354
 
353
- const result = await files.replaceFile(form, fileID, keepUrl);
355
+ const result = await files.replaceFile(form, fileID, keepUrl, setProgress);
354
356
  if (isReqOk(result.status)) {
355
357
  dispatch(setIsUploading(false));
356
358
  dispatch(setUploadSuccess(true));
@@ -367,15 +369,19 @@ function replaceFile(
367
369
  };
368
370
  }
369
371
 
370
- function downloadFiles(fileID: number | number[], zip: boolean, fileName?: string): (dispatch: Dispatch) => Promise<void> {
372
+ function downloadFiles(
373
+ fileID: number | number[],
374
+ zip: boolean,
375
+ fileName?: string
376
+ ): (dispatch: Dispatch) => Promise<void> {
371
377
  return async (dispatch) => {
372
378
  try {
373
379
  const responseActions = {
374
380
  handleSuccess: (response: any) => {
375
381
  const url = window.URL.createObjectURL(new Blob([response]));
376
- const a = document.createElement('a');
382
+ const a = document.createElement("a");
377
383
  a.href = url;
378
- a.download = fileName ? fileName : "download.zip"
384
+ a.download = fileName ? fileName : "download.zip";
379
385
  document.body.appendChild(a);
380
386
  a.click();
381
387
  window.URL.revokeObjectURL(url);
@@ -392,6 +398,12 @@ function downloadFiles(fileID: number | number[], zip: boolean, fileName?: strin
392
398
  };
393
399
  }
394
400
 
401
+ function resetError(): (dispatch: Dispatch) => Promise<void> {
402
+ return async (dispatch) => {
403
+ dispatch(setUploadError(false, ""));
404
+ };
405
+ }
406
+
395
407
  export {
396
408
  getFolderContent,
397
409
  updateCurrentFolder,
@@ -409,4 +421,5 @@ export {
409
421
  updateTab,
410
422
  replaceFile,
411
423
  downloadFiles,
424
+ resetError,
412
425
  };
@@ -79,7 +79,11 @@ function getSiteImages(props: IGetSiteImages): (dispatch: Dispatch, getState: ()
79
79
  };
80
80
  }
81
81
 
82
- function uploadImage(imageFiles: File | File[], site: number | string): (dispatch: Dispatch) => Promise<IImage> {
82
+ function uploadImage(
83
+ imageFiles: File | File[],
84
+ site: number | string,
85
+ setProgress?: (progress: number) => void
86
+ ): (dispatch: Dispatch) => Promise<IImage> {
83
87
  return async (dispatch) => {
84
88
  try {
85
89
  dispatch(setIsUploading(true));
@@ -91,7 +95,7 @@ function uploadImage(imageFiles: File | File[], site: number | string): (dispatc
91
95
  const form = new FormData();
92
96
  form.append("file", image);
93
97
  site && form.append("site", JSON.stringify(site));
94
- const createdImage = await images.createImage(form);
98
+ const createdImage = await images.createImage(form, setProgress);
95
99
  return { ...createdImage, image };
96
100
  });
97
101
  const results = await Promise.all(uploadPromises);
@@ -49,13 +49,15 @@ import { resetPageEditor } from "@ax/containers/PageEditor/actions";
49
49
  import { analyticsActions } from "@ax/containers/Analytics";
50
50
  import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
51
51
  import { socialActions } from "@ax/containers/Settings/Social";
52
+ import { integrationsActions } from "@ax/containers/Integrations";
52
53
  import { getDefaultTheme, handleRequest, isReqOk, sortBy } from "@ax/helpers";
53
54
  import { usersActions } from "@ax/containers/Users";
54
55
 
55
56
  const { setIsLoading, setIsSaving, setLanguage } = appActions;
56
- const { resetDefaultsValues } = navigationActions;
57
+ const { resetDefaultsValues, getDefaults } = navigationActions;
57
58
  const { resetMenuValues } = menuActions;
58
59
  const { getAnalytics } = analyticsActions;
60
+ const { getIntegrations } = integrationsActions;
59
61
  const { getUsers, getUserCurrentPermissions, getRoles } = usersActions;
60
62
 
61
63
  function setSites(sitesList: ISite[]): ISetSitesAction {
@@ -126,7 +128,28 @@ function getSites(params: IGetSitesParams = { recentSitesNumber: 7 }): (dispatch
126
128
 
127
129
  await handleRequest(callback, responseActions, [])(dispatch);
128
130
  } catch (e) {
129
- console.log(e); // TODO: capturar errores mejor
131
+ console.log(e);
132
+ }
133
+ };
134
+ }
135
+
136
+ function getSite(siteID: number): (dispatch: Dispatch, getState: any) => Promise<void> {
137
+ return async (dispatch, getState) => {
138
+ try {
139
+ const responseActions = {
140
+ handleSuccess: async (data: ISite) => {
141
+ await setSiteInfo(data)(dispatch, getState);
142
+ await getDefaults()(dispatch, getState);
143
+ await getIntegrations(data.id)(dispatch);
144
+ dispatch(setCurrentSiteInfo(data));
145
+ },
146
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
147
+ };
148
+ const callback = async () => sites.getSiteInfo(siteID);
149
+
150
+ await handleRequest(callback, responseActions, [])(dispatch);
151
+ } catch (e) {
152
+ console.log(e);
130
153
  }
131
154
  };
132
155
  }
@@ -621,12 +644,14 @@ function deleteAndRemoveFromSiteBulk(
621
644
  },
622
645
  };
623
646
 
624
- const callbackPages = async () => pages.bulkDelete(pageIds);
647
+ const pageNoGlobalIds = pageIds.filter((elemento) => !globalPageIds.includes(elemento));
648
+
649
+ const callbackPages = async () => pages.bulkDelete(pageNoGlobalIds);
625
650
  const callbackGlobalPages = async () => sites.removePageBulk(currentSiteInfo.id, globalPageIds);
626
651
 
627
652
  let errors = 0;
628
653
 
629
- if (pageIds.length > 0) {
654
+ if (pageNoGlobalIds.length > 0) {
630
655
  const result = await handleRequest(callbackPages, responsePageActions, [])(dispatch);
631
656
  if (!result) {
632
657
  errors = errors + 1;
@@ -698,4 +723,5 @@ export {
698
723
  setContentFilters,
699
724
  deleteAndRemoveFromSiteBulk,
700
725
  setListConfig,
726
+ getSite,
701
727
  };
@@ -66,7 +66,7 @@ export const initialState = {
66
66
  config,
67
67
  };
68
68
 
69
- export function reducer(state = initialState, action: SitesActionsCreators): ISitesState {
69
+ export function reducer(state = initialState, action: any): ISitesState {
70
70
  switch (action.type) {
71
71
  case SET_FILTER:
72
72
  case SET_SITES:
@@ -46,7 +46,7 @@ const NavMenu = (props: IProps) => {
46
46
  const goToPublishedSite = () => {
47
47
  const language = siteLanguages.find((l) => l.id === lang.id);
48
48
  if (language && language.home) {
49
- window.open(language.home, "_blank");
49
+ window.open(`${language.home}/`, "_blank");
50
50
  }
51
51
  };
52
52
 
@@ -19,6 +19,7 @@ import {
19
19
  IErrorItem,
20
20
  IGetSitesParams,
21
21
  ISiteRoles,
22
+ IPageLanguage,
22
23
  } from "@ax/types";
23
24
  import { MainWrapper, Modal, TableList, ErrorToast, Toast, EmptyState, Notification } from "@ax/components";
24
25
  import { isGlobalStructuredData, isStructuredDataFromPage } from "@ax/helpers";
@@ -406,7 +407,21 @@ const Content = (props: IProps): JSX.Element => {
406
407
  .filter((page: IPage) => pageIds.includes(page.id) && page.origin !== "GLOBAL")
407
408
  .map((page: IPage) => page.id);
408
409
 
409
- const deleted = await deleteAndRemoveFromSiteBulk(filteredPageIds, globalPageIds);
410
+ const globalPageTranslatedIds = pagesSelected.flatMap((page: IPage) => {
411
+ return page.origin === "GLOBAL"
412
+ ? page.pageLanguages.filter((trans: any) => pageIds.includes(trans.pageId)).map((trans: any) => trans.pageId)
413
+ : [];
414
+ });
415
+
416
+ const filteredPageTranslatedIds = pagesSelected.flatMap((page: IPage) => {
417
+ return page.origin !== "GLOBAL"
418
+ ? page.pageLanguages.filter((trans: any) => pageIds.includes(trans.pageId)).map((trans: any) => trans.pageId)
419
+ : [];
420
+ });
421
+
422
+ const deleted = deleteAllVersions
423
+ ? await deleteAndRemoveFromSiteBulk(filteredPageTranslatedIds, globalPageTranslatedIds)
424
+ : await deleteAndRemoveFromSiteBulk(filteredPageIds, globalPageIds);
410
425
 
411
426
  if (deleted) {
412
427
  setDeletedItem(pageIds);
@@ -415,13 +430,25 @@ const Content = (props: IProps): JSX.Element => {
415
430
  };
416
431
 
417
432
  const bulkDelete = async () => {
433
+ let allPageVersions: number[] = [];
434
+ if (deleteAllVersions) {
435
+ const selectedPages = currentSitePages.filter((page) => selectedItems.all.includes(page.id));
436
+ const pageLanguages = selectedPages.map((element) => element.pageLanguages);
437
+ pageLanguages.forEach((element) => {
438
+ const ids = element.map((lang: IPageLanguage) => lang.pageId);
439
+ allPageVersions = [...allPageVersions, ...ids];
440
+ });
441
+ }
442
+
418
443
  isStructuredData
419
444
  ? await deleteDataContent(selectedItems.all).then((deleted: boolean) => {
420
445
  if (deleted) {
421
- setDeletedItem(selectedItems.all);
446
+ deleteAllVersions ? setDeletedItem(allPageVersions) : setDeletedItem(selectedItems.all);
422
447
  toggleToast();
423
448
  }
424
449
  })
450
+ : deleteAllVersions
451
+ ? await handleBulkDelete(allPageVersions)
425
452
  : await handleBulkDelete(selectedItems.all);
426
453
  toggleDeleteModal();
427
454
  const allPageItemsSelected = selectedItems.all.length >= currentSitePages.length;
@@ -891,7 +918,7 @@ interface IDispatchProps {
891
918
  getSitePages(params: IGetSitePagesParams, structuredData?: string | undefined, filterQuery?: string): Promise<void>;
892
919
  updatePageStatus(ids: number[], status: string, updatePageStatus?: boolean): Promise<boolean>;
893
920
  deletePage(params?: ISavePageParams): Promise<boolean>;
894
- setHistoryPush(page: string, isEditor: boolean): any;
921
+ setHistoryPush(page: string, isEditor: boolean): Promise<void>;
895
922
  setLanguage(lang: { locale: string; id: number | null }): void;
896
923
  createNewTranslation(isNewTranslation: boolean): void;
897
924
  getFilteredContent(filter: string | null): void;