элементы и передвижение

This commit is contained in:
2025-07-23 17:50:44 +03:00
parent 907b3e315e
commit 7c7e0db426
9 changed files with 100 additions and 193 deletions

View File

@@ -6,7 +6,7 @@ import { cellAddressToCoordinates } from '@/lib/cell-utils'
import { useToast } from '@/lib/hooks/useToast'
import { getLatestFileForTemplate } from '@/service/fileApiService'
import { Template, TemplateElement } from '@/type/template'
import { ArrowLeft, FileText, Grid, Save } 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'
@@ -44,25 +44,23 @@ const FormElement: FC<FormElementProps> = ({ element, value, onChange }) => {
)
return (
<div className="space-y-3">
<div className="relative space-y-3">
{/* Показываем индикатор ячеек для всех элементов */}
{element.targetCells && element.targetCells.length > 0 && (
<div className="flex justify-end">
<div className="group/cells relative">
<Grid className="h-3 w-3 cursor-help text-gray-500 opacity-60 transition-opacity hover:opacity-100" />
<div className="pointer-events-none absolute right-0 top-full z-50 mt-2 whitespace-nowrap rounded bg-gray-900 p-2 text-xs text-white opacity-0 shadow-lg transition-opacity group-hover/cells:opacity-100">
<div className="mb-1 font-medium">Целевые ячейки:</div>
{element.targetCells.map((cell, i) => (
<div key={i} className="font-mono">
{cell.sheet}!{cell.cell}
{cell.displayName && (
<span className="ml-1 text-gray-300">
({cell.displayName})
</span>
)}
</div>
))}
</div>
<div className="group/cells absolute right-0 top-0">
<Grid className="h-3 w-3 cursor-help text-gray-500 opacity-60 transition-opacity hover:opacity-100" />
<div className="pointer-events-none absolute right-0 top-full z-50 mt-2 whitespace-nowrap rounded bg-gray-900 p-2 text-xs text-white opacity-0 shadow-lg transition-opacity group-hover/cells:opacity-100">
<div className="mb-1 font-medium">Целевые ячейки:</div>
{element.targetCells.map((cell, i) => (
<div key={i} className="font-mono">
{cell.sheet}!{cell.cell}
{cell.displayName && (
<span className="ml-1 text-gray-300">
({cell.displayName})
</span>
)}
</div>
))}
</div>
</div>
)}
@@ -78,6 +76,7 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
const [showSpreadsheet, setShowSpreadsheet] = useState(false)
const engineRef = useRef<any>(null)
const toast = useToast()
const navigate = useNavigate()
const handleFieldChange = (elementId: string, value: any) => {
setFormData(prev => ({
@@ -266,7 +265,8 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
return (
<div className="flex h-screen flex-col bg-gray-50">
<div className="flex-shrink-0 border-b bg-card px-4 py-2">
<div className="flex items-center justify-between">
<div className="relative flex items-center">
{/* Левая часть: кнопка назад и заголовок */}
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" onClick={onBack}>
<ArrowLeft className="h-4 w-4" />
@@ -280,15 +280,40 @@ const ProtocolForm: FC<ProtocolFormProps> = ({ template, onSave, onBack }) => {
</span>
</div>
</div>
<div className="flex gap-2">
{/* Кнопки справа */}
<div className="absolute right-0 flex gap-2">
<Button
variant="outline"
size="sm"
onClick={() => navigate(`/templates/${template.id}/edit`)}
className="flex items-center gap-1 hover:bg-muted"
>
<Settings className="h-4 w-4" />
<span className="text-sm">Редактор шаблона</span>
</Button>
<Button
variant="outline"
size="sm"
onClick={() => navigate(`/templates/${template.id}/elements`)}
className="flex items-center gap-1 hover:bg-muted"
>
<Wrench className="h-4 w-4" />
<span className="text-sm">Редактор интерфейса</span>
</Button>
</div>
{/* Центрированные кнопки */}
<div className="absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 gap-2">
<Button
variant={showSpreadsheet ? 'default' : 'outline'}
size="icon"
onClick={() => setShowSpreadsheet(!showSpreadsheet)}
aria-label={
showSpreadsheet ? 'Скрыть таблицы' : 'Показать таблицы'
}
>
<Grid className="mr-2 h-4 w-4" />
{showSpreadsheet ? 'Скрыть таблицы' : 'Показать таблицы'}
<Grid className="h-4 w-4" />
</Button>
<Button onClick={handleSave} disabled={!canSave}>
<Button variant="outline" onClick={handleSave} disabled={!canSave}>
<Save className="mr-2 h-4 w-4" />
Сохранить протокол
</Button>