Files
apf_portal/apps/portal-admin/project.json
T
Julien Gautier 7d56802e1d
CI / commits (pull_request) Successful in 2m51s
CI / scan (pull_request) Successful in 3m6s
CI / check (pull_request) Successful in 3m16s
CI / a11y (pull_request) Successful in 2m7s
CI / perf (pull_request) Successful in 6m34s
feat(portal-admin): audit dashboard — bar / donut / stacked-bar above the table
PR 3 of the charts chantier — closes the loop on ADR-0023 by
wiring the three starter components from #171 onto the /audit
page.

Three computed signals derive aggregations from the *current page's*
items (no new BFF endpoint — server-side stats land separately if
ever needed):

  * `dailyVolume` — events grouped by ISO date (YYYY-MM-DD).
  * `outcomeBreakdown` — counts per outcome.
  * `dailyByEventType` — flat (day, eventType, count) triples.

A new `<section class="charts">` renders above the existing filter
form, behind a `hasChartData()` guard so the section disappears
entirely on empty pages (no "0 events" donut, no half-rendered
bars). Each chart sits in a `.chart-tile`; the stacked-bar gets
`.chart-tile--wide` to span both grid columns since its legend
benefits from the extra horizontal space.

A `.charts-note` paragraph above the grid says explicitly that
the aggregations are "computed from the events currently loaded
on this page only" — honest disclosure of the per-page scope, no
misleading "all-time" framing.

Captions / descriptions / aria-labels live in plain English in the
template per ADR-0020's source-locale-only chrome posture. No new
i18n strings.

Bundle impact: the lazy `audit` chunk grows from ~4.4 KB to ~84 KB
gzip with the chart deps loaded — comfortable under [ADR-0017]'s
100 KB cap. The estimate in ADR-0023 was ~65 KB; Plot's full mark
set + d3-scale-chromatic interpolators add a bit more than
projected but still fit the budget.

Side tweaks:
  * `apps/portal-admin/project.json` bumps the `anyComponentStyle`
    budget from 5/6 KB to 6/8 KB to accommodate the charts grid
    SCSS (audit.scss lands at ~6.5 KB).
  * `apps/portal-admin/tsconfig.app.json` references the new
    `libs/shared/charts/tsconfig.lib.json` (auto-added by `nx
    sync` after the import in audit.ts).

Verification:
  * 57 portal-admin specs pass (was 54; +3 for the charts section
    rendering, the empty-page hide guard, and the donut center
    label binding).
  * `pnpm nx run-many -t lint test build --projects=portal-shell,
    portal-admin,shared-charts` — green.
  * Audit chunk gzip = 84 KB, under the budget.
2026-05-16 22:14:21 +02:00

124 lines
3.1 KiB
JSON

{
"name": "portal-admin",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"prefix": "app",
"sourceRoot": "apps/portal-admin/src",
"tags": ["scope:portal-admin", "type:app"],
"i18n": {
"sourceLocale": {
"code": "en",
"baseHref": "/en/"
},
"locales": {
"fr": {
"translation": "apps/portal-admin/src/locale/messages.fr.xlf",
"baseHref": "/fr/"
}
}
},
"targets": {
"build": {
"executor": "@angular/build:application",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/portal-admin",
"browser": "apps/portal-admin/src/main.ts",
"polyfills": ["@angular/localize/init"],
"tsConfig": "apps/portal-admin/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "apps/portal-admin/public"
}
],
"styles": ["apps/portal-admin/src/styles.css"]
},
"configurations": {
"production": {
"localize": ["en", "fr"],
"i18nMissingTranslation": "error",
"budgets": [
{
"type": "initial",
"maximumWarning": "1.5mb",
"maximumError": "1.5mb"
},
{
"type": "anyScript",
"maximumWarning": "500kb",
"maximumError": "500kb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "8kb"
},
{
"type": "bundle",
"name": "styles",
"maximumWarning": "150kb",
"maximumError": "150kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"extract-i18n": {
"executor": "@angular/build:extract-i18n",
"options": {
"buildTarget": "portal-admin:build",
"outputPath": "apps/portal-admin/src/locale",
"outFile": "messages.xlf"
}
},
"serve": {
"continuous": true,
"executor": "@angular/build:dev-server",
"options": {
"port": 4300
},
"configurations": {
"production": {
"buildTarget": "portal-admin:build:production"
},
"development": {
"buildTarget": "portal-admin:build:development"
}
},
"defaultConfiguration": "development"
},
"lint": {
"executor": "@nx/eslint:lint"
},
"test": {
"executor": "@angular/build:unit-test",
"options": {
"watch": false
},
"configurations": {
"watch": {
"watch": true
}
}
},
"serve-static": {
"continuous": true,
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "portal-admin:build",
"port": 4300,
"staticFilePath": "dist/apps/portal-admin/browser"
}
}
}
}