@griddo/ax 11.15.7 → 11.15.8-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.atoms.test.tsx +409 -0
  3. package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.helpers.test.tsx +418 -0
  4. package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.test.tsx +776 -29
  5. package/src/__tests__/components/FieldsBehavior/FieldsBehavior.test.tsx +368 -11
  6. package/src/__tests__/modules/Users/UserList/UserList.test.tsx +6 -6
  7. package/src/components/Fields/IntegrationsField/IntegrationItem/atoms.tsx +14 -5
  8. package/src/components/Fields/IntegrationsField/IntegrationItem/index.tsx +1 -8
  9. package/src/components/Fields/UrlField/index.tsx +5 -4
  10. package/src/components/Fields/Wysiwyg/atoms.tsx +140 -0
  11. package/src/components/Fields/Wysiwyg/config.tsx +190 -9
  12. package/src/components/Fields/Wysiwyg/helpers.tsx +54 -1
  13. package/src/components/Fields/Wysiwyg/index.tsx +210 -61
  14. package/src/components/Fields/Wysiwyg/style.tsx +32 -1
  15. package/src/components/Fields/Wysiwyg/vendors.tsx +0 -1
  16. package/src/components/FieldsBehavior/index.tsx +66 -31
  17. package/src/components/Icon/components/Sync.js +16 -0
  18. package/src/components/Icon/svgs/Sync.svg +3 -0
  19. package/src/components/RestoreModal/index.tsx +1 -3
  20. package/src/components/ScheduleModal/index.tsx +3 -3
  21. package/src/components/TableList/index.tsx +5 -3
  22. package/src/containers/FileDrive/actions.tsx +5 -5
  23. package/src/containers/Forms/actions.tsx +40 -38
  24. package/src/containers/Gallery/actions.tsx +27 -27
  25. package/src/containers/Integrations/actions.tsx +2 -2
  26. package/src/containers/Navigation/Defaults/actions.tsx +1 -1
  27. package/src/containers/PageEditor/actions.tsx +3 -5
  28. package/src/containers/Redirects/actions.tsx +2 -2
  29. package/src/containers/Sites/actions.tsx +15 -8
  30. package/src/containers/StructuredData/actions.tsx +5 -5
  31. package/src/containers/Users/actions.tsx +2 -2
  32. package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +36 -43
  33. package/src/modules/Categories/CategoriesList/CategoryPanel/index.tsx +15 -11
  34. package/src/modules/Categories/CategoriesList/atoms.tsx +42 -12
  35. package/src/modules/Categories/CategoriesList/index.tsx +8 -30
  36. package/src/modules/Content/PageItem/index.tsx +6 -5
  37. package/src/modules/Content/atoms.tsx +7 -3
  38. package/src/modules/Content/index.tsx +8 -16
  39. package/src/modules/FileDrive/FileModal/DetailPanel/index.tsx +14 -14
  40. package/src/modules/FileDrive/FolderItem/index.tsx +46 -54
  41. package/src/modules/FileDrive/GridItem/index.tsx +32 -37
  42. package/src/modules/FileDrive/ListItem/index.tsx +31 -37
  43. package/src/modules/FileDrive/atoms.tsx +59 -12
  44. package/src/modules/FileDrive/index.tsx +88 -98
  45. package/src/modules/Forms/FormCategoriesList/CategoryItem/index.tsx +42 -34
  46. package/src/modules/Forms/FormCategoriesList/atoms.tsx +17 -6
  47. package/src/modules/Forms/FormCategoriesList/index.tsx +30 -34
  48. package/src/modules/Forms/FormEditor/index.tsx +14 -6
  49. package/src/modules/Forms/FormList/FormItem/index.tsx +5 -1
  50. package/src/modules/Forms/FormList/index.tsx +15 -9
  51. package/src/modules/Forms/atoms.tsx +7 -4
  52. package/src/modules/GlobalEditor/atoms.tsx +77 -0
  53. package/src/modules/GlobalEditor/index.tsx +24 -7
  54. package/src/modules/MediaGallery/FolderItem/index.tsx +36 -52
  55. package/src/modules/MediaGallery/GridItem/index.tsx +27 -38
  56. package/src/modules/MediaGallery/ImageModal/DetailPanel/index.tsx +13 -13
  57. package/src/modules/MediaGallery/ImageModal/index.tsx +2 -16
  58. package/src/modules/MediaGallery/ListItem/index.tsx +25 -37
  59. package/src/modules/MediaGallery/atoms.tsx +84 -15
  60. package/src/modules/MediaGallery/index.tsx +62 -122
  61. package/src/modules/Navigation/Defaults/Item/atoms.tsx +2 -4
  62. package/src/modules/Navigation/Defaults/Item/index.tsx +80 -94
  63. package/src/modules/Navigation/Defaults/atoms.tsx +179 -7
  64. package/src/modules/Navigation/Defaults/index.tsx +51 -18
  65. package/src/modules/Navigation/Defaults/style.tsx +10 -7
  66. package/src/modules/Navigation/Menus/List/Table/Item/atoms.tsx +33 -19
  67. package/src/modules/Navigation/Menus/List/Table/Item/index.tsx +18 -19
  68. package/src/modules/Navigation/Menus/List/Table/index.tsx +15 -13
  69. package/src/modules/Navigation/Menus/List/index.tsx +1 -1
  70. package/src/modules/PageEditor/atoms.tsx +14 -11
  71. package/src/modules/PageEditor/index.tsx +11 -16
  72. package/src/modules/Redirects/RedirectItem/index.tsx +37 -39
  73. package/src/modules/Redirects/atoms.tsx +58 -12
  74. package/src/modules/Redirects/index.tsx +30 -58
  75. package/src/modules/Settings/Integrations/IntegrationItem/CopyModal/index.tsx +1 -1
  76. package/src/modules/Settings/Integrations/IntegrationItem/index.tsx +57 -69
  77. package/src/modules/Settings/Integrations/atoms.tsx +72 -8
  78. package/src/modules/Settings/Integrations/index.tsx +34 -48
  79. package/src/modules/StructuredData/Form/index.tsx +25 -8
  80. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/atoms.tsx +26 -75
  81. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +15 -33
  82. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +63 -41
  83. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/style.tsx +13 -8
  84. package/src/modules/StructuredData/StructuredDataList/index.tsx +11 -16
  85. package/src/modules/StructuredData/{StructuredDataList/atoms.tsx → atoms.tsx} +25 -28
  86. package/src/modules/Users/UserList/UserItem/index.tsx +18 -35
  87. package/src/modules/Users/UserList/atoms.tsx +61 -0
  88. package/src/modules/Users/UserList/index.tsx +12 -32
