@griddo/ax 11.15.9 → 11.16.0-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 (95) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/RestrictionsModal/CurrentAccessList/CurrentAccessList.test.tsx +173 -0
  3. package/src/__tests__/components/RestrictionsModal/OptionsStep/OptionsStep.test.tsx +160 -0
  4. package/src/__tests__/components/RestrictionsModal/RestrictionsModal.test.tsx +134 -0
  5. package/src/__tests__/components/RestrictionsModal/RolesList/RolesList.test.tsx +234 -0
  6. package/src/__tests__/components/RestrictionsModal/UsersList/UsersList.test.tsx +288 -0
  7. package/src/__tests__/hooks/users.test.tsx +382 -0
  8. package/src/api/pages.tsx +24 -1
  9. package/src/api/sites.tsx +14 -14
  10. package/src/api/structuredData.tsx +17 -7
  11. package/src/components/Browser/index.tsx +12 -0
  12. package/src/components/Browser/style.tsx +5 -1
  13. package/src/components/ConfigPanel/Form/index.tsx +11 -10
  14. package/src/components/ContentItem/index.tsx +31 -0
  15. package/src/components/ContentItem/style.tsx +43 -0
  16. package/src/components/Fields/ImageField/index.tsx +2 -1
  17. package/src/components/Fields/RadioField/index.tsx +3 -3
  18. package/src/components/Fields/RadioField/style.tsx +1 -1
  19. package/src/components/FloatingNote/index.tsx +12 -1
  20. package/src/components/FloatingNote/style.tsx +2 -1
  21. package/src/components/Modal/style.tsx +11 -0
  22. package/src/components/PageFinder/SelectionListItem/index.tsx +27 -17
  23. package/src/components/PageFinder/index.tsx +65 -28
  24. package/src/components/PageFinder/style.tsx +0 -1
  25. package/src/components/RestrictionsModal/CurrentAccessList/index.tsx +74 -0
  26. package/src/components/RestrictionsModal/CurrentAccessList/style.tsx +155 -0
  27. package/src/components/RestrictionsModal/OptionsStep/index.tsx +55 -0
  28. package/src/components/RestrictionsModal/OptionsStep/style.tsx +29 -0
  29. package/src/components/RestrictionsModal/RolesList/RoleItem/index.tsx +54 -0
  30. package/src/components/RestrictionsModal/RolesList/RoleItem/style.tsx +34 -0
  31. package/src/components/RestrictionsModal/RolesList/index.tsx +107 -0
  32. package/src/components/RestrictionsModal/RolesList/style.tsx +76 -0
  33. package/src/components/RestrictionsModal/UsersList/UserItem/index.tsx +78 -0
  34. package/src/components/RestrictionsModal/UsersList/UserItem/style.tsx +73 -0
  35. package/src/components/RestrictionsModal/UsersList/index.tsx +151 -0
  36. package/src/components/RestrictionsModal/UsersList/style.tsx +55 -0
  37. package/src/components/RestrictionsModal/index.tsx +181 -0
  38. package/src/components/RestrictionsModal/style.tsx +31 -0
  39. package/src/components/RestrictionsModal/utils.tsx +24 -0
  40. package/src/components/ScheduleModal/index.tsx +32 -8
  41. package/src/components/SelectionComponent/index.tsx +65 -0
  42. package/src/components/SelectionComponent/style.tsx +69 -0
  43. package/src/components/TableFilters/RoleFilter/index.tsx +3 -3
  44. package/src/components/TableList/TableItem/style.tsx +7 -13
  45. package/src/components/Tabs/index.tsx +2 -1
  46. package/src/components/UserRolesAndSites/index.tsx +2 -2
  47. package/src/components/index.tsx +6 -0
  48. package/src/containers/PageEditor/actions.tsx +43 -0
  49. package/src/containers/PageEditor/constants.tsx +1 -0
  50. package/src/containers/PageEditor/interfaces.tsx +26 -19
  51. package/src/containers/PageEditor/reducer.tsx +32 -19
  52. package/src/containers/Users/reducer.tsx +1 -0
  53. package/src/helpers/forms.tsx +3 -1
  54. package/src/hooks/index.tsx +2 -1
  55. package/src/hooks/users.tsx +154 -14
  56. package/src/modules/ActivityLog/LogFilters/UserFilter/index.tsx +11 -12
  57. package/src/modules/Content/PageItem/index.tsx +17 -10
  58. package/src/modules/Content/index.tsx +1 -3
  59. package/src/modules/GlobalEditor/Editor/index.tsx +6 -0
  60. package/src/modules/GlobalEditor/PageBrowser/index.tsx +6 -0
  61. package/src/modules/GlobalEditor/Preview/index.tsx +4 -2
  62. package/src/modules/GlobalEditor/index.tsx +72 -45
  63. package/src/modules/Navigation/Menus/List/Table/ConfigPanel/Form/index.tsx +3 -5
  64. package/src/modules/Navigation/Menus/List/Table/ConfigPanel/index.tsx +4 -4
  65. package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/ConnectedField/index.tsx +2 -3
  66. package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +3 -4
  67. package/src/modules/Navigation/Menus/List/Table/SidePanel/index.tsx +5 -6
  68. package/src/modules/PageEditor/Editor/index.tsx +6 -0
  69. package/src/modules/PageEditor/PageBrowser/index.tsx +6 -0
  70. package/src/modules/PageEditor/Preview/index.tsx +9 -2
  71. package/src/modules/PageEditor/atoms.tsx +110 -3
  72. package/src/modules/PageEditor/index.tsx +76 -95
  73. package/src/modules/Settings/Integrations/IntegrationForm/index.tsx +1 -3
  74. package/src/modules/Sites/SitesList/GridView/GridSiteItem/style.tsx +19 -2
  75. package/src/modules/Sites/SitesList/WelcomeModal/FinalStep/index.tsx +2 -2
  76. package/src/modules/Sites/SitesList/WelcomeModal/utils.ts +2 -2
  77. package/src/modules/StructuredData/Form/ConnectedField/index.tsx +2 -2
  78. package/src/modules/StructuredData/Form/index.tsx +120 -75
  79. package/src/modules/StructuredData/Form/style.tsx +7 -1
  80. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +15 -8
  81. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +15 -9
  82. package/src/modules/StructuredData/{StructuredDataList/StructuredDataItem/utils.tsx → utils.tsx} +16 -2
  83. package/src/modules/Users/Profile/atoms.tsx +62 -4
  84. package/src/modules/Users/Profile/index.tsx +83 -4
  85. package/src/modules/Users/Profile/style.tsx +60 -0
  86. package/src/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/index.tsx +3 -5
  87. package/src/modules/Users/UserCreate/SiteItem/index.tsx +2 -2
  88. package/src/modules/Users/UserCreate/atoms.tsx +69 -0
  89. package/src/modules/Users/UserCreate/index.tsx +149 -70
  90. package/src/modules/Users/UserCreate/style.tsx +24 -1
  91. package/src/modules/Users/UserForm/index.tsx +260 -146
  92. package/src/modules/Users/UserForm/style.tsx +13 -1
  93. package/src/modules/Users/UserList/UserItem/index.tsx +3 -3
  94. package/src/types/index.tsx +19 -6
  95. package/src/types/logs.tsx +1 -1
