mirror of
https://github.com/langgenius/dify.git
synced 2026-04-22 03:37:44 +08:00
refactor(skill): use node.parent chain for ancestor traversal
Replace getAncestorIds(treeData) with node.parent chain traversal for more efficient ancestor lookup. This avoids re-traversing the tree data structure and uses react-arborist's built-in parent refs. Also rename hook to useSyncTreeWithActiveTab for clarity.
This commit is contained in:
@ -16,8 +16,8 @@ import Toast from '@/app/components/base/toast'
|
||||
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
|
||||
import { useRenameAppAssetNode } from '@/service/use-app-asset'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { useRevealActiveTab } from '../hooks/use-reveal-active-tab'
|
||||
import { useSkillAssetTreeData } from '../hooks/use-skill-asset-tree'
|
||||
import { useSyncTreeWithActiveTab } from '../hooks/use-sync-tree-with-active-tab'
|
||||
import TreeContextMenu from './tree-context-menu'
|
||||
import TreeNode from './tree-node'
|
||||
|
||||
@ -85,10 +85,9 @@ const FileTree: React.FC<FileTreeProps> = ({ className }) => {
|
||||
})
|
||||
}, [appId, renameNode, t])
|
||||
|
||||
useRevealActiveTab({
|
||||
useSyncTreeWithActiveTab({
|
||||
treeRef,
|
||||
activeTabId,
|
||||
treeChildren: treeData?.children,
|
||||
})
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import type { TreeApi } from 'react-arborist'
|
||||
import type { TreeNodeData } from '../type'
|
||||
import type { AppAssetTreeView } from '@/types/app-asset'
|
||||
import { useEffect } from 'react'
|
||||
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||
import { getAncestorIds } from '../utils/tree-utils'
|
||||
|
||||
type UseRevealActiveTabOptions = {
|
||||
treeRef: React.RefObject<TreeApi<TreeNodeData> | null>
|
||||
activeTabId: string | null
|
||||
treeChildren: AppAssetTreeView[] | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that handles revealing the active tab in the file tree.
|
||||
* Expands ancestor folders and scrolls to the active node.
|
||||
*/
|
||||
export function useRevealActiveTab({
|
||||
treeRef,
|
||||
activeTabId,
|
||||
treeChildren,
|
||||
}: UseRevealActiveTabOptions): void {
|
||||
const storeApi = useWorkflowStore()
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeTabId || !treeChildren)
|
||||
return
|
||||
|
||||
const tree = treeRef.current
|
||||
if (!tree)
|
||||
return
|
||||
|
||||
const ancestors = getAncestorIds(activeTabId, treeChildren)
|
||||
if (ancestors.length > 0)
|
||||
storeApi.getState().revealFile(ancestors)
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const node = tree.get(activeTabId)
|
||||
if (node) {
|
||||
tree.openParents(node)
|
||||
tree.scrollTo(activeTabId)
|
||||
}
|
||||
})
|
||||
}, [activeTabId, treeChildren, storeApi, treeRef])
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
'use client'
|
||||
|
||||
import type { TreeApi } from 'react-arborist'
|
||||
import type { TreeNodeData } from '../type'
|
||||
import { useEffect } from 'react'
|
||||
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||
|
||||
type UseSyncTreeWithActiveTabOptions = {
|
||||
treeRef: React.RefObject<TreeApi<TreeNodeData> | null>
|
||||
activeTabId: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that synchronizes the file tree with the active tab.
|
||||
* Expands ancestor folders and scrolls to the active node.
|
||||
*
|
||||
* Uses node.parent chain for efficient ancestor traversal instead of
|
||||
* re-traversing the tree data structure.
|
||||
*/
|
||||
export function useSyncTreeWithActiveTab({
|
||||
treeRef,
|
||||
activeTabId,
|
||||
}: UseSyncTreeWithActiveTabOptions): void {
|
||||
const storeApi = useWorkflowStore()
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeTabId)
|
||||
return
|
||||
|
||||
const tree = treeRef.current
|
||||
if (!tree)
|
||||
return
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const node = tree.get(activeTabId)
|
||||
if (!node)
|
||||
return
|
||||
|
||||
// Traverse parent chain to collect ancestor folder IDs
|
||||
const ancestors: string[] = []
|
||||
let current = node.parent
|
||||
while (current && !current.isRoot) {
|
||||
ancestors.push(current.id)
|
||||
current = current.parent
|
||||
}
|
||||
|
||||
if (ancestors.length > 0)
|
||||
storeApi.getState().revealFile(ancestors)
|
||||
|
||||
tree.openParents(node)
|
||||
tree.scrollTo(activeTabId)
|
||||
})
|
||||
}, [activeTabId, treeRef, storeApi])
|
||||
}
|
||||
Reference in New Issue
Block a user