@deix/rossini-identity-management 0.1.0

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 (126) hide show
  1. package/README.md +6 -0
  2. package/lib/app/[locale]/groups/page.d.ts +4 -0
  3. package/lib/app/[locale]/groups/page.d.ts.map +1 -0
  4. package/lib/app/[locale]/groups/page.js +9 -0
  5. package/lib/app/[locale]/layout.d.ts +10 -0
  6. package/lib/app/[locale]/layout.d.ts.map +1 -0
  7. package/lib/app/[locale]/layout.js +24 -0
  8. package/lib/app/[locale]/users/page.d.ts +4 -0
  9. package/lib/app/[locale]/users/page.d.ts.map +1 -0
  10. package/lib/app/[locale]/users/page.js +9 -0
  11. package/lib/app/layout.d.ts +13 -0
  12. package/lib/app/layout.d.ts.map +1 -0
  13. package/lib/app/layout.js +20 -0
  14. package/lib/components/AddItemDialog.d.ts +16 -0
  15. package/lib/components/AddItemDialog.d.ts.map +1 -0
  16. package/lib/components/AddItemDialog.js +45 -0
  17. package/lib/components/DeleteConfirmationDialog.d.ts +9 -0
  18. package/lib/components/DeleteConfirmationDialog.d.ts.map +1 -0
  19. package/lib/components/DeleteConfirmationDialog.js +35 -0
  20. package/lib/components/SearchField.d.ts +8 -0
  21. package/lib/components/SearchField.d.ts.map +1 -0
  22. package/lib/components/SearchField.js +16 -0
  23. package/lib/components/groups/CreateGroupDialog.d.ts +8 -0
  24. package/lib/components/groups/CreateGroupDialog.d.ts.map +1 -0
  25. package/lib/components/groups/CreateGroupDialog.js +24 -0
  26. package/lib/components/groups/GroupDetails.d.ts +8 -0
  27. package/lib/components/groups/GroupDetails.d.ts.map +1 -0
  28. package/lib/components/groups/GroupDetails.js +18 -0
  29. package/lib/components/groups/GroupForm.d.ts +11 -0
  30. package/lib/components/groups/GroupForm.d.ts.map +1 -0
  31. package/lib/components/groups/GroupForm.js +38 -0
  32. package/lib/components/groups/GroupTabs.d.ts +16 -0
  33. package/lib/components/groups/GroupTabs.d.ts.map +1 -0
  34. package/lib/components/groups/GroupTabs.js +29 -0
  35. package/lib/components/groups/GroupUsers.d.ts +8 -0
  36. package/lib/components/groups/GroupUsers.d.ts.map +1 -0
  37. package/lib/components/groups/GroupUsers.js +74 -0
  38. package/lib/components/groups/Groups.d.ts +9 -0
  39. package/lib/components/groups/Groups.d.ts.map +1 -0
  40. package/lib/components/groups/Groups.js +78 -0
  41. package/lib/components/groups/GroupsTable.d.ts +11 -0
  42. package/lib/components/groups/GroupsTable.d.ts.map +1 -0
  43. package/lib/components/groups/GroupsTable.js +43 -0
  44. package/lib/components/index.d.ts +3 -0
  45. package/lib/components/index.d.ts.map +1 -0
  46. package/lib/components/index.js +2 -0
  47. package/lib/components/users/CreateUserDialog.d.ts +8 -0
  48. package/lib/components/users/CreateUserDialog.d.ts.map +1 -0
  49. package/lib/components/users/CreateUserDialog.js +24 -0
  50. package/lib/components/users/UserCredentials.d.ts +8 -0
  51. package/lib/components/users/UserCredentials.d.ts.map +1 -0
  52. package/lib/components/users/UserCredentials.js +17 -0
  53. package/lib/components/users/UserDetails.d.ts +8 -0
  54. package/lib/components/users/UserDetails.d.ts.map +1 -0
  55. package/lib/components/users/UserDetails.js +18 -0
  56. package/lib/components/users/UserForm.d.ts +14 -0
  57. package/lib/components/users/UserForm.d.ts.map +1 -0
  58. package/lib/components/users/UserForm.js +62 -0
  59. package/lib/components/users/UserGroups.d.ts +8 -0
  60. package/lib/components/users/UserGroups.d.ts.map +1 -0
  61. package/lib/components/users/UserGroups.js +64 -0
  62. package/lib/components/users/Users.d.ts +9 -0
  63. package/lib/components/users/Users.d.ts.map +1 -0
  64. package/lib/components/users/Users.js +84 -0
  65. package/lib/components/users/UsersTable.d.ts +13 -0
  66. package/lib/components/users/UsersTable.d.ts.map +1 -0
  67. package/lib/components/users/UsersTable.js +62 -0
  68. package/lib/components/users/UsersTabs.d.ts +16 -0
  69. package/lib/components/users/UsersTabs.d.ts.map +1 -0
  70. package/lib/components/users/UsersTabs.js +32 -0
  71. package/lib/config/i18n.d.ts +3 -0
  72. package/lib/config/i18n.d.ts.map +1 -0
  73. package/lib/config/i18n.js +14 -0
  74. package/lib/config/index.d.ts +11 -0
  75. package/lib/config/index.d.ts.map +1 -0
  76. package/lib/config/index.js +18 -0
  77. package/lib/config/palette.d.ts +5 -0
  78. package/lib/config/palette.d.ts.map +1 -0
  79. package/lib/config/palette.js +88 -0
  80. package/lib/index.d.ts +5 -0
  81. package/lib/index.d.ts.map +1 -0
  82. package/lib/index.js +2 -0
  83. package/lib/lang/groups.d.ts +6 -0
  84. package/lib/lang/groups.d.ts.map +1 -0
  85. package/lib/lang/groups.js +71 -0
  86. package/lib/lang/home.d.ts +6 -0
  87. package/lib/lang/home.d.ts.map +1 -0
  88. package/lib/lang/home.js +11 -0
  89. package/lib/lang/users.d.ts +6 -0
  90. package/lib/lang/users.d.ts.map +1 -0
  91. package/lib/lang/users.js +123 -0
  92. package/lib/middleware.d.ts +5 -0
  93. package/lib/middleware.d.ts.map +1 -0
  94. package/lib/middleware.js +9 -0
  95. package/lib/tsconfig.tsbuildinfo +1 -0
  96. package/lib/types/config.d.ts +8 -0
  97. package/lib/types/config.d.ts.map +1 -0
  98. package/lib/types/config.js +1 -0
  99. package/lib/types/groups.d.ts +5 -0
  100. package/lib/types/groups.d.ts.map +1 -0
  101. package/lib/types/groups.js +1 -0
  102. package/lib/types/index.d.ts +1 -0
  103. package/lib/types/index.d.ts.map +1 -0
  104. package/lib/types/index.js +1 -0
  105. package/lib/types/tables.d.ts +12 -0
  106. package/lib/types/tables.d.ts.map +1 -0
  107. package/lib/types/tables.js +1 -0
  108. package/lib/types/users.d.ts +11 -0
  109. package/lib/types/users.d.ts.map +1 -0
  110. package/lib/types/users.js +1 -0
  111. package/lib/utils/helpers/index.d.ts +1 -0
  112. package/lib/utils/helpers/index.d.ts.map +1 -0
  113. package/lib/utils/helpers/index.js +1 -0
  114. package/lib/utils/hooks/groups.d.ts +10 -0
  115. package/lib/utils/hooks/groups.d.ts.map +1 -0
  116. package/lib/utils/hooks/groups.js +133 -0
  117. package/lib/utils/hooks/index.d.ts +1 -0
  118. package/lib/utils/hooks/index.d.ts.map +1 -0
  119. package/lib/utils/hooks/index.js +1 -0
  120. package/lib/utils/hooks/users.d.ts +29 -0
  121. package/lib/utils/hooks/users.d.ts.map +1 -0
  122. package/lib/utils/hooks/users.js +254 -0
  123. package/lib/utils/index.d.ts +1 -0
  124. package/lib/utils/index.d.ts.map +1 -0
  125. package/lib/utils/index.js +1 -0
  126. package/package.json +99 -0
