@fluxo-dev/shell-reporting 25.3.2 → 25.3.4

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.
@@ -1,46 +1,89 @@
1
- import { c as createReactComponent, p as promiseNativeConstructor, f as fails$1, _ as _export, s as speciesConstructor$1, g as getBuiltIn$1, a as promiseResolve$1, i as isCallable$1, d as defineBuiltIn$1 } from './index.esm2.js';
1
+ import { c as createReactComponent, p as promiseNativeConstructor, f as fails$1, _ as _export, s as speciesConstructor$1, g as getBuiltIn$1, a as promiseResolve$1, i as isCallable$1, d as defineBuiltIn$1, R as ReportDesigner } from './index.esm2.js';
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
- import { ShellPage, DataCard, ConfirmModal } from '@fluxo-dev/ui-components';
4
- import { Stack, Text, TextInput, Textarea, Group, Button, Loader, Divider, Center, Modal } from '@mantine/core';
5
- import { useState, useEffect } from 'react';
3
+ import { Stack, Text, TextInput, Textarea, Group, Button, Paper, Skeleton, Center, Select, Badge, Menu, ActionIcon, Modal } from '@mantine/core';
4
+ import { useState, useEffect, useRef, useCallback } from 'react';
6
5
  import { FluxoClientSys } from '@fluxo-dev/api-client-base';
7
6
  import { useNavigate } from 'react-router-dom';
8
7
  import { showNotification } from '@mantine/notifications';
8
+ import { ShellPage, ConfirmModal } from '@fluxo-dev/ui-components';
9
9
  import '@mantine/dates';
10
10
 
11
11
  /**
12
- * @tabler/icons-react v2.47.0 - MIT
12
+ * @license @tabler/icons-react v3.36.0 - MIT
13
+ *
14
+ * This source code is licensed under the MIT license.
15
+ * See the LICENSE file in the root directory of this source tree.
13
16
  */
14
17
 
15
18
 
