mirror of https://github.com/langgenius/dify.git
refactor(web): migrate workflow run history from useSWR to TanStack Query (#30077)
This commit is contained in:
parent
64a14dcdbc
commit
5896bc89f5
|
|
@ -8,7 +8,6 @@ import Header from '@/app/components/workflow/header'
|
||||||
import {
|
import {
|
||||||
useStore,
|
useStore,
|
||||||
} from '@/app/components/workflow/store'
|
} from '@/app/components/workflow/store'
|
||||||
import { fetchWorkflowRunHistory } from '@/service/workflow'
|
|
||||||
import InputFieldButton from './input-field-button'
|
import InputFieldButton from './input-field-button'
|
||||||
import Publisher from './publisher'
|
import Publisher from './publisher'
|
||||||
import RunMode from './run-mode'
|
import RunMode from './run-mode'
|
||||||
|
|
@ -21,7 +20,6 @@ const RagPipelineHeader = () => {
|
||||||
const viewHistoryProps = useMemo(() => {
|
const viewHistoryProps = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
historyUrl: `/rag/pipelines/${pipelineId}/workflow-runs`,
|
historyUrl: `/rag/pipelines/${pipelineId}/workflow-runs`,
|
||||||
historyFetcher: fetchWorkflowRunHistory,
|
|
||||||
}
|
}
|
||||||
}, [pipelineId])
|
}, [pipelineId])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,16 +58,12 @@ vi.mock('@/app/components/app/store', () => ({
|
||||||
vi.mock('@/app/components/workflow/header', () => ({
|
vi.mock('@/app/components/workflow/header', () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
default: (props: HeaderProps) => {
|
default: (props: HeaderProps) => {
|
||||||
const historyFetcher = props.normal?.runAndHistoryProps?.viewHistoryProps?.historyFetcher
|
|
||||||
const hasHistoryFetcher = typeof historyFetcher === 'function'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-testid="workflow-header"
|
data-testid="workflow-header"
|
||||||
data-show-run={String(Boolean(props.normal?.runAndHistoryProps?.showRunButton))}
|
data-show-run={String(Boolean(props.normal?.runAndHistoryProps?.showRunButton))}
|
||||||
data-show-preview={String(Boolean(props.normal?.runAndHistoryProps?.showPreviewButton))}
|
data-show-preview={String(Boolean(props.normal?.runAndHistoryProps?.showPreviewButton))}
|
||||||
data-history-url={props.normal?.runAndHistoryProps?.viewHistoryProps?.historyUrl ?? ''}
|
data-history-url={props.normal?.runAndHistoryProps?.viewHistoryProps?.historyUrl ?? ''}
|
||||||
data-has-history-fetcher={String(hasHistoryFetcher)}
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -86,11 +82,6 @@ vi.mock('@/app/components/workflow/header', () => ({
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
vi.mock('@/service/workflow', () => ({
|
|
||||||
__esModule: true,
|
|
||||||
fetchWorkflowRunHistory: vi.fn(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock('@/service/use-workflow', () => ({
|
vi.mock('@/service/use-workflow', () => ({
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
useResetWorkflowVersionHistory: () => mockResetWorkflowVersionHistory,
|
useResetWorkflowVersionHistory: () => mockResetWorkflowVersionHistory,
|
||||||
|
|
@ -127,7 +118,6 @@ describe('WorkflowHeader', () => {
|
||||||
expect(header).toHaveAttribute('data-show-run', 'false')
|
expect(header).toHaveAttribute('data-show-run', 'false')
|
||||||
expect(header).toHaveAttribute('data-show-preview', 'true')
|
expect(header).toHaveAttribute('data-show-preview', 'true')
|
||||||
expect(header).toHaveAttribute('data-history-url', '/apps/app-id/advanced-chat/workflow-runs')
|
expect(header).toHaveAttribute('data-history-url', '/apps/app-id/advanced-chat/workflow-runs')
|
||||||
expect(header).toHaveAttribute('data-has-history-fetcher', 'true')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should configure run mode when app is not in advanced chat mode', () => {
|
it('should configure run mode when app is not in advanced chat mode', () => {
|
||||||
|
|
@ -142,7 +132,6 @@ describe('WorkflowHeader', () => {
|
||||||
expect(header).toHaveAttribute('data-show-run', 'true')
|
expect(header).toHaveAttribute('data-show-run', 'true')
|
||||||
expect(header).toHaveAttribute('data-show-preview', 'false')
|
expect(header).toHaveAttribute('data-show-preview', 'false')
|
||||||
expect(header).toHaveAttribute('data-history-url', '/apps/app-id/workflow-runs')
|
expect(header).toHaveAttribute('data-history-url', '/apps/app-id/workflow-runs')
|
||||||
expect(header).toHaveAttribute('data-has-history-fetcher', 'true')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@ import { useShallow } from 'zustand/react/shallow'
|
||||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||||
import Header from '@/app/components/workflow/header'
|
import Header from '@/app/components/workflow/header'
|
||||||
import { useResetWorkflowVersionHistory } from '@/service/use-workflow'
|
import { useResetWorkflowVersionHistory } from '@/service/use-workflow'
|
||||||
import {
|
|
||||||
fetchWorkflowRunHistory,
|
|
||||||
} from '@/service/workflow'
|
|
||||||
import { useIsChatMode } from '../../hooks'
|
import { useIsChatMode } from '../../hooks'
|
||||||
import ChatVariableTrigger from './chat-variable-trigger'
|
import ChatVariableTrigger from './chat-variable-trigger'
|
||||||
import FeaturesTrigger from './features-trigger'
|
import FeaturesTrigger from './features-trigger'
|
||||||
|
|
@ -33,7 +30,6 @@ const WorkflowHeader = () => {
|
||||||
return {
|
return {
|
||||||
onClearLogAndMessageModal: handleClearLogAndMessageModal,
|
onClearLogAndMessageModal: handleClearLogAndMessageModal,
|
||||||
historyUrl: isChatMode ? `/apps/${appDetail!.id}/advanced-chat/workflow-runs` : `/apps/${appDetail!.id}/workflow-runs`,
|
historyUrl: isChatMode ? `/apps/${appDetail!.id}/advanced-chat/workflow-runs` : `/apps/${appDetail!.id}/workflow-runs`,
|
||||||
historyFetcher: fetchWorkflowRunHistory,
|
|
||||||
}
|
}
|
||||||
}, [appDetail, isChatMode, handleClearLogAndMessageModal])
|
}, [appDetail, isChatMode, handleClearLogAndMessageModal])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,13 @@
|
||||||
import type { Fetcher } from 'swr'
|
|
||||||
import type { WorkflowRunHistoryResponse } from '@/types/workflow'
|
|
||||||
import {
|
import {
|
||||||
RiCheckboxCircleLine,
|
RiCheckboxCircleLine,
|
||||||
RiCloseLine,
|
RiCloseLine,
|
||||||
RiErrorWarningLine,
|
RiErrorWarningLine,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import { noop } from 'lodash-es'
|
|
||||||
import {
|
import {
|
||||||
memo,
|
memo,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useSWR from 'swr'
|
|
||||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||||
import {
|
import {
|
||||||
ClockPlay,
|
ClockPlay,
|
||||||
|
|
@ -30,6 +26,7 @@ import {
|
||||||
useWorkflowStore,
|
useWorkflowStore,
|
||||||
} from '@/app/components/workflow/store'
|
} from '@/app/components/workflow/store'
|
||||||
import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
|
import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
|
||||||
|
import { useWorkflowRunHistory } from '@/service/use-workflow'
|
||||||
import { cn } from '@/utils/classnames'
|
import { cn } from '@/utils/classnames'
|
||||||
import {
|
import {
|
||||||
useIsChatMode,
|
useIsChatMode,
|
||||||
|
|
@ -44,13 +41,11 @@ export type ViewHistoryProps = {
|
||||||
withText?: boolean
|
withText?: boolean
|
||||||
onClearLogAndMessageModal?: () => void
|
onClearLogAndMessageModal?: () => void
|
||||||
historyUrl?: string
|
historyUrl?: string
|
||||||
historyFetcher?: Fetcher<WorkflowRunHistoryResponse, string>
|
|
||||||
}
|
}
|
||||||
const ViewHistory = ({
|
const ViewHistory = ({
|
||||||
withText,
|
withText,
|
||||||
onClearLogAndMessageModal,
|
onClearLogAndMessageModal,
|
||||||
historyUrl,
|
historyUrl,
|
||||||
historyFetcher,
|
|
||||||
}: ViewHistoryProps) => {
|
}: ViewHistoryProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const isChatMode = useIsChatMode()
|
const isChatMode = useIsChatMode()
|
||||||
|
|
@ -68,11 +63,11 @@ const ViewHistory = ({
|
||||||
const { handleBackupDraft } = useWorkflowRun()
|
const { handleBackupDraft } = useWorkflowRun()
|
||||||
const { closeAllInputFieldPanels } = useInputFieldPanel()
|
const { closeAllInputFieldPanels } = useInputFieldPanel()
|
||||||
|
|
||||||
const fetcher = historyFetcher ?? (noop as Fetcher<WorkflowRunHistoryResponse, string>)
|
const shouldFetchHistory = open && !!historyUrl
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
isLoading,
|
isLoading,
|
||||||
} = useSWR((open && historyUrl && historyFetcher) ? historyUrl : null, fetcher)
|
} = useWorkflowRunHistory(historyUrl, shouldFetchHistory)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
(
|
(
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import type {
|
||||||
UpdateWorkflowParams,
|
UpdateWorkflowParams,
|
||||||
VarInInspect,
|
VarInInspect,
|
||||||
WorkflowConfigResponse,
|
WorkflowConfigResponse,
|
||||||
|
WorkflowRunHistoryResponse,
|
||||||
} from '@/types/workflow'
|
} from '@/types/workflow'
|
||||||
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
import { del, get, patch, post, put } from './base'
|
import { del, get, patch, post, put } from './base'
|
||||||
|
|
@ -25,6 +26,14 @@ export const useAppWorkflow = (appID: string) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useWorkflowRunHistory = (url?: string, enabled = true) => {
|
||||||
|
return useQuery<WorkflowRunHistoryResponse>({
|
||||||
|
queryKey: [NAME_SPACE, 'runHistory', url],
|
||||||
|
queryFn: () => get<WorkflowRunHistoryResponse>(url as string),
|
||||||
|
enabled: !!url && enabled,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const useInvalidateAppWorkflow = () => {
|
export const useInvalidateAppWorkflow = () => {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
return (appID: string) => {
|
return (appID: string) => {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
import type { Fetcher } from 'swr'
|
|
||||||
import type { BlockEnum } from '@/app/components/workflow/types'
|
import type { BlockEnum } from '@/app/components/workflow/types'
|
||||||
import type { CommonResponse } from '@/models/common'
|
import type { CommonResponse } from '@/models/common'
|
||||||
import type { FlowType } from '@/types/common'
|
import type { FlowType } from '@/types/common'
|
||||||
import type {
|
import type {
|
||||||
ChatRunHistoryResponse,
|
|
||||||
ConversationVariableResponse,
|
ConversationVariableResponse,
|
||||||
FetchWorkflowDraftResponse,
|
FetchWorkflowDraftResponse,
|
||||||
NodesDefaultConfigsResponse,
|
NodesDefaultConfigsResponse,
|
||||||
VarInInspect,
|
VarInInspect,
|
||||||
WorkflowRunHistoryResponse,
|
|
||||||
} from '@/types/workflow'
|
} from '@/types/workflow'
|
||||||
import { get, post } from './base'
|
import { get, post } from './base'
|
||||||
import { getFlowPrefix } from './utils'
|
import { getFlowPrefix } from './utils'
|
||||||
|
|
@ -24,18 +21,10 @@ export const syncWorkflowDraft = ({ url, params }: {
|
||||||
return post<CommonResponse & { updated_at: number, hash: string }>(url, { body: params }, { silent: true })
|
return post<CommonResponse & { updated_at: number, hash: string }>(url, { body: params }, { silent: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchNodesDefaultConfigs: Fetcher<NodesDefaultConfigsResponse, string> = (url) => {
|
export const fetchNodesDefaultConfigs = (url: string) => {
|
||||||
return get<NodesDefaultConfigsResponse>(url)
|
return get<NodesDefaultConfigsResponse>(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchWorkflowRunHistory: Fetcher<WorkflowRunHistoryResponse, string> = (url) => {
|
|
||||||
return get<WorkflowRunHistoryResponse>(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchChatRunHistory: Fetcher<ChatRunHistoryResponse, string> = (url) => {
|
|
||||||
return get<ChatRunHistoryResponse>(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const singleNodeRun = (flowType: FlowType, flowId: string, nodeId: string, params: object) => {
|
export const singleNodeRun = (flowType: FlowType, flowId: string, nodeId: string, params: object) => {
|
||||||
return post(`${getFlowPrefix(flowType)}/${flowId}/workflows/draft/nodes/${nodeId}/run`, { body: params })
|
return post(`${getFlowPrefix(flowType)}/${flowId}/workflows/draft/nodes/${nodeId}/run`, { body: params })
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +37,7 @@ export const getLoopSingleNodeRunUrl = (flowType: FlowType, isChatFlow: boolean,
|
||||||
return `${getFlowPrefix(flowType)}/${flowId}/${isChatFlow ? 'advanced-chat/' : ''}workflows/draft/loop/nodes/${nodeId}/run`
|
return `${getFlowPrefix(flowType)}/${flowId}/${isChatFlow ? 'advanced-chat/' : ''}workflows/draft/loop/nodes/${nodeId}/run`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchPublishedWorkflow: Fetcher<FetchWorkflowDraftResponse, string> = (url) => {
|
export const fetchPublishedWorkflow = (url: string) => {
|
||||||
return get<FetchWorkflowDraftResponse>(url)
|
return get<FetchWorkflowDraftResponse>(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,15 +57,13 @@ export const fetchPipelineNodeDefault = (pipelineId: string, blockType: BlockEnu
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: archived
|
export const fetchCurrentValueOfConversationVariable = ({
|
||||||
export const updateWorkflowDraftFromDSL = (appId: string, data: string) => {
|
url,
|
||||||
return post<FetchWorkflowDraftResponse>(`apps/${appId}/workflows/draft/import`, { body: { data } })
|
params,
|
||||||
}
|
}: {
|
||||||
|
|
||||||
export const fetchCurrentValueOfConversationVariable: Fetcher<ConversationVariableResponse, {
|
|
||||||
url: string
|
url: string
|
||||||
params: { conversation_id: string }
|
params: { conversation_id: string }
|
||||||
}> = ({ url, params }) => {
|
}) => {
|
||||||
return get<ConversationVariableResponse>(url, { params })
|
return get<ConversationVariableResponse>(url, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue