mirror of
https://github.com/langgenius/dify.git
synced 2026-05-13 08:57:28 +08:00
183 lines
5.9 KiB
TypeScript
183 lines
5.9 KiB
TypeScript
import type { FC } from 'react'
|
|
import type { Viewport } from 'reactflow'
|
|
import type { SyncWorkflowDraft, SyncWorkflowDraftCallback } from '../types'
|
|
import type { Shape as HooksStoreShape } from '@/app/components/workflow/hooks-store'
|
|
import type { NestedNodeConfig } from '@/app/components/workflow/nodes/_base/types'
|
|
import type { Edge, Node } from '@/app/components/workflow/types'
|
|
import { useCallback, useEffect, useMemo } from 'react'
|
|
import { useStoreApi } from 'reactflow'
|
|
import { InteractionMode, WorkflowWithInnerContext } from '@/app/components/workflow'
|
|
import { useNodesInteractions } from '@/app/components/workflow/hooks'
|
|
import { useSetWorkflowVarsWithValue } from '@/app/components/workflow/hooks/use-fetch-workflow-inspect-vars'
|
|
import { useInspectVarsCrudCommon } from '@/app/components/workflow/hooks/use-inspect-vars-crud-common'
|
|
import { useWorkflowStore } from '@/app/components/workflow/store'
|
|
import { BlockEnum } from '@/app/components/workflow/types'
|
|
import { FlowType } from '@/types/common'
|
|
import { useAvailableNodesMetaData } from '../hooks'
|
|
import SubGraphChildren from './sub-graph-children'
|
|
|
|
type SubGraphMainBaseProps = {
|
|
nodes: Node[]
|
|
edges: Edge[]
|
|
viewport: Viewport
|
|
title: string
|
|
extractorNodeId: string
|
|
configsMap?: HooksStoreShape['configsMap']
|
|
selectableNodeTypes?: BlockEnum[]
|
|
onSave?: (nodes: Node[], edges: Edge[]) => void
|
|
onSyncWorkflowDraft?: SyncWorkflowDraft
|
|
isOpen: boolean
|
|
pendingSingleRun?: boolean
|
|
onPendingSingleRunHandled?: () => void
|
|
}
|
|
|
|
type SubGraphMainProps
|
|
= | (SubGraphMainBaseProps & {
|
|
variant: 'agent'
|
|
nestedNodeConfig: NestedNodeConfig
|
|
onNestedNodeConfigChange: (config: NestedNodeConfig) => void
|
|
})
|
|
| (SubGraphMainBaseProps & {
|
|
variant: 'assemble'
|
|
nestedNodeConfig: NestedNodeConfig
|
|
onNestedNodeConfigChange: (config: NestedNodeConfig) => void
|
|
})
|
|
|
|
const SubGraphMain: FC<SubGraphMainProps> = (props) => {
|
|
const {
|
|
nodes,
|
|
edges,
|
|
viewport,
|
|
variant,
|
|
title,
|
|
extractorNodeId,
|
|
configsMap,
|
|
selectableNodeTypes,
|
|
onSave,
|
|
onSyncWorkflowDraft,
|
|
isOpen,
|
|
pendingSingleRun,
|
|
onPendingSingleRunHandled,
|
|
} = props
|
|
const reactFlowStore = useStoreApi()
|
|
const workflowStore = useWorkflowStore()
|
|
const { handleNodeSelect } = useNodesInteractions()
|
|
const availableNodesMetaData = useAvailableNodesMetaData()
|
|
const flowType = configsMap?.flowType ?? FlowType.appFlow
|
|
const flowId = configsMap?.flowId ?? ''
|
|
const { fetchInspectVars } = useSetWorkflowVarsWithValue({
|
|
flowType,
|
|
flowId,
|
|
interactionMode: InteractionMode.Subgraph,
|
|
})
|
|
const inspectVarsCrud = useInspectVarsCrudCommon({
|
|
flowType,
|
|
flowId,
|
|
interactionMode: InteractionMode.Subgraph,
|
|
})
|
|
|
|
const handleSyncSubGraphDraft = useCallback(async () => {
|
|
const { getNodes, edges } = reactFlowStore.getState()
|
|
await onSave?.(getNodes() as Node[], edges as Edge[])
|
|
}, [onSave, reactFlowStore])
|
|
|
|
const handleSyncWorkflowDraft = useCallback(async (
|
|
notRefreshWhenSyncError?: boolean,
|
|
callback?: SyncWorkflowDraftCallback,
|
|
) => {
|
|
try {
|
|
await handleSyncSubGraphDraft()
|
|
if (onSyncWorkflowDraft) {
|
|
await onSyncWorkflowDraft(notRefreshWhenSyncError, callback)
|
|
return
|
|
}
|
|
callback?.onSuccess?.()
|
|
}
|
|
catch {
|
|
callback?.onError?.()
|
|
}
|
|
finally {
|
|
callback?.onSettled?.()
|
|
}
|
|
}, [handleSyncSubGraphDraft, onSyncWorkflowDraft])
|
|
|
|
useEffect(() => {
|
|
if (!isOpen || !pendingSingleRun)
|
|
return
|
|
|
|
const { getNodes } = reactFlowStore.getState()
|
|
const currentNodes = getNodes()
|
|
const hasExtractorNode = currentNodes.some(node => node.id === extractorNodeId)
|
|
if (!hasExtractorNode)
|
|
return
|
|
|
|
// NodePanel listens for pendingSingleRun only when the extractor node is selected in this subgraph.
|
|
handleNodeSelect(extractorNodeId, false, true)
|
|
|
|
// Defer run until the selection is applied and the panel is ready.
|
|
const frame = requestAnimationFrame(() => {
|
|
const store = workflowStore.getState()
|
|
store.setPendingSingleRun({
|
|
nodeId: extractorNodeId,
|
|
action: 'run',
|
|
})
|
|
onPendingSingleRunHandled?.()
|
|
})
|
|
|
|
return () => cancelAnimationFrame(frame)
|
|
}, [extractorNodeId, handleNodeSelect, isOpen, onPendingSingleRunHandled, pendingSingleRun, reactFlowStore, workflowStore])
|
|
|
|
const resolvedSelectableTypes = useMemo(() => {
|
|
if (selectableNodeTypes && selectableNodeTypes.length > 0)
|
|
return selectableNodeTypes
|
|
return variant === 'agent' ? [BlockEnum.LLM] : [BlockEnum.Code]
|
|
}, [selectableNodeTypes, variant])
|
|
|
|
const hooksStore = useMemo(() => ({
|
|
interactionMode: InteractionMode.Subgraph,
|
|
subGraphSelectableNodeTypes: resolvedSelectableTypes,
|
|
availableNodesMetaData,
|
|
configsMap,
|
|
fetchInspectVars,
|
|
...inspectVarsCrud,
|
|
doSyncWorkflowDraft: handleSyncWorkflowDraft,
|
|
syncWorkflowDraftWhenPageClose: handleSyncSubGraphDraft,
|
|
}), [availableNodesMetaData, configsMap, fetchInspectVars, handleSyncSubGraphDraft, handleSyncWorkflowDraft, inspectVarsCrud, resolvedSelectableTypes])
|
|
|
|
const subGraphChildren = variant === 'agent'
|
|
? (
|
|
<SubGraphChildren
|
|
variant="agent"
|
|
title={title}
|
|
extractorNodeId={extractorNodeId}
|
|
nestedNodeConfig={props.nestedNodeConfig}
|
|
onNestedNodeConfigChange={props.onNestedNodeConfigChange}
|
|
/>
|
|
)
|
|
: (
|
|
<SubGraphChildren
|
|
variant="assemble"
|
|
title={title}
|
|
extractorNodeId={extractorNodeId}
|
|
nestedNodeConfig={props.nestedNodeConfig}
|
|
onNestedNodeConfigChange={props.onNestedNodeConfigChange}
|
|
/>
|
|
)
|
|
|
|
return (
|
|
<WorkflowWithInnerContext
|
|
nodes={nodes}
|
|
edges={edges}
|
|
viewport={viewport}
|
|
hooksStore={hooksStore}
|
|
allowSelectionWhenReadOnly
|
|
canvasReadOnly
|
|
interactionMode={InteractionMode.Subgraph}
|
|
>
|
|
{subGraphChildren}
|
|
</WorkflowWithInnerContext>
|
|
)
|
|
}
|
|
|
|
export default SubGraphMain
|