MFE Integration

usePostgrestPagination

Composable Vue 3 per gestire lo stato di paginazione PostgREST in un MFE — page/pageSize reattivi, offset calcolato, navigazione e reset.

Cos'è

usePostgrestPagination è un composable Vue 3 leggero che incapsula lo stato reattivo di una paginazione PostgREST: pagina corrente, dimensione pagina, totale record, calcolo automatico dell'offset e helper di navigazione (nextPage, prevPage, reset).

Non esegue chiamate HTTP: si compone con BaseMfePostgrestService o PostgrestMfeService — passa offset e pageSize come query e aggiorna totalCount con totalRecords ricevuto dalla risposta.

Signature

function usePostgrestPagination(initialPageSize?: number): {
  page: Ref<number>
  pageSize: Ref<number>
  offset: ComputedRef<number>
  totalCount: Ref<number>
  totalPages: ComputedRef<number>
  setPage: (newPage: number) => void
  nextPage: () => void
  prevPage: () => void
  setTotalCount: (count: number) => void
  reset: () => void
}

Parametri

ParametroTipoDefaultDescrizione
initialPageSizenumber10Dimensione iniziale della pagina (modificabile via pageSize.value)

Stato ritornato

CampoTipoDescrizione
pageRef<number>Pagina corrente (zero-based: pagina 0 = prima pagina)
pageSizeRef<number>Numero record per pagina
offsetComputedRef<number>page * pageSize — da passare a query.offset
totalCountRef<number>Totale record (aggiornato da setTotalCount)
totalPagesComputedRef<number>Math.ceil(totalCount / pageSize)

Metodi

MetodoComportamento
setPage(newPage)Imposta direttamente la pagina (no clamp: la responsabilità di validare è del chiamante)
nextPage()Incrementa page se page < totalPages - 1, altrimenti no-op
prevPage()Decrementa page se page > 0, altrimenti no-op
setTotalCount(count)Aggiorna totalCount (da chiamare dopo ogni fetch con response.totalRecords)
reset()Riporta page = 0 e totalCount = 0 (utile dopo cambio di filtri)

Esempio completo

<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { useMfeContext } from '@pzeta/mfe-contracts'
import {
  BaseMfePostgrestService,
  usePostgrestPagination,
} from '@pzeta/postgrest/mfe'

interface Cliente {
  idanagrafica: number
  denominazione: string
}

class ClientiService extends BaseMfePostgrestService<Cliente, number> {
  constructor(http = useMfeContext().http) {
    super(http, 'anagrafica', 'idanagrafica', 'Cliente')
  }
}

const service = new ClientiService()
const clienti = ref<Cliente[]>([])
const loading = ref(false)

const {
  page,
  pageSize,
  offset,
  totalCount,
  totalPages,
  setTotalCount,
  nextPage,
  prevPage,
  reset,
} = usePostgrestPagination(25)

async function load() {
  loading.value = true
  try {
    const { data, totalRecords } = await service.getAll({
      order: 'denominazione.asc',
      limit: pageSize.value,
      offset: offset.value,
    })
    clienti.value = data
    setTotalCount(totalRecords)
  } finally {
    loading.value = false
  }
}

// Ricarica quando cambia pagina o pageSize
watch([page, pageSize], load)

onMounted(load)
</script>

<template>
  <table>
    <tr v-for="c in clienti" :key="c.idanagrafica">
      <td>{{ c.denominazione }}</td>
    </tr>
  </table>

  <div class="flex items-center gap-3">
    <button :disabled="page === 0" @click="prevPage">Precedente</button>
    <span>Pagina {{ page + 1 }} di {{ totalPages }}</span>
    <button :disabled="page >= totalPages - 1" @click="nextPage">Successiva</button>
    <span class="ml-auto">{{ totalCount }} record totali</span>
  </div>
</template>

Pattern: reset su cambio filtro

Quando l'utente modifica un filtro è importante riportare la paginazione all'inizio per evitare di chiedere un offset oltre il nuovo totalCount:

const filtroNome = ref('')

watch(filtroNome, () => {
  reset()  // page = 0, totalCount = 0
  load()
})
Internamente page è zero-based (allineato a offset = page * pageSize). Per l'interfaccia utente mostra page + 1 (vedi esempio). Non confondere i due indici quando passi al backend.

Tipi correlati