Files
dify/web/app/components/workflow/skill/hooks/use-node-move.ts
yyh 2151676db1 refactor: use react-arborist built-in drag for internal node moves
Switch from native HTML5 drag to react-arborist's built-in drag system
for internal node drag-and-drop. The HTML5Backend used by react-arborist
was intercepting dragstart events, preventing native drag from working.

- Add onMove callback and disableDrop validation to Tree component
- Sync react-arborist drag state (isDragging, willReceiveDrop) to Zustand
- Simplify use-node-move to only handle API execution
- Update use-unified-drag to only handle external file uploads
- External file drops continue to work via native HTML5 events
2026-01-20 18:09:08 +08:00

46 lines
1.3 KiB
TypeScript

'use client'
// Internal tree node move handler - API execution logic only
// Drag state syncing is handled by react-arborist + TreeNode useEffect
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { useStore as useAppStore } from '@/app/components/app/store'
import Toast from '@/app/components/base/toast'
import { useMoveAppAssetNode } from '@/service/use-app-asset'
import { toApiParentId } from '../utils/tree-utils'
export function useNodeMove() {
const { t } = useTranslation('workflow')
const appDetail = useAppStore(s => s.appDetail)
const appId = appDetail?.id || ''
const moveNode = useMoveAppAssetNode()
// Execute move API call - validation is handled by react-arborist's disableDrop callback
const executeMoveNode = useCallback(async (nodeId: string, targetFolderId: string | null) => {
try {
await moveNode.mutateAsync({
appId,
nodeId,
payload: { parent_id: toApiParentId(targetFolderId) },
})
Toast.notify({
type: 'success',
message: t('skillSidebar.menu.moved'),
})
}
catch {
Toast.notify({
type: 'error',
message: t('skillSidebar.menu.moveError'),
})
}
}, [appId, moveNode, t])
return {
executeMoveNode,
isMoving: moveNode.isPending,
}
}