@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
@@ -103,18 +103,23 @@ const ColumnCell = styled(Cell)`
103
103
  align-items: center;
104
104
  `;
105
105
 
106
+ const ModalContent = styled.div`
107
+ padding: ${(p) => p.theme.spacing.m};
108
+ `;
109
+
106
110
  export {
107
- CheckCell,
108
- NameCell,
109
111
  ActionsCell,
110
- ActionsWrapper,
111
- StyledActionMenu,
112
- TransCell,
112
+ CheckCell,
113
+ ColumnCell,
114
+ FlagsWrapper,
113
115
  LiveCell,
114
- StatusCell,
116
+ ModalContent,
115
117
  ModDate,
118
+ NameCell,
119
+ StatusCell,
116
120
  StructuredDataRow,
117
- FlagsWrapper,
121
+ StyledActionMenu,
118
122
  Title,
119
- ColumnCell,
123
+ TransCell,
124
+ ActionsWrapper,
120
125
  };
@@ -45,7 +45,7 @@ import type {
45
45
  IStructuredDataValue,
46
46
  } from "@ax/types";
47
47
 
48
- import { DeleteModal } from "./atoms";
48
+ import { DeleteModal } from "../atoms";
49
49
  import BulkHeader from "./BulkHeader";
50
50
  import ContentFilters from "./ContentFilters";
51
51
  import GlobalPageItem from "./GlobalPageItem";
@@ -85,6 +85,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
85
85
  filter,
86
86
  setFilter,
87
87
  isLoading,
88
+ isSaving,
88
89
  setCurrentPageID,
89
90
  addTemplate,
90
91
  template,
