renalware-core 2.0.132 → 2.0.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/renalware/core.js.erb +1 -1
  3. data/app/assets/stylesheets/renalware/core.scss +1 -1
  4. data/app/assets/stylesheets/renalware/modules/_clinics.scss +1 -2
  5. data/app/assets/stylesheets/renalware/modules/_patients.scss +1 -1
  6. data/app/assets/stylesheets/renalware/partials/_dashboards.scss +15 -0
  7. data/app/components/renalware/application_component.rb +22 -0
  8. data/app/components/renalware/events/biopsies_component.html.slim +14 -0
  9. data/app/components/renalware/events/biopsies_component.rb +20 -0
  10. data/app/components/renalware/letters/letters_in_progress_component.html.slim +8 -0
  11. data/app/components/renalware/letters/letters_in_progress_component.rb +32 -0
  12. data/app/components/renalware/letters/unread_electronic_ccs_component.html.slim +7 -0
  13. data/app/components/renalware/letters/unread_electronic_ccs_component.rb +24 -0
  14. data/app/components/renalware/messaging/unread_messages_component.html.slim +11 -0
  15. data/app/components/renalware/messaging/unread_messages_component.rb +24 -0
  16. data/app/components/renalware/patients/bookmarks_component.html.slim +11 -0
  17. data/app/components/renalware/patients/bookmarks_component.rb +22 -0
  18. data/app/controllers/renalware/clinical/body_compositions_controller.rb +1 -1
  19. data/app/controllers/renalware/pathology/code_groups_controller.rb +44 -0
  20. data/app/controllers/renalware/transplants/wait_lists_controller.rb +17 -8
  21. data/app/models/renalware/clinical/body_composition.rb +7 -0
  22. data/app/models/renalware/hd/mdm_patients_query.rb +10 -1
  23. data/app/models/renalware/pathology/code_group.rb +10 -3
  24. data/app/models/renalware/pathology/code_group_membership.rb +2 -0
  25. data/app/models/renalware/pathology/current_observation_set.rb +16 -3
  26. data/app/models/renalware/pathology/observations_jsonb_serializer.rb +1 -1
  27. data/app/models/renalware/pathology/version.rb +11 -0
  28. data/app/models/renalware/system/component.rb +25 -0
  29. data/app/models/renalware/system/dashboard.rb +20 -0
  30. data/app/models/renalware/system/dashboard_component.rb +17 -0
  31. data/app/models/renalware/transplants.rb +8 -1
  32. data/app/models/renalware/transplants/registrations/wait_list_form.rb +16 -0
  33. data/app/models/renalware/transplants/registrations/wait_list_query.rb +17 -3
  34. data/app/models/renalware/ukrdc/incoming/file_list.rb +1 -1
  35. data/app/models/renalware/ukrdc/incoming/import_surveys.rb +16 -0
  36. data/app/models/renalware/ukrdc/outgoing/rendering/base.rb +22 -0
  37. data/app/models/renalware/ukrdc/outgoing/rendering/dialysis_session.rb +2 -2
  38. data/app/models/renalware/ukrdc/outgoing/rendering/hd_session_observations.rb +1 -1
  39. data/app/models/renalware/user.rb +9 -0
  40. data/app/policies/renalware/hd/closed_session_policy.rb +1 -1
  41. data/app/policies/renalware/pathology/code_group_policy.rb +23 -0
  42. data/app/presenters/renalware/hd/protocol_presenter.rb +8 -2
  43. data/app/views/renalware/clinical/body_compositions/_form.html.slim +6 -0
  44. data/app/views/renalware/clinical/body_compositions/_table.html.slim +4 -0
  45. data/app/views/renalware/dashboard/bookmarks/_bookmark.html.slim +5 -5
  46. data/app/views/renalware/dashboard/bookmarks/_table.html.slim +5 -5
  47. data/app/views/renalware/dashboard/dashboards/_content.html.slim +4 -41
  48. data/app/views/renalware/dashboard/letters/_letter.html.slim +2 -2
  49. data/app/views/renalware/hd/mdm_patients/_patient.html.slim +5 -1
  50. data/app/views/renalware/hd/mdm_patients/_table.html.slim +2 -1
  51. data/app/views/renalware/hd/protocols/_recent_pathology.html.slim +5 -12
  52. data/app/views/renalware/mdm/{_biopsies.html.slim → _biopsies.html.slim.dead} +0 -0
  53. data/app/views/renalware/mdm_patients/_patient.html.slim +5 -1
  54. data/app/views/renalware/mdm_patients/_table.html.slim +1 -1
  55. data/app/views/renalware/medications/prescriptions/_tables.html.slim +27 -23
  56. data/app/views/renalware/messaging/internal/receipts/_receipt.html.slim +1 -1
  57. data/app/views/renalware/modalities/modalities/index.html.slim +17 -16
  58. data/app/views/renalware/navigation/_super_admin.html.slim +1 -0
  59. data/app/views/renalware/pathology/code_groups/edit.html.slim +8 -0
  60. data/app/views/renalware/pathology/code_groups/index.html.slim +16 -0
  61. data/app/views/renalware/pathology/code_groups/show.html.slim +34 -0
  62. data/app/views/renalware/problems/problems/index.html.slim +9 -5
  63. data/app/views/renalware/surveys/_eq5d_summary_part.html.slim +17 -17
  64. data/app/views/renalware/surveys/_pos_s_summary_part.html.slim +61 -60
  65. data/app/views/renalware/transplants/mdm/_bottom.html.slim +1 -1
  66. data/app/views/renalware/transplants/mdm_patients/_patient.html.slim +5 -1
  67. data/app/views/renalware/transplants/mdm_patients/_table.html.slim +1 -1
  68. data/app/views/renalware/transplants/wait_lists/_registration.html.slim +1 -0
  69. data/app/views/renalware/transplants/wait_lists/show.html.slim +24 -1
  70. data/config/locales/renalware/clinical/body_composition.yml +4 -0
  71. data/config/routes/pathology.rb +1 -0
  72. data/db/migrate/20200114151225_add_clinical_body_composition_cols.rb +11 -0
  73. data/db/migrate/20200127165951_create_pathology_versions.rb +16 -0
  74. data/db/migrate/20200127170711_add_created_by_to_pathology_code_groups.rb +15 -0
  75. data/db/migrate/20200129093835_create_system_dashboards.rb +73 -0
  76. data/db/seeds/default/pathology/code_groups.rb +15 -0
  77. data/db/seeds/default/pathology/seeds.rb +2 -1
  78. data/lib/core_extensions/active_record/migration_helpers.rb +3 -2
  79. data/lib/renalware/engine.rb +1 -1
  80. data/lib/renalware/version.rb +1 -1
  81. data/lib/tasks/spec.rake +23 -21
  82. data/spec/factories/clinical/body_compositions.rb +3 -1
  83. data/spec/factories/pathology/code_group_memberships.rb +7 -0
  84. data/spec/factories/pathology/code_groups.rb +13 -0
  85. data/spec/factories/transplants/registration_status_descriptions.rb +5 -0
  86. data/spec/support/devise_spec_helper.rb +24 -8
  87. data/spec/support/ukrdc_helpers.rb +2 -1
  88. metadata +53 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f670bf5df7603c7132365ac119ae9f6bdbb43dde12a24a04d3d015b5a694626c
