feat: 字段编辑弹窗添加「完成」按钮 去除关闭按钮,添加取消按钮

- 弹窗底部添加「完成」按钮,点击关闭弹窗
- DialogContent 支持 showCloseButton prop 控制关闭按钮显示
- 底部添加取消和完成两个按钮
This commit is contained in:
雨霖铃
2026-06-06 19:51:46 +08:00
parent 78f5292b00
commit 2464a5fea6
3 changed files with 32 additions and 15 deletions
+4 -4
View File
@@ -1011,10 +1011,6 @@
"message": "数据格式", "message": "数据格式",
"description": "Translation key: testDataGenerator_format" "description": "Translation key: testDataGenerator_format"
}, },
"testDataGenerator_defaultNullRate": {
"message": "默认空值率",
"description": "Translation key: testDataGenerator_defaultNullRate"
},
"testDataGenerator_generate": { "testDataGenerator_generate": {
"message": "生成数据", "message": "生成数据",
"description": "Translation key: testDataGenerator_generate" "description": "Translation key: testDataGenerator_generate"
@@ -1163,6 +1159,10 @@
"message": "确认", "message": "确认",
"description": "Translation key: testDataGenerator_confirm" "description": "Translation key: testDataGenerator_confirm"
}, },
"testDataGenerator_done": {
"message": "完成",
"description": "Translation key: testDataGenerator_done"
},
"testDataGenerator_noSearchResults": { "testDataGenerator_noSearchResults": {
"message": "未找到匹配的规则", "message": "未找到匹配的规则",
"description": "Translation key: testDataGenerator_noSearchResults" "description": "Translation key: testDataGenerator_noSearchResults"
+10 -2
View File
@@ -26,10 +26,16 @@ const DialogOverlay = React.forwardRef<
)); ));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
interface DialogContentProps extends React.ComponentPropsWithoutRef<
typeof DialogPrimitive.Content
> {
showCloseButton?: boolean;
}
const DialogContent = React.forwardRef< const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>, React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> DialogContentProps
>(({ className, children, ...props }, ref) => ( >(({ className, children, showCloseButton = true, ...props }, ref) => (
<DialogPortal> <DialogPortal>
<DialogOverlay /> <DialogOverlay />
<DialogPrimitive.Content <DialogPrimitive.Content
@@ -41,10 +47,12 @@ const DialogContent = React.forwardRef<
{...props} {...props}
> >
{children} {children}
{showCloseButton && (
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"> <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" /> <X className="h-4 w-4" />
<span className="sr-only">Close</span> <span className="sr-only">Close</span>
</DialogPrimitive.Close> </DialogPrimitive.Close>
)}
</DialogPrimitive.Content> </DialogPrimitive.Content>
</DialogPortal> </DialogPortal>
)); ));
+14 -5
View File
@@ -9,6 +9,7 @@ import { cn } from '@/lib/utils';
import { useGenerator } from './hooks/useGenerator'; import { useGenerator } from './hooks/useGenerator';
import type { FieldConfig, GenerateResult } from '@/types/testDataGenerator'; import type { FieldConfig, GenerateResult } from '@/types/testDataGenerator';
import { Dialog, DialogContent } from '@/components/ui/dialog'; import { Dialog, DialogContent } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { toast } from 'sonner'; import { toast } from 'sonner';
// 生成唯一 ID 的辅助函数 // 生成唯一 ID 的辅助函数
@@ -39,7 +40,6 @@ export default function TestDataGeneratorPage() {
// 生成选项 // 生成选项
const [count, setCount] = useState(100); const [count, setCount] = useState(100);
const [format, setFormat] = useState<'json' | 'csv'>('json'); const [format, setFormat] = useState<'json' | 'csv'>('json');
const [defaultNullRate, setDefaultNullRate] = useState(10);
// 当前标签页 // 当前标签页
const [activeTab, setActiveTab] = useState<TabType>('fields'); const [activeTab, setActiveTab] = useState<TabType>('fields');
@@ -206,8 +206,6 @@ export default function TestDataGeneratorPage() {
onCountChange={setCount} onCountChange={setCount}
format={format} format={format}
onFormatChange={setFormat} onFormatChange={setFormat}
defaultNullRate={defaultNullRate}
onDefaultNullRateChange={setDefaultNullRate}
/> />
</div> </div>
@@ -264,8 +262,11 @@ export default function TestDataGeneratorPage() {
{/* 字段编辑弹窗 */} {/* 字段编辑弹窗 */}
<Dialog open={isEditorOpen} onOpenChange={setIsEditorOpen}> <Dialog open={isEditorOpen} onOpenChange={setIsEditorOpen}>
<DialogContent className="w-[calc(100vw-4rem)] max-w-[420px] max-h-[calc(100vh-4rem)] overflow-hidden p-0 pt-8"> <DialogContent
<div className="overflow-y-auto max-h-[calc(100vh-6rem)] px-6 pb-6"> showCloseButton={false}
className="w-[calc(100vw-4rem)] max-w-[420px] max-h-[calc(100vh-4rem)] p-0 pt-6 flex flex-col"
>
<div className="flex-1 overflow-y-auto px-6 pb-4">
{selectedField && selectedIndex !== null && ( {selectedField && selectedIndex !== null && (
<FieldEditor <FieldEditor
field={selectedField} field={selectedField}
@@ -273,6 +274,14 @@ export default function TestDataGeneratorPage() {
/> />
)} )}
</div> </div>
<div className="flex justify-end gap-2 px-6 py-2 border-t shrink-0">
<Button variant="ghost" size="sm" onClick={() => setIsEditorOpen(false)}>
{t('testDataGenerator_cancel')}
</Button>
<Button size="sm" onClick={() => setIsEditorOpen(false)}>
{t('testDataGenerator_done')}
</Button>
</div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
</div> </div>