Files
dify/web/app/components/workflow/node-actions-menu/use-node-actions-menu-model.ts

105 lines
3.2 KiB
TypeScript

import type { Node } from '@/app/components/workflow/types'
import { useCallback, useMemo } from 'react'
import { useEdges } from 'reactflow'
import { CollectionType } from '@/app/components/tools/types'
import {
useNodeDataUpdate,
useNodeMetaData,
useNodesInteractions,
useNodesReadOnly,
useNodesSyncDraft,
} from '@/app/components/workflow/hooks'
import { BlockEnum } from '@/app/components/workflow/types'
import { canRunBySingle } from '@/app/components/workflow/utils'
import { useAllWorkflowTools } from '@/service/use-tools'
import { canFindTool } from '@/utils'
type UseNodeActionsMenuModelParams = {
id: string
data: Node['data']
onClose: () => void
showHelpLink?: boolean
}
export function useNodeActionsMenuModel({
id,
data,
onClose,
showHelpLink = true,
}: UseNodeActionsMenuModelParams) {
const edges = useEdges()
const {
handleNodeDelete,
handleNodesDuplicate,
handleNodeSelect,
handleNodesCopy,
} = useNodesInteractions()
const { handleNodeDataUpdate } = useNodeDataUpdate()
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const { nodesReadOnly } = useNodesReadOnly()
const nodeMetaData = useNodeMetaData({ id, data } as Node)
const { data: workflowTools } = useAllWorkflowTools()
const isChildNode = !!(data.isInIteration || data.isInLoop)
const canRun = canRunBySingle(data.type, isChildNode)
const canChangeBlock = !nodeMetaData.isTypeFixed && !nodeMetaData.isUndeletable && !nodesReadOnly
const sourceHandle = useMemo(() => {
return edges.find(edge => edge.target === id)?.sourceHandle || 'source'
}, [edges, id])
const workflowAppHref = useMemo(() => {
const isWorkflowTool = data.type === BlockEnum.Tool && data.provider_type === CollectionType.workflow
if (!isWorkflowTool || !workflowTools || !data.provider_id)
return undefined
const workflowTool = workflowTools.find(item => canFindTool(item.id, data.provider_id))
if (!workflowTool?.workflow_app_id)
return undefined
return `/app/${workflowTool.workflow_app_id}/workflow`
}, [data.provider_id, data.provider_type, data.type, workflowTools])
const handleRun = useCallback(() => {
handleNodeSelect(id)
handleNodeDataUpdate({ id, data: { _isSingleRun: true } })
handleSyncWorkflowDraft(true)
onClose()
}, [handleNodeDataUpdate, handleNodeSelect, handleSyncWorkflowDraft, id, onClose])
const handleCopy = useCallback(() => {
onClose()
handleNodesCopy(id)
}, [handleNodesCopy, id, onClose])
const handleDuplicate = useCallback(() => {
onClose()
handleNodesDuplicate(id)
}, [handleNodesDuplicate, id, onClose])
const handleDelete = useCallback(() => {
onClose()
handleNodeDelete(id)
}, [handleNodeDelete, id, onClose])
return {
about: {
author: nodeMetaData.author,
description: nodeMetaData.description,
},
canChangeBlock,
canRun,
data,
handleCopy,
handleDelete,
handleDuplicate,
handleRun,
helpLinkUri: showHelpLink ? nodeMetaData.helpLinkUri : undefined,
id,
isSingleton: nodeMetaData.isSingleton,
isUndeletable: nodeMetaData.isUndeletable,
nodesReadOnly,
sourceHandle,
workflowAppHref,
}
}