feat: Catalog Reference route (native @a2ui/angular) - #129
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a custom 11-component dashboard catalog, a code-generation script to bundle source files, and integrates 'Custom Catalog' and 'Catalog Reference' views into the shell routes and sidebar navigation, complete with unit tests. Feedback focuses on improving robustness: clamping negative values to zero in BarChart and PieChart to prevent invalid SVG rendering, and adding a safety guard in DataTable to prevent runtime errors if a row is null or undefined.
| protected readonly bars = computed<Bar[]>(() => { | ||
| const data = this.data(); | ||
| const max = data.reduce((m, d) => Math.max(m, Number(d.value) || 0), 0); | ||
| return data.map((d, i) => { | ||
| const value = Number(d.value) || 0; |
There was a problem hiding this comment.
If any data item contains a negative value, Number(d.value) will be negative, resulting in a negative height for the SVG <rect>. Negative heights are invalid in SVG and can cause rendering issues or browser warnings.
Consider clamping the values to 0 or greater to ensure robust rendering.
| protected readonly bars = computed<Bar[]>(() => { | |
| const data = this.data(); | |
| const max = data.reduce((m, d) => Math.max(m, Number(d.value) || 0), 0); | |
| return data.map((d, i) => { | |
| const value = Number(d.value) || 0; | |
| protected readonly bars = computed<Bar[]>(() => { | |
| const data = this.data(); | |
| const max = data.reduce((m, d) => Math.max(m, Math.max(0, Number(d.value) || 0)), 0); | |
| return data.map((d, i) => { | |
| const value = Math.max(0, Number(d.value) || 0); |
| protected readonly slices = computed<PieSlice[]>(() => { | ||
| const data = this.data(); | ||
| const innerR = this.innerRadius(); | ||
| const total = data.reduce((sum, d) => sum + (Number(d.value) || 0), 0); | ||
| if (total <= 0) return []; | ||
|
|
||
| const slices: PieSlice[] = []; | ||
| let cursor = 0; | ||
| data.forEach((d, i) => { | ||
| const value = Number(d.value) || 0; |
There was a problem hiding this comment.
If any data item contains a negative value, it can corrupt the total and cursor calculations, leading to incorrect or overlapping slices and invalid SVG arc paths.
Consider clamping the values to 0 or greater to ensure robust rendering.
| protected readonly slices = computed<PieSlice[]>(() => { | |
| const data = this.data(); | |
| const innerR = this.innerRadius(); | |
| const total = data.reduce((sum, d) => sum + (Number(d.value) || 0), 0); | |
| if (total <= 0) return []; | |
| const slices: PieSlice[] = []; | |
| let cursor = 0; | |
| data.forEach((d, i) => { | |
| const value = Number(d.value) || 0; | |
| protected readonly slices = computed<PieSlice[]>(() => { | |
| const data = this.data(); | |
| const innerR = this.innerRadius(); | |
| const total = data.reduce((sum, d) => sum + Math.max(0, Number(d.value) || 0), 0); | |
| if (total <= 0) return []; | |
| const slices: PieSlice[] = []; | |
| let cursor = 0; | |
| data.forEach((d, i) => { | |
| const value = Math.max(0, Number(d.value) || 0); |
| protected cell(row: Record<string, unknown>, key: string): string { | ||
| return String(row[key] ?? ''); | ||
| } |
There was a problem hiding this comment.
If row is null or undefined at runtime (due to unexpected or malformed data model), accessing row[key] will throw a TypeError.
Consider adding a guard to safely handle null or undefined rows.
| protected cell(row: Record<string, unknown>, key: string): string { | |
| return String(row[key] ?? ''); | |
| } | |
| protected cell(row: Record<string, unknown> | null | undefined, key: string): string { | |
| return row ? String(row[key] ?? '') : ''; | |
| } |
Enables in-app (no-iframe) rendering of custom catalogs. Pin shell zod to
3.25.76 so app-authored catalog schemas share the exact zod instance the
@a2ui/web_core binder introspects (Angular's own zod 4 stays nested/isolated).
Validated end-to-end: a shell-authored custom Title resolves a {path} binding
via <a2ui-v09-surface>.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Port of the react-flight-catalog dashboard catalog to native @a2ui/angular renderers (Row/Column/Title/Badge/Metric/DashboardCard/FlightCard/DataTable/ Button + hand-rolled SVG PieChart/BarChart), themed via --cpk-* tokens. buildDashboardCatalog() registers all 11 into an AngularCatalog. Surface-render tests green (children, chart shapes, path bindings, action dispatch). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Native /custom-catalog page: renders the Flight Card + Sales Dashboard trees via <a2ui-v09-surface> (no iframe) from the 11-component dashboard catalog, with an editable Monaco data-model panel. Example toggle + data-state tabs (Morning/Afternoon, Q1-Q4); editing the JSON live-updates the surface via updateDataModel. Surfaces are built once per example (createSurface+ updateComponents), so data changes push updateDataModel only. Nav item added to Google's list; shell spec nav counts updated for the new route. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generated data module (committed) + Node codegen that reads apis.ts, dashboard-catalog.ts, and the 11 renderer files. Wired via yarn generate:catalog-source; generated file + scripts/ excluded from lint and prettier. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s + source) Per-component reference for the 11-component dashboard catalog: native @a2ui/angular previews, A2UI usage snippets, props tables, plus raw Definitions/Renderers source viewers. Includes a docs-vs-catalog sync test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3f4cacd to
e0211fb
Compare
A per-component reference for the custom A2UI catalog: live native preview, A2UI usage snippet, and props for every component — plus Definitions and Renderers views that show the catalog's own source.
What
/catalog-referenceroute with a component index grouped by category (Layout / Content / Data Display / Interactive).createSurface/updateComponents), and a props table.shell/scripts/generate-catalog-source.mjs.Why
Gives contributors a browsable, always-in-sync reference for what the native catalog offers and exactly how to author each component in A2UI.
Testing
ng build(lint + AOT) green on a clean build;catalog-reference+composer-shellunit tests pass (24 specs).Contributed by CopilotKit.
Screenshots
/catalog-reference— live native preview + A2UI usage + props (PieChart shown):