@firecms/user_management 3.0.0-beta.7 → 3.0.0-beta.9

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