diff --git a/rhino/rhinopanel.py b/rhino/rhinopanel.py index 960dc50..11a036b 100644 --- a/rhino/rhinopanel.py +++ b/rhino/rhinopanel.py @@ -160,19 +160,21 @@ class EbenenBridge(panel_base.BaseBridge): if t == "READY": self._on_ready() elif t == "APPLY": - # Jedes Panel ist autoritativ fuer SEINE Slice; die andere kommt - # aus doc.Strings (Fallback) damit build_layers nicht mit leerer - # Liste arbeitet. So ueberschreiben wir nicht versehentlich die - # andere Panel-Slice mit "[]" bei Split-APPLYs. + print("[EBENEN-BE] APPLY from mode={} payload-z={} payload-e={}".format( + self._mode, + len(p.get("zeichnungsebenen") or []), + len(p.get("ebenen") or []))) if self._mode == "zeichnungsebenen": z_payload = p.get("zeichnungsebenen") or [] e_raw = doc.Strings.GetValue("dossier_ebenen") e_payload = json.loads(e_raw) if e_raw else [] + print("[EBENEN-BE] mode=zeichnungsebenen: e from doc.Strings n={}".format(len(e_payload))) self._apply(z_payload, e_payload, save_z=True, save_e=False) else: e_payload = p.get("ebenen") or [] z_raw = doc.Strings.GetValue("dossier_zeichnungsebenen") z_payload = json.loads(z_raw) if z_raw else [] + print("[EBENEN-BE] mode=ebenen: z from doc.Strings n={}".format(len(z_payload))) self._apply(z_payload, e_payload, save_z=False, save_e=True) elif t == "LAYER_STYLE": layer_builder.update_layer_style(doc, p["code"], p.get("color"), p.get("lw")) diff --git a/src/App.jsx b/src/App.jsx index 2de9dec..5edd95d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -110,7 +110,11 @@ export default function App() { useEffect(() => { if (structureKey === appliedStructureKey) return + console.log('[EBENEN-UI] structureKey diff → schedule applyAll in 200ms', { + ebenenCount: ebenen.length, appliedCount: appliedE.length, + }) const t = setTimeout(() => { + console.log('[EBENEN-UI] applyAll firing now', { ebenenCount: ebenen.length }) applyAll([], ebenen) setAppliedE(ebenen) }, 200) diff --git a/src/ZeichnungsebenenApp.jsx b/src/ZeichnungsebenenApp.jsx index 83bce0a..1c35cfd 100644 --- a/src/ZeichnungsebenenApp.jsx +++ b/src/ZeichnungsebenenApp.jsx @@ -88,7 +88,11 @@ export default function ZeichnungsebenenApp() { useEffect(() => { if (structureKey === appliedStructureKey) return + console.log('[ZEICHNUNGSEBENEN-UI] structureKey diff → schedule applyAll in 200ms', { + zCount: zeichnungsebenen.length, appliedCount: appliedZ.length, + }) const t = setTimeout(() => { + console.log('[ZEICHNUNGSEBENEN-UI] applyAll firing now', { zCount: zeichnungsebenen.length }) applyAll(zeichnungsebenen, []) setAppliedZ(zeichnungsebenen) }, 200) diff --git a/src/components/EbenenManager.jsx b/src/components/EbenenManager.jsx index 4cc81de..efc7459 100644 --- a/src/components/EbenenManager.jsx +++ b/src/components/EbenenManager.jsx @@ -352,25 +352,31 @@ export default function EbenenManager({ setDeleteTarget(null) } - const nextFreeCode = () => { - const codes = ebenen.map(e => parseInt(e.code, 10)).filter(n => !isNaN(n)) - const next = codes.length ? Math.max(...codes) + 1 : 50 - return String(next).padStart(2, '0') + const nextFreeAfter = (afterCode) => { + // Naechste freie Nummer NACH afterCode (= activeCode). Wenn afterCode + // = "20", probiert "21", dann "22", etc. Fallback: max+1. + const existing = new Set(ebenen.map(e => e.code)) + let n = parseInt(afterCode, 10) + if (isNaN(n)) n = 49 + for (let i = 1; i < 100; i++) { + const c = String(n + i).padStart(2, '0') + if (!existing.has(c)) return c + } + const codes = ebenen.map(e => parseInt(e.code, 10)).filter(x => !isNaN(x)) + return String((codes.length ? Math.max(...codes) : 49) + 1).padStart(2, '0') } const addNew = () => { - // Modal-Dialog via window.prompt fuer expliziten Name-Input — selbe UX - // wie bei Ebenenkombinationen. Code wird automatisch generiert. const name = (window.prompt('Name für neue Ebene:', 'NEU') || '').trim() if (!name) return - // Doppel-Namen erlauben (gibt's auch bisher), aber doppel-Codes vermeiden. - const code = nextFreeCode() - onChange([...ebenen, { + // Code-Vergabe: eine nach der aktuell angewaehlten Ebene. + const code = nextFreeAfter(activeCode) + const newEbene = { code, name: name.toUpperCase(), color: '#888888', lw: 0.18, visible: true, locked: false, - }]) - // Direkt in den Edit-Mode fuer Code-Feld — User kann Code anpassen - // falls die Auto-Vergabe nicht passt. + } + console.log('[EBENEN-UI] addNew →', { activeCode, code, name: newEbene.name, ebenenCountBefore: ebenen.length }) + onChange([...ebenen, newEbene]) setAutoEdit({ code, field: 'code', token: Date.now() }) } diff --git a/src/components/GeschossManager.jsx b/src/components/GeschossManager.jsx index 7571a77..5b97b08 100644 --- a/src/components/GeschossManager.jsx +++ b/src/components/GeschossManager.jsx @@ -94,8 +94,6 @@ export default function GeschossManager({ .reduce((s, z) => s + (z.hoehe ?? 0), 0) const addQuick = () => { - // Modal-Dialog via window.prompt fuer expliziten Name-Input — selbe UX - // wie bei Ebenenkombinationen / neuer Ebene. const defaultName = `${zeichnungsebenen.filter(z => z.isGeschoss).length + 1}OG` const name = (window.prompt( 'Name für neue Zeichnungsebene (Geschoss):', @@ -110,6 +108,7 @@ export default function GeschossManager({ schnitthoehe: 1.0, visible: true, } + console.log('[ZEICHNUNGSEBENEN-UI] addQuick →', { newZ, countBefore: zeichnungsebenen.length }) onChange([...zeichnungsebenen, newZ]) }