@griddo/ax 10.1.96 → 10.2.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 (201) hide show
  1. package/package.json +3 -2
  2. package/src/__mocks__/axios/Roles.ts +10 -0
  3. package/src/__mocks__/axios/UserList.ts +545 -0
  4. package/src/__mocks__/store/GenericStore.ts +25 -0
  5. package/src/__mocks__/store/Roles.ts +1050 -0
  6. package/src/__mocks__/store/SitesList.ts +7 -1
  7. package/src/__mocks__/store/UserList.ts +482 -0
  8. package/src/__mocks__/store/UsersCreate.ts +298 -0
  9. package/src/__tests__/components/Avatar/Avatar.test.tsx +49 -48
  10. package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +2 -0
  11. package/src/__tests__/components/ConfigPanel/Form/Form.test.tsx +2 -0
  12. package/src/__tests__/components/ConfigPanel/GlobalPageForm/GlobalPageForm.test.tsx +25 -0
  13. package/src/__tests__/components/Fields/Button/Button.test.tsx +2 -2
  14. package/src/__tests__/components/Fields/ImageField/ImageField.test.tsx +2 -0
  15. package/src/__tests__/components/Fields/IntegrationsField/IntegrationsField.test.tsx +44 -2
  16. package/src/__tests__/components/Fields/Tooltip/Tooltip.test.tsx +0 -1
  17. package/src/__tests__/components/Gallery/Gallery.test.tsx +4 -0
  18. package/src/__tests__/components/Gallery/GalleryPanel/DetailPanel/DetailPanel.test.tsx +14 -0
  19. package/src/__tests__/components/Gallery/GalleryPanel/GalleryPanel.test.tsx +2 -1
  20. package/src/__tests__/components/Lists/Lists.test.tsx +3 -3
  21. package/src/__tests__/components/Login/Login.test.tsx +1 -1
  22. package/src/__tests__/components/TableFilters/DateFilter/DateFilter.test.tsx +1 -1
  23. package/src/__tests__/components/TableFilters/NameFilter/NameFilter.test.tsx +1 -1
  24. package/src/__tests__/components/TableFilters/RoleFilter/RoleFilter.test.tsx +165 -0
  25. package/src/__tests__/components/TableFilters/StatusFilter/StatusFilter.test.tsx +2 -2
  26. package/src/__tests__/components/TableFilters/UsersFilter/UsersFilter.test.tsx +153 -0
  27. package/src/__tests__/components/Tabs/Tabs.test.tsx +1 -1
  28. package/src/__tests__/modules/Settings/Integrations/Integrations.test.tsx +6 -0
  29. package/src/__tests__/modules/Sites/Sites.test.tsx +2 -1
  30. package/src/__tests__/modules/Sites/SitesList/ListView/BulkHeader/BulkHeader.test.tsx +14 -5
  31. package/src/__tests__/modules/Sites/SitesList/SitesList.test.tsx +6 -4
  32. package/src/__tests__/modules/Users/Roles/BulkHeader/BulkHeader.test.tsx +158 -0
  33. package/src/__tests__/modules/Users/Roles/Roles.test.tsx +619 -0
  34. package/src/__tests__/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/RoleItem.test.tsx +107 -0
  35. package/src/__tests__/modules/Users/UserCreate/SiteItem/RolesModal/RolesModal.test.tsx +159 -0
  36. package/src/__tests__/modules/Users/UserCreate/SiteItem/SiteItem.test.tsx +175 -0
  37. package/src/__tests__/modules/Users/UserCreate/UserCreate.test.tsx +320 -0
  38. package/src/__tests__/modules/Users/UserList/UserItem/UserItem.test.tsx +417 -0
  39. package/src/__tests__/modules/Users/UserList/UserList.test.tsx +310 -0
  40. package/src/api/index.tsx +2 -0
  41. package/src/api/roles.tsx +77 -0
  42. package/src/api/users.tsx +22 -2
  43. package/src/components/ActionMenu/index.tsx +12 -6
  44. package/src/components/Avatar/index.tsx +5 -3
  45. package/src/components/Avatar/style.tsx +8 -9
  46. package/src/components/BulkSelectionOptions/index.tsx +19 -12
  47. package/src/components/BulkSelectionOptions/style.tsx +6 -11
  48. package/src/components/ConfigPanel/Form/index.tsx +24 -1
  49. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +17 -4
  50. package/src/components/ElementsTooltip/index.tsx +1 -1
  51. package/src/components/Fields/IntegrationsField/index.tsx +5 -6
  52. package/src/components/Fields/RadioField/index.tsx +1 -1
  53. package/src/components/Fields/ReferenceField/AutoPanel/index.tsx +3 -3
  54. package/src/components/Fields/ReferenceField/ItemList/index.tsx +1 -1
  55. package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +3 -3
  56. package/src/components/Fields/TagsField/index.tsx +4 -2
  57. package/src/components/Fields/TextField/index.tsx +3 -0
  58. package/src/components/Fields/UrlField/index.tsx +5 -5
  59. package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +42 -15
  60. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +1 -1
  61. package/src/components/Gallery/GalleryPanel/index.tsx +20 -5
  62. package/src/components/Gallery/index.tsx +12 -6
  63. package/src/components/Icon/index.tsx +9 -1
  64. package/src/components/MainWrapper/AppBar/atoms.tsx +2 -2
  65. package/src/components/MainWrapper/AppBar/index.tsx +12 -10
  66. package/src/components/MainWrapper/AppBar/style.tsx +2 -1
  67. package/src/components/Modal/style.tsx +2 -2
  68. package/src/components/Nav/index.tsx +12 -2
  69. package/src/components/PageFinder/index.tsx +2 -2
  70. package/src/components/SearchField/index.tsx +3 -8
  71. package/src/components/TableFilters/PermissionsFilter/index.tsx +50 -0
  72. package/src/{modules/Users/UserList/HeaderMenus/Name → components/TableFilters/PermissionsFilter}/style.tsx +6 -2
  73. package/src/components/TableFilters/RoleFilter/index.tsx +61 -0
  74. package/src/components/TableFilters/RoleFilter/style.tsx +28 -0
  75. package/src/components/TableFilters/UsersFilter/index.tsx +55 -0
  76. package/src/components/TableFilters/UsersFilter/style.tsx +31 -0
  77. package/src/components/TableFilters/index.tsx +6 -0
  78. package/src/components/TableList/TableItem/style.tsx +2 -2
  79. package/src/components/TableList/style.tsx +1 -1
  80. package/src/components/index.tsx +7 -1
  81. package/src/containers/App/actions.tsx +3 -3
  82. package/src/containers/PageEditor/actions.tsx +14 -20
  83. package/src/containers/Redirects/actions.tsx +1 -0
  84. package/src/containers/Sites/actions.tsx +22 -14
  85. package/src/containers/Sites/interfaces.tsx +3 -3
  86. package/src/containers/Sites/reducer.tsx +1 -1
  87. package/src/containers/StructuredData/actions.tsx +15 -3
  88. package/src/containers/Users/actions.tsx +160 -26
  89. package/src/containers/Users/constants.tsx +8 -10
  90. package/src/containers/Users/interfaces.tsx +25 -3
  91. package/src/containers/Users/reducer.tsx +24 -15
  92. package/src/guards/index.tsx +2 -1
  93. package/src/guards/restricted/index.tsx +21 -0
  94. package/src/hooks/index.tsx +3 -0
  95. package/src/hooks/users.tsx +38 -0
  96. package/src/modules/App/Routing/NavMenu/NavItem/index.tsx +10 -5
  97. package/src/modules/App/Routing/NavMenu/index.tsx +16 -7
  98. package/src/modules/App/Routing/PrivateRoute/index.tsx +13 -5
  99. package/src/modules/App/Routing/index.tsx +17 -6
  100. package/src/modules/Categories/CategoriesList/BulkHeader/TableHeader/style.tsx +1 -0
  101. package/src/modules/Categories/CategoriesList/BulkHeader/index.tsx +2 -10
  102. package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +27 -12
  103. package/src/modules/Categories/CategoriesList/CategoryItem/style.tsx +4 -2
  104. package/src/modules/Categories/CategoriesList/index.tsx +27 -8
  105. package/src/modules/Content/BulkHeader/index.tsx +7 -3
  106. package/src/modules/Content/PageImporter/index.tsx +1 -1
  107. package/src/modules/Content/PageItem/index.tsx +45 -31
  108. package/src/modules/Content/PageItem/style.tsx +2 -1
  109. package/src/modules/Content/index.tsx +22 -13
  110. package/src/modules/FramePreview/index.tsx +2 -2
  111. package/src/modules/GlobalEditor/index.tsx +68 -53
  112. package/src/modules/GlobalSettings/index.tsx +2 -0
  113. package/src/modules/Navigation/Defaults/BulkHeader/index.tsx +2 -10
  114. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +9 -11
  115. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +5 -1
  116. package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +10 -5
  117. package/src/modules/Navigation/Defaults/Item/index.tsx +41 -27
  118. package/src/modules/Navigation/Defaults/Item/style.tsx +2 -1
  119. package/src/modules/Navigation/Defaults/index.tsx +29 -10
  120. package/src/modules/Navigation/Menus/List/Table/Header/index.tsx +7 -5
  121. package/src/modules/Navigation/Menus/List/Table/Item/index.tsx +10 -10
  122. package/src/modules/Navigation/Menus/List/Table/Item/style.tsx +2 -1
  123. package/src/modules/Navigation/Menus/List/index.tsx +6 -2
  124. package/src/modules/Navigation/Menus/index.tsx +12 -7
  125. package/src/modules/PageEditor/Editor/index.tsx +5 -1
  126. package/src/modules/PageEditor/PageBrowser/index.tsx +9 -3
  127. package/src/modules/PageEditor/index.tsx +67 -57
  128. package/src/modules/Redirects/index.tsx +97 -98
  129. package/src/modules/Settings/ContentTypes/DataPacks/AddModal/index.tsx +5 -1
  130. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +8 -9
  131. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +7 -3
  132. package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +5 -1
  133. package/src/modules/Settings/ContentTypes/DataPacks/Item/index.tsx +5 -1
  134. package/src/modules/Settings/Integrations/BulkHeader/index.tsx +2 -17
  135. package/src/modules/Settings/Integrations/IntegrationForm/index.tsx +6 -2
  136. package/src/modules/Settings/Integrations/IntegrationItem/index.tsx +18 -8
  137. package/src/modules/Settings/Integrations/IntegrationItem/style.tsx +6 -3
  138. package/src/modules/Settings/Integrations/index.tsx +32 -7
  139. package/src/modules/Settings/Languages/LanguagePanel/index.tsx +6 -2
  140. package/src/modules/Settings/Languages/Table/Header/index.tsx +4 -2
  141. package/src/modules/Settings/Languages/Table/Item/index.tsx +19 -43
  142. package/src/modules/Settings/Languages/Table/Item/style.tsx +11 -54
  143. package/src/modules/Settings/Languages/index.tsx +2 -2
  144. package/src/modules/Settings/SeoAnalyticsSettings/Analytics/index.tsx +2 -4
  145. package/src/modules/Settings/SeoAnalyticsSettings/index.tsx +4 -2
  146. package/src/modules/Settings/Social/index.tsx +1 -1
  147. package/src/modules/Settings/index.tsx +17 -11
  148. package/src/modules/Sites/SitesList/GridView/GridSiteItem/index.tsx +31 -18
  149. package/src/modules/Sites/SitesList/ListView/BulkHeader/index.tsx +21 -12
  150. package/src/modules/Sites/SitesList/ListView/ListSiteItem/index.tsx +31 -18
  151. package/src/modules/Sites/SitesList/RecentSiteItem/index.tsx +1 -1
  152. package/src/modules/Sites/SitesList/index.tsx +16 -24
  153. package/src/modules/Sites/index.tsx +7 -3
  154. package/src/modules/StructuredData/Form/index.tsx +1 -1
  155. package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +8 -5
  156. package/src/modules/StructuredData/StructuredDataList/ContentFilters/index.tsx +8 -5
  157. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +29 -15
  158. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +50 -19
  159. package/src/modules/StructuredData/StructuredDataList/index.tsx +9 -6
  160. package/src/modules/Users/Profile/index.tsx +16 -4
  161. package/src/modules/Users/Roles/BulkHeader/TableHeader/index.tsx +52 -0
  162. package/src/modules/Users/Roles/BulkHeader/TableHeader/style.tsx +43 -0
  163. package/src/modules/Users/Roles/BulkHeader/index.tsx +74 -0
  164. package/src/modules/Users/Roles/RoleItem/index.tsx +104 -0
  165. package/src/modules/Users/Roles/RoleItem/style.tsx +127 -0
  166. package/src/modules/Users/Roles/SideModal/index.tsx +81 -0
  167. package/src/modules/Users/Roles/SideModal/style.tsx +132 -0
  168. package/src/modules/Users/Roles/hooks.tsx +78 -0
  169. package/src/modules/Users/Roles/index.tsx +256 -0
  170. package/src/modules/Users/Roles/style.tsx +23 -0
  171. package/src/modules/Users/Roles/utils.tsx +12 -0
  172. package/src/modules/Users/UserCreate/OptionItem/index.tsx +45 -0
  173. package/src/modules/Users/UserCreate/OptionItem/style.tsx +48 -0
  174. package/src/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/index.tsx +48 -0
  175. package/src/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/style.tsx +42 -0
  176. package/src/modules/Users/UserCreate/SiteItem/RolesModal/index.tsx +140 -0
  177. package/src/modules/Users/UserCreate/SiteItem/RolesModal/style.tsx +94 -0
  178. package/src/modules/Users/UserCreate/SiteItem/index.tsx +103 -22
  179. package/src/modules/Users/UserCreate/SiteItem/style.tsx +49 -6
  180. package/src/modules/Users/UserCreate/index.tsx +278 -121
  181. package/src/modules/Users/UserCreate/style.tsx +71 -4
  182. package/src/modules/Users/UserEdit/index.tsx +71 -24
  183. package/src/modules/Users/UserForm/atoms.tsx +40 -8
  184. package/src/modules/Users/UserForm/index.tsx +335 -116
  185. package/src/modules/Users/UserForm/style.tsx +70 -6
  186. package/src/modules/Users/UserList/BulkHeader/TableHeader/index.tsx +61 -31
  187. package/src/modules/Users/UserList/BulkHeader/TableHeader/style.tsx +18 -4
  188. package/src/modules/Users/UserList/BulkHeader/index.tsx +10 -3
  189. package/src/modules/Users/UserList/UserItem/index.tsx +121 -38
  190. package/src/modules/Users/UserList/UserItem/style.tsx +32 -14
  191. package/src/modules/Users/UserList/hooks.tsx +13 -8
  192. package/src/modules/Users/UserList/index.tsx +67 -29
  193. package/src/modules/Users/UserList/utils.tsx +1 -1
  194. package/src/modules/Users/index.tsx +20 -3
  195. package/src/routes/index.tsx +9 -17
  196. package/src/routes/multisite.tsx +73 -8
  197. package/src/routes/site.tsx +96 -10
  198. package/src/types/index.tsx +42 -1
  199. package/tsconfig.paths.json +1 -0
  200. package/src/__tests__/components/Avatar/__snapshots__/Avatar.test.tsx.snap +0 -61
  201. package/src/modules/Users/UserList/HeaderMenus/Name/index.tsx +0 -55
