Sliding-window loading for the grand livre + year-scoped sticky footer
With 5+ years of migrated history, loading every ligne up front took ~40s. The table now only ever holds a date-range window (~18 months around today by default), extended by 6 months when scrolling near either edge and trimmed from the far end past a 30-month cap. The totals footer and "Année" filter can't be answered from a partial window, so they're backed by two new small endpoints (LedgerStatsController) instead: per-compte totals for whichever year is currently scrolled into view, and the distinct list of years with data.
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
<label>Client
|
||||
<select v-model="filterClient">
|
||||
<option value="">Tous</option>
|
||||
<option v-for="c in allClients" :key="c" :value="c">{{ c }}</option>
|
||||
<option v-for="c in allClientsList" :key="c" :value="c">{{ c }}</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<label>Année
|
||||
<select v-model="filterYear">
|
||||
<option value="">Toutes</option>
|
||||
<option v-for="y in allYears" :key="y" :value="y">{{ y }}</option>
|
||||
<option v-for="y in allYearsList" :key="y" :value="y">{{ y }}</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
@@ -57,12 +57,12 @@
|
||||
|
||||
<button type="button" class="button figli-clear-drilldown" v-if="filterEntreeId" @click="filterEntreeId = null">✕ Entrée + sorties liées uniquement</button>
|
||||
|
||||
<span class="figli-count" v-if="!loading">{{ filteredRows.length }} / {{ rows.length }} lignes{{ errorCount ? ' — ' + errorCount + ' avec écart' : '' }}</span>
|
||||
<span class="figli-count" v-if="!loading">{{ filteredRows.length }} / {{ rows.length }} lignes chargées{{ errorCount ? ' — ' + errorCount + ' avec écart' : '' }}</span>
|
||||
</div>
|
||||
|
||||
<p v-if="loading">Chargement des données…</p>
|
||||
<p v-else-if="error" class="figli-error">Erreur de chargement : {{ error }}</p>
|
||||
<div v-else class="figli-table-wrap">
|
||||
<div v-else ref="tableWrap" class="figli-table-wrap">
|
||||
<table ref="tableEl" @mouseover="onCellHover" @mouseleave="clearColHover">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -79,11 +79,16 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ref="topSentinel" class="figli-sentinel-row">
|
||||
<td :colspan="6 + allComptes.length + 3">
|
||||
<span v-if="loadingOlder">Chargement des mois précédents…</span>
|
||||
</td>
|
||||
</tr>
|
||||
<template v-for="item in groupedRows" :key="item.key">
|
||||
<tr v-if="item.isGroup" class="figli-group-row">
|
||||
<tr v-if="item.isGroup" class="figli-group-row" :data-year="item.year">
|
||||
<td :colspan="6 + allComptes.length + 3">{{ item.label }} <span class="figli-note">({{ item.count }} lignes)</span></td>
|
||||
</tr>
|
||||
<tr v-else :class="{'figli-error-row': item.hasError}">
|
||||
<tr v-else :class="{'figli-error-row': item.hasError}" :data-year="item.date ? item.date.slice(0, 4) : null">
|
||||
<td class="actions-col">
|
||||
<button
|
||||
v-if="item.linkable"
|
||||
@@ -125,16 +130,24 @@
|
||||
<td class="amount" :class="{'figli-ecart': item.hasError}">{{ item.hasError ? formatEur(item.ecart) : '' }}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<tr ref="bottomSentinel" class="figli-sentinel-row">
|
||||
<td :colspan="6 + allComptes.length + 3">
|
||||
<span v-if="loadingNewer">Chargement des mois suivants…</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="figli-totals-row">
|
||||
<td class="actions-col"></td>
|
||||
<td class="actions-col"></td>
|
||||
<td colspan="4">Solde (créditeur / débiteur) — {{ filteredRows.length }} lignes filtrées</td>
|
||||
<td class="amount">{{ formatEur(footerTotals.montant_ht) }}</td>
|
||||
<td class="amount">{{ formatEur(footerTotals.montant_ttc) }}</td>
|
||||
<td v-for="c in allComptes" :key="c" class="amount compte-col" :class="soldeClass(footerTotals.parCompte[c])">{{ formatEur(footerTotals.parCompte[c]) }}</td>
|
||||
<td class="amount" :class="soldeClass(footerTotals.ecart)">{{ formatEur(footerTotals.ecart) }}</td>
|
||||
<td colspan="4">
|
||||
Solde {{ currentYear || '…' }} (créditeur / débiteur)
|
||||
<span v-if="currentYearLoading" class="figli-note">chargement…</span>
|
||||
</td>
|
||||
<td class="amount">{{ currentYearTotals ? formatEur(currentYearTotals.montant_ht) : '' }}</td>
|
||||
<td class="amount">{{ currentYearTotals ? formatEur(currentYearTotals.montant_ttc) : '' }}</td>
|
||||
<td v-for="c in allComptes" :key="c" class="amount compte-col" :class="currentYearTotals ? soldeClass(currentYearTotals.par_compte[c]) : ''">{{ currentYearTotals && currentYearTotals.par_compte[c] !== undefined ? formatEur(currentYearTotals.par_compte[c]) : '' }}</td>
|
||||
<td class="amount" :class="currentYearTotals ? soldeClass(currentYearTotals.ecart) : ''">{{ currentYearTotals ? formatEur(currentYearTotals.ecart) : '' }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user