mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-17 12:19:50 +02:00
Lot 4 : Grille servie depuis l'instantané et requêtes allégées
- Grille : lecture de l'instantané grid_rows (gamme INIT et dernières gammes enregistrées reportées), recalcul en arrière-plan au-delà de 20 h, version de format dans chaque ligne pour écarter les anciens instantanés. - Navigateur : lignes réutilisées au retour sur la Grille (< 10 min), Grille conservée pendant un changement de magasin ou une actualisation, React.memo sur la Grille, les filtres et la barre du bas, en-tête mémorisé. - Fiche produit : toutes les lectures en parallèle. - Ventes par mois et stock sans vente : plages de dates au lieu de TO_CHAR. - Accueil : vagues de 12 appels, cache de 30 min. - API v1 : comptage et page en parallèle, last_used_at au plus une fois par minute, version interne non exposée. - Plan : suivi du lot 4, avec ce qui reste à valider sur la base réelle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcA129WzGTH6zxPHFBGWmn
This commit is contained in:
13 files changed
+393
-119
No files matched your search
@@ -114,9 +114,33 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
const forceRefresh = refreshRequest !== servedRefreshRef.current;
|
||||
if (forceRefresh) params.set("refresh", "1");
|
||||
|
||||
const cle = `${codeFournisseur}:${magasin || "TOTAL"}`;
|
||||
const { rowsMeta, rows: lignesEnMemoire, setRowsMeta } = useGridStore.getState();
|
||||
|
||||
// Retour sur la Grille (même fournisseur, même magasin, chargée il y a
|
||||
// moins de 10 min) : les lignes sont encore en mémoire, rien à retélécharger.
|
||||
if (!forceRefresh && rowsMeta?.key === cle && lignesEnMemoire.length > 0
|
||||
&& Date.now() - rowsMeta.loadedAt < 10 * 60 * 1000) {
|
||||
setRowsLoaded(lignesEnMemoire.length);
|
||||
setTotalRows(lignesEnMemoire.length);
|
||||
setIsLoadingRows(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Changement de magasin (ou rechargement) sur le même fournisseur : la
|
||||
// Grille reste affichée — les lignes portent déjà le détail par magasin,
|
||||
// la bascule est immédiate — et les chiffres complétés pour ce magasin
|
||||
// remplacent l'affichage d'un bloc, une fois reçus.
|
||||
const memeFournisseur = rowsMeta?.key.startsWith(`${codeFournisseur}:`) === true && lignesEnMemoire.length > 0;
|
||||
|
||||
const accumulatedRows: ProductRow[] = [];
|
||||
let lastFlush = 0;
|
||||
setRows([]);
|
||||
if (!memeFournisseur) {
|
||||
setRows([]);
|
||||
// Les lignes vont être remplacées : tant que ce chargement n'est pas
|
||||
// terminé, elles ne correspondent plus à aucune clé.
|
||||
setRowsMeta(null);
|
||||
}
|
||||
setRowsLoaded(0);
|
||||
setTotalRows(null);
|
||||
setLoadError(null);
|
||||
@@ -130,10 +154,12 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
// Les lignes déjà poussées dans le store ne doivent plus bouger : on lui
|
||||
// passe une copie, et on continue d'accumuler dans le tableau privé.
|
||||
const flush = (loaded: number, total: number | null, final = false) => {
|
||||
setRows(final ? accumulatedRows : accumulatedRows.slice());
|
||||
setRowsLoaded(loaded);
|
||||
setTotalRows(total);
|
||||
lastFlush = Date.now();
|
||||
// Même fournisseur : on garde les lignes affichées jusqu'au bout.
|
||||
if (memeFournisseur && !final) return;
|
||||
setRows(final ? accumulatedRows : accumulatedRows.slice());
|
||||
};
|
||||
|
||||
async function loadRows() {
|
||||
@@ -184,6 +210,7 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
}
|
||||
|
||||
flush(loaded, total, true);
|
||||
setRowsMeta({ key: cle, loadedAt: Date.now() });
|
||||
if (forceRefresh) servedRefreshRef.current = refreshRequest;
|
||||
} catch (error) {
|
||||
if (!controller.signal.aborted) {
|
||||
@@ -265,7 +292,9 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
|
||||
<div className="flex items-center justify-between gap-3 text-[13px] text-[var(--text-primary)]">
|
||||
<span className="flex items-center gap-2">
|
||||
<Loader2 className="h-4 w-4 animate-spin text-[var(--accent)]" />
|
||||
Chargement des produits de {nomFournisseur}…
|
||||
{nbRows > 0
|
||||
? "Mise à jour des chiffres… la grille reste utilisable."
|
||||
: `Chargement des produits de ${nomFournisseur}…`}
|
||||
</span>
|
||||
<span className="tabular-nums text-[var(--text-secondary)]">
|
||||
{totalRows
|
||||
|
||||
Reference in new issue
Block a user