Skip to content

[V2 Repeq] Mon-espace: panneau latéral 4 états (A/B/C/D) + branchement DeclarationLink #3300

@Viczei

Description

@Viczei

Contexte

Intègre le panneau latéral "Représentation équilibrée" dans mon-espace : 4 états (A non commencée / B en cours / C transmise modifiable / D lecture seule), boutons Déclarer/Reprendre/Modifier/Consulter, téléchargement PDF, deadline. Branche le lien DeclarationLink type="representation" actuellement placeholder sur cette nouvelle infra. Issue parent #3287. Dépend de #3291, #3298.

La distinction entre état C (modifiable) et D (lecture seule) est déterminée par la deadline repeqModificationDeadline stockée dans la table campaign_deadlines (cf. #3288, décision architecturale Q2). Le panneau lit cette deadline via getRepeqModificationDeadline(campaignDeadlines, year) depuis ~/modules/domain (cf. #3289).

Fichiers impactés

  • packages/app/src/modules/my-space/RepresentationProcessPanel.tsx (création)
  • packages/app/src/modules/my-space/RepresentationProcessPanel.module.scss (création — ou réutiliser DeclarationProcessPanel.module.scss si identique)
  • packages/app/src/modules/my-space/representationProcessState.ts (création — computeRepresentationPanelVariant, computeRepresentationCtaHref)
  • packages/app/src/modules/my-space/__tests__/RepresentationProcessPanel.test.tsx (création)
  • packages/app/src/modules/my-space/__tests__/representationProcessState.test.ts (création)
  • packages/app/src/modules/my-space/DeclarationLink.tsx (modification — type="representation" ouvre RepresentationProcessPanel)
  • packages/app/src/modules/my-space/CompanyDeclarationsPage.tsx (modification — charger la repeq de l'année + rendre RepresentationProcessPanel avec la deadline)
  • packages/app/src/modules/my-space/types.ts (modification — étendre DeclarationItem si besoin pour repeq fields ou créer un RepresentationItem)
  • packages/app/src/modules/my-space/buildDeclarationList.ts (modification — intégrer les repeq pour chaque année)
  • packages/app/src/server/api/routers/company.ts (modification — getWithDeclarations joint la table repeq et remplit les champs)

Changement attendu

  1. representationProcessState.ts :
    • computeRepresentationPanelVariant(declaration: RepresentationItem | undefined, modificationDeadline: Date, now?: Date): "start" | "in_progress" | "submitted_modifiable" | "read_only" — pattern computePanelVariant adapté aux 4 états :
      • "start" si pas de ligne ou status draft/to_complete.
      • "in_progress" si status === "in_progress".
      • "submitted_modifiable" si submitted && !isDeadlinePassed(modificationDeadline, now).
      • "read_only" si submitted && isDeadlinePassed(modificationDeadline, now).
      • now est injecté pour la testabilité (pattern déjà en usage dans declarationProcessState).
    • computeRepresentationCtaHref(declaration, siren) — retourne /representation-equilibree/etape/N où N = currentStep si in_progress, /etape/1 sinon ; pour "submitted_modifiable", pointe vers /etape/1 (accès direct RGAA N°15/N°17).
  2. RepresentationProcessPanel : pattern DeclarationProcessPanel adapté.
    • Dialog DSFR (<dialog role="dialog" aria-labelledby>).
    • Props : { variant, year, lastActionDate, siren, ctaHref, modificationDeadline }.
    • Selon variant :
      • A (start) : alerte info "Déclarez chaque année…" + deadline (getRepeqDeclarationDeadline(year)) + lien "En savoir plus" + bouton "Déclarer" primaire.
      • B (in_progress) : stepper vertical 4 étapes (reproduit le pattern VerticalStepper ou en crée un nouveau RepresentationVerticalStepper si les étapes diffèrent trop) + bouton "Reprendre la déclaration" primaire.
      • C (submitted_modifiable) : alerte success + deadline (format DSFR à partir de modificationDeadline passée en prop) + <DownloadRepeqPdfButton /> + 2 boutons ("Modifier" primaire → /etape/1, "Consulter" secondaire → /representation-equilibree/{siren}/{year}).
      • D (read_only) : alerte info + <DownloadRepeqPdfButton /> + bouton unique "Consulter" secondaire.
  3. DeclarationLink : remplace le placeholder actuel (type === "representation" → bouton inerte) par un bouton qui ouvre REPRESENTATION_PROCESS_PANEL_ID (même pattern que remuneration).
  4. CompanyDeclarationsPage : ajoute <RepresentationProcessPanel {...} /> après DeclarationProcessPanel. Calcule la variant via computeRepresentationPanelVariant(repeqItem, getRepeqModificationDeadline(campaignDeadlines, year)).
  5. Company router getWithDeclarations : modifie la requête pour joindre la table representationEquilibreeDeclarations et renvoyer pour chaque année un item de type "representation" avec les champs pertinents (status, currentStep, updatedAt, submittedAt). Intègre dans buildDeclarationList (étendre pour supporter les 2 types déjà prévus dans EXPECTED_DECLARATION_TYPES).
  6. Types : étend DeclarationItem pour supporter type: "representation" avec les champs minimaux { type, siren, year, status, currentStep, updatedAt, submittedAt }. Les champs actuels spécifiques rémunération (compliancePath, secondDeclarationStatus, etc.) restent optionnels/nullables pour les lignes repeq.
  7. Tests :
    • representationProcessState.test.ts : 4 cas de variants (start / in_progress / submitted_modifiable avec deadline future / read_only avec deadline dépassée) + 2 cas de ctaHref.
    • RepresentationProcessPanel.test.tsx : rendu des 4 états (snapshot ou assertions ciblées). Assertion clé : état D (read_only) n'affiche pas le bouton "Modifier".
    • DeclarationLink.test.tsx (existant) : ajout d'un test que type="representation" rend un bouton aria-controls={REPRESENTATION_PROCESS_PANEL_ID}.
    • buildDeclarationList.test.ts : ajout de lignes repeq en plus de remuneration.

Scénarios de test

  • S1 — État A, clic "Déclarer" → panneau ouvert, bouton primaire route /representation-equilibree/etape/1.
  • S11 — État C (deadline non dépassée), clic "Modifier" → route /representation-equilibree/etape/1 (accès direct, pas via récap).
  • S12 — État D (deadline dépassée), pas de bouton "Modifier", seul "Consulter" + PDF.

Références visuelles

Desktop
Mon-espace panneau latéral desktop

Mobile
Mon-espace panneau latéral mobile

Annexe pipeline (lecture locale par code-dev / design-validator) :

  • /tmp/egapro-mocks/epic-3287/screenshots/mon-espace-side-panel-desktop.png
  • /tmp/egapro-mocks/epic-3287/screenshots/mon-espace-side-panel-mobile.png

Critères d'acceptation

  • Panneau latéral "Représentation équilibrée" accessible depuis la ligne "Représentation" du tableau mon-espace
  • 4 variants affichés selon l'état réel en DB
  • La variant utilise getRepeqModificationDeadline(campaignDeadlines, year) depuis ~/modules/domain (pas de date hardcodée)
  • État C (submitted, deadline future) : 2 boutons ("Modifier" accès direct étape 1 + "Consulter")
  • État D (submitted, deadline passée) : pas de bouton "Modifier", seul "Consulter" + PDF
  • PDF téléchargeable dans les états C et D
  • Toute fr-alert affichée dans le panneau (info deadline, succès transmission) possède un fr-alert__title conforme DSFR (RGAA N°33)
  • Tests verts (≥ 6 cas dont le test de bascule C→D via la deadline)
  • pnpm typecheck + pnpm lint:check + pnpm format:check + pnpm test verts
  • RGAA (rgaa-auditor) — dialog a role="dialog" + aria-modal + aria-labelledby
  • Validation visuelle (design-validator) PASS sur mon-espace-side-panel-*.png pour les 4 états

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status

    To Do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions