@firecms/user_management 3.0.0-canary.11 → 3.0.0-canary.111

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