@firecms/user_management 3.0.0-3.0.0-canary.44.0 → 3.0.0-beta.10

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