From 8329fa133d61f3bfd7ff98cf3c37a14c5a467f0b Mon Sep 17 00:00:00 2001 From: Julien Gautier Date: Tue, 12 May 2026 01:17:30 +0200 Subject: [PATCH] refactor(libs): graduate Icon / LayoutStateService / brand tokens to libs/shared/* (#99) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Per ADR-0020 §"Shared-libs graduation": the three primitives that `portal-shell` (today) and `portal-admin` (next) will both share move out of `apps/portal-shell/src/` and into the workspace libs. Mechanical move — no behaviour change, prepares the ground for the admin-app PR. ## Graduated | Primitive | Old location | New location | |---|---|---| | `Icon` component (+ `IconName` type) | `apps/portal-shell/src/app/components/icon/` | [`libs/shared/ui/src/lib/icon/`](libs/shared/ui/src/lib/icon/) | | `LayoutStateService` (+ `ThemeMode` type) | `apps/portal-shell/src/app/state/` | [`libs/shared/state/src/lib/`](libs/shared/state/src/lib/) | | Brand-palette `@theme` block | `apps/portal-shell/src/styles.css` | [`libs/shared/tokens/src/brand-tokens.css`](libs/shared/tokens/src/brand-tokens.css) | ## Notable changes - **Icon selector renamed `app-icon` → `lib-icon`.** Required by the lib's ESLint `@angular-eslint/component-selector` rule (prefix `lib` for shared libs). All ~20 usages in `portal-shell` templates updated in one sweep. - **New `shared-state` library** generated via `nx g @nx/angular:library libs/shared/state`. Mirrors the existing `feature-auth` / `shared-ui` shape (vite + Angular + spec setup). `tsconfig.base.json` path alias `shared-state` added by the generator. - **Lib tags rebalanced** to satisfy the module-boundary lint rule: - `shared-state`: new lib → `scope:shared, type:shared`. - `shared-ui`: was `scope:portal-shell` (scaffold default) → `scope:shared, type:shared`. - **`shared-tokens` is now CSS-only.** The placeholder TS function is gone; `index.ts` is an empty `export {}` with a TODO note. Vitest config flips `passWithNoTests: true` so the test target stops failing on the empty lib. - **`portal-shell`'s `styles.css`** drops the inline `@theme {}` block and instead `@import`s `../../../libs/shared/tokens/src/brand-tokens.css`. Both apps will read the same source. - Placeholder scaffolded files in `shared-ui/src/lib/shared-ui/` removed. ## Verification - `nx run-many -t lint test build` across `portal-shell, shared-ui, shared-state, shared-tokens` — green. - Tests redistributed: **portal-shell 28**, **shared-state 9**, **shared-ui 3**, **shared-tokens 0** = 40 total (same as before the move). - Production build: **128.7 KB gzip** initial per locale (was 128.5 KB on `main` — noise-level delta). - Brand-color CSS variables (`--color-brand-primary-500: #12546c`, …) still inlined in the produced `styles-*.css`. - `dist/.../browser/{en,fr}/` emitted as expected. ## What this PR explicitly does NOT do - Move other components (Header, Sidebar, Footer, ThemeSwitcher, LocaleSwitcher). Those are app-specific shell concerns; if `portal-admin` ends up needing them, they graduate in their own PR. - Set up `portal-admin`. That's the next PR on the admin track — and now imports from `shared-ui` / `shared-state` / `shared-tokens` will Just Work. - Refactor `feature-auth`'s tagging. It still says `scope:portal-shell`; revisit when the auth implementation actually lands and the dual-audience design (per ADR-0008) makes the right scope obvious. ## Test plan - [x] Per-project run-many — green. - [x] Production build emits both locales with brand tokens applied. - [ ] Manual: `pnpm exec nx serve portal-shell` — the dev experience is unchanged. - [ ] Manual: serve-static + locale switcher / theme switcher / sidebar collapse / navigation — all the behaviours the moved primitives drive still work in production. --------- Co-authored-by: Julien Gautier Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/99 --- .../src/app/components/header/header.html | 8 +-- .../src/app/components/header/header.spec.ts | 2 +- .../src/app/components/header/header.ts | 4 +- .../locale-switcher/locale-switcher.html | 6 +-- .../locale-switcher/locale-switcher.ts | 2 +- .../src/app/components/sidebar/sidebar.html | 6 +-- .../src/app/components/sidebar/sidebar.ts | 4 +- .../theme-switcher/theme-switcher.html | 6 +-- .../theme-switcher/theme-switcher.spec.ts | 2 +- .../theme-switcher/theme-switcher.ts | 4 +- apps/portal-shell/src/styles.css | 51 ++----------------- apps/portal-shell/tsconfig.app.json | 10 +++- libs/shared/state/README.md | 7 +++ libs/shared/state/eslint.config.mjs | 34 +++++++++++++ libs/shared/state/project.json | 13 +++++ libs/shared/state/src/index.ts | 1 + .../src/lib}/layout-state.service.spec.ts | 0 .../state/src/lib}/layout-state.service.ts | 0 libs/shared/state/src/test-setup.ts | 5 ++ libs/shared/state/tsconfig.json | 23 +++++++++ libs/shared/state/tsconfig.lib.json | 26 ++++++++++ libs/shared/state/tsconfig.spec.json | 23 +++++++++ libs/shared/state/vite.config.mts | 28 ++++++++++ libs/shared/tokens/src/brand-tokens.css | 46 +++++++++++++++++ libs/shared/tokens/src/index.ts | 8 ++- .../tokens/src/lib/shared-tokens.spec.ts | 7 --- libs/shared/tokens/src/lib/shared-tokens.ts | 3 -- libs/shared/tokens/vitest.config.mts | 3 ++ libs/shared/ui/project.json | 2 +- libs/shared/ui/src/index.ts | 2 +- .../shared/ui/src/lib}/icon/icon.spec.ts | 10 ++-- .../shared/ui/src/lib}/icon/icon.ts | 12 ++--- .../shared/ui/src/lib/shared-ui/shared-ui.css | 0 .../ui/src/lib/shared-ui/shared-ui.html | 1 - .../ui/src/lib/shared-ui/shared-ui.spec.ts | 21 -------- libs/shared/ui/src/lib/shared-ui/shared-ui.ts | 9 ---- tsconfig.base.json | 3 +- 37 files changed, 267 insertions(+), 125 deletions(-) create mode 100644 libs/shared/state/README.md create mode 100644 libs/shared/state/eslint.config.mjs create mode 100644 libs/shared/state/project.json create mode 100644 libs/shared/state/src/index.ts rename {apps/portal-shell/src/app/state => libs/shared/state/src/lib}/layout-state.service.spec.ts (100%) rename {apps/portal-shell/src/app/state => libs/shared/state/src/lib}/layout-state.service.ts (100%) create mode 100644 libs/shared/state/src/test-setup.ts create mode 100644 libs/shared/state/tsconfig.json create mode 100644 libs/shared/state/tsconfig.lib.json create mode 100644 libs/shared/state/tsconfig.spec.json create mode 100644 libs/shared/state/vite.config.mts create mode 100644 libs/shared/tokens/src/brand-tokens.css delete mode 100644 libs/shared/tokens/src/lib/shared-tokens.spec.ts delete mode 100644 libs/shared/tokens/src/lib/shared-tokens.ts rename {apps/portal-shell/src/app/components => libs/shared/ui/src/lib}/icon/icon.spec.ts (85%) rename {apps/portal-shell/src/app/components => libs/shared/ui/src/lib}/icon/icon.ts (87%) delete mode 100644 libs/shared/ui/src/lib/shared-ui/shared-ui.css delete mode 100644 libs/shared/ui/src/lib/shared-ui/shared-ui.html delete mode 100644 libs/shared/ui/src/lib/shared-ui/shared-ui.spec.ts delete mode 100644 libs/shared/ui/src/lib/shared-ui/shared-ui.ts diff --git a/apps/portal-shell/src/app/components/header/header.html b/apps/portal-shell/src/app/components/header/header.html index aac8858..e7693dc 100644 --- a/apps/portal-shell/src/app/components/header/header.html +++ b/apps/portal-shell/src/app/components/header/header.html @@ -29,7 +29,7 @@
- + - +