@deix/rossini-identity-management 0.1.0 → 0.1.1

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.
Files changed (50) hide show
  1. package/lib/app/[locale]/groups/{page.js → page.jsx} +1 -1
  2. package/lib/app/[locale]/{layout.js → layout.jsx} +4 -3
  3. package/lib/app/[locale]/users/{page.js → page.jsx} +1 -1
  4. package/lib/app/{layout.js → layout.jsx} +7 -3
  5. package/lib/components/AddItemDialog.jsx +50 -0
  6. package/lib/components/DeleteConfirmationDialog.jsx +44 -0
  7. package/lib/components/SearchField.jsx +18 -0
  8. package/lib/components/groups/CreateGroupDialog.d.ts.map +1 -1
  9. package/lib/components/groups/{CreateGroupDialog.js → CreateGroupDialog.jsx} +9 -8
  10. package/lib/components/groups/GroupDetails.d.ts.map +1 -1
  11. package/lib/components/groups/{GroupDetails.js → GroupDetails.jsx} +5 -6
  12. package/lib/components/groups/GroupForm.jsx +46 -0
  13. package/lib/components/groups/GroupTabs.d.ts.map +1 -1
  14. package/lib/components/groups/GroupTabs.jsx +33 -0
  15. package/lib/components/groups/GroupUsers.d.ts.map +1 -1
  16. package/lib/components/groups/GroupUsers.jsx +88 -0
  17. package/lib/components/groups/Groups.d.ts.map +1 -1
  18. package/lib/components/groups/{Groups.js → Groups.jsx} +45 -30
  19. package/lib/components/groups/GroupsTable.jsx +55 -0
  20. package/lib/components/users/CreateUserDialog.d.ts.map +1 -1
  21. package/lib/components/users/{CreateUserDialog.js → CreateUserDialog.jsx} +9 -8
  22. package/lib/components/users/UserCredentials.d.ts.map +1 -1
  23. package/lib/components/users/{UserCredentials.js → UserCredentials.jsx} +8 -6
  24. package/lib/components/users/UserDetails.d.ts.map +1 -1
  25. package/lib/components/users/{UserDetails.js → UserDetails.jsx} +5 -6
  26. package/lib/components/users/UserForm.jsx +75 -0
  27. package/lib/components/users/UserGroups.d.ts.map +1 -1
  28. package/lib/components/users/UserGroups.jsx +78 -0
  29. package/lib/components/users/Users.d.ts.map +1 -1
  30. package/lib/components/users/{Users.js → Users.jsx} +45 -30
  31. package/lib/components/users/UsersTable.jsx +76 -0
  32. package/lib/components/users/UsersTabs.d.ts.map +1 -1
  33. package/lib/components/users/UsersTabs.jsx +36 -0
  34. package/lib/config/{index.js → index.jsx} +3 -1
  35. package/lib/tsconfig.tsbuildinfo +1 -1
  36. package/lib/utils/hooks/useAPIClient.d.ts +10 -0
  37. package/lib/utils/hooks/useAPIClient.d.ts.map +1 -0
  38. package/lib/utils/hooks/useAPIClient.jsx +18 -0
  39. package/package.json +1 -1
  40. package/lib/components/AddItemDialog.js +0 -45
  41. package/lib/components/DeleteConfirmationDialog.js +0 -35
  42. package/lib/components/SearchField.js +0 -16
  43. package/lib/components/groups/GroupForm.js +0 -38
  44. package/lib/components/groups/GroupTabs.js +0 -29
  45. package/lib/components/groups/GroupUsers.js +0 -74
  46. package/lib/components/groups/GroupsTable.js +0 -43
  47. package/lib/components/users/UserForm.js +0 -62
  48. package/lib/components/users/UserGroups.js +0 -64
  49. package/lib/components/users/UsersTable.js +0 -62
  50. package/lib/components/users/UsersTabs.js +0 -32
@@ -1,17 +1,19 @@
1
1
  import React from 'react';
2
- import { useAPI, useLocale } from '@deix/rossini-core';
2
+ import { useLocale } from '@deix/rossini-core';
3
3
  import { Box, Button } from '@mui/material';
