mirror of
https://github.com/langgenius/dify.git
synced 2026-04-28 20:17:29 +08:00
Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow
This commit is contained in:
commit
a647698c32
@ -78,7 +78,7 @@ const WorkflowChecklist = () => {
|
|||||||
placement='bottom-end'
|
placement='bottom-end'
|
||||||
offset={{
|
offset={{
|
||||||
mainAxis: 12,
|
mainAxis: 12,
|
||||||
crossAxis: -4,
|
crossAxis: 4,
|
||||||
}}
|
}}
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
@ -174,7 +174,7 @@ const WorkflowChecklist = () => {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
!needWarningNodes.length && (
|
!needWarningNodes.length && (
|
||||||
<div className='mx-4 mb-3 py-4 rounded-lg bg-gray-50 text-gray-400 text-center'>
|
<div className='mx-4 mb-3 py-4 rounded-lg bg-gray-50 text-gray-400 text-xs text-center'>
|
||||||
<ChecklistSquare className='mx-auto mb-[5px] w-8 h-8 text-gray-300' />
|
<ChecklistSquare className='mx-auto mb-[5px] w-8 h-8 text-gray-300' />
|
||||||
{t('workflow.panel.checklistResolved')}
|
{t('workflow.panel.checklistResolved')}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -16,14 +16,12 @@ import {
|
|||||||
BlockEnum,
|
BlockEnum,
|
||||||
WorkflowRunningStatus,
|
WorkflowRunningStatus,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
import ViewHistory from './view-history'
|
||||||
import {
|
import {
|
||||||
Play,
|
Play,
|
||||||
StopCircle,
|
StopCircle,
|
||||||
} from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
|
} 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'
|
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'
|
import { useFeaturesStore } from '@/app/components/base/features/hooks'
|
||||||
|
|
||||||
const RunMode = memo(() => {
|
const RunMode = memo(() => {
|
||||||
@ -160,11 +158,7 @@ const PreviewMode = memo(() => {
|
|||||||
PreviewMode.displayName = 'PreviewMode'
|
PreviewMode.displayName = 'PreviewMode'
|
||||||
|
|
||||||
const RunAndHistory: FC = () => {
|
const RunAndHistory: FC = () => {
|
||||||
const { t } = useTranslation()
|
|
||||||
const { setCurrentLogItem, setShowMessageLogModal } = useAppStore()
|
|
||||||
const workflowStore = useWorkflowStore()
|
|
||||||
const isChatMode = useIsChatMode()
|
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'>
|
||||||
@ -175,23 +169,7 @@ const RunAndHistory: FC = () => {
|
|||||||
isChatMode && <PreviewMode />
|
isChatMode && <PreviewMode />
|
||||||
}
|
}
|
||||||
<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
|
<ViewHistory />
|
||||||
popupContent={t('workflow.common.viewRunHistory')}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`
|
|
||||||
flex items-center justify-center w-7 h-7 rounded-md hover:bg-black/5 cursor-pointer
|
|
||||||
${showRunHistory && 'bg-primary-50'}
|
|
||||||
`}
|
|
||||||
onClick={() => {
|
|
||||||
workflowStore.setState({ showRunHistory: !showRunHistory })
|
|
||||||
setCurrentLogItem()
|
|
||||||
setShowMessageLogModal(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ClockPlay className={`w-4 h-4 ${showRunHistory ? 'text-primary-600' : 'text-gray-500'}`} />
|
|
||||||
</div>
|
|
||||||
</TooltipPlus>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
174
web/app/components/workflow/header/view-history.tsx
Normal file
174
web/app/components/workflow/header/view-history.tsx
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import {
|
||||||
|
memo,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
|
import cn from 'classnames'
|
||||||
|
import useSWR from 'swr'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import {
|
||||||
|
useIsChatMode,
|
||||||
|
useWorkflow,
|
||||||
|
useWorkflowRun,
|
||||||
|
} from '../hooks'
|
||||||
|
import { WorkflowRunningStatus } from '../types'
|
||||||
|
import {
|
||||||
|
PortalToFollowElem,
|
||||||
|
PortalToFollowElemContent,
|
||||||
|
PortalToFollowElemTrigger,
|
||||||
|
} from '@/app/components/base/portal-to-follow-elem'
|
||||||
|
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
||||||
|
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||||
|
import {
|
||||||
|
ClockPlay,
|
||||||
|
ClockPlaySlim,
|
||||||
|
} from '@/app/components/base/icons/src/vender/line/time'
|
||||||
|
import { CheckCircle, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
||||||
|
import { AlertCircle, AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||||
|
import {
|
||||||
|
fetcChatRunHistory,
|
||||||
|
fetchWorkflowRunHistory,
|
||||||
|
} from '@/service/workflow'
|
||||||
|
import Loading from '@/app/components/base/loading'
|
||||||
|
import {
|
||||||
|
useStore,
|
||||||
|
useWorkflowStore,
|
||||||
|
} from '@/app/components/workflow/store'
|
||||||
|
|
||||||
|
const ViewHistory = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const isChatMode = useIsChatMode()
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
const { formatTimeFromNow } = useWorkflow()
|
||||||
|
const workflowStore = useWorkflowStore()
|
||||||
|
const { appDetail, setCurrentLogItem, setShowMessageLogModal } = useAppStore()
|
||||||
|
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
||||||
|
const { handleBackupDraft } = useWorkflowRun()
|
||||||
|
const { data: runList, isLoading: runListLoading } = useSWR((appDetail && !isChatMode) ? `/apps/${appDetail.id}/workflow-runs` : null, fetchWorkflowRunHistory)
|
||||||
|
const { data: chatList, isLoading: chatListLoading } = useSWR((appDetail && isChatMode) ? `/apps/${appDetail.id}/advanced-chat/workflow-runs` : null, fetcChatRunHistory)
|
||||||
|
|
||||||
|
const data = isChatMode ? chatList : runList
|
||||||
|
const isLoading = isChatMode ? chatListLoading : runListLoading
|
||||||
|
|
||||||
|
return (
|
||||||
|
(
|
||||||
|
<PortalToFollowElem
|
||||||
|
placement='bottom-end'
|
||||||
|
offset={{
|
||||||
|
mainAxis: 4,
|
||||||
|
crossAxis: 131,
|
||||||
|
}}
|
||||||
|
open={open}
|
||||||
|
onOpenChange={setOpen}
|
||||||
|
>
|
||||||
|
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
|
||||||
|
<TooltipPlus
|
||||||
|
popupContent={t('workflow.common.viewRunHistory')}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
flex items-center justify-center w-7 h-7 rounded-md hover:bg-black/5 cursor-pointer
|
||||||
|
${open && 'bg-primary-50'}
|
||||||
|
`}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentLogItem()
|
||||||
|
setShowMessageLogModal(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ClockPlay className={`w-4 h-4 ${open ? 'text-primary-600' : 'text-gray-500'}`} />
|
||||||
|
</div>
|
||||||
|
</TooltipPlus>
|
||||||
|
</PortalToFollowElemTrigger>
|
||||||
|
<PortalToFollowElemContent className='z-[12]'>
|
||||||
|
<div
|
||||||
|
className='flex flex-col ml-2 w-[240px] bg-white border-[0.5px] border-gray-200 shadow-xl rounded-xl overflow-y-auto'
|
||||||
|
style={{
|
||||||
|
maxHeight: 'calc(2 / 3 * 100vh)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='sticky top-0 bg-white flex items-center justify-between px-4 pt-3 text-base font-semibold text-gray-900'>
|
||||||
|
<div className='grow'>{t('workflow.common.runHistory')}</div>
|
||||||
|
<div
|
||||||
|
className='shrink-0 flex items-center justify-center w-6 h-6 cursor-pointer'
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentLogItem()
|
||||||
|
setShowMessageLogModal(false)
|
||||||
|
setOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<XClose className='w-4 h-4 text-gray-500' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
isLoading && (
|
||||||
|
<div className='grow flex items-center justify-center h-full'>
|
||||||
|
<Loading />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<div className='p-2'>
|
||||||
|
{
|
||||||
|
!data?.data.length && (
|
||||||
|
<div className='py-12'>
|
||||||
|
<ClockPlaySlim className='mx-auto mb-2 w-8 h-8 text-gray-300' />
|
||||||
|
<div className='text-center text-[13px] text-gray-400'>
|
||||||
|
{t('workflow.common.notRunning')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
data?.data.map(item => (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className={cn(
|
||||||
|
'flex mb-0.5 px-2 py-[7px] rounded-lg hover:bg-primary-50 cursor-pointer',
|
||||||
|
item.id === historyWorkflowData?.id && 'bg-primary-50',
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
workflowStore.setState({
|
||||||
|
historyWorkflowData: item,
|
||||||
|
})
|
||||||
|
handleBackupDraft()
|
||||||
|
setOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
!isChatMode && item.status === WorkflowRunningStatus.Stopped && (
|
||||||
|
<AlertTriangle className='mt-0.5 mr-1.5 w-3.5 h-3.5 text-[#F79009]' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!isChatMode && item.status === WorkflowRunningStatus.Failed && (
|
||||||
|
<AlertCircle className='mt-0.5 mr-1.5 w-3.5 h-3.5 text-[#F04438]' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!isChatMode && item.status === WorkflowRunningStatus.Succeeded && (
|
||||||
|
<CheckCircle className='mt-0.5 mr-1.5 w-3.5 h-3.5 text-[#12B76A]' />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex items-center text-[13px] font-medium leading-[18px]',
|
||||||
|
item.id === historyWorkflowData?.id && 'text-primary-600',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{`Test ${isChatMode ? 'Chat' : 'Run'}#${item.sequence_number}`}
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center text-xs text-gray-500 leading-[18px]'>
|
||||||
|
{item.created_by_account.name} · {formatTimeFromNow((item.finished_at || item.created_at) * 1000)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PortalToFollowElemContent>
|
||||||
|
</PortalToFollowElem>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(ViewHistory)
|
||||||
@ -78,21 +78,23 @@ const ChatRecord = () => {
|
|||||||
background: 'linear-gradient(156deg, rgba(242, 244, 247, 0.80) 0%, rgba(242, 244, 247, 0.00) 99.43%), var(--white, #FFF)',
|
background: 'linear-gradient(156deg, rgba(242, 244, 247, 0.80) 0%, rgba(242, 244, 247, 0.00) 99.43%), var(--white, #FFF)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'>
|
<div className='shrink-0 flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'>
|
||||||
{`TEST CHAT#${historyWorkflowData?.sequence_number}`}
|
{`TEST CHAT#${historyWorkflowData?.sequence_number}`}
|
||||||
</div>
|
</div>
|
||||||
<Chat
|
<div className='grow h-0'>
|
||||||
config={{} as any}
|
<Chat
|
||||||
chatList={chatMessageList}
|
config={{} as any}
|
||||||
chatContainerclassName='px-4'
|
chatList={chatMessageList}
|
||||||
chatContainerInnerClassName='pt-6'
|
chatContainerclassName='px-4'
|
||||||
chatFooterClassName='px-4 rounded-b-2xl'
|
chatContainerInnerClassName='pt-6'
|
||||||
chatFooterInnerClassName='pb-4'
|
chatFooterClassName='px-4 rounded-b-2xl'
|
||||||
chatNode={<UserInput />}
|
chatFooterInnerClassName='pb-4'
|
||||||
noChatInput
|
chatNode={<UserInput />}
|
||||||
allToolIcons={{}}
|
noChatInput
|
||||||
showPromptLog
|
allToolIcons={{}}
|
||||||
/>
|
showPromptLog
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { Panel as NodePanel } from '../nodes'
|
|||||||
import { useStore } from '../store'
|
import { useStore } from '../store'
|
||||||
import { useIsChatMode } from '../hooks'
|
import { useIsChatMode } from '../hooks'
|
||||||
import DebugAndPreview from './debug-and-preview'
|
import DebugAndPreview from './debug-and-preview'
|
||||||
import RunHistory from './run-history'
|
|
||||||
import Record from './record'
|
import Record from './record'
|
||||||
import InputsPanel from './inputs-panel'
|
import InputsPanel from './inputs-panel'
|
||||||
import WorkflowPreview from './workflow-preview'
|
import WorkflowPreview from './workflow-preview'
|
||||||
@ -21,7 +20,6 @@ const Panel: FC = () => {
|
|||||||
const nodes = useNodes<CommonNodeType>()
|
const nodes = useNodes<CommonNodeType>()
|
||||||
const isChatMode = useIsChatMode()
|
const isChatMode = useIsChatMode()
|
||||||
const selectedNode = nodes.find(node => node.data.selected)
|
const selectedNode = nodes.find(node => node.data.selected)
|
||||||
const showRunHistory = useStore(state => state.showRunHistory)
|
|
||||||
const showInputsPanel = useStore(s => s.showInputsPanel)
|
const showInputsPanel = useStore(s => s.showInputsPanel)
|
||||||
const workflowRunningData = useStore(s => s.workflowRunningData)
|
const workflowRunningData = useStore(s => s.workflowRunningData)
|
||||||
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
||||||
@ -88,11 +86,6 @@ const Panel: FC = () => {
|
|||||||
<NodePanel {...selectedNode!} />
|
<NodePanel {...selectedNode!} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
showRunHistory && (
|
|
||||||
<RunHistory />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,12 @@
|
|||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import { useIsChatMode } from '../hooks'
|
|
||||||
import Run from '../run'
|
import Run from '../run'
|
||||||
import { useStore } from '../store'
|
import { useStore } from '../store'
|
||||||
|
|
||||||
const Record = () => {
|
const Record = () => {
|
||||||
const isChatMode = useIsChatMode()
|
|
||||||
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`
|
<div className='flex flex-col w-[400px] h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white'>
|
||||||
flex flex-col h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white
|
|
||||||
${isChatMode ? 'w-[320px]' : 'w-[400px]'}
|
|
||||||
`}>
|
|
||||||
<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#${historyWorkflowData?.sequence_number}`}
|
{`Test Run#${historyWorkflowData?.sequence_number}`}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,130 +0,0 @@
|
|||||||
import { memo } from 'react'
|
|
||||||
import cn from 'classnames'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import useSWR from 'swr'
|
|
||||||
import { WorkflowRunningStatus } from '../types'
|
|
||||||
import {
|
|
||||||
useIsChatMode,
|
|
||||||
useWorkflow,
|
|
||||||
useWorkflowRun,
|
|
||||||
} from '../hooks'
|
|
||||||
import { CheckCircle, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
|
||||||
import { AlertCircle, AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
|
||||||
import {
|
|
||||||
useStore,
|
|
||||||
useWorkflowStore,
|
|
||||||
} from '@/app/components/workflow/store'
|
|
||||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
|
||||||
import { fetcChatRunHistory, fetchWorkflowRunHistory } from '@/service/workflow'
|
|
||||||
import Loading from '@/app/components/base/loading'
|
|
||||||
import { ClockPlaySlim } from '@/app/components/base/icons/src/vender/line/time'
|
|
||||||
|
|
||||||
const RunHistory = () => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
const isChatMode = useIsChatMode()
|
|
||||||
const { appDetail, setCurrentLogItem, setShowMessageLogModal } = useAppStore()
|
|
||||||
const { formatTimeFromNow } = useWorkflow()
|
|
||||||
const { handleBackupDraft } = useWorkflowRun()
|
|
||||||
const workflowStore = useWorkflowStore()
|
|
||||||
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
|
||||||
const { data: runList, isLoading: runListLoading } = useSWR((appDetail && !isChatMode) ? `/apps/${appDetail.id}/workflow-runs` : null, fetchWorkflowRunHistory)
|
|
||||||
|
|
||||||
const { data: chatList, isLoading: chatListLoading } = useSWR((appDetail && isChatMode) ? `/apps/${appDetail.id}/advanced-chat/workflow-runs` : null, fetcChatRunHistory)
|
|
||||||
|
|
||||||
const data = isChatMode ? chatList : runList
|
|
||||||
const isLoading = isChatMode ? chatListLoading : runListLoading
|
|
||||||
|
|
||||||
if (!appDetail)
|
|
||||||
return null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='absolute -top-2 right-2 flex flex-col ml-2 w-[240px] min-h-[214px] bg-white border-[0.5px] border-gray-200 shadow-xl rounded-xl overflow-y-auto z-[11]'>
|
|
||||||
<div className='shrink-0 flex items-center justify-between px-4 pt-3 text-base font-semibold text-gray-900'>
|
|
||||||
{t('workflow.common.runHistory')}
|
|
||||||
<div
|
|
||||||
className='flex items-center justify-center w-6 h-6 cursor-pointer'
|
|
||||||
onClick={() => {
|
|
||||||
workflowStore.setState({
|
|
||||||
showRunHistory: false,
|
|
||||||
})
|
|
||||||
setCurrentLogItem()
|
|
||||||
setShowMessageLogModal(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<XClose className='w-4 h-4 text-gray-500' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{
|
|
||||||
isLoading && (
|
|
||||||
<div className='grow flex items-center justify-center h-full'>
|
|
||||||
<Loading />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<div className='grow p-2 overflow-y-auto'>
|
|
||||||
{
|
|
||||||
!data?.data.length && (
|
|
||||||
<div className='flex justify-center items-center h-full'>
|
|
||||||
<div>
|
|
||||||
<div className='flex justify-center mb-2'>
|
|
||||||
<ClockPlaySlim className='w-8 h-8 text-gray-300' />
|
|
||||||
</div>
|
|
||||||
<div className='text-center text-[13px] text-gray-400'>
|
|
||||||
{t('workflow.common.notRunning')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
data?.data.map(item => (
|
|
||||||
<div
|
|
||||||
key={item.id}
|
|
||||||
className={cn(
|
|
||||||
'flex mb-0.5 px-2 py-[7px] rounded-lg hover:bg-primary-50 cursor-pointer',
|
|
||||||
item.id === historyWorkflowData?.id && 'bg-primary-50',
|
|
||||||
)}
|
|
||||||
onClick={() => {
|
|
||||||
workflowStore.setState({
|
|
||||||
historyWorkflowData: item,
|
|
||||||
})
|
|
||||||
handleBackupDraft()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
!isChatMode && item.status === WorkflowRunningStatus.Stopped && (
|
|
||||||
<AlertTriangle className='mt-0.5 mr-1.5 w-3.5 h-3.5 text-[#F79009]' />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!isChatMode && item.status === WorkflowRunningStatus.Failed && (
|
|
||||||
<AlertCircle className='mt-0.5 mr-1.5 w-3.5 h-3.5 text-[#F04438]' />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!isChatMode && item.status === WorkflowRunningStatus.Succeeded && (
|
|
||||||
<CheckCircle className='mt-0.5 mr-1.5 w-3.5 h-3.5 text-[#12B76A]' />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'flex items-center text-[13px] font-medium leading-[18px]',
|
|
||||||
item.id === historyWorkflowData?.id && 'text-primary-600',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{`Test ${isChatMode ? 'Chat' : 'Run'}#${item.sequence_number}`}
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center text-xs text-gray-500 leading-[18px]'>
|
|
||||||
{item.created_by_account.name} · {formatTimeFromNow((item.finished_at || item.created_at) * 1000)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(RunHistory)
|
|
||||||
Loading…
Reference in New Issue
Block a user