215 lines
9.4 KiB
TypeScript
215 lines
9.4 KiB
TypeScript
/**
|
||
* filekorolheader: 查看参数对话框 - 参数详情展示组件
|
||
* 功能:展示参数详细信息、参数配置、选项列表
|
||
* 路径:/ai-crop-model/data-sense-center/device-parameter/components
|
||
* 规范:遵循crop-x/docs/开发项目规范.md,使用shadcn语义化样式
|
||
*/
|
||
|
||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog';
|
||
import { Button } from '@/components/ui/button';
|
||
import { Badge } from '@/components/ui/badge';
|
||
import { Card } from '@/components/ui/card';
|
||
import { ParameterDefinition, DeviceType } from './deviceParameterReducer';
|
||
import { Eye, Settings, Hash } from 'lucide-react';
|
||
|
||
interface ViewParameterDialogProps {
|
||
open: boolean;
|
||
onOpenChange: (open: boolean) => void;
|
||
viewingParam: ParameterDefinition | null;
|
||
selectedType: DeviceType | null;
|
||
}
|
||
|
||
export function ViewParameterDialog({ open, onOpenChange, viewingParam, selectedType }: ViewParameterDialogProps) {
|
||
const getParamTypeLabel = (type: string) => {
|
||
const labels: Record<string, string> = {
|
||
'number': '数字',
|
||
'string': '文本',
|
||
'boolean': '布尔',
|
||
'select': '选择'
|
||
};
|
||
return labels[type] || type;
|
||
};
|
||
|
||
const getParamTypeColor = (type: string) => {
|
||
const colors: Record<string, string> = {
|
||
'number': 'border-blue-200 dark:border-blue-800 text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-950',
|
||
'string': 'border-green-200 dark:border-green-800 text-green-700 dark:text-green-300 bg-green-50 dark:bg-green-950',
|
||
'boolean': 'border-purple-200 dark:border-purple-800 text-purple-700 dark:text-purple-300 bg-purple-50 dark:bg-purple-950',
|
||
'select': 'border-orange-200 dark:border-orange-800 text-orange-700 dark:text-orange-300 bg-orange-50 dark:bg-orange-950'
|
||
};
|
||
return colors[type] || 'border-gray-200 dark:border-gray-800 text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-950';
|
||
};
|
||
|
||
return (
|
||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
||
<DialogHeader>
|
||
<DialogTitle className="flex items-center gap-2 text-xl">
|
||
<Eye className="w-5 h-5" />
|
||
参数详情
|
||
</DialogTitle>
|
||
<DialogDescription>
|
||
查看参数的详细配置信息
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
|
||
{viewingParam && (
|
||
<div className="space-y-6">
|
||
{/* 参数基本信息 */}
|
||
<Card className="p-4">
|
||
<div className="flex items-center gap-2 mb-4">
|
||
<Hash className="w-5 h-5 text-primary" />
|
||
<h3 className="text-lg font-medium">基本信息</h3>
|
||
</div>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">参数标识</div>
|
||
<div className="font-mono text-sm font-medium bg-muted p-2 rounded">
|
||
{viewingParam.key}
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">参数名称</div>
|
||
<div className="font-medium text-base">{viewingParam.label}</div>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">数据类型</div>
|
||
<Badge
|
||
variant="outline"
|
||
className={`font-light ${getParamTypeColor(viewingParam.type)}`}
|
||
>
|
||
{getParamTypeLabel(viewingParam.type)}
|
||
</Badge>
|
||
</div>
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">是否必填</div>
|
||
{viewingParam.required ? (
|
||
<Badge className="bg-red-50 dark:bg-red-950 text-red-600 dark:text-red-400 border-red-200 dark:border-red-800 font-light">
|
||
必填
|
||
</Badge>
|
||
) : (
|
||
<span className="text-muted-foreground text-sm font-light">选填</span>
|
||
)}
|
||
</div>
|
||
<div className="md:col-span-2">
|
||
<div className="text-sm text-muted-foreground mb-1">参数描述</div>
|
||
<div className="text-sm bg-muted/30 p-3 rounded">
|
||
{viewingParam.description || '暂无描述'}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* 参数配置 */}
|
||
<Card className="p-4">
|
||
<div className="flex items-center gap-2 mb-4">
|
||
<Settings className="w-5 h-5 text-primary" />
|
||
<h3 className="text-lg font-medium">参数配置</h3>
|
||
</div>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">默认值</div>
|
||
<div className="bg-muted/30 p-3 rounded">
|
||
{viewingParam.type === 'boolean' ? (
|
||
<Badge
|
||
variant={viewingParam.defaultValue ? 'default' : 'secondary'}
|
||
className="font-light"
|
||
>
|
||
{viewingParam.defaultValue ? '是' : '否'}
|
||
</Badge>
|
||
) : viewingParam.type === 'select' && viewingParam.options ? (
|
||
<div>
|
||
<span className="font-medium">
|
||
{viewingParam.options.find(opt => opt.value === viewingParam.defaultValue)?.label || viewingParam.defaultValue}
|
||
</span>
|
||
<div className="text-xs text-muted-foreground mt-1">
|
||
值: {viewingParam.defaultValue}
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<span className="font-medium">
|
||
{viewingParam.defaultValue?.toString() || '-'}
|
||
</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{viewingParam.unit && (
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">单位</div>
|
||
<div className="bg-muted/30 p-3 rounded font-medium">
|
||
{viewingParam.unit}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{viewingParam.type === 'number' && (viewingParam.min !== undefined || viewingParam.max !== undefined) && (
|
||
<div className="md:col-span-2">
|
||
<div className="text-sm text-muted-foreground mb-1">取值范围</div>
|
||
<div className="bg-muted/30 p-3 rounded font-medium">
|
||
{viewingParam.min !== undefined && viewingParam.max !== undefined
|
||
? `${viewingParam.min} ~ ${viewingParam.max}`
|
||
: viewingParam.min !== undefined
|
||
? `≥ ${viewingParam.min}`
|
||
: viewingParam.max !== undefined
|
||
? `≤ ${viewingParam.max}`
|
||
: '-'}
|
||
{viewingParam.unit && ` ${viewingParam.unit}`}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</Card>
|
||
|
||
{/* 选择类型选项 */}
|
||
{viewingParam.type === 'select' && viewingParam.options && (
|
||
<Card className="p-4">
|
||
<div className="flex items-center gap-2 mb-4">
|
||
<Settings className="w-5 h-5 text-primary" />
|
||
<h3 className="text-lg font-medium">选项列表</h3>
|
||
<Badge variant="outline" className="font-light">
|
||
{viewingParam.options.length} 个选项
|
||
</Badge>
|
||
</div>
|
||
<div className="space-y-2">
|
||
{viewingParam.options.map((option, index) => (
|
||
<div key={index} className="flex items-center justify-between p-3 bg-muted/30 rounded">
|
||
<div>
|
||
<span className="font-medium">{option.label}</span>
|
||
<span className="text-muted-foreground text-sm ml-2">
|
||
({option.value})
|
||
</span>
|
||
{viewingParam.defaultValue === option.value && (
|
||
<Badge variant="default" className="ml-2 text-xs">
|
||
默认
|
||
</Badge>
|
||
)}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</Card>
|
||
)}
|
||
|
||
{/* 设备信息 */}
|
||
<Card className="p-4">
|
||
<div className="text-sm text-muted-foreground mb-2">所属设备类型</div>
|
||
<div className="font-medium">{selectedType?.name}</div>
|
||
{selectedType?.manufacturer && (
|
||
<div className="text-sm text-muted-foreground mt-1">
|
||
{selectedType.manufacturer} {selectedType.model ? `· ${selectedType.model}` : ''}
|
||
</div>
|
||
)}
|
||
</Card>
|
||
</div>
|
||
)}
|
||
|
||
<DialogFooter>
|
||
<Button onClick={() => onOpenChange(false)}>
|
||
关闭
|
||
</Button>
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
);
|
||
} |