@@ -13,7 +13,7 @@ import {
13
13
  } from "@ax/components";
14
14
  import { appActions } from "@ax/containers/App";
15
15
  import { redirectsActions } from "@ax/containers/Redirects";
16
- import { useBulkSelection, useModal, useToast } from "@ax/hooks";
16
+ import { useBulkSelection, useModals, useToast } from "@ax/hooks";
17
17
  import type { IEmptyStateProps, INavItem, IQueryValue, IRedirect, IRootState, ISite } from "@ax/types";
18
18
 
19
19
  import { DeleteModal, ImportCheckModal, ImportModal, OverwriteModal } from "./atoms";
@@ -40,24 +40,20 @@ const Redirects = (props: IProps): JSX.Element => {
40
40
  imports,
41
41
  totalImports,
42
42
  isLoading,
43
+ isSaving,
43
44
  } = props;
44
45
 
45
46
  const itemsPerPage = 50;
46
47
  const firstPage = 1;
47
48
  const [page, setPage] = useState(1);
48
49
  const [isScrolling, setIsScrolling] = useState(false);
49
- const [isBulkLoading, setIsBulkLoading] = useState(false);
50
50
  const [isOpenedSecond, setIsOpenedSecond] = useState(false);
51
- const { isOpen, toggleModal } = useModal();
52
- const { isOpen: isOpenDelete, toggleModal: toggleModalDelete } = useModal();
51
+ const { isOpen, toggleModal } = useModals(["edit", "delete", "overwrite", "import", "checkImport"] as const);
53
52
  const tableRef = useRef<HTMLDivElement>(null);
