renalware-core 2.0.0.pre.rc10 → 2.0.0.pre.rc11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/renalware/modules/_dashboard.scss +12 -3
  3. data/app/assets/stylesheets/renalware/modules/_letters.scss +0 -6
  4. data/app/assets/stylesheets/renalware/modules/_pathology.scss +5 -0
  5. data/app/assets/stylesheets/renalware/modules/_patients.scss +24 -0
  6. data/app/assets/stylesheets/renalware/modules/_users.scss +36 -0
  7. data/app/controllers/renalware/admin/cache_controller.rb +17 -0
  8. data/app/controllers/renalware/admin/users_controller.rb +1 -0
  9. data/app/controllers/renalware/api/token_authenticated_api_controller.rb +25 -0
  10. data/app/controllers/renalware/api/v1/patients/patients_controller.rb +17 -0
  11. data/app/controllers/renalware/concerns/devise_controller_methods.rb +4 -1
  12. data/app/controllers/renalware/devise/sessions_controller.rb +0 -29
  13. data/app/controllers/renalware/pathology/historical_observation_results_controller.rb +8 -10
  14. data/app/controllers/renalware/pathology/recent_observation_results_controller.rb +8 -10
  15. data/app/controllers/renalware/renal/aki_alerts_controller.rb +6 -1
  16. data/app/controllers/renalware/reporting/audits_controller.rb +1 -1
  17. data/app/controllers/renalware/system/errors_controller.rb +3 -1
  18. data/app/controllers/renalware/transplants/wait_lists_controller.rb +12 -3
  19. data/app/models/renalware/admin.rb +4 -0
  20. data/app/models/renalware/api.rb +6 -0
  21. data/app/models/renalware/clinics/current_observations.rb +1 -0
  22. data/app/models/renalware/events/event_query.rb +1 -1
  23. data/app/models/renalware/feeds/hl7_message.rb +16 -1
  24. data/app/models/renalware/hd/mdm_patients_query.rb +1 -1
  25. data/app/models/renalware/letters/pdf_letter_cache.rb +5 -1
  26. data/app/models/renalware/medications/prescription.rb +1 -0
  27. data/app/models/renalware/pathology/create_observations_grouped_by_date_table.rb +39 -0
  28. data/app/models/renalware/pathology/observation.rb +1 -1
  29. data/app/models/renalware/pathology/observation_digest.rb +12 -0
  30. data/app/models/renalware/pathology/observation_requests_attributes_builder.rb +2 -1
  31. data/app/models/renalware/pathology/observations_grouped_by_date_query.rb +91 -0
  32. data/app/models/renalware/pathology/observations_grouped_by_date_table.rb +59 -0
  33. data/app/models/renalware/pd/mdm_patients_query.rb +3 -1
  34. data/app/models/renalware/renal/aki_alert.rb +1 -0
  35. data/app/models/renalware/reporting/audit.rb +2 -0
  36. data/app/models/renalware/system/update_user.rb +0 -1
  37. data/app/models/renalware/transplants/registrations/wait_list_query.rb +9 -5
  38. data/app/models/renalware/transplants.rb +2 -0
  39. data/app/models/renalware/user.rb +26 -8
  40. data/app/policies/renalware/admin/cache_policy.rb +15 -0
  41. data/app/presenters/renalware/admin/users/summary_part.rb +23 -0
  42. data/app/presenters/renalware/events/summary_part.rb +15 -8
  43. data/app/presenters/renalware/hd/mdm_presenter.rb +1 -1
  44. data/app/presenters/renalware/letters/summary_part.rb +4 -4
  45. data/app/presenters/renalware/mdm_presenter.rb +18 -9
  46. data/app/presenters/renalware/pathology/historical_observation_results/html_table_view.rb +15 -1
  47. data/app/presenters/renalware/problems/summary_part.rb +4 -6
  48. data/app/presenters/renalware/summary_part.rb +5 -4
  49. data/app/views/renalware/admin/cache/show.html.slim +20 -0
  50. data/app/views/renalware/admin/feeds/files/index.html.slim +0 -1
  51. data/app/views/renalware/admin/users/_summary_part.html.slim +3 -0
  52. data/app/views/renalware/admin/users/index.html.slim +25 -8
  53. data/app/views/renalware/admissions/_summary_part.html.slim +11 -12
  54. data/app/views/renalware/api/v1/patients/patients/show.json.jbuilder +17 -0
  55. data/app/views/renalware/dashboard/dashboards/_content.html.slim +3 -0
  56. data/app/views/renalware/devise/registrations/edit.html.slim +2 -0
  57. data/app/views/renalware/events/events/_summary_part.html.slim +4 -5
  58. data/app/views/renalware/letters/_summary_part.html.slim +15 -14
  59. data/app/views/renalware/letters/letters/_table.html.slim +2 -1
  60. data/app/views/renalware/mdm/_pathology.html.slim +4 -2
  61. data/app/views/renalware/medications/_summary_part.html.slim +1 -1
  62. data/app/views/renalware/navigation/_renal.html.slim +1 -1
  63. data/app/views/renalware/navigation/_renalware_admin.html.slim +1 -0
  64. data/app/views/renalware/pathology/_navigation.html.slim +1 -1
  65. data/app/views/renalware/pathology/historical_observation_results/_table.html.slim +13 -0
  66. data/app/views/renalware/pathology/historical_observation_results/index.html.slim +3 -3
  67. data/app/views/renalware/pathology/observation_requests/_table.html.slim +1 -1
  68. data/app/views/renalware/pathology/recent_observation_results/_table.html.slim +18 -0
  69. data/app/views/renalware/pathology/recent_observation_results/index.html.slim +3 -3
  70. data/app/views/renalware/patients/clinical_summaries/show.html.slim +7 -4
  71. data/app/views/renalware/patients/side_menu/_actions.html.slim +26 -21
  72. data/app/views/renalware/problems/problems/_problem.html.slim +3 -0
  73. data/app/views/renalware/problems/problems/_summary_part.html.slim +16 -5
  74. data/app/views/renalware/renal/aki_alerts/edit.html.slim +4 -0
  75. data/app/views/renalware/renal/aki_alerts/index.html.slim +8 -0
  76. data/app/views/renalware/transplants/mdm/_pathology_cmvdna.html.slim +3 -1
  77. data/app/views/renalware/transplants/wait_lists/show.html.slim +2 -2
  78. data/config/initializers/inflections.rb +1 -0
  79. data/config/locales/renalware/mdm.yml +2 -2
  80. data/config/locales/renalware/renal/aki_alerts.en.yml +4 -0
  81. data/config/routes.rb +22 -5
  82. data/config/{schedule.rb → schedule.rb.example} +0 -0
  83. data/db/functions/update_current_observation_set_from_trigger_v03.sql +93 -0
  84. data/db/functions/update_current_observation_set_from_trigger_v04.sql +93 -0
  85. data/db/migrate/20180202184954_create_view_pathology_observation_digests.rb +5 -0
  86. data/db/migrate/20180206225525_update_fn_update_current_observation_set_from_trigger.rb +9 -0
  87. data/db/migrate/20180208150629_add_authentication_token_to_users.rb +5 -0
  88. data/db/migrate/20180213124203_add_cancelled_to_pathology_observations.rb +9 -0
  89. data/db/migrate/20180213125734_update_fn_update_current_obs_set_trgger.rb +9 -0
  90. data/db/migrate/20180214124317_add_cols_to_aki_alerts.rb +9 -0
  91. data/db/migrate/20180216132741_disable_some_audits.rb +8 -0
  92. data/db/seeds/default/transplants/transplant_donor_stages.rb +2 -2
  93. data/db/views/pathology_observation_digests_v01.sql +20 -0
  94. data/lib/renalware/version.rb +1 -1
  95. data/spec/factories/pathology/observation_requests.rb +31 -0
  96. data/spec/support/login_macros.rb +4 -2
  97. metadata +37 -9
