Commit a55a7603 authored by StyleZhang's avatar StyleZhang

split hooks

parent 64fa343d
...@@ -4,7 +4,7 @@ import { ...@@ -4,7 +4,7 @@ import {
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useStore } from './store' import { useStore } from './store'
import { useWorkflow } from './hooks' import { useNodesSyncDraft } from './hooks'
import { XClose } from '@/app/components/base/icons/src/vender/line/general' import { XClose } from '@/app/components/base/icons/src/vender/line/general'
import { import {
FeaturesChoose, FeaturesChoose,
...@@ -14,7 +14,7 @@ import { ...@@ -14,7 +14,7 @@ import {
const Features = () => { const Features = () => {
const { t } = useTranslation() const { t } = useTranslation()
const setShowFeaturesPanel = useStore(state => state.setShowFeaturesPanel) const setShowFeaturesPanel = useStore(state => state.setShowFeaturesPanel)
const { handleSyncWorkflowDraft } = useWorkflow() const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const handleFeaturesChange = useCallback(() => { const handleFeaturesChange = useCallback(() => {
handleSyncWorkflowDraft() handleSyncWorkflowDraft()
......
...@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next' ...@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
import { useStore } from '../store' import { useStore } from '../store'
import { import {
useIsChatMode, useIsChatMode,
useWorkflow, useWorkflowRun,
} from '../hooks' } from '../hooks'
import RunAndHistory from './run-and-history' import RunAndHistory from './run-and-history'
import EditingTitle from './editing-title' import EditingTitle from './editing-title'
...@@ -24,15 +24,15 @@ const Header: FC = () => { ...@@ -24,15 +24,15 @@ const Header: FC = () => {
const appSidebarExpand = useAppStore(s => s.appSidebarExpand) const appSidebarExpand = useAppStore(s => s.appSidebarExpand)
const isChatMode = useIsChatMode() const isChatMode = useIsChatMode()
const runningStatus = useStore(s => s.runningStatus) const runningStatus = useStore(s => s.runningStatus)
const { handleRunInit } = useWorkflow() const { handleRunSetting } = useWorkflowRun()
const handleShowFeatures = useCallback(() => { const handleShowFeatures = useCallback(() => {
useStore.setState({ showFeaturesPanel: true }) useStore.setState({ showFeaturesPanel: true })
}, []) }, [])
const handleGoBackToEdit = useCallback(() => { const handleGoBackToEdit = useCallback(() => {
handleRunInit(true) handleRunSetting(true)
}, [handleRunInit]) }, [handleRunSetting])
return ( return (
<div <div
......
...@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next' ...@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
import { useStore } from '../store' import { useStore } from '../store'
import { import {
useIsChatMode, useIsChatMode,
useWorkflow, useWorkflowRun,
} from '../hooks' } from '../hooks'
import { WorkflowRunningStatus } from '../types' import { WorkflowRunningStatus } from '../types'
import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices' import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
...@@ -54,11 +54,11 @@ RunMode.displayName = 'RunMode' ...@@ -54,11 +54,11 @@ RunMode.displayName = 'RunMode'
const PreviewMode = memo(() => { const PreviewMode = memo(() => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleRunInit } = useWorkflow() const { handleRunSetting } = useWorkflowRun()
const runningStatus = useStore(s => s.runningStatus) const runningStatus = useStore(s => s.runningStatus)
const handleClick = () => { const handleClick = () => {
handleRunInit() handleRunSetting()
} }
return ( return (
......
export * from './use-edges-interactions'
export * from './use-node-data-update'
export * from './use-nodes-interactions'
export * from './use-nodes-data'
export * from './use-nodes-sync-draft'
export * from './use-workflow'
export * from './use-workflow-run'
import { useCallback } from 'react'
import produce from 'immer'
import type {
EdgeMouseHandler,
OnEdgesChange,
} from 'reactflow'
import { useStoreApi } from 'reactflow'
import { useStore } from '../store'
import { useNodesSyncDraft } from './use-nodes-sync-draft'
export const useEdgesInteractions = () => {
const store = useStoreApi()
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const handleEdgeEnter = useCallback<EdgeMouseHandler>((_, edge) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const {
edges,
setEdges,
} = store.getState()
const newEdges = produce(edges, (draft) => {
const currentEdge = draft.find(e => e.id === edge.id)!
currentEdge.data = { ...currentEdge.data, _hovering: true }
})
setEdges(newEdges)
}, [store])
const handleEdgeLeave = useCallback<EdgeMouseHandler>((_, edge) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const {
edges,
setEdges,
} = store.getState()
const newEdges = produce(edges, (draft) => {
const currentEdge = draft.find(e => e.id === edge.id)!
currentEdge.data = { ...currentEdge.data, _hovering: false }
})
setEdges(newEdges)
}, [store])
const handleEdgeDeleteByDeleteBranch = useCallback((nodeId: string, branchId: string) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const {
edges,
setEdges,
} = store.getState()
const newEdges = produce(edges, (draft) => {
const index = draft.findIndex(edge => edge.source === nodeId && edge.sourceHandle === branchId)
if (index > -1)
draft.splice(index, 1)
})
setEdges(newEdges)
handleSyncWorkflowDraft()
}, [store, handleSyncWorkflowDraft])
const handleEdgeDelete = useCallback(() => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const {
edges,
setEdges,
} = store.getState()
const newEdges = produce(edges, (draft) => {
const index = draft.findIndex(edge => edge.selected)
if (index > -1)
draft.splice(index, 1)
})
setEdges(newEdges)
handleSyncWorkflowDraft()
}, [store, handleSyncWorkflowDraft])
const handleEdgesChange = useCallback<OnEdgesChange>((changes) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const {
edges,
setEdges,
} = store.getState()
const newEdges = produce(edges, (draft) => {
changes.forEach((change) => {
if (change.type === 'select')
draft.find(edge => edge.id === change.id)!.selected = change.selected
})
})
setEdges(newEdges)
}, [store])
return {
handleEdgeEnter,
handleEdgeLeave,
handleEdgeDeleteByDeleteBranch,
handleEdgeDelete,
handleEdgesChange,
}
}
import { useCallback } from 'react'
import produce from 'immer'
import { useStoreApi } from 'reactflow'
import { useStore } from '../store'
import { useNodesSyncDraft } from './use-nodes-sync-draft'
type NodeDataUpdatePayload = {
id: string
data: Record<string, any>
}
export const useNodeDataUpdate = () => {
const store = useStoreApi()
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const handleNodeDataUpdate = useCallback(({ id, data }: NodeDataUpdatePayload) => {
const {
getNodes,
setNodes,
} = store.getState()
const newNodes = produce(getNodes(), (draft) => {
const currentNode = draft.find(node => node.id === id)!
currentNode.data = { ...currentNode.data, ...data }
})
setNodes(newNodes)
}, [store])
const handleNodeDataUpdateWithSyncDraft = useCallback((payload: NodeDataUpdatePayload) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
handleNodeDataUpdate(payload)
handleSyncWorkflowDraft(true)
}, [handleSyncWorkflowDraft, handleNodeDataUpdate])
return {
handleNodeDataUpdate,
handleNodeDataUpdateWithSyncDraft,
}
}
import { useTranslation } from 'react-i18next'
import produce from 'immer'
import type { BlockEnum } from '../types'
import {
NODES_EXTRA_DATA,
NODES_INITIAL_DATA,
} from '../constants'
export const useNodesInitialData = () => {
const { t } = useTranslation()
return produce(NODES_INITIAL_DATA, (draft) => {
Object.keys(draft).forEach((key) => {
draft[key as BlockEnum].title = t(`workflow.blocks.${key}`)
})
})
}
export const useNodesExtraData = () => {
const { t } = useTranslation()
return produce(NODES_EXTRA_DATA, (draft) => {
Object.keys(draft).forEach((key) => {
draft[key as BlockEnum].about = t(`workflow.blocksAbout.${key}`)
})
})
}
import { useCallback } from 'react'
import produce from 'immer'
import { useDebounceFn } from 'ahooks'
import {
useReactFlow,
useStoreApi,
} from 'reactflow'
import { useStore } from '../store'
import { syncWorkflowDraft } from '@/service/workflow'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { useStore as useAppStore } from '@/app/components/app/store'
export const useNodesSyncDraft = () => {
const store = useStoreApi()
const reactFlow = useReactFlow()
const featuresStore = useFeaturesStore()
const shouldDebouncedSyncWorkflowDraft = useCallback(() => {
const {
getNodes,
edges,
} = store.getState()
const { getViewport } = reactFlow
const appId = useAppStore.getState().appDetail?.id
if (appId) {
const features = featuresStore!.getState().features
const producedNodes = produce(getNodes(), (draft) => {
draft.forEach((node) => {
Object.keys(node.data).forEach((key) => {
if (key.startsWith('_'))
delete node.data[key]
})
})
})
const producedEdges = produce(edges, (draft) => {
draft.forEach((edge) => {
delete edge.data
})
})
syncWorkflowDraft({
url: `/apps/${appId}/workflows/draft`,
params: {
graph: {
nodes: producedNodes,
edges: producedEdges,
viewport: getViewport(),
},
features: {
opening_statement: features.opening.opening_statement,
suggested_questions: features.opening.suggested_questions,
suggested_questions_after_answer: features.suggested,
text_to_speech: features.text2speech,
speech_to_text: features.speech2text,
retriever_resource: features.citation,
sensitive_word_avoidance: features.moderation,
},
},
}).then((res) => {
useStore.setState({ draftUpdatedAt: res.updated_at })
})
}
}, [store, reactFlow, featuresStore])
const { run: debouncedSyncWorkflowDraft } = useDebounceFn(shouldDebouncedSyncWorkflowDraft, {
wait: 2000,
trailing: true,
})
const handleSyncWorkflowDraft = useCallback((shouldDelay?: boolean) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
if (shouldDelay)
debouncedSyncWorkflowDraft()
else
shouldDebouncedSyncWorkflowDraft()
}, [debouncedSyncWorkflowDraft, shouldDebouncedSyncWorkflowDraft])
return {
handleSyncWorkflowDraft,
}
}
import { useCallback } from 'react'
import {
useReactFlow,
useStoreApi,
} from 'reactflow'
import produce from 'immer'
import { useStore } from '../store'
import {
NodeRunningStatus,
WorkflowRunningStatus,
} from '../types'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { IOtherOptions } from '@/service/base'
import { ssePost } from '@/service/base'
export const useWorkflowRun = () => {
const store = useStoreApi()
const reactflow = useReactFlow()
const handleRunSetting = useCallback((shouldClear?: boolean) => {
useStore.setState({ runningStatus: shouldClear ? undefined : WorkflowRunningStatus.Waiting })
const { setNodes, getNodes } = store.getState()
const newNodes = produce(getNodes(), (draft) => {
draft.forEach((node) => {
node.data._runningStatus = shouldClear ? undefined : NodeRunningStatus.Waiting
})
})
setNodes(newNodes)
}, [store])
const handleRun = useCallback((params: any, callback?: IOtherOptions) => {
const {
getNodes,
setNodes,
} = store.getState()
const appDetail = useAppStore.getState().appDetail
let url = ''
if (appDetail?.mode === 'advanced-chat')
url = `/apps/${appDetail.id}/advanced-chat/workflows/draft/run`
if (appDetail?.mode === 'workflow')
url = `/apps/${appDetail.id}/workflows/draft/run`
ssePost(
url,
{
body: params,
},
{
onWorkflowStarted: ({ task_id, workflow_run_id, sequence_number }) => {
useStore.setState({ runningStatus: WorkflowRunningStatus.Running })
useStore.setState({ taskId: task_id })
useStore.setState({ currentSequenceNumber: sequence_number })
useStore.setState({ workflowRunId: workflow_run_id })
const newNodes = produce(getNodes(), (draft) => {
draft.forEach((node) => {
node.data._runningStatus = NodeRunningStatus.Waiting
})
})
setNodes(newNodes)
},
onWorkflowFinished: ({ data }) => {
useStore.setState({ runningStatus: data.status as WorkflowRunningStatus })
},
onNodeStarted: ({ data }) => {
const nodes = getNodes()
const {
getViewport,
setViewport,
} = reactflow
const viewport = getViewport()
const currentNodeIndex = nodes.findIndex(node => node.id === data.node_id)
const position = nodes[currentNodeIndex].position
const zoom = 1
setViewport({
zoom,
x: 200 / viewport.zoom - position.x,
y: 200 / viewport.zoom - position.y,
})
const newNodes = produce(nodes, (draft) => {
draft[currentNodeIndex].data._runningStatus = NodeRunningStatus.Running
})
setNodes(newNodes)
},
onNodeFinished: ({ data }) => {
const newNodes = produce(getNodes(), (draft) => {
const currentNode = draft.find(node => node.id === data.node_id)!
currentNode.data._runningStatus = data.status
})
setNodes(newNodes)
},
...callback,
},
)
}, [store, reactflow])
return {
handleRunSetting,
handleRun,
}
}
import { useCallback } from 'react'
import produce from 'immer'
import {
getIncomers,
getOutgoers,
useStoreApi,
} from 'reactflow'
import { getLayoutByDagre } from '../utils'
import type { Node } from '../types'
import { BlockEnum } from '../types'
import { useStore as useAppStore } from '@/app/components/app/store'
export const useIsChatMode = () => {
const appDetail = useAppStore(s => s.appDetail)
return appDetail?.mode === 'advanced-chat'
}
export const useWorkflow = () => {
const store = useStoreApi()
const handleLayout = useCallback(async () => {
const {
getNodes,
edges,
setNodes,
} = store.getState()
const layout = getLayoutByDagre(getNodes(), edges)
const newNodes = produce(getNodes(), (draft) => {
draft.forEach((node) => {
const nodeWithPosition = layout.node(node.id)
node.position = {
x: nodeWithPosition.x,
y: nodeWithPosition.y,
}
})
})
setNodes(newNodes)
}, [store])
const getTreeLeafNodes = useCallback(() => {
const {
getNodes,
edges,
} = store.getState()
const nodes = getNodes()
const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
if (!startNode)
return []
const list: Node[] = []
const preOrder = (root: Node, callback: (node: Node) => void) => {
const outgoers = getOutgoers(root, nodes, edges)
if (outgoers.length) {
outgoers.forEach((outgoer) => {
preOrder(outgoer, callback)
})
}
else {
callback(root)
}
}
preOrder(startNode, (node) => {
list.push(node)
})
return list.filter((item) => {
if (item.data.type === BlockEnum.IfElse)
return false
if (item.data.type === BlockEnum.QuestionClassifier)
return false
return true
})
}, [store])
const getBeforeNodesInSameBranch = useCallback((nodeId: string) => {
const {
getNodes,
edges,
} = store.getState()
const nodes = getNodes()
const currentNode = nodes.find(node => node.id === nodeId)!
const list: Node[] = []
const traverse = (root: Node, callback: (node: Node) => void) => {
const incomers = getIncomers(root, nodes, edges)
if (incomers.length) {
incomers.forEach((node) => {
callback(node)
traverse(node, callback)
})
}
}
traverse(currentNode, (node) => {
list.push(node)
})
const length = list.length
if (length && list.some(item => item.data.type === BlockEnum.Start)) {
return list.reverse().filter((item) => {
if (item.data.type === BlockEnum.IfElse)
return false
if (item.data.type === BlockEnum.QuestionClassifier)
return false
return true
})
}
return []
}, [store])
return {
handleLayout,
getTreeLeafNodes,
getBeforeNodesInSameBranch,
}
}
...@@ -20,8 +20,10 @@ import type { ...@@ -20,8 +20,10 @@ import type {
Node, Node,
} from './types' } from './types'
import { import {
useEdgesInteractions,
useNodesInitialData, useNodesInitialData,
useWorkflow, useNodesInteractions,
useNodesSyncDraft,
} from './hooks' } from './hooks'
import Header from './header' import Header from './header'
import CustomNode from './nodes' import CustomNode from './nodes'
...@@ -65,6 +67,7 @@ const Workflow: FC<WorkflowProps> = memo(({ ...@@ -65,6 +67,7 @@ const Workflow: FC<WorkflowProps> = memo(({
}) => { }) => {
const showFeaturesPanel = useStore(state => state.showFeaturesPanel) const showFeaturesPanel = useStore(state => state.showFeaturesPanel)
const runningStatus = useStore(s => s.runningStatus) const runningStatus = useStore(s => s.runningStatus)
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
useEffect(() => { useEffect(() => {
setAutoFreeze(false) setAutoFreeze(false)
...@@ -75,8 +78,6 @@ const Workflow: FC<WorkflowProps> = memo(({ ...@@ -75,8 +78,6 @@ const Workflow: FC<WorkflowProps> = memo(({
}, []) }, [])
const { const {
handleSyncWorkflowDraft,
handleNodeDragStart, handleNodeDragStart,
handleNodeDrag, handleNodeDrag,
handleNodeDragStop, handleNodeDragStop,
...@@ -84,12 +85,13 @@ const Workflow: FC<WorkflowProps> = memo(({ ...@@ -84,12 +85,13 @@ const Workflow: FC<WorkflowProps> = memo(({
handleNodeLeave, handleNodeLeave,
handleNodeClick, handleNodeClick,
handleNodeConnect, handleNodeConnect,
} = useNodesInteractions()
const {
handleEdgeEnter, handleEdgeEnter,
handleEdgeLeave, handleEdgeLeave,
handleEdgeDelete, handleEdgeDelete,
handleEdgesChange, handleEdgesChange,
} = useWorkflow() } = useEdgesInteractions()
useOnViewportChange({ useOnViewportChange({
onEnd: () => handleSyncWorkflowDraft(), onEnd: () => handleSyncWorkflowDraft(),
......
...@@ -3,7 +3,7 @@ import { ...@@ -3,7 +3,7 @@ import {
useCallback, useCallback,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useNodesInteractions } from '@/app/components/workflow/hooks'
import BlockSelector from '@/app/components/workflow/block-selector' import BlockSelector from '@/app/components/workflow/block-selector'
import { Plus } from '@/app/components/base/icons/src/vender/line/general' import { Plus } from '@/app/components/base/icons/src/vender/line/general'
import type { OnSelectBlock } from '@/app/components/workflow/types' import type { OnSelectBlock } from '@/app/components/workflow/types'
...@@ -19,7 +19,7 @@ const Add = ({ ...@@ -19,7 +19,7 @@ const Add = ({
branchName, branchName,
}: AddProps) => { }: AddProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleNodeAddNext } = useWorkflow() const { handleNodeAddNext } = useNodesInteractions()
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => { const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
handleNodeAddNext(nodeId, type, sourceHandle, toolDefaultValue) handleNodeAddNext(nodeId, type, sourceHandle, toolDefaultValue)
......
...@@ -9,7 +9,7 @@ import type { ...@@ -9,7 +9,7 @@ import type {
} from '@/app/components/workflow/types' } from '@/app/components/workflow/types'
import BlockIcon from '@/app/components/workflow/block-icon' import BlockIcon from '@/app/components/workflow/block-icon'
import BlockSelector from '@/app/components/workflow/block-selector' import BlockSelector from '@/app/components/workflow/block-selector'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useNodesInteractions } from '@/app/components/workflow/hooks'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
type ItemProps = { type ItemProps = {
...@@ -25,7 +25,7 @@ const Item = ({ ...@@ -25,7 +25,7 @@ const Item = ({
data, data,
}: ItemProps) => { }: ItemProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleNodeChange } = useWorkflow() const { handleNodeChange } = useNodesInteractions()
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => { const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue) handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue)
}, [nodeId, sourceHandle, handleNodeChange]) }, [nodeId, sourceHandle, handleNodeChange])
......
...@@ -5,7 +5,7 @@ import { ...@@ -5,7 +5,7 @@ import {
useState, useState,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useWorkflow } from '../../../hooks' import { useNodeDataUpdate } from '../../../hooks'
import type { Node } from '../../../types' import type { Node } from '../../../types'
import { canRunBySingle } from '../../../utils' import { canRunBySingle } from '../../../utils'
import PanelOperator from './panel-operator' import PanelOperator from './panel-operator'
...@@ -22,7 +22,7 @@ const NodeControl: FC<NodeControlProps> = ({ ...@@ -22,7 +22,7 @@ const NodeControl: FC<NodeControlProps> = ({
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const { handleNodeDataUpdate } = useWorkflow() const { handleNodeDataUpdate } = useNodeDataUpdate()
const handleOpenChange = useCallback((newOpen: boolean) => { const handleOpenChange = useCallback((newOpen: boolean) => {
setOpen(newOpen) setOpen(newOpen)
......
...@@ -14,7 +14,7 @@ import { BlockEnum } from '../../../types' ...@@ -14,7 +14,7 @@ import { BlockEnum } from '../../../types'
import type { Node } from '../../../types' import type { Node } from '../../../types'
import BlockSelector from '../../../block-selector' import BlockSelector from '../../../block-selector'
import type { ToolDefaultValue } from '../../../block-selector/types' import type { ToolDefaultValue } from '../../../block-selector/types'
import { useWorkflow } from '../../../hooks' import { useNodesInteractions } from '../../../hooks'
type NodeHandleProps = { type NodeHandleProps = {
handleId: string handleId: string
...@@ -30,7 +30,7 @@ export const NodeTargetHandle = ({ ...@@ -30,7 +30,7 @@ export const NodeTargetHandle = ({
nodeSelectorClassName, nodeSelectorClassName,
}: NodeHandleProps) => { }: NodeHandleProps) => {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const { handleNodeAddPrev } = useWorkflow() const { handleNodeAddPrev } = useNodesInteractions()
const edges = useEdges() const edges = useEdges()
const connectedEdges = getConnectedEdges([{ id } as Node], edges) const connectedEdges = getConnectedEdges([{ id } as Node], edges)
const connected = connectedEdges.find(edge => edge.targetHandle === handleId && edge.target === id) const connected = connectedEdges.find(edge => edge.targetHandle === handleId && edge.target === id)
...@@ -92,7 +92,7 @@ export const NodeSourceHandle = ({ ...@@ -92,7 +92,7 @@ export const NodeSourceHandle = ({
nodeSelectorClassName, nodeSelectorClassName,
}: NodeHandleProps) => { }: NodeHandleProps) => {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const { handleNodeAddNext } = useWorkflow() const { handleNodeAddNext } = useNodesInteractions()
const edges = useEdges() const edges = useEdges()
const connectedEdges = getConnectedEdges([{ id } as Node], edges) const connectedEdges = getConnectedEdges([{ id } as Node], edges)
const connected = connectedEdges.find(edge => edge.sourceHandle === handleId && edge.source === id) const connected = connectedEdges.find(edge => edge.sourceHandle === handleId && edge.source === id)
......
...@@ -4,7 +4,7 @@ import { ...@@ -4,7 +4,7 @@ import {
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import BlockSelector from '@/app/components/workflow/block-selector' import BlockSelector from '@/app/components/workflow/block-selector'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useNodesInteractions } from '@/app/components/workflow/hooks'
import type { OnSelectBlock } from '@/app/components/workflow/types' import type { OnSelectBlock } from '@/app/components/workflow/types'
type ChangeBlockProps = { type ChangeBlockProps = {
...@@ -16,7 +16,7 @@ const ChangeBlock = ({ ...@@ -16,7 +16,7 @@ const ChangeBlock = ({
sourceHandle, sourceHandle,
}: ChangeBlockProps) => { }: ChangeBlockProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleNodeChange } = useWorkflow() const { handleNodeChange } = useNodesInteractions()
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => { const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue) handleNodeChange(nodeId, type, sourceHandle, toolDefaultValue)
......
...@@ -14,7 +14,7 @@ import ChangeBlock from './change-block' ...@@ -14,7 +14,7 @@ import ChangeBlock from './change-block'
import { useStore } from '@/app/components/workflow/store' import { useStore } from '@/app/components/workflow/store'
import { import {
useNodesExtraData, useNodesExtraData,
useWorkflow, useNodesInteractions,
} from '@/app/components/workflow/hooks' } from '@/app/components/workflow/hooks'
import { DotsHorizontal } from '@/app/components/base/icons/src/vender/line/general' import { DotsHorizontal } from '@/app/components/base/icons/src/vender/line/general'
import { import {
...@@ -52,7 +52,7 @@ const PanelOperator = ({ ...@@ -52,7 +52,7 @@ const PanelOperator = ({
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getLanguage(locale) const language = getLanguage(locale)
const edges = useEdges() const edges = useEdges()
const { handleNodeDelete } = useWorkflow() const { handleNodeDelete } = useNodesInteractions()
const nodesExtraData = useNodesExtraData() const nodesExtraData = useNodesExtraData()
const toolsets = useStore(s => s.toolsets) const toolsets = useStore(s => s.toolsets)
const toolsMap = useStore(s => s.toolsMap) const toolsMap = useStore(s => s.toolsMap)
......
import { useWorkflow } from '@/app/components/workflow/hooks' import { useNodeDataUpdate } from '@/app/components/workflow/hooks'
import type { CommonNodeType } from '@/app/components/workflow/types' import type { CommonNodeType } from '@/app/components/workflow/types'
const useNodeCrud = <T>(id: string, data: CommonNodeType<T>) => { const useNodeCrud = <T>(id: string, data: CommonNodeType<T>) => {
const { handleNodeDataUpdate } = useWorkflow() const { handleNodeDataUpdateWithSyncDraft } = useNodeDataUpdate()
const setInputs = (newInputs: CommonNodeType<T>) => { const setInputs = (newInputs: CommonNodeType<T>) => {
handleNodeDataUpdate({ handleNodeDataUpdateWithSyncDraft({
id, id,
data: newInputs, data: newInputs,
}) })
......
import { useState } from 'react' import { useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useNodeDataUpdate } from '@/app/components/workflow/hooks'
import type { CommonNodeType, InputVar, Variable } from '@/app/components/workflow/types' import type { CommonNodeType, InputVar, Variable } from '@/app/components/workflow/types'
import { InputVarType, NodeRunningStatus } from '@/app/components/workflow/types' import { InputVarType, NodeRunningStatus } from '@/app/components/workflow/types'
import { useStore as useAppStore } from '@/app/components/app/store' import { useStore as useAppStore } from '@/app/components/app/store'
...@@ -21,7 +21,7 @@ const useOneStepRun = <T>({ id, data, defaultRunInputData, isInvalid = () => tru ...@@ -21,7 +21,7 @@ const useOneStepRun = <T>({ id, data, defaultRunInputData, isInvalid = () => tru
const [runInputData, setRunInputData] = useState<Record<string, any>>(defaultRunInputData || {}) const [runInputData, setRunInputData] = useState<Record<string, any>>(defaultRunInputData || {})
const [runResult, setRunResult] = useState<any>(null) const [runResult, setRunResult] = useState<any>(null)
const { handleNodeDataUpdate }: { handleNodeDataUpdate: (data: any) => void } = useWorkflow() const { handleNodeDataUpdate }: { handleNodeDataUpdate: (data: any) => void } = useNodeDataUpdate()
const isShowSingleRun = data._isSingleRun const isShowSingleRun = data._isSingleRun
const hideSingleRun = () => { const hideSingleRun = () => {
handleNodeDataUpdate({ handleNodeDataUpdate({
......
...@@ -18,7 +18,10 @@ import { ...@@ -18,7 +18,10 @@ import {
XClose, XClose,
} from '@/app/components/base/icons/src/vender/line/general' } from '@/app/components/base/icons/src/vender/line/general'
import BlockIcon from '@/app/components/workflow/block-icon' import BlockIcon from '@/app/components/workflow/block-icon'
import { useWorkflow } from '@/app/components/workflow/hooks' import {
useNodeDataUpdate,
useNodesInteractions,
} from '@/app/components/workflow/hooks'
import { canRunBySingle } from '@/app/components/workflow/utils' import { canRunBySingle } from '@/app/components/workflow/utils'
import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/development' import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/development'
import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices' import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
...@@ -36,18 +39,20 @@ const BasePanel: FC<BasePanelProps> = ({ ...@@ -36,18 +39,20 @@ const BasePanel: FC<BasePanelProps> = ({
children, children,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleNodeSelect } = useNodesInteractions()
const { const {
handleNodeSelect,
handleNodeDataUpdate, handleNodeDataUpdate,
} = useWorkflow() handleNodeDataUpdateWithSyncDraft,
} = useNodeDataUpdate()
const handleTitleChange = useCallback((title: string) => { const handleTitleChange = useCallback((title: string) => {
if (!title) if (!title)
return return
handleNodeDataUpdate({ id, data: { ...data, title } }) handleNodeDataUpdateWithSyncDraft({ id, data: { ...data, title } })
}, [handleNodeDataUpdate, id, data]) }, [handleNodeDataUpdateWithSyncDraft, id, data])
const handleDescriptionChange = useCallback((desc: string) => { const handleDescriptionChange = useCallback((desc: string) => {
handleNodeDataUpdate({ id, data: { ...data, desc } }) handleNodeDataUpdateWithSyncDraft({ id, data: { ...data, desc } })
}, [handleNodeDataUpdate, id, data]) }, [handleNodeDataUpdateWithSyncDraft, id, data])
return ( return (
<div className='w-[420px] h-full bg-white shadow-lg border-[0.5px] border-gray-200 rounded-2xl overflow-y-auto'> <div className='w-[420px] h-full bg-white shadow-lg border-[0.5px] border-gray-200 rounded-2xl overflow-y-auto'>
......
...@@ -3,7 +3,7 @@ import type { FC } from 'react' ...@@ -3,7 +3,7 @@ import type { FC } from 'react'
import React, { useCallback } from 'react' import React, { useCallback } from 'react'
import produce from 'immer' import produce from 'immer'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useWorkflow } from '../../../hooks' import { useEdgesInteractions } from '../../../hooks'
import AddButton from '../../_base/components/add-button' import AddButton from '../../_base/components/add-button'
import Item from './class-item' import Item from './class-item'
import type { Topic } from '@/app/components/workflow/nodes/question-classifier/types' import type { Topic } from '@/app/components/workflow/nodes/question-classifier/types'
...@@ -22,7 +22,7 @@ const ClassList: FC<Props> = ({ ...@@ -22,7 +22,7 @@ const ClassList: FC<Props> = ({
onChange, onChange,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleEdgeDeleteByDeleteBranch } = useWorkflow() const { handleEdgeDeleteByDeleteBranch } = useEdgesInteractions()
const handleClassChange = useCallback((index: number) => { const handleClassChange = useCallback((index: number) => {
return (value: Topic) => { return (value: Topic) => {
......
...@@ -10,7 +10,7 @@ import { ...@@ -10,7 +10,7 @@ import {
useReactFlow, useReactFlow,
useViewport, useViewport,
} from 'reactflow' } from 'reactflow'
import { useWorkflow } from '../hooks' import { useNodesSyncDraft } from '../hooks'
import { useStore } from '../store' import { useStore } from '../store'
import { import {
PortalToFollowElem, PortalToFollowElem,
...@@ -29,7 +29,7 @@ const ZoomInOut: FC = () => { ...@@ -29,7 +29,7 @@ const ZoomInOut: FC = () => {
fitView, fitView,
} = useReactFlow() } = useReactFlow()
const { zoom } = useViewport() const { zoom } = useViewport()
const { handleSyncWorkflowDraft } = useWorkflow() const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const runningStatus = useStore(s => s.runningStatus) const runningStatus = useStore(s => s.runningStatus)
......
...@@ -17,7 +17,7 @@ export const useChat = ( ...@@ -17,7 +17,7 @@ export const useChat = (
) => { ) => {
const { t } = useTranslation() const { t } = useTranslation()
const { notify } = useToastContext() const { notify } = useToastContext()
const run = useWorkflowRun() const { handleRun } = useWorkflowRun()
const hasStopResponded = useRef(false) const hasStopResponded = useRef(false)
const connversationId = useRef('') const connversationId = useRef('')
const taskIdRef = useRef('') const taskIdRef = useRef('')
...@@ -126,7 +126,7 @@ export const useChat = ( ...@@ -126,7 +126,7 @@ export const useChat = (
let hasSetResponseId = false let hasSetResponseId = false
run( handleRun(
params, params,
{ {
onData: (message: string, isFirstMessage: boolean, { conversationId: newConversationId, messageId, taskId }: any) => { onData: (message: string, isFirstMessage: boolean, { conversationId: newConversationId, messageId, taskId }: any) => {
...@@ -179,7 +179,7 @@ export const useChat = ( ...@@ -179,7 +179,7 @@ export const useChat = (
}, },
}, },
) )
}, [run, handleResponding, handleUpdateChatList, notify, t, updateCurrentQA]) }, [handleRun, handleResponding, handleUpdateChatList, notify, t, updateCurrentQA])
return { return {
conversationId: connversationId.current, conversationId: connversationId.current,
......
...@@ -7,10 +7,7 @@ import { useNodes } from 'reactflow' ...@@ -7,10 +7,7 @@ import { useNodes } from 'reactflow'
import FormItem from '../nodes/_base/components/before-run-form/form-item' import FormItem from '../nodes/_base/components/before-run-form/form-item'
import { BlockEnum } from '../types' import { BlockEnum } from '../types'
import { useStore } from '../store' import { useStore } from '../store'
import { import { useWorkflowRun } from '../hooks'
useWorkflow,
useWorkflowRun,
} from '../hooks'
import type { StartNodeType } from '../nodes/start/types' import type { StartNodeType } from '../nodes/start/types'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
...@@ -18,8 +15,10 @@ const InputsPanel = () => { ...@@ -18,8 +15,10 @@ const InputsPanel = () => {
const { t } = useTranslation() const { t } = useTranslation()
const nodes = useNodes<StartNodeType>() const nodes = useNodes<StartNodeType>()
const inputs = useStore(s => s.inputs) const inputs = useStore(s => s.inputs)
const run = useWorkflowRun() const {
const { handleRunInit } = useWorkflow() handleRun,
handleRunSetting,
} = useWorkflowRun()
const startNode = nodes.find(node => node.data.type === BlockEnum.Start) const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
const variables = startNode?.data.variables || [] const variables = startNode?.data.variables || []
...@@ -34,10 +33,10 @@ const InputsPanel = () => { ...@@ -34,10 +33,10 @@ const InputsPanel = () => {
useStore.setState({ showInputsPanel: false }) useStore.setState({ showInputsPanel: false })
}, []) }, [])
const handleRun = () => { const doRun = () => {
handleCancel() handleCancel()
handleRunInit() handleRunSetting()
run({ inputs }) handleRun({ inputs })
} }
return ( return (
...@@ -72,7 +71,7 @@ const InputsPanel = () => { ...@@ -72,7 +71,7 @@ const InputsPanel = () => {
<Button <Button
type='primary' type='primary'
className='py-0 w-[190px] h-8 rounded-lg text-[13px] font-medium' className='py-0 w-[190px] h-8 rounded-lg text-[13px] font-medium'
onClick={handleRun} onClick={doRun}
> >
{t('workflow.singleRun.startRun')} {t('workflow.singleRun.startRun')}
</Button> </Button>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment