From 0e34600714186c27bc87641836456fd5a47ac9a3 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Fri, 26 Jun 2026 21:30:22 -0700 Subject: [PATCH] feat: client-side session search by name, date, and notes (2.4.0) Add a search bar to the sessions list panel that filters rows in real time. Searches display label, ISO date, month/year, and session notes. The count badge updates to show matching/total; a no-results message appears when the query has no matches. --- config.py | 2 +- static/css/style.css | 23 ++++++++++++++++++++++ templates/league_sessions.html | 35 ++++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/config.py b/config.py index edb1d78..c0d56dc 100644 --- a/config.py +++ b/config.py @@ -9,7 +9,7 @@ DATA_PATH = BASE_DIR / "data" / "entries.csv" DEFAULT_DATABASE_URL = f"sqlite:///{BASE_DIR / 'data' / 'boker-dev.sqlite3'}" ELIGIBLE_MIN_SESSIONS = 3 -APP_VERSION = "2.3.1" +APP_VERSION = "2.4.0" def load_local_env(env_path: Path) -> None: diff --git a/static/css/style.css b/static/css/style.css index f213241..ca76ef1 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -2346,6 +2346,29 @@ select.control { cursor: pointer; } } /* Session create form — horizontal 3-col grid */ +.sessions-search-bar { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 16px; + border-bottom: 1px solid var(--border); + background: var(--surface-sunk); +} +.sessions-search-bar__icon { + color: var(--faintest); + flex-shrink: 0; +} +.sessions-search-bar__input { + flex: 1; + background: none; + border: none; + outline: none; + font-size: .85rem; + color: var(--text); + font-family: inherit; +} +.sessions-search-bar__input::placeholder { color: var(--faintest); } + .session-create-row { display: grid; grid-template-columns: 1fr 1fr 1fr; diff --git a/templates/league_sessions.html b/templates/league_sessions.html index 60f5d50..b6c64da 100644 --- a/templates/league_sessions.html +++ b/templates/league_sessions.html @@ -48,7 +48,7 @@

All sessions

- {{ sessions|length }} total + {{ sessions|length }} total {% if can_manage and empty_count > 0 %}
@@ -58,10 +58,21 @@
{% if sessions %} + +
{% for session in sessions %} {% set sm = db_id_to_summary.get(session.id) %} -
+
{{ session.session_date.strftime('%b') }} @@ -152,6 +163,26 @@ document.querySelectorAll('[data-close-modal]').forEach(function(btn) { reopenModal && reopenModal.addEventListener('click', function(e) { if (e.target === this) this.setAttribute('hidden', ''); }); + +(function () { + var input = document.getElementById('sess-search'); + var countLabel = document.getElementById('sess-count-label'); + var emptyMsg = document.getElementById('sess-empty-search'); + if (!input) return; + var total = {{ sessions|length }}; + input.addEventListener('input', function () { + var q = this.value.toLowerCase().trim(); + var rows = document.querySelectorAll('.session-row[data-search]'); + var visible = 0; + rows.forEach(function (row) { + var match = !q || row.dataset.search.includes(q); + row.style.display = match ? '' : 'none'; + if (match) visible++; + }); + if (countLabel) countLabel.textContent = q ? visible + ' of ' + total : total + ' total'; + if (emptyMsg) emptyMsg.style.display = (q && visible === 0) ? '' : 'none'; + }); +})(); {% endblock %}