элементы и передвижение
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user