@@ -1,15 +1,28 @@
1
- import { useState } from "react";
1
+ import { useEffect, useMemo, useState } from "react";
2
2
  import { connect } from "react-redux";
3
- import type { ISite, IRootState, IUser, IRole, ISiteRoles } from "@ax/types";
3
+
4
+ import {
5
+ Button,
6
+ ErrorToast,
7
+ FieldsBehavior,
8
+ FloatingPanel,
9
+ MainWrapper,
10
+ Modal,
11
+ Notification,
12
+ PageFinder,
13
+ SearchField,
14
+ } from "@ax/components";
4
15
  import { appActions } from "@ax/containers/App";
5
16
  import { usersActions } from "@ax/containers/Users";
6
- import { ErrorToast, FieldsBehavior, MainWrapper, SearchField, Notification, Button, Modal } from "@ax/components";
7
- import { useModal } from "@ax/hooks";
17
+ import { isValidEmail } from "@ax/helpers/forms";
18
+ import { useModals } from "@ax/hooks";
19
+ import type { IPage, IRole, IRootState, ISite, IUser, UserPagePermissionEntry, UserRoleAssignment } from "@ax/types";
8
20
 
21
+ import { PagePermissionsList, SettingsSection } from "./atoms";
22
+ import OptionItem from "./OptionItem";
9
23
  import SiteItem from "./SiteItem";
