Skip to content

Commit

Permalink
Fix: support file download in workflow result (#11338)
Browse files Browse the repository at this point in the history
  • Loading branch information
JzoNgKVO authored and iamjoel committed Dec 16, 2024
1 parent 8eb888f commit b68de4f
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 135 deletions.
2 changes: 1 addition & 1 deletion web/app/components/app/text-generate/item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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')}
Expand Down
27 changes: 17 additions & 10 deletions web/app/components/app/text-generate/item/result-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -56,14 +56,21 @@ 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}
showDeleteAction={false}
showDownloadAction
canPreview
/>
<div className='flex flex-col gap-2'>
{data?.files.map((item: any) => (
<div key={item.varName} className='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>
)}
</>
)}
Expand Down
54 changes: 37 additions & 17 deletions web/app/components/base/file-uploader/file-list-in-log.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react'
import React, { useMemo, 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'
Expand All @@ -12,23 +13,36 @@ import { SupportUploadFileTypes } from '@/app/components/workflow/types'
import cn from '@/utils/classnames'

type Props = {
fileList: FileEntity[]
fileList: {
varName: string
list: FileEntity[]
}[]
isExpanded?: boolean
noBorder?: boolean
noPadding?: boolean
}

const FileListInLog = ({ fileList }: Props) => {
const [expanded, setExpanded] = useState(false)
const FileListInLog = ({ fileList, isExpanded = false, noBorder = false, noPadding = false }: Props) => {
const { t } = useTranslation()
const [expanded, setExpanded] = useState(isExpanded)
const fullList = useMemo(() => {
return fileList.reduce((acc: FileEntity[], { list }) => {
return [...acc, ...list]
}, [])
}, [fileList])

if (!fileList.length)
return null

return (
<div className={cn('border-t border-divider-subtle px-3 py-2', expanded && 'py-3')}>
<div className={cn('px-3 py-2', expanded && 'py-3', !noBorder && 'border-t border-divider-subtle', noPadding && '!p-0')}>
<div className='flex justify-between gap-1'>
{expanded && (
<div></div>
<div className='grow py-1 text-text-secondary system-xs-semibold-uppercase cursor-pointer' onClick={() => setExpanded(!expanded)}>{t('appLog.runDetail.fileListLabel')}</div>
)}
{!expanded && (
<div className='flex'>
{fileList.map((file) => {
<div className='flex gap-1'>
{fullList.map((file) => {
const { id, name, type, supportFileType, base64Url, url } = file
const isImageFile = supportFileType === SupportUploadFileTypes.image
return (
Expand Down Expand Up @@ -63,19 +77,25 @@ 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>
{expanded && (
<div className='flex flex-col gap-1'>
{fileList.map(file => (
<FileItem
key={file.id}
file={file}
showDeleteAction={false}
showDownloadAction
/>
<div className='flex flex-col gap-3'>
{fileList.map(item => (
<div key={item.varName} className='flex flex-col gap-1 system-xs-regular'>
<div className='py-1 text-text-tertiary '>{item.varName}</div>
{item.list.map(file => (
<FileItem
key={file.id}
file={file}
showDeleteAction={false}
showDownloadAction
canPreview
/>
))}
</div>
))}
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {
memo,
useState,
} from 'react'
import {
RiDeleteBinLine,
RiDownloadLine,
RiEyeLine,
} from '@remixicon/react'
import FileTypeIcon from '../file-type-icon'
import {
downloadFile,
fileIsUploaded,
getFileAppearanceType,
getFileExtension,
Expand All @@ -19,110 +22,132 @@ import { formatFileSize } from '@/utils/format'
import cn from '@/utils/classnames'
import { ReplayLine } from '@/app/components/base/icons/src/vender/other'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
import ImagePreview from '@/app/components/base/image-uploader/image-preview'

type FileInAttachmentItemProps = {
file: FileEntity
showDeleteAction?: boolean
showDownloadAction?: boolean
onRemove?: (fileId: string) => void
onReUpload?: (fileId: string) => void
canPreview?: boolean
}
const FileInAttachmentItem = ({
file,
showDeleteAction,
showDownloadAction = true,
onRemove,
onReUpload,
canPreview,
}: FileInAttachmentItemProps) => {
const { id, name, type, progress, supportFileType, base64Url, url, isRemote } = file
const ext = getFileExtension(name, type, isRemote)
const isImageFile = supportFileType === SupportUploadFileTypes.image

const [imagePreviewUrl, setImagePreviewUrl] = useState('')
return (
<div className={cn(
'flex items-center pr-3 h-12 rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg shadow-xs',
progress === -1 && 'bg-state-destructive-hover border-state-destructive-border',
)}>
<div className='flex items-center justify-center w-12 h-12'>
{
isImageFile && (
<FileImageRender
className='w-8 h-8'
imageUrl={base64Url || url || ''}
/>
)
}
{
!isImageFile && (
<FileTypeIcon
type={getFileAppearanceType(name, type)}
size='lg'
/>
)
}
</div>
<div className='grow w-0 mr-1'>
<div
className='flex items-center mb-0.5 system-xs-medium text-text-secondary truncate'
title={file.name}
>
<div className='truncate'>{name}</div>
<>
<div className={cn(
'flex items-center pr-3 h-12 rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg shadow-xs',
progress === -1 && 'bg-state-destructive-hover border-state-destructive-border',
)}>
<div className='flex items-center justify-center w-12 h-12'>
{
isImageFile && (
<FileImageRender
className='w-8 h-8'
imageUrl={base64Url || url || ''}
/>
)
}
{
!isImageFile && (
<FileTypeIcon
type={getFileAppearanceType(name, type)}
size='lg'
/>
)
}
</div>
<div className='flex items-center system-2xs-medium-uppercase text-text-tertiary'>
<div className='grow w-0 mr-1'>
<div
className='flex items-center mb-0.5 system-xs-medium text-text-secondary truncate'
title={file.name}
>
<div className='truncate'>{name}</div>
</div>
<div className='flex items-center system-2xs-medium-uppercase text-text-tertiary'>
{
ext && (
<span>{ext.toLowerCase()}</span>
)
}
{
ext && (
<span className='mx-1 system-2xs-medium'></span>
)
}
{
!!file.size && (
<span>{formatFileSize(file.size)}</span>
)
}
</div>
</div>
<div className='shrink-0 flex items-center'>
{
progress >= 0 && !fileIsUploaded(file) && (
<ProgressCircle
className='mr-2.5'
percentage={progress}
/>
)
}
{
ext && (
<span>{ext.toLowerCase()}</span>
progress === -1 && (
<ActionButton
className='mr-1'
onClick={() => onReUpload?.(id)}
>
<ReplayLine className='w-4 h-4 text-text-tertiary' />
</ActionButton>
)
}
{
ext && (
<span className='mx-1 system-2xs-medium'></span>
showDeleteAction && (
<ActionButton onClick={() => onRemove?.(id)}>
<RiDeleteBinLine className='w-4 h-4' />
</ActionButton>
)
}
{
!!file.size && (
<span>{formatFileSize(file.size)}</span>
canPreview && isImageFile && (
<ActionButton className='mr-1' onClick={() => setImagePreviewUrl(url || '')}>
<RiEyeLine className='w-4 h-4' />
</ActionButton>
)
}
{
showDownloadAction && (
<ActionButton onClick={(e) => {
e.stopPropagation()
downloadFile(url || base64Url || '', name)
}}>
<RiDownloadLine className='w-4 h-4' />
</ActionButton>
)
}
</div>
</div>
<div className='shrink-0 flex items-center'>
{
progress >= 0 && !fileIsUploaded(file) && (
<ProgressCircle
className='mr-2.5'
percentage={progress}
/>
)
}
{
progress === -1 && (
<ActionButton
className='mr-1'
onClick={() => onReUpload?.(id)}
>
<ReplayLine className='w-4 h-4 text-text-tertiary' />
</ActionButton>
)
}
{
showDeleteAction && (
<ActionButton onClick={() => onRemove?.(id)}>
<RiDeleteBinLine className='w-4 h-4' />
</ActionButton>
)
}
{
showDownloadAction && (
<ActionButton
size='xs'
>
<RiDownloadLine className='w-3.5 h-3.5 text-text-tertiary' />
</ActionButton>
)
}
</div>
</div>
{
imagePreviewUrl && canPreview && (
<ImagePreview
title={name}
url={imagePreviewUrl}
onCancel={() => setImagePreviewUrl('')}
/>
)
}
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const FileItem = ({
onRemove,
onReUpload,
}: FileItemProps) => {
const { id, name, type, progress, url, isRemote } = file
const { id, name, type, progress, url, base64Url, isRemote } = file
const ext = getFileExtension(name, type, isRemote)
const uploadError = progress === -1

Expand Down Expand Up @@ -86,7 +86,7 @@ const FileItem = ({
className='hidden group-hover/file-item:flex absolute -right-1 -top-1'
onClick={(e) => {
e.stopPropagation()
downloadFile(url || '', name)
downloadFile(url || base64Url || '', name)
}}
>
<RiDownloadLine className='w-3.5 h-3.5 text-text-tertiary' />
Expand Down
Loading

0 comments on commit b68de4f

Please sign in to comment.