Grayscale OSM base tiles, mobile-friendly dashboard and map with touch multi-select and box select, wider road click radius, and strip internal properties from JOSM export

This commit is contained in:
zyphlar
2026-10-15 12:44:48 -07:00
parent 7e5b3dc2ee
commit 9b8752eef5
6 changed files with 457 additions and 102 deletions
+127 -2
View File
@@ -346,6 +346,115 @@
color: #444;
font-style: italic;
}
/* ── Collapsible top menu (mobile) ── */
.topbar-menu {
flex: 1;
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
}
.topbar-spacer { flex: 1; }
.topbar-user { font-size: 11px; color: #888; }
.menu-toggle {
display: none;
margin-left: auto;
width: 40px;
height: 36px;
padding: 8px;
border: none;
border-radius: 5px;
background: #ffffff18;
cursor: pointer;
flex-direction: column;
justify-content: space-between;
}
.menu-toggle span {
display: block;
height: 2px;
border-radius: 1px;
background: #ddd;
}
@media (max-width: 768px) {
html, body { height: auto; }
.page { height: auto; min-height: 100%; }
.topbar {
flex-wrap: wrap;
position: sticky;
top: 0;
z-index: 10;
}
.menu-toggle { display: flex; }
.topbar-menu {
display: none;
flex-basis: 100%;
flex-direction: column;
align-items: stretch;
gap: 6px;
max-width: 560px;
margin: 0 auto;
padding: 4px 0 6px;
}
.topbar-menu.open { display: flex; }
.topbar-sep, .topbar-spacer { display: none; }
.topbar-menu .btn-topbar,
.topbar-menu form,
.topbar-menu form .btn-topbar {
display: block;
width: 100%;
padding: 10px 12px;
font-size: 14px;
text-align: left;
}
.topbar-user { padding: 4px 2px 0; font-size: 12px; }
.main {
flex-direction: column;
overflow: visible;
}
.left {
width: 100%;
max-width: 560px;
margin: 0 auto;
border-right: none;
overflow: visible;
}
.workflows { overflow: visible; padding: 12px; }
.county-tab { padding: 12px; font-size: 14px; }
.step { flex-wrap: wrap; padding: 10px 12px; }
.step-label { font-size: 13px; min-width: 120px; }
.step-actions { margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.btn-run { padding: 8px 16px; font-size: 13px; }
.upload-input { width: 100%; max-width: 200px; }
.files-strip { max-height: 160px; overflow-y: auto; }
.right {
min-height: 60vh;
border-top: 1px solid #d8dbe0;
}
}
</style>
</head>
<body>
@@ -354,10 +463,14 @@
<!-- Top bar -->
<div class="topbar">
<h1>OSM Import Tools</h1>
<button class="menu-toggle" id="menuToggle" aria-label="Toggle menu" aria-expanded="false" aria-controls="topbarMenu">
<span></span><span></span><span></span>
</button>
<div class="topbar-menu" id="topbarMenu">
<div class="topbar-sep"></div>
<button class="btn-topbar" onclick="runScript('ls', '')">List Files</button>
<button class="btn-topbar" onclick="clearData()" style="color:#f88;">Clear Data</button>
<div style="flex:1"></div>
<div class="topbar-spacer"></div>
<a href="/counties" class="btn-topbar">Counties</a>
<a href="/exceptions" class="btn-topbar">Street Exceptions</a>
<a href="/exclusions" class="btn-topbar">Exclusions</a>
@@ -366,13 +479,14 @@
<a href="/map" class="btn-topbar purple">Open Map Viewer</a>
<div class="topbar-sep"></div>
{% if current_user %}
<span style="font-size:11px;color:#888;">{{ current_user }}</span>
<span class="topbar-user">{{ current_user }}</span>
<form method="POST" action="/logout" style="display:inline;margin:0">
<button type="submit" class="btn-topbar">Logout</button>
</form>
{% else %}
<a href="/login" class="btn-topbar" style="color:#f0a830;">Login</a>
{% endif %}
</div><!-- /topbar-menu -->
</div>
<div class="main">
@@ -611,6 +725,13 @@
});
}
// Mobile top menu toggle
document.getElementById('menuToggle').addEventListener('click', function() {
const menu = document.getElementById('topbarMenu');
const open = menu.classList.toggle('open');
this.setAttribute('aria-expanded', open ? 'true' : 'false');
});
// Init
if (activeCounty) selectCounty(activeCounty);
@@ -622,6 +743,10 @@
showStatus(`Running: ${scriptName} (${activeCounty})`, 'info');
disableButtons();
document.getElementById('cancelButton').classList.add('active');
// On narrow screens the console is below the steps; bring it into view
if (window.matchMedia('(max-width: 768px)').matches) {
document.querySelector('.right').scrollIntoView({ behavior: 'smooth', block: 'start' });
}
let forceDownload = false;
if (scriptName === 'diff-addresses') {
+68 -1
View File
@@ -67,6 +67,64 @@
z-index: 1000;
}
.multiselect-fab {
display: none;
position: absolute;
top: 64px;
right: 10px;
z-index: 998; /* above the map, below the drawer's overlay (999) */
width: 44px;
height: 44px;
border: none;
border-radius: 4px;
background: white;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
align-items: center;
justify-content: center;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.multiselect-fab svg {
fill: none;
stroke: #333;
stroke-width: 2;
}
.multiselect-fab.active {
background: #007bff;
}
.multiselect-fab.active svg {
stroke: white;
}
.multiselect-fab .fab-count {
position: absolute;
top: -6px;
right: -6px;
min-width: 20px;
height: 20px;
padding: 0 5px;
border-radius: 10px;
background: #ffc107;
color: #222;
font-size: 11px;
font-weight: 700;
line-height: 20px;
text-align: center;
}
.multiselect-fab .fab-count:empty {
display: none;
}
@media (max-width: 768px) {
.multiselect-fab {
display: flex;
}
}
/* Crosshair cursor in multi-select mode */
.leaflet-container.multi-select-active,
.leaflet-container.multi-select-active.leaflet-grab {
@@ -84,6 +142,15 @@
<span></span>
</button>
<!-- Floating multi-select toggle (mobile only; desktop uses the panel button) -->
<button class="multiselect-fab" id="multiSelectFab" aria-pressed="false" aria-label="Toggle multi-select">
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true">
<rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/>
<rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/>
</svg>
<span class="fab-count"></span>
</button>
<!-- Overlay for mobile -->
<div class="overlay" id="overlay"></div>
@@ -142,7 +209,7 @@
Multi-Select: OFF
</button>
<div style="margin-top: 5px; padding: 5px; background: #e7f3ff; border-radius: 4px; font-size: 10px; color: #004085;">
<strong>Tip:</strong> Enable multi-select or hold Shift to select multiple features by clicking or dragging a box
<strong>Tip:</strong> Enable multi-select or hold Shift to select multiple features by clicking or dragging a box. On touch screens, turn on multi-select (the grid button on the map), then drag a finger to draw a box or tap features to add or remove them; use two fingers to pan and zoom.
</div>
<h3 style="margin-top: 10px;">Load Data</h3>