Skip to content

Commit

Permalink
Merge pull request #475 from ministryofjustice/CBO-1417-hearing-day-p…
Browse files Browse the repository at this point in the history
…agination

[CBO-1417] hearing day pagination
  • Loading branch information
jsugarman authored Feb 25, 2021
2 parents 6e92c41 + f8d7074 commit ecff27c
Show file tree
Hide file tree
Showing 36 changed files with 1,347 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ commands:
steps:
- run:
name: Run brakeman
command: bundle exec brakeman --quiet --exit-on-warn
command: bundle exec brakeman

rspec:
steps:
Expand Down
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ Performance/StringInclude:
Rails/FilePath:
Enabled: false

Rails/HelperInstanceVariable:
Exclude:
- app/helpers/hearing_paginator.rb

Rails/OutputSafety:
Exclude:
- lib/gds_design_system_breadcrumb_builder.rb
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ group :development, :test do
gem 'dotenv-rails', require: 'dotenv/rails-now'
gem 'factory_bot_rails'
gem 'faker'
# gem 'meta_request', '~> 0.7.2'
gem 'pry'
gem 'pry-byebug'
gem 'pry-rails'
Expand All @@ -70,6 +69,7 @@ end
group :development do
gem 'foreman'
gem 'listen', '>= 3.0.5', '< 3.5'
gem 'meta_request', '~> 0.7.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ GEM
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
meta_request (0.7.2)
rack-contrib (>= 1.1, < 3)
railties (>= 3.0.0, < 7)
method_source (1.0.0)
mimemagic (0.3.5)
mini_mime (1.0.2)
Expand Down Expand Up @@ -274,6 +277,8 @@ GEM
racc (1.5.2)
racc (1.5.2-java)
rack (2.2.3)
rack-contrib (2.1.0)
rack (~> 2.0)
rack-proxy (0.6.5)
rack
rack-test (1.1.0)
Expand Down Expand Up @@ -498,6 +503,7 @@ DEPENDENCIES
launchy
listen (>= 3.0.5, < 3.5)
logstasher
meta_request (~> 0.7.2)
oauth2 (~> 1.4.4)
pg (>= 0.18, < 2.0)
prometheus_exporter
Expand Down
40 changes: 29 additions & 11 deletions app/controllers/hearings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,57 @@ class HearingsController < ApplicationController
(proc { |v| v.prosecution_case_path(v.controller.prosecution_case_reference) })

def show
add_breadcrumb "#{t('generic.hearing_day')} #{@hearing_day&.strftime('%d/%m/%Y')}", ''
add_breadcrumb "#{t('generic.hearing_day')} #{hearing_day&.strftime('%d/%m/%Y')}", ''

return if @hearing
return if hearing

redirect_back(fallback_location: prosecution_case_path(prosecution_case_reference),
allow_other_host: false,
notice: I18n.t('hearings.show.flash.notice.no_hearing_details'))
end

def prosecution_case_reference
params[:urn]
@prosecution_case_reference ||= params[:urn]
end

private

def load_and_authorize_search
@hearing_search = CourtDataAdaptor::Query::Hearing.new(params[:id])
authorize! :show, @hearing_search
# TODO: this should be hitting the hearing endpoint ideally, however, since pagination
# currently requires having knowlegde of all hearings via the prosecution case endpoint
# it is pointless and time-consuming to to query both endpoints when the prosecution case
# endpoint contains all the info we need. If we could pass a "pagination collection" this would
# allow us to revert to using the hearing endpoint.
#
@prosecution_case_search = Search.new(filter: 'case_reference', term: prosecution_case_reference)
authorize! :create, @prosecution_case_search
end

def set_hearing
@hearing = @hearing_search.call
hearing
end

def set_hearing_day
@hearing_day = (hearing_datetime || earliest_hearing_datetime)
hearing_day
end

def hearing_datetime
@hearing_datetime ||= params[:hearing_day]&.to_datetime
def hearing
@hearing ||= helpers.decorate(prosecution_case.hearings.find { |hearing| hearing.id == params[:id] })
end

def earliest_hearing_datetime
@hearing&.hearing_days&.map(&:to_datetime)&.sort&.first
def hearing_day
@hearing_day ||= paginator.current_item.hearing_date || helpers.earliest_day_for(hearing)
end

def paginator
@paginator ||= helpers.paginator(prosecution_case, page: page)
end

def prosecution_case
@prosecution_case ||= helpers.decorate(@prosecution_case_search.execute.first)
end

