Files
dify/web/app/components/workflow/skill/file-tree/tree-context-menu.tsx
yyh b8d67a42bd refactor(skill): migrate skill editor store to workflow store slice injection
Refactor the skill editor state management from a standalone Zustand store
with Context provider pattern to a slice injection pattern that integrates
with the existing workflow store. This aligns with how rag-pipeline already
injects its slice.

- Remove SkillEditorProvider and SkillEditorContext
- Export createSkillEditorSlice for injection into workflow store
- Update all components to use useStore/useWorkflowStore from workflow store
- Add SkillEditorSliceShape to SliceFromInjection union type
- Use type-safe slice creator args without any types
2026-01-16 13:51:49 +08:00

63 lines
1.7 KiB
TypeScript

'use client'
import type { FC } from 'react'
import type { TreeApi } from 'react-arborist'
import type { TreeNodeData } from '../type'
import { useClickAway } from 'ahooks'
import * as React from 'react'
import { useCallback, useMemo, useRef } from 'react'
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
import { useSkillAssetTreeData } from '../hooks/use-skill-asset-tree'
import { findNodeById } from '../utils/tree-utils'
import NodeMenu from './node-menu'
type TreeContextMenuProps = {
treeRef: React.RefObject<TreeApi<TreeNodeData> | null>
}
const TreeContextMenu: FC<TreeContextMenuProps> = ({ treeRef }) => {
const ref = useRef<HTMLDivElement>(null)
const contextMenu = useStore(s => s.contextMenu)
const storeApi = useWorkflowStore()
const { data: treeData } = useSkillAssetTreeData()
const handleClose = useCallback(() => {
storeApi.getState().setContextMenu?.(null)
}, [storeApi])
useClickAway(() => {
handleClose()
}, ref)
const targetNode = useMemo(() => {
if (!contextMenu?.nodeId || !treeData?.children)
return null
return findNodeById(treeData.children, contextMenu.nodeId)
}, [contextMenu?.nodeId, treeData?.children])
const isFolder = targetNode?.node_type === 'folder'
if (!contextMenu)
return null
return (
<div
ref={ref}
className="fixed z-[100]"
style={{
top: contextMenu.top,
left: contextMenu.left,
}}
>
<NodeMenu
type={isFolder ? 'folder' : 'file'}
nodeId={contextMenu.nodeId}
onClose={handleClose}
treeRef={treeRef}
/>
</div>
)
}
export default React.memo(TreeContextMenu)