Skip to content

feat: DAG Behavioral Changes (Canvas resource, Source Models, ... buttons)#8715

Open
royendo wants to merge 120 commits intomainfrom
feat/dag-changes
Open

feat: DAG Behavioral Changes (Canvas resource, Source Models, ... buttons)#8715
royendo wants to merge 120 commits intomainfrom
feat/dag-changes

Conversation

@royendo
Copy link
Contributor

@royendo royendo commented Jan 28, 2026

Reworking DAG viewer as an alternate resource reviewer with richer context per node.

Edit 3/24: https://www.loom.com/share/aee0287f46ca44f4888920d5064b5578
https://www.loom.com/share/e76af474e7474ad28496ddd4153ea901

  • Source Model concept: Models with no model dependencies are now classified as Source Models via coerceResourceKind, with a distinct emerald color (--source) and "source model" display name
  • Canvas resources in DAG: Canvas resources now appear in the graph with proper dependency tracking (parser changes in parse_canvas.go, parse_node.go)
  • Contextual resource nodes: Nodes display rich metadata inline — connector icons, badges (Materialized, Incremental, Partitioned), test status, schedule info, security indicators, measure/dimension counts
  • Resource Describe modal: New ResourceDescribeModal with detailed resource info including connector, refresh schedule (as YAML), retry config (as YAML), security policies, measures/dimensions lists, SQL query, and partition navigation
  • Node actions menu: "..." button on nodes with Describe, Refresh, Go to file, and View partitions actions
  • Project graph page (/graph): Full-page sidebar layout with breadcrumb navigation, tree dropdown with search and status filter (OK/Pending/Errored), and refresh all
  • Quick-view overlay refactor: ResourceGraphOverlay now uses the app Dialog component instead of custom Overlay with fixed/absolute positioning
  • Connector detection: New connector-type-detector.ts that infers connector type from file paths (S3, GCS, Azure, HTTPS, local) and SQL content (read_parquet, read_csv, etc.)
  • New connector icons: Added Azure Blob Storage, Google Cloud Storage, HTTPS, and local file icons
  • Cleanup: Removed SummaryGraph/SummaryNode (replaced by ResourceKindSelector), removed ErrorBoundary, navigation-utils, url-sync modules

Post-review refinements (latest commits)

  • Fixed O(N²) in normalizeSeeds() using a Set
  • Replaced magic kind strings with ResourceKind constants in graph-builder.ts
  • Consolidated duplicate SECTION_ORDER / SECTION_LABELS into shared config.ts
  • Changed seed signature from join("|") to JSON.stringify to handle names with pipes
  • Added 9 unit tests for deriveConnectorType()
  • Removed dev-only console.log from GraphCanvas
  • Replaced ensureFlowProps reactive block with static void [] to avoid unnecessary Svelte reactivity
  • Removed left accent stripe from nodes; added neutral depth shadow instead
  • Added file path tooltip on node hover via native title attribute
  • Fixed source color (--source) for light mode readability (emerald-600 / emerald-light-400)
  • Status filter (OK/Pending/Errored) now only filters the dropdown list, not the DAG graph cards
  • Widened filter dropdowns from w-64 to w-96
  • Removed extra box-shadow from root/connector node so all nodes have uniform shadow

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I am proud of this work!

Copy link
Contributor Author

@royendo royendo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review - DAG Nit Behavioral Fixes

Good UX improvements with the dropdown menu replacing the old toolbar. Here's my feedback:

Issues to Address

1. ResourceNode.svelte - Code duplication
The node markup is duplicated for error vs non-error cases (lines ~134-230 and ~240-330). This makes maintenance harder. Consider extracting the common parts:

