refactor: modularize report designer components and controllers into a new report-designer module.
This commit is contained in:
@@ -26,3 +26,7 @@ File riassuntivo dello stato di sviluppo di Zentral.
|
||||
- Pulizia menu Zentral (rimozione voci ridondanti) e creazione nuova Dashboard principale con riepilogo moduli attivi.
|
||||
- [2025-12-04 Dashboard Widgets](./devlog/2025-12-04-030000_dashboard_widgets.md) - **Completato**
|
||||
- Implementazione sistema widget personalizzabili (drag & drop), salvataggio preferenze utente, widget "Active Modules" e "Warehouse Stats".
|
||||
- [2025-12-04 Report Designer Module](./devlog/2025-12-04-215121_report_designer_module.md) - **Completato**
|
||||
- Refactoring Report Designer in modulo autonomo e abilitazione stampa PDF condizionale.
|
||||
- [2025-12-04 Fix Report Designer Imports](./devlog/2025-12-04-212500_fix_report_designer_imports.md) - **Completato**
|
||||
- Correzione import path nel modulo Report Designer e registrazione modulo nel backend.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Fix Report Designer Imports and Activation
|
||||
|
||||
## Problema
|
||||
Il modulo Report Designer non si caricava a causa di percorsi di importazione errati nei componenti frontend e mancava la registrazione del modulo nel backend.
|
||||
|
||||
## Modifiche Apportate
|
||||
|
||||
### Frontend
|
||||
Corretti i percorsi di importazione in:
|
||||
- `DatasetManagerDialog.tsx`
|
||||
- `PreviewDialog.tsx`
|
||||
- `OutputFieldsEditor.tsx`
|
||||
- `FilterBuilder.tsx`
|
||||
- `RelationshipEditor.tsx`
|
||||
- `PropertiesPanel.tsx`
|
||||
- `PageNavigator.tsx`
|
||||
- `ContextMenu.tsx`
|
||||
- `EditorCanvas.tsx`
|
||||
- `DataBindingPanel.tsx`
|
||||
- `DatasetSelector.tsx`
|
||||
- `EditorToolbar.tsx`
|
||||
|
||||
I percorsi `../../services/reportService` e `../../types/report` sono stati aggiornati a `../../../../services/reportService` e `../../../../types/report`.
|
||||
|
||||
### Backend
|
||||
- Aggiornato `ModuleService.cs` per includere il modulo `report-designer` nel metodo `SeedDefaultModulesAsync`.
|
||||
- Riavviato il backend per applicare il seeding del nuovo modulo.
|
||||
|
||||
## Verifica
|
||||
- Attivato il modulo `report-designer` tramite l'interfaccia `/modules`.
|
||||
- Verificato il caricamento corretto della pagina `/report-designer`.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Refactoring Report Designer into a Module
|
||||
|
||||
## Obiettivo
|
||||
Trasformare la parte del report designer in un modulo a sé stante (`report-designer`).
|
||||
Una volta attivato, questo modulo abilita nelle altre applicazioni la possibilità di stampare PDF.
|
||||
|
||||
## Stato Attuale
|
||||
Il codice del report designer è sparso in `src/frontend/src/pages` e `src/backend/Zentral.API/Controllers`.
|
||||
|
||||
## Piano di Lavoro
|
||||
1. **Frontend**:
|
||||
- [x] Creare struttura modulo: `src/frontend/src/modules/report-designer/`
|
||||
- [x] Spostare pagine e componenti.
|
||||
- [x] Creare `routes.tsx`.
|
||||
- [x] Aggiornare i riferimenti e le rotte in `App.tsx`.
|
||||
- [x] Aggiornare `reportService.ts` con le nuove rotte API.
|
||||
2. **Backend**:
|
||||
- [x] Creare struttura modulo: `src/backend/Zentral.API/Modules/ReportDesigner/`
|
||||
- [x] Spostare Controller (`ReportTemplatesController`, `ReportResourcesController`, `ReportsController`).
|
||||
- [x] Aggiornare namespace e rotte API.
|
||||
- [x] Spostare DTO condivisi in `AprtModels.cs` per risolvere dipendenze circolari/mancanti.
|
||||
3. **Integrazione**:
|
||||
- [x] Verificare build Frontend e Backend.
|
||||
|
||||
## Log
|
||||
- 2025-12-04: Iniziato refactoring.
|
||||
- 2025-12-04: Spostati file frontend e creati routes.
|
||||
- 2025-12-04: Aggiornato App.tsx con ModuleGuard.
|
||||
- 2025-12-04: Spostati controller backend e aggiornati namespace.
|
||||
- 2025-12-04: Risolti problemi di compilazione backend spostando DTO.
|
||||
- 2025-12-04: Aggiornato reportService.ts frontend.
|
||||
- 2025-12-04: Completato.
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using Zentral.API.Services.Reports;
|
||||
using Zentral.Domain.Entities;
|
||||
using Zentral.Infrastructure.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
@@ -4,10 +4,10 @@ using Zentral.Infrastructure.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Zentral.API.Controllers;
|
||||
namespace Zentral.API.Modules.ReportDesigner.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/report-resources")]
|
||||
[Route("api/report-designer/resources")]
|
||||
public class ReportResourcesController : ControllerBase
|
||||
{
|
||||
private readonly ZentralDbContext _context;
|
||||
@@ -4,10 +4,10 @@ using Zentral.Infrastructure.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Zentral.API.Controllers;
|
||||
namespace Zentral.API.Modules.ReportDesigner.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/report-templates")]
|
||||
[Route("api/report-designer/templates")]
|
||||
public class ReportTemplatesController : ControllerBase
|
||||
{
|
||||
private readonly ZentralDbContext _context;
|
||||
@@ -4,10 +4,10 @@ using Zentral.Infrastructure.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Zentral.API.Controllers;
|
||||
namespace Zentral.API.Modules.ReportDesigner.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/reports")]
|
||||
[Route("api/report-designer/reports")]
|
||||
public class ReportsController : ControllerBase
|
||||
{
|
||||
private readonly ReportGeneratorService _reportGenerator;
|
||||
@@ -1226,65 +1226,4 @@ public class ReportsController : ControllerBase
|
||||
#endregion
|
||||
}
|
||||
|
||||
// DTOs
|
||||
public class DebugBindingRequest
|
||||
{
|
||||
public List<DataSourceSelection> DataSources { get; set; } = new();
|
||||
public string? PropertyName { get; set; }
|
||||
}
|
||||
|
||||
public class PreviewReportRequest
|
||||
{
|
||||
public int TemplateId { get; set; }
|
||||
public List<DataSourceSelection> DataSources { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DataSourceSelection
|
||||
{
|
||||
public string DatasetId { get; set; } = string.Empty;
|
||||
public int EntityId { get; set; }
|
||||
public string? Alias { get; set; }
|
||||
}
|
||||
|
||||
public class DatasetTypeDto
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
public string Category { get; set; } = "Principale";
|
||||
public bool IsVirtual { get; set; } = false;
|
||||
}
|
||||
|
||||
public class EntityListItemDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string? SecondaryInfo { get; set; }
|
||||
public string? Status { get; set; }
|
||||
}
|
||||
|
||||
public class DataSchemaDto
|
||||
{
|
||||
public string EntityType { get; set; } = string.Empty;
|
||||
public string DatasetId { get; set; } = string.Empty;
|
||||
public List<DataFieldDto> Fields { get; set; } = new();
|
||||
public List<DataCollectionDto> ChildCollections { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DataFieldDto
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = "string";
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string? Group { get; set; }
|
||||
}
|
||||
|
||||
public class DataCollectionDto
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public List<DataFieldDto> Fields { get; set; } = new();
|
||||
}
|
||||
// DTOs moved to AprtModels.cs
|
||||
@@ -507,6 +507,20 @@ public class ModuleService
|
||||
RoutePath = "/hr",
|
||||
IsAvailable = true,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
},
|
||||
new AppModule
|
||||
{
|
||||
Code = "report-designer",
|
||||
Name = "Report Designer",
|
||||
Description = "Creazione e personalizzazione di report e stampe",
|
||||
Icon = "Print",
|
||||
BasePrice = 1000m,
|
||||
MonthlyMultiplier = 1.2m,
|
||||
SortOrder = 80,
|
||||
IsCore = false,
|
||||
RoutePath = "/report-designer",
|
||||
IsAvailable = true,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -398,3 +398,66 @@ public class ReportImageDto
|
||||
public long FileSize { get; set; }
|
||||
public bool Attivo { get; set; } = true;
|
||||
}
|
||||
|
||||
// DTOs moved from ReportsController
|
||||
public class DebugBindingRequest
|
||||
{
|
||||
public List<DataSourceSelection> DataSources { get; set; } = new();
|
||||
public string? PropertyName { get; set; }
|
||||
}
|
||||
|
||||
public class PreviewReportRequest
|
||||
{
|
||||
public int TemplateId { get; set; }
|
||||
public List<DataSourceSelection> DataSources { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DataSourceSelection
|
||||
{
|
||||
public string DatasetId { get; set; } = string.Empty;
|
||||
public int EntityId { get; set; }
|
||||
public string? Alias { get; set; }
|
||||
}
|
||||
|
||||
public class DatasetTypeDto
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
public string Category { get; set; } = "Principale";
|
||||
public bool IsVirtual { get; set; } = false;
|
||||
}
|
||||
|
||||
public class EntityListItemDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string? SecondaryInfo { get; set; }
|
||||
public string? Status { get; set; }
|
||||
}
|
||||
|
||||
public class DataSchemaDto
|
||||
{
|
||||
public string EntityType { get; set; } = string.Empty;
|
||||
public string DatasetId { get; set; } = string.Empty;
|
||||
public List<DataFieldDto> Fields { get; set; } = new();
|
||||
public List<DataCollectionDto> ChildCollections { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DataFieldDto
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = "string";
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string? Group { get; set; }
|
||||
}
|
||||
|
||||
public class DataCollectionDto
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public List<DataFieldDto> Fields { get; set; } = new();
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import { AppLanguageProvider } from "./contexts/LanguageContext";
|
||||
import Layout from "./components/Layout";
|
||||
import Dashboard from "./pages/Dashboard";
|
||||
|
||||
import ReportTemplatesPage from "./pages/ReportTemplatesPage";
|
||||
import ReportEditorPage from "./pages/ReportEditorPage";
|
||||
import ReportDesignerRoutes from "./modules/report-designer/routes";
|
||||
import ModulesAdminPage from "./pages/ModulesAdminPage";
|
||||
import ModulePurchasePage from "./pages/ModulePurchasePage";
|
||||
import AutoCodesAdminPage from "./pages/AutoCodesAdminPage";
|
||||
@@ -59,17 +58,14 @@ function App() {
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<Dashboard />} />
|
||||
|
||||
{/* Report Designer Module */}
|
||||
<Route
|
||||
path="report-templates"
|
||||
element={<ReportTemplatesPage />}
|
||||
/>
|
||||
<Route
|
||||
path="report-editor"
|
||||
element={<ReportEditorPage />}
|
||||
/>
|
||||
<Route
|
||||
path="report-editor/:id"
|
||||
element={<ReportEditorPage />}
|
||||
path="report-designer/*"
|
||||
element={
|
||||
<ModuleGuard moduleCode="report-designer">
|
||||
<ReportDesignerRoutes />
|
||||
</ModuleGuard>
|
||||
}
|
||||
/>
|
||||
{/* Admin */}
|
||||
<Route path="modules" element={<ModulesAdminPage />} />
|
||||
|
||||
@@ -166,7 +166,7 @@ export default function Sidebar({ onClose }: { onClose?: () => void }) {
|
||||
{ id: 'modules', label: t('menu.modules'), icon: <ModulesIcon />, path: '/modules' },
|
||||
{ id: 'autocodes', label: t('menu.autoCodes'), icon: <AutoCodeIcon />, path: '/admin/auto-codes' },
|
||||
{ id: 'customfields', label: t('menu.customFields'), icon: <AutoCodeIcon />, path: '/admin/custom-fields' },
|
||||
{ id: 'reports', label: t('menu.reports'), icon: <PrintIcon />, path: '/report-templates' },
|
||||
{ id: 'reports', label: t('menu.reports'), icon: <PrintIcon />, path: '/report-designer', moduleCode: 'report-designer' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
TextFields as EditTextIcon,
|
||||
Image as ReplaceImageIcon,
|
||||
} from "@mui/icons-material";
|
||||
import type { ZrtElement } from "../../types/report";
|
||||
import type { ZrtElement } from "../../../../types/report";
|
||||
|
||||
export interface ContextMenuPosition {
|
||||
x: number;
|
||||
@@ -46,7 +46,7 @@ import type {
|
||||
DataSchemaDto,
|
||||
DataFieldDto,
|
||||
DatasetTypeDto,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
|
||||
interface DataBindingPanelProps {
|
||||
schemas: DataSchemaDto[];
|
||||
@@ -49,15 +49,15 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
virtualDatasetService,
|
||||
reportGeneratorService,
|
||||
} from "../../services/reportService";
|
||||
} from "../../../../services/reportService";
|
||||
import type {
|
||||
VirtualDatasetDto,
|
||||
VirtualDatasetConfiguration,
|
||||
VirtualDatasetSource,
|
||||
DatasetTypeDto,
|
||||
VirtualDatasetValidationResult,
|
||||
} from "../../types/report";
|
||||
import { defaultVirtualDatasetConfiguration } from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
import { defaultVirtualDatasetConfiguration } from "../../../../types/report";
|
||||
import RelationshipEditor from "./RelationshipEditor";
|
||||
import FilterBuilder from "./FilterBuilder";
|
||||
import OutputFieldsEditor from "./OutputFieldsEditor";
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
ExpandMore as ExpandMoreIcon,
|
||||
ExpandLess as ExpandLessIcon,
|
||||
} from "@mui/icons-material";
|
||||
import type { DatasetTypeDto } from "../../types/report";
|
||||
import type { DatasetTypeDto } from "../../../../types/report";
|
||||
|
||||
interface DatasetSelectorProps {
|
||||
availableDatasets: DatasetTypeDto[];
|
||||
@@ -13,13 +13,13 @@ import type {
|
||||
ZrtElement,
|
||||
PageSize,
|
||||
PageOrientation,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
import {
|
||||
getPageDimensions,
|
||||
mmToPx,
|
||||
pxToMm,
|
||||
defaultStyle,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
import type { SnapOptions } from "./EditorToolbar";
|
||||
|
||||
// Extend fabric types to include data property
|
||||
@@ -66,7 +66,7 @@ import {
|
||||
History as HistoryIcon,
|
||||
AutoMode as AutoSaveIcon,
|
||||
} from "@mui/icons-material";
|
||||
import type { ElementType } from "../../types/report";
|
||||
import type { ElementType } from "../../../../types/report";
|
||||
|
||||
// Snap options type
|
||||
export interface SnapOptions {
|
||||
@@ -22,12 +22,12 @@ import {
|
||||
FilterList as FilterIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useQueries } from "@tanstack/react-query";
|
||||
import { reportGeneratorService } from "../../services/reportService";
|
||||
import { reportGeneratorService } from "../../../../services/reportService";
|
||||
import type {
|
||||
VirtualDatasetSource,
|
||||
VirtualDatasetFilter,
|
||||
DatasetTypeDto,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
|
||||
interface FilterBuilderProps {
|
||||
sources: VirtualDatasetSource[];
|
||||
@@ -348,7 +348,7 @@ export default function FilterBuilder({
|
||||
selectedField?.type === "date"
|
||||
? "YYYY-MM-DD"
|
||||
: selectedField?.type === "number" ||
|
||||
selectedField?.type === "currency"
|
||||
selectedField?.type === "currency"
|
||||
? "0"
|
||||
: "Testo"
|
||||
}
|
||||
@@ -30,13 +30,13 @@ import {
|
||||
AttachMoney as CurrencyIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useQueries } from "@tanstack/react-query";
|
||||
import { reportGeneratorService } from "../../services/reportService";
|
||||
import { reportGeneratorService } from "../../../../services/reportService";
|
||||
import type {
|
||||
VirtualDatasetSource,
|
||||
VirtualDatasetOutputField,
|
||||
DatasetTypeDto,
|
||||
DataFieldDto,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
|
||||
interface OutputFieldsEditorProps {
|
||||
sources: VirtualDatasetSource[];
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
KeyboardArrowUp as MoveUpIcon,
|
||||
KeyboardArrowDown as MoveDownIcon,
|
||||
} from "@mui/icons-material";
|
||||
import type { ZrtPage, ZrtElement } from "../../types/report";
|
||||
import type { ZrtPage, ZrtElement } from "../../../../types/report";
|
||||
|
||||
interface PageNavigatorProps {
|
||||
pages: ZrtPage[];
|
||||
@@ -44,12 +44,12 @@ import {
|
||||
ArrowBack as BackIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useQueries } from "@tanstack/react-query";
|
||||
import { reportGeneratorService } from "../../services/reportService";
|
||||
import { reportGeneratorService } from "../../../../services/reportService";
|
||||
import type {
|
||||
DatasetTypeDto,
|
||||
DataSourceSelection,
|
||||
EntityListItemDto,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
|
||||
interface PreviewDialogProps {
|
||||
open: boolean;
|
||||
@@ -54,8 +54,8 @@ import type {
|
||||
ZrtTableColumn,
|
||||
DataSchemaDto,
|
||||
DatasetTypeDto,
|
||||
} from "../../types/report";
|
||||
import { defaultImageSettings } from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
import { defaultImageSettings } from "../../../../types/report";
|
||||
|
||||
interface PropertiesPanelProps {
|
||||
element: ZrtElement | null;
|
||||
@@ -21,13 +21,13 @@ import {
|
||||
ArrowForward as ArrowIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useQueries } from "@tanstack/react-query";
|
||||
import { reportGeneratorService } from "../../services/reportService";
|
||||
import { reportGeneratorService } from "../../../../services/reportService";
|
||||
import type {
|
||||
VirtualDatasetSource,
|
||||
VirtualDatasetRelationship,
|
||||
DatasetTypeDto,
|
||||
DataSchemaDto,
|
||||
} from "../../types/report";
|
||||
} from "../../../../types/report";
|
||||
|
||||
interface RelationshipEditorProps {
|
||||
sources: VirtualDatasetSource[];
|
||||
@@ -7,14 +7,14 @@ import {
|
||||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useHistory } from "../hooks/useHistory";
|
||||
import { usePanelLayout } from "../hooks/usePanelLayout";
|
||||
import { useCollaborationRoom } from "../contexts/CollaborationContext";
|
||||
import { useHistory } from "../../../hooks/useHistory";
|
||||
import { usePanelLayout } from "../../../hooks/usePanelLayout";
|
||||
import { useCollaborationRoom } from "../../../contexts/CollaborationContext";
|
||||
import type {
|
||||
DataChangeMessage,
|
||||
ItemCreatedMessage,
|
||||
ItemDeletedMessage,
|
||||
} from "../services/collaboration";
|
||||
} from "../../../services/collaboration";
|
||||
import {
|
||||
Box,
|
||||
CircularProgress,
|
||||
@@ -72,7 +72,7 @@ import {
|
||||
reportGeneratorService,
|
||||
virtualDatasetService,
|
||||
openBlobInNewTab,
|
||||
} from "../services/reportService";
|
||||
} from "../../../services/reportService";
|
||||
import type {
|
||||
ZrtTemplate,
|
||||
ZrtElement,
|
||||
@@ -85,13 +85,13 @@ import type {
|
||||
DatasetTypeDto,
|
||||
DataSourceSelection,
|
||||
ReportTemplateDto,
|
||||
} from "../types/report";
|
||||
} from "../../../types/report";
|
||||
import {
|
||||
defaultTemplate,
|
||||
defaultStyle,
|
||||
defaultImageSettings,
|
||||
defaultPage,
|
||||
} from "../types/report";
|
||||
} from "../../../types/report";
|
||||
|
||||
// Panel types for mobile navigation
|
||||
type MobilePanel = "pages" | "data" | "properties" | null;
|
||||
@@ -632,7 +632,7 @@ export default function ReportEditorPage() {
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
navigate(`/report-editor/${result.id}`, { replace: true });
|
||||
navigate(`/report-designer/editor/${result.id}`, { replace: true });
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -38,8 +38,8 @@ import {
|
||||
Description as DescriptionIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { reportTemplateService, downloadBlob } from "../services/reportService";
|
||||
import type { ReportTemplateDto } from "../types/report";
|
||||
import { reportTemplateService, downloadBlob } from "../../../services/reportService";
|
||||
import type { ReportTemplateDto } from "../../../types/report";
|
||||
|
||||
export default function ReportTemplatesPage() {
|
||||
const navigate = useNavigate();
|
||||
@@ -92,7 +92,7 @@ export default function ReportTemplatesPage() {
|
||||
queryClient.invalidateQueries({ queryKey: ["report-templates"] });
|
||||
setImportDialog(false);
|
||||
setImportFile(null);
|
||||
navigate(`/report-editor/${newTemplate.id}`);
|
||||
navigate(`/report-designer/editor/${newTemplate.id}`);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -179,7 +179,7 @@ export default function ReportTemplatesPage() {
|
||||
<Button
|
||||
variant="contained"
|
||||
startIcon={<AddIcon />}
|
||||
onClick={() => navigate("/report-editor")}
|
||||
onClick={() => navigate("/report-designer/editor")}
|
||||
>
|
||||
{t("reports.newTemplate")}
|
||||
</Button>
|
||||
@@ -265,7 +265,7 @@ export default function ReportTemplatesPage() {
|
||||
<Button
|
||||
variant="contained"
|
||||
startIcon={<AddIcon />}
|
||||
onClick={() => navigate("/report-editor")}
|
||||
onClick={() => navigate("/report-designer/editor")}
|
||||
fullWidth={isMobile}
|
||||
>
|
||||
{t("reports.createTemplate")}
|
||||
@@ -388,7 +388,7 @@ export default function ReportTemplatesPage() {
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() =>
|
||||
navigate(`/report-editor/${template.id}`)
|
||||
navigate(`/report-designer/editor/${template.id}`)
|
||||
}
|
||||
>
|
||||
<EditIcon fontSize={isMobile ? "small" : "medium"} />
|
||||
@@ -435,7 +435,7 @@ export default function ReportTemplatesPage() {
|
||||
<Fab
|
||||
color="primary"
|
||||
aria-label={t("reports.newTemplate")}
|
||||
onClick={() => navigate("/report-editor")}
|
||||
onClick={() => navigate("/report-designer/editor")}
|
||||
sx={{
|
||||
position: "fixed",
|
||||
bottom: 16,
|
||||
13
src/frontend/src/modules/report-designer/routes.tsx
Normal file
13
src/frontend/src/modules/report-designer/routes.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
import ReportTemplatesPage from "./pages/ReportTemplatesPage";
|
||||
import ReportEditorPage from "./pages/ReportEditorPage";
|
||||
|
||||
export default function ReportDesignerRoutes() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route index element={<ReportTemplatesPage />} />
|
||||
<Route path="editor" element={<ReportEditorPage />} />
|
||||
<Route path="editor/:id" element={<ReportEditorPage />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
@@ -19,19 +19,19 @@ import type {
|
||||
export const reportTemplateService = {
|
||||
getAll: async (categoria?: string): Promise<ReportTemplateDto[]> => {
|
||||
const params = categoria ? { categoria } : {};
|
||||
const response = await api.get("/report-templates", { params });
|
||||
const response = await api.get("/report-designer/templates", { params });
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getById: async (id: number): Promise<ReportTemplateDto> => {
|
||||
const response = await api.get(`/report-templates/${id}`);
|
||||
const response = await api.get(`/report-designer/templates/${id}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
create: async (
|
||||
template: Partial<ReportTemplateDto>,
|
||||
): Promise<ReportTemplateDto> => {
|
||||
const response = await api.post("/report-templates", template);
|
||||
const response = await api.post("/report-designer/templates", template);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
@@ -39,21 +39,21 @@ export const reportTemplateService = {
|
||||
id: number,
|
||||
template: Partial<ReportTemplateDto>,
|
||||
): Promise<ReportTemplateDto> => {
|
||||
const response = await api.put(`/report-templates/${id}`, template);
|
||||
const response = await api.put(`/report-designer/templates/${id}`, template);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
delete: async (id: number): Promise<void> => {
|
||||
await api.delete(`/report-templates/${id}`);
|
||||
await api.delete(`/report-designer/templates/${id}`);
|
||||
},
|
||||
|
||||
clone: async (id: number): Promise<ReportTemplateDto> => {
|
||||
const response = await api.post(`/report-templates/${id}/clone`);
|
||||
const response = await api.post(`/report-designer/templates/${id}/clone`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
export: async (id: number): Promise<Blob> => {
|
||||
const response = await api.get(`/report-templates/${id}/export`, {
|
||||
const response = await api.get(`/report-designer/templates/${id}/export`, {
|
||||
responseType: "blob",
|
||||
});
|
||||
return response.data;
|
||||
@@ -62,14 +62,14 @@ export const reportTemplateService = {
|
||||
import: async (file: File): Promise<ReportTemplateDto> => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
const response = await api.post("/report-templates/import", formData, {
|
||||
const response = await api.post("/report-designer/templates/import", formData, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getCategories: async (): Promise<string[]> => {
|
||||
const response = await api.get("/report-templates/categories");
|
||||
const response = await api.get("/report-designer/templates/categories");
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
@@ -77,12 +77,12 @@ export const reportTemplateService = {
|
||||
// Fonts
|
||||
export const reportFontService = {
|
||||
getAll: async (): Promise<ReportFontDto[]> => {
|
||||
const response = await api.get("/report-resources/fonts");
|
||||
const response = await api.get("/report-designer/resources/fonts");
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getById: async (id: number): Promise<ReportFontDto> => {
|
||||
const response = await api.get(`/report-resources/fonts/${id}`);
|
||||
const response = await api.get(`/report-designer/resources/fonts/${id}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
@@ -97,18 +97,18 @@ export const reportFontService = {
|
||||
formData.append("fontFamily", fontFamily);
|
||||
formData.append("fontStyle", fontStyle);
|
||||
formData.append("file", file);
|
||||
const response = await api.post("/report-resources/fonts", formData, {
|
||||
const response = await api.post("/report-designer/resources/fonts", formData, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
delete: async (id: number): Promise<void> => {
|
||||
await api.delete(`/report-resources/fonts/${id}`);
|
||||
await api.delete(`/report-designer/resources/fonts/${id}`);
|
||||
},
|
||||
|
||||
getFamilies: async (): Promise<string[]> => {
|
||||
const response = await api.get("/report-resources/fonts/families");
|
||||
const response = await api.get("/report-designer/resources/fonts/families");
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
@@ -117,12 +117,12 @@ export const reportFontService = {
|
||||
export const reportImageService = {
|
||||
getAll: async (categoria?: string): Promise<ReportImageDto[]> => {
|
||||
const params = categoria ? { categoria } : {};
|
||||
const response = await api.get("/report-resources/images", { params });
|
||||
const response = await api.get("/report-designer/resources/images", { params });
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getById: async (id: number): Promise<ReportImageDto> => {
|
||||
const response = await api.get(`/report-resources/images/${id}`);
|
||||
const response = await api.get(`/report-designer/resources/images/${id}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
@@ -135,7 +135,7 @@ export const reportImageService = {
|
||||
formData.append("nome", nome);
|
||||
formData.append("categoria", categoria);
|
||||
formData.append("file", file);
|
||||
const response = await api.post("/report-resources/images", formData, {
|
||||
const response = await api.post("/report-designer/resources/images", formData, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
return response.data;
|
||||
@@ -145,16 +145,16 @@ export const reportImageService = {
|
||||
id: number,
|
||||
data: Partial<ReportImageDto>,
|
||||
): Promise<ReportImageDto> => {
|
||||
const response = await api.put(`/report-resources/images/${id}`, data);
|
||||
const response = await api.put(`/report-designer/resources/images/${id}`, data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
delete: async (id: number): Promise<void> => {
|
||||
await api.delete(`/report-resources/images/${id}`);
|
||||
await api.delete(`/report-designer/resources/images/${id}`);
|
||||
},
|
||||
|
||||
getCategories: async (): Promise<string[]> => {
|
||||
const response = await api.get("/report-resources/images/categories");
|
||||
const response = await api.get("/report-designer/resources/images/categories");
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
@@ -162,7 +162,7 @@ export const reportImageService = {
|
||||
// Report Generation
|
||||
export const reportGeneratorService = {
|
||||
generate: async (request: GenerateReportRequest): Promise<Blob> => {
|
||||
const response = await api.post("/reports/generate", request, {
|
||||
const response = await api.post("/report-designer/reports/generate", request, {
|
||||
responseType: "blob",
|
||||
});
|
||||
return response.data;
|
||||
@@ -173,7 +173,7 @@ export const reportGeneratorService = {
|
||||
templateId?: number,
|
||||
): Promise<Blob> => {
|
||||
const params = templateId ? { templateId } : {};
|
||||
const response = await api.get(`/reports/evento/${eventoId}`, {
|
||||
const response = await api.get(`/report-designer/reports/evento/${eventoId}`, {
|
||||
params,
|
||||
responseType: "blob",
|
||||
});
|
||||
@@ -181,26 +181,26 @@ export const reportGeneratorService = {
|
||||
},
|
||||
|
||||
preview: async (request: PreviewReportRequest): Promise<Blob> => {
|
||||
const response = await api.post("/reports/preview", request, {
|
||||
const response = await api.post("/report-designer/reports/preview", request, {
|
||||
responseType: "blob",
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getSchema: async (datasetId: string): Promise<DataSchemaDto> => {
|
||||
const response = await api.get(`/reports/schema/${datasetId}`);
|
||||
const response = await api.get(`/report-designer/reports/schema/${datasetId}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getAvailableDatasets: async (): Promise<DatasetTypeDto[]> => {
|
||||
const response = await api.get("/reports/datasets");
|
||||
const response = await api.get("/report-designer/reports/datasets");
|
||||
return response.data;
|
||||
},
|
||||
|
||||
getEntitiesForDataset: async (
|
||||
datasetId: string,
|
||||
): Promise<EntityListItemDto[]> => {
|
||||
const response = await api.get(`/reports/datasets/${datasetId}/entities`);
|
||||
const response = await api.get(`/report-designer/reports/datasets/${datasetId}/entities`);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user