Data
ReportDesigner
Designer visuale a tre pannelli per report personalizzati — palette dei componenti, canvas righe/colonne con riordino drag-and-drop e editor delle proprietà con formula builder e validazione della sintassi per motore di calcolo.
Import
import { ReportDesigner } from '@pzeta/vue-components'
import type {
ReportRiga,
ReportColonna,
ReportEspressione,
ReportValidaFormula,
} from '@pzeta/vue-components'
Struttura
Il designer è organizzato in tre pannelli:
- Palette (sinistra): aggiunta di righe/colonne e libreria di espressioni riutilizzabili;
- Canvas (centro): righe riordinabili via drag-and-drop e colonne, con richiesta di anteprima;
- Editor proprietà (destra): formula builder con validazione della sintassi per motore di calcolo.
Struttura dati
type ReportElementoTipo = 'riga' | 'colonna' | 'espressione'
type ReportMotore = string // es. 'sql' | 'javascript' | 'jsonata'
interface ReportRiga {
id: string | number
label: string
formula?: string
motore?: ReportMotore
[key: string]: unknown // proprietà aggiuntive di dominio
}
interface ReportColonna {
id: string | number
label: string
campo?: string // campo sorgente / chiave dati
formato?: string // es. 'valuta' | 'numero' | 'data'
formula?: string // per colonne calcolate
motore?: ReportMotore
[key: string]: unknown
}
interface ReportEspressione {
id: string | number
label: string
formula: string
motore: ReportMotore
[key: string]: unknown
}
Esempio Base
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
righe | ReportRiga[] | [] | Righe del report (asse verticale) |
colonne | ReportColonna[] | [] | Colonne del report (asse orizzontale) |
espressioni | ReportEspressione[] | [] | Libreria di espressioni riutilizzabili mostrate nella palette |
motoriAbilitati | ReportMotore[] | [] | Motori di valutazione selezionabili nell'editor delle formule |
validaFormula | ReportValidaFormula | null | null | Validatore async della sintassi (null = formula valida) |
titolo | string | null | null | Titolo mostrato nell'intestazione del canvas |
disabled | boolean | false | Disabilita ogni interazione (sola lettura) |
Emits
| Evento | Payload | Descrizione |
|---|---|---|
riordina-righe | { righe: ReportRiga[]; from: number; to: number } | Righe riordinate via drag-and-drop |
salva-riga | ReportRiga | Salvataggio di una riga dall'editor |
salva-colonna | ReportColonna | Salvataggio di una colonna dall'editor |
salva-espressione | ReportEspressione | Salvataggio di un'espressione dall'editor |
elimina-elemento | { tipo: ReportElementoTipo; elemento: ReportElemento } | Elemento eliminato dal canvas |
preview | { righe: ReportRiga[]; colonne: ReportColonna[] } | Richiesta di anteprima del report |
Slot
| Slot | Scope | Descrizione |
|---|---|---|
preview | { righe: ReportRiga[]; colonne: ReportColonna[] } | Render del risultato dell'anteprima |
proprieta | { tipo: ReportElementoTipo; elemento: ReportElemento; motore?: ReportMotore } | Editor di proprietà custom, tipicamente specifico per motore |
Esempi
Validazione delle formule per motore
Il validatore riceve motore e formula e risolve null se la sintassi è valida, altrimenti il messaggio d'errore mostrato nell'editor.
<script setup lang="ts">
import type { ReportValidaFormula } from '@pzeta/vue-components'
const validaFormula: ReportValidaFormula = async (motore, formula) => {
if (!formula.trim()) return 'La formula non può essere vuota'
if (motore === 'sql' && !/^[A-Z_]+\(/.test(formula.trim())) {
return 'Attesa una funzione di aggregazione (es. SUM(...))'
}
// Validazione remota opzionale:
// const res = await api.validate(motore, formula)
// return res.valid ? null : res.error
return null
}
</script>
<template>
<ReportDesigner
:righe="righe"
:colonne="colonne"
:motori-abilitati="['sql', 'javascript', 'jsonata']"
:valida-formula="validaFormula"
/>
</template>
Anteprima personalizzata
<template>
<ReportDesigner :righe="righe" :colonne="colonne" @preview="onPreview">
<template #preview="{ righe, colonne }">
<table class="w-full text-sm">
<thead>
<tr>
<th></th>
<th v-for="c in colonne" :key="c.id">{{ c.label }}</th>
</tr>
</thead>
<tbody>
<tr v-for="r in righe" :key="r.id">
<td class="font-medium">{{ r.label }}</td>
<td v-for="c in colonne" :key="c.id">—</td>
</tr>
</tbody>
</table>
</template>
</ReportDesigner>
</template>
Sola lettura
<template>
<ReportDesigner :righe="righe" :colonne="colonne" disabled />
</template>
Comportamento
- Le righe si riordinano via drag-and-drop; ogni riordino emette
riordina-righecon il nuovo ordine completo e gli indicifrom/to. - Il salvataggio di un elemento dall'editor emette l'evento
salva-*corrispondente al tipo: la persistenza è responsabilità del consumer. - Con
disabledil designer è in sola lettura e non emette eventi di modifica.
TypeScript
import type {
ReportDesignerProps,
ReportDesignerEmits,
ReportDesignerSlots,
ReportRiga,
ReportColonna,
ReportEspressione,
ReportElemento,
ReportElementoTipo,
ReportMotore,
ReportValidaFormula,
ReportDesignerSelezione,
} from '@pzeta/vue-components'
QRCode
Genera lato client un QR code da una stringa o URL e lo mostra come immagine, con dimensione, livello di correzione d'errore e colori configurabili.
SwipeListItem
Elemento di lista con azioni rivelate dallo scorrimento orizzontale, pensato per le code operative su mobile. Soglia di completamento configurabile, resistenza verso le azioni non eseguibili e fallback accessibile da tastiera.