From ea150dc33651f4920181f7d3592623ff6b6ef14e Mon Sep 17 00:00:00 2001 From: Silow <99187811+Silow9@users.noreply.github.com> Date: Mon, 28 Apr 2025 15:31:22 +0800 Subject: [PATCH] feat: Upload a folder to knowledgebase (#17026) Co-authored-by: Silow9 --- .../datasets/create/file-uploader/index.tsx | 76 +++++++++++++++---- web/i18n/de-DE/dataset-creation.ts | 2 +- web/i18n/en-US/dataset-creation.ts | 2 +- web/i18n/es-ES/dataset-creation.ts | 2 +- web/i18n/fa-IR/dataset-creation.ts | 2 +- web/i18n/fr-FR/dataset-creation.ts | 2 +- web/i18n/hi-IN/dataset-creation.ts | 2 +- web/i18n/it-IT/dataset-creation.ts | 2 +- web/i18n/ja-JP/dataset-creation.ts | 2 +- web/i18n/ko-KR/dataset-creation.ts | 2 +- web/i18n/pl-PL/dataset-creation.ts | 2 +- web/i18n/pt-BR/dataset-creation.ts | 2 +- web/i18n/ro-RO/dataset-creation.ts | 2 +- web/i18n/ru-RU/dataset-creation.ts | 2 +- web/i18n/sl-SI/dataset-creation.ts | 2 +- web/i18n/th-TH/dataset-creation.ts | 2 +- web/i18n/tr-TR/dataset-creation.ts | 2 +- web/i18n/uk-UA/dataset-creation.ts | 2 +- web/i18n/vi-VN/dataset-creation.ts | 2 +- web/i18n/zh-Hans/dataset-creation.ts | 2 +- web/i18n/zh-Hant/dataset-creation.ts | 2 +- 21 files changed, 81 insertions(+), 35 deletions(-) diff --git a/web/app/components/datasets/create/file-uploader/index.tsx b/web/app/components/datasets/create/file-uploader/index.tsx index 84ef226d34..5ed4b7dd05 100644 --- a/web/app/components/datasets/create/file-uploader/index.tsx +++ b/web/app/components/datasets/create/file-uploader/index.tsx @@ -196,22 +196,68 @@ const FileUploader = ({ e.stopPropagation() e.target === dragRef.current && setDragging(false) } + type FileWithPath = { + relativePath?: string + } & File + const traverseFileEntry = useCallback( + (entry: any, prefix = ''): Promise => { + return new Promise((resolve) => { + if (entry.isFile) { + entry.file((file: FileWithPath) => { + file.relativePath = `${prefix}${file.name}` + resolve([file]) + }) + } + else if (entry.isDirectory) { + const reader = entry.createReader() + const entries: any[] = [] + const read = () => { + reader.readEntries(async (results: FileSystemEntry[]) => { + if (!results.length) { + const files = await Promise.all( + entries.map(ent => + traverseFileEntry(ent, `${prefix}${entry.name}/`), + ), + ) + resolve(files.flat()) + } + else { + entries.push(...results) + read() + } + }) + } + read() + } + else { + resolve([]) + } + }) + }, + [], + ) - const handleDrop = useCallback((e: DragEvent) => { - e.preventDefault() - e.stopPropagation() - setDragging(false) - if (!e.dataTransfer) - return - - let files = [...e.dataTransfer.files] as File[] - if (notSupportBatchUpload) - files = files.slice(0, 1) - - const validFiles = files.filter(isValid) - initialUpload(validFiles) - }, [initialUpload, isValid, notSupportBatchUpload]) - + const handleDrop = useCallback( + async (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + setDragging(false) + if (!e.dataTransfer) return + const nested = await Promise.all( + Array.from(e.dataTransfer.items).map((it) => { + const entry = (it as any).webkitGetAsEntry?.() + if (entry) return traverseFileEntry(entry) + const f = it.getAsFile?.() + return f ? Promise.resolve([f]) : Promise.resolve([]) + }), + ) + let files = nested.flat() + if (notSupportBatchUpload) files = files.slice(0, 1) + const valid = files.filter(isValid) + initialUpload(valid) + }, + [initialUpload, isValid, notSupportBatchUpload, traverseFileEntry], + ) const selectHandle = () => { if (fileUploader.current) fileUploader.current.click() diff --git a/web/i18n/de-DE/dataset-creation.ts b/web/i18n/de-DE/dataset-creation.ts index a4815c1def..60102a2a7d 100644 --- a/web/i18n/de-DE/dataset-creation.ts +++ b/web/i18n/de-DE/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Textdatei hochladen', - button: 'Datei hierher ziehen oder', + button: 'Dateien und Ordner hierher ziehen oder klicken', browse: 'Durchsuchen', tip: 'Unterstützt {{supportTypes}}. Maximal {{size}}MB pro Datei.', validation: { diff --git a/web/i18n/en-US/dataset-creation.ts b/web/i18n/en-US/dataset-creation.ts index 5a2ad90620..fe48e076fa 100644 --- a/web/i18n/en-US/dataset-creation.ts +++ b/web/i18n/en-US/dataset-creation.ts @@ -35,7 +35,7 @@ const translation = { }, uploader: { title: 'Upload file', - button: 'Drag and drop file, or', + button: 'Drag and drop file or folder, or', browse: 'Browse', tip: 'Supports {{supportTypes}}. Max {{size}}MB each.', validation: { diff --git a/web/i18n/es-ES/dataset-creation.ts b/web/i18n/es-ES/dataset-creation.ts index 9d9b45e4a6..7047ff9e9a 100644 --- a/web/i18n/es-ES/dataset-creation.ts +++ b/web/i18n/es-ES/dataset-creation.ts @@ -27,7 +27,7 @@ const translation = { }, uploader: { title: 'Cargar archivo', - button: 'Arrastra y suelta el archivo, o', + button: 'Arrastre y suelte archivos o carpetas, o', browse: 'Buscar', tip: 'Soporta {{supportTypes}}. Máximo {{size}}MB cada uno.', validation: { diff --git a/web/i18n/fa-IR/dataset-creation.ts b/web/i18n/fa-IR/dataset-creation.ts index a2fded6ffe..0ca51ef534 100644 --- a/web/i18n/fa-IR/dataset-creation.ts +++ b/web/i18n/fa-IR/dataset-creation.ts @@ -27,7 +27,7 @@ const translation = { }, uploader: { title: 'بارگذاری فایل', - button: 'کشیدن و رها کردن فایل، یا', + button: 'فایل ها یا پوشه ها را بکشید و رها کنید یا', browse: 'مرور', tip: 'پشتیبانی از {{supportTypes}}. حداکثر {{size}}MB هر کدام.', validation: { diff --git a/web/i18n/fr-FR/dataset-creation.ts b/web/i18n/fr-FR/dataset-creation.ts index 9dec33c5ad..e7357749c4 100644 --- a/web/i18n/fr-FR/dataset-creation.ts +++ b/web/i18n/fr-FR/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Télécharger le fichier texte', - button: 'Glisser et déposer le fichier, ou', + button: 'Faites glisser et déposez des fichiers ou des dossiers, ou', browse: 'Parcourir', tip: 'Prend en charge {{supportTypes}}. Max {{size}}MB chacun.', validation: { diff --git a/web/i18n/hi-IN/dataset-creation.ts b/web/i18n/hi-IN/dataset-creation.ts index 19af14efad..6e397e398e 100644 --- a/web/i18n/hi-IN/dataset-creation.ts +++ b/web/i18n/hi-IN/dataset-creation.ts @@ -27,7 +27,7 @@ const translation = { }, uploader: { title: 'फ़ाइल अपलोड करें', - button: 'फ़ाइल खींचें और छोड़ें, या', + button: 'फ़ाइलों या फ़ोल्डरों को खींचें और छोड़ें, या', browse: 'ब्राउज़ करें', tip: 'समर्थित {{supportTypes}}। प्रत्येक अधिकतम {{size}}MB।', validation: { diff --git a/web/i18n/it-IT/dataset-creation.ts b/web/i18n/it-IT/dataset-creation.ts index 28a1c7a376..eaa5cdf16c 100644 --- a/web/i18n/it-IT/dataset-creation.ts +++ b/web/i18n/it-IT/dataset-creation.ts @@ -27,7 +27,7 @@ const translation = { }, uploader: { title: 'Carica file', - button: 'Trascina e rilascia il file, o', + button: 'Trascina e rilascia file o cartelle, oppure', browse: 'Sfoglia', tip: 'Supporta {{supportTypes}}. Max {{size}}MB ciascuno.', validation: { diff --git a/web/i18n/ja-JP/dataset-creation.ts b/web/i18n/ja-JP/dataset-creation.ts index 401f0b9084..3de5b4c615 100644 --- a/web/i18n/ja-JP/dataset-creation.ts +++ b/web/i18n/ja-JP/dataset-creation.ts @@ -30,7 +30,7 @@ const translation = { }, uploader: { title: 'テキストファイルをアップロード', - button: 'ファイルをドラッグ&ドロップするか', + button: 'ファイルまたはフォルダをドラッグアンドドロップする', browse: '参照', tip: '{{supportTypes}}をサポートしています。1つあたりの最大サイズは{{size}}MBです。', validation: { diff --git a/web/i18n/ko-KR/dataset-creation.ts b/web/i18n/ko-KR/dataset-creation.ts index b40be59fce..33ca624307 100644 --- a/web/i18n/ko-KR/dataset-creation.ts +++ b/web/i18n/ko-KR/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: '텍스트 파일 업로드', - button: '파일을 끌어다 놓거나', + button: '파일이나 폴더를 끌어서 놓기', browse: '찾아보기', tip: '{{supportTypes}}을(를) 지원합니다. 파일당 최대 크기는 {{size}}MB입니다.', validation: { diff --git a/web/i18n/pl-PL/dataset-creation.ts b/web/i18n/pl-PL/dataset-creation.ts index 553e3808d1..98c0613a30 100644 --- a/web/i18n/pl-PL/dataset-creation.ts +++ b/web/i18n/pl-PL/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Prześlij plik tekstowy', - button: 'Przeciągnij i upuść plik lub', + button: 'Przeciągnij i upuść pliki lub foldery lub', browse: 'Przeglądaj', tip: 'Obsługuje {{supportTypes}}. Maksymalnie {{size}}MB każdy.', validation: { diff --git a/web/i18n/pt-BR/dataset-creation.ts b/web/i18n/pt-BR/dataset-creation.ts index de806f8276..a3949f484b 100644 --- a/web/i18n/pt-BR/dataset-creation.ts +++ b/web/i18n/pt-BR/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Enviar arquivo de texto', - button: 'Arraste e solte o arquivo, ou', + button: 'Arraste e solte arquivos ou pastas, ou', browse: 'Navegar', tip: 'Suporta {{supportTypes}}. Máximo de {{size}}MB cada.', validation: { diff --git a/web/i18n/ro-RO/dataset-creation.ts b/web/i18n/ro-RO/dataset-creation.ts index d3fd9fe04f..3587070999 100644 --- a/web/i18n/ro-RO/dataset-creation.ts +++ b/web/i18n/ro-RO/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Încărcați fișier text', - button: 'Trageți și fixați fișierul, sau', + button: 'Trageți și plasați fișiere sau foldere sau', browse: 'Răsfoire', tip: 'Acceptă {{supportTypes}}. Maxim {{size}}MB fiecare.', validation: { diff --git a/web/i18n/ru-RU/dataset-creation.ts b/web/i18n/ru-RU/dataset-creation.ts index 3bf367689c..765bb88497 100644 --- a/web/i18n/ru-RU/dataset-creation.ts +++ b/web/i18n/ru-RU/dataset-creation.ts @@ -27,7 +27,7 @@ const translation = { }, uploader: { title: 'Загрузить файл', - button: 'Перетащите файл или', + button: 'Перетащите файлы или папки или', browse: 'Обзор', tip: 'Поддерживаются {{supportTypes}}. Максимум {{size}} МБ каждый.', validation: { diff --git a/web/i18n/sl-SI/dataset-creation.ts b/web/i18n/sl-SI/dataset-creation.ts index 3bc1d86bc6..e675c61813 100644 --- a/web/i18n/sl-SI/dataset-creation.ts +++ b/web/i18n/sl-SI/dataset-creation.ts @@ -32,7 +32,7 @@ const translation = { }, uploader: { title: 'Naloži datoteko', - button: 'Povleci in spusti datoteko ali', + button: 'Povleci in spusti datoteke ali mape oz', browse: 'Prebrskaj', tip: 'Podprti tipi datotek: {{supportTypes}}. Največ {{size}}MB na datoteko.', validation: { diff --git a/web/i18n/th-TH/dataset-creation.ts b/web/i18n/th-TH/dataset-creation.ts index d4ef1a9af9..4be2250184 100644 --- a/web/i18n/th-TH/dataset-creation.ts +++ b/web/i18n/th-TH/dataset-creation.ts @@ -32,7 +32,7 @@ const translation = { }, uploader: { title: 'อัปโหลดไฟล์', - button: 'ลากและวางไฟล์ หรือ', + button: 'ลากและวางไฟล์หรือโฟลเดอร์หรือ', browse: 'เล็ม', tip: 'รองรับ {{supportTypes}} สูงสุด {{size}}MB แต่ละตัว', validation: { diff --git a/web/i18n/tr-TR/dataset-creation.ts b/web/i18n/tr-TR/dataset-creation.ts index 1da6f97c4c..0394a4816a 100644 --- a/web/i18n/tr-TR/dataset-creation.ts +++ b/web/i18n/tr-TR/dataset-creation.ts @@ -27,7 +27,7 @@ const translation = { }, uploader: { title: 'Dosya yükle', - button: 'Dosyayı sürükleyip bırakın veya', + button: 'Dosyaları veya klasörleri sürükleyip bırakın veya', browse: 'Göz atın', tip: 'Destekler {{supportTypes}}. Her biri en fazla {{size}}MB.', validation: { diff --git a/web/i18n/uk-UA/dataset-creation.ts b/web/i18n/uk-UA/dataset-creation.ts index 120c24a9d0..96af3bbd1e 100644 --- a/web/i18n/uk-UA/dataset-creation.ts +++ b/web/i18n/uk-UA/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Завантажити текстовий файл', - button: 'Перетягніть файл або', + button: 'Перетягніть файли або папки або', browse: 'Оберіть', tip: 'Підтримуються {{supportTypes}}. Максимум {{size}} МБ кожен.', validation: { diff --git a/web/i18n/vi-VN/dataset-creation.ts b/web/i18n/vi-VN/dataset-creation.ts index cae2bfb814..8acaf329b2 100644 --- a/web/i18n/vi-VN/dataset-creation.ts +++ b/web/i18n/vi-VN/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: 'Tải lên tệp văn bản', - button: 'Kéo và thả tệp, hoặc', + button: 'Kéo và thả các tập tin hoặc thư mục, hoặc', browse: 'Chọn tệp', tip: 'Hỗ trợ {{supportTypes}}. Tối đa {{size}}MB mỗi tệp.', validation: { diff --git a/web/i18n/zh-Hans/dataset-creation.ts b/web/i18n/zh-Hans/dataset-creation.ts index aec029be2e..6a91b1b996 100644 --- a/web/i18n/zh-Hans/dataset-creation.ts +++ b/web/i18n/zh-Hans/dataset-creation.ts @@ -35,7 +35,7 @@ const translation = { }, uploader: { title: '上传文本文件', - button: '拖拽文件至此,或者', + button: '拖拽文件或文件夹至此,或者', browse: '选择文件', tip: '已支持 {{supportTypes}},每个文件不超过 {{size}}MB。', validation: { diff --git a/web/i18n/zh-Hant/dataset-creation.ts b/web/i18n/zh-Hant/dataset-creation.ts index be183ae72f..9f5186d024 100644 --- a/web/i18n/zh-Hant/dataset-creation.ts +++ b/web/i18n/zh-Hant/dataset-creation.ts @@ -22,7 +22,7 @@ const translation = { }, uploader: { title: '上傳文字檔案', - button: '拖拽檔案至此,或者', + button: '拖拽檔案或檔案夾至此,或者', browse: '選擇檔案', tip: '已支援 {{supportTypes}},每個檔案不超過 {{size}}MB。', validation: {