@firecms/user_management 3.0.0-canary.16 → 3.0.0-canary.160
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/LICENSE +114 -21
- package/README.md +2 -2
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/{useBuildFirestoreUserManagement.d.ts → useBuildUserManagement.d.ts} +17 -8
- package/dist/index.es.js +2238 -1210
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +2313 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/types/user_management.d.ts +10 -3
- package/dist/useUserManagementPlugin.d.ts +8 -3
- package/dist/utils/permissions.d.ts +2 -2
- package/package.json +14 -28
- package/src/components/roles/RolesDetailsForm.tsx +80 -32
- package/src/components/roles/RolesTable.tsx +6 -4
- package/src/components/roles/RolesView.tsx +3 -1
- package/src/components/users/UserDetailsForm.tsx +16 -16
- package/src/components/users/UsersTable.tsx +6 -6
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useBuildUserManagement.tsx +349 -0
- package/src/types/user_management.tsx +13 -3
- package/src/useUserManagementPlugin.tsx +89 -3
- package/src/utils/permissions.ts +9 -8
- package/src/hooks/useBuildFirestoreUserManagement.tsx +0 -240
@@ -1,5 +1,6 @@
|
|
1
|
-
import { PermissionsBuilder, Role, User } from "@firecms/core";
|
1
|
+
import { Authenticator, PermissionsBuilder, Role, User } from "@firecms/core";
|
2
2
|
export type UserManagement<USER extends User = User> = {
|
3
|
+
authenticator?: Authenticator<USER>;
|
3
4
|
loading: boolean;
|
4
5
|
users: USER[];
|
5
6
|
saveUser: (user: USER) => Promise<USER>;
|
@@ -15,6 +16,10 @@ export type UserManagement<USER extends User = User> = {
|
|
15
16
|
* Can the logged user edit roles?
|
16
17
|
*/
|
17
18
|
canEditRoles?: boolean;
|
19
|
+
/**
|
20
|
+
* Is the logged user Admin?
|
21
|
+
*/
|
22
|
+
isAdmin?: boolean;
|
18
23
|
/**
|
19
24
|
* Include a button to create default roles, in case there are no roles in the system.
|
20
25
|
*/
|
@@ -29,8 +34,10 @@ export type UserManagement<USER extends User = User> = {
|
|
29
34
|
*/
|
30
35
|
collectionPermissions: PermissionsBuilder;
|
31
36
|
/**
|
32
|
-
* Define the roles for a given user.
|
37
|
+
* Define the roles for a given user. You will typically want to plug this into your auth controller.
|
33
38
|
* @param user
|
34
39
|
*/
|
35
|
-
defineRolesFor: (user: User) => Promise<Role[]> | Role[] | undefined;
|
40
|
+
defineRolesFor: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
|
41
|
+
rolesError?: Error;
|
42
|
+
usersError?: Error;
|
36
43
|
};
|
@@ -1,5 +1,10 @@
|
|
1
|
-
import { FireCMSPlugin } from "@firecms/core";
|
1
|
+
import { FireCMSPlugin, User } from "@firecms/core";
|
2
2
|
import { UserManagement } from "./types";
|
3
|
-
export declare function useUserManagementPlugin({ userManagement }: {
|
4
|
-
userManagement: UserManagement
|
3
|
+
export declare function useUserManagementPlugin<USER extends User = any>({ userManagement }: {
|
4
|
+
userManagement: UserManagement<USER>;
|
5
5
|
}): FireCMSPlugin;
|
6
|
+
export declare function IntroWidget({ noUsers, noRoles, userManagement }: {
|
7
|
+
noUsers: boolean;
|
8
|
+
noRoles: boolean;
|
9
|
+
userManagement: UserManagement<any>;
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { EntityCollection, Permissions, Role, User } from "@firecms/core";
|
2
2
|
export declare const RESERVED_GROUPS: string[];
|
3
|
-
export declare function resolveUserRolePermissions<
|
3
|
+
export declare function resolveUserRolePermissions<USER extends User>({ collection, user }: {
|
4
4
|
collection: EntityCollection<any>;
|
5
|
-
user:
|
5
|
+
user: USER | null;
|
6
6
|
}): Permissions;
|
7
7
|
export declare function getUserRoles(roles: Role[], fireCMSUser: User): Role[] | undefined;
|
8
8
|
export declare const areRolesEqual: (rolesA: Role[], rolesB: Role[]) => boolean;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@firecms/user_management",
|
3
3
|
"type": "module",
|
4
|
-
"version": "3.0.0-canary.
|
4
|
+
"version": "3.0.0-canary.160",
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
7
7
|
},
|
@@ -24,36 +24,28 @@
|
|
24
24
|
},
|
25
25
|
"./package.json": "./package.json"
|
26
26
|
},
|
27
|
-
"packageManager": "yarn@4.1.0",
|
28
27
|
"main": "./dist/index.umd.js",
|
29
28
|
"module": "./dist/index.es.js",
|
30
29
|
"types": "dist/index.d.ts",
|
31
30
|
"source": "src/index.ts",
|
32
31
|
"dependencies": {
|
33
|
-
"@firecms/core": "^3.0.0-canary.
|
34
|
-
"@firecms/formex": "^3.0.0-canary.
|
35
|
-
"@firecms/ui": "^3.0.0-canary.
|
32
|
+
"@firecms/core": "^3.0.0-canary.160",
|
33
|
+
"@firecms/formex": "^3.0.0-canary.160",
|
34
|
+
"@firecms/ui": "^3.0.0-canary.159",
|
36
35
|
"date-fns": "^3.6.0"
|
37
36
|
},
|
38
37
|
"peerDependencies": {
|
39
|
-
"
|
40
|
-
"react": "^18.
|
41
|
-
"react-dom": "^18.2.0"
|
38
|
+
"react": "^18.3.1",
|
39
|
+
"react-dom": "^18.3.1"
|
42
40
|
},
|
43
41
|
"devDependencies": {
|
44
|
-
"@types/node": "^20.
|
45
|
-
"@types/react": "^18.
|
46
|
-
"@types/react-dom": "^18.
|
47
|
-
"
|
48
|
-
"eslint": "
|
49
|
-
"
|
50
|
-
"
|
51
|
-
"eslint-plugin-n": "^16.6.2",
|
52
|
-
"eslint-plugin-promise": "^6.1.1",
|
53
|
-
"eslint-plugin-react": "^7.34.1",
|
54
|
-
"eslint-plugin-react-hooks": "^4.6.0",
|
55
|
-
"typescript": "^5.4.2",
|
56
|
-
"vite": "^5.2.3"
|
42
|
+
"@types/node": "^20.17.9",
|
43
|
+
"@types/react": "^18.3.11",
|
44
|
+
"@types/react-dom": "^18.3.1",
|
45
|
+
"babel-plugin-react-compiler": "beta",
|
46
|
+
"eslint-plugin-react-compiler": "beta",
|
47
|
+
"typescript": "^5.7.2",
|
48
|
+
"vite": "^5.4.11"
|
57
49
|
},
|
58
50
|
"scripts": {
|
59
51
|
"dev": "vite",
|
@@ -65,11 +57,5 @@
|
|
65
57
|
"src",
|
66
58
|
"bin"
|
67
59
|
],
|
68
|
-
"
|
69
|
-
"extends": [
|
70
|
-
"react-app",
|
71
|
-
"react-app/jest"
|
72
|
-
]
|
73
|
-
},
|
74
|
-
"gitHead": "6c7d1dd64fa4b9f31433ab6dd938835589e8a25a"
|
60
|
+
"gitHead": "840f2733672a90a6a56aed89259eaa5365589512"
|
75
61
|
}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import React, { useCallback, useState } from "react";
|
2
2
|
import * as Yup from "yup";
|
3
3
|
|
4
|
-
import { EntityCollection, FieldCaption, Role, toSnakeCase, } from "@firecms/core";
|
4
|
+
import { EntityCollection, FieldCaption, Role, toSnakeCase, useAuthController, User, } from "@firecms/core";
|
5
5
|
import {
|
6
6
|
Button,
|
7
7
|
Checkbox,
|
8
8
|
Dialog,
|
9
9
|
DialogActions,
|
10
|
-
DialogContent,
|
10
|
+
DialogContent, DialogTitle,
|
11
11
|
DoneIcon,
|
12
12
|
LoadingButton,
|
13
13
|
Paper,
|
@@ -30,6 +30,16 @@ export const RoleYupSchema = Yup.object().shape({
|
|
30
30
|
name: Yup.string().required("Required")
|
31
31
|
});
|
32
32
|
|
33
|
+
function canRoleBeEdited(loggedUser: User) {
|
34
|
+
const loggedUserIsAdmin = loggedUser.roles?.map(r => r.id).includes("admin");
|
35
|
+
console.log("loggedUserIsAdmin", loggedUser);
|
36
|
+
if (!loggedUserIsAdmin) {
|
37
|
+
throw new Error("Only admins can edit roles");
|
38
|
+
}
|
39
|
+
|
40
|
+
return true;
|
41
|
+
}
|
42
|
+
|
33
43
|
export function RolesDetailsForm({
|
34
44
|
open,
|
35
45
|
role,
|
@@ -46,27 +56,39 @@ export function RolesDetailsForm({
|
|
46
56
|
|
47
57
|
const { saveRole } = useUserManagement();
|
48
58
|
const isNewRole = !role;
|
59
|
+
const {
|
60
|
+
user: loggedInUser
|
61
|
+
} = useAuthController();
|
49
62
|
|
50
63
|
const [savingError, setSavingError] = useState<Error | undefined>();
|
51
64
|
|
52
65
|
const onRoleUpdated = useCallback((role: Role) => {
|
53
66
|
setSavingError(undefined);
|
67
|
+
if (!loggedInUser) throw new Error("User not found");
|
68
|
+
canRoleBeEdited(loggedInUser);
|
54
69
|
return saveRole(role);
|
55
|
-
}, [saveRole]);
|
70
|
+
}, [saveRole, loggedInUser]);
|
56
71
|
|
57
72
|
const formex = useCreateFormex({
|
58
73
|
initialValues: role ?? {
|
59
74
|
name: ""
|
60
75
|
} as Role,
|
61
76
|
onSubmit: (role: Role, formexController) => {
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
77
|
+
try {
|
78
|
+
return onRoleUpdated(role)
|
79
|
+
.then(() => {
|
80
|
+
formexController.resetForm({
|
81
|
+
values: role
|
82
|
+
});
|
83
|
+
handleClose();
|
84
|
+
})
|
85
|
+
.catch(e => {
|
86
|
+
setSavingError(e);
|
66
87
|
});
|
67
|
-
|
68
|
-
|
69
|
-
.
|
88
|
+
} catch (e: any) {
|
89
|
+
setSavingError(e);
|
90
|
+
return Promise.resolve();
|
91
|
+
}
|
70
92
|
},
|
71
93
|
validation: (values) => {
|
72
94
|
return RoleYupSchema.validate(values, { abortEarly: false })
|
@@ -121,14 +143,10 @@ export function RolesDetailsForm({
|
|
121
143
|
position: "relative",
|
122
144
|
height: "100%"
|
123
145
|
}}>
|
146
|
+
<DialogTitle variant={"h4"} gutterBottom={false}>
|
147
|
+
Role
|
148
|
+
</DialogTitle>
|
124
149
|
<DialogContent className="flex-grow">
|
125
|
-
<div
|
126
|
-
className="flex flex-row pt-12 pb-8">
|
127
|
-
<Typography variant={"h4"}
|
128
|
-
className="flex-grow">
|
129
|
-
Role
|
130
|
-
</Typography>
|
131
|
-
</div>
|
132
150
|
|
133
151
|
<div className={"grid grid-cols-12 gap-8"}>
|
134
152
|
|
@@ -168,11 +186,9 @@ export function RolesDetailsForm({
|
|
168
186
|
</div>
|
169
187
|
|
170
188
|
<div className={"col-span-12"}>
|
171
|
-
<Paper
|
172
|
-
|
173
|
-
|
174
|
-
<Table>
|
175
|
-
<TableHeader>
|
189
|
+
<Paper className="bg-inherit overflow-hidden">
|
190
|
+
<Table className={"w-full rounded-md"}>
|
191
|
+
<TableHeader className={"rounded-md"}>
|
176
192
|
<TableCell></TableCell>
|
177
193
|
<TableCell
|
178
194
|
align="center">Create
|
@@ -190,6 +206,9 @@ export function RolesDetailsForm({
|
|
190
206
|
align="center">Delete
|
191
207
|
entities
|
192
208
|
</TableCell>
|
209
|
+
<TableCell
|
210
|
+
align="center">
|
211
|
+
</TableCell>
|
193
212
|
</TableHeader>
|
194
213
|
|
195
214
|
<TableBody>
|
@@ -245,6 +264,9 @@ export function RolesDetailsForm({
|
|
245
264
|
|
246
265
|
</Tooltip>
|
247
266
|
</TableCell>
|
267
|
+
<TableCell
|
268
|
+
align="center">
|
269
|
+
</TableCell>
|
248
270
|
</TableRow>
|
249
271
|
{collections && collections.map((col) => (
|
250
272
|
<TableRow key={col.name}>
|
@@ -256,29 +278,49 @@ export function RolesDetailsForm({
|
|
256
278
|
align="center">
|
257
279
|
<Checkbox
|
258
280
|
disabled={isAdmin || defaultCreate || !editable}
|
259
|
-
checked={(isAdmin || defaultCreate || getIn(values, `collectionPermissions.${col.
|
260
|
-
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.
|
281
|
+
checked={(isAdmin || defaultCreate || getIn(values, `collectionPermissions.${col.id}.create`)) ?? false}
|
282
|
+
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.id}.create`, checked)}/>
|
261
283
|
</TableCell>
|
262
284
|
<TableCell
|
263
285
|
align="center">
|
264
286
|
<Checkbox
|
265
287
|
disabled={isAdmin || defaultRead || !editable}
|
266
|
-
checked={(isAdmin || defaultRead || getIn(values, `collectionPermissions.${col.
|
267
|
-
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.
|
288
|
+
checked={(isAdmin || defaultRead || getIn(values, `collectionPermissions.${col.id}.read`)) ?? false}
|
289
|
+
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.id}.read`, checked)}/>
|
268
290
|
</TableCell>
|
269
291
|
<TableCell
|
270
292
|
align="center">
|
271
293
|
<Checkbox
|
272
294
|
disabled={isAdmin || defaultEdit || !editable}
|
273
|
-
checked={(isAdmin || defaultEdit || getIn(values, `collectionPermissions.${col.
|
274
|
-
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.
|
295
|
+
checked={(isAdmin || defaultEdit || getIn(values, `collectionPermissions.${col.id}.edit`)) ?? false}
|
296
|
+
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.id}.edit`, checked)}/>
|
275
297
|
</TableCell>
|
276
298
|
<TableCell
|
277
299
|
align="center">
|
278
300
|
<Checkbox
|
279
301
|
disabled={isAdmin || defaultDelete || !editable}
|
280
|
-
checked={(isAdmin || defaultDelete || getIn(values, `collectionPermissions.${col.
|
281
|
-
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.
|
302
|
+
checked={(isAdmin || defaultDelete || getIn(values, `collectionPermissions.${col.id}.delete`)) ?? false}
|
303
|
+
onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.id}.delete`, checked)}/>
|
304
|
+
</TableCell>
|
305
|
+
|
306
|
+
<TableCell
|
307
|
+
align="center">
|
308
|
+
<Tooltip
|
309
|
+
title="Allow all permissions in this collections">
|
310
|
+
<Button
|
311
|
+
className={"color-inherit"}
|
312
|
+
onClick={() => {
|
313
|
+
setFieldValue(`collectionPermissions.${col.id}.create`, true);
|
314
|
+
setFieldValue(`collectionPermissions.${col.id}.read`, true);
|
315
|
+
setFieldValue(`collectionPermissions.${col.id}.edit`, true);
|
316
|
+
setFieldValue(`collectionPermissions.${col.id}.delete`, true);
|
317
|
+
}}
|
318
|
+
disabled={isAdmin || !editable}
|
319
|
+
variant={"text"}>
|
320
|
+
All
|
321
|
+
</Button>
|
322
|
+
|
323
|
+
</Tooltip>
|
282
324
|
</TableCell>
|
283
325
|
</TableRow>
|
284
326
|
))}
|
@@ -296,6 +338,8 @@ export function RolesDetailsForm({
|
|
296
338
|
<div className={"col-span-12 md:col-span-4"}>
|
297
339
|
<Select
|
298
340
|
error={touched.config && Boolean(errors.config)}
|
341
|
+
size={"large"}
|
342
|
+
fullWidth={true}
|
299
343
|
id="createCollections"
|
300
344
|
name="createCollections"
|
301
345
|
label="Create collections"
|
@@ -318,6 +362,8 @@ export function RolesDetailsForm({
|
|
318
362
|
|
319
363
|
<div className={"col-span-12 md:col-span-4"}>
|
320
364
|
<Select
|
365
|
+
size={"large"}
|
366
|
+
fullWidth={true}
|
321
367
|
error={touched.config && Boolean(errors.config)}
|
322
368
|
id="editCollections"
|
323
369
|
name="editCollections"
|
@@ -344,6 +390,8 @@ export function RolesDetailsForm({
|
|
344
390
|
|
345
391
|
<div className={"col-span-12 md:col-span-4"}>
|
346
392
|
<Select
|
393
|
+
size={"large"}
|
394
|
+
fullWidth={true}
|
347
395
|
error={touched.config && Boolean(errors.config)}
|
348
396
|
id="deleteCollections"
|
349
397
|
name="deleteCollections"
|
@@ -373,8 +421,8 @@ export function RolesDetailsForm({
|
|
373
421
|
</DialogContent>
|
374
422
|
|
375
423
|
<DialogActions position={"sticky"}>
|
376
|
-
{savingError && <Typography className={"text-red-500"}>
|
377
|
-
There was an error saving this role
|
424
|
+
{savingError && <Typography className={"text-red-500 dark:text-red-500"}>
|
425
|
+
{savingError.message ?? "There was an error saving this role"}
|
378
426
|
</Typography>}
|
379
427
|
<Button variant={"text"}
|
380
428
|
onClick={() => {
|
@@ -13,7 +13,7 @@ import {
|
|
13
13
|
Tooltip,
|
14
14
|
Typography
|
15
15
|
} from "@firecms/ui";
|
16
|
-
import {
|
16
|
+
import { ConfirmationDialog, Role } from "@firecms/core";
|
17
17
|
import { useUserManagement } from "../../hooks";
|
18
18
|
import { RoleChip } from "./RoleChip";
|
19
19
|
import { DEFAULT_ROLES } from "./default_roles";
|
@@ -38,7 +38,7 @@ export function RolesTable({
|
|
38
38
|
|
39
39
|
return <div
|
40
40
|
className="w-full overflow-auto">
|
41
|
-
<Table>
|
41
|
+
<Table className={"w-full"}>
|
42
42
|
<TableHeader>
|
43
43
|
<TableCell header={true} className="w-16"></TableCell>
|
44
44
|
<TableCell header={true}>Role</TableCell>
|
@@ -61,7 +61,9 @@ export function RolesTable({
|
|
61
61
|
>
|
62
62
|
<TableCell style={{ width: "64px" }}>
|
63
63
|
{!role.isAdmin &&
|
64
|
-
<Tooltip
|
64
|
+
<Tooltip
|
65
|
+
asChild={true}
|
66
|
+
title={"Delete this role"}>
|
65
67
|
<IconButton
|
66
68
|
size={"small"}
|
67
69
|
disabled={!editable}
|
@@ -113,7 +115,7 @@ export function RolesTable({
|
|
113
115
|
|
114
116
|
</Table>
|
115
117
|
|
116
|
-
<
|
118
|
+
<ConfirmationDialog
|
117
119
|
open={Boolean(roleToBeDeleted)}
|
118
120
|
loading={deleteInProgress}
|
119
121
|
onAccept={() => {
|
@@ -36,7 +36,9 @@ export const RolesView = React.memo(
|
|
36
36
|
component="h4">
|
37
37
|
Roles
|
38
38
|
</Typography>
|
39
|
-
<Tooltip
|
39
|
+
<Tooltip
|
40
|
+
asChild={true}
|
41
|
+
title={!canEditRoles ? "Update plans to customise roles" : undefined}>
|
40
42
|
<Button
|
41
43
|
size={"large"}
|
42
44
|
disabled={!canEditRoles}
|
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
Dialog,
|
6
6
|
DialogActions,
|
7
7
|
DialogContent,
|
8
|
+
DialogTitle,
|
8
9
|
DoneIcon,
|
9
10
|
LoadingButton,
|
10
11
|
MultiSelect,
|
@@ -140,14 +141,11 @@ export function UserDetailsForm({
|
|
140
141
|
position: "relative",
|
141
142
|
height: "100%"
|
142
143
|
}}>
|
144
|
+
|
145
|
+
<DialogTitle variant={"h4"} gutterBottom={false}>
|
146
|
+
User
|
147
|
+
</DialogTitle>
|
143
148
|
<DialogContent className="h-full flex-grow">
|
144
|
-
<div
|
145
|
-
className="flex flex-row pt-4 pb-4">
|
146
|
-
<Typography variant={"h4"}
|
147
|
-
className="flex-grow">
|
148
|
-
User
|
149
|
-
</Typography>
|
150
|
-
</div>
|
151
149
|
|
152
150
|
<div className={"grid grid-cols-12 gap-8"}>
|
153
151
|
|
@@ -181,17 +179,19 @@ export function UserDetailsForm({
|
|
181
179
|
</div>
|
182
180
|
<div className={"col-span-12"}>
|
183
181
|
<MultiSelect
|
182
|
+
className={"w-full"}
|
184
183
|
label="Roles"
|
185
184
|
value={values.roles?.map(r => r.id) ?? []}
|
186
|
-
|
187
|
-
renderValue={(value: string) => {
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
}}
|
185
|
+
onValueChange={(value: string[]) => setFieldValue("roles", value.map(id => roles.find(r => r.id === id) as Role))}
|
186
|
+
// renderValue={(value: string) => {
|
187
|
+
// const userRole = roles
|
188
|
+
// .find((role) => role.id === value);
|
189
|
+
// if (!userRole) return null;
|
190
|
+
// return <div className="flex flex-wrap space-x-2 space-y-2">
|
191
|
+
// <RoleChip key={userRole?.id} role={userRole}/>
|
192
|
+
// </div>;
|
193
|
+
// }}
|
194
|
+
>
|
195
195
|
{roles.map(userRole => <MultiSelectItem key={userRole.id}
|
196
196
|
value={userRole.id}>
|
197
197
|
<RoleChip key={userRole?.id} role={userRole}/>
|
@@ -5,7 +5,7 @@ import * as locales from "date-fns/locale";
|
|
5
5
|
|
6
6
|
import {
|
7
7
|
defaultDateFormat,
|
8
|
-
|
8
|
+
ConfirmationDialog, Role,
|
9
9
|
useAuthController,
|
10
10
|
useCustomizationController, User,
|
11
11
|
useSnackbarController
|
@@ -50,11 +50,10 @@ export function UsersTable({ onUserClicked }: {
|
|
50
50
|
return (
|
51
51
|
<div className="overflow-auto">
|
52
52
|
|
53
|
-
<Table>
|
53
|
+
<Table className={"w-full"}>
|
54
54
|
|
55
55
|
<TableHeader>
|
56
56
|
<TableCell className="truncate w-16"></TableCell>
|
57
|
-
<TableCell>ID</TableCell>
|
58
57
|
<TableCell>Email</TableCell>
|
59
58
|
<TableCell>Name</TableCell>
|
60
59
|
<TableCell>Roles</TableCell>
|
@@ -75,7 +74,9 @@ export function UsersTable({ onUserClicked }: {
|
|
75
74
|
}}
|
76
75
|
>
|
77
76
|
<TableCell className={"w-10"}>
|
78
|
-
<Tooltip
|
77
|
+
<Tooltip
|
78
|
+
asChild={true}
|
79
|
+
title={"Delete this user"}>
|
79
80
|
<IconButton
|
80
81
|
size={"small"}
|
81
82
|
onClick={(event) => {
|
@@ -86,7 +87,6 @@ export function UsersTable({ onUserClicked }: {
|
|
86
87
|
</IconButton>
|
87
88
|
</Tooltip>
|
88
89
|
</TableCell>
|
89
|
-
<TableCell>{user.uid}</TableCell>
|
90
90
|
<TableCell>{user.email}</TableCell>
|
91
91
|
<TableCell className={"font-medium align-left"}>{user.displayName}</TableCell>
|
92
92
|
<TableCell className="align-left">
|
@@ -147,7 +147,7 @@ export function UsersTable({ onUserClicked }: {
|
|
147
147
|
</TableBody>
|
148
148
|
</Table>
|
149
149
|
|
150
|
-
<
|
150
|
+
<ConfirmationDialog
|
151
151
|
open={Boolean(userToBeDeleted)}
|
152
152
|
loading={deleteInProgress}
|
153
153
|
onAccept={() => {
|
package/src/hooks/index.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export * from "./
|
1
|
+
export * from "./useBuildUserManagement";
|
2
2
|
export * from "./useUserManagement";
|