54
53
  const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
55
54
  const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery } = useFilterQuery(currentSite);
56
55
  const { isVisible, toggleToast, setIsVisible } = useToast();
57
56
  const { isVisible: isImportVisible, toggleToast: toggleImportToast, setIsVisible: setIsImportVisible } = useToast();
58
- const { isOpen: isOpenOverwrite, toggleModal: toggleOverwriteModal } = useModal();
59
- const { isOpen: isOpenImport, toggleModal: toggleImportModal } = useModal();
60
- const { isOpen: isOpenCheckImport, toggleModal: toggleCheckImportModal } = useModal();
61
57
  const [importData, setImportData] = useState<{ from: string; to: string }[]>([]);
62
58
  const [isUploading, setIsUploading] = useState(false);
63
59
  const [searchQuery, setSearchQuery] = useState<string>("");
@@ -129,13 +125,11 @@ const Redirects = (props: IProps): JSX.Element => {
129
125
  } = useBulkSelection(redIds);
130
126
 
131
127
  const bulkDelete = async () => {
132
- setIsBulkLoading(true);
133
128
  const deleted = await deleteRedirect(selectedItems.all);
134
129
  if (deleted) {
135
130
  toggleToast();
136
131
  }
137
- toggleModalDelete();
138
- setIsBulkLoading(false);
132
+ toggleModal("delete");
139
133
  };
140
134
 
141
135
  const unselectAllItems = () => resetBulkSelection();
