@fluxo-dev/shell 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/index.esm.css +115 -0
  2. package/index.esm.d.ts +1 -0
  3. package/index.esm.js +68195 -0
  4. package/package.json +4 -1
  5. package/src/index.d.ts +1 -0
  6. package/src/lib/app.d.ts +16 -0
  7. package/src/lib/components/error-page/404.d.ts +1 -0
  8. package/src/lib/components/routes/main-routes.d.ts +6 -0
  9. package/src/lib/layouts/blank/blank-layout.d.ts +2 -0
  10. package/src/lib/layouts/main/app-bar.d.ts +9 -0
  11. package/src/lib/layouts/main/app-layout.d.ts +5 -0
  12. package/src/lib/layouts/main/content.d.ts +2 -0
  13. package/src/lib/layouts/main/footer-bar.d.ts +5 -0
  14. package/src/lib/layouts/main/navbar-item.d.ts +12 -0
  15. package/src/lib/layouts/main/navbar.d.ts +1 -0
  16. package/src/lib/layouts/main/search-bar.d.ts +5 -0
  17. package/src/lib/layouts/main/shell-spotlight.d.ts +2 -0
  18. package/src/lib/models/app-jit.d.ts +5 -0
  19. package/src/lib/pages/general/fluxo-plugin-loader.d.ts +7 -0
  20. package/src/lib/pages/login/account-confirmation.d.ts +2 -0
  21. package/src/lib/pages/login/change-password.d.ts +2 -0
  22. package/src/lib/pages/login/forgot-password.d.ts +2 -0
  23. package/src/lib/pages/login/login-page.d.ts +2 -0
  24. package/src/lib/pages/login/reset-password.d.ts +2 -0
  25. package/src/lib/pages/settings/apps/add-jit-app.d.ts +5 -0
  26. package/src/lib/pages/settings/apps/app-item.d.ts +10 -0
  27. package/src/lib/pages/settings/apps/app-jit-item.d.ts +8 -0
  28. package/src/lib/pages/settings/apps/apps-list.d.ts +6 -0
  29. package/src/lib/pages/settings/apps/embedded-module-item.d.ts +10 -0
  30. package/src/lib/pages/settings/apps/install-or-upgrade-app.d.ts +6 -0
  31. package/src/lib/pages/settings/menu-designer/custom-node.d.ts +14 -0
  32. package/src/lib/pages/settings/menu-designer/menu-create-form.d.ts +5 -0
  33. package/src/lib/pages/settings/menu-designer/menu-designer.d.ts +1 -0
  34. package/src/lib/pages/settings/menu-designer/menu-item-edit.d.ts +8 -0
  35. package/src/lib/pages/settings/menu-designer/placeholder.d.ts +8 -0
  36. package/src/lib/pages/settings/security/components/domani-role/domain-role-form.d.ts +6 -0
  37. package/src/lib/pages/settings/security/components/domani-role/domain-role-grid.d.ts +1 -0
  38. package/src/lib/pages/settings/security/components/permission/create-custom-permission-form.d.ts +7 -0
  39. package/src/lib/pages/settings/security/components/permission/create-scope-form.d.ts +7 -0
  40. package/src/lib/pages/settings/security/components/permission/permission-grid.d.ts +1 -0
  41. package/src/lib/pages/settings/security/components/permission/permission-navigator.d.ts +8 -0
  42. package/src/lib/pages/settings/security/components/permission/update-permission.d.ts +5 -0
  43. package/src/lib/pages/settings/security/components/route-rule/route-rule-create-form.d.ts +7 -0
  44. package/src/lib/pages/settings/security/components/route-rule/route-rule-grid.d.ts +1 -0
  45. package/src/lib/pages/settings/security/components/user/user-form.d.ts +7 -0
  46. package/src/lib/pages/settings/security/components/user/users-grid.d.ts +1 -0
  47. package/src/lib/pages/settings/settings.d.ts +6 -0
  48. package/src/lib/pages/settings/token/token-row.d.ts +7 -0
  49. package/src/lib/pages/settings/token/tokens.d.ts +2 -0
  50. package/src/lib/pages/settings/ui/ui.d.ts +1 -0
  51. package/src/lib/services/app-jit-manager.d.ts +10 -0
  52. package/src/lib/services/app-menu.service.d.ts +5 -0
  53. package/src/lib/utils/icon-factory.d.ts +9 -0
  54. package/src/lib/utils/security/only-not-logged-route.d.ts +2 -0
  55. package/src/lib/utils/security/protected-route.d.ts +2 -0
  56. package/.babelrc +0 -12
  57. package/.eslintrc.json +0 -18
  58. package/jest.config.ts +0 -11
  59. package/project.json +0 -43
  60. package/src/index.ts +0 -1
  61. package/src/lib/app.module.css +0 -1
  62. package/src/lib/app.spec.tsx +0 -17
  63. package/src/lib/app.tsx +0 -374
  64. package/src/lib/components/error-page/404.tsx +0 -16
  65. package/src/lib/components/routes/main-routes.tsx +0 -26
  66. package/src/lib/layouts/blank/blank-layout.tsx +0 -10
  67. package/src/lib/layouts/main/app-bar.tsx +0 -192
  68. package/src/lib/layouts/main/app-layout.tsx +0 -52
  69. package/src/lib/layouts/main/content.tsx +0 -10
  70. package/src/lib/layouts/main/footer-bar.tsx +0 -76
  71. package/src/lib/layouts/main/navbar-item.module.css +0 -49
  72. package/src/lib/layouts/main/navbar-item.tsx +0 -129
  73. package/src/lib/layouts/main/navbar.tsx +0 -38
  74. package/src/lib/layouts/main/search-bar.tsx +0 -44
  75. package/src/lib/layouts/main/shell-spotlight.tsx +0 -58
  76. package/src/lib/models/app-jit.ts +0 -6
  77. package/src/lib/pages/general/fluxo-plugin-loader.tsx +0 -22
  78. package/src/lib/pages/login/account-confirmation.tsx +0 -86
  79. package/src/lib/pages/login/change-password.tsx +0 -58
  80. package/src/lib/pages/login/forgot-password.tsx +0 -53
  81. package/src/lib/pages/login/login-page.tsx +0 -70
  82. package/src/lib/pages/login/reset-password.tsx +0 -91
  83. package/src/lib/pages/settings/apps/add-jit-app.tsx +0 -79
  84. package/src/lib/pages/settings/apps/app-item.tsx +0 -157
  85. package/src/lib/pages/settings/apps/app-jit-item.tsx +0 -105
  86. package/src/lib/pages/settings/apps/apps-list.tsx +0 -171
  87. package/src/lib/pages/settings/apps/embedded-module-item.tsx +0 -66
  88. package/src/lib/pages/settings/apps/install-or-upgrade-app.tsx +0 -105
  89. package/src/lib/pages/settings/menu-designer/custom-node.module.css +0 -34
  90. package/src/lib/pages/settings/menu-designer/custom-node.tsx +0 -160
  91. package/src/lib/pages/settings/menu-designer/menu-create-form.tsx +0 -109
  92. package/src/lib/pages/settings/menu-designer/menu-designer.module.css +0 -19
  93. package/src/lib/pages/settings/menu-designer/menu-designer.tsx +0 -463
  94. package/src/lib/pages/settings/menu-designer/menu-item-edit.tsx +0 -115
  95. package/src/lib/pages/settings/menu-designer/placeholder.module.css +0 -8
  96. package/src/lib/pages/settings/menu-designer/placeholder.tsx +0 -13
  97. package/src/lib/pages/settings/security/components/domani-role/domain-role-form.tsx +0 -67
  98. package/src/lib/pages/settings/security/components/domani-role/domain-role-grid.tsx +0 -139
  99. package/src/lib/pages/settings/security/components/permission/create-custom-permission-form.tsx +0 -64
  100. package/src/lib/pages/settings/security/components/permission/create-scope-form.tsx +0 -158
  101. package/src/lib/pages/settings/security/components/permission/permission-grid.tsx +0 -304
  102. package/src/lib/pages/settings/security/components/permission/permission-navigator.tsx +0 -320
  103. package/src/lib/pages/settings/security/components/permission/update-permission.tsx +0 -54
  104. package/src/lib/pages/settings/security/components/route-rule/route-rule-create-form.tsx +0 -59
  105. package/src/lib/pages/settings/security/components/route-rule/route-rule-grid.tsx +0 -229
  106. package/src/lib/pages/settings/security/components/user/user-form.tsx +0 -123
  107. package/src/lib/pages/settings/security/components/user/users-grid.tsx +0 -127
  108. package/src/lib/pages/settings/settings.tsx +0 -298
  109. package/src/lib/pages/settings/token/token-row.tsx +0 -69
  110. package/src/lib/pages/settings/token/tokens.tsx +0 -73
  111. package/src/lib/pages/settings/ui/ui.tsx +0 -149
  112. package/src/lib/services/app-jit-manager.ts +0 -92
  113. package/src/lib/services/app-menu.service.ts +0 -35
  114. package/src/lib/utils/icon-factory.tsx +0 -25
  115. package/src/lib/utils/security/only-not-logged-route.tsx +0 -17
  116. package/src/lib/utils/security/protected-route.tsx +0 -47
  117. package/tsconfig.json +0 -20
  118. package/tsconfig.lib.json +0 -24
  119. package/tsconfig.spec.json +0 -20
