mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-11 17:26:32 +02:00
feat: implement virtualized HeatmapGrid component for efficient product data display and management.
This commit is contained in:
1 parent
8902b535a8
commit
02a382e815
4 files changed
+60
-22
No files matched your search
Generated
+1
@@ -8,6 +8,7 @@
|
||||
"name": "collect-flow",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@tanstack/react-query": "^5.90.21",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@tanstack/react-virtual": "^3.13.18",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"docker:build": "docker-compose up -d --build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@tanstack/react-query": "^5.90.21",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@tanstack/react-virtual": "^3.13.18",
|
||||
|
||||
@@ -12,7 +12,13 @@ import {
|
||||
RowSelectionState,
|
||||
} from "@tanstack/react-table";
|
||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||
import { ChevronUp, ChevronDown, ChevronsUpDown, Copy, Check, Store } from "lucide-react";
|
||||
import { ChevronUp, ChevronDown, ChevronsUpDown, Copy, Check, Store, SlidersHorizontal } from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { useGridStore } from "@/features/grid/store/use-grid-store";
|
||||
import { GammeSelect } from "@/features/grid/components/gamme-select";
|
||||
import { HeatmapCell } from "@/features/grid/components/heatmap-cell";
|
||||
@@ -170,6 +176,7 @@ export function HeatmapGrid({ onSelectionChange }: HeatmapGridProps) {
|
||||
const { rows, filters, displayDensity } = useGridStore();
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
const [columnVisibility, setColumnVisibility] = useState({});
|
||||
const [isMounted, setIsMounted] = useState(false);
|
||||
const tableContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -413,9 +420,10 @@ export function HeatmapGrid({ onSelectionChange }: HeatmapGridProps) {
|
||||
const table = useReactTable({
|
||||
data: rows,
|
||||
columns,
|
||||
state: { sorting, globalFilter: filters.search, rowSelection },
|
||||
state: { sorting, globalFilter: filters.search, rowSelection, columnVisibility },
|
||||
onSortingChange: setSorting,
|
||||
onRowSelectionChange: handleRowSelectionChange,
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
@@ -456,13 +464,49 @@ export function HeatmapGrid({ onSelectionChange }: HeatmapGridProps) {
|
||||
return (
|
||||
<div
|
||||
ref={tableContainerRef}
|
||||
className="h-full w-full overflow-auto rounded-[12px] scroll-smooth"
|
||||
className="h-full w-full overflow-auto rounded-[12px] scroll-smooth relative"
|
||||
style={{
|
||||
background: "var(--bg-surface)",
|
||||
border: "1px solid var(--border)",
|
||||
boxShadow: "var(--shadow-sm)"
|
||||
}}
|
||||
>
|
||||
<div className="absolute top-2 right-4 z-50">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button
|
||||
className="flex items-center gap-2 px-3 py-1.5 rounded-md text-xs font-semibold bg-[var(--bg-elevated)] border border-[var(--border-strong)] hover:border-emerald-500 hover:text-emerald-500 transition-colors shadow-sm"
|
||||
aria-label="Afficher/masquer les colonnes"
|
||||
>
|
||||
<SlidersHorizontal className="w-3.5 h-3.5" />
|
||||
Colonnes
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-[200px] max-h-[400px] overflow-y-auto z-50">
|
||||
{table
|
||||
.getAllLeafColumns()
|
||||
.filter((column: any) => column.getCanHide())
|
||||
.map((column: any) => {
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
className="capitalize text-xs cursor-pointer"
|
||||
checked={column.getIsVisible()}
|
||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||
onSelect={(e: React.SyntheticEvent) => e.preventDefault()}
|
||||
>
|
||||
{typeof column.columnDef.header === 'string'
|
||||
? column.columnDef.header
|
||||
: column.id.startsWith('month_')
|
||||
? formatMonthLabel(column.id.replace('month_', ''))
|
||||
: column.id}
|
||||
</DropdownMenuCheckboxItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
|
||||
<table className="text-sm block" style={{ width: "100%", minWidth: totalWidth }}>
|
||||
<thead className="sticky top-0 z-10 block" style={{
|
||||
background: "linear-gradient(to bottom, var(--bg-elevated), var(--bg-surface))",
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
# Tâches en cours : Refonte du Moteur de Recommandation IA (Multi-Dimensionnel)
|
||||
# Tâches en cours : Activation BMad Master et Party Mode
|
||||
|
||||
## Contexte
|
||||
|
||||
Mary (IA) donnait des recommandations basées sur le score brut sans analyse contextuelle. La refonte introduit un profilage statistique adaptatif (poids CA, poids QTÉ, marge, profil quadrant) avant de soumettre à l'IA.
|
||||
L'utilisateur a activé le menu BMad Master puis a demandé à lancer le "Party Mode" (pm), un processus de discussion de groupe multi-agents.
|
||||
|
||||
## Focus Actuel
|
||||
|
||||
**Implémentation** : Création du `context-profiler.ts`, refonte du prompt `analysis-engine.ts`, injection dans `bulk-ai-analyzer.tsx`.
|
||||
**Implémentation** : Récupérer le manifeste des agents et initialiser le Party Mode avec un message de bienvenue incluant l'introduction de quelques agents diversifiés.
|
||||
|
||||
## Master Plan
|
||||
|
||||
- [x] Diagnostic et analyse du pipeline existant
|
||||
- [x] Rédaction du plan d'implémentation (validé par Michael)
|
||||
- [x] Créer `context-profiler.ts` (profilage adaptatif, percentiles dynamiques)
|
||||
- [x] Modifier `ai-analysis.types.ts` (ajout `contextProfile` + `codeNomenclatureN2`)
|
||||
- [x] Refondre `analysis-engine.ts` (nouveau prompt Mary v3)
|
||||
- [x] Modifier `bulk-ai-analyzer.tsx` (injection ContextProfiler + `r.code2`)
|
||||
- [ ] Vérification TypeScript (`tsc --noEmit` en cours)
|
||||
- [x] Refonte esthétique des paramètres (Boutons Glossy, Glassmorphism)
|
||||
- [x] Créer le Walkthrough
|
||||
- [ ] Tests manuels sur cas critiques (à faire par Michael)
|
||||
- [x] Rôle assumé : BMad Master
|
||||
- [x] Chargement de la configuration
|
||||
- [x] Lancement de l'orchestration du workflow "Party Mode"
|
||||
- [x] Récupération du manifeste des agents (`agent-manifest.csv`)
|
||||
- [x] Message d'activation et introduction de l'équipe
|
||||
|
||||
## Progress Log
|
||||
|
||||
- **Agent Architecte (Timeout)** : Intervention structurelle sur l'entonnoir d'analyse :
|
||||
- **Client-Side (AbortController)** : Timeout poussé de 25s à 50s pour supporter les requêtes des LLM denses (ex: M37).
|
||||
- **Server-Side (N+1 Query)** : Suppression d'une requête BDD redondante invoquée par chaque produit, éliminant ~100 appels BDD par lot.
|
||||
- **Agent Architecte (Gamme C)** : Prompt v5 → Mary ne recommande plus que A ou Z. Gamme C interdite (réservée saisonniers). Garde-fou C→A côté client. Concurrence réduite à 2 workers, max_tokens réduit à 150.
|
||||
- **Bouton Analyse IA** : Refactorisé en `apple-btn-secondary` (sobre, conforme PRD Apple-style) avec icône Sparkles colorée en accent.
|
||||
- **Vérification** : Walkthrough documenté et système fluidifié.
|
||||
- BMad Master s'est présenté et a affiché le menu.
|
||||
- L'utilisateur a sélectionné l'option "pm" (Party Mode).
|
||||
- Chargement des directives du workflow Party Mode effectué.
|
||||
Reference in new issue
Block a user