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