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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/renalware/modules/_dashboard.scss +12 -3
- data/app/assets/stylesheets/renalware/modules/_letters.scss +0 -6
- data/app/assets/stylesheets/renalware/modules/_pathology.scss +5 -0
- data/app/assets/stylesheets/renalware/modules/_patients.scss +24 -0
- data/app/assets/stylesheets/renalware/modules/_users.scss +36 -0
- data/app/controllers/renalware/admin/cache_controller.rb +17 -0
- data/app/controllers/renalware/admin/users_controller.rb +1 -0
- data/app/controllers/renalware/api/token_authenticated_api_controller.rb +25 -0
- data/app/controllers/renalware/api/v1/patients/patients_controller.rb +17 -0
- data/app/controllers/renalware/concerns/devise_controller_methods.rb +4 -1
- data/app/controllers/renalware/devise/sessions_controller.rb +0 -29
- data/app/controllers/renalware/pathology/historical_observation_results_controller.rb +8 -10
- data/app/controllers/renalware/pathology/recent_observation_results_controller.rb +8 -10
- data/app/controllers/renalware/renal/aki_alerts_controller.rb +6 -1
- data/app/controllers/renalware/reporting/audits_controller.rb +1 -1
- data/app/controllers/renalware/system/errors_controller.rb +3 -1
- data/app/controllers/renalware/transplants/wait_lists_controller.rb +12 -3
- data/app/models/renalware/admin.rb +4 -0
- data/app/models/renalware/api.rb +6 -0
- data/app/models/renalware/clinics/current_observations.rb +1 -0
- data/app/models/renalware/events/event_query.rb +1 -1
- data/app/models/renalware/feeds/hl7_message.rb +16 -1
- data/app/models/renalware/hd/mdm_patients_query.rb +1 -1
- data/app/models/renalware/letters/pdf_letter_cache.rb +5 -1
- data/app/models/renalware/medications/prescription.rb +1 -0
- data/app/models/renalware/pathology/create_observations_grouped_by_date_table.rb +39 -0
- data/app/models/renalware/pathology/observation.rb +1 -1
- data/app/models/renalware/pathology/observation_digest.rb +12 -0
- data/app/models/renalware/pathology/observation_requests_attributes_builder.rb +2 -1
- data/app/models/renalware/pathology/observations_grouped_by_date_query.rb +91 -0
- data/app/models/renalware/pathology/observations_grouped_by_date_table.rb +59 -0
- data/app/models/renalware/pd/mdm_patients_query.rb +3 -1
- data/app/models/renalware/renal/aki_alert.rb +1 -0
- data/app/models/renalware/reporting/audit.rb +2 -0
- data/app/models/renalware/system/update_user.rb +0 -1
- data/app/models/renalware/transplants/registrations/wait_list_query.rb +9 -5
- data/app/models/renalware/transplants.rb +2 -0
- data/app/models/renalware/user.rb +26 -8
- data/app/policies/renalware/admin/cache_policy.rb +15 -0
- data/app/presenters/renalware/admin/users/summary_part.rb +23 -0
- data/app/presenters/renalware/events/summary_part.rb +15 -8
- data/app/presenters/renalware/hd/mdm_presenter.rb +1 -1
- data/app/presenters/renalware/letters/summary_part.rb +4 -4
- data/app/presenters/renalware/mdm_presenter.rb +18 -9
- data/app/presenters/renalware/pathology/historical_observation_results/html_table_view.rb +15 -1
- data/app/presenters/renalware/problems/summary_part.rb +4 -6
- data/app/presenters/renalware/summary_part.rb +5 -4
- data/app/views/renalware/admin/cache/show.html.slim +20 -0
- data/app/views/renalware/admin/feeds/files/index.html.slim +0 -1
- data/app/views/renalware/admin/users/_summary_part.html.slim +3 -0
- data/app/views/renalware/admin/users/index.html.slim +25 -8
- data/app/views/renalware/admissions/_summary_part.html.slim +11 -12
- data/app/views/renalware/api/v1/patients/patients/show.json.jbuilder +17 -0
- data/app/views/renalware/dashboard/dashboards/_content.html.slim +3 -0
- data/app/views/renalware/devise/registrations/edit.html.slim +2 -0
- data/app/views/renalware/events/events/_summary_part.html.slim +4 -5
- data/app/views/renalware/letters/_summary_part.html.slim +15 -14
- data/app/views/renalware/letters/letters/_table.html.slim +2 -1
- data/app/views/renalware/mdm/_pathology.html.slim +4 -2
- data/app/views/renalware/medications/_summary_part.html.slim +1 -1
- data/app/views/renalware/navigation/_renal.html.slim +1 -1
- data/app/views/renalware/navigation/_renalware_admin.html.slim +1 -0
- data/app/views/renalware/pathology/_navigation.html.slim +1 -1
- data/app/views/renalware/pathology/historical_observation_results/_table.html.slim +13 -0
- data/app/views/renalware/pathology/historical_observation_results/index.html.slim +3 -3
- data/app/views/renalware/pathology/observation_requests/_table.html.slim +1 -1
- data/app/views/renalware/pathology/recent_observation_results/_table.html.slim +18 -0
- data/app/views/renalware/pathology/recent_observation_results/index.html.slim +3 -3
- data/app/views/renalware/patients/clinical_summaries/show.html.slim +7 -4
- data/app/views/renalware/patients/side_menu/_actions.html.slim +26 -21
- data/app/views/renalware/problems/problems/_problem.html.slim +3 -0
- data/app/views/renalware/problems/problems/_summary_part.html.slim +16 -5
- data/app/views/renalware/renal/aki_alerts/edit.html.slim +4 -0
- data/app/views/renalware/renal/aki_alerts/index.html.slim +8 -0
- data/app/views/renalware/transplants/mdm/_pathology_cmvdna.html.slim +3 -1
- data/app/views/renalware/transplants/wait_lists/show.html.slim +2 -2
- data/config/initializers/inflections.rb +1 -0
- data/config/locales/renalware/mdm.yml +2 -2
- data/config/locales/renalware/renal/aki_alerts.en.yml +4 -0
- data/config/routes.rb +22 -5
- data/config/{schedule.rb → schedule.rb.example} +0 -0
- data/db/functions/update_current_observation_set_from_trigger_v03.sql +93 -0
- data/db/functions/update_current_observation_set_from_trigger_v04.sql +93 -0
- data/db/migrate/20180202184954_create_view_pathology_observation_digests.rb +5 -0
- data/db/migrate/20180206225525_update_fn_update_current_observation_set_from_trigger.rb +9 -0
- data/db/migrate/20180208150629_add_authentication_token_to_users.rb +5 -0
- data/db/migrate/20180213124203_add_cancelled_to_pathology_observations.rb +9 -0
- data/db/migrate/20180213125734_update_fn_update_current_obs_set_trgger.rb +9 -0
- data/db/migrate/20180214124317_add_cols_to_aki_alerts.rb +9 -0
- data/db/migrate/20180216132741_disable_some_audits.rb +8 -0
- data/db/seeds/default/transplants/transplant_donor_stages.rb +2 -2
- data/db/views/pathology_observation_digests_v01.sql +20 -0
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/pathology/observation_requests.rb +31 -0
- data/spec/support/login_macros.rb +4 -2
- 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_%';")
|
@@ -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(
|
6
|
-
@
|
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(
|
16
|
+
.apply_filter(named_filter)
|
15
17
|
end
|
16
18
|
|
17
19
|
def search
|
18
20
|
@search ||= begin
|
19
|
-
query = query_for_filter(
|
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,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
|
-
|
17
|
+
if: ->(user){ user.with_extended_validation }
|
16
18
|
}
|
17
19
|
validates :signature, presence: {
|
18
20
|
on: :update,
|
19
|
-
|
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
|
30
|
-
|
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,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
|
7
|
-
@
|
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
|
15
|
+
def recent_events_count
|
16
16
|
title_friendly_collection_count(
|
17
|
-
actual:
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
7
|
-
@current_problems ||= patient.problems.current.ordered
|
8
|
-
end
|
6
|
+
delegate :cache_key, to: :problems
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
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"
|
@@ -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-
|
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
|
16
|
-
th.col-width-
|
17
|
-
th.col-width-
|
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
|
28
|
-
|
29
|
-
|
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
|
-
.
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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)
|
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
|
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.
|
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.
|
14
|
+
= render "renalware/events/events/table", events: summary_part.recent_events
|