Skip to content

Commit be51761

Browse files
authored
Merge pull request #837 from NHSDigital/11590-medical-info-page-review-workflow
Add review workflow to medical information page
2 parents 53b2ce8 + 74c1eb6 commit be51761

16 files changed

Lines changed: 509 additions & 27 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@use "../vendor/nhsuk-frontend/base" as *;
2+
3+
.app-card-with-status__tag {
4+
position: absolute;
5+
top: nhsuk-spacing(3);
6+
right: nhsuk-spacing(3);
7+
z-index: 1;
8+
}

manage_breast_screening/assets/sass/main.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@forward "components/count";
88
@forward "components/appointment-status";
99
@forward "components/secondary-navigation";
10+
@forward "components/card-with-status";
1011
@forward "components/special-appointment-banner";
1112
@forward "components/nested-info";
1213

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{% from "nhsuk/components/card/macro.jinja" import card %}
2+
{% from "nhsuk/components/tag/macro.jinja" import tag %}
3+
4+
{% macro card_with_status(section, anchor, status_tag_properties, action_button_properties=None, csrf_input=None) %}
5+
{% set outer_caller = caller if caller is defined else none %}
6+
<div id="{{ anchor }}" class="app-card-with-status">
7+
{% call card({
8+
"heading": section.label
9+
}) %}
10+
<div class="app-card-with-status__tag">
11+
{{ tag(status_tag_properties) }}
12+
</div>
13+
14+
{% if outer_caller %}
15+
{{ outer_caller() }}
16+
{% endif %}
17+
18+
{% if action_button_properties %}
19+
<hr class="nhsuk-section-break nhsuk-section-break--visible nhsuk-u-margin-bottom-4">
20+
21+
{% if action_button_properties.is_anchor %}
22+
<a href="{{ action_button_properties.href }}" class="nhsuk-button nhsuk-button--secondary"> {{ action_button_properties.text }} </a>
23+
{% else %}
24+
<form method="post" action="{{ action_button_properties.href }}">
25+
{{ csrf_input }}
26+
<button type="submit" class="nhsuk-button nhsuk-button--secondary nhsuk-u-margin-bottom-0"> {{ action_button_properties.text }} </button>
27+
</form>
28+
{% endif %}
29+
{% endif %}
30+
{% endcall %}
31+
</div>
32+
{% endmacro %}

manage_breast_screening/mammograms/jinja2/mammograms/record_medical_information.jinja

Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
{% extends "wizard_step.jinja" %}
22
{% from "nhsuk/components/button/macro.jinja" import button %}
3-
{% from "nhsuk/components/card/macro.jinja" import card %}
43
{% from "nhsuk/components/inset-text/macro.jinja" import insetText %}
54
{% from "nhsuk/components/summary-list/macro.jinja" import summaryList %}
65
{% from "components/participant-details/summary_list_rows.jinja" import last_mammogram_html %}
76
{% from "mammograms/medical_information/medical_history/cards/breast_cancer_history_card.jinja" import breast_cancer_history_card %}
7+
{% from "mammograms/components/card_with_status.jinja" import card_with_status %}
88

99
{% block step_content %}
1010

11-
{% call card({"heading": "Mammogram history"}) %}
11+
{% call card_with_status(
12+
section=sections.MAMMOGRAM_HISTORY,
13+
anchor=presenter.get_anchor(sections.MAMMOGRAM_HISTORY),
14+
status_tag_properties=presenter.review_status_tag_properties(sections.MAMMOGRAM_HISTORY),
15+
action_button_properties=presenter.review_action_button_properties(sections.MAMMOGRAM_HISTORY),
16+
csrf_input=csrf_input,
17+
) %}
1218
<p>The last confirmed mammogram and any added manually since then</p>
1319

1420
{{ summaryList({
@@ -29,12 +35,15 @@
2935
"href": presenter.add_mammogram_button.href,
3036
"classes": "nhsuk-button--secondary nhsuk-button--small"
3137
}) }}
32-
3338
{% endcall %}
3439

35-
{% call card({
36-
"heading": "Symptoms",
37-
}) %}
40+
{% call card_with_status(
41+
section=sections.SYMPTOMS,
42+
anchor=presenter.get_anchor(sections.SYMPTOMS),
43+
status_tag_properties=presenter.review_status_tag_properties(sections.SYMPTOMS),
44+
action_button_properties=presenter.review_action_button_properties(sections.SYMPTOMS),
45+
csrf_input=csrf_input,
46+
) %}
3847
<p {%- if not presenter.symptom_rows %} class="nhsuk-u-margin-bottom-3"{% endif %}>Any problems or symptoms, including lumps, swelling, rashes or nipple changes</p>
3948
{% if presenter.symptom_rows %}
4049
{{ summaryList({
@@ -64,7 +73,14 @@
6473
</div>
6574
{% endcall %}
6675

67-
{% set medical_history_card_html %}
76+
{% call card_with_status(
77+
section=sections.MEDICAL_HISTORY,
78+
anchor=presenter.get_anchor(sections.MEDICAL_HISTORY),
79+
status_tag_properties=presenter.review_status_tag_properties(sections.MEDICAL_HISTORY),
80+
action_button_properties=presenter.review_action_button_properties(sections.MEDICAL_HISTORY),
81+
csrf_input=csrf_input,
82+
) %}
83+
6884
{% set mastectomy_or_lumpectomy_history_html %}
6985
{% for presented_item in presenter.mastectomy_or_lumpectomy_history %}
7086
<a style="float: right" class="nhsuk-link nhsuk-link--no-visited-state" href="{{ presented_item.change_link.href}}">
@@ -199,14 +215,15 @@
199215
}) }}
200216
{% endfor %}
201217
</div>
202-
{% endset %}
203-
204-
{{ card({
205-
"heading": "Medical history",
206-
"descriptionHtml": medical_history_card_html
207-
}) }}
218+
{% endcall %}
208219

