renalware-core 2.0.67 → 2.0.68

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/renalware/partials/_forms.scss +33 -2
  3. data/app/assets/stylesheets/renalware/partials/_navigation.scss +4 -0
  4. data/app/controllers/renalware/hd/mdm_patients_controller.rb +19 -6
  5. data/app/controllers/renalware/pd/mdm_patients_controller.rb +9 -1
  6. data/app/controllers/renalware/research/studies_controller.rb +6 -1
  7. data/app/controllers/renalware/research/study_participants_controller.rb +13 -11
  8. data/app/models/renalware/hd/mdm_patients_form.rb +1 -0
  9. data/app/models/renalware/hd/mdm_patients_query.rb +20 -4
  10. data/app/models/renalware/patients/mdm_patients_query.rb +1 -1
  11. data/app/models/renalware/patients/search_query.rb +1 -1
  12. data/app/models/renalware/pd/mdm_patients_query.rb +18 -2
  13. data/app/models/renalware/transplants/mdm_patients_query.rb +1 -1
  14. data/app/views/renalware/clinics/appointments/new.html.slim +9 -8
  15. data/app/views/renalware/hd/mdm_patients/_filters.html.slim +3 -2
  16. data/app/views/renalware/hd/mdm_patients/_tabs.html.slim +8 -0
  17. data/app/views/renalware/hd/mdm_patients/index.html.slim +3 -0
  18. data/app/views/renalware/letters/printable_letters/_recipient_address_cover_sheet.html.slim +1 -1
  19. data/app/views/renalware/pd/mdm_patients/_tabs.html.slim +8 -0
  20. data/app/views/renalware/research/studies/_tabs.html.slim +12 -0
  21. data/app/views/renalware/research/studies/edit.html.slim +25 -1
  22. data/app/views/renalware/research/studies/index.html.slim +9 -15
  23. data/app/views/renalware/research/studies/show.html.slim +9 -13
  24. data/app/views/renalware/research/study_participants/_filters.html.slim +1 -1
  25. data/app/views/renalware/research/study_participants/_form.html.slim +18 -43
  26. data/app/views/renalware/research/study_participants/edit.html.slim +7 -1
  27. data/app/views/renalware/research/study_participants/index.html.slim +8 -22
  28. data/app/views/renalware/research/study_participants/new.html.slim +7 -1
  29. data/config/locales/renalware/hd/mdm_patients.yml +4 -0
  30. data/config/locales/renalware/pd/mdm.en.yml +4 -0
  31. data/config/routes.rb +8 -1
  32. data/db/migrate/20190104095254_create_active_storage_tables.active_storage.rb +27 -0
  33. data/lib/renalware/version.rb +1 -1
  34. data/spec/factories/hd/patients.rb +23 -1
  35. data/spec/factories/pd/modality_descriptions.rb +3 -0
  36. data/spec/factories/pd/patients.rb +23 -1
  37. data/spec/support/devise_spec_helper.rb +3 -0
  38. metadata +14 -16
  39. data/app/assets/javascripts/renalware/research.js +0 -18
  40. data/app/views/renalware/research/study_participants/create.js.erb +0 -3
  41. data/app/views/renalware/research/study_participants/new.js.erb +0 -4
  42. data/app/views/renalware/research/study_participants/update.js.erb +0 -3
  43. data/spec/support/capybara.rb +0 -23
  44. data/spec/support/select2_spec_helper.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf634cea697775671cc9b95511d93c3927bfaef385d14257daffa16ca86086bb
4
- data.tar.gz: da6403cbe24ea79e5690cb0e767bf83fd3931495950ad2135ffc9b08cad32ce6
3
+ metadata.gz: c551c17f27d4ce7093dcacaa92bb5936b9d9131ecc452fabb288b11a409c42e8
4
+ data.tar.gz: ce9f5588b3f29e82f900ac88d89ace8e11e0535c113b3479edf3d0745dd6d578
5
5
  SHA512:
6
- metadata.gz: d2d4668c9ce60c07e2d66bd2676270342c087292d32737a03a4a5db0f953b6f3339573f1815ba4e0efc939979c67b2de3e5f0192f5d3a4fd7250b9de10b95580
7
- data.tar.gz: 51c70c6a5b0d163669a13f5c3674afabb6dbdfd22093951521210b80d42d860c248a438c13c994b1f4a4cb103ea3969e1d856fd79c5631fb6f73557bb763b160
6
+ metadata.gz: f0e617fd1c72cd5162a23f853647d568296a3dbeb32a023daeadc3b517abee63bc7fe30adc06d8a2328ab0099526afc06a0b98f2a5cc74d942a6db570cf4bce3
7
+ data.tar.gz: 3b90fa1559317b7a89d94b879b147723b2aa47f87d46b84a0360025e49765934b6462ccfe6655fc5f52b22aee5c022555dfd81632126622aeb872751e1880fdb
@@ -3,8 +3,18 @@ textarea::placeholder {
3
3
  color: $form-hint-colour
4
4
  }
5
5
 
6
- .panel.compact {
7
- padding: 0.5rem 1rem;
6
+ .panel {
7
+ p {
8
+ padding-left: 0;
9
+ }
10
+
11
+ &.compact {
12
+ padding: 0.5rem 1rem;
13
+ }
14
+
15
+ .muted {
16
+ color: $dashboard-muted-color;
17
+ }
8
18
  }
9
19
 
10
20
  textarea.monospace {
@@ -434,3 +444,24 @@ fieldset {
434
444
  }
435
445
  }
436
446
  }
