feat(filters): surface started/ended date filters on the PlayEvent filter bar
Add Started and Finished DateRangePicker widgets to the PlayEvent filter bar and wire filter-started / filter-ended into the filter-bar date-range serializer, so the started/ended DateCriterion fields (added for #67) are reachable from the UI — enabling "finished in year Y" range filtering. Builds on #67 (PlayEventFilter.started/ended are DateCriterion); the bare field names round-trip through _parse_range like the Purchase date fields. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1479,6 +1479,8 @@ class PlayEventFilterBar(_FilterBarBase):
|
||||
def _playevent_fields(existing: dict) -> list:
|
||||
game_choice = _filter_get_choice(existing, "game")
|
||||
days_min, days_max = _parse_range(existing, "days_to_finish")
|
||||
started_min, started_max = _parse_range(existing, "started")
|
||||
ended_min, ended_max = _parse_range(existing, "ended")
|
||||
|
||||
fields = [
|
||||
Div(
|
||||
@@ -1495,6 +1497,24 @@ def _playevent_fields(existing: dict) -> list:
|
||||
),
|
||||
],
|
||||
),
|
||||
_filter_field(
|
||||
"Started",
|
||||
DateRangePicker(
|
||||
label="Started",
|
||||
input_name_prefix="filter-started",
|
||||
min_value=started_min,
|
||||
max_value=started_max,
|
||||
),
|
||||
),
|
||||
_filter_field(
|
||||
"Finished",
|
||||
DateRangePicker(
|
||||
label="Finished",
|
||||
input_name_prefix="filter-ended",
|
||||
min_value=ended_min,
|
||||
max_value=ended_max,
|
||||
),
|
||||
),
|
||||
RangeSlider(
|
||||
label="Days to Finish",
|
||||
input_name_prefix="filter-days-to-finish",
|
||||
|
||||
@@ -223,6 +223,59 @@ class FilterBarRenderingTest(TestCase):
|
||||
)
|
||||
self._assert_shell(html, "/presets/playevents/list", "/presets/playevents/save")
|
||||
|
||||
def test_playevent_filter_bar_renders_date_inputs(self):
|
||||
"""PlayEventFilterBar surfaces started and ended as DateRangePicker
|
||||
widgets whose -min/-max hidden inputs (the JS serializer contract)
|
||||
carry the filter-started / filter-ended prefixes, in labelled fields."""
|
||||
from common.components import PlayEventFilterBar
|
||||
|
||||
html = str(
|
||||
PlayEventFilterBar(
|
||||
filter_json="", preset_list_url="/l", preset_save_url="/s"
|
||||
)
|
||||
)
|
||||
for name in (
|
||||
"filter-started-min",
|
||||
"filter-started-max",
|
||||
"filter-ended-min",
|
||||
"filter-ended-max",
|
||||
):
|
||||
self.assertIn(f'name="{name}"', html)
|
||||
self.assertIn(f'id="{name}"', html)
|
||||
self.assertIn("<date-range-picker", html)
|
||||
self.assertIn("Started", html)
|
||||
self.assertIn("Finished", html)
|
||||
self.assertNoEscapedTags(html)
|
||||
|
||||
def test_playevent_filter_bar_prepopulates_ended_between(self):
|
||||
"""A BETWEEN filter on ended populates both date bounds via _parse_range."""
|
||||
from common.components import PlayEventFilterBar
|
||||
|
||||
filter_json = json.dumps(
|
||||
{
|
||||
"ended": {
|
||||
"value": "2024-01-01",
|
||||
"value2": "2024-12-31",
|
||||
"modifier": "BETWEEN",
|
||||
}
|
||||
}
|
||||
)
|
||||
html = str(
|
||||
PlayEventFilterBar(
|
||||
filter_json=filter_json,
|
||||
preset_list_url="/l",
|
||||
preset_save_url="/s",
|
||||
)
|
||||
)
|
||||
self.assertIn(
|
||||
'name="filter-ended-min" id="filter-ended-min" value="2024-01-01"',
|
||||
html,
|
||||
)
|
||||
self.assertIn(
|
||||
'name="filter-ended-max" id="filter-ended-max" value="2024-12-31"',
|
||||
html,
|
||||
)
|
||||
|
||||
def test_game_filter_bar_has_new_widgets(self):
|
||||
"""The expanded games FilterBar exposes platform_group, device, playevent_note,
|
||||
purchase_type / purchase_ownership_type, plus count and aggregate-playtime
|
||||
|
||||
@@ -201,6 +201,8 @@ function buildFilterJSON(form: HTMLElement): Record<string, unknown> {
|
||||
const dateRangeFields = [
|
||||
{ prefix: "filter-date-purchased", key: "date_purchased" },
|
||||
{ prefix: "filter-date-refunded", key: "date_refunded" },
|
||||
{ prefix: "filter-started", key: "started" },
|
||||
{ prefix: "filter-ended", key: "ended" },
|
||||
];
|
||||
dateRangeFields.forEach((dateField) => {
|
||||
const valueMin = stringValue(form, dateField.prefix + "-min");
|
||||
|
||||
Reference in New Issue
Block a user