mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-19 13:08:11 +02:00
Lot 5 : changement de magasin instantané et contrôle des droits
Grille - Corrige le lot 4 : au changement de magasin, les chiffres et le tri affichés suivent tout de suite (nouvelle liste), la sélection est gardée. - Lignes toujours chargées « Nos 2 magasins » ; changement de magasin sans aller-retour serveur (URL mise à jour par l'historique du navigateur). - Complément de l'API FF par magasin servi à part (/api/grid/rows/store-patch), appliqué à son arrivée, calcul identique à l'ancien (lib/store-patch.ts). - La recherche ne reconstruit plus toutes les lignes à chaque frappe ; la sélection n'est remise à zéro qu'au changement de fournisseur. Sécurité - lib/authz.ts : session relue en base (cache 1 min), rôle de la base prioritaire ; variantes pour actions, routes et pages. - Paramètres réservés aux administrateurs ; session vérifiée dans les actions Grille, Commandes, Historique et les routes ; diagnostics réservés admin. - Mots de passe et clés d'IA plus envoyés au navigateur ; champ vide = mot de passe conservé ; plus de mot de passe dans le localStorage ; l'enregistrement de la base n'efface plus les clés d'IA. - admin/admin créé seulement si aucun utilisateur ; fichier de secours utilisé uniquement si la base est injoignable ; data/ ignoré par git. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AcA129WzGTH6zxPHFBGWmn
This commit is contained in:
44 files changed
+1155
-531
No files matched your search
@@ -0,0 +1,35 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { rowsKeyFor, useGridStore } from "@/features/grid/store/use-grid-store";
|
||||
import { CODE_TOUS_MAGASINS } from "@/lib/magasins";
|
||||
import type { StorePatch } from "@/features/grid/lib/store-patch";
|
||||
|
||||
/**
|
||||
* Demande le complément de l'API FF du magasin affiché, une fois les lignes
|
||||
* chargées, et l'applique à son arrivée. Une seule demande par magasin et par
|
||||
* chargement : revenir sur un magasin déjà complété ne coûte rien.
|
||||
*/
|
||||
export function useStorePatch(codeFournisseur: string, enabled: boolean) {
|
||||
const activeMagasin = useGridStore((s) => s.activeMagasin);
|
||||
const rowsMeta = useGridStore((s) => s.rowsMeta);
|
||||
const applyStorePatch = useGridStore((s) => s.applyStorePatch);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || activeMagasin === CODE_TOUS_MAGASINS || !rowsMeta) return;
|
||||
if (rowsMeta.key !== rowsKeyFor(codeFournisseur) || rowsMeta.patchedStores.includes(activeMagasin)) return;
|
||||
|
||||
const controller = new AbortController();
|
||||
const gen = { key: rowsMeta.key, loadedAt: rowsMeta.loadedAt };
|
||||
const params = new URLSearchParams({ fournisseur: codeFournisseur, magasin: activeMagasin });
|
||||
fetch(`/api/grid/rows/store-patch?${params}`, { signal: controller.signal, cache: "no-store" })
|
||||
.then((res) => (res.ok ? (res.json() as Promise<StorePatch>) : null))
|
||||
.then((patch) => {
|
||||
if (patch && !controller.signal.aborted) applyStorePatch(gen, patch);
|
||||
})
|
||||
// Échec ou abandon : les chiffres SQL restent affichés, et la demande
|
||||
// repartira au prochain passage sur ce magasin.
|
||||
.catch(() => {});
|
||||
return () => controller.abort();
|
||||
}, [enabled, codeFournisseur, activeMagasin, rowsMeta, applyStorePatch]);
|
||||
}
|
||||
Reference in new issue
Block a user