Ebene-Add: Code = activeCode + nächste freie Nummer + Debug-Logs

Feature: neue Ebenen kriegen jetzt einen Code direkt nach dem
aktuell angewaehlten (z.B. active="20" → "21" oder naechste freie
darunter). Vorher war's Max+1 → sprang auf "100", neue Ebene landet
am Listen-Ende und wirkte „unsichtbar" weil weit unten.

Debug-Logs eingebaut um zu diagnostizieren warum Anlegen aus User-
Sicht nicht funktioniert:
- [EBENEN-UI] addNew → bei jedem Click + im Ebenen-Panel
- [ZEICHNUNGSEBENEN-UI] addQuick → bei jedem Click + im Z-Panel
- [EBENEN-UI/ZEICHNUNGSEBENEN-UI] structureKey diff → wenn der
  Auto-Apply-useEffect feuert
- [EBENEN-UI/ZEICHNUNGSEBENEN-UI] applyAll firing now → wenn der
  Debounce-Timer am Ende den Backend-Call macht
- [EBENEN-BE] APPLY from mode=X → Backend-Receiver
- [EBENEN-BE] mode=X: y from doc.Strings n=N → was aus doc.Strings
  als Fallback geladen wurde

So sehen wir wo's stockt — UI feuert nicht, Debounce klemmt,
Backend kriegt's nicht, oder build_layers schmeisst still.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 00:29:46 +02:00
parent 10690f4514
commit d63bca1ad8
5 changed files with 33 additions and 18 deletions
+4
View File
@@ -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)
+4
View File
@@ -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)
+18 -12
View File
@@ -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() })
}
+1 -2
View File
@@ -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])
}