@@ -0,0 +1,48 @@
1
+ import React from "react";
2
+
3
+ import { CheckField, Tag } from "@ax/components";
4
+ import { ICheck, IRole } from "@ax/types";
5
+
6
+ import * as S from "./style";
7
+
8
+ const RoleItem = (props: IRoleItemProps): JSX.Element => {
9
+ const { role, onChange, onClick, isChecked = false, isSelected = false, isReadOnly = false } = props;
10
+
11
+ const handleClick = () => {
12
+ onClick && onClick(role);
13
+ onChange && onChange({ value: role.id, isChecked: !isChecked });
14
+ };
15
+
16
+ return (
17
+ <S.RoleItem
18
+ role="rowgroup"
19
+ selected={isChecked}
20
+ isSelected={isSelected}
21
+ isReadOnly={isReadOnly}
22
+ data-testid="roles-modal-item"
23
+ >
24
+ {!isReadOnly && (
25
+ <S.CheckCell role="cell">
26
+ <CheckField name={role.name} value={role.id} checked={isChecked} onChange={onChange} />
27
+ </S.CheckCell>
28
+ )}
29
+ <S.TitleCell onClick={handleClick} data-testid="roles-modal-item-title">
30
+ <S.Name>
31
+ <Tag text={role.name} color={role.hex} />
32
+ </S.Name>
33
+ <S.Description>{role.description}</S.Description>
34
+ </S.TitleCell>
35
+ </S.RoleItem>
36
+ );
37
+ };
38
+
39
+ export interface IRoleItemProps {
40
+ role: IRole;
41
+ isChecked?: boolean;
42
+ isSelected?: boolean;
43
+ onChange?(value: ICheck): void;
44
+ onClick?(role: IRole): void;
45
+ isReadOnly?: boolean;
46
+ }
47
+
48
+ export default RoleItem;
@@ -0,0 +1,42 @@
1
+ import styled from "styled-components";
2
+ import { Cell, Row } from "@ax/components/TableList/TableItem/style";
3
+
4
+ const CheckCell = styled(Cell)`
5
+ padding-left: ${(p) => p.theme.spacing.m};
6
+ width: 32px;
7
+ justify-content: flex-start;
8
+ label {
9
+ margin-bottom: ${(p) => p.theme.spacing.s};
10
+ }
11
+ `;
12
+
13
+ const TitleCell = styled(Cell)`
14
+ color: ${(p) => p.theme.color.textHighEmphasis};
15
+ width: 100%;
16
+ `;
17
+
18
+ const Name = styled.div`
19
+ ${(p) => p.theme.textStyle.uiS};
20
+ color: ${(p) => p.theme.color.textMediumEmphasis};
21
+ margin-bottom: ${(p) => p.theme.spacing.xxs};
22
+ `;
23
+
24
+ const Description = styled.div`
25
+ ${(p) => p.theme.textStyle.fieldContent};
26
+ color: ${(p) => p.theme.color.textHighEmphasis};
27
+ `;
28
+
29
+ const RoleItem = styled(Row)<{ isSelected: boolean; isReadOnly: boolean }>`
30
+ border: ${(p) => (p.isSelected ? `2px solid ${p.theme.color.interactive01}` : `1px solid ${p.theme.color.uiLine}`)};
31
+ :before {
32
+ background-color: transparent;
33
+ }
34
+ :hover {
35
+ cursor: ${(p) => (p.isReadOnly ? "default" : "pointer")};
36
+ &:before {
37
+ background-color: ${(p) => (p.isReadOnly ? "transparent" : p.theme.color.overlayHoverPrimary)};
38
+ }
39
+ }
40
+ `;
41
+
42
+ export { CheckCell, TitleCell, RoleItem, Name, Description };
@@ -0,0 +1,140 @@
1
+ import React, { useState, useEffect } from "react";
2
+
3
+ import { Button, Modal, NoteField, Icon } from "@ax/components";
4
+ import { ICheck, IRole } from "@ax/types";
5
+ import { useModal } from "@ax/hooks";
6
+
7
+ import RoleItem from "./RoleItem";
8
+
9
+ import * as S from "./style";
10
+
11
+ const RolesModal = (props: IRolesModalProps): JSX.Element => {
12
+ const { roles, isOpen, toggleModal, addRoles, selectedRoles, allSites, isGlobal } = props;
13
+
14
+ const [rolesChecked, setRolesChecked] = useState<number[]>(selectedRoles ? selectedRoles : []);
15
+ const [selected, setSelected] = useState<IRole | undefined>(roles ? roles[0] : undefined);
16
+
17
+ const { isOpen: isAlertOpen, toggleModal: toggleAlertModal } = useModal(false);
18
+
19
+ useEffect(() => {
20
+ setRolesChecked(selectedRoles ? selectedRoles : []);
21
+ }, [selectedRoles]);
22
+
23
+ const handleChange = (value: ICheck) => {
24
+ if (value.isChecked) {
25
+ setRolesChecked((state) => [...state, value.value]);
26
+ } else {
27
+ const updatedRoles = rolesChecked.filter((id: number) => id !== value.value);
28
+ setRolesChecked(updatedRoles);
29
+ }
30
+ };
31
+
32
+ const handleClick = (role: IRole) => setSelected(role);
33
+
34
+ const checkRoles = () => (allSites ? toggleAlertModal() : handleAddRoles());
35
+
36
+ const handleAddRoles = () => {
37
+ addRoles(rolesChecked);
38
+ isAlertOpen && toggleAlertModal();
39
+ toggleModal();
40
+ };
41
+
42
+ const mainModalAction = {
43
+ title: "Update User Roles",
44
+ onClick: handleAddRoles,
45
+ };
46
+
47
+ const secondaryModalAction = { title: "Cancel", onClick: toggleAlertModal };
48
+
49
+ const rolePermissions = isGlobal ? selected?.permissions.globalPermissions : selected?.permissions.sitePermissions
50
+
51
+ return (
52
+ <>
53
+ <Modal isOpen={isOpen} hide={toggleModal} title="Add User Roles" size="XL" overflow="hidden">
54
+ {isOpen && (
55
+ <S.ModalContent data-testid="modal-roles-content">
56
+ <S.RoleList>
57
+ <S.Selected>{rolesChecked.length} Roles Selected</S.Selected>
58
+ {roles &&
59
+ roles
60
+ .filter((role: IRole) => role.active)
61
+ .map((role: IRole) => {
62
+ const isChecked = rolesChecked.includes(role.id);
63
+ return (
64
+ <RoleItem
65
+ key={role.id}
66
+ role={role}
67
+ isChecked={isChecked}
68
+ isSelected={role.id === selected?.id}
69
+ onChange={handleChange}
70
+ onClick={handleClick}
71
+ />
72
+ );
73
+ })}
74
+ </S.RoleList>
75
+ <S.SidePanel>
76
+ <S.RoleInfo>
77
+ {selected && (
78
+ <div data-testid="permissions-wrapper">
79
+ <NoteField value={{ title: selected.name, text: selected.description }} />
80
+ <S.PermissionsList>
81
+ <S.PermissionsListTitle>
82
+ Permissions ({selected.permissions.totalPermissions})
83
+ </S.PermissionsListTitle>
84
+ <S.PermissionsWrapper>
85
+ {rolePermissions && rolePermissions.map((permission: { name: string; key: string }) => (
86
+ <S.Permission key={permission.key}>
87
+ <S.IconWrapper data-testid="success-icon">
88
+ <Icon name="done" size="16" />
89
+ </S.IconWrapper>
90
+ {permission.name}
91
+ </S.Permission>
92
+ ))}
93
+ </S.PermissionsWrapper>
94
+ </S.PermissionsList>
95
+ </div>
96
+ )}
97
+ </S.RoleInfo>
98
+ <S.ButtonWrapper>
99
+ <Button type="button" buttonStyle="line" onClick={checkRoles}>
100
+ Add User Role
101
+ </Button>
102
+ </S.ButtonWrapper>
103
+ </S.SidePanel>
104
+ </S.ModalContent>
105
+ )}
106
+ </Modal>
107
+ <Modal
108
+ isOpen={isAlertOpen}
109
+ hide={toggleAlertModal}
110
+ title="Update Roles"
111
+ size="S"
112
+ mainAction={mainModalAction}
113
+ secondaryAction={secondaryModalAction}
114
+ >
115
+ {isAlertOpen && (
116
+ <S.ModalContentPadding>
117
+ <p>
118
+ This user can access all existing and future sites as a viewer. By changing the role on this site,{" "}
119
+ <strong>‘All site permissions’ will be removed from the user,</strong> but they will{" "}
120
+ <strong>still have access to all sites</strong> they have access currently. This user must be given{" "}
121
+ <strong>access manually</strong> when creating a new site.
122
+ </p>
123
+ </S.ModalContentPadding>
124
+ )}
125
+ </Modal>
126
+ </>
127
+ );
128
+ };
129
+
130
+ export interface IRolesModalProps {
131
+ roles?: IRole[];
132
+ isOpen: boolean;
133
+ selectedRoles?: number[];
134
+ toggleModal(): void;
135
+ addRoles(roles: number[]): void;
136
+ isGlobal: boolean;
137
+ allSites?: boolean;
138
+ }
139
+
140
+ export default RolesModal;
@@ -0,0 +1,94 @@
1
+ import styled from "styled-components";
2
+
3
+ const ModalContent = styled.div`
4
+ display: flex;
5
+ max-height: calc(640px - 58px);
6
+ width: 100%;
7
+ overflow: hidden;
8
+ `;
9
+
10
+ const RoleList = styled.div`
11
+ padding: ${(p) => `${p.theme.spacing.s} ${p.theme.spacing.m}`};
12
+ overflow: auto;
13
+ width: 100%;
14
+ `;
15
+
16
+ const SidePanel = styled.div`
17
+ display: flex;
18
+ flex-flow: column nowrap;
19
+ background-color: ${(p) => p.theme.color.uiBarBackground};
20
+ width: ${(p) => `calc(${p.theme.spacing.xl} * 5)`};
21
+ border-left: 1px solid ${(p) => p.theme.color.uiLine};
22
+ flex-shrink: 0;
23
+ `;
24
+
25
+ const PermissionsList = styled.div``;
26
+
27
+ const PermissionsWrapper = styled.div`
28
+ height: 340px;
29
+ margin-right: -${(p) => p.theme.spacing.m};
30
+ overflow: auto;
31
+ `;
32
+
33
+ const PermissionsListTitle = styled.div`
34
+ color: ${(p) => p.theme.colors.textMediumEmphasis};
35
+ ${(p) => p.theme.textStyle.uiS};
36
+ margin-top: ${(p) => p.theme.spacing.s};
37
+ margin-bottom: ${(p) => p.theme.spacing.xs};
38
+ `;
39
+
40
+ const Permission = styled.div`
41
+ display: flex;
42
+ align-items: center;
43
+ margin-bottom: ${(p) => p.theme.spacing.xs};
44
+ `;
45
+
46
+ const RoleInfo = styled.div`
47
+ padding: ${(p) => p.theme.spacing.m};
48
+ height: calc(640px - 58px);
49
+ `;
50
+
51
+ const IconWrapper = styled.span`
52
+ padding-right: ${(p) => p.theme.spacing.s};
53
+ height: 16px;
54
+ `;
55
+
56
+ const ButtonWrapper = styled.div`
57
+ display: flex;
58
+ bottom: 0;
59
+ position: absolute;
60
+ height: 72px;
61
+ width: ${(p) => `calc(${p.theme.spacing.xl} * 5)`};
62
+ background-color: ${(p) => p.theme.color.uiBarBackground};
63
+ border-top: 1px solid ${(p) => p.theme.color.uiLine};
64
+ justify-content: flex-end;
65
+ padding: ${(p) => `${p.theme.spacing.s} ${p.theme.spacing.m} ${p.theme.spacing.m} ${p.theme.spacing.m}`};
66
+ `;
67
+
68
+ const Selected = styled.div`
69
+ ${(p) => p.theme.textStyle.headingXS};
70
+ color: ${(p) => p.theme.color.textMediumEmphasis};
71
+ margin-bottom: ${(p) => p.theme.spacing.s};
72
+ `;
73
+
74
+ const ModalContentPadding = styled.div`
75
+ display: flex;
76
+ height: 100%;
77
+ wdith: 100%;
78
+ padding: ${(p) => p.theme.spacing.m};
79
+ `;
80
+
81
+ export {
82
+ ModalContent,
83
+ RoleList,
84
+ SidePanel,
85
+ PermissionsList,
86
+ PermissionsListTitle,
87
+ PermissionsWrapper,
88
+ Permission,
89
+ IconWrapper,
90
+ ButtonWrapper,
91
+ RoleInfo,
92
+ Selected,
93
+ ModalContentPadding,
94
+ };
@@ -1,44 +1,125 @@
1
1
  import React from "react";
