feat: click-drag drawing, layer tree, settings modal, UI improvements

- interaction: click-drag drawing for 2-point tools (line, rect, circle, dimension, leader)
- interaction: preview rendering during drag with setPreviewElement
- interaction: handleDrawDown only sets phase=drawing on first point
- CanvasArea: sync activeLayerId to LayerManager
- CanvasArea: callback refresh useEffect prevents stale closures
- App.tsx: functional setElements updates for handleElementCreated/Deleted/Modified
- LayerPanel: tree structure with sub-layers (onReorder, onAddSubLayer)
- TreeView: drag-and-drop reordering support
- RightSidebar: onReorder, onAddSubLayer, onUpdateElement props
- PropertiesPanel: onUpdateElement prop
- SettingsModal: personal/password/language/theme/users/plugins/AI tabs
- styles.css: extensive UI styling additions
- types: updated RightSidebarProps, CanvasAreaProps, LayerPanelProps
This commit is contained in:
2026-06-27 14:12:37 +02:00
parent 39422a4348
commit 4303076ce4
17 changed files with 929 additions and 144 deletions
+16 -4
View File
@@ -9,9 +9,9 @@ import type { UserCursor } from '../crdt';
export type ViewMode = '2d' | 'iso' | 'front' | 'top';
export type RibbonTab = 'start' | 'insert' | 'format' | 'view' | 'tools' | 'ki';
export type RightPanel = 'tool' | 'layer' | 'library' | 'ki' | 'plugins';
export type RightPanel = 'tool' | 'layer' | 'library' | 'ki';
export type Theme = 'light' | 'dark';
export type DrawerTab = 'tool' | 'layer' | 'library' | 'ki' | 'plugins';
export type DrawerTab = 'tool' | 'layer' | 'library' | 'ki';
export interface TreeNode {
id: string;
@@ -64,6 +64,12 @@ export interface TopbarProps {
onRedo: () => void;
onThemeToggle: () => void;
theme: Theme;
onOpenSettings?: () => void;
}
export interface SettingsModalProps {
open: boolean;
onClose: () => void;
}
export interface RibbonBarProps {
@@ -77,6 +83,7 @@ export interface LeftSidebarProps {
onToolChange: (tool: string) => void;
selectedTemplate?: string | null;
onTemplateSelect?: (templateName: string | null) => void;
onCollapse?: () => void;
}
export interface CanvasAreaProps {
@@ -90,6 +97,7 @@ export interface CanvasAreaProps {
activeTool: string;
elements: CADElement[];
layers: CADLayer[];
activeLayerId?: string;
onElementCreated: (el: CADElement) => void;
onElementsDeleted: (ids: string[]) => void;
onElementsModified: (els: CADElement[]) => void;
@@ -125,9 +133,10 @@ export interface RightSidebarProps {
onRenameLayer?: (id: string, name: string) => void;
onDuplicateLayer?: (id: string) => void;
onToggleLock?: (id: string) => void;
onUpdateLayerColor?: (id: string, color: string) => void;
onReorder?: (draggedId: string, targetId: string, position: 'before' | 'after' | 'inside') => void;
onUpdateLayerLineType?: (id: string, lineType: 'solid' | 'dashed' | 'dotted') => void;
onUpdateLayerTransparency?: (id: string, transparency: number) => void;
onAddSubLayer?: (parentId: string) => void;
onRenameBlock?: (id: string, name: string) => void;
onDuplicateBlock?: (id: string) => void;
onDeleteBlock?: (id: string) => void;
@@ -142,6 +151,7 @@ export interface RightSidebarProps {
onKISend?: (text: string) => void;
onKISuggestionClick?: (suggestion: KISuggestion) => void;
kiLoading?: boolean;
onUpdateElement?: (el: CADElement) => void;
}
export interface PropertiesPanelProps {
@@ -160,9 +170,10 @@ export interface LayerPanelProps {
onRenameLayer?: (id: string, name: string) => void;
onDuplicateLayer?: (id: string) => void;
onToggleLock?: (id: string) => void;
onUpdateLayerColor?: (id: string, color: string) => void;
onReorder?: (draggedId: string, targetId: string, position: 'before' | 'after' | 'inside') => void;
onUpdateLayerLineType?: (id: string, lineType: 'solid' | 'dashed' | 'dotted') => void;
onUpdateLayerTransparency?: (id: string, transparency: number) => void;
onAddSubLayer?: (parentId: string) => void;
}
export interface BlockLibraryProps {
@@ -212,6 +223,7 @@ export interface TreeViewProps {
nodes: TreeNode[];
onSelect: (id: string) => void;
onToggle: (id: string) => void;
onReorder?: (draggedId: string, targetId: string, position: 'before' | 'after' | 'inside') => void;
draggable?: boolean;
renderIcon?: (node: TreeNode) => ReactNode;
}