rapport - par categorie - probleme de presentation avec combobox #126

Closed
opened 2026-04-21 00:43:36 +00:00 by maximus · 0 comments
Owner

Contexte

Le rapport d'analyse "par categorie" (/reports/category) utilise depuis le commit bd992f2 le composant partage CategoryCombobox a la place d'un <select> natif. Le combobox calcule correctement la profondeur de chaque categorie (via parent_id) et applique une indentation proportionnelle, mais il affiche les items dans l'ordre recu — c'est-a-dire l'ordre de getAllCategoriesWithCounts() : ORDER BY c.sort_order, c.name.

Comme sort_order est attribue par parent (et non globalement), le tri global entremele parents et enfants. Resultat : la liste non filtree montre des niveaux melanges avec indentation visuelle, mais sans logique d'arbre. Le filtrage au clavier semble fonctionner car, en reduisant la liste, il masque l'interclassement des niveaux.

La solution canonique existe deja dans le projet : buildTree + flattenTreeToCategories dans src/hooks/useCategories.ts:61-92 (parcours depth-first qui emet chaque parent immediatement suivi de ses enfants).

Travail a faire

  • Extraire buildTree et flattenTreeToCategories de src/hooks/useCategories.ts vers un util partage src/utils/categoryTree.ts (ou reexport depuis useCategories.ts)
  • Dans src/components/shared/CategoryCombobox.tsx, trier la prop categories en ordre d'arbre (depth-first, siblings tries par sort_order puis name) via useMemo, reutiliser la meme passe pour calculer la profondeur
  • Preserver le comportement de filtrage : quand l'utilisateur tape, filtrer sur la liste deja triee (l'ordre d'arbre est conserve entre les elements restants)
  • Ajouter des tests unitaires (Vitest) sur flattenTreeToCategories et sur CategoryCombobox (ordre des <li> rendus)
  • Ajouter une entree sous ## [Unreleased] > Fixed dans CHANGELOG.md et ## [Unreleased] > Corrige dans CHANGELOG.fr.md

Fichiers concernes

  • src/components/shared/CategoryCombobox.tsx — tri hierarchique en memo, reutilisation de depths
  • src/hooks/useCategories.ts — exporter (ou deplacer) buildTree / flattenTreeToCategories
  • src/utils/categoryTree.ts (nouveau, optionnel) — emplacement partage si extraction
  • CHANGELOG.md + CHANGELOG.fr.md — entree Fixed / Corrige

