septastic/api/templates/route.html
Nicholas Orlowsky 12e4f08a6a
All checks were successful
Create and publish a Docker image / build-and-push-image (push) Successful in 5m26s
fix autoscroll
2025-10-07 19:02:30 -04:00

170 lines
5.1 KiB
HTML

{%- import "route_symbol.html" as scope -%}
<style>
.train-direction-table {
width: 100%;
border-collapse: collapse;
font-family: sans-serif;
font-size: 14px;
}
.train-direction-table th,
.train-direction-table td {
border: 1px solid #000;
padding: 4px 8px;
text-align: left;
cursor: pointer;
}
.train-direction-table th {
background-color: #f0f0f0;
font-weight: bold;
}
.highlight-row td,
.highlight-row th {
background-color: #d0ebff !important;
}
.highlight-col {
background-color: #d0ebff !important;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", () => {
const scrollToNextColumn = (directionId) => {
const target = document.getElementById("next-col-" + directionId);
if (target) {
const scrollContainer = target.closest(".tscroll");
const firstCol = scrollContainer.querySelector("th:first-child");
const firstColWidth = firstCol ? firstCol.offsetWidth : 0;
// Get the target's position relative to the scroll container
const targetLeft = target.offsetLeft;
// Scroll so the target appears right after the sticky column
scrollContainer.scrollLeft = targetLeft - firstColWidth;
}
};
document.querySelectorAll("details[data-direction-id]").forEach(details => {
const directionId = details.getAttribute("data-direction-id");
// Scroll immediately if details is already open
if (details.open) {
setTimeout(() => scrollToNextColumn(directionId), 50);
}
// Also scroll when details is opened
details.addEventListener("toggle", () => {
if (details.open) {
setTimeout(() => scrollToNextColumn(directionId), 50);
}
});
});
document.querySelectorAll(".train-direction-table").forEach((table) => {
table.addEventListener("click", (e) => {
const cell = e.target.closest("td, th");
if (!cell) return;
// Clear previous highlights
table.querySelectorAll("tr").forEach(row => row.classList.remove("highlight-row"));
table.querySelectorAll("td, th").forEach(c => c.classList.remove("highlight-col"));
const row = cell.parentNode;
const colIndex = Array.from(cell.parentNode.children).indexOf(cell);
// If it's the first column (row header)
if (cell.cellIndex === 0 && cell.tagName === "TD") {
row.classList.add("highlight-row");
}
// If it's a column header
else if (row.parentNode.tagName === "THEAD") {
table.querySelectorAll("tr").forEach(r => {
const cell = r.children[colIndex];
if (cell) cell.classList.add("highlight-col");
});
}
// If it's a center cell
else {
row.classList.add("highlight-row");
table.querySelectorAll("tr").forEach(r => {
const cell = r.children[colIndex];
if (cell) cell.classList.add("highlight-col");
});
}
});
});
});
</script>
<div style="display: flex; align-items: center;">
{% call scope::route_symbol(route) %}
<h1 style="margin-left: 15px;">{{ route.name }}</h1>
</div>
{% for timetable in timetables %}
<details style="margin-top: 15px;" data-direction-id="{{ timetable.direction.direction_id }}">
<summary>
<div style="display: inline-block;">
<h3>{{ timetable.direction.direction | capitalize }} to</h3>
<h2>{{ timetable.direction.direction_destination }}</h2>
</div>
</summary>
<div class="tscroll">
<table class="train-direction-table" style="margin-top: 5px;">
<thead>
<tr>
<th>Stop</th>
{% for trip_id in timetable.trip_ids %}
{% if let Some(next_id_v) = timetable.next_id %}
{% if next_id_v == trip_id %}
<th class="next-col" id="next-col-{{ timetable.direction.direction_id }}">
{% else %}
<th>
{% endif %}
{% else %}
<th>
{% endif %}
{{ trip_id }}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in timetable.rows %}
{% if let Some(filter_stop_v) = filter_stops %}
{% if !filter_stop_v.contains(&row.stop_id) %}
{% continue %}
{% endif %}
{% endif %}
<tr>
<td>{{ row.stop_name }}</td>
{% for time in row.times %}
{% if let Some(t) = time %}
{% let live_o = timetable.tracking_data[loop.index0] %}
{% if let Tracked(live) = live_o %}
{% let time = (t + (live.delay * 60.0) as i64) %}
<td style="background-color: #003300">
<span style="color: #22bb22"> {{ time | format_time }} </span>
</td>
{% elif let TripTracking::Cancelled = live_o %}
<td style="color: #ff0000"><s>{{ t | format_time }}</s></td>
{% else %}
<td>{{ t | format_time }}</td>
{% endif %}
{% else %}
<td>
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</details>
{% endfor %}