feat(lineage): add materialization badge for model nodes#1237
Conversation
Show the materialization strategy (table, view, incremental, ephemeral, materialized_view) on model nodes instead of the generic resource type icon. Each materialization type gets a distinct icon from the cube family: - table: solid cube (reuses existing model icon) - view: eye icon - incremental: 2/3 solid + 1/3 dashed cube - ephemeral: fully dashed cube - materialized_view: solid cube with small eye overlay The badge appears in both the canvas graph nodes and the sidebar detail view. Non-model nodes continue to show the resource type tag. Also adds ResourceTypeTag stories and MaterializationTag stories, and updates LineageCanvas/NodeView fixtures with realistic materialization data across all dbt layers (staging=view, intermediate=ephemeral, fact=incremental, dimension=table, mart=materialized_view). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Danyel Fisher <danyel@gmail.com>
Code Review — PR 1237SummaryAdds materialization badges (table, view, incremental, ephemeral, materialized_view) to model nodes in the lineage graph and sidebar. Clean implementation with proper fallback to ResourceTypeTag for non-model nodes. Type checks and lint pass. Findings[Critical] SVG clipPath ID collision in IconIncrementalFile: const IconIncremental: IconComponent = (props) => {
const id = useId();
const bottomId = `inc-bottom-${id}`;
const topId = `inc-top-${id}`;
// use bottomId/topId in clipPath defs and references
};Alternatively, use a CSS [Warning] Dangling JSDoc comment in primitives.tsFile: Verdict |
Hardcoded clipPath IDs caused collisions when multiple incremental model nodes rendered in the same graph. Use React useId() to generate unique IDs per instance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Danyel Fisher <danyel@gmail.com>
…NodeTag Materialization is only meaningful for model resources, so these two concepts belong in a single component. NodeTag takes resourceType and optional materialized — when resourceType is "model" with a materialization, it shows the materialization icon/label; otherwise it shows the resource type. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Danyel Fisher <danyel@gmail.com>
Main refactored NodeView's inline types to use NodeData from api/info. Took main's version since NodeData already includes config.materialized. Fixed NodeView.stories.tsx to use NodeViewNodeData instead of LineageGraphNode to match tightened DI prop types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Danyel Fisher <danyel@gmail.com>
Code Review — PR #1237SummaryMaterialization badges for model nodes in the lineage graph, with a clean unification of Findings[Warning] SchemaSummary test may rely on a testId that nothing rendersFile: [Minor] Missing
|
| Check | Result |
|---|---|
pnpm type:check |
Pass |
pnpm lint |
Pass (578 files, 0 errors) |
| Tag unit tests | Pass (17/17) |
Verdict
No critical issues. The testId concern in SchemaSummary is worth a quick look but isn't blocking. Clean integration, good test coverage of the core branching logic, and the NodeTag unification is well-motivated. 👍
- Fix SchemaSummary test to assert on rendered text instead of mock's data-testid - Add dynamic_table and streaming_table materialization types (Snowflake, Databricks) - Add materialization-change story (base=view, current=table) - Add aria-hidden to decorative SVG icons in NodeTag and LineageNode - Improve style tests to verify useIsDark is called - Consolidate NodeTag stories into unified AllTypes view - Remove redundant individual materialization substories from NodeView Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Danyel Fisher <danyel@gmail.com>
There was a problem hiding this comment.
Pull request overview
Adds model materialization badges to lineage UI nodes by introducing a unified NodeTag component that renders either a resource type or a model materialization (with distinct icons), and wires materialization data through the lineage graph/node views and Storybook fixtures.
Changes:
- Replace
ResourceTypeTagwith a unifiedNodeTagthat can display model materialization (table/view/incremental/ephemeral/materialized_view, etc.). - Add materialization icon support to lineage styling utilities and propagate
materializedthrough graph/node data. - Update tests and Storybook stories/fixtures to cover the new tag behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| js/src/components/summary/tests/SchemaSummary.test.tsx | Updates mocks/assertions to use NodeTag instead of ResourceTypeTag. |
| js/packages/ui/src/primitives.ts | Re-exports NodeTag via primitives entrypoint. |
| js/packages/ui/src/components/summary/SchemaSummary.tsx | Switches summary card tag from ResourceTypeTag to NodeTag. |
| js/packages/ui/src/components/lineage/tags/index.ts | Barrel now exports NodeTag instead of ResourceTypeTag. |
| js/packages/ui/src/components/lineage/tags/tests/ResourceTypeTag.test.tsx | Removes tests for deleted ResourceTypeTag. |
| js/packages/ui/src/components/lineage/tags/tests/NodeTag.test.tsx | Adds unit tests for NodeTag resource-type/materialization behavior. |
| js/packages/ui/src/components/lineage/tags/ResourceTypeTag.tsx | Removes the old ResourceTypeTag component. |
| js/packages/ui/src/components/lineage/tags/NodeTag.tsx | Adds the unified tag component (resource type + optional materialization). |
| js/packages/ui/src/components/lineage/styles.tsx | Adds materialization icons + getIconForMaterialization. |
| js/packages/ui/src/components/lineage/nodes/LineageNode.tsx | Uses materialization icon when node is a model with materialized. |
| js/packages/ui/src/components/lineage/NodeViewOss.tsx | Injected tag now derives materialized from node config and renders NodeTag. |
| js/packages/ui/src/components/lineage/GraphNodeOss.tsx | Populates materialized into node data from base/current config. |
| js/packages/ui/src/api/info.ts | Extends NodeData with config.materialized typing. |
| js/packages/storybook/stories/lineage/fixtures.ts | Adds materialized to fixtures and seeds example graphs with materializations. |
| js/packages/storybook/stories/lineage/NodeView.stories.tsx | Uses NodeTag for the “ResourceTypeTag” injection + adds materialization-change story. |
| js/packages/storybook/stories/lineage/NodeTag.stories.tsx | New Storybook stories covering resource types and materialization variants. |
Code Review — PR #1237SummaryAdds materialization badges to model nodes by unifying Findings[Warning] SchemaSummary does not pass
|
gcko
left a comment
There was a problem hiding this comment.
Claude Code Review: No critical issues found. Two minor findings posted as comment — SchemaSummary missing materialized prop (inconsistent UX) and unused MaterializationType export.
SchemaSummary was missing the materialized prop on NodeTag, causing models to show "model" instead of their materialization strategy. Also removes unused MaterializationType export from styles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
Use `!= null` instead of truthy check for showMaterialization so TypeScript explicitly narrows `materialized` to `string` in the truthy branch. Addresses Copilot review feedback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
Thanks for catching the SchemaSummary prop! I thought I'd gotten that one. |
PR checklist
What type of PR is this?
Feature + Refactor
What this PR does / why we need it:
Adds materialization badges to model nodes in the lineage graph. Instead of showing the generic "model" resource type, model nodes now display their materialization strategy (table, view, incremental, ephemeral, materialized_view) with a distinct icon.
Key design decision: materialization is only meaningful for models, so
ResourceTypeTagandMaterializationTagare unified into a singleNodeTagcomponent. It takesresourceTypeand optionalmaterialized— when the resource is a model with materialization data, it shows the materialization; otherwise it shows the resource type.Each materialization type gets a distinct icon:
Special notes for your reviewer:
NodeTagreplaces bothResourceTypeTagandMaterializationTag— two separate components collapsed into oneNodeViewOss.tsxnow lives insideNodeTagitselfuseId()to avoid collisions when multiple incremental icons renderDoes this PR introduce a user-facing change?:
Model nodes in the lineage graph now show their materialization strategy (table, view, incremental, ephemeral, materialized view) instead of the generic "model" label.