From c7bfd773e361a32bb480545c9df4e70799fc73b9 Mon Sep 17 00:00:00 2001 From: zhujingyang <72259332+zjy365@users.noreply.github.com> Date: Fri, 4 Aug 2023 18:16:34 +0800 Subject: [PATCH] feat: file drag and drop (#2) * feat file drag and drop Signed-off-by: jingyang <3161362058@qq.com> * add file select i18n Signed-off-by: jingyang <3161362058@qq.com> * add i18n Interpolation Signed-off-by: jingyang <3161362058@qq.com> --------- Signed-off-by: jingyang <3161362058@qq.com> --- client/public/locales/en/common.json | 11 +- client/public/locales/zh/common.json | 11 +- .../pages/kb/detail/components/Import/Csv.tsx | 2 +- .../detail/components/Import/FileSelect.tsx | 100 +++++++++++++++--- 4 files changed, 109 insertions(+), 15 deletions(-) diff --git a/client/public/locales/en/common.json b/client/public/locales/en/common.json index b5b8a774f..949de6c63 100644 --- a/client/public/locales/en/common.json +++ b/client/public/locales/en/common.json @@ -27,6 +27,15 @@ "Input": "Input", "Output": "Output" }, + "file": { + "Click to download CSV template": "Click to download CSV template", + "Drag and drop": "Drag and drop files here, or click", + "Release the mouse to upload the file": "Release the mouse to upload the file", + "select a document": "select a document", + "support": "support {{fileExtension}} file", + "upload error description": "Only upload multiple files or one folder at a time", + "If the imported file is garbled, please convert CSV to utf-8 encoding format": "If the imported file is garbled, please convert CSV to utf-8 encoding format" + }, "home": { "Quickly build AI question and answer library": "Quickly build AI question and answer library", "Start Now": "Start Now", @@ -65,4 +74,4 @@ "Update password succseful": "Update password succseful", "Usage Record": "Usage" } -} +} \ No newline at end of file diff --git a/client/public/locales/zh/common.json b/client/public/locales/zh/common.json index 0850d3cb1..d25a0d370 100644 --- a/client/public/locales/zh/common.json +++ b/client/public/locales/zh/common.json @@ -27,6 +27,15 @@ "Input": "输入", "Output": "输出" }, + "file": { + "Click to download CSV template": "点击下载 CSV 模板", + "Drag and drop": "拖拽文件至此,或点击", + "Release the mouse to upload the file": "松开鼠标上传文件", + "select a document": "选择文件", + "support": "支持 {{fileExtension}} 文件", + "upload error description": "单次只支持上传多个文件或者一个文件夹", + "If the imported file is garbled, please convert CSV to utf-8 encoding format": "如果导入文件乱码,请将 CSV 转成 utf-8 编码格式" + }, "home": { "Quickly build AI question and answer library": "快速搭建 AI 问答系统", "Start Now": "立即开始", @@ -65,4 +74,4 @@ "Update password succseful": "修改密码成功", "Usage Record": "使用记录" } -} +} \ No newline at end of file diff --git a/client/src/pages/kb/detail/components/Import/Csv.tsx b/client/src/pages/kb/detail/components/Import/Csv.tsx index 3a0d9f0d6..96d12372a 100644 --- a/client/src/pages/kb/detail/components/Import/Csv.tsx +++ b/client/src/pages/kb/detail/components/Import/Csv.tsx @@ -136,7 +136,7 @@ const CsvImport = ({ kbId }: { kbId: string }) => { fileExtension={fileExtension} onSelectFile={onSelectFile} isLoading={selecting} - tipText={'如果导入文件乱码,请将 CSV 转成 utf-8 编码格式'} + tipText={'If the imported file is garbled, please convert CSV to utf-8 encoding format'} py={emptyFiles ? '100px' : 5} isCsv /> diff --git a/client/src/pages/kb/detail/components/Import/FileSelect.tsx b/client/src/pages/kb/detail/components/Import/FileSelect.tsx index 20cdf8c14..15c52c9fc 100644 --- a/client/src/pages/kb/detail/components/Import/FileSelect.tsx +++ b/client/src/pages/kb/detail/components/Import/FileSelect.tsx @@ -1,10 +1,11 @@ -import React from 'react'; -import { Box, Flex, type BoxProps } from '@chakra-ui/react'; +import MyIcon from '@/components/Icon'; import { useLoading } from '@/hooks/useLoading'; import { useSelectFile } from '@/hooks/useSelectFile'; - -import MyIcon from '@/components/Icon'; +import { useToast } from '@/hooks/useToast'; import { fileDownload } from '@/utils/file'; +import { Box, Flex, Text, type BoxProps } from '@chakra-ui/react'; +import { DragEvent, useCallback, useState } from 'react'; +import { useTranslation } from 'next-i18next'; interface Props extends BoxProps { fileExtension: string; @@ -23,13 +24,79 @@ const FileSelect = ({ ...props }: Props) => { const { Loading: FileSelectLoading } = useLoading(); + const { t } = useTranslation(); const csvTemplate = `question,answer,source\n"什么是 laf","laf 是一个云函数开发平台……","laf git doc"\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……","sealos git doc"`; + const { toast } = useToast(); + const { File, onOpen } = useSelectFile({ fileType: fileExtension, multiple: true }); + const [isDragging, setIsDragging] = useState(false); + + const handleDragEnter = (e: DragEvent) => { + e.preventDefault(); + setIsDragging(true); + }; + + const handleDragLeave = (e: DragEvent) => { + e.preventDefault(); + setIsDragging(false); + }; + + const handleDrop = useCallback(async (e: DragEvent) => { + e.preventDefault(); + setIsDragging(false); + + const items = e.dataTransfer.items; + const fileList: File[] = []; + + if (e.dataTransfer.items.length <= 1) { + const traverseFileTree = async (item: any) => { + return new Promise((resolve, reject) => { + if (item.isFile) { + item.file((file: File) => { + fileList.push(file); + resolve(); + }); + } else if (item.isDirectory) { + const dirReader = item.createReader(); + dirReader.readEntries(async (entries: any[]) => { + for (let i = 0; i < entries.length; i++) { + await traverseFileTree(entries[i]); + } + resolve(); + }); + } + }); + }; + + for (let i = 0; i < items.length; i++) { + const item = items[i].webkitGetAsEntry(); + if (item) { + await traverseFileTree(item); + } + } + } else { + const files = Array.from(e.dataTransfer.files); + let isErr = files.some((item) => item.type === ''); + if (isErr) { + return toast({ + title: t('file.upload error description'), + status: 'error' + }); + } + + for (let i = 0; i < files.length; i++) { + fileList.push(files[i]); + } + } + + onSelectFile(fileList); + }, []); + return ( - {/* 拖拽文件至此,或{' '} */} - 点击 - - 选择文件 - + {isDragging ? ( + t('file.Release the mouse to upload the file') + ) : ( + + {t('file.Drag and drop')} + + {t('file.select a document')} + + + )} - 支持 {fileExtension} 文件 + {t('file.support', { fileExtension: fileExtension })} {tipText && ( - {tipText} + {t(tipText)} )} {isCsv && ( @@ -72,7 +148,7 @@ const FileSelect = ({ }) } > - 点击下载 CSV 模板 + {t('file.Click to download CSV template')} )}