run history

This commit is contained in:
StyleZhang 2024-03-20 20:27:33 +08:00
parent 17f572f23f
commit 94ca0edb68
7 changed files with 129 additions and 29 deletions

View File

@ -30,6 +30,7 @@ const Header: FC = () => {
const appSidebarExpand = useAppStore(s => s.appSidebarExpand)
const {
nodesReadOnly,
getNodesReadOnly,
} = useNodesReadOnly()
const isRestoring = useStore(s => s.isRestoring)
const {
@ -39,8 +40,15 @@ const Header: FC = () => {
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const handleShowFeatures = useCallback(() => {
workflowStore.setState({ showFeaturesPanel: true })
}, [workflowStore])
const {
isRestoring,
setShowFeaturesPanel,
} = workflowStore.getState()
if (getNodesReadOnly() && !isRestoring)
return
setShowFeaturesPanel(true)
}, [workflowStore, getNodesReadOnly])
const handleGoBackToEdit = useCallback(() => {
handleRunSetting(true)
@ -102,6 +110,7 @@ const Header: FC = () => {
className={`
mr-2 px-3 py-0 h-8 bg-white text-[13px] font-medium text-gray-700
border-[0.5px] border-gray-200 shadow-xs
${nodesReadOnly && !isRestoring && 'opacity-50 !cursor-not-allowed'}
`}
onClick={handleShowFeatures}
>

View File

@ -1,6 +1,7 @@
import type { FC } from 'react'
import { memo } from 'react'
import { memo, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { useStoreApi } from 'reactflow'
import {
useStore,
useWorkflowStore,
@ -11,7 +12,10 @@ import {
useNodesSyncDraft,
useWorkflowRun,
} from '../hooks'
import { WorkflowRunningStatus } from '../types'
import {
BlockEnum,
WorkflowRunningStatus,
} from '../types'
import {
Play,
StopCircle,
@ -20,20 +24,59 @@ 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'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
const RunMode = memo(() => {
const { t } = useTranslation()
const store = useStoreApi()
const workflowStore = useWorkflowStore()
const { handleStopRun } = useWorkflowRun()
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
const featuresStore = useFeaturesStore()
const {
handleStopRun,
handleRunSetting,
handleRun,
} = useWorkflowRun()
const {
doSyncWorkflowDraft,
handleSyncWorkflowDraft,
} = useNodesSyncDraft()
const workflowRunningData = useStore(s => s.workflowRunningData)
const showInputsPanel = useStore(s => s.showInputsPanel)
const isRunning = workflowRunningData?.result.status === WorkflowRunningStatus.Running
const handleClick = () => {
workflowStore.setState({ showInputsPanel: true })
handleSyncWorkflowDraft(true)
}
const handleClick = useCallback(async () => {
const {
setShowInputsPanel,
workflowRunningData,
} = workflowStore.getState()
if (workflowRunningData?.result.status === WorkflowRunningStatus.Running)
return
const { getNodes } = store.getState()
const nodes = getNodes()
const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
const startVariables = startNode?.data.variables || []
const fileSettings = featuresStore!.getState().features.file
if (!startVariables.length && !fileSettings.image.enabled) {
await doSyncWorkflowDraft()
handleRunSetting()
handleRun({ inputs: {}, files: [] })
}
else {
setShowInputsPanel(true)
handleSyncWorkflowDraft(true)
}
}, [
workflowStore,
handleSyncWorkflowDraft,
handleRunSetting,
handleRun,
doSyncWorkflowDraft,
store,
featuresStore,
])
return (
<>
@ -44,7 +87,7 @@ const RunMode = memo(() => {
${showInputsPanel && 'bg-primary-50'}
${isRunning && 'bg-primary-50 !cursor-not-allowed'}
`}
onClick={() => !isRunning && handleClick()}
onClick={handleClick}
>
{
isRunning

View File

@ -22,7 +22,7 @@ export const useNodesSyncDraft = () => {
const { getNodesReadOnly } = useNodesReadOnly()
const debouncedSyncWorkflowDraft = useStore(s => s.debouncedSyncWorkflowDraft)
const doSyncWorkflowDraft = useCallback(() => {
const doSyncWorkflowDraft = useCallback(async () => {
const {
getNodes,
edges,
@ -90,6 +90,7 @@ export const useNodesSyncDraft = () => {
}, [debouncedSyncWorkflowDraft, doSyncWorkflowDraft, getNodesReadOnly])
return {
doSyncWorkflowDraft,
handleSyncWorkflowDraft,
}
}

View File

@ -36,19 +36,22 @@ export const useWorkflowRun = () => {
const handleBackupDraft = useCallback(() => {
const {
getNodes,
getEdges,
getViewport,
} = reactflow
edges,
} = store.getState()
const { getViewport } = reactflow
const {
backupDraft,
setBackupDraft,
} = workflowStore.getState()
setBackupDraft({
nodes: getNodes(),
edges: getEdges(),
viewport: getViewport(),
})
}, [reactflow, workflowStore])
if (!backupDraft) {
setBackupDraft({
nodes: getNodes(),
edges,
viewport: getViewport(),
})
}
}, [reactflow, workflowStore, store])
const handleLoadBackupDraft = useCallback(() => {
const {
@ -56,7 +59,10 @@ export const useWorkflowRun = () => {
setEdges,
} = store.getState()
const { setViewport } = reactflow
const { backupDraft } = workflowStore.getState()
const {
backupDraft,
setBackupDraft,
} = workflowStore.getState()
if (backupDraft) {
const {
@ -67,6 +73,8 @@ export const useWorkflowRun = () => {
setNodes(nodes)
setEdges(edges)
setViewport(viewport)
setBackupDraft(undefined)
}
}, [store, reactflow, workflowStore])

View File

@ -13,13 +13,21 @@ import {
useReactFlow,
useStoreApi,
} from 'reactflow'
import type { Connection } from 'reactflow'
import type {
Connection,
Viewport,
} from 'reactflow'
import type { ToolsMap } from '../block-selector/types'
import {
generateNewNode,
getLayoutByDagre,
initialEdges,
initialNodes,
} from '../utils'
import type { Node } from '../types'
import type {
Edge,
Node,
} from '../types'
import {
BlockEnum,
WorkflowRunningStatus,
@ -270,6 +278,17 @@ export const useWorkflow = () => {
}
}, [store])
const renderTreeFromRecord = useCallback((nodes: Node[], edges: Edge[], viewport?: Viewport) => {
const { setNodes } = store.getState()
const { setViewport, setEdges } = reactflow
setNodes(initialNodes(nodes, edges))
setEdges(initialEdges(edges, nodes))
if (viewport)
setViewport(viewport)
}, [store, reactflow])
return {
handleLayout,
getTreeLeafNodes,
@ -278,6 +297,7 @@ export const useWorkflow = () => {
isValidConnection,
formatTimeFromNow,
getValidTreeNodes,
renderTreeFromRecord,
}
}

View File

@ -1,13 +1,24 @@
import { memo } from 'react'
import { useIsChatMode } from '../hooks'
import { memo, useCallback } from 'react'
import {
useIsChatMode,
useWorkflow,
} from '../hooks'
import Run from '../run'
import { useStore } from '../store'
import ChatRecord from './chat-record'
import type { WorkflowRunDetailResponse } from '@/models/log'
const Record = () => {
const isChatMode = useIsChatMode()
const { renderTreeFromRecord } = useWorkflow()
const historyWorkflowData = useStore(s => s.historyWorkflowData)
const getResultCallback = useCallback((res: WorkflowRunDetailResponse) => {
const { graph } = res
renderTreeFromRecord(graph.nodes, graph.edges, graph.viewport)
}, [renderTreeFromRecord])
return (
<div className={`
flex flex-col h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white
@ -19,7 +30,12 @@ const Record = () => {
{
isChatMode
? <ChatRecord />
: <Run runID={historyWorkflowData?.id || ''} />
: (
<Run
runID={historyWorkflowData?.id || ''}
getResultCallback={getResultCallback}
/>
)
}
</div>
)

View File

@ -16,9 +16,10 @@ import { useStore as useAppStore } from '@/app/components/app/store'
export type RunProps = {
activeTab?: 'RESULT' | 'TRACING'
runID: string
getResultCallback?: (result: WorkflowRunDetailResponse) => void
}
const RunPanel: FC<RunProps> = ({ activeTab = 'RESULT', runID }) => {
const RunPanel: FC<RunProps> = ({ activeTab = 'RESULT', runID, getResultCallback }) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const [currentTab, setCurrentTab] = useState<string>(activeTab)
@ -42,6 +43,8 @@ const RunPanel: FC<RunProps> = ({ activeTab = 'RESULT', runID }) => {
runID,
})
setRunDetail(res)
if (getResultCallback)
getResultCallback(res)
}
catch (err) {
notify({
@ -49,7 +52,7 @@ const RunPanel: FC<RunProps> = ({ activeTab = 'RESULT', runID }) => {
message: `${err}`,
})
}
}, [notify])
}, [notify, getResultCallback])
const getTracingList = useCallback(async (appID: string, runID: string) => {
try {