From e32490f54ec03af4e541ac1e167332a0a1a295b4 Mon Sep 17 00:00:00 2001
From: Wu Tianwei <30284043+WTW0313@users.noreply.github.com>
Date: Wed, 11 Feb 2026 14:09:33 +0800
Subject: [PATCH] feat(workflow): enhance workflow run history management and
UI updates (#32230)
---
.../rag-pipeline/hooks/use-pipeline-run.ts | 9 ++++--
.../workflow-app/hooks/use-workflow-run.ts | 15 ++++++++--
.../workflow/header/view-history.tsx | 30 ++++++-------------
.../workflow/panel/workflow-preview.tsx | 10 ++-----
web/app/components/workflow/utils/common.ts | 6 ++--
web/service/use-workflow.ts | 14 ++++++++-
web/types/workflow.ts | 16 ++++++++--
7 files changed, 63 insertions(+), 37 deletions(-)
diff --git a/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts b/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts
index dc2a234d1e..b35441365b 100644
--- a/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts
+++ b/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts
@@ -12,7 +12,7 @@ import { useWorkflowRunEvent } from '@/app/components/workflow/hooks/use-workflo
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
import { WorkflowRunningStatus } from '@/app/components/workflow/types'
import { ssePost } from '@/service/base'
-import { useInvalidAllLastRun } from '@/service/use-workflow'
+import { useInvalidAllLastRun, useInvalidateWorkflowRunHistory } from '@/service/use-workflow'
import { stopWorkflowRun } from '@/service/workflow'
import { FlowType } from '@/types/common'
import { useNodesSyncDraft } from './use-nodes-sync-draft'
@@ -93,6 +93,7 @@ export const usePipelineRun = () => {
const pipelineId = useStore(s => s.pipelineId)
const invalidAllLastRun = useInvalidAllLastRun(FlowType.ragPipeline, pipelineId)
+ const invalidateRunHistory = useInvalidateWorkflowRunHistory()
const { fetchInspectVars } = useSetWorkflowVarsWithValue({
flowType: FlowType.ragPipeline,
flowId: pipelineId!,
@@ -132,6 +133,7 @@ export const usePipelineRun = () => {
...restCallback
} = callback || {}
const { pipelineId } = workflowStore.getState()
+ const runHistoryUrl = `/rag/pipelines/${pipelineId}/workflow-runs`
workflowStore.setState({ historyWorkflowData: undefined })
const workflowContainer = document.getElementById('workflow-container')
@@ -170,12 +172,14 @@ export const usePipelineRun = () => {
},
onWorkflowStarted: (params) => {
handleWorkflowStarted(params)
+ invalidateRunHistory(runHistoryUrl)
if (onWorkflowStarted)
onWorkflowStarted(params)
},
onWorkflowFinished: (params) => {
handleWorkflowFinished(params)
+ invalidateRunHistory(runHistoryUrl)
fetchInspectVars({})
invalidAllLastRun()
@@ -184,6 +188,7 @@ export const usePipelineRun = () => {
},
onError: (params) => {
handleWorkflowFailed()
+ invalidateRunHistory(runHistoryUrl)
if (onError)
onError(params)
@@ -275,7 +280,7 @@ export const usePipelineRun = () => {
...restCallback,
},
)
- }, [store, doSyncWorkflowDraft, workflowStore, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, handleWorkflowFailed, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace])
+ }, [store, doSyncWorkflowDraft, workflowStore, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, invalidateRunHistory, handleWorkflowFailed, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace])
const handleStopRun = useCallback((taskId: string) => {
const { pipelineId } = workflowStore.getState()
diff --git a/web/app/components/workflow-app/hooks/use-workflow-run.ts b/web/app/components/workflow-app/hooks/use-workflow-run.ts
index ef6d7731a4..ae4a21f5a0 100644
--- a/web/app/components/workflow-app/hooks/use-workflow-run.ts
+++ b/web/app/components/workflow-app/hooks/use-workflow-run.ts
@@ -23,7 +23,7 @@ import { useWorkflowStore } from '@/app/components/workflow/store'
import { WorkflowRunningStatus } from '@/app/components/workflow/types'
import { handleStream, post, sseGet, ssePost } from '@/service/base'
import { ContentType } from '@/service/fetch'
-import { useInvalidAllLastRun } from '@/service/use-workflow'
+import { useInvalidAllLastRun, useInvalidateWorkflowRunHistory } from '@/service/use-workflow'
import { stopWorkflowRun } from '@/service/workflow'
import { AppModeEnum } from '@/types/app'
import { useSetWorkflowVarsWithValue } from '../../workflow/hooks/use-fetch-workflow-inspect-vars'
@@ -66,6 +66,7 @@ export const useWorkflowRun = () => {
const configsMap = useConfigsMap()
const { flowId, flowType } = configsMap
const invalidAllLastRun = useInvalidAllLastRun(flowType, flowId)
+ const invalidateRunHistory = useInvalidateWorkflowRunHistory()
const { fetchInspectVars } = useSetWorkflowVarsWithValue({
...configsMap,
@@ -189,6 +190,9 @@ export const useWorkflowRun = () => {
} = callback || {}
workflowStore.setState({ historyWorkflowData: undefined })
const appDetail = useAppStore.getState().appDetail
+ const runHistoryUrl = appDetail?.mode === AppModeEnum.ADVANCED_CHAT
+ ? `/apps/${appDetail.id}/advanced-chat/workflow-runs`
+ : `/apps/${appDetail?.id}/workflow-runs`
const workflowContainer = document.getElementById('workflow-container')
const {
@@ -363,6 +367,7 @@ export const useWorkflowRun = () => {
const wrappedOnError = (params: any) => {
clearAbortController()
handleWorkflowFailed()
+ invalidateRunHistory(runHistoryUrl)
clearListeningState()
if (onError)
@@ -381,6 +386,7 @@ export const useWorkflowRun = () => {
...restCallback,
onWorkflowStarted: (params) => {
handleWorkflowStarted(params)
+ invalidateRunHistory(runHistoryUrl)
if (onWorkflowStarted)
onWorkflowStarted(params)
@@ -388,6 +394,7 @@ export const useWorkflowRun = () => {
onWorkflowFinished: (params) => {
clearListeningState()
handleWorkflowFinished(params)
+ invalidateRunHistory(runHistoryUrl)
if (onWorkflowFinished)
onWorkflowFinished(params)
@@ -496,6 +503,7 @@ export const useWorkflowRun = () => {
},
onWorkflowPaused: (params) => {
handleWorkflowPaused()
+ invalidateRunHistory(runHistoryUrl)
if (onWorkflowPaused)
onWorkflowPaused(params)
const url = `/workflow/${params.workflow_run_id}/events`
@@ -694,6 +702,7 @@ export const useWorkflowRun = () => {
},
onWorkflowFinished: (params) => {
handleWorkflowFinished(params)
+ invalidateRunHistory(runHistoryUrl)
if (onWorkflowFinished)
onWorkflowFinished(params)
@@ -704,6 +713,7 @@ export const useWorkflowRun = () => {
},
onError: (params) => {
handleWorkflowFailed()
+ invalidateRunHistory(runHistoryUrl)
if (onError)
onError(params)
@@ -803,6 +813,7 @@ export const useWorkflowRun = () => {
},
onWorkflowPaused: (params) => {
handleWorkflowPaused()
+ invalidateRunHistory(runHistoryUrl)
if (onWorkflowPaused)
onWorkflowPaused(params)
const url = `/workflow/${params.workflow_run_id}/events`
@@ -837,7 +848,7 @@ export const useWorkflowRun = () => {
},
finalCallbacks,
)
- }, [store, doSyncWorkflowDraft, workflowStore, pathname, handleWorkflowFailed, flowId, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace, handleWorkflowPaused, handleWorkflowNodeHumanInputRequired, handleWorkflowNodeHumanInputFormFilled, handleWorkflowNodeHumanInputFormTimeout])
+ }, [store, doSyncWorkflowDraft, workflowStore, pathname, handleWorkflowFailed, flowId, handleWorkflowStarted, handleWorkflowFinished, fetchInspectVars, invalidAllLastRun, invalidateRunHistory, handleWorkflowNodeStarted, handleWorkflowNodeFinished, handleWorkflowNodeIterationStarted, handleWorkflowNodeIterationNext, handleWorkflowNodeIterationFinished, handleWorkflowNodeLoopStarted, handleWorkflowNodeLoopNext, handleWorkflowNodeLoopFinished, handleWorkflowNodeRetry, handleWorkflowAgentLog, handleWorkflowTextChunk, handleWorkflowTextReplace, handleWorkflowPaused, handleWorkflowNodeHumanInputRequired, handleWorkflowNodeHumanInputFormFilled, handleWorkflowNodeHumanInputFormTimeout])
const handleStopRun = useCallback((taskId: string) => {
const setStoppedState = () => {
diff --git a/web/app/components/workflow/header/view-history.tsx b/web/app/components/workflow/header/view-history.tsx
index f9b446e930..94963e29fc 100644
--- a/web/app/components/workflow/header/view-history.tsx
+++ b/web/app/components/workflow/header/view-history.tsx
@@ -1,18 +1,8 @@
-import {
- RiCheckboxCircleLine,
- RiCloseLine,
- RiErrorWarningLine,
-} from '@remixicon/react'
import {
memo,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
-import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
-import {
- ClockPlay,
- ClockPlaySlim,
-} from '@/app/components/base/icons/src/vender/line/time'
import Loading from '@/app/components/base/loading'
import {
PortalToFollowElem,
@@ -89,9 +79,7 @@ const ViewHistory = ({
open && 'bg-components-button-secondary-bg-hover',
)}
>
-