Skip to content

Commit

Permalink
Tp2000 959 measure list design changes (#1072)
Browse files Browse the repository at this point in the history
* Add regulation to measure list table

* WIP - Add selected filters to template

* Add selected filter string formatting

* Small design changes

* broken test - WIP

* Fix tests

* Capitalise all chosen filter bullets
  • Loading branch information
LaurenMullally authored Oct 23, 2023
1 parent 1075b47 commit e110c0f
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 9 deletions.
2 changes: 1 addition & 1 deletion measures/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def __init__(self, *args, **kwargs):
)

measure_filters_modifier = BooleanFilter(
label="Filter by current Workbasket",
label="Filter by current workbasket",
widget=forms.CheckboxInput(),
method="measures_filter",
required=False,
Expand Down
2 changes: 1 addition & 1 deletion measures/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ def __init__(self, *args, **kwargs):
Div(
"modc",
HTML(
"<h3 class='govuk-body'>To use the 'Include inherited measures' filter, enter a valid commodity code in the 'Select commodity code' filter above</h3>",
"<h3 class='govuk-body'>To use the 'Include inherited measures' filter, enter a valid commodity code in the 'Specific commodity code' filter above</h3>",
),
css_class="govuk-grid-column-full form-group-margin-bottom-2",
),
Expand Down
2 changes: 2 additions & 0 deletions measures/jinja2/includes/measures/list.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
{"text": create_link(measure.order_number.get_url(), measure.order_number.order_number) if measure.order_number else '-'},
{"text": footnotes_display(measure.footnoteassociationmeasure_set.current())},
{"text": conditions_list(measure) if measure.conditions.current() else "-", "classes": "govuk-!-width-one-quarter"},
{"text": create_link(url("regulation-ui-detail", kwargs={"role_type": measure.generating_regulation.role_type,"regulation_id": measure.generating_regulation.regulation_id}), measure.generating_regulation.regulation_id) if measure.generating_regulation.regulation_id else '-'},
]) or "" }}
{% endfor %}
{{ govukTable({
Expand All @@ -84,6 +85,7 @@
{"text": "Quota"},
{"text": "Footnote"},
{"text": "Conditions"},
{"text": "Regulations"},
],
"rows": table_rows,
"classes": "govuk-table-m"
Expand Down
15 changes: 15 additions & 0 deletions measures/jinja2/measures/list.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,22 @@
<p class="govuk-body-l">
{{ objects_count }} results
</p>
<p class="govuk-body govuk-!-margin-top-2">
You are currently viewing {{ objects_count }} results for:
</p>
<div class="govuk-grid-row">
{% for list in selected_filter_lists %}
<div class="govuk-grid-column-one-half">
<ul class="govuk-list govuk-list--bullet">
{% for item in list %}
<li>{{item}}</li>
{%endfor%}
</ul>
</div>
{%endfor%}
</div>

<hr/>
{% endif %}
{% if object_list %}
{% include list_include %}
Expand Down
9 changes: 2 additions & 7 deletions measures/jinja2/measures/search.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,12 @@

{% block content %}
<h1 class="govuk-heading-xl">{{ page_title }}</h1>
<p class="govuk-body">
Search for {{object_list.model._meta.verbose_name_plural}}.
Alternatively, <a class="govuk-link" href="{{ url("measure-ui-create") }}">create a new {{ object_list.model._meta.verbose_name }}</a>.
</p>

<div class="filter-layout full-width-search">
<div class="govuk-!-margin-bottom-5 govuk-grid-column-full">
<div class="full-width-search">
<div class="govuk-!-margin-bottom-5">
<form method="get" action="{{ url(form_url) }}">
{{ crispy(filter.form) }}
</form>
</div>
</div>

{% endblock %}
60 changes: 60 additions & 0 deletions measures/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from decimal import Decimal
from typing import OrderedDict
from unittest.mock import patch
from urllib.parse import urlencode

import pytest
from bs4 import BeautifulSoup
Expand Down Expand Up @@ -2616,3 +2617,62 @@ def test_measures_list_sorting(valid_user_client, date_ranges):
int(el.text) for el in soup.select(".govuk-table tbody tr td:nth-child(2)")
]
assert measure_sids == expected_order_list[index]


def test_measure_list_results_show_chosen_filters(valid_user_client, date_ranges):
# make measure types
type1 = factories.MeasureTypeFactory.create(sid="111")

# Erga Omnes
area_1 = factories.GeographicalAreaFactory.create(
area_code=AreaCode.GROUP,
area_id="1011",
)

# make measure
measure = factories.MeasureFactory.create(
measure_type=type1,
geographical_area=area_1,
valid_between=date_ranges.later,
)
url_params = urlencode(
{
"goods_nomenclature": measure.goods_nomenclature_id,
"sid": measure.sid,
"regulation": measure.generating_regulation_id,
"goods_nomenclature__item_id": measure.goods_nomenclature.item_id[:3],
"measure_type": measure.measure_type_id,
"geographical_area": measure.geographical_area_id,
"start_date_0": measure.valid_between.lower.day,
"start_date_1": measure.valid_between.lower.month,
"start_date_2": measure.valid_between.lower.year,
"end_date_0": measure.valid_between.upper.day,
"end_date_1": measure.valid_between.upper.month,
"end_date_2": measure.valid_between.upper.year,
},
)
response = valid_user_client.get(f"{reverse('measure-ui-list')}?{url_params}")

assert response.status_code == 200

soup = BeautifulSoup(response.content.decode(response.charset), "html.parser")
assert len(soup.find_all("ul", class_="govuk-list--bullet")) == 2

list = soup.find("ul", {"class": "govuk-list govuk-list--bullet"})
items = list.find_all("li")

current_tranx = Transaction.objects.last()
with override_current_transaction(current_tranx):
assert (
f"Commodity Code {measure.goods_nomenclature.autocomplete_label}"
in items[0]
)
assert (
f"Commodity Code starting with {measure.goods_nomenclature.item_id[:3]}"
in items[1]
)
assert f"ID {measure.sid}" in items[2]
assert (
f"Regulation {measure.generating_regulation.autocomplete_label}" in items[3]
)
assert f"Measure Type {measure.measure_type.autocomplete_label}" in items[4]
113 changes: 113 additions & 0 deletions measures/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
from rest_framework import viewsets
from rest_framework.reverse import reverse

from additional_codes.models import AdditionalCode
from certificates.models import Certificate
from commodities.models.orm import GoodsNomenclature
from common.forms import unprefix_formset_data
from common.models import TrackedModel
from common.pagination import build_pagination_list
Expand All @@ -36,6 +39,7 @@
from common.views import TamatoListView
from common.views import TrackedModelDetailMixin
from common.views import TrackedModelDetailView
from footnotes.models import Footnote
from geo_areas.models import GeographicalArea
from geo_areas.utils import get_all_members_of_geo_groups
from measures import forms
Expand All @@ -54,6 +58,8 @@
from measures.parsers import DutySentenceParser
from measures.patterns import MeasureCreationPattern
from measures.util import diff_components
from quotas.models import QuotaOrderNumber
from regulations.models import Regulation
from workbaskets.forms import SelectableObjectsForm
from workbaskets.models import WorkBasket
from workbaskets.session_store import SessionStore
Expand Down Expand Up @@ -189,6 +195,112 @@ def cleaned_query_params(self):
else:
return self.filterset.data

def selected_filter_formatter(self) -> List[List[str]]:
"""
A function that formats the selected filter choices into nicely written
up strings.
Those strings are then split into nested lists of 7 items to prepare
them for template rendering.
"""
selected_filters = {k: v for k, v in self.filterset.data.items() if v}
selected_filters_strings = []

if "goods_nomenclature" in selected_filters:
goods = GoodsNomenclature.objects.current().get(
id=selected_filters["goods_nomenclature"],
)
selected_filters_strings.append(
f"Commodity Code {goods.autocomplete_label}",
)

if "goods_nomenclature__item_id" in selected_filters:
selected_filters_strings.append(
f"Commodity Code starting with {selected_filters['goods_nomenclature__item_id']}",
)

if "order_number" in selected_filters:
quota = QuotaOrderNumber.objects.current().get(
id=selected_filters["order_number"],
)
selected_filters_strings.append(
f"Quota Order Number {quota.structure_code}",
)

if "sid" in selected_filters:
measure = Measure.objects.current().get(sid=selected_filters["sid"])
selected_filters_strings.append(f"ID {measure.sid}")

if "additional_code" in selected_filters:
code = AdditionalCode.objects.current().get(
id=selected_filters["additional_code"],
)
selected_filters_strings.append(f"Additional Code {code.structure_code}")

if "certificates" in selected_filters:
certificate = Certificate.objects.current().get(
id=selected_filters["certificates"],
)
selected_filters_strings.append(f"Certificate {certificate.structure_code}")

if "regulation" in selected_filters:
regulation = Regulation.objects.current().get(
id=selected_filters["regulation"],
)
selected_filters_strings.append(
f"Regulation {regulation.autocomplete_label}",
)

if "measure_type" in selected_filters:
measure_type = MeasureType.objects.current().get(
id=selected_filters["measure_type"],
)
selected_filters_strings.append(
f"Measure Type {measure_type.autocomplete_label}",
)

if "geographical_area" in selected_filters:
area = GeographicalArea.objects.current().get(
id=selected_filters["geographical_area"],
)
selected_filters_strings.append(f"{area.autocomplete_label}")

if "footnote" in selected_filters:
footnote = Footnote.objects.current().get(id=selected_filters["footnote"])
selected_filters_strings.append(f"Footnote {footnote.structure_code}")

if "start_date_0" and "start_date_1" and "start_date_2" in selected_filters:
if selected_filters["start_date_modifier"] == "exact":
modifier = ""
else:
modifier = selected_filters["start_date_modifier"]
selected_filters_strings.append(
f"Start date: {modifier} {selected_filters['start_date_0']}/{selected_filters['start_date_1']}/{selected_filters['start_date_2']}",
)

if "end_date_0" and "end_date_1" and "end_date_2" in selected_filters:
if selected_filters["end_date_modifier"] == "exact":
modifier = ""
else:
modifier = selected_filters["end_date_modifier"]
selected_filters_strings.append(
f"End date: {modifier} {selected_filters['end_date_0']}/{selected_filters['end_date_1']}/{selected_filters['end_date_2']}",
)

if "modc" in selected_filters:
selected_filters_strings.append("Include inherited measures")

if "measure_filters_modifier" in selected_filters:
selected_filters_strings.append("Filter by current workbasket")

# This splits the selected_filter_strings into nested lists of 7 so that the lists can be shown side by side in the template.
selected_filters_lists = [
selected_filters_strings[x : x + 7]
for x in range(0, len(selected_filters_strings), 7)
]

return selected_filters_lists

@property
def paginator(self):
filterset_class = self.get_filterset_class()
Expand Down Expand Up @@ -219,6 +331,7 @@ def get_context_data(self, **kwargs):
page.number,
page.paginator.num_pages,
),
"selected_filter_lists": self.selected_filter_formatter(),
},
)
if context["has_previous_page"]:
Expand Down

0 comments on commit e110c0f

Please sign in to comment.