Onboarding : état vide dédié de la page Import, bouton « Créer un dossier d'exemple » et liens vers le guide #356

Closed
opened 2026-09-26 12:24:30 +00:00 by maximus · 0 comments
Owner

Vague planned-2026-10-03-onboarding-phase1 (séance /plan-run du 2026-10-03, spec + /review-spec du 2026-09-25, verdict APPROUVÉ après intégration). Les fichiers spec-decisions-onboarding-phase1.md / spec-plan-onboarding-phase1.md sont ignorés par git : ce corps est auto-suffisant, ne pas chercher le spec. Analyse d'origine : docs/analyse-onboarding-2026-09.md.

Règles de la vague : pile linéaire (chaque PR part de la précédente) ; ne pas toucher CHANGELOG.md / CHANGELOG.fr.md avant #357 qui les centralise ; FR + EN pour toute clé i18n (.claude/rules/i18n.md) ; aucune migration DB ; aucune chaîne en dur dans les composants.

Objectif

La page Import sans dossier propose de le choisir ; avec un dossier vide, elle propose de créer le dossier d'exemple ; les deux états et le popover « ? » mènent au guide d'export CSV.

Tâches

  • src/hooks/useImportWizard.ts : exporter wizardReducer + initialWizardState (privé en :179) ; état sampleCreated: string[] | null ; action createSampleFolders() = invoke<string[]>("create_sample_import_folders", { importFolder: state.importFolder, today }) avec today = date locale du webview formatée YYYY-MM-DD, puis scanFolderInternal(folder), puis SET_SAMPLE_CREATED(names) ; reset et browseFolder remettent sampleCreated à null ; erreur → SET_ERROR existant (message tel que renvoyé par Rust) ; logInfo avec les noms de dossiers seulement, jamais le chemin complet
  • src/components/import/ImportEmptyState.tsx (nouveau, pur, construit sur EmptyState) : props { hasFolder, folderName, onBrowse, onCreateSample, onRefresh, isCreatingSample } ; sans dossier → « Commencez par choisir le dossier où vous déposerez vos relevés », bouton primaire « Choisir un dossier » (onBrowse), lien secondaire « Comment exporter un CSV depuis ma banque ? » → /settings/users#import-export ; avec dossier → « Créez un sous-dossier par banque dans {folderName} et déposez-y vos fichiers CSV », bouton primaire « Créer un dossier d'exemple » (disabled pendant isCreatingSample), bouton secondaire « Actualiser » (onRefresh), même lien ; folderName = dernier segment du chemin
  • ImportPage.tsx : rendre ImportEmptyState à la place de SourceList quand state.step === "source-list" et state.scannedSources.length === 0 ; SourceList.tsx reste intact ; bandeau de succès refermable quand state.sampleCreated est non nul (même forme que le bandeau d'erreur :49-60, bordure var(--positive)) : « Deux dossiers d'exemple ont été créés : Exemple Desjardins, Exemple Tangerine. Cliquez sur l'un d'eux pour lancer l'import. Supprimez-les quand vos vrais relevés sont en place. »
  • ImportFolderConfig.tsx : « Parcourir » en style secondaire (bordure, comme « Actualiser ») quand folderPath est nul, pour qu'un seul bouton primaire soit à l'écran
  • PageHelp.tsx : prop optionnelle linkTo?: string ; si présente, <Link to={linkTo}> rendu sous la liste tips avec le libellé t(${helpKey}.help.linkLabel) ; pas de fermeture explicite au clic (la navigation démonte la page) ; ImportPage passe linkTo="/settings/users#import-export"
  • Clés i18n FR + EN : import.empty.noFolder.*, import.empty.noSources.*, import.empty.createSample, import.empty.refresh, import.empty.guideLink, import.empty.sampleCreated, import.help.linkLabel

Fichiers concernés

  • src/hooks/useImportWizard.ts + src/hooks/useImportWizard.test.ts (nouveau)
  • src/components/import/ImportEmptyState.tsx (nouveau) + ImportEmptyState.test.tsx (nouveau)
  • src/components/import/ImportFolderConfig.tsx
  • src/components/shared/PageHelp.tsx
  • src/pages/ImportPage.tsx
  • src/i18n/locales/fr.json, src/i18n/locales/en.json

Depends on

Critères d'acceptation

  • useImportWizard.test.ts : SET_SAMPLE_CREATED pose les noms ; reset et SET_IMPORT_FOLDER (via browseFolder) l'effacent ; une erreur de création laisse scannedSources inchangé
  • ImportEmptyState.test.tsx : variante sans dossier (bouton « Choisir un dossier », lien guide) ; variante avec dossier (bouton « Créer » désactivé quand isCreatingSample, « Actualiser », lien guide) ; folderName affiché sans le chemin complet
  • Sur un dossier vide, « Créer un dossier d'exemple » → les deux sources apparaissent dans SourceList sans clic supplémentaire, bandeau de succès affiché et refermable
  • Relancer quand un dossier d'exemple existe → message d'erreur dans le bandeau d'erreur existant, rien d'écrit
  • Avec au moins une source scannée, ImportEmptyState n'est jamais rendu
  • Journaux (Paramètres → Systèmes → Journaux) : la création apparaît avec les noms de dossiers, sans chemin absolu
  • npm test, npm run build verts

Review caveats

  • (ARCHITECTURE, résolu) SourceList reste une liste pure ; un seul bouton primaire par état.
  • (SECURITE, rendu obligatoire le 2026-10-03) Noms de dossiers dans les journaux, jamais de chemins complets : les journaux sont joignables à une rétroaction.
  • (ARCHITECTURE + TECHNIQUE, résolu) linkTo + ${helpKey}.help.linkLabel ; pas de fermeture explicite du popover.

Décisions prises en planification

  • Case 5 de la liste = « une transaction classée à la main » (is_manually_categorized = 1) et non « règle créée » ni « transactions catégorisées » : le seed IPC met 180 mots-clés dans tout profil neuf et le wizard catégorise pendant l'import (useImportWizard.ts:1016).
  • Ordre des vagues : planned-2026-09-24-paiements s'exécute avant celle-ci (fichiers partagés : fr.json, en.json, CHANGELOG, architecture.md, guide-utilisateur.md) ; partir d'un main qui contient déjà ses clés.
  • Pas de bouton « Retirer le dossier d'exemple » : l'utilisateur supprime les sous-dossiers lui-même, puis l'import dans l'historique s'il le souhaite (fonction existante).

Spec source

spec-plan-onboarding-phase1.md (local, ignoré par git)

Vague `planned-2026-10-03-onboarding-phase1` (séance `/plan-run` du 2026-10-03, spec + `/review-spec` du 2026-09-25, verdict APPROUVÉ après intégration). Les fichiers `spec-decisions-onboarding-phase1.md` / `spec-plan-onboarding-phase1.md` sont **ignorés par git** : ce corps est auto-suffisant, ne pas chercher le spec. Analyse d'origine : `docs/analyse-onboarding-2026-09.md`. Règles de la vague : pile linéaire (chaque PR part de la précédente) ; **ne pas toucher `CHANGELOG.md` / `CHANGELOG.fr.md`** avant #357 qui les centralise ; FR + EN pour toute clé i18n (`.claude/rules/i18n.md`) ; aucune migration DB ; aucune chaîne en dur dans les composants. ## Objectif La page Import sans dossier propose de le choisir ; avec un dossier vide, elle propose de créer le dossier d'exemple ; les deux états et le popover « ? » mènent au guide d'export CSV. ## Tâches - [ ] `src/hooks/useImportWizard.ts` : exporter `wizardReducer` + `initialWizardState` (privé en `:179`) ; état `sampleCreated: string[] | null` ; action `createSampleFolders()` = `invoke<string[]>("create_sample_import_folders", { importFolder: state.importFolder, today })` avec `today` = date locale du webview formatée `YYYY-MM-DD`, puis `scanFolderInternal(folder)`, puis `SET_SAMPLE_CREATED(names)` ; `reset` et `browseFolder` remettent `sampleCreated` à `null` ; erreur → `SET_ERROR` existant (message tel que renvoyé par Rust) ; `logInfo` avec les **noms** de dossiers seulement, jamais le chemin complet - [ ] `src/components/import/ImportEmptyState.tsx` (nouveau, pur, construit sur `EmptyState`) : props `{ hasFolder, folderName, onBrowse, onCreateSample, onRefresh, isCreatingSample }` ; sans dossier → « Commencez par choisir le dossier où vous déposerez vos relevés », bouton primaire « Choisir un dossier » (`onBrowse`), lien secondaire « Comment exporter un CSV depuis ma banque ? » → `/settings/users#import-export` ; avec dossier → « Créez un sous-dossier par banque dans {folderName} et déposez-y vos fichiers CSV », bouton primaire « Créer un dossier d'exemple » (`disabled` pendant `isCreatingSample`), bouton secondaire « Actualiser » (`onRefresh`), même lien ; `folderName` = dernier segment du chemin - [ ] `ImportPage.tsx` : rendre `ImportEmptyState` à la place de `SourceList` quand `state.step === "source-list"` et `state.scannedSources.length === 0` ; **`SourceList.tsx` reste intact** ; bandeau de succès refermable quand `state.sampleCreated` est non nul (même forme que le bandeau d'erreur `:49-60`, bordure `var(--positive)`) : « Deux dossiers d'exemple ont été créés : Exemple Desjardins, Exemple Tangerine. Cliquez sur l'un d'eux pour lancer l'import. Supprimez-les quand vos vrais relevés sont en place. » - [ ] `ImportFolderConfig.tsx` : « Parcourir » en style secondaire (bordure, comme « Actualiser ») quand `folderPath` est nul, pour qu'un seul bouton primaire soit à l'écran - [ ] `PageHelp.tsx` : prop optionnelle `linkTo?: string` ; si présente, `<Link to={linkTo}>` rendu sous la liste `tips` avec le libellé `t(`${helpKey}.help.linkLabel`)` ; pas de fermeture explicite au clic (la navigation démonte la page) ; `ImportPage` passe `linkTo="/settings/users#import-export"` - [ ] Clés i18n FR + EN : `import.empty.noFolder.*`, `import.empty.noSources.*`, `import.empty.createSample`, `import.empty.refresh`, `import.empty.guideLink`, `import.empty.sampleCreated`, `import.help.linkLabel` ## Fichiers concernés - `src/hooks/useImportWizard.ts` + `src/hooks/useImportWizard.test.ts` (nouveau) - `src/components/import/ImportEmptyState.tsx` (nouveau) + `ImportEmptyState.test.tsx` (nouveau) - `src/components/import/ImportFolderConfig.tsx` - `src/components/shared/PageHelp.tsx` - `src/pages/ImportPage.tsx` - `src/i18n/locales/fr.json`, `src/i18n/locales/en.json` ## Depends on - #352 - #354 - #355 ## Critères d'acceptation - [ ] `useImportWizard.test.ts` : `SET_SAMPLE_CREATED` pose les noms ; `reset` et `SET_IMPORT_FOLDER` (via `browseFolder`) l'effacent ; une erreur de création laisse `scannedSources` inchangé - [ ] `ImportEmptyState.test.tsx` : variante sans dossier (bouton « Choisir un dossier », lien guide) ; variante avec dossier (bouton « Créer » désactivé quand `isCreatingSample`, « Actualiser », lien guide) ; `folderName` affiché sans le chemin complet - [ ] Sur un dossier vide, « Créer un dossier d'exemple » → les deux sources apparaissent dans `SourceList` sans clic supplémentaire, bandeau de succès affiché et refermable - [ ] Relancer quand un dossier d'exemple existe → message d'erreur dans le bandeau d'erreur existant, rien d'écrit - [ ] Avec au moins une source scannée, `ImportEmptyState` n'est jamais rendu - [ ] Journaux (`Paramètres → Systèmes → Journaux`) : la création apparaît avec les noms de dossiers, sans chemin absolu - [ ] `npm test`, `npm run build` verts ## Review caveats - (ARCHITECTURE, résolu) `SourceList` reste une liste pure ; un seul bouton primaire par état. - (SECURITE, rendu obligatoire le 2026-10-03) Noms de dossiers dans les journaux, jamais de chemins complets : les journaux sont joignables à une rétroaction. - (ARCHITECTURE + TECHNIQUE, résolu) `linkTo` + `${helpKey}.help.linkLabel` ; pas de fermeture explicite du popover. ## Décisions prises en planification - Case 5 de la liste = « une transaction classée à la main » (`is_manually_categorized = 1`) et non « règle créée » ni « transactions catégorisées » : le seed IPC met 180 mots-clés dans tout profil neuf et le wizard catégorise pendant l'import (`useImportWizard.ts:1016`). - Ordre des vagues : `planned-2026-09-24-paiements` s'exécute **avant** celle-ci (fichiers partagés : `fr.json`, `en.json`, CHANGELOG, `architecture.md`, `guide-utilisateur.md`) ; partir d'un `main` qui contient déjà ses clés. - Pas de bouton « Retirer le dossier d'exemple » : l'utilisateur supprime les sous-dossiers lui-même, puis l'import dans l'historique s'il le souhaite (fonction existante). ## Spec source spec-plan-onboarding-phase1.md (local, ignoré par git)
maximus added this to the planned-2026-10-03-onboarding-phase1 milestone 2026-09-26 12:24:30 +00:00
maximus added the
status:ready
type:feature
source:human
labels 2026-09-26 12:24:30 +00:00
maximus changed title from Onboarding: Import empty states, « Create sample folder » button and deep links to the guide to Onboarding : état vide dédié de la page Import, bouton « Créer un dossier d'exemple » et liens vers le guide 2026-10-03 14:09:46 +00:00
maximus added
status:in-progress
and removed
status:ready
labels 2026-10-04 00:05:58 +00:00
maximus added
status:review
and removed
status:in-progress
labels 2026-10-04 00:11:14 +00:00
maximus added
status:approved
and removed
status:review
labels 2026-10-04 00:12:26 +00:00
maximus removed the
status:approved
label 2026-10-04 12:52:53 +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#356
No description provided.