From e391550a3094a951b455143d252d0fea677396f1 Mon Sep 17 00:00:00 2001 From: Michael SCHAL Date: Fri, 20 Mar 2026 14:25:30 +0100 Subject: [PATCH] feat: Introduce product assortment grid client and direct PostgreSQL data access for FF Nancy. --- src/features/grid/components/grid-client.tsx | 14 +++++++++----- src/lib/pg-ff-client.ts | 15 +++++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/features/grid/components/grid-client.tsx b/src/features/grid/components/grid-client.tsx index 117f5cf..f538556 100644 --- a/src/features/grid/components/grid-client.tsx +++ b/src/features/grid/components/grid-client.tsx @@ -23,9 +23,10 @@ interface GridClientProps { magasin: string; } -export function GridClient({ initialRows, nomFournisseur, fournisseurs, magasins, magasin }: GridClientProps) { +export function GridClient({ initialRows, codeFournisseur, nomFournisseur, fournisseurs, magasins, magasin }: GridClientProps) { const setRows = useGridStore((s) => s.setRows); const setActiveGridQuery = useGridStore((s) => s.setActiveGridQuery); + const setFilter = useGridStore((s) => s.setFilter); const searchParams = useSearchParams(); const [selectedCodeins, setSelectedCodeins] = useState([]); @@ -52,12 +53,15 @@ export function GridClient({ initialRows, nomFournisseur, fournisseurs, magasins useEffect(() => { if (!isMounted) return; - // Optimisation : On évite le JSON.parse(JSON.stringify()) qui est très lourd sur 1000 lignes - // On passe directement les initialRows au moteur de score, ou on fait une copie superficielle si nécessaire. - // Le moteur de score doit idéalement retourner de nouveaux objets. + // Réinitialiser les filtres gamme et code3 lors du changement de fournisseur. + // Ces filtres sont persistés en localStorage (Zustand persist) et s'appliquent + // au nouveau fournisseur, cachant toutes les lignes si le filtre ne correspond pas. + setFilter("codeGamme", null); + setFilter("code3", null); + const scoredRows = computeProductScores([...initialRows]); setRows(scoredRows); - }, [initialRows, setRows, isMounted]); + }, [codeFournisseur, initialRows, setRows, setFilter, isMounted]); const handleSave = () => { startTransition(async () => { diff --git a/src/lib/pg-ff-client.ts b/src/lib/pg-ff-client.ts index b5701db..fe7dbef 100644 --- a/src/lib/pg-ff-client.ts +++ b/src/lib/pg-ff-client.ts @@ -267,12 +267,19 @@ export async function pgGetNomenclatureByFournisseur(codefou: string): Promise r.column_name); - console.log("[pg-ff] Nomenclature colonnes:", nomCols.join(", ")); - _nomenclatureParentCol = nomCols.find(c => /parent/i.test(c) || (c !== "no_id" && /no_id$/i.test(c))) ?? null; + const nomCols = (metaResult.rows as { column_name: string; data_type: string }[]); + console.log("[pg-ff] Nomenclature colonnes:", nomCols.map(r => `${r.column_name}(${r.data_type})`).join(", ")); + // Cherche une colonne "parent" qui soit un entier (FK vers no_id du parent) + // "chemin_pere" = chemin vers le père en français + // On vérifie le data_type : integer/bigint/smallint uniquement (pas text/varchar qui serait un chemin matérialisé) + const parentRow = nomCols.find(r => + (/parent|pere|father/i.test(r.column_name) || (r.column_name !== "no_id" && /no_id$/i.test(r.column_name))) + && /int|serial/i.test(r.data_type) + ); + _nomenclatureParentCol = parentRow?.column_name ?? null; console.log("[pg-ff] Nomenclature parentCol:", _nomenclatureParentCol); } const parentCol = _nomenclatureParentCol;