Commit
·
e507e4c
1
Parent(s):
7c4651b
� ENHANCE FILE UPLOAD: Allow document upload without assistant
Browse files✅ 改进文档上传功能:
- � 移除必须选择Assistant才能上传文档的限制
- � 文字改为 "Drag or drop a file"
- � 现在可以直接上传文档到知识库
- � 支持在没有选择Assistant时查看所有已上传文档
� 用户体验提升:
- 更直观的文件上传界面
- 无需预先选择Assistant即可管理文档
- 符合用户期望的拖拽上传体验
� My Device页面文档管理更加灵活!
frontend/src/components/playground/DocumentsTab.tsx
CHANGED
|
@@ -47,7 +47,26 @@ export function DocumentsTab({
|
|
| 47 |
useEffect(() => {
|
| 48 |
const loadDocuments = async () => {
|
| 49 |
if (!currentAssistant) {
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
return
|
| 52 |
}
|
| 53 |
|
|
@@ -82,15 +101,17 @@ export function DocumentsTab({
|
|
| 82 |
|
| 83 |
const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
| 84 |
const files = event.target.files
|
| 85 |
-
if (!files
|
| 86 |
|
| 87 |
setIsUploading(true)
|
| 88 |
|
| 89 |
try {
|
| 90 |
const formData = new FormData()
|
| 91 |
|
| 92 |
-
// Add assistant ID to the upload
|
| 93 |
-
|
|
|
|
|
|
|
| 94 |
|
| 95 |
for (const file of Array.from(files)) {
|
| 96 |
formData.append('files', file)
|
|
@@ -162,11 +183,81 @@ export function DocumentsTab({
|
|
| 162 |
<div className="space-y-4 pb-6">
|
| 163 |
{!currentAssistant ? (
|
| 164 |
<Card>
|
| 165 |
-
<
|
| 166 |
-
<
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
</CardContent>
|
| 171 |
</Card>
|
| 172 |
) : (
|
|
|
|
| 47 |
useEffect(() => {
|
| 48 |
const loadDocuments = async () => {
|
| 49 |
if (!currentAssistant) {
|
| 50 |
+
// Load all documents when no assistant is selected
|
| 51 |
+
try {
|
| 52 |
+
const response = await fetch('/rag/documents')
|
| 53 |
+
if (response.ok) {
|
| 54 |
+
const data = await response.json()
|
| 55 |
+
const allFiles: UploadedFile[] = data.documents.map((doc: any) => ({
|
| 56 |
+
id: doc.id,
|
| 57 |
+
name: doc.filename,
|
| 58 |
+
size: doc.size || 0,
|
| 59 |
+
type: doc.content_type || 'application/octet-stream',
|
| 60 |
+
uploadedAt: doc.upload_date,
|
| 61 |
+
status: 'processed',
|
| 62 |
+
chunks: doc.chunk_count,
|
| 63 |
+
assistantId: doc.assistant_id
|
| 64 |
+
}))
|
| 65 |
+
setUploadedFiles(allFiles)
|
| 66 |
+
}
|
| 67 |
+
} catch (error) {
|
| 68 |
+
console.error('Error loading documents:', error)
|
| 69 |
+
}
|
| 70 |
return
|
| 71 |
}
|
| 72 |
|
|
|
|
| 101 |
|
| 102 |
const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
| 103 |
const files = event.target.files
|
| 104 |
+
if (!files) return
|
| 105 |
|
| 106 |
setIsUploading(true)
|
| 107 |
|
| 108 |
try {
|
| 109 |
const formData = new FormData()
|
| 110 |
|
| 111 |
+
// Add assistant ID to the upload (if available)
|
| 112 |
+
if (currentAssistant) {
|
| 113 |
+
formData.append('assistant_id', currentAssistant.id)
|
| 114 |
+
}
|
| 115 |
|
| 116 |
for (const file of Array.from(files)) {
|
| 117 |
formData.append('files', file)
|
|
|
|
| 183 |
<div className="space-y-4 pb-6">
|
| 184 |
{!currentAssistant ? (
|
| 185 |
<Card>
|
| 186 |
+
<CardHeader>
|
| 187 |
+
<CardTitle className="flex items-center gap-2">
|
| 188 |
+
<BookOpen className="h-4 w-4 text-blue-600" />
|
| 189 |
+
<span>Documents & Knowledge Base</span>
|
| 190 |
+
</CardTitle>
|
| 191 |
+
</CardHeader>
|
| 192 |
+
<CardContent className="space-y-4">
|
| 193 |
+
{/* Upload Area */}
|
| 194 |
+
<div className="border-2 border-dashed border-gray-200 rounded-lg p-6 text-center hover:border-gray-300 transition-colors">
|
| 195 |
+
<input
|
| 196 |
+
type="file"
|
| 197 |
+
id="file-upload"
|
| 198 |
+
multiple
|
| 199 |
+
accept=".pdf,.txt,.docx,.md"
|
| 200 |
+
onChange={handleFileUpload}
|
| 201 |
+
className="hidden"
|
| 202 |
+
disabled={isUploading || isLoading}
|
| 203 |
+
/>
|
| 204 |
+
<Label
|
| 205 |
+
htmlFor="file-upload"
|
| 206 |
+
className="cursor-pointer flex flex-col items-center space-y-2"
|
| 207 |
+
>
|
| 208 |
+
<Upload className="h-8 w-8 text-gray-400" />
|
| 209 |
+
<span className="text-sm font-medium">
|
| 210 |
+
{isUploading ? 'Uploading...' : 'Drag or drop a file'}
|
| 211 |
+
</span>
|
| 212 |
+
<span className="text-xs text-muted-foreground">
|
| 213 |
+
PDF, TXT, DOCX, MD supported
|
| 214 |
+
</span>
|
| 215 |
+
</Label>
|
| 216 |
+
</div>
|
| 217 |
+
|
| 218 |
+
{/* Documents List */}
|
| 219 |
+
{uploadedFiles.length > 0 && (
|
| 220 |
+
<div className="space-y-2">
|
| 221 |
+
<Label className="text-sm font-medium">Documents ({uploadedFiles.length})</Label>
|
| 222 |
+
|
| 223 |
+
<div className="space-y-1">
|
| 224 |
+
{uploadedFiles.map((file) => (
|
| 225 |
+
<div
|
| 226 |
+
key={file.id}
|
| 227 |
+
className="flex items-center justify-between p-2 border rounded bg-gray-50/50 hover:bg-gray-50"
|
| 228 |
+
>
|
| 229 |
+
<div className="flex items-center space-x-2 flex-1 min-w-0">
|
| 230 |
+
<File className="h-3 w-3 text-blue-600 flex-shrink-0" />
|
| 231 |
+
<span className="text-sm truncate">{file.name}</span>
|
| 232 |
+
{file.chunks && (
|
| 233 |
+
<span className="text-xs text-muted-foreground flex-shrink-0">
|
| 234 |
+
{file.chunks} chunks
|
| 235 |
+
</span>
|
| 236 |
+
)}
|
| 237 |
+
</div>
|
| 238 |
+
<Button
|
| 239 |
+
size="sm"
|
| 240 |
+
variant="ghost"
|
| 241 |
+
onClick={() => removeFile(file.id)}
|
| 242 |
+
disabled={isLoading}
|
| 243 |
+
className="h-6 w-6 p-0 text-red-500 hover:text-red-600 hover:bg-red-50"
|
| 244 |
+
>
|
| 245 |
+
<X className="h-3 w-3" />
|
| 246 |
+
</Button>
|
| 247 |
+
</div>
|
| 248 |
+
))}
|
| 249 |
+
</div>
|
| 250 |
+
</div>
|
| 251 |
+
)}
|
| 252 |
+
|
| 253 |
+
{/* Empty State */}
|
| 254 |
+
{uploadedFiles.length === 0 && (
|
| 255 |
+
<div className="text-center py-3">
|
| 256 |
+
<p className="text-xs text-muted-foreground">
|
| 257 |
+
No documents uploaded yet
|
| 258 |
+
</p>
|
| 259 |
+
</div>
|
| 260 |
+
)}
|
| 261 |
</CardContent>
|
| 262 |
</Card>
|
| 263 |
) : (
|
static/assets/index-7336e918.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/assets/index-7336e918.js.map
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Edge LLM</title>
|
| 8 |
-
<script type="module" crossorigin src="/assets/index-
|
| 9 |
<link rel="stylesheet" href="/assets/index-529e312c.css">
|
| 10 |
</head>
|
| 11 |
<body>
|
|
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Edge LLM</title>
|
| 8 |
+
<script type="module" crossorigin src="/assets/index-7336e918.js"></script>
|
| 9 |
<link rel="stylesheet" href="/assets/index-529e312c.css">
|
| 10 |
</head>
|
| 11 |
<body>
|