fix: layer panel collapsible tree + element actions (visibility toggle, delete) + RenderEngine skips invisible elements

This commit is contained in:
2026-06-27 23:59:12 +02:00
parent affa6be151
commit a4371ca3ce
5 changed files with 91 additions and 44 deletions
+68 -42
View File
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React from 'react';
import type { LayerPanelProps } from '../types/ui.types';
import type { CADLayer, CADElement } from '../types/cad.types';
import type { TreeNode } from '../types/ui.types';
@@ -67,6 +67,8 @@ const LayerPanel: React.FC<LayerPanelProps> = ({
onToggleLock,
onReorder,
onAddSubLayer,
onElementsDeleted,
onToggleElementVisible,
}) => {
const buildTree = (parentId: string | null): TreeNode[] => {
return layers
@@ -87,7 +89,7 @@ const LayerPanel: React.FC<LayerPanelProps> = ({
id: l.id,
name: l.name,
icon: layerIcon,
expanded: true,
expanded: false,
active: l.id === activeLayerId,
children: [...subLayerNodes, ...elementNodes],
count: layerElements.length > 0 ? layerElements.length : undefined,
@@ -132,46 +134,70 @@ const LayerPanel: React.FC<LayerPanelProps> = ({
renderIcon={(node) => node.icon}
renderActions={(node) => {
const layer = layers.find((l) => l.id === node.id);
if (!layer) return null;
return (
<div style={{ display: 'flex', gap: '2px', opacity: 0.6 }}>
<button
onClick={(e) => { e.stopPropagation(); onToggleLayer(layer.id); }}
title={layer.visible ? 'Sichtbar' : 'Versteckt'}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: layer.visible ? 'var(--text-color, #ccc)' : 'var(--text-muted, #666)' }}
>
{layer.visible ? '👁' : '🚫'}
</button>
<button
onClick={(e) => { e.stopPropagation(); onToggleLock?.(layer.id); }}
title={layer.locked ? 'Gesperrt' : 'Entsperrt'}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: layer.locked ? 'var(--accent, #f59e0b)' : 'var(--text-muted, #666)' }}
>
{layer.locked ? '🔒' : '🔓'}
</button>
<button
onClick={(e) => { e.stopPropagation(); handleAddSubLayer(layer.id); }}
title="Teilebene hinzufugen"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--text-color, #ccc)' }}
>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
</button>
<button
onClick={(e) => { e.stopPropagation(); onDuplicateLayer?.(layer.id); }}
title="Duplizieren"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--text-color, #ccc)' }}
>
</button>
<button
onClick={(e) => { e.stopPropagation(); onDeleteLayer?.(layer.id); }}
title="Loschen"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: '#f44336' }}
>
</button>
</div>
);
if (layer) {
return (
<div style={{ display: 'flex', gap: '2px', opacity: 0.6 }}>
<button
onClick={(e) => { e.stopPropagation(); onToggleLayer(layer.id); }}
title={layer.visible ? 'Sichtbar' : 'Versteckt'}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: layer.visible ? 'var(--text-color, #ccc)' : 'var(--text-muted, #666)' }}
>
{layer.visible ? '👁' : '🚫'}
</button>
<button
onClick={(e) => { e.stopPropagation(); onToggleLock?.(layer.id); }}
title={layer.locked ? 'Gesperrt' : 'Entsperrt'}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: layer.locked ? 'var(--accent, #f59e0b)' : 'var(--text-muted, #666)' }}
>
{layer.locked ? '🔒' : '🔓'}
</button>
<button
onClick={(e) => { e.stopPropagation(); handleAddSubLayer(layer.id); }}
title="Teilebene hinzufugen"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--text-color, #ccc)' }}
>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
</button>
<button
onClick={(e) => { e.stopPropagation(); onDuplicateLayer?.(layer.id); }}
title="Duplizieren"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--text-color, #ccc)' }}
>
</button>
<button
onClick={(e) => { e.stopPropagation(); onDeleteLayer?.(layer.id); }}
title="Loschen"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: '#f44336' }}
>
</button>
</div>
);
}
const element = elements.find((el) => el.id === node.id);
if (element) {
const isVisible = element.properties?.visible !== false;
return (
<div style={{ display: 'flex', gap: '2px', opacity: 0.6 }}>
<button
onClick={(e) => { e.stopPropagation(); onToggleElementVisible?.(element.id); }}
title={isVisible ? 'Sichtbar' : 'Versteckt'}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: isVisible ? 'var(--text-color, #ccc)' : 'var(--text-muted, #666)' }}
>
{isVisible ? '👁' : '🚫'}
</button>
<button
onClick={(e) => { e.stopPropagation(); onElementsDeleted?.([element.id]); }}
title="Loschen"
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: '#f44336' }}
>
</button>
</div>
);
}
return null;
}}
/>
)}