Skip to content

feat: lineage scoping and explorer dependency chain sort#56

Merged
wicky-zipstack merged 8 commits intomainfrom
feat/lineage-scoping
Apr 17, 2026
Merged

feat: lineage scoping and explorer dependency chain sort#56
wicky-zipstack merged 8 commits intomainfrom
feat/lineage-scoping

Conversation

@wicky-zipstack
Copy link
Copy Markdown
Contributor

@wicky-zipstack wicky-zipstack commented Apr 10, 2026

What

  • Lineage scoping: highlight selected model's parent/child chain, fade unrelated nodes
  • Explorer: dependency chain sort (default), execution order, A-Z, Z-A sorting
  • Child models indented in explorer to show hierarchy
  • Explorer auto-refreshes when model configuration (references) is saved
  • Add references field to explorer API response

Why

  • When a model is opened, the lineage tab showed ALL project models equally — confusing with large model counts
  • No way to understand parent-child relationships from the explorer without opening lineage tab
  • No sorting options for models in the explorer pane

How

  • lineage-tab.jsx & no-code-model.jsx: getRelatedNodeIds() traverses edges to find ancestors/descendants, applyScopedStyles() applies opacity + dashed border
  • file_explorer.py: added references field from model_data to API response
  • explorer-component.jsx: sortModels() with dep_chain grouping, applyModelDecorations() for child indent, sort dropdown with 4 options
  • setRefreshModels(true) after config save triggers explorer re-fetch

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. Lineage scoping is purely visual (opacity/border styles). Explorer sort is additive — default "Dependency Chain" maintains all models visible. Backend change only adds a new field to the API response, no existing fields changed.

Database Migrations

  • None required

Env Config

  • None required

Relevant Docs

  • N/A

Related Issues or PRs

Dependencies Versions

  • No dependency changes

Notes on Testing

  • Open a model tab, check lineage: selected model should have dashed blue border, its chain highlighted, unrelated nodes faded
  • Toggle layout direction: scoping should persist
  • Check explorer sort dropdown: Dependency Chain groups parents with children, A-Z/Z-A alphabetical
  • Change model references in Configuration modal: explorer should auto-refresh with updated ordering
  • Child/reference models should appear slightly indented

Screenshots

image

Checklist

- Lineage scoping: highlight selected model's parent/child chain, fade unrelated nodes
- Selected model shown with dashed blue border, related edges in blue
- Explorer: add references to API, dependency chain sort (default), A-Z, Z-A, execution order
- Child models indented in explorer to show hierarchy
- Explorer auto-refreshes on model config save via setRefreshModels
- Applied in both bottom section lineage and standalone LineageTab
@wicky-zipstack wicky-zipstack requested review from a team as code owners April 10, 2026 16:27
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 10, 2026

Greptile Summary

This PR introduces lineage scoping (selected model's ancestor/descendant chain highlighted, unrelated nodes faded) and four sort modes for the explorer's no-code model list, with child models visually indented under their parents in "Dependency Chain" mode. The backend adds a references field to the explorer API response to drive frontend sorting. Previous review concerns — stale-closure on sort rebuild and incorrect _isChild detection for external table references — have both been addressed with modelSortByRef and the modelNames set filter respectively.

Confidence Score: 5/5

Safe to merge — no P0/P1 issues; all previous reviewer concerns resolved.

All changes are additive (new CSS variable, new API field, new sort options) with no breaking modifications to existing fields or flows. The stale-closure and external-reference-filter bugs flagged in prior review rounds are both addressed. The one remaining finding is a stale comment, which is P2 and does not affect runtime behavior.

No files require special attention.

Important Files Changed

Filename Overview
frontend/src/ide/explorer/explorer-component.jsx Adds sort dropdown with 4 options; modelSortByRef ref avoids stale-closure in rebuildTree; useEffect on modelSortBy handles UI rebuild after state settles; applyModelDecorations correctly filters external table refs before setting _isChild.
frontend/src/ide/editor/lineage-utils.js New shared utility exporting getRelatedNodeIds (DFS ancestor/descendant traversal) and applyScopedStyles; correctly guards against missing node labels and unrelated edges.
frontend/src/ide/editor/lineage-tab/lineage-tab.jsx Imports shared applyScopedStyles; applies scoping consistently across all three layout code paths (initial fetch, second fetch, toggle direction); selectedModelName added to effect dependencies.
frontend/src/ide/editor/no-code-model/no-code-model.jsx Uses shared applyScopedStyles for bottom-panel lineage; adds setRefreshModels(true) after config save to trigger explorer re-fetch; stale comment on line 2454.
backend/backend/application/file_explorer/file_explorer.py Adds references field to each no-code model item in the API response; additive change, no existing fields touched.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Model Tab Opened] --> B[getLineageData / fetch lineage API]
    B --> C[getLayoutedElements]
    C --> D{modelName set?}
    D -- Yes --> E[applyScopedStyles]
    E --> F[setNodes / setEdges with scoped styles]
    D -- No --> F2[setNodes / setEdges full view]

    G[Toggle Layout Direction] --> C

    H[Config Save] --> I[setRefreshModels true]
    I --> J[Explorer useEffect fires getExplorer]
    J --> K[sortModels + applyModelDecorations]
    K --> L{sortBy}
    L -- dep_chain --> M[DFS from roots, childrenOf map]
    L -- exec_order --> N[Keep backend topological order]
    L -- alpha_asc/desc --> O[localeCompare sort]
    M & N & O --> P[transformTree → setTreeData]
    P --> Q[_isChild nodes get explorer-child-model CSS class]
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: frontend/src/ide/editor/no-code-model/no-code-model.jsx
Line: 2454-2455