@@ -0,0 +1,59 @@
1
+ require_dependency "renalware/pathology"
2
+ require "attr_extras"
3
+
4
+ module Renalware
5
+ module Pathology
6
+ # A helper class wrapping a custom relation object which has aggregated a
7
+ # patient's pathology results by date of observation using raw SQL + PGResult.
8
+ # Note we implement the required interface for kaminari pagination (we delegate to the
9
+ # underlying relation to achieve this).
10
+ #
11
+ # This class exists to make the underlying PGResult set (wrapped in a custom relation-like
12
+ # object) easier to consume.
13
+ #
14
+ # Example usage:
15
+ # (ruby)
16
+ # codes = %i(HGB PLT WBC)
17
+ # rows = ObservationsGroupedByDateQuery.new(patient_id: 1, codes: codes)
18
+ # table = ObservationsGroupedByDateTable.new(rows: rows, codes: %i(HGB PLT WBC))
19
+ # (html)
20
+ # table
21
+ # tr
22
+ # td Date
23
+ # - table.codes do |code|
24
+ # td= code
25
+ # tbody
26
+ # tr
27
+ # - table.each_row do |row|
28
+ # td= l(row.observed_on)
29
+ # - table.codes.each do |code|
30
+ # td= row.result_for(code)
31
+ #
32
+ # = paginate(table)
33
+ #
34
+ class ObservationsGroupedByDateTable
35
+ attr_reader_initialize [:observation_descriptions!, :relation!]
36
+ delegate :current_page, :total_pages, :limit_value, to: :relation
37
+
38
+ def rows
39
+ @rows ||= relation.all.map(&:with_indifferent_access).map { |row| Row.new(row) }
40
+ end
41
+
42
+ class Row
43
+ pattr_initialize :row
44
+
45
+ def observed_on
46
+ Date.parse(row[:observed_on])
47
+ end
48
+
49
+ def result_for(code)
50
+ results[code&.to_sym]
51
+ end
52
+
53
+ def results
54
+ @results = JSON.parse(row[:results]).with_indifferent_access
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -4,10 +4,12 @@ module Renalware
4
4
  include ModalityScopes
