openstreetmap-tools/web/templates/index.html
Edward Betts 2a82a9e8fa Fix sidebar scroll cut off by removing Bootstrap h-100 from main row
Bootstrap's h-100 class applies height:100% !important, overriding the
custom calc(100vh - 56px) on #main-row. This made the sidebar 900px tall
starting at y=56 (below the navbar), extending 56px below the viewport
and cutting off the bottom of the stop list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 21:09:10 +00:00

136 lines
5.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% if route_name %}{{ route_name }} {% endif %}OSM Public Transport → GeoJSON</title>
{% if route_name %}<meta property="og:title" content="{{ route_name }} OSM Public Transport → GeoJSON">{% endif %}
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<nav class="navbar navbar-dark bg-dark px-3" style="height:56px">
<a class="navbar-brand" href="{{ url_for('index') }}">OSM Public Transport → GeoJSON</a>
<a class="nav-link text-white" href="{{ url_for('docs') }}">API docs</a>
</nav>
<div class="container-fluid h-100 p-0">
<div class="row g-0" id="main-row">
<!-- Sidebar -->
<div class="col-3 border-end" id="sidebar">
<!-- Load form -->
<form method="post" action="{{ url_for('load') }}" class="mb-3">
<label class="form-label fw-semibold small">Relation ID or OSM URL</label>
<div class="input-group input-group-sm">
<input type="text" name="relation" class="form-control"
placeholder="e.g. 15083963"
value="{{ relation_id or '' }}">
<button class="btn btn-primary" type="submit">Load</button>
</div>
</form>
<!-- Error alert -->
{% if error %}
<div class="alert alert-danger alert-dismissible py-2 small" role="alert">
{{ error }}
<button type="button" class="btn-close btn-sm" data-bs-dismiss="alert"></button>
</div>
{% endif %}
<div id="js-alert" class="alert alert-danger alert-dismissible py-2 small d-none" role="alert">
<span id="js-alert-msg"></span>
<button type="button" class="btn-close btn-sm" data-bs-dismiss="alert"></button>
</div>
<!-- Route master panel (shown when a route_master relation is loaded) -->
<div id="route-master-panel" class="d-none">
<div class="mb-3">
<div class="fw-semibold" id="route-master-name"></div>
<a id="route-master-osm-link" class="small text-muted" target="_blank" rel="noopener">View on OSM ↗</a>
</div>
<div class="fw-semibold small mb-1">Routes</div>
<div id="route-master-list"></div>
</div>
<!-- Route info (hidden until loaded) -->
<div id="route-panel" class="d-none">
<div class="mb-3">
<div class="fw-semibold" id="route-name"></div>
<a id="route-osm-link" class="small text-muted" target="_blank" rel="noopener">View on OSM ↗</a>
</div>
<!-- From / To slots -->
<div class="mb-1">
<label class="form-label fw-semibold small mb-1">From</label>
<div class="slot-box active" id="slot-from" title="Click to make active, then click a stop">
<span class="placeholder" id="slot-from-text">Click a stop…</span>
<span class="pencil" id="slot-from-pencil"></span>
</div>
</div>
<div class="mb-3">
<label class="form-label fw-semibold small mb-1">To</label>
<div class="slot-box" id="slot-to" title="Click to make active, then click a stop">
<span class="placeholder" id="slot-to-text">Click a stop…</span>
<span class="pencil d-none" id="slot-to-pencil"></span>
</div>
</div>
<!-- Clear button -->
<button class="btn btn-outline-secondary btn-sm w-100 mb-3" id="btn-clear" type="button">
✕ Clear selection
</button>
<!-- Include stops toggle -->
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="include-stops" checked>
<label class="form-check-label small" for="include-stops">Include stops in GeoJSON</label>
</div>
<!-- Download buttons -->
<div class="d-grid gap-2 mb-3">
<button class="btn btn-outline-secondary btn-sm disabled" id="btn-download-segment">
↓ Download segment
</button>
<button class="btn btn-outline-secondary btn-sm" id="btn-download-full">
↓ Download full route
</button>
</div>
<!-- Other directions -->
<div id="other-directions-panel" class="d-none mb-3">
<div class="fw-semibold small mb-1">Other directions</div>
<div id="other-directions-list"></div>
</div>
<!-- Stop list -->
<div class="fw-semibold small mb-1">Stops <span id="stop-count" class="text-muted"></span></div>
<div id="stop-list"></div>
</div>
</div><!-- /sidebar -->
<!-- Map -->
<div class="col-9" id="map"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
// Injected by Flask so app.js works correctly under any mount path.
const RELATION_ID = {{ relation_id | tojson }};
const URLS = {
routeApi: {{ url_for('api_route', relation_id=0)[:-1] | tojson }},
segmentApi: {{ url_for('api_segment', relation_id=0)[:-1] | tojson }},
routeMasterApi: {{ url_for('api_route_master', relation_id=0)[:-1] | tojson }},
routePage: {{ url_for('route_page', relation_id=0)[:-1] | tojson }},
};
</script>
<script src="{{ url_for('static', filename='app.js') }}"></script>
</body>
</html>