Skip to content

Conversation

@swebberuk
Copy link
Contributor

@swebberuk swebberuk commented Nov 27, 2025

Description

  1. Copied CSS from prototype and added to main.scss
  2. Copied HTML from prototype and added to new appointment-status-bar/template.jinja
  3. Updated layout-app.jinja to include appointment-status-bar/template.jinja

What appointment status bar looks like with changes from this PR:

image

How appointment status bar looks in prototype:

image

Jira link

https://nhsd-jira.digital.nhs.uk/browse/DTOSS-11576

Review notes

Review checklist

  • Check database queries are correctly scoped to current_provider

@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from c65c56b to a98f0ad Compare November 27, 2025 13:23
@@ -0,0 +1,33 @@
{% from 'nhsuk/components/tag/macro.jinja' import tag %}

{% if presented_appointment.active %}
Copy link
Contributor Author

@swebberuk swebberuk Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll need to alter this if condition - story states "The bar should only display if the current user is the one that has the appointment 'in progress'". Don't know if we've already done something similar somewhere else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that comes to mind is for workflow transitions like starting appointments, we have to check both whether the appointment is startable (based on its state) and whether the current user is permitted to start the appointment.

Copy link
Contributor Author

@swebberuk swebberuk Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have tried to implement adding a show_status_bar_for function in AppointmentPresenter:

def show_status_bar_for(self, user):
    # The appointment status bar should only display if the current user
    # is the one that has the appointment 'in progress'
    current_status = self._appointment.current_status
    return (
        current_status.state == AppointmentStatus.IN_PROGRESS
        and user.nhs_uid == current_status.created_by.nhs_uid
    )

There was a suggestion that the current owner should be stored the appointment table, rather than determining using self._appointment.current_status. If we think that would be useful then I could look at doing that as a separate task.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prototype has a quite explicit concept of "currently running the workflow in this session" - which I'm not sure prod (yet?) has - not sure what the closest equivalent on prod would be.

<span class="app-status-bar__key">Appointment:</span>
<span>{{ presented_appointment.clinic_slot.slot_time_and_clinic_date }}</span>
</div>
<div class="app-status-bar__item">
Copy link
Contributor Author

@swebberuk swebberuk Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to add a yellow tag if the appointment is 'special'. If I try:

{% if presented_appointment.is_special_appointment %}
{{ tag(presented_appointment.special_appointment_tag_properties) }}
{% endif %}

Then the "Special appointment" text doesn't align with the other text. This is because special_appointment_tag_properties contains nhsuk-u-margin-top-2.

image

Looks okay if, rather than using special_appointment_tag_properties, I add the HTML myself - but seems wrong that have to do this:

{% if presented_appointment.is_special_appointment %}
<strong class="nhsuk-tag nhsuk-tag--yellow nhsuk-u-nowrap">
  Special appointment
</strong>
{% endif %}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's generally better to use the macros if we can, as it's easy to keep up to date with changes to the design system that way.

Can we split special_appointment_tag_properties into two methods, one for each use case? Or make it a method accepting parameters?

If it helps you could also split out a presenter just for this component

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I can split into two methods, but not sure what to name them. Does anyone have any suggestions please?

I could name the new version something like special_appointment_status_bar_tag_properties but that is quite wordy and specific to the status bar. e.g.:

@cached_property
def special_appointment_status_bar_tag_properties(self):
	return {
		"classes": "nhsuk-tag--yellow nhsuk-u-margin-left-1",
		"text": "Special appointment",
	}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking you could give the presented appointment a member status_bar, pass that to this component instead of the presented_appointment itself, and then call this property as presented_status_bar.tag_properties

Any other suggestions welcome though, I haven't thought about this in too much detail.

@@ -0,0 +1,3 @@
{% macro appointment_status_bar(presented_appointment) %}
Copy link
Contributor

@MatMoore MatMoore Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a think about it, but for components like this that might be reusable by other services, we could consider following the design system style of having each macro take a single params argument, rather than presented_appointment as you have here.

I don't particularly like this style but given that we are already following the conventions of macro.jinja / template.jinja files, and namespacing all the css, it might make it easier for other teams to lift and shift.

Copy link
Contributor Author

@swebberuk swebberuk Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did rename presented_appointment to params. I then wanted to add another parameter user. It seemed easier to understand when using two parameters, rather than combining into a Dict, so reverted to using: appointment_status_bar(user, presented_appointment). If we want to go with a single parameter named params then I can do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, shall we just have a single jinja file instead of splitting the macro.jinja and template.jinja?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combined macro.jinja and template.jinja into single file named appointment-status-bar.jinja

@@ -0,0 +1,33 @@
{% from 'nhsuk/components/tag/macro.jinja' import tag %}

{% if presented_appointment.active %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that comes to mind is for workflow transitions like starting appointments, we have to check both whether the appointment is startable (based on its state) and whether the current user is permitted to start the appointment.

<span class="app-status-bar__key">Appointment:</span>
<span>{{ presented_appointment.clinic_slot.slot_time_and_clinic_date }}</span>
</div>
<div class="app-status-bar__item">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's generally better to use the macros if we can, as it's easy to keep up to date with changes to the design system that way.

Can we split special_appointment_tag_properties into two methods, one for each use case? Or make it a method accepting parameters?

If it helps you could also split out a presenter just for this component

}
}) }}

