Composables

useExport

Composable principale per generare ed eseguire un export.

Panoramica

useExport gestisce la selezione campi, formato, filtri, ordinamento, applicazione di template salvati e l'esecuzione dell'export. Distingue tra export sincrono (Blob restituito direttamente) e asincrono (server risponde con 202 Accepted e exportId, segue polling). In entrambi i casi il file viene scaricato automaticamente con downloadBlob.

Internamente usa useExportTemplates per la gestione dei modelli e usePolling per il tracking degli export asincroni.

Inizializzazione

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

const {
  loading, errore,
  risorsa, campiDisponibili, campiSelezionati,
  formato, nomeFile, filtri, ordinamento,
  exportResult, exportProgresso, isPolling,
  templateManager,
  loadMetadata, applyTemplate,
  toggleField, selectAllFields, deselectAllFields, moveField,
  executeExport, cancelExport, reset,
} = useExport()

Parametri

ParametroTipoDefaultDescrizione
apiOverrideImportExportApiuseApi()Istanza API

Stato reattivo

ProprietàTipoDescrizione
loadingRef<boolean>Operazione in corso
erroreRef<string | null>Messaggio errore
risorsaRef<string>Codice risorsa
campiDisponibiliRef<CampoMetadato[]>Campi esportabili (caricati da loadMetadata)
campiSelezionatiRef<string[]>Nomi campo nell'ordine scelto dall'utente
formatoRef<FileFormato>xlsx (default), csv, json
nomeFileRef<string>Nome file output (opzionale, default export_{risorsa})
filtriRef<Record<string, unknown>>Filtri server-side
ordinamentoRef<Array<{ campo, direzione }>>Ordinamento (passa il primo elemento al backend)
exportResultRef<ExportResult | null>Risultato finale (sync o async)
exportProgressoRef<ExportProgresso | null>Progresso polling per async
isPollingRef<boolean>Polling attivo
templateManageroggettoRestituito da useExportTemplates

Metodi

loadMetadata(codiceRisorsa)

Imposta risorsa.value, carica campiDisponibili da getExportFieldMetadata e i template della risorsa via templateManager.loadTemplates.

await loadMetadata('anagrafica')
// campiDisponibili.value popolato
// templateManager.templates.value popolato

applyTemplate()

Applica il template attualmente selezionato (templateManager.selectedTemplate): popola campiSelezionati, formato, filtri, ordinamento.

toggleField(campo), selectAllFields(), deselectAllFields(), moveField(from, to)

Manipolano campiSelezionati. moveField riordina spostando un elemento da from a to (drag-and-drop dal PickList).

executeExport()

Esegue la chiamata POST /api/export/execute. Comportamento:

  1. Costruisce ExportRequest da stato corrente (campi, filtri, ordinamento, modelloId, nomeFile)
  2. Se la risposta è un Blob → download immediato + exportResult settato a { tipo: 'sincrono', stato: 'completato' }
  3. Se la risposta è asincrona (202):
    • stato: 'in_corso' → parte polling
    • urlDownload presente → download immediato
    • stato: 'errore' → errore propagato

cancelExport()

Annulla l'export tramite AbortController. Ferma anche l'eventuale polling in corso.

reset()

Azzera l'intero stato (campi, formato, filtri, ordinamento, polling, template selezionato).

Tipo ExportRequest

interface ExportRequest {
  risorsa: string
  formato: FileFormato
  campi: string[]
  filtri?: Record<string, unknown>
  ordinamento?: Array<{ campo: string; direzione: 'asc' | 'desc' }>
  nomeFile?: string
  modelloId?: string
}

Tipo ExportResult

Discriminated union su tipo:

type ExportResult =
  | {
      tipo: 'sincrono'
      stato: 'completato'
      nomeFile: string
    }
  | {
      tipo: 'asincrono'
      exportId: string
      stato: 'completato' | 'in_corso' | 'errore'
      nomeFile?: string
      dimensione?: number
      righeEsportate?: number
      urlDownload?: string
      tempoEsecuzione?: number
    }

Type guard disponibile:

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

if (isAsyncExportResult(result)) {
  console.log('Export asincrono:', result.exportId)
}

Esempio

const exporter = useExport()

await exporter.loadMetadata('anagrafica')
exporter.selectAllFields()
exporter.formato.value = 'xlsx'
exporter.filtri.value = { attivo: true }
exporter.ordinamento.value = [{ campo: 'cognome', direzione: 'asc' }]

await exporter.executeExport()
// Sincrono: file scaricato, exportResult.value.stato = 'completato'
// Async: polling parte, exportProgresso.value si aggiorna