mirror of
https://gitee.com/dify_ai/dify.git
synced 2025-12-07 11:55:44 +08:00
Compare commits
2 Commits
fix/indexi
...
feat/suppo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cbc59d92f | ||
|
|
323a6f8ca4 |
@@ -334,7 +334,7 @@ const GenerationItem: FC<IGenerationItemProps> = ({
|
||||
</SimpleBtn>
|
||||
)
|
||||
}
|
||||
{(currentTab === 'RESULT' || !isWorkflow) && (
|
||||
{((currentTab === 'RESULT' && workflowProcessData?.resultText) || !isWorkflow) && (
|
||||
<SimpleBtn
|
||||
isDisabled={isError || !messageId}
|
||||
className={cn(isMobile && '!px-1.5', 'space-x-1')}
|
||||
|
||||
@@ -27,15 +27,15 @@ const ResultTab = ({
|
||||
onCurrentTabChange(tab)
|
||||
}
|
||||
useEffect(() => {
|
||||
if (data?.resultText)
|
||||
if (data?.resultText || !!data?.files?.length)
|
||||
switchTab('RESULT')
|
||||
else
|
||||
switchTab('DETAIL')
|
||||
}, [data?.resultText])
|
||||
}, [data?.files?.length, data?.resultText])
|
||||
|
||||
return (
|
||||
<div className='grow relative flex flex-col'>
|
||||
{data?.resultText && (
|
||||
{(data?.resultText || !!data?.files?.length) && (
|
||||
<div className='shrink-0 flex items-center mb-2 border-b-[0.5px] border-[rgba(0,0,0,0.05)]'>
|
||||
<div
|
||||
className={cn(
|
||||
@@ -56,7 +56,7 @@ const ResultTab = ({
|
||||
<div className={cn('grow bg-white')}>
|
||||
{currentTab === 'RESULT' && (
|
||||
<>
|
||||
<Markdown content={data?.resultText || ''} />
|
||||
{data?.resultText && <Markdown content={data?.resultText || ''} />}
|
||||
{!!data?.files?.length && (
|
||||
<FileList
|
||||
files={data?.files}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RiArrowRightSLine } from '@remixicon/react'
|
||||
import FileImageRender from './file-image-render'
|
||||
import FileTypeIcon from './file-type-icon'
|
||||
@@ -16,18 +17,18 @@ type Props = {
|
||||
}
|
||||
|
||||
const FileListInLog = ({ fileList }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
|
||||
if (!fileList.length)
|
||||
return null
|
||||
return (
|
||||
<div className={cn('border-t border-divider-subtle px-3 py-2', expanded && 'py-3')}>
|
||||
<div className='flex justify-between gap-1'>
|
||||
{expanded && (
|
||||
<div></div>
|
||||
<div className='text-text-tertiary system-xs-medium-uppercase'>{t('appLog.runDetail.fileListLabel')}</div>
|
||||
)}
|
||||
{!expanded && (
|
||||
<div className='flex'>
|
||||
<div className='flex gap-1'>
|
||||
{fileList.map((file) => {
|
||||
const { id, name, type, supportFileType, base64Url, url } = file
|
||||
const isImageFile = supportFileType === SupportUploadFileTypes.image
|
||||
@@ -63,7 +64,7 @@ const FileListInLog = ({ fileList }: Props) => {
|
||||
</div>
|
||||
)}
|
||||
<div className='flex items-center gap-1 cursor-pointer' onClick={() => setExpanded(!expanded)}>
|
||||
{!expanded && <div className='text-text-tertiary system-xs-medium-uppercase'>DETAIL</div>}
|
||||
{!expanded && <div className='text-text-tertiary system-xs-medium-uppercase'>{t('appLog.runDetail.fileListDetail')}</div>}
|
||||
<RiArrowRightSLine className={cn('w-4 h-4 text-text-tertiary', expanded && 'rotate-90')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -162,7 +162,7 @@ export const getFilesInLogs = (rawData: any) => {
|
||||
if (typeof rawData[key] === 'object' || Array.isArray(rawData[key]))
|
||||
return rawData[key]
|
||||
return undefined
|
||||
}).filter(Boolean)).filter(item => item?.model_identity === '__dify__file__')
|
||||
}).filter(Boolean)).filter(item => item?.dify_model_identity === '__dify__file__')
|
||||
return getProcessedFilesFromResponse(originalFiles)
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ const WorkflowPreview = () => {
|
||||
}, [showDebugAndPreviewPanel, showInputsPanel])
|
||||
|
||||
useEffect(() => {
|
||||
if ((workflowRunningData?.result.status === WorkflowRunningStatus.Succeeded || workflowRunningData?.result.status === WorkflowRunningStatus.Failed) && !workflowRunningData.resultText)
|
||||
if ((workflowRunningData?.result.status === WorkflowRunningStatus.Succeeded || workflowRunningData?.result.status === WorkflowRunningStatus.Failed) && !workflowRunningData.resultText && !workflowRunningData.result.files?.length)
|
||||
switchTab('DETAIL')
|
||||
}, [workflowRunningData])
|
||||
|
||||
|
||||
@@ -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 - 50 - 16 : undefined}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -38,7 +38,7 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
</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,9 +49,9 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{outputs && (
|
||||
{(outputs || !!allFiles?.length) && (
|
||||
<div className='px-4 py-2'>
|
||||
<Markdown content={outputs} />
|
||||
{outputs && <Markdown content={outputs} />}
|
||||
{!!allFiles?.length && (
|
||||
<FileList
|
||||
files={allFiles}
|
||||
|
||||
@@ -79,6 +79,8 @@ const translation = {
|
||||
runDetail: {
|
||||
title: 'Conversation Log',
|
||||
workflowTitle: 'Log Detail',
|
||||
fileListLabel: 'File List',
|
||||
fileListDetail: 'Detail',
|
||||
},
|
||||
promptLog: 'Prompt Log',
|
||||
agentLog: 'Agent Log',
|
||||
|
||||
@@ -79,6 +79,8 @@ const translation = {
|
||||
runDetail: {
|
||||
title: '对话日志',
|
||||
workflowTitle: '日志详情',
|
||||
fileListLabel: '文件列表',
|
||||
fileListDetail: '详情',
|
||||
},
|
||||
promptLog: 'Prompt 日志',
|
||||
agentLog: 'Agent 日志',
|
||||
|
||||
Reference in New Issue
Block a user