Onboarding : carte d'étape, mise en évidence du contrôle, et carte de la page Import #398
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/Simpl-Resultat#398
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Milestone
planned-2026-10-06-onboarding-parcours-guide, issue 3/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.mdetspec-plan-onboarding-parcours-guide.md) est locale et ignorée par git : ce corps est auto-suffisant.Sur la page de l'étape en cours, une carte remplace le bandeau. Elle dit quoi faire, met en évidence le contrôle à utiliser, voit la réussite en direct et mène à l'étape suivante. Cette issue livre la carte générique, la mise en évidence et la carte de la page Import, qui suit l'assistant pour les étapes 2, 3 et 4.
À faire
src/components/onboarding/StepCard.tsx, piloté par props :h2avectabIndex={-1}:onboarding.card.stepOfpuis le libellé de l'étape. Dans « Étape n sur N », N est le nombre de lignes déverrouillées et n le rang (à partir de 1, dans l'ordre de la liste) de l'étape que montre la carte. Sur/import, c'est la première non faite parmiimportFolder,sourceetimport, ouimportquand les trois sont faites ;role="status"toujours rendue, d'abord vide, qui reçoitonboarding.card.donequand les étapes de la page sont faites ;onboarding.card.skip) seulement tant que l'étape n'est pas faite ;onboarding.card.next) seulement une fois les étapes de la page faites, en lien versnextStep.toavec l'état de focus ;onboarding.banner.complete, « Ouvrir le guide », « Fermer »).src/components/onboarding/OnboardingStepCard.tsx, la carte connectée :useOnboarding();mode === "card"et quecardPagevaut la route courante ;readOnboardingNavState(location.state).focusest vrai, puis consomme l'état (navigate(pathname, { replace: true, state: null }), une seule fois) ;skip,hideet le lien suivant ;Chaque page de carte rend
OnboardingStepCarden premier enfant, avant son en-tête.Mise en évidence, dans
src/styles.css:[data-onboarding-highlight="true"] { outline: 3px solid var(--accent); outline-offset: 2px; }, distinct de l'anneau de focusring-[var(--primary)];box-shadow,animation-iteration-count: 3;@media (prefers-reduced-motion: reduce): aucune animation.Un test lit
styles.css, extrait--accent,--backgroundet--carddes deux thèmes (:rootet.dark) et calcule le contraste WCAG, qui doit être d'au moins 3:1. Si l'accent échoue, créer une variable--onboarding-ringqui passe et la tester.Propriété
onboardingTarget?: boolean. Le composant rend alorsdata-onboarding-target="<clé>"etdata-onboarding-highlight="true". Elle s'ajoute sur :EmptyState(parEmptyStateAction,EmptyState.tsx:8-10), qu'ImportEmptyStatepasse à « Choisir un dossier » ou à « Créer un dossier d'exemple » ;SourceList, qui la passe à la première carte de sa boucle (SourceList.tsx:41-52,SourceCard) ;WizardNavigation(:52-61).ImportFolderConfigne reçoit pas de cible : sans dossier, l'état vide et son bouton sont toujours affichés (ImportPage.tsx:51,:109).ImportCardInputdansshared/types(wizardStep,folderLoaded,hasFolder,sourceCount,importing, etimportedCount, nombre ounullhors dereport).importCardModel(input, checklist)dansonboardingPath.tslit la table ci-dessous dans l'ordre et s'arrête à la première ligne qui s'applique.importedCountvient destate.importReport.importedCount(ImportReport,shared/types/index.ts:315-323).ImportPageconstruit l'entrée, rendOnboardingStepCardet passe la cible du modèle.CARD_PAGESreçoit/import.#384, fin du flash « aucun dossier » :
useImportWizardexposeimportFolderLoaded.finallyde la lecture du dossier au montage (:320-332, qui avale aujourd'hui ses erreurs).RESET(:290-298, qui reconstruit depuisinitialState), avec un test du reducer.CHANGELOG FR et EN (Added).
Modèle de la carte Import (dans cet ordre)
importingpasse avant les compteurs, parce que la ligneimported_filesest écritecompletedavant les insertions (useImportWizard.ts:1065, puis:1106).folderLoadedfauximportingcard.import.importingreportavecimportedCount === 0(insertion en échec ou doublons seulement)card.import.failedreportavecimportedCount > 0card.doneet « Étape suivante » ou fincard.import.noFoldercard.import.noSourcessource-listavec sourcescard.import.sourceListSourceListsource-configcard.import.sourceConfigfile-previewcard.import.filePreviewduplicate-checkcard.import.duplicateCheckconfirmcard.import.confirmcard.doneet « Étape suivante » ou finTextes (FR / EN)
onboarding.card.stepOfonboarding.card.skiponboarding.card.doneonboarding.card.nextonboarding.card.import.noFolderonboarding.card.import.noSourcesonboarding.card.import.sourceListonboarding.card.import.sourceConfigonboarding.card.import.filePreviewonboarding.card.import.duplicateCheckonboarding.card.import.confirmonboarding.card.import.importingonboarding.card.import.failedInterpolations : les libellés de boutons ne sont jamais recopiés.
{{button}}:import.empty.noFolder.ctapournoFolder;import.wizard.preview,import.wizard.checkDuplicates,import.wizard.confirmouimport.wizard.importselon l'état.{{refresh}}:import.empty.refresh.{{sample}}:import.empty.createSample.{{folder}}:folderNameFromPath.{{step}}:onboarding.checklist.items.<clé>.Fichiers concernés
ImportCardInput), src/utils/onboardingPath.ts (+ test :importCardModel,CARD_PAGES)importFolderLoaded,RESET)Depends on
Critères d'acceptation
StepCard(tests de rendu) :role="status"présent avant et après la réussite ;h2avectabIndex=-1et « Étape n sur N » ;onboardingTarget, exactement un élément portedata-onboarding-highlight="true"; sans, aucun (tests).importCardModelcouvre chaque ligne de la table, ordre compris :importingpasse avant « étapes cochées », etreportavecimportedCount === 0donnefailed.prefers-reduced-motion.RESET).npm run buildetnpx vitest runverts.Review caveats
cardPage), pasnextStep, qui décide de son affichage.OnboardingStepCardlit le contexte.Décisions prises en planification
outlineen--accent, 3 pulsations au plus, rien sousprefers-reduced-motion; le focus va sur le titre de la carte, pas sur la cible (WCAG 2.2.2, 1.4.11, 1.4.1, 4.1.3).onboarding_checklist_hiddenpar profil ; masquer le bandeau masque la liste, et le réaffichage depuis Paramètres → Utilisateurs rétablit tout.hidden, étapes passées, initialisation).Spec source
spec-plan-onboarding-parcours-guide.md (et spec-decisions-onboarding-parcours-guide.md)