4
- data.tar.gz: 0a8dde1dd0be593ee8483e01f8128e31f544a1c6eed362fe8fd263e78fd78684
3
+ metadata.gz: 958097e494920445885eb75809fb828e40462d27b0b65ed48e3aab2e0c0d8cc8
4
+ data.tar.gz: 935763fcf2fae4e1a76c2b2fca9e5f3b48b0a7d457b971a65b9c913864ef0024
5
5
  SHA512:
6
- metadata.gz: dc8e11f2b13664bddaabdef7d8bede3f1e2a14bc63862b703a628ad3f8fd6019bcb6d285fd40a81bdd530417ce5c46cbfc8ba8f6a61d5901b7e8523ca783b6a6
7
- data.tar.gz: 5d77baac6abc4e238faa59e4147948315beed80cf363fac2b8c6cb88436b44ff8898a668ef71a3c81a5ccc3e8ca520f596a1919a242275c4540128431f7fa46d
6
+ metadata.gz: b0749b3a7697bcec528d027e5660f89992490fe516e981900bcdfd2560ccffafe08d27229b9ac46257a4de9a3547f90d4fd737091e53e8251adc8e328c63ae97
7
+ data.tar.gz: 95f5b2ab947a8d66e3e6072dda55aeba46bdb441fded424a7c7aaa09a2e6c5a4227f126edf32315270bba351d838e85c9a645740cc2fdde9a241a136cc7e1c75
@@ -32,7 +32,7 @@
32
32
  //= require underscore/underscore
33
33
  //= require select2/dist/js/select2
