Gruppen-Isolation: Rahmen im Viewport, Knopf dort platziert, Bbox-Auswahl

Drei Verbesserungen nach Vectorworks-Vorbild (Screenshot-Referenz):
- Sichtbarer Rahmen um die ganze Ansicht, solange eine Gruppe betreten ist
  (statt nur der gedimmten Elemente ohne Kontur).
- "Gruppe verlassen" sitzt jetzt oben rechts IM Viewport (wie in
  Vectorworks), nicht mehr als lose schwebender Knopf über der ganzen App.
- Ist eine GRUPPE (nicht einzelne Elemente) gewählt, zeigt die Auswahl nur
  noch eine gestrichelte Bounding-Box mit vier Eckpunkten statt jeden
  einzelnen Mitglieds-Umriss einzeln zu umranden.
This commit is contained in:
2026-08-22 11:28:59 +02:00
parent 91ed2b2454
commit 53144c8b06
4 changed files with 174 additions and 32 deletions
+2 -13
View File
@@ -2857,6 +2857,7 @@ export default function App() {
selectedStairIds={selectedStairIds} selectedStairIds={selectedStairIds}
selectedExtrudedSolidIds={selectedExtrudedSolidIds} selectedExtrudedSolidIds={selectedExtrudedSolidIds}
selectedColumnIds={selectedColumnIds} selectedColumnIds={selectedColumnIds}
selectedGroupIds={selectedGroupIds}
selectedRoomIds={selectedRoomIds} selectedRoomIds={selectedRoomIds}
selectedRoofIds={selectedRoofIds} selectedRoofIds={selectedRoofIds}
selectedContextObjectIds={selectedContextObjectIds} selectedContextObjectIds={selectedContextObjectIds}
@@ -2866,6 +2867,7 @@ export default function App() {
onStampEdit={onOpenStampEditor} onStampEdit={onOpenStampEditor}
onEditDrawingText={onEditDrawingText} onEditDrawingText={onEditDrawingText}
onEnterGroup={onEnterGroup} onEnterGroup={onEnterGroup}
onLeaveGroup={onLeaveGroup}
groupPath={groupPath} groupPath={groupPath}
editTextId={editTextId} editTextId={editTextId}
editTextMinHeightM={editTextMinHeightM} editTextMinHeightM={editTextMinHeightM}
@@ -2906,19 +2908,6 @@ export default function App() {
onEdit3dWallTop={onEdit3dWallTop} onEdit3dWallTop={onEdit3dWallTop}
onEdit3dEnd={onEdit3dEnd} onEdit3dEnd={onEdit3dEnd}
/> />
{/* "Gruppe verlassen" (Vectorworks-artig): sichtbar, solange eine
Gruppe betreten ist (Isolation — alles andere gedimmt/gesperrt,
s. viewportContent.tsx). Verlässt genau EIN Level. */}
{groupPath.length > 0 && (
<button
type="button"
className="plan-leave-group-btn"
onClick={onLeaveGroup}
title={t("group.leave.hint")}
>
{t("group.leave")}
</button>
)}
{/* Command-Line (Rhino-artig) UNTER dem Viewport — nur Viewport-breit. {/* Command-Line (Rhino-artig) UNTER dem Viewport — nur Viewport-breit.
Prompt + klickbare Inline-Optionen + Texteingabe + Autocomplete. */} Prompt + klickbare Inline-Optionen + Texteingabe + Autocomplete. */}
<CommandLine <CommandLine
+87
View File
@@ -327,6 +327,13 @@ export interface PlanViewProps {
* markiert den Querschnitt-Umriss JEDER dieser Stützen mit einer Akzentkontur. * markiert den Querschnitt-Umriss JEDER dieser Stützen mit einer Akzentkontur.
*/ */
selectedColumnIds?: string[]; selectedColumnIds?: string[];
/**
* IDs der gewählten GRUPPEN (Vectorworks-artig). Nicht-leer → die Ansicht
* zeigt statt der einzelnen Mitglieds-Umrisse nur eine Bounding-Box mit vier
* Eckpunkten (s. `groupBBox`); die per-Kind-`selected…Ids`-Felder tragen
* weiterhin die volle Mitgliedschaft (für Verschieben/Griffe/Löschen).
*/
selectedGroupIds?: string[];
/** /**
* Der Stempel-Griff des (einzeln) gewählten Raums: sein Anker (Meter) + ID. * Der Stempel-Griff des (einzeln) gewählten Raums: sein Anker (Meter) + ID.
* PlanView zeichnet einen ziehbaren Griff und meldet Bewegung/Doppelklick. * PlanView zeichnet einen ziehbaren Griff und meldet Bewegung/Doppelklick.
@@ -525,6 +532,7 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
selectedSectionLineIds, selectedSectionLineIds,
selectedExtrudedSolidIds, selectedExtrudedSolidIds,
selectedColumnIds, selectedColumnIds,
selectedGroupIds,
roomStamp, roomStamp,
onStampMove, onStampMove,
onStampEdit, onStampEdit,
@@ -2270,6 +2278,48 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
); );
}, [plan, selectedColumnIds]); }, [plan, selectedColumnIds]);
// Ist eine GRUPPE gewählt (statt einzelner Elemente), zeigt die Auswahl NUR
// eine einfache Bounding-Box mit vier Eckpunkten statt jedes einzelnen
// Mitglieds-Umrisses (Nutzer-Wunsch, Vectorworks-Vorbild: „einfach vier
// Aussenpunkte zeigen") — vereint dieselben Hervorhebungs-Listen, die sonst
// einzeln gezeichnet würden.
const groupBBox = useMemo(() => {
if (!selectedGroupIds || selectedGroupIds.length === 0) return null;
const pts: Vec2[] = [];
for (const poly of highlightPolys) pts.push(...poly.pts);
for (const poly of highlightCeilingPolys) pts.push(...poly.pts);
for (const poly of highlightRoomPolys) pts.push(...poly.pts);
for (const poly of highlightRoofPolys) pts.push(...poly.pts);
for (const poly of highlightColumnPolys) pts.push(...poly.pts);
const fromLineOrPoly = (p: { kind: string; a?: Vec2; b?: Vec2; from?: Vec2; to?: Vec2; center?: Vec2; pts?: Vec2[] }) => {
if (p.kind === "line" && p.a && p.b) pts.push(p.a, p.b);
else if (p.kind === "arc" && p.from && p.to) pts.push(p.from, p.to);
else if (p.pts) pts.push(...p.pts);
};
for (const p of highlightDrawPrims) fromLineOrPoly(p);
for (const p of highlightOpeningPrims) fromLineOrPoly(p);
for (const p of highlightStairPrims) fromLineOrPoly(p);
if (pts.length === 0) return null;
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
for (const p of pts) {
minX = Math.min(minX, p.x);
minY = Math.min(minY, p.y);
maxX = Math.max(maxX, p.x);
maxY = Math.max(maxY, p.y);
}
return { minX, minY, maxX, maxY };
}, [
selectedGroupIds,
highlightPolys,
highlightCeilingPolys,
highlightRoomPolys,
highlightRoofPolys,
highlightColumnPolys,
highlightDrawPrims,
highlightOpeningPrims,
highlightStairPrims,
]);
// Zusammenhängende 2D-Zeichen-Linien (gleiche drawingId + Stil) zu Zügen // Zusammenhängende 2D-Zeichen-Linien (gleiche drawingId + Stil) zu Zügen
// bündeln, damit sie als EIN <polyline>/<polygon> gezeichnet werden können — // bündeln, damit sie als EIN <polyline>/<polygon> gezeichnet werden können —
// so gehren dicke Ecken sauber (kein Butt-Cap-Sprung). generatePlan schiebt die // so gehren dicke Ecken sauber (kein Butt-Cap-Sprung). generatePlan schiebt die
@@ -2461,6 +2511,11 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
CAD-typische Gehrung an den Ecken (stroke-linejoin), keine Stufe bei CAD-typische Gehrung an den Ecken (stroke-linejoin), keine Stufe bei
dicken Linien. Nach der Haupt-Ebene gezeichnet (2D liegt ohnehin oben). */} dicken Linien. Nach der Haupt-Ebene gezeichnet (2D liegt ohnehin oben). */}
{drawingRunEls} {drawingRunEls}
{/* Ist eine GRUPPE gewählt, ersetzt die Bounding-Box unten die einzelnen
Mitglieds-Hervorhebungen (s. `groupBBox`) — dieser ganze Block bleibt
dann aus. */}
{!groupBBox && (
<>
{/* Auswahl-Hervorhebung: alle Bänder der gewählten Wand (bzw. das lokal {/* Auswahl-Hervorhebung: alle Bänder der gewählten Wand (bzw. das lokal
getroffene Polygon) mit Akzentkontur überzeichnen. */} getroffene Polygon) mit Akzentkontur überzeichnen. */}
{highlightPolys.map((poly, i) => ( {highlightPolys.map((poly, i) => (
@@ -2640,6 +2695,38 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
/> />
), ),
)} )}
</>
)}
{/* Gruppen-Auswahl: nur eine Bounding-Box mit vier Eckpunkten (kein
Umriss jedes einzelnen Mitglieds) — s. `groupBBox`. */}
{groupBBox && (() => {
const c1 = toScreen({ x: groupBBox.minX, y: groupBBox.minY });
const c2 = toScreen({ x: groupBBox.maxX, y: groupBBox.minY });
const c3 = toScreen({ x: groupBBox.maxX, y: groupBBox.maxY });
const c4 = toScreen({ x: groupBBox.minX, y: groupBBox.maxY });
const size = 5 / (meetScale(view, svgRef.current) ?? 1);
const corners = [c1, c2, c3, c4];
return (
<>
<polygon
className="plan-group-bbox"
points={corners.map((s) => `${s.x},${s.y}`).join(" ")}
pointerEvents="none"
/>
{corners.map((s, i) => (
<rect
key={`gbb-${i}`}
className="plan-group-bbox-corner"
x={s.x - size}
y={s.y - size}
width={size * 2}
height={size * 2}
pointerEvents="none"
/>
))}
</>
);
})()}
{/* Auswahl-Rechteck (Marquee). Gestrichelt; die crossing-Variante (rechts→ {/* Auswahl-Rechteck (Marquee). Gestrichelt; die crossing-Variante (rechts→
links, berührend) hebt sich farblich/strichlich ab. Das Rechteck steht links, berührend) hebt sich farblich/strichlich ab. Das Rechteck steht
bereits in viewBox-Einheiten → direkt setzbar. */} bereits in viewBox-Einheiten → direkt setzbar. */}
+43 -17
View File
@@ -2110,6 +2110,23 @@ body {
vector-effect: non-scaling-stroke; vector-effect: non-scaling-stroke;
} }
/* Gruppen-Auswahl (Vectorworks-artig): statt jedes Mitglieds-Umrisses nur eine
gestrichelte Bounding-Box mit vier Eckpunkt-Griffen — dieselbe Akzentfarbe
wie die normale Auswahl, aber gestrichelt (sofort als "Gruppe" erkennbar). */
.plan-svg .plan-group-bbox {
fill: none;
stroke: var(--accent);
stroke-width: 1.5;
stroke-dasharray: 6 4;
vector-effect: non-scaling-stroke;
}
.plan-svg .plan-group-bbox-corner {
fill: var(--accent);
stroke: #fff;
stroke-width: 1.5;
vector-effect: non-scaling-stroke;
}
/* Hervorhebung selektierter 2D-Zeichenelemente (Mehrfach/Marquee): Akzentkontur /* Hervorhebung selektierter 2D-Zeichenelemente (Mehrfach/Marquee): Akzentkontur
über der Geometrie, keine Füllung. */ über der Geometrie, keine Füllung. */
.plan-svg .plan-sel-draw { .plan-svg .plan-sel-draw {
@@ -2119,25 +2136,34 @@ body {
vector-effect: non-scaling-stroke; vector-effect: non-scaling-stroke;
} }
/* "Gruppe verlassen" (Vectorworks-artig): schwebender Knopf oben links über /* Gruppen-Isolation (Vectorworks „Gruppe betreten"): sichtbarer Rahmen um
dem Grundriss, sichtbar nur solange eine Gruppe betreten ist (Isolation). */ die ganze Ansicht, solange eine Gruppe betreten ist — dieselbe visuelle
.plan-leave-group-btn { Sprache wie Vectorworks' "Ansichtsbereich"-Rahmen. */
position: absolute; .pane-isolated {
top: 10px; outline: 2px solid var(--accent);
left: 10px; outline-offset: -2px;
z-index: 20;
padding: 6px 12px;
border-radius: 6px;
border: 1px solid var(--accent);
background: var(--field-bg);
color: var(--accent);
font-size: 12px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
} }
.plan-leave-group-btn:hover {
/* "Gruppe verlassen": Knopf oben RECHTS in der Ansicht (analog `.pane-title`
oben links), sichtbar nur solange eine Gruppe betreten ist. */
.pane-leave-group-btn {
position: absolute;
top: 12px;
right: 12px;
z-index: 3;
padding: 5px 11px;
border-radius: 6px;
border: 1px solid var(--accent-border);
background: var(--accent-dim); background: var(--accent-dim);
color: var(--muted);
font-size: 10px;
font-weight: 700;
letter-spacing: 0.04em;
cursor: pointer;
}
.pane-leave-group-btn:hover {
color: var(--accent);
border-color: var(--accent);
} }
/* Auswahl-Rechteck (Marquee, Links-Drag): gestrichelte Akzentkontur, leichte /* Auswahl-Rechteck (Marquee, Links-Drag): gestrichelte Akzentkontur, leichte
+42 -2
View File
@@ -88,6 +88,7 @@ export function Content({
selectedStairIds, selectedStairIds,
selectedExtrudedSolidIds, selectedExtrudedSolidIds,
selectedColumnIds, selectedColumnIds,
selectedGroupIds,
selectedRoomIds, selectedRoomIds,
selectedRoofIds, selectedRoofIds,
selectedContextObjectIds, selectedContextObjectIds,
@@ -98,6 +99,7 @@ export function Content({
onEditDrawingText, onEditDrawingText,
onEnterGroup, onEnterGroup,
groupPath, groupPath,
onLeaveGroup,
editTextId, editTextId,
editTextMinHeightM, editTextMinHeightM,
onCommitTextEdit, onCommitTextEdit,
@@ -183,6 +185,7 @@ export function Content({
selectedStairIds: string[]; selectedStairIds: string[];
selectedExtrudedSolidIds: string[]; selectedExtrudedSolidIds: string[];
selectedColumnIds: string[]; selectedColumnIds: string[];
selectedGroupIds: string[];
selectedRoomIds: string[]; selectedRoomIds: string[];
selectedRoofIds: string[]; selectedRoofIds: string[];
selectedContextObjectIds: string[]; selectedContextObjectIds: string[];
@@ -193,6 +196,7 @@ export function Content({
onEditDrawingText?: (drawingId: string) => void; onEditDrawingText?: (drawingId: string) => void;
onEnterGroup?: (hit: GroupableHit) => boolean; onEnterGroup?: (hit: GroupableHit) => boolean;
groupPath: string[]; groupPath: string[];
onLeaveGroup?: () => void;
editTextId?: string | null; editTextId?: string | null;
editTextMinHeightM?: number | null; editTextMinHeightM?: number | null;
onCommitTextEdit?: (doc: RichTextDoc) => void; onCommitTextEdit?: (doc: RichTextDoc) => void;
@@ -315,6 +319,7 @@ export function Content({
selectedStairIds={selectedStairIds} selectedStairIds={selectedStairIds}
selectedExtrudedSolidIds={selectedExtrudedSolidIds} selectedExtrudedSolidIds={selectedExtrudedSolidIds}
selectedColumnIds={selectedColumnIds} selectedColumnIds={selectedColumnIds}
selectedGroupIds={selectedGroupIds}
selectedRoomIds={selectedRoomIds} selectedRoomIds={selectedRoomIds}
selectedRoofIds={selectedRoofIds} selectedRoofIds={selectedRoofIds}
selectedSectionLineId={selectedSectionLineId} selectedSectionLineId={selectedSectionLineId}
@@ -324,6 +329,7 @@ export function Content({
onEditDrawingText={onEditDrawingText} onEditDrawingText={onEditDrawingText}
onEnterGroup={onEnterGroup} onEnterGroup={onEnterGroup}
groupPath={groupPath} groupPath={groupPath}
onLeaveGroup={onLeaveGroup}
editTextId={editTextId} editTextId={editTextId}
editTextMinHeightM={editTextMinHeightM} editTextMinHeightM={editTextMinHeightM}
onCommitTextEdit={onCommitTextEdit} onCommitTextEdit={onCommitTextEdit}
@@ -382,6 +388,7 @@ export function Content({
selectedStairIds={selectedStairIds} selectedStairIds={selectedStairIds}
selectedExtrudedSolidIds={selectedExtrudedSolidIds} selectedExtrudedSolidIds={selectedExtrudedSolidIds}
selectedColumnIds={selectedColumnIds} selectedColumnIds={selectedColumnIds}
selectedGroupIds={selectedGroupIds}
selectedRoomIds={selectedRoomIds} selectedRoomIds={selectedRoomIds}
selectedRoofIds={selectedRoofIds} selectedRoofIds={selectedRoofIds}
selectedContextObjectIds={selectedContextObjectIds} selectedContextObjectIds={selectedContextObjectIds}
@@ -392,6 +399,7 @@ export function Content({
onEditDrawingText={onEditDrawingText} onEditDrawingText={onEditDrawingText}
onEnterGroup={onEnterGroup} onEnterGroup={onEnterGroup}
groupPath={groupPath} groupPath={groupPath}
onLeaveGroup={onLeaveGroup}
editTextId={editTextId} editTextId={editTextId}
editTextMinHeightM={editTextMinHeightM} editTextMinHeightM={editTextMinHeightM}
onCommitTextEdit={onCommitTextEdit} onCommitTextEdit={onCommitTextEdit}
@@ -492,6 +500,7 @@ export function Content({
selectedStairIds={selectedStairIds} selectedStairIds={selectedStairIds}
selectedExtrudedSolidIds={selectedExtrudedSolidIds} selectedExtrudedSolidIds={selectedExtrudedSolidIds}
selectedColumnIds={selectedColumnIds} selectedColumnIds={selectedColumnIds}
selectedGroupIds={selectedGroupIds}
selectedRoomIds={selectedRoomIds} selectedRoomIds={selectedRoomIds}
selectedRoofIds={selectedRoofIds} selectedRoofIds={selectedRoofIds}
selectedContextObjectIds={selectedContextObjectIds} selectedContextObjectIds={selectedContextObjectIds}
@@ -502,6 +511,7 @@ export function Content({
onEditDrawingText={onEditDrawingText} onEditDrawingText={onEditDrawingText}
onEnterGroup={onEnterGroup} onEnterGroup={onEnterGroup}
groupPath={groupPath} groupPath={groupPath}
onLeaveGroup={onLeaveGroup}
editTextId={editTextId} editTextId={editTextId}
editTextMinHeightM={editTextMinHeightM} editTextMinHeightM={editTextMinHeightM}
onCommitTextEdit={onCommitTextEdit} onCommitTextEdit={onCommitTextEdit}
@@ -550,6 +560,7 @@ function LevelPlanView({
selectedStairIds, selectedStairIds,
selectedExtrudedSolidIds, selectedExtrudedSolidIds,
selectedColumnIds, selectedColumnIds,
selectedGroupIds,
selectedRoomIds, selectedRoomIds,
selectedRoofIds, selectedRoofIds,
selectedContextObjectIds, selectedContextObjectIds,
@@ -560,6 +571,7 @@ function LevelPlanView({
onEditDrawingText, onEditDrawingText,
onEnterGroup, onEnterGroup,
groupPath, groupPath,
onLeaveGroup,
editTextId, editTextId,
editTextMinHeightM, editTextMinHeightM,
onCommitTextEdit, onCommitTextEdit,
@@ -601,6 +613,7 @@ function LevelPlanView({
selectedStairIds: string[]; selectedStairIds: string[];
selectedExtrudedSolidIds: string[]; selectedExtrudedSolidIds: string[];
selectedColumnIds: string[]; selectedColumnIds: string[];
selectedGroupIds: string[];
selectedRoomIds: string[]; selectedRoomIds: string[];
selectedRoofIds: string[]; selectedRoofIds: string[];
selectedContextObjectIds?: string[]; selectedContextObjectIds?: string[];
@@ -611,6 +624,7 @@ function LevelPlanView({
onEditDrawingText?: (drawingId: string) => void; onEditDrawingText?: (drawingId: string) => void;
onEnterGroup?: (hit: GroupableHit) => boolean; onEnterGroup?: (hit: GroupableHit) => boolean;
groupPath: string[]; groupPath: string[];
onLeaveGroup?: () => void;
editTextId?: string | null; editTextId?: string | null;
editTextMinHeightM?: number | null; editTextMinHeightM?: number | null;
onCommitTextEdit?: (doc: RichTextDoc) => void; onCommitTextEdit?: (doc: RichTextDoc) => void;
@@ -683,12 +697,22 @@ function LevelPlanView({
}); });
return ( return (
<section className="pane"> <section className={groupPath.length > 0 ? "pane pane-isolated" : "pane"}>
<div className="pane-title"> <div className="pane-title">
{isDrawing {isDrawing
? t("content.drawingTitle", { name: level.name }) ? t("content.drawingTitle", { name: level.name })
: t("content.grundrissTitle", { name: level.name })} : t("content.grundrissTitle", { name: level.name })}
</div> </div>
{groupPath.length > 0 && (
<button
type="button"
className="pane-leave-group-btn"
onClick={onLeaveGroup}
title={t("group.leave.hint")}
>
{t("group.leave")}
</button>
)}
<PlanView <PlanView
ref={planViewRef} ref={planViewRef}
plan={plan} plan={plan}
@@ -701,6 +725,7 @@ function LevelPlanView({
selectedStairIds={selectedStairIds} selectedStairIds={selectedStairIds}
selectedExtrudedSolidIds={selectedExtrudedSolidIds} selectedExtrudedSolidIds={selectedExtrudedSolidIds}
selectedColumnIds={selectedColumnIds} selectedColumnIds={selectedColumnIds}
selectedGroupIds={selectedGroupIds}
selectedRoomIds={selectedRoomIds} selectedRoomIds={selectedRoomIds}
selectedRoofIds={selectedRoofIds} selectedRoofIds={selectedRoofIds}
selectedContextObjectIds={selectedContextObjectIds} selectedContextObjectIds={selectedContextObjectIds}
@@ -768,6 +793,7 @@ function SectionPlanView({
selectedStairIds, selectedStairIds,
selectedExtrudedSolidIds, selectedExtrudedSolidIds,
selectedColumnIds, selectedColumnIds,
selectedGroupIds,
selectedRoomIds, selectedRoomIds,
selectedRoofIds, selectedRoofIds,
selectedSectionLineId, selectedSectionLineId,
@@ -777,6 +803,7 @@ function SectionPlanView({
onEditDrawingText, onEditDrawingText,
onEnterGroup, onEnterGroup,
groupPath, groupPath,
onLeaveGroup,
editTextId, editTextId,
editTextMinHeightM, editTextMinHeightM,
onCommitTextEdit, onCommitTextEdit,
@@ -814,6 +841,7 @@ function SectionPlanView({
selectedStairIds: string[]; selectedStairIds: string[];
selectedExtrudedSolidIds: string[]; selectedExtrudedSolidIds: string[];
selectedColumnIds: string[]; selectedColumnIds: string[];
selectedGroupIds: string[];
selectedRoomIds: string[]; selectedRoomIds: string[];
selectedRoofIds: string[]; selectedRoofIds: string[];
selectedSectionLineId: string | null; selectedSectionLineId: string | null;
@@ -823,6 +851,7 @@ function SectionPlanView({
onEditDrawingText?: (drawingId: string) => void; onEditDrawingText?: (drawingId: string) => void;
onEnterGroup?: (hit: GroupableHit) => boolean; onEnterGroup?: (hit: GroupableHit) => boolean;
groupPath: string[]; groupPath: string[];
onLeaveGroup?: () => void;
editTextId?: string | null; editTextId?: string | null;
editTextMinHeightM?: number | null; editTextMinHeightM?: number | null;
onCommitTextEdit?: (doc: RichTextDoc) => void; onCommitTextEdit?: (doc: RichTextDoc) => void;
@@ -921,10 +950,20 @@ function SectionPlanView({
} }
return ( return (
<section className="pane"> <section className={groupPath.length > 0 ? "pane pane-isolated" : "pane"}>
<div className="pane-title"> <div className="pane-title">
{t("content.sectionTitle", { name: level.name, kind: kindLabel })} {t("content.sectionTitle", { name: level.name, kind: kindLabel })}
</div> </div>
{groupPath.length > 0 && (
<button
type="button"
className="pane-leave-group-btn"
onClick={onLeaveGroup}
title={t("group.leave.hint")}
>
{t("group.leave")}
</button>
)}
<PlanView <PlanView
ref={planViewRef} ref={planViewRef}
plan={plan} plan={plan}
@@ -937,6 +976,7 @@ function SectionPlanView({
selectedStairIds={selectedStairIds} selectedStairIds={selectedStairIds}
selectedExtrudedSolidIds={selectedExtrudedSolidIds} selectedExtrudedSolidIds={selectedExtrudedSolidIds}
selectedColumnIds={selectedColumnIds} selectedColumnIds={selectedColumnIds}
selectedGroupIds={selectedGroupIds}
selectedRoomIds={selectedRoomIds} selectedRoomIds={selectedRoomIds}
selectedRoofIds={selectedRoofIds} selectedRoofIds={selectedRoofIds}
selectedSectionLineIds={selectedSectionLineId ? [selectedSectionLineId] : []} selectedSectionLineIds={selectedSectionLineId ? [selectedSectionLineId] : []}