v1.3.0: Refactoring Phase 3+4, Symbol-Verwaltung Redesign, Schlauch-Labels Fix
- Refactoring: Error Boundaries, apiFetch Wrapper, Socket Status-Tracking - Refactoring: UI Kontrast (theme-aware colors), unused imports bereinigt - Symbol-Verwaltung: Neues Split-Panel (Meine Symbole + Bibliothek) - Symbol-Verwaltung: Umbenennen (TLF rot/blau), Duplikate erlaubt - Symbol-Verwaltung: Karten-Sidebar zeigt eigene Symbole bevorzugt - Schlauch-Labels: Groessere Schrift (13px/10px), verschiebbar (Drag) - Schema: TenantSymbol customName, sortOrder, unique constraint entfernt - Open Source Referenz entfernt (kostenloses Projekt)
This commit is contained in:
@@ -1472,21 +1472,27 @@ export function MapView({
|
||||
midpoint = [cx / len, cy / len]
|
||||
}
|
||||
|
||||
// Apply stored label offset if present
|
||||
const labelOffset = f.properties.labelOffset as [number, number] | undefined
|
||||
if (labelOffset) {
|
||||
midpoint = [midpoint[0] + labelOffset[0], midpoint[1] + labelOffset[1]]
|
||||
}
|
||||
|
||||
const el = document.createElement('div')
|
||||
const isDanger = f.type === 'dangerzone'
|
||||
el.style.cssText = `
|
||||
background: ${isDanger ? 'rgba(220,38,38,0.85)' : 'rgba(0,0,0,0.75)'};
|
||||
background: ${isDanger ? 'rgba(220,38,38,0.85)' : 'rgba(0,0,0,0.82)'};
|
||||
color: #fff;
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
font-size: 11px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
pointer-events: ${canEdit ? 'auto' : 'none'};
|
||||
letter-spacing: 0.3px;
|
||||
border: 1px solid ${isDanger ? '#dc2626' : 'rgba(255,255,255,0.4)'};
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
|
||||
cursor: ${canEdit ? 'pointer' : 'default'};
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.3);
|
||||
cursor: ${canEdit ? 'grab' : 'default'};
|
||||
transform: translate(0,0);
|
||||
will-change: transform;
|
||||
`
|
||||
@@ -1503,11 +1509,11 @@ export function MapView({
|
||||
|
||||
const labelLine = document.createElement('div')
|
||||
labelLine.textContent = label
|
||||
labelLine.style.cssText = 'font-size:11px;font-weight:600;line-height:1.2;'
|
||||
labelLine.style.cssText = 'font-size:13px;font-weight:700;line-height:1.3;'
|
||||
|
||||
const infoLine = document.createElement('div')
|
||||
infoLine.textContent = `${lenText} / ${hoseCount} Schl.`
|
||||
infoLine.style.cssText = 'font-size:8px;opacity:0.8;line-height:1.2;font-weight:400;'
|
||||
infoLine.style.cssText = 'font-size:10px;opacity:0.85;line-height:1.3;font-weight:500;'
|
||||
|
||||
el.appendChild(labelLine)
|
||||
el.appendChild(infoLine)
|
||||
@@ -1519,11 +1525,11 @@ export function MapView({
|
||||
|
||||
const labelLine = document.createElement('div')
|
||||
labelLine.textContent = label
|
||||
labelLine.style.cssText = 'font-size:11px;font-weight:600;line-height:1.2;'
|
||||
labelLine.style.cssText = 'font-size:13px;font-weight:700;line-height:1.3;'
|
||||
|
||||
const infoLine = document.createElement('div')
|
||||
infoLine.textContent = areaText
|
||||
infoLine.style.cssText = 'font-size:8px;opacity:0.8;line-height:1.2;font-weight:400;'
|
||||
infoLine.style.cssText = 'font-size:10px;opacity:0.85;line-height:1.3;font-weight:500;'
|
||||
|
||||
el.appendChild(labelLine)
|
||||
el.appendChild(infoLine)
|
||||
@@ -1539,9 +1545,41 @@ export function MapView({
|
||||
})
|
||||
}
|
||||
|
||||
const marker = new maplibregl.Marker({ element: el, anchor: 'center', rotationAlignment: 'viewport' })
|
||||
const marker = new maplibregl.Marker({ element: el, anchor: 'center', draggable: canEdit, rotationAlignment: 'viewport' })
|
||||
.setLngLat(midpoint)
|
||||
.addTo(map.current)
|
||||
|
||||
// Save label position offset on drag end
|
||||
if (canEdit) {
|
||||
marker.on('dragend', () => {
|
||||
const newPos = marker.getLngLat()
|
||||
// Calculate midpoint without offset to get the base midpoint
|
||||
let baseMid: [number, number]
|
||||
const feat = featuresRef.current.find(feat => feat.id === f.id)
|
||||
if (!feat) return
|
||||
if (feat.geometry.type === 'LineString') {
|
||||
const coords = feat.geometry.coordinates as number[][]
|
||||
const midIdx = Math.floor(coords.length / 2)
|
||||
if (coords.length === 2) {
|
||||
baseMid = [(coords[0][0] + coords[1][0]) / 2, (coords[0][1] + coords[1][1]) / 2]
|
||||
} else {
|
||||
baseMid = coords[midIdx] as [number, number]
|
||||
}
|
||||
} else {
|
||||
const ring = (feat.geometry.coordinates as number[][][])[0]
|
||||
const len = ring.length - 1
|
||||
let cx = 0, cy = 0
|
||||
for (let i = 0; i < len; i++) { cx += ring[i][0]; cy += ring[i][1] }
|
||||
baseMid = [cx / len, cy / len]
|
||||
}
|
||||
const offset: [number, number] = [newPos.lng - baseMid[0], newPos.lat - baseMid[1]]
|
||||
const updated = featuresRef.current.map(pf =>
|
||||
pf.id === f.id ? { ...pf, properties: { ...pf.properties, labelOffset: offset } } : pf
|
||||
)
|
||||
onFeaturesChangeRef.current(updated)
|
||||
})
|
||||
}
|
||||
|
||||
markersRef.current.push(marker)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user