diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index 157451dbc44a..3d424eee5fa1 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -1086,7 +1086,7 @@ const message = {
clearList: 'Clear list',
deleteRecycleHelper: 'Are you sure you want to permanently delete the following files?',
typeErrOrEmpty: '[{0}] file type is wrong or empty folder',
- dropHelper: 'Drag [{0}] here, or',
+ dropHelper: 'Drag the files you want to upload here',
},
ssh: {
autoStart: 'Auto Start',
diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts
index b727ce833d75..f510ec06312a 100644
--- a/frontend/src/lang/modules/tw.ts
+++ b/frontend/src/lang/modules/tw.ts
@@ -1035,7 +1035,7 @@ const message = {
clearList: '清空列表',
deleteRecycleHelper: '確定永久刪除以下文件?',
typeErrOrEmpty: '【{0}】 檔案類型錯誤或為空資料夾',
- dropHelper: '將【{0}】拖曳到此處,或',
+ dropHelper: '將需要上傳的文件拖曳到此處',
},
ssh: {
autoStart: '開機自啟',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 6347b45116a7..bd67dad2d44f 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -1036,7 +1036,7 @@ const message = {
clearList: '清空列表',
deleteRecycleHelper: '确定永久删除以下文件?',
typeErrOrEmpty: '【{0}】 文件类型错误或为空文件夹',
- dropHelper: '将【{0}】拖拽到此处,或者',
+ dropHelper: '将需要上传的文件拖曳到此处',
},
ssh: {
autoStart: '开机自启',
diff --git a/frontend/src/views/host/file-management/upload/index.vue b/frontend/src/views/host/file-management/upload/index.vue
index bd306fedc6e7..22292f161156 100644
--- a/frontend/src/views/host/file-management/upload/index.vue
+++ b/frontend/src/views/host/file-management/upload/index.vue
@@ -19,9 +19,21 @@
{ uploaderFiles.value.splice(index, 1); }; +const handleDragover = (event: DragEvent) => { + event.preventDefault(); +}; + +const handleDrop = (event: DragEvent) => { + event.preventDefault(); + const items = event.dataTransfer.items; + + if (items) { + for (let i = 0; i < items.length; i++) { + const entry = items[i].webkitGetAsEntry(); + if (entry) { + traverseFileTree(entry); + } + } + } +}; + +const convertFileToUploadFile = (file: File, path: string): UploadFile => { + const uid = Date.now(); + + const uploadRawFile: UploadRawFile = new File([file], file.name, { + type: file.type, + lastModified: file.lastModified, + }) as UploadRawFile; + uploadRawFile.uid = uid; + + let fileName = file.name; + if (path != '') { + fileName = path + file.name; + } + return { + name: fileName, + size: file.size, + status: 'ready', + uid: uid, + raw: uploadRawFile, + }; +}; + +const traverseFileTree = (item: any, path = '') => { + path = path || ''; + if (item.isFile) { + item.file((file: File) => { + uploaderFiles.value.push(convertFileToUploadFile(file, path)); + }); + } else if (item.isDirectory) { + const dirReader = item.createReader(); + dirReader.readEntries((entries) => { + for (let i = 0; i < entries.length; i++) { + traverseFileTree(entries[i], path + item.name + '/'); + } + }); + } +}; + +const handleDragleave = (event) => { + event.preventDefault(); +}; + const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => { if (_uploadFile.size == 64 || _uploadFile.size == 0) { uploaderFiles.value = uploadFiles; @@ -172,8 +241,9 @@ const submit = async () => { if (file.raw.webkitRelativePath != '') { formData.append('path', path.value + '/' + getPathWithoutFilename(file.raw.webkitRelativePath)); } else { - formData.append('path', path.value); + formData.append('path', path.value + '/' + getPathWithoutFilename(file.name)); } + uploadPrecent.value = 0; await UploadFileData(formData, { onUploadProgress: (progressEvent) => { const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100); @@ -197,7 +267,7 @@ const submit = async () => { if (file.raw.webkitRelativePath != '') { formData.append('path', path.value + '/' + getPathWithoutFilename(file.raw.webkitRelativePath)); } else { - formData.append('path', path.value); + formData.append('path', path.value + '/' + getPathWithoutFilename(file.name)); } formData.append('chunk', chunk); formData.append('chunkIndex', c.toString());