4
4
  import usersTranslations from '../../lang/users';
5
5
  import { useSendUpdatePasswordEmail } from '../../utils/hooks/users';
6
- import { useConfig } from '../../config';
7
6
  import { useQueryClient } from '@tanstack/react-query';
7
+ import { useAPIClient } from '../../utils/hooks/useAPIClient';
8
8
  const UserCredentials = ({ user }) => {
9
9
  const locale = useLocale();
10
- const config = useConfig();
11
- const apiClient = useAPI(config.generalProperties.apiURL);
10
+ const apiClient = useAPIClient();
12
11
  const queryClient = useQueryClient();
13
12
  const { mutate: sendResetPasswordEmail } = useSendUpdatePasswordEmail(queryClient, apiClient);
14
- return (React.createElement(Box, { sx: { mt: 2 } },
15
- React.createElement(Button, { variant: 'contained', onClick: () => sendResetPasswordEmail(user.id) }, usersTranslations.sendResetPasswordEmail[locale])));
13
+ return (<Box sx={{ mt: 2 }}>
14
+ <Button variant='contained' onClick={() => sendResetPasswordEmail(user.id)}>
15
+ {usersTranslations.sendResetPasswordEmail[locale]}
16
+ </Button>
17
+ </Box>);
16
18
  };
17
19
  export default UserCredentials;