@@ -0,0 +1,78 @@
1
+ 'use client';
2
+ import React, { useEffect, useState } from 'react';
3
+ import GroupAddIcon from '@mui/icons-material/GroupAdd';
4
+ import { Box, Button, Grid, IconButton, Link } from '@mui/material';
5
+ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
6
+ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
7
+ import { useAPI, useLocale } from '@deix/rossini-core';
8
+ import { SearchField } from '..';
9
+ import CreateGroupDialog from './CreateGroupDialog';
10
+ import GroupsTable from './GroupsTable';
11
+ import groupsTranslations from '../../lang/groups';
12
+ import { useDeleteGroup, useGroups } from '../../utils/hooks/groups';
13
+ import GroupTabs from './GroupTabs';
14
+ import { useQueryClient } from '@tanstack/react-query';
15
+ const Groups = ({ apiUrl, additionalTabs = [] }) => {
16
+ const locale = useLocale();
17
+ const apiClient = useAPI(apiUrl);
18
+ const queryClient = useQueryClient();
19
+ const { data: groups } = useGroups(apiClient);
20
+ const { mutate: deleteGroup } = useDeleteGroup(queryClient, apiClient);
21
+ const [searchString, setSearchString] = useState('');
22
+ const [filteredGroups, setFilteredGroups] = useState();
23
+ const [selectedGroup, setSelectedGroup] = useState();
24
+ const [openGroupDialog, setOpenGroupDialog] = useState(false);
25
+ useEffect(() => {
26
+ if (groups && searchString === '') {
27
+ setFilteredGroups(groups);
28
+ }
29
+ else if (groups && searchString !== '') {
30
+ setFilteredGroups(groups.filter((group) => group.name.includes(searchString)));
31
+ }
32
+ }, [searchString, groups, setFilteredGroups]);
33
+ const handleDelete = (id) => {
34
+ deleteGroup(id);
35
+ setSelectedGroup(undefined);
36
+ };
37
+ return (React.createElement(Box, { sx: {
38
+ flexGrow: 1,
39
+ maxWidth: '100%',
40
+ overflowX: 'hidden',
41
+ paddingTop: 3,
42
+ paddingLeft: 3,
43
+ paddingRight: 3,
44
+ } },
45
+ !selectedGroup && (React.createElement(React.Fragment, null,
46
+ React.createElement(Grid, { container: true, spacing: 2, sx: { marginBottom: 2 } },
47
+ React.createElement(Grid, { item: true },
48
+ React.createElement(SearchField, { placeholder: groupsTranslations.search[locale], onSearch: (value) => setSearchString(value) })),
49
+ React.createElement(Grid, { item: true },
50
+ React.createElement(Button, { variant: 'contained', startIcon: React.createElement(GroupAddIcon, null), onClick: () => {
51
+ setOpenGroupDialog(true);
52
+ setSelectedGroup(undefined);
53
+ } }, groupsTranslations.new[locale]))),
54
+ React.createElement(GroupsTable, { groups: filteredGroups, selectedGroup: selectedGroup, setSelectedGroup: (group) => {
55
+ setSelectedGroup(group);
56
+ }, onDelete: handleDelete }))),
57
+ selectedGroup && (React.createElement(Box, { sx: {
58
+ display: 'flex',
59
+ flexDirection: 'column',
60
+ alignItems: 'flex-start',
61
+ width: '100%',
62
+ } },
63
+ React.createElement(Box, { sx: {
64
+ display: 'flex',
65
+ flexDirection: 'row',
66
+ alignItems: 'center',
67
+ } },
68
+ React.createElement(IconButton, { "aria-label": 'delete', color: 'primary', onClick: () => setSelectedGroup(undefined), sx: { mr: 2 } },
69
+ React.createElement(ArrowBackIcon, null)),
70
+ React.createElement(Link, { underline: 'none', href: '#', onClick: () => setSelectedGroup(undefined) }, groupsTranslations.title[locale]),
71
+ React.createElement(KeyboardArrowRightIcon, null),
72
+ selectedGroup.name),
73
+ React.createElement(GroupTabs, { group: selectedGroup, additionalTabs: additionalTabs }))),
74
+ React.createElement(CreateGroupDialog, { open: openGroupDialog, onClose: () => {
75
+ setOpenGroupDialog(false);
76
+ } })));
77
+ };
78
+ export default Groups;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { Group } from '../../types/groups';
3
+ export interface TableProps {
4
+ groups?: Group[];
5
+ selectedGroup?: Group;
6
+ setSelectedGroup: (group: Group) => void;
7
+ onDelete: (id: string) => void;
8
+ }
9
+ declare const GroupsTable: ({ groups, selectedGroup, setSelectedGroup, onDelete, }: TableProps) => React.JSX.Element;
10
+ export default GroupsTable;
11
+ //# sourceMappingURL=GroupsTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupsTable.d.ts","sourceRoot":"","sources":["../../../src/components/groups/GroupsTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAW3C,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,KAAK,CAAC;IACtB,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,QAAA,MAAM,WAAW,2DAKd,UAAU,sBA8DZ,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { isStringTranslation, useLocale } from '@deix/rossini-core';
3
+ import DeleteIcon from '@mui/icons-material/Delete';
4
+ import { IconButton, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, useTheme, } from '@mui/material';
5
+ import { useState } from 'react';
6
+ import DeleteConfirmationDialog from '../DeleteConfirmationDialog';
7
+ const groupsTableColumns = [
8
+ {
9
+ id: 'name',
10
+ label: { en: 'Name', it: 'Nome' },
11
+ },
12
+ ];
13
+ const GroupsTable = ({ groups = [], selectedGroup, setSelectedGroup, onDelete, }) => {
14
+ const locale = useLocale();
15
+ const muiTheme = useTheme();
16
+ const [openConfirmationDialog, setOpenConfirmationDialog] = useState(false);
17
+ const [deleteId, setDeleteId] = useState();
18
+ return (React.createElement(React.Fragment, null,
19
+ React.createElement(TableContainer, null,
20
+ React.createElement(Table, { size: 'small' },
21
+ React.createElement(TableHead, null,
22
+ React.createElement(TableRow, null,
23
+ groupsTableColumns.map((col) => (React.createElement(TableCell, { key: col.id, align: col.align || 'inherit' }, isStringTranslation(col.label)
24
+ ? col.label[locale]
25
+ : col.label))),
26
+ React.createElement(TableCell, { padding: 'none' }, ''))),
27
+ React.createElement(TableBody, null, groups.map((group, rowIdx) => (React.createElement(TableRow, { key: rowIdx, onClick: () => setSelectedGroup(group), sx: {
28
+ cursor: 'pointer',
29
+ background: selectedGroup && group.id === selectedGroup.id
30
+ ? muiTheme.palette.primary.light
31
+ : undefined,
32
+ } },
33
+ React.createElement(TableCell, null, group.name),
34
+ React.createElement(TableCell, { padding: 'none', align: 'right' },
35
+ React.createElement(IconButton, { size: 'small', onClick: (evt) => {
36
+ evt.stopPropagation();
37
+ setOpenConfirmationDialog(true);
38
+ setDeleteId(group.id);
39
+ } },
40
+ React.createElement(DeleteIcon, null))))))))),
41
+ React.createElement(DeleteConfirmationDialog, { open: openConfirmationDialog, onClose: () => setOpenConfirmationDialog(false), onConfirm: () => (deleteId ? onDelete(deleteId) : {}) })));
42
+ };
43
+ export default GroupsTable;
@@ -0,0 +1,3 @@
1
+ export { default as SearchField } from './SearchField';
2
+ export { default as DeleteConfirmationDialog } from './DeleteConfirmationDialog';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as SearchField } from './SearchField';
2
+ export { default as DeleteConfirmationDialog } from './DeleteConfirmationDialog';
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export interface CreateUserDialogProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ }
6
+ declare const CreateUserDialog: ({ open, onClose }: CreateUserDialogProps) => React.JSX.Element;
7
+ export default CreateUserDialog;
8
+ //# sourceMappingURL=CreateUserDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CreateUserDialog.d.ts","sourceRoot":"","sources":["../../../src/components/users/CreateUserDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,gBAAgB,sBAAuB,qBAAqB,sBAqBjE,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { useAPI, useLocale } from '@deix/rossini-core';
3
+ import { Dialog, DialogContent, DialogTitle } from '@mui/material';
4
+ import { useQueryClient } from '@tanstack/react-query';
5
+ import { useConfig } from '../../config';
6
+ import { useAddUser } from '../../utils/hooks/users';
7
+ import UserForm from './UserForm';
8
+ import usersTranslations from '../../lang/users';
9
+ const CreateUserDialog = ({ open, onClose }) => {
10
+ const locale = useLocale();
11
+ const config = useConfig();
12
+ const apiClient = useAPI(config.generalProperties.apiURL);
13
+ const queryClient = useQueryClient();
14
+ const { mutate: addUser } = useAddUser(queryClient, apiClient);
15
+ const handleSave = (userFormData) => {
16
+ addUser(userFormData);
17
+ onClose();
18
+ };
19
+ return (React.createElement(Dialog, { open: open, fullWidth: true, maxWidth: 'sm', onClose: onClose },
20
+ React.createElement(DialogTitle, null, usersTranslations.create[locale]),
21
+ React.createElement(DialogContent, null,
22
+ React.createElement(UserForm, { mode: 'create', onSave: handleSave, onCancel: onClose }))));
23
+ };
24
+ export default CreateUserDialog;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { User } from '../../types/users';
3
+ interface UserCredentialsProps {
4
+ user: User;
5
+ }
6
+ declare const UserCredentials: ({ user }: UserCredentialsProps) => React.JSX.Element;
7
+ export default UserCredentials;
8
+ //# sourceMappingURL=UserCredentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserCredentials.d.ts","sourceRoot":"","sources":["../../../src/components/users/UserCredentials.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAOzC,UAAU,oBAAoB;IAC5B,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,eAAe,aAAc,oBAAoB,sBAmBtD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useAPI, useLocale } from '@deix/rossini-core';
3
+ import { Box, Button } from '@mui/material';
4
+ import usersTranslations from '../../lang/users';
5
+ import { useSendUpdatePasswordEmail } from '../../utils/hooks/users';
6
+ import { useConfig } from '../../config';
7
+ import { useQueryClient } from '@tanstack/react-query';
8
+ const UserCredentials = ({ user }) => {
9
+ const locale = useLocale();
10
+ const config = useConfig();
11
+ const apiClient = useAPI(config.generalProperties.apiURL);
12
+ const queryClient = useQueryClient();
13
+ 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])));
16
+ };
17
+ export default UserCredentials;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { User } from '../../types/users';
3
+ export interface UserDetailsProps {
4
+ user: User;
5
+ }
6
+ declare const UserDetails: ({ user }: UserDetailsProps) => React.JSX.Element;
7
+ export default UserDetails;
8
+ //# sourceMappingURL=UserDetails.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { useAPI } from '@deix/rossini-core';
3
+ import { useQueryClient } from '@tanstack/react-query';
4
+ import { useConfig } from '../../config';
5
+ import { useUpdateUser } from '../../utils/hooks/users';
6
+ import UserForm from './UserForm';
7
+ const UserDetails = ({ user }) => {
8
+ const config = useConfig();
9
+ const apiClient = useAPI(config.generalProperties.apiURL);
10
+ const queryClient = useQueryClient();
11
+ const { mutate: updateUser } = useUpdateUser(queryClient, apiClient);
12
+ const handleUpdate = (user) => {
13
+ updateUser(user);
14
+ };
15
+ return (React.createElement(React.Fragment, null,
16
+ React.createElement(UserForm, { mode: 'modify', user: user, onSave: handleUpdate, onCancel: () => { } })));
17
+ };
18
+ export default UserDetails;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { User } from '../../types/users';
3
+ export interface UserFormFields extends User {
4
+ sendEmailOnCreation: boolean;
5
+ }
6
+ export interface UserFormProps {
7
+ onSave: (user: UserFormFields) => void;
8
+ onCancel?: () => void;
9
+ user?: User;
10
+ mode?: 'create' | 'modify';
11
+ }
12
+ declare const UserForm: ({ user, onSave, onCancel, mode, }: UserFormProps) => React.JSX.Element;
13
+ export default UserForm;
14
+ //# sourceMappingURL=UserForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserForm.d.ts","sourceRoot":"","sources":["../../../src/components/users/UserForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAc1B,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,MAAM,WAAW,cAAe,SAAQ,IAAI;IAC1C,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,sCAKX,aAAa,sBA8Jf,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,62 @@
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 (React.createElement("form", { onSubmit: (event) => void handleSubmit(onSubmit)(event) },
39
+ React.createElement(Grid, { container: true, spacing: 2, sx: { mt: 2, maxWidth: 'sm' }, justifyContent: 'stretch' },
40
+ React.createElement(Grid, { item: true, xs: 12 },
41
+ React.createElement(Controller, { name: 'username', control: control, render: ({ field }) => (React.createElement(TextField, { size: 'small', fullWidth: true, label: usersTranslations.username[locale], disabled: mode === 'modify', sx: { flexShrink: 0 }, ...field })) })),
42
+ React.createElement(Grid, { item: true, xs: 12 },
43
+ React.createElement(Controller, { name: 'firstName', control: control, render: ({ field }) => (React.createElement(TextField, { size: 'small', fullWidth: true, label: usersTranslations.firstName[locale], sx: { flexShrink: 0 }, ...field })) })),
44
+ React.createElement(Grid, { item: true, xs: 12 },
45
+ React.createElement(Controller, { name: 'lastName', control: control, render: ({ field }) => (React.createElement(TextField, { size: 'small', fullWidth: true, label: usersTranslations.lastName[locale], sx: { flexShrink: 0 }, ...field })) })),
46
+ React.createElement(Grid, { item: true, xs: 12 },
47
+ React.createElement(Controller, { name: 'email', control: control, render: ({ field }) => (React.createElement(TextField, { size: 'small', fullWidth: true, label: usersTranslations.email[locale], sx: { flexShrink: 0 }, ...field })) })),
48
+ React.createElement(Grid, { item: true, xs: 12 },
49
+ React.createElement(Controller, { name: 'enabled', control: control, render: ({ field }) => (React.createElement(FormControlLabel, { sx: { ml: 1 }, control: React.createElement(Switch, { checked: field.value, size: 'small', ...field }), label: usersTranslations.enabled[locale] })) })),
50
+ mode === 'create' && (React.createElement(Grid, { item: true, xs: 12 },
51
+ React.createElement(Controller, { name: 'sendEmailOnCreation', control: control, render: ({ field }) => (React.createElement(FormControlLabel, { sx: { ml: 1 }, control: React.createElement(Switch, { checked: field.value, size: 'small', ...field }), label: usersTranslations.sendResetPasswordEmail[locale] })) }))),
52
+ React.createElement(Grid, { item: true, sx: {
53
+ mt: 2,
54
+ display: 'flex',
55
+ justifyContent: 'flex-end',
56
+ gap: 2,
57
+ width: '100%',
58
+ } },
59
+ mode === 'create' && (React.createElement(Button, { variant: 'outlined', onClick: onCancel }, usersTranslations.cancel[locale])),
60
+ React.createElement(Button, { variant: 'contained', type: 'submit' }, usersTranslations.save[locale])))));
61
+ };
62
+ export default UserForm;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { User } from '../../types/users';
3
+ interface UserGroupsProps {
4
+ user: User;
5
+ }
6
+ declare const UserGroups: ({ user }: UserGroupsProps) => React.JSX.Element;
7
+ export default UserGroups;
8
+ //# sourceMappingURL=UserGroups.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,64 @@
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, useAPI, useLocale } from '@deix/rossini-core';
6
+ import { useConfig } from '../../config';
7
+ import { useAddUserToGroup, useRemoveUserFromGroup, useUserGroups, } from '../../utils/hooks/users';
8
+ import { useState } from 'react';
9
+ import DeleteConfirmationDialog from '../DeleteConfirmationDialog';
10
+ import { useQueryClient } from '@tanstack/react-query';
11
+ import usersTranslations from '../../lang/users';
12
+ import AddItemDialog from '../AddItemDialog';
13
+ import { useGroups } from '../../utils/hooks/groups';
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 config = useConfig();
23
+ const apiClient = useAPI(config.generalProperties.apiURL);
24
+ const queryClient = useQueryClient();
25
+ const { data: groups } = useGroups(apiClient);
26
+ const { data: userGroups } = useUserGroups(user?.id, apiClient);
27
+ const { mutate: addUserToGroup } = useAddUserToGroup(queryClient, apiClient);
28
+ const { mutate: removeUserFromGroup } = useRemoveUserFromGroup(queryClient, apiClient);
29
+ const [openAddGroupDialog, setOpenAddGroupDialog] = useState(false);
30
+ const [openConfirmationDialog, setOpenConfirmationDialog] = useState(false);
31
+ const [deleteId, setDeleteId] = useState();
32
+ return (React.createElement(React.Fragment, null,
33
+ userGroups && userGroups.length > 0 && (React.createElement(Box, { maxWidth: 'sm' },
34
+ React.createElement(TableContainer, null,
35
+ React.createElement(Table, { size: 'small' },
36
+ React.createElement(TableHead, null,
37
+ React.createElement(TableRow, null,
38
+ userGroupsTableColumns.map((col) => (React.createElement(TableCell, { key: col.id, align: col.align || 'inherit' }, isStringTranslation(col.label)
39
+ ? col.label[locale]
40
+ : col.label))),
41
+ React.createElement(TableCell, { padding: 'none' }, ''))),
42
+ React.createElement(TableBody, null, userGroups?.map((group, rowIdx) => (React.createElement(TableRow, { key: rowIdx },
43
+ React.createElement(TableCell, null, group.name),
44
+ React.createElement(TableCell, { padding: 'none', align: 'right' },
45
+ React.createElement(IconButton, { size: 'small', onClick: (evt) => {
46
+ evt.stopPropagation();
47
+ setOpenConfirmationDialog(true);
48
+ setDeleteId(group.id);
49
+ } },
50
+ React.createElement(DeleteIcon, null))))))))))),
51
+ React.createElement(Button, { variant: 'outlined', startIcon: React.createElement(AddIcon, null), onClick: () => setOpenAddGroupDialog(true), sx: { marginTop: 2 } }, usersTranslations.addGroup[locale]),
52
+ React.createElement(AddItemDialog, { open: openAddGroupDialog, onClose: () => setOpenAddGroupDialog(false), onConfirm: (value) => {
53
+ if (value) {
54
+ addUserToGroup({ userId: user.id, groupId: value?.value });
55
+ }
56
+ }, title: usersTranslations.addGroup, options: groups?.map((group) => ({
57
+ value: group.id,
58
+ label: group.name,
59
+ })) }),
60
+ React.createElement(DeleteConfirmationDialog, { open: openConfirmationDialog, onClose: () => setOpenConfirmationDialog(false), onConfirm: () => deleteId
61
+ ? removeUserFromGroup({ userId: user.id, groupId: deleteId })
62
+ : {} })));
63
+ };
64
+ export default UserGroups;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { UserTab } from './UsersTabs';
3
+ interface UsersProps {
4
+ apiUrl: string;
5
+ additionalTabs?: UserTab[];
6
+ }
7
+ declare const Users: ({ apiUrl, additionalTabs }: UsersProps) => React.JSX.Element;
8
+ export default Users;
9
+ //# sourceMappingURL=Users.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,84 @@
1
+ 'use client';
2
+ import React, { useEffect, useState } from 'react';
3
+ import PersonAddIcon from '@mui/icons-material/PersonAdd';
4
+ import { Box, Button, Grid, IconButton, Link } from '@mui/material';
5
+ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
6
+ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
7
+ import { useAPI, useLocale } from '@deix/rossini-core';
8
+ import { useQueryClient } from '@tanstack/react-query';
9
+ import { SearchField } from '../../components';
10
+ import CreateUserDialog from './CreateUserDialog';
11
+ import UsersTable from './UsersTable';
12
+ import usersTranslations from '../../lang/users';
13
+ import { useDeleteUser, useUsers } from '../../utils/hooks/users';
14
+ import UserTabs from './UsersTabs';
15
+ const Users = ({ apiUrl, additionalTabs = [] }) => {
16
+ const locale = useLocale();
17
+ const apiClient = useAPI(apiUrl);
18
+ const queryClient = useQueryClient();
19
+ const { data: users } = useUsers(apiClient);
20
+ const { mutate: deleteUser } = useDeleteUser(queryClient, apiClient);
21
+ const [searchString, setSearchString] = useState('');
22
+ const [filteredUsers, setFilteredUsers] = useState();
23
+ const [selectedUser, setSelectedUser] = useState();
24
+ const [openCreateUserDialog, setOpenCreateUserDialog] = useState(false);
25
+ useEffect(() => {
26
+ if (users && searchString === '') {
27
+ setFilteredUsers(users);
28
+ }
29
+ else if (users && searchString !== '') {
30
+ setFilteredUsers(users.filter((user) => user.username?.toLowerCase().includes(searchString.toLowerCase()) ||
31
+ user.firstName
32
+ ?.toLowerCase()
33
+ .includes(searchString.toLowerCase()) ||
34
+ user.lastName
35
+ ?.toLocaleLowerCase()
36
+ .includes(searchString.toLowerCase())));
37
+ }
38
+ }, [searchString, users, setFilteredUsers]);
39
+ const handleDelete = (id) => {
40
+ deleteUser(id);
41
+ setSelectedUser(undefined);
42
+ };
43
+ return (React.createElement(Box, { sx: {
44
+ flexGrow: 1,
45
+ maxWidth: '100%',
46
+ overflowX: 'hidden',
47
+ paddingTop: 3,
48
+ paddingLeft: 3,
49
+ 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: {
64
+ display: 'flex',
65
+ flexDirection: 'column',
66
+ alignItems: 'flex-start',
67
+ 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
+ } })));
83
+ };
84
+ export default Users;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { Group } from '../../types/groups';
3
+ import { User } from '../../types/users';
4
+ export interface TableProps {
5
+ users?: User[];
6
+ groups?: Group[];
7
+ selectedUser?: User;
8
+ setSelectedUser: (user: User) => void;
9
+ onDelete: (id: string) => void;
10
+ }
11
+ declare const UsersTable: ({ users, selectedUser, setSelectedUser, onDelete, }: TableProps) => React.JSX.Element;
12
+ export default UsersTable;
13
+ //# sourceMappingURL=UsersTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsersTable.d.ts","sourceRoot":"","sources":["../../../src/components/users/UsersTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAiB1B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAuBzC,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,QAAA,MAAM,UAAU,wDAKb,UAAU,sBAoEZ,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,62 @@
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 (React.createElement(React.Fragment, null,
34
+ React.createElement(TableContainer, null,
35
+ React.createElement(Table, { size: 'small' },
36
+ React.createElement(TableHead, null,
37
+ React.createElement(TableRow, null,
38
+ usersTableColumns.map((col) => (React.createElement(TableCell, { key: col.id, align: col.align || 'inherit' }, isStringTranslation(col.label)
39
+ ? col.label[locale]
40
+ : col.label))),
41
+ React.createElement(TableCell, { padding: 'none' }, ''))),
42
+ React.createElement(TableBody, null, users.map((user, rowIdx) => (React.createElement(TableRow, { key: rowIdx, onClick: () => setSelectedUser(user), sx: {
43
+ cursor: 'pointer',
44
+ background: selectedUser && user.id === selectedUser.id
45
+ ? muiTheme.palette.primary.light
46
+ : undefined,
47
+ } },
48
+ React.createElement(TableCell, null, user.firstName),
49
+ React.createElement(TableCell, null, user.lastName),
50
+ React.createElement(TableCell, null, user.username),
51
+ React.createElement(TableCell, null, user.email),
52
+ React.createElement(TableCell, null, user.enabled ? React.createElement(CheckIcon, null) : React.createElement(CloseIcon, null)),
53
+ React.createElement(TableCell, { padding: 'none', align: 'right' },
54
+ React.createElement(IconButton, { size: 'small', onClick: (evt) => {
55
+ evt.stopPropagation();
56
+ setOpenConfirmationDialog(true);
57
+ setDeleteId(user.id);
58
+ } },
59
+ React.createElement(DeleteIcon, null))))))))),
60
+ React.createElement(DeleteConfirmationDialog, { open: openConfirmationDialog, onClose: () => setOpenConfirmationDialog(false), onConfirm: () => (deleteId ? onDelete(deleteId) : {}) })));
61
+ };
62
+ export default UsersTable;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { StringTranslation } from '@deix/rossini-core';
3
+ import { User } from '../../types/users';
4
+ export interface UserTab {
5
+ title: StringTranslation;
6
+ component: React.FunctionComponent<{
7
+ user: User;
8
+ }>;
9
+ }
10
+ export interface UserTabsProps {
11
+ user: User;
12
+ additionalTabs?: UserTab[];
13
+ }
14
+ declare const UserTabs: ({ user, additionalTabs }: UserTabsProps) => React.JSX.Element;
15
+ export default UserTabs;
16
+ //# sourceMappingURL=UsersTabs.d.ts.map
@@ -0,0 +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"}