dify-conversation/app/components/workflow/workflow-process.tsx
2025-04-11 08:14:27 +08:00

105 lines
3.0 KiB
TypeScript

import {
useEffect,
useMemo,
useState,
} from 'react'
import cn from 'classnames'
import NodePanel from './node'
import type { WorkflowProcess } from '@/types/app'
import CheckCircle from '@/app/components/base/icons/solid/general/check-circle'
import AlertCircle from '@/app/components/base/icons/solid/alert-circle'
import Loading02 from '@/app/components/base/icons/line/loading-02'
import ChevronRight from '@/app/components/base/icons/line/chevron-right'
import { WorkflowRunningStatus } from '@/types/app'
type WorkflowProcessProps = {
data: WorkflowProcess
grayBg?: boolean
expand?: boolean
hideInfo?: boolean
}
const WorkflowProcessItem = ({
data,
grayBg,
expand = false,
hideInfo = false,
}: WorkflowProcessProps) => {
const [collapse, setCollapse] = useState(!expand)
const running = data.status === WorkflowRunningStatus.Running
const succeeded = data.status === WorkflowRunningStatus.Succeeded
const failed = data.status === WorkflowRunningStatus.Failed || data.status === WorkflowRunningStatus.Stopped
const background = useMemo(() => {
if (running && !collapse)
return 'linear-gradient(180deg, #E1E4EA 0%, #EAECF0 100%)'
if (succeeded && !collapse)
return 'linear-gradient(180deg, #ECFDF3 0%, #F6FEF9 100%)'
if (failed && !collapse)
return 'linear-gradient(180deg, #FEE4E2 0%, #FEF3F2 100%)'
}, [running, succeeded, failed, collapse])
useEffect(() => {
setCollapse(!expand)
}, [expand])
return (
<div
className={cn(
'mb-2 rounded-xl border-[0.5px] border-black/[0.08]',
collapse ? 'py-[7px]' : hideInfo ? 'pt-2 pb-1' : 'py-2',
collapse && (!grayBg ? 'bg-white' : 'bg-gray-50'),
hideInfo ? 'mx-[-8px] px-1' : 'w-full px-3',
)}
style={{
background,
}}
>
<div
className={cn(
'flex items-center h-[18px] cursor-pointer',
hideInfo && 'px-[6px]',
)}
onClick={() => setCollapse(!collapse)}
>
{
running && (
<Loading02 className='shrink-0 mr-1 w-3 h-3 text-[#667085] animate-spin' />
)
}
{
succeeded && (
<CheckCircle className='shrink-0 mr-1 w-3 h-3 text-[#12B76A]' />
)
}
{
failed && (
<AlertCircle className='shrink-0 mr-1 w-3 h-3 text-[#F04438]' />
)
}
<div className='grow text-xs font-medium text-gray-700 leading-[18px]'>Workflow Process</div>
<ChevronRight className={`'ml-1 w-3 h-3 text-gray-500' ${collapse ? '' : 'rotate-90'}`} />
</div>
{
!collapse && (
<div className='mt-1.5'>
{
data.tracing.map(node => (
<div key={node.id} className='mb-0.5 last-of-type:mb-0'>
<NodePanel
nodeInfo={node}
hideInfo={hideInfo}
/>
</div>
))
}
</div>
)
}
</div>
)
}
export default WorkflowProcessItem