@griddo/ax 11.15.9 → 11.16.0-rc.1
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.
- package/package.json +2 -2
- package/src/__tests__/components/RestrictionsModal/CurrentAccessList/CurrentAccessList.test.tsx +173 -0
- package/src/__tests__/components/RestrictionsModal/OptionsStep/OptionsStep.test.tsx +160 -0
- package/src/__tests__/components/RestrictionsModal/RestrictionsModal.test.tsx +134 -0
- package/src/__tests__/components/RestrictionsModal/RolesList/RolesList.test.tsx +234 -0
- package/src/__tests__/components/RestrictionsModal/UsersList/UsersList.test.tsx +288 -0
- package/src/__tests__/hooks/users.test.tsx +382 -0
- package/src/api/pages.tsx +24 -1
- package/src/api/sites.tsx +14 -14
- package/src/api/structuredData.tsx +17 -7
- package/src/components/Browser/index.tsx +12 -0
- package/src/components/Browser/style.tsx +5 -1
- package/src/components/ConfigPanel/Form/index.tsx +11 -10
- package/src/components/ContentItem/index.tsx +31 -0
- package/src/components/ContentItem/style.tsx +43 -0
- package/src/components/Fields/ImageField/index.tsx +2 -1
- package/src/components/Fields/RadioField/index.tsx +3 -3
- package/src/components/Fields/RadioField/style.tsx +1 -1
- package/src/components/FloatingNote/index.tsx +12 -1
- package/src/components/FloatingNote/style.tsx +2 -1
- package/src/components/Modal/style.tsx +11 -0
- package/src/components/PageFinder/SelectionListItem/index.tsx +27 -17
- package/src/components/PageFinder/index.tsx +65 -28
- package/src/components/PageFinder/style.tsx +0 -1
- package/src/components/RestrictionsModal/CurrentAccessList/index.tsx +74 -0
- package/src/components/RestrictionsModal/CurrentAccessList/style.tsx +155 -0
- package/src/components/RestrictionsModal/OptionsStep/index.tsx +55 -0
- package/src/components/RestrictionsModal/OptionsStep/style.tsx +29 -0
- package/src/components/RestrictionsModal/RolesList/RoleItem/index.tsx +54 -0
- package/src/components/RestrictionsModal/RolesList/RoleItem/style.tsx +34 -0
- package/src/components/RestrictionsModal/RolesList/index.tsx +107 -0
- package/src/components/RestrictionsModal/RolesList/style.tsx +76 -0
- package/src/components/RestrictionsModal/UsersList/UserItem/index.tsx +78 -0
- package/src/components/RestrictionsModal/UsersList/UserItem/style.tsx +73 -0
- package/src/components/RestrictionsModal/UsersList/index.tsx +151 -0
- package/src/components/RestrictionsModal/UsersList/style.tsx +55 -0
- package/src/components/RestrictionsModal/index.tsx +181 -0
- package/src/components/RestrictionsModal/style.tsx +31 -0
- package/src/components/RestrictionsModal/utils.tsx +24 -0
- package/src/components/ScheduleModal/index.tsx +32 -8
- package/src/components/SelectionComponent/index.tsx +65 -0
- package/src/components/SelectionComponent/style.tsx +69 -0
- package/src/components/TableFilters/RoleFilter/index.tsx +3 -3
- package/src/components/TableList/TableItem/style.tsx +7 -13
- package/src/components/Tabs/index.tsx +2 -1
- package/src/components/UserRolesAndSites/index.tsx +2 -2
- package/src/components/index.tsx +6 -0
- package/src/containers/PageEditor/actions.tsx +43 -0
- package/src/containers/PageEditor/constants.tsx +1 -0
- package/src/containers/PageEditor/interfaces.tsx +26 -19
- package/src/containers/PageEditor/reducer.tsx +32 -19
- package/src/containers/Users/reducer.tsx +1 -0
- package/src/helpers/forms.tsx +3 -1
- package/src/hooks/index.tsx +2 -1
- package/src/hooks/users.tsx +154 -14
- package/src/modules/ActivityLog/LogFilters/UserFilter/index.tsx +11 -12
- package/src/modules/Content/PageItem/index.tsx +17 -10
- package/src/modules/Content/index.tsx +1 -3
- package/src/modules/GlobalEditor/Editor/index.tsx +6 -0
- package/src/modules/GlobalEditor/PageBrowser/index.tsx +6 -0
- package/src/modules/GlobalEditor/Preview/index.tsx +4 -2
- package/src/modules/GlobalEditor/index.tsx +72 -45
- package/src/modules/Navigation/Menus/List/Table/ConfigPanel/Form/index.tsx +3 -5
- package/src/modules/Navigation/Menus/List/Table/ConfigPanel/index.tsx +4 -4
- package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/ConnectedField/index.tsx +2 -3
- package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +3 -4
- package/src/modules/Navigation/Menus/List/Table/SidePanel/index.tsx +5 -6
- package/src/modules/PageEditor/Editor/index.tsx +6 -0
- package/src/modules/PageEditor/PageBrowser/index.tsx +6 -0
- package/src/modules/PageEditor/Preview/index.tsx +9 -2
- package/src/modules/PageEditor/atoms.tsx +110 -3
- package/src/modules/PageEditor/index.tsx +76 -95
- package/src/modules/Settings/Integrations/IntegrationForm/index.tsx +1 -3
- package/src/modules/Sites/SitesList/GridView/GridSiteItem/style.tsx +19 -2
- package/src/modules/Sites/SitesList/WelcomeModal/FinalStep/index.tsx +2 -2
- package/src/modules/Sites/SitesList/WelcomeModal/utils.ts +2 -2
- package/src/modules/StructuredData/Form/ConnectedField/index.tsx +2 -2
- package/src/modules/StructuredData/Form/index.tsx +120 -75
- package/src/modules/StructuredData/Form/style.tsx +7 -1
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +15 -8
- package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +15 -9
- package/src/modules/StructuredData/{StructuredDataList/StructuredDataItem/utils.tsx → utils.tsx} +16 -2
- package/src/modules/Users/Profile/atoms.tsx +62 -4
- package/src/modules/Users/Profile/index.tsx +83 -4
- package/src/modules/Users/Profile/style.tsx +60 -0
- package/src/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/index.tsx +3 -5
- package/src/modules/Users/UserCreate/SiteItem/index.tsx +2 -2
- package/src/modules/Users/UserCreate/atoms.tsx +69 -0
- package/src/modules/Users/UserCreate/index.tsx +149 -70
- package/src/modules/Users/UserCreate/style.tsx +24 -1
- package/src/modules/Users/UserForm/index.tsx +260 -146
- package/src/modules/Users/UserForm/style.tsx +13 -1
- package/src/modules/Users/UserList/UserItem/index.tsx +3 -3
- package/src/types/index.tsx +19 -6
- package/src/types/logs.tsx +1 -1
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { sites as sitesApi } from "@ax/api";
|
|
5
|
+
import {
|
|
6
|
+
Button,
|
|
7
|
+
ErrorToast,
|
|
8
|
+
FieldsBehavior,
|
|
9
|
+
FloatingPanel,
|
|
10
|
+
PageFinder,
|
|
11
|
+
ProfileImage,
|
|
12
|
+
SearchField,
|
|
13
|
+
} from "@ax/components";
|
|
5
14
|
import { appActions } from "@ax/containers/App";
|
|
6
15
|
import { RouteLeavingGuard } from "@ax/guards";
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
16
|
+
import { isReqOk } from "@ax/helpers";
|
|
17
|
+
import { useModals } from "@ax/hooks";
|
|
18
|
+
import type {
|
|
19
|
+
IImage,
|
|
20
|
+
ILanguage,
|
|
21
|
+
IPage,
|
|
22
|
+
IRole,
|
|
23
|
+
IRootState,
|
|
24
|
+
ISite,
|
|
25
|
+
IUser,
|
|
26
|
+
UserPagePermissionEntry,
|
|
27
|
+
UserRoleAssignment,
|
|
28
|
+
} from "@ax/types";
|
|
9
29
|
|
|
10
30
|
import { timezones } from "../../Settings/Globals/constants";
|
|
31
|
+
import { PagePermissionsList, SettingsSection } from "../UserCreate/atoms";
|
|
11
32
|
import OptionItem from "../UserCreate/OptionItem";
|
|
12
33
|
import SiteItem from "../UserCreate/SiteItem";
|
|
13
34
|
import RolesModal from "../UserCreate/SiteItem/RolesModal";
|
|
@@ -29,26 +50,30 @@ const UserForm = (props: IProps) => {
|
|
|
29
50
|
readOnlySites = false,
|
|
30
51
|
isSiteView = false,
|
|
31
52
|
site,
|
|
53
|
+
siteLanguages,
|
|
54
|
+
globalLanguages,
|
|
32
55
|
} = props;
|
|
33
56
|
|
|
34
|
-
const { id, username, name, email, image, company, position, timezone, isSuperAdmin } = form;
|
|
57
|
+
const { id, username, name, email, image, company, position, timezone, isSuperAdmin, pagePermissions } = form;
|
|
35
58
|
|
|
36
59
|
const getSortedItemsByName = (items: ISite[]) =>
|
|
37
60
|
items.sort((item1: ISite, item2: ISite) => item1.name.localeCompare(item2.name));
|
|
38
61
|
|
|
39
62
|
const sortedByNameSites = getSortedItemsByName(sites);
|
|
40
63
|
|
|
41
|
-
const { isOpen, toggleModal } =
|
|
42
|
-
const { isOpen: isOpenRoleModal, toggleModal: toggleRoleModal } = useModal(false);
|
|
43
|
-
const { isOpen: isOpenTypeChangeModal, toggleModal: toggleTypeChangeModal } = useModal(false);
|
|
64
|
+
const { isOpen, toggleModal } = useModals(["password", "roles", "typeChange", "pagePermissions"]);
|
|
44
65
|
const [sitesList, setSiteList] = useState(sortedByNameSites);
|
|
45
66
|
const [showMore, setShowMore] = useState(false);
|
|
67
|
+
const [selectedPages, setSelectedPages] = useState<IPage[]>([]);
|
|
46
68
|
|
|
47
69
|
const allowedRoutes = ["/profile"];
|
|
48
70
|
const { isDirty } = shouldBeSaved(user, form);
|
|
49
71
|
|
|
50
72
|
const isSameUser = currentUser && currentUser.id === user.id;
|
|
51
73
|
const isEditDisabled = !!currentUser && !currentUser.isSuperAdmin && isSiteView && !isSameUser;
|
|
74
|
+
const defaultLanguage = isSiteView
|
|
75
|
+
? siteLanguages.find((lang) => lang.isDefault)
|
|
76
|
+
: globalLanguages.find((lang) => lang.isDefault);
|
|
52
77
|
|
|
53
78
|
useEffect(() => {
|
|
54
79
|
if (form.roles.length === 0) {
|
|
@@ -56,6 +81,43 @@ const UserForm = (props: IProps) => {
|
|
|
56
81
|
}
|
|
57
82
|
}, [form.roles]);
|
|
58
83
|
|
|
84
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: runs on mount only
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const fetchPages = async () => {
|
|
87
|
+
if (!pagePermissions || pagePermissions.length === 0) {
|
|
88
|
+
setSelectedPages([]);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const siteId: "global" | number = isSiteView ? site!.id : "global";
|
|
93
|
+
const pagePermission = pagePermissions.find((entry) => entry.siteId === siteId);
|
|
94
|
+
|
|
95
|
+
if (pagePermission && pagePermission.pageIds.length > 0) {
|
|
96
|
+
try {
|
|
97
|
+
const params = {
|
|
98
|
+
siteID: siteId,
|
|
99
|
+
page: 1,
|
|
100
|
+
itemsPerPage: 50,
|
|
101
|
+
deleted: false,
|
|
102
|
+
filterPages: pagePermission.pageIds,
|
|
103
|
+
lang: defaultLanguage?.id,
|
|
104
|
+
ignoreLang: true,
|
|
105
|
+
};
|
|
106
|
+
const response = await sitesApi.getSitePages(params);
|
|
107
|
+
if (isReqOk(response.status) && response.data?.items) {
|
|
108
|
+
setSelectedPages(response.data.items);
|
|
109
|
+
}
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error("Failed to fetch page permissions", error);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
setSelectedPages([]);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
fetchPages();
|
|
119
|
+
}, []);
|
|
120
|
+
|
|
59
121
|
const handleImageChange = (value: IImage) => setForm({ ...form, image: value || null });
|
|
60
122
|
const handleNameChange = (value: string) => setForm({ ...form, name: value });
|
|
61
123
|
const handleEmailChange = (value: string) => setForm({ ...form, email: value });
|
|
@@ -64,16 +126,35 @@ const UserForm = (props: IProps) => {
|
|
|
64
126
|
const handlePositionChange = (value: string) => setForm({ ...form, position: value });
|
|
65
127
|
const handleTimezoneChange = (value: string) => setForm({ ...form, timezone: value });
|
|
66
128
|
|
|
129
|
+
const handleSetPage = (pages: IPage | IPage[]) => {
|
|
130
|
+
const pagesArray = Array.isArray(pages) ? pages : [pages];
|
|
131
|
+
const pageIds = pagesArray.map((p) => p.id);
|
|
132
|
+
const siteId: "global" | number = isSiteView ? site!.id : "global";
|
|
133
|
+
|
|
134
|
+
const newEntry: UserPagePermissionEntry = { siteId, pageIds };
|
|
135
|
+
|
|
136
|
+
const currentPagePermissions = pagePermissions || [];
|
|
137
|
+
const existingIndex = currentPagePermissions.findIndex((entry) => entry.siteId === siteId);
|
|
138
|
+
const newPagePermissions: UserPagePermissionEntry[] =
|
|
139
|
+
existingIndex >= 0
|
|
140
|
+
? currentPagePermissions.map((entry, index) => (index === existingIndex ? newEntry : entry))
|
|
141
|
+
: [...currentPagePermissions, newEntry];
|
|
142
|
+
|
|
143
|
+
setForm({ ...form, pagePermissions: newPagePermissions });
|
|
144
|
+
setSelectedPages(pagesArray);
|
|
145
|
+
toggleModal("pagePermissions");
|
|
146
|
+
};
|
|
147
|
+
|
|
67
148
|
const toggleSuperAdmin = () => {
|
|
68
149
|
setForm({ ...form, isSuperAdmin: !form.isSuperAdmin });
|
|
69
|
-
|
|
150
|
+
toggleModal("typeChange");
|
|
70
151
|
};
|
|
71
152
|
|
|
72
|
-
const handleAddRoles = (newRoles:
|
|
153
|
+
const handleAddRoles = (newRoles: UserRoleAssignment) => {
|
|
73
154
|
const oldRoles =
|
|
74
155
|
newRoles.siteId === "all"
|
|
75
|
-
? form.roles.filter((role
|
|
76
|
-
: form.roles.filter((role
|
|
156
|
+
? form.roles.filter((role) => role.siteId === "global")
|
|
157
|
+
: form.roles.filter((role) => role.siteId !== newRoles.siteId);
|
|
77
158
|
|
|
78
159
|
const updatedRoles = [...oldRoles, newRoles];
|
|
79
160
|
|
|
@@ -81,7 +162,7 @@ const UserForm = (props: IProps) => {
|
|
|
81
162
|
};
|
|
82
163
|
|
|
83
164
|
const getAllSitesWithRoles = () => {
|
|
84
|
-
const siteRoles = form.roles.find((role
|
|
165
|
+
const siteRoles = form.roles.find((role) => role.siteId === "all");
|
|
85
166
|
return sites.map((site: ISite) => {
|
|
86
167
|
return { siteId: site.id, roles: siteRoles ? siteRoles.roles : [] };
|
|
87
168
|
});
|
|
@@ -89,9 +170,9 @@ const UserForm = (props: IProps) => {
|
|
|
89
170
|
|
|
90
171
|
const handleAddSiteRoles = (newRoles: number[]) => {
|
|
91
172
|
if (!site) return;
|
|
92
|
-
const hasAllSites = form.roles.find((role
|
|
173
|
+
const hasAllSites = form.roles.find((role) => role.siteId === "all");
|
|
93
174
|
const userRoles = hasAllSites ? getAllSitesWithRoles() : form.roles;
|
|
94
|
-
const oldRoles = userRoles.filter((role
|
|
175
|
+
const oldRoles = userRoles.filter((role) => role.siteId !== site.id);
|
|
95
176
|
const newSiteRoles = { siteId: site.id, roles: newRoles };
|
|
96
177
|
const updatedRoles = newRoles.length > 0 ? [...oldRoles, newSiteRoles] : oldRoles;
|
|
97
178
|
setForm({ ...form, roles: updatedRoles });
|
|
@@ -99,13 +180,13 @@ const UserForm = (props: IProps) => {
|
|
|
99
180
|
|
|
100
181
|
const handleChangeType = (value: string) => {
|
|
101
182
|
if ((isSuperAdmin && value === "member") || (!isSuperAdmin && value === "superadmin")) {
|
|
102
|
-
|
|
183
|
+
toggleModal("typeChange");
|
|
103
184
|
}
|
|
104
185
|
};
|
|
105
186
|
|
|
106
187
|
const modalProps = {
|
|
107
|
-
isOpen,
|
|
108
|
-
toggleModal,
|
|
188
|
+
isOpen: isOpen("password"),
|
|
189
|
+
toggleModal: () => toggleModal("password"),
|
|
109
190
|
id,
|
|
110
191
|
};
|
|
111
192
|
|
|
@@ -114,11 +195,11 @@ const UserForm = (props: IProps) => {
|
|
|
114
195
|
onClick: toggleSuperAdmin,
|
|
115
196
|
};
|
|
116
197
|
|
|
117
|
-
const secondaryTypeChangeModalAction = { title: "Cancel", onClick:
|
|
198
|
+
const secondaryTypeChangeModalAction = { title: "Cancel", onClick: () => toggleModal("typeChange") };
|
|
118
199
|
|
|
119
200
|
const modalTypeChangeProps = {
|
|
120
|
-
isOpen:
|
|
121
|
-
toggleModal:
|
|
201
|
+
isOpen: isOpen("typeChange"),
|
|
202
|
+
toggleModal: () => toggleModal("typeChange"),
|
|
122
203
|
email,
|
|
123
204
|
isSuperAdmin,
|
|
124
205
|
mainModalAction: mainTypeChangeModalAction,
|
|
@@ -135,12 +216,12 @@ const UserForm = (props: IProps) => {
|
|
|
135
216
|
setSiteList(sortedSites);
|
|
136
217
|
};
|
|
137
218
|
|
|
138
|
-
const selectSite = (id: number |
|
|
219
|
+
const selectSite = (id: number | "global" | "all") => {
|
|
139
220
|
const { roles } = form;
|
|
140
|
-
const hasSite = roles.find((siteRole
|
|
221
|
+
const hasSite = roles.find((siteRole) => siteRole.siteId === id);
|
|
141
222
|
if (hasSite) {
|
|
142
223
|
const filteredRoles = roles.filter(
|
|
143
|
-
(siteRole
|
|
224
|
+
(siteRole) =>
|
|
144
225
|
(Number.isInteger(id) && siteRole.siteId !== id && siteRole.siteId !== "all") ||
|
|
145
226
|
(!Number.isInteger(id) && siteRole.siteId !== id),
|
|
146
227
|
);
|
|
@@ -170,17 +251,17 @@ const UserForm = (props: IProps) => {
|
|
|
170
251
|
return currentSite?.name;
|
|
171
252
|
};
|
|
172
253
|
|
|
173
|
-
const sitesID = form.roles.map((roleSite
|
|
254
|
+
const sitesID = form.roles.map((roleSite) => roleSite.siteId);
|
|
174
255
|
|
|
175
256
|
const siteSelectedRoles = isSiteView
|
|
176
|
-
? form.roles.find((roleSite
|
|
257
|
+
? form.roles.find((roleSite) => roleSite.siteId === site?.id || roleSite.siteId === "all")
|
|
177
258
|
: undefined;
|
|
178
259
|
|
|
179
|
-
const rolesAll = form.roles.find((roleSite
|
|
260
|
+
const rolesAll = form.roles.find((roleSite) => roleSite.siteId === "all");
|
|
180
261
|
const allDescription =
|
|
181
262
|
"The user will have access to all existing and future sites depending on the permissions assigned to the role.";
|
|
182
263
|
|
|
183
|
-
const rolesGlobal = form.roles.find((roleSite
|
|
264
|
+
const rolesGlobal = form.roles.find((roleSite) => roleSite.siteId === "global");
|
|
184
265
|
const globalDescription = "Global data will be accessible to the user based on the permissions assigned to the role.";
|
|
185
266
|
|
|
186
267
|
return (
|
|
@@ -198,125 +279,126 @@ const UserForm = (props: IProps) => {
|
|
|
198
279
|
<S.NameTitle>{user.name}</S.NameTitle>
|
|
199
280
|
</S.UserName>
|
|
200
281
|
</S.Header>
|
|
201
|
-
<
|
|
202
|
-
title="Name"
|
|
203
|
-
name="name"
|
|
204
|
-
fieldType="TextField"
|
|
205
|
-
placeholder="Type a name"
|
|
206
|
-
mandatory
|
|
207
|
-
value={name}
|
|
208
|
-
onChange={handleNameChange}
|
|
209
|
-
disabled={isEditDisabled}
|
|
210
|
-
/>
|
|
211
|
-
<FieldsBehavior
|
|
212
|
-
title="Email"
|
|
213
|
-
name="email"
|
|
214
|
-
fieldType="TextField"
|
|
215
|
-
placeholder="Type an email"
|
|
216
|
-
mandatory
|
|
217
|
-
value={email}
|
|
218
|
-
onChange={handleEmailChange}
|
|
219
|
-
disabled={isSameUser || isEditDisabled}
|
|
220
|
-
/>
|
|
221
|
-
<FieldsBehavior
|
|
222
|
-
title="Alias"
|
|
223
|
-
name="username"
|
|
224
|
-
fieldType="TextField"
|
|
225
|
-
placeholder="Type an alias"
|
|
226
|
-
mandatory
|
|
227
|
-
value={username}
|
|
228
|
-
onChange={handleUsernameChange}
|
|
229
|
-
prefix="@"
|
|
230
|
-
disabled={isEditDisabled}
|
|
231
|
-
/>
|
|
232
|
-
<FieldsBehavior
|
|
233
|
-
title="Company"
|
|
234
|
-
name="company"
|
|
235
|
-
fieldType="TextField"
|
|
236
|
-
placeholder="Type a company"
|
|
237
|
-
value={company || ""}
|
|
238
|
-
onChange={handleCompanyChange}
|
|
239
|
-
disabled={isEditDisabled}
|
|
240
|
-
/>
|
|
241
|
-
{isSameUser && (
|
|
282
|
+
<S.FieldsWrapper hasBoder={isSiteView}>
|
|
242
283
|
<FieldsBehavior
|
|
243
|
-
title="
|
|
244
|
-
name="
|
|
284
|
+
title="Name"
|
|
285
|
+
name="name"
|
|
245
286
|
fieldType="TextField"
|
|
246
|
-
|
|
247
|
-
placeholder="Type a password"
|
|
287
|
+
placeholder="Type a name"
|
|
248
288
|
mandatory
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
onClickIcon={toggleModal}
|
|
289
|
+
value={name}
|
|
290
|
+
onChange={handleNameChange}
|
|
291
|
+
disabled={isEditDisabled}
|
|
253
292
|
/>
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
293
|
+
<FieldsBehavior
|
|
294
|
+
title="Email"
|
|
295
|
+
name="email"
|
|
296
|
+
fieldType="TextField"
|
|
297
|
+
placeholder="Type an email"
|
|
298
|
+
mandatory
|
|
299
|
+
value={email}
|
|
300
|
+
onChange={handleEmailChange}
|
|
301
|
+
disabled={isSameUser || isEditDisabled}
|
|
302
|
+
/>
|
|
303
|
+
<FieldsBehavior
|
|
304
|
+
title="Alias"
|
|
305
|
+
name="username"
|
|
306
|
+
fieldType="TextField"
|
|
307
|
+
placeholder="Type an alias"
|
|
308
|
+
mandatory
|
|
309
|
+
value={username}
|
|
310
|
+
onChange={handleUsernameChange}
|
|
311
|
+
prefix="@"
|
|
312
|
+
disabled={isEditDisabled}
|
|
313
|
+
/>
|
|
314
|
+
<FieldsBehavior
|
|
315
|
+
title="Company"
|
|
316
|
+
name="company"
|
|
317
|
+
fieldType="TextField"
|
|
318
|
+
placeholder="Type a company"
|
|
319
|
+
value={company || ""}
|
|
320
|
+
onChange={handleCompanyChange}
|
|
321
|
+
disabled={isEditDisabled}
|
|
322
|
+
/>
|
|
323
|
+
{isSameUser && (
|
|
324
|
+
<FieldsBehavior
|
|
325
|
+
title="Password"
|
|
326
|
+
name="password"
|
|
327
|
+
fieldType="TextField"
|
|
328
|
+
inputType="password"
|
|
329
|
+
placeholder="Type a password"
|
|
330
|
+
mandatory
|
|
331
|
+
readonly
|
|
332
|
+
value="********"
|
|
333
|
+
icon="edit"
|
|
334
|
+
onClickIcon={toggleModal}
|
|
335
|
+
/>
|
|
336
|
+
)}
|
|
337
|
+
<FieldsBehavior
|
|
338
|
+
title="Job title"
|
|
339
|
+
name="position"
|
|
340
|
+
fieldType="TextField"
|
|
341
|
+
placeholder="Type a job"
|
|
342
|
+
value={position || ""}
|
|
343
|
+
onChange={handlePositionChange}
|
|
344
|
+
disabled={isEditDisabled}
|
|
345
|
+
/>
|
|
346
|
+
<FieldsBehavior
|
|
347
|
+
title="Time zone"
|
|
348
|
+
name="timezone"
|
|
349
|
+
fieldType="Select"
|
|
350
|
+
value={timezone}
|
|
351
|
+
options={timezones}
|
|
352
|
+
onChange={handleTimezoneChange}
|
|
353
|
+
mandatory={true}
|
|
354
|
+
disabled={isEditDisabled}
|
|
355
|
+
/>
|
|
356
|
+
</S.FieldsWrapper>
|
|
274
357
|
{isSiteView ? (
|
|
275
358
|
isSuperAdmin ? (
|
|
276
359
|
<>
|
|
277
|
-
<
|
|
278
|
-
<
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
/>
|
|
288
|
-
</S.SettingContent>
|
|
289
|
-
</S.SettingsWrapper>
|
|
360
|
+
<SettingsSection heading="Roles assigned">
|
|
361
|
+
<OptionItem
|
|
362
|
+
name="superadmin"
|
|
363
|
+
title="Super admin"
|
|
364
|
+
description="You can manage all aspects of your site, including inviting people and managing their permissions."
|
|
365
|
+
onChange={toggleSuperAdmin}
|
|
366
|
+
value={isSuperAdmin}
|
|
367
|
+
readOnly={readOnlySites}
|
|
368
|
+
/>
|
|
369
|
+
</SettingsSection>
|
|
290
370
|
</>
|
|
291
371
|
) : (
|
|
292
372
|
<>
|
|
293
|
-
<
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
)}
|
|
301
|
-
</S.HeadingWrapper>
|
|
302
|
-
<S.SettingContent>
|
|
303
|
-
<S.SettingText>You can add a one or more roles to this user.</S.SettingText>
|
|
304
|
-
</S.SettingContent>
|
|
305
|
-
</S.SettingsWrapper>
|
|
373
|
+
<SettingsSection
|
|
374
|
+
heading="Roles Assigned"
|
|
375
|
+
description="You can add a one or more roles to this user."
|
|
376
|
+
actionLabel="Add Role"
|
|
377
|
+
onActionClick={() => toggleModal("roles")}
|
|
378
|
+
showAction={!siteSelectedRoles || siteSelectedRoles.roles.length === 0}
|
|
379
|
+
/>
|
|
306
380
|
<S.RoleList>
|
|
307
381
|
{siteSelectedRoles?.roles.map((siteRoleId: number) => {
|
|
308
382
|
const role = roles.find((role: IRole) => role.id === siteRoleId);
|
|
309
383
|
return role && <RoleItem key={role.name} role={role} isReadOnly={true} />;
|
|
310
384
|
})}
|
|
311
385
|
{siteSelectedRoles && siteSelectedRoles.roles.length > 0 && !isSameUser && (
|
|
312
|
-
<Button type="button" buttonStyle="line" onClick={
|
|
386
|
+
<Button type="button" buttonStyle="line" onClick={() => toggleModal("roles")}>
|
|
313
387
|
Manage user roles
|
|
314
388
|
</Button>
|
|
315
389
|
)}
|
|
316
390
|
</S.RoleList>
|
|
391
|
+
<SettingsSection
|
|
392
|
+
heading="Page permissions"
|
|
393
|
+
description="You can give access only to a specific page/s to this user."
|
|
394
|
+
actionLabel="Add Page"
|
|
395
|
+
onActionClick={() => toggleModal("pagePermissions")}
|
|
396
|
+
showAction={selectedPages.length === 0}
|
|
397
|
+
/>
|
|
398
|
+
<PagePermissionsList pages={selectedPages} onManageClick={() => toggleModal("pagePermissions")} />
|
|
317
399
|
<RolesModal
|
|
318
|
-
isOpen={
|
|
319
|
-
toggleModal={
|
|
400
|
+
isOpen={isOpen("roles")}
|
|
401
|
+
toggleModal={() => toggleModal("roles")}
|
|
320
402
|
roles={roles}
|
|
321
403
|
addRoles={handleAddSiteRoles}
|
|
322
404
|
selectedRoles={siteSelectedRoles ? siteSelectedRoles.roles : []}
|
|
@@ -348,28 +430,23 @@ const UserForm = (props: IProps) => {
|
|
|
348
430
|
</S.OptionsWrapper>
|
|
349
431
|
)}
|
|
350
432
|
{isSuperAdmin && readOnlySites && (
|
|
351
|
-
<
|
|
352
|
-
<
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
/>
|
|
362
|
-
</S.SettingContent>
|
|
363
|
-
</S.SettingsWrapper>
|
|
433
|
+
<SettingsSection heading="Sites & roles assigned">
|
|
434
|
+
<OptionItem
|
|
435
|
+
name="superadmin"
|
|
436
|
+
title="Super admin"
|
|
437
|
+
description="The user will have full access to all features and their configuration. They will also have access to all sites."
|
|
438
|
+
onChange={toggleSuperAdmin}
|
|
439
|
+
value={isSuperAdmin}
|
|
440
|
+
readOnly={readOnlySites}
|
|
441
|
+
/>
|
|
442
|
+
</SettingsSection>
|
|
364
443
|
)}
|
|
365
444
|
{!isSuperAdmin && (
|
|
366
445
|
<S.MemberWrapper>
|
|
367
|
-
<
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
</S.SettingContent>
|
|
372
|
-
</S.SettingsWrapper>
|
|
446
|
+
<SettingsSection
|
|
447
|
+
heading="Global data Permissions"
|
|
448
|
+
description="The user can have access to global data with specific role."
|
|
449
|
+
/>
|
|
373
450
|
<S.GlobalPermissionsFieldWrapper>
|
|
374
451
|
<SiteItem
|
|
375
452
|
sites={sitesID}
|
|
@@ -382,6 +459,18 @@ const UserForm = (props: IProps) => {
|
|
|
382
459
|
readOnly={readOnlySites}
|
|
383
460
|
/>
|
|
384
461
|
</S.GlobalPermissionsFieldWrapper>
|
|
462
|
+
{sitesID.includes("global") && (
|
|
463
|
+
<>
|
|
464
|
+
<SettingsSection
|
|
465
|
+
heading="Page permissions"
|
|
466
|
+
description="You can give access only to a specific page/s to this user."
|
|
467
|
+
actionLabel="Add Role"
|
|
468
|
+
onActionClick={() => toggleModal("pagePermissions")}
|
|
469
|
+
showAction={selectedPages.length === 0}
|
|
470
|
+
/>
|
|
471
|
+
<PagePermissionsList pages={selectedPages} onManageClick={() => toggleModal("pagePermissions")} />
|
|
472
|
+
</>
|
|
473
|
+
)}
|
|
385
474
|
<S.SettingsWrapper>
|
|
386
475
|
<S.Heading>Sites & roles assigned</S.Heading>
|
|
387
476
|
{form.roles.length > 0 ? (
|
|
@@ -398,7 +487,7 @@ const UserForm = (props: IProps) => {
|
|
|
398
487
|
|
|
399
488
|
<S.SiteList>
|
|
400
489
|
{!rolesAll &&
|
|
401
|
-
form.roles.map((siteRole
|
|
490
|
+
form.roles.map((siteRole, index: number) => {
|
|
402
491
|
if (siteRole.siteId !== "all" && siteRole.siteId !== "global") {
|
|
403
492
|
const siteName = getSiteName(siteRole.siteId);
|
|
404
493
|
if (!siteName) return <></>;
|
|
@@ -465,7 +554,7 @@ const UserForm = (props: IProps) => {
|
|
|
465
554
|
sitesList.map((site: ISite) => {
|
|
466
555
|
const rolesSite = form.roles.find((roleSite: any) => roleSite.siteId === site.id);
|
|
467
556
|
return (
|
|
468
|
-
!form.roles.find((roleSite
|
|
557
|
+
!form.roles.find((roleSite) => roleSite.siteId === site.id) && (
|
|
469
558
|
<SiteItem
|
|
470
559
|
readOnly={readOnlySites}
|
|
471
560
|
disabled={!!rolesAll}
|
|
@@ -490,6 +579,27 @@ const UserForm = (props: IProps) => {
|
|
|
490
579
|
</S.Wrapper>
|
|
491
580
|
<PasswordModal {...modalProps} />
|
|
492
581
|
<TypeChangeModal {...modalTypeChangeProps} />
|
|
582
|
+
<FloatingPanel
|
|
583
|
+
title="Page Permissions"
|
|
584
|
+
toggleModal={() => toggleModal("pagePermissions")}
|
|
585
|
+
isOpen={isOpen("pagePermissions")}
|
|
586
|
+
>
|
|
587
|
+
<S.PanelContent>
|
|
588
|
+
{isOpen("pagePermissions") && (
|
|
589
|
+
<PageFinder
|
|
590
|
+
onClick={handleSetPage}
|
|
591
|
+
isOpen={isOpen("pagePermissions")}
|
|
592
|
+
multiple
|
|
593
|
+
globalContent={!isSiteView}
|
|
594
|
+
hideSites
|
|
595
|
+
pages={selectedPages.map((p) => p.id)}
|
|
596
|
+
defaultLang={defaultLanguage?.id}
|
|
597
|
+
alwaysShowButton
|
|
598
|
+
disableTranslations
|
|
599
|
+
/>
|
|
600
|
+
)}
|
|
601
|
+
</S.PanelContent>
|
|
602
|
+
</FloatingPanel>
|
|
493
603
|
</>
|
|
494
604
|
);
|
|
495
605
|
};
|
|
@@ -500,6 +610,8 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
500
610
|
currentUser: state.users.currentUser,
|
|
501
611
|
sites: state.sites.allSites,
|
|
502
612
|
roles: state.users.roles,
|
|
613
|
+
siteLanguages: state.sites.currentSiteLanguages,
|
|
614
|
+
globalLanguages: state.app.globalLangs,
|
|
503
615
|
});
|
|
504
616
|
|
|
505
617
|
interface IDispatchProps {
|
|
@@ -522,6 +634,8 @@ interface IProfileProps {
|
|
|
522
634
|
isSiteView?: boolean;
|
|
523
635
|
roles: IRole[];
|
|
524
636
|
site: ISite | null;
|
|
637
|
+
siteLanguages: ILanguage[];
|
|
638
|
+
globalLanguages: ILanguage[];
|
|
525
639
|
}
|
|
526
640
|
|
|
527
641
|
type IProps = IProfileProps & IDispatchProps;
|
|
@@ -34,7 +34,6 @@ const ModalContent = 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
|
padding-bottom: ${(p) => p.theme.spacing.s};
|
|
40
39
|
`;
|
|
@@ -73,6 +72,7 @@ const SelectAllSitesFieldWrapper = styled.div``;
|
|
|
73
72
|
|
|
74
73
|
const GlobalPermissionsFieldWrapper = styled.div`
|
|
75
74
|
padding-bottom: ${(p) => p.theme.spacing.m};
|
|
75
|
+
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
76
76
|
`;
|
|
77
77
|
|
|
78
78
|
const SiteList = styled.div`
|
|
@@ -106,6 +106,7 @@ const MemberWrapper = styled.div``;
|
|
|
106
106
|
|
|
107
107
|
const OptionsWrapper = styled.div`
|
|
108
108
|
padding-bottom: ${(p) => p.theme.spacing.m};
|
|
109
|
+
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
109
110
|
`;
|
|
110
111
|
|
|
111
112
|
const Label = styled.div`
|
|
@@ -120,6 +121,15 @@ const HelpText = styled.div`
|
|
|
120
121
|
color: ${(p) => p.theme.color?.textMediumEmphasis};
|
|
121
122
|
`;
|
|
122
123
|
|
|
124
|
+
const PanelContent = styled.div`
|
|
125
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
126
|
+
height: 100%;
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
const FieldsWrapper = styled.div<{ hasBoder: boolean }>`
|
|
130
|
+
border-bottom: ${(p) => (p.hasBoder ? `1px solid ${p.theme.color.uiLine}` : `none`)};
|
|
131
|
+
`;
|
|
132
|
+
|
|
123
133
|
export {
|
|
124
134
|
Wrapper,
|
|
125
135
|
Header,
|
|
@@ -142,4 +152,6 @@ export {
|
|
|
142
152
|
HelpText,
|
|
143
153
|
OptionsWrapper,
|
|
144
154
|
MemberWrapper,
|
|
155
|
+
PanelContent,
|
|
156
|
+
FieldsWrapper,
|
|
145
157
|
};
|
|
@@ -4,7 +4,7 @@ import { Avatar, CheckField, ElementsTooltip, Tag, Toast, Tooltip, TruncatedTool
|
|
|
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, IRootState, ISite,
|
|
7
|
+
import type { ICheck, IRole, IRootState, ISite, IUser } from "@ax/types";
|
|
8
8
|
|
|
9
9
|
import { DeleteModal } from "../atoms";
|
|
10
10
|
|
|
@@ -110,8 +110,8 @@ const UserItem = (props: IUserItemProps): JSX.Element => {
|
|
|
110
110
|
user.isSuperAdmin
|
|
111
111
|
? ["ALL SITES"]
|
|
112
112
|
: user?.roles
|
|
113
|
-
.filter((siteRoles
|
|
114
|
-
.map((siteRoles
|
|
113
|
+
.filter((siteRoles) => siteRoles.siteId === "all" || Number.isInteger(siteRoles.siteId))
|
|
114
|
+
.map((siteRoles) => getSiteNameById(siteRoles.siteId));
|
|
115
115
|
|
|
116
116
|
let rolesIds: number[] = [];
|
|
117
117
|
|