aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2022-06-29 13:07:33 +0200
committerDaniel Schadt <kingdread@gmx.de>2022-06-29 13:07:33 +0200
commitedd344cd9af5d4c0ca1ccd491bca004956264708 (patch)
treeab23312ee6d74fae7fc800267185b99b4e06a367
parent315372ff4d55cec4a846923b4e95bc604d3f75e9 (diff)
downloadfietsboek-edd344cd9af5d4c0ca1ccd491bca004956264708.tar.gz
fietsboek-edd344cd9af5d4c0ca1ccd491bca004956264708.tar.bz2
fietsboek-edd344cd9af5d4c0ca1ccd491bca004956264708.zip
add tooltips to track overview
-rw-r--r--fietsboek/models/track.py25
-rw-r--r--fietsboek/static/fietsboek.js22
-rw-r--r--fietsboek/static/theme.css4
-rw-r--r--fietsboek/templates/home.jinja22
-rw-r--r--fietsboek/templates/layout.jinja230
5 files changed, 68 insertions, 15 deletions
diff --git a/fietsboek/models/track.py b/fietsboek/models/track.py
index 001d4b9..4c0583b 100644
--- a/fietsboek/models/track.py
+++ b/fietsboek/models/track.py
@@ -13,9 +13,13 @@ from sqlalchemy import (
from sqlalchemy.orm import relationship
from sqlalchemy.types import TypeDecorator
+from pyramid.i18n import TranslationString as _
+
import enum
import gzip
+from markupsafe import Markup
+
from .meta import Base
from .. import util
@@ -104,6 +108,27 @@ class Track(Base):
return util.tour_metadata(self.gpx_data)["uphill"]
return self.cache.uphill
+ def html_tooltip(self, localizer):
+ """Generate a quick summary of the track as a HTML element.
+
+ This can be used in Bootstrap tooltips.
+
+ :param localizer: The localizer used for localization.
+ :type localizer: pyramid.i18n.Localizer
+ :return: The generated HTML.
+ :rtype: Markup
+ """
+ rows = [
+ (_("tooltip.table.length"), f'{round(self.length, 2)} km'),
+ (_("tooltip.table.uphill"), f'{round(self.uphill, 2)} m'),
+ (_("tooltip.table.downhill"), f'{round(self.downhill, 2)} m'),
+ ]
+ rows = [
+ "<tr><td>{}</td><td>{}</td></tr>".format(localizer.translate(name), value)
+ for (name, value) in rows
+ ]
+ return Markup(f'<table>{"".join(rows)}</table>')
+
class TrackCache(Base):
__tablename__ = 'track_cache'
diff --git a/fietsboek/static/fietsboek.js b/fietsboek/static/fietsboek.js
index 85711e9..0f0685d 100644
--- a/fietsboek/static/fietsboek.js
+++ b/fietsboek/static/fietsboek.js
@@ -5,14 +5,17 @@ function tagClicked(event) {
function updateTagList() {
let input = document.querySelector('#formTagsInput');
- input.value = "";
- document.querySelectorAll(".tag-badge").forEach((t) => {
- input.value += t.textContent + " ";
- });
- input.value = input.value.trim();
+ if (input) {
+ input.value = "";
+ document.querySelectorAll(".tag-badge").forEach((t) => {
+ input.value += t.textContent + " ";
+ });
+ input.value = input.value.trim();
+ }
}
document.addEventListener('DOMContentLoaded', function(event) {
+ /* Enable the "Add tag" button */
let $ = (selector) => document.querySelector(selector);
let button = $("#add-tag-btn");
if (button) {
@@ -32,6 +35,15 @@ document.addEventListener('DOMContentLoaded', function(event) {
})
}
+ /* Enable clicking on a tag to remove it */
document.querySelectorAll(".tag-badge").forEach((t) => t.addEventListener("click", tagClicked));
+
+ /* Initialize the pre-loaded tags */
updateTagList();
+
+ /* Enable tooltips */
+ var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
+ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
+ return new bootstrap.Tooltip(tooltipTriggerEl, {sanitize: false})
+ });
});
diff --git a/fietsboek/static/theme.css b/fietsboek/static/theme.css
index 4f10970..274b030 100644
--- a/fietsboek/static/theme.css
+++ b/fietsboek/static/theme.css
@@ -5,6 +5,10 @@ body {
background: #efefef;
}
+.tooltip-inner {
+ max-width: 400px;
+}
+
.list-group.list-group-root {
padding: 0;
overflow: hidden;
diff --git a/fietsboek/templates/home.jinja2 b/fietsboek/templates/home.jinja2
index 4e78e7d..ccd9af0 100644
--- a/fietsboek/templates/home.jinja2
+++ b/fietsboek/templates/home.jinja2
@@ -12,7 +12,7 @@
<a class="list-group-item list-group-item-secondary">{{ month_name(request, month.month) }} &mdash; {{ (month.total_length / 1000) | round(2) }} km</a>
<div class="list-group">
{% for track in month %}
- <span class="list-group-item">{{ track.date.day }}: <a href="{{ request.route_url('details', id=track.id) }}">{{ track.title | default(track.date, true) }}</a></span>
+ <span class="list-group-item">{{ track.date.day }}: <a href="{{ request.route_url('details', id=track.id) }}" data-bs-toggle="tooltip" data-bs-container="body" data-bs-html="true" title="{{ track.html_tooltip(request.localizer) }}">{{ track.title | default(track.date, true) }}</a></span>
{% endfor %}
</div>
{% endfor %}
diff --git a/fietsboek/templates/layout.jinja2 b/fietsboek/templates/layout.jinja2
index b445b2f..2515f01 100644
--- a/fietsboek/templates/layout.jinja2
+++ b/fietsboek/templates/layout.jinja2
@@ -7,7 +7,7 @@
<meta name="description" content="Fietslog Tour Diary">
<link rel="shortcut icon" href="{{request.static_url('fietsboek:static/pyramid-16x16.png')}}">
- <title>{% block title %}Fietslog{% endblock %}</title>
+ <title>{% block title %}Fietsboek{% endblock %}</title>
<style>
@font-face {
@@ -25,19 +25,31 @@
</head>
<body>
- <nav class="navbar navbar-dark bg-dark">
+ <nav class="navbar navbar-dark bg-dark navbar-expand-lg">
<div class="container-fluid">
<span class="navbar-brand mb-0 h1">Fietsboek</span>
- <ul class="navbar-nav me-auto mb-2 mb-lg-0">
- <li class="nav-item">
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="{{ _('page.navbar.toggle') }}">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ <div class="collapse navbar-collapse" id="navbar">
+ <ul class="navbar-nav me-auto mb-2 mb-lg-0">
+ <li class="nav-item">
+ <a class="nav-link" href="{{ request.route_url('home') }}">{{ _("page.navbar.home") }}</a>
+ </li>
{% if request.identity is none %}
- <a class="nav-link" href="{{ request.route_url('login') }}">{{ _("page.navbar.login") }}</a>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ request.route_url('login') }}">{{ _("page.navbar.login") }}</a>
+ </li>
{% else %}
- <a class="nav-link" href="{{ request.route_url('logout') }}">{{ _("page.navbar.logout") }}</a>
- <a class="nav-link" href="{{ request.route_url('upload') }}">{{ _("page.navbar.upload") }}</a>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ request.route_url('logout') }}">{{ _("page.navbar.logout") }}</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ request.route_url('upload') }}">{{ _("page.navbar.upload") }}</a>
+ </li>
{% endif %}
- </li>
- </ul>
+ </ul>
+ </div>
</div>
</nav>