Comment:
**Stale comment describes the wrong function**

The comment `// Find all ancestor and descendant node IDs for a given model` was written for `getRelatedNodeIds`, which has since been extracted to `lineage-utils.js`. It now sits above `getLineageData`, incorrectly describing that function.

```suggestion
  const getLineageData = (callSample = false) => {
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (8): Last reviewed commit: "merge: resolve conflicts with main — com..." | Re-trigger Greptile

Comment thread frontend/src/ide/explorer/explorer-component.jsx Outdated
Comment thread frontend/src/ide/explorer/explorer-component.jsx Outdated
Comment thread frontend/src/ide/editor/lineage-tab/lineage-tab.jsx
Comment thread frontend/src/ide/editor/no-code-model/no-code-model.jsx
…r external refs

- handleModelSort: pass sortBy directly to sortModels instead of relying on async state
- applyModelDecorations: filter references to only include sibling model names, ignore external table references
Copy link
Copy Markdown
Contributor

@tahierhussain tahierhussain left a comment

Choose a reason for hiding this comment

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

@wicky-zipstack Please make the following changes:

  1. Add optional chaining wherever necessary in the frontend to avoid runtime errors.
  2. Please add screenshots for the UI changes addressed in this PR to the PR description.

Comment thread frontend/src/ide/ide-layout.css
Comment thread frontend/src/ide/explorer/explorer-component.jsx
- Remove !important from explorer-child-model padding — use higher specificity selector instead
- Move static sort dropdown items to MODULE_SORT_ITEMS constant outside component
- Memoize sort menu config with useMemo to avoid recreation on every render
- Wrap handleModelSort with useCallback
Comment thread frontend/src/ide/editor/lineage-tab/lineage-tab.jsx Outdated
Comment thread frontend/src/ide/editor/lineage-tab/lineage-tab.jsx Outdated
Comment thread frontend/src/ide/explorer/explorer-component.jsx
…le, exec_order

- Extract getRelatedNodeIds and applyScopedStyles into shared lineage-utils.js
- Remove duplicate functions from lineage-tab.jsx and no-code-model.jsx
- Move hardcoded #1677ff to --lineage-selected-border CSS variable (light: #1677ff, dark: #69b1ff)
- Add comment clarifying exec_order fallback uses backend's topological order
- handleModelSort and modelSortMenu were defined before setTreeData, causing
  'Cannot access setTreeData before initialization' ReferenceError
- Moved both after rebuildTree/setTreeData definition to fix initialization order
Comment thread frontend/src/ide/explorer/explorer-component.jsx Outdated
Copy link
Copy Markdown
Contributor

@tahierhussain tahierhussain left a comment

Choose a reason for hiding this comment

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

LGTM

…tyling

Explorer sort dropdown:
- Use modelSortByRef to avoid stale closure in treeNoCodeModeTitleIcon
- Apply sort and decorations BEFORE transformTree so _isChild flag is set
  when className is assigned (parent-child indent now displays correctly)
- Conditional indent: only show in Dependency Chain mode, not in Execution
  Order/A→Z/Z→A modes
- Show checkmark on currently selected sort option in the dropdown menu
- useEffect rebuilds tree on modelSortBy change so dropdown reflects current state

Race condition fix:
- Move setRefreshModels(true) from handleSourceDestinationChange into
  runTransformation .then() callback. Calling it before the run completed
  triggered concurrent getExplorer/fetch_all_models that conflicted with
  in-progress sync_file_models, causing "No module named" import errors.

No Credits chip styling:
- Match border and background with the standard info chip (raw, etc.)
- Only the text and icon stay red to indicate error state
- Now consistent across light and dark themes
- file_explorer.py: keep both refs_by_name (dependency chain) and
  model_lookup (run status fields) — output includes references +
  run_status/failure_reason/last_run_at/run_duration
- explorer-component.jsx: keep both MODEL_SORT_OPTIONS and
  MODEL_STATUS_DOT_STYLE/getModelRunStatus constants
- no-code-model.jsx: keep comment for setRefreshModels call
@wicky-zipstack wicky-zipstack merged commit 6c3ca18 into main Apr 17, 2026
7 checks passed
@wicky-zipstack wicky-zipstack deleted the feat/lineage-scoping branch April 17, 2026 06:27
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.

3 participants