feat(portal-shell): collapse accessibility routes into one i18n-marked route (#94)
## Summary
Continue ADR-0019: replace the `/accessibility` + `/accessibilite` twin routes with a single canonical route whose content is i18n-marked in the template. The per-locale build (en/fr) already inlines the right copy — the route-data + `copy()` service indirection is no longer carrying its weight.
## What changes
- **`AccessibilityStatement`** loses its `ActivatedRoute` injection, the `Lang` discriminator, and the `COPY` lookup table. The component is now a plain shell over the template.
- **`accessibility.html`** carries the title + intro + status panel as `i18n="@@page.accessibility.*"` markers. Six new trans-units in [`messages.fr.xlf`](apps/portal-shell/src/locale/messages.fr.xlf) provide the French copy — verbatim from the old `COPY.fr` block, so the page reads the same in FR as before.
- **`app.routes.ts`** declares the single canonical route at `path: 'accessibility'` and keeps `/accessibilite` alive as a `redirectTo: 'accessibility'`. Drops `data: { lang: ... }` — no longer consumed.
- **`footer.html`** collapses the dual link into one i18n-marked link (`@@footer.accessibilityLink`). EN bundle reads "Accessibility statement"; FR bundle reads "Déclaration d'accessibilité".
## Decision worth flagging
The path stays in English across both locales for now: `/en/accessibility` and `/fr/accessibility`. Translating route *segments* (`/fr/declaration-d-accessibilite`) needs either a custom URL serializer or per-locale route trees — not worth the complexity at this scale. The page title and the link label already differ per locale via i18n, which is what's actually visible to users.
The historical `/accessibilite` path keeps working via the route-level redirect. Drops out of the codebase once analytics confirm no traffic reaches it.
## Test plan
- [x] `pnpm exec nx run-many -t lint test build --projects=portal-shell` — green. **35 / 35 specs** (was 36; the obsolete `lang`-fallback test is removed).
- [x] Production build emits both locales. FR bundle contains `Statut`, `Déclaration`, the FR intro / panel bodies. No leftover English on swept strings.
- [x] `extract-i18n` clean (49 unique units now: +5 for `page.accessibility.*` + `footer.accessibilityLink`, −0; the old route-data `lang` markers were not i18n).
- [ ] Manual: serve-static then `/en/accessibility` and `/fr/accessibility` render their respective content; `/fr/accessibilite` 301-redirects to `/fr/accessibility`.
- [ ] Manual: footer shows one link, locale-aware ("Accessibility statement" / "Déclaration d'accessibilité").
- [ ] Manual: browser tab title flips between bundles ("Accessibility statement · APF Portal" / "Déclaration d'accessibilité · Portail APF").
## What this PR explicitly does NOT do
- Translate the URL path segment (next ADR-only refinement if needed).
- Add the locale switcher in the footer — that's the next PR on the i18n track.
- Wire a CI gate on missing translations.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #94
This commit was merged in pull request #94.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { Route } from '@angular/router';
|
||||
|
||||
// Tab titles per route — marked with `$localize` so each locale's
|
||||
// bundle ships its own. The `/accessibility` and `/accessibilite`
|
||||
// pair shares a title key; the upcoming route fusion (per ADR-0019)
|
||||
// collapses them to a single localised route.
|
||||
// bundle ships its own. The accessibility statement now lives at the
|
||||
// single canonical path `/accessibility` (per ADR-0019, replacing the
|
||||
// previous `/accessibility` + `/accessibilite` pair).
|
||||
const homeTitle = $localize`:@@route.home.title:APF Portal`;
|
||||
const accessibilityTitle = $localize`:@@route.accessibility.title:Accessibility statement · APF Portal`;
|
||||
|
||||
@@ -14,21 +14,21 @@ export const appRoutes: Route[] = [
|
||||
loadComponent: () => import('./pages/home/home').then((m) => m.Home),
|
||||
title: homeTitle,
|
||||
},
|
||||
// RGAA + ADR-0016: the accessibility statement must be reachable
|
||||
// from both locales' canonical paths. Same component, content
|
||||
// driven by the `lang` route data property.
|
||||
// RGAA + ADR-0016: the accessibility statement is reachable from
|
||||
// `/accessibility` in every locale. Content is i18n-marked so the
|
||||
// per-locale bundle ships the right copy automatically.
|
||||
{
|
||||
path: 'accessibility',
|
||||
loadComponent: () =>
|
||||
import('./pages/accessibility/accessibility').then((m) => m.AccessibilityStatement),
|
||||
data: { lang: 'en' },
|
||||
title: accessibilityTitle,
|
||||
},
|
||||
// Backward-compat: the historical French path redirects to the
|
||||
// canonical one. Bookmarks and existing inbound links keep working.
|
||||
// Drops out of the codebase once analytics confirm no traffic.
|
||||
{
|
||||
path: 'accessibilite',
|
||||
loadComponent: () =>
|
||||
import('./pages/accessibility/accessibility').then((m) => m.AccessibilityStatement),
|
||||
data: { lang: 'fr' },
|
||||
title: accessibilityTitle,
|
||||
redirectTo: 'accessibility',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user