Fix: support file download in workflow result (#11338)
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import { Markdown } from '@/app/components/base/markdown'
|
||||
import LoadingAnim from '@/app/components/base/chat/chat/loading-anim'
|
||||
import { FileList } from '@/app/components/base/file-uploader'
|
||||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
|
||||
|
||||
type OutputPanelProps = {
|
||||
isRunning?: boolean
|
||||
@@ -19,6 +22,30 @@ const OutputPanel: FC<OutputPanelProps> = ({
|
||||
error,
|
||||
height,
|
||||
}) => {
|
||||
const isTextOutput = useMemo(() => {
|
||||
return outputs && Object.keys(outputs).length === 1 && typeof outputs[Object.keys(outputs)[0]] === 'string'
|
||||
}, [outputs])
|
||||
|
||||
const fileList = useMemo(() => {
|
||||
const fileList: any[] = []
|
||||
if (!outputs)
|
||||
return fileList
|
||||
if (Object.keys(outputs).length > 1)
|
||||
return fileList
|
||||
for (const key in outputs) {
|
||||
if (Array.isArray(outputs[key])) {
|
||||
outputs[key].map((output: any) => {
|
||||
if (output.dify_model_identity === '__dify__file__')
|
||||
fileList.push(output)
|
||||
return null
|
||||
})
|
||||
}
|
||||
else if (outputs[key].dify_model_identity === '__dify__file__') {
|
||||
fileList.push(outputs[key])
|
||||
}
|
||||
}
|
||||
return getProcessedFilesFromResponse(fileList)
|
||||
}, [outputs])
|
||||
return (
|
||||
<div className='py-2'>
|
||||
{isRunning && (
|
||||
@@ -36,20 +63,31 @@ const OutputPanel: FC<OutputPanelProps> = ({
|
||||
<Markdown content='No Output' />
|
||||
</div>
|
||||
)}
|
||||
{outputs && Object.keys(outputs).length === 1 && (
|
||||
{isTextOutput && (
|
||||
<div className='px-4 py-2'>
|
||||
<Markdown content={outputs[Object.keys(outputs)[0]] || ''} />
|
||||
</div>
|
||||
)}
|
||||
{fileList.length > 0 && (
|
||||
<div className='px-4 py-2'>
|
||||
<FileList
|
||||
files={fileList}
|
||||
showDeleteAction={false}
|
||||
showDownloadAction
|
||||
canPreview
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{outputs && Object.keys(outputs).length > 1 && height! > 0 && (
|
||||
<div className='px-4 py-2 flex flex-col gap-2'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
<CodeEditor
|
||||
showFileList
|
||||
readOnly
|
||||
title={<div></div>}
|
||||
language={CodeLanguage.json}
|
||||
value={outputs}
|
||||
isJSONStringifyBeauty
|
||||
height={height}
|
||||
height={height ? (height - 16) / 2 : undefined}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@@ -6,14 +6,13 @@ import { Markdown } from '@/app/components/base/markdown'
|
||||
import LoadingAnim from '@/app/components/base/chat/chat/loading-anim'
|
||||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
import { FileList } from '@/app/components/base/file-uploader'
|
||||
import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||
|
||||
type ResultTextProps = {
|
||||
isRunning?: boolean
|
||||
outputs?: any
|
||||
error?: string
|
||||
onClick?: () => void
|
||||
allFiles?: FileEntity[]
|
||||
allFiles?: any[]
|
||||
}
|
||||
|
||||
const ResultText: FC<ResultTextProps> = ({
|
||||
@@ -25,20 +24,20 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='bg-background-section-burn py-2'>
|
||||
<div className='bg-background-section-burn'>
|
||||
{isRunning && !outputs && (
|
||||
<div className='pt-4 pl-[26px]'>
|
||||
<LoadingAnim type='text' />
|
||||
</div>
|
||||
)}
|
||||
{!isRunning && error && (
|
||||
<div className='px-4'>
|
||||
<div className='px-4 py-2'>
|
||||
<StatusContainer status='failed'>
|
||||
{error}
|
||||
</StatusContainer>
|
||||
</div>
|
||||
)}
|
||||
{!isRunning && !outputs && !error && (
|
||||
{!isRunning && !outputs && !error && !allFiles?.length && (
|
||||
<div className='mt-[120px] px-4 py-2 flex flex-col items-center text-[13px] leading-[18px] text-gray-500'>
|
||||
<ImageIndentLeft className='w-6 h-6 text-gray-400' />
|
||||
<div className='mr-2'>{t('runLog.resultEmpty.title')}</div>
|
||||
@@ -49,18 +48,25 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{outputs && (
|
||||
<div className='px-4 py-2'>
|
||||
<Markdown content={outputs} />
|
||||
{!!allFiles?.length && (
|
||||
<FileList
|
||||
files={allFiles}
|
||||
showDeleteAction={false}
|
||||
showDownloadAction
|
||||
canPreview
|
||||
/>
|
||||
{(outputs || !!allFiles?.length) && (
|
||||
<>
|
||||
{outputs && (
|
||||
<div className='px-4 py-2'>
|
||||
<Markdown content={outputs} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{!!allFiles?.length && allFiles.map(item => (
|
||||
<div key={item.varName} className='px-4 py-2 flex flex-col gap-1 system-xs-regular'>
|
||||
<div className='py-1 text-text-tertiary '>{item.varName}</div>
|
||||
<FileList
|
||||
files={item.list}
|
||||
showDeleteAction={false}
|
||||
showDownloadAction
|
||||
canPreview
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
Reference in New Issue
Block a user