Composables

useSpreadsheetVersioni

Storico versioni di un foglio. Lista summary ordinata desc + ripristino come nuova revisione.

Signature

function useSpreadsheetVersioni(): UseSpreadsheetVersioniReturn

Gestisce lo storico versioni di un foglio: lista summary (senza snapshot) per UI, e funzione di ripristino che clona una versione passata come nuova versione corrente.

Risultato

interface UseSpreadsheetVersioniReturn {
  versioni: Ref<FoglioVersioneSummary[]>
  isLoading: Ref<boolean>
  isRipristinando: Ref<boolean>
  error: Ref<string | null>
  load(idfolio: number): Promise<void>
  ripristina(idversione: number): Promise<void>
}

FoglioVersioneSummary

interface FoglioVersioneSummary {
  idversione: number
  idfolio: number
  numerorevisione: number       // monotono crescente
  idautore: number
  datacreazione: string         // ISO 8601
}
Summary senza snapshot: il payload JSONB del foglio può essere molto grande. La libreria distingue:
  • FoglioVersioneSummary (questa) — solo metadata, lista di N righe
  • FoglioVersione (con snapshot) — payload completo, caricato solo al ripristino

load(idfolio)

versioni.load(42)

Chiama FogliPostgrestService.listaVersioni(idfolio) che fa:

GET /foglidicalcoloversioni?idfolio=eq.42&order=numerorevisione.desc&select=idversione,idfolio,numerorevisione,idautore,datacreazione

Ordinamento desc → la versione più recente in cima.

ripristina(idversione)

await versioni.ripristina(17)

Chiama l'RPC POST /rpc/ripristina_versione_foglio con p_idversione = 17. Lato DB:

1. Recupera snapshot della versione 17
2. Crea una nuova riga in foglidicalcoloversioni con:
   - stesso snapshot
   - numerorevisione = MAX(numerorevisione) + 1 (es. 18)
3. Aggiorna foglidicalcolo.datamodifica
4. Ritorna nuova idversione

Dopo il ripristino, il composable richiama load(idfolio) per refresh.

Il ripristino è conservativo: lo storico precedente non viene toccato. La rev. 17 originale resta, e la rev. 18 è una copia esatta. Audit-friendly.

Pattern: integrazione con SpreadsheetEditor

SpreadsheetEditor gestisce internamente questo composable e lo usa così:

const versioni = useSpreadsheetVersioni()

async function handleRipristina(idversione: number) {
  await versioni.ripristina(idversione)
  // L'editor deve ricaricare il foglio per vedere il nuovo snapshot:
  if (spreadsheet.state.value.idfolio) {
    await spreadsheet.load(spreadsheet.state.value.idfolio)
  }
}

Esempio standalone

<script setup lang="ts">
import { ref } from 'vue'
import { useSpreadsheetVersioni } from '@pzeta/vue-foglidicalcolo'

const props = defineProps<{ idfolio: number }>()
const versioni = useSpreadsheetVersioni()

await versioni.load(props.idfolio)

async function ripristina(idv: number) {
  if (!confirm('Vuoi davvero ripristinare questa versione?')) return
  await versioni.ripristina(idv)
  // Notifica il parent (es. emit) per ricaricare l'editor
}
</script>

<template>
  <ul>
    <li v-for="v in versioni.versioni.value" :key="v.idversione">
      Rev. {{ v.numerorevisione }} — {{ new Date(v.datacreazione).toLocaleString('it-IT') }}
      <button :disabled="versioni.isRipristinando.value" @click="ripristina(v.idversione)">
        Ripristina
      </button>
    </li>
  </ul>

  <p v-if="versioni.error.value" class="text-red-600">{{ versioni.error.value }}</p>
</template>

Limite versioni

Configurabile via PzetaFogliDiCalcoloOptions.maxVersioni (default 10). Il DB può applicare rotazione automatica tramite trigger (es. dopo INSERT, eliminare le versioni più vecchie eccedenti).

Il composable non applica il limite client-side: si fida del DB. Se vedi più di maxVersioni voci, verifica che il trigger di rotazione sia attivo nello schema.

Tipi correlati