2
2
 
3
- import { CheckField } from "@ax/components";
3
+ import { CheckField, Button, ElementsTooltip } from "@ax/components";
4
+ import { useModal } from "@ax/hooks";
5
+
6
+ import { IRole } from "@ax/types";
7
+ import RolesModal from "./RolesModal";
4
8
 
5
9
  import * as S from "./style";
6
10
 
7
- const SiteItem = (props: IProps) => {
8
- const { item, sites, disabled = false, readOnly = false } = props;
11
+ const SiteItem = (props: ISiteItemProps): JSX.Element => {
12
+ const { item, sites, roles, disabled = false, readOnly = false, addRoles, selected, featured, description } = props;
9
13
  const { name, id, onChange } = item;
10
14
  const isSelected = sites.includes(id);
11
15
 
12
- const onClick = (e: React.MouseEvent) => {
16
+ const { isOpen, toggleModal } = useModal();
17
+
18
+ const handleClick = (e: React.MouseEvent) => {
13
19
  if (readOnly) return;
14
20
  e.preventDefault();
15
21
  e.stopPropagation();
16
- onChange();
22
+ onChange(id);
17
23
  };
18
24
 
25
+ const handleChange = () => onChange(id);
26
+
27
+ const handleAddRoles = (roles: number[]) => addRoles && addRoles({ siteId: id, roles });
28
+
29
+ const rolesString =
30
+ roles && roles.filter((role: IRole) => selected && selected.includes(role.id)).map((role: IRole) => role.name);
31
+ const colors =
32
+ rolesString &&
33
+ rolesString.reduce((prev, current) => {
34
+ const color: IRole | undefined = roles.find((role: IRole) => role.name === current);
35
+ return { ...prev, [current]: color?.hex };
36
+ }, {});
37
+
38
+ const textButton = selected && selected.length ? "Edit Roles" : "Add Roles";
39
+ const iconButton = selected && selected.length ? "edit" : undefined;
40
+
19
41
  return (
20
- <S.SiteItem
21
- disabled={disabled}
22
- role="rowgroup"
23
- readOnly={readOnly}
24
- selected={!readOnly && isSelected}
25
- onClick={onClick}
26
- >
27
- {!readOnly ? (
28
- <S.CheckCell role="cell">
29
- <CheckField disabled={disabled} name="check" value={id} checked={isSelected} onChange={onChange} />
30
- </S.CheckCell>
31
- ) : null}
32
- <S.NameCell disabled={disabled}>{name}</S.NameCell>
33
- </S.SiteItem>
42
+ <>
43
+ <S.SiteItem
44
+ disabled={disabled}
45
+ role="rowgroup"
46
+ readOnly={readOnly}
47
+ selected={!readOnly && isSelected}
48
+ data-testid="user-site-item"
49
+ isChecked={featured && isSelected}
50
+ >
51
+ {!readOnly ? (
52
+ <S.CheckCell role="cell" featured={featured} onClick={handleClick} data-testid="check-cell">
53
+ <CheckField disabled={disabled} name={name} value={id} checked={isSelected} onChange={handleChange} />
54
+ </S.CheckCell>
55
+ ) : null}
56
+ {featured ? (
57
+ <S.WrapperCell role="cell" data-testid="wrapper-cell-featured">
58
+ <S.Name onClick={handleClick}>{name}</S.Name>
59
+ <S.Description onClick={handleClick}>{description}</S.Description>
60
+ <S.Actions hasTags={rolesString ? rolesString.length > 0 : false}>
61
+ <ElementsTooltip
62
+ elements={rolesString}
63
+ maxChar={30}
64
+ rounded={true}
65
+ defaultElements={2}
66
+ elementsPerRow={2}
67
+ colors={colors}
68
+ />
69
+ {!readOnly && (
70
+ <Button type="button" buttonStyle="text" onClick={toggleModal} icon={iconButton}>
71
+ {textButton}
72
+ </Button>
73
+ )}
74
+ </S.Actions>
75
+ </S.WrapperCell>
76
+ ) : (
77
+ <>
78
+ <S.NameCell role="cell" disabled={disabled} onClick={handleClick} data-testid="name-cell">
79
+ {name}
80
+ </S.NameCell>
81
+ <S.RolesCell role="cell" onClick={handleClick}>
82
+ <ElementsTooltip
83
+ elements={rolesString}
84
+ maxChar={30}
85
+ rounded={true}
86
+ defaultElements={2}
87
+ elementsPerRow={2}
88
+ colors={colors}
89
+ />
90
+ </S.RolesCell>
91
+ {!readOnly && (
92
+ <S.ActionCell role="cell" data-testid="action-cell">
93
+ <Button type="button" buttonStyle="text" onClick={toggleModal} icon={iconButton}>
94
+ {textButton}
95
+ </Button>
96
+ </S.ActionCell>
97
+ )}
98
+ </>
99
+ )}
100
+ </S.SiteItem>
101
+ <RolesModal
102
+ isOpen={isOpen}
103
+ toggleModal={toggleModal}
104
+ roles={roles}
105
+ addRoles={handleAddRoles}
106
+ selectedRoles={selected}
107
+ isGlobal={id==="global"}
108
+ />
109
+ </>
34
110
  );
35
111
  };
36
112
 
37
- interface IProps {
38
- item: { name: string; id: number | string; onChange: () => void };
113
+ export interface ISiteItemProps {
114
+ item: { name: string; id: number | string; onChange: (id: number | string) => void };
39
115
  sites: (string | number)[];
116
+ roles?: IRole[];
117
+ addRoles?(newRoles: any): void;
118
+ selected?: number[];
40
119
  disabled?: boolean;
41
120
  readOnly?: boolean;
121
+ featured?: boolean;
122
+ description?: string;
42
123
  }
43
124
 
44
- export default SiteItem;
125
+ export default SiteItem;
@@ -1,30 +1,73 @@
1
1
  import styled from "styled-components";
2
2
  import { Cell, Row } from "@ax/components/TableList/TableItem/style";
3
3
 
4
- const CheckCell = styled(Cell)`
5
- padding-left: ${(p) => p.theme.spacing.m};
4
+ const CheckCell = styled(Cell)<{ featured?: boolean }>`
5
+ padding: ${(p) => (p.featured ? p.theme.spacing.s : `12px ${p.theme.spacing.s}`)};
6
6
  width: 32px;
7
+ justify-content: ${(p) => (p.featured ? "flex-start" : "center")};
7
8
  label {
8
9
  margin-bottom: ${(p) => p.theme.spacing.s};
9
10
  }
10
11
  `;
11
12
 
12
13
  const NameCell = styled(Cell)<{ disabled?: boolean }>`
13
- width: 40%;
14
14
  ${(p) => p.theme.textStyle.uiL};
15
15
  color: ${(p) => (p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.textHighEmphasis)};
16
+ flex-grow: 1;
17
+ padding: ${(p) => `12px ${p.theme.spacing.s}`};
16
18
  `;
17
19
 
18
- const SiteItem = styled(Row)<{ disabled?: boolean; readOnly?: boolean }>`
19
- pointer-events: ${(p) => (p.disabled || p.readOnly ? "none" : "auto")};
20
+ const RolesCell = styled(Cell)`
21
+ padding: ${(p) => `12px ${p.theme.spacing.s}`};
22
+ `;
23
+
24
+ const ActionCell = styled(Cell)`
25
+ flex: 0 0 150px;
26
+ padding: ${(p) => `12px ${p.theme.spacing.s}`};
27
+ `;
28
+
29
+ const SiteItem = styled(Row)<{ disabled?: boolean; readOnly?: boolean; isChecked?: boolean }>`
30
+ pointer-events: ${(p) => (p.disabled ? "none" : "auto")};
31
+ border: ${(p) => (p.isChecked ? `2px solid ${p.theme.color.interactive01}` : `1px solid ${p.theme.color.uiLine}`)};
32
+ :before {
33
+ background-color: transparent;
34
+ }
20
35
  &:hover {
36
+ cursor: ${(p) => (p.readOnly ? "default" : "pointer")};
21
37
  background-color: ${(p) =>
22
38
  p.readOnly
23
39
  ? p.theme.color.uiBackground02
24
40
  : p.selected
25
41
  ? p.theme.color.overlayPressedPrimary
26
42
  : p.theme.color.overlayHoverPrimary};
43
+ &:before {
44
+ background-color: ${(p) => (p.readOnly ? "transparent" : p.theme.color.overlayHoverPrimary)};
45
+ }
46
+ }
47
+ `;
48
+
49
+ const WrapperCell = styled(Cell)`
50
+ width: 100%;
51
+ `;
52
+
53
+ const Name = styled.div`
54
+ ${(p) => p.theme.textStyle.uiL};
55
+ color: ${(p) => p.theme.color.textHighEmphasis};
56
+ margin-bottom: ${(p) => p.theme.spacing.xxs};
57
+ `;
58
+
59
+ const Description = styled.div`
60
+ ${(p) => p.theme.textStyle.uiXS};
61
+ color: ${(p) => p.theme.color.textMediumEmphasis};
62
+ margin-bottom: ${(p) => p.theme.spacing.s};
63
+ `;
64
+
65
+ const Actions = styled.div<{ hasTags: boolean }>`
66
+ display: flex;
67
+ align-items: center;
68
+ & > div {
69
+ margin-right: ${(p) => (p.hasTags ? p.theme.spacing.s : "0")};
27
70
  }
28
71
  `;
29
72
 
30
- export { CheckCell, NameCell, SiteItem };
73
+ export { CheckCell, NameCell, RolesCell, ActionCell, SiteItem, WrapperCell, Name, Description, Actions };