Surface de test

  • Tests existants touchant CategoryCombobox : aucun
  • Tests existants touchant categoryService pour le tri : aucun (categorizationService.test.ts et reportService.test.ts ne couvrent pas l'ordre)
  • Tests a ajouter :
    • src/utils/categoryTree.test.ts — cas multi-niveaux avec sort_order per-parent (chaque parent suivi immediatement de ses enfants)
    • src/components/shared/CategoryCombobox.test.tsx — rendu : ordre des <li> respecte la hierarchie, indentation matche le depth
  • Test de regression requis : oui (bug). Le test de tri d'arbre agit comme garde-fou.

Decision de scope

Fix dans le composant partage CategoryCombobox (decision confirmee lors de l'analyse).
Les quatre consommateurs (CategoryZoomHeader / rapport par categorie, TransactionFilterBar, SplitAdjustmentModal, TransactionTable) beneficient automatiquement du correctif sans modification.
Ecarte : pre-trier dans getAllCategoriesWithCounts — laisserait la meme bombe a retardement dans les trois autres consommateurs.

Criteres d'acceptation

  • Dans le rapport d'analyse par categorie, le menu deroulant non filtre affiche d'abord chaque parent de niveau 0, immediatement suivi de tous ses descendants (depth-first)
  • Les siblings (memes parent_id) restent tries par sort_order puis name
  • L'indentation visuelle continue de refleter depth (inchangee visuellement, mais l'ordre devient coherent)
  • La saisie pour filtrer continue de fonctionner (items restants tries dans l'ordre hierarchique)
  • TransactionFilterBar, SplitAdjustmentModal et TransactionTable beneficient automatiquement du correctif
  • npm run build et npm test passent
  • Entrees CHANGELOG FR + EN ajoutees sous ## [Unreleased]

Complexite estimee

Simple — ~30 lignes de changement net (extraction helper + useMemo dans le combobox + 2 tests). Aucun changement de schema, aucun changement IPC, aucun impact i18n.

Root cause (resume technique)

  • getAllCategoriesWithCounts() retourne ORDER BY c.sort_order, c.name — tri global sur un champ qui est alloue par parent.
  • CategoryCombobox.computeDepths calcule la profondeur mais ne reordonne pas.
  • Consequence : parents et enfants arrivent entremeles dans le DOM, avec indentation correcte mais ordre incoherent.
  • Fix : trier en profondeur (DFS siblings-by-sort_order) avant rendu, dans le composant.
## Contexte Le rapport d'analyse "par categorie" (`/reports/category`) utilise depuis le commit bd992f2 le composant partage `CategoryCombobox` a la place d'un `<select>` natif. Le combobox calcule correctement la profondeur de chaque categorie (via `parent_id`) et applique une indentation proportionnelle, mais il affiche les items dans l'ordre recu — c'est-a-dire l'ordre de `getAllCategoriesWithCounts()` : `ORDER BY c.sort_order, c.name`. Comme `sort_order` est attribue par parent (et non globalement), le tri global entremele parents et enfants. Resultat : la liste non filtree montre des niveaux melanges avec indentation visuelle, mais sans logique d'arbre. Le filtrage au clavier semble fonctionner car, en reduisant la liste, il masque l'interclassement des niveaux. La solution canonique existe deja dans le projet : `buildTree` + `flattenTreeToCategories` dans `src/hooks/useCategories.ts:61-92` (parcours depth-first qui emet chaque parent immediatement suivi de ses enfants). ## Travail a faire - [ ] Extraire `buildTree` et `flattenTreeToCategories` de `src/hooks/useCategories.ts` vers un util partage `src/utils/categoryTree.ts` (ou reexport depuis `useCategories.ts`) - [ ] Dans `src/components/shared/CategoryCombobox.tsx`, trier la prop `categories` en ordre d'arbre (depth-first, siblings tries par `sort_order` puis `name`) via `useMemo`, reutiliser la meme passe pour calculer la profondeur - [ ] Preserver le comportement de filtrage : quand l'utilisateur tape, filtrer sur la liste deja triee (l'ordre d'arbre est conserve entre les elements restants) - [ ] Ajouter des tests unitaires (Vitest) sur `flattenTreeToCategories` et sur `CategoryCombobox` (ordre des `<li>` rendus) - [ ] Ajouter une entree sous `## [Unreleased] > Fixed` dans `CHANGELOG.md` et `## [Unreleased] > Corrige` dans `CHANGELOG.fr.md` ## Fichiers concernes - `src/components/shared/CategoryCombobox.tsx` — tri hierarchique en memo, reutilisation de `depths` - `src/hooks/useCategories.ts` — exporter (ou deplacer) `buildTree` / `flattenTreeToCategories` - `src/utils/categoryTree.ts` (nouveau, optionnel) — emplacement partage si extraction - `CHANGELOG.md` + `CHANGELOG.fr.md` — entree Fixed / Corrige ## Surface de test - Tests existants touchant `CategoryCombobox` : aucun - Tests existants touchant `categoryService` pour le tri : aucun (`categorizationService.test.ts` et `reportService.test.ts` ne couvrent pas l'ordre) - Tests a ajouter : - `src/utils/categoryTree.test.ts` — cas multi-niveaux avec `sort_order` per-parent (chaque parent suivi immediatement de ses enfants) - `src/components/shared/CategoryCombobox.test.tsx` — rendu : ordre des `<li>` respecte la hierarchie, indentation matche le depth - Test de regression requis : **oui** (bug). Le test de tri d'arbre agit comme garde-fou. ## Decision de scope Fix dans le composant partage `CategoryCombobox` (decision confirmee lors de l'analyse). Les quatre consommateurs (`CategoryZoomHeader` / rapport par categorie, `TransactionFilterBar`, `SplitAdjustmentModal`, `TransactionTable`) beneficient automatiquement du correctif sans modification. Ecarte : pre-trier dans `getAllCategoriesWithCounts` — laisserait la meme bombe a retardement dans les trois autres consommateurs. ## Criteres d'acceptation - [ ] Dans le rapport d'analyse par categorie, le menu deroulant non filtre affiche d'abord chaque parent de niveau 0, immediatement suivi de tous ses descendants (depth-first) - [ ] Les siblings (memes `parent_id`) restent tries par `sort_order` puis `name` - [ ] L'indentation visuelle continue de refleter `depth` (inchangee visuellement, mais l'ordre devient coherent) - [ ] La saisie pour filtrer continue de fonctionner (items restants tries dans l'ordre hierarchique) - [ ] `TransactionFilterBar`, `SplitAdjustmentModal` et `TransactionTable` beneficient automatiquement du correctif - [ ] `npm run build` et `npm test` passent - [ ] Entrees CHANGELOG FR + EN ajoutees sous `## [Unreleased]` ## Complexite estimee **Simple** — ~30 lignes de changement net (extraction helper + `useMemo` dans le combobox + 2 tests). Aucun changement de schema, aucun changement IPC, aucun impact i18n. ## Root cause (resume technique) - `getAllCategoriesWithCounts()` retourne `ORDER BY c.sort_order, c.name` — tri global sur un champ qui est alloue par parent. - `CategoryCombobox.computeDepths` calcule la profondeur mais ne reordonne pas. - Consequence : parents et enfants arrivent entremeles dans le DOM, avec indentation correcte mais ordre incoherent. - Fix : trier en profondeur (DFS siblings-by-sort_order) avant rendu, dans le composant.
maximus added the
source:human
status:ready
type:bug
labels 2026-04-21 01:07:28 +00:00
maximus added the
status:in-progress
label 2026-04-22 00:58:40 +00:00
maximus added
status:review
and removed
status:in-progress
labels 2026-04-22 00:59:20 +00:00
maximus added
status:approved
and removed
status:review
labels 2026-04-22 01:00:01 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#126
No description provided.