feat: 数据格式改为按钮组选择
- 移除 Select 下拉框 - 改为 JSON/CSV 按钮组 - 选中状态与生成数量按钮样式统一 feat: 优化空值率设置 - 增加 75% 预设选项 - 设置 100% 时自动设为必填 - 限制输入范围 0-100 fix: 空值率预设改为纯数字显示 - 5%/20%/50%/75% 统一样式 fix: 移除空值率低/中/高 i18n 翻译键 fix: 精简生成数量预设选项 - 移除 10、500 - 保留 50、100、1000、5000、10000
This commit is contained in:
@@ -38,7 +38,14 @@ export default function FieldEditor({ field, onChange }: FieldEditorProps) {
|
||||
};
|
||||
|
||||
const handleNullRateChange = (nullRate: number) => {
|
||||
onChange({ ...field, nullRate });
|
||||
// 限制范围 0-100
|
||||
const clampedRate = Math.max(0, Math.min(100, nullRate));
|
||||
// 设置为 100% 时自动设为必填
|
||||
if (clampedRate === 100) {
|
||||
onChange({ ...field, nullRate: clampedRate, required: true });
|
||||
} else {
|
||||
onChange({ ...field, nullRate: clampedRate });
|
||||
}
|
||||
};
|
||||
|
||||
const handleUniqueChange = (unique: boolean) => {
|
||||
@@ -63,9 +70,10 @@ export default function FieldEditor({ field, onChange }: FieldEditorProps) {
|
||||
};
|
||||
|
||||
const nullRatePresets = [
|
||||
{ label: t('testDataGenerator_nullRateLow'), value: 5 },
|
||||
{ label: t('testDataGenerator_nullRateMedium'), value: 20 },
|
||||
{ label: t('testDataGenerator_nullRateHigh'), value: 50 },
|
||||
{ label: '5%', value: 5 },
|
||||
{ label: '20%', value: 20 },
|
||||
{ label: '50%', value: 50 },
|
||||
{ label: '75%', value: 75 },
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -129,7 +137,12 @@ export default function FieldEditor({ field, onChange }: FieldEditorProps) {
|
||||
<Input
|
||||
type="number"
|
||||
value={field.nullRate}
|
||||
onChange={(e) => handleNullRateChange(Number(e.target.value))}
|
||||
onChange={(e) => {
|
||||
const value = Number(e.target.value);
|
||||
if (value >= 0 && value <= 100) {
|
||||
handleNullRateChange(value);
|
||||
}
|
||||
}}
|
||||
min={0}
|
||||
max={100}
|
||||
step={5}
|
||||
|
||||
@@ -5,13 +5,6 @@
|
||||
|
||||
import { useI18n } from '@/utils/chromeI18n';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
|
||||
interface GenerateOptionsProps {
|
||||
count: number;
|
||||
@@ -22,7 +15,12 @@ interface GenerateOptionsProps {
|
||||
onDefaultNullRateChange: (rate: number) => void;
|
||||
}
|
||||
|
||||
const COUNT_PRESETS = [10, 50, 100, 500, 1000, 5000, 10000];
|
||||
const COUNT_PRESETS = [50, 100, 1000, 5000, 10000];
|
||||
|
||||
const FORMAT_OPTIONS = [
|
||||
{ value: 'json' as const, label: 'JSON' },
|
||||
{ value: 'csv' as const, label: 'CSV' },
|
||||
];
|
||||
|
||||
export default function GenerateOptions({
|
||||
count,
|
||||
@@ -76,15 +74,21 @@ export default function GenerateOptions({
|
||||
<label className="text-sm font-medium text-foreground">
|
||||
{t('testDataGenerator_format')}
|
||||
</label>
|
||||
<Select value={format} onValueChange={(v) => onFormatChange(v as 'json' | 'csv')}>
|
||||
<SelectTrigger className="h-9">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="json">JSON</SelectItem>
|
||||
<SelectItem value="csv">CSV</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="flex gap-2">
|
||||
{FORMAT_OPTIONS.map((option) => (
|
||||
<button
|
||||
key={option.value}
|
||||
onClick={() => onFormatChange(option.value)}
|
||||
className={`flex-1 px-3 py-1.5 text-xs font-medium rounded-md transition-colors ${
|
||||
format === option.value
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'bg-muted text-muted-foreground hover:bg-muted/80'
|
||||
}`}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 默认空值率 */}
|
||||
|
||||
Reference in New Issue
Block a user