@@ -117,7 +118,6 @@ const StructuredDataList = (props: IProps): JSX.Element => {
117
118
  const isLastItem = page === lastPage && currentSitePages.length === 1;
118
119
 
119
120
  const [isScrolling, setIsScrolling] = useState(false);
120
- const [isBulkLoading, setIsBulkLoading] = useState(false);
121
121
  const [deletedItem, setDeletedItem] = useState<number | number[] | null>(null);
122
122
  const { isVisible: isDataToast, toggleToast: toggleDataToast, setIsVisible: setIsDataToast } = useToast();
123
123
  const { isVisible: isPageToast, toggleToast: togglePageToast, setIsVisible: setIsPageToast } = useToast();
@@ -349,7 +349,6 @@ const StructuredDataList = (props: IProps): JSX.Element => {
349
349
  };
350
350
 
351
351
  const bulkDelete = async () => {
352
- setIsBulkLoading(true);
353
352
  const idsToBeDeleted = getAllLangPagesIds(currentSitePages, selectedItems, deleteAllVersions);
354
353
  const deleted = isStructuredDataFromPage
355
354
  ? await deleteBulk(idsToBeDeleted)
@@ -367,7 +366,6 @@ const StructuredDataList = (props: IProps): JSX.Element => {
367
366
  : isStructuredDataFromPage && handleGetGlobalPages();
368
367
  unselectAllItems();
369
368
  toggleModal("delete");
370
- setIsBulkLoading(false);
371
369
  };
372
370
 
373
371
  const handleBulkDelete = () => {
@@ -378,7 +376,6 @@ const StructuredDataList = (props: IProps): JSX.Element => {
378
376
  };
379
377
 
380
378
  const bulkPublishPage = async (isPublish: boolean) => {
381
- setIsBulkLoading(true);
382
379
  const { notPublished, published, drafts } = selectedItems;
383
380
 
384
381
  if (drafts && drafts.length > 0) {
@@ -407,14 +404,11 @@ const StructuredDataList = (props: IProps): JSX.Element => {
407
404
 
408
405
  handleGetGlobalPages();
409
406
  unselectAllItems();
410
- setIsBulkLoading(false);
411
407
  };
412
408
 
413
409
  const bulkPublishData = (status: string) => {
414
- setIsBulkLoading(true);
415
410
  setDataStatus(selectedItems.all, status);
416
411
  unselectAllItems();
417
- setIsBulkLoading(false);
418
412
  };
419
413
 
420
414
  const bulkFilter = (bulkSelection: number[]) => filterByStatus(bulkSelection, currentSitePages);
@@ -493,7 +487,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
493
487
  checkState={checkState}
494
488
  isScrolling={isScrolling}
495
489
  isEditable={isDataEditable}
496
- isLoading={isBulkLoading}
490
+ isLoading={isSaving}
497
491
  isFromPage={isStructuredDataFromPage}
498
492
  sortItems={sortItems}
499
493
  sortedListStatus={sortedListStatus}
@@ -693,6 +687,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
693
687
  onScroll={onScroll}
694
688
  hasFixedHeader={true}
695
689
  tableRef={tableRef}
690
+ skipLoading={isSaving}
696
691
  >
697
692
  <>
698
693
  <S.SearchTags>
@@ -730,13 +725,11 @@ const StructuredDataList = (props: IProps): JSX.Element => {
730
725
  <DeleteModal
731
726
  isOpen={isOpen("delete")}
732
727
  toggleModal={() => toggleModal("delete")}
733
- mainModalAction={{
734
- title: isBulkLoading ? "Deleting" : "Delete",
735
- onClick: bulkDelete,
736
- disabled: isBulkLoading,
737
- }}
738
- secondaryModalAction={{ title: "Cancel", onClick: () => toggleModal("delete") }}
739
- {...{ arePagesTranslated, deleteAllVersions, setDeleteAllVersions }}
728
+ arePagesTranslated={arePagesTranslated}
729
+ deleteAllVersions={deleteAllVersions}
730
+ setDeleteAllVersions={setDeleteAllVersions}
731
+ onDelete={bulkDelete}
732
+ isDeleting={isSaving}
740
733
  />
741
734
  {isDataToast && <Toast action={undoDeleteData} setIsVisible={setIsDataToast} message={"Data deleted"} />}
742
735
  {isPageToast && (
@@ -761,6 +754,7 @@ const mapStateToProps = (state: IRootState) => ({
761
754
  currentSiteID: state.sites.currentSiteInfo?.id || null,
762
755
  activatedDataPacks: state.dataPacks.activated,
763
756
  isLoading: state.app.isLoading,
757
+ isSaving: state.app.isSaving,
764
758
  template: state.pageEditor.template,
765
759
  currentSitePages: state.sites.currentSitePages,
766
760
  currentSiteErrorPages: state.sites.currentSiteErrorPages,
@@ -838,6 +832,7 @@ interface ICategoriesProps {
838
832
  currentSiteID: number | null;
839
833
  activatedDataPacks: IDataPack[];
840
834
  isLoading: boolean;
835
+ isSaving: boolean;
841
836
  template: string;
842
837
  currentSitePages: IPage[];
843
838
  currentSiteErrorPages: number[];
@@ -1,19 +1,20 @@
1
- import React from "react";
1
+ import type React from "react";
2
2
 
3
- import { IModal } from "@ax/types";
4
- import { Modal, FieldsBehavior, Button } from "@ax/components";
3
+ import { FieldsBehavior, Modal } from "@ax/components";
4
+ import type { IModal } from "@ax/types";
5
5
 
6
- import * as S from "./style";
6
+ import * as S from "./StructuredDataList/style";
7
7
 
8
8
  const DeleteModal = (props: IDeleteModal): JSX.Element => {
9
9
  const {
10
10
  isOpen,
11
11
  toggleModal,
12
- mainModalAction,
13
- secondaryModalAction,
14
12
  arePagesTranslated,
15
13
  deleteAllVersions,
16
14
  setDeleteAllVersions,
15
+ onDelete,
16
+ isDeleting,
17
+ title,
17
18
  } = props;
18
19
 
19
20
  const options = [
@@ -29,6 +30,14 @@ const DeleteModal = (props: IDeleteModal): JSX.Element => {
29
30
  },
30
31
  ];
31
32
 
33
+ const mainModalAction = {
34
+ title: isDeleting ? "Deleting" : "Delete",
35
+ onClick: onDelete,
36
+ disabled: isDeleting,
37
+ };
38
+
39
+ const secondaryModalAction = { title: "Cancel", onClick: toggleModal };
40
+
32
41
  return (
33
42
  <Modal
34
43
  isOpen={isOpen}
@@ -37,13 +46,15 @@ const DeleteModal = (props: IDeleteModal): JSX.Element => {
37
46
  secondaryAction={secondaryModalAction}
38
47
  mainAction={mainModalAction}
39
48
  size="S"
49
+ height="auto"
40
50
  >
41
51
  {arePagesTranslated ? (
42
52
  <>
43
53
  <S.ModalContent>
44
54
  <p>
45
- Are you sure you want to delete <strong>these pages</strong> page? If you delete it, this page does not
46
- appear in the sites associated. Also, this page has some translations associated.
55
+ Are you sure you want to delete {title ? <strong>{title}</strong> : <strong>these pages</strong>} page? If
56
+ you delete it, this page does not appear in the sites associated. Also, this page has some translations
57
+ associated.
47
58
  </p>
48
59
  <FieldsBehavior
49
60
  name="removeAllVersions"
@@ -56,35 +67,21 @@ const DeleteModal = (props: IDeleteModal): JSX.Element => {
56
67
  </>
57
68
  ) : (
58
69
  <S.ModalContent>
59
- Are you sure you want to delete <strong>these pages</strong> page? If you delete it, this page does not appear
60
- in the sites associated. This action <strong>cannot be undone</strong>.
70
+ Are you sure you want to delete {title ? <strong>{title}</strong> : <strong>these pages</strong>} page? If you
71
+ delete it, this page does not appear in the sites associated. This action <strong>cannot be undone</strong>.
61
72
  </S.ModalContent>
62
73
  )}
63
74
  </Modal>
64
75
  );
65
76
  };
66
77
 
67
- const MainActionButton = (props: IActionButton): JSX.Element => (
68
- <Button type="button" onClick={props.onClick}>
69
- {props.title}
70
- </Button>
71
- );
72
-
73
- const SecondaryActionButton = (props: IActionButton): JSX.Element => (
74
- <Button type="button" buttonStyle="text" onClick={props.onClick}>
75
- {props.title}
76
- </Button>
77
- );
78
-
79
78
  interface IDeleteModal extends IModal {
80
79
  arePagesTranslated: boolean;
81
80
  deleteAllVersions: boolean;
82
81
  setDeleteAllVersions: React.Dispatch<React.SetStateAction<boolean>>;
82
+ onDelete: () => void;
83
+ isDeleting?: boolean;
84
+ title?: string;
83
85
  }
84
86
 
85
- interface IActionButton {
86
- onClick: () => void;
87
- title: string;
88
- }
89
-
90
- export { DeleteModal, MainActionButton, SecondaryActionButton };
87
+ export { DeleteModal };
@@ -1,10 +1,12 @@
1
1
  import { connect } from "react-redux";
2
2
 
3
- import { Avatar, CheckField, ElementsTooltip, Modal, Tag, Toast, Tooltip, TruncatedTooltip } from "@ax/components";
3
+ import { Avatar, CheckField, ElementsTooltip, Tag, Toast, Tooltip, TruncatedTooltip } from "@ax/components";
4
4
  import { usersActions } from "@ax/containers/Users";
5
5
  import { getDaysAgo } from "@ax/helpers";
6
6
  import { useModal, usePermission, useToast } from "@ax/hooks";
7
- import type { ICheck, IRole, ISite, ISiteRoles, IUser } from "@ax/types";
7
+ import type { ICheck, IRole, IRootState, ISite, ISiteRoles, IUser } from "@ax/types";
8
+
9
+ import { DeleteModal } from "../atoms";
8
10
 
9
11
  import * as S from "./style";
10
12
 
@@ -21,6 +23,7 @@ const UserItem = (props: IUserItemProps): JSX.Element => {
21
23
  isSiteView = false,
22
24
  roles,
23
25
  hoverCheck,
26
+ isSaving,
24
27
  toggleDeleteToast,
25
28
  removeUserFromSite,
26
29
  getUsers,
@@ -84,13 +87,6 @@ const UserItem = (props: IUserItemProps): JSX.Element => {
84
87
  }
85
88
  };
86
89
 
87
- const mainDeleteAction = {
88
- title: isSiteView ? "Remove" : "Delete",
89
- onClick: isSiteView ? handleRemoveUserFromSite : handleDeleteUser,
90
- };
91
-
92
- const secondaryDeleteAction = { title: "Cancel", onClick: toggleModal };
93
-
94
90
  const tagColor = user.status === "invited" ? "#FFBB37" : "#AFC628";
95
91
  const days = user.dateCreated ? getDaysAgo(user.dateCreated) : "";
96
92
  const tooltipText = user.status === "invited" ? `Invited: ${days}` : "User Active";
@@ -203,32 +199,14 @@ const UserItem = (props: IUserItemProps): JSX.Element => {
203
199
  <S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
204
200
  </S.ActionsCell>
205
201
  </S.UserRow>
206
- <Modal
202
+ <DeleteModal
207
203
  isOpen={isOpen}
208
- hide={toggleModal}
209
- title={isSiteView ? "Remove user from this site?" : "Delete User?"}
210
- secondaryAction={secondaryDeleteAction}
211
- mainAction={mainDeleteAction}
212
- >
213
- {isOpen ? (
214
- <S.ModalContent data-testid="modal-delete-content">
215
- {isSiteView ? (
216
- <p>
217
- Are you sure you want to remove <strong>{user.email}</strong> from this site? If you remove it, this
218
- user will no longer have access to this site but it will still be able to log in.
219
- </p>
220
- ) : (
221
- <p>
222
- Are you sure you want to delete <strong>{user.email}</strong>? If you delete it, this user will no
223
- longer be able to log in.
224
- </p>
225
- )}
226
- <p>
227
- This action <strong>cannot be undone</strong>.
228
- </p>
229
- </S.ModalContent>
230
- ) : null}
231
- </Modal>
204
+ toggleModal={toggleModal}
205
+ onDelete={isSiteView ? handleRemoveUserFromSite : handleDeleteUser}
206
+ isSiteView={isSiteView}
207
+ userEmail={user.email}
208
+ isDeleting={isSaving}
209
+ />
232
210
  {isVisible && <Toast {...toastProps} />}
233
211
  </>
234
212
  );
@@ -242,12 +220,17 @@ interface IProps {
242
220
  isSiteView?: boolean;
243
221
  roles: IRole[];
244
222
  hoverCheck: boolean;
223
+ isSaving: boolean;
245
224
  onChange: (value: ICheck) => void;
246
225
  onClick: (id: number) => void;
247
226
  toggleDeleteToast: () => void;
248
227
  getUsers: () => void;
249
228
  }
250
229
 
230
+ const mapStateToProps = (state: IRootState) => ({
231
+ isSaving: state.app.isSaving,
232
+ });
233
+
251
234
  const mapDispatchToProps = {
252
235
  deleteUser: usersActions.deleteUser,
253
236
  resendInvitation: usersActions.resendInvitation,
@@ -262,4 +245,4 @@ interface IDispatchProps {
262
245
 
263
246
  export type IUserItemProps = IProps & IDispatchProps;
264
247
 
265
- export default connect(null, mapDispatchToProps)(UserItem);
248
+ export default connect(mapStateToProps, mapDispatchToProps)(UserItem);
@@ -0,0 +1,61 @@
1
+ import { Modal } from "@ax/components";
2
+ import type { IModal } from "@ax/types";
3
+
4
+ import * as S from "./style";
5
+
6
+ const DeleteModal = (props: IDeleteModalProps): JSX.Element => {
7
+ const { isOpen, toggleModal, onDelete, isSiteView, userEmail, isBulk = false, isDeleting = false } = props;
8
+
9
+ const action = isSiteView ? "Remove" : "Delete";
10
+ const actionGerund = isSiteView ? "Removing" : "Deleting";
11
+
12
+ const buttonTitle = isDeleting ? actionGerund : action;
13
+ const modalTitle = isBulk
14
+ ? isSiteView
15
+ ? "Remove users from this site?"
16
+ : "Delete Users?"
17
+ : isSiteView
18
+ ? "Remove user from this site?"
19
+ : "Delete User?";
20
+
21
+ const getContent = () => {
22
+ if (isBulk) {
23
+ return isSiteView
24
+ ? "Are you sure you want to remove these users from this site? If you remove them, these users will no longer have access to this site but they will still be able to log in. This action cannot be undone."
25
+ : "Are you sure you want to delete these users? If you delete them, they no longer be able to log in.";
26
+ }
27
+ return isSiteView
28
+ ? `Are you sure you want to remove ${userEmail} from this site? If you remove it, this user will no longer have access to this site but it will still be able to log in.`
29
+ : `Are you sure you want to delete ${userEmail}? If you delete it, this user will no longer be able to log in.`;
30
+ };
31
+
32
+ return (
33
+ <Modal
34
+ isOpen={isOpen}
35
+ hide={toggleModal}
36
+ title={modalTitle}
37
+ secondaryAction={{ title: "Cancel", onClick: toggleModal }}
38
+ mainAction={{ title: buttonTitle, onClick: onDelete, disabled: isDeleting }}
39
+ height="auto"
40
+ >
41
+ {isOpen && (
42
+ <S.ModalContent data-testid="modal-delete-content">
43
+ <p>{getContent()}</p>
44
+ <p>
45
+ This action <strong>cannot be undone</strong>.
46
+ </p>
47
+ </S.ModalContent>
48
+ )}
49
+ </Modal>
50
+ );
51
+ };
52
+
53
+ interface IDeleteModalProps extends IModal {
54
+ onDelete: () => void;
55
+ isSiteView?: boolean;
56
+ userEmail?: string;
57
+ isBulk?: boolean;
58
+ isDeleting?: boolean;
59
+ }
60
+
61
+ export { DeleteModal };
@@ -6,7 +6,6 @@ import {
6
6
  ErrorToast,
7
7
  FilterTagsBar,
8
8
  MainWrapper,
9
- Modal,
10
9
  Nav,
11
10
  SearchTagsBar,
12
11
  TableList,
@@ -19,6 +18,7 @@ import { useBulkSelection, useModal, usePermission, useToast } from "@ax/hooks";
19
18
  import type { IGetRoles, IGetSitesParams, IQueryValue, IRole, IRootState, ISite, IUser } from "@ax/types";
20
19
 
21
20
  import BulkHeader from "./BulkHeader";
21
+ import { DeleteModal } from "./atoms";
22
22
  import { useFilterQuery, useSortedListStatus } from "./hooks";
23
23
  import UserItem from "./UserItem";
24
24
  import { getSortedListStatus } from "./utils";
@@ -40,12 +40,12 @@ const UserList = (props: IUserListProps): JSX.Element => {
40
40
  getRoles,
41
41
  roles,
42
42
  getSites,
43
+ isSaving,
43
44
  } = props;
44
45
 
45
46
  const itemsPerPage = 50;
46
47
  const firstPage = 1;
47
48
 
48
- const [isBulkLoading, setIsBulkLoading] = useState(false);
49
49
  const [page, setPage] = useState(1);
50
50
  const [isScrolling, setIsScrolling] = useState(false);
51
51
  const [searchQuery, setSearchQuery] = useState<string>("");
@@ -143,7 +143,6 @@ const UserList = (props: IUserListProps): JSX.Element => {
143
143
  };
144
144
 
145
145
  const bulkDelete = async () => {
146
- setIsBulkLoading(true);
147
146
  if (isSiteView) {
148
147
  const siteId = currentSiteInfo.id;
149
148
  await removeUsersBulk(siteId, selectedItems.all);
@@ -154,7 +153,6 @@ const UserList = (props: IUserListProps): JSX.Element => {
154
153
  toggleModal();
155
154
  toggleToast();
156
155
  resetBulkSelection();
157
- setIsBulkLoading(false);
158
156
  };
159
157
 
160
158
  const rightButtonProps = allowedToCreateUsers
@@ -205,7 +203,7 @@ const UserList = (props: IUserListProps): JSX.Element => {
205
203
  roles={roles}
206
204
  setHoverCheck={setHoverCheck}
207
205
  selectedItems={selectedItems}
208
- isLoading={isBulkLoading}
206
+ isLoading={isSaving}
209
207
  />
210
208
  );
211
209
 
@@ -221,13 +219,6 @@ const UserList = (props: IUserListProps): JSX.Element => {
221
219
  toggleToast();
222
220
  };
223
221
 
224
- const mainDeleteAction = {
225
- title: isSiteView ? (isBulkLoading ? "Removing" : "Remove") : isBulkLoading ? "Deleting" : "Delete",
226
- onClick: bulkDelete,
227
- disabled: isBulkLoading,
228
- };
229
- const secondaryDeleteAction = { title: "Cancel", onClick: toggleModal };
230
-
231
222
  const filterLabels = {
232
223
  filterRoles: "Role",
233
224
  filterSites: "Site",
@@ -290,27 +281,14 @@ const UserList = (props: IUserListProps): JSX.Element => {
290
281
  </TableList>
291
282
  </S.TableListWrapper>
292
283
  </S.UsersWrapper>
293
- <Modal
284
+ <DeleteModal
294
285
  isOpen={isOpen}
295
- hide={toggleModal}
296
- title={isSiteView ? "Remove users from this site?" : "Delete Users?"}
297
- secondaryAction={secondaryDeleteAction}
298
- mainAction={mainDeleteAction}
299
- >
300
- {isOpen ? (
301
- <S.ModalContent data-testid="user-delete-bulk-modal">
302
- <p>
303
- {isSiteView
304
- ? "Are you sure you want to remove these users from this site? If you remove them, these users will no longer have access to this site but they will still be able to log in. This action cannot be undone."
305
- : "Are you sure you want to delete these users? If you delete them, they no longer be able to log in."}
306
- </p>
307
-
308
- <p>
309
- This action <strong>cannot be undone</strong>.
310
- </p>
311
- </S.ModalContent>
312
- ) : null}
313
- </Modal>
286
+ toggleModal={toggleModal}
287
+ onDelete={bulkDelete}
288
+ isSiteView={isSiteView}
289
+ isBulk={true}
290
+ isDeleting={isSaving}
291
+ />
314
292
  {isVisible && <Toast {...toastProps} />}
315
293
  </MainWrapper>
316
294
  );
@@ -321,6 +299,7 @@ const mapStateToProps = (state: IRootState) => ({
321
299
  currentSiteInfo: state.sites.currentSiteInfo,
322
300
  sites: state.sites.sites,
323
301
  roles: state.users.roles,
302
+ isSaving: state.app.isSaving,
324
303
  });
325
304
 
326
305
  const mapDispatchToProps = {
@@ -350,6 +329,7 @@ interface IProps {
350
329
  currentSiteInfo: ISite | null;
351
330
  sites: ISite[];
352
331
  roles: IRole[];
332
+ isSaving: boolean;
353
333
  }
354
334
 
355
335
  export type IUserListProps = IProps & IDispatchProps;