diff --git a/web/app/components/app/text-generate/item/result-tab.tsx b/web/app/components/app/text-generate/item/result-tab.tsx index 5518643f2c..5e646c14f0 100644 --- a/web/app/components/app/text-generate/item/result-tab.tsx +++ b/web/app/components/app/text-generate/item/result-tab.tsx @@ -62,6 +62,7 @@ const ResultTab = ({ files={data?.files} showDeleteAction={false} showDownloadAction + canPreview /> )} diff --git a/web/app/components/base/chat/chat/answer/index.tsx b/web/app/components/base/chat/chat/answer/index.tsx index 41d4f3829f..d199530815 100644 --- a/web/app/components/base/chat/chat/answer/index.tsx +++ b/web/app/components/base/chat/chat/answer/index.tsx @@ -175,6 +175,7 @@ const Answer: FC = ({ files={allFiles} showDeleteAction={false} showDownloadAction + canPreview /> ) } diff --git a/web/app/components/base/chat/chat/check-input-forms-hooks.ts b/web/app/components/base/chat/chat/check-input-forms-hooks.ts index 159ec33606..62c59a06fb 100644 --- a/web/app/components/base/chat/chat/check-input-forms-hooks.ts +++ b/web/app/components/base/chat/chat/check-input-forms-hooks.ts @@ -19,6 +19,9 @@ export const useCheckInputsForms = () => { if (hasEmptyInput) return + if (fileIsUploading) + return + if (!inputs[variable]) hasEmptyInput = label as string @@ -27,7 +30,7 @@ export const useCheckInputsForms = () => { if (Array.isArray(files)) fileIsUploading = files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId) else - fileIsUploading = files.transfer_method === TransferMethod.local_file && !files.uploadedId + fileIsUploading = files.transferMethod === TransferMethod.local_file && !files.uploadedId } }) } diff --git a/web/app/components/base/file-uploader/file-image-render.tsx b/web/app/components/base/file-uploader/file-image-render.tsx index 358c93b82b..1a433dec5d 100644 --- a/web/app/components/base/file-uploader/file-image-render.tsx +++ b/web/app/components/base/file-uploader/file-image-render.tsx @@ -24,7 +24,6 @@ const FileImageRender = ({ onLoad={onLoad} onError={onError} src={imageUrl} - onClick={() => showDownloadAction && window.open(imageUrl, '_blank')} /> ) diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx index aee1abc808..04b76eaa39 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx @@ -1,15 +1,24 @@ -import { RiCloseLine } from '@remixicon/react' +import { useState } from 'react' +import { + RiCloseLine, + RiDownloadLine, +} from '@remixicon/react' import FileImageRender from '../file-image-render' import type { FileEntity } from '../types' -import { fileIsUploaded } from '../utils' +import { + downloadFile, + fileIsUploaded, +} from '../utils' import Button from '@/app/components/base/button' import ProgressCircle from '@/app/components/base/progress-bar/progress-circle' import { ReplayLine } from '@/app/components/base/icons/src/vender/other' +import ImagePreview from '@/app/components/base/image-uploader/image-preview' type FileImageItemProps = { file: FileEntity showDeleteAction?: boolean showDownloadAction?: boolean + canPreview?: boolean onRemove?: (fileId: string) => void onReUpload?: (fileId: string) => void } @@ -17,52 +26,83 @@ const FileImageItem = ({ file, showDeleteAction, showDownloadAction, + canPreview, onRemove, onReUpload, }: FileImageItemProps) => { - const { id, progress, base64Url, url } = file + const { id, progress, base64Url, url, name } = file + const [imagePreviewUrl, setImagePreviewUrl] = useState('') return ( -
+ <> +
canPreview && setImagePreviewUrl(url || '')} + > + { + showDeleteAction && ( + + ) + } + + { + progress >= 0 && !fileIsUploaded(file) && ( +
+ +
+ ) + } + { + progress === -1 && ( +
+ onReUpload?.(id)} + /> +
+ ) + } + { + showDownloadAction && ( +
+
{ + e.stopPropagation() + downloadFile(url || '', name) + }} + > + +
+
+ ) + } +
{ - showDeleteAction && ( - + imagePreviewUrl && canPreview && ( + setImagePreviewUrl('')} + /> ) } - - { - progress >= 0 && !fileIsUploaded(file) && ( -
- -
- ) - } - { - progress === -1 && ( -
- onReUpload?.(id)} - /> -
- ) - } -
+ ) } diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx index 8627483a86..7a1297f2dd 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx @@ -3,6 +3,7 @@ import { RiDownloadLine, } from '@remixicon/react' import { + downloadFile, fileIsUploaded, getFileAppearanceType, getFileExtension, @@ -30,14 +31,14 @@ const FileItem = ({ onRemove, onReUpload, }: FileItemProps) => { - const { id, name, type, progress } = file + const { id, name, type, progress, url } = file const ext = getFileExtension(name, type) const uploadError = progress === -1 return (
onRemove?.(id)} > @@ -56,7 +57,7 @@ const FileItem = ({
{name}
-
+
{ showDownloadAction && ( - - - - - + { + e.stopPropagation() + downloadFile(url || '', name) + }} + > + + ) } { diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx index e1327ae138..69204640e0 100644 --- a/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx +++ b/web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx @@ -14,6 +14,7 @@ type FileListProps = { onReUpload?: (fileId: string) => void showDeleteAction?: boolean showDownloadAction?: boolean + canPreview?: boolean } export const FileList = ({ className, @@ -22,6 +23,7 @@ export const FileList = ({ onRemove, showDeleteAction = true, showDownloadAction = false, + canPreview, }: FileListProps) => { return (
@@ -36,6 +38,7 @@ export const FileList = ({ showDownloadAction={showDownloadAction} onRemove={onRemove} onReUpload={onReUpload} + canPreview={canPreview} /> ) } diff --git a/web/app/components/base/file-uploader/utils.ts b/web/app/components/base/file-uploader/utils.ts index 3c14be9d4a..ae4b333003 100644 --- a/web/app/components/base/file-uploader/utils.ts +++ b/web/app/components/base/file-uploader/utils.ts @@ -161,8 +161,21 @@ export const getFilesInLogs = (rawData: any) => { } export const fileIsUploaded = (file: FileEntity) => { - const localFileUploaded = file.transferMethod === TransferMethod.local_file && file.uploadedId - const fromUrlFileUploaded = file.transferMethod === TransferMethod.remote_url && file.progress === 100 + if (file.uploadedId) + return true - return localFileUploaded || fromUrlFileUploaded + if (file.transferMethod === TransferMethod.remote_url && file.progress === 100) + return true +} + +export const downloadFile = (url: string, filename: string) => { + const anchor = document.createElement('a') + anchor.href = url + anchor.download = filename + anchor.style.display = 'none' + anchor.target = '_blank' + anchor.title = filename + document.body.appendChild(anchor) + anchor.click() + document.body.removeChild(anchor) } diff --git a/web/app/components/workflow/run/result-text.tsx b/web/app/components/workflow/run/result-text.tsx index 98c79851fa..1369d49c61 100644 --- a/web/app/components/workflow/run/result-text.tsx +++ b/web/app/components/workflow/run/result-text.tsx @@ -57,6 +57,7 @@ const ResultText: FC = ({ files={allFiles} showDeleteAction={false} showDownloadAction + canPreview /> )}