From 5b598e77436471cc93a8888c562ded6cd96f2b99 Mon Sep 17 00:00:00 2001 From: weeman <weeman@frankfurt.ccc.de> Date: Mon, 23 Dec 2024 22:02:50 +0100 Subject: [PATCH] =?UTF-8?q?Setzte=20sticky=20Raumnamen=20f=C3=BCr=20den=20?= =?UTF-8?q?Fahrplan.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leider klappen die aktuellen position: sticky Attribute nicht. Deswegen jetzt eine Lösung per JavaScript. Beim Scrollen vom Container wird `top` der Raumnamen entsprechend der Scroll-Position nachgezogen. --- .../plainui/components/calendar.html.j2 | 16 ++++--- src/plainui/jinja2/plainui/fahrplan.html.j2 | 4 ++ .../jinja2/plainui/public_fahrplan.html.j2 | 1 + src/plainui/static/plainui/js/fahrplan.js | 47 +++++++++++++++++++ src/plainui/styles/components/_calendar.scss | 9 +++- src/plainui/styles/components/_fahrplan.scss | 1 + 6 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 src/plainui/static/plainui/js/fahrplan.js diff --git a/src/plainui/jinja2/plainui/components/calendar.html.j2 b/src/plainui/jinja2/plainui/components/calendar.html.j2 index 3e52e8350..e09a5a8df 100644 --- a/src/plainui/jinja2/plainui/components/calendar.html.j2 +++ b/src/plainui/jinja2/plainui/components/calendar.html.j2 @@ -7,7 +7,7 @@ {%- else -%} {% set time_steps = events.calendar_time_steps -%} {% set step_minutes = events.calendar_step_minutes -%} - <div class="hub-fahrplan"> + <div id="hub-fahrplan-calendar" class="hub-fahrplan"> {% for step in time_steps %} <hr class="hub-calendar__divider" style="top: {{ 56 + (loop.index0 * step_minutes * 6) }}px"> @@ -33,12 +33,14 @@ <div class="hub-calendar__column-title-inner">{{ room.name }}</div> </h2> {% else %} - <a class="text-decoration-none a" - href="{{ url('plainui:room', slug=room.slug) }}"> - <h2 class="hub-calendar__column-title" title="{{ room.name }}"> - <div class="hub-calendar__column-title-inner">{{ room.name }}</div> - </h2> - </a> + <div class="hub-calendar__column-title"> + <a class="text-decoration-none a" + href="{{ url('plainui:room', slug=room.slug) }}"> + <h2 title="{{ room.name }}"> + <div class="hub-calendar__column-title-inner">{{ room.name }}</div> + </h2> + </a> + </div> {% endif %} {% for entry in room_events %} {% if entry.type == 'space' %} diff --git a/src/plainui/jinja2/plainui/fahrplan.html.j2 b/src/plainui/jinja2/plainui/fahrplan.html.j2 index 1e2b05bfc..79f6c5e63 100644 --- a/src/plainui/jinja2/plainui/fahrplan.html.j2 +++ b/src/plainui/jinja2/plainui/fahrplan.html.j2 @@ -4,6 +4,10 @@ {% import "plainui/components/nav.html.j2" as navMacro with context %} {% import "plainui/components/tagbox.html.j2" as tagMacros with context %} +{% block head %} + <script src="{{ static('plainui/js/fahrplan.js') }}" /></script> +{% endblock head %} + {% macro filter_button(value, active, label) -%} <button type="submit" name="set" diff --git a/src/plainui/jinja2/plainui/public_fahrplan.html.j2 b/src/plainui/jinja2/plainui/public_fahrplan.html.j2 index 81e484660..f077861d4 100644 --- a/src/plainui/jinja2/plainui/public_fahrplan.html.j2 +++ b/src/plainui/jinja2/plainui/public_fahrplan.html.j2 @@ -22,6 +22,7 @@ document.querySelector('html').classList.add('js'); }); </script> + <script src="{{ static('plainui/js/fahrplan.js') }}" /></script> </head> <body class="hub-fahrplan__pub-body eyecandy"> <div class="hub-bg-L04 hub-fahrplan__pub-content"> diff --git a/src/plainui/static/plainui/js/fahrplan.js b/src/plainui/static/plainui/js/fahrplan.js new file mode 100644 index 000000000..ad7272a70 --- /dev/null +++ b/src/plainui/static/plainui/js/fahrplan.js @@ -0,0 +1,47 @@ +// No ES modules used. Wrap into a closure to avoid collisions. +(function () { + // Wait until document is loaded + const docReady = (callback) => { + if (document.readyState != "loading") callback(); + else document.addEventListener("DOMContentLoaded", callback); + }; + + // Defined in _calendar.scss + const scrollOffset = -5; + + /** + * Tries to get the Fahrplan Element. + * This may be something different depending on whether it shows the public or regular Fahrplan view. + */ + const getFahrplanElement = () => { + return document.querySelector(".hub-fahrplan__pub-box") ?? document.getElementById("hub-fahrplan-calendar"); + }; + + docReady(() => { + const fahrplanElement = getFahrplanElement(); + + if (fahrplanElement === null) { + // Nothing to do, if there is no Fahrplan + return; + } + + const roomNames = document.querySelectorAll(".hub-calendar__column-title"); + + /** + * When scrolling, keep room names always on top of the columns. + * + * @param {Event} event + */ + const handleScroll = (event) => { + // Keep room names always on top of the columns + const scrollPosition = event.target.scrollTop; + const roomNameTop = `${scrollPosition + scrollOffset}px`; + + roomNames.forEach((roomName) => { + roomName.style.top = roomNameTop; + }); + }; + + fahrplanElement.addEventListener("scroll", handleScroll); + }); +})(); diff --git a/src/plainui/styles/components/_calendar.scss b/src/plainui/styles/components/_calendar.scss index fed3ebe66..dd9cfd8cc 100644 --- a/src/plainui/styles/components/_calendar.scss +++ b/src/plainui/styles/components/_calendar.scss @@ -1,7 +1,13 @@ .hub-calendar__column-title { height: 72px; margin-bottom: 0; - padding: map-get($spacers, 1); + padding: 0 map-get($spacers, 1) map-get($spacers, 1); + position: relative; + top: -5px; +} + +.hub-calendar__column-title h2 { + font-size: 1.8rem; } .hub-calendar__column-title-inner { @@ -9,7 +15,6 @@ -webkit-box-orient: vertical; color: $white; display: -webkit-box; - font: $hub-head-category-font; overflow: hidden; text-align: center; text-overflow: ellipsis; diff --git a/src/plainui/styles/components/_fahrplan.scss b/src/plainui/styles/components/_fahrplan.scss index 8e06c1a60..f991cb55c 100644 --- a/src/plainui/styles/components/_fahrplan.scss +++ b/src/plainui/styles/components/_fahrplan.scss @@ -123,6 +123,7 @@ $public-fahrplan-body-padding: 0.7rem; } .hub-fahrplan__pub-box { + padding-top: 10px; max-height: 100%; overflow: scroll; } -- GitLab