@@ -1,463 +0,0 @@
1
- import React, {useEffect, useState} from "react";
2
- import {getBackendOptions, MultiBackend, NodeModel, Tree,} from "@minoru/react-dnd-treeview";
3
- import {DndProvider} from "react-dnd";
4
- import {DataCard} from "@fluxo-dev/ui-components";
5
- import {CustomNode} from "./custom-node";
6
- import {Placeholder} from "./placeholder";
7
- import styles from './menu-designer.module.css';
8
- import {
9
- IconApps,
10
- IconArrowDown,
11
- IconBoxModel,
12
- IconDeviceFloppy,
13
- IconFolderPlus,
14
- IconPlus,
15
- IconX
16
- } from '@tabler/icons-react';
17
- import {IFluxoRootState, useAppSelector} from "@fluxo-dev/state";
18
- import {AppMenu, AppMenuContextType, AppMenuItem, Feature, FeatureList, FluxoClientSys} from "@fluxo-dev/api-client-base";
19
- import {
20
- Button,
21
- Center,
22
- Chip,
23
- Divider,
24
- Grid,
25
- Group,
26
- Loader,
27
- LoadingOverlay,
28
- Modal,
29
- rem,
30
- Select,
31
- Stack
32
- } from "@mantine/core";
33
- import {MenuItemEdit} from "./menu-item-edit";
34
- import {showNotification} from "@mantine/notifications";
35
- import {useNavigate} from "react-router-dom";
36
- import {MenuCreateForm} from "./menu-create-form";
37
-
38
- export function MenuDesigner() {
39
-
40
- const [sysFeatures, setSysFeatures] = useState<FeatureList>();
41
- const [currentSelectedFeatures, setCurrentSelectedFeatures] = useState<Feature[]>();
42
- const [currentSelectedFeatureId, setCurrentSelectedFeatureId] = useState<string | undefined | null>();
43
- const [featureSearchValue, setFeatureSearchValue] = useState<string | undefined>();
44
- const [treeData, setTreeData] = useState<NodeModel<AppMenuItem>[]>([]);
45
- const [editMenuItemModalOpened, setEditMenuItemModalOpened] = useState<boolean>(false);
46
- const [editMenuItem, setEditMenuItem] = useState<AppMenuItem>();
47
- const [editNodeId, setEditNodeId] = useState<string | number>();
48
- const [loadData, setLoadData] = useState<boolean>(false);
49
- const [webMenu, setWebMenu] = useState<AppMenu[]>([]);
50
- const [currentWebMenu, setCurrentWebMenu] = useState<AppMenu | undefined>(undefined);
51
- const [currentWebMenuLoaded, setCurrentWebMenuLoaded] = useState<boolean>(false);
52
- const [showMenuCreateForm, setShowMenuCreateForm] = useState<boolean>(false);
53
-
54
- const [currentAppMenuItemsAreChanged, setCurrentAppMenuItemsAreChanged] = useState<boolean>(false);
55
-
56
- const handleDrop = (newTree: NodeModel<AppMenuItem>[]) => setTreeData(newTree);
57
-
58
- const {appMenu} = useAppSelector((state: IFluxoRootState) => state.layout);
59
- const navigation = useNavigate();
60
-
61
- useEffect(() => {
62
- //const result = generateMenuObjectFromMenu((appMenu as AppMenuItem[]));
63
- //setTreeData(result);
64
- }, [appMenu])
65
-
66
- useEffect(() => {
67
- loadAppMenuList();
68
- }, []);
69
-
70
- const loadAppMenuList = () => {
71
- FluxoClientSys.Instance.configuration.getAppMenuList()
72
- .then((r) => {
73
- setWebMenu(r);
74
- setCurrentWebMenu(r[0]);
75
- setCurrentWebMenuLoaded(true);
76
- })
77
- }
78
-
79
- useEffect(() => {
80
-
81
- if(currentWebMenu) {
82
- onWebMenuChanged(currentWebMenu.id);
83
- }
84
-
85
- }, [currentWebMenu]);
86
-
87
- useEffect(() => {
88
-
89
- if(treeData) {
90
- const r = generateMenuFromDesigner(treeData);
91
- }
92
-
93
- }, [treeData])
94
-
95
- useEffect(() => {
96
- FluxoClientSys.Instance.configuration.getSystemFeatures()
97
- .then((res) => {
98
- setSysFeatures(res);
99
- })
100
- }, [])
101
-
102
- const generateMenuFromDesigner = (nodes: NodeModel<AppMenuItem>[], parent: string | number | undefined = 'root'): AppMenuItem[] => {
103
-
104
- const res: AppMenuItem[] = [];
105
-
106
- nodes.filter(a => a.parent === parent).map((item) => {
107
-
108
- item.data!.children = generateMenuFromDesigner(nodes.filter(a => a.id !== item.id), item.id);
109
- res.push(item.data!);
110
-
111
- });
112
-
113
- return res;
114
- }
115
-
116
- const generateMenuObjectFromMenu = (menu: AppMenuItem[], parent: string | number | undefined = 'root'): NodeModel<AppMenuItem>[] => {
117
-
118
- const res: NodeModel<AppMenuItem>[] = [];
119
-
120
- menu.map((menuItem: AppMenuItem) => {
121
-
122
- const omit = (prop: string, { [prop]: _, ...rest }) => rest as AppMenuItem;
123
-
124
- const tmpId = getRandomIntInclusive(1000000,9999999);
125
- const obj: NodeModel<AppMenuItem> = {
126
- droppable: true,
127
- data: omit('children', menuItem),
128
- text: menuItem.label,
129
- id: tmpId,
130
- parent: parent,
131
- };
132
-
133
- res.push(obj)
134
-
135
- if(menuItem.children && menuItem.children.length > 0)
136
- res.push(...generateMenuObjectFromMenu(menuItem.children, tmpId))
137
-
138
- });
139
-
140
- return res;
141
- }
142
-
143
- function getRandomIntInclusive(min: number, max: number) {
144
- min = Math.ceil(min);
145
- max = Math.floor(max);
146
- return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
147
- }
148
-
149
- const addGroupToMenuHandler = () => {
150
-
151
- const tmpId = getRandomIntInclusive(1000000,9999999);
152
-
153
- const tData = [...treeData]
154
- tData?.push({
155
- id: tmpId,
156
- droppable: true,
157
- data: {icon: 'dashboard', featureIdentifier: '', children: [], label: 'Nuovo gruppo', routerLink: undefined, isGroup: true},
158
- parent: 'root',
159
- text: 'Nuovo gruppo',
160
- })
161
- setTreeData(tData);
162
- setCurrentAppMenuItemsAreChanged(true);
163
- }
164
-
165
- const addFeatureToMenuHandler = () => {
166
- const currentFeature = sysFeatures?.features.filter(a => a.identifier === currentSelectedFeatureId)[0];
167
-
168
- if(!currentFeature)
169
- return;
170
-
171
- const tmpId = getRandomIntInclusive(1000000,9999999);
172
-
173
- const menuItemLabel = currentFeature.identifier === 'webclient.routing.menugroup' ? 'Nuovo gruppo' : currentFeature.description;
174
-
175
- if(currentFeature) {
176
- const tData = [...treeData]
177
- tData?.push({
178
- id: tmpId,
179
- droppable: true,
180
- data: {
181
- icon: 'dashboard',
182
- featureIdentifier: currentFeature.identifier,
183
- children: [],
184
- label: menuItemLabel,
185
- routerLink: currentFeature.routerLink,
186
- isGroup: false,
187
- menuItemId: currentFeature.menuItemId,
188
- },
189
- parent: 'root',
190
- text: menuItemLabel,
191
- })
192
- setTreeData(tData);
193
- setCurrentAppMenuItemsAreChanged(true);
194
- }
195
- }
196
-
197
- const saveButtonHandler = () => {
198
-
199
- if(currentWebMenu === undefined)
200
- return;
201
-
202
- setLoadData(true);
203
- const result = generateAppMenuItem(treeData);
204
-
205
- FluxoClientSys.Instance.configuration.saveAppMenu(currentWebMenu.id, result)
206
- .then((res) => {
207
-
208
- showNotification({
209
- title: 'Salvataggio completato',
210
- message: `Il menu è stato salvato con successo`,
211
- color: 'green',
212
- })
213
-
214
- navigation(0);
215
-
216
- }).catch((err) => {
217
-
218
- showNotification({
219
- title: 'Errore',
220
- message: `Errore durante il salvataggio del menu. ${err.message}`,
221
- color: 'red',
222
- })
223
-
224
- })
225
- .finally(() => {
226
- setLoadData(false);
227
- })
228
- }
229
-
230
- const generateAppMenuItem = (menuItems: NodeModel<AppMenuItem>[], parent: string | number = 'root') => {
231
-
232
- const appMenuItems: AppMenuItem[] = []
233
-
234
- menuItems.filter(a => a.parent === parent).forEach((node) => {
235
-
236
- const currentMenuItem = node.data!
237
-
238
- currentMenuItem.children = generateAppMenuItem(menuItems, node.id);
239
-
240
- appMenuItems.push(currentMenuItem);
241
- })
242
-
243
- return appMenuItems;
244
-
245
- }
246
-
247
- const updateAppMenuItem = (nodeId: string | number, menuItem: AppMenuItem) => {
248
- const tData = [...treeData];
249
-
250
- tData.forEach((n) => {
251
- if(n.id === nodeId) {
252
- n.text = menuItem.label;
253
- n.data = menuItem;
254
- }
255
- })
256
-
257
- setTreeData(tData);
258
- setEditMenuItemModalOpened(false);
259
- }
260
-
261
- const deleteAppMenuItem = (nodeId: string | number) => {
262
- const tData = deleteDescendants([...treeData], nodeId);
263
- setTreeData(tData);
264
- }
265
-
266
- function deleteDescendants(nodes: NodeModel<AppMenuItem>[], nodeId: number | string): NodeModel<AppMenuItem>[] {
267
- const descendants = nodes.filter((node) => node.parent === nodeId);
268
- descendants.forEach((descendant) => {
269
- nodes = deleteDescendants(nodes, descendant.id);
270
- });
271
- return nodes.filter((node) => node.id !== nodeId);
272
- }
273
-
274
- const onWebMenuChanged = (webMenuId: number) => {
275
- setCurrentWebMenuLoaded(false);
276
-
277
- FluxoClientSys.Instance.configuration.getAppMenu(webMenuId)
278
- .then((res) => {
279
- const result = generateMenuObjectFromMenu((res as AppMenuItem[]));
280
- setTreeData(result);
281
- setCurrentWebMenuLoaded(true);
282
- setCurrentAppMenuItemsAreChanged(false);
283
- })
284
-
285
- }
286
-
287
- return (
288
- <Stack gap={8}>
289
-
290
- <DataCard title={'Gestione Menu'}>
291
- <Stack>
292
- <Grid gutter={16} align={'flex-start'}>
293
- <Grid.Col span={10.5}>
294
- <Select
295
- allowDeselect={false}
296
- value={currentWebMenu?.id.toString()} data={webMenu?.map(a => {return {label: a.name, value: a.id.toString()}})}
297
- onChange={(v) => {
298
- const tmp = webMenu?.filter(a => a.id.toString() === v)[0];
299
- setCurrentWebMenu(tmp);
300
- }}
301
- />
302
- </Grid.Col>
303
- <Grid.Col span={1.5}>
304
- <Button fullWidth leftSection={<IconPlus size={18} />} onClick={() => setShowMenuCreateForm(true)}>Crea menu</Button>
305
- </Grid.Col>
306
- </Grid>
307
- </Stack>
308
- </DataCard>
309
-
310
- {!currentWebMenuLoaded &&
311
- <Center>
312
- <Loader size={32} />
313
- </Center>
314
- }
315
-
316
- {currentWebMenu && currentWebMenuLoaded &&
317
- <>
318
- <Center>
319
- <IconArrowDown size={48} color={'gray'} />
320
- </Center>
321
- <DataCard title={`Menu designer - ${currentWebMenu.name}`}
322
- elements={[
323
- <Chip
324
- icon={<IconDeviceFloppy style={{ width: rem(14), height: rem(14) }} />}
325
- color={currentAppMenuItemsAreChanged ? 'yellow' : 'green'}
326
- variant="filled"
327
- size={'xs'}
328
- checked={true}
329
- >
330
- {currentAppMenuItemsAreChanged ? 'Modifiche non salvate' : 'Salvato'}
331
- </Chip>
332
- ]}
333
- >
334
-
335
- <Stack>
336
- <Grid gutter={16} align={'flex-start'}>
337
- <LoadingOverlay visible={loadData} />
338
-
339
- <Grid.Col span={{lg: 3}}>
340
- {sysFeatures &&
341
- <Select
342
- placeholder="Seleziona un modulo"
343
- onChange={(module) => {
344
- setCurrentSelectedFeatures(sysFeatures?.features.filter(a => a.moduleKey === module));
345
- setCurrentSelectedFeatureId(null);
346
- setFeatureSearchValue(undefined);
347
- }}
348
- leftSection={<IconBoxModel />}
349
- data={sysFeatures?.modules.map((e) => {
350
- return {
351
- value: `${e.key}.${e.name}`,
352
- label: `${e.description} (${e.name})`,
353
- }
354
- })}
355
- />
356
- }
357
- </Grid.Col>
358
- <Grid.Col span={{lg: 9}}>
359
- <Group align={'end'}>
360
- <div style={{width: 'calc(100% - 336px)'}}>
361
- <Select
362
- disabled={!currentSelectedFeatures}
363
- placeholder="Seleziona una feature"
364
- searchable
365
- leftSection={<IconApps />}
366
- value={currentSelectedFeatureId}
367
- onChange={(v) => {
368
- setCurrentSelectedFeatureId(v)
369
- }}
370
- onSearchChange={(v) => setFeatureSearchValue(v)}
371
- searchValue={featureSearchValue}
372
- clearable
373
- data={currentSelectedFeatures === undefined ? [] : currentSelectedFeatures?.map((e) => {
374
- return {
375
- value: e.identifier,
376
- label: e.name,
377
- }
378
- })}
379
- />
380
- </div>
381
- <div style={{width: 150}}>
382
- <Button onClick={() => addFeatureToMenuHandler()} disabled={!currentSelectedFeatureId} fullWidth leftSection={<IconPlus size={18} />}>Voce</Button>
383
- </div>
384
- <div style={{width: 150}}>
385
- <Button onClick={() => addGroupToMenuHandler()} fullWidth leftSection={<IconFolderPlus size={18} />}>Gruppo</Button>
386
- </div>
387
- </Group>
388
- </Grid.Col>
389
- </Grid>
390
- <DndProvider backend={MultiBackend} options={getBackendOptions()}>
391
- <Tree
392
- listComponent={'div'}
393
- listItemComponent={'div'}
394
- placeholderComponent={'div'}
395
- tree={treeData ?? []}
396
- rootId={'root'}
397
- sort={false}
398
- onDrop={handleDrop}
399
- dropTargetOffset={10}
400
- canDrop={(tree, { dragSource, dropTargetId, dropTarget }) => {
401
- return dropTarget?.data?.isGroup || dropTarget === undefined;
402
- }}
403
- classes={{
404
- root: styles["treeRoot"],
405
- draggingSource: styles["draggingSource"],
406
- placeholder: styles["placeholderContainer"]
407
- }}
408
- placeholderRender={(node, { depth }) => (
409
- <Placeholder node={node} depth={depth} />
410
- )}
411
- render={(node, { depth, isOpen, onToggle }) => (
412
- <CustomNode
413
- nodes={treeData ?? []}
414
- node={node}
415
- depth={depth}
416
- isOpen={isOpen}
417
- onToggle={onToggle}
418
- onDeleteButtonClick={(nodeId) => deleteAppMenuItem(nodeId)}
419
- onEditButtonClick={(i) => {
420
- setEditMenuItem(i);
421
- setEditNodeId(node.id);
422
- setEditMenuItemModalOpened(true);
423
- }}
424
- />
425
- )}
426
- />
427
- </DndProvider>
428
- {(editMenuItem && editNodeId) &&
429
- <Modal title={'Modifica voce di menu'} closeOnEscape={false} closeOnClickOutside={false} centered opened={editMenuItemModalOpened} onClose={() => setEditMenuItemModalOpened(false)}>
430
- <MenuItemEdit
431
- nodeId={editNodeId}
432
- menuItem={editMenuItem}
433
- onCancelClick={() => {setEditMenuItemModalOpened(false); setEditMenuItem(undefined)}}
434
- onSaveClick={(nodeId, i) => updateAppMenuItem(nodeId, i)}
435
- />
436
- </Modal>
437
- }
438
-
439
- <Divider />
440
-
441
- <Group justify={'end'}>
442
- <Button color={'red'} disabled={currentWebMenu.contextType == AppMenuContextType.Default} onClick={() => navigation(0)} variant={'outline'}>Elimina</Button>
443
- <Button onClick={() => saveButtonHandler()}>Salva</Button>
444
- </Group>
445
-
446
- </Stack>
447
- </DataCard>
448
- </>
449
- }
450
-
451
- <Modal centered title={'Aggiungi menu'} opened={showMenuCreateForm} onClose={() => setShowMenuCreateForm(false)} size={'md'} padding={'md'}>
452
- <MenuCreateForm
453
- onCancel={() => setShowMenuCreateForm(false)}
454
- onCreated={() => {
455
- setShowMenuCreateForm(false)
456
- loadAppMenuList();
457
- }}
458
- />
459
- </Modal>
460
-
461
- </Stack>
462
- );
463
- }
@@ -1,115 +0,0 @@
1
- import {forwardRef, useEffect, useState} from "react";
2
- import {Button, Divider, Group, Select, Stack, Switch, TextInput, Text} from "@mantine/core";
3
- import {AppMenuItem} from "@fluxo-dev/api-client-base";
4
- import {IconFactory} from "../../../utils/icon-factory";
5
-
6
- export interface MenuItemEditProps {
7
-
8
- nodeId: string | number,
9
- menuItem: AppMenuItem,
10
- onCancelClick: () => void,
11
- onSaveClick: (nodeId: string | number, item: AppMenuItem) => void;
12
- }
13
- export function MenuItemEdit(props: MenuItemEditProps) {
14
-
15
- const [label, setLabel] = useState(props.menuItem.label);
16
- const [hasIndex, setHasIndex] = useState<boolean>(props.menuItem.hasIndex ?? false);
17
- const [icon, setIcon] = useState<string | undefined>(props.menuItem.icon ?? undefined);
18
- const [identifier] = useState(props.menuItem.featureIdentifier);
19
- const [routerLink, setRouterLink] = useState<string | undefined>(props.menuItem.routerLink);
20
- const [routerLinkTextValue, setRouterLinkTextValue] = useState<string>(props.menuItem.routerLink ? props.menuItem.routerLink : '');
21
- const [routerLinkError, setRouterLinkError] = useState<string | null>();
22
-
23
- const [isValid, setIsValid] = useState<boolean>(true);
24
-
25
- const [item, setItem] = useState<AppMenuItem>(props.menuItem);
26
-
27
- useEffect(() => {
28
- setItem({
29
- icon: icon,
30
- featureIdentifier: identifier,
31
- hasIndex: hasIndex,
32
- label: label,
33
- children: props.menuItem.children,
34
- routerLink: routerLink,
35
- isGroup: props.menuItem.isGroup,
36
- menuItemId: props.menuItem.menuItemId
37
- });
38
-
39
- if(!props.menuItem.isGroup) {
40
- if (label && routerLink && icon)
41
- setIsValid(true)
42
- else
43
- setIsValid(false);
44
- } else {
45
- if (label && icon)
46
- setIsValid(true)
47
- else
48
- setIsValid(false);
49
- }
50
-
51
- }, [label, hasIndex, icon, routerLink])
52
-
53
- const handleRouterLinkChanged = (v: string) => {
54
-
55
- setRouterLinkTextValue(v);
56
-
57
- const isExternalLink = props.menuItem.featureIdentifier === 'webclient.routing.externallink';
58
- let regex = /^[\w-]+(?:\/[\w-]+)*$/;
59
-
60
- if(isExternalLink)
61
- regex = /^(https?:\/\/)?([\w]+\.)+[\w]{2,63}\.[a-zA-Z]{2,6}[\/\?\#]?.*$/;
62
-
63
- if (regex.test(v)) {
64
- setRouterLink(v);
65
- setRouterLinkError(null)
66
- } else {
67
- setRouterLink(undefined);
68
- setRouterLinkError(isExternalLink ? 'Link non valido' : 'Link non valido, es: registries/product/create')
69
- }
70
- }
71
-
72
- const SelectItem = forwardRef<HTMLDivElement, any>(
73
- ({ label, value, ...others }: any, ref) => (
74
- <div ref={ref} {...others}>
75
- <Group wrap="nowrap">
76
- {IconFactory.getIcon(value ?? '')}
77
-
78
- <div>
79
- <Text size="sm">{label}</Text>
80
- </div>
81
- </Group>
82
- </div>
83
- )
84
- );
85
-
86
- return (
87
- <Stack>
88
- <TextInput label={'Etichetta'} value={label} onChange={(v) => setLabel(v.currentTarget.value)} />
89
-
90
- {!props.menuItem.isGroup &&
91
- <Switch label={'Indicizzato'} checked={hasIndex} offLabel={'NO'} onLabel={'SI'} onChange={(e) => setHasIndex(e.currentTarget.checked)} />
92
- }
93
-
94
- <Select
95
- leftSection={IconFactory.getIcon(icon ?? '')}
96
- data={IconFactory.getIconIdentifiers().map((e) => {return {
97
- label: e,
98
- value: e,
99
- }})}
100
- searchable
101
- label={'Icona'} value={icon} onChange={(v) => setIcon(v!)}
102
- />
103
-
104
- {!props.menuItem.isGroup &&
105
- <TextInput label={'Route'} disabled={true} value={routerLinkTextValue} error={routerLinkError} onChange={(v) => handleRouterLinkChanged(v.currentTarget.value)} />
106
- }
107
-
108
- <Divider />
109
- <Group align={'end'} justify={'right'}>
110
- <Button variant={'subtle'} onClick={() => props.onCancelClick()}>Annulla</Button>
111
- <Button disabled={!isValid} onClick={() => props.onSaveClick(props.nodeId, item)}>Salva</Button>
112
- </Group>
113
- </Stack>
114
- )
115
- }
@@ -1,8 +0,0 @@
1
- .root {
2
- background-color: #1967d2;
3
- height: 2px;
4
- position: absolute;
5
- right: 0;
6
- transform: translateY(-50%);
7
- top: 0;
8
- }
@@ -1,13 +0,0 @@
1
- import React from "react";
2
- import { NodeModel } from "@minoru/react-dnd-treeview";
3
- import styles from "./placeholder.module.css";
4
-
5
- type Props = {
6
- node: NodeModel;
7
- depth: number;
8
- };
9
-
10
- export const Placeholder: React.FC<Props> = (props) => {
11
- const left = props.depth * 24;
12
- return <div className={styles["root"]} style={{ left }}></div>;
13
- };
@@ -1,67 +0,0 @@
1
- import {DomainRole, DomainRoleService} from "@fluxo-dev/api-client-base";
2
- import {useForm} from "@mantine/form";
3
- import {Button, Stack, TextInput} from "@mantine/core";
4
- import {IconFilePlus} from '@tabler/icons-react';
5
- import {showNotification} from "@mantine/notifications";
6
-
7
- export interface DomainRoleFormProps {
8
- domainRole: DomainRole | undefined;
9
- onCreate: () => void;
10
- }
11
-
12
- export function DomainRoleForm (props: DomainRoleFormProps) {
13
-
14
- const domainRoleService = new DomainRoleService();
15
-
16
- const form = useForm<DomainRole>({
17
- initialValues: {
18
- name: props.domainRole?.name ?? '',
19
- description: props.domainRole?.description ?? '',
20
- identifier: props.domainRole?.identifier ?? '',
21
- }
22
- });
23
-
24
- const save = (value: DomainRole) => {
25
-
26
- (props.domainRole ? domainRoleService.update(props.domainRole.id!.toString(), value) : domainRoleService.create(value))
27
- .then((res) => {
28
-
29
- showNotification({
30
- title: 'Operazione completata',
31
- message: 'Ruolo salvato correttamente',
32
- color: 'green',
33
- })
34
- form.reset();
35
- form.resetDirty();
36
- if (props.onCreate)
37
- props.onCreate();
38
-
39
- })
40
- .catch((err) => {
41
- showNotification({
42
- title: 'Errore',
43
- message: 'Si è verificato un errore: ' + err.message,
44
- color: 'red',
45
- })
46
- })
47
- }
48
-
49
- return (
50
- <form onKeyDown={event => { if (event.which === 13) event.preventDefault() }}
51
- onSubmit={form.onSubmit(
52
- (values, event) => {
53
- event?.preventDefault();
54
- save(values);
55
- })}>
56
- <Stack>
57
- <TextInput label={"Identificatore"} placeholder={'Es: administrator'} required {...form.getInputProps('identifier')} />
58
- <TextInput label={"Nome"} placeholder={'Es: Amministratore'} required {...form.getInputProps('name')} />
59
- <TextInput label={"Descrizione"} placeholder={'Es: Ruolo amministratore'} required {...form.getInputProps('description')} />
60
-
61
- <Stack align="flex-end" mt="md">
62
- <Button type="submit" leftSection={<IconFilePlus />} ml='auto' disabled={!form.isDirty()}>Salva</Button>
63
- </Stack >
64
- </Stack>
65
- </form>
66
- )
67
- }