34
34
  //= require jquery_nested_form
35
- //= require foundation-datepicker
35
+ //= require foundation-datepicker/js/foundation-datepicker
36
36
  //= require renalware/double_scroll
37
37
  //= require cocoon
38
38
  //= require mousetrap/mousetrap
@@ -7,7 +7,7 @@
7
7
 
8
8
  @import "font-awesome-sprockets";
9
9
  @import "font-awesome";
10
- @import "foundation-datepicker";
10
+ @import "foundation-datepicker/css/foundation-datepicker";
11
11
  @import "dataTables/jquery.dataTables.foundation";
12
12
  @import "trix";
13
13
  @import "balloon-css/src/balloon";
@@ -1,5 +1,4 @@
1
- .page--visits {
2
-
1
+ .page--clinics-visits {
3
2
  .filters__output {
4
3
  display: none;
5
4
  }
@@ -353,7 +353,7 @@ form {
353
353
  }
354
354
  }
355
355
 
356
- .page--clinical_summaries {
356
+ .page--patients-clinical_summaries {
357
357
  .summary-part--letters {
358
358
  @include grid-column(12);
359
359
  }
@@ -0,0 +1,15 @@
1
+ @media only screen and (min-width: 830px) {
2
+ // Add body page--* classes to give them, the dashboard look.
3
+ body.page--dashboard-dashboards {
4
+ .main-content {
5
+ background-color: #E8EDEE;
6
+ }
7
+
8
+ article {
9
+ background-color: #fff;
10
+ padding: 0.3rem .5rem .5rem;
11
+ border-top-width: 2px;
12
+ border-top-color: $nhs-bright-blue;
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ class ApplicationComponent < ActionView::Component::Base
5
+ include Renalware::Engine.routes.url_helpers
6
+ include Pundit::Helper
7
+
8
+ # Not sure why include Renalware::Engine.routes.url_helpers does not make the
9
+ # engine urls visible in the views (seems to resolve alwatys to /assets?..)
10
+ # so we expose routes here so inside a component html file we can use
11
+ # e.g. renalware.bookmarks_path
12
+ def renalware
13
+ Renalware::Engine.routes.url_helpers
14
+ end
15
+
16
+ # Added this helper as I can't seem to get the Pundit #policy helper to be included
17
+ # in the context when renderingt a component template.
18
+ def policy(record)
19
+ current_user && Pundit.policy(current_user, record)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ article.events
2
+ header
3
+ h2 Biopsies
4
+ .supplemental
5
+ span= "#{biopsies.length} of #{total_biopsies}"
6
+ span.noprint
7
+ = link_to "View All",
8
+ renalware.patient_events_path(patient),
9
+ class: "button secondary"
10
+
11
+ = render "renalware/events/events/table",
12
+ events: biopsies,
13
+ exclude_type_column: true,
14
+ toggle_prefix: "biopsy"
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Events
5
+ class BiopsiesComponent < ApplicationComponent
6
+ validates :patient, presence: true
7
+
8
+ def initialize(patient:, limit: 6)
9
+ @patient = patient
10
+ relation = Biopsy.for_patient(patient).includes(:created_by)
11
+ @biopsies = relation.limit(limit).ordered
12
+ @total_biopsies = relation.count
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :patient, :biopsies, :total_biopsies
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ article.letters
2
+ header
3
+ h2 Letters in Progress
4
+ - if letters_in_progress.any?
5
+ #letters-in-progress
6
+ = render "renalware/dashboard/letters/table", letters: letters_in_progress
7
+ - else
8
+ p.empty-section Letters in Progress
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Letters
5
+ class LettersInProgressComponent < ApplicationComponent
6
+ attr_reader :current_user
7
+
8
+ def initialize(current_user:)
9
+ @current_user = current_user
10
+ end
11
+
12
+ # Note we want oldest letters ordered first here - elsewhere letters are newest first
13
+ def letters_in_progress
14
+ @letters_in_progress ||= begin
15
+ present_letters(
16
+ Letters::Letter
17
+ .reversed
18
+ .where("author_id = ? or created_by_id = ?", current_user.id, current_user.id)
19
+ .in_progress
20
+ .includes(:author, :patient, :letterhead)
21
+ )
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def present_letters(letters)
28
+ CollectionPresenter.new(letters, Letters::LetterPresenterFactory)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ article.electonic_ccs
2
+ header
3
+ h2 Electronic CCs
4
+ - if unread_electronic_ccs.any?
5
+ = render "renalware/letters/electronic_receipts/table", receipts: unread_electronic_ccs
6
+ - else
7
+ p.empty-section You have no electronic CCs.
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Letters
5
+ class UnreadElectronicCCsComponent < ApplicationComponent
6
+ attr_reader :current_user
7
+
8
+ def initialize(current_user:)
9
+ @current_user = current_user
10
+ end
11
+
12
+ def unread_electronic_ccs
13
+ @unread_electronic_ccs ||= begin
14
+ receipts = Letters::ElectronicReceipt
15
+ .includes(letter: [:patient, :author, :letterhead])
16
+ .unread
17
+ .for_recipient(current_user.id)
18
+ .order(created_at: :asc)
19
+ CollectionPresenter.new(receipts, Letters::ElectronicReceiptPresenter)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ article.messages
2
+ header
3
+ h2 Messages
4
+ ul
5
+ li= render "renalware/messaging/shared/key"
6
+ - if unread_message_receipts.any?
7
+ .unread-messages
8
+ = render "renalware/messaging/internal/receipts/table",
9
+ receipts: unread_message_receipts
10
+ - else
11
+ p.empty-section You have no messages.
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Messaging
5
+ class UnreadMessagesComponent < ApplicationComponent
6
+ attr_reader :current_user
7
+
8
+ def initialize(current_user:)
9
+ @current_user = Messaging::Internal.cast_recipient(current_user)
10
+ end
11
+
12
+ def unread_message_receipts
13
+ @unread_message_receipts ||= begin
14
+ receipts = current_user
15
+ .receipts
16
+ .includes(message: [:author, :patient])
17
+ .order("messaging_messages.sent_at asc")
18
+ .unread
19
+ CollectionPresenter.new(receipts, Messaging::Internal::ReceiptPresenter)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ article.bookmarks
2
+ header
3
+ h2.title= "Bookmarked Patients"
4
+ ul
5
+ li= link_to "View All", renalware.bookmarks_path, class: "button"
6
+
7
+ - if bookmarks.any?
8
+ #bookmarks
9
+ = render "renalware/dashboard/bookmarks/table", bookmarks: bookmarks
10
+ - else
11
+ p.empty-section= t(".bookmarks.none")
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Patients
5
+ class BookmarksComponent < ApplicationComponent
6
+ attr_reader :current_user
7
+
8
+ def initialize(current_user:)
9
+ @current_user = current_user
10
+ end
11
+
12
+ def bookmarks
13
+ @bookmarks ||= begin
14
+ Patients.cast_user(current_user)
15
+ .bookmarks
16
+ .ordered
17
+ .includes(patient: [current_modality: :description])
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -89,7 +89,7 @@ module Renalware
89
89
  :assessed_on, :overhydration, :volume_of_distribution, :total_body_water,
90
90
  :extracellular_water, :intracellular_water, :lean_tissue_index,
91
91
  :fat_tissue_index, :lean_tissue_mass, :fat_tissue_mass, :adipose_tissue_mass,
92
- :body_cell_mass, :quality_of_reading, :assessor_id, :notes
92
+ :body_cell_mass, :quality_of_reading, :assessor_id, :notes, :weight, :pre_post_hd
93
93
  ]
94
94
  end
95
95
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/pathology"
4
+
5
+ module Renalware
6
+ module Pathology
7
+ class CodeGroupsController < Pathology::BaseController
8
+ def index
9
+ groups = CodeGroup.order(:name)
10
+ authorize groups, :index?
11
+ render locals: { groups: groups }
12
+ end
13
+
14
+ def show
15
+ render locals: { group: find_authorize_group }
16
+ end
17
+
18
+ def edit
19
+ render locals: { group: find_authorize_group }
20
+ end
21
+
22
+ def update
23
+ group = find_authorize_group
24
+ if group.update_by(current_user, code_group_params)
25
+ redirect_to pathology_code_groups_path, notice: "Group saved"
26
+ else
27
+ render :edit, locals: { group: group }
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def find_authorize_group
34
+ CodeGroup.find(params[:id]).tap { |group| authorize group }
35
+ end
36
+
37
+ def code_group_params
38
+ params
39
+ .require(:code_group)
40
+ .permit(:description)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -7,30 +7,39 @@ module Renalware
7
7
  class WaitListsController < BaseController
8
8
  include Renalware::Concerns::Pageable
9
9
 
10
+ # Here we display a named filter eg Active and query for patients based on registration
11
+ # status and also any search criteria entered in the search form which is backed by our
12
+ # ransack #search object.
10
13
  def show
14
+ form = Registrations::WaitListForm.new(form_params)
15
+ query = query_for(form)
11
16
  registrations = query.call.page(page).per(per_page || 50)
12
17
  authorize registrations
13
18
  render locals: {
14
19
  path_params: path_params,
15
20
  registrations: CollectionPresenter.new(registrations, WaitListRegistrationPresenter),
16
- q: query.search
21
+ q: query.search,
22
+ form: form
17
23
  }
18
24
  end
19
25
 
20
26
  private
21
27
 
22
- def query
23
- @query ||= begin
24
- Registrations::WaitListQuery.new(
25
- named_filter: params[:named_filter],
26
- q: params[:q]
27
- )
28
- end
28
+ def query_for(form)
29
+ Registrations::WaitListQuery.new(
30
+ named_filter: params[:named_filter],
31
+ ukt_recipient_number: form.ukt_recipient_number,
32
+ q: params[:q]
33
+ )
29
34
  end
30
35
 
31
36
  def path_params
32
37
  params.permit([:controller, :action, :named_filter])
33
38
  end
39
+
40
+ def form_params
41
+ params.fetch(:form, {}).permit(:ukt_recipient_number)
42
+ end
34
43
  end
35
44
  end
36
45
  end
@@ -9,6 +9,12 @@ module Renalware
9
9
  include PatientScope
10
10
  include Accountable
11
11
 
12
+ # This maps to a PG enum
13
+ enum pre_post_hd: {
14
+ pre: "pre",
15
+ post: "post"
16
+ }
17
+
12
18
  belongs_to :patient, class_name: "Renalware::Clinical::Patient", touch: true
13
19
  belongs_to :assessor, class_name: "User", foreign_key: "assessor_id"
14
20
  belongs_to :modality_description, class_name: "Modalities::Description"
@@ -32,6 +38,7 @@ module Renalware
32
38
  validates :body_cell_mass, presence: true, numeric_inclusion: { in: 0..150 }
33
39
  validates :quality_of_reading, presence: true, numeric_inclusion: { in: 50..100 }
34
40
  validates :assessed_on, presence: true, timeliness: { type: :date, allow_blank: false }
41
+ validates :weight, "renalware/patients/weight" => true
35
42
  end
36
43
  end
37
44
  end
@@ -23,6 +23,15 @@ module Renalware
23
23
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
24
24
  def search
25
25
  @search ||= begin
26
+ nasty_join_sql_to_get_around_a_kaminari_count_issue = <<-SQL
27
+ inner join modality_modalities X1
28
+ on patients.id = X1.patient_id
29
+ and X1.state = 'current'
30
+ and X1.ended_on IS NULL
31
+ inner join modality_descriptions MD1
32
+ on MD1.id = X1.description_id
33
+ and MD1.code = 'hd'
34
+ SQL
26
35
  HD::Patient
27
36
  .include(QueryablePatient)
28
37
  .extending(PatientTransplantScopes)
@@ -34,7 +43,7 @@ module Renalware
34
43
  .extending(NamedFilterScopes)
35
44
  .with_current_pathology
36
45
  .with_registration_statuses
37
- .with_current_modality_of_class(Renalware::HD::ModalityDescription)
46
+ .joins(nasty_join_sql_to_get_around_a_kaminari_count_issue)
38
47
  .public_send(named_filter.to_s)
39
48
  .ransack(params)
40
49
  end
@@ -28,9 +28,14 @@ module Renalware
28
28
  # G.name,
29
29
  # M.subgroup,
30
30
  # M.position_within_subgroup;
31
-
32
31
  class CodeGroup < ApplicationRecord
32
+ include Accountable
33
+ has_paper_trail(
34
+ class_name: "Renalware::Pathology::Version",
35
+ on: [:create, :update, :destroy]
36
+ )
33
37
  validates :name, presence: true, uniqueness: true
38
+ validates :description, presence: true
34
39
  has_many(
35
40
  :memberships,
36
41
  class_name: "CodeGroupMembership",
@@ -42,8 +47,10 @@ module Renalware
42
47
  )
43
48
 
44
49
  def self.descriptions_for_group(name)
45
- CodeGroup
46
- .find_by!(name: name)
50
+ group = CodeGroup.find_by(name: name)
51
+ return [] if group.nil?
52
+
53
+ group
47
54
  .observation_descriptions
48
55
  .order(subgroup: :asc, position_within_subgroup: :asc)
49
56
  end