From 541fb550abd3e9c9509d002f29fa5270d01024dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Fri, 19 Jun 2026 13:34:06 +0200 Subject: [PATCH] Convert search_select.js to TypeScript (issue #17) - Add ts/search_select.ts: typed port of the SearchSelect/FilterSelect widget. Exports SearchSelectOption / SearchSelectChangeDetail as the single source of truth for the "search-select:change" event contract - add_purchase.ts now imports those types via `import type` (no runtime coupling), instead of redefining them locally - Declare window.readSearchSelect in ts/globals.d.ts - Point the SearchSelect component Media and every view/e2e/test reference at the compiled dist/search_select.js - Update doc comments in common/components/search_select.py to name the TS source Co-Authored-By: Claude Sonnet 4.6 --- common/components/search_select.py | 9 +- e2e/test_boolean_filter_e2e.py | 2 +- e2e/test_date_filter_e2e.py | 2 +- e2e/test_date_range_picker_e2e.py | 2 +- e2e/test_purchase_e2e.py | 2 +- e2e/test_range_slider_e2e.py | 2 +- e2e/test_search_select_e2e.py | 2 +- e2e/test_string_filter_e2e.py | 2 +- games/views/game.py | 4 +- games/views/playevent.py | 4 +- games/views/purchase.py | 4 +- games/views/session.py | 4 +- tests/test_node_tree.py | 6 +- tests/test_rendered_pages.py | 2 +- ts/add_purchase.ts | 13 +- ts/globals.d.ts | 1 + .../search_select.js => ts/search_select.ts | 243 ++++++++++-------- 17 files changed, 165 insertions(+), 139 deletions(-) rename games/static/js/search_select.js => ts/search_select.ts (72%) diff --git a/common/components/search_select.py b/common/components/search_select.py index a58b41f..b289b05 100644 --- a/common/components/search_select.py +++ b/common/components/search_select.py @@ -6,7 +6,8 @@ hidden ```` so an existing ``ModelMultipleChoiceField`` keeps validating. This module imports only from ``common.components`` — it has no Django-forms or ``games`` knowledge. Styling is inline Tailwind utilities; behavioural hooks are -``data-*`` attributes wired up by ``games/static/js/search_select.js``. +``data-*`` attributes wired up by ``ts/search_select.ts`` (compiled to +``games/static/js/dist/search_select.js``). Option sourcing follows two axes. *Population*: options are either rendered inline up front (``options=``, no ``search_url``) or fetched from ``search_url``. @@ -25,8 +26,8 @@ from typing import TypedDict from common.components.core import Attributes, Element, HTMLAttribute, Media, Node from common.components.primitives import Div, Input, Pill, Span, Template -# Both comboboxes are wired by search_select.js. -_SEARCH_SELECT_MEDIA = Media(js=("search_select.js",)) +# Both comboboxes are wired by ts/search_select.ts (compiled to dist/). +_SEARCH_SELECT_MEDIA = Media(js=("dist/search_select.js",)) class SearchSelectOption(TypedDict): @@ -81,7 +82,7 @@ DEFAULT_PREFETCH = 20 # Inline class strings (ported verbatim from the retired SelectableFilter CSS) # so the filter combobox is fully self-styled — nothing in input.css. JS-added # rows/pills are cloned from server-rendered