209-
{% set breast_features_card_html %}
220+
{% call card_with_status(
221+
section=sections.BREAST_FEATURES,
222+
anchor=presenter.get_anchor(sections.BREAST_FEATURES),
223+
status_tag_properties=presenter.review_status_tag_properties(sections.BREAST_FEATURES),
224+
action_button_properties=presenter.review_action_button_properties(sections.BREAST_FEATURES),
225+
csrf_input=csrf_input,
226+
) %}
210227
{% set breast_features_recorded = false %}
211228

212229
{% set insetHtml %}
@@ -220,23 +237,51 @@
220237
<p class="nhsuk-u-margin-top-4 nhsuk-u-margin-bottom-0">
221238
<a href="#" class="nhsuk-link nhsuk-link--no-visited-state">{{ "Add another feature" if breast_features_recorded else "Add a feature" }}</a>
222239
</p>
223-
{% endset %}
224-
{{ card({
225-
"heading": "Breast features",
226-
"descriptionHtml": breast_features_card_html
227-
}) }}
228240

229-
{% set other_information_card_html %}
241+
{% if presenter.breast_features_action_button %}
242+
{% if presenter.breast_features_action_button.is_anchor %}
243+
<a href="{{ presenter.breast_features_action_button.href }}" class="nhsuk-link {{ presenter.breast_features_action_button.classes }}">
244+
{{ presenter.breast_features_action_button.text }}
245+
</a>
246+
{% else %}
247+
<form method="post" action="{{ presenter.breast_features_action_button.href }}" class="app-inline-form">
248+
{{ csrf_input }}
249+
<button type="submit" class="nhsuk-link-button {{ presenter.breast_features_action_button.classes }}">
250+
{{ presenter.breast_features_action_button.text }}
251+
</button>
252+
</form>
253+
{% endif %}
254+
{% endif %}
255+
{% endcall %}
256+
257+
{% call card_with_status(
258+
section=sections.OTHER_INFORMATION,
259+
anchor=presenter.get_anchor(sections.OTHER_INFORMATION),
260+
status_tag_properties=presenter.review_status_tag_properties(sections.OTHER_INFORMATION),
261+
action_button_properties=presenter.review_action_button_properties(sections.OTHER_INFORMATION),
262+
csrf_input=csrf_input,
263+
) %}
230264
{% set hrt_link %}
231265
<a class="nhsuk-link" href="#">Enter hormone replacement therapy (HRT)</a>
232266
{% endset %}
233267
{% set pregnancy_and_breastfeeding_link %}
234268
<a class="nhsuk-link" href="#">Enter pregnancy and breastfeeding</a>
235269
{% endset %}
236-
{% endset %}
237-
{{ card({
238-
"heading": "Other information",
239-
"descriptionHtml": other_information_card_html
240-
}) }}
270+
271+
{% if presenter.other_information_action_button %}
272+
{% if presenter.other_information_action_button.is_anchor %}
273+
<a href="{{ presenter.other_information_action_button.href }}" class="nhsuk-link {{ presenter.other_information_action_button.classes }}">
274+
{{ presenter.other_information_action_button.text }}
275+
</a>
276+
{% else %}
277+
<form method="post" action="{{ presenter.other_information_action_button.href }}" class="app-inline-form">
278+
{{ csrf_input }}
279+
<button type="submit" class="nhsuk-link-button {{ presenter.other_information_action_button.classes }}">
280+
{{ presenter.other_information_action_button.text }}
281+
</button>
282+
</form>
283+
{% endif %}
284+
{% endif %}
285+
{% endcall %}
241286

242287
{% endblock %}

manage_breast_screening/mammograms/presenters/medical_information_presenter.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,28 @@
2626
from manage_breast_screening.mammograms.presenters.symptom_presenter import (
2727
SymptomPresenter,
2828
)
29+
from manage_breast_screening.participants.models import MedicalInformationSection
2930

3031
from .appointment_presenters import AppointmentPresenter
3132

