mirror of https://github.com/langgenius/dify.git
add proccess of workflow in web app
This commit is contained in:
parent
1201bef879
commit
9b5deaf80a
|
|
@ -23,10 +23,13 @@ import { fetchTextGenerationMessge } from '@/service/debug'
|
|||
import AnnotationCtrlBtn from '@/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn'
|
||||
import EditReplyModal from '@/app/components/app/annotation/edit-annotation-modal'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import WorkflowProcessItem from '@/app/components/base/chat/chat/answer/workflow-process'
|
||||
import type { WorkflowProcess } from '@/app/components/base/chat/types'
|
||||
|
||||
const MAX_DEPTH = 3
|
||||
export type IGenerationItemProps = {
|
||||
isWorkflow?: boolean
|
||||
workflowProcessData?: WorkflowProcess
|
||||
className?: string
|
||||
isError: boolean
|
||||
onRetry: () => void
|
||||
|
|
@ -78,6 +81,7 @@ export const copyIcon = (
|
|||
|
||||
const GenerationItem: FC<IGenerationItemProps> = ({
|
||||
isWorkflow,
|
||||
workflowProcessData,
|
||||
className,
|
||||
isError,
|
||||
onRetry,
|
||||
|
|
@ -280,6 +284,9 @@ const GenerationItem: FC<IGenerationItemProps> = ({
|
|||
}
|
||||
<div className={`flex ${contentClassName}`}>
|
||||
<div className='grow w-0'>
|
||||
{workflowProcessData && (
|
||||
<WorkflowProcessItem data={workflowProcessData} />
|
||||
)}
|
||||
{isError
|
||||
? <div className='text-gray-400 text-sm'>{t('share.generation.batchFailed.outputPlaceholder')}</div>
|
||||
: (
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ import NodePanel from '@/app/components/workflow/run/node'
|
|||
|
||||
type WorkflowProcessProps = {
|
||||
data: WorkflowProcess
|
||||
grayBg?: boolean
|
||||
}
|
||||
const WorkflowProcessItem = ({
|
||||
data,
|
||||
grayBg,
|
||||
}: WorkflowProcessProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [collapse, setCollapse] = useState(true)
|
||||
|
|
@ -37,9 +39,9 @@ const WorkflowProcessItem = ({
|
|||
return (
|
||||
<div
|
||||
className={`
|
||||
px-3 w-full rounded-xl border-[0.5px] border-black/[0.08]
|
||||
mb-2 px-3 w-full rounded-xl border-[0.5px] border-black/[0.08]
|
||||
${collapse ? 'py-[7px]' : 'py-2'}
|
||||
${collapse && 'bg-white'}
|
||||
${collapse && (grayBg ? 'bg-white' : 'bg-gray-50')}
|
||||
`}
|
||||
style={{
|
||||
background,
|
||||
|
|
@ -67,7 +69,7 @@ const WorkflowProcessItem = ({
|
|||
<div className='grow text-xs font-medium text-gray-700'>
|
||||
{t('workflow.common.workflowProcess')}
|
||||
</div>
|
||||
<ChevronRight className='ml-1 w-3 h-3 text-gray-500' />
|
||||
<ChevronRight className={`'ml-1 w-3 h-3 text-gray-500' ${collapse ? '' : 'rotate-90'}`} />
|
||||
</div>
|
||||
{
|
||||
!collapse && (
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import type { FC } from 'react'
|
|||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import { t } from 'i18next'
|
||||
import produce from 'immer'
|
||||
import cn from 'classnames'
|
||||
import TextGenerationRes from '@/app/components/app/text-generate/item'
|
||||
import NoData from '@/app/components/share/text-generation/no-data'
|
||||
|
|
@ -14,7 +15,8 @@ import type { PromptConfig } from '@/models/debug'
|
|||
import type { InstalledApp } from '@/models/explore'
|
||||
import type { ModerationService } from '@/models/common'
|
||||
import { TransferMethod, type VisionFile, type VisionSettings } from '@/types/app'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { BlockEnum, NodeRunningStatus, WorkflowRunningStatus } from '@/app/components/workflow/types'
|
||||
import type { WorkflowProcess } from '@/app/components/base/chat/types'
|
||||
|
||||
export type IResultProps = {
|
||||
isWorkflow: boolean
|
||||
|
|
@ -76,6 +78,14 @@ const Result: FC<IResultProps> = ({
|
|||
doSetCompletionRes(res)
|
||||
}
|
||||
const getCompletionRes = () => completionResRef.current
|
||||
const [workflowProcessData, doSetWorkflowProccessData] = useState<WorkflowProcess>()
|
||||
const workflowProcessDataRef = useRef<WorkflowProcess>()
|
||||
const setWorkflowProccessData = (data: WorkflowProcess) => {
|
||||
workflowProcessDataRef.current = data
|
||||
doSetWorkflowProccessData(data)
|
||||
}
|
||||
const getWorkflowProccessData = () => workflowProcessDataRef.current
|
||||
|
||||
const { notify } = Toast
|
||||
const isNoData = !completionRes
|
||||
|
||||
|
|
@ -188,12 +198,28 @@ const Result: FC<IResultProps> = ({
|
|||
{
|
||||
onWorkflowStarted: ({ workflow_run_id }) => {
|
||||
tempMessageId = workflow_run_id
|
||||
setWorkflowProccessData({
|
||||
status: WorkflowRunningStatus.Running,
|
||||
tracing: [],
|
||||
})
|
||||
setRespondingFalse()
|
||||
// console.log('onWorkflowStarted runID: ', workflow_run_id)
|
||||
},
|
||||
onNodeStarted: ({ data }) => {
|
||||
setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => {
|
||||
draft.tracing!.push({
|
||||
...data,
|
||||
status: NodeRunningStatus.Running,
|
||||
} as any)
|
||||
}))
|
||||
// console.log('onNodeStarted: ', data.node_type)
|
||||
},
|
||||
onNodeFinished: ({ data }) => {
|
||||
setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => {
|
||||
const currentIndex = draft.tracing!.findIndex(trace => trace.node_id === data.node_id)
|
||||
if (currentIndex > -1 && draft.tracing)
|
||||
draft.tracing[currentIndex] = data as any
|
||||
}))
|
||||
// console.log('onNodeFinished: ', data.node_type, data)
|
||||
if (data.node_type === BlockEnum.LLM && data.outputs.text)
|
||||
setCompletionRes(data.outputs.text)
|
||||
|
|
@ -215,6 +241,9 @@ const Result: FC<IResultProps> = ({
|
|||
notify({ type: 'info', message: 'Outputs not existed.' })
|
||||
setCompletionRes('')
|
||||
}
|
||||
setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => {
|
||||
draft.status = data.error ? WorkflowRunningStatus.Failed : WorkflowRunningStatus.Succeeded
|
||||
}))
|
||||
setRespondingFalse()
|
||||
setMessageId(tempMessageId)
|
||||
onCompleted(getCompletionRes(), taskId, true)
|
||||
|
|
@ -271,6 +300,7 @@ const Result: FC<IResultProps> = ({
|
|||
const renderTextGenerationRes = () => (
|
||||
<TextGenerationRes
|
||||
isWorkflow={isWorkflow}
|
||||
workflowProcessData={workflowProcessData}
|
||||
className='mt-3'
|
||||
isError={isError}
|
||||
onRetry={handleSend}
|
||||
|
|
|
|||
|
|
@ -44,14 +44,14 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed = true, className }) => {
|
|||
<div
|
||||
className={cn(
|
||||
'flex items-center pl-[6px] py-3 pr-3 cursor-pointer',
|
||||
!collapsed && 'pb-2',
|
||||
!collapseState && 'pb-2',
|
||||
)}
|
||||
onClick={() => setCollapseState(!collapseState)}
|
||||
>
|
||||
<ChevronRight
|
||||
className={cn(
|
||||
'shrink-0 w-3 h-3 mr-1 text-gray-400 transition-all group-hover:text-gray-500',
|
||||
!collapsed && 'rotate-90',
|
||||
!collapseState && 'rotate-90',
|
||||
)}
|
||||
/>
|
||||
<BlockIcon className='shrink-0 mr-2' type={nodeInfo.node_type} />
|
||||
|
|
|
|||
Loading…
Reference in New Issue