elements constructor улучшен

This commit is contained in:
2025-07-22 10:33:21 +03:00
parent ac8be1a347
commit 553da77a87
7 changed files with 688 additions and 253 deletions

View File

@@ -34,7 +34,6 @@ import {
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '../ui/dialog'
import { Input } from '../ui/input'
import {
@@ -45,6 +44,7 @@ import {
SelectValue,
} from '../ui/select'
import { Textarea } from '../ui/textarea'
import { ElementFormulaBar } from './ElementFormulaBar'
import { VisualLayoutEditor } from './VisualLayoutEditor'
interface ElementFormProps {
@@ -705,6 +705,14 @@ interface ElementConstructorProps {
) => void
onElementDelete: (elementId: string) => void
disabled?: boolean
// Пропсы для сохранения
hasUnsavedChanges?: boolean
isSaving?: boolean
lastSaveError?: string | null
onManualSave?: () => Promise<void>
onClearError?: () => void
// Пропсы для настроек макета
onLayoutSettingsChange?: (settings: FormLayoutSettings) => void
}
export const ElementConstructor: React.FC<ElementConstructorProps> = ({
@@ -713,6 +721,12 @@ export const ElementConstructor: React.FC<ElementConstructorProps> = ({
onElementUpdate,
onElementDelete,
disabled = false,
hasUnsavedChanges = false,
isSaving = false,
lastSaveError = null,
onManualSave,
onClearError,
onLayoutSettingsChange,
}) => {
const elements = template.elements
const layoutSettings = template.layoutSettings || {
@@ -877,94 +891,96 @@ export const ElementConstructor: React.FC<ElementConstructorProps> = ({
// };
return (
<div className="flex h-full w-full">
{/* Main Content */}
<div className="flex flex-1 flex-col bg-gray-50">
<div className="flex items-center justify-between border-b bg-white p-2">
<div className="px-2">
<h3 className="text-sm font-medium">Холст</h3>
<p className="text-xs text-gray-500">
Перетаскивайте элементы для настройки их расположения
</p>
</div>
<div className="flex items-center gap-2">
<Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
<DialogTrigger asChild>
<Button variant="outline" size="sm" disabled={disabled}>
<Plus className="mr-2 h-4 w-4" />
Добавить элемент
</Button>
</DialogTrigger>
<DialogContent className="max-h-[80vh] max-w-4xl overflow-y-auto">
<DialogHeader>
<DialogTitle>Добавить новый элемент</DialogTitle>
<DialogDescription>
Настройте параметры нового элемента формы.
</DialogDescription>
</DialogHeader>
<ElementForm formData={formData} setFormData={setFormData} />
<div className="flex justify-end gap-2 pt-4">
<Button
onClick={() => setIsAddDialogOpen(false)}
variant="outline"
>
Отмена
</Button>
<Button
onClick={handleAddElement}
disabled={
disabled ||
!formData.label ||
(formData.type !== 'standards' &&
formData.type !== 'calibration-conditions' &&
formData.type !== 'button-group' &&
!formData.targetCells?.length)
}
>
<Plus className="mr-2 h-4 w-4" />
Добавить элемент
</Button>
</div>
</DialogContent>
</Dialog>
<div className="flex h-full w-full flex-col bg-background">
<ElementFormulaBar
elementCount={elements.length}
onAddElement={() => setIsAddDialogOpen(true)}
onAutoArrange={handleAutoArrange}
disabled={disabled}
hasUnsavedChanges={hasUnsavedChanges}
isSaving={isSaving}
lastSaveError={lastSaveError}
onManualSave={onManualSave}
onClearError={onClearError}
showGrid={layoutSettings.showGrid}
onToggleGrid={
onLayoutSettingsChange
? () => {
const newSettings = {
...layoutSettings,
showGrid: !layoutSettings.showGrid,
}
onLayoutSettingsChange(newSettings)
}
: undefined
}
/>
{editingElement && (
<Dialog
open={!!editingElement}
onOpenChange={() => handleCancelEdit()}
>
<DialogContent className="max-h-[80vh] max-w-4xl overflow-y-auto">
<DialogHeader>
<DialogTitle>Редактировать элемент</DialogTitle>
<DialogDescription>
Измените параметры элемента формы.
</DialogDescription>
</DialogHeader>
<ElementForm formData={formData} setFormData={setFormData} />
<div className="flex justify-end gap-2 pt-4">
<Button onClick={handleCancelEdit} variant="outline">
Отмена
</Button>
<Button onClick={handleUpdateElement} disabled={disabled}>
Сохранить изменения
</Button>
</div>
</DialogContent>
</Dialog>
)}
</div>
</div>
<div className="flex-1 overflow-hidden">
<VisualLayoutEditor
elements={elements}
layoutSettings={layoutSettings}
onElementUpdate={onElementUpdate}
onElementDelete={handleDeleteAndSelect}
onLayoutSettingsChange={() => {}} // Настройки макета только для чтения
onElementEdit={handleEditElement}
/>
</div>
<div className="flex-1 overflow-hidden">
<VisualLayoutEditor
elements={elements}
layoutSettings={layoutSettings}
onElementUpdate={onElementUpdate}
onElementDelete={handleDeleteAndSelect}
onLayoutSettingsChange={onLayoutSettingsChange || (() => {})}
onElementEdit={handleEditElement}
/>
</div>
{/* Диалог добавления элемента */}
<Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
<DialogContent className="max-h-[80vh] max-w-4xl overflow-y-auto">
<DialogHeader>
<DialogTitle>Добавить новый элемент</DialogTitle>
<DialogDescription>
Настройте параметры нового элемента формы.
</DialogDescription>
</DialogHeader>
<ElementForm formData={formData} setFormData={setFormData} />
<div className="flex justify-end gap-2 pt-4">
<Button onClick={() => setIsAddDialogOpen(false)} variant="outline">
Отмена
</Button>
<Button
onClick={handleAddElement}
disabled={
disabled ||
!formData.label ||
(formData.type !== 'standards' &&
formData.type !== 'calibration-conditions' &&
formData.type !== 'button-group' &&
!formData.targetCells?.length)
}
>
<Plus className="mr-2 h-4 w-4" />
Добавить элемент
</Button>
</div>
</DialogContent>
</Dialog>
{/* Диалог редактирования элемента */}
{editingElement && (
<Dialog open={!!editingElement} onOpenChange={() => handleCancelEdit()}>
<DialogContent className="max-h-[80vh] max-w-4xl overflow-y-auto">
<DialogHeader>
<DialogTitle>Редактировать элемент</DialogTitle>
<DialogDescription>
Измените параметры элемента формы.
</DialogDescription>
</DialogHeader>
<ElementForm formData={formData} setFormData={setFormData} />
<div className="flex justify-end gap-2 pt-4">
<Button onClick={handleCancelEdit} variant="outline">
Отмена
</Button>
<Button onClick={handleUpdateElement} disabled={disabled}>
Сохранить изменения
</Button>
</div>
</DialogContent>
</Dialog>
)}
</div>
)
}