diff --git a/src/components/FileDescriptionDialog.tsx b/src/components/FileDescriptionDialog.tsx new file mode 100644 index 0000000..3eef32d --- /dev/null +++ b/src/components/FileDescriptionDialog.tsx @@ -0,0 +1,179 @@ +import { useState, useEffect } from 'react'; +import { queryApi as projectApi } from '@/modules/project-api'; +import { toast } from 'sonner'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Textarea } from '@/components/ui/textarea'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; + +const API_URL = '/root/v1/dev-cnb'; + +export type FileDescriptionData = { + filepath: string; + title?: string; + tags?: string[]; + summary?: string; + description?: string; + link?: string; +}; + +interface FileDescriptionDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + data: FileDescriptionData; + onSuccess?: () => void; +} + +export function FileDescriptionDialog({ + open, + onOpenChange, + data, + onSuccess, +}: FileDescriptionDialogProps) { + const [loading, setLoading] = useState(false); + const [formData, setFormData] = useState({ + filepath: data.filepath, + title: '', + tags: [], + summary: '', + description: '', + link: '', + }); + + // 当打开对话框或数据变化时,同步数据 + useEffect(() => { + if (open && data.filepath) { + setFormData({ + filepath: data.filepath, + title: data.title || '', + tags: data.tags || [], + summary: data.summary || '', + description: data.description || '', + link: data.link || '', + }); + } + }, [open, data]); + + const handleSave = async () => { + setLoading(true); + try { + // 过滤掉空值 + const updateData: Partial = { + filepath: formData.filepath, + }; + if (formData.title) updateData.title = formData.title; + if (formData.tags && formData.tags.length > 0) updateData.tags = formData.tags; + if (formData.summary) updateData.summary = formData.summary; + if (formData.description) updateData.description = formData.description; + if (formData.link) updateData.link = formData.link; + + const res = await projectApi['project-file']['update'](updateData, { url: API_URL }); + if (res.code === 200) { + toast.success('保存成功'); + onOpenChange(false); + onSuccess?.(); + } else { + toast.error(res.message ?? '保存失败'); + } + } catch { + toast.error('保存失败'); + } finally { + setLoading(false); + } + }; + + const handleTagsChange = (value: string) => { + // 标签以逗号分隔 + const tags = value.split(',').map((t) => t.trim()).filter(Boolean); + setFormData((prev) => ({ ...prev, tags })); + }; + + return ( + + + + 编辑文件描述 + +
+ {/* 文件路径(只读) */} +
+ + +
+ + {/* 标题 */} +
+ + setFormData((prev) => ({ ...prev, title: e.target.value }))} + placeholder="输入文件标题" + /> +
+ + {/* 标签 */} +
+ + handleTagsChange(e.target.value)} + placeholder="输入标签,用逗号分隔" + /> + 多个标签用逗号分隔 +
+ + {/* 摘要 */} +
+ + setFormData((prev) => ({ ...prev, summary: e.target.value }))} + placeholder="简短描述文件内容" + /> +
+ + {/* 链接 */} +
+ + setFormData((prev) => ({ ...prev, link: e.target.value }))} + placeholder="关联的外部链接(如文档、Issue 等)" + /> +
+ + {/* 描述 */} +
+ +