Skip to content

Commit

Permalink
Build new session triage tab (#3133)
Browse files Browse the repository at this point in the history
This updates the design of the session triage page to match the latest
designs in the prototype, where a single tab for triage is shown and the
nurses are able to filter the patients by triage outcome and the status
is shown per programme.

## Screenshots

<img width="1132" alt="Screenshot 2025-03-04 at 15 32 45"
src="https://github.com/user-attachments/assets/9f26ca47-76a6-4952-86ea-68e70fa77cde"
/>
<img width="1139" alt="Screenshot 2025-03-04 at 15 33 02"
src="https://github.com/user-attachments/assets/3a8d7d35-9487-471d-b47b-1f6ad72cfa7e"
/>
<img width="895" alt="Screenshot 2025-03-04 at 15 33 20"
src="https://github.com/user-attachments/assets/21fa57bf-3781-4425-a08e-b6d1fd4262c7"
/>
  • Loading branch information
thomasleese authored Mar 4, 2025
2 parents e6efe65 + da1cfc7 commit d004a0a
Show file tree
Hide file tree
Showing 43 changed files with 409 additions and 238 deletions.
2 changes: 1 addition & 1 deletion app/components/app_outcome_banner_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def vaccination_record
end

def triage
@triage ||= @patient_session.latest_triage(programme:)
@triage ||= @patient_session.triage.latest(programme:)
end

def show_location?
Expand Down
2 changes: 1 addition & 1 deletion app/components/app_patient_page_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<%= render AppHealthAnswersCardComponent.new(patient_session.consent.latest(programme:), heading: "All answers to health questions") %>
<% end %>

<% if patient_session.triages(programme:).any? %>
<% if patient_session.triage.all(programme:).any? %>
<%= render AppCardComponent.new do |c| %>
<% c.with_heading { "Triage notes" } %>
<%= render AppTriageNotesComponent.new(patient_session:, programme:) %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def initialize(patient_session, link_to:, context:)
@patient = patient_session.patient
@link_to = link_to
@context = context

raise "Unknown context: #{context}" unless context.in?(%i[consent triage])
end

def call
Expand All @@ -28,10 +30,7 @@ def call
summary_list.with_row do |row|
row.with_key { "Status" }
row.with_value do
render AppProgrammeStatusTagsComponent.new(
patient_session.consent.status,
context:
)
render AppProgrammeStatusTagsComponent.new(status, context:)
end
end
end
Expand All @@ -41,4 +40,8 @@ def call
private

attr_reader :patient_session, :patient, :link_to, :context

def status
patient_session.send(context).status
end
end
30 changes: 25 additions & 5 deletions app/components/app_search_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ class AppSearchComponent < ViewComponent::Base
<% end %>
<% end %>
<% end %>
<% if triage_status %>
<%= f.govuk_radio_buttons_fieldset :triage_status, legend: { text: "Triage outcome", size: "s" } do %>
<%= f.govuk_radio_button :triage_status, "", label: { text: "Any" } %>
<% PatientSession::Triage::STATUSES.each do |status| %>
<%= f.govuk_radio_button :triage_status, status, label: { text: t(status, scope: %i[patient_session status triage label]) } %>
<% end %>
<% end %>
<% end %>
<% if year_groups.any? %>
<%= f.govuk_check_boxes_fieldset :year_groups, legend: { text: "Year group", size: "s" } do %>
Expand All @@ -44,15 +53,15 @@ class AppSearchComponent < ViewComponent::Base
<%= f.govuk_check_box :missing_nhs_number, 1, 0, multiple: false, link_errors: true, label: { text: "Missing NHS number" } %>
<% end %>
<% unless consent_status || year_groups.any? %>
<% if show_buttons_in_details? %>
<div class="app-button-group">
<%= f.govuk_submit "Update results", secondary: true, class: "app-button--small" %>
<%= govuk_button_link_to "Clear filters", @url, class: "app-button--small app-button--secondary" %>
</div>
<% end %>
<% end %>
<% if consent_status || year_groups.any? %>
<% unless show_buttons_in_details? %>
<div class="app-button-group">
<%= f.govuk_submit "Update results", secondary: true, class: "app-button--small" %>
<%= govuk_button_link_to "Clear filters", @url, class: "app-button--small app-button--secondary" %>
Expand All @@ -62,17 +71,28 @@ class AppSearchComponent < ViewComponent::Base
<% end %>
ERB

def initialize(form:, url:, consent_status: false, year_groups: [])
def initialize(
form:,
url:,
consent_status: false,
triage_status: false,
year_groups: []
)
super

@form = form
@url = url

@consent_status = consent_status
@triage_status = triage_status
@year_groups = year_groups
end

private

attr_reader :form, :url, :consent_status, :year_groups
attr_reader :form, :url, :consent_status, :triage_status, :year_groups

def show_buttons_in_details?
!(consent_status || triage_status || year_groups.any?)
end
end
4 changes: 2 additions & 2 deletions app/components/app_simple_status_banner_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def description

if patient_session.consent_given_triage_needed?(programme:)
reasons = [
if patient_session.consent_needs_triage?(programme:)
if patient_session.consent.latest(programme:).any?(&:triage_needed?)
I18n.t(
"patient_session_statuses.#{status}.banner_explanation.consent_needs_triage",
**options
Expand Down Expand Up @@ -83,7 +83,7 @@ def who_refused

def nurse
(
patient_session.triages(programme:) +
patient_session.triage.all(programme:) +
patient_session.vaccination_records(programme:)
).max_by(&:updated_at)&.performed_by&.full_name
end
Expand Down
2 changes: 1 addition & 1 deletion app/components/app_triage_form_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def initialize(
@triage =
triage ||
Triage.new.tap do |t|
if (latest_triage = patient_session.latest_triage(programme:))
if (latest_triage = patient_session.triage.latest(programme:))
t.status = latest_triage.status
end
end
Expand Down
9 changes: 5 additions & 4 deletions app/controllers/concerns/search_form_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ def set_search_form
@form =
SearchForm.new(
params.fetch(:search_form, {}).permit(
:q,
:"date_of_birth(3i)",
:"date_of_birth(2i)",
:"date_of_birth(1i)",
:missing_nhs_number,
:"date_of_birth(2i)",
:"date_of_birth(3i)",
:consent_status,
:missing_nhs_number,
:q,
:triage_status,
year_groups: []
)
)
Expand Down
4 changes: 0 additions & 4 deletions app/controllers/consents_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# frozen_string_literal: true

require "pagy/extras/array"

class ConsentsController < ApplicationController
include Pagy::Backend

before_action :set_session
before_action :set_patient_session
before_action :set_programme
Expand Down
37 changes: 37 additions & 0 deletions app/controllers/sessions/triage_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

require "pagy/extras/array"

class Sessions::TriageController < ApplicationController
include Pagy::Backend
include SearchFormConcern

before_action :set_session
before_action :set_search_form

layout "full"

def show
scope =
@session.patient_sessions.preload_for_status.in_programmes(
@session.programmes
)

patient_sessions = @form.apply(scope)

if patient_sessions.is_a?(Array)
@pagy, @patient_sessions = pagy_array(patient_sessions)
else
@pagy, @patient_sessions = pagy(patient_sessions)
end
end

private

def set_session
@session =
policy_scope(Session).includes(:programmes).find_by!(
slug: params[:session_slug]
)
end
end
40 changes: 1 addition & 39 deletions app/controllers/triages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# frozen_string_literal: true

require "pagy/extras/array"

class TriagesController < ApplicationController
include Pagy::Backend

include TriageMailerConcern
include PatientTabsConcern
include PatientSortingConcern

before_action :set_session
before_action :set_patient, only: %i[create new]
Expand All @@ -18,38 +12,6 @@ class TriagesController < ApplicationController

after_action :verify_authorized

def index
@programme =
@session.programmes.find_by(type: params[:programme_type]) ||
@session.programmes.first

all_patient_sessions =
@session
.patient_sessions
.preload_for_status
.in_programmes([@programme])
.order_by_name

@current_tab = TAB_PATHS[:triage][params[:tab]]
tab_patient_sessions =
group_patient_sessions_by_state(
all_patient_sessions,
@programme,
section: :triage
)
@tab_counts = count_patient_sessions(tab_patient_sessions)
patient_sessions = tab_patient_sessions[@current_tab] || []

sort_and_filter_patients!(patient_sessions, programme: @programme)
@pagy, @patient_sessions = pagy_array(patient_sessions)

session[:current_section] = "triage"

authorize Triage

render layout: "full"
end

def new
authorize @triage
end
Expand Down Expand Up @@ -136,7 +98,7 @@ def redirect_path
elsif session[:current_section] == "consents"
session_consent_path(@session)
else # if current_section is triage or anything else
session_triage_path(@session, programme_type: @programme)
session_triage_path(@session)
end
end
end
5 changes: 5 additions & 0 deletions app/forms/search_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class SearchForm
attribute :date_of_birth, :date
attribute :missing_nhs_number, :boolean
attribute :q, :string
attribute :triage_status, :string
attribute :year_groups, array: true

def year_groups=(values)
Expand All @@ -31,6 +32,10 @@ def apply(scope)
scope = scope.select { it.consent.status.values.include?(status) }
end

if (status = triage_status&.to_sym).present?
scope = scope.select { it.triage.status.values.include?(status) }
end

scope
end
end
2 changes: 1 addition & 1 deletion app/lib/reports/offline_session_exporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def add_patient_cells(row, patient_session:, programme:)

gillick_assessment = patient_session.gillick_assessment(programme:)
consents = patient_session.consent.latest(programme:)
triage = patient_session.latest_triage(programme:)
triage = patient_session.triage.latest(programme:)

row[:organisation_code] = organisation.ods_code
row[:person_forename] = patient.given_name
Expand Down
2 changes: 1 addition & 1 deletion app/lib/reports/programme_vaccinations_exporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def row(vaccination_record:)

consents = patient_session&.consent&.latest(programme:) || []
gillick_assessment = patient_session&.gillick_assessment(programme:)
triage = patient_session&.latest_triage(programme:)
triage = patient_session&.triage&.latest(programme:)

[
organisation.ods_code,
Expand Down
17 changes: 6 additions & 11 deletions app/models/concerns/patient_session_status_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,33 +73,28 @@ def no_consent?(programme:)
consent.status[programme] == PatientSession::Consent::NONE
end

def consent_needs_triage?(programme:)
consent.latest(programme:).any?(&:triage_needed?)
end

def triage_needed?(programme:)
consent_needs_triage?(programme:) ||
vaccination_partially_administered?(programme:)
triage.status[programme] == PatientSession::Triage::REQUIRED
end

def triage_not_needed?(programme:)
!triage_needed?(programme:)
triage.status[programme] == PatientSession::Triage::NOT_REQUIRED
end

def triage_ready_to_vaccinate?(programme:)
latest_triage(programme:)&.ready_to_vaccinate?
triage.status[programme] == PatientSession::Triage::SAFE_TO_VACCINATE
end

def triage_keep_in_triage?(programme:)
latest_triage(programme:)&.needs_follow_up?
triage.latest(programme:)&.needs_follow_up?
end

def triage_do_not_vaccinate?(programme:)
latest_triage(programme:)&.do_not_vaccinate?
triage.status[programme] == PatientSession::Triage::DO_NOT_VACCINATE
end

def triage_delay_vaccination?(programme:)
latest_triage(programme:)&.delay_vaccination?
triage.status[programme] == PatientSession::Triage::DELAY_VACCINATION
end

def vaccination_administered?(programme:)
Expand Down
2 changes: 1 addition & 1 deletion app/models/patient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Patient < ApplicationRecord
->(programmes) do
where(
birth_academic_year:
programmes.map(&:birth_academic_years).sort.uniq
programmes.flat_map(&:birth_academic_years).sort.uniq
)
end

Expand Down
23 changes: 4 additions & 19 deletions app/models/patient_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,12 @@ def consent
@consent ||= PatientSession::Consent.new(self)
end

def gillick_assessment(programme:)
gillick_assessments.select { it.programme_id == programme.id }.last
def triage
@triage ||= PatientSession::Triage.new(self)
end

def triages(programme:)
patient.triages.select { it.programme_id == programme.id }
end

def latest_triage(programme:)
latest_triage_by_programme[programme.id]
def gillick_assessment(programme:)
gillick_assessments.select { it.programme_id == programme.id }.last
end

def vaccination_records(programme:, for_session: false)
Expand All @@ -155,15 +151,4 @@ def todays_attendance
).find_or_initialize_by(session_date:)
end
end

private

def latest_triage_by_programme
@latest_triage_by_programme ||=
patient
.triages
.reject(&:invalidated?)
.group_by(&:programme_id)
.transform_values { it.max_by(&:created_at) }
end
end
Loading

0 comments on commit d004a0a

Please sign in to comment.