feat: lineage scoping and explorer dependency chain sort#56
feat: lineage scoping and explorer dependency chain sort#56wicky-zipstack wants to merge 7 commits intomainfrom
Conversation
- 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
|
| 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()
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
…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
tahierhussain
left a comment
There was a problem hiding this comment.
@wicky-zipstack Please make the following changes:
- Add optional chaining wherever necessary in the frontend to avoid runtime errors.
- Please add screenshots for the UI changes addressed in this PR to the PR description.
- 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
…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
…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
What
Why
How
getRelatedNodeIds()traverses edges to find ancestors/descendants,applyScopedStyles()applies opacity + dashed borderreferencesfield from model_data to API responsesortModels()with dep_chain grouping,applyModelDecorations()for child indent, sort dropdown with 4 optionssetRefreshModels(true)after config save triggers explorer re-fetchCan 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)
Database Migrations
Env Config
Relevant Docs
Related Issues or PRs
Dependencies Versions
Notes on Testing
Screenshots
Checklist