5
5
  include PatientPathologyScopes
6
6
  MODALITY_NAMES = "PD".freeze
7
+ DEFAULT_SEARCH_PREDICATE = "hgb_date desc".freeze
7
8
  attr_reader :q, :relation
8
9
 
9
10
  def initialize(relation: PD::Patient.all, q:)
10
- @q = q
11
+ @q = q || {}
12
+ @q[:s] = DEFAULT_SEARCH_PREDICATE if @q[:s].blank?
11
13
  @relation = relation
12
14
  end
13
15
 
@@ -9,6 +9,7 @@ module Renalware
9
9
  belongs_to :action, class_name: "Renal::AKIAlertAction"
10
10
  belongs_to :hospital_ward, class_name: "Hospitals::Ward"
11
11
  validates :patient, presence: true
12
+ validates :max_aki, inclusion: 1..3, allow_nil: true
12
13
  alias_attribute :decided_by, :updated_by
13
14
  end
14
15
  end
@@ -6,6 +6,8 @@ module Renalware
6
6
  validates :name, presence: true
7
7
  validates :view_name, presence: true
8
8
 
9
+ scope :enabled, ->{ where(enabled: true) }
10
+
9
11
  def self.available_audit_materialized_views
10
12
  result = connection.execute("SELECT oid::regclass::text FROM pg_class
11
13
  WHERE relkind in ('m', 'v') and relname like 'reporting_%';")
@@ -21,7 +21,6 @@ module Renalware
21
21
 
22
22
  def update!(params)
23
23
  User.transaction do
24
- user.skip_validation = true
25
24
  approve if can_approve?(params)
26
25
  unexpire if can_unexpire?(params)
27
26
  authorise(params)
@@ -1,22 +1,24 @@
1
+ require_dependency "renalware/transplants"
2
+
1
3
  module Renalware
2
4
  module Transplants
3
5
  module Registrations
4
6
  class WaitListQuery
5
- def initialize(quick_filter:, q: nil)
6
- @quick_filter = quick_filter.to_sym
7
- @q = q || {}
7
+ def initialize(named_filter:, q: nil)
8
+ @named_filter = named_filter&.to_sym || :active
9
+ @q = (q || ActionController::Parameters.new).permit(:s, :q)
8
10
  end
9
11
 
10
12
  def call
11
13
  search
12
14
  .result
13
15
  .extending(Scopes)
14
- .apply_filter(@quick_filter)
16
+ .apply_filter(named_filter)
15
17
  end
16
18
 
17
19
  def search
18
20
  @search ||= begin
19
- query = query_for_filter(@quick_filter).merge(@q)
21
+ query = query_for_filter(named_filter).merge(q)
20
22
  QueryableRegistration
21
23
  .includes(patient: [current_modality: :description])
22
24
  .search(query).tap do |s|
@@ -42,6 +44,8 @@ module Renalware
42
44
 
43
45
  private
44
46
 
47
+ attr_reader :q, :named_filter
48
+
45
49
  def query_for_filter(filter)
46
50
  case filter
47
51
  when :active
@@ -1,5 +1,7 @@
1
1
  module Renalware
2
2
  module Transplants
3
+ WAITLIST_FILTERS = %w(active suspended active_and_suspended working_up status_mismatch).freeze
4
+
3
5
  def self.table_name_prefix
4
6
  "transplant_"
5
7
  end
@@ -1,3 +1,5 @@
1
+ require "devise"
2
+
1
3
  module Renalware
2
4
  class User < ApplicationRecord
3
5
  include Deviseable
@@ -12,11 +14,11 @@ module Renalware
12
14
  validate :approval_with_roles, on: :update
13
15
  validates :professional_position, presence: {
14
16
  on: :update,
15
- unless: :skip_validation
17
+ if: ->(user){ user.with_extended_validation }
16
18
  }
17
19
  validates :signature, presence: {
18
20
  on: :update,
19
- unless: :skip_validation
21
+ if: ->(user){ user.with_extended_validation }
20
22
  }
21
23
 
22
24
  scope :unapproved, -> { where(approved: [nil, false]) }
@@ -25,13 +27,16 @@ module Renalware
25
27
  }