@@ -165,7 +159,7 @@ const Redirects = (props: IProps): JSX.Element => {
165
159
  const TableHeader = (
166
160
  <BulkHeader
167
161
  showBulk={areItemsSelected(redIds)}
168
- bulkDelete={toggleModalDelete}
162
+ bulkDelete={() => toggleModal("delete")}
169
163
  selectAllItems={handleSelectAll}
170
164
  totalItems={totalItems}
171
165
  selectItems={selectItems}
@@ -178,7 +172,7 @@ const Redirects = (props: IProps): JSX.Element => {
178
172
  sortedListStatus={sortedListStatus}
179
173
  setHoverCheck={setHoverCheck}
180
174
  selectedItems={selectedItems}
181
- isLoading={isBulkLoading}
175
+ isLoading={isSaving}
182
176
  />
183
177
  );
184
178
 
@@ -193,7 +187,7 @@ const Redirects = (props: IProps): JSX.Element => {
193
187
 
194
188
  const rightLineButtonProps = {
195
189
  label: "Import Redirects",
196
- action: () => toggleImportModal(),
190
+ action: () => toggleModal("import"),
197
191
  };
198
192
 
199
193
  const handleMenuClick = (path: string) => {
@@ -203,18 +197,18 @@ const Redirects = (props: IProps): JSX.Element => {
203
197
  const handleModal = () => {
204
198
  setFormValues(initState);
205
199
  setIsOpenedSecond(false);
206
- toggleModal();
200
+ toggleModal("edit");
207
201
  };
208
202
 
209
203
  const handleAddRedirect = async (force?: boolean) => {
210
204
  const toPage = formValues.to.pageId ? formValues.to.pageId : formValues.to.url;
211
- await addRedirect({ from: formValues.from, to: toPage }, toggleOverwriteModal, force, filterQuery);
212
- isOpen && toggleModal();
205
+ await addRedirect({ from: formValues.from, to: toPage }, () => toggleModal("overwrite"), force, filterQuery);
206
+ isOpen("edit") && toggleModal("edit");
213
207
  };
214
208
 
215
209
  const addItemActionForce = () => {
216
210
  handleAddRedirect(true);
217
- toggleOverwriteModal();
211
+ toggleModal("overwrite");
218
212
  };
219
213
 
220
214
  const pagination = {
@@ -234,27 +228,12 @@ const Redirects = (props: IProps): JSX.Element => {
234
228
  message: `${(imports?.ok.length || 0) + (imports?.existing.length || 0)} Redirects imported`,
235
229
  };
236
230
 
237
- const mainDeleteModalAction = {
238
- title: isBulkLoading ? "Deleting" : "Delete",
239
- onClick: bulkDelete,
240
- disabled: isBulkLoading,
241
- };
242
-
243
- const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
244
-
245
- const mainOverwriteModalAction = {
246
- title: "Overwrite redirect",
247
- onClick: addItemActionForce,
248
- };
249
-
250
- const secondaryOverwriteModalAction = { title: "Cancel", onClick: toggleOverwriteModal };
251
-
252
231
  const handleCheckImportData = async (data: { from: string; to: string }[]) => {
253
232
  setImportData(data);
254
233
  await importRedirects(data, true);
255
- toggleImportModal();
234
+ toggleModal("import");
256
235
  setIsUploading(false);
257
- toggleCheckImportModal();
236
+ toggleModal("checkImport");
258
237
  };
259
238
 
260
239
  const handleImportData = async () => {
@@ -262,16 +241,9 @@ const Redirects = (props: IProps): JSX.Element => {
262
241
  if (imported) {
263
242
  toggleImportToast();
264
243
  }
265
- toggleCheckImportModal();
266
- };
267
-
268
- const mainImportModalAction = {
269
- title: "Import correct directs",
270
- onClick: handleImportData,
244
+ toggleModal("checkImport");
271
245
  };
272
246
 
273
- const secondaryImportModalAction = { title: "Cancel", onClick: toggleCheckImportModal };
274
-
275
247
  const searchFilters = [
276
248
  { value: "from", label: "Old URL" },
277
249
  { value: "to", label: "New URL" },
@@ -350,9 +322,9 @@ const Redirects = (props: IProps): JSX.Element => {
350
322
  </S.ContentWrapper>
351
323
  </S.Wrapper>
352
324
  <RedirectPanel
353
- isOpen={isOpen}
325
+ isOpen={isOpen("edit")}
354
326
  isOpenedSecond={isOpenedSecond}
355
- toggleModal={toggleModal}
327
+ toggleModal={() => toggleModal("edit")}
356
328
  toggleSecondaryPanel={toggleSecondaryPanel}
357
329
  formValues={formValues}
358
330
  setFormValues={setFormValues}
@@ -360,29 +332,27 @@ const Redirects = (props: IProps): JSX.Element => {
360
332
  currentFilter={filterQuery}
361
333
  />
362
334
  <DeleteModal
363
- isOpen={isOpenDelete}
364
- toggleModal={toggleModalDelete}
365
- secondaryModalAction={secondaryDeleteModalAction}
366
- mainModalAction={mainDeleteModalAction}
335
+ isOpen={isOpen("delete")}
336
+ toggleModal={() => toggleModal("delete")}
337
+ onDelete={bulkDelete}
338
+ isDeleting={isSaving}
367
339
  />
368
340
  <OverwriteModal
369
- isOpen={isOpenOverwrite}
370
- toggleModal={toggleOverwriteModal}
371
- secondaryModalAction={secondaryOverwriteModalAction}
372
- mainModalAction={mainOverwriteModalAction}
341
+ isOpen={isOpen("overwrite")}
342
+ toggleModal={() => toggleModal("overwrite")}
343
+ onOverwrite={addItemActionForce}
373
344
  />
374
345
  <ImportModal
375
- isOpen={isOpenImport}
376
- toggleModal={toggleImportModal}
346
+ isOpen={isOpen("import")}
347
+ toggleModal={() => toggleModal("import")}
377
348
  checkImportData={handleCheckImportData}
378
349
  isUploading={isUploading}
379
350
  setIsUploading={setIsUploading}
380
351
  />
381
352
  <ImportCheckModal
382
- isOpen={isOpenCheckImport}
383
- toggleModal={toggleCheckImportModal}
384
- mainModalAction={mainImportModalAction}
385
- secondaryModalAction={secondaryImportModalAction}
353
+ isOpen={isOpen("checkImport")}
354
+ toggleModal={() => toggleModal("checkImport")}
355
+ onImport={handleImportData}
386
356
  imports={imports}
387
357
  totalImports={totalImports}
388
358
  />
@@ -397,6 +367,7 @@ const mapStateToProps = (state: IRootState) => ({
397
367
  totalImports: state.redirects.totalImports,
398
368
  imports: state.redirects.imports,
399
369
  isLoading: state.app.isLoading,
370
+ isSaving: state.app.isSaving,
400
371
  });
401
372
 
402
373
  const mapDispatchToProps = {
@@ -414,6 +385,7 @@ interface IRedirectsProps {
414
385
  currentSite: ISite | null;
415
386
  totalImports: number;
416
387
  isLoading: boolean;
388
+ isSaving: boolean;
417
389
  imports: null | {
418
390
  error: IRedirect[];
419
391
  existing: IRedirect[];
@@ -1,4 +1,4 @@
1
- import React, { useState } from "react";
1
+ import { useState } from "react";
2
2
 
3
3
  import { FieldsBehavior, Modal } from "@ax/components";
4
4
 
@@ -1,16 +1,20 @@
1
+ import { useState } from "react";
1
2
  import { connect } from "react-redux";
2
3
  import { Link } from "react-router-dom";
3
- import type { UniqueIdentifier } from "@dnd-kit/core";
4
- import { useSortable } from "@dnd-kit/sortable";
5
4
 
6
- import { useModal, usePermission, useToast } from "@ax/hooks";
7
- import type { ICheck, IIntegration } from "@ax/types";
8
- import { CheckField, Icon, Modal, Toast, ToggleField, Tooltip } from "@ax/components";
9
5
  import { integrations } from "@ax/api";
10
- import { integrationsActions } from "@ax/containers/Integrations";
6
+ import { CheckField, Icon, Toast, ToggleField, Tooltip } from "@ax/components";
11
7
  import { appActions } from "@ax/containers/App";
8
+ import { integrationsActions } from "@ax/containers/Integrations";
9
+ import { useModals, usePermissions, useToast } from "@ax/hooks";
10
+ import type { ICheck, IIntegration, IRootState } from "@ax/types";
11
+
12
+ import type { UniqueIdentifier } from "@dnd-kit/core";
13
+ import { useSortable } from "@dnd-kit/sortable";
12
14
 
15
+ import { ChangeStateModal, DeleteModal } from "../atoms";
13
16
  import CopyModal from "./CopyModal";
17
+
14
18
  import * as S from "./style";
15
19
 
16
20
  const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
@@ -25,17 +29,18 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
25
29
  toggleToastChange,
26
30
  listLength,
27
31
  hoverCheck,
32
+ isSaving,
28
33
  } = props;
29
34
 
30
- const { isOpen: isOpenDelete, toggleModal: toggleModalDelete } = useModal();
31
- const { isOpen: isOpenChangeState, toggleModal: toggleModalChangeState } = useModal();
32
- const { isOpen: isOpenCopy, toggleModal: toggleModalCopy } = useModal();
35
+ const { isOpen, toggleModal } = useModals(["delete", "changeState", "copy"]);
33
36
  const { isVisible: isVisibleCopy, toggleToast: toggleToastCopy, setIsVisible: setIsVisibleCopy } = useToast();
34
37
 
35
- const isAllowedToManageIntegrations = usePermission("general.manageSiteThirdPartyIntegrations");
36
- const isAllowedToActivateIntegrations = usePermission("general.activateSiteThirdPartyIntegrations");
37
- const isAllowedToDeactivateIntegrations = usePermission("general.deactivateSiteThirdPartyIntegrations");
38
- const isAllowedToDeleteIntegrations = usePermission("general.deleteSiteThirdPartyIntegrations");
38
+ const isAllowedTo = usePermissions({
39
+ manage: "general.manageSiteThirdPartyIntegrations",
40
+ activate: "general.activateSiteThirdPartyIntegrations",
41
+ deactivate: "general.deactivateSiteThirdPartyIntegrations",
42
+ delete: "general.deleteSiteThirdPartyIntegrations",
43
+ });
39
44
 
40
45
  const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
41
46
  id: integration.id as UniqueIdentifier,
@@ -60,12 +65,16 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
60
65
  };
61
66
 
62
67
  const removeItem = async () => {
63
- if (integration.id) {
64
- const params = getParams();
65
- const deleted = await deleteIntegration(integration.id, params);
66
- if (deleted) {
67
- toggleToastDelete({ total: 1 });
68
+ try {
69
+ if (integration.id) {
70
+ const params = getParams();
71
+ const deleted = await deleteIntegration(integration.id, params);
72
+ if (deleted) {
73
+ toggleToastDelete({ total: 1 });
74
+ }
68
75
  }
76
+ } finally {
77
+ toggleModal("delete");
69
78
  }
70
79
  };
71
80
 
@@ -76,45 +85,32 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
76
85
  if (changed) {
77
86
  toggleToastChange({ total: 1, active });
78
87
  }
88
+ toggleModal("changeState");
79
89
  };
80
90
 
81
91
  const menuOptions = [
82
92
  {
83
93
  label: "copy in another site",
84
94
  icon: "copy2",
85
- action: toggleModalCopy,
95
+ action: () => toggleModal("copy"),
86
96
  },
87
97
  ];
88
98
 
89
- if (isAllowedToDeleteIntegrations) {
99
+ if (isAllowedTo.delete) {
90
100
  menuOptions.push({
91
101
  label: "delete",
92
102
  icon: "delete",
93
- action: toggleModalDelete,
103
+ action: () => toggleModal("delete"),
94
104
  });
95
105
  }
96
106
 
97
- const mainDeleteModalAction = {
98
- title: "Delete add-on",
99
- onClick: removeItem,
100
- };
101
-
102
- const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
103
-
104
- const mainChangeStateModalAction = {
105
- title: `${integration.active ? "Disable" : "Enable"} add-on`,
106
- onClick: handleChangeState,
107
- };
108
-
109
- const secondaryChangeStateModalAction = { title: "Cancel", onClick: toggleModalChangeState };
110
-
111
107
  const copyToastProps = {
112
108
  setIsVisible: setIsVisibleCopy,
113
109
  message: "1 Add-on copied to another Site",
114
110
  };
115
111
 
116
112
  const copyIntegration = async (site: number) => {
117
- toggleModalCopy();
113
+ toggleModal("copy");
118
114
  if (integration.id) {
119
115
  await integrations.duplicateIntegration(integration.id, site);
120
116
  toggleToastCopy();
@@ -132,8 +128,7 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
132
128
  const handleCheckClick = (e: React.MouseEvent<HTMLDivElement>) => e.stopPropagation();
133
129
 
134
130
  const isToggleDisabled =
135
- (integration.active && !isAllowedToDeactivateIntegrations) ||
136
- (!integration.active && !isAllowedToActivateIntegrations);
131
+ (integration.active && !isAllowedTo.deactivate) || (!integration.active && !isAllowedTo.activate);
137
132
 
138
133
  const getIntegrationDescription = () => {
139
134
  switch (integration.type) {
@@ -198,7 +193,7 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
198
193
  data-testid="integration-item-row"
199
194
  disabled={!integration.editable}
200
195
  onClick={handleClick}
201
- clickable={isAllowedToManageIntegrations}
196
+ clickable={isAllowedTo.manage}
202
197
  ref={setNodeRef}
203
198
  cssTransform={transform}
204
199
  transition={transition}
@@ -236,7 +231,7 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
236
231
  <ToggleField
237
232
  name="state"
238
233
  value={integration.active}
239
- onChange={toggleModalChangeState}
234
+ onChange={() => toggleModal("changeState")}
240
235
  disabled={isToggleDisabled}
241
236
  size="s"
242
237
  />
@@ -247,34 +242,22 @@ const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
247
242
  </>
248
243
  )}
249
244
  </S.ItemRow>
250
- <Modal
251
- isOpen={isOpenDelete}
252
- hide={toggleModalDelete}
253
- title="Delete add-on"
254
- secondaryAction={secondaryDeleteModalAction}
255
- mainAction={mainDeleteModalAction}
256
- size="S"
257
- >
258
- <S.ModalContent>
259
- Are you sure you want to delete <strong>{integration.name} add-on</strong>? This action{" "}
260
- <strong>cannot be undone</strong>.
261
- </S.ModalContent>
262
- </Modal>
263
- <Modal
264
- isOpen={isOpenChangeState}
265
- hide={toggleModalChangeState}
266
- title={`${integration.active ? "Disable" : "Enable"} Add-on`}
267
- secondaryAction={secondaryChangeStateModalAction}
268
- mainAction={mainChangeStateModalAction}
269
- size="S"
270
- >
271
- <S.ModalContent>
272
- Are you sure you want to {integration.active ? "disable" : "enable"}{" "}
273
- <strong>{integration.name} add-on</strong>? This add-on will {integration.active ? "stop" : "start"} working
274
- in the pages previously added.
275
- </S.ModalContent>
276
- </Modal>
277
- <CopyModal isOpen={isOpenCopy} hide={toggleModalCopy} action={copyIntegration} />
245
+ <DeleteModal
246
+ isOpen={isOpen("delete")}
247
+ toggleModal={() => toggleModal("delete")}
248
+ integrations={[integration]}
249
+ selectedIds={[integration.id ?? 0]}
250
+ onDelete={removeItem}
251
+ isDeleting={isSaving}
252
+ />
253
+ <ChangeStateModal
254
+ isOpen={isOpen("changeState")}
255
+ toggleModal={() => toggleModal("changeState")}
256
+ integration={integration}
257
+ onChangeState={handleChangeState}
258
+ isUpdating={isSaving}
259
+ />
260
+ <CopyModal isOpen={isOpen("copy")} hide={() => toggleModal("copy")} action={copyIntegration} />
278
261
  {isVisibleCopy && <Toast {...copyToastProps} />}
279
262
  </>
280
263
  );
@@ -291,8 +274,13 @@ interface IProps {
291
274
  toggleToastChange: (state: { total: number; active: boolean }) => void;
292
275
  listLength: number;
293
276
  hoverCheck: boolean;
277
+ isSaving: boolean;
294
278
  }
295
279
 
280
+ const mapStateToProps = (state: IRootState) => ({
281
+ isSaving: state.app.isSaving,
282
+ });
283
+
296
284
  const mapDispatchToProps = {
297
285
  setHistoryPush: appActions.setHistoryPush,
298
286
  setCurrentIntegration: integrationsActions.setCurrentIntegration,
@@ -305,4 +293,4 @@ interface IDispatchProps {
305
293
 
306
294
  export type IIntegrationItemProps = IProps & IDispatchProps;
307
295
 
308
- export default connect(null, mapDispatchToProps)(IntegrationItem);
296
+ export default connect(mapStateToProps, mapDispatchToProps)(IntegrationItem);
@@ -1,13 +1,20 @@
1
- import React from "react";
2
-
3
- import { IIntegration, IModal } from "@ax/types";
4
1
  import { Modal } from "@ax/components";
2
+ import type { IIntegration, IModal } from "@ax/types";
5
3
 
6
4
  import { getIntegrationsNames } from "./utils";
5
+
7
6
  import * as S from "./style";
8
7
 
9
- const DeleteModal = (props: IModal & { integrations: IIntegration[]; selectedIds: number[] }): JSX.Element => {
10
- const { isOpen, toggleModal, mainModalAction, secondaryModalAction, integrations, selectedIds } = props;
8
+ const DeleteModal = (props: IDeleteModalProps): JSX.Element => {
9
+ const { isOpen, toggleModal, integrations, selectedIds, onDelete, isDeleting = false } = props;
10
+
11
+ const mainModalAction = {
12
+ title: isDeleting ? "Deleting" : "Delete",
13
+ onClick: onDelete,
14
+ disabled: isDeleting,
15
+ };
16
+
17
+ const secondaryModalAction = { title: "Cancel", onClick: toggleModal };
11
18
 
12
19
  return (
13
20
  <Modal
@@ -17,6 +24,7 @@ const DeleteModal = (props: IModal & { integrations: IIntegration[]; selectedIds
17
24
  secondaryAction={secondaryModalAction}
18
25
  mainAction={mainModalAction}
19
26
  size="S"
27
+ height="auto"
20
28
  >
21
29
  <S.ModalContent>
22
30
  Are you sure you want to delete {getIntegrationsNames(integrations, selectedIds)}? This action{" "}
@@ -26,8 +34,16 @@ const DeleteModal = (props: IModal & { integrations: IIntegration[]; selectedIds
26
34
  );
27
35
  };
28
36
 
29
- const DeactivateModal = (props: IModal & { integrations: IIntegration[]; selectedIds: number[] }): JSX.Element => {
30
- const { isOpen, toggleModal, mainModalAction, secondaryModalAction, integrations, selectedIds } = props;
37
+ const DeactivateModal = (props: IDeactivateModalProps): JSX.Element => {
38
+ const { isOpen, toggleModal, integrations, selectedIds, onDeactivate, isDeactivating = false } = props;
39
+
40
+ const mainModalAction = {
41
+ title: isDeactivating ? "Disabling" : "Deactivate",
42
+ onClick: onDeactivate,
43
+ disabled: isDeactivating,
44
+ };
45
+
46
+ const secondaryModalAction = { title: "Cancel", onClick: toggleModal };
31
47
 
32
48
  return (
33
49
  <Modal
@@ -46,4 +62,52 @@ const DeactivateModal = (props: IModal & { integrations: IIntegration[]; selecte
46
62
  );
47
63
  };
48
64
 
49
- export { DeleteModal, DeactivateModal };
65
+ const ChangeStateModal = (props: IChangeStateModalProps): JSX.Element => {
66
+ const { isOpen, toggleModal, integration, onChangeState, isUpdating } = props;
67
+
68
+ const mainModalAction = {
69
+ title: isUpdating ? "Updating" : `${integration.active ? "Disable" : "Enable"} Add-on`,
70
+ onClick: onChangeState,
71
+ disabled: isUpdating,
72
+ };
73
+
74
+ const secondaryModalAction = { title: "Cancel", onClick: toggleModal };
75
+
76
+ return (
77
+ <Modal
78
+ isOpen={isOpen}
79
+ hide={toggleModal}
80
+ title={`${integration.active ? "Disable" : "Enable"} Add-on`}
81
+ secondaryAction={secondaryModalAction}
82
+ mainAction={mainModalAction}
83
+ size="S"
84
+ >
85
+ <S.ModalContent>
86
+ Are you sure you want to {integration.active ? "disable" : "enable"} <strong>{integration.name} add-on</strong>?
87
+ This add-on will {integration.active ? "stop" : "start"} working in the pages previously added.
88
+ </S.ModalContent>
89
+ </Modal>
90
+ );
91
+ };
92
+
93
+ interface IDeleteModalProps extends IModal {
94
+ integrations: IIntegration[];
95
+ selectedIds: number[];
96
+ onDelete(): void;
97
+ isDeleting?: boolean;
98
+ }
99
+
100
+ interface IDeactivateModalProps extends IModal {
101
+ integrations: IIntegration[];
102
+ selectedIds: number[];
103
+ onDeactivate(): void | Promise<void>;
104
+ isDeactivating?: boolean;
105
+ }
106
+
107
+ interface IChangeStateModalProps extends IModal {
108
+ integration: IIntegration;
109
+ isUpdating: boolean;
110
+ onChangeState(): void;
111
+ }
112
+
113
+ export { DeleteModal, DeactivateModal, ChangeStateModal };