33+
# Section order for "Next section" navigation
34+
SECTION_ORDER = {
35+
MedicalInformationSection.MAMMOGRAM_HISTORY: MedicalInformationSection.SYMPTOMS,
36+
MedicalInformationSection.SYMPTOMS: MedicalInformationSection.MEDICAL_HISTORY,
37+
MedicalInformationSection.MEDICAL_HISTORY: MedicalInformationSection.BREAST_FEATURES,
38+
MedicalInformationSection.BREAST_FEATURES: MedicalInformationSection.OTHER_INFORMATION,
39+
MedicalInformationSection.OTHER_INFORMATION: MedicalInformationSection.OTHER_INFORMATION,
40+
}
41+
42+
# Section IDs for anchor navigation
43+
SECTION_ANCHORS = {
44+
MedicalInformationSection.MAMMOGRAM_HISTORY: "mammogram-history",
45+
MedicalInformationSection.SYMPTOMS: "symptoms",
46+
MedicalInformationSection.MEDICAL_HISTORY: "medical-history",
47+
MedicalInformationSection.BREAST_FEATURES: "breast-features",
48+
MedicalInformationSection.OTHER_INFORMATION: "other-information",
49+
}
50+
3251

3352
class MedicalInformationPresenter:
3453
def __init__(self, appointment):
@@ -75,6 +94,11 @@ def __init__(self, appointment):
7594
symptom.symptom_type_id for symptom in symptoms
7695
}
7796

97+
self._section_reviews = {
98+
review.section: review
99+
for review in appointment.medical_information_reviews.all()
100+
}
101+
78102
@property
79103
def symptom_rows(self):
80104
return [symptom.summary_list_row for symptom in self.symptoms]
@@ -255,3 +279,44 @@ def _present_items(self, items, presenter_class):
255279
presenter_class(item, counter=counter)
256280
for counter, item in enumerate(items, 1)
257281
]
282+
283+
def get_anchor(self, section):
284+
return SECTION_ANCHORS.get(section)
285+
286+
def is_section_reviewed(self, section):
287+
return section in self._section_reviews
288+
289+
def review_status_tag_properties(self, section):
290+
if self.is_section_reviewed(section):
291+
return {
292+
"text": "Reviewed",
293+
"classes": "nhsuk-tag--green app-section-review-tag",
294+
}
295+
else:
296+
return {
297+
"text": "To review",
298+
"classes": "nhsuk-tag--blue app-section-review-tag",
299+
}
300+
301+
def review_action_button_properties(self, section):
302+
if self.is_section_reviewed(section):
303+
next_section = SECTION_ORDER.get(section)
304+
anchor = SECTION_ANCHORS.get(next_section)
305+
return {
306+
"href": f"#{anchor}",
307+
"text": "Next section",
308+
"is_anchor": True,
309+
}
310+
else:
311+
url = reverse(
312+
"mammograms:mark_section_reviewed",
313+
kwargs={
314+
"pk": self.appointment.pk,
315+
"section": section,
316+
},
317+
)
318+
return {
319+
"href": url,
320+
"text": "Mark as reviewed",
321+
"is_anchor": False,
322+
}

manage_breast_screening/mammograms/tests/presenters/test_medical_information_presenter.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from manage_breast_screening.mammograms.presenters.medical_information_presenter import (
44
MedicalInformationPresenter,
55
)
6+
from manage_breast_screening.participants.models import MedicalInformationSection
67
from manage_breast_screening.participants.models.symptom import (
78
RelativeDateChoices,
89
SymptomAreas,
@@ -12,6 +13,7 @@
1213
CystHistoryItemFactory,
1314
ImplantedMedicalDeviceHistoryItemFactory,
1415
MastectomyOrLumpectomyHistoryItemFactory,
16+
MedicalInformationReviewFactory,
1517
OtherProcedureHistoryItemFactory,
1618
SymptomFactory,
1719
)
@@ -272,3 +274,32 @@ def test_add_mammogram_button(self):
272274
),
273275
"text": "Add another mammogram",
274276
}
277+
278+
@pytest.mark.parametrize(
279+
"section,expected_anchor",
280+
[
281+
(MedicalInformationSection.MAMMOGRAM_HISTORY, "mammogram-history"),
282+
(MedicalInformationSection.SYMPTOMS, "symptoms"),
283+
(MedicalInformationSection.MEDICAL_HISTORY, "medical-history"),
284+
(MedicalInformationSection.BREAST_FEATURES, "breast-features"),
285+
(MedicalInformationSection.OTHER_INFORMATION, "other-information"),
286+
],
287+
)
288+
def test_get_anchor_returns_correct_anchor(self, section, expected_anchor):
289+
appointment = AppointmentFactory()
290+
presenter = MedicalInformationPresenter(appointment)
291+
292+
assert presenter.get_anchor(section) == expected_anchor
293+
294+
def test_is_section_reviewed_returns_true_when_reviewed(self):
295+
appointment = AppointmentFactory()
296+
MedicalInformationReviewFactory.create(
297+
appointment=appointment, section=MedicalInformationSection.SYMPTOMS
298+
)
299+
presenter = MedicalInformationPresenter(appointment)
300+
301+
assert presenter.is_section_reviewed(MedicalInformationSection.SYMPTOMS) is True
302+
assert (
303+
presenter.is_section_reviewed(MedicalInformationSection.BREAST_FEATURES)
304+
is False
305+
)

0 commit comments

Comments
 (0)