26
28
  scope :author, -> { where.not(signature: nil) }
27
29
  scope :ordered, -> { order(:family_name, :given_name) }
30
+ scope :excluding_system_user, -> { where.not(username: SystemUser.username) }
31
+ scope :with_no_role, lambda {
32
+ left_joins(:roles)
33
+ .distinct("roles_users.user_id")
34
+ .where("roles_users.user_id is null")
35
+ }
28
36
 
29
- # Non-persistent attribute to signify we want to bypassing the :update validations
30
- attr_writer :skip_validation
31
-
32
- def skip_validation
33
- @skip_validation || reset_password_token
34
- end
37
+ # Non-persistent attribute to signify we want to use extended validation.
38
+ # We need to refactor this by ising a form object for updating a user.
39
+ attr_accessor :with_extended_validation
35
40
 
36
41
  def self.policy_class
37
42
  UserPolicy
@@ -59,8 +64,21 @@ module Renalware
59
64
  signed
60
65
  end
61
66
 
67
+ def generate_new_authentication_token!
68
+ build_authentication_token.tap do |token|
69
+ update_column(:authentication_token, token)
70
+ end
71
+ end
72
+
62
73
  private
63
74
 
75
+ def build_authentication_token
76
+ loop do
77
+ token = ::Devise.friendly_token
78
+ break token unless User.find_by(authentication_token: token)
79
+ end
80
+ end
81
+
64
82
  def approval_with_roles
65
83
  if approved? && roles.empty?
66
84
  errors.add(:approved, "approved users must have a role")
