Commit 84e2071a authored by StyleZhang's avatar StyleZhang

run

parent b3b9e1da
...@@ -14,15 +14,13 @@ import { Grid01 } from '@/app/components/base/icons/src/vender/line/layout' ...@@ -14,15 +14,13 @@ import { Grid01 } from '@/app/components/base/icons/src/vender/line/layout'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import { ArrowNarrowLeft } from '@/app/components/base/icons/src/vender/line/arrows' import { ArrowNarrowLeft } from '@/app/components/base/icons/src/vender/line/arrows'
import { useStore as useAppStore } from '@/app/components/app/store' import { useStore as useAppStore } from '@/app/components/app/store'
import { Mode } from '@/app/components/workflow/types'
const Header: FC = () => { const Header: FC = () => {
const { t } = useTranslation() const { t } = useTranslation()
const appDetail = useAppStore(s => s.appDetail) const appDetail = useAppStore(s => s.appDetail)
const appSidebarExpand = useAppStore(s => s.appSidebarExpand) const appSidebarExpand = useAppStore(s => s.appSidebarExpand)
const isChatMode = useIsChatMode() const isChatMode = useIsChatMode()
const mode = useStore(state => state.mode) const runningStatus = useStore(s => s.runningStatus)
const runTaskId = useStore(state => state.runTaskId)
const handleShowFeatures = useCallback(() => { const handleShowFeatures = useCallback(() => {
useStore.setState({ showFeaturesPanel: true }) useStore.setState({ showFeaturesPanel: true })
...@@ -37,26 +35,26 @@ const Header: FC = () => { ...@@ -37,26 +35,26 @@ const Header: FC = () => {
> >
<div> <div>
{ {
appSidebarExpand && ( appSidebarExpand === 'collapse' && (
<div className='text-xs font-medium text-gray-700'>{appDetail?.name}</div> <div className='text-xs font-medium text-gray-700'>{appDetail?.name}</div>
) )
} }
{ {
mode === Mode.Editing && !runTaskId && <EditingTitle /> !runningStatus && <EditingTitle />
} }
{ {
(mode === Mode.Running || runTaskId) && <RunningTitle /> runningStatus && <RunningTitle />
} }
</div> </div>
<div className='flex items-center'> <div className='flex items-center'>
{ {
(mode === Mode.Running || runTaskId) && ( runningStatus && (
<Button <Button
className={` className={`
mr-2 px-3 py-0 h-8 bg-white text-[13px] font-medium text-primary-600 mr-2 px-3 py-0 h-8 bg-white text-[13px] font-medium text-primary-600
border-[0.5px] border-gray-200 shadow-xs border-[0.5px] border-gray-200 shadow-xs
`} `}
onClick={() => useStore.setState({ mode: Mode.Editing, runTaskId: '' })} onClick={() => useStore.setState({ runningStatus: undefined })}
> >
<ArrowNarrowLeft className='mr-1 w-4 h-4' /> <ArrowNarrowLeft className='mr-1 w-4 h-4' />
{t('workflow.common.goBackToEdit')} {t('workflow.common.goBackToEdit')}
......
...@@ -3,61 +3,102 @@ import { memo } from 'react' ...@@ -3,61 +3,102 @@ import { memo } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useStore } from '../store' import { useStore } from '../store'
import { useIsChatMode } from '../hooks' import { useIsChatMode } from '../hooks'
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'
import { ClockPlay } from '@/app/components/base/icons/src/vender/line/time' import { ClockPlay } from '@/app/components/base/icons/src/vender/line/time'
import TooltipPlus from '@/app/components/base/tooltip-plus' import TooltipPlus from '@/app/components/base/tooltip-plus'
import { Loading02 } from '@/app/components/base/icons/src/vender/line/general' import { Loading02 } from '@/app/components/base/icons/src/vender/line/general'
const RunAndHistory: FC = () => { const RunMode = memo(() => {
const { t } = useTranslation() const { t } = useTranslation()
const isChatMode = useIsChatMode() const runningStatus = useStore(s => s.runningStatus)
const mode = useStore(state => state.mode) const showInputsPanel = useStore(s => s.showInputsPanel)
const showRunHistory = useStore(state => state.showRunHistory) const isRunning = runningStatus === WorkflowRunningStatus.Running
const handleClick = () => {
useStore.setState({ showInputsPanel: true })
}
return (
<div
className={`
flex items-center px-1.5 h-7 rounded-md text-[13px] font-medium text-primary-600
hover:bg-primary-50 cursor-pointer
${showInputsPanel && 'bg-primary-50'}
${isRunning && 'bg-primary-50 !cursor-not-allowed'}
`}
onClick={() => !isRunning && handleClick()}
>
{
isRunning
? (
<>
<Loading02 className='mr-1 w-4 h-4 animate-spin' />
{t('workflow.common.running')}
</>
)
: (
<>
<Play className='mr-1 w-4 h-4' />
{t('workflow.common.run')}
</>
)
}
</div>
)
})
RunMode.displayName = 'RunMode'
const PreviewMode = memo(() => {
const { t } = useTranslation()
const runningStatus = useStore(s => s.runningStatus)
const isRunning = runningStatus === WorkflowRunningStatus.Running
const handleClick = () => { const handleClick = () => {
if (!isChatMode) useStore.setState({ runningStatus: WorkflowRunningStatus.Succeeded })
useStore.setState({ showInputsPanel: true })
} }
return (
<div
className={`
flex items-center px-1.5 h-7 rounded-md text-[13px] font-medium text-primary-600
hover:bg-primary-50 cursor-pointer
${isRunning && 'bg-primary-50 opacity-50 !cursor-not-allowed'}
`}
onClick={() => !isRunning && handleClick()}
>
{
isRunning
? (
<>
{t('workflow.common.inPreview')}
</>
)
: (
<>
<Play className='mr-1 w-4 h-4' />
{t('workflow.common.preview')}
</>
)
}
</div>
)
})
PreviewMode.displayName = 'PreviewMode'
const RunAndHistory: FC = () => {
const { t } = useTranslation()
const isChatMode = useIsChatMode()
const showRunHistory = useStore(state => state.showRunHistory)
return ( return (
<div className='flex items-center px-0.5 h-8 rounded-lg border-[0.5px] border-gray-200 bg-white shadow-xs'> <div className='flex items-center px-0.5 h-8 rounded-lg border-[0.5px] border-gray-200 bg-white shadow-xs'>
<div {
className={` !isChatMode && <RunMode />
flex items-center px-1.5 h-7 rounded-md text-[13px] font-medium text-primary-600 }
hover:bg-primary-50 cursor-pointer {
${mode === 'running' && 'bg-primary-50 !cursor-not-allowed'} isChatMode && <PreviewMode />
${mode === 'running' && isChatMode && 'opacity-50'} }
`}
onClick={() => mode !== 'running' && handleClick()}
>
{
mode === 'running'
? (
<>
{
!isChatMode && (
<Loading02 className='mr-1 w-4 h-4 animate-spin' />
)
}
{
!isChatMode
? t('workflow.common.running')
: t('workflow.common.inPreview')
}
</>
)
: (
<>
<Play className='mr-1 w-4 h-4' />
{
!isChatMode
? t('workflow.common.run')
: t('workflow.common.preview')
}
</>
)
}
</div>
<div className='mx-0.5 w-[0.5px] h-8 bg-gray-200'></div> <div className='mx-0.5 w-[0.5px] h-8 bg-gray-200'></div>
<TooltipPlus <TooltipPlus
popupContent={t('workflow.common.viewRunHistory')} popupContent={t('workflow.common.viewRunHistory')}
......
...@@ -135,10 +135,21 @@ export const useWorkflow = () => { ...@@ -135,10 +135,21 @@ export const useWorkflow = () => {
}, [reactFlow]) }, [reactFlow])
const handleNodeDragStart = useCallback<NodeDragHandler>(() => { const handleNodeDragStart = useCallback<NodeDragHandler>(() => {
useStore.getState().setIsDragging(true) const {
runningStatus,
setIsDragging,
} = useStore.getState()
if (!runningStatus)
setIsDragging(true)
}, []) }, [])
const handleNodeDrag = useCallback<NodeDragHandler>((e, node: Node) => { const handleNodeDrag = useCallback<NodeDragHandler>((e, node: Node) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -240,10 +251,15 @@ export const useWorkflow = () => { ...@@ -240,10 +251,15 @@ export const useWorkflow = () => {
const handleNodeDragStop = useCallback<NodeDragHandler>(() => { const handleNodeDragStop = useCallback<NodeDragHandler>(() => {
const { const {
runningStatus,
setIsDragging, setIsDragging,
setHelpLineHorizontal, setHelpLineHorizontal,
setHelpLineVertical, setHelpLineVertical,
} = useStore.getState() } = useStore.getState()
if (runningStatus)
return
setIsDragging(false) setIsDragging(false)
setHelpLineHorizontal() setHelpLineHorizontal()
setHelpLineVertical() setHelpLineVertical()
...@@ -251,6 +267,11 @@ export const useWorkflow = () => { ...@@ -251,6 +267,11 @@ export const useWorkflow = () => {
}, [handleSyncWorkflowDraft]) }, [handleSyncWorkflowDraft])
const handleNodeEnter = useCallback<NodeMouseHandler>((_, node) => { const handleNodeEnter = useCallback<NodeMouseHandler>((_, node) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -268,6 +289,11 @@ export const useWorkflow = () => { ...@@ -268,6 +289,11 @@ export const useWorkflow = () => {
}, [store]) }, [store])
const handleNodeLeave = useCallback<NodeMouseHandler>(() => { const handleNodeLeave = useCallback<NodeMouseHandler>(() => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -281,6 +307,11 @@ export const useWorkflow = () => { ...@@ -281,6 +307,11 @@ export const useWorkflow = () => {
}, [store]) }, [store])
const handleNodeSelect = useCallback((nodeId: string, cancelSelection?: boolean) => { const handleNodeSelect = useCallback((nodeId: string, cancelSelection?: boolean) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -304,7 +335,12 @@ export const useWorkflow = () => { ...@@ -304,7 +335,12 @@ export const useWorkflow = () => {
}, [store, handleSyncWorkflowDraft]) }, [store, handleSyncWorkflowDraft])
const handleNodeClick = useCallback<NodeMouseHandler>((_, node) => { const handleNodeClick = useCallback<NodeMouseHandler>((_, node) => {
if (useStore.getState().isDragging) const {
runningStatus,
isDragging,
} = useStore.getState()
if (runningStatus || isDragging)
return return
handleNodeSelect(node.id) handleNodeSelect(node.id)
...@@ -316,6 +352,11 @@ export const useWorkflow = () => { ...@@ -316,6 +352,11 @@ export const useWorkflow = () => {
target, target,
targetHandle, targetHandle,
}) => { }) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -340,6 +381,11 @@ export const useWorkflow = () => { ...@@ -340,6 +381,11 @@ export const useWorkflow = () => {
}, [store, handleSyncWorkflowDraft]) }, [store, handleSyncWorkflowDraft])
const handleNodeDelete = useCallback((nodeId: string) => { const handleNodeDelete = useCallback((nodeId: string) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -363,6 +409,11 @@ export const useWorkflow = () => { ...@@ -363,6 +409,11 @@ export const useWorkflow = () => {
}, [store, handleSyncWorkflowDraft]) }, [store, handleSyncWorkflowDraft])
const handleNodeDataUpdate = useCallback(({ id, data }: { id: string; data: Record<string, any> }) => { const handleNodeDataUpdate = useCallback(({ id, data }: { id: string; data: Record<string, any> }) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -382,6 +433,11 @@ export const useWorkflow = () => { ...@@ -382,6 +433,11 @@ export const useWorkflow = () => {
sourceHandle: string, sourceHandle: string,
toolDefaultValue?: ToolDefaultValue, toolDefaultValue?: ToolDefaultValue,
) => { ) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -432,6 +488,11 @@ export const useWorkflow = () => { ...@@ -432,6 +488,11 @@ export const useWorkflow = () => {
sourceHandle: string, sourceHandle: string,
toolDefaultValue?: ToolDefaultValue, toolDefaultValue?: ToolDefaultValue,
) => { ) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -486,6 +547,11 @@ export const useWorkflow = () => { ...@@ -486,6 +547,11 @@ export const useWorkflow = () => {
}, [store, nodesInitialData, handleSyncWorkflowDraft]) }, [store, nodesInitialData, handleSyncWorkflowDraft])
const handleEdgeEnter = useCallback<EdgeMouseHandler>((_, edge) => { const handleEdgeEnter = useCallback<EdgeMouseHandler>((_, edge) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -499,6 +565,11 @@ export const useWorkflow = () => { ...@@ -499,6 +565,11 @@ export const useWorkflow = () => {
}, [store]) }, [store])
const handleEdgeLeave = useCallback<EdgeMouseHandler>((_, edge) => { const handleEdgeLeave = useCallback<EdgeMouseHandler>((_, edge) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -512,6 +583,11 @@ export const useWorkflow = () => { ...@@ -512,6 +583,11 @@ export const useWorkflow = () => {
}, [store]) }, [store])
const handleEdgeDelete = useCallback(() => { const handleEdgeDelete = useCallback(() => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -527,6 +603,11 @@ export const useWorkflow = () => { ...@@ -527,6 +603,11 @@ export const useWorkflow = () => {
}, [store, handleSyncWorkflowDraft]) }, [store, handleSyncWorkflowDraft])
const handleEdgesChange = useCallback<OnEdgesChange>((changes) => { const handleEdgesChange = useCallback<OnEdgesChange>((changes) => {
const { runningStatus } = useStore.getState()
if (runningStatus)
return
const { const {
edges, edges,
setEdges, setEdges,
...@@ -585,10 +666,14 @@ export const useWorkflowRun = () => { ...@@ -585,10 +666,14 @@ export const useWorkflowRun = () => {
ssePost( ssePost(
url, url,
params,
{ {
onWorkflowStarted: () => { body: params,
},
{
onWorkflowStarted: ({ task_id, workflow_run_id }) => {
useStore.setState({ runningStatus: WorkflowRunningStatus.Running }) useStore.setState({ runningStatus: WorkflowRunningStatus.Running })
useStore.setState({ taskId: task_id })
useStore.setState({ workflowRunId: workflow_run_id })
}, },
onWorkflowFinished: ({ data }) => { onWorkflowFinished: ({ data }) => {
useStore.setState({ runningStatus: data.status as WorkflowRunningStatus }) useStore.setState({ runningStatus: data.status as WorkflowRunningStatus })
...@@ -597,7 +682,7 @@ export const useWorkflowRun = () => { ...@@ -597,7 +682,7 @@ export const useWorkflowRun = () => {
const newNodes = produce(getNodes(), (draft) => { const newNodes = produce(getNodes(), (draft) => {
const currentNode = draft.find(node => node.id === data.node_id)! const currentNode = draft.find(node => node.id === data.node_id)!
currentNode.data._running = NodeRunningStatus.Running currentNode.data._runningStatus = NodeRunningStatus.Running
}) })
setNodes(newNodes) setNodes(newNodes)
}, },
...@@ -605,7 +690,7 @@ export const useWorkflowRun = () => { ...@@ -605,7 +690,7 @@ export const useWorkflowRun = () => {
const newNodes = produce(getNodes(), (draft) => { const newNodes = produce(getNodes(), (draft) => {
const currentNode = draft.find(node => node.id === data.node_id)! const currentNode = draft.find(node => node.id === data.node_id)!
currentNode.data._running = data.status currentNode.data._runningStatus = data.status
}) })
setNodes(newNodes) setNodes(newNodes)
}, },
......
...@@ -31,6 +31,10 @@ import Panel from './panel' ...@@ -31,6 +31,10 @@ import Panel from './panel'
import Features from './features' import Features from './features'
import HelpLine from './help-line' import HelpLine from './help-line'
import { useStore } from './store' import { useStore } from './store'
import {
initialEdges,
initialNodes,
} from './utils'
import { import {
fetchWorkflowDraft, fetchWorkflowDraft,
syncWorkflowDraft, syncWorkflowDraft,
...@@ -130,7 +134,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({ ...@@ -130,7 +134,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({
edges, edges,
}) => { }) => {
const appDetail = useAppStore(state => state.appDetail) const appDetail = useAppStore(state => state.appDetail)
const { data, isLoading, error } = useSWR(appDetail?.id ? `/apps/${appDetail.id}/workflows/draft` : null, fetchWorkflowDraft) const { data, isLoading, error, mutate } = useSWR(appDetail?.id ? `/apps/${appDetail.id}/workflows/draft` : null, fetchWorkflowDraft)
const nodesInitialData = useNodesInitialData() const nodesInitialData = useNodesInitialData()
useEffect(() => { useEffect(() => {
...@@ -145,7 +149,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({ ...@@ -145,7 +149,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({
data: nodesInitialData.start, data: nodesInitialData.start,
position: { position: {
x: 100, x: 100,
y: 100, y: 200,
}, },
} }
}, [nodesInitialData]) }, [nodesInitialData])
...@@ -155,7 +159,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({ ...@@ -155,7 +159,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({
return nodes return nodes
if (data) if (data)
return data.graph.nodes return initialNodes(data.graph.nodes)
return [startNode] return [startNode]
}, [data, nodes, startNode]) }, [data, nodes, startNode])
...@@ -164,7 +168,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({ ...@@ -164,7 +168,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({
return edges return edges
if (data) if (data)
return data.graph.edges return initialEdges(data.graph.edges)
return [] return []
}, [data, edges]) }, [data, edges])
...@@ -199,6 +203,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({ ...@@ -199,6 +203,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({
}, },
}).then((res) => { }).then((res) => {
useStore.setState({ draftUpdatedAt: res.updated_at }) useStore.setState({ draftUpdatedAt: res.updated_at })
mutate()
}) })
} }
}) })
......
...@@ -44,13 +44,13 @@ const BaseNode: FC<BaseNodeProps> = ({ ...@@ -44,13 +44,13 @@ const BaseNode: FC<BaseNodeProps> = ({
group relative w-[240px] bg-[#fcfdff] shadow-xs group relative w-[240px] bg-[#fcfdff] shadow-xs
border border-transparent rounded-[15px] border border-transparent rounded-[15px]
hover:shadow-lg hover:shadow-lg
${data._runningStatus === NodeRunningStatus.Running && 'border-primary-500'} ${data._runningStatus === NodeRunningStatus.Running && '!border-primary-500'}
${data._runningStatus === NodeRunningStatus.Succeeded && 'border-[#12B76A]'} ${data._runningStatus === NodeRunningStatus.Succeeded && '!border-[#12B76A]'}
${data._runningStatus === NodeRunningStatus.Failed && 'border-[#F04438]'} ${data._runningStatus === NodeRunningStatus.Failed && '!border-[#F04438]'}
`} `}
> >
{ {
data.type !== BlockEnum.VariableAssigner && ( data.type !== BlockEnum.VariableAssigner && !data._runningStatus && (
<NodeTargetHandle <NodeTargetHandle
id={id} id={id}
data={data} data={data}
...@@ -60,7 +60,7 @@ const BaseNode: FC<BaseNodeProps> = ({ ...@@ -60,7 +60,7 @@ const BaseNode: FC<BaseNodeProps> = ({
) )
} }
{ {
data.type !== BlockEnum.IfElse && data.type !== BlockEnum.QuestionClassifier && ( data.type !== BlockEnum.IfElse && data.type !== BlockEnum.QuestionClassifier && !data._runningStatus && (
<NodeSourceHandle <NodeSourceHandle
id={id} id={id}
data={data} data={data}
...@@ -69,10 +69,14 @@ const BaseNode: FC<BaseNodeProps> = ({ ...@@ -69,10 +69,14 @@ const BaseNode: FC<BaseNodeProps> = ({
/> />
) )
} }
<NodeControl {
id={id} !data._runningStatus && (
data={data} <NodeControl
/> id={id}
data={data}
/>
)
}
<div className='flex items-center px-3 pt-3 pb-2'> <div className='flex items-center px-3 pt-3 pb-2'>
<BlockIcon <BlockIcon
className='shrink-0 mr-2' className='shrink-0 mr-2'
......
...@@ -17,7 +17,7 @@ const Operator = () => { ...@@ -17,7 +17,7 @@ const Operator = () => {
width: 128, width: 128,
height: 80, height: 80,
}} }}
className='!static !m-0 !w-[128px] !h-[80px] border-[0.5px] border-black/[0.08]' className='!static !m-0 !w-[128px] !h-[80px] !border-[0.5px] !border-black/[0.08] !rounded-lg !shadow-lg'
pannable pannable
/> />
<div className='flex items-center mt-1 p-0.5 rounded-lg border-[0.5px] border-gray-100 bg-white shadow-lg text-gray-500'> <div className='flex items-center mt-1 p-0.5 rounded-lg border-[0.5px] border-gray-100 bg-white shadow-lg text-gray-500'>
......
...@@ -15,9 +15,10 @@ import Record from './record' ...@@ -15,9 +15,10 @@ import Record from './record'
import InputsPanel from './inputs-panel' import InputsPanel from './inputs-panel'
const Panel: FC = () => { const Panel: FC = () => {
const isChatMode = useIsChatMode()
const runTaskId = useStore(state => state.runTaskId)
const nodes = useNodes<CommonNodeType>() const nodes = useNodes<CommonNodeType>()
const isChatMode = useIsChatMode()
const runningStatus = useStore(s => s.runningStatus)
const workflowRunId = useStore(s => s.workflowRunId)
const selectedNode = nodes.find(node => node.data.selected) const selectedNode = nodes.find(node => node.data.selected)
const showRunHistory = useStore(state => state.showRunHistory) const showRunHistory = useStore(state => state.showRunHistory)
const showInputsPanel = useStore(s => s.showInputsPanel) const showInputsPanel = useStore(s => s.showInputsPanel)
...@@ -27,11 +28,11 @@ const Panel: FC = () => { ...@@ -27,11 +28,11 @@ const Panel: FC = () => {
showDebugAndPreviewPanel, showDebugAndPreviewPanel,
} = useMemo(() => { } = useMemo(() => {
return { return {
showWorkflowInfoPanel: !isChatMode && !selectedNode && !runTaskId, showWorkflowInfoPanel: !isChatMode && !selectedNode && !runningStatus,
showNodePanel: !!selectedNode && !runTaskId, showNodePanel: !!selectedNode && !runningStatus,
showDebugAndPreviewPanel: isChatMode && !selectedNode && !runTaskId, showDebugAndPreviewPanel: isChatMode && !selectedNode && !runningStatus,
} }
}, [selectedNode, isChatMode, runTaskId]) }, [selectedNode, isChatMode, runningStatus])
return ( return (
<div className='absolute top-14 right-0 bottom-2 flex z-10'> <div className='absolute top-14 right-0 bottom-2 flex z-10'>
...@@ -41,7 +42,7 @@ const Panel: FC = () => { ...@@ -41,7 +42,7 @@ const Panel: FC = () => {
) )
} }
{ {
runTaskId && ( runningStatus && !isChatMode && workflowRunId && (
<Record /> <Record />
) )
} }
......
import { import {
memo, memo,
useCallback, useCallback,
useState,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useNodes } from 'reactflow' import { useNodes } from 'reactflow'
...@@ -15,13 +14,13 @@ import Button from '@/app/components/base/button' ...@@ -15,13 +14,13 @@ import Button from '@/app/components/base/button'
const InputsPanel = () => { const InputsPanel = () => {
const { t } = useTranslation() const { t } = useTranslation()
const nodes = useNodes<StartNodeType>() const nodes = useNodes<StartNodeType>()
const inputs = useStore(s => s.inputs)
const run = useWorkflowRun() const run = useWorkflowRun()
const [inputs, setInputs] = useState<Record<string, string>>({})
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 || []
const handleValueChange = (variable: string, v: string) => { const handleValueChange = (variable: string, v: string) => {
setInputs({ useStore.getState().setInputs({
...inputs, ...inputs,
[variable]: v, [variable]: v,
}) })
...@@ -32,7 +31,8 @@ const InputsPanel = () => { ...@@ -32,7 +31,8 @@ const InputsPanel = () => {
}, []) }, [])
const handleRun = () => { const handleRun = () => {
run(inputs) handleCancel()
run({ inputs })
} }
return ( return (
......
...@@ -4,19 +4,19 @@ import { useStore } from '../store' ...@@ -4,19 +4,19 @@ import { useStore } from '../store'
import { XClose } from '@/app/components/base/icons/src/vender/line/general' import { XClose } from '@/app/components/base/icons/src/vender/line/general'
const Record = () => { const Record = () => {
const { runTaskId, setRunTaskId } = useStore() const { workflowRunId, setWorkflowRunId } = useStore()
return ( return (
<div className='flex flex-col w-[400px] h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white'> <div className='flex flex-col w-[400px] h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white'>
<div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'> <div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'>
Test Run#5 Test Run#5
<div <div
className='flex items-center justify-center w-6 h-6 cursor-pointer' className='flex items-center justify-center w-6 h-6 cursor-pointer'
onClick={() => setRunTaskId('')} onClick={() => setWorkflowRunId('')}
> >
<XClose className='w-4 h-4 text-gray-500' /> <XClose className='w-4 h-4 text-gray-500' />
</div> </div>
</div> </div>
<Run runID={runTaskId} /> <Run runID={workflowRunId} />
</div> </div>
) )
} }
......
...@@ -13,7 +13,8 @@ import type { WorkflowRunningStatus } from './types' ...@@ -13,7 +13,8 @@ import type { WorkflowRunningStatus } from './types'
type State = { type State = {
mode: Mode mode: Mode
runTaskId: string taskId: string
workflowRunId: string
showRunHistory: boolean showRunHistory: boolean
showFeaturesPanel: boolean showFeaturesPanel: boolean
isDragging: boolean isDragging: boolean
...@@ -25,11 +26,13 @@ type State = { ...@@ -25,11 +26,13 @@ type State = {
publishedAt: number publishedAt: number
runningStatus?: WorkflowRunningStatus runningStatus?: WorkflowRunningStatus
showInputsPanel: boolean showInputsPanel: boolean
inputs: Record<string, string>
} }
type Action = { type Action = {
setMode: (mode: Mode) => void setMode: (mode: Mode) => void
setRunTaskId: (runTaskId: string) => void setTaskId: (taskId: string) => void
setWorkflowRunId: (workflowRunId: string) => void
setShowRunHistory: (showRunHistory: boolean) => void setShowRunHistory: (showRunHistory: boolean) => void
setShowFeaturesPanel: (showFeaturesPanel: boolean) => void setShowFeaturesPanel: (showFeaturesPanel: boolean) => void
setIsDragging: (isDragging: boolean) => void setIsDragging: (isDragging: boolean) => void
...@@ -41,12 +44,15 @@ type Action = { ...@@ -41,12 +44,15 @@ type Action = {
setPublishedAt: (publishedAt: number) => void setPublishedAt: (publishedAt: number) => void
setRunningStatus: (runningStatus?: WorkflowRunningStatus) => void setRunningStatus: (runningStatus?: WorkflowRunningStatus) => void
setShowInputsPanel: (showInputsPanel: boolean) => void setShowInputsPanel: (showInputsPanel: boolean) => void
setInputs: (inputs: Record<string, string>) => void
} }
export const useStore = create<State & Action>(set => ({ export const useStore = create<State & Action>(set => ({
mode: Mode.Editing, mode: Mode.Editing,
runTaskId: '', taskId: '',
setRunTaskId: runTaskId => set(() => ({ runTaskId })), setTaskId: taskId => set(() => ({ taskId })),
workflowRunId: '',
setWorkflowRunId: workflowRunId => set(() => ({ workflowRunId })),
setMode: mode => set(() => ({ mode })), setMode: mode => set(() => ({ mode })),
showRunHistory: false, showRunHistory: false,
setShowRunHistory: showRunHistory => set(() => ({ showRunHistory })), setShowRunHistory: showRunHistory => set(() => ({ showRunHistory })),
...@@ -70,4 +76,6 @@ export const useStore = create<State & Action>(set => ({ ...@@ -70,4 +76,6 @@ export const useStore = create<State & Action>(set => ({
setRunningStatus: runningStatus => set(() => ({ runningStatus })), setRunningStatus: runningStatus => set(() => ({ runningStatus })),
showInputsPanel: false, showInputsPanel: false,
setShowInputsPanel: showInputsPanel => set(() => ({ showInputsPanel })), setShowInputsPanel: showInputsPanel => set(() => ({ showInputsPanel })),
inputs: {},
setInputs: inputs => set(() => ({ inputs })),
})) }))
...@@ -9,6 +9,7 @@ import type { ...@@ -9,6 +9,7 @@ import type {
Node, Node,
} from './types' } from './types'
import { BlockEnum } from './types' import { BlockEnum } from './types'
import type { QuestionClassifierNodeType } from './nodes/question-classifier/types'
export const nodesLevelOrderTraverse = ( export const nodesLevelOrderTraverse = (
firstNode: Node, firstNode: Node,
...@@ -80,19 +81,43 @@ export const nodesLevelOrderTraverse = ( ...@@ -80,19 +81,43 @@ export const nodesLevelOrderTraverse = (
} }
} }
export const initialNodesAndEdges = (nodes: Node[], edges: Edge[]) => { export const initialNodes = (nodes: Node[]) => {
const newNodes = produce(nodes, (draft) => { const newNodes = produce(nodes, (draft) => {
draft.forEach((node) => { draft.forEach((node) => {
node.type = 'custom' node.type = 'custom'
if (node.data.type === BlockEnum.IfElse) {
node.data._targetBranches = [
{
id: 'true',
name: 'IS TRUE',
},
{
id: 'false',
name: 'IS FALSE',
},
]
}
if (node.data.type === BlockEnum.QuestionClassifier) {
node.data._targetBranches = (node.data as QuestionClassifierNodeType).classes.map((topic) => {
return topic
})
}
}) })
}) })
return newNodes
}
export const initialEdges = (edges: Edge[]) => {
const newEdges = produce(edges, (draft) => { const newEdges = produce(edges, (draft) => {
draft.forEach((edge) => { draft.forEach((edge) => {
edge.type = 'custom' edge.type = 'custom'
}) })
}) })
return [newNodes, newEdges] return newEdges
} }
export type PositionMap = { export type PositionMap = {
......
...@@ -421,7 +421,27 @@ export const upload = (options: any, isPublicAPI?: boolean, url?: string, search ...@@ -421,7 +421,27 @@ export const upload = (options: any, isPublicAPI?: boolean, url?: string, search
}) })
} }
export const ssePost = (url: string, fetchOptions: FetchOptionType, { isPublicAPI = false, onData, onCompleted, onThought, onFile, onMessageEnd, onMessageReplace, onError, getAbortController }: IOtherOptions) => { export const ssePost = (
url: string,
fetchOptions: FetchOptionType,
{
isPublicAPI = false,
onData,
onCompleted,
onThought,
onFile,
onMessageEnd,
onMessageReplace,
onWorkflowStarted,
onWorkflowFinished,
onNodeStarted,
onNodeFinished,
onTextChunk,
onTextReplace,
onError,
getAbortController,
}: IOtherOptions,
) => {
const abortController = new AbortController() const abortController = new AbortController()
const options = Object.assign({}, baseOptions, { const options = Object.assign({}, baseOptions, {
...@@ -459,7 +479,7 @@ export const ssePost = (url: string, fetchOptions: FetchOptionType, { isPublicAP ...@@ -459,7 +479,7 @@ export const ssePost = (url: string, fetchOptions: FetchOptionType, { isPublicAP
return return
} }
onData?.(str, isFirstMessage, moreInfo) onData?.(str, isFirstMessage, moreInfo)
}, onCompleted, onThought, onMessageEnd, onMessageReplace, onFile) }, onCompleted, onThought, onMessageEnd, onMessageReplace, onFile, onWorkflowStarted, onWorkflowFinished, onNodeStarted, onNodeFinished, onTextChunk, onTextReplace)
}).catch((e) => { }).catch((e) => {
if (e.toString() !== 'AbortError: The user aborted a request.') if (e.toString() !== 'AbortError: The user aborted a request.')
Toast.notify({ type: 'error', message: e }) Toast.notify({ type: 'error', message: e })
......
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