@firecms/user_management 3.0.0-beta.8 → 3.0.0-canary.100

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/dist/index.es.js CHANGED
@@ -1,319 +1,452 @@
1
- import F, { useEffect as ce, useCallback as k, useContext as Fe, useState as A } from "react";
2
- import { getFirestore as Y, onSnapshot as ue, collection as ee, setDoc as me, doc as H, addDoc as Ae, deleteDoc as he } from "@firebase/firestore";
3
- import { jsx as e, jsxs as s, Fragment as K } from "react/jsx-runtime";
4
- import { getColorSchemeForSeed as Pe, Chip as Te, Dialog as fe, DialogContent as ge, Typography as P, TextField as Q, Paper as pe, Table as re, TableHeader as ie, TableCell as d, TableBody as oe, TableRow as W, Tooltip as V, Checkbox as I, Select as ne, SelectItem as L, DialogActions as Ce, Button as O, LoadingButton as ve, DoneIcon as we, IconButton as ye, DeleteIcon as be, CenteredView as Ne, Container as Ue, AddIcon as le, MultiSelect as Le, MultiSelectItem as Be } from "@firecms/ui";
5
- import * as M from "yup";
6
- import { toSnakeCase as _e, FieldCaption as B, DeleteConfirmationDialog as xe, useNavigationController as Ve, useSnackbarController as se, useAuthController as ae, useCustomizationController as Me, defaultDateFormat as Oe } from "@firecms/core";
7
- import { useCreateFormex as Re, getIn as J, Formex as De } from "@firecms/formex";
8
- import { format as $e } from "date-fns";
9
- import * as qe from "date-fns/locale";
10
- const gn = ["Admin"], Ye = {
11
- read: !1,
12
- edit: !1,
13
- create: !1,
14
- delete: !1
1
+ import React, { useEffect, useCallback, useContext, useState } from "react";
2
+ import equal from "react-fast-compare";
3
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
4
+ import { getColorSchemeForSeed, Chip, Dialog, DialogContent, Typography, TextField, Paper, Table, TableHeader, TableCell, TableBody, TableRow, Tooltip, Checkbox, Select, SelectItem, DialogActions, Button, LoadingButton, DoneIcon, IconButton, DeleteIcon, CenteredView, Container, AddIcon, MultiSelect, MultiSelectItem } from "@firecms/ui";
5
+ import * as Yup from "yup";
6
+ import { toSnakeCase, FieldCaption, DeleteConfirmationDialog, useNavigationController, useSnackbarController, useAuthController, useCustomizationController, defaultDateFormat } from "@firecms/core";
7
+ import { useCreateFormex, getIn, Formex } from "@firecms/formex";
8
+ import { format } from "date-fns";
9
+ import * as locales from "date-fns/locale";
10
+ const RESERVED_GROUPS = ["Admin"];
11
+ const DEFAULT_PERMISSIONS = {
12
+ read: false,
13
+ edit: false,
14
+ create: false,
15
+ delete: false
15
16
  };
16
- function We({
17
- collection: t,
18
- user: r
17
+ function resolveUserRolePermissions({
18
+ collection,
19
+ user
19
20
  }) {
20
- const n = r?.roles;
21
- if (n) {
22
- if (t.ownerId === r?.uid)
23
- return {
24
- read: !0,
25
- create: !0,
26
- edit: !0,
27
- delete: !0
28
- };
29
- {
30
- const l = {
31
- read: !1,
32
- create: !1,
33
- edit: !1,
34
- delete: !1
35
- };
36
- return n.map((i) => je(i, t.id)).reduce(te, l);
37
- }
38
- } else return Ye;
21
+ const roles = user?.roles;
22
+ if (!roles) {
23
+ return DEFAULT_PERMISSIONS;
24
+ } else if (collection.ownerId === user?.uid) {
25
+ return {
26
+ read: true,
27
+ create: true,
28
+ edit: true,
29
+ delete: true
30
+ };
31
+ } else {
32
+ const basePermissions = {
33
+ read: false,
34
+ create: false,
35
+ edit: false,
36
+ delete: false
37
+ };
38
+ return roles.map((role) => resolveCollectionRole(role, collection.id)).reduce(mergePermissions, basePermissions);
39
+ }
39
40
  }
40
- function je(t, r) {
41
- const n = {
42
- read: t.isAdmin || t.defaultPermissions?.read,
43
- create: t.isAdmin || t.defaultPermissions?.create,
44
- edit: t.isAdmin || t.defaultPermissions?.edit,
45
- delete: t.isAdmin || t.defaultPermissions?.delete
41
+ function resolveCollectionRole(role, id) {
42
+ const basePermissions = {
43
+ read: role.isAdmin || role.defaultPermissions?.read,
44
+ create: role.isAdmin || role.defaultPermissions?.create,
45
+ edit: role.isAdmin || role.defaultPermissions?.edit,
46
+ delete: role.isAdmin || role.defaultPermissions?.delete
46
47
  };
47
- return t.collectionPermissions && t.collectionPermissions[r] ? te(t.collectionPermissions[r], n) : t.defaultPermissions ? te(t.defaultPermissions, n) : n;
48
+ if (role.collectionPermissions && role.collectionPermissions[id]) {
49
+ return mergePermissions(role.collectionPermissions[id], basePermissions);
50
+ } else if (role.defaultPermissions) {
51
+ return mergePermissions(role.defaultPermissions, basePermissions);
52
+ } else {
53
+ return basePermissions;
54
+ }
48
55
  }
49
- const te = (t, r) => ({
50
- read: t.read || r.read,
51
- create: t.create || r.create,
52
- edit: t.edit || r.edit,
53
- delete: t.delete || r.delete
54
- });
55
- function pn(t, r) {
56
- return t ? r.roles ? r.roles.map((n) => t.find((l) => l.id === n.id)).filter(Boolean) : [] : void 0;
56
+ const mergePermissions = (permA, permB) => {
57
+ return {
58
+ read: permA.read || permB.read,
59
+ create: permA.create || permB.create,
60
+ edit: permA.edit || permB.edit,
61
+ delete: permA.delete || permB.delete
62
+ };
63
+ };
64
+ function getUserRoles(roles, fireCMSUser) {
65
+ return !roles ? void 0 : fireCMSUser.roles ? fireCMSUser.roles.map((role) => roles.find((r) => r.id === role.id)).filter(Boolean) : [];
57
66
  }
58
- const ze = (t, r) => {
59
- const n = t.map((i) => i.id), l = r.map((i) => i.id);
60
- return n.length === r.length && n.every((i) => l.includes(i));
67
+ const areRolesEqual = (rolesA, rolesB) => {
68
+ const rolesAIds = rolesA.map((r) => r.id);
69
+ const rolesBIds = rolesB.map((r) => r.id);
70
+ return rolesAIds.length === rolesB.length && rolesAIds.every((role) => rolesBIds.includes(role));
61
71
  };
62
- function Cn(t, r) {
63
- if (!r)
72
+ function cacheDelegatedLoginToken(projectId, delegatedToken) {
73
+ if (!delegatedToken) {
64
74
  return;
65
- const n = Je(r), l = new Date(n.exp * 1e3);
66
- localStorage.setItem(`auth_token::${t}`, JSON.stringify({
67
- token: r,
68
- expiry: l
75
+ }
76
+ const data = parseJwt(delegatedToken);
77
+ const expiry = new Date(data.exp * 1e3);
78
+ localStorage.setItem(`auth_token::${projectId}`, JSON.stringify({
79
+ token: delegatedToken,
80
+ expiry
69
81
  }));
70
82
  }
71
- function vn(t) {
72
- const r = localStorage.getItem(`auth_token::${t}`);
73
- if (r) {
74
- const n = JSON.parse(r);
75
- if (n.expiry = new Date(n.expiry), n.expiry > /* @__PURE__ */ new Date())
76
- return n.token;
83
+ function getDelegatedLoginTokenFromCache(projectId) {
84
+ const entry = localStorage.getItem(`auth_token::${projectId}`);
85
+ if (entry) {
86
+ const data = JSON.parse(entry);
87
+ data.expiry = new Date(data.expiry);
88
+ if (data.expiry > /* @__PURE__ */ new Date()) {
89
+ return data.token;
90
+ }
77
91
  }
92
+ return void 0;
78
93
  }
79
- function wn() {
80
- for (let t = 0; t < localStorage.length; t++) {
81
- const r = localStorage.key(t);
82
- r?.startsWith("auth_token::") && localStorage.removeItem(r);
94
+ function clearDelegatedLoginTokensCache() {
95
+ for (let i = 0; i < localStorage.length; i++) {
96
+ const key = localStorage.key(i);
97
+ if (key?.startsWith("auth_token::")) {
98
+ localStorage.removeItem(key);
99
+ }
83
100
  }
84
101
  }
85
- function Je(t) {
86
- if (!t)
102
+ function parseJwt(token) {
103
+ if (!token) {
87
104
  throw new Error("No JWT token");
88
- const n = t.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), l = decodeURIComponent(window.atob(n).split("").map(function(i) {
89
- return "%" + ("00" + i.charCodeAt(0).toString(16)).slice(-2);
105
+ }
106
+ const base64Url = token.split(".")[1];
107
+ const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
108
+ const jsonPayload = decodeURIComponent(window.atob(base64).split("").map(function(c) {
109
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
90
110
  }).join(""));
91
- return JSON.parse(l);
111
+ return JSON.parse(jsonPayload);
92
112
  }
93
- function yn(t, r = 10) {
94
- if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(t))
113
+ function darkenColor(hexColor, darkenBy = 10) {
114
+ if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(hexColor)) {
95
115
  throw new Error("Invalid color format");
96
- let n = t.substring(1).split("");
97
- n.length === 3 && (n = [n[0], n[0], n[1], n[1], n[2], n[2]]);
98
- let l = parseInt(n[0] + n[1], 16), i = parseInt(n[2] + n[3], 16), m = parseInt(n[4] + n[5], 16);
99
- return l = Math.floor(l * (1 - r / 100)), i = Math.floor(i * (1 - r / 100)), m = Math.floor(m * (1 - r / 100)), "#" + (l < 16 ? "0" : "") + l.toString(16) + (i < 16 ? "0" : "") + i.toString(16) + (m < 16 ? "0" : "") + m.toString(16);
116
+ }
117
+ let color = hexColor.substring(1).split("");
118
+ if (color.length === 3) {
119
+ color = [color[0], color[0], color[1], color[1], color[2], color[2]];
120
+ }
121
+ let r = parseInt(color[0] + color[1], 16);
122
+ let g = parseInt(color[2] + color[3], 16);
123
+ let b = parseInt(color[4] + color[5], 16);
124
+ r = Math.floor(r * (1 - darkenBy / 100));
125
+ g = Math.floor(g * (1 - darkenBy / 100));
126
+ b = Math.floor(b * (1 - darkenBy / 100));
127
+ return "#" + (r < 16 ? "0" : "") + r.toString(16) + (g < 16 ? "0" : "") + g.toString(16) + (b < 16 ? "0" : "") + b.toString(16);
100
128
  }
101
- function bn(t, r = 10) {
102
- if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(t))
129
+ function hexToRgbaWithOpacity(hexColor, opacity = 10) {
130
+ if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(hexColor)) {
103
131
  throw new Error("Invalid color format");
104
- let n = t.substring(1).split("");
105
- n.length === 3 && (n = [n[0], n[0], n[1], n[1], n[2], n[2]]);
106
- const l = parseInt(n[0] + n[1], 16), i = parseInt(n[2] + n[3], 16), m = parseInt(n[4] + n[5], 16), g = r / 100;
107
- return `rgba(${l}, ${i}, ${m}, ${g})`;
132
+ }
133
+ let color = hexColor.substring(1).split("");
134
+ if (color.length === 3) {
135
+ color = [color[0], color[0], color[1], color[1], color[2], color[2]];
136
+ }
137
+ const r = parseInt(color[0] + color[1], 16);
138
+ const g = parseInt(color[2] + color[3], 16);
139
+ const b = parseInt(color[4] + color[5], 16);
140
+ const alpha = opacity / 100;
141
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
108
142
  }
109
- function Nn({
110
- firebaseApp: t,
111
- usersPath: r = "__FIRECMS/config/users",
112
- rolesPath: n = "__FIRECMS/config/roles",
113
- usersLimit: l,
114
- canEditRoles: i = !0,
115
- allowDefaultRolesCreation: m,
116
- includeCollectionConfigPermissions: g
143
+ function useBuildUserManagement({
144
+ dataSourceDelegate,
145
+ usersPath = "__FIRECMS/config/users",
146
+ rolesPath = "__FIRECMS/config/roles",
147
+ usersLimit,
148
+ canEditRoles = true,
149
+ allowDefaultRolesCreation,
150
+ includeCollectionConfigPermissions
117
151
  }) {
118
- const [v, R] = F.useState(!0), [w, c] = F.useState(!0), [E, U] = F.useState([]), [a, C] = F.useState([]), y = a.map((f) => ({
119
- ...f,
120
- roles: E.filter((p) => f.roles?.includes(p.id))
121
- })), [b, _] = F.useState(), [z, u] = F.useState(), h = v || w;
122
- ce(() => {
123
- if (!t || !n) return;
124
- const f = Y(t);
125
- return ue(
126
- ee(f, n),
127
- {
128
- next: (p) => {
129
- _(void 0);
130
- try {
131
- const N = He(p.docs);
132
- U(N);
133
- } catch (N) {
134
- console.error("Error loading roles", N), _(N);
135
- }
136
- R(!1);
137
- },
138
- error: (p) => {
139
- console.error("Error loading roles", p), _(p), R(!1);
152
+ const [rolesLoading, setRolesLoading] = React.useState(true);
153
+ const [usersLoading, setUsersLoading] = React.useState(true);
154
+ const [roles, setRoles] = React.useState([]);
155
+ const [usersWithRoleIds, setUsersWithRoleIds] = React.useState([]);
156
+ const users = usersWithRoleIds.map((u) => ({
157
+ ...u,
158
+ roles: roles.filter((r) => u.roles?.includes(r.id))
159
+ }));
160
+ const [rolesError, setRolesError] = React.useState();
161
+ const [usersError, setUsersError] = React.useState();
162
+ const loading = rolesLoading || usersLoading;
163
+ useEffect(() => {
164
+ if (!dataSourceDelegate || !rolesPath) return;
165
+ if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
166
+ return dataSourceDelegate.listenCollection?.({
167
+ path: rolesPath,
168
+ onUpdate(entities) {
169
+ setRolesError(void 0);
170
+ try {
171
+ const newRoles = entityToRoles(entities);
172
+ if (!equal(newRoles, roles))
173
+ setRoles(newRoles);
174
+ } catch (e) {
175
+ setRoles([]);
176
+ console.error("Error loading roles", e);
177
+ setRolesError(e);
140
178
  }
179
+ setRolesLoading(false);
180
+ },
181
+ onError(e) {
182
+ setRoles([]);
183
+ console.error("Error loading roles", e);
184
+ setRolesError(e);
185
+ setRolesLoading(false);
141
186
  }
142
- );
143
- }, [t, n]), ce(() => {
144
- if (!t || !r) return;
145
- const f = Y(t);
146
- return ue(
147
- ee(f, r),
148
- {
149
- next: (p) => {
150
- u(void 0);
151
- try {
152
- const N = Ge(p.docs);
153
- C(N);
154
- } catch (N) {
155
- console.error("Error loading users", N), u(N);
156
- }
157
- c(!1);
158
- },
159
- error: (p) => {
160
- console.error("Error loading users", p), u(p), c(!1);
187
+ });
188
+ }, [dataSourceDelegate?.initialised, rolesPath]);
189
+ useEffect(() => {
190
+ if (!dataSourceDelegate || !usersPath) return;
191
+ if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
192
+ return dataSourceDelegate.listenCollection?.({
193
+ path: usersPath,
194
+ onUpdate(entities) {
195
+ setUsersError(void 0);
196
+ try {
197
+ const newUsers = entitiesToUsers(entities);
198
+ if (!equal(newUsers, usersWithRoleIds))
199
+ setUsersWithRoleIds(newUsers);
200
+ } catch (e) {
201
+ setUsersWithRoleIds([]);
202
+ console.error("Error loading users", e);
203
+ setUsersError(e);
161
204
  }
205
+ setUsersLoading(false);
206
+ },
207
+ onError(e) {
208
+ setUsersWithRoleIds([]);
209
+ console.error("Error loading users", e);
210
+ setUsersError(e);
211
+ setUsersLoading(false);
162
212
  }
163
- );
164
- }, [t, r]);
165
- const x = k(async (f) => {
166
- if (!t) throw Error("useFirestoreUserManagement Firebase not initialised");
167
- const p = Y(t);
168
- if (!p || !r) throw Error("useFirestoreUserManagement Firestore not initialised");
169
- console.debug("Persisting user", f);
170
- const N = f.roles?.map((Ie) => Ie.id), {
171
- uid: q,
172
- ...Z
173
- } = f, de = {
174
- ...Z,
175
- roles: N
213
+ });
214
+ }, [dataSourceDelegate?.initialised, usersPath]);
215
+ const saveUser = useCallback(async (user) => {
216
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
217
+ if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
218
+ console.debug("Persisting user", user);
219
+ const roleIds = user.roles?.map((r) => r.id);
220
+ const {
221
+ uid,
222
+ ...userData
223
+ } = user;
224
+ const data = {
225
+ ...userData,
226
+ roles: roleIds
176
227
  };
177
- return q ? me(H(p, r, q), de, { merge: !0 }).then(() => f) : Ae(ee(p, r), de).then(() => f);
178
- }, [r, t]), D = k((f) => {
179
- if (!t) throw Error("useFirestoreUserManagement Firebase not initialised");
180
- const p = Y(t);
181
- if (!p || !n) throw Error("useFirestoreUserManagement Firestore not initialised");
182
- console.debug("Persisting role", f);
228
+ if (uid) {
229
+ return dataSourceDelegate.saveEntity({
230
+ status: "existing",
231
+ path: usersPath,
232
+ entityId: uid,
233
+ values: data
234
+ }).then(() => user);
235
+ } else {
236
+ return dataSourceDelegate.saveEntity({
237
+ status: "new",
238
+ path: usersPath,
239
+ values: data
240
+ }).then(() => user);
241
+ }
242
+ }, [usersPath, dataSourceDelegate?.initialised]);
243
+ const saveRole = useCallback((role) => {
244
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
245
+ if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
246
+ console.debug("Persisting role", role);
183
247
  const {
184
- id: N,
185
- ...q
186
- } = f, Z = H(p, n, N);
187
- return me(Z, q, { merge: !0 });
188
- }, [n, t]), T = k(async (f) => {
189
- if (!t) throw Error("useFirestoreUserManagement Firebase not initialised");
190
- const p = Y(t);
191
- if (!p || !r) throw Error("useFirestoreUserManagement Firestore not initialised");
192
- console.debug("Deleting", f);
193
- const { uid: N } = f;
194
- return he(H(p, r, N));
195
- }, [r, t]), o = k((f) => {
196
- if (!t) throw Error("useFirestoreUserManagement Firebase not initialised");
197
- const p = Y(t);
198
- if (!p || !n) throw Error("useFirestoreUserManagement Firestore not initialised");
199
- console.debug("Deleting", f);
200
- const { id: N } = f, q = H(p, n, N);
201
- return he(q);
202
- }, [n, t]), S = k(({
203
- collection: f,
204
- user: p
205
- }) => We({
206
- collection: f,
207
- user: p
208
- }), []), $ = k((f) => {
209
- if (!y) throw Error("Users not loaded");
210
- return y.find((N) => N.email?.toLowerCase() === f?.email?.toLowerCase())?.roles;
211
- }, [y]), G = k(({ user: f }) => {
212
- if (console.debug("Authenticating user", f), h)
213
- return console.warn("User management is still loading"), !1;
214
- if (y.length === 0 || y.find((N) => N.email?.toLowerCase() === f?.email?.toLowerCase()))
215
- return !0;
248
+ id,
249
+ ...roleData
250
+ } = role;
251
+ return dataSourceDelegate.saveEntity({
252
+ status: "existing",
253
+ path: rolesPath,
254
+ entityId: id,
255
+ values: roleData
256
+ }).then(() => {
257
+ return;
258
+ });
259
+ }, [rolesPath, dataSourceDelegate?.initialised]);
260
+ const deleteUser = useCallback(async (user) => {
261
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
262
+ if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
263
+ console.debug("Deleting", user);
264
+ const { uid } = user;
265
+ const entity = {
266
+ path: usersPath,
267
+ id: uid,
268
+ values: {}
269
+ };
270
+ await dataSourceDelegate.deleteEntity({ entity });
271
+ }, [usersPath, dataSourceDelegate?.initialised]);
272
+ const deleteRole = useCallback(async (role) => {
273
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
274
+ if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
275
+ console.debug("Deleting", role);
276
+ const { id } = role;
277
+ const entity = {
278
+ path: usersPath,
279
+ id,
280
+ values: {}
281
+ };
282
+ await dataSourceDelegate.deleteEntity({ entity });
283
+ }, [rolesPath, dataSourceDelegate?.initialised]);
284
+ const collectionPermissions = useCallback(({
285
+ collection,
286
+ user
287
+ }) => resolveUserRolePermissions({
288
+ collection,
289
+ user
290
+ }), []);
291
+ const defineRolesFor = useCallback((user) => {
292
+ if (!users) throw Error("Users not loaded");
293
+ const mgmtUser = users.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
294
+ return mgmtUser?.roles;
295
+ }, [users]);
296
+ const authenticator = useCallback(({ user }) => {
297
+ console.debug("Authenticating user", user);
298
+ if (loading) {
299
+ console.warn("User management is still loading");
300
+ return false;
301
+ }
302
+ if (users.length === 0) {
303
+ return true;
304
+ }
305
+ const mgmtUser = users.find((u) => u.email?.toLowerCase() === user?.email?.toLowerCase());
306
+ if (mgmtUser) {
307
+ return true;
308
+ }
216
309
  throw Error("Could not find a user with the provided email in the user management system.");
217
- }, [h, y]), ke = E.some((f) => f.id === "admin");
310
+ }, [loading, users]);
311
+ const isAdmin = roles.some((r) => r.id === "admin");
218
312
  return {
219
- loading: h,
220
- roles: E,
221
- users: y,
222
- saveUser: x,
223
- saveRole: D,
224
- rolesError: b,
225
- deleteUser: T,
226
- deleteRole: o,
227
- usersLimit: l,
228
- usersError: z,
229
- isAdmin: ke,
230
- canEditRoles: i === void 0 ? !0 : i,
231
- allowDefaultRolesCreation: m === void 0 ? !0 : m,
232
- includeCollectionConfigPermissions: !!g,
233
- collectionPermissions: S,
234
- defineRolesFor: $,
235
- authenticator: G
313
+ loading,
314
+ roles,
315
+ users,
316
+ saveUser,
317
+ saveRole,
318
+ rolesError,
319
+ deleteUser,
320
+ deleteRole,
321
+ usersLimit,
322
+ usersError,
323
+ isAdmin,
324
+ canEditRoles: canEditRoles === void 0 ? true : canEditRoles,
325
+ allowDefaultRolesCreation: allowDefaultRolesCreation === void 0 ? true : allowDefaultRolesCreation,
326
+ includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
327
+ collectionPermissions,
328
+ defineRolesFor,
329
+ authenticator
236
330
  };
237
331
  }
238
- const Ge = (t) => t.map((r) => {
239
- const n = r.data();
240
- return {
241
- uid: r.id,
242
- ...n,
243
- created_on: n?.created_on?.toDate(),
244
- updated_on: n?.updated_on?.toDate()
245
- };
246
- }), He = (t) => t.map((r) => ({
247
- id: r.id,
248
- ...r.data()
249
- })), Ee = F.createContext({});
250
- function Ke({
251
- children: t,
252
- userManagement: r
332
+ const entitiesToUsers = (docs) => {
333
+ return docs.map((doc) => {
334
+ const data = doc.values;
335
+ const newVar = {
336
+ uid: doc.id,
337
+ ...data,
338
+ created_on: data?.created_on,
339
+ updated_on: data?.updated_on
340
+ };
341
+ return newVar;
342
+ });
343
+ };
344
+ const entityToRoles = (entities) => {
345
+ return entities.map((doc) => ({
346
+ id: doc.id,
347
+ ...doc.values
348
+ }));
349
+ };
350
+ const UserManagementContext = React.createContext({});
351
+ function UserManagementProvider({
352
+ children,
353
+ userManagement
253
354
  }) {
254
- return /* @__PURE__ */ e(Ee.Provider, { value: r, children: t });
355
+ return /* @__PURE__ */ jsx(UserManagementContext.Provider, { value: userManagement, children });
255
356
  }
256
- const j = () => Fe(Ee);
257
- function X({ role: t }) {
258
- let r;
259
- return t.isAdmin ? r = "blueDarker" : t.id === "editor" ? r = "yellowLight" : t.id === "viewer" ? r = "grayLight" : r = Pe(t.id), /* @__PURE__ */ e(
260
- Te,
357
+ const useUserManagement = () => useContext(UserManagementContext);
358
+ function RoleChip({ role }) {
359
+ let colorScheme;
360
+ if (role.isAdmin) {
361
+ colorScheme = "blueDarker";
362
+ } else if (role.id === "editor") {
363
+ colorScheme = "yellowLight";
364
+ } else if (role.id === "viewer") {
365
+ colorScheme = "grayLight";
366
+ } else {
367
+ colorScheme = getColorSchemeForSeed(role.id);
368
+ }
369
+ return /* @__PURE__ */ jsx(
370
+ Chip,
261
371
  {
262
- colorScheme: r,
263
- children: t.name
372
+ colorScheme,
373
+ children: role.name
264
374
  },
265
- t.id
375
+ role.id
266
376
  );
267
377
  }
268
- const Qe = M.object().shape({
269
- id: M.string().required("Required"),
270
- name: M.string().required("Required")
378
+ const RoleYupSchema = Yup.object().shape({
379
+ id: Yup.string().required("Required"),
380
+ name: Yup.string().required("Required")
271
381
  });
272
- function Xe({
273
- open: t,
274
- role: r,
275
- editable: n,
276
- handleClose: l,
277
- collections: i
382
+ function RolesDetailsForm({
383
+ open,
384
+ role,
385
+ editable,
386
+ handleClose,
387
+ collections
278
388
  }) {
279
- const { saveRole: m } = j(), g = !r, [v, R] = A(), w = k((o) => (R(void 0), m(o)), [m]), c = Re({
280
- initialValues: r ?? {
389
+ const { saveRole } = useUserManagement();
390
+ const isNewRole = !role;
391
+ const [savingError, setSavingError] = useState();
392
+ const onRoleUpdated = useCallback((role2) => {
393
+ setSavingError(void 0);
394
+ return saveRole(role2);
395
+ }, [saveRole]);
396
+ const formex = useCreateFormex({
397
+ initialValues: role ?? {
281
398
  name: ""
282
399
  },
283
- onSubmit: (o, S) => w(o).then(() => {
284
- S.resetForm({
285
- values: o
286
- }), l();
287
- }).catch(($) => R($)),
288
- validation: (o) => Qe.validate(o, { abortEarly: !1 }).then(() => ({})).catch((S) => {
289
- const $ = {};
290
- return S.inner.forEach((G) => {
291
- $[G.path] = G.message;
292
- }), $;
293
- })
294
- }), {
295
- isSubmitting: E,
296
- touched: U,
297
- values: a,
298
- errors: C,
299
- handleChange: y,
300
- setFieldValue: b,
301
- dirty: _,
302
- setFieldTouched: z
303
- } = c, u = a.isAdmin ?? !1, h = a.defaultPermissions?.create ?? !1, x = a.defaultPermissions?.read ?? !1, D = a.defaultPermissions?.edit ?? !1, T = a.defaultPermissions?.delete ?? !1;
304
- return F.useEffect(() => {
305
- !J(U, "id") && a.name && b("id", _e(a.name));
306
- }, [U, a.name]), /* @__PURE__ */ e(
307
- fe,
400
+ onSubmit: (role2, formexController) => {
401
+ return onRoleUpdated(role2).then(() => {
402
+ formexController.resetForm({
403
+ values: role2
404
+ });
405
+ handleClose();
406
+ }).catch((e) => setSavingError(e));
407
+ },
408
+ validation: (values2) => {
409
+ return RoleYupSchema.validate(values2, { abortEarly: false }).then(() => ({})).catch((e) => {
410
+ const errors2 = {};
411
+ e.inner.forEach((error) => {
412
+ errors2[error.path] = error.message;
413
+ });
414
+ return errors2;
415
+ });
416
+ }
417
+ });
418
+ const {
419
+ isSubmitting,
420
+ touched,
421
+ values,
422
+ errors,
423
+ handleChange,
424
+ setFieldValue,
425
+ dirty,
426
+ setFieldTouched
427
+ } = formex;
428
+ const isAdmin = values.isAdmin ?? false;
429
+ const defaultCreate = values.defaultPermissions?.create ?? false;
430
+ const defaultRead = values.defaultPermissions?.read ?? false;
431
+ const defaultEdit = values.defaultPermissions?.edit ?? false;
432
+ const defaultDelete = values.defaultPermissions?.delete ?? false;
433
+ React.useEffect(() => {
434
+ const idTouched = getIn(touched, "id");
435
+ if (!idTouched && values.name) {
436
+ setFieldValue("id", toSnakeCase(values.name));
437
+ }
438
+ }, [touched, values.name]);
439
+ return /* @__PURE__ */ jsx(
440
+ Dialog,
308
441
  {
309
- open: t,
442
+ open,
310
443
  maxWidth: "4xl",
311
- children: /* @__PURE__ */ e(De, { value: c, children: /* @__PURE__ */ s(
444
+ children: /* @__PURE__ */ jsx(Formex, { value: formex, children: /* @__PURE__ */ jsxs(
312
445
  "form",
313
446
  {
314
- noValidate: !0,
447
+ noValidate: true,
315
448
  autoComplete: "off",
316
- onSubmit: c.handleSubmit,
449
+ onSubmit: formex.handleSubmit,
317
450
  style: {
318
451
  display: "flex",
319
452
  flexDirection: "column",
@@ -321,13 +454,13 @@ function Xe({
321
454
  height: "100%"
322
455
  },
323
456
  children: [
324
- /* @__PURE__ */ s(ge, { className: "flex-grow", children: [
325
- /* @__PURE__ */ e(
457
+ /* @__PURE__ */ jsxs(DialogContent, { className: "flex-grow", children: [
458
+ /* @__PURE__ */ jsx(
326
459
  "div",
327
460
  {
328
461
  className: "flex flex-row pt-12 pb-8",
329
- children: /* @__PURE__ */ e(
330
- P,
462
+ children: /* @__PURE__ */ jsx(
463
+ Typography,
331
464
  {
332
465
  variant: "h4",
333
466
  className: "flex-grow",
@@ -336,161 +469,162 @@ function Xe({
336
469
  )
337
470
  }
338
471
  ),
339
- /* @__PURE__ */ s("div", { className: "grid grid-cols-12 gap-8", children: [
340
- /* @__PURE__ */ s("div", { className: "col-span-12 md:col-span-8", children: [
341
- /* @__PURE__ */ e(
342
- Q,
472
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-8", children: [
473
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12 md:col-span-8", children: [
474
+ /* @__PURE__ */ jsx(
475
+ TextField,
343
476
  {
344
477
  name: "name",
345
- required: !0,
346
- error: U.name && !!C.name,
347
- value: a.name,
348
- disabled: u || !n,
349
- onChange: y,
478
+ required: true,
479
+ error: touched.name && Boolean(errors.name),
480
+ value: values.name,
481
+ disabled: isAdmin || !editable,
482
+ onChange: handleChange,
350
483
  "aria-describedby": "name-helper-text",
351
484
  label: "Name"
352
485
  }
353
486
  ),
354
- /* @__PURE__ */ e(B, { children: U.name && C.name ? C.name : "Name of this role" })
487
+ /* @__PURE__ */ jsx(FieldCaption, { children: touched.name && Boolean(errors.name) ? errors.name : "Name of this role" })
355
488
  ] }),
356
- /* @__PURE__ */ s("div", { className: "col-span-12 md:col-span-4", children: [
357
- /* @__PURE__ */ e(
358
- Q,
489
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12 md:col-span-4", children: [
490
+ /* @__PURE__ */ jsx(
491
+ TextField,
359
492
  {
360
493
  name: "id",
361
- required: !0,
362
- error: U.id && !!C.id,
363
- value: a.id,
364
- disabled: !g || !n,
365
- onChange: (o) => {
366
- y(o), z("id", !0);
494
+ required: true,
495
+ error: touched.id && Boolean(errors.id),
496
+ value: values.id,
497
+ disabled: !isNewRole || !editable,
498
+ onChange: (e) => {
499
+ handleChange(e);
500
+ setFieldTouched("id", true);
367
501
  },
368
502
  "aria-describedby": "id-helper-text",
369
503
  label: "ID"
370
504
  }
371
505
  ),
372
- /* @__PURE__ */ e(B, { children: U.id && C.id ? C.id : "ID of this role" })
506
+ /* @__PURE__ */ jsx(FieldCaption, { children: touched.id && Boolean(errors.id) ? errors.id : "ID of this role" })
373
507
  ] }),
374
- /* @__PURE__ */ s("div", { className: "col-span-12", children: [
375
- /* @__PURE__ */ e(
376
- pe,
508
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12", children: [
509
+ /* @__PURE__ */ jsx(
510
+ Paper,
377
511
  {
378
512
  className: "bg-inherit",
379
- children: /* @__PURE__ */ s(re, { children: [
380
- /* @__PURE__ */ s(ie, { children: [
381
- /* @__PURE__ */ e(d, {}),
382
- /* @__PURE__ */ e(
383
- d,
513
+ children: /* @__PURE__ */ jsxs(Table, { children: [
514
+ /* @__PURE__ */ jsxs(TableHeader, { children: [
515
+ /* @__PURE__ */ jsx(TableCell, {}),
516
+ /* @__PURE__ */ jsx(
517
+ TableCell,
384
518
  {
385
519
  align: "center",
386
520
  children: "Create entities"
387
521
  }
388
522
  ),
389
- /* @__PURE__ */ e(
390
- d,
523
+ /* @__PURE__ */ jsx(
524
+ TableCell,
391
525
  {
392
526
  align: "center",
393
527
  children: "Read entities"
394
528
  }
395
529
  ),
396
- /* @__PURE__ */ e(
397
- d,
530
+ /* @__PURE__ */ jsx(
531
+ TableCell,
398
532
  {
399
533
  align: "center",
400
534
  children: "Update entities"
401
535
  }
402
536
  ),
403
- /* @__PURE__ */ e(
404
- d,
537
+ /* @__PURE__ */ jsx(
538
+ TableCell,
405
539
  {
406
540
  align: "center",
407
541
  children: "Delete entities"
408
542
  }
409
543
  )
410
544
  ] }),
411
- /* @__PURE__ */ s(oe, { children: [
412
- /* @__PURE__ */ s(W, { children: [
413
- /* @__PURE__ */ e(
414
- d,
545
+ /* @__PURE__ */ jsxs(TableBody, { children: [
546
+ /* @__PURE__ */ jsxs(TableRow, { children: [
547
+ /* @__PURE__ */ jsx(
548
+ TableCell,
415
549
  {
416
550
  scope: "row",
417
- children: /* @__PURE__ */ e("strong", { children: "All collections" })
551
+ children: /* @__PURE__ */ jsx("strong", { children: "All collections" })
418
552
  }
419
553
  ),
420
- /* @__PURE__ */ e(
421
- d,
554
+ /* @__PURE__ */ jsx(
555
+ TableCell,
422
556
  {
423
557
  align: "center",
424
- children: /* @__PURE__ */ e(
425
- V,
558
+ children: /* @__PURE__ */ jsx(
559
+ Tooltip,
426
560
  {
427
561
  title: "Create entities in collections",
428
- children: /* @__PURE__ */ e(
429
- I,
562
+ children: /* @__PURE__ */ jsx(
563
+ Checkbox,
430
564
  {
431
- disabled: u || !n,
432
- checked: (u || h) ?? !1,
433
- onCheckedChange: (o) => b("defaultPermissions.create", o)
565
+ disabled: isAdmin || !editable,
566
+ checked: (isAdmin || defaultCreate) ?? false,
567
+ onCheckedChange: (checked) => setFieldValue("defaultPermissions.create", checked)
434
568
  }
435
569
  )
436
570
  }
437
571
  )
438
572
  }
439
573
  ),
440
- /* @__PURE__ */ e(
441
- d,
574
+ /* @__PURE__ */ jsx(
575
+ TableCell,
442
576
  {
443
577
  align: "center",
444
- children: /* @__PURE__ */ e(
445
- V,
578
+ children: /* @__PURE__ */ jsx(
579
+ Tooltip,
446
580
  {
447
581
  title: "Access all data in every collection",
448
- children: /* @__PURE__ */ e(
449
- I,
582
+ children: /* @__PURE__ */ jsx(
583
+ Checkbox,
450
584
  {
451
- disabled: u || !n,
452
- checked: (u || x) ?? !1,
453
- onCheckedChange: (o) => b("defaultPermissions.read", o)
585
+ disabled: isAdmin || !editable,
586
+ checked: (isAdmin || defaultRead) ?? false,
587
+ onCheckedChange: (checked) => setFieldValue("defaultPermissions.read", checked)
454
588
  }
455
589
  )
456
590
  }
457
591
  )
458
592
  }
459
593
  ),
460
- /* @__PURE__ */ e(
461
- d,
594
+ /* @__PURE__ */ jsx(
595
+ TableCell,
462
596
  {
463
597
  align: "center",
464
- children: /* @__PURE__ */ e(
465
- V,
598
+ children: /* @__PURE__ */ jsx(
599
+ Tooltip,
466
600
  {
467
601
  title: "Update data in any collection",
468
- children: /* @__PURE__ */ e(
469
- I,
602
+ children: /* @__PURE__ */ jsx(
603
+ Checkbox,
470
604
  {
471
- disabled: u || !n,
472
- checked: (u || D) ?? !1,
473
- onCheckedChange: (o) => b("defaultPermissions.edit", o)
605
+ disabled: isAdmin || !editable,
606
+ checked: (isAdmin || defaultEdit) ?? false,
607
+ onCheckedChange: (checked) => setFieldValue("defaultPermissions.edit", checked)
474
608
  }
475
609
  )
476
610
  }
477
611
  )
478
612
  }
479
613
  ),
480
- /* @__PURE__ */ e(
481
- d,
614
+ /* @__PURE__ */ jsx(
615
+ TableCell,
482
616
  {
483
617
  align: "center",
484
- children: /* @__PURE__ */ e(
485
- V,
618
+ children: /* @__PURE__ */ jsx(
619
+ Tooltip,
486
620
  {
487
621
  title: "Delete data in any collection",
488
- children: /* @__PURE__ */ e(
489
- I,
622
+ children: /* @__PURE__ */ jsx(
623
+ Checkbox,
490
624
  {
491
- disabled: u || !n,
492
- checked: (u || T) ?? !1,
493
- onCheckedChange: (o) => b("defaultPermissions.delete", o)
625
+ disabled: isAdmin || !editable,
626
+ checked: (isAdmin || defaultDelete) ?? false,
627
+ onCheckedChange: (checked) => setFieldValue("defaultPermissions.delete", checked)
494
628
  }
495
629
  )
496
630
  }
@@ -498,100 +632,100 @@ function Xe({
498
632
  }
499
633
  )
500
634
  ] }),
501
- i && i.map((o) => /* @__PURE__ */ s(W, { children: [
502
- /* @__PURE__ */ e(
503
- d,
635
+ collections && collections.map((col) => /* @__PURE__ */ jsxs(TableRow, { children: [
636
+ /* @__PURE__ */ jsx(
637
+ TableCell,
504
638
  {
505
639
  scope: "row",
506
- children: o.name
640
+ children: col.name
507
641
  }
508
642
  ),
509
- /* @__PURE__ */ e(
510
- d,
643
+ /* @__PURE__ */ jsx(
644
+ TableCell,
511
645
  {
512
646
  align: "center",
513
- children: /* @__PURE__ */ e(
514
- I,
647
+ children: /* @__PURE__ */ jsx(
648
+ Checkbox,
515
649
  {
516
- disabled: u || h || !n,
517
- checked: (u || h || J(a, `collectionPermissions.${o.path}.create`)) ?? !1,
518
- onCheckedChange: (S) => b(`collectionPermissions.${o.path}.create`, S)
650
+ disabled: isAdmin || defaultCreate || !editable,
651
+ checked: (isAdmin || defaultCreate || getIn(values, `collectionPermissions.${col.path}.create`)) ?? false,
652
+ onCheckedChange: (checked) => setFieldValue(`collectionPermissions.${col.path}.create`, checked)
519
653
  }
520
654
  )
521
655
  }
522
656
  ),
523
- /* @__PURE__ */ e(
524
- d,
657
+ /* @__PURE__ */ jsx(
658
+ TableCell,
525
659
  {
526
660
  align: "center",
527
- children: /* @__PURE__ */ e(
528
- I,
661
+ children: /* @__PURE__ */ jsx(
662
+ Checkbox,
529
663
  {
530
- disabled: u || x || !n,
531
- checked: (u || x || J(a, `collectionPermissions.${o.path}.read`)) ?? !1,
532
- onCheckedChange: (S) => b(`collectionPermissions.${o.path}.read`, S)
664
+ disabled: isAdmin || defaultRead || !editable,
665
+ checked: (isAdmin || defaultRead || getIn(values, `collectionPermissions.${col.path}.read`)) ?? false,
666
+ onCheckedChange: (checked) => setFieldValue(`collectionPermissions.${col.path}.read`, checked)
533
667
  }
534
668
  )
535
669
  }
536
670
  ),
537
- /* @__PURE__ */ e(
538
- d,
671
+ /* @__PURE__ */ jsx(
672
+ TableCell,
539
673
  {
540
674
  align: "center",
541
- children: /* @__PURE__ */ e(
542
- I,
675
+ children: /* @__PURE__ */ jsx(
676
+ Checkbox,
543
677
  {
544
- disabled: u || D || !n,
545
- checked: (u || D || J(a, `collectionPermissions.${o.path}.edit`)) ?? !1,
546
- onCheckedChange: (S) => b(`collectionPermissions.${o.path}.edit`, S)
678
+ disabled: isAdmin || defaultEdit || !editable,
679
+ checked: (isAdmin || defaultEdit || getIn(values, `collectionPermissions.${col.path}.edit`)) ?? false,
680
+ onCheckedChange: (checked) => setFieldValue(`collectionPermissions.${col.path}.edit`, checked)
547
681
  }
548
682
  )
549
683
  }
550
684
  ),
551
- /* @__PURE__ */ e(
552
- d,
685
+ /* @__PURE__ */ jsx(
686
+ TableCell,
553
687
  {
554
688
  align: "center",
555
- children: /* @__PURE__ */ e(
556
- I,
689
+ children: /* @__PURE__ */ jsx(
690
+ Checkbox,
557
691
  {
558
- disabled: u || T || !n,
559
- checked: (u || T || J(a, `collectionPermissions.${o.path}.delete`)) ?? !1,
560
- onCheckedChange: (S) => b(`collectionPermissions.${o.path}.delete`, S)
692
+ disabled: isAdmin || defaultDelete || !editable,
693
+ checked: (isAdmin || defaultDelete || getIn(values, `collectionPermissions.${col.path}.delete`)) ?? false,
694
+ onCheckedChange: (checked) => setFieldValue(`collectionPermissions.${col.path}.delete`, checked)
561
695
  }
562
696
  )
563
697
  }
564
698
  )
565
- ] }, o.name))
699
+ ] }, col.name))
566
700
  ] })
567
701
  ] })
568
702
  }
569
703
  ),
570
- /* @__PURE__ */ e(B, { children: "You can customise the permissions that the users related to this role can perform in the entities of each collection" })
704
+ /* @__PURE__ */ jsx(FieldCaption, { children: "You can customise the permissions that the users related to this role can perform in the entities of each collection" })
571
705
  ] }),
572
- /* @__PURE__ */ s("div", { className: "col-span-12 md:col-span-4", children: [
573
- /* @__PURE__ */ s(
574
- ne,
706
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12 md:col-span-4", children: [
707
+ /* @__PURE__ */ jsxs(
708
+ Select,
575
709
  {
576
- error: U.config && !!C.config,
710
+ error: touched.config && Boolean(errors.config),
577
711
  id: "createCollections",
578
712
  name: "createCollections",
579
713
  label: "Create collections",
580
714
  position: "item-aligned",
581
- disabled: u || !n,
582
- onChange: (o) => b("config.createCollections", o.target.value === "true"),
583
- value: u || a.config?.createCollections ? "true" : "false",
584
- renderValue: (o) => o === "true" ? "Yes" : "No",
715
+ disabled: isAdmin || !editable,
716
+ onChange: (event) => setFieldValue("config.createCollections", event.target.value === "true"),
717
+ value: isAdmin || values.config?.createCollections ? "true" : "false",
718
+ renderValue: (value) => value === "true" ? "Yes" : "No",
585
719
  children: [
586
- /* @__PURE__ */ e(
587
- L,
720
+ /* @__PURE__ */ jsx(
721
+ SelectItem,
588
722
  {
589
723
  value: "true",
590
724
  children: " Yes "
591
725
  }
592
726
  ),
593
- /* @__PURE__ */ e(
594
- L,
727
+ /* @__PURE__ */ jsx(
728
+ SelectItem,
595
729
  {
596
730
  value: "false",
597
731
  children: " No "
@@ -600,38 +734,38 @@ function Xe({
600
734
  ]
601
735
  }
602
736
  ),
603
- /* @__PURE__ */ e(B, { children: U.config && C.config ? C.config : "Can the user create collections" })
737
+ /* @__PURE__ */ jsx(FieldCaption, { children: touched.config && Boolean(errors.config) ? errors.config : "Can the user create collections" })
604
738
  ] }),
605
- /* @__PURE__ */ s("div", { className: "col-span-12 md:col-span-4", children: [
606
- /* @__PURE__ */ s(
607
- ne,
739
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12 md:col-span-4", children: [
740
+ /* @__PURE__ */ jsxs(
741
+ Select,
608
742
  {
609
- error: U.config && !!C.config,
743
+ error: touched.config && Boolean(errors.config),
610
744
  id: "editCollections",
611
745
  name: "editCollections",
612
746
  label: "Edit collections",
613
- disabled: u || !n,
747
+ disabled: isAdmin || !editable,
614
748
  position: "item-aligned",
615
- onChange: (o) => b("config.editCollections", o.target.value === "own" ? "own" : o.target.value === "true"),
616
- value: u ? "true" : a.config?.editCollections === "own" ? "own" : a.config?.editCollections ? "true" : "false",
617
- renderValue: (o) => o === "own" ? "Own" : o === "true" ? "Yes" : "No",
749
+ onChange: (event) => setFieldValue("config.editCollections", event.target.value === "own" ? "own" : event.target.value === "true"),
750
+ value: isAdmin ? "true" : values.config?.editCollections === "own" ? "own" : values.config?.editCollections ? "true" : "false",
751
+ renderValue: (value) => value === "own" ? "Own" : value === "true" ? "Yes" : "No",
618
752
  children: [
619
- /* @__PURE__ */ e(
620
- L,
753
+ /* @__PURE__ */ jsx(
754
+ SelectItem,
621
755
  {
622
756
  value: "true",
623
757
  children: " Yes "
624
758
  }
625
759
  ),
626
- /* @__PURE__ */ e(
627
- L,
760
+ /* @__PURE__ */ jsx(
761
+ SelectItem,
628
762
  {
629
763
  value: "false",
630
764
  children: " No "
631
765
  }
632
766
  ),
633
- /* @__PURE__ */ e(
634
- L,
767
+ /* @__PURE__ */ jsx(
768
+ SelectItem,
635
769
  {
636
770
  value: "own",
637
771
  children: " Only his/her own "
@@ -640,38 +774,38 @@ function Xe({
640
774
  ]
641
775
  }
642
776
  ),
643
- /* @__PURE__ */ e(B, { children: U.config && C.config ? C.config : "Can the user edit collections" })
777
+ /* @__PURE__ */ jsx(FieldCaption, { children: touched.config && Boolean(errors.config) ? errors.config : "Can the user edit collections" })
644
778
  ] }),
645
- /* @__PURE__ */ s("div", { className: "col-span-12 md:col-span-4", children: [
646
- /* @__PURE__ */ s(
647
- ne,
779
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12 md:col-span-4", children: [
780
+ /* @__PURE__ */ jsxs(
781
+ Select,
648
782
  {
649
- error: U.config && !!C.config,
783
+ error: touched.config && Boolean(errors.config),
650
784
  id: "deleteCollections",
651
785
  name: "deleteCollections",
652
786
  label: "Delete collections",
653
- disabled: u || !n,
787
+ disabled: isAdmin || !editable,
654
788
  position: "item-aligned",
655
- onChange: (o) => b("config.deleteCollections", o.target.value === "own" ? "own" : o.target.value === "true"),
656
- value: u ? "true" : a.config?.deleteCollections === "own" ? "own" : a.config?.deleteCollections ? "true" : "false",
657
- renderValue: (o) => o === "own" ? "Own" : o === "true" ? "Yes" : "No",
789
+ onChange: (event) => setFieldValue("config.deleteCollections", event.target.value === "own" ? "own" : event.target.value === "true"),
790
+ value: isAdmin ? "true" : values.config?.deleteCollections === "own" ? "own" : values.config?.deleteCollections ? "true" : "false",
791
+ renderValue: (value) => value === "own" ? "Own" : value === "true" ? "Yes" : "No",
658
792
  children: [
659
- /* @__PURE__ */ e(
660
- L,
793
+ /* @__PURE__ */ jsx(
794
+ SelectItem,
661
795
  {
662
796
  value: "true",
663
797
  children: " Yes "
664
798
  }
665
799
  ),
666
- /* @__PURE__ */ e(
667
- L,
800
+ /* @__PURE__ */ jsx(
801
+ SelectItem,
668
802
  {
669
803
  value: "false",
670
804
  children: " No "
671
805
  }
672
806
  ),
673
- /* @__PURE__ */ e(
674
- L,
807
+ /* @__PURE__ */ jsx(
808
+ SelectItem,
675
809
  {
676
810
  value: "own",
677
811
  children: " Only his/her own "
@@ -680,32 +814,32 @@ function Xe({
680
814
  ]
681
815
  }
682
816
  ),
683
- /* @__PURE__ */ e(B, { children: U.config && C.config ? C.config : "Can the user delete collections" })
817
+ /* @__PURE__ */ jsx(FieldCaption, { children: touched.config && Boolean(errors.config) ? errors.config : "Can the user delete collections" })
684
818
  ] })
685
819
  ] })
686
820
  ] }),
687
- /* @__PURE__ */ s(Ce, { position: "sticky", children: [
688
- v && /* @__PURE__ */ e(P, { className: "text-red-500", children: "There was an error saving this role" }),
689
- /* @__PURE__ */ e(
690
- O,
821
+ /* @__PURE__ */ jsxs(DialogActions, { position: "sticky", children: [
822
+ savingError && /* @__PURE__ */ jsx(Typography, { className: "text-red-500", children: "There was an error saving this role" }),
823
+ /* @__PURE__ */ jsx(
824
+ Button,
691
825
  {
692
826
  variant: "text",
693
827
  onClick: () => {
694
- l();
828
+ handleClose();
695
829
  },
696
830
  children: "Cancel"
697
831
  }
698
832
  ),
699
- /* @__PURE__ */ e(
700
- ve,
833
+ /* @__PURE__ */ jsx(
834
+ LoadingButton,
701
835
  {
702
836
  variant: "filled",
703
837
  color: "primary",
704
838
  type: "submit",
705
- disabled: !_,
706
- loading: E,
707
- startIcon: /* @__PURE__ */ e(we, {}),
708
- children: g ? "Create role" : "Update"
839
+ disabled: !dirty,
840
+ loading: isSubmitting,
841
+ startIcon: /* @__PURE__ */ jsx(DoneIcon, {}),
842
+ children: isNewRole ? "Create role" : "Update"
709
843
  }
710
844
  )
711
845
  ] })
@@ -715,24 +849,24 @@ function Xe({
715
849
  }
716
850
  );
717
851
  }
718
- const Se = [
852
+ const DEFAULT_ROLES = [
719
853
  {
720
854
  id: "admin",
721
855
  name: "Admin",
722
- isAdmin: !0
856
+ isAdmin: true
723
857
  },
724
858
  {
725
859
  id: "editor",
726
860
  name: "Editor",
727
- isAdmin: !1,
861
+ isAdmin: false,
728
862
  defaultPermissions: {
729
- read: !0,
730
- create: !0,
731
- edit: !0,
732
- delete: !0
863
+ read: true,
864
+ create: true,
865
+ edit: true,
866
+ delete: true
733
867
  },
734
868
  config: {
735
- createCollections: !0,
869
+ createCollections: true,
736
870
  editCollections: "own",
737
871
  deleteCollections: "own"
738
872
  }
@@ -740,78 +874,86 @@ const Se = [
740
874
  {
741
875
  id: "viewer",
742
876
  name: "Viewer",
743
- isAdmin: !1,
877
+ isAdmin: false,
744
878
  defaultPermissions: {
745
- read: !0,
746
- create: !1,
747
- edit: !1,
748
- delete: !1
879
+ read: true,
880
+ create: false,
881
+ edit: false,
882
+ delete: false
749
883
  }
750
884
  }
751
885
  ];
752
- function Ze({
753
- onRoleClicked: t,
754
- editable: r
886
+ function RolesTable({
887
+ onRoleClicked,
888
+ editable
755
889
  }) {
756
890
  const {
757
- roles: n,
758
- saveRole: l,
759
- deleteRole: i,
760
- allowDefaultRolesCreation: m
761
- } = j(), [g, v] = A(void 0), [R, w] = A(!1);
762
- return /* @__PURE__ */ s(
891
+ roles,
892
+ saveRole,
893
+ deleteRole,
894
+ allowDefaultRolesCreation
895
+ } = useUserManagement();
896
+ const [roleToBeDeleted, setRoleToBeDeleted] = useState(void 0);
897
+ const [deleteInProgress, setDeleteInProgress] = useState(false);
898
+ return /* @__PURE__ */ jsxs(
763
899
  "div",
764
900
  {
765
901
  className: "w-full overflow-auto",
766
902
  children: [
767
- /* @__PURE__ */ s(re, { children: [
768
- /* @__PURE__ */ s(ie, { children: [
769
- /* @__PURE__ */ e(d, { header: !0, className: "w-16" }),
770
- /* @__PURE__ */ e(d, { header: !0, children: "Role" }),
771
- /* @__PURE__ */ e(d, { header: !0, className: "items-center", children: "Is Admin" }),
772
- /* @__PURE__ */ e(d, { header: !0, children: "Default permissions" })
903
+ /* @__PURE__ */ jsxs(Table, { children: [
904
+ /* @__PURE__ */ jsxs(TableHeader, { children: [
905
+ /* @__PURE__ */ jsx(TableCell, { header: true, className: "w-16" }),
906
+ /* @__PURE__ */ jsx(TableCell, { header: true, children: "Role" }),
907
+ /* @__PURE__ */ jsx(TableCell, { header: true, className: "items-center", children: "Is Admin" }),
908
+ /* @__PURE__ */ jsx(TableCell, { header: true, children: "Default permissions" })
773
909
  ] }),
774
- /* @__PURE__ */ s(oe, { children: [
775
- n && n.map((c) => {
776
- const E = c.isAdmin || c.defaultPermissions?.create, U = c.isAdmin || c.defaultPermissions?.read, a = c.isAdmin || c.defaultPermissions?.edit, C = c.isAdmin || c.defaultPermissions?.delete;
777
- return /* @__PURE__ */ s(
778
- W,
910
+ /* @__PURE__ */ jsxs(TableBody, { children: [
911
+ roles && roles.map((role) => {
912
+ const canCreateAll = role.isAdmin || role.defaultPermissions?.create;
913
+ const canReadAll = role.isAdmin || role.defaultPermissions?.read;
914
+ const canUpdateAll = role.isAdmin || role.defaultPermissions?.edit;
915
+ const canDeleteAll = role.isAdmin || role.defaultPermissions?.delete;
916
+ return /* @__PURE__ */ jsxs(
917
+ TableRow,
779
918
  {
780
919
  onClick: () => {
781
- t(c);
920
+ onRoleClicked(role);
782
921
  },
783
922
  children: [
784
- /* @__PURE__ */ e(d, { style: { width: "64px" }, children: !c.isAdmin && /* @__PURE__ */ e(V, { title: "Delete this role", children: /* @__PURE__ */ e(
785
- ye,
923
+ /* @__PURE__ */ jsx(TableCell, { style: { width: "64px" }, children: !role.isAdmin && /* @__PURE__ */ jsx(Tooltip, { title: "Delete this role", children: /* @__PURE__ */ jsx(
924
+ IconButton,
786
925
  {
787
926
  size: "small",
788
- disabled: !r,
789
- onClick: (y) => (y.stopPropagation(), v(c)),
790
- children: /* @__PURE__ */ e(be, {})
927
+ disabled: !editable,
928
+ onClick: (event) => {
929
+ event.stopPropagation();
930
+ return setRoleToBeDeleted(role);
931
+ },
932
+ children: /* @__PURE__ */ jsx(DeleteIcon, {})
791
933
  }
792
934
  ) }) }),
793
- /* @__PURE__ */ e(d, { children: /* @__PURE__ */ e(X, { role: c }) }),
794
- /* @__PURE__ */ e(d, { className: "items-center", children: /* @__PURE__ */ e(I, { checked: c.isAdmin ?? !1 }) }),
795
- /* @__PURE__ */ e(d, { children: /* @__PURE__ */ s("ul", { children: [
796
- E && /* @__PURE__ */ e("li", { children: "Create" }),
797
- U && /* @__PURE__ */ e("li", { children: "Read" }),
798
- a && /* @__PURE__ */ e("li", { children: "Update" }),
799
- C && /* @__PURE__ */ e("li", { children: "Delete" })
935
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(RoleChip, { role }) }),
936
+ /* @__PURE__ */ jsx(TableCell, { className: "items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: role.isAdmin ?? false }) }),
937
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("ul", { children: [
938
+ canCreateAll && /* @__PURE__ */ jsx("li", { children: "Create" }),
939
+ canReadAll && /* @__PURE__ */ jsx("li", { children: "Read" }),
940
+ canUpdateAll && /* @__PURE__ */ jsx("li", { children: "Update" }),
941
+ canDeleteAll && /* @__PURE__ */ jsx("li", { children: "Delete" })
800
942
  ] }) })
801
943
  ]
802
944
  },
803
- c.name
945
+ role.name
804
946
  );
805
947
  }),
806
- (!n || n.length === 0) && /* @__PURE__ */ e(W, { children: /* @__PURE__ */ e(d, { colspan: 4, children: /* @__PURE__ */ s(Ne, { className: "flex flex-col gap-4 my-8 items-center", children: [
807
- /* @__PURE__ */ e(P, { variant: "label", children: "You don't have any roles yet." }),
808
- m && /* @__PURE__ */ e(
809
- O,
948
+ (!roles || roles.length === 0) && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colspan: 4, children: /* @__PURE__ */ jsxs(CenteredView, { className: "flex flex-col gap-4 my-8 items-center", children: [
949
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: "You don't have any roles yet." }),
950
+ allowDefaultRolesCreation && /* @__PURE__ */ jsx(
951
+ Button,
810
952
  {
811
953
  variant: "outlined",
812
954
  onClick: () => {
813
- Se.forEach((c) => {
814
- l(c);
955
+ DEFAULT_ROLES.forEach((role) => {
956
+ saveRole(role);
815
957
  });
816
958
  },
817
959
  children: "Create default roles"
@@ -820,146 +962,182 @@ function Ze({
820
962
  ] }) }) })
821
963
  ] })
822
964
  ] }),
823
- /* @__PURE__ */ e(
824
- xe,
965
+ /* @__PURE__ */ jsx(
966
+ DeleteConfirmationDialog,
825
967
  {
826
- open: !!g,
827
- loading: R,
968
+ open: Boolean(roleToBeDeleted),
969
+ loading: deleteInProgress,
828
970
  onAccept: () => {
829
- g && (w(!0), i(g).then(() => {
830
- v(void 0);
831
- }).finally(() => {
832
- w(!1);
833
- }));
971
+ if (roleToBeDeleted) {
972
+ setDeleteInProgress(true);
973
+ deleteRole(roleToBeDeleted).then(() => {
974
+ setRoleToBeDeleted(void 0);
975
+ }).finally(() => {
976
+ setDeleteInProgress(false);
977
+ });
978
+ }
834
979
  },
835
980
  onCancel: () => {
836
- v(void 0);
981
+ setRoleToBeDeleted(void 0);
837
982
  },
838
- title: /* @__PURE__ */ e(K, { children: "Delete?" }),
839
- body: /* @__PURE__ */ e(K, { children: "Are you sure you want to delete this role?" })
983
+ title: /* @__PURE__ */ jsx(Fragment, { children: "Delete?" }),
984
+ body: /* @__PURE__ */ jsx(Fragment, { children: "Are you sure you want to delete this role?" })
840
985
  }
841
986
  )
842
987
  ]
843
988
  }
844
989
  );
845
990
  }
846
- const en = F.memo(
847
- function({ children: r }) {
848
- const { collections: n } = Ve(), [l, i] = A(!1), [m, g] = A(), { canEditRoles: v } = j(), R = k((c) => {
849
- i(!0), g(c);
991
+ const RolesView = React.memo(
992
+ function RolesView2({ children }) {
993
+ const { collections } = useNavigationController();
994
+ const [dialogOpen, setDialogOpen] = useState(false);
995
+ const [selectedRole, setSelectedRole] = useState();
996
+ const { canEditRoles } = useUserManagement();
997
+ const onRoleClicked = useCallback((user) => {
998
+ setDialogOpen(true);
999
+ setSelectedRole(user);
850
1000
  }, []);
851
- return /* @__PURE__ */ s(Ue, { className: "w-full flex flex-col py-4 gap-4", maxWidth: "6xl", children: [
852
- r,
853
- /* @__PURE__ */ s("div", { className: "flex items-center mt-12", children: [
854
- /* @__PURE__ */ e(
855
- P,
1001
+ const handleClose = () => {
1002
+ setSelectedRole(void 0);
1003
+ setDialogOpen(false);
1004
+ };
1005
+ return /* @__PURE__ */ jsxs(Container, { className: "w-full flex flex-col py-4 gap-4", maxWidth: "6xl", children: [
1006
+ children,
1007
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center mt-12", children: [
1008
+ /* @__PURE__ */ jsx(
1009
+ Typography,
856
1010
  {
857
- gutterBottom: !0,
1011
+ gutterBottom: true,
858
1012
  variant: "h4",
859
1013
  className: "flex-grow",
860
1014
  component: "h4",
861
1015
  children: "Roles"
862
1016
  }
863
1017
  ),
864
- /* @__PURE__ */ e(V, { title: v ? void 0 : "Update plans to customise roles", children: /* @__PURE__ */ e(
865
- O,
1018
+ /* @__PURE__ */ jsx(Tooltip, { title: !canEditRoles ? "Update plans to customise roles" : void 0, children: /* @__PURE__ */ jsx(
1019
+ Button,
866
1020
  {
867
1021
  size: "large",
868
- disabled: !v,
869
- startIcon: /* @__PURE__ */ e(le, {}),
870
- onClick: () => i(!0),
1022
+ disabled: !canEditRoles,
1023
+ startIcon: /* @__PURE__ */ jsx(AddIcon, {}),
1024
+ onClick: () => setDialogOpen(true),
871
1025
  children: "Add role"
872
1026
  }
873
1027
  ) })
874
1028
  ] }),
875
- /* @__PURE__ */ e(Ze, { onRoleClicked: R, editable: !!v }),
876
- /* @__PURE__ */ e(
877
- Xe,
1029
+ /* @__PURE__ */ jsx(RolesTable, { onRoleClicked, editable: Boolean(canEditRoles) }),
1030
+ /* @__PURE__ */ jsx(
1031
+ RolesDetailsForm,
878
1032
  {
879
- open: l,
880
- role: m,
881
- editable: v,
882
- collections: n,
883
- handleClose: () => {
884
- g(void 0), i(!1);
885
- }
1033
+ open: dialogOpen,
1034
+ role: selectedRole,
1035
+ editable: canEditRoles,
1036
+ collections,
1037
+ handleClose
886
1038
  },
887
- m?.id ?? "new"
1039
+ selectedRole?.id ?? "new"
888
1040
  )
889
1041
  ] });
890
1042
  }
891
- ), nn = M.object().shape({
892
- displayName: M.string().required("Required"),
893
- email: M.string().email().required("Required"),
894
- roles: M.array().min(1)
1043
+ );
1044
+ const UserYupSchema = Yup.object().shape({
1045
+ displayName: Yup.string().required("Required"),
1046
+ email: Yup.string().email().required("Required"),
1047
+ roles: Yup.array().min(1)
895
1048
  });
896
- function tn(t, r, n, l, i) {
897
- const m = n.filter((w) => w.roles?.map((c) => c.id).includes("admin")), g = t.roles?.map((w) => w.id).includes("admin");
898
- if ((!i || !ze(i.roles ?? [], r.roles ?? [])) && !g)
1049
+ function canUserBeEdited(loggedUser, user, users, roles, prevUser) {
1050
+ const admins = users.filter((u) => u.roles?.map((r) => r.id).includes("admin"));
1051
+ const loggedUserIsAdmin = loggedUser.roles?.map((r) => r.id).includes("admin");
1052
+ const didRolesChange = !prevUser || !areRolesEqual(prevUser.roles ?? [], user.roles ?? []);
1053
+ if (didRolesChange && !loggedUserIsAdmin) {
899
1054
  throw new Error("Only admins can change roles");
900
- if (i && i.roles?.map((w) => w.id).includes("admin") && !r.roles?.map((w) => w.id).includes("admin") && m.length === 1)
1055
+ }
1056
+ const adminRoleRemoved = prevUser && prevUser.roles?.map((r) => r.id).includes("admin") && !user.roles?.map((r) => r.id).includes("admin");
1057
+ if (adminRoleRemoved && admins.length === 1) {
901
1058
  throw new Error("There must be at least one admin");
902
- return !0;
1059
+ }
1060
+ return true;
903
1061
  }
904
- function rn({
905
- open: t,
906
- user: r,
907
- handleClose: n
1062
+ function UserDetailsForm({
1063
+ open,
1064
+ user: userProp,
1065
+ handleClose
908
1066
  }) {
909
- const l = se(), {
910
- user: i
911
- } = ae(), {
912
- saveUser: m,
913
- users: g,
914
- roles: v
915
- } = j(), R = !r, w = k((h) => {
916
- if (!i)
1067
+ const snackbarController = useSnackbarController();
1068
+ const {
1069
+ user: loggedInUser
1070
+ } = useAuthController();
1071
+ const {
1072
+ saveUser,
1073
+ users,
1074
+ roles
1075
+ } = useUserManagement();
1076
+ const isNewUser = !userProp;
1077
+ const onUserUpdated = useCallback((savedUser) => {
1078
+ if (!loggedInUser) {
917
1079
  throw new Error("Logged user not found");
1080
+ }
918
1081
  try {
919
- return tn(i, h, g, v, r), m(h);
920
- } catch (x) {
921
- return Promise.reject(x);
1082
+ canUserBeEdited(loggedInUser, savedUser, users, roles, userProp);
1083
+ return saveUser(savedUser);
1084
+ } catch (e) {
1085
+ return Promise.reject(e);
922
1086
  }
923
- }, [v, m, r, g, i]), c = Re({
924
- initialValues: r ?? {
1087
+ }, [roles, saveUser, userProp, users, loggedInUser]);
1088
+ const formex = useCreateFormex({
1089
+ initialValues: userProp ?? {
925
1090
  displayName: "",
926
1091
  email: "",
927
- roles: v.filter((h) => h.id === "editor")
1092
+ roles: roles.filter((r) => r.id === "editor")
928
1093
  },
929
- validation: (h) => nn.validate(h, { abortEarly: !1 }).then(() => ({})).catch((x) => x.inner.reduce((D, T) => (D[T.path] = T.message, D), {})),
930
- onSubmit: (h, x) => w(h).then(() => {
931
- n(), x.resetForm({
932
- values: h
1094
+ validation: (values2) => {
1095
+ return UserYupSchema.validate(values2, { abortEarly: false }).then(() => {
1096
+ return {};
1097
+ }).catch((e) => {
1098
+ return e.inner.reduce((acc, error) => {
1099
+ acc[error.path] = error.message;
1100
+ return acc;
1101
+ }, {});
933
1102
  });
934
- }).catch((D) => {
935
- l.open({
936
- type: "error",
937
- message: D.message
1103
+ },
1104
+ onSubmit: (user, formexController) => {
1105
+ return onUserUpdated(user).then(() => {
1106
+ handleClose();
1107
+ formexController.resetForm({
1108
+ values: user
1109
+ });
1110
+ }).catch((e) => {
1111
+ snackbarController.open({
1112
+ type: "error",
1113
+ message: e.message
1114
+ });
938
1115
  });
939
- })
940
- }), {
941
- isSubmitting: E,
942
- touched: U,
943
- handleChange: a,
944
- values: C,
945
- errors: y,
946
- setFieldValue: b,
947
- dirty: _,
948
- handleSubmit: z,
949
- submitCount: u
950
- } = c;
951
- return /* @__PURE__ */ e(
952
- fe,
1116
+ }
1117
+ });
1118
+ const {
1119
+ isSubmitting,
1120
+ touched,
1121
+ handleChange,
1122
+ values,
1123
+ errors,
1124
+ setFieldValue,
1125
+ dirty,
1126
+ handleSubmit,
1127
+ submitCount
1128
+ } = formex;
1129
+ return /* @__PURE__ */ jsx(
1130
+ Dialog,
953
1131
  {
954
- open: t,
955
- onOpenChange: (h) => h ? void 0 : n(),
1132
+ open,
1133
+ onOpenChange: (open2) => !open2 ? handleClose() : void 0,
956
1134
  maxWidth: "4xl",
957
- children: /* @__PURE__ */ e(De, { value: c, children: /* @__PURE__ */ s(
1135
+ children: /* @__PURE__ */ jsx(Formex, { value: formex, children: /* @__PURE__ */ jsxs(
958
1136
  "form",
959
1137
  {
960
- onSubmit: z,
1138
+ onSubmit: handleSubmit,
961
1139
  autoComplete: "off",
962
- noValidate: !0,
1140
+ noValidate: true,
963
1141
  style: {
964
1142
  display: "flex",
965
1143
  flexDirection: "column",
@@ -967,13 +1145,13 @@ function rn({
967
1145
  height: "100%"
968
1146
  },
969
1147
  children: [
970
- /* @__PURE__ */ s(ge, { className: "h-full flex-grow", children: [
971
- /* @__PURE__ */ e(
1148
+ /* @__PURE__ */ jsxs(DialogContent, { className: "h-full flex-grow", children: [
1149
+ /* @__PURE__ */ jsx(
972
1150
  "div",
973
1151
  {
974
1152
  className: "flex flex-row pt-4 pb-4",
975
- children: /* @__PURE__ */ e(
976
- P,
1153
+ children: /* @__PURE__ */ jsx(
1154
+ Typography,
977
1155
  {
978
1156
  variant: "h4",
979
1157
  className: "flex-grow",
@@ -982,80 +1160,81 @@ function rn({
982
1160
  )
983
1161
  }
984
1162
  ),
985
- /* @__PURE__ */ s("div", { className: "grid grid-cols-12 gap-8", children: [
986
- /* @__PURE__ */ s("div", { className: "col-span-12", children: [
987
- /* @__PURE__ */ e(
988
- Q,
1163
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-8", children: [
1164
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12", children: [
1165
+ /* @__PURE__ */ jsx(
1166
+ TextField,
989
1167
  {
990
1168
  name: "displayName",
991
- required: !0,
992
- error: u > 0 && !!y.displayName,
993
- value: C.displayName ?? "",
994
- onChange: a,
1169
+ required: true,
1170
+ error: submitCount > 0 && Boolean(errors.displayName),
1171
+ value: values.displayName ?? "",
1172
+ onChange: handleChange,
995
1173
  "aria-describedby": "name-helper-text",
996
1174
  label: "Name"
997
1175
  }
998
1176
  ),
999
- /* @__PURE__ */ e(B, { children: u > 0 && y.displayName ? y.displayName : "Name of this user" })
1177
+ /* @__PURE__ */ jsx(FieldCaption, { children: submitCount > 0 && Boolean(errors.displayName) ? errors.displayName : "Name of this user" })
1000
1178
  ] }),
1001
- /* @__PURE__ */ s("div", { className: "col-span-12", children: [
1002
- /* @__PURE__ */ e(
1003
- Q,
1179
+ /* @__PURE__ */ jsxs("div", { className: "col-span-12", children: [
1180
+ /* @__PURE__ */ jsx(
1181
+ TextField,
1004
1182
  {
1005
- required: !0,
1006
- error: u > 0 && !!y.email,
1183
+ required: true,
1184
+ error: submitCount > 0 && Boolean(errors.email),
1007
1185
  name: "email",
1008
- value: C.email ?? "",
1009
- onChange: a,
1186
+ value: values.email ?? "",
1187
+ onChange: handleChange,
1010
1188
  "aria-describedby": "email-helper-text",
1011
1189
  label: "Email"
1012
1190
  }
1013
1191
  ),
1014
- /* @__PURE__ */ e(B, { children: u > 0 && y.email ? y.email : "Email of this user" })
1192
+ /* @__PURE__ */ jsx(FieldCaption, { children: submitCount > 0 && Boolean(errors.email) ? errors.email : "Email of this user" })
1015
1193
  ] }),
1016
- /* @__PURE__ */ e("div", { className: "col-span-12", children: /* @__PURE__ */ e(
1017
- Le,
1194
+ /* @__PURE__ */ jsx("div", { className: "col-span-12", children: /* @__PURE__ */ jsx(
1195
+ MultiSelect,
1018
1196
  {
1019
1197
  label: "Roles",
1020
- value: C.roles?.map((h) => h.id) ?? [],
1021
- onMultiValueChange: (h) => b("roles", h.map((x) => v.find((D) => D.id === x))),
1022
- renderValue: (h) => {
1023
- const x = v.find((D) => D.id === h);
1024
- return x ? /* @__PURE__ */ e("div", { className: "flex flex-wrap space-x-2 space-y-2", children: /* @__PURE__ */ e(X, { role: x }, x?.id) }) : null;
1198
+ value: values.roles?.map((r) => r.id) ?? [],
1199
+ onMultiValueChange: (value) => setFieldValue("roles", value.map((id) => roles.find((r) => r.id === id))),
1200
+ renderValue: (value) => {
1201
+ const userRole = roles.find((role) => role.id === value);
1202
+ if (!userRole) return null;
1203
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap space-x-2 space-y-2", children: /* @__PURE__ */ jsx(RoleChip, { role: userRole }, userRole?.id) });
1025
1204
  },
1026
- children: v.map((h) => /* @__PURE__ */ e(
1027
- Be,
1205
+ children: roles.map((userRole) => /* @__PURE__ */ jsx(
1206
+ MultiSelectItem,
1028
1207
  {
1029
- value: h.id,
1030
- children: /* @__PURE__ */ e(X, { role: h }, h?.id)
1208
+ value: userRole.id,
1209
+ children: /* @__PURE__ */ jsx(RoleChip, { role: userRole }, userRole?.id)
1031
1210
  },
1032
- h.id
1211
+ userRole.id
1033
1212
  ))
1034
1213
  }
1035
1214
  ) })
1036
1215
  ] })
1037
1216
  ] }),
1038
- /* @__PURE__ */ s(Ce, { children: [
1039
- /* @__PURE__ */ e(
1040
- O,
1217
+ /* @__PURE__ */ jsxs(DialogActions, { children: [
1218
+ /* @__PURE__ */ jsx(
1219
+ Button,
1041
1220
  {
1042
1221
  variant: "text",
1043
1222
  onClick: () => {
1044
- n();
1223
+ handleClose();
1045
1224
  },
1046
1225
  children: "Cancel"
1047
1226
  }
1048
1227
  ),
1049
- /* @__PURE__ */ e(
1050
- ve,
1228
+ /* @__PURE__ */ jsx(
1229
+ LoadingButton,
1051
1230
  {
1052
1231
  variant: "filled",
1053
1232
  color: "primary",
1054
1233
  type: "submit",
1055
- disabled: !_,
1056
- loading: E,
1057
- startIcon: /* @__PURE__ */ e(we, {}),
1058
- children: R ? "Create user" : "Update"
1234
+ disabled: !dirty,
1235
+ loading: isSubmitting,
1236
+ startIcon: /* @__PURE__ */ jsx(DoneIcon, {}),
1237
+ children: isNewUser ? "Create user" : "Update"
1059
1238
  }
1060
1239
  )
1061
1240
  ] })
@@ -1065,79 +1244,91 @@ function rn({
1065
1244
  }
1066
1245
  );
1067
1246
  }
1068
- function on({ onUserClicked: t }) {
1247
+ function UsersTable({ onUserClicked }) {
1069
1248
  const {
1070
- users: r,
1071
- saveUser: n,
1072
- deleteUser: l
1073
- } = j(), i = ae(), m = se(), g = Me(), v = g?.locale ? qe[g?.locale] : void 0, R = g?.dateTimeFormat ?? Oe, [w, c] = A(void 0), [E, U] = A(!1);
1074
- return /* @__PURE__ */ s("div", { className: "overflow-auto", children: [
1075
- /* @__PURE__ */ s(re, { children: [
1076
- /* @__PURE__ */ s(ie, { children: [
1077
- /* @__PURE__ */ e(d, { className: "truncate w-16" }),
1078
- /* @__PURE__ */ e(d, { children: "ID" }),
1079
- /* @__PURE__ */ e(d, { children: "Email" }),
1080
- /* @__PURE__ */ e(d, { children: "Name" }),
1081
- /* @__PURE__ */ e(d, { children: "Roles" }),
1082
- /* @__PURE__ */ e(d, { children: "Created on" })
1249
+ users,
1250
+ saveUser,
1251
+ deleteUser
1252
+ } = useUserManagement();
1253
+ const authController = useAuthController();
1254
+ const snackbarController = useSnackbarController();
1255
+ const customizationController = useCustomizationController();
1256
+ const dateUtilsLocale = customizationController?.locale ? locales[customizationController?.locale] : void 0;
1257
+ const dateFormat = customizationController?.dateTimeFormat ?? defaultDateFormat;
1258
+ const [userToBeDeleted, setUserToBeDeleted] = useState(void 0);
1259
+ const [deleteInProgress, setDeleteInProgress] = useState(false);
1260
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-auto", children: [
1261
+ /* @__PURE__ */ jsxs(Table, { children: [
1262
+ /* @__PURE__ */ jsxs(TableHeader, { children: [
1263
+ /* @__PURE__ */ jsx(TableCell, { className: "truncate w-16" }),
1264
+ /* @__PURE__ */ jsx(TableCell, { children: "ID" }),
1265
+ /* @__PURE__ */ jsx(TableCell, { children: "Email" }),
1266
+ /* @__PURE__ */ jsx(TableCell, { children: "Name" }),
1267
+ /* @__PURE__ */ jsx(TableCell, { children: "Roles" }),
1268
+ /* @__PURE__ */ jsx(TableCell, { children: "Created on" })
1083
1269
  ] }),
1084
- /* @__PURE__ */ s(oe, { children: [
1085
- r && r.map((a) => {
1086
- const C = a.roles, y = a.created_on ? $e(a.created_on, R, { locale: v }) : "";
1087
- return /* @__PURE__ */ s(
1088
- W,
1270
+ /* @__PURE__ */ jsxs(TableBody, { children: [
1271
+ users && users.map((user) => {
1272
+ const userRoles = user.roles;
1273
+ const formattedDate = user.created_on ? format(user.created_on, dateFormat, { locale: dateUtilsLocale }) : "";
1274
+ return /* @__PURE__ */ jsxs(
1275
+ TableRow,
1089
1276
  {
1090
1277
  onClick: () => {
1091
- t(a);
1278
+ onUserClicked(user);
1092
1279
  },
1093
1280
  children: [
1094
- /* @__PURE__ */ e(d, { className: "w-10", children: /* @__PURE__ */ e(V, { title: "Delete this user", children: /* @__PURE__ */ e(
1095
- ye,
1281
+ /* @__PURE__ */ jsx(TableCell, { className: "w-10", children: /* @__PURE__ */ jsx(Tooltip, { title: "Delete this user", children: /* @__PURE__ */ jsx(
1282
+ IconButton,
1096
1283
  {
1097
1284
  size: "small",
1098
- onClick: (b) => (b.stopPropagation(), c(a)),
1099
- children: /* @__PURE__ */ e(be, {})
1285
+ onClick: (event) => {
1286
+ event.stopPropagation();
1287
+ return setUserToBeDeleted(user);
1288
+ },
1289
+ children: /* @__PURE__ */ jsx(DeleteIcon, {})
1100
1290
  }
1101
1291
  ) }) }),
1102
- /* @__PURE__ */ e(d, { children: a.uid }),
1103
- /* @__PURE__ */ e(d, { children: a.email }),
1104
- /* @__PURE__ */ e(d, { className: "font-medium align-left", children: a.displayName }),
1105
- /* @__PURE__ */ e(d, { className: "align-left", children: C ? /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2", children: C.map(
1106
- (b) => /* @__PURE__ */ e(X, { role: b }, b?.id)
1292
+ /* @__PURE__ */ jsx(TableCell, { children: user.uid }),
1293
+ /* @__PURE__ */ jsx(TableCell, { children: user.email }),
1294
+ /* @__PURE__ */ jsx(TableCell, { className: "font-medium align-left", children: user.displayName }),
1295
+ /* @__PURE__ */ jsx(TableCell, { className: "align-left", children: userRoles ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: userRoles.map(
1296
+ (userRole) => /* @__PURE__ */ jsx(RoleChip, { role: userRole }, userRole?.id)
1107
1297
  ) }) : null }),
1108
- /* @__PURE__ */ e(d, { children: y })
1298
+ /* @__PURE__ */ jsx(TableCell, { children: formattedDate })
1109
1299
  ]
1110
1300
  },
1111
- "row_" + a.uid
1301
+ "row_" + user.uid
1112
1302
  );
1113
1303
  }),
1114
- (!r || r.length === 0) && /* @__PURE__ */ e(W, { children: /* @__PURE__ */ e(d, { colspan: 6, children: /* @__PURE__ */ s(Ne, { className: "flex flex-col gap-4 my-8 items-center", children: [
1115
- /* @__PURE__ */ e(P, { variant: "label", children: "There are no users yet" }),
1116
- /* @__PURE__ */ e(
1117
- O,
1304
+ (!users || users.length === 0) && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colspan: 6, children: /* @__PURE__ */ jsxs(CenteredView, { className: "flex flex-col gap-4 my-8 items-center", children: [
1305
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: "There are no users yet" }),
1306
+ /* @__PURE__ */ jsx(
1307
+ Button,
1118
1308
  {
1119
1309
  variant: "outlined",
1120
1310
  onClick: () => {
1121
- if (!i.user?.uid)
1311
+ if (!authController.user?.uid) {
1122
1312
  throw Error("UsersTable, authController misconfiguration");
1123
- n({
1124
- uid: i.user?.uid,
1125
- email: i.user?.email,
1126
- displayName: i.user?.displayName,
1127
- photoURL: i.user?.photoURL,
1128
- providerId: i.user?.providerId,
1129
- isAnonymous: i.user?.isAnonymous,
1313
+ }
1314
+ saveUser({
1315
+ uid: authController.user?.uid,
1316
+ email: authController.user?.email,
1317
+ displayName: authController.user?.displayName,
1318
+ photoURL: authController.user?.photoURL,
1319
+ providerId: authController.user?.providerId,
1320
+ isAnonymous: authController.user?.isAnonymous,
1130
1321
  roles: [{ id: "admin", name: "Admin" }],
1131
1322
  created_on: /* @__PURE__ */ new Date()
1132
1323
  }).then(() => {
1133
- m.open({
1324
+ snackbarController.open({
1134
1325
  type: "success",
1135
1326
  message: "User added successfully"
1136
1327
  });
1137
- }).catch((a) => {
1138
- m.open({
1328
+ }).catch((error) => {
1329
+ snackbarController.open({
1139
1330
  type: "error",
1140
- message: "Error adding user: " + a.message
1331
+ message: "Error adding user: " + error.message
1141
1332
  });
1142
1333
  });
1143
1334
  },
@@ -1147,193 +1338,212 @@ function on({ onUserClicked: t }) {
1147
1338
  ] }) }) })
1148
1339
  ] })
1149
1340
  ] }),
1150
- /* @__PURE__ */ e(
1151
- xe,
1341
+ /* @__PURE__ */ jsx(
1342
+ DeleteConfirmationDialog,
1152
1343
  {
1153
- open: !!w,
1154
- loading: E,
1344
+ open: Boolean(userToBeDeleted),
1345
+ loading: deleteInProgress,
1155
1346
  onAccept: () => {
1156
- w && (U(!0), l(w).then(() => {
1157
- c(void 0);
1158
- }).catch((a) => {
1159
- m.open({
1160
- type: "error",
1161
- message: "Error deleting user: " + a.message
1347
+ if (userToBeDeleted) {
1348
+ setDeleteInProgress(true);
1349
+ deleteUser(userToBeDeleted).then(() => {
1350
+ setUserToBeDeleted(void 0);
1351
+ }).catch((error) => {
1352
+ snackbarController.open({
1353
+ type: "error",
1354
+ message: "Error deleting user: " + error.message
1355
+ });
1356
+ }).finally(() => {
1357
+ setDeleteInProgress(false);
1162
1358
  });
1163
- }).finally(() => {
1164
- U(!1);
1165
- }));
1359
+ }
1166
1360
  },
1167
1361
  onCancel: () => {
1168
- c(void 0);
1362
+ setUserToBeDeleted(void 0);
1169
1363
  },
1170
- title: /* @__PURE__ */ e(K, { children: "Delete?" }),
1171
- body: /* @__PURE__ */ e(K, { children: "Are you sure you want to delete this user?" })
1364
+ title: /* @__PURE__ */ jsx(Fragment, { children: "Delete?" }),
1365
+ body: /* @__PURE__ */ jsx(Fragment, { children: "Are you sure you want to delete this user?" })
1172
1366
  }
1173
1367
  )
1174
1368
  ] });
1175
1369
  }
1176
- const ln = function({ children: r }) {
1177
- const [n, l] = A(), [i, m] = A(), { users: g, usersLimit: v } = j(), R = v !== void 0 && g && g.length >= v, w = k((E) => {
1178
- m(E), l(!0);
1179
- }, []), c = k(() => {
1180
- l(!1), m(void 0);
1370
+ const UsersView = function UsersView2({ children }) {
1371
+ const [dialogOpen, setDialogOpen] = useState();
1372
+ const [selectedUser, setSelectedUser] = useState();
1373
+ const { users, usersLimit } = useUserManagement();
1374
+ const reachedUsersLimit = usersLimit !== void 0 && (users && users.length >= usersLimit);
1375
+ const onUserClicked = useCallback((user) => {
1376
+ setSelectedUser(user);
1377
+ setDialogOpen(true);
1181
1378
  }, []);
1182
- return /* @__PURE__ */ s(Ue, { className: "w-full flex flex-col py-4 gap-4", maxWidth: "6xl", children: [
1183
- r,
1184
- /* @__PURE__ */ s(
1379
+ const handleClose = useCallback(() => {
1380
+ setDialogOpen(false);
1381
+ setSelectedUser(void 0);
1382
+ }, []);
1383
+ return /* @__PURE__ */ jsxs(Container, { className: "w-full flex flex-col py-4 gap-4", maxWidth: "6xl", children: [
1384
+ children,
1385
+ /* @__PURE__ */ jsxs(
1185
1386
  "div",
1186
1387
  {
1187
1388
  className: "flex items-center mt-12",
1188
1389
  children: [
1189
- /* @__PURE__ */ e(
1190
- P,
1390
+ /* @__PURE__ */ jsx(
1391
+ Typography,
1191
1392
  {
1192
- gutterBottom: !0,
1393
+ gutterBottom: true,
1193
1394
  variant: "h4",
1194
1395
  className: "flex-grow",
1195
1396
  component: "h4",
1196
1397
  children: "Users"
1197
1398
  }
1198
1399
  ),
1199
- /* @__PURE__ */ e(
1200
- O,
1400
+ /* @__PURE__ */ jsx(
1401
+ Button,
1201
1402
  {
1202
1403
  size: "large",
1203
- disabled: R,
1204
- startIcon: /* @__PURE__ */ e(le, {}),
1205
- onClick: () => l(!0),
1404
+ disabled: reachedUsersLimit,
1405
+ startIcon: /* @__PURE__ */ jsx(AddIcon, {}),
1406
+ onClick: () => setDialogOpen(true),
1206
1407
  children: "Add user"
1207
1408
  }
1208
1409
  )
1209
1410
  ]
1210
1411
  }
1211
1412
  ),
1212
- /* @__PURE__ */ e(on, { onUserClicked: w }),
1213
- /* @__PURE__ */ e(
1214
- rn,
1413
+ /* @__PURE__ */ jsx(UsersTable, { onUserClicked }),
1414
+ /* @__PURE__ */ jsx(
1415
+ UserDetailsForm,
1215
1416
  {
1216
- open: n ?? !1,
1217
- user: i,
1218
- handleClose: c
1417
+ open: dialogOpen ?? false,
1418
+ user: selectedUser,
1419
+ handleClose
1219
1420
  },
1220
- i?.uid ?? "new"
1421
+ selectedUser?.uid ?? "new"
1221
1422
  )
1222
1423
  ] });
1223
1424
  };
1224
- function Un({ userManagement: t }) {
1225
- const r = t.users.length === 0, n = t.roles.length === 0;
1425
+ function useUserManagementPlugin({ userManagement }) {
1426
+ const noUsers = userManagement.users.length === 0;
1427
+ const noRoles = userManagement.roles.length === 0;
1226
1428
  return {
1227
1429
  key: "user_management",
1228
- loading: t.loading,
1430
+ loading: userManagement.loading,
1229
1431
  homePage: {
1230
- additionalChildrenStart: r || n ? /* @__PURE__ */ e(
1231
- sn,
1432
+ additionalChildrenStart: noUsers || noRoles ? /* @__PURE__ */ jsx(
1433
+ IntroWidget,
1232
1434
  {
1233
- noUsers: r,
1234
- noRoles: n,
1235
- userManagement: t
1435
+ noUsers,
1436
+ noRoles,
1437
+ userManagement
1236
1438
  }
1237
1439
  ) : void 0
1238
1440
  },
1239
1441
  provider: {
1240
- Component: Ke,
1442
+ Component: UserManagementProvider,
1241
1443
  props: {
1242
- userManagement: t
1444
+ userManagement
1243
1445
  }
1244
1446
  }
1245
1447
  };
1246
1448
  }
1247
- function sn({
1248
- noUsers: t,
1249
- noRoles: r,
1250
- userManagement: n
1449
+ function IntroWidget({
1450
+ noUsers,
1451
+ noRoles,
1452
+ userManagement
1251
1453
  }) {
1252
- const l = ae(), i = se();
1253
- return /* @__PURE__ */ s(
1254
- pe,
1454
+ const authController = useAuthController();
1455
+ const snackbarController = useSnackbarController();
1456
+ const buttonLabel = noUsers && noRoles ? "Create default roles and add current user as admin" : noUsers ? "Add current user as admin" : noRoles ? "Create default roles" : void 0;
1457
+ return /* @__PURE__ */ jsxs(
1458
+ Paper,
1255
1459
  {
1256
1460
  className: "my-4 flex flex-col px-4 py-6 bg-white dark:bg-slate-800 gap-2",
1257
1461
  children: [
1258
- /* @__PURE__ */ e(P, { variant: "subtitle2", className: "uppercase", children: "Create your users and roles" }),
1259
- /* @__PURE__ */ e(P, { children: "You have no users or roles defined. You can create default roles and add the current user as admin." }),
1260
- /* @__PURE__ */ s(O, { onClick: () => {
1261
- if (!l.user?.uid)
1462
+ /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", className: "uppercase", children: "Create your users and roles" }),
1463
+ /* @__PURE__ */ jsx(Typography, { children: "You have no users or roles defined. You can create default roles and add the current user as admin." }),
1464
+ /* @__PURE__ */ jsxs(Button, { onClick: () => {
1465
+ if (!authController.user?.uid) {
1262
1466
  throw Error("UsersTable, authController misconfiguration");
1263
- t && n.saveUser({
1264
- uid: l.user?.uid,
1265
- email: l.user?.email,
1266
- displayName: l.user?.displayName,
1267
- photoURL: l.user?.photoURL,
1268
- providerId: l.user?.providerId,
1269
- isAnonymous: l.user?.isAnonymous,
1270
- roles: [{
1271
- id: "admin",
1272
- name: "Admin"
1273
- }],
1274
- created_on: /* @__PURE__ */ new Date()
1275
- }).then(() => {
1276
- i.open({
1277
- type: "success",
1278
- message: "User added successfully"
1467
+ }
1468
+ if (noUsers) {
1469
+ userManagement.saveUser({
1470
+ uid: authController.user?.uid,
1471
+ email: authController.user?.email,
1472
+ displayName: authController.user?.displayName,
1473
+ photoURL: authController.user?.photoURL,
1474
+ providerId: authController.user?.providerId,
1475
+ isAnonymous: authController.user?.isAnonymous,
1476
+ roles: [{
1477
+ id: "admin",
1478
+ name: "Admin"
1479
+ }],
1480
+ created_on: /* @__PURE__ */ new Date()
1481
+ }).then(() => {
1482
+ snackbarController.open({
1483
+ type: "success",
1484
+ message: "User added successfully"
1485
+ });
1486
+ }).catch((error) => {
1487
+ snackbarController.open({
1488
+ type: "error",
1489
+ message: "Error adding user: " + error.message
1490
+ });
1279
1491
  });
1280
- }).catch((g) => {
1281
- i.open({
1282
- type: "error",
1283
- message: "Error adding user: " + g.message
1492
+ }
1493
+ if (noRoles) {
1494
+ DEFAULT_ROLES.forEach((role) => {
1495
+ userManagement.saveRole(role);
1284
1496
  });
1285
- }), r && Se.forEach((g) => {
1286
- n.saveRole(g);
1287
- });
1497
+ }
1288
1498
  }, children: [
1289
- /* @__PURE__ */ e(le, {}),
1290
- t && r ? "Create default roles and add current user as admin" : t ? "Add current user as admin" : r ? "Create default roles" : void 0
1499
+ /* @__PURE__ */ jsx(AddIcon, {}),
1500
+ buttonLabel
1291
1501
  ] })
1292
1502
  ]
1293
1503
  }
1294
1504
  );
1295
1505
  }
1296
- const xn = [
1506
+ const userManagementAdminViews = [
1297
1507
  {
1298
1508
  path: "users",
1299
1509
  name: "CMS Users",
1300
1510
  group: "Admin",
1301
1511
  icon: "face",
1302
- view: /* @__PURE__ */ e(ln, {})
1512
+ view: /* @__PURE__ */ jsx(UsersView, {})
1303
1513
  },
1304
1514
  {
1305
1515
  path: "roles",
1306
1516
  name: "Roles",
1307
1517
  group: "Admin",
1308
1518
  icon: "gpp_good",
1309
- view: /* @__PURE__ */ e(en, {})
1519
+ view: /* @__PURE__ */ jsx(RolesView, {})
1310
1520
  }
1311
1521
  ];
1312
1522
  export {
1313
- sn as IntroWidget,
1314
- gn as RESERVED_GROUPS,
1315
- X as RoleChip,
1316
- Qe as RoleYupSchema,
1317
- Xe as RolesDetailsForm,
1318
- Ze as RolesTable,
1319
- en as RolesView,
1320
- rn as UserDetailsForm,
1321
- Ee as UserManagementContext,
1322
- Ke as UserManagementProvider,
1323
- nn as UserYupSchema,
1324
- on as UsersTable,
1325
- ln as UsersView,
1326
- ze as areRolesEqual,
1327
- Cn as cacheDelegatedLoginToken,
1328
- wn as clearDelegatedLoginTokensCache,
1329
- yn as darkenColor,
1330
- vn as getDelegatedLoginTokenFromCache,
1331
- pn as getUserRoles,
1332
- bn as hexToRgbaWithOpacity,
1333
- We as resolveUserRolePermissions,
1334
- Nn as useFirestoreUserManagement,
1335
- j as useUserManagement,
1336
- Un as useUserManagementPlugin,
1337
- xn as userManagementAdminViews
1523
+ IntroWidget,
1524
+ RESERVED_GROUPS,
1525
+ RoleChip,
1526
+ RoleYupSchema,
1527
+ RolesDetailsForm,
1528
+ RolesTable,
1529
+ RolesView,
1530
+ UserDetailsForm,
1531
+ UserManagementContext,
1532
+ UserManagementProvider,
1533
+ UserYupSchema,
1534
+ UsersTable,
1535
+ UsersView,
1536
+ areRolesEqual,
1537
+ cacheDelegatedLoginToken,
1538
+ clearDelegatedLoginTokensCache,
1539
+ darkenColor,
1540
+ getDelegatedLoginTokenFromCache,
1541
+ getUserRoles,
1542
+ hexToRgbaWithOpacity,
1543
+ resolveUserRolePermissions,
1544
+ useBuildUserManagement,
1545
+ useUserManagement,
1546
+ useUserManagementPlugin,
1547
+ userManagementAdminViews
1338
1548
  };
1339
1549
  //# sourceMappingURL=index.es.js.map