@@ -0,0 +1,15 @@
1
+ require_dependency "renalware/admin"
2
+
3
+ module Renalware
4
+ module Admin
5
+ class CachePolicy < BasePolicy
6
+ def show?
7
+ user_is_super_admin?
8
+ end
9
+
10
+ def destroy
11
+ user_is_super_admin?
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module Renalware
2
+ module Admin
3
+ module Users
4
+ class SummaryPart < Renalware::SummaryPart
5
+ def to_partial_path
6
+ "renalware/admin/users/summary_part"
7
+ end
8
+
9
+ def users_needing_approval_count
10
+ @users_needing_approval_count ||= User.unapproved.count
11
+ end
12
+
13
+ def users_needing_approval_title
14
+ [
15
+ users_needing_approval_count,
16
+ "user".pluralize(users_needing_approval_count),
17
+ "awaiting approval"
18
+ ].join(" ")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -3,8 +3,8 @@ require_dependency "renalware/events"
3
3
  module Renalware
4
4
  module Events
5
5
  class SummaryPart < Renalware::SummaryPart
6
- def current_events
7
- @current_events ||= begin
6
+ def recent_events
7
+ @recent_events ||= begin
8
8
  Events::Event.includes([:created_by, :event_type])
9
9
  .for_patient(patient)
10
10
  .limit(Renalware.config.clinical_summary_max_events_to_display)
@@ -12,20 +12,27 @@ module Renalware
12
12
  end
13
13
  end
14
14
 
15
- def current_events_count
15
+ def recent_events_count
16
16
  title_friendly_collection_count(
17
- actual: current_events.size,
17
+ actual: recent_events.size,
18
18
  total: patient.summary.events_count
19
19
  )
20
20
  end
21
21
 
22
+ # AR::Relation#cache_key here will issue:
23
+ # SELECT COUNT(*) AS "size", MAX("events"."updated_at") AS timestamp
24
+ # FROM "events" WHERE "events"."patient_id" = 1
25
+ # and use size and timestamp in the cache key.
26
+ # We purposefully don't use the recent_events relation here as it has includes and a limit
27
+ # and apart from being slower, using LIMIT in cache_key sql has been known to produce
28
+ # inconsistent results.
29
+ def cache_key
30
+ Events::Event.for_patient(patient).cache_key
31
+ end
32
+
22
33
  def to_partial_path
23
34
  "renalware/events/events/summary_part"
24
35
  end
25
-
26
- # def cache_key
27
- # Events::Event.for_patient(patient).maximum(:updated_at)
28
- # end
29
36
  end
30
37
  end
31
38
  end
@@ -14,7 +14,7 @@ module Renalware
14
14
  @sessions ||= begin
15
15
  sessions = Sessions::LatestPatientSessionsQuery
16
16
  .new(patient: patient)
17
- .call(max_sessions: 6)
17
+ .call(max_sessions: 6).includes(:patient, :hospital_unit)
18
18
  CollectionPresenter.new(sessions, SessionPresenter, view_context)
19
19
  end
20
20
  end
@@ -19,9 +19,9 @@ module Renalware
19
19
  "renalware/letters/summary_part"
20
20
  end
21
21
 
22
- # def cache_key
23
- # letters_patient.letters.maximum(:updated_at)
24
- # end
22
+ def cache_key
23
+ letters_patient.letters.cache_key
24
+ end
25
25
 
26
26
  private
27
27
 
@@ -41,7 +41,7 @@ module Renalware
41
41
  end
42
42
 
43
43
  def letters_patient
44
- Renalware::Letters.cast_patient(patient)
44
+ @letters_patient ||= Renalware::Letters.cast_patient(patient)
45
45
  end
46
46
  end
47
47
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:disable Metrics/ClassLength
1
2
  require_dependency "renalware/clinics"
2
3
 
3
4
  module Renalware
@@ -14,11 +15,12 @@ module Renalware
14
15
  end
15
16
 
16
17
  def pathology_for_codes(codes = nil)
