@firecms/user_management 3.0.0-canary.80 → 3.0.0-canary.82

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