@@ -1 +1 @@
1
- {"version":3,"file":"UserDetails.d.ts","sourceRoot":"","sources":["../../../src/components/users/UserDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAIzC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,WAAW,aAAc,gBAAgB,sBAoB9C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"UserDetails.d.ts","sourceRoot":"","sources":["../../../src/components/users/UserDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAKzC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,WAAW,aAAc,gBAAgB,sBAmB9C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -1,18 +1,17 @@
1
1
  import React from 'react';
2
- import { useAPI } from '@deix/rossini-core';
3
2
  import { useQueryClient } from '@tanstack/react-query';
4
- import { useConfig } from '../../config';
5
3
  import { useUpdateUser } from '../../utils/hooks/users';
6
4
  import UserForm from './UserForm';
5
+ import { useAPIClient } from '../../utils/hooks/useAPIClient';
7
6
  const UserDetails = ({ user }) => {
8
- const config = useConfig();
9
- const apiClient = useAPI(config.generalProperties.apiURL);
7
+ const apiClient = useAPIClient();
10
8
  const queryClient = useQueryClient();
11
9
  const { mutate: updateUser } = useUpdateUser(queryClient, apiClient);
12
10
  const handleUpdate = (user) => {
13
11
  updateUser(user);
14
12
  };
15
- return (React.createElement(React.Fragment, null,
16
- React.createElement(UserForm, { mode: 'modify', user: user, onSave: handleUpdate, onCancel: () => { } })));
13
+ return (<>
14
+ <UserForm mode='modify' user={user} onSave={handleUpdate} onCancel={() => { }}/>
15
+ </>);
17
16
  };
18
17
  export default UserDetails;
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { useLocale } from '@deix/rossini-core';
3
+ import { Button, FormControlLabel, Grid, Switch, TextField, } from '@mui/material';
4
+ import { Controller, useForm } from 'react-hook-form';
5
+ import { useEffect } from 'react';
6
+ import usersTranslations from '../../lang/users';
7
+ const UserForm = ({ user, onSave, onCancel, mode = 'create', }) => {
8
+ const locale = useLocale();
9
+ const { control, handleSubmit, setValue } = useForm({
10
+ defaultValues: {
11
+ id: user?.id || '',
12
+ username: user?.username || '',
13
+ firstName: user?.firstName || '',
14
+ lastName: user?.lastName || '',
15
+ email: user?.email || '',
16
+ emailVerified: user?.emailVerified || true,
17
+ enabled: user?.enabled || true,
18
+ sendEmailOnCreation: true,
19
+ },
20
+ });
21
+ useEffect(() => {
22
+ if (user) {
23
+ setValue('id', user?.id);
24
+ setValue('username', user?.username);
25
+ setValue('firstName', user?.firstName);
26
+ setValue('lastName', user?.lastName);
27
+ setValue('email', user?.email);
28
+ setValue('emailVerified', user?.emailVerified);
29
+ setValue('enabled', user?.enabled);
30
+ setValue('groups', user?.groups);
31
+ // The user already exists, we don't want to send an email
32
+ setValue('sendEmailOnCreation', false);
33
+ }
34
+ }, [user, setValue]);
35
+ const onSubmit = (data) => {
36
+ onSave(data);
37
+ };
38
+ return (<form onSubmit={(event) => void handleSubmit(onSubmit)(event)}>
39
+ <Grid container spacing={2} sx={{ mt: 2, maxWidth: 'sm' }} justifyContent='stretch'>
40
+ <Grid item xs={12}>
41
+ <Controller name='username' control={control} render={({ field }) => (<TextField size='small' fullWidth label={usersTranslations.username[locale]} disabled={mode === 'modify'} sx={{ flexShrink: 0 }} {...field}/>)}/>
42
+ </Grid>
43
+ <Grid item xs={12}>
44
+ <Controller name='firstName' control={control} render={({ field }) => (<TextField size='small' fullWidth label={usersTranslations.firstName[locale]} sx={{ flexShrink: 0 }} {...field}/>)}/>
45
+ </Grid>
46
+ <Grid item xs={12}>
47
+ <Controller name='lastName' control={control} render={({ field }) => (<TextField size='small' fullWidth label={usersTranslations.lastName[locale]} sx={{ flexShrink: 0 }} {...field}/>)}/>
48
+ </Grid>
49
+ <Grid item xs={12}>
50
+ <Controller name='email' control={control} render={({ field }) => (<TextField size='small' fullWidth label={usersTranslations.email[locale]} sx={{ flexShrink: 0 }} {...field}/>)}/>
51
+ </Grid>
52
+ <Grid item xs={12}>
53
+ <Controller name='enabled' control={control} render={({ field }) => (<FormControlLabel sx={{ ml: 1 }} control={<Switch checked={field.value} size='small' {...field}/>} label={usersTranslations.enabled[locale]}/>)}/>
54
+ </Grid>
55
+ {mode === 'create' && (<Grid item xs={12}>
56
+ <Controller name='sendEmailOnCreation' control={control} render={({ field }) => (<FormControlLabel sx={{ ml: 1 }} control={<Switch checked={field.value} size='small' {...field}/>} label={usersTranslations.sendResetPasswordEmail[locale]}/>)}/>
57
+ </Grid>)}
58
+ <Grid item sx={{
59
+ mt: 2,
60
+ display: 'flex',
61
+ justifyContent: 'flex-end',
62
+ gap: 2,
63
+ width: '100%',
64
+ }}>
65
+ {mode === 'create' && (<Button variant='outlined' onClick={onCancel}>
66
+ {usersTranslations.cancel[locale]}
67
+ </Button>)}
68
+ <Button variant='contained' type='submit'>
69
+ {usersTranslations.save[locale]}
70
+ </Button>
71
+ </Grid>
72
+ </Grid>
73
+ </form>);
74
+ };
75
+ export default UserForm;
@@ -1 +1 @@
1
- {"version":3,"file":"UserGroups.d.ts","sourceRoot":"","sources":["../../../src/components/users/UserGroups.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAsBzC,UAAU,eAAe;IACvB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,UAAU,aAAc,eAAe,sBA6F5C,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"UserGroups.d.ts","sourceRoot":"","sources":["../../../src/components/users/UserGroups.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAsBzC,UAAU,eAAe;IACvB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,UAAU,aAAc,eAAe,sBA4F5C,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,78 @@
1
+ import React from 'react';
2
+ import { Box, Button, IconButton, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, } from '@mui/material';
3
+ import AddIcon from '@mui/icons-material/Add';
4
+ import DeleteIcon from '@mui/icons-material/Delete';
5
+ import { isStringTranslation, useLocale } from '@deix/rossini-core';
6
+ import { useAddUserToGroup, useRemoveUserFromGroup, useUserGroups, } from '../../utils/hooks/users';
7
+ import { useState } from 'react';
8
+ import DeleteConfirmationDialog from '../DeleteConfirmationDialog';
9
+ import { useQueryClient } from '@tanstack/react-query';
10
+ import usersTranslations from '../../lang/users';
11
+ import AddItemDialog from '../AddItemDialog';
12
+ import { useGroups } from '../../utils/hooks/groups';
13
+ import { useAPIClient } from '../../utils/hooks/useAPIClient';
14
+ const userGroupsTableColumns = [
15
+ {
16
+ id: 'name',
17
+ label: { en: 'Group', it: 'Gruppo' },
18
+ },
19
+ ];
20
+ const UserGroups = ({ user }) => {
21
+ const locale = useLocale();
22
+ const apiClient = useAPIClient();
23
+ const queryClient = useQueryClient();
24
+ const { data: groups } = useGroups(apiClient);
25
+ const { data: userGroups } = useUserGroups(user?.id, apiClient);
26
+ const { mutate: addUserToGroup } = useAddUserToGroup(queryClient, apiClient);
27
+ const { mutate: removeUserFromGroup } = useRemoveUserFromGroup(queryClient, apiClient);
28
+ const [openAddGroupDialog, setOpenAddGroupDialog] = useState(false);
29
+ const [openConfirmationDialog, setOpenConfirmationDialog] = useState(false);
30
+ const [deleteId, setDeleteId] = useState();
31
+ return (<>
32
+ {userGroups && userGroups.length > 0 && (<Box maxWidth='sm'>
33
+ <TableContainer>
34
+ <Table size='small'>
35
+ <TableHead>
36
+ <TableRow>
37
+ {userGroupsTableColumns.map((col) => (<TableCell key={col.id} align={col.align || 'inherit'}>
38
+ {isStringTranslation(col.label)
39
+ ? col.label[locale]
40
+ : col.label}
41
+ </TableCell>))}
42
+ <TableCell padding='none'>{''}</TableCell>
43
+ </TableRow>
44
+ </TableHead>
45
+ <TableBody>
46
+ {userGroups?.map((group, rowIdx) => (<TableRow key={rowIdx}>
47
+ <TableCell>{group.name}</TableCell>
48
+ <TableCell padding='none' align='right'>
49
+ <IconButton size='small' onClick={(evt) => {
50
+ evt.stopPropagation();
51
+ setOpenConfirmationDialog(true);
52
+ setDeleteId(group.id);
53
+ }}>
54
+ <DeleteIcon />
55
+ </IconButton>
56
+ </TableCell>
57
+ </TableRow>))}
58
+ </TableBody>
59
+ </Table>
60
+ </TableContainer>
61
+ </Box>)}
62
+ <Button variant='outlined' startIcon={<AddIcon />} onClick={() => setOpenAddGroupDialog(true)} sx={{ marginTop: 2 }}>
63
+ {usersTranslations.addGroup[locale]}
64
+ </Button>
65
+ <AddItemDialog open={openAddGroupDialog} onClose={() => setOpenAddGroupDialog(false)} onConfirm={(value) => {
66
+ if (value) {
67
+ addUserToGroup({ userId: user.id, groupId: value?.value });
68
+ }
69
+ }} title={usersTranslations.addGroup} options={groups?.map((group) => ({
70
+ value: group.id,
71
+ label: group.name,
72
+ }))}/>
73
+ <DeleteConfirmationDialog open={openConfirmationDialog} onClose={() => setOpenConfirmationDialog(false)} onConfirm={() => deleteId
74
+ ? removeUserFromGroup({ userId: user.id, groupId: deleteId })
75
+ : {}}/>
76
+ </>);
77
+ };
78
+ export default UserGroups;
@@ -1 +1 @@
1
- {"version":3,"file":"Users.d.ts","sourceRoot":"","sources":["../../../src/components/users/Users.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,OAAiB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEhD,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED,QAAA,MAAM,KAAK,+BAAqC,UAAU,sBA8HzD,CAAC;AAEF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Users.d.ts","sourceRoot":"","sources":["../../../src/components/users/Users.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,OAAiB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGhD,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED,QAAA,MAAM,KAAK,+BAAqC,UAAU,sBAgIzD,CAAC;AAEF,eAAe,KAAK,CAAC"}
@@ -12,6 +12,7 @@ import UsersTable from './UsersTable';
12
12
  import usersTranslations from '../../lang/users';
13
13
  import { useDeleteUser, useUsers } from '../../utils/hooks/users';
14
14
  import UserTabs from './UsersTabs';
15
+ import { APIClientProvider } from '../../utils/hooks/useAPIClient';
15
16
  const Users = ({ apiUrl, additionalTabs = [] }) => {
16
17
  const locale = useLocale();
17
18
  const apiClient = useAPI(apiUrl);
@@ -40,45 +41,59 @@ const Users = ({ apiUrl, additionalTabs = [] }) => {
40
41
  deleteUser(id);
41
42
  setSelectedUser(undefined);
42
43
  };
43
- return (React.createElement(Box, { sx: {
44
+ return (<APIClientProvider baseURL={apiUrl}>
45
+ <Box sx={{
44
46
  flexGrow: 1,
45
47
  maxWidth: '100%',
46
48
  overflowX: 'hidden',
47
49
  paddingTop: 3,
48
50
  paddingLeft: 3,
49
51
  paddingRight: 3,
50
- } },
51
- !selectedUser && (React.createElement(React.Fragment, null,
52
- React.createElement(Grid, { container: true, spacing: 2, sx: { marginBottom: 2 } },
53
- React.createElement(Grid, { item: true },
54
- React.createElement(SearchField, { placeholder: usersTranslations.search[locale], onSearch: (value) => setSearchString(value) })),
55
- React.createElement(Grid, { item: true },
56
- React.createElement(Button, { variant: 'contained', startIcon: React.createElement(PersonAddIcon, null), onClick: () => {
57
- setOpenCreateUserDialog(true);
58
- setSelectedUser(undefined);
59
- } }, usersTranslations.new[locale]))),
60
- React.createElement(UsersTable, { users: filteredUsers, selectedUser: selectedUser, setSelectedUser: (user) => {
61
- setSelectedUser(user);
62
- }, onDelete: handleDelete }))),
63
- selectedUser && (React.createElement(Box, { sx: {
52
+ }}>
53
+ {!selectedUser && (<>
54
+ <Grid container spacing={2} sx={{ marginBottom: 2 }}>
55
+ <Grid item>
56
+ <SearchField placeholder={usersTranslations.search[locale]} onSearch={(value) => setSearchString(value)}/>
57
+ </Grid>
58
+ <Grid item>
59
+ <Button variant='contained' startIcon={<PersonAddIcon />} onClick={() => {
60
+ setOpenCreateUserDialog(true);
61
+ setSelectedUser(undefined);
62
+ }}>
63
+ {usersTranslations.new[locale]}
64
+ </Button>
65
+ </Grid>
66
+ </Grid>
67
+ <UsersTable users={filteredUsers} selectedUser={selectedUser} setSelectedUser={(user) => {
68
+ setSelectedUser(user);
69
+ }} onDelete={handleDelete}/>
70
+ </>)}
71
+ {selectedUser && (<Box sx={{
64
72
  display: 'flex',
65
73
  flexDirection: 'column',
66
74
  alignItems: 'flex-start',
67
75
  width: '100%',
68
- } },
69
- React.createElement(Box, { sx: {
70
- display: 'flex',
71
- flexDirection: 'row',
72
- alignItems: 'center',
73
- } },
74
- React.createElement(IconButton, { "aria-label": 'delete', color: 'primary', onClick: () => setSelectedUser(undefined), sx: { mr: 2 } },
75
- React.createElement(ArrowBackIcon, null)),
76
- React.createElement(Link, { underline: 'none', href: '#', onClick: () => setSelectedUser(undefined) }, usersTranslations.title[locale]),
77
- React.createElement(KeyboardArrowRightIcon, null),
78
- selectedUser.username),
79
- React.createElement(UserTabs, { user: selectedUser, additionalTabs: additionalTabs }))),
80
- React.createElement(CreateUserDialog, { open: openCreateUserDialog, onClose: () => {
81
- setOpenCreateUserDialog(false);
82
- } })));
76
+ }}>
77
+ <Box sx={{
78
+ display: 'flex',
79
+ flexDirection: 'row',
80
+ alignItems: 'center',
81
+ }}>
82
+ <IconButton aria-label='delete' color='primary' onClick={() => setSelectedUser(undefined)} sx={{ mr: 2 }}>
83
+ <ArrowBackIcon />
84
+ </IconButton>
85
+ <Link underline='none' href='#' onClick={() => setSelectedUser(undefined)}>
86
+ {usersTranslations.title[locale]}
87
+ </Link>
88
+ <KeyboardArrowRightIcon />
89
+ {selectedUser.username}
90
+ </Box>
91
+ <UserTabs user={selectedUser} additionalTabs={additionalTabs}/>
92
+ </Box>)}
93
+ <CreateUserDialog open={openCreateUserDialog} onClose={() => {
94
+ setOpenCreateUserDialog(false);
95
+ }}/>
96
+ </Box>
97
+ </APIClientProvider>);
83
98
  };
84
99
  export default Users;
@@ -0,0 +1,76 @@
1
+ import React from 'react';
2
+ import { isStringTranslation, useLocale } from '@deix/rossini-core';
3
+ import CheckIcon from '@mui/icons-material/Check';
4
+ import CloseIcon from '@mui/icons-material/Close';
5
+ import DeleteIcon from '@mui/icons-material/Delete';
6
+ import { IconButton, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, useTheme, } from '@mui/material';
7
+ import { useState } from 'react';
8
+ import DeleteConfirmationDialog from '../DeleteConfirmationDialog';
9
+ const usersTableColumns = [
10
+ {
11
+ id: 'firstName',
12
+ label: { en: 'First Name', it: 'Nome' },
13
+ },
14
+ {
15
+ id: 'lastName',
16
+ label: { en: 'Last Name', it: 'Cognome' },
17
+ },
18
+ {
19
+ id: 'username',
20
+ label: { en: 'Username', it: 'Username' },
21
+ },
22
+ { id: 'email', label: 'Email' },
23
+ {
24
+ id: 'enabled',
25
+ label: { en: 'Enabled', it: 'Utente Abilitato' },
26
+ },
27
+ ];
28
+ const UsersTable = ({ users = [], selectedUser, setSelectedUser, onDelete, }) => {
29
+ const locale = useLocale();
30
+ const muiTheme = useTheme();
31
+ const [openConfirmationDialog, setOpenConfirmationDialog] = useState(false);
32
+ const [deleteId, setDeleteId] = useState();
33
+ return (<>
34
+ <TableContainer>
35
+ <Table size='small'>
36
+ <TableHead>
37
+ <TableRow>
38
+ {usersTableColumns.map((col) => (<TableCell key={col.id} align={col.align || 'inherit'}>
39
+ {isStringTranslation(col.label)
40
+ ? col.label[locale]
41
+ : col.label}
42
+ </TableCell>))}
43
+ <TableCell padding='none'>{''}</TableCell>
44
+ </TableRow>
45
+ </TableHead>
46
+ <TableBody>
47
+ {users.map((user, rowIdx) => (<TableRow key={rowIdx} onClick={() => setSelectedUser(user)} sx={{
48
+ cursor: 'pointer',
49
+ background: selectedUser && user.id === selectedUser.id
50
+ ? muiTheme.palette.primary.light
51
+ : undefined,
52
+ }}>
53
+ <TableCell>{user.firstName}</TableCell>
54
+ <TableCell>{user.lastName}</TableCell>
55
+ <TableCell>{user.username}</TableCell>
56
+ <TableCell>{user.email}</TableCell>
57
+ <TableCell>
58
+ {user.enabled ? <CheckIcon /> : <CloseIcon />}
59
+ </TableCell>
60
+ <TableCell padding='none' align='right'>
61
+ <IconButton size='small' onClick={(evt) => {
62
+ evt.stopPropagation();
63
+ setOpenConfirmationDialog(true);
64
+ setDeleteId(user.id);
65
+ }}>
66
+ <DeleteIcon />
67
+ </IconButton>
68
+ </TableCell>
69
+ </TableRow>))}
70
+ </TableBody>
71
+ </Table>
72
+ </TableContainer>
73
+ <DeleteConfirmationDialog open={openConfirmationDialog} onClose={() => setOpenConfirmationDialog(false)} onConfirm={() => (deleteId ? onDelete(deleteId) : {})}/>
74
+ </>);
75
+ };
76
+ export default UsersTable;
@@ -1 +1 @@
1
- {"version":3,"file":"UsersTabs.d.ts","sourceRoot":"","sources":["../../../src/components/users/UsersTabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAa,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAKzC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,KAAK,CAAC,iBAAiB,CAAC;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,6BAAmC,aAAa,sBAgD7D,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"UsersTabs.d.ts","sourceRoot":"","sources":["../../../src/components/users/UsersTabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAa,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAKzC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,KAAK,CAAC,iBAAiB,CAAC;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,6BAAmC,aAAa,sBAoD7D,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+ import React, { useState } from 'react';
3
+ import { Box, Tab, Tabs } from '@mui/material';
4
+ import { useLocale } from '@deix/rossini-core';
5
+ import usersTranslations from '../../lang/users';
6
+ import UserDetails from './UserDetails';
7
+ import UserGroups from './UserGroups';
8
+ import UserCredentials from './UserCredentials';
9
+ const UserTabs = ({ user, additionalTabs = [] }) => {
10
+ const locale = useLocale();
11
+ const [selectedTab, setSelectedTab] = useState('DETAILS');
12
+ return (<Box sx={{
13
+ flexGrow: 1,
14
+ maxWidth: '100%',
15
+ overflowX: 'hidden',
16
+ alignSelf: 'stretch',
17
+ }}>
18
+ <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
19
+ <Tabs value={selectedTab} onChange={(_evt, newValue) => {
20
+ setSelectedTab(newValue);
21
+ }} aria-label='basic tabs example'>
22
+ <Tab label={usersTranslations.details[locale]} value='DETAILS'/>
23
+ <Tab label={usersTranslations.userGroups[locale]} value='USER_GROUPS'/>
24
+ <Tab label={usersTranslations.credentials[locale]} value='CREDENTIALS'/>
25
+ {additionalTabs.map((tab, index) => (<Tab key={`tab${index}`} label={tab.title[locale]} value={`ADDITIONAL_TAB_${index}`}/>))}
26
+ </Tabs>
27
+ </Box>
28
+ <Box sx={{ p: 1 }}>
29
+ {selectedTab === 'DETAILS' && <UserDetails user={user}/>}
30
+ {selectedTab === 'USER_GROUPS' && <UserGroups user={user}/>}
31
+ {selectedTab === 'CREDENTIALS' && <UserCredentials user={user}/>}
32
+ {additionalTabs.map((tab, index) => selectedTab === `ADDITIONAL_TAB_${index}` && (<tab.component key={`tab${index}`} user={user}/>))}
33
+ </Box>
34
+ </Box>);
35
+ };
36
+ export default UserTabs;
@@ -13,6 +13,8 @@ export const getConfig = (publicRuntimeEnv) => ({
13
13
  // read at runtime
14
14
  const ConfigContext = createContext(getConfig({}));
15
15
  export const ConfigProvider = ({ publicRuntimeEnv, children, }) => {
16
- return (React.createElement(ConfigContext.Provider, { value: getConfig(publicRuntimeEnv) }, children));
16
+ return (<ConfigContext.Provider value={getConfig(publicRuntimeEnv)}>
17
+ {children}
18
+ </ConfigContext.Provider>);
17
19
  };
18
20
  export const useConfig = () => useContext(ConfigContext);