Skip to content

Commit edc37f8

Browse files
committed
[#2111] set-up for filter web-components
1 parent d210a6d commit edc37f8

File tree

17 files changed

+1525
-25
lines changed

17 files changed

+1525
-25
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Nieuwe features
2222
in Docker/Kubernetes.
2323
* [:gh:`2107`]: Productie logs worden weggeschreven als JSON voor gebruik in log analyse
2424
tools.
25+
* [:gh:`2111`]: Filter-drowdowns and mobiele filters in pop-up scherm toegeveogd ten behoeve van de ‘Mijn Afval’ app.
2526
* [:gh:`2113`]: Diagram (chart.js) toegevoegd ten behoeve van de ‘Mijn Afval’ app.
2627
* [:gh:`2119`, :gh:`2182`, :pr:`2151`]: API-client en configuratie voor 'Mijn Afval' aangemaakt.
2728

package-lock.json

Lines changed: 0 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/open_inwoner/mijn_afval/views.py

Lines changed: 110 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ class _BAGObjectData(TypedDict):
120120
containers: list[_AfvalContainerData]
121121

122122

123+
class _FilterChoice(TypedDict):
124+
"""A single choice in a filter group."""
125+
126+
value: str
127+
label: str
128+
129+
130+
class _FilterGroup(TypedDict):
131+
"""A group of filter choices."""
132+
133+
name: str
134+
label: str
135+
choices: list[_FilterChoice]
136+
137+
123138
def _format_container_for_table(
124139
ledigingen: list[_LedigingData],
125140
totaal_gewicht: str,
@@ -260,6 +275,89 @@ def _format_afval_profiel(profiel: AfvalProfiel) -> list[_BAGObjectData]:
260275
return result
261276

262277

278+
def _extract_filter_options(afval_data: list[_BAGObjectData]) -> list[_FilterGroup]:
279+
"""
280+
Extract unique filter options from the formatted afval data.
281+
282+
Args:
283+
afval_data: List of formatted BAG object data
284+
285+
Returns:
286+
List of filter groups with their available choices
287+
"""
288+
addresses: dict[str, str] = {} # value: label
289+
container_types: dict[str, str] = {} # value: label
290+
periods: dict[str, str] = {} # year: year (as label)
291+
292+
# Extract unique values from the data
293+
for bag_obj in afval_data:
294+
# Extract address
295+
if bag_obj["object_address"]:
296+
addresses[bag_obj["object_address"]] = bag_obj["object_address"]
297+
298+
# Extract container types and periods
299+
for container in bag_obj["containers"]:
300+
# Container type
301+
container_type = container["type"]
302+
if container_type not in container_types:
303+
container_types[container_type] = _get_container_type_label(
304+
container_type
305+
)
306+
307+
# Extract years from ledigingen dates
308+
for lediging in container["ledigingen"]:
309+
# Date format is "dd-mm-yyyy", extract year
310+
date_parts = lediging["tijdstip_datum"].split("-")
311+
if len(date_parts) == 3:
312+
year = date_parts[2]
313+
if year not in periods:
314+
periods[year] = _("Jaar {year}").format(year=year)
315+
316+
# Build filter groups
317+
filter_groups: list[_FilterGroup] = []
318+
319+
# Adres filter
320+
if addresses:
321+
filter_groups.append(
322+
{
323+
"name": "adres",
324+
"label": _("Adres"),
325+
"choices": [
326+
{"value": value, "label": label}
327+
for value, label in sorted(addresses.items())
328+
],
329+
}
330+
)
331+
332+
# Type container filter
333+
if container_types:
334+
filter_groups.append(
335+
{
336+
"name": "type-container",
337+
"label": _("Type container"),
338+
"choices": [
339+
{"value": value, "label": label}
340+
for value, label in sorted(container_types.items())
341+
],
342+
}
343+
)
344+
345+
# Periode filter (sorted by year descending)
346+
if periods:
347+
filter_groups.append(
348+
{
349+
"name": "periode",
350+
"label": _("Periode"),
351+
"choices": [
352+
{"value": value, "label": label}
353+
for value, label in sorted(periods.items(), reverse=True)
354+
],
355+
}
356+
)
357+
358+
return filter_groups
359+
360+
263361
class AfvalProfielView(
264362
LoginRequiredMixin, BaseBreadcrumbMixin, AppConfigMixin, TemplateView
265363
):
@@ -305,7 +403,7 @@ def get_context_data(self, **kwargs):
305403
afval_config = MijnAfvalConfig.get_solo()
306404

307405
if not (openafval_service := afval_config.openafval_service):
308-
messages.error(_("This module is not yet configured"))
406+
messages.error(self.request, _("This module is not yet configured"))
309407
return context
310408

311409
api_client = build_zgw_client(
@@ -320,11 +418,19 @@ def get_context_data(self, **kwargs):
320418
messages.error(
321419
self.request,
322420
_(
323-
"We kunnen uw afvalgegevens momenteel niet ophalen. "
324-
"Probeer het later opnieuw."
421+
"We kunnen uw afvalgegevens momenteel niet ophalen. Probeer het later opnieuw."
325422
),
326423
)
327424
afval_data = []
328425

329-
context["afval_data"] = afval_data
426+
# Extract filter options from the formatted data for the frontend filters
427+
filter_groups = _extract_filter_options(afval_data)
428+
429+
context.update(
430+
{
431+
"afval_data": afval_data,
432+
"filter_groups": filter_groups,
433+
}
434+
)
435+
330436
return context
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// FilterTag - Active filter pills/tags
2+
3+
.oip-filter-tags {
4+
display: flex;
5+
flex-direction: row;
6+
gap: var(--spacing-medium, 0.75rem);
7+
flex-wrap: wrap;
8+
margin-bottom: var(--spacing-large, 1rem);
9+
margin-top: var(--spacing-medium, 0.75rem);
10+
}
11+
12+
.oip-filter-tag {
13+
display: inline-flex;
14+
align-items: center;
15+
gap: var(--spacing-small, 0.5rem);
16+
padding: 12px 16px;
17+
border: 1px solid var(--color-primary);
18+
border-radius: 3px;
19+
background-color: white;
20+
color: var(--font-color-body);
21+
font-size: var(--font-size-body, 1rem);
22+
cursor: pointer;
23+
transition: all 0.2s ease;
24+
white-space: nowrap;
25+
26+
&:hover {
27+
background-color: var(--color-gray-lightest);
28+
}
29+
30+
&:focus {
31+
outline: 2px solid var(--color-primary);
32+
outline-offset: 2px;
33+
}
34+
}
35+
36+
.oip-filter-tag__label {
37+
font-weight: 500;
38+
}
39+
40+
.oip-filter-tag__close {
41+
font-size: var(--font-size-body-large, 1.0625rem);
42+
font-weight: bold;
43+
line-height: 1;
44+
cursor: pointer;
45+
}

0 commit comments

Comments
 (0)