Onboarding : carte de l'étape « Classer une transaction à la main » (Transactions) #399

Closed
opened 2026-10-07 23:50:08 +00:00 by maximus · 0 comments
Owner

Milestone planned-2026-10-06-onboarding-parcours-guide, issue 4/6. Phase 2 de l'onboarding (#391) : bandeau de démarrage sur chaque page, et cartes d'étape avec mise en évidence. La spec (spec-decisions-onboarding-parcours-guide.md et spec-plan-onboarding-parcours-guide.md) est locale et ignorée par git : ce corps est auto-suffisant.

La carte de l'étape 5 ouvre la page Transactions sur les transactions non catégorisées, toutes dates confondues, et met en évidence la catégorie de la première ligne.

À faire

  1. Entrée guidée. useTransactions(initialFilters?) accepte des filtres de départ ; son reducer reste exporté. TransactionsPage démarre avec { dateFrom: null, uncategorizedOnly: true } quand readOnboardingNavState(location.state).guided est vrai. Le filtre par défaut part sinon du 1er janvier (useTransactions.ts:67), et en janvier les relevés d'exemple tombent l'année précédente.
  2. Repli : si la première page revient avec totalCount === 0 alors que le filtre guidé est actif, le reducer retire uncategorizedOnly et relance la lecture, une seule fois. Pas de compteur uncategorized : le prédicat reste celui de getTransactionPage (t.category_id IS NULL, t.parent_transaction_id IS NULL).
  3. Cible : un enveloppeur qui porte data-onboarding-target et data-onboarding-highlight, autour de la catégorie de la première ligne affichée (TransactionTable.tsx:190-201). TransactionTable reçoit onboardingTarget?: boolean ; CategoryCombobox ne change pas.
  4. transactionsCardModel({ uncategorizedOnly }) : texte uncategorized quand le filtre est appliqué, sinon all. La page rend OnboardingStepCard en premier enfant, avant son en-tête. CARD_PAGES reçoit /transactions.
  5. CHANGELOG FR et EN (Added).

Textes (FR / EN)

Clé FR EN
onboarding.card.transactions.uncategorized Seules les transactions {{filter}} sont affichées. Cliquez sur la catégorie de l'une d'elles et choisissez-en une dans la liste. Simpl'Résultat retient ce choix, et la catégorisation automatique ne le remplacera pas. Only {{filter}} transactions are shown. Click the category of one of them and pick one from the list. Simpl'Résultat keeps your choice, and automatic categorization will not replace it.
onboarding.card.transactions.all Cliquez sur la catégorie d'une transaction et choisissez-en une dans la liste. Simpl'Résultat retient ce choix, et la catégorisation automatique ne le remplacera pas. Click a transaction's category and pick one from the list. Simpl'Résultat keeps your choice, and automatic categorization will not replace it.

{{filter}} : transactions.filters.uncategorized, en minuscules dans la phrase. L'affirmation « la catégorisation automatique ne le remplacera pas » est vraie : autoCategorizeTransactions ne touche que category_id IS NULL AND is_manually_categorized = 0.

Fichiers concernés

  • src/hooks/useTransactions.ts (+ useTransactions.test.ts)
  • src/pages/TransactionsPage.tsx
  • src/components/transactions/TransactionTable.tsx (+ test de rendu de la cible)
  • src/utils/onboardingPath.ts (+ test : transactionsCardModel, CARD_PAGES)
  • src/i18n/locales/fr.json, en.json ; CHANGELOG.md, CHANGELOG.fr.md

Depends on

Critères d'acceptation

  • Reducer de useTransactions (tests) : filtres de départ appliqués ; repli du filtre guidé sur totalCount === 0, une seule fois ; une visite ordinaire garde les filtres par défaut.
  • TransactionTable : avec onboardingTarget, exactement un élément porte la mise en évidence, autour de la catégorie de la première ligne (test de rendu).
  • transactionsCardModel : les deux textes.
  • Profil neuf, arrivée par « Étape suivante » : liste non catégorisée sans borne de date, carte, cible. Classer une transaction coche l'étape en direct (#390 mergée), la carte reste, annonce « Fait. » et propose l'étape Budget, ou la fin en édition Gratuite.
  • FR et EN ; CHANGELOG FR et EN ; npm run build et npx vitest run verts.

Review caveats

  • Toute lecture de l'état de navigation passe par readOnboardingNavState (CWE-476).
  • Le repli ne doit pas boucler : une seule fois par entrée guidée.

Décisions prises en planification

  • Entrée guidée sans borne de date, filtrée sur « Non catégorisées » s'il en existe, sinon toutes les transactions.
  • D8 : un seul état masqué, la préférence onboarding_checklist_hidden par profil ; masquer le bandeau masque la liste, et le réaffichage depuis Paramètres → Utilisateurs rétablit tout.
  • Le fournisseur d'onboarding est le seul écrivain des préférences d'onboarding (hidden, étapes passées, initialisation).

Spec source

spec-plan-onboarding-parcours-guide.md (et spec-decisions-onboarding-parcours-guide.md)

