UI: Finalized sidebar compaction, collapsible handle, dropdown fixes, and owner status filtering
Deploy Bürgerwind / deploy (push) Successful in 17s
Details
Deploy Bürgerwind / deploy (push) Successful in 17s
Details
This commit is contained in:
parent
a47047d34d
commit
0d9306741e
78
app.js
78
app.js
|
|
@ -594,20 +594,30 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
variantTabs.forEach(tab => {
|
variantTabs.forEach(tab => {
|
||||||
tab.addEventListener('click', () => {
|
tab.addEventListener('click', () => {
|
||||||
if (state.activeVariant === tab.dataset.variant) return;
|
if (state.activeVariant === tab.dataset.variant) return;
|
||||||
|
|
||||||
variantTabs.forEach(t => t.classList.remove('active'));
|
variantTabs.forEach(t => t.classList.remove('active'));
|
||||||
tab.classList.add('active');
|
tab.classList.add('active');
|
||||||
|
|
||||||
const newVariant = tab.dataset.variant;
|
|
||||||
|
|
||||||
state.map.removeLayer(variantLayers[state.activeVariant]);
|
state.map.removeLayer(variantLayers[state.activeVariant]);
|
||||||
state.activeVariant = newVariant;
|
state.activeVariant = tab.dataset.variant;
|
||||||
variantLayers[state.activeVariant].addTo(state.map);
|
variantLayers[state.activeVariant].addTo(state.map);
|
||||||
|
updateProximityLines();
|
||||||
document.getElementById('statusInfo').innerText = `Variante ${newVariant} aktiv.`;
|
closeEditPanel();
|
||||||
|
document.getElementById('statusInfo').innerText = `Variante ${state.activeVariant} aktiv.`;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Sidebar Toggle Logic
|
||||||
|
const btnToggleSidebar = document.getElementById('btnToggleSidebar');
|
||||||
|
const sidebar = document.querySelector('.sidebar');
|
||||||
|
if (btnToggleSidebar && sidebar) {
|
||||||
|
btnToggleSidebar.onclick = () => {
|
||||||
|
sidebar.classList.toggle('collapsed');
|
||||||
|
// Give the transition time to finish before invalidating map size
|
||||||
|
setTimeout(() => {
|
||||||
|
state.map.invalidateSize();
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Hilfsgeometrien Toggle
|
// Hilfsgeometrien Toggle
|
||||||
const checkShowAux = document.getElementById('checkShowAux');
|
const checkShowAux = document.getElementById('checkShowAux');
|
||||||
if (checkShowAux) {
|
if (checkShowAux) {
|
||||||
|
|
@ -627,6 +637,21 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Eigentümerzustimmung Toggle
|
||||||
|
const checkShowOwners = document.getElementById('checkShowOwners');
|
||||||
|
if (checkShowOwners) {
|
||||||
|
checkShowOwners.onchange = () => {
|
||||||
|
const ownerLayer = overlays["Eigentümer (ALKIS DB)"];
|
||||||
|
if (ownerLayer) {
|
||||||
|
if (checkShowOwners.checked) {
|
||||||
|
state.map.addLayer(ownerLayer);
|
||||||
|
} else {
|
||||||
|
state.map.removeLayer(ownerLayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// UTM Creation Logic
|
// UTM Creation Logic
|
||||||
const btnCreateAtUTM = document.getElementById('btnCreateAtUTM');
|
const btnCreateAtUTM = document.getElementById('btnCreateAtUTM');
|
||||||
const inputUtmE = document.getElementById('utm-e');
|
const inputUtmE = document.getElementById('utm-e');
|
||||||
|
|
@ -923,7 +948,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const layerControl = L.control.layers(baseLayers, overlays, { collapsed: false }).addTo(state.map);
|
const layerControl = L.control.layers(baseLayers, overlays, { collapsed: true }).addTo(state.map);
|
||||||
|
|
||||||
// Update proximity lines when layers are toggled in legend
|
// Update proximity lines when layers are toggled in legend
|
||||||
state.map.on('overlayadd overlayremove', () => {
|
state.map.on('overlayadd overlayremove', () => {
|
||||||
|
|
@ -1425,7 +1450,13 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
overlays[layerName] = layer;
|
overlays[layerName] = layer;
|
||||||
state.map.addLayer(layer);
|
|
||||||
|
// Only add to map if checkbox is checked
|
||||||
|
const checkShowOwners = document.getElementById('checkShowOwners');
|
||||||
|
if (!checkShowOwners || checkShowOwners.checked) {
|
||||||
|
state.map.addLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
layerControl.addOverlay(layer, layerName);
|
layerControl.addOverlay(layer, layerName);
|
||||||
layer.bringToFront(); // Ensure it's on top of local shapefiles
|
layer.bringToFront(); // Ensure it's on top of local shapefiles
|
||||||
}
|
}
|
||||||
|
|
@ -1470,6 +1501,16 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
const btnConfirmMapping = document.getElementById('btnConfirmMapping');
|
const btnConfirmMapping = document.getElementById('btnConfirmMapping');
|
||||||
const ownerTableBody = document.querySelector('#ownerTable tbody');
|
const ownerTableBody = document.querySelector('#ownerTable tbody');
|
||||||
const ownerSearch = document.getElementById('ownerSearch');
|
const ownerSearch = document.getElementById('ownerSearch');
|
||||||
|
const ownerStatusFilter = document.getElementById('ownerStatusFilter');
|
||||||
|
|
||||||
|
// Populate Status Filter Options
|
||||||
|
if (ownerStatusFilter) {
|
||||||
|
ownerStatusFilter.innerHTML = `
|
||||||
|
<option value="">Alle Status</option>
|
||||||
|
<option value="HAS_STATUS">Nur mit Status</option>
|
||||||
|
${Object.keys(STATUS_MAP).map(s => `<option value="${s}">${s}</option>`).join('')}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
btnManageOwners.onclick = () => {
|
btnManageOwners.onclick = () => {
|
||||||
const ownerLayer = Object.keys(overlays).find(k => k.toLowerCase().includes('eigentümer'));
|
const ownerLayer = Object.keys(overlays).find(k => k.toLowerCase().includes('eigentümer'));
|
||||||
|
|
@ -1595,17 +1636,32 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
renderOwnerRows(owners);
|
renderOwnerRows(owners);
|
||||||
|
|
||||||
ownerSearch.oninput = () => {
|
const runFilter = () => {
|
||||||
const query = ownerSearch.value.toLowerCase();
|
const query = ownerSearch.value.toLowerCase();
|
||||||
|
const statusFilter = ownerStatusFilter.value;
|
||||||
const filtered = {};
|
const filtered = {};
|
||||||
|
|
||||||
for (let name in owners) {
|
for (let name in owners) {
|
||||||
const o = owners[name];
|
const o = owners[name];
|
||||||
if (name.toLowerCase().includes(query) || (o.address && o.address.toLowerCase().includes(query))) {
|
const stored = state.ownerStatuses[name.toLowerCase()] || { status: 'none' };
|
||||||
|
const currentStatus = typeof stored === 'object' ? (stored.status || 'none') : (stored || 'none');
|
||||||
|
|
||||||
|
const matchesQuery = name.toLowerCase().includes(query) || (o.address && o.address.toLowerCase().includes(query));
|
||||||
|
let matchesStatus = !statusFilter || currentStatus === statusFilter;
|
||||||
|
|
||||||
|
if (statusFilter === 'HAS_STATUS') {
|
||||||
|
matchesStatus = currentStatus !== 'none' && currentStatus !== '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchesQuery && matchesStatus) {
|
||||||
filtered[name] = o;
|
filtered[name] = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderOwnerRows(filtered);
|
renderOwnerRows(filtered);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ownerSearch.oninput = runFilter;
|
||||||
|
ownerStatusFilter.onchange = runFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderOwnerRows(owners) {
|
function renderOwnerRows(owners) {
|
||||||
|
|
|
||||||
20
index.html
20
index.html
|
|
@ -35,9 +35,12 @@
|
||||||
<div class="variant-tab" data-variant="B">Var B</div>
|
<div class="variant-tab" data-variant="B">Var B</div>
|
||||||
<div class="variant-tab" data-variant="C">Var C</div>
|
<div class="variant-tab" data-variant="C">Var C</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 12px; padding: 0 5px;">
|
<div style="margin-top: 8px; padding: 0 5px; display: flex; flex-direction: column; gap: 4px;">
|
||||||
<label style="cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.85rem; color: var(--text-dim);">
|
<label style="cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-dim);">
|
||||||
<input type="checkbox" id="checkShowAux" checked> Hilfsgeometrien anzeigen
|
<input type="checkbox" id="checkShowAux" checked> Hilfsgeometrien
|
||||||
|
</label>
|
||||||
|
<label style="cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-dim);">
|
||||||
|
<input type="checkbox" id="checkShowOwners" checked> Eigentümerzustimmung
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -127,6 +130,9 @@
|
||||||
Bereit. (v1.0.3 - Mirrored Nordex Default)
|
Bereit. (v1.0.3 - Mirrored Nordex Default)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button class="sidebar-toggle" id="btnToggleSidebar" title="Sidebar einklappen/ausklappen">
|
||||||
|
<span class="toggle-icon">◀</span>
|
||||||
|
</button>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- Floating Edit Panel -->
|
<!-- Floating Edit Panel -->
|
||||||
|
|
@ -225,8 +231,12 @@
|
||||||
|
|
||||||
<!-- Stage 2: Owner List -->
|
<!-- Stage 2: Owner List -->
|
||||||
<div id="ownerListSection" style="display: none;">
|
<div id="ownerListSection" style="display: none;">
|
||||||
<div style="padding: 15px; border-bottom: 1px solid var(--border-color);">
|
<div style="padding: 15px; border-bottom: 1px solid var(--border-color); display: flex; gap: 10px;">
|
||||||
<input type="text" id="ownerSearch" class="input-styled" placeholder="Eigentümer suchen...">
|
<input type="text" id="ownerSearch" class="input-styled" placeholder="Eigentümer suchen..." style="flex: 2;">
|
||||||
|
<select id="ownerStatusFilter" class="input-styled" style="flex: 1;">
|
||||||
|
<option value="">Alle Status</option>
|
||||||
|
<!-- Options filled via JS -->
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="owner-table-container">
|
<div class="owner-table-container">
|
||||||
<table id="ownerTable">
|
<table id="ownerTable">
|
||||||
|
|
|
||||||
54
style.css
54
style.css
|
|
@ -43,6 +43,13 @@ body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-shadow: 4px 0 15px rgba(0, 0, 0, 0.5);
|
box-shadow: 4px 0 15px rgba(0, 0, 0, 0.5);
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed {
|
||||||
|
margin-left: -260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-header {
|
.sidebar-header {
|
||||||
|
|
@ -97,7 +104,7 @@ body {
|
||||||
|
|
||||||
.input-styled {
|
.input-styled {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: #0a2d2d; /* Solid dark blue-green */
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
|
@ -112,7 +119,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-styled option {
|
.input-styled option {
|
||||||
background: #1e1e1e;
|
background: #0a2d2d;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,7 +412,7 @@ body {
|
||||||
|
|
||||||
.edit-input {
|
.edit-input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: #0a2d2d;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
@ -415,6 +422,11 @@ body {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edit-input option {
|
||||||
|
background: #0a2d2d;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-primary-mini {
|
.btn-primary-mini {
|
||||||
background: var(--primary-color);
|
background: var(--primary-color);
|
||||||
color: #000;
|
color: #000;
|
||||||
|
|
@ -528,6 +540,42 @@ body {
|
||||||
transition: transform 0.2s ease;
|
transition: transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sidebar Toggle Handle (Lasche) */
|
||||||
|
.sidebar-toggle {
|
||||||
|
position: absolute;
|
||||||
|
right: -24px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 24px;
|
||||||
|
height: 60px;
|
||||||
|
background: var(--panel-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-left: none;
|
||||||
|
border-radius: 0 8px 8px 0;
|
||||||
|
color: var(--primary-color);
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 101;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 4px 0 8px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-toggle:hover {
|
||||||
|
background: var(--bg-dark);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed .toggle-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-icon {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
.turbine-icon-container svg {
|
.turbine-icon-container svg {
|
||||||
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.5));
|
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.5));
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue