Refactor and use entities#176
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the dashboard data flow to introduce an entities layer with Zod-backed schemas, moves API client logic into features, and improves type-safety across the webapp (notably by enabling noUncheckedIndexedAccess). It also refactors the dashboard header for i18n usage and tightens some chart-related typings.
Changes:
- Introduce
@entities/dashboard/*Zod schemas and validate dashboard payloads in the API client. - Refactor dashboard widgets (header/year selection, year-level dashboard rendering) and add i18n strings for the header.
- Strengthen typing in chart utilities (palette tuple typing, sunburst palettes) and enable stricter TS checks.
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| webapp/tsconfig.app.json | Enables noUncheckedIndexedAccess for stricter indexing safety. |
| webapp/src/widgets/dashboard/year-dashboard.tsx | Adds year-scoped dashboard widget using entity schemas and chart adapters. |
| webapp/src/widgets/dashboard/loaded-dashboard.tsx | Refactors year selection logic and composes Header + YearDashboard. |
| webapp/src/widgets/dashboard/header.tsx | Replaces inline strings with i18n keys and normalizes year-change callback typing. |
| webapp/src/widgets/dashboard/dashboard.tsx | Switches to new useApi() API and entity DashboardData typing. |
| webapp/src/shared/ui/chart.tsx | Adds tooltip formatting TODO notes (no functional changes). |
| webapp/src/shared/lib/utils.ts | Adds TODO notes about representing missing numeric values (no functional changes). |
| webapp/src/shared/lib/palette.ts | Tightens chart palette typing to a fixed-length tuple. |
| webapp/src/shared/i18n/translations/fr/all4trees.json | Adds dashboard header translation keys (FR). |
| webapp/src/shared/i18n/translations/en/all4trees.json | Adds dashboard header translation keys (EN). |
| webapp/src/shared/api/client.ts | Narrows shared API module to authenticated fetch helpers returning unknown. |
| webapp/src/features/popup/socio-eco/popup-socio-eco.tsx | Simplifies TABS typing via as const. |
| webapp/src/features/popup/forest-inventory/popup-forest-inventory.tsx | Simplifies TABS typing via as const. |
| webapp/src/features/hooks/useApi.ts | Points useApi() to the new @features/contexts/ApiContext. |
| webapp/src/features/contexts/ApiContext.ts | Moves API context typing to @features/api/client. |
| webapp/src/features/charts/soil/lib/taxon.ts | Adds validation around taxon parsing (currently conflicts with caller expectations). |
| webapp/src/features/charts/soil/lib/sunburst.ts | Replaces slice() with fixed tuples for palette levels. |
| webapp/src/features/charts/components/radar-benef-control.tsx | Updates tooltip content (currently contains debug label formatting). |
| webapp/src/features/charts/biodiversity/chart-forest-potential.tsx | Adds fromEpfData() adapter to map entity data into chart props. |
| webapp/src/features/api/client.ts | Introduces feature-level API client that validates responses with Zod. |
| webapp/src/entities/dashboard/generic.ts | Adds generic dashboard schemas/types (years, dictionaries, dashboard record). |
| webapp/src/entities/dashboard/epf.ts | Adds EPF-specific schema/type for biodiversity chart inputs. |
| webapp/src/app/providers/ApiProvider.tsx | Updates imports to the new API client/context locations. |
| webapp/package.json | Adds zod dependency. |
| webapp/package-lock.json | Locks zod dependency. |
| webapp/biome.json | Updates import sorting/organization to include @entities/**. |
Files not reviewed (1)
- webapp/package-lock.json: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
60d0156 to
66feeed
Compare
|
|
||
| export function precise(value?: number | null) { | ||
| if (!value || Number.isNaN(value)) { | ||
| // TODO: missing or erroneous values should not be considered as 0, but rather as null or undefined. |
There was a problem hiding this comment.
In some cases Cathaline asked us to put "0" for empty values, in other cases "N/A".
Check hiw data is formatted here
It is certainly not the best way to do it, but that's why this method returns "0"
There was a problem hiding this comment.
OK, good to know, I'll adapt the comment
| { | ||
| /* Force a space between item label and value*/ "\xa0" + | ||
| item.value.toLocaleString() | ||
| // ^ TODO: why not using CSS to add a space between the label and the value? |
There was a problem hiding this comment.
This code is generated automatically when importing shadcn components, see Shadcn Doc. We might want to tweak this code, but as long as it is not strictly necessary, I would prefer to keep it as is
(Same for every component in shared/ui)
| epf_diameter_distribution: ValueAndErrorSchema, | ||
| epf_dominant_height: ValueAndErrorSchema, | ||
| epf_microhabitats: ValueAndErrorSchema, | ||
| epf_necromass_pied: ValueAndErrorSchema, // needed? |
There was a problem hiding this comment.
Not needed indeed. I added them in the config.json to help me construct the (very long) formulat for 'epf_deadwoord' but I removed them in #162
| import { EpfDataSchema } from "@entities/dashboard/epf"; | ||
| import type { YearData } from "@entities/dashboard/generic"; | ||
|
|
||
| // TODO: don't do that! Pass the original values, and truncate only when displaying them, |
There was a problem hiding this comment.
I'm not sure to understand, this method was called just before passing the data to the chart , therefore just before displaying it, is that not enough ?
I saw that now the values are not truncated in the chart anymore, how do you suggest to do that ?
There was a problem hiding this comment.
indeed. What I mean:
- pass the original values to the chart component
- pass a formatter function to the chart component to show the expected text (truncated, localized, etc).
It's generally better to do so. When truncating, if at some point (in the code now or in a later modification), we perform operations on the values, we could end up with issues (e.g., 0.1 + 0.2 = 0.30000000000000004). That's why it's recommended to let the original data flow in the app, and to format (truncate) only when needed, ie. when creating the text in the chart.
I saw that now the values are not truncated in the chart anymore, how do you suggest to do that ?
in a formatter function. If you agree with the comment, I'll do it
564e2ef to
9d72562
Compare
f1b496a to
f954812
Compare
f954812 to
18b905a
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
18b905a to
812e0dc
Compare
3c80447 to
3991b3a
Compare
9e13740 to
04f97b2
Compare
Take care: it is based on #175, not on main.