Milestone `planned-2026-10-06-onboarding-parcours-guide`, issue 4/6. Phase 2 de l'onboarding (#391) : bandeau de démarrage sur chaque page, et cartes d'étape avec mise en évidence. La spec (`spec-decisions-onboarding-parcours-guide.md` et `spec-plan-onboarding-parcours-guide.md`) est locale et ignorée par git : ce corps est auto-suffisant. La carte de l'étape 5 ouvre la page Transactions sur les transactions non catégorisées, toutes dates confondues, et met en évidence la catégorie de la première ligne. ## À faire 1. **Entrée guidée.** `useTransactions(initialFilters?)` accepte des filtres de départ ; son reducer reste exporté. `TransactionsPage` démarre avec `{ dateFrom: null, uncategorizedOnly: true }` quand `readOnboardingNavState(location.state).guided` est vrai. Le filtre par défaut part sinon du 1er janvier (`useTransactions.ts:67`), et en janvier les relevés d'exemple tombent l'année précédente. 2. **Repli** : si la première page revient avec `totalCount === 0` alors que le filtre guidé est actif, le reducer retire `uncategorizedOnly` et relance la lecture, une seule fois. Pas de compteur `uncategorized` : le prédicat reste celui de `getTransactionPage` (`t.category_id IS NULL`, `t.parent_transaction_id IS NULL`). 3. **Cible** : un enveloppeur qui porte `data-onboarding-target` et `data-onboarding-highlight`, autour de la catégorie de la **première** ligne affichée (`TransactionTable.tsx:190-201`). `TransactionTable` reçoit `onboardingTarget?: boolean` ; `CategoryCombobox` ne change pas. 4. **`transactionsCardModel({ uncategorizedOnly })`** : texte `uncategorized` quand le filtre est appliqué, sinon `all`. La page rend `OnboardingStepCard` en premier enfant, avant son en-tête. `CARD_PAGES` reçoit `/transactions`. 5. **CHANGELOG** FR et EN (Added). ## Textes (FR / EN) | Clé | FR | EN | |---|---|---| | `onboarding.card.transactions.uncategorized` | Seules les transactions {{filter}} sont affichées. Cliquez sur la catégorie de l'une d'elles et choisissez-en une dans la liste. Simpl'Résultat retient ce choix, et la catégorisation automatique ne le remplacera pas. | Only {{filter}} transactions are shown. Click the category of one of them and pick one from the list. Simpl'Résultat keeps your choice, and automatic categorization will not replace it. | | `onboarding.card.transactions.all` | Cliquez sur la catégorie d'une transaction et choisissez-en une dans la liste. Simpl'Résultat retient ce choix, et la catégorisation automatique ne le remplacera pas. | Click a transaction's category and pick one from the list. Simpl'Résultat keeps your choice, and automatic categorization will not replace it. | `{{filter}}` : `transactions.filters.uncategorized`, en minuscules dans la phrase. L'affirmation « la catégorisation automatique ne le remplacera pas » est vraie : `autoCategorizeTransactions` ne touche que `category_id IS NULL AND is_manually_categorized = 0`. ## Fichiers concernés - src/hooks/useTransactions.ts (+ useTransactions.test.ts) - src/pages/TransactionsPage.tsx - src/components/transactions/TransactionTable.tsx (+ test de rendu de la cible) - src/utils/onboardingPath.ts (+ test : `transactionsCardModel`, `CARD_PAGES`) - src/i18n/locales/fr.json, en.json ; CHANGELOG.md, CHANGELOG.fr.md ## Depends on - #398 ## Critères d'acceptation - [ ] Reducer de `useTransactions` (tests) : filtres de départ appliqués ; repli du filtre guidé sur `totalCount === 0`, une seule fois ; une visite ordinaire garde les filtres par défaut. - [ ] `TransactionTable` : avec `onboardingTarget`, exactement un élément porte la mise en évidence, autour de la catégorie de la première ligne (test de rendu). - [ ] `transactionsCardModel` : les deux textes. - [ ] Profil neuf, arrivée par « Étape suivante » : liste non catégorisée sans borne de date, carte, cible. Classer une transaction coche l'étape en direct (#390 mergée), la carte reste, annonce « Fait. » et propose l'étape Budget, ou la fin en édition Gratuite. - [ ] FR et EN ; CHANGELOG FR et EN ; `npm run build` et `npx vitest run` verts. ## Review caveats - Toute lecture de l'état de navigation passe par `readOnboardingNavState` (CWE-476). - Le repli ne doit pas boucler : une seule fois par entrée guidée. ## Décisions prises en planification - Entrée guidée sans borne de date, filtrée sur « Non catégorisées » s'il en existe, sinon toutes les transactions. - D8 : un seul état masqué, la préférence `onboarding_checklist_hidden` par profil ; masquer le bandeau masque la liste, et le réaffichage depuis Paramètres → Utilisateurs rétablit tout. - Le fournisseur d'onboarding est le seul écrivain des préférences d'onboarding (`hidden`, étapes passées, initialisation). ## Spec source spec-plan-onboarding-parcours-guide.md (et spec-decisions-onboarding-parcours-guide.md)
maximus added this to the planned-2026-10-06-onboarding-parcours-guide milestone 2026-10-07 23:50:08 +00:00
maximus added the
status:ready
type:feature
source:human
labels 2026-10-07 23:50:08 +00:00
maximus added
status:review
and removed
status:ready
labels 2026-10-08 13:00:01 +00:00
maximus added
status:approved
and removed
status:review
labels 2026-10-09 00:00:31 +00:00
maximus removed the
status:approved
label 2026-10-09 01:11:27 +00:00
Sign in to join this conversation.
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#399
No description provided.