// SPDX-License-Identifier: AGPL-3.0-or-later // Copyright (C) 2026 Karim Gabriele Varano import { useEffect, useState } from 'react' import Icon from './components/Icon' import { BarButton, BarCombo, BAR_H } from './components/BarControls' import { onMessage, notifyReady, masseSetActive as setActive, masseSavePreset as savePreset, masseDeletePreset as deletePreset } from './lib/rhinoBridge' const RAUM_RUNDUNGS_LABELS = { 'exakt': 'Exakt (2 Nachk.)', '0.01': 'auf 0.01 m²', '0.1': 'auf 0.1 m²', '0.5': 'auf 0.5 m²', '1': 'auf 1 m²', } const labelXs = { fontSize: 9, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, } const pillInput = { height: BAR_H, background: 'var(--bg-input)', border: '1px solid var(--border)', borderRadius: 999, color: 'var(--text-primary)', fontSize: 11, fontFamily: 'var(--font)', padding: '0 10px', outline: 'none', boxSizing: 'border-box', } function Row({ label, children }) { return (
{label}
{children}
) } export default function MasseSettingsApp() { const [presets, setPresets] = useState([]) const [activeId, setActiveId] = useState(null) useEffect(() => { onMessage('STATE', (s) => { setPresets(s.presets || []) setActiveId(s.activeId || null) }) notifyReady() }, []) const active = presets.find(p => p.id === activeId) || presets[0] const update = (patch) => { if (!active) return savePreset({ ...active, ...patch }) } const addNew = () => { const name = (window.prompt('Name für neues Mass:') || '').trim() if (!name) return const tmpl = active || { raumRundung: '0.1', dimDezimalstellen: 2, dimEinheit: 'm' } savePreset({ name, raumRundung: tmpl.raumRundung, dimDezimalstellen: tmpl.dimDezimalstellen, dimEinheit: tmpl.dimEinheit, }) } const remove = () => { if (!active) return if (presets.length <= 1) { window.alert('Mindestens ein Mass muss erhalten bleiben.') return } if (!window.confirm(`Mass "${active.name}" löschen?`)) return deletePreset(active.id) } return (
{/* Header */}
Masse Globale Vorgaben für Raum-Rundung und Mass-Linien
{/* Picker + Aktionen */}
setActive(v)}> {presets.map(p => ( ))}
{active && (
update({ name: e.target.value })} style={{ ...pillInput, width: '100%' }} /> update({ raumRundung: v })}> {Object.entries(RAUM_RUNDUNGS_LABELS).map(([v, l]) => ( ))} update({ dimDezimalstellen: parseInt(v, 10) })}> {[0, 1, 2, 3, 4].map(n => ( ))} update({ dimEinheit: v })}>
)}
Änderungen werden sofort auf alle Räume angewendet. Pro-Raum gesetzte Rundungen (im Element-Panel) haben Vorrang vor dem aktiven Mass. Mass-Linien-Anwendung kommt im nächsten Schritt.
) }