архитектура добавления элементов, список эталонов
This commit is contained in:
@@ -17,7 +17,12 @@ export const ElementsCreation: FC = () => {
|
||||
};
|
||||
|
||||
const handleElementAdd = (element: TemplateElement) => {
|
||||
if (!selectedTemplate) return;
|
||||
console.log('handleElementAdd called with element:', element);
|
||||
|
||||
if (!selectedTemplate) {
|
||||
console.log('No selected template');
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedTemplate = {
|
||||
...selectedTemplate,
|
||||
@@ -25,6 +30,9 @@ export const ElementsCreation: FC = () => {
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
console.log('Updated template:', updatedTemplate);
|
||||
console.log('Elements count:', updatedTemplate.elements.length);
|
||||
|
||||
updateTemplate(updatedTemplate);
|
||||
setSelectedTemplate(updatedTemplate);
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { FC } from "react";
|
||||
import { DualSpreadsheet } from "../../../../components";
|
||||
import { exampleCalculationsData, exampleTemplateData } from "../../../../lib/template-data";
|
||||
// import { exampleCalculationsData, exampleTemplateData } from "../../../../lib/template-data";
|
||||
|
||||
const Home: FC = () => {
|
||||
const initialData = {
|
||||
Report: exampleTemplateData,
|
||||
Calculations: exampleCalculationsData
|
||||
Report: {},
|
||||
Calculations: {}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,17 +1,95 @@
|
||||
import { ArrowLeft, Download, FileText, Plus, Save } from 'lucide-react';
|
||||
import { ArrowLeft, Download, FileText, Plus, Save, Settings, Wrench } from 'lucide-react';
|
||||
import { FC, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { StandardsSelector } from '../../../../components/StandardsElement/StandardsSelector';
|
||||
import { Badge } from '../../../../components/ui/badge';
|
||||
import { Button } from '../../../../components/ui/button';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../../../components/ui/card';
|
||||
import { Checkbox } from '../../../../components/ui/checkbox';
|
||||
import { Input } from '../../../../components/ui/input';
|
||||
import { Label } from '../../../../components/ui/label';
|
||||
import { RadioGroup, RadioGroupItem } from '../../../../components/ui/radio-group';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../../components/ui/select';
|
||||
import { Textarea } from '../../../../components/ui/textarea';
|
||||
import { useTemplateContext } from '../../../../contexts/TemplateContext';
|
||||
import { Template, TemplateElement } from '../../../../types/template';
|
||||
|
||||
// Моковые данные для эталонов (такие же как в StandardsSelector)
|
||||
const mockStandards = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Эталон массы 1 кг",
|
||||
shortName: "ЭМ-1кг",
|
||||
type: "Масса",
|
||||
registryNumber: "ГРСИ 12345-01",
|
||||
range: "0.5-2 кг",
|
||||
accuracy: "±0.001 г",
|
||||
certificateNumber: "СИ-2024-001",
|
||||
validUntil: "2025-12-31",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Эталон длины 1 м",
|
||||
shortName: "ЭД-1м",
|
||||
type: "Длина",
|
||||
registryNumber: "ГРСИ 12345-02",
|
||||
range: "0.5-2 м",
|
||||
accuracy: "±0.001 мм",
|
||||
certificateNumber: "СИ-2024-002",
|
||||
validUntil: "2025-06-30",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Эталон температуры 20°C",
|
||||
shortName: "ЭТ-20°C",
|
||||
type: "Температура",
|
||||
registryNumber: "ГРСИ 12345-03",
|
||||
range: "15-25°C",
|
||||
accuracy: "±0.01°C",
|
||||
certificateNumber: "СИ-2024-003",
|
||||
validUntil: "2025-03-15",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "Эталон давления 1 Па",
|
||||
shortName: "ЭД-1Па",
|
||||
type: "Давление",
|
||||
registryNumber: "ГРСИ 12345-04",
|
||||
range: "0.5-2 Па",
|
||||
accuracy: "±0.001 Па",
|
||||
certificateNumber: "СИ-2024-004",
|
||||
validUntil: "2025-09-20",
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
name: "Эталон времени 1 с",
|
||||
shortName: "ЭВ-1с",
|
||||
type: "Время",
|
||||
registryNumber: "ГРСИ 12345-05",
|
||||
range: "0.5-2 с",
|
||||
accuracy: "±0.000001 с",
|
||||
certificateNumber: "СИ-2024-005",
|
||||
validUntil: "2025-12-01",
|
||||
},
|
||||
];
|
||||
|
||||
// Функция для получения данных эталона по ID
|
||||
const getStandardById = (id: string) => {
|
||||
return mockStandards.find(standard => standard.id === id);
|
||||
};
|
||||
|
||||
// Функция для получения типа эталона в сокращенном виде
|
||||
const getStandardTypeBadge = (type: string) => {
|
||||
switch (type) {
|
||||
case "Манометр грузопоршневой":
|
||||
return "МГП";
|
||||
case "Калибратор давления":
|
||||
return "КД";
|
||||
default:
|
||||
return "МО";
|
||||
}
|
||||
};
|
||||
|
||||
interface ProtocolFormProps {
|
||||
template: Template;
|
||||
onSave: (data: Record<string, any>) => void;
|
||||
@@ -25,6 +103,8 @@ interface FormElementProps {
|
||||
}
|
||||
|
||||
const FormElement: FC<FormElementProps> = ({ element, value, onChange }) => {
|
||||
const [isStandardsDialogOpen, setIsStandardsDialogOpen] = useState(false);
|
||||
|
||||
const renderInput = () => {
|
||||
switch (element.type) {
|
||||
case 'text':
|
||||
@@ -113,6 +193,76 @@ const FormElement: FC<FormElementProps> = ({ element, value, onChange }) => {
|
||||
</div>
|
||||
);
|
||||
|
||||
case 'standards':
|
||||
const selectedStandards = Array.isArray(value) ? value : [];
|
||||
const selectedStandardsData = selectedStandards
|
||||
.map(id => getStandardById(id))
|
||||
.filter(Boolean);
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
{/* Блок с измерительными эталонами */}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<Label className="text-sm font-medium">Эталоны</Label>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setIsStandardsDialogOpen(true)}
|
||||
className="h-7 px-2"
|
||||
>
|
||||
<Settings className="w-3 h-3 mr-1" />
|
||||
Настроить
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
{selectedStandardsData.length > 0 ? (
|
||||
<div className="space-y-1.5">
|
||||
{selectedStandardsData.map((standard, index) => (
|
||||
standard && (
|
||||
<div
|
||||
key={standard.id}
|
||||
className="flex items-center gap-2 p-2 bg-muted/30 rounded-md text-sm"
|
||||
>
|
||||
<div className="w-5 h-5 rounded-full bg-primary/10 flex items-center justify-center shrink-0">
|
||||
<span className="text-xs font-medium text-primary">{index + 1}</span>
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-medium text-xs text-foreground truncate">
|
||||
{standard.shortName}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{standard.accuracy} • {standard.range}
|
||||
</div>
|
||||
</div>
|
||||
<Badge variant="secondary" className="text-xs shrink-0">
|
||||
<Wrench className="w-3 h-3 mr-1" />
|
||||
{getStandardTypeBadge(standard.type)}
|
||||
</Badge>
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-sm text-muted-foreground bg-muted/30 rounded-md p-3 border border-dashed text-center">
|
||||
<Settings className="w-4 h-4 mx-auto mb-1 opacity-50" />
|
||||
Эталоны не выбраны
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<StandardsSelector
|
||||
isOpen={isStandardsDialogOpen}
|
||||
onClose={() => setIsStandardsDialogOpen(false)}
|
||||
value={selectedStandards}
|
||||
onChange={onChange}
|
||||
registryNumber={element.targetCells?.[0]?.displayName || "ГРСИ 12345"}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -125,7 +275,7 @@ const FormElement: FC<FormElementProps> = ({ element, value, onChange }) => {
|
||||
{element.label}
|
||||
</label>
|
||||
{element.required && (
|
||||
<Badge variant="required" className="text-xs">
|
||||
<Badge variant="destructive" className="text-xs">
|
||||
!
|
||||
</Badge>
|
||||
)}
|
||||
@@ -136,7 +286,7 @@ const FormElement: FC<FormElementProps> = ({ element, value, onChange }) => {
|
||||
{element.targetCells.map((target, index) => (
|
||||
<Badge
|
||||
key={index}
|
||||
variant="excel"
|
||||
variant="secondary"
|
||||
className="text-xs font-mono"
|
||||
title={target.displayName}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user