Files
smart-cropx-ui/src/app/(app)/ai-crop-model/data-sense-center/device-parameter/components/ViewParameterDialog.tsx
2025-11-10 09:19:56 +08:00

215 lines
9.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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>
);
}