16
- var IconPlus = createReactComponent("plus", "IconPlus", [
17
- ["path", { d: "M12 5l0 14", key: "svg-0" }],
18
- ["path", { d: "M5 12l14 0", key: "svg-1" }]
19
- ]);
19
+ const __iconNode$6 = [["path", { "d": "M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-0" }], ["path", { "d": "M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-1" }], ["path", { "d": "M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "key": "svg-2" }]];
20
+ const IconDotsVertical = createReactComponent("outline", "dots-vertical", "DotsVertical", __iconNode$6);
20
21
 
21
22
  /**
22
- * @tabler/icons-react v2.47.0 - MIT
23
+ * @license @tabler/icons-react v3.36.0 - MIT
24
+ *
25
+ * This source code is licensed under the MIT license.
26
+ * See the LICENSE file in the root directory of this source tree.
23
27
  */
24
28
 
25
29
 
26
- var IconReport = createReactComponent("report", "IconReport", [
27
- [
28
- "path",
29
- { d: "M8 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h5.697", key: "svg-0" }
30
- ],
31
- ["path", { d: "M18 14v4h4", key: "svg-1" }],
32
- ["path", { d: "M18 11v-4a2 2 0 0 0 -2 -2h-2", key: "svg-2" }],
33
- [
34
- "path",
35
- {
36
- d: "M8 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z",
37
- key: "svg-3"
38
- }
39
- ],
40
- ["path", { d: "M18 18m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0", key: "svg-4" }],
41
- ["path", { d: "M8 11h4", key: "svg-5" }],
42
- ["path", { d: "M8 15h3", key: "svg-6" }]
43
- ]);
30
+ const __iconNode$5 = [["path", { "d": "M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1", "key": "svg-0" }], ["path", { "d": "M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z", "key": "svg-1" }], ["path", { "d": "M16 5l3 3", "key": "svg-2" }]];
31
+ const IconEdit = createReactComponent("outline", "edit", "Edit", __iconNode$5);
32
+
33
+ /**
34
+ * @license @tabler/icons-react v3.36.0 - MIT
35
+ *
36
+ * This source code is licensed under the MIT license.
37
+ * See the LICENSE file in the root directory of this source tree.
38
+ */
39
+
40
+
41
+ const __iconNode$4 = [["path", { "d": "M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6", "key": "svg-0" }], ["path", { "d": "M11 13l9 -9", "key": "svg-1" }], ["path", { "d": "M15 4h5v5", "key": "svg-2" }]];
42
+ const IconExternalLink = createReactComponent("outline", "external-link", "ExternalLink", __iconNode$4);
43
+
44
+ /**
45
+ * @license @tabler/icons-react v3.36.0 - MIT
46
+ *
47
+ * This source code is licensed under the MIT license.
48
+ * See the LICENSE file in the root directory of this source tree.
49
+ */
50
+
51
+
52
+ const __iconNode$3 = [["path", { "d": "M5 4h4l3 3h7a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2", "key": "svg-0" }]];
53
+ const IconFolder = createReactComponent("outline", "folder", "Folder", __iconNode$3);
54
+
55
+ /**
56
+ * @license @tabler/icons-react v3.36.0 - MIT
57
+ *
58
+ * This source code is licensed under the MIT license.
59
+ * See the LICENSE file in the root directory of this source tree.
60
+ */
61
+
62
+
63
+ const __iconNode$2 = [["path", { "d": "M12 5l0 14", "key": "svg-0" }], ["path", { "d": "M5 12l14 0", "key": "svg-1" }]];
64
+ const IconPlus = createReactComponent("outline", "plus", "Plus", __iconNode$2);
65
+
66
+ /**
67
+ * @license @tabler/icons-react v3.36.0 - MIT
68
+ *
69
+ * This source code is licensed under the MIT license.
70
+ * See the LICENSE file in the root directory of this source tree.
71
+ */
72
+
73
+
74
+ const __iconNode$1 = [["path", { "d": "M8 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h5.697", "key": "svg-0" }], ["path", { "d": "M18 14v4h4", "key": "svg-1" }], ["path", { "d": "M18 11v-4a2 2 0 0 0 -2 -2h-2", "key": "svg-2" }], ["path", { "d": "M8 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z", "key": "svg-3" }], ["path", { "d": "M18 18m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0", "key": "svg-4" }], ["path", { "d": "M8 11h4", "key": "svg-5" }], ["path", { "d": "M8 15h3", "key": "svg-6" }]];
75
+ const IconReport = createReactComponent("outline", "report", "Report", __iconNode$1);
76
+
77
+ /**
78
+ * @license @tabler/icons-react v3.36.0 - MIT
79
+ *
80
+ * This source code is licensed under the MIT license.
81
+ * See the LICENSE file in the root directory of this source tree.
82
+ */
83
+
84
+
85
+ const __iconNode = [["path", { "d": "M4 7l16 0", "key": "svg-0" }], ["path", { "d": "M10 11l0 6", "key": "svg-1" }], ["path", { "d": "M14 11l0 6", "key": "svg-2" }], ["path", { "d": "M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12", "key": "svg-3" }], ["path", { "d": "M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3", "key": "svg-4" }]];
86
+ const IconTrash = createReactComponent("outline", "trash", "Trash", __iconNode);
44
87
 
45
88
  var $ = _export;
46
89
  var NativePromiseConstructor = promiseNativeConstructor;
@@ -85,9 +128,14 @@ if (isCallable(NativePromiseConstructor)) {
85
128
  }
86
129
 
87
130
  function CreateReport(props) {
88
- const [name, setName] = useState('');
89
- const [note, setNote] = useState('');
131
+ const [name, setName] = useState(props.initialName || '');
132
+ const [note, setNote] = useState(props.initialNote || '');
90
133
  const [loading, setLoading] = useState(false);
134
+ const isEditMode = props.mode === 'edit';
135
+ useEffect(() => {
136
+ if (props.initialName) setName(props.initialName);
137
+ if (props.initialNote) setNote(props.initialNote);
138
+ }, [props.initialName, props.initialNote]);
91
139
  const createReport = () => {
92
140
  if (!name) return;
93
141
  const command = {
@@ -116,22 +164,57 @@ function CreateReport(props) {
116
164
  setLoading(false);
117
165
  });
118
166
  };
167
+ const updateReport = () => {
168
+ if (!name || !props.reportId) return;
169
+ setLoading(true);
170
+ FluxoClientSys.Instance.reporting.updateReport(props.reportId, {
171
+ name: name,
172
+ annotations: note
173
+ }).then(() => {
174
+ var _a;
175
+ showNotification({
176
+ title: 'Report aggiornato',
177
+ message: 'Il report è stato aggiornato con successo',
178
+ color: 'teal'
179
+ });
180
+ (_a = props.onUpdated) === null || _a === void 0 ? void 0 : _a.call(props);
181
+ }).catch(err => {
182
+ showNotification({
183
+ title: 'Errore',
184
+ message: 'Si è verificato un errore durante l\'aggiornamento del report',
185
+ color: 'red'
186
+ });
187
+ }).finally(() => {
188
+ setLoading(false);
189
+ });
190
+ };
191
+ const handleSubmit = () => {
192
+ if (isEditMode) {
193
+ updateReport();
194
+ } else {
195
+ createReport();
196
+ }
197
+ };
119
198
  return jsxs(Stack, {
120
- children: [jsxs(Text, {
121
- children: [jsx("b", {
122
- children: "Nome:"
123
- }), " ", props.name]
124
- }), jsxs(Text, {
125
- children: [jsx("b", {
126
- children: "Categoria:"
127
- }), " ", props.scope, ".", props.packageName, ".", props.namespace, ".", props.id]
199
+ children: [!isEditMode && jsxs(Fragment, {
200
+ children: [jsxs(Text, {
201
+ children: [jsx("b", {
202
+ children: "Nome:"
203
+ }), " ", props.name]
204
+ }), jsxs(Text, {
205
+ children: [jsx("b", {
206
+ children: "Categoria:"
207
+ }), " ", props.scope, ".", props.packageName, ".", props.namespace, ".", props.id]
208
+ })]
128
209
  }), jsx(TextInput, {
129
210
  disabled: loading,
130
211
  label: 'Nome report',
212
+ value: name,
131
213
  onChange: v => setName(v.target.value)
132
214
  }), jsx(Textarea, {
133
215
  disabled: loading,
134
216
  label: 'Note',
217
+ value: note,
135
218
  onChange: v => setNote(v.target.value)
136
219
  }), jsxs(Group, {
137
220
  justify: 'right',
@@ -141,9 +224,9 @@ function CreateReport(props) {
141
224
  variant: 'subtle',
142
225
  children: "Annulla"
143
226
  }), jsx(Button, {
144
- onClick: createReport,
227
+ onClick: handleSubmit,
145
228
  disabled: !name || loading,
146
- children: "Crea"
229
+ children: isEditMode ? 'Salva' : 'Crea'
147
230
  })]
148
231
  })]
149
232
  });
@@ -152,32 +235,143 @@ function CreateReport(props) {
152
235
  function ReportsManager() {
153
236
  const [reportsList, setReportsList] = useState([]);
154
237
  const [loading, setLoading] = useState(true);
155
- const navigate = useNavigate();
156
- const [createReportModalOpened, setCreateReportModalOpened] = useState(false);
157
- const [deleteReportModalOpened, setDeleteReportModalOpened] = useState(false);
158
- const [currentId, setCurrentId] = useState();
159
- const [currentScope, setCurrentScope] = useState('');
160
- const [currentPackageName, setCurrentPackageName] = useState('');
161
- const [currentNamespace, setCurrentNamespace] = useState('');
162
- const [currentReportId, setCurrentReportId] = useState('');
163
- const [currentReportTypeName, setCurrentReportTypeName] = useState('');
164
- const [currentReportName, setCurrentReportName] = useState('');
238
+ useNavigate();
239
+ // Refactored state management
240
+ const [selectedCategory, setSelectedCategory] = useState(null);
241
+ const [selectedReport, setSelectedReport] = useState(null);
242
+ const [selectedCategoryKey, setSelectedCategoryKey] = useState(null);
243
+ const [modals, setModals] = useState({
244
+ create: false,
245
+ delete: false,
246
+ edit: false,
247
+ reportEditor: false
248
+ });
249
+ const [editingReportId, setEditingReportId] = useState(null);
250
+ const [editingReport, setEditingReport] = useState(null);
251
+ const isClosingRef = useRef(false);
165
252
  useEffect(() => {
166
253
  refresh();
167
254
  }, []);
255
+ useEffect(() => {
256
+ // Auto-select first category when data loads
257
+ if (reportsList.length > 0 && !selectedCategoryKey) {
258
+ const firstCategory = reportsList[0];
259
+ setSelectedCategoryKey(`${firstCategory.scope}-${firstCategory.reportTypeId}`);
260
+ }
261
+ }, [reportsList, selectedCategoryKey]);
262
+ // Intercetta il refresh e il cambio tab del browser
263
+ useEffect(() => {
264
+ if (!modals.reportEditor) return;
265
+ const handleBeforeUnload = e => {
266
+ e.preventDefault();
267
+ e.returnValue = 'Sei sicuro di voler uscire? Le modifiche non salvate andranno perse.';
268
+ return e.returnValue;
269
+ };
270
+ window.addEventListener('beforeunload', handleBeforeUnload);
271
+ return () => window.removeEventListener('beforeunload', handleBeforeUnload);
272
+ }, [modals.reportEditor]);
273
+ // Intercetta la navigazione nel router (back button del browser)
274
+ useEffect(() => {
275
+ if (!modals.reportEditor) return;
276
+ const handlePopState = () => {
277
+ if (!isClosingRef.current) {
278
+ const confirmExit = window.confirm('Sei sicuro di voler uscire dall\'editor? Le modifiche non salvate andranno perse.');
279
+ if (!confirmExit) {
280
+ window.history.pushState(null, '', window.location.href);
281
+ } else {
282
+ setModals(prev => Object.assign(Object.assign({}, prev), {
283
+ reportEditor: false
284
+ }));
285
+ setEditingReportId(null);
286
+ }
287
+ }
288
+ };
289
+ // Aggiungi uno stato alla history per intercettare il back button
290
+ window.history.pushState(null, '', window.location.href);
291
+ window.addEventListener('popstate', handlePopState);
292
+ return () => {
293
+ window.removeEventListener('popstate', handlePopState);
294
+ };
295
+ }, [modals.reportEditor]);
168
296
  const refresh = () => {
169
297
  FluxoClientSys.Instance.reporting.getReportsList().then(res => {
170
298
  setReportsList(res);
171
299
  setLoading(false);
172
300
  });
173
301
  };
302
+ // Helper functions for modal management
303
+ const openCreateModal = category => {
304
+ setSelectedCategory(category);
305
+ setModals(prev => Object.assign(Object.assign({}, prev), {
306
+ create: true
307
+ }));
308
+ };
309
+ const closeCreateModal = () => {
310
+ setSelectedCategory(null);
311
+ setModals(prev => Object.assign(Object.assign({}, prev), {
312
+ create: false
313
+ }));
314
+ };
315
+ const openEditModal = (report, category) => {
316
+ setEditingReport({
317
+ id: report.id,
318
+ name: report.name,
319
+ annotations: report.annotations || '',
320
+ scope: category.scope,
321
+ packageName: category.packageName,
322
+ namespace: category.namespace,
323
+ reportTypeId: category.reportTypeId,
324
+ categoryName: category.name
325
+ });
326
+ setModals(prev => Object.assign(Object.assign({}, prev), {
327
+ edit: true
328
+ }));
329
+ };
330
+ const closeEditModal = () => {
331
+ setEditingReport(null);
332
+ setModals(prev => Object.assign(Object.assign({}, prev), {
333
+ edit: false
334
+ }));
335
+ };
336
+ const openDeleteModal = report => {
337
+ setSelectedReport(report);
338
+ setModals(prev => Object.assign(Object.assign({}, prev), {
339
+ delete: true
340
+ }));
341
+ };
342
+ const closeDeleteModal = () => {
343
+ setSelectedReport(null);
344
+ setModals(prev => Object.assign(Object.assign({}, prev), {
345
+ delete: false
346
+ }));
347
+ };
348
+ const openReportEditor = reportId => {
349
+ setEditingReportId(reportId);
350
+ setModals(prev => Object.assign(Object.assign({}, prev), {
351
+ reportEditor: true
352
+ }));
353
+ };
354
+ const handleCloseReportEditor = useCallback(() => {
355
+ const confirmClose = window.confirm('Sei sicuro di voler chiudere l\'editor? Le modifiche non salvate andranno perse.');
356
+ if (confirmClose) {
357
+ isClosingRef.current = true;
358
+ setModals(prev => Object.assign(Object.assign({}, prev), {
359
+ reportEditor: false
360
+ }));
361
+ setEditingReportId(null);
362
+ // Reset del flag dopo un breve delay
363
+ setTimeout(() => {
364
+ isClosingRef.current = false;
365
+ }, 100);
366
+ }
367
+ }, []);
174
368
  const deleteReport = () => {
175
- if (!currentId) return;
176
- FluxoClientSys.Instance.reporting.deleteReport(currentId).then(() => {
369
+ if (!(selectedReport === null || selectedReport === void 0 ? void 0 : selectedReport.id)) return;
370
+ FluxoClientSys.Instance.reporting.deleteReport(selectedReport.id).then(() => {
177
371
  showNotification({
178
372
  title: 'Report eliminato',
179
373
  message: 'Il report è stato eliminato con successo',
180
- color: 'success'
374
+ color: 'green'
181
375
  });
182
376
  refresh();
183
377
  }).catch(() => {
@@ -187,105 +381,312 @@ function ReportsManager() {
187
381
  color: 'red'
188
382
  });
189
383
  }).finally(() => {
190
- setDeleteReportModalOpened(false);
191
- setCurrentId(undefined);
384
+ closeDeleteModal();
192
385
  });
193
386
  };
387
+ // Get currently selected category data
388
+ const getCurrentCategory = () => {
389
+ if (!selectedCategoryKey) return null;
390
+ return reportsList.find(cat => `${cat.scope}-${cat.reportTypeId}` === selectedCategoryKey);
391
+ };
392
+ const currentCategory = getCurrentCategory();
194
393
  return jsxs(ShellPage, {
195
394
  headerProps: {
196
395
  title: 'Reports'
197
396
  },
198
- children: [loading ? jsx(Loader, {
199
- size: 48,
200
- style: {
201
- margin: 'auto'
202
- }
203
- }) : jsx(Stack, {
204
- children: reportsList.map(report => {
205
- return jsx(DataCard, {
206
- title: report.name,
207
- actions: [{
208
- label: 'Nuovo report',
209
- icon: jsx(IconPlus, {
210
- size: 18
397
+ children: [loading ? jsx(Stack, {
398
+ gap: "sm",
399
+ maw: 1280,
400
+ m: '0 auto',
401
+ children: [1, 2, 3].map(i => jsxs(Paper, {
402
+ p: "sm",
403
+ withBorder: true,
404
+ children: [jsxs(Group, {
405
+ justify: "space-between",
406
+ mb: "xs",
407
+ children: [jsx(Skeleton, {
408
+ height: 20,
409
+ width: 200
410
+ }), jsx(Skeleton, {
411
+ height: 16,
412
+ circle: true
413
+ })]
414
+ }), jsx(Skeleton, {
415
+ height: 32,
416
+ mt: "sm"
417
+ })]
418
+ }, i))
419
+ }) : reportsList.length === 0 ? jsx(Center, {
420
+ py: 60,
421
+ maw: 1280,
422
+ m: '0 auto',
423
+ children: jsxs(Stack, {
424
+ align: "center",
425
+ gap: "sm",
426
+ children: [jsx(IconFolder, {
427
+ size: 48,
428
+ stroke: 1.2,
429
+ style: {
430
+ opacity: 0.4
431
+ }
432
+ }), jsx(Text, {
433
+ size: "sm",
434
+ c: "dimmed",
435
+ children: "Nessuna categoria di report disponibile"
436
+ })]
437
+ })
438
+ }) : jsxs(Stack, {
439
+ gap: "sm",
440
+ maw: 1280,
441
+ m: '0 auto',
442
+ children: [jsx(Paper, {
443
+ p: "sm",
444
+ withBorder: true,
445
+ children: jsxs(Group, {
446
+ justify: "space-between",
447
+ align: "flex-end",
448
+ children: [jsx(Select, {
449
+ label: "Categoria",
450
+ placeholder: "Seleziona categoria",
451
+ value: selectedCategoryKey,
452
+ onChange: value => setSelectedCategoryKey(value),
453
+ data: reportsList.map(category => ({
454
+ value: `${category.scope}-${category.reportTypeId}`,
455
+ label: `${category.name} (${category.reports.length})`
456
+ })),
457
+ searchable: true,
458
+ clearable: true,
459
+ leftSection: jsx(IconFolder, {
460
+ size: 16
461
+ }),
462
+ style: {
463
+ flex: 1,
464
+ maxWidth: 400
465
+ },
466
+ size: "sm"
467
+ }), currentCategory && jsx(Button, {
468
+ size: "sm",
469
+ variant: "light",
470
+ leftSection: jsx(IconPlus, {
471
+ size: 16
211
472
  }),
212
- onClick: () => {
213
- setCurrentScope(report.scope);
214
- setCurrentPackageName(report.packageName);
215
- setCurrentNamespace(report.namespace);
216
- setCurrentReportId(report.reportTypeId);
217
- setCurrentReportTypeName(report.name);
218
- setCreateReportModalOpened(true);
219
- }
220
- }],
221
- children: jsxs(Stack, {
222
- children: [report.reports.map((r, index) => {
223
- return jsxs(Fragment, {
473
+ onClick: () => openCreateModal({
474
+ scope: currentCategory.scope,
475
+ packageName: currentCategory.packageName,
476
+ namespace: currentCategory.namespace,
477
+ reportTypeId: currentCategory.reportTypeId,
478
+ name: currentCategory.name
479
+ }),
480
+ children: "Nuovo report"
481
+ })]
482
+ })
483
+ }), currentCategory ? jsx(Paper, {
484
+ p: "sm",
485
+ withBorder: true,
486
+ children: jsxs(Stack, {
487
+ gap: "sm",
488
+ children: [jsx(Group, {
489
+ justify: "space-between",
490
+ mb: "xs",
491
+ children: jsxs(Group, {
492
+ gap: "xs",
493
+ children: [jsx(Text, {
494
+ size: "sm",
495
+ children: currentCategory.name
496
+ }), jsx(Badge, {
497
+ size: "sm",
498
+ variant: "dot",
499
+ color: currentCategory.reports.length > 0 ? 'blue' : 'gray',
500
+ children: currentCategory.reports.length
501
+ })]
502
+ })
503
+ }), currentCategory.reports.length === 0 ? jsx(Center, {
504
+ py: 40,
505
+ children: jsxs(Stack, {
506
+ align: "center",
507
+ gap: "sm",
508
+ children: [jsx(IconReport, {
509
+ size: 40,
510
+ stroke: 1.2,
511
+ style: {
512
+ opacity: 0.4
513
+ }
514
+ }), jsx(Text, {
515
+ size: "sm",
516
+ c: "dimmed",
517
+ children: "Nessun report"
518
+ }), jsx(Button, {
519
+ size: "xs",
520
+ variant: "light",
521
+ leftSection: jsx(IconPlus, {
522
+ size: 14
523
+ }),
524
+ onClick: () => openCreateModal({
525
+ scope: currentCategory.scope,
526
+ packageName: currentCategory.packageName,
527
+ namespace: currentCategory.namespace,
528
+ reportTypeId: currentCategory.reportTypeId,
529
+ name: currentCategory.name
530
+ }),
531
+ children: "Crea report"
532
+ })]
533
+ })
534
+ }) : jsx(Stack, {
535
+ gap: 8,
536
+ children: currentCategory.reports.map(report => jsx(Paper, {
537
+ p: "xs",
538
+ withBorder: true,
539
+ style: {
540
+ cursor: 'pointer'
541
+ },
542
+ onClick: () => openReportEditor(report.id),
543
+ children: jsxs(Group, {
544
+ justify: "space-between",
224
545
  children: [jsxs(Group, {
225
- justify: 'space-between',
226
- children: [jsxs(Group, {
227
- children: [jsx(IconReport, {
228
- color: 'gray',
229
- size: 18
230
- }), jsx(Text, {
231
- fw: 600,
232
- size: 'md',
233
- children: r.name
234
- })]
235
- }), jsxs(Group, {
236
- children: [jsx(Button, {
237
- onClick: () => navigate(r.id.toString(), {
238
- state: {
239
- title: `Report/${r.name}`
240
- }
546
+ gap: "sm",
547
+ children: [jsx(IconReport, {
548
+ size: 16,
549
+ style: {
550
+ opacity: 0.6
551
+ }
552
+ }), jsx(Text, {
553
+ size: "sm",
554
+ children: report.name
555
+ })]
556
+ }), jsxs(Menu, {
557
+ shadow: "sm",
558
+ width: 160,
559
+ position: "bottom-end",
560
+ children: [jsx(Menu.Target, {
561
+ children: jsx(ActionIcon, {
562
+ variant: "subtle",
563
+ color: "gray",
564
+ size: "sm",
565
+ onClick: e => e.stopPropagation(),
566
+ children: jsx(IconDotsVertical, {
567
+ size: 16
568
+ })
569
+ })
570
+ }), jsxs(Menu.Dropdown, {
571
+ children: [jsx(Menu.Item, {
572
+ leftSection: jsx(IconEdit, {
573
+ size: 14
241
574
  }),
242
- size: 'xs',
575
+ onClick: e => {
576
+ e.stopPropagation();
577
+ openEditModal(report, currentCategory);
578
+ },
243
579
  children: "Modifica"
244
- }), jsx(Button, {
245
- onClick: () => {
246
- setCurrentId(r.id);
247
- setCurrentReportName(r.name);
248
- setDeleteReportModalOpened(true);
580
+ }), jsx(Menu.Item, {
581
+ leftSection: jsx(IconExternalLink, {
582
+ size: 14
583
+ }),
584
+ onClick: e => {
585
+ e.stopPropagation();
586
+ openReportEditor(report.id);
587
+ },
588
+ children: "Apri designer"
589
+ }), jsx(Menu.Item, {
590
+ leftSection: jsx(IconTrash, {
591
+ size: 14
592
+ }),
593
+ color: "red",
594
+ onClick: e => {
595
+ e.stopPropagation();
596
+ openDeleteModal({
597
+ id: report.id,
598
+ name: report.name
599
+ });
249
600
  },
250
- size: 'xs',
251
- color: 'red',
252
601
  children: "Elimina"
253
602
  })]
254
603
  })]
255
- }), index !== report.reports.length - 1 && jsx(Divider, {})]
256
- });
257
- }), report.reports.length === 0 && jsx(Center, {
258
- children: jsx(Text, {
259
- size: 'md',
260
- children: "Nessun report per la categoria"
604
+ })]
261
605
  })
262
- })]
606
+ }, report.id))
607
+ })]
608
+ })
609
+ }) : jsx(Paper, {
610
+ p: "sm",
611
+ withBorder: true,
612
+ children: jsx(Center, {
613
+ py: 30,
614
+ children: jsx(Text, {
615
+ size: "sm",
616
+ c: "dimmed",
617
+ children: "Seleziona una categoria"
263
618
  })
264
- });
265
- })
619
+ })
620
+ })]
266
621
  }), jsx(Modal, {
267
- title: 'Nuovo report',
622
+ title: "Nuovo report",
268
623
  centered: true,
269
- opened: createReportModalOpened,
270
- onClose: () => setCreateReportModalOpened(false),
271
- children: jsx(CreateReport, {
272
- name: currentReportTypeName,
273
- scope: currentScope,
274
- packageName: currentPackageName,
275
- namespace: currentNamespace,
276
- id: currentReportId,
624
+ opened: modals.create,
625
+ onClose: closeCreateModal,
626
+ size: "sm",
627
+ children: selectedCategory && jsx(CreateReport, {
628
+ name: selectedCategory.name,
629
+ scope: selectedCategory.scope,
630
+ packageName: selectedCategory.packageName,
631
+ namespace: selectedCategory.namespace,
632
+ id: selectedCategory.reportTypeId,
277
633
  onCreated: newReportId => {
278
- setCreateReportModalOpened(false);
279
- navigate(newReportId.toString());
634
+ closeCreateModal();
635
+ refresh();
636
+ openReportEditor(newReportId);
637
+ },
638
+ onCancel: closeCreateModal
639
+ })
640
+ }), jsx(Modal, {
641
+ title: "Modifica report",
642
+ centered: true,
643
+ opened: modals.edit,
644
+ onClose: closeEditModal,
645
+ size: "sm",
646
+ children: editingReport && jsx(CreateReport, {
647
+ mode: "edit",
648
+ reportId: editingReport.id,
649
+ initialName: editingReport.name,
650
+ initialNote: editingReport.annotations,
651
+ name: editingReport.categoryName,
652
+ scope: editingReport.scope,
653
+ packageName: editingReport.packageName,
654
+ namespace: editingReport.namespace,
655
+ id: editingReport.reportTypeId,
656
+ onCreated: () => {},
657
+ onUpdated: () => {
658
+ closeEditModal();
659
+ refresh();
280
660
  },
281
- onCancel: () => setCreateReportModalOpened(false)
661
+ onCancel: closeEditModal
282
662
  })
283
663
  }), jsx(ConfirmModal, {
284
- open: deleteReportModalOpened,
285
- onButtonConfirmClick: () => deleteReport(),
286
- onButtonCancelClick: () => setDeleteReportModalOpened(true),
287
- title: 'Elimina report',
288
- messageText: `Sei sicuro di voler eliminare il report ${currentReportName}?`
664
+ open: modals.delete,
665
+ onButtonConfirmClick: deleteReport,
666
+ onButtonCancelClick: closeDeleteModal,
667
+ title: "Elimina report",
668
+ messageText: `Sei sicuro di voler eliminare il report "${selectedReport === null || selectedReport === void 0 ? void 0 : selectedReport.name}"?`
669
+ }), jsx(Modal, {
670
+ title: "Editor Report",
671
+ styles: {
672
+ header: {
673
+ marginBottom: 0,
674
+ boxShadow: 'rgba(33, 33, 33, 0.1) 2px 1px 1px',
675
+ minHeight: 48,
676
+ padding: 8
677
+ }
678
+ },
679
+ padding: 0,
680
+ closeOnEscape: false,
681
+ closeOnClickOutside: false,
682
+ withCloseButton: true,
683
+ opened: modals.reportEditor,
684
+ fullScreen: true,
685
+ onClose: handleCloseReportEditor,
686
+ children: editingReportId && jsx(ReportDesigner, {
687
+ mode: "designer",
688
+ reportId: editingReportId
689
+ })
289
690
  })]
290
691
  });
291
692
  }