17
- presenter = Pathology::HistoricalObservationResults::Presenter.new
18
- options = {}
19
- options[:descriptions] = pathology_descriptions_for_codes(codes) if Array(codes).any?
20
- Pathology::ViewObservationResults.new(pathology_patient.observations, presenter, options).call
21
- OpenStruct.new(table: pathology_table_view, rows: presenter.view_model)
18
+ Pathology::CreateObservationsGroupedByDateTable.new(
19
+ patient: patient,
20
+ observation_descriptions: pathology_descriptions_for_codes(codes),
21
+ page: 1,
22
+ per_page: 10
23
+ ).call
22
24
  end
23
25
 
24
26
  def clinic_visits(limit: 6)
@@ -89,9 +91,11 @@ module Renalware
89
91
  @current_problems ||= patient.problems.current.limit(6).with_created_by.ordered
90
92
  end
91
93
 
94
+ # rubocop:disable Lint/UnusedMethodArgument
92
95
  def events_of_type(type: nil)
93
96
  Events::Event.for_patient(patient).includes([:created_by, :event_type]).limit(6).ordered
94
97
  end
98
+ # rubocop:enable Lint/UnusedMethodArgument
95
99
  alias_method :events, :events_of_type
96
100
 
97
101
  def letters
@@ -111,16 +115,20 @@ module Renalware
111
115
  private
112
116
 
113
117
  def pathology_descriptions_for_codes(codes)
114
- Pathology::ObservationDescription.for(Array(codes))
118
+ if codes.nil?
119
+ Pathology::RelevantObservationDescription.all
120
+ else
121
+ Pathology::ObservationDescription.for(Array(codes))
122
+ end
115
123
  end
116
124
 
117
125
  def pathology_patient
118
126
  Renalware::Pathology.cast_patient(patient)
119
127
  end
120
128
 
121
- def pathology_table_view
122
- Pathology::HistoricalObservationResults::HTMLTableView.new(view_context)
123
- end
129
+ # def pathology_table_view
130
+ # Pathology::HistoricalObservationResults::HTMLTableView.new(view_context)
131
+ # end
124
132
 
125
133
  def execute_prescriptions_query(relation)
126
134
  query = Medications::PrescriptionsQuery.new(relation: relation)
@@ -128,6 +136,7 @@ module Renalware
128
136
  .with_created_by
129
137
  .with_medication_route
130
138
  .with_drugs
139
+ .with_classifications
131
140
  .with_termination
132
141
  .eager_load(drug: [:drug_types])
133
142
  .map { |prescrip| Medications::PrescriptionPresenter.new(prescrip) }
@@ -43,7 +43,21 @@ module Renalware
43
43
  end
44
44
 
45
45
  def format_body_cell(cell)
46
- content_tag(:td, cell, class: cell.html_class)
46
+ if cell.respond_to?(:cancelled?)
47
+ if cell.cancelled?
48
+ # content = cell.cancelled ? "CANCL" : cell.to_s
49
+ content_tag(:td, class: cell.html_class, style: "text-align: center") do
50
+ tooltip_with_block(label: cell.comment) do
51
+ content_tag(:i, "", class: "fa fa-warning centre")
52
+ end
53
+ end
54
+ else
55
+ content_tag(:td, cell, class: cell.html_class)
56
+ end
57
+ else
58
+ # A date?
59
+ content_tag(:td, cell, class: cell.html_class)
60
+ end
47
61
  end
48
62
  end
49
63
  end
@@ -3,13 +3,11 @@ require_dependency "renalware/problems"
3
3
  module Renalware
4
4
  module Problems
5
5
  class SummaryPart < Renalware::SummaryPart
6
- def current_problems
7
- @current_problems ||= patient.problems.current.ordered
8
- end
6
+ delegate :cache_key, to: :problems
9
7
 
10
- # def cache_key
11
- # current_problems.maximum(:updated_at)
12
- # end
8
+ def problems
9
+ @problems ||= patient.problems.ordered
10
+ end
13
11
 
14
12
  def to_partial_path
15
13
  "renalware/problems/problems/summary_part"
@@ -5,6 +5,7 @@ module Renalware
5
5
  # reporting dashboards or summary pages. The Clinical Summary for instance comprises an array