{{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will having this in the header mean it's skipped by the skip link? This doesn't seem right to me for something that we want users to perceive for clinical safety reasons.

Copy link
Contributor Author

@swebberuk swebberuk Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have asked about skip link in screening-manage-ucd Slack channel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from ea97030 to ff8bba2 Compare December 1, 2025 14:55
@swebberuk swebberuk requested a review from MatMoore December 1, 2025 15:29
@swebberuk swebberuk changed the title [wip] investigating how to add appointment status bar Appointment status bar Dec 2, 2025
@MatMoore MatMoore added the deploy label Dec 4, 2025
}

.app-status-bar {
background-color: #00386e;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this scss is temporary but these colours and paddings should be aligned with the design system tokens where possible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have updated to use tokens where I could find them (e.g. $color_nhsuk-white, nhsuk-spacing(4)). Couldn't find tokens for #00386e.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth extracting a var for it in that case, like $color_app-dark-blue? Or maybe using the colour functions of sass to adjust the shade of an existing colour?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

$color_app-dark-blue: #00386e;

<span class="app-status-bar__key">Appointment:</span>
<span>{{ presented_appointment.clinic_slot.slot_time_and_clinic_date }}</span>
</div>
<div class="app-status-bar__item">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking you could give the presented appointment a member status_bar, pass that to this component instead of the presented_appointment itself, and then call this property as presented_status_bar.tag_properties

Any other suggestions welcome though, I haven't thought about this in too much detail.

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

The review app is available at this URL:
https://pr-783.manage-breast-screening.non-live.screening.nhs.uk
You must authenticate with HTTP basic authentication. Ask the team for credentials.

@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from cb43f8f to d4321f8 Compare December 11, 2025 09:03
@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from 0e7b184 to 7a38a4b Compare December 11, 2025 10:20
@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from 13c7fed to 29ed564 Compare December 11, 2025 11:55
@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from b00e2c2 to a3af82a Compare December 11, 2025 12:43
@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch 2 times, most recently from e8ed520 to 4ba7db1 Compare December 11, 2025 13:04
@swebberuk swebberuk marked this pull request as ready for review December 11, 2025 13:12
@swebberuk swebberuk requested a review from a team as a code owner December 11, 2025 13:12
@swebberuk swebberuk requested a review from MatMoore December 11, 2025 13:14
Copy link
Contributor

@MatMoore MatMoore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think this is almost good to merge, just have some questions about the scss.

}

.app-status-bar {
background-color: #00386e;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth extracting a var for it in that case, like $color_app-dark-blue? Or maybe using the colour functions of sass to adjust the shade of an existing colour?

}

.app-status-bar__key {
font-weight: 600 !important;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced with @include nhsuk-typography-weight-bold(true);

}

html:has(.app-status-bar--rows-2) {
scroll-padding-top: 144px;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the 144px come from here? Does it need to be calculated from something else?

@@ -0,0 +1,3 @@
{% macro appointment_status_bar(presented_appointment) %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, shall we just have a single jinja file instead of splitting the macro.jinja and template.jinja?

The bar should only display if the current user is

the one that has the appointment in progress.
@swebberuk swebberuk force-pushed the DTOSS-11576-appointment-status-bar branch from 47f309f to 4a4f8a9 Compare December 11, 2025 15:54
@swebberuk swebberuk merged commit 991ecd2 into main Dec 11, 2025
24 of 25 checks passed
@swebberuk swebberuk deleted the DTOSS-11576-appointment-status-bar branch December 11, 2025 16:08
Comment on lines +86 to +126
.app-status-bar {
background-color: $color_app-dark-blue;
color: $color_nhsuk-white;
padding: nhsuk-spacing(2) 0;
border-bottom: 1px solid nhsuk-colour("grey-4");
}

.app-status-bar a {
color: $color_nhsuk-white;
}
.app-status-bar a:hover,
.app-status-bar a:active {
color: $color_nhsuk-white;
}
.app-status-bar a:focus {
color: $color_nhsuk-black;
}

.app-status-bar__row {
display: flex;
flex-wrap: wrap;
gap: nhsuk-spacing(4);
align-items: center;
}

.app-status-bar__row + .app-status-bar__row {
margin-top: nhsuk-spacing(2);
padding-top: nhsuk-spacing(2);
border-top: 1px solid rgba($color_nhsuk-white, 0.2);
}

.app-status-bar__item {
display: flex;
gap: nhsuk-spacing(2);
align-items: center;
}

.app-status-bar__key {
@include nhsuk-typography-weight-bold(true);
opacity: 0.9;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine it might be good to put these in their own named file inside a folder like _components?

@@ -0,0 +1,33 @@
{% from 'nhsuk/components/tag/macro.jinja' import tag %}

{% if presented_appointment.active %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prototype has a quite explicit concept of "currently running the workflow in this session" - which I'm not sure prod (yet?) has - not sure what the closest equivalent on prod would be.

}

.app-status-bar {
background-color: $color_app-dark-blue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you check the scss from the prototype, this was background-color: nhsuk-shade($nhsuk-brand-colour, 40%); which is probably clearer for how we chose this number / where it came from.

Comment on lines +9 to +15
<span class="app-status-bar__key">Appointment:</span>
<span>
{{ presented_status_bar.clinic_slot.clinic_date_and_slot_time }}
{% if presented_status_bar.appointment.is_special_appointment %}
{{ tag(presented_status_bar.tag_properties) }}
{% endif %}
</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I somewhat wonder if these and other items within the summary list should use a definition list. @colinrotherham any thoughts?

@swebberuk swebberuk mentioned this pull request Dec 15, 2025
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants