From fda99279d3bcdc0be72f2e6bc45b46e11fcec897 Mon Sep 17 00:00:00 2001 From: tlartem Date: Fri, 18 Jul 2025 08:35:36 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=B5=D1=82=D0=BA=D0=B0=20=D1=82=D0=BE?= =?UTF-8?q?=D1=87=D0=BA=D0=B0=D0=BC=D0=B8=20=D0=B8=20=D0=B2=D1=8B=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TemplateManager/ElementConstructor.tsx | 725 ++++++++++-------- .../TemplateManager/VisualLayoutEditor.tsx | 4 +- src/pages/ElementsCreation/ui/Page/Page.tsx | 209 ++--- src/pages/ProtocolCreation/ui/Page/Page.tsx | 2 +- 4 files changed, 540 insertions(+), 400 deletions(-) diff --git a/src/components/TemplateManager/ElementConstructor.tsx b/src/components/TemplateManager/ElementConstructor.tsx index 52f0991..d0de120 100644 --- a/src/components/TemplateManager/ElementConstructor.tsx +++ b/src/components/TemplateManager/ElementConstructor.tsx @@ -1,58 +1,91 @@ -import { Calendar, LayoutGrid, Plus, Settings, Trash2 } from 'lucide-react'; -import React, { useState } from 'react'; -import { getAvailableElementTypes, getElementDefinition } from '../../lib/element-registry'; -import { autoArrangeElements, findFreePosition, generateDefaultLayout } from '../../lib/utils'; -import { CellTarget, ElementType, FormLayoutSettings, TemplateElement } from '../../types/template'; -import { Button } from '../ui/button'; -import { Checkbox } from '../ui/checkbox'; -import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'; -import { Input } from '../ui/input'; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'; -import { Textarea } from '../ui/textarea'; -import { VisualLayoutEditor } from './VisualLayoutEditor'; +import { Calendar, LayoutGrid, Plus, Settings, Trash2 } from 'lucide-react' +import React, { useState } from 'react' +import { + getAvailableElementTypes, + getElementDefinition, +} from '../../lib/element-registry' +import { + autoArrangeElements, + findFreePosition, + generateDefaultLayout, +} from '../../lib/utils' +import { + CellTarget, + ElementType, + FormLayoutSettings, + TemplateElement, +} from '../../types/template' +import { Button } from '../ui/button' +import { Checkbox } from '../ui/checkbox' +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '../ui/dialog' +import { Input } from '../ui/input' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '../ui/select' +import { Textarea } from '../ui/textarea' +import { VisualLayoutEditor } from './VisualLayoutEditor' interface ElementFormProps { - formData: Partial; - setFormData: React.Dispatch>>; + formData: Partial + setFormData: React.Dispatch>> } const CellTargetEditor: React.FC<{ - targets: CellTarget[]; - onChange: (targets: CellTarget[]) => void; + targets: CellTarget[] + onChange: (targets: CellTarget[]) => void }> = ({ targets, onChange }) => { const handleAddTarget = () => { - onChange([...targets, { sheet: 'L', cell: '', displayName: '' }]); - }; + onChange([...targets, { sheet: 'L', cell: '', displayName: '' }]) + } - const handleUpdateTarget = (index: number, field: keyof CellTarget, value: string) => { + const handleUpdateTarget = ( + index: number, + field: keyof CellTarget, + value: string, + ) => { const updatedTargets = targets.map((target, i) => - i === index ? { ...target, [field]: value } : target - ); - onChange(updatedTargets); - }; + i === index ? { ...target, [field]: value } : target, + ) + onChange(updatedTargets) + } const handleRemoveTarget = (index: number) => { - onChange(targets.filter((_, i) => i !== index)); - }; + onChange(targets.filter((_, i) => i !== index)) + } return (
-
+
{targets.map((target, index) => ( -
-
+
+
- +
- + handleUpdateTarget(index, 'cell', e.target.value)} + onChange={(e) => + handleUpdateTarget(index, 'cell', e.target.value) + } className="h-8" />
- + handleUpdateTarget(index, 'displayName', e.target.value)} + onChange={(e) => + handleUpdateTarget(index, 'displayName', e.target.value) + } className="h-8" />
@@ -90,27 +131,31 @@ const CellTargetEditor: React.FC<{ onClick={() => handleRemoveTarget(index)} className="h-6 text-xs text-red-600 hover:text-red-700" > - + Удалить
))} {targets.length === 0 && ( -

+

Добавьте ячейки для связи с элементом

)}
- ); -}; + ) +} // Live Preview компонент -const ElementPreview: React.FC<{ element: Partial }> = ({ element }) => { - const elementDefinition = element.type ? getElementDefinition(element.type) : null; +const ElementPreview: React.FC<{ element: Partial }> = ({ + element, +}) => { + const elementDefinition = element.type + ? getElementDefinition(element.type) + : null if (elementDefinition && elementDefinition.Preview) { - return ; + return } // Fallback для старых элементов @@ -123,8 +168,8 @@ const ElementPreview: React.FC<{ element: Partial }> = ({ eleme disabled className="w-full" /> - ); - + ) + case 'textarea': return (