ImportWizard
Panoramica
ImportWizard è il componente di alto livello che orchestra l'intero workflow di importazione. Espone un Dialog con uno Stepper lineare a 4 step:
- Carica File — drag & drop o file picker, validazione lato client, opzioni CSV se applicabili
- Mapping Campi — auto-suggest + tabella interattiva per associare colonne sorgente a campi destinazione
- Anteprima — dry-run lato server (
POST /api/import/test) con tabella errori/warning - Importa — esecuzione effettiva, sincrona o asincrona (con
ImportStatusTrackere polling)
Il componente crea internamente l'istanza di ImportExportApi e la fornisce ai sotto-componenti tramite provide(IMPORT_EXPORT_API_KEY). Tutta la logica di stato è delegata a useImport.
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
visible | boolean | — | Visibilità del dialog (v-model) |
baseUrl | string | — | URL base dei microservizi import/export |
risorsa | string | undefined | Codice risorsa target (es. 'anagrafica'). Se omesso, va impostato dall'utente prima dell'upload |
api | ImportExportClient | undefined | Client custom (interfaccia, non classe) — utile per testing, mock o backend alternativi. Se omesso, viene istanziato new ImportExportApi(baseUrl). Vedi Client interfaces |
Emits
| Evento | Payload | Descrizione |
|---|---|---|
update:visible | boolean | Richiesta apertura/chiusura dialog (v-model) |
importCompleted | { righeImportate: number; righeScartate: number } | Import completato (stato === 'completato' || 'parziale') |
error | Error | Errore propagato dall'ErrorBoundary interno |
Comportamento
- Reset alla chiusura: alla
hidedel dialog viene chiamatoreset()diuseImporte ilResetBoundaryinterno viene azzerato. Lo stato non sopravvive tra una sessione e l'altra. - Sincronizzazione
risorsa: la prop viene riallineata sia al cambio prop sia all'apertura del dialog (dopo chereset()ha azzerato il valore interno). - Auto-upload: se al
select-filelarisorsaè già valorizzata, l'upload parte automaticamente (handleSelectFile). Lo step 1 → 2 avviene quando l'upload + caricamento metadati ha successo. - Soglia async: se il file ha ≥ 500 righe (
ASYNC_THRESHOLD) l'esecuzione è asincrona —executeImportriceve unimportIdeuseImportStatusavvia il polling. Il valore è override-abile passandouseImport(api, { asyncThreshold: 1000 })quando si usano i singoli step manualmente. - Navigazione: lo Stepper è
linear— è possibile tornare indietro tramite il pulsante "Indietro", magoToSteprifiuta salti in avanti di più di 1 step.
Esempio completo
<script setup lang="ts">
import { ref } from 'vue'
import { ImportWizard } from '@pzeta/vue-importexport'
import '@pzeta/vue-importexport/style.css'
const showImport = ref(false)
const baseUrl = import.meta.env.VITE_IMPORTEXPORT_API_URL
function onCompleted(result: { righeImportate: number; righeScartate: number }) {
console.log(`Importate ${result.righeImportate}, scartate ${result.righeScartate}`)
// ricarica lista anagrafica, mostra toast, ecc.
}
function onError(err: Error) {
console.error('Errore wizard import:', err)
}
</script>
<template>
<button @click="showImport = true">Importa anagrafica</button>
<ImportWizard
v-model:visible="showImport"
:base-url="baseUrl"
risorsa="anagrafica"
@import-completed="onCompleted"
@error="onError"
/>
</template>
Selezione dinamica risorsa
Se non passi risorsa come prop, il primo step deve includere un Select per farla scegliere all'utente. In tal caso bisogna ricomporre il wizard manualmente usando useImport e i singoli ImportStep* — ImportWizard da solo non espone uno slot per la selezione risorsa.
Iniezione contesto
I sotto-componenti del wizard usano useApi() per recuperare l'istanza condivisa:
// All'interno di ImportWizard:
const apiInstance = props.api ?? new ImportExportApi(props.baseUrl)
provide(IMPORT_EXPORT_API_KEY, apiInstance)
IMPORT_EXPORT_API_KEY è tipizzato come InjectionKey<ImportExportClient> — quindi qualsiasi oggetto che soddisfi le 3 interfacce IImportClient/IExportClient/ITemplateClient può essere iniettato (mock, GraphQL adapter, SDK custom).
Note
- Il dialog ha
maxWidth: 56rem— adatto a desktop. Su mobile occupa tutta la larghezza disponibile. - L'
ErrorBoundaryinterno cattura errori di render e invocazione e mostra una fallback UI con pulsante "Chiudi". - Il file picker accetta solo
.csv,.xlsx,.xls,.jsoned è limitato a 50 MB lato client.