Composables

useImport

Composable principale per orchestrare l'intero workflow di import.

Panoramica

useImport è il composable di alto livello che gestisce l'intero ciclo di vita dell'import: stato globale, upload, lettura headers client-side, mapping (delegato a useFieldMapping), test (dry-run), esecuzione e polling per import asincroni (delegato a useImportStatus). Include anche il download del template d'esempio e l'annullamento dell'upload tramite AbortController.

ImportWizard lo usa internamente — chiamarlo manualmente serve solo se vuoi comporre un wizard custom o invocare gli step da pagine separate.

Inizializzazione

import { useImport } from '@pzeta/vue-importexport'

const {
  stepCorrente, errore, loading,
  file, formato, risorsa, opzioniCsv,
  setFile, upload, cancelUpload,
  campiDestinazione, fieldMapping, anteprimaRigheFile,
  testResult, testImport,
  importResult, importStatus, isAsync, executeImport,
  canProceed, goToStep, reset, downloadTemplate,
} = useImport()

Parametri

ParametroTipoDefaultDescrizione
apiOverrideImportExportApiuseApi()Istanza API; se omesso viene iniettata via inject(IMPORT_EXPORT_API_KEY)
options.asyncThresholdnumber500Soglia righe oltre cui l'esecuzione è considerata asincrona (parte il polling)

Stato reattivo

ProprietàTipoDescrizione
statoRef<ImportStato>Stato della macchina (idle, uploading, ...)
stepCorrenteRef<number>Indice step (0-3)
erroreRef<string | null>Messaggio errore corrente
loadingRef<boolean>Operazione in corso
fileRef<File | null>File selezionato
formatoRef<FileFormato>Derivato dall'estensione
risorsaRef<string>Codice risorsa target
opzioniCsvRef<CsvOpzioni>Opzioni di parsing CSV
uploadResultRef<UploadResult | null>Risposta upload (sessionId, righe, colonne)
campiDestinazioneRef<CampoMetadato[]>Campi target dalla risorsa
fieldMappingoggettoRestituito da useFieldMapping
anteprimaRigheFileRef<Record<string, unknown>[]>Prime righe lette client-side
testResultRef<TestImportResult | null>Risultato dry-run
importResultRef<ImportResult | null>Risultato esecuzione
importStatusoggettoRestituito da useImportStatus
isAsyncComputedRef<boolean>true se righe >= asyncThreshold
canProceedComputedRef<boolean>Validità dello step corrente

Tipo ImportStato

type ImportStato =
  | 'idle' | 'uploading' | 'uploaded'
  | 'testing' | 'tested'
  | 'importing' | 'completed' | 'error'

Metodi

setFile(file)

Imposta il file e deriva il formato dall'estensione.

setFile(fileFromInput)
// formato.value = 'csv' | 'xlsx' | 'xls' | 'json'

upload()

Esegue l'upload (POST /api/import/upload), legge headers client-side via readFileHeaders, carica i metadati campi (getImportFieldMetadata), inizializza il mapping (fieldMapping.initFromColumns) e avanza allo step 1.

Le colonne reali vengono lette dal file lato client; la risposta server è usata come fallback. Questo permette il mapping anche se il backend non restituisce le colonne.

await upload()
// stepCorrente.value = 1
// fieldMapping inizializzato con auto-suggest

cancelUpload()

Annulla l'upload in corso. Funziona solo durante loading: true (upload effettivamente attivo).

testImport()

Esegue il dry-run filtrando i mapping attivi. Aggiorna testResult e avanza allo step 2.

await testImport()
// testResult.value = { righeValide, righeErrore, ... }

executeImport()

Esegue l'import effettivo. Se isAsync.value === true e il server non risponde subito con completato, parte il polling tramite importStatus.startPolling(importId).

await executeImport()
// Sincrono: stato.value = 'completed'
// Async: importStatus.progresso si aggiorna nel tempo

goToStep(step)

Naviga allo step indicato. Permette al massimo stepCorrente + 1 (no salti in avanti) ma libertà di tornare indietro.

reset()

Azzera l'intero stato (file, formato, risorsa, mapping, test, result, polling). Usato dal Dialog di ImportWizard alla chiusura.

downloadTemplate(risorsa, formato)

Scarica un template d'esempio della risorsa. Imposta errore.value se il download fallisce. Il file viene salvato come template_{risorsa}.{formato}.

await downloadTemplate('anagrafica', 'xlsx')
// browser scarica template_anagrafica.xlsx

Validazione step (canProceed)

StepCondizione
0 (Upload)file !== null && risorsa !== ''
1 (Mapping)fieldMapping.isValid.value === true
2 (Preview)testResult !== null && testResult.righeErrore === 0
3 (Execute)sempre false (è lo step finale)

Esempio completo (wizard custom)

<script setup lang="ts">
import { useImport, useApi } from '@pzeta/vue-importexport'

const api = useApi()
const importer = useImport(api, { asyncThreshold: 1000 })

async function start(file: File) {
  importer.risorsa.value = 'contratto'
  importer.setFile(file)
  await importer.upload()      // step 1
  // L'utente fa il mapping...
  await importer.testImport()  // step 2
  // L'utente conferma...
  await importer.executeImport() // step 3
}
</script>