feat: standalone parameterized custom viz components#9685
feat: standalone parameterized custom viz components#9685nishantmonu51 wants to merge 4 commits into
Conversation
Extract inline canvas custom charts into reusable component resources: - Components declare typed params (metrics_view, measure, dimension, time_dimension, scalars) validated at parse and reconcile time - Canvas items reference components via 'component:' + 'params:' bindings; param-bound metrics views flow through transitive access security - ResolveComponent merges defaults, validates bindings, resolves templates, and injects scalar params as native Vega-Lite params - Component workspace with live preview, test bindings, used-by panel, and breaking-change warnings - 'Save as custom viz' extraction from inline charts and 'Detach copy' inverse - Vega-Lite examples gallery (vendored snapshot with static SVG thumbnails) with AI-first import: spec-in-prompt generation, placeholder file, and a self-healing validation loop with static structure/consistency checks - Generated components include customizable order_by and limit params with density-based defaults; order_by follows re-bound fields in the editor - Dev-agent instructions for authoring components (metrics_sql dialect rules, encoding/param type matching, row-local calculate preservation for diverging charts) Gated behind the customComponents frontend flag and custom_components runtime flag.
- Format touched files with prettier - Fix svelte-check errors: Extract string keys in AllKeys so ComponentRefSpec's index signature doesn't widen keys to string | number; narrow the index signature values to scalars (matching the parser's scalar-only bindings); type initializeRow over AddableItem; pass the required editor binding in ComponentWorkspace; remove unused imports and cast union field accesses - Add customComponents to the expected maps in Test_ResolveFeatureFlags
- Add the component_extract_title message key (en/es) - Bind the required viewVL prop on the preview's inline VegaLiteRenderer - Cast metrics_view access in FiltersMapper to string | null
- ResolveCanvas: skip templated metrics_view renderer properties instead of looking them up as literal resource names (param-bound metrics views are collected from the canvas items) - Frontend: give canvas items referencing an external component their positional instance id as component.id, so two references to the same component get distinct DOM ids and consistent selection/cleanup; make the drag-move reselect path instance-aware and use getElementById for ids containing '::' - Transitive access: scan metrics_sql lists (multi-query custom charts) for metrics view refs, not just single query strings - Parser: components declaring a metrics_view param with a default now get a ref to the default metrics view for DAG ordering and invalidation
|
@codex: review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 573137c8c0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if allowTemplated && hasTemplatedString(props) { | ||
| if renderer == "custom_chart" { | ||
| return validateCustomChart(props) | ||
| } | ||
| // Skip field-membership validation, but still reject unknown renderers. | ||
| if !knownRenderers[renderer] { | ||
| return fmt.Errorf("unsupported renderer %q", renderer) | ||
| } | ||
| return nil |
There was a problem hiding this comment.
Do not skip validation for templated renderers
When a parameterized non-custom_chart renderer has any template in its properties, this branch returns before the renderer-specific checks run. For example, a kpi component with metrics_view: "{{ .params.metrics_view }}" but no required measure now reconciles as valid, and ResolveComponent only resolves templates rather than re-running ValidateRendererProperties, so canvases can serve broken renderer props instead of surfacing the validation error.
Useful? React with 👍 / 👎.
| case "time_dimension": | ||
| // A dimension picker restricted to the metrics view's time dimension. | ||
| return { | ||
| type: "dimension", | ||
| ...common, | ||
| meta: { includeTime: true, searchableItems: [] }, | ||
| }; |
There was a problem hiding this comment.
Restrict time-dimension params to time fields
For time_dimension params this returns a generic dimension selector with searchableItems: [], but useMetricFieldData only applies searchableItems when the user has typed a search term; with an empty search the dropdown still lists every dimension, while includeTime only adds the primary time dimension. This lets users bind non-time dimensions that later fail reconcile and prevents searching for secondary time-typed dimensions that the backend accepts.
Useful? React with 👍 / 👎.
type: componentauthoring surface ("custom viz"): components declare typed params (metrics_view,measure,dimension,time_dimension, scalars) and canvases reference them viacomponent:+params:bindings, validated end to end and covered by transitive-access security.Save as custom vizextraction from inline charts andDetach copyinverse.order_byandlimitparams with density-based defaults; the editor offers bound fields asorder_bychoices and keeps the binding in step when fields are re-bound.calculatetransforms for diverging charts).customComponentsfrontend flag andcustom_componentsruntime flag.Checklist: