Ручные правки
This commit is contained in:
@@ -1,22 +1,33 @@
|
||||
import { ArrowLeft, Save, Upload, Wrench } from 'lucide-react'
|
||||
import {
|
||||
AlignCenter,
|
||||
AlignLeft,
|
||||
AlignRight,
|
||||
ArrowLeft,
|
||||
Bold,
|
||||
FileText,
|
||||
Grid,
|
||||
Italic,
|
||||
Palette,
|
||||
Type,
|
||||
Underline,
|
||||
Upload,
|
||||
Wrench,
|
||||
} from 'lucide-react'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import * as XLSX from 'xlsx'
|
||||
import { Template } from '../../types/template'
|
||||
import DualSpreadsheet from '../DualSpreadsheet/DualSpreadsheet'
|
||||
import { Button } from '../ui/button'
|
||||
import { Separator } from '../ui/separator'
|
||||
|
||||
interface TemplateEditorProps {
|
||||
template: Template
|
||||
onSave: (template: Template) => void
|
||||
onCancel: () => void
|
||||
onBack: () => void
|
||||
}
|
||||
|
||||
export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
template,
|
||||
onSave,
|
||||
onCancel,
|
||||
onBack,
|
||||
}) => {
|
||||
const [editedTemplate, setEditedTemplate] = useState<Template>(template)
|
||||
@@ -24,13 +35,17 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
template.excelData || {},
|
||||
)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [dataVersion, setDataVersion] = useState(0) // Для принудительного обновления
|
||||
const [dataVersion, setDataVersion] = useState(0) // Для принудительного
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.target.files?.[0]
|
||||
if (!file) return
|
||||
|
||||
if (!file) {
|
||||
console.log('No file selected')
|
||||
return
|
||||
}
|
||||
|
||||
setIsLoading(true)
|
||||
const reader = new FileReader()
|
||||
@@ -134,12 +149,8 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
reader.readAsArrayBuffer(file)
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
onSave(editedTemplate)
|
||||
}
|
||||
|
||||
const handleCreateElements = () => {
|
||||
navigate('/elements')
|
||||
navigate(`/templates/${editedTemplate.id}/elements`)
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -166,44 +177,74 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<Wrench className="h-3.5 w-3.5" />
|
||||
Создать элементы
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" onClick={onCancel}>
|
||||
Отмена
|
||||
Элементы интерфейса
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleSave}
|
||||
onClick={() =>
|
||||
navigate(`/templates/${editedTemplate.id}/protocols`)
|
||||
}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<Save className="h-3.5 w-3.5" />
|
||||
Сохранить
|
||||
<FileText className="h-3.5 w-3.5" />
|
||||
Создать протокол
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Панель загрузки Excel */}
|
||||
{/* Компактная панель загрузки Excel и инструментов */}
|
||||
<div className="flex-shrink-0 border-b bg-muted/30 px-4 py-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-xs font-medium text-muted-foreground">
|
||||
Excel шаблон:
|
||||
</span>
|
||||
{editedTemplate.excelFile ? (
|
||||
<div className="flex items-center gap-2 rounded-md bg-emerald-50 px-2 py-1">
|
||||
<Upload className="h-3 w-3 text-emerald-600" />
|
||||
<span className="text-xs text-emerald-700">
|
||||
{editedTemplate.excelFile.name}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
Файл не загружен
|
||||
</div>
|
||||
)}
|
||||
{/* Левая часть - панель инструментов стилизации */}
|
||||
<div className="flex items-center gap-0.5 rounded-lg border bg-background p-0.5">
|
||||
{/* Группа текстового форматирования */}
|
||||
<div className="flex items-center">
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<Bold className="h-3 w-3" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<Italic className="h-3 w-3" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<Underline className="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Separator orientation="vertical" className="mx-0.5 h-4" />
|
||||
|
||||
{/* Группа выравнивания */}
|
||||
<div className="flex items-center">
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<AlignLeft className="h-3 w-3" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<AlignCenter className="h-3 w-3" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<AlignRight className="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Separator orientation="vertical" className="mx-0.5 h-4" />
|
||||
|
||||
{/* Группа цвета и стилей */}
|
||||
<div className="flex items-center">
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<Palette className="h-3 w-3" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<Type className="h-3 w-3" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
|
||||
<Grid className="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
|
||||
{/* Правая часть - загрузка Excel */}
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
@@ -211,27 +252,47 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
onChange={handleFileUpload}
|
||||
className="hidden"
|
||||
/>
|
||||
|
||||
{/* Статус файла - всегда отображается */}
|
||||
<div
|
||||
className={`flex items-center gap-1.5 rounded-md border px-2 py-1 ${
|
||||
editedTemplate.excelFile
|
||||
? 'border-emerald-200 bg-emerald-50'
|
||||
: 'border-gray-200 bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
<FileText
|
||||
className={`h-3 w-3 ${
|
||||
editedTemplate.excelFile
|
||||
? 'text-emerald-600'
|
||||
: 'text-gray-400'
|
||||
}`}
|
||||
/>
|
||||
<span
|
||||
className={`max-w-32 truncate text-xs font-medium ${
|
||||
editedTemplate.excelFile
|
||||
? 'text-emerald-700'
|
||||
: 'text-gray-500'
|
||||
}`}
|
||||
>
|
||||
{editedTemplate.excelFile
|
||||
? editedTemplate.excelFile.name
|
||||
: 'Файл не выбран'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Кнопка загрузки - всегда отображается */}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
className="flex h-7 items-center gap-2"
|
||||
className="h-7 rounded-md px-2"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current border-t-transparent" />
|
||||
<span className="text-xs">Загрузка...</span>
|
||||
</>
|
||||
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current border-t-transparent" />
|
||||
) : (
|
||||
<>
|
||||
<Upload className="h-3 w-3" />
|
||||
<span className="text-xs">
|
||||
{editedTemplate.excelFile
|
||||
? 'Заменить файл'
|
||||
: 'Загрузить Excel'}
|
||||
</span>
|
||||
</>
|
||||
<Upload className="h-3 w-3" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -244,6 +305,7 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
key={dataVersion}
|
||||
templateData={{ L: excelData }}
|
||||
mergedCells={editedTemplate.mergedCells}
|
||||
templateId={`template-${editedTemplate.id}`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user