6
6
  # of various SummaryParts
7
7
  class SummaryPart
8
+ DATE_FORMAT = "%Y%m%d%H%M%S%L".freeze
8
9
  rattr_initialize :patient
9
10
  attr_implement :to_partial_path
10
11
 
@@ -13,16 +14,16 @@ module Renalware
13
14
  nil
14
15
  end
15
16
 
16
- def cache?
17
- cache_key.present?
18
- end
19
-
20
17
  def render?
21
18
  true
22
19
  end
23
20
 
24
21
  protected
25
22
 
23
+ def date_formatted_for_cache(date)
24
+ date&.strftime(DATE_FORMAT)
25
+ end
26
+
26
27
  def title_friendly_collection_count(actual:, total:)
27
28
  if total > actual
28
29
  "#{actual} of #{total}"
@@ -0,0 +1,20 @@
1
+ = within_admin_layout(title: "Cache") do
2
+ .panel
3
+ p
4
+ | The cache (backed by Redis) stores some queries and html fragments in order to make
5
+ | the rendering of pages faster and less resource intensive. Cached elements are invalidated
6
+ | when the underlying database data changes (but it only examines the updated_at column and
7
+ | count of records, in order to catch edits, inserts and deletions) or the html template
8
+ | changes (changes are only reflected after am app restart in this latter case).
9
+ p
10
+ | There are certain cases where you might need to clear the cache:
11
+ ol
12
+ li
13
+ | You have changed the underlying database data directly in SQL without also updating the
14
+ | updated_at column.
15
+
16
+ = link_to "Clear the Application Cache",
17
+ admin_cache_path,
18
+ method: :delete,
19
+ data: { confirm: "Are you sure you want to clear the application cache?\n" },
20
+ class: "button alert"
@@ -1,5 +1,4 @@
1
1
  = within_admin_layout(title: "File Imports") do
2
-
3
2
  .row
4
3
  .small-12.columns.panel
5
4
  .row
@@ -0,0 +1,3 @@
1
+ section.admin--users
2
+ h2 Admin
3
+ = link_to summary_part.users_needing_approval_title, admin_users_path(q: { unapproved: true })
@@ -2,19 +2,25 @@
2
2
 
3
3
  = render "filters", user_search: user_search
4
4
 
5
- table
5
+ table.admin-users
6
6
  thead
7
7
  th.col-width-tiny
8
8
  th.col-width-tiny ID
