diff --git a/app/components/app_patient_programme_session_table_component.rb b/app/components/app_patient_programme_session_table_component.rb new file mode 100644 index 0000000000..92c39dd876 --- /dev/null +++ b/app/components/app_patient_programme_session_table_component.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +class AppPatientProgrammeSessionTableComponent < ViewComponent::Base + erb_template <<-ERB + <% if sessions.any? %> + <%= govuk_table(html_attributes: { class: "nhsuk-table-responsive" }) do |table| %> + <% table.with_head do |head| %> + <% head.with_row do |row| %> + <% row.with_cell(text: "Location") %> + <% row.with_cell(text: "Session dates") %> + <% row.with_cell(text: "Session outcome") %> + <% end %> + <% end %> + + <% table.with_body do |body| %> + <% sessions.each do |session| %> + <% body.with_row do |row| %> + <% row.with_cell do %> + Location + <%= link_to session.location.name, + session_patient_programme_path(session, patient, programme_type) %> + <% end %> + + <% row.with_cell do %> + Session dates + + <% end %> + + <% row.with_cell do %> + Session outcome + <%= session_outcome_tag(session, programme_type) %> + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> + <% else %> +

No sessions

+ <% end %> + ERB + + def initialize(patient, current_team:, programme_type:) + @patient = patient + @current_team = current_team + @programme_type = programme_type + end + + private + + attr_reader :patient, :current_team, :programme_type + + delegate :govuk_table, to: :helpers + + def sessions + @sessions ||= + patient + .sessions + .for_team(current_team) + .has_any_programme_types_of(programme_type) + .includes(:location, :session_programme_year_groups) + end + + def session_outcome_tag(session, programme_type) + vaccination_record = + session + .vaccination_records + .where(programme_type:, patient:) + .order(:performed_at_date, :performed_at_time) + .last + return "No outcome" unless vaccination_record + + helpers.vaccination_record_status_tag(vaccination_record) + end +end diff --git a/app/views/patients/programmes/show.html.erb b/app/views/patients/programmes/show.html.erb index 09b259fb0a..05189f331c 100644 --- a/app/views/patients/programmes/show.html.erb +++ b/app/views/patients/programmes/show.html.erb @@ -15,3 +15,8 @@ @patient, academic_year: AcademicYear.current, show_caption: false, programme: @programme, ) %> <% end %> + +<%= render AppCardComponent.new(section: true) do |card| %> + <% card.with_heading { "Sessions" } %> + <%= render AppPatientProgrammeSessionTableComponent.new(@patient, current_team:, programme_type: @programme.type) %> +<% end %> diff --git a/app/views/patients/show.html.erb b/app/views/patients/show.html.erb index e7a6dfa0e9..86f2fba5b0 100644 --- a/app/views/patients/show.html.erb +++ b/app/views/patients/show.html.erb @@ -49,12 +49,14 @@ ) %> <% end %> - <%= render AppCardComponent.new(section: true) do |card| %> - <% card.with_heading { "Sessions" } %> - <%= render AppPatientSessionTableComponent.new(@patient, current_team:) %> + <% unless Flipper.enabled?(:child_record_redesign) %> + <%= render AppCardComponent.new(section: true) do |card| %> + <% card.with_heading { "Sessions" } %> + <%= render AppPatientSessionTableComponent.new(@patient, current_team:) %> - <% unless @in_generic_clinic %> - <%= govuk_button_to "Invite to community clinic", invite_to_clinic_patient_path(@patient), secondary: true %> + <% unless @in_generic_clinic %> + <%= govuk_button_to "Invite to community clinic", invite_to_clinic_patient_path(@patient), secondary: true %> + <% end %> <% end %> <% end %> diff --git a/spec/components/app_patient_programme_session_table_component_spec.rb b/spec/components/app_patient_programme_session_table_component_spec.rb new file mode 100644 index 0000000000..522919351c --- /dev/null +++ b/spec/components/app_patient_programme_session_table_component_spec.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +describe AppPatientProgrammeSessionTableComponent do + subject { render_inline(component) } + + let(:component) do + described_class.new(patient, current_team: team, programme_type:) + end + let(:programme_type) { :hpv } + let(:team) { create(:team) } + + context "without a session" do + let(:patient) { create(:patient) } + + it { should have_content("No sessions") } + end + + context "with one session" do + let(:programmes) { [Programme.hpv, Programme.mmr] } + + let(:location) do + create(:school, name: "Waterloo Road", programmes:, academic_year: 2024) + end + let(:session) do + create( + :session, + team:, + location:, + programmes:, + date: Date.new(2025, 1, 1) + ) + end + + # Can't use year_group here because we need an absolute date, not one + # relative to the current academic year. + let(:patient) { create(:patient, date_of_birth: Date.new(2011, 9, 1)) } + + before { create_list(:patient_location, 1, patient:, session:) } + + it { should have_link("Waterloo Road") } + it { should have_content("1 January 2025") } + + context "with multiple sessions" do + let(:other_location) do + create( + :school, + name: "Paddington Road", + programmes: other_programmes, + academic_year: 2024 + ) + end + let(:other_session) do + create( + :session, + team:, + location: other_location, + programmes: other_programmes, + date: Date.new(2025, 2, 1) + ) + end + let(:other_programmes) { [Programme.hpv, Programme.menacwy] } + + before do + create(:patient_location, patient:, session: other_session) + create( + :vaccination_record, + patient:, + session:, + outcome: :administered, + performed_at_date: 1.month.ago, + programme_type: + ) + create( + :vaccination_record, + patient:, + session:, + outcome: :refused, + performed_at_date: 1.year.ago, + programme_type: + ) + end + + it { should have_link("Waterloo Road") } + it { should have_content("1 January 2025") } + it { should have_content("Vaccinated") } + + it { should have_link("Paddington Road") } + it { should have_content("1 February 2025") } + it { should have_content("No outcome") } + + context "with a programme type filter that matches only one session" do + let(:component) do + described_class.new( + patient, + current_team: team, + programme_type: :menacwy + ) + end + + it { should_not have_link("Waterloo Road") } + it { should have_link("Paddington Road") } + end + end + end +end diff --git a/spec/components/app_patient_session_table_component_spec.rb b/spec/components/app_patient_session_table_component_spec.rb index ec2d4d558e..dbb957ca49 100644 --- a/spec/components/app_patient_session_table_component_spec.rb +++ b/spec/components/app_patient_session_table_component_spec.rb @@ -14,7 +14,7 @@ end context "with a session" do - let(:programmes) { [Programme.hpv] } + let(:programmes) { [Programme.hpv, Programme.mmr] } let(:location) do create(:school, name: "Waterloo Road", programmes:, academic_year: 2024) diff --git a/spec/features/viewing_child_records_spec.rb b/spec/features/viewing_child_records_spec.rb index f2b4922b6a..291a47f018 100644 --- a/spec/features/viewing_child_records_spec.rb +++ b/spec/features/viewing_child_records_spec.rb @@ -19,11 +19,13 @@ and_i_can_only_see_tabs_for_relevant_programmes when_i_click_on_the_flu_tab - then_i_see_the_childs_flu_information + then_i_see_the_childs_flu_vaccinations + and_i_see_the_childs_flu_sessions and_the_flu_tab_is_selected when_i_click_on_the_hpv_tab - then_i_see_the_childs_hpv_information + then_i_see_the_childs_hpv_vaccinations + and_i_see_the_childs_hpv_sessions and_the_hpv_tab_is_selected end @@ -88,6 +90,7 @@ def and_patients_exist def and_the_patient_is_vaccinated create( :vaccination_record, + outcome: :administered, patient: @patient, programme: @hpv, session: @session @@ -134,10 +137,9 @@ def when_i_click_on_the_flu_tab click_on "Flu" end - def then_i_see_the_childs_flu_information + def then_i_see_the_childs_flu_vaccinations expect(page).to have_current_path(patient_programme_path(@patient, "flu")) expect(page).to have_css("h3.nhsuk-card__heading", text: "Vaccinations") - expect(page).to have_css(".nhsuk-body", text: "No vaccinations") end def and_the_flu_tab_is_selected @@ -148,14 +150,29 @@ def when_i_click_on_the_hpv_tab click_on "HPV" end - def then_i_see_the_childs_hpv_information + def then_i_see_the_childs_hpv_vaccinations expect(page).to have_current_path(patient_programme_path(@patient, "hpv")) expect(page).to have_css("h3.nhsuk-card__heading", text: "Vaccinations") - expect(page).to have_css(".nhsuk-table__cell", text: "Recorded in Mavis") - expect(page).to have_css(".nhsuk-table__cell", text: "Vaccinated") end def and_the_hpv_tab_is_selected expect(page).to have_css(".app-secondary-navigation__current", text: "HPV") end + + def and_i_see_the_childs_flu_sessions + within(".nhsuk-card", text: "Sessions") do + expect(page).to have_content("No sessions") + end + end + + def and_i_see_the_childs_hpv_sessions + within(".nhsuk-card", text: "Sessions") do + expect(page).to have_link( + @session.location.name, + href: session_patient_programme_path(@session, @patient, "hpv") + ) + expect(page).to have_content(@session.dates.first.to_fs(:long)) + expect(page).to have_content("Vaccinated") + end + end end