10
24
  import RolesModal from "./SiteItem/RolesModal";
11
25
  import RoleItem from "./SiteItem/RolesModal/RoleItem";
12
- import OptionItem from "./OptionItem";
13
26
 
14
27
  import * as S from "./style";
15
28
 
@@ -18,18 +31,19 @@ const UserCreate = (props: IUserCreateProps) => {
18
31
 
19
32
  const isSiteView = !!site;
20
33
 
21
- const initState: IState = { name: "", email: "", roles: [], isSuperAdmin: false };
34
+ const initState: IState = { name: "", email: "", roles: [], pagePermissions: [], isSuperAdmin: false };
22
35
  const [state, setState] = useState(initState);
36
+ const [userAlreadyExists, setUserAlreadyExists] = useState(false);
37
+ const [selectedPages, setSelectedPages] = useState<IPage[]>([]);
23
38
 
24
- const getSortedSitesByName = (sites: ISite[]) =>
25
- sites.sort((site1: ISite, site2: ISite) => site1.name.localeCompare(site2.name));
26
- const sortedByNameSites = getSortedSitesByName(sites);
39
+ const { isOpen, toggleModal } = useModals(["roles", "advise", "pagePermissions"]);
27
40
 
28
- const [sitesList, setSiteList] = useState(sortedByNameSites);
29
- const [userAlreadyExists, setUserAlreadyExists] = useState(false);
41
+ const sortedByNameSites = useMemo(
42
+ () => [...sites].sort((site1: ISite, site2: ISite) => site1.name.localeCompare(site2.name)),
43
+ [sites],
44
+ );
30
45
 
31
- const { isOpen, toggleModal } = useModal(false);
32
- const { isOpen: isOpenAdvise, toggleModal: toggleAdviseModal } = useModal(false);
46
+ const findRolesBySiteId = (siteId: number | string) => state.roles.find((role) => role.siteId === siteId);
33
47
 
34
48
  const handleNameChange = (value: string) => setState({ ...state, name: value });
35
49
 
@@ -37,20 +51,21 @@ const UserCreate = (props: IUserCreateProps) => {
37
51
 
38
52
  const handleCreate = async () => {
39
53
  const { email } = state;
54
+ if (!isValidEmail(email)) {
55
+ return;
56
+ }
40
57
  const globalUser = users.find((user) => user.email === email);
41
58
  setUserAlreadyExists(false);
42
59
 
43
60
  const BASE_URL = isSiteView ? "/sites/users" : "/users";
44
61
 
45
- if (isOpenAdvise) {
46
- toggleAdviseModal();
62
+ if (isOpen("advise")) {
63
+ toggleModal("advise");
47
64
  }
48
65
 
49
66
  if (isSiteView && globalUser?.id) {
50
67
  const { id, roles } = globalUser;
51
- const userAlreadyExists = roles.find(
52
- (siteRole: ISiteRoles) => siteRole.siteId === "all" || siteRole.siteId === site.id,
53
- );
68
+ const userAlreadyExists = roles.find((siteRole) => siteRole.siteId === "all" || siteRole.siteId === site.id);
54
69
  if (userAlreadyExists) {
55
70
  setUserAlreadyExists(true);
56
71
  } else {
@@ -68,12 +83,12 @@ const UserCreate = (props: IUserCreateProps) => {
68
83
  }
69
84
  };
70
85
 
71
- const selectSite = (id: number | string) => {
86
+ const selectSite = (id: number | "global" | "all") => {
72
87
  const { roles } = state;
73
- const hasSite = roles.find((siteRole: ISiteRoles) => siteRole.siteId === id);
88
+ const hasSite = roles.find((siteRole) => siteRole.siteId === id);
74
89
  if (hasSite) {
75
90
  const filteredRoles = roles.filter(
76
- (siteRole: ISiteRoles) =>
91
+ (siteRole) =>
77
92
  (Number.isInteger(id) && siteRole.siteId !== id && siteRole.siteId !== "all") ||
78
93
  (!Number.isInteger(id) && siteRole.siteId !== id),
79
94
  );
@@ -83,23 +98,29 @@ const UserCreate = (props: IUserCreateProps) => {
83
98
  }
84
99
  };
85
100
 
101
+ const [filteredSites, setFilteredSites] = useState(sortedByNameSites);
102
+
103
+ useEffect(() => {
104
+ setFilteredSites(sortedByNameSites);
105
+ }, [sortedByNameSites]);
106
+
86
107
  const filterSitesList = (query: string) => {
87
- const filteredSites = sites.filter((site) =>
108
+ const filtered = sites.filter((site) =>
88
109
  site.name.toLowerCase().replace(" ", "").includes(query.toLowerCase().replace(" ", "")),
89
110
  );
90
- const sortedSites = getSortedSitesByName(filteredSites);
91
- setSiteList(sortedSites);
111
+ const sorted = [...filtered].sort((site1: ISite, site2: ISite) => site1.name.localeCompare(site2.name));
112
+ setFilteredSites(sorted);
92
113
  };
93
114
 
94
- const handleAddRoles = (newRoles: ISiteRoles) => {
95
- const oldRoles = state.roles.filter((role: ISiteRoles) => role.siteId !== newRoles.siteId);
115
+ const handleAddRoles = (newRoles: UserRoleAssignment) => {
116
+ const oldRoles = state.roles.filter((role) => role.siteId !== newRoles.siteId);
96
117
  const updatedRoles = newRoles.roles.length > 0 ? [...oldRoles, newRoles] : oldRoles;
97
118
  setState({ ...state, roles: updatedRoles });
98
119
  };
99
120
 
100
121
  const handleAddSiteRoles = (newRoles: number[]) => {
101
122
  if (!site) return;
102
- const oldRoles = state.roles.filter((role: ISiteRoles) => role.siteId !== site.id);
123
+ const oldRoles = state.roles.filter((role) => role.siteId !== site.id);
103
124
  const newSiteRoles = { siteId: site.id, roles: newRoles };
104
125
  const updatedRoles = newRoles.length > 0 ? [...oldRoles, newSiteRoles] : oldRoles;
105
126
  setState({ ...state, roles: updatedRoles });
@@ -107,25 +128,42 @@ const UserCreate = (props: IUserCreateProps) => {
107
128
 
108
129
  const toggleSuperAdmin = () => setState({ ...state, isSuperAdmin: !state.isSuperAdmin });
109
130
 
131
+ const handleSetPage = (pages: IPage | IPage[]) => {
132
+ const pagesArray = Array.isArray(pages) ? pages : [pages];
133
+ const pageIds = pagesArray.map((p) => p.id);
134
+ const siteId: "global" | number = isSiteView ? site!.id : "global";
135
+
136
+ const newEntry: UserPagePermissionEntry = { siteId, pageIds };
137
+
138
+ const currentPagePermissions = state.pagePermissions || [];
139
+ const existingIndex = currentPagePermissions.findIndex((entry) => entry.siteId === siteId);
140
+ const newPagePermissions: UserPagePermissionEntry[] =
141
+ existingIndex >= 0
142
+ ? currentPagePermissions.map((entry, index) => (index === existingIndex ? newEntry : entry))
143
+ : [...currentPagePermissions, newEntry];
144
+
145
+ setState({ ...state, pagePermissions: newPagePermissions });
146
+ setSelectedPages(pagesArray);
147
+ toggleModal("pagePermissions");
148
+ };
149
+
110
150
  const rightButtonProps = {
111
151
  label: "Add User",
112
- action: state.roles.length === 0 && !state.isSuperAdmin ? toggleAdviseModal : handleCreate,
152
+ action: state.roles.length === 0 && !state.isSuperAdmin ? () => toggleModal("advise") : handleCreate,
113
153
  disabled: isSaving,
114
154
  };
115
155
 
116
156
  const name = state.name.trim() === "" ? "Name" : state.name;
117
157
 
118
- const sitesID = state.roles.map((roleSite: ISiteRoles) => roleSite.siteId);
158
+ const sitesID = state.roles.map((roleSite) => roleSite.siteId);
119
159
 
120
- const siteSelectedRoles = isSiteView
121
- ? state.roles.find((roleSite: ISiteRoles) => roleSite.siteId === site.id)
122
- : undefined;
160
+ const siteSelectedRoles = isSiteView ? findRolesBySiteId(site.id) : undefined;
123
161
 
124
- const rolesAll = state.roles.find((roleSite: ISiteRoles) => roleSite.siteId === "all");
162
+ const rolesAll = findRolesBySiteId("all");
125
163
  const allDescription =
126
164
  "The user will have access to all existing and future sites depending on the permissions assigned to the role.";
127
165
 
128
- const rolesGlobal = state.roles.find((roleSite: ISiteRoles) => roleSite.siteId === "global");
166
+ const rolesGlobal = findRolesBySiteId("global");
129
167
  const globalDescription = "Global data will be accessible to the user based on the permissions assigned to the role.";
130
168
 
131
169
  const mainModalAction = {
@@ -133,7 +171,7 @@ const UserCreate = (props: IUserCreateProps) => {
133
171
  onClick: handleCreate,
134
172
  };
135
173
 
136
- const secondaryModalAction = { title: "Cancel", onClick: toggleAdviseModal };
174
+ const secondaryModalAction = { title: "Cancel", onClick: () => toggleModal("advise") };
137
175
 
138
176
  return (
139
177
  <MainWrapper backLink={true} title="New User" rightButton={rightButtonProps}>
@@ -144,41 +182,43 @@ const UserCreate = (props: IUserCreateProps) => {
144
182
  </S.NotificationWrapper>
145
183
  )}
146
184
  <S.Wrapper>
147
- <S.SubTitle>User data</S.SubTitle>
148
- <S.NameTitle>{name}</S.NameTitle>
149
- <FieldsBehavior
150
- title="Name"
151
- name="name"
152
- fieldType="TextField"
153
- placeholder="Type a name"
154
- mandatory={true}
155
- value={state.name}
156
- onChange={handleNameChange}
157
- autoComplete="user-name"
158
- />
159
- <FieldsBehavior
160
- title="Email"
161
- name="email"
162
- fieldType="TextField"
163
- placeholder="Type an email"
164
- mandatory={true}
165
- value={state.email}
166
- onChange={handleEmailChange}
167
- autoComplete="user-email"
168
- />
185
+ <S.FieldsWrapper hasBoder={isSiteView}>
186
+ <S.SubTitle>User data</S.SubTitle>
187
+ <S.NameTitle>{name}</S.NameTitle>
188
+ <FieldsBehavior
189
+ title="Name"
190
+ name="name"
191
+ fieldType="TextField"
192
+ placeholder="Type a name"
193
+ mandatory={true}
194
+ value={state.name}
195
+ onChange={handleNameChange}
196
+ autoComplete="user-name"
197
+ />
198
+ <FieldsBehavior
199
+ title="Email"
200
+ name="email"
201
+ fieldType="TextField"
202
+ placeholder="Type an email"
203
+ mandatory={true}
204
+ value={state.email}
205
+ onChange={handleEmailChange}
206
+ autoComplete="user-email"
207
+ />
208
+ </S.FieldsWrapper>
169
209
  {isSiteView ? (
170
210
  <>
171
211
  <S.SettingsWrapper>
172
212
  <S.HeadingWrapper>
173
213
  <S.Heading>Roles Assigned</S.Heading>
174
214
  {(!siteSelectedRoles || siteSelectedRoles.roles.length === 0) && (
175
- <Button type="button" buttonStyle="text" onClick={toggleModal} icon="addCircle">
215
+ <Button type="button" buttonStyle="text" onClick={() => toggleModal("roles")} icon="addCircle">
176
216
  Add Role
177
217
  </Button>
178
218
  )}
179
219
  </S.HeadingWrapper>
180
220
  <S.SettingContent>
181
- <S.SettingText>You can add a one or more roles to this user.</S.SettingText>
221
+ <S.SettingText>You can add one or more roles to this user.</S.SettingText>
182
222
  </S.SettingContent>
183
223
  </S.SettingsWrapper>
184
224
  <S.RoleList data-testid="user-role-list">
@@ -187,14 +227,22 @@ const UserCreate = (props: IUserCreateProps) => {
187
227
  return role && <RoleItem key={role.name} role={role} isReadOnly={true} />;
188
228
  })}
189
229
  {siteSelectedRoles && siteSelectedRoles.roles.length > 0 && (
190
- <Button type="button" buttonStyle="line" onClick={toggleModal}>
230
+ <Button type="button" buttonStyle="line" onClick={() => toggleModal("roles")}>
191
231
  Manage user roles
192
232
  </Button>
193
233
  )}
194
234
  </S.RoleList>
235
+ <SettingsSection
236
+ heading="Page permissions"
237
+ description="You can give access only to a specific page/s to this user."
238
+ actionLabel="Add Page"
239
+ onActionClick={() => toggleModal("pagePermissions")}
240
+ showAction={selectedPages.length === 0}
241
+ />
242
+ <PagePermissionsList pages={selectedPages} onManageClick={() => toggleModal("pagePermissions")} />
195
243
  <RolesModal
196
- isOpen={isOpen}
197
- toggleModal={toggleModal}
244
+ isOpen={isOpen("roles")}
245
+ toggleModal={() => toggleModal("roles")}
198
246
  roles={roles}
199
247
  addRoles={handleAddSiteRoles}
200
248
  selectedRoles={siteSelectedRoles ? siteSelectedRoles.roles : []}
@@ -219,7 +267,7 @@ const UserCreate = (props: IUserCreateProps) => {
219
267
  onChange={toggleSuperAdmin}
220
268
  value={!state.isSuperAdmin}
221
269
  />
222
- <S.HelpText>Show the diference between types & roles in our Documentation</S.HelpText>
270
+ <S.HelpText>Show the difference between types & roles in our Documentation</S.HelpText>
223
271
  </S.OptionsWrapper>
224
272
  {!state.isSuperAdmin && (
225
273
  <S.MemberWrapper>
@@ -240,6 +288,18 @@ const UserCreate = (props: IUserCreateProps) => {
240
288
  description={globalDescription}
241
289
  />
242
290
  </S.GlobalPermissionsFieldWrapper>
291
+ {sitesID.includes("global") && (
292
+ <>
293
+ <SettingsSection
294
+ heading="Page permissions"
295
+ description="You can give access only to a specific page/s to this user."
296
+ actionLabel="Add Page"
297
+ onActionClick={() => toggleModal("pagePermissions")}
298
+ showAction={selectedPages.length === 0}
299
+ />
300
+ <PagePermissionsList pages={selectedPages} onManageClick={() => toggleModal("pagePermissions")} />
301
+ </>
302
+ )}
243
303
  <S.SettingsWrapper>
244
304
  <S.Heading>Sites access</S.Heading>
245
305
  <S.SettingContent>
@@ -270,9 +330,9 @@ const UserCreate = (props: IUserCreateProps) => {
270
330
  />
271
331
  </S.SelectAllSitesFieldWrapper>
272
332
  <S.SiteList data-testid="user-site-list">
273
- {sitesList.length > 0 &&
274
- sitesList.map((site: ISite) => {
275
- const rolesSite = state.roles.find((roleSite: ISiteRoles) => roleSite.siteId === site.id);
333
+ {filteredSites.length > 0 &&
334
+ filteredSites.map((site: ISite) => {
335
+ const rolesSite = state.roles.find((roleSite) => roleSite.siteId === site.id);
276
336
  return (
277
337
  <SiteItem
278
338
  disabled={!!rolesAll}
@@ -292,8 +352,8 @@ const UserCreate = (props: IUserCreateProps) => {
292
352
  )}
293
353
  </S.Wrapper>
294
354
  <Modal
295
- isOpen={isOpenAdvise}
296
- hide={toggleAdviseModal}
355
+ isOpen={isOpen("advise")}
356
+ hide={() => toggleModal("advise")}
297
357
  title="Create User?"
298
358
  secondaryAction={secondaryModalAction}
299
359
  mainAction={mainModalAction}
@@ -305,13 +365,31 @@ const UserCreate = (props: IUserCreateProps) => {
305
365
  <strong>won&apos;t have access to anything or view any content</strong>.
306
366
  </S.ModalContent>
307
367
  </Modal>
368
+ <FloatingPanel
369
+ title="Page Permissions"
370
+ toggleModal={() => toggleModal("pagePermissions")}
371
+ isOpen={isOpen("pagePermissions")}
372
+ >
373
+ <S.PanelContent>
374
+ {isOpen("pagePermissions") && (
375
+ <PageFinder
376
+ onClick={handleSetPage}
377
+ isOpen={isOpen("pagePermissions")}
378
+ multiple
379
+ globalContent={!isSiteView}
380
+ hideSites
381
+ alwaysShowButton
382
+ />
383
+ )}
384
+ </S.PanelContent>
385
+ </FloatingPanel>
308
386
  </MainWrapper>
309
387
  );
310
388
  };
311
389
 
312
390
  interface IDispatchProps {
313
391
  setHistoryPush(path: string): void;
314
- createUser(data: { name: string; email: string; roles: ISiteRoles[] }): Promise<boolean>;
392
+ createUser(data: { name: string; email: string; roles: UserRoleAssignment[] }): Promise<boolean>;
315
393
  updateUser(id: number, data: IUser, isProfile: boolean): Promise<boolean>;
316
394
  }
317
395
  interface IProfileProps {
@@ -325,8 +403,9 @@ interface IProfileProps {
325
403
  interface IState {
326
404
  name: string;
327
405
  email: string;
328
- roles: ISiteRoles[];
406
+ roles: UserRoleAssignment[];
329
407
  isSuperAdmin: boolean;
408
+ pagePermissions: UserPagePermissionEntry[];
330
409
  }
331
410
 
332
411
  const mapStateToProps = (state: IRootState) => ({
@@ -34,7 +34,6 @@ const Heading = styled.div`
34
34
 
35
35
  const SettingsWrapper = styled.div`
36
36
  position: relative;
37
- border-top: 1px solid ${(p) => p.theme.color.uiLine};
38
37
  padding-top: ${(p) => p.theme.spacing.m};
39
38
  `;
40
39
 
@@ -52,6 +51,7 @@ const SelectAllSitesFieldWrapper = styled.div``;
52
51
 
53
52
  const GlobalPermissionsFieldWrapper = styled.div`
54
53
  padding-bottom: ${(p) => p.theme.spacing.m};
54
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
55
55
  `;
56
56
 
57
57
  const SettingText = styled.div`
@@ -99,10 +99,21 @@ const RoleList = styled.div`
99
99
  }
100
100
  `;
101
101
 
102
+ const PageList = styled.ul`
103
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
104
+ padding-top: ${(p) => p.theme.spacing.xs};
105
+
106
+ & button {
107
+ margin-top: ${(p) => p.theme.spacing.s};
108
+ margin-bottom: ${(p) => p.theme.spacing.s};
109
+ }
110
+ `;
111
+
102
112
  const MemberWrapper = styled.div``;
103
113
 
104
114
  const OptionsWrapper = styled.div`
105
115
  padding-bottom: ${(p) => p.theme.spacing.m};
116
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
106
117
  `;
107
118
 
108
119
  const Label = styled.div`
@@ -121,6 +132,15 @@ const ModalContent = styled.div`
121
132
  padding: ${(p) => p.theme.spacing.m};
122
133
  `;
123
134
 
135
+ const PanelContent = styled.div`
136
+ padding: ${(p) => p.theme.spacing.m};
137
+ height: 100%;
138
+ `;
139
+
140
+ const FieldsWrapper = styled.div<{ hasBoder: boolean }>`
141
+ border-bottom: ${(p) => (p.hasBoder ? `1px solid ${p.theme.color.uiLine}` : `none`)};
142
+ `;
143
+
124
144
  export {
125
145
  Wrapper,
126
146
  NameTitle,
@@ -142,4 +162,7 @@ export {
142
162
  Label,
143
163
  HelpText,
144
164
  ModalContent,
165
+ PanelContent,
166
+ PageList,
167
+ FieldsWrapper,
145
168
  };