9
- th.col-width-medium= sort_link(user_search,
9
+ th.col-width-large= sort_link(user_search,
10
10
  :family_name,
11
11
  [:family_name, :given_name],
12
12
  "User")
13
13
  th.col-width-small= sort_link(user_search, :username, "Login")
14
14
  th= sort_link(user_search, :email, "Email")
15
- th Telephone #
16
- th.col-width-date-time= sort_link(user_search, :created_at, "Added")
17
- th.col-width-tiny Approved
15
+ th.col-width-medium Role
16
+ th.col-width-tiny= sort_link(user_search, :approved, "Approved")
17
+ th.col-width-date= sort_link(user_search, :expired_at, "Expired On")
18
+ th.col-width-date-time.show-for-large-up= sort_link(user_search, :current_sign_in_at, "Current sign in")
19
+ th.col-width-date-time.show-for-large-up= sort_link(user_search, :last_sign_in_at, "Last sign in")
20
+ th.col-width-date-time.show-for-large-up= sort_link(user_search, :last_activity_at, "Last activity")
21
+ th.col-width-medium.show-for-xlarge-up Telephone #
22
+ th.col-width-date-time.show-for-xlarge-up= sort_link(user_search, :created_at, "Added")
23
+
18
24
 
19
25
  tbody
20
26
  - users.each do |user|
@@ -24,8 +30,19 @@
24
30
  td= user.to_s
25
31
  td= user.username
26
32
  td= user.email
27
- td= user.telephone
28
- td= l user.created_at
29
- td= yes_no(user.approved?)
33
+ td
34
+ - user.roles.each do |role|
35
+ span.tag(class=role.name)= role.name.humanize
36
+ td.approved
37
+ - if user.approved?
38
+ i.fa.fa-check-square-o
39
+ - else
40
+ i.unapproved.fa.fa-square-o
41
+ td.expired= l(user.expired_at&.to_date)
42
+ td.show-for-large-up= l(user.current_sign_in_at)
43
+ td.show-for-large-up= l(user.last_sign_in_at)
44
+ td.show-for-large-up= l(user.last_activity_at)
45
+ td.show-for-xlarge-up= user.telephone
46
+ td.show-for-xlarge-up= l(user.created_at)
30
47
 
31
48
  = paginate users
@@ -1,14 +1,13 @@
1
- .columns.large-12.xlarge-6
2
- #admissions
3
- article
4
- header
5
- h2= "Admissions (#{summary_part.admissions_count})"
1
+ #admissions.summary-part--admissions
2
+ article
3
+ header
4
+ h2= "Admissions (#{summary_part.admissions_count})"
6
5
 
7
- ul
8
- li= link_to admissions_admissions_path(query: { term: summary_part.patient_nhs_number }),
9
- class: "button" do
10
- | View All
6
+ ul
7
+ li= link_to admissions_admissions_path(query: { term: summary_part.patient_nhs_number }),
8
+ class: "button" do
9
+ | View All
11
10
 
12
- = render "renalware/admissions/admissions/table",
13
- admissions: summary_part.admissions,
14
- compact: true
11
+ = render "renalware/admissions/admissions/table",
12
+ admissions: summary_part.admissions,
13
+ compact: true
@@ -0,0 +1,17 @@
1
+ json.nhs_number patient.nhs_number
2
+ json.secure_id patient.secure_id
3
+ json.legacy_patient_id patient.legacy_patient_id
4
+ json.local_patient_id patient.local_patient_id
5
+ json.local_patient_id_2 patient.local_patient_id_2
6
+ json.local_patient_id_3 patient.local_patient_id_3
7
+ json.local_patient_id_4 patient.local_patient_id_4
8
+ json.local_patient_id_5 patient.local_patient_id_5
9
+ json.title patient.title
10
+ json.given_name patient.given_name
11
+ json.family_name patient.family_name
12
+ json.born_on patient.born_on&.to_s
13
+ json.died_on patient.died_on&.to_s
14
+ json.sex patient.sex&.code
15
+ json.ethnicity patient.ethnicity&.code
16
+ json.medications_url api_v1_patient_medications_prescriptions_url(patient_id: patient)
17
+ json.hd_profile_url api_v1_patient_hd_current_profile_url(patient_id: patient)
@@ -32,3 +32,6 @@
32
32
  receipts: dashboard.unread_electronic_ccs
33
33
  - else
34
34
  p.empty-section= t(".electronic_ccs.none")
35
+
36
+ - if current_user_is_admin?
37
+ = render Renalware::Admin::Users::SummaryPart.new(nil)
@@ -10,6 +10,8 @@
10
10
 
11
11
  = custom_devise_error_messages!
12
12
 
13
+ = f.hidden_field :with_extended_validation
14
+
13
15
  .field.large-8.small-6
14
16
  = f.label :email
15
17
  = f.email_field :email, autofocus: true
@@ -1,9 +1,8 @@
1
- .columns.large-12.xlarge-6
2
- span
3
- #events
1
+ - cache(summary_part) do
2
+ #events.summary-part--events
4
3
  article
5
4
  header
6
- h2= link_to "Events (#{summary_part.current_events_count})",
5
+ h2= link_to "Events (#{summary_part.recent_events_count})",
7
6
  patient_events_path(summary_part.patient)
8
7
 
9
8
  ul
@@ -12,4 +11,4 @@
12
11
  li= link_to patient_events_path(summary_part.patient), class: "button" do
13
12
  | View All
14
13
 
15
- = render "renalware/events/events/table", events: summary_part.current_events
14
+ = render "renalware/events/events/table", events: summary_part.recent_events