def page
@page ||= params[:page]
end
end
15 changes: 5 additions & 10 deletions app/decorators/cracked_ineffective_trial_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def cracked?
].any?
end

def cracked_on_sentence(hearing, prosecution_case)
t('cracked_ineffective_trial.cracked_on_sentence_html',
def cracked_on_sentence(hearing)
t('cracked_ineffective_trial.cracked_on_sentence',
type: type&.humanize,
cracked_at_link: cracked_at_link(hearing, prosecution_case))
cracked_at: cracked_at(hearing))
end

def description_sentence
Expand All @@ -24,12 +24,7 @@ def description_sentence

private

def cracked_at_link(hearing, prosecution_case)
heard_at = hearing.hearing_days.first.to_date.strftime('%d/%m/%Y')
view.link_to(heard_at,
view.hearing_path(id: hearing.id,
urn: prosecution_case.prosecution_case_reference,
hearing_day: heard_at),
class: 'govuk-link')
def cracked_at(hearing)
hearing.hearing_days.first.to_date.strftime('%d/%m/%Y')
end
end
4 changes: 3 additions & 1 deletion app/decorators/hearing_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def cracked_ineffective_trial
end

def hearing_events_for_day(hearing_day)
hearing_events.select { |event| event.occurred_at.to_date.eql?(hearing_day) }.sort_by(&:occurred_at)
hearing_events.select do |event|
event.occurred_at.to_date == hearing_day.to_date
end.sort_by(&:occurred_at)
end

private
Expand Down
11 changes: 11 additions & 0 deletions app/decorators/prosecution_case_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ def hearings_by_datetime
hearings.sort_by { |h| h.hearing_days.map(&:to_datetime) }
end

def hearings_with_day_by_datetime
Enumerator.new do |enum|
hearings_by_datetime.each do |hearing|
hearing.hearing_days.map(&:to_datetime).sort.each do |day|
hearing.day = day
enum.yield(hearing)
end
end
end
end

def cracked?
hearings.map { |h| h.cracked_ineffective_trial&.cracked? }.any?
end
Expand Down
11 changes: 11 additions & 0 deletions app/helpers/hearing_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module HearingHelper
def paginator(...)
HearingPaginator.new(...)
end

def earliest_day_for(hearing)
hearing&.hearing_days&.map(&:to_datetime)&.sort&.first
end
end
89 changes: 89 additions & 0 deletions app/helpers/hearing_paginator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# frozen_string_literal: true

# Creates a chronologically sorted set of "items"
# with next and previous navigation helpers.
#
# Next and previous correlate to navigation over all
# a cases' hearing's hearing days.
#
class HearingPaginator
include ActionView::Helpers
include Rails.application.routes.url_helpers

PageItem = Struct.new(:id, :hearing_date)

def initialize(prosecution_case, page: 0)
@prosecution_case = prosecution_case
@current_page = page.to_i
end

def current_page
@current_page ||= 0
end

def current_item
items[current_page || first_page]
end

def items
@items ||= hearing_items_by_datetime
end

def first_page?
current_page == first_page
end

def first_page
0
end

def last_page?
current_page == last_page
end

def last_page
[items.size - 1, 0].max
end

def next_page_link
# TODO: add <span class="govuk-visually-hidden"> set of pages</span> within hyperlink ?!
link_to(t('hearings.show.pagination.next_page'),
hearing_path(id: next_item.id,
urn: @prosecution_case.prosecution_case_reference,
page: next_page),
class: 'moj-pagination__link')
end

def previous_page_link
# TODO: add <span class="govuk-visually-hidden"> set of pages</span> within hyperlink ?!
link_to(t('hearings.show.pagination.previous_page'),
hearing_path(id: previous_item.id,
urn: @prosecution_case.prosecution_case_reference,
page: previous_page),
class: 'moj-pagination__link')
end

private

def next_item
items[next_page]
end

def next_page
[current_page + 1, last_page].min
end

def previous_item
items[previous_page]
end

def previous_page
[current_page - 1, first_page].max
end

def hearing_items_by_datetime
@prosecution_case.hearings_with_day_by_datetime.map do |hearing|
PageItem.new(hearing.id, hearing.day)
end
end
end
10 changes: 10 additions & 0 deletions app/views/hearings/_pagination.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
%nav#pagination-label.moj-pagination
%p.govuk-visually-hidden{ 'aria-labelledby': 'pagination-label' }
Pagination navigation
%ul.moj-pagination__list
- unless paginator.first_page?
%li.moj-pagination__item.moj-pagination__item--prev
= paginator.previous_page_link
- unless paginator.last_page?
%li.moj-pagination__item.moj-pagination__item--next
= paginator.next_page_link
11 changes: 6 additions & 5 deletions app/views/hearings/show.html.haml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
= govuk_page_title(@hearing_day&.strftime('%d/%m/%Y'), t('generic.hearing_day'))
- hearing = decorate(@hearing)