<!-- Common node wrapper -->
{#snippet nodeContent()}
  <Handle ... />
  <Handle ... />
  {#if !isInOverlay}
    <div class="node-menu">...</div>
  {/if}
  <div class="icon-wrapper">...</div>
  <div class="details">...</div>
{/snippet}

{#if hasError}
  <Tooltip>
    <div class="node" ...>
      {@render nodeContent()}
    </div>
    <TooltipContent>...</TooltipContent>
  </Tooltip>
{:else}
  <div class="node" ...>
    {@render nodeContent()}
  </div>
{/if}

2. ResourceNode.svelte - Import formatting (line ~17)

import { GitFork } from "lucide-svelte";
  import { builderActions, getAttrs } from "bits-ui";

The GitFork import has inconsistent indentation.

3. ResourceNode.svelte - Unused import
NodeToolbar is still in the imports but was removed from usage. Clean this up.

4. ResourceNode.svelte - handleRefresh doesn't show feedback

function handleRefresh(e?: MouseEvent) {
    e?.stopPropagation();
    if (!isModel || !data?.resource?.meta?.name?.name) return;
    void $triggerMutation.mutateAsync({...});
}

Consider adding loading state or toast notification so users know the refresh was triggered.

5. GraphCanvas.svelte - Global CSS selector

:global(.svelte-flow .svelte-flow__pane) {
    background-color: var(--surface-background, #ffffff);
}

This could unintentionally affect other xyflow instances in the app. Consider scoping it more specifically or using a data attribute.

Minor Suggestions

  • The icon size changed from 20px to 16px in the node - was this intentional?
  • Consider memoizing handleViewGraph since it accesses reactive stores

Otherwise the dropdown approach is much cleaner than the old toolbar!

@royendo
Copy link
Contributor Author

royendo commented Jan 28, 2026

  1. Code Duplication - I'd recommend accepting the duplication as a Svelte 4 limitation. The differences between the two branches are:

Error case wraps in with error tooltip content
Error case always shows status, non-error only shows if effectiveStatusLabel is truthy
Extracting to a child component would add complexity (passing many props, handling slots) for minimal benefit. The duplication is easy to maintain since changes are typically made to both blocks together.

  1. Icon Size (16px) - This is intentional for the compact dropdown-based design. The node itself is more compact now, so smaller icons fit better.

  2. handleViewGraph - Correct, no memoization needed. It's an event handler that reads current reactive values at click time, not a computed value that needs caching.

@royendo royendo changed the title feat: nit dag changes feat: DAG Behavioral Changes (Canvas resource, Source Models, ... buttons) Jan 28, 2026
@royendo royendo changed the title feat: DAG Behavioral Changes (Canvas resource, Source Models, ... buttons) draft: feat: DAG Behavioral Changes (Canvas resource, Source Models, ... buttons) Feb 4, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@ericpgreen2 ericpgreen2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several UX issues that should be addressed before this ships, followed by a design suggestion that could address many of them holistically.

1. Confusing initial state. The graph initializes showing disconnected dashboard nodes floating in space with no connecting edges. There's no orientation for the user — the first impression is "something is broken." The graph should initialize in a state that shows a connected, meaningful lineage.

image

2. URL does not stay in sync with graph state. Navigating through the graph (selecting resources, filtering, searching) doesn't consistently update the URL in Rill Cloud. The status filter in Rill Developer also isn't reflected in the URL. All user-facing state should be URL-addressable so links can be shared and the back button works.

3. Clicking a node highlights it but does nothing. Selecting a node adds a highlight border and dims other edges, but there's no contextual information surfaced — no detail panel, no inline expansion. The only affordance is the three-dot menu, which you have to discover separately. This makes selection feel broken.

4. Node titles are frequently truncated. auction_ex..., Adbid..., model_metrics_expl..., bids_data_r... — the resource name is the most important piece of information on a node, but it's consistently cut off. The kind badge and three-dot menu consume most of the horizontal space.

image

5. Unbounded vertical scrolling with duplicated nodes. Different DAGs are stacked vertically on the same surface with no containment or index. In the "dashboards" sprawl view, the same source (e.g., Adbids) appears three times side-by-side identically, making it look like three different resources rather than one shared dependency. There's no indication of how many graphs exist or where you are.

6. "Refresh all sources and models" button is oversized. The button is visually much taller than the toolbar buttons above it (Deploy, AI) and bumps against the page edge.

image

7. Layout shift on project title hover (Rill Developer). Hovering over the project title causes a pencil icon to appear that pushes the DAG icon sideways.

A possible design direction

Many of these issues stem from the same root cause: the nodes are optimized for inspection when the graph should be optimized for orientation. The primary value of a DAG is showing how a project connects — topology first, detail second. But the current node design inverts this: the kind badge (Metrics View, Explore, Source) is the most prominent element, the three-dot menu is always visible, and the content row (badges, measures, connector icons) is always rendered. The resource name gets whatever space is left.

This cascades: tall, wide nodes mean fewer fit on screen, connections span larger distances, topology is harder to read, and you need vertical scrolling and "sprawl mode" with duplicated nodes to see everything. Selection feels like a no-op because all the metadata is already shown inline — there's nothing left to reveal.

Consider making nodes compact and name-first, with selection or hover revealing the detail layer:

  • Default state: A small colored kind indicator (dot or icon, not a full text badge) and the resource name. No three-dot menu, no content row. Nodes become roughly half their current height.
  • Selected/hovered state: The node expands to show the metadata row and surfaces the context menu. This gives selection a clear purpose — it's how you inspect a node.

The kind is already communicated by color and DAG position; the text badge is redundant at the overview level. With compact nodes, the topology becomes legible at a glance, names stop truncating, more trees fit in a bounded viewport, and the sprawl mode with duplicated resources may become unnecessary.


Developed in collaboration with Claude Code

@ericpgreen2 ericpgreen2 requested a review from Di7design March 24, 2026 12:12
@ericpgreen2
Copy link
Contributor

Tagging @Di7design for design thoughts as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants