TreeRemote
Panoramica
TreeRemote è un componente Tree che carica la struttura gerarchica dei nodi in modo asincrono tramite fetchFn, o dichiarando la risorsa PostgREST con endpoint (vedi Sorgente dati endpoint). Ideale per dati con struttura ad albero come categorie, organigrammi, filesystem o menu di navigazione.
La fetchFn deve restituire un array di TreeNode nel formato PrimeVue:
interface TreeNode {
key: string
label: string
data?: unknown
icon?: string
children?: TreeNode[]
leaf?: boolean
}
Caratteristiche principali:
- Tre modalità di selezione:
single,multiple,checkbox - Filtro/ricerca sui nodi
- Filtri dinamici su altri campi del form
- Supporto
metaKeySelectionper selezione multipla con Ctrl/Cmd
Casi d'uso tipici: navigazione categorie, selezione reparti organizzativi, selezione voci di menu, strutture di classificazione.
Anteprima live (con fetchFn mockato)
Utilizzo nello schema
const schema = [{
name: 'categoriaSelezionata',
type: 'treeremote',
label: 'Categoria',
props: {
fetchFn: fetchAlberoCategorie,
selectionMode: 'single',
showFilter: true,
}
}, {
// Selezione multipla con checkbox
name: 'repartiAssegnati',
type: 'treeremote',
label: 'Reparti',
props: {
fetchFn: fetchAlberoReparti,
selectionMode: 'checkbox',
metaKeySelection: false,
}
}]
Utilizzo diretto
Selezione singola
<TreeRemote
v-model="categoriaSelezionata"
:fetch-fn="fetchCategorie"
selection-mode="single"
show-filter
label="Categoria"
/>
Selezione multipla con checkbox
<TreeRemote
v-model="repartiSelezionati"
:fetch-fn="fetchReparti"
selection-mode="checkbox"
:meta-key-selection="false"
label="Reparti assegnati"
/>
Struttura dati attesa da fetchFn
// La fetchFn deve restituire TreeNode[]
const fetchCategorie = async (): Promise<TreeNode[]> => {
const res = await fetch('/api/categorie/albero')
const data = await res.json()
// Trasformare i dati nel formato TreeNode se necessario
return data
}
// Esempio struttura TreeNode
const esempio: TreeNode[] = [{
key: '0',
label: 'Elettronica',
icon: 'pi pi-desktop',
children: [{
key: '0-0',
label: 'Computer',
icon: 'pi pi-laptop',
data: { id: 1, slug: 'computer' }
}, {
key: '0-1',
label: 'Smartphone',
icon: 'pi pi-mobile',
leaf: true,
data: { id: 2, slug: 'smartphone' }
}]
}]
Formato del valore (modelValue)
Il valore dipende dalla selectionMode:
// selectionMode: 'single'
// Record<string, boolean> con una sola chiave
{ '0-1': true }
// selectionMode: 'multiple'
// Record<string, boolean> con più chiavi
{ '0-0': true, '0-1': true }
// selectionMode: 'checkbox'
// Record con stato checked/partialChecked per ogni nodo
{ '0': { checked: false, partialChecked: true }, '0-0': { checked: true, partialChecked: false } }
Sorgente dati endpoint
In alternativa a fetchFn, TreeRemote può comporre da sé la chiamata PostgREST a partire dalla risorsa dichiarata:
props: {
endpoint: 'categorie_albero',
order: 'ordinamento.asc'
}
fetchFn ha sempre la precedenza: se sono presenti entrambe, endpoint viene ignorato. La forma dell'endpoint, la traduzione dei filtri e l'ordine con cui viene risolto il trasporto sono descritti in Sorgente dati endpoint.
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
modelValue | Record<string, boolean> | string[] | null | null | Nodi selezionati (v-model). Record<string, boolean> per single/multiple/checkbox; string[] accettato come alternativa quando il consumer gestisce la selezione come lista di chiavi |
label | string | — | Etichetta del campo |
helperText | string | — | Testo di supporto sotto il campo |
error | string | — | Messaggio di errore (attiva stato invalid) |
disabled | boolean | false | Disabilita il campo |
invalid | boolean | false | Attiva visivamente lo stato di errore |
fetchFn | FetchFn<TreeNode> | — | Funzione asincrona per caricare i nodi |
filter | string | FilterCriteria | — | Filtro statico passato alla fetchFn |
filterFields | RemoteFilterField[] | [] | Campi del form da osservare per filtri dinamici; la forma estesa { field, column, operator } permette colonna e operatore diversi |
fullData | Record<string, unknown> | {} | Dati completi del form (per filtri dinamici) |
endpoint | string | — | Risorsa PostgREST [schema.]risorsa, alternativa a fetchFn — vedi Sorgente dati endpoint |
select | string | — | Colonne da selezionare (solo con endpoint) |
order | string | — | Ordinamento PostgREST, es. 'nome.asc' (solo con endpoint) |
limit | number | — | Numero massimo di righe restituite (solo con endpoint) |
baseUrl | string | '' | Prefisso del gateway PostgREST, se l'endpoint dichiara uno schema |
keyName | string | 'id' | Chiave primaria della risorsa (solo client PostgREST standalone) |
selectionMode | 'single' | 'multiple' | 'checkbox' | 'single' | Modalità di selezione |
showFilter | boolean | false | Mostra campo di ricerca/filtro |
filterPlaceholder | string | (da i18n) | Placeholder del campo filtro |
metaKeySelection | boolean | true | Richiede Ctrl/Cmd per selezione multipla |
Metodi esposti
| Metodo | Descrizione |
|---|---|
reload() | Ricarica i nodi chiamando nuovamente la fetchFn |
Slot
Tutti gli slot del componente Tree di @pzeta/vue-components vengono propagati automaticamente. Slot tipici:
| Slot | Props | Descrizione |
|---|---|---|
default | { node } | Template personalizzato per ogni nodo (sostituisce label + icon) |
nodeicon | { node, expanded, selected } | Override dell'icona del nodo |
togglericon | { node, expanded } | Override dell'icona di espansione/collasso |
header/footer | — | Contenuto sopra/sotto la lista nodi |
Eventi
| Evento | Payload | Descrizione |
|---|---|---|
update:modelValue | Record<string, boolean> | string[] | null | Selezione aggiornata |
Validazione suggerita
import { z } from 'zod'
const schema = z.object({
// Selezione singola: verifica che almeno un nodo sia selezionato
categoriaSelezionata: z.record(z.boolean())
.refine(v => Object.keys(v).length > 0, 'Seleziona una categoria')
.nullable()
.refine(v => v !== null, { message: 'La categoria è obbligatoria' }),
})