90504dd32b404923ad704906742f93a8edd241bb
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
67e50be1dc |
fix(portal-admin): html/body overflow-y hidden as a shell shield (#176)
## Summary Tiny follow-up to #175 — the bar / donut / stacked-bar charts on the audit-log Charts tab still surfaced a *phantom* body scrollbar plus an empty band below the footer in some viewport widths. The lib-side overflow constraints from #175 hold for the cases tested, but the symptom can re-appear from any future layout escape (a wider downstream component, a third-party iframe, an unforeseen flex bug). This PR adds a `html, body { overflow-y: hidden }` shield at the global stylesheet so any vertical overflow at the document level — wherever it comes from — stops at the shell boundary instead of producing a phantom scrollbar. Element-level scrolling on `<main>` (the only surface that *should* scroll) is unaffected. ## What lands `apps/portal-admin/src/styles.css`: ```css html, body { overflow-y: hidden; } ``` That's the whole change. The admin shell already commits to the "fills the viewport, never scrolls the body" layout — `<app-root>` is locked at `height: 100vh` and `<main>` owns its own `overflow-y: auto`. Anything that escapes that contract is, by design, a bug to fix at the source. The shield is a safety net, not a load-bearing layout rule. ## Notes for the reviewer - **Why only portal-admin?** `portal-shell`'s app.scss carries the exact same `height: 100vh` + `<main> overflow-y: auto` shape, so the same shield would make sense there too. Holding it back to a separate PR because portal-shell hasn't actually demonstrated the symptom and the audit-log chantier is the immediate motivation — a one-line shield to the public-facing app deserves its own minute of consideration. Trivial to extend if/when we want symmetry. - **Why not just delete `height: 100vh` and let the document scroll naturally?** The admin shell deliberately keeps the header, sidebar, and footer pinned while only the content area scrolls — that's a deliberate UX choice for a dense admin surface (long audit-log tables, future CMS editors), not an accident. Keeping the 100vh contract and adding the shield preserves the intent. - **Manual reproduction of the original symptom** (now fixed): pre-shield, switching to the Charts tab on a 1280×720 viewport produced a body scrollbar with ~12 px of empty space below the footer, even though every visible element was inside `<main>`. Post-shield, the body scrollbar is gone; `<main>`'s internal scrollbar still works for the table page below the fold. ## Test plan - [x] `pnpm nx build portal-admin` — clean. - [x] `pnpm nx test portal-admin` — 62 specs pass (no behavioural change). - [x] `pnpm nx lint portal-admin` — same three pre-existing warnings, no new ones. - [ ] **Manual smoke** — `pnpm nx serve portal-admin`, sign in with `Portal.Admin`: - Navigate to `/admin/audit`, switch to Charts — no body scrollbar, no gap under the footer, charts still render at the column width. - Resize the viewport across the `(max-width: 800px)` breakpoint — body still doesn't scroll; `<main>` still does where it should. - Open the user-list page (long table) — `<main>` scrolls internally as expected; the shield does *not* prevent legitimate content scrolling. - Toggle dark mode — no visual regression. ## What's next - Mirror the same shield into `apps/portal-shell/src/styles.css` if/when a layout escape shows up there. Tracked in `docs/decisions/0020-portal-admin-app.md` follow-ups. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #176 |
||
|
|
d962be838a |
feat(portal-admin): skeleton app per ADR-0020 (#100)
## Summary
First step of the admin track per ADR-0020. Scaffold the second Angular SPA in the workspace alongside `portal-shell`, with the architectural decisions from the v1 ADRs already wired so subsequent feature PRs can drop straight into modules.
## What lands
- **App generated** via `nx g @nx/angular:application` (with the matching e2e project skeleton). Standalone, zoneless-ready, prefix `app`, scss component styles, css root stylesheet, no SSR.
- **Tags** `scope:portal-admin, type:app` — module-boundary lint now treats `portal-admin` distinctly from `portal-shell` and lets it depend only on `scope:portal-admin` + `scope:shared` libs.
- **Tailwind v4 + brand tokens**: `.postcssrc.json`, `@import 'tailwindcss'`, class-based dark variant, and `@import '../../../libs/shared/tokens/src/brand-tokens.css'` — identical visual baseline to portal-shell.
- **i18n config mirrors portal-shell** (per ADR-0019): sourceLocale `en`, target `fr`, baseHref `/{locale}/` per locale, `@angular/localize/init` polyfill, `localize: ["en", "fr"]` on production, `i18nMissingTranslation: "error"` so CI blocks any PR that adds a marker without translating it. Seed [`messages.fr.xlf`](apps/portal-admin/src/locale/messages.fr.xlf) carries the four marked strings used today.
- **Budgets** relaxed to **500 KB gzip initial** per ADR-0020 §"Performance budgets" (vs 300 KB for portal-shell).
- **Skeleton home page** at `/` — `<h1>` + intro paragraph + "Skeleton — coming soon" chip in the brand-accent palette. All marked for i18n.
- **Skip-link landmark** (WCAG 2.4.1) with the same component-scoped scss as portal-shell.
- **Wildcard catch-all route** → bounces unknown paths to home (same defensive pattern as PR #96 on portal-shell).
- **Dev server on port 4300** (vs 4200 for portal-shell) — both can run in parallel.
- **`serve-static` target without `spa: true`** — locale-prefixed routing in production is handled by the reverse proxy (per ADR-0019), same as portal-shell since PR #92.
## CLAUDE.md
Picked up the second app in the **Naming** entry and the **Commands** snippet (`<app>` is now one of `portal-shell`, `portal-admin`, `portal-bff`).
## Verification
- `pnpm exec nx run-many -t lint test build --projects=portal-shell,portal-admin,shared-ui,shared-state,shared-tokens` — green.
- `portal-admin` test: 1 spec (skip-link + main landmark present).
- Production build of `portal-admin`: **62 KB gzip initial per locale** (vs 500 KB budget — plenty of headroom for the upcoming modules).
- Both `dist/apps/portal-admin/browser/{en,fr}/` emit with the right `<html lang>` and `<base href>`. FR bundle contains `"Administration"` / `"Squelette"` / `"bientôt disponible"` — translations applied.
- portal-shell production build unchanged.
## Out of scope (each its own follow-up PR)
- Admin app shell (header / sidebar / footer with "Admin" badge — likely sharing graduated primitives plus admin-specific bits).
- OpenTelemetry tracing setup (`service.name=portal-admin` per ADR-0012).
- `environment.ts` wiring (per ADR-0018) for admin-specific endpoints.
- BFF `AdminModule` + `AdminRoleGuard` + smoke `/api/admin/me` (per ADR-0020 §"Auth").
- First functional module — CMS / menu / users / audit viewer.
## Test plan
- [x] Lint + test + build green across the workspace.
- [x] Per-locale production build emits both folders with correct metadata.
- [ ] Manual: `pnpm exec nx serve portal-admin` boots on `:4300`, smoke page renders.
- [ ] Manual: prod build + `pnpm exec nx run portal-admin:serve-static` → `http://localhost:4300/en/` and `/fr/` show the placeholder with the matching language.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #100
|