= render partial: 'listing_info', locals: { hearing: hearing, hearing_day: @hearing_day }
= render partial: 'pagination', locals: { paginator: @paginator }

= render partial: 'attendees', locals: { hearing: hearing }
= render partial: 'listing_info', locals: { hearing: @hearing, hearing_day: @hearing_day }

= render partial: 'hearing_events', locals: { hearing: hearing, hearing_day: @hearing_day }
= render partial: 'attendees', locals: { hearing: @hearing }

= render partial: 'hearing_events', locals: { hearing: @hearing, hearing_day: @hearing_day }

- if Rails.configuration.x.display_raw_responses
= render partial: 'raw_response', locals: { hearing: hearing }
= render partial: 'raw_response', locals: { hearing: @hearing }
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
%td.govuk-table__cell
- prosecution_case.hearings.each do |hearing|
- if hearing.cracked_ineffective_trial&.cracked?
= hearing.cracked_ineffective_trial.cracked_on_sentence(hearing, prosecution_case)
= hearing.cracked_ineffective_trial.cracked_on_sentence(hearing)
%br
= hearing.cracked_ineffective_trial.description
17 changes: 8 additions & 9 deletions app/views/prosecution_cases/_hearing_summaries.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
%th.govuk-table__header{ scope: 'col' }= t('search.result.hearing.hearing_type')
%th.govuk-table__header{ scope: 'col' }= t('search.result.hearing.providers')
%tbody.govuk-table__body
- prosecution_case.hearings_by_datetime.each do |hearing|
- hearing.hearing_days.map(&:to_date).sort.each do |hearing_day|
%tr.govuk-table__row
%td.govuk-table__cell
= link_to hearing_day.to_date.strftime('%d/%m/%Y'), hearing_path(id: hearing.id, urn: prosecution_case.prosecution_case_reference, hearing_day: hearing_day.to_date.strftime('%d/%m/%Y')), class: 'govuk-link'
%td.govuk-table__cell
= hearing.hearing_type
%td.govuk-table__cell
= hearing ? decorate(hearing).provider_list : t('generic.not_available')
- prosecution_case.hearings_with_day_by_datetime.each_with_index do |hearing, idx|
%tr.govuk-table__row
%td.govuk-table__cell
= link_to hearing.day.strftime('%d/%m/%Y'), hearing_path(id: hearing.id, urn: prosecution_case.prosecution_case_reference, page: idx), class: 'govuk-link'
%td.govuk-table__cell
= hearing.hearing_type
%td.govuk-table__cell
= hearing ? hearing.provider_list : t('generic.not_available')
1 change: 1 addition & 0 deletions app/webpack/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
$govuk-font-url-function: frontend-font-url;
$govuk-image-url-function: frontend-image-url;
@import "~govuk-frontend/govuk/all";
@import "@ministryofjustice/frontend/moj/all";
@import "core/typography";

@import "components/cookie_banner";
Expand Down
4 changes: 4 additions & 0 deletions config/brakeman.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
:quiet: true
:exit_on_warn: true
:exit_on_error: false
2 changes: 0 additions & 2 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "laa_court_data_ui_production"

config.action_mailer.perform_caching = false

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
Expand Down
2 changes: 1 addition & 1 deletion config/locales/en/decorators/cracked_ineffective_trial.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
en:
cracked_ineffective_trial:
cracked_on_sentence_html: "%{type} on %{cracked_at_link}"
cracked_on_sentence: "%{type} on %{cracked_at}"
3 changes: 3 additions & 0 deletions config/locales/en/views/hearings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ en:
notice:
no_hearing_details: No hearing details available
hearing_type: Hearing type
pagination:
next_page: Next hearing day
previous_page: Previous hearing day
result: Result
time_listed: Time listed
4 changes: 3 additions & 1 deletion config/webpacker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ default: &default

# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: ['node_modules/govuk-frontend/govuk']
additional_paths:
- node_modules/govuk-frontend/govuk
- node_modules/@ministryofjustice/frontend/moj

# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
Expand Down
Loading

0 comments on commit ecff27c

Please sign in to comment.