все к лучшему

This commit is contained in:
2025-07-22 08:34:05 +03:00
parent 3a1bb42aee
commit abc2ee44bd
9 changed files with 440 additions and 90 deletions

View File

@@ -17,17 +17,10 @@ import { Textarea } from '@/component/ui/textarea'
import { useTemplateContext } from '@/entitiy/template/model/TemplateContext'
import { cellAddressToCoordinates } from '@/lib/cell-utils'
import { getElementDefinition } from '@/lib/element-registry'
import { useToast } from '@/lib/hooks/useToast'
import { getLatestFileForTemplate } from '@/service/fileApiService'
import { Template, TemplateElement } from '@/type/template'
import {
ArrowLeft,
Download,
FileText,
Grid,
Save,
Settings,
Wrench,
} from 'lucide-react'
import { ArrowLeft, FileText, Grid, Save, Settings, Wrench } from 'lucide-react'
import { FC, useEffect, useMemo, useRef, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
@@ -371,6 +364,7 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
const [formData, setFormData] = useState<Record<string, any>>({})
const [showSpreadsheet, setShowSpreadsheet] = useState(false)
const engineRef = useRef<any>(null)
const toast = useToast()
const handleFieldChange = (elementId: string, value: any) => {
setFormData(prev => ({
@@ -443,7 +437,7 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
try {
if (!engineRef.current) {
alert('Движок ещё не инициализирован')
toast.error('Движок ещё не инициализирован')
return
}
@@ -469,7 +463,9 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
cells.forEach((tc, idx) => {
const cellValue = getStandardById(value[idx] as string)?.name || ''
const { row, col } = cellAddressToCoordinates(tc.cell)
if (tc.sheet === 'Calculations') alert('Лист Calculations')
if (tc.sheet === 'Calculations') {
toast.warning('Обнаружен лист Calculations')
}
const sheetName =
tc.sheet === 'R' || tc.sheet === 'Calculations' ? 'R' : 'L'
engineRef.current.setCellValueWithoutRecalc(
@@ -564,7 +560,7 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
// Получаем последний файл для шаблона
const latestFile = await getLatestFileForTemplate(template.id)
if (!latestFile) {
alert('Не найден исходный файл Excel для шаблона')
toast.error('Не найден исходный файл Excel для шаблона')
return
}
@@ -574,7 +570,7 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
template_id: template.id,
}
// console.log('[DBG] POST body', body)
console.log('[DBG] POST body', body)
const resp = await fetch('/api/protocols/', {
method: 'POST',
@@ -583,20 +579,12 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
})
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
const result = await resp.json()
// console.log('✅ Протокол создан, ID:', result.protocol_id)
} catch (err) {
console.error('Ошибка при создании протокола', err)
alert('Ошибка при создании протокола')
toast.error('Ошибка при создании протокола')
}
}
const handleExport = () => {
// console.log('Экспорт в Excel:', { formData })
alert('Функция экспорта будет реализована в следующих версиях')
}
const canvasSize = useMemo(() => {
const PADDING_Y = 200
const baseWidth = 1200
@@ -619,29 +607,23 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
}
}, [template.elements])
// Проверяем есть ли кнопка сохранения (есть ли название протокола)
const protocolNameElement = template.elements.find(
el => el.name === 'protocolName' || el.label === 'Название протокола'
)
// const canSave = protocolNameElement
// ? !!formData[protocolNameElement.id]?.trim()
// : false
const canSave = true
return (
<div className="flex h-screen flex-col bg-gray-50">
{/* Заголовок */}
<div className="shrink-0 border-b border-gray-200 bg-white p-4">
<div className="flex-shrink-0 border-b bg-card px-4 py-2">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Button variant="ghost" onClick={onBack}>
<ArrowLeft className="mr-2 h-4 w-4" />
Назад
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" onClick={onBack}>
<ArrowLeft className="h-4 w-4" />
</Button>
<div>
<h1 className="text-xl font-semibold text-gray-800">
Создание протокола: {template.name}
</h1>
<div className="flex items-center space-x-2">
<FileText className="h-5 w-5" />
<h1 className="text-lg font-semibold">Создание протокола</h1>
<span className="text-sm text-muted-foreground"></span>
<span className="text-sm text-muted-foreground">
{template.name}
</span>
</div>
</div>
<div className="flex gap-2">
@@ -652,10 +634,6 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
<Grid className="mr-2 h-4 w-4" />
{showSpreadsheet ? 'Скрыть таблицы' : 'Показать таблицы'}
</Button>
<Button variant="outline" onClick={handleExport}>
<Download className="mr-2 h-4 w-4" />
Экспорт в Excel
</Button>
<Button onClick={handleSave} disabled={!canSave}>
<Save className="mr-2 h-4 w-4" />
Сохранить протокол
@@ -673,6 +651,7 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
mergedCells={template.mergedCells || []}
templateId={template.id}
onEngineReady={engine => (engineRef.current = engine)}
enableAutoSave={false}
/>
</div>
@@ -745,7 +724,7 @@ export const ProtocolCreation: FC = () => {
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(
null
)
const toast = useToast()
// Автоматически выбираем шаблон если передан ID в URL
useEffect(() => {
if (templateId && templates.length > 0) {
@@ -757,10 +736,7 @@ export const ProtocolCreation: FC = () => {
}, [templateId, templates])
const handleProtocolSave = (data: Record<string, any>) => {
// console.log('Сохранение протокола:', data)
// Здесь будет логика сохранения протокола
alert(`Протокол "${data.protocolName}" сохранен!`)
navigate('/templates')
toast.success(`Протокол "${data.protocolName}" сохранен!`)
}
const handleBack = () => {