useSpreadsheetERP
Signature
function useSpreadsheetERP(options: UseSpreadsheetERPOptions): UseSpreadsheetERPReturn
Gestisce catalogo sorgenti ERP, sorgenti attive sul foglio, fetch in parallelo e refresh debounced quando cambiano i filtri globali.
Opzioni
interface UseSpreadsheetERPOptions {
idfolio: Ref<number | null>
filtriGlobali: Ref<GlobalFilters>
sorgentiConfig: Ref<DataSourceConfig[]>
refreshInterval?: Ref<number | null> // secondi
}
| Opzione | Descrizione |
|---|---|
idfolio | ID foglio corrente (per logging/contesto) |
filtriGlobali | Filtri globali reattivi del foglio. Cambio → debouncedRefreshAll (500ms) |
sorgentiConfig | Sorgenti dichiarate sul foglio (tipicamente computed da state.sorgentierp) |
refreshInterval | Se valorizzato > 0, setInterval(refreshAll, n * 1000) |
Risultato
interface UseSpreadsheetERPReturn {
catalogo: Ref<SorgenteCatalogo[]>
sorgentiAttive: Ref<ErpDataSource[]>
isRefreshing: Ref<boolean>
lastRefreshAt: Ref<Date | null>
errors: Ref<Record<string, string>> // chiave: codice sorgente
isCatalogoLoading: Ref<boolean>
caricaCatalogo(): Promise<void>
addSource(config: DataSourceConfig): void
removeSource(codice: string): void
refreshAll(): Promise<void>
refreshSource(codice: string): Promise<void>
aggiornaFiltriSorgente(codice: string, filtri: Record<string, unknown>): void
}
ErpDataSource
interface ErpDataSource {
codice: string
config: DataSourceConfig
righe: ErpRow[] // dati caricati
totaleRighe: number // da Content-Range
lastFetchAt: Date | null
isLoading: boolean
error: string | null
}
Comportamento
caricaCatalogo()
Carica il catalogo da FogliPostgrestService.catalogo() la prima volta. Idempotente: se catalogo.value.length > 0, ritorna immediatamente.
addSource(config)
Aggiunge una sorgente alla lista attiva. Idempotente: se il codice esiste già, no-op.
erp.addSource({
codice: 'fatture_riepilogo',
cellaDestinazione: 'A1',
sheetIndex: 0,
filtri: { tipooperazione: 'V' },
usaFiltriGlobali: true,
limitRighe: 500,
})
addSourcenon triggera un fetch automatico. Devi chiamare refreshSource(codice) o refreshAll() esplicitamente. (SpreadsheetEditor lo fa al mount.)removeSource(codice)
Rimuove la sorgente dalla lista attiva e pulisce eventuali errori associati.
refreshSource(codice)
Fetch di una sola sorgente:
1. Cerca la sorgente in sorgentiAttive
2. Cerca l'entry nel catalogo (per endpoint)
3. isLoading = true, error = null
4. ErpDataService.fetchSorgente(config, filtriGlobali, catalogoEntry)
5. Aggiorna righe, totaleRighe, lastFetchAt
6. isLoading = false
In caso di errore: errors[codice] viene popolato e source.error aggiornato.
refreshAll()
Promise.allSettled su tutte le sorgenti attive. Aggiorna lastRefreshAt e isRefreshing (globale).
isRefreshing.value = true
await Promise.allSettled(codici.map((c) => refreshSource(c)))
lastRefreshAt.value = new Date()
isRefreshing.value = false
Le sorgenti che falliscono non bloccano le altre.
Watcher reattivo su filtriGlobali
const debouncedRefreshAll = debounce(refreshAll, 500)
watch(filtriGlobali, () => {
if (sorgentiAttive.value.length > 0) debouncedRefreshAll()
}, { deep: true })
Tutte le sorgenti con config.usaFiltriGlobali === true riceveranno i nuovi filtri (composti con i filtri specifici di ciascuna).
aggiornaFiltriSorgente(codice, filtri)
Modifica i filtri specifici di una sorgente attiva (sovrascrive config.filtri). Non triggera fetch automatico — fallo manualmente dopo:
erp.aggiornaFiltriSorgente('fatture_riepilogo', { tipooperazione: 'A' })
await erp.refreshSource('fatture_riepilogo')
Auto-refresh interval
watch(refreshInterval, () => {
stopAutoRefresh()
avviaAutoRefresh()
}, { immediate: true })
function avviaAutoRefresh() {
const interval = refreshInterval?.value
if (!interval || interval <= 0) return
autoRefreshInterval = setInterval(() => refreshAll(), interval * 1000)
}
Cleanup su onUnmounted.
Esempio: dashboard ERP read-only
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useSpreadsheetERP } from '@pzeta/vue-foglidicalcolo'
const idfolio = ref<number | null>(42)
const filtriGlobali = ref({
periodo: { da: '2026-01-01', a: '2026-12-31' },
})
const sorgentiConfig = ref([
{
codice: 'fatture_riepilogo',
cellaDestinazione: 'A1',
sheetIndex: 0,
filtri: { tipooperazione: 'V' },
usaFiltriGlobali: true,
},
])
const erp = useSpreadsheetERP({
idfolio,
filtriGlobali,
sorgentiConfig,
refreshInterval: ref(60), // refresh ogni 60s
})
await erp.caricaCatalogo()
sorgentiConfig.value.forEach((c) => erp.addSource(c))
await erp.refreshAll()
</script>
<template>
<div v-for="s in erp.sorgentiAttive.value" :key="s.codice">
<h3>{{ s.codice }} ({{ s.totaleRighe }} righe)</h3>
<p v-if="s.isLoading">Caricamento...</p>
<p v-else-if="s.error" class="text-red-600">⚠ {{ s.error }}</p>
<p v-else>Ultimo aggiornamento: {{ s.lastFetchAt }}</p>
</div>
</template>
Tipi correlati
SorgenteCatalogo— voce del catalogoErpDataSource— sorgente attiva con datiDataSourceConfig— configurazioneErpDataServiceSpreadsheetErpPanel