@fluxo-dev/shell 0.0.8
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/.babelrc +12 -0
- package/.eslintrc.json +18 -0
- package/README.md +7 -0
- package/jest.config.ts +11 -0
- package/package.json +4 -0
- package/project.json +43 -0
- package/src/index.ts +1 -0
- package/src/lib/app.module.css +1 -0
- package/src/lib/app.spec.tsx +17 -0
- package/src/lib/app.tsx +374 -0
- package/src/lib/components/error-page/404.tsx +16 -0
- package/src/lib/components/routes/main-routes.tsx +26 -0
- package/src/lib/layouts/blank/blank-layout.tsx +10 -0
- package/src/lib/layouts/main/app-bar.tsx +192 -0
- package/src/lib/layouts/main/app-layout.tsx +52 -0
- package/src/lib/layouts/main/content.tsx +10 -0
- package/src/lib/layouts/main/footer-bar.tsx +76 -0
- package/src/lib/layouts/main/navbar-item.module.css +49 -0
- package/src/lib/layouts/main/navbar-item.tsx +129 -0
- package/src/lib/layouts/main/navbar.tsx +38 -0
- package/src/lib/layouts/main/search-bar.tsx +44 -0
- package/src/lib/layouts/main/shell-spotlight.tsx +58 -0
- package/src/lib/models/app-jit.ts +6 -0
- package/src/lib/pages/general/fluxo-plugin-loader.tsx +22 -0
- package/src/lib/pages/login/account-confirmation.tsx +86 -0
- package/src/lib/pages/login/change-password.tsx +58 -0
- package/src/lib/pages/login/forgot-password.tsx +53 -0
- package/src/lib/pages/login/login-page.tsx +70 -0
- package/src/lib/pages/login/reset-password.tsx +91 -0
- package/src/lib/pages/settings/apps/add-jit-app.tsx +79 -0
- package/src/lib/pages/settings/apps/app-item.tsx +157 -0
- package/src/lib/pages/settings/apps/app-jit-item.tsx +105 -0
- package/src/lib/pages/settings/apps/apps-list.tsx +171 -0
- package/src/lib/pages/settings/apps/embedded-module-item.tsx +66 -0
- package/src/lib/pages/settings/apps/install-or-upgrade-app.tsx +105 -0
- package/src/lib/pages/settings/menu-designer/custom-node.module.css +34 -0
- package/src/lib/pages/settings/menu-designer/custom-node.tsx +160 -0
- package/src/lib/pages/settings/menu-designer/menu-create-form.tsx +109 -0
- package/src/lib/pages/settings/menu-designer/menu-designer.module.css +19 -0
- package/src/lib/pages/settings/menu-designer/menu-designer.tsx +463 -0
- package/src/lib/pages/settings/menu-designer/menu-item-edit.tsx +115 -0
- package/src/lib/pages/settings/menu-designer/placeholder.module.css +8 -0
- package/src/lib/pages/settings/menu-designer/placeholder.tsx +13 -0
- package/src/lib/pages/settings/security/components/domani-role/domain-role-form.tsx +67 -0
- package/src/lib/pages/settings/security/components/domani-role/domain-role-grid.tsx +139 -0
- package/src/lib/pages/settings/security/components/permission/create-custom-permission-form.tsx +64 -0
- package/src/lib/pages/settings/security/components/permission/create-scope-form.tsx +158 -0
- package/src/lib/pages/settings/security/components/permission/permission-grid.tsx +304 -0
- package/src/lib/pages/settings/security/components/permission/permission-navigator.tsx +320 -0
- package/src/lib/pages/settings/security/components/permission/update-permission.tsx +54 -0
- package/src/lib/pages/settings/security/components/route-rule/route-rule-create-form.tsx +59 -0
- package/src/lib/pages/settings/security/components/route-rule/route-rule-grid.tsx +229 -0
- package/src/lib/pages/settings/security/components/user/user-form.tsx +123 -0
- package/src/lib/pages/settings/security/components/user/users-grid.tsx +127 -0
- package/src/lib/pages/settings/settings.tsx +298 -0
- package/src/lib/pages/settings/token/token-row.tsx +69 -0
- package/src/lib/pages/settings/token/tokens.tsx +73 -0
- package/src/lib/pages/settings/ui/ui.tsx +149 -0
- package/src/lib/services/app-jit-manager.ts +92 -0
- package/src/lib/services/app-menu.service.ts +35 -0
- package/src/lib/utils/icon-factory.tsx +25 -0
- package/src/lib/utils/security/only-not-logged-route.tsx +17 -0
- package/src/lib/utils/security/protected-route.tsx +47 -0
- package/tsconfig.json +20 -0
- package/tsconfig.lib.json +24 -0
- package/tsconfig.spec.json +20 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ActionIcon,
|
|
3
|
+
Badge,
|
|
4
|
+
Button,
|
|
5
|
+
Center,
|
|
6
|
+
Divider,
|
|
7
|
+
Grid,
|
|
8
|
+
Group,
|
|
9
|
+
Loader,
|
|
10
|
+
Modal,
|
|
11
|
+
Select,
|
|
12
|
+
Stack,
|
|
13
|
+
Table,
|
|
14
|
+
Text
|
|
15
|
+
} from "@mantine/core";
|
|
16
|
+
import React, {useEffect, useState} from "react";
|
|
17
|
+
import {UpdatePermission} from "./update-permission";
|
|
18
|
+
import {FluxoClientSys, Permission, PermissionScope} from "@fluxo-dev/api-client-base";
|
|
19
|
+
import {IconArrowDown, IconCloudOff, IconPlus, IconRefresh, IconTrash} from '@tabler/icons-react';
|
|
20
|
+
import {DataCard, WaitData} from "@fluxo-dev/ui-components";
|
|
21
|
+
import {CreateScopeForm} from "./create-scope-form";
|
|
22
|
+
import {CreateCustomPermissionForm} from "./create-custom-permission-form";
|
|
23
|
+
import {showNotification} from "@mantine/notifications";
|
|
24
|
+
|
|
25
|
+
export function PermissionGrid() {
|
|
26
|
+
|
|
27
|
+
const [permissions, setPermissions] = useState<Permission[]>([]);
|
|
28
|
+
const [updatePermissionModal, setUpdatePermissionModal] = useState<boolean>(false);
|
|
29
|
+
|
|
30
|
+
const [permissionScopes, setPermissionScopes] = useState<PermissionScope[]>([]);
|
|
31
|
+
const [permissionScopesLoaded, setPermissionScopesLoaded] = useState<boolean>(false);
|
|
32
|
+
|
|
33
|
+
const [currentScope, setCurrentScope] = useState<string | null>(null);
|
|
34
|
+
const [currentPackageName, setCurrentPackageName] = useState<string | null>(null);
|
|
35
|
+
const [currentNamespace, setCurrentNamespace] = useState<string | null>(null);
|
|
36
|
+
const [permissionLoading, setPermissionLoading] = useState<boolean>(false);
|
|
37
|
+
|
|
38
|
+
const [createPermissionScopeModalOpened, setCreatePermissionScopeModalOpened] = useState<boolean>(false);
|
|
39
|
+
const [createCustomPermissionModalOpened, setCreateCustomPermissionModalOpened] = useState<boolean>(false);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
loadPermissionScopes();
|
|
43
|
+
}, [])
|
|
44
|
+
|
|
45
|
+
const loadPermissionScopes = () => {
|
|
46
|
+
FluxoClientSys.Instance.security.permission.getPermissionScopes()
|
|
47
|
+
.then((res) => {
|
|
48
|
+
setPermissionScopes(res);
|
|
49
|
+
setPermissionScopesLoaded(true);
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if(currentScope && currentPackageName && currentNamespace)
|
|
55
|
+
getPermissionInScope();
|
|
56
|
+
else
|
|
57
|
+
setPermissions([]);
|
|
58
|
+
}, [currentScope, currentPackageName, currentNamespace]);
|
|
59
|
+
|
|
60
|
+
const getPermissionInScope = () => {
|
|
61
|
+
|
|
62
|
+
if(!currentScope || !currentPackageName || !currentNamespace) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
setPermissionLoading(true);
|
|
67
|
+
|
|
68
|
+
FluxoClientSys.Instance.security.permission.getPermissionsInScope(currentScope, currentPackageName, currentNamespace)
|
|
69
|
+
.then((res) => {
|
|
70
|
+
setPermissions(res);
|
|
71
|
+
setPermissionLoading(false);
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const deleteCustomPermission = (permissionId: number) => {
|
|
76
|
+
FluxoClientSys.Instance.security.permission.deleteCustomPermission(permissionId)
|
|
77
|
+
.then(() => {
|
|
78
|
+
showNotification({
|
|
79
|
+
title: 'Operazione completata',
|
|
80
|
+
message: 'Il permesso è stato eliminato con successo',
|
|
81
|
+
color: 'green',
|
|
82
|
+
})
|
|
83
|
+
getPermissionInScope();
|
|
84
|
+
})
|
|
85
|
+
.catch(() => {
|
|
86
|
+
showNotification({
|
|
87
|
+
title: 'Operazione fallita',
|
|
88
|
+
message: 'Non è stato possibile eliminare il permesso',
|
|
89
|
+
color: 'red',
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const deletePermissionScope = () => {
|
|
95
|
+
|
|
96
|
+
if(!currentScope || !currentPackageName || !currentNamespace) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
FluxoClientSys.Instance.security.permission.deletePermissionScope(currentScope, currentPackageName, currentNamespace)
|
|
101
|
+
.then(() => {
|
|
102
|
+
showNotification({
|
|
103
|
+
title: 'Operazione completata',
|
|
104
|
+
message: 'Lo scope è stato eliminato con successo',
|
|
105
|
+
color: 'green',
|
|
106
|
+
})
|
|
107
|
+
setCurrentScope(null);
|
|
108
|
+
setCurrentPackageName(null);
|
|
109
|
+
setCurrentNamespace(null);
|
|
110
|
+
setPermissions([]);
|
|
111
|
+
loadPermissionScopes();
|
|
112
|
+
})
|
|
113
|
+
.catch(() => {
|
|
114
|
+
showNotification({
|
|
115
|
+
title: 'Operazione fallita',
|
|
116
|
+
message: 'Non è stato possibile eliminare lo scope',
|
|
117
|
+
color: 'red',
|
|
118
|
+
})
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const getScopes = () => {
|
|
123
|
+
if(permissionScopes === undefined) return [];
|
|
124
|
+
return [...new Set(permissionScopes.map(a => a.scope))];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const getPackageNames = (scope: string | null) => {
|
|
128
|
+
if(permissionScopes === undefined || !scope) return [];
|
|
129
|
+
return [...new Set(permissionScopes.filter(a => a.scope === scope).map(a => a.packageName))];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const getNamespaces = (scope: string | null, packageName: string | null) => {
|
|
133
|
+
if(permissionScopes === undefined || !scope || !packageName) return [];
|
|
134
|
+
return [...new Set(permissionScopes.filter(a => a.scope === scope && a.packageName === packageName).map(a => a.namespace))];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<DataCard title={'Permessi'}
|
|
139
|
+
actions={[
|
|
140
|
+
{
|
|
141
|
+
icon: <IconArrowDown size={18}/>,
|
|
142
|
+
label: 'Installa permessi',
|
|
143
|
+
onClick: () => {
|
|
144
|
+
setUpdatePermissionModal(true)
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
icon: <IconPlus size={18}/>,
|
|
149
|
+
label: 'Crea nuovo scope',
|
|
150
|
+
onClick: () => {
|
|
151
|
+
setCreatePermissionScopeModalOpened(true)
|
|
152
|
+
}
|
|
153
|
+
}]}>
|
|
154
|
+
|
|
155
|
+
<Stack>
|
|
156
|
+
<Grid>
|
|
157
|
+
<Grid.Col span={4}>
|
|
158
|
+
<Select
|
|
159
|
+
data={getScopes()}
|
|
160
|
+
searchable
|
|
161
|
+
placeholder={'Seleziona uno scope'}
|
|
162
|
+
value={currentScope}
|
|
163
|
+
label={'Scope'}
|
|
164
|
+
onChange={(v) => {
|
|
165
|
+
setCurrentScope(v)
|
|
166
|
+
setCurrentPackageName(null);
|
|
167
|
+
setCurrentNamespace(null);
|
|
168
|
+
}} />
|
|
169
|
+
</Grid.Col>
|
|
170
|
+
<Grid.Col span={4}>
|
|
171
|
+
<Select
|
|
172
|
+
disabled={!currentScope}
|
|
173
|
+
searchable
|
|
174
|
+
placeholder={'Seleziona un package name'}
|
|
175
|
+
data={getPackageNames(currentScope)}
|
|
176
|
+
value={currentPackageName}
|
|
177
|
+
label={'Package name'}
|
|
178
|
+
onChange={(v) => {
|
|
179
|
+
setCurrentPackageName(v)
|
|
180
|
+
setCurrentNamespace(null);
|
|
181
|
+
}} />
|
|
182
|
+
</Grid.Col>
|
|
183
|
+
<Grid.Col span={4}>
|
|
184
|
+
<Select
|
|
185
|
+
disabled={!currentPackageName}
|
|
186
|
+
searchable
|
|
187
|
+
placeholder={'Seleziona un namespace'}
|
|
188
|
+
data={getNamespaces(currentScope, currentPackageName)}
|
|
189
|
+
value={currentNamespace}
|
|
190
|
+
label={'Namespace'}
|
|
191
|
+
onChange={(v) => {
|
|
192
|
+
setCurrentNamespace(v)
|
|
193
|
+
}} />
|
|
194
|
+
</Grid.Col>
|
|
195
|
+
</Grid>
|
|
196
|
+
|
|
197
|
+
<Divider />
|
|
198
|
+
|
|
199
|
+
{permissionLoading &&
|
|
200
|
+
<Loader />
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
{(currentScope && currentPackageName && currentNamespace && !permissionLoading && permissions.length) === 0 &&
|
|
204
|
+
<Stack>
|
|
205
|
+
<Group justify={'right'} align={'center'}>
|
|
206
|
+
<Button color={'red'} disabled={permissions.length > 0} onClick={deletePermissionScope} leftSection={<IconTrash size={18}/>}>Elimina scope</Button>
|
|
207
|
+
<Button leftSection={<IconPlus size={18}/>} onClick={() => setCreateCustomPermissionModalOpened(true)}>Crea permesso custom</Button>
|
|
208
|
+
</Group>
|
|
209
|
+
<Center>
|
|
210
|
+
<Text size={'md'}>Nessun permesso esistente.</Text>
|
|
211
|
+
</Center>
|
|
212
|
+
</Stack>
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
{(!currentScope || !currentPackageName || !currentNamespace) &&
|
|
216
|
+
<Stack align={'center'} mt={32} mb={32}>
|
|
217
|
+
<IconCloudOff color={'gray'} size={64} />
|
|
218
|
+
<Center>
|
|
219
|
+
<Text size={'md'}>Seleziona uno scope, un package name e un namespace per visualizzare i permessi associati.</Text>
|
|
220
|
+
</Center>
|
|
221
|
+
</Stack>
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
{!permissionLoading && permissions.length > 0 &&
|
|
225
|
+
<Stack>
|
|
226
|
+
<Group justify={'right'} align={'center'}>
|
|
227
|
+
<Button disabled={permissions.length > 0} leftSection={<IconTrash size={18}/>}>Elimina scope</Button>
|
|
228
|
+
<Button leftSection={<IconPlus size={18}/>} onClick={() => setCreateCustomPermissionModalOpened(true)}>Crea permesso custom</Button>
|
|
229
|
+
</Group>
|
|
230
|
+
<Table highlightOnHover>
|
|
231
|
+
<Table.Thead>
|
|
232
|
+
<Table.Tr>
|
|
233
|
+
<Table.Th>Id</Table.Th>
|
|
234
|
+
<Table.Th>Scope</Table.Th>
|
|
235
|
+
<Table.Th>Identificatore</Table.Th>
|
|
236
|
+
<Table.Th>Descrizione</Table.Th>
|
|
237
|
+
<Table.Th style={{maxWidth: 130, width: 130}}>Personalizzato</Table.Th>
|
|
238
|
+
<Table.Th style={{maxWidth: 80, width: 80}}>Azioni</Table.Th>
|
|
239
|
+
</Table.Tr>
|
|
240
|
+
</Table.Thead>
|
|
241
|
+
<tbody>
|
|
242
|
+
{permissions.map((element, i) => {
|
|
243
|
+
return (
|
|
244
|
+
<Table.Tr key={i}>
|
|
245
|
+
<Table.Td>{element.id}</Table.Td>
|
|
246
|
+
<Table.Td>{`${element.scope}.${element.packageName}.${element.namespace}`}</Table.Td>
|
|
247
|
+
<Table.Td>{element.identifier}</Table.Td>
|
|
248
|
+
<Table.Td>{element.description}</Table.Td>
|
|
249
|
+
<Table.Td style={{maxWidth: 130, width: 130}}>
|
|
250
|
+
{element.isCustom ?
|
|
251
|
+
<Badge w={'100%'} color={'green'}>Si</Badge> :
|
|
252
|
+
<Badge w={'100%'} color={'red'}>No</Badge>
|
|
253
|
+
}
|
|
254
|
+
</Table.Td>
|
|
255
|
+
<Table.Td style={{maxWidth: 130, width: 130}}>
|
|
256
|
+
<ActionIcon
|
|
257
|
+
onClick={() => deleteCustomPermission(element.id)}
|
|
258
|
+
disabled={!element.isCustom}>
|
|
259
|
+
<IconTrash size={18} />
|
|
260
|
+
</ActionIcon>
|
|
261
|
+
</Table.Td>
|
|
262
|
+
</Table.Tr>
|
|
263
|
+
)
|
|
264
|
+
})}
|
|
265
|
+
</tbody>
|
|
266
|
+
</Table>
|
|
267
|
+
</Stack>
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
<Modal centered opened={updatePermissionModal} onClose={() => {
|
|
273
|
+
setUpdatePermissionModal(false);
|
|
274
|
+
}} title="Aggiorna permessi">
|
|
275
|
+
<UpdatePermission onUpdated={() => {
|
|
276
|
+
setUpdatePermissionModal(false)
|
|
277
|
+
}} onCanceled={() => setUpdatePermissionModal(false)} />
|
|
278
|
+
</Modal>
|
|
279
|
+
|
|
280
|
+
<Modal centered opened={createPermissionScopeModalOpened} onClose={() => {
|
|
281
|
+
setCreatePermissionScopeModalOpened(false);
|
|
282
|
+
}} title="Crea nuovo scope">
|
|
283
|
+
<CreateScopeForm
|
|
284
|
+
permissionScopes={permissionScopes}
|
|
285
|
+
onCreated={() => { setCreatePermissionScopeModalOpened(false); loadPermissionScopes() }}
|
|
286
|
+
onCanceled={() => {setCreatePermissionScopeModalOpened(false)}}
|
|
287
|
+
/>
|
|
288
|
+
</Modal>
|
|
289
|
+
|
|
290
|
+
<Modal centered opened={createCustomPermissionModalOpened} onClose={() => {
|
|
291
|
+
setCreatePermissionScopeModalOpened(false);
|
|
292
|
+
}} title="Crea nuovo permesso custom">
|
|
293
|
+
<CreateCustomPermissionForm
|
|
294
|
+
permissionScope={permissionScopes.filter(a => a.scope === currentScope && a.packageName === currentPackageName && a.namespace === currentNamespace)[0]}
|
|
295
|
+
onCreated={() => {setCreateCustomPermissionModalOpened(false); getPermissionInScope()}}
|
|
296
|
+
onCanceled={() => {setCreateCustomPermissionModalOpened(false)}}
|
|
297
|
+
/>
|
|
298
|
+
</Modal>
|
|
299
|
+
|
|
300
|
+
</Stack>
|
|
301
|
+
|
|
302
|
+
</DataCard>
|
|
303
|
+
)
|
|
304
|
+
}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import React, {useEffect, useState} from "react";
|
|
2
|
+
import {
|
|
3
|
+
FluxoClientSys,
|
|
4
|
+
Permission, PermissionScope
|
|
5
|
+
} from "@fluxo-dev/api-client-base";
|
|
6
|
+
import {Badge, Checkbox, Grid, Group, Loader, NavLink, ScrollArea, Stack, Text, TextInput} from "@mantine/core";
|
|
7
|
+
import {IconSearch} from '@tabler/icons-react';
|
|
8
|
+
import {NoData} from "@fluxo-dev/ui-components";
|
|
9
|
+
import {showNotification} from "@mantine/notifications";
|
|
10
|
+
|
|
11
|
+
export interface PermissionNavigatorProps {
|
|
12
|
+
context: {type: 'domainRole' | 'menu' | 'route-rule', id: string};
|
|
13
|
+
onUpdate: (currentPermissionCount: number) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function PermissionNavigator(props: PermissionNavigatorProps) {
|
|
17
|
+
|
|
18
|
+
const [structuredPermissions, setStructuredPermissions] = useState<PermissionScope[]>();
|
|
19
|
+
const [domainRolePermissions, setDomainRolePermissions] = useState<Permission[]>([]);
|
|
20
|
+
|
|
21
|
+
const [structuredPermissionLoaded, setStructuredPermissionLoaded] = useState<boolean>(false);
|
|
22
|
+
const [domainRolePermissionLoaded, setDomainRolePermissionLoaded] = useState<boolean>(false);
|
|
23
|
+
|
|
24
|
+
//const [currentPackageName, setCurrentPackageName] = useState<StructuredPermissionsPackageName>();
|
|
25
|
+
|
|
26
|
+
const [selectedPermissionsIds, setSelectedPermissionsIds] = useState<number[]>([]);
|
|
27
|
+
|
|
28
|
+
const [currentScope, setCurrentScope] = useState<string>();
|
|
29
|
+
const [currentPackageName, setCurrentPackageName] = useState<string>();
|
|
30
|
+
const [currentNamespace, setCurrentNamespace] = useState<string>();
|
|
31
|
+
|
|
32
|
+
const [currentPermissions, setCurrentPermissions] = useState<Permission[]>([]);
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
props.onUpdate(selectedPermissionsIds.length);
|
|
37
|
+
}, [selectedPermissionsIds])
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
FluxoClientSys.Instance.security.permission.getPermissionScopes()
|
|
41
|
+
.then((res) => {
|
|
42
|
+
setStructuredPermissions(res);
|
|
43
|
+
setStructuredPermissionLoaded(true);
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
if(props.context.type === 'domainRole') {
|
|
47
|
+
|
|
48
|
+
FluxoClientSys.Instance.security.domainRole.getPermissions(props.context.id)
|
|
49
|
+
.then((res) => {
|
|
50
|
+
setDomainRolePermissions(res);
|
|
51
|
+
setDomainRolePermissionLoaded(true);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
} else if(props.context.type === 'menu') {
|
|
55
|
+
|
|
56
|
+
FluxoClientSys.Instance.configuration.getMenuItemPermissions(props.context.id)
|
|
57
|
+
.then((res) => {
|
|
58
|
+
setDomainRolePermissions(res);
|
|
59
|
+
setDomainRolePermissionLoaded(true);
|
|
60
|
+
});
|
|
61
|
+
} else {
|
|
62
|
+
|
|
63
|
+
FluxoClientSys.Instance.security.routeRule.getPermissions(props.context.id)
|
|
64
|
+
.then((res) => {
|
|
65
|
+
setDomainRolePermissions(res);
|
|
66
|
+
setDomainRolePermissionLoaded(true);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}, [])
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if(structuredPermissionLoaded && domainRolePermissionLoaded) {
|
|
74
|
+
const initPermissions = [...domainRolePermissions.map((p) => p.id)];
|
|
75
|
+
setSelectedPermissionsIds(initPermissions);
|
|
76
|
+
}
|
|
77
|
+
}, [structuredPermissionLoaded, domainRolePermissionLoaded])
|
|
78
|
+
|
|
79
|
+
const addOrRemovePermission = (permissionId: number) => {
|
|
80
|
+
if(props.context.type === 'domainRole') {
|
|
81
|
+
addOrRemovePermissionForDomainRole(permissionId);
|
|
82
|
+
} else if(props.context.type === 'menu') {
|
|
83
|
+
addOrRemovePermissionForMenu(permissionId);
|
|
84
|
+
} else if(props.context.type === 'route-rule') {
|
|
85
|
+
addOrRemovePermissionForRouteRule(permissionId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const addOrRemovePermissionForRouteRule = (menuItemId: number) => {
|
|
90
|
+
if(selectedPermissionsIds.includes(menuItemId)) {
|
|
91
|
+
|
|
92
|
+
FluxoClientSys.Instance.security.routeRule.removePermission(+props.context.id, menuItemId)
|
|
93
|
+
.then((res) => {
|
|
94
|
+
setSelectedPermissionsIds(selectedPermissionsIds.filter((p) => p !== menuItemId));
|
|
95
|
+
showNotification({
|
|
96
|
+
title: "Permesso rimosso",
|
|
97
|
+
message: "Il permesso è stato rimosso correttamente",
|
|
98
|
+
color: "green",
|
|
99
|
+
});
|
|
100
|
+
})
|
|
101
|
+
.catch((err) => {
|
|
102
|
+
showNotification({
|
|
103
|
+
title: "Errore",
|
|
104
|
+
message: "Si è verificato un errore durante la rimozione del permesso",
|
|
105
|
+
color: "red",
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
} else {
|
|
110
|
+
|
|
111
|
+
FluxoClientSys.Instance.security.routeRule.addPermission(+props.context.id, menuItemId)
|
|
112
|
+
.then((res) => {
|
|
113
|
+
setSelectedPermissionsIds([...selectedPermissionsIds, menuItemId]);
|
|
114
|
+
showNotification({
|
|
115
|
+
title: "Permesso aggiunto",
|
|
116
|
+
message: "Il permesso è stato aggiunto correttamente",
|
|
117
|
+
color: "green",
|
|
118
|
+
});
|
|
119
|
+
})
|
|
120
|
+
.catch((err) => {
|
|
121
|
+
showNotification({
|
|
122
|
+
title: "Errore",
|
|
123
|
+
message: "Si è verificato un errore durante l'aggiunta del permesso",
|
|
124
|
+
color: "red",
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const addOrRemovePermissionForMenu = (menuItemId: number) => {
|
|
130
|
+
if(selectedPermissionsIds.includes(menuItemId)) {
|
|
131
|
+
|
|
132
|
+
FluxoClientSys.Instance.configuration.removeMenuItemPermission(+props.context.id, menuItemId)
|
|
133
|
+
.then((res) => {
|
|
134
|
+
setSelectedPermissionsIds(selectedPermissionsIds.filter((p) => p !== menuItemId));
|
|
135
|
+
showNotification({
|
|
136
|
+
title: "Permesso rimosso",
|
|
137
|
+
message: "Il permesso è stato rimosso correttamente",
|
|
138
|
+
color: "green",
|
|
139
|
+
});
|
|
140
|
+
})
|
|
141
|
+
.catch((err) => {
|
|
142
|
+
showNotification({
|
|
143
|
+
title: "Errore",
|
|
144
|
+
message: "Si è verificato un errore durante la rimozione del permesso",
|
|
145
|
+
color: "red",
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
} else {
|
|
150
|
+
|
|
151
|
+
FluxoClientSys.Instance.configuration.addMenuItemPermission(+props.context.id, menuItemId)
|
|
152
|
+
.then((res) => {
|
|
153
|
+
setSelectedPermissionsIds([...selectedPermissionsIds, menuItemId]);
|
|
154
|
+
showNotification({
|
|
155
|
+
title: "Permesso aggiunto",
|
|
156
|
+
message: "Il permesso è stato aggiunto correttamente",
|
|
157
|
+
color: "green",
|
|
158
|
+
});
|
|
159
|
+
})
|
|
160
|
+
.catch((err) => {
|
|
161
|
+
showNotification({
|
|
162
|
+
title: "Errore",
|
|
163
|
+
message: "Si è verificato un errore durante l'aggiunta del permesso",
|
|
164
|
+
color: "red",
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const addOrRemovePermissionForDomainRole = (permissionId: number) => {
|
|
171
|
+
if(selectedPermissionsIds.includes(permissionId)) {
|
|
172
|
+
|
|
173
|
+
FluxoClientSys.Instance.security.domainRole.removePermission(+props.context.id, permissionId)
|
|
174
|
+
.then((res) => {
|
|
175
|
+
setSelectedPermissionsIds(selectedPermissionsIds.filter((p) => p !== permissionId));
|
|
176
|
+
showNotification({
|
|
177
|
+
title: "Permesso rimosso",
|
|
178
|
+
message: "Il permesso è stato rimosso correttamente",
|
|
179
|
+
color: "green",
|
|
180
|
+
});
|
|
181
|
+
})
|
|
182
|
+
.catch((err) => {
|
|
183
|
+
showNotification({
|
|
184
|
+
title: "Errore",
|
|
185
|
+
message: "Si è verificato un errore durante la rimozione del permesso",
|
|
186
|
+
color: "red",
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
} else {
|
|
191
|
+
|
|
192
|
+
FluxoClientSys.Instance.security.domainRole.addPermission(+props.context.id, permissionId)
|
|
193
|
+
.then((res) => {
|
|
194
|
+
setSelectedPermissionsIds([...selectedPermissionsIds, permissionId]);
|
|
195
|
+
showNotification({
|
|
196
|
+
title: "Permesso aggiunto",
|
|
197
|
+
message: "Il permesso è stato aggiunto correttamente",
|
|
198
|
+
color: "green",
|
|
199
|
+
});
|
|
200
|
+
})
|
|
201
|
+
.catch((err) => {
|
|
202
|
+
showNotification({
|
|
203
|
+
title: "Errore",
|
|
204
|
+
message: "Si è verificato un errore durante l'aggiunta del permesso",
|
|
205
|
+
color: "red",
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const getScopes = () => {
|
|
212
|
+
if(structuredPermissions === undefined) return [];
|
|
213
|
+
return [...new Set(structuredPermissions.map(a => a.scope))];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const getPackageNames = (scope: string) => {
|
|
217
|
+
if(structuredPermissions === undefined) return [];
|
|
218
|
+
return [...new Set(structuredPermissions.filter(a => a.scope === scope).map(a => a.packageName))];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const getNamespaces = (scope: string, packageName: string) => {
|
|
222
|
+
if(structuredPermissions === undefined) return [];
|
|
223
|
+
return [...new Set(structuredPermissions.filter(a => a.scope === scope && a.packageName === packageName).map(a => a.namespace))];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const getPermissions = (scope: string, packageName: string, namespace: string) => {
|
|
227
|
+
FluxoClientSys.Instance.security.permission.getPermissionsInScope(scope, packageName, namespace)
|
|
228
|
+
.then((res) => {
|
|
229
|
+
setCurrentPermissions(res);
|
|
230
|
+
})
|
|
231
|
+
.catch((err) => {
|
|
232
|
+
showNotification({
|
|
233
|
+
title: "Errore",
|
|
234
|
+
message: "Si è verificato un errore durante il caricamento dei permessi",
|
|
235
|
+
color: "red",
|
|
236
|
+
})
|
|
237
|
+
})
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
<>
|
|
242
|
+
{!(structuredPermissionLoaded && domainRolePermissionLoaded) ?
|
|
243
|
+
<Loader /> :
|
|
244
|
+
|
|
245
|
+
<Stack gap={8}>
|
|
246
|
+
|
|
247
|
+
<Grid h={480} m={0} mt={1}>
|
|
248
|
+
<Grid.Col span={4} p={0} style={{border: '1px solid #ececec', borderRight: 'none'}}>
|
|
249
|
+
|
|
250
|
+
<ScrollArea h={430}>
|
|
251
|
+
{getScopes().map((s) => {
|
|
252
|
+
return (
|
|
253
|
+
<NavLink key={s} label={s} leftSection={<Badge size="xs" variant="filled" color="yellow" w={16} h={16} p={0}>{99}</Badge>}>
|
|
254
|
+
<>
|
|
255
|
+
{getPackageNames(s).map((n) => {
|
|
256
|
+
return (
|
|
257
|
+
<NavLink
|
|
258
|
+
key={n}
|
|
259
|
+
label={n}
|
|
260
|
+
leftSection={<Badge size="xs" variant="filled" color="yellow" w={16} h={16} p={0}>{99}</Badge>}>
|
|
261
|
+
|
|
262
|
+
{getNamespaces(s, n).map((ns) => {
|
|
263
|
+
return (
|
|
264
|
+
<NavLink
|
|
265
|
+
key={ns}
|
|
266
|
+
label={ns}
|
|
267
|
+
onClick={() => {
|
|
268
|
+
setCurrentScope(s);
|
|
269
|
+
setCurrentPackageName(n);
|
|
270
|
+
setCurrentNamespace(ns);
|
|
271
|
+
getPermissions(s, n, ns)
|
|
272
|
+
}}
|
|
273
|
+
leftSection={<Badge size="xs" variant="filled" color="yellow" w={16} h={16} p={0}>{99}</Badge>} />
|
|
274
|
+
)
|
|
275
|
+
})}
|
|
276
|
+
|
|
277
|
+
</NavLink>
|
|
278
|
+
)
|
|
279
|
+
})}
|
|
280
|
+
</>
|
|
281
|
+
</NavLink>
|
|
282
|
+
)
|
|
283
|
+
})}
|
|
284
|
+
</ScrollArea>
|
|
285
|
+
</Grid.Col>
|
|
286
|
+
<Grid.Col h={480} span={8} p={0} style={{border: '1px solid #ececec'}}>
|
|
287
|
+
|
|
288
|
+
{(currentPackageName && currentScope && currentNamespace) ?
|
|
289
|
+
<>
|
|
290
|
+
<Group justify={'space-between'} style={{background: '#ececec', marginBottom: 8}}>
|
|
291
|
+
<Text size={'md'} p={8}>{`${currentScope}.${currentPackageName}.${currentNamespace}`}</Text>
|
|
292
|
+
<TextInput pr={8} leftSection={<IconSearch size={16} />} placeholder={'Cerca'} />
|
|
293
|
+
</Group>
|
|
294
|
+
<ScrollArea h={430}>
|
|
295
|
+
<Stack style={{width: '100%'}} p={8}>
|
|
296
|
+
{currentPermissions?.map((p) => {
|
|
297
|
+
return (
|
|
298
|
+
<Checkbox
|
|
299
|
+
key={p.id}
|
|
300
|
+
description={p.identifier}
|
|
301
|
+
label={!p.isCustom ? p.description : <>{p.description}<Badge ml={8}>Personalizzato</Badge></>}
|
|
302
|
+
onChange={() => addOrRemovePermission(p.id)}
|
|
303
|
+
checked={selectedPermissionsIds.includes(p.id)}
|
|
304
|
+
/>
|
|
305
|
+
)
|
|
306
|
+
})}
|
|
307
|
+
</Stack>
|
|
308
|
+
</ScrollArea>
|
|
309
|
+
</> :
|
|
310
|
+
<div style={{marginTop: 32}}>
|
|
311
|
+
<NoData message={'Seleziona un package'} />
|
|
312
|
+
</div>
|
|
313
|
+
}
|
|
314
|
+
</Grid.Col>
|
|
315
|
+
</Grid>
|
|
316
|
+
</Stack>
|
|
317
|
+
}
|
|
318
|
+
</>
|
|
319
|
+
)
|
|
320
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Button, Group, Stack, Textarea} from "@mantine/core";
|
|
3
|
+
import {FluxoClientSys, InstallPermissionCommand} from "@fluxo-dev/api-client-base";
|
|
4
|
+
import {showNotification} from "@mantine/notifications";
|
|
5
|
+
|
|
6
|
+
export interface UpdatePermissionProps {
|
|
7
|
+
onUpdated: () => void;
|
|
8
|
+
onCanceled: () => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function UpdatePermission(props: UpdatePermissionProps) {
|
|
12
|
+
|
|
13
|
+
const [permissionsJson, setPermissionsJson] = React.useState<string>('');
|
|
14
|
+
|
|
15
|
+
const updatePermissions = () => {
|
|
16
|
+
try{
|
|
17
|
+
const data = JSON.parse(permissionsJson) as InstallPermissionCommand;
|
|
18
|
+
|
|
19
|
+
FluxoClientSys.Instance.security.permission.installPermissions(data)
|
|
20
|
+
.then(() => {
|
|
21
|
+
|
|
22
|
+
showNotification({
|
|
23
|
+
title: 'Operazione completata',
|
|
24
|
+
color: 'green',
|
|
25
|
+
message: `I permessi sono stati aggiornati con successo`,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
props.onUpdated();
|
|
29
|
+
}, (err) => {
|
|
30
|
+
showNotification({
|
|
31
|
+
title: 'Operazione fallita',
|
|
32
|
+
color: 'red',
|
|
33
|
+
message: `Non è stato possibile aggiornare i permessi: ${err.message}`,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}catch (err) {
|
|
37
|
+
showNotification({
|
|
38
|
+
title: 'Operazione fallita',
|
|
39
|
+
color: 'red',
|
|
40
|
+
message: `Il file non è valido.`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Stack>
|
|
47
|
+
<Textarea minRows={20} value={permissionsJson} onChange={(v) => setPermissionsJson(v.target.value)} />
|
|
48
|
+
<Group justify={'right'}>
|
|
49
|
+
<Button onClick={props.onCanceled}>Annulla</Button>
|
|
50
|
+
<Button onClick={updatePermissions} disabled={!permissionsJson}>Aggiorna</Button>
|
|
51
|
+
</Group>
|
|
52
|
+
</Stack>
|
|
53
|
+
)
|
|
54
|
+
}
|