refactor: reorganize autocodes into modules with updated UI, new translations, and backend migrations.
This commit is contained in:
@@ -47,3 +47,5 @@ File riassuntivo dello stato di sviluppo di Zentral.
|
|||||||
- [2025-12-06 01:48:00 - Traduzione Modulo Acquisti](./devlog/2025-12-06-014800_translate_purchases.md) - **Completato**
|
- [2025-12-06 01:48:00 - Traduzione Modulo Acquisti](./devlog/2025-12-06-014800_translate_purchases.md) - **Completato**
|
||||||
- [2025-12-06 01:35:00 - Fix Traduzione Tab Applicazioni](./devlog/2025-12-06-013500_fix_apps_tab_translation.md) - **Completato**
|
- [2025-12-06 01:35:00 - Fix Traduzione Tab Applicazioni](./devlog/2025-12-06-013500_fix_apps_tab_translation.md) - **Completato**
|
||||||
- Corretta chiave di traduzione errata per la tab "Gestione Applicazioni" e migliorata la gestione dell'aggiornamento etichette tab.
|
- Corretta chiave di traduzione errata per la tab "Gestione Applicazioni" e migliorata la gestione dell'aggiornamento etichette tab.
|
||||||
|
- [2025-12-06 Auto Codes Reorganization](./devlog/2025-12-06-021000_autocodes_reorg.md) - **Completato**
|
||||||
|
- Riorganizzazione UI Auto Codes, allineamento stile a Custom Fields, miglioramento traduzioni e categorizzazione.
|
||||||
|
|||||||
30
docs/development/devlog/2025-12-06-021000_autocodes_reorg.md
Normal file
30
docs/development/devlog/2025-12-06-021000_autocodes_reorg.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Riorganizzazione Auto Codes
|
||||||
|
|
||||||
|
## Obiettivo
|
||||||
|
Riorganizzare la sezione "Auto Codes" per allinearla graficamente e strutturalmente alla sezione "Custom Fields", migliorando le traduzioni e la categorizzazione.
|
||||||
|
|
||||||
|
## Stato Attuale
|
||||||
|
- La pagina `AutoCodesAdminPage.tsx` funziona ma ha nomi di moduli hardcoded in `types/autoCode.ts`.
|
||||||
|
- La struttura grafica è simile ma può essere migliorata per essere identica a `CustomFieldsAdminPage`.
|
||||||
|
- Mancano alcune traduzioni e la categorizzazione potrebbe non essere aggiornata con gli ultimi moduli.
|
||||||
|
|
||||||
|
## Piano di Lavoro
|
||||||
|
1. **Analisi e Preparazione**
|
||||||
|
- [x] Identificare le differenze stilistiche tra `AutoCodesAdminPage` e `CustomFieldsAdminPage`.
|
||||||
|
- [x] Identificare le stringhe non tradotte (es. nomi moduli).
|
||||||
|
|
||||||
|
2. **Refactoring Frontend**
|
||||||
|
- [x] Aggiornare `AutoCodesAdminPage.tsx` per usare lo stesso layout di `CustomFieldsAdminPage`.
|
||||||
|
- [x] Sostituire i nomi hardcoded dei moduli con chiavi di traduzione.
|
||||||
|
- [x] Aggiornare `types/autoCode.ts` per rimuovere `appNames` hardcoded o mapparlo su chiavi i18n.
|
||||||
|
|
||||||
|
3. **Aggiornamento Traduzioni**
|
||||||
|
- [x] Aggiungere le chiavi mancanti in `public/locales/it/translation.json`.
|
||||||
|
- [x] Aggiungere le chiavi mancanti in `public/locales/en/translation.json`.
|
||||||
|
|
||||||
|
4. **Verifica**
|
||||||
|
- [x] Verificare che la pagina si carichi correttamente.
|
||||||
|
- [x] Verificare che le traduzioni funzionino.
|
||||||
|
- [x] Verificare che la categorizzazione sia corretta.
|
||||||
|
- [x] Aggiornare `AutoCodeDto` nel frontend per usare `moduleCode`.
|
||||||
|
- [x] Creare migrazione per aggiornare `ModuleCode` nel database per le entità esistenti.
|
||||||
4704
src/backend/Zentral.Infrastructure/Migrations/20251206011423_UpdateAutoCodeModules.Designer.cs
generated
Normal file
4704
src/backend/Zentral.Infrastructure/Migrations/20251206011423_UpdateAutoCodeModules.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Zentral.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class UpdateAutoCodeModules : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql("UPDATE AutoCodes SET ModuleCode = 'warehouse' WHERE EntityCode IN ('warehouse_article', 'warehouse_location', 'inventory_count', 'stock_movement', 'stock_valuation')");
|
||||||
|
migrationBuilder.Sql("UPDATE AutoCodes SET ModuleCode = 'purchases' WHERE EntityCode IN ('supplier', 'purchase_order')");
|
||||||
|
migrationBuilder.Sql("UPDATE AutoCodes SET ModuleCode = 'sales' WHERE EntityCode IN ('sales_order')");
|
||||||
|
migrationBuilder.Sql("UPDATE AutoCodes SET ModuleCode = 'production' WHERE EntityCode IN ('production_order', 'bill_of_materials', 'work_center', 'production_cycle')");
|
||||||
|
migrationBuilder.Sql("UPDATE AutoCodes SET ModuleCode = 'core' WHERE EntityCode IN ('cliente')");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"none": "None",
|
"none": "None",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
|
"copy": "Copy",
|
||||||
"required": "Required",
|
"required": "Required",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"active": "Active",
|
"active": "Active",
|
||||||
@@ -431,10 +432,20 @@
|
|||||||
"patternHelper": "Pattern for code generation",
|
"patternHelper": "Pattern for code generation",
|
||||||
"previewLabel": "Preview:",
|
"previewLabel": "Preview:",
|
||||||
"resetSequence": "Reset Sequence",
|
"resetSequence": "Reset Sequence",
|
||||||
|
"description": "Description",
|
||||||
"everyYear": "Every year",
|
"everyYear": "Every year",
|
||||||
"everyMonth": "Every month",
|
"everyMonth": "Every month",
|
||||||
"generationActive": "Generation active",
|
"generationActive": "Generation active",
|
||||||
"readOnly": "Code not editable"
|
"readOnly": "Code not editable",
|
||||||
|
"noConfigs": "No automatic codes configured for this app.",
|
||||||
|
"modules": {
|
||||||
|
"core": "Core System",
|
||||||
|
"warehouse": "Warehouse",
|
||||||
|
"purchases": "Purchases",
|
||||||
|
"sales": "Sales",
|
||||||
|
"production": "Production",
|
||||||
|
"quality": "Quality"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"customFields": {
|
"customFields": {
|
||||||
"title": "Custom Fields Management",
|
"title": "Custom Fields Management",
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
"notes": "Note",
|
"notes": "Note",
|
||||||
"preview": "Anteprima",
|
"preview": "Anteprima",
|
||||||
"none": "Nessuno",
|
"none": "Nessuno",
|
||||||
"view": "Dettaglio"
|
"view": "Dettaglio",
|
||||||
|
"copy": "Copia"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
@@ -428,10 +429,20 @@
|
|||||||
"patternHelper": "Pattern per generazione codice",
|
"patternHelper": "Pattern per generazione codice",
|
||||||
"previewLabel": "Anteprima:",
|
"previewLabel": "Anteprima:",
|
||||||
"resetSequence": "Reset Sequenza",
|
"resetSequence": "Reset Sequenza",
|
||||||
|
"description": "Descrizione",
|
||||||
"everyYear": "Ogni anno",
|
"everyYear": "Ogni anno",
|
||||||
"everyMonth": "Ogni mese",
|
"everyMonth": "Ogni mese",
|
||||||
"generationActive": "Generazione attiva",
|
"generationActive": "Generazione attiva",
|
||||||
"readOnly": "Codice non modificabile"
|
"readOnly": "Codice non modificabile",
|
||||||
|
"noConfigs": "Nessun codice automatico configurato per questa applicazione.",
|
||||||
|
"modules": {
|
||||||
|
"core": "Sistema Base",
|
||||||
|
"warehouse": "Magazzino",
|
||||||
|
"purchases": "Acquisti",
|
||||||
|
"sales": "Vendite",
|
||||||
|
"production": "Produzione",
|
||||||
|
"quality": "Qualità"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"customFields": {
|
"customFields": {
|
||||||
"title": "Gestione Campi Personalizzati",
|
"title": "Gestione Campi Personalizzati",
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import type {
|
|||||||
AutoCodeUpdateDto,
|
AutoCodeUpdateDto,
|
||||||
PlaceholderInfo,
|
PlaceholderInfo,
|
||||||
} from "../types/autoCode";
|
} from "../types/autoCode";
|
||||||
import { groupByModule, appNames, appIcons } from "../types/autoCode";
|
import { groupByModule, appIcons } from "../types/autoCode";
|
||||||
|
|
||||||
export default function AutoCodesAdminPage() {
|
export default function AutoCodesAdminPage() {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@@ -169,150 +169,163 @@ export default function AutoCodesAdminPage() {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Accordion per moduli */}
|
{/* Accordion per moduli */}
|
||||||
{Object.entries(groupedConfigs).map(([appCode, moduleConfigs]) => (
|
{Object.keys(appIcons).map((appCode) => {
|
||||||
<Accordion
|
const moduleConfigs = groupedConfigs[appCode] || [];
|
||||||
key={appCode}
|
return (
|
||||||
expanded={expandedModule === appCode}
|
<Accordion
|
||||||
onChange={(_, isExpanded) =>
|
key={appCode}
|
||||||
setExpandedModule(isExpanded ? appCode : false)
|
expanded={expandedModule === appCode}
|
||||||
}
|
onChange={(_, isExpanded) =>
|
||||||
sx={{ mb: 1 }}
|
setExpandedModule(isExpanded ? appCode : false)
|
||||||
>
|
}
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
sx={{ mb: 1 }}
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
>
|
||||||
{getAppIcon(appCode)}
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography variant="h6">
|
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||||
{appNames[appCode] || appCode}
|
{getAppIcon(appCode)}
|
||||||
</Typography>
|
<Typography variant="h6">
|
||||||
<Chip
|
{t(`autoCodes.modules.${appCode}`) || appCode}
|
||||||
label={`${moduleConfigs.length} configurazioni`}
|
</Typography>
|
||||||
size="small"
|
<Chip
|
||||||
variant="outlined"
|
label={`${moduleConfigs.length} configurazioni`}
|
||||||
/>
|
size="small"
|
||||||
</Box>
|
variant="outlined"
|
||||||
</AccordionSummary>
|
/>
|
||||||
<AccordionDetails>
|
</Box>
|
||||||
<TableContainer component={Paper} variant="outlined">
|
</AccordionSummary>
|
||||||
<Table size="small">
|
<AccordionDetails>
|
||||||
<TableHead>
|
{moduleConfigs.length === 0 ? (
|
||||||
<TableRow>
|
<Typography
|
||||||
<TableCell>{t("autoCodes.entity")}</TableCell>
|
color="text.secondary"
|
||||||
<TableCell>{t("autoCodes.prefix")}</TableCell>
|
align="center"
|
||||||
<TableCell>{t("autoCodes.pattern")}</TableCell>
|
sx={{ py: 2 }}
|
||||||
<TableCell>{t("autoCodes.example")}</TableCell>
|
>
|
||||||
<TableCell>{t("autoCodes.sequence")}</TableCell>
|
{t("autoCodes.noConfigs")}
|
||||||
<TableCell>{t("autoCodes.reset")}</TableCell>
|
</Typography>
|
||||||
<TableCell align="center">{t("autoCodes.status")}</TableCell>
|
) : (
|
||||||
<TableCell align="right">{t("common.actions")}</TableCell>
|
<TableContainer component={Paper} variant="outlined">
|
||||||
</TableRow>
|
<Table size="small">
|
||||||
</TableHead>
|
<TableHead>
|
||||||
<TableBody>
|
<TableRow>
|
||||||
{moduleConfigs.map((config) => (
|
<TableCell>{t("autoCodes.entity")}</TableCell>
|
||||||
<TableRow key={config.id} hover>
|
<TableCell>{t("autoCodes.prefix")}</TableCell>
|
||||||
<TableCell>
|
<TableCell>{t("autoCodes.pattern")}</TableCell>
|
||||||
<Box>
|
<TableCell>{t("autoCodes.example")}</TableCell>
|
||||||
<Typography variant="body2" fontWeight="medium">
|
<TableCell>{t("autoCodes.sequence")}</TableCell>
|
||||||
{config.entityName}
|
<TableCell>{t("autoCodes.reset")}</TableCell>
|
||||||
</Typography>
|
<TableCell align="center">{t("autoCodes.status")}</TableCell>
|
||||||
<Typography variant="caption" color="text.secondary">
|
<TableCell align="right">{t("common.actions")}</TableCell>
|
||||||
{config.entityCode}
|
</TableRow>
|
||||||
</Typography>
|
</TableHead>
|
||||||
</Box>
|
<TableBody>
|
||||||
</TableCell>
|
{moduleConfigs.map((config) => (
|
||||||
<TableCell>
|
<TableRow key={config.id} hover>
|
||||||
<Chip
|
<TableCell>
|
||||||
label={config.prefix || "-"}
|
<Box>
|
||||||
size="small"
|
<Typography variant="body2" fontWeight="medium">
|
||||||
variant="outlined"
|
{config.entityName}
|
||||||
/>
|
</Typography>
|
||||||
</TableCell>
|
<Typography variant="caption" color="text.secondary">
|
||||||
<TableCell>
|
{config.entityCode}
|
||||||
<Typography
|
</Typography>
|
||||||
variant="body2"
|
</Box>
|
||||||
sx={{ fontFamily: "monospace", fontSize: "0.85rem" }}
|
</TableCell>
|
||||||
>
|
<TableCell>
|
||||||
{config.pattern}
|
<Chip
|
||||||
</Typography>
|
label={config.prefix || "-"}
|
||||||
</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 0.5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
sx={{
|
|
||||||
fontFamily: "monospace",
|
|
||||||
color: "primary.main",
|
|
||||||
fontWeight: "medium",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{config.exampleCode}
|
|
||||||
</Typography>
|
|
||||||
<Tooltip title={t("autoCodes.previewTooltip")}>
|
|
||||||
<IconButton
|
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() =>
|
variant="outlined"
|
||||||
previewMutation.mutate(config.entityCode)
|
/>
|
||||||
}
|
</TableCell>
|
||||||
disabled={!config.isEnabled}
|
<TableCell>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{ fontFamily: "monospace", fontSize: "0.85rem" }}
|
||||||
>
|
>
|
||||||
<PreviewIcon fontSize="small" />
|
{config.pattern}
|
||||||
</IconButton>
|
</Typography>
|
||||||
</Tooltip>
|
</TableCell>
|
||||||
</Box>
|
<TableCell>
|
||||||
</TableCell>
|
<Box
|
||||||
<TableCell>
|
sx={{
|
||||||
<Typography variant="body2">
|
display: "flex",
|
||||||
{config.lastSequence}
|
alignItems: "center",
|
||||||
</Typography>
|
gap: 0.5,
|
||||||
</TableCell>
|
}}
|
||||||
<TableCell>
|
>
|
||||||
{config.resetSequenceMonthly ? (
|
<Typography
|
||||||
<Chip label={t("autoCodes.monthly")} size="small" color="info" />
|
variant="body2"
|
||||||
) : config.resetSequenceYearly ? (
|
sx={{
|
||||||
<Chip label={t("autoCodes.yearly")} size="small" color="warning" />
|
fontFamily: "monospace",
|
||||||
) : (
|
color: "primary.main",
|
||||||
<Chip label={t("autoCodes.never")} size="small" variant="outlined" />
|
fontWeight: "medium",
|
||||||
)}
|
}}
|
||||||
</TableCell>
|
>
|
||||||
<TableCell align="center">
|
{config.exampleCode}
|
||||||
<Chip
|
</Typography>
|
||||||
label={config.isEnabled ? t("apps.admin.active") : t("apps.admin.inactive")}
|
<Tooltip title={t("autoCodes.previewTooltip")}>
|
||||||
size="small"
|
<IconButton
|
||||||
color={config.isEnabled ? "success" : "default"}
|
size="small"
|
||||||
/>
|
onClick={() =>
|
||||||
</TableCell>
|
previewMutation.mutate(config.entityCode)
|
||||||
<TableCell align="right">
|
}
|
||||||
<Tooltip title={t("common.edit")}>
|
disabled={!config.isEnabled}
|
||||||
<IconButton
|
>
|
||||||
size="small"
|
<PreviewIcon fontSize="small" />
|
||||||
onClick={() => setEditingConfig(config)}
|
</IconButton>
|
||||||
>
|
</Tooltip>
|
||||||
<EditIcon fontSize="small" />
|
</Box>
|
||||||
</IconButton>
|
</TableCell>
|
||||||
</Tooltip>
|
<TableCell>
|
||||||
<Tooltip title={t("autoCodes.resetTooltip")}>
|
<Typography variant="body2">
|
||||||
<IconButton
|
{config.lastSequence}
|
||||||
size="small"
|
</Typography>
|
||||||
onClick={() => setConfirmReset(config.entityCode)}
|
</TableCell>
|
||||||
disabled={!config.isEnabled}
|
<TableCell>
|
||||||
>
|
{config.resetSequenceMonthly ? (
|
||||||
<ResetIcon fontSize="small" />
|
<Chip label={t("autoCodes.monthly")} size="small" color="info" />
|
||||||
</IconButton>
|
) : config.resetSequenceYearly ? (
|
||||||
</Tooltip>
|
<Chip label={t("autoCodes.yearly")} size="small" color="warning" />
|
||||||
</TableCell>
|
) : (
|
||||||
</TableRow>
|
<Chip label={t("autoCodes.never")} size="small" variant="outlined" />
|
||||||
))}
|
)}
|
||||||
</TableBody>
|
</TableCell>
|
||||||
</Table>
|
<TableCell align="center">
|
||||||
</TableContainer>
|
<Chip
|
||||||
</AccordionDetails>
|
label={config.isEnabled ? t("apps.admin.active") : t("apps.admin.inactive")}
|
||||||
</Accordion>
|
size="small"
|
||||||
))}
|
color={config.isEnabled ? "success" : "default"}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Tooltip title={t("common.edit")}>
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => setEditingConfig(config)}
|
||||||
|
>
|
||||||
|
<EditIcon fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title={t("autoCodes.resetTooltip")}>
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => setConfirmReset(config.entityCode)}
|
||||||
|
disabled={!config.isEnabled}
|
||||||
|
>
|
||||||
|
<ResetIcon fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
)}
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
{/* Dialog modifica configurazione */}
|
{/* Dialog modifica configurazione */}
|
||||||
<EditConfigDialog
|
<EditConfigDialog
|
||||||
@@ -396,7 +409,7 @@ export default function AutoCodesAdminPage() {
|
|||||||
>
|
>
|
||||||
{previewCode}
|
{previewCode}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Tooltip title="Copia">
|
<Tooltip title={t("common.copy")}>
|
||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -718,7 +731,7 @@ function EditConfigDialog({
|
|||||||
|
|
||||||
<Grid size={{ xs: 12 }}>
|
<Grid size={{ xs: 12 }}>
|
||||||
<TextField
|
<TextField
|
||||||
label="Descrizione"
|
label={t("autoCodes.description")}
|
||||||
value={formData.description ?? config.description ?? ""}
|
value={formData.description ?? config.description ?? ""}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setFormData({
|
setFormData({
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export interface AutoCodeDto {
|
|||||||
lastResetMonth: number | null;
|
lastResetMonth: number | null;
|
||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
isReadOnly: boolean;
|
isReadOnly: boolean;
|
||||||
appCode: string | null;
|
moduleCode: string | null;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
sortOrder: number;
|
sortOrder: number;
|
||||||
exampleCode: string;
|
exampleCode: string;
|
||||||
@@ -60,7 +60,7 @@ export interface PlaceholderInfo {
|
|||||||
*/
|
*/
|
||||||
export function groupByModule(configs: AutoCodeDto[]): Record<string, AutoCodeDto[]> {
|
export function groupByModule(configs: AutoCodeDto[]): Record<string, AutoCodeDto[]> {
|
||||||
return configs.reduce((acc, config) => {
|
return configs.reduce((acc, config) => {
|
||||||
const module = config.appCode || "core";
|
const module = config.moduleCode || "core";
|
||||||
if (!acc[module]) {
|
if (!acc[module]) {
|
||||||
acc[module] = [];
|
acc[module] = [];
|
||||||
}
|
}
|
||||||
@@ -69,17 +69,7 @@ export function groupByModule(configs: AutoCodeDto[]): Record<string, AutoCodeDt
|
|||||||
}, {} as Record<string, AutoCodeDto[]>);
|
}, {} as Record<string, AutoCodeDto[]>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Nomi visualizzati per i moduli
|
|
||||||
*/
|
|
||||||
export const appNames: Record<string, string> = {
|
|
||||||
core: "Sistema Base",
|
|
||||||
warehouse: "Magazzino",
|
|
||||||
purchases: "Acquisti",
|
|
||||||
sales: "Vendite",
|
|
||||||
production: "Produzione",
|
|
||||||
quality: "Qualità",
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Icone per i moduli (nomi MUI icons)
|
* Icone per i moduli (nomi MUI icons)
|
||||||
|
|||||||
Reference in New Issue
Block a user