Files
protoc-frontend/src/component/VerificationConditionsElement/VerificationConditionsEditor.tsx

228 lines
8.8 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.
import { Badge } from '@/component/ui/badge'
import { Card, CardContent, CardHeader, CardTitle } from '@/component/ui/card'
import { Label } from '@/component/ui/label'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/component/ui/select'
import { Building2, Target } from 'lucide-react'
import { useLaboratories } from './hooks'
import { mockApiHelpers } from './mockData'
import { ConditionCellMapping, VerificationConditionsConfig } from './types'
interface VerificationConditionsEditorProps {
config: VerificationConditionsConfig
onChange: (config: VerificationConditionsConfig) => void
}
export function VerificationConditionsEditor({
config,
onChange,
}: VerificationConditionsEditorProps) {
const { data: laboratories = [], isLoading } = useLaboratories()
const updateConfig = (updates: Partial<VerificationConditionsConfig>) => {
onChange({ ...config, ...updates })
}
// Получаем выбранную лабораторию
const selectedLab = laboratories.find(
lab => lab.id === config.selectedLaboratoryId
)
// Получаем все доступные условия (либо все из БД, либо условия конкретной лаборатории)
const availableConditions = config.selectedLaboratoryId
? mockApiHelpers.getLaboratoryConditions(config.selectedLaboratoryId)
: mockApiHelpers.getAllConditions()
// Обновление привязки условия к ячейке
const updateConditionMapping = (cellIndex: number, conditionKey: string) => {
const conditionName =
availableConditions.find(c => c.key === conditionKey)?.name ||
conditionKey
const newMappings = [...(config.conditionMappings || [])]
const existingIndex = newMappings.findIndex(m => m.cellIndex === cellIndex)
if (conditionKey === '__none__') {
// Убираем привязку
if (existingIndex >= 0) {
newMappings.splice(existingIndex, 1)
}
} else {
// Добавляем или обновляем привязку
const mapping: ConditionCellMapping = {
cellIndex,
conditionKey,
conditionName,
}
if (existingIndex >= 0) {
newMappings[existingIndex] = mapping
} else {
newMappings.push(mapping)
}
}
updateConfig({ conditionMappings: newMappings })
}
// Получить выбранное условие для ячейки
const getSelectedCondition = (cellIndex: number): string => {
const mapping = config.conditionMappings?.find(
m => m.cellIndex === cellIndex
)
return mapping?.conditionKey || '__none__'
}
return (
<div className="space-y-4">
{/* Выбор лаборатории */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Building2 className="h-4 w-4" />
Лаборатория
</CardTitle>
</CardHeader>
<CardContent>
<div>
<Label htmlFor="laboratory">Выберите лабораторию</Label>
<Select
value={config.selectedLaboratoryId?.toString() || '__none__'}
onValueChange={value => {
const laboratoryId =
value === '__none__' ? undefined : parseInt(value)
updateConfig({
selectedLaboratoryId: laboratoryId,
conditionMappings: [], // Сбрасываем привязки при смене лаборатории
})
}}
>
<SelectTrigger>
<SelectValue placeholder="Выберите лабораторию" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__">Все условия из БД</SelectItem>
{laboratories.map(lab => (
<SelectItem key={lab.id} value={lab.id.toString()}>
{lab.name}
</SelectItem>
))}
</SelectContent>
</Select>
<p className="mt-1 text-xs text-muted-foreground">
{config.selectedLaboratoryId
? 'Доступны только условия выбранной лаборатории'
: 'Доступны все условия из базы данных'}
</p>
</div>
</CardContent>
</Card>
{/* Привязка условий к ячейкам */}
{config.targetCells.length > 0 && (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Target className="h-4 w-4" />
Привязка условий к ячейкам
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="rounded-md bg-blue-50 p-3 text-sm text-blue-800 dark:bg-blue-950 dark:text-blue-200">
<p className="font-medium">Настройка записи данных</p>
<p className="mt-1">
Выберите какое условие будет записываться в каждую целевую
ячейку.
</p>
</div>
<div className="space-y-3">
{config.targetCells.map((cell, index) => (
<div
key={index}
className="flex items-center gap-3 rounded-md border p-3"
>
<Badge variant="outline" className="shrink-0">
{cell.sheet}!{cell.cell}
</Badge>
<div className="flex-1">
<Label className="text-xs text-muted-foreground">
Ячейка {index + 1} - выберите условие:
</Label>
<Select
value={getSelectedCondition(index)}
onValueChange={value =>
updateConditionMapping(index, value)
}
>
<SelectTrigger className="mt-1">
<SelectValue placeholder="Выберите условие" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__">Не выбрано</SelectItem>
{availableConditions.map(condition => (
<SelectItem key={condition.key} value={condition.key}>
<div className="flex items-center gap-2">
<span>{condition.name}</span>
{condition.unit && (
<Badge variant="secondary" className="text-xs">
{condition.unit}
</Badge>
)}
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
))}
</div>
{/* Подсказка с доступными условиями */}
<div className="rounded-md bg-muted/50 p-3 text-sm text-muted-foreground">
<p className="font-medium">
Доступные условия{' '}
{selectedLab ? `для ${selectedLab.name}` : 'из базы данных'}:
</p>
<ul className="mt-1 space-y-1">
{availableConditions.map(condition => (
<li key={condition.key}>
<strong>{condition.name}</strong>
{condition.unit && ` (${condition.unit})`}
{'isRequired' in condition &&
condition.isRequired &&
' - обязательное'}
</li>
))}
</ul>
</div>
</CardContent>
</Card>
)}
{/* Подсказка если нет целевых ячеек */}
{config.targetCells.length === 0 && (
<Card>
<CardContent className="pt-6">
<div className="text-center text-sm text-muted-foreground">
<Target className="mx-auto mb-2 h-8 w-8 opacity-50" />
<p className="font-medium">Целевые ячейки не настроены</p>
<p className="mt-1">
Сначала настройте целевые ячейки в основном редакторе элементов,
затем вернитесь сюда для привязки условий.
</p>
</div>
</CardContent>
</Card>
)}
</div>
)
}