Skip to content

feat: lineage scoping and explorer dependency chain sort#56

Open
wicky-zipstack wants to merge 7 commits intomainfrom
feat/lineage-scoping
Open

feat: lineage scoping and explorer dependency chain sort#56
wicky-zipstack wants to merge 7 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 adds lineage scoping (highlight/fade ancestor-descendant chains when a model is open) and a sort dropdown to the explorer (dependency chain, execution order, A-Z, Z-A), with child models indented to show hierarchy. A references field is added to the file-explorer API response to power the frontend sort, and the explorer auto-refreshes after a model run so updated references are reflected in the dependency-chain ordering.

Confidence Score: 5/5

Safe to merge — all findings are P2 style/minor-behavior concerns with no correctness or data-integrity impact.

The previous P1 concerns (stale closure, external-ref filtering) were properly resolved with the modelSortByRef pattern and the modelNames guard. The two remaining findings are P2: a stale code comment and an overly-broad explorer refresh trigger. Neither blocks the feature from working correctly.

frontend/src/ide/editor/no-code-model/no-code-model.jsx — misplaced comment and broad setRefreshModels trigger.

Important Files Changed

Filename Overview
frontend/src/ide/explorer/explorer-component.jsx Adds sort dropdown (dep_chain, exec_order, A-Z, Z-A) and child-model indentation; stale-closure concern from prior review is addressed via modelSortByRef + useEffect; external-ref filtering in applyModelDecorations is correct.
frontend/src/ide/editor/lineage-utils.js New shared utility extracting getRelatedNodeIds and applyScopedStyles; recursive DFS is guarded by the visited set, scoping logic is correct.
frontend/src/ide/editor/lineage-tab/lineage-tab.jsx Imports applyScopedStyles from lineage-utils, applies scoping on fetch and layout toggle when selectedModelName is provided; dependency array correctly updated.
frontend/src/ide/editor/no-code-model/no-code-model.jsx Imports applyScopedStyles, applies scoping on lineage load and layout toggle; setRefreshModels(true) fires on every successful run rather than only on config/references save — wider than the stated intent.
backend/backend/application/file_explorer/file_explorer.py Adds references field to the no-code model API response using a pre-built lookup dict; additive change with no breaking impact on existing fields.
frontend/src/store/project-store.js Adds schemaList state and setSchemaList action to the shared project store, consumed by the explorer to populate the shared schema list for PR #55 integration.

Sequence Diagram

sequenceDiagram
    participant User
    participant NoCodeModel
    participant LineageUtils
    participant ExplorerComponent
    participant Backend

    User->>NoCodeModel: Open model tab
    NoCodeModel->>Backend: GET /lineage
    Backend-->>NoCodeModel: nodes + edges
    NoCodeModel->>LineageUtils: applyScopedStyles(nodes, edges, modelName)
    LineageUtils-->>NoCodeModel: { styledNodes, styledEdges }
    NoCodeModel->>NoCodeModel: setNodes / setEdges

    User->>NoCodeModel: runTransformation(spec)
    NoCodeModel->>Backend: POST /execute/run
    Backend-->>NoCodeModel: success
    NoCodeModel->>ExplorerComponent: setRefreshModels(true)
    ExplorerComponent->>Backend: GET /file_explorer
    Backend-->>ExplorerComponent: tree with references[]
    ExplorerComponent->>ExplorerComponent: sortModels() + applyModelDecorations()

    User->>ExplorerComponent: Click sort dropdown
    ExplorerComponent->>ExplorerComponent: handleModelSort(key) → modelSortByRef.current = key
    ExplorerComponent->>ExplorerComponent: useEffect[modelSortBy] → rebuildTree()
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: 2176-2177

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

The comment `// Find all ancestor and descendant node IDs for a given model` describes `getRelatedNodeIds` (now in `lineage-utils.js`), not `getLineageData`. `getLineageData` fetches the lineage graph from the API — this comment is leftover from when the utilities were co-located here.

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

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

---

This is a comment left during a code review.
Path: frontend/src/ide/editor/no-code-model/no-code-model.jsx
Line: 1613-1619

Comment:
**Explorer refreshes on every run, not only on config saves**

`setRefreshModels(true)` is called inside `runTransformation`, so every successful model run triggers a full explorer re-fetch — even when the user re-runs without touching the model's references. This is broader than the stated intent ("auto-refreshes when model configuration is saved").

If references only change when the model spec is saved (i.e., via a dedicated save flow rather than through `runTransformation`), consider moving this call to the save-config handler instead, or gating it on whether `references` actually changed between the old and new spec.

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

Reviews (7): Last reviewed commit: "fix: explorer sort dropdown UX, race con..." | 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
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