447
+
448
+ .panel.danger-zone {
449
+ background-color: $white;
450
+ color: $nhs-red;
451
+
452
+ h4 {
453
+ color: inherit;
454
+ }
455
+
456
+ a {
457
+ color: inherit;
458
+ font-weight: bold;
459
+ background-color: $table-border-color;
460
+
461
+ &:hover,
462
+ &:active {
463
+ background-color: $nhs-red;
464
+ color: $white;
465
+ }
466
+ }
467
+ }
@@ -20,6 +20,10 @@
20
20
  dd {
21
21
  margin: 0;
22
22
  padding: 0;
23
+
24
+ i {
25
+ margin-right: .7rem;
26
+ }
23
27
  }
24
28
  }
25
29
 
@@ -6,12 +6,6 @@ module Renalware
6
6
  module HD
7
7
  class MDMPatientsController < Renalware::MDMPatientsController
8
8
  def index
9
- filter_form = form_object_class.new(filter_form_params)
10
-
11
- query = HD::MDMPatientsQuery.new(
12
- params: filter_form.ransacked_parameters.merge(query_params).with_indifferent_access
13
- )
14
-
15
9
  render_index(filter_form: filter_form,
16
10
  query: query,
17
11
  page_title: t(".page_title"),
@@ -21,6 +15,21 @@ module Renalware
21
15
 
22
16
  private
23
17
 
18
+ def query
19
+ @query ||= begin
20
+ MDMPatientsQuery.new(
21
+ params: filter_form.ransacked_parameters.merge(query_params).with_indifferent_access,
22
+ named_filter: named_filter
23
+ )
24
+ end
25
+ end
26
+
27
+ # Pass in the current path to the filter form so it can render the correct URI in form and
28
+ # reset links.
29
+ def filter_form
30
+ @filter_form ||= form_object_class.new(filter_form_params.merge(url: request.path))
31
+ end
32
+
24
33
  # Permit all attributes on the filter form object. Slightly messy
25
34
  def filter_form_params
26
35
  params.fetch(:filter, {}).permit(form_object_class.permittable_attributes)
@@ -35,6 +44,10 @@ module Renalware
35
44
  params.fetch(:q, {}).permit(:s)
36
45
  end
37
46
 
47
+ def named_filter
48
+ params[:named_filter]
49
+ end
50
+
38
51
  def render_index(filter_form:, **args)
39
52
  presenter = build_presenter(params: params, **args)
40
53
  authorize presenter.patients
@@ -6,10 +6,18 @@ module Renalware
6
6
  module PD
7
7
  class MDMPatientsController < Renalware::MDMPatientsController
8
8
  def index
9
- render_index(query: MDMPatientsQuery.new(q: params[:q]),
9
+ render_index(query: query,
10
10
  page_title: t(".page_title"),
11
11
  view_proc: ->(patient) { patient_pd_mdm_path(patient) })
12
12
  end
13
+
14
+ def query
15
+ @query ||= MDMPatientsQuery.new(q: params[:q], named_filter: named_filter)
16
+ end
17
+
18
+ def named_filter
19
+ params[:named_filter]
20
+ end
13
21
  end
14
22
  end
15
23
  end
@@ -14,6 +14,11 @@ module Renalware
14
14
  render locals: { studies: studies, query: query }
15
15
  end
16
16
 
17
+ def show
18
+ study = find_and_authorize_study
19
+ render locals: { study: study }
20
+ end
21
+
17
22
  def new
18
23
  study = Study.new
19
24
  authorize study
@@ -38,7 +43,7 @@ module Renalware
38
43
  def update
39
44
  study = find_and_authorize_study
40
45
  if study.update_by(current_user, study_params)
41
- redirect_to research_studies_path, notice: success_msg_for("clinical study")
46
+ redirect_to research_study_path(study), notice: success_msg_for("clinical study")
42
47
  else
43
48
  render_edit(study)
44
49
  end
@@ -9,7 +9,9 @@ module Renalware
9
9
 
10
10
  def index
11
11
  authorize StudyParticipant, :index?
12
- render_current_action_with_locals
12
+ query = StudyParticipantsQuery.new(study: study, options: params[:q])
13
+ participants = query.call.page(page).per(per_page)
14
+ render locals: { study: study, participants: participants, query: query.search }
13
15
  end
14
16
 
15
17
  def show
@@ -23,7 +25,10 @@ module Renalware
23
25
  authorize participant
24
26
 
25
27
  if participant.save
26
- render_current_action_with_locals
28
+ redirect_to(
29
+ research_study_participants_path(study),
30
+ notice: success_msg_for("participant")
31
+ )
27
32
  else
28
33
  render_new(participant)
29
34
  end
@@ -50,7 +55,10 @@ module Renalware
50
55
  def update
51
56
  participant = find_and_authorise_participant
52
57
  if participant.update(participant_params_for_update)
53
- render_current_action_with_locals
58
+ redirect_to(
59
+ research_study_participants_path(study),
60
+ notice: success_msg_for("participant")
61
+ )
54
62
  else
55
63
  render_edit(participant)
56
64
  end
@@ -63,17 +71,11 @@ module Renalware
63
71
  end
64
72
 
65
73
  def render_edit(participant)
66
- render :new, locals: { participant: participant }, layout: false
74
+ render :edit, locals: { participant: participant }
67
75
  end
68
76
 
69
77
  def render_new(participant)
70
- render :new, locals: { participant: participant }, layout: false
71
- end
72
-
73
- def render_current_action_with_locals
74
- query = StudyParticipantsQuery.new(study: study, options: params[:q])
75
- participants = query.call.page(page).per(per_page)
76
- render locals: { study: study, participants: participants, query: query.search }
78
+ render :new, locals: { participant: participant }
77
79
  end
78
80
 
79
81
  def study
@@ -14,6 +14,7 @@ module Renalware
14
14
  attribute :hospital_unit_id, Integer
15
15
  attribute :named_nurse_id, Integer
16
16
  attribute :schedule_definition_ids, String # an Integer array in string form e.g. "[1 ,2]"
17
+ attribute :url
17
18
 
18
19
  # The hash returned here is passed into the Ransack #search method later i the ouery object.
19
20
  def ransacked_parameters
@@ -9,18 +9,19 @@ module Renalware
9
9
  include PatientPathologyScopes
10
10
  MODALITY_NAMES = "HD"
11
11
  DEFAULT_SEARCH_PREDICATE = "hgb_date desc"
12
- attr_reader :params
12
+ attr_reader :params, :named_filter
13
13
 
14
- def initialize(params:)
14
+ def initialize(params:, named_filter:)
15
15
  @params = params || {}
16
16
  @params[:s] = DEFAULT_SEARCH_PREDICATE if @params[:s].blank?
17
+ @named_filter = named_filter || :none
17
18
  end
18
19
 
19
20
  def call
20
21
  search.result
21
22
  end
22
23
 
23
- # rubocop:disable Metrics/MethodLength
24
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
24
25
  def search
25
26
  @search ||= begin
26
27
  HD::Patient
@@ -31,13 +32,15 @@ module Renalware
31
32
  .eager_load(hd_profile: [:hospital_unit])
32
33
  .extending(ModalityScopes)
33
34
  .extending(PatientPathologyScopes)
35
+ .extending(NamedFilterScopes)
34
36
  .with_current_pathology
35
37
  .with_registration_statuses
36
38
  .with_current_modality_matching(MODALITY_NAMES)
39
+ .public_send(named_filter.to_s)
37
40
  .ransack(params)
38
41
  end
39
42
  end
40
- # rubocop:enable Metrics/MethodLength
43
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
41
44
 
42
45
  # Module to allow us to mixin ransackers
43
46
  module QueryablePatient
@@ -63,5 +66,18 @@ module Renalware
63
66
  end
64
67
  end
65
68
  end
69
+
70
+ # Module to allow us to mixin named filters like on_worryboard which correspond to tabs
71
+ # on the UI for example.
72
+ module NamedFilterScopes
73
+ def none
74
+ self # NOOP - aka 'all'
75
+ end
76
+
77
+ def patients_on_the_worry_board
78
+ joins("RIGHT OUTER JOIN patient_worries ON patient_worries.patient_id = patients.id")
79
+ end
80
+ alias_method :on_worryboard, :patients_on_the_worry_board
81
+ end
66
82
  end
67
83
  end
@@ -25,7 +25,7 @@ module Renalware
25
25
  .extending(PatientPathologyScopes)
26
26
  .with_current_pathology
27
27
  .with_current_modality_matching(modality_names)
28
- .search(q)
28
+ .ransack(q)
29
29
  end
30
30
  end
31
31
  end
@@ -31,7 +31,7 @@ module Renalware
31
31
  def search
32
32
  @search ||= begin
33
33
  scope
34
- .search(identity_match: term).tap do |search|
34
+ .ransack(identity_match: term).tap do |search|
35
35
  search.sorts = %w(family_name given_name)
36
36
  end
37
37
  end
@@ -7,31 +7,47 @@ module Renalware
7
7
  include PatientPathologyScopes
8
8
  MODALITY_NAMES = "PD"
9
9
  DEFAULT_SEARCH_PREDICATE = "hgb_date desc"
10
- attr_reader :q, :relation
10
+ attr_reader :q, :relation, :named_filter
11
11
 
12
- def initialize(relation: PD::Patient.all, q:)
12
+ def initialize(relation: PD::Patient.all, q:, named_filter: nil)
13
13
  @q = q || {}
14
14
  @q[:s] = DEFAULT_SEARCH_PREDICATE if @q[:s].blank?
15
15
  @relation = relation
16
+ @named_filter = named_filter || :none
16
17
  end
17
18
 
18
19
  def call
19
20
  search.result
20
21
  end
21
22
 
23
+ # rubocop:disable Metrics/MethodLength
22
24
  def search
23
25
  @search ||= begin
24
26
  relation
25
27
  .extending(PatientTransplantScopes)
26
28
  .extending(ModalityScopes)
27
29
  .extending(PatientPathologyScopes)
30
+ .extending(NamedFilterScopes)
28
31
  .with_current_modality_matching(MODALITY_NAMES)
29
32
  .with_current_pathology
30
33
  .with_registration_statuses
31
34
  .left_outer_joins(:current_observation_set)
35
+ .public_send(named_filter.to_s)
32
36
  .ransack(q)
33
37
  end
34
38
  end
39
+ # rubocop:enable Metrics/MethodLength
40
+ end
41
+
42
+ module NamedFilterScopes
43
+ def none
44
+ self # NOOP
45
+ end
46
+
47
+ def patients_on_the_worry_board
48
+ joins("RIGHT OUTER JOIN patient_worries ON patient_worries.patient_id = patients.id")
49
+ end
50
+ alias_method :on_worryboard, :patients_on_the_worry_board
35
51
  end
36
52
  end
37
53
  end
@@ -9,7 +9,7 @@ module Renalware
9
9
  class MDMPatientsQuery
10
10
  include ModalityScopes
11
11
  include PatientPathologyScopes
12
- MODALITY_NAMES = ["Transplant"].freeze
12
+ MODALITY_NAMES = "Transplant"
13
13
  DEFAULT_SEARCH_PREDICATE = "hgb_date DESC"
14
14
  attr_reader :q, :relation, :named_filter
15
15
 
@@ -12,14 +12,15 @@
12
12
  / the blank option. Selecting index 1 fails silently if there is nothing there (no patient
13
13
  / selected yet) otherwise it will display the selected patient who will always be
14
14
  / at option index 1.
15
- = f.input :patient_id,
16
- wrapper: :horizontal_medium,
17
- collection: [[appointment.patient&.to_s(:long), appointment.patient&.id]],
18
- selected: 1,
19
- input_html: { \
20
- class: "patient-id-select2 patient-ajax-search",
21
- data: { "ajax--url" => search_patients_path(format: :json),
22
- placeholder: "Search by patient name or hospital/NHS no." } \
15
+ #patient-select2
16
+ = f.input :patient_id,
17
+ wrapper: :horizontal_medium,
18
+ collection: [[appointment.patient&.to_s(:long), appointment.patient&.id]],
19
+ selected: 1,
20
+ input_html: { \
21
+ class: "patient-id-select2 patient-ajax-search",
22
+ data: { "ajax--url" => search_patients_path(format: :json),
23
+ placeholder: "Search by patient name or hospital/NHS no." } \
23
24
  }
24
25
 
25
26
  = f.input :clinic_id,
@@ -1,6 +1,7 @@
1
+
1
2
  = simple_form_for filter_form,
2
3
  as: :filter,
3
- url: hd_mdm_patients_path,
4
+ url: filter_form.url,
4
5
  method: :get,
5
6
  html: { autocomplete: "off" },
6
7
  wrapper: :horizontal_form do |f|
@@ -27,4 +28,4 @@
27
28
  .medium-2.columns.actions
28
29
  = f.submit t("helpers.submit.filter"), class: "button", name: nil
29
30
  span= " or "
30
- = link_to t("helpers.reset"), hd_mdm_patients_path
31
+ = link_to t("helpers.reset"), filter_form.url
@@ -0,0 +1,8 @@
1
+ - named_filter_param = params[:named_filter]
2
+
3
+ dl.sub-nav
4
+ dd(class=("active" unless named_filter_param.present?))
5
+ = link_to t(".tab.all"), hd_mdm_patients_path
6
+ - %i(on_worryboard).each do |filter|
7
+ dd(class=("active" if named_filter_param == filter.to_s))
8
+ = link_to t(".tab.#{filter}"), hd_filtered_mdm_patients_path(named_filter: filter)
@@ -1,6 +1,9 @@
1
1
  = content_for(:filters) do
2
2
  = render_if_exists "filters", presenter: presenter, filter_form: filter_form
3
3
 
4
+ = content_for(:tabs) do
5
+ = render_if_exists "tabs", presenter: presenter
6
+
4
7
  = within_admin_layout(title: presenter.page_title)
5
8
  = render "table", presenter: presenter
6
9
  = paginate presenter.patients
@@ -20,7 +20,7 @@ scss:
20
20
  .address-in-window {
21
21
  position: absolute;
22
22
  left: 60px;
23
- top: 75px;
23
+ top: 130px;
24
24
  width: 50%;
25
25
  height: 50%;
26
26
  line-height: 1.2em;
@@ -0,0 +1,8 @@
1
+ - named_filter_param = params[:named_filter]
2
+
3
+ dl.sub-nav
4
+ dd(class=("active" unless named_filter_param.present?))
5
+ = link_to t(".tab.all"), pd_mdm_patients_path
6
+ - %i(on_worryboard).each do |filter|
7
+ dd(class=("active" if named_filter_param == filter.to_s))
8
+ = link_to t(".tab.#{filter}"), pd_filtered_mdm_patients_path(named_filter: filter)
@@ -0,0 +1,12 @@
1
+ dl.sub-nav
2
+ dd= link_to "Summary", research_study_path(study)
3
+ dd
4
+ = link_to edit_research_study_path(study) do
5
+ i.fas.fa-cogs
6
+ | Settings
7
+ dd
8
+ = link_to research_study_participants_path(study) do
9
+ i.fas.fa-users
10
+ | Participants
11
+ / dd(class=("active" if params.fetch(:q, {})[:expired]))
12
+ / = link_to "Members", admin_expired_users_path
@@ -1,5 +1,29 @@
1
- = within_admin_layout(title: "Edit",
1
+ = content_for(:tabs) do
2
+ = render "tabs", study: study
3
+
4
+ = within_admin_layout(title: study.code,
2
5
  breadcrumbs: breadcrumb_for("Clinical Studies",
3
6
  research_studies_path)) do
4
7
 
5
8
  = render "form", study: study
9
+
10
+ br
11
+ hr
12
+ br
13
+ .panel.danger-zone
14
+ h4 Danger zone
15
+ br
16
+ - super_admin = current_user.has_role?(:super_admin)
17
+ - if super_admin
18
+ p= link_to "Delete this study",
19
+ research_study_path(study),
20
+ method: :delete,
21
+ data: { confirm: "Are you sure you want to delete this study?", disable: true },
22
+ class: "button"
23
+ - else
24
+ p= link_to "Delete this study",
25
+ "#",
26
+ class: "button",
27
+ disabled: true
28
+ p
29
+ i You need to have the super_admin role to delete a study
@@ -8,30 +8,24 @@
8
8
  table
9
9
  thead
10
10
  tr
11
- th.col-width-date= sort_link(query, :started_on, "Started")
12
- th.col-width-date= sort_link(query, :terminated_on, "Terminated")
11
+ th
13
12
  th.col-width-small= sort_link(query, :code, "Code")
14
13
  th Description
15
14
  th= sort_link(query, :code, "Leader")
16
15
  th Participants
17
- th
16
+ th.col-width-date= sort_link(query, :started_on, "Started")
17
+ th.col-width-date= sort_link(query, :terminated_on, "Terminated")
18
+
18
19
  tbody
19
20
  - studies.each do |study|
20
21
  tr
21
- td= l(study.started_on)
22
- td= l(study.terminated_on)
22
+ td.actions.left
23
+ = link_to "View", research_study_path(study)
23
24
  td= study.code
24
- td= study.description
25
+ td= study.description.truncate(60)
25
26
  td= study.leader
26
27
  td= study.participants.count
27
- td.actions
28
- = link_to "Delete",
29
- research_study_path(study),
30
- method: :delete,
31
- data: { confirm: "Are you sure you want to delete this study?" }
32
- = " | "
33
- = link_to "Edit", edit_research_study_path(study)
34
- = " | "
35
- = link_to "View Participants", research_study_participants_path(study)
28
+ td= l(study.started_on)
29
+ td= l(study.terminated_on)
36
30
 
37
31
  = paginate studies
@@ -1,18 +1,14 @@
1
- = content_for(:actions) do
2
- = link_to("Add Participant", new_research_study_participant_path(study), class: :button)
1
+ = content_for(:tabs) do
2
+ = render "tabs", study: study
3
3
 
4
4
  = within_admin_layout(title: study.code,
5
5
  breadcrumbs: breadcrumb_for("Clinical Studies",
6
6
  research_studies_path)) do
7
7
 
8
- p= study.description
9
-
10
- table
11
- thead
12
- tr
13
- th Patient
14
- th
15
- tbody
16
- - study.participants.each do |participant|
17
- tr
18
- td= participant
8
+ - if study.description.present?
9
+ p.panel.radius.compact
10
+ = "Description: #{study.description}"
11
+ br
12
+ = "Started on: #{l(study.started_on)}"
13
+ br
14
+ = "Leader: #{study.leader}"
@@ -8,6 +8,6 @@
8
8
  = f.input :identity_match, label: "Search by Hosp/NHS no or name"
9
9
 
10
10
  .columns.medium-4.actions.end
11
- = f.submit t("helpers.submit.filter"), class: "button", name: nil
11
+ = f.submit t("helpers.submit.filter"), class: "button secondary", name: nil
12
12
  span= " or "
13
13
  = link_to t("helpers.reset"), research_study_participants_path(study)
@@ -1,44 +1,19 @@
1
- ruby:
2
- url = if participant.new_record?
3
- research_study_participants_path(participant.study)
4
- else
5
- research_study_participant_path(participant.study, participant)
6
- end
7
- .modal
8
- .modal__header
9
- h2= participant.persisted? ? "Edit Patient" : "Add Patient"
10
- = render "renalware/shared/modal_close_link"
1
+ = simple_form_for(participant,
2
+ url: url,
3
+ html: { autocomplete: "off" },
4
+ wrapper: :horizontal_form) do |f|
5
+ - if participant.persisted?
6
+ h5= participant.patient.to_s(:long)
7
+ - else
8
+ #patient-select2
9
+ = f.input :participant_id,
10
+ collection: [],
11
+ input_html: { \
12
+ class: "patient-id-select2 patient-ajax-search",
13
+ data: { "ajax--url" => search_patients_path(format: :json),
14
+ placeholder: "Search by patient name or hospital/NHS no." } \
15
+ }
11
16
 
12
- .modal__body
13
- = render "renalware/shared/errors", model: participant
14
-
15
- = simple_form_for(participant,
16
- url: url,
17
- remote: true,
18
- html: { autocomplete: "off" },
19
- wrapper: :horizontal_form) do |f|
20
- - if participant.persisted?
21
- h5= participant.patient.to_s(:long)
22
- - else
23
- = f.input :participant_id,
24
- collection: [],
25
- input_html: { \
26
- class: "patient-id-select2 patient-ajax-search",
27
- data: { "ajax--url" => search_patients_path(format: :json),
28
- placeholder: "Search by patient name or hospital/NHS no." } \
29
- }
30
-
31
- = f.input :joined_on, as: :date_picker
32
- = f.input :left_on, as: :date_picker
33
-
34
- = f.submit "Add", class: :button
35
- span= " or "
36
- = link_to "Cancel",
37
- "#",
38
- "aria-label" => "Close",
39
- class: "reveal-modal-close"
40
-
41
- .modal__footer
42
-
43
- javascript:
44
- $(document).ready(Renalware.Research.init);
17
+ = f.input :joined_on, as: :date_picker
18
+ = f.input :left_on, as: :date_picker
19
+ = save_or_cancel(form: f, back_path: research_study_participants_path(participant.study))
@@ -1 +1,7 @@
1
- = render "form", participant: participant
1
+ = within_admin_layout(title: "Edit",
2
+ breadcrumbs: breadcrumb_for("Clinical Studies",
3
+ research_studies_path)) do
4
+
5
+ = render "form",
6
+ participant: participant,
7
+ url: research_study_participant_path(participant.study, participant)
@@ -1,28 +1,14 @@
1
- = content_for(:actions) do
2
- = link_to("Add",
3
- new_research_study_participant_path,
4
- id: "add-study-participants",
5
- class: :button,
6
- data: { "reveal-id" => "study-participant-modal", "reveal-ajax" => "true" })
7
-
8
1
  = content_for(:filters) do
2
+ = link_to(new_research_study_participant_path, class: :button) do
3
+ i.fas.fa-plus
4
+ | Add
9
5
  = render "filters", study: study, query: query
10
6
 
11
- = within_admin_layout(\
12
- title: "Participants",
13
- breadcrumbs: [\
14
- breadcrumb_for("Clinical Studies", research_studies_path),
15
- breadcrumb_for(study.code, edit_research_study_path(study))\
16
- ]) do
7
+ = content_for(:tabs) do
8
+ = render "renalware/research/studies/tabs", study: study
17
9
 
18
- - if study.description.present?
19
- p.panel.radius.compact
20
- = "Description: #{study.description}"
21
- br
22
- = "Started on: #{l(study.started_on)}"
23
- br
24
- = "Leader: #{study.leader}"
10
+ = within_admin_layout(\
11
+ title: study.code,
12
+ breadcrumbs: breadcrumb_for("Clinical Studies", research_studies_path)) do
25
13
 
26
14
  = render "table", study: study, participants: participants, query: query
27
-
28
- #study-participant-modal.reveal-modal.small(data-reveal)
@@ -1 +1,7 @@
1
- = render "form", participant: participant
1
+ = within_admin_layout(title: "Add Participant",
2
+ breadcrumbs: breadcrumb_for("Clinical Studies",
3
+ research_studies_path)) do
4
+
5
+ = render "form",
6
+ participant: participant,
7
+ url: research_study_participants_path(participant.study)
@@ -37,3 +37,7 @@ en:
37
37
  cre: CRE
38
38
  cre_date: CRE Date
39
39
  egfr: EGFR
40
+ tabs:
41
+ tab:
42
+ all: All
43
+ on_worryboard: On Worryboard
@@ -4,3 +4,7 @@ en:
4
4
  mdm_patients:
5
5
  index:
6
6
  page_title: PD MDM Patients
7
+ tabs:
8
+ tab:
9
+ all: All
10
+ on_worryboard: On Worryboard
@@ -95,7 +95,7 @@ Renalware::Engine.routes.draw do
95
95
  end
96
96
 
97
97
  namespace :research do
98
- resources :studies, except: :show do
98
+ resources :studies do
99
99
  resources :participants, controller: :study_participants
100
100
  end
101
101
  end
@@ -162,6 +162,10 @@ Renalware::Engine.routes.draw do
162
162
  resources :dialysates, except: :show
163
163
  resource :ongoing_sessions, only: :show
164
164
  resources :mdm_patients, only: :index
165
+ resources :mdm_patients, only: :index
166
+ constraints(named_filter: /(on_worryboard)/) do
167
+ get "mdm_patients/:named_filter", to: "mdm_patients#index", as: :filtered_mdm_patients
168
+ end
165
169
  resources :unmet_preferences, only: :index
166
170
  resources :units, only: [] do
167
171
  resources :stations do
@@ -240,6 +244,9 @@ Renalware::Engine.routes.draw do
240
244
  resources :bag_types, except: [:show]
241
245
  resources :infection_organisms
242
246
  resources :mdm_patients, only: :index
247
+ constraints(named_filter: /(on_worryboard)/) do
248
+ get "mdm_patients/:named_filter", to: "mdm_patients#index", as: :filtered_mdm_patients
249
+ end
243
250
  end
244
251
 
245
252
  namespace :renal do
@@ -0,0 +1,27 @@
1
+ # This migration comes from active_storage (originally 20170806125915)
2
+ class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
3
+ def change
4
+ create_table :active_storage_blobs do |t|
5
+ t.string :key, null: false
6
+ t.string :filename, null: false
7
+ t.string :content_type
8
+ t.text :metadata
9
+ t.bigint :byte_size, null: false
10
+ t.string :checksum, null: false
11
+ t.datetime :created_at, null: false
12
+
13
+ t.index [:key], unique: true
14
+ end
15
+
16
+ create_table :active_storage_attachments do |t|
17
+ t.string :name, null: false
18
+ t.references :record, null: false, polymorphic: true, index: false
19
+ t.references :blob, null: false
20
+
21
+ t.datetime :created_at, null: false
22
+
23
+ t.index [:record_type, :record_id, :name, :blob_id], name: "index_active_storage_attachments_uniqueness", unique: true
24
+ t.foreign_key :active_storage_blobs, column: :blob_id
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Renalware
4
- VERSION = "2.0.67"
4
+ VERSION = "2.0.68"
5
5
  end
@@ -1,5 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  FactoryBot.define do
4
- factory :hd_patient, class: "Renalware::HD::Patient", parent: :patient
4
+ factory :hd_patient, class: "Renalware::HD::Patient", parent: :patient do
5
+ trait :with_hd_modality do
6
+ after(:create) do |instance|
7
+ # This a rather clumsy approach to trying to re-use the set_modality helper
8
+ # in PatientsSpecHelper; we can't include the module here so I am creating
9
+ # a contrived class so I can mix in PatientsSpecHelper.
10
+ # Other options here
11
+ # https://github.com/thoughtbot/factory_bot/issues/564#issuecomment-157669866
12
+ class ModalityMaker
13
+ include PatientsSpecHelper
14
+
15
+ def call(patient)
16
+ set_modality(
17
+ patient: patient,
18
+ modality_description: FactoryBot.create(:hd_modality_description),
19
+ by: patient.created_by
20
+ )
21
+ end
22
+ end
23
+ ModalityMaker.new.call(instance)
24
+ end
25
+ end
26
+ end
5
27
  end
@@ -2,6 +2,9 @@
2
2
 
3
3
  FactoryBot.define do
4
4
  factory :pd_modality_description, class: "Renalware::PD::ModalityDescription" do
5
+ initialize_with do
6
+ Renalware::PD::ModalityDescription.find_or_create_by!(name: name)
7
+ end
5
8
  name { "PD" }
6
9
  end
7
10
  end
@@ -1,5 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  FactoryBot.define do
4
- factory :pd_patient, class: "Renalware::PD::Patient", parent: :patient
4
+ factory :pd_patient, class: "Renalware::PD::Patient", parent: :patient do
5
+ trait :with_pd_modality do
6
+ after(:create) do |instance|
7
+ # This a rather clumsy approach to trying to re-use the set_modality helper
8
+ # in PatientsSpecHelper; we can't include the module here so I am creating
9
+ # a contrived class so I can mix in PatientsSpecHelper.
10
+ # Other options here
11
+ # https://github.com/thoughtbot/factory_bot/issues/564#issuecomment-157669866
12
+ class ModalityMaker
13
+ include PatientsSpecHelper
14
+
15
+ def call(patient)
16
+ set_modality(
17
+ patient: patient,
18
+ modality_description: FactoryBot.create(:pd_modality_description),
19
+ by: patient.created_by
20
+ )
21
+ end
22
+ end
23
+ ModalityMaker.new.call(instance)
24
+ end
25
+ end
26
+ end
5
27
  end
@@ -8,6 +8,9 @@ RSpec.configure do |config|
8
8
  config.include LoginMacros, type: :controller
9
9
 
10
10
  config.include Warden::Test::Helpers, type: :feature
11
+ config.include Warden::Test::Helpers, type: :system
12
+ config.include Devise::Test::IntegrationHelpers, type: :system
13
+ config.include LoginMacros, type: :system
11
14
  config.include LoginMacros, type: :feature
12
15
 
13
16
  config.include Warden::Test::Helpers, type: :request
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renalware-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.67
4
+ version: 2.0.68
5
5
  platform: ruby
6
6
  authors:
7
7
  - Airslie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-02 00:00:00.000000000 Z
11
+ date: 2019-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_type
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.27.0
33
+ version: 0.28.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.27.0
40
+ version: 0.28.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: ahoy_matey
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -282,14 +282,14 @@ dependencies:
282
282
  requirements:
283
283
  - - "~>"
284
284
  - !ruby/object:Gem::Version
285
- version: 5.3.1
285
+ version: 5.6.1
286
286
  type: :runtime
287
287
  prerelease: false
288
288
  version_requirements: !ruby/object:Gem::Requirement
289
289
  requirements:
290
290
  - - "~>"
291
291
  - !ruby/object:Gem::Version
292
- version: 5.3.1
292
+ version: 5.6.1
293
293
  - !ruby/object:Gem::Dependency
294
294
  name: foundation-rails
295
295
  requirement: !ruby/object:Gem::Requirement
@@ -310,14 +310,14 @@ dependencies:
310
310
  requirements:
311
311
  - - "~>"
312
312
  - !ruby/object:Gem::Version
313
- version: 5.2.3
313
+ version: 5.2.5
314
314
  type: :runtime
315
315
  prerelease: false
316
316
  version_requirements: !ruby/object:Gem::Requirement
317
317
  requirements:
318
318
  - - "~>"
319
319
  - !ruby/object:Gem::Version
320
- version: 5.2.3
320
+ version: 5.2.5
321
321
  - !ruby/object:Gem::Dependency
322
322
  name: hashdiff
323
323
  requirement: !ruby/object:Gem::Requirement
@@ -758,14 +758,14 @@ dependencies:
758
758
  requirements:
759
759
  - - "~>"
760
760
  - !ruby/object:Gem::Version
761
- version: 2.0.1
761
+ version: 2.0.5
762
762
  type: :runtime
763
763
  prerelease: false
764
764
  version_requirements: !ruby/object:Gem::Requirement
765
765
  requirements:
766
766
  - - "~>"
767
767
  - !ruby/object:Gem::Version
768
- version: 2.0.1
768
+ version: 2.0.5
769
769
  - !ruby/object:Gem::Dependency
770
770
  name: slim-rails
771
771
  requirement: !ruby/object:Gem::Requirement
@@ -986,7 +986,6 @@ files:
986
986
  - app/assets/javascripts/renalware/problems.js
987
987
  - app/assets/javascripts/renalware/renal.js
988
988
  - app/assets/javascripts/renalware/reporting.js.erb
989
- - app/assets/javascripts/renalware/research.js
990
989
  - app/assets/javascripts/renalware/searchables.js
991
990
  - app/assets/javascripts/renalware/select2-ajax-search.js
992
991
  - app/assets/javascripts/renalware/session_timeout_redirect.js.erb
@@ -2240,6 +2239,7 @@ files:
2240
2239
  - app/views/renalware/hd/mdm_patients/_filters.html.slim
2241
2240
  - app/views/renalware/hd/mdm_patients/_patient.html.slim
2242
2241
  - app/views/renalware/hd/mdm_patients/_table.html.slim
2242
+ - app/views/renalware/hd/mdm_patients/_tabs.html.slim
2243
2243
  - app/views/renalware/hd/mdm_patients/index.html.slim
2244
2244
  - app/views/renalware/hd/ongoing_sessions/_filters.html.slim
2245
2245
  - app/views/renalware/hd/ongoing_sessions/_session.html.slim
@@ -2587,6 +2587,7 @@ files:
2587
2587
  - app/views/renalware/pd/infection_organisms/update.js.erb
2588
2588
  - app/views/renalware/pd/mdm/_summary.html.slim
2589
2589
  - app/views/renalware/pd/mdm/_top.html.slim
2590
+ - app/views/renalware/pd/mdm_patients/_tabs.html.slim
2590
2591
  - app/views/renalware/pd/peritonitis_episodes/_details.html.slim
2591
2592
  - app/views/renalware/pd/peritonitis_episodes/_fields.html.slim
2592
2593
  - app/views/renalware/pd/peritonitis_episodes/_form.html.slim
@@ -2663,6 +2664,7 @@ files:
2663
2664
  - app/views/renalware/research/_alerts.html.slim
2664
2665
  - app/views/renalware/research/studies/_filters.html.slim
2665
2666
  - app/views/renalware/research/studies/_form.html.slim
2667
+ - app/views/renalware/research/studies/_tabs.html.slim
2666
2668
  - app/views/renalware/research/studies/edit.html.slim
2667
2669
  - app/views/renalware/research/studies/index.html.slim
2668
2670
  - app/views/renalware/research/studies/new.html.slim
@@ -2670,12 +2672,9 @@ files:
2670
2672
  - app/views/renalware/research/study_participants/_filters.html.slim
2671
2673
  - app/views/renalware/research/study_participants/_form.html.slim
2672
2674
  - app/views/renalware/research/study_participants/_table.html.slim
2673
- - app/views/renalware/research/study_participants/create.js.erb
2674
2675
  - app/views/renalware/research/study_participants/edit.html.slim
2675
2676
  - app/views/renalware/research/study_participants/index.html.slim
2676
2677
  - app/views/renalware/research/study_participants/new.html.slim
2677
- - app/views/renalware/research/study_participants/new.js.erb
2678
- - app/views/renalware/research/study_participants/update.js.erb
2679
2678
  - app/views/renalware/shared/_attributes_group.html.slim
2680
2679
  - app/views/renalware/shared/_attributes_list.html.slim
2681
2680
  - app/views/renalware/shared/_error_messages.html.slim
@@ -3384,6 +3383,7 @@ files:
3384
3383
  - db/migrate/20181126090401_add_warnings_to_hd_transmission_logs.rb
3385
3384
  - db/migrate/20181126123745_refresh_hd_grouped_transmission_logs_view.rb
3386
3385
  - db/migrate/20181217124025_change_ukrdc_transmission_log_error_type.rb
3386
+ - db/migrate/20190104095254_create_active_storage_tables.active_storage.rb
3387
3387
  - db/seeds.rb
3388
3388
  - db/seeds/default/accesses/access_pd_catheter_insertion_techniques.csv
3389
3389
  - db/seeds/default/accesses/access_pd_catheter_insertion_techniques.rb
@@ -3705,7 +3705,6 @@ files:
3705
3705
  - spec/factories/transplants/registrations.rb
3706
3706
  - spec/factories/virology/patients.rb
3707
3707
  - spec/factories/virology/vaccinations.rb
3708
- - spec/support/capybara.rb
3709
3708
  - spec/support/capybara_helper.rb
3710
3709
  - spec/support/database_functions_spec_helper.rb
3711
3710
  - spec/support/date_helpers.rb
@@ -3726,7 +3725,6 @@ files:
3726
3725
  - spec/support/patients_spec_helper.rb
3727
3726
  - spec/support/pundit_matcher.rb
3728
3727
  - spec/support/roles_spec_helper.rb
3729
- - spec/support/select2_spec_helper.rb
3730
3728
  - spec/support/select_date_spec_helper.rb
3731
3729
  - spec/support/shared_contexts/a_global_rule_set.rb
3732
3730
  - spec/support/shared_examples/accountable_examples.rb
@@ -1,18 +0,0 @@
1
- var Renalware = typeof Renalware === 'undefined' ? {} : Renalware;
2
-
3
- Renalware.Research = (function() {
4
- var focusPatientInput = function() {
5
- $('.patient-ajax-search').select2('open');
6
- $('select2-patient-ajax-search-container .select2-search__field').focus();
7
- };
8
-
9
- return {
10
- init: function () {
11
- initDatepickersIn(".modal");
12
- Renalware.PatientSearch.init();
13
- focusPatientInput();
14
- }
15
- };
16
- }());
17
-
18
- $(document).on('opened.fndtn.reveal', '#study-participant-modal', Renalware.Research.init);
@@ -1,3 +0,0 @@
1
- <%= refresh(".flash-message", partial: "renalware/shared/flash_messages", locals: local_assigns) %>
2
- $(".study-participants-table").replaceWith("<%= j(render 'table', **local_assigns) %>");
3
- $("#study-participant-modal").foundation('reveal', 'close');
@@ -1,4 +0,0 @@
1
- // We render this view if there was a validation error submitting the foundation reveal modal.
2
- // Replace the original content so that error messages are displayed.
3
- var modal = $("#study-participant-modal")
4
- $(modal).html("<%= j(render 'form', participant: participant) %>");
@@ -1,3 +0,0 @@
1
- <%= refresh(".flash-message", partial: "renalware/shared/flash_messages", locals: local_assigns) %>
2
- $(".study-participants-table").replaceWith("<%= j(render 'table', **local_assigns) %>");
3
- $("#study-participant-modal").foundation('reveal', 'close');
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # # frozen_string_literal: true
4
- if defined?(Capybara)
5
- Capybara.register_driver(:headless_chrome) do |app|
6
- capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
7
- chromeOptions: { args: %w(headless disable-gpu window-size=1366,1768) }
8
- )
9
-
10
- Capybara::Selenium::Driver.new(
11
- app,
12
- browser: :chrome,
13
- desired_capabilities: capabilities
14
- )
15
- end
16
-
17
- if RUBY_PLATFORM.match?(/darwin/)
18
- Capybara::Screenshot.register_driver(:headless_chrome) do |driver, path|
19
- driver.browser.save_screenshot(path)
20
- end
21
- end
22
- Capybara.javascript_driver = :headless_chrome
23
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Select2SpecHelper
4
- def select2(value, opts)
5
- scope = opts[:from]
6
- select2_container = first("#{scope} + .select2-container")
7
- select2_container.first(".select2-selection").click
8
-
9
- first("input.select2-search__field").set(value)
10
- page.execute_script(%|$("#{scope} ~ input.select2-search__field:visible").keyup();|)
11
- body = find(:xpath, "//body")
12
- matches = body.find_all(".select2-results li", text: value)
13
- matches.last.click
14
- end
15
-
16
- # select2_ajax helper to make capybara work with ajax-enabled Select2 elements
17
- # assumes 'placeholder' option is used in Select2 (if it is using ajax, it should be)
18
- #
19
- # usage:
20
- #
21
- # it "should have a select2 field for searching by team name" do
22
- # @team = Factory :team
23
- # select2_ajax @team.name, from: "Select a Team", minlength: 4
24
- # click_button "Join"
25
- # page.should have_content "You are now on '#{@team.name}'."
26
- # end
27
- # Thx to https://gist.github.com/sbeam/3849340
28
- def select2_ajax(value, options = {})
29
- if !options.is_a?(Hash) || !options.key?(:from)
30
- raise "Must pass a hash containing 'from'"
31
- end
32
-
33
- placeholder = options[:from]
34
- minlength = options[:minlength] || 4
35
-
36
- # click_link placeholder
37
-
38
- page.find(:xpath, "//*[text()='#{placeholder}']").click
39
-
40
- js = %Q|container = $('.select2-container:contains("#{placeholder}")');
41
- $('input[type=text]', container).val('#{value[0, minlength]}').trigger('keyup');
42
- window.setTimeout( function() {
43
- $('li:contains("#{value}")', container).click();
44
- }, 5000);|
45
- page.execute_script(js)
46
- end
47
- end