Öffnung: ⚙-Knopf springt in den Tür-/Fenstertyp-Editor
Discoverability für die vertieften Bauteil-Typen: neben dem Typ-Dropdown einer gewählten Öffnung öffnet ein ⚙-Knopf das Ressourcen-Fenster direkt beim passenden Typeditor-Tab (Tür→doorStyles, Fenster→windowStyles). - ResourceManager: initialTab-Prop (springt auch bei bereits offenem Fenster auf den angeforderten Tab). - host.onEditOpeningType(kind) + App-Wiring (resourcesTab-State). tsc + vitest 620 grün.
This commit is contained in:
+9
-1
@@ -93,7 +93,7 @@ import { Viewport3D } from "./viewport/Viewport3D";
|
||||
import type { DisplayResolver, ViewportContextInfo } from "./viewport/Viewport3D";
|
||||
import type { Pick3dHit } from "./viewport/Wasm3DViewport";
|
||||
import { ResourceManager } from "./ui/ResourceManager";
|
||||
import type { ResourceManagerHandlers } from "./ui/ResourceManager";
|
||||
import type { ResourceManagerHandlers, TabId as ResourceTabId } from "./ui/ResourceManager";
|
||||
import { LayoutSheetView } from "./ui/LayoutSheet";
|
||||
import {
|
||||
createLayout,
|
||||
@@ -408,6 +408,9 @@ export default function App() {
|
||||
// bleibt lokal. Wird über die Oberleiste geöffnet und über X / Hintergrund-
|
||||
// Klick / Esc geschlossen.
|
||||
const [resourcesOpen, setResourcesOpen] = useState(false);
|
||||
// Angeforderter Start-Tab des Ressourcen-Fensters (z. B. „doorStyles", wenn man
|
||||
// von einer gewählten Tür in den Typeditor springt).
|
||||
const [resourcesTab, setResourcesTab] = useState<ResourceTabId>("components");
|
||||
|
||||
// Aktives Layout-Blatt im HAUPT-Viewport (DOSSIER A3, Phase 2b): Id des offenen
|
||||
// Layouts oder null (= normale Modell-Ansicht). Transienter UI-State; das
|
||||
@@ -3109,6 +3112,10 @@ export default function App() {
|
||||
if (selection?.kind === "opening")
|
||||
updateOpening(selection.id, { typeId: typeId || undefined });
|
||||
},
|
||||
onEditOpeningType: (kind) => {
|
||||
setResourcesTab(kind === "door" ? "doorStyles" : "windowStyles");
|
||||
setResourcesOpen(true);
|
||||
},
|
||||
// ── Treppen-Attribute (nur bei selektierter Treppe) ────────────────────
|
||||
onSetStairShape: (shape) => {
|
||||
if (selection?.kind === "stair") updateStair(selection.id, { shape });
|
||||
@@ -4910,6 +4917,7 @@ export default function App() {
|
||||
<ResourceManager
|
||||
project={project}
|
||||
handlers={resourceHandlers}
|
||||
initialTab={resourcesTab}
|
||||
onClose={() => setResourcesOpen(false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -340,6 +340,7 @@ export const de = {
|
||||
// ── Öffnungs-Attribute (Object-Info-Panel) ──────────────────────────────
|
||||
"objinfo.opening.section": "Öffnung",
|
||||
"objinfo.opening.type": "Typ",
|
||||
"objinfo.opening.editType": "Typ bearbeiten (Ressourcen)",
|
||||
"objinfo.stair.type": "Typ",
|
||||
"objinfo.type.none": "(kein Typ)",
|
||||
"objinfo.opening.kind": "Art",
|
||||
|
||||
@@ -340,6 +340,7 @@ export const en: Record<TranslationKey, string> = {
|
||||
// ── Opening attributes (object info panel) ──────────────────────────────
|
||||
"objinfo.opening.section": "Opening",
|
||||
"objinfo.opening.type": "Type",
|
||||
"objinfo.opening.editType": "Edit type (Resources)",
|
||||
"objinfo.stair.type": "Type",
|
||||
"objinfo.type.none": "(no type)",
|
||||
"objinfo.opening.kind": "Type",
|
||||
|
||||
@@ -578,7 +578,8 @@ export function OpeningSection({
|
||||
<div className="objinfo-sep" />
|
||||
<div className="objinfo-section-label">{t("objinfo.opening.section")}</div>
|
||||
|
||||
{/* Tür-/Fenstertyp (Bibliothek) — je nach Art aus doorTypes bzw. windowTypes. */}
|
||||
{/* Tür-/Fenstertyp (Bibliothek) — je nach Art aus doorTypes bzw. windowTypes.
|
||||
Der ⚙-Knopf springt direkt in den Typeditor (Ressourcen-Fenster). */}
|
||||
<div className="objinfo-field">
|
||||
<span className="objinfo-flabel">{t("objinfo.opening.type")}</span>
|
||||
<Dropdown
|
||||
@@ -592,8 +593,17 @@ export function OpeningSection({
|
||||
).map((ty) => ({ value: ty.id, label: ty.name })),
|
||||
]}
|
||||
title={t("objinfo.opening.type")}
|
||||
width={130}
|
||||
width={106}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="objinfo-typebtn"
|
||||
title={t("objinfo.opening.editType")}
|
||||
aria-label={t("objinfo.opening.editType")}
|
||||
onClick={() => host.onEditOpeningType(isDoor ? "door" : "window")}
|
||||
>
|
||||
⚙
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Art-Segment Fenster/Tür. */}
|
||||
|
||||
@@ -294,6 +294,11 @@ export interface PanelHostValue {
|
||||
onSetOpeningLintelLines: (lintelLines: "keine" | "innen" | "aussen" | "beide") => void;
|
||||
/** Weist der Öffnung einen Tür-/Fenstertyp (Bibliothek) zu; "" löst die Zuweisung. */
|
||||
onSetOpeningType: (typeId: string) => void;
|
||||
/**
|
||||
* Öffnet das Ressourcen-Fenster direkt beim Tür- bzw. Fenstertyp-Editor
|
||||
* (Discoverability: von der gewählten Öffnung in den Typeditor springen).
|
||||
*/
|
||||
onEditOpeningType: (kind: "door" | "window") => void;
|
||||
|
||||
// ── Treppen-Attribute (Object-Info-Panel; nur die selektierte Treppe) ───
|
||||
/** Setzt die Grundform (gerade/L/Wendel). */
|
||||
|
||||
@@ -4044,6 +4044,24 @@ body {
|
||||
letter-spacing: 0.04em;
|
||||
margin: 2px 2px 4px;
|
||||
}
|
||||
/* „Typ bearbeiten"-Knopf (⚙) neben dem Öffnungstyp-Dropdown. */
|
||||
.objinfo-typebtn {
|
||||
margin-left: 4px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
padding: 0;
|
||||
border: 1px solid var(--border, #444);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: var(--fg, inherit);
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
.objinfo-typebtn:hover {
|
||||
background: var(--hover, rgba(127, 127, 127, 0.18));
|
||||
}
|
||||
|
||||
/* Mess-Werkzeug: Live-Messwerte im Objekt-Info-Panel. */
|
||||
.objinfo-measure {
|
||||
margin: 2px 2px 8px;
|
||||
|
||||
@@ -2951,7 +2951,7 @@ function EmptyState({ text }: { text: string }) {
|
||||
|
||||
// ── Manager-Schublade ──────────────────────────────────────────────────────
|
||||
|
||||
type TabId =
|
||||
export type TabId =
|
||||
| "components"
|
||||
| "hatches"
|
||||
| "lines"
|
||||
@@ -3064,12 +3064,20 @@ export function ResourceManager({
|
||||
project,
|
||||
onClose,
|
||||
handlers,
|
||||
initialTab,
|
||||
}: {
|
||||
project: Project;
|
||||
onClose: () => void;
|
||||
handlers: ResourceManagerHandlers;
|
||||
/** Beim Öffnen (bzw. bei erneutem Sprung) direkt aktiver Tab, z. B. „doorStyles". */
|
||||
initialTab?: TabId;
|
||||
}) {
|
||||
const [tab, setTab] = useState<TabId>("components");
|
||||
const [tab, setTab] = useState<TabId>(initialTab ?? "components");
|
||||
// Erneuter Sprung aus einem Element heraus (z. B. „Typ bearbeiten" an einer
|
||||
// Öffnung): auf den angeforderten Tab wechseln, auch wenn das Fenster schon offen ist.
|
||||
useEffect(() => {
|
||||
if (initialTab) setTab(initialTab);
|
||||
}, [initialTab]);
|
||||
const [rect, setRect] = useState<WindowRect>(initialRect);
|
||||
|
||||
// Verschieben über die Kopfzeile: Cursor − linke/obere Kante festhalten und die
|
||||
|
||||
Reference in New Issue
Block a user