renalware-core 2.0.126 → 2.0.127
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/base/_variables.scss +2 -2
- data/app/assets/stylesheets/renalware/modules/_clinical.scss +3 -3
- data/app/assets/stylesheets/renalware/modules/_problems.scss +4 -1
- data/app/assets/stylesheets/renalware/modules/_rotated_tables_headings.scss +39 -0
- data/app/assets/stylesheets/renalware/modules/_surveys.scss +4 -0
- data/app/assets/stylesheets/renalware/partials/_forms.scss +1 -1
- data/app/assets/stylesheets/renalware/partials/_tables.scss +9 -3
- data/app/assets/stylesheets/renalware/partials/_tabs.scss +4 -4
- data/app/assets/stylesheets/renalware/partials/_toggling.scss +51 -1
- data/app/models/renalware/patients/ingestion/command_factory.rb +63 -51
- data/app/models/renalware/patients/ingestion/message_mappers/patient.rb +0 -17
- data/app/models/renalware/surveys/pos_s_summary_part.rb +9 -5
- data/app/models/renalware/ukrdc/incoming/import_survey.rb +6 -2
- data/app/models/renalware/ukrdc/incoming/xml_document.rb +11 -1
- data/app/presenters/renalware/hd/mdm_presenter.rb +6 -0
- data/app/presenters/renalware/problems/summary_part.rb +1 -1
- data/app/views/renalware/hd/mdm/_top.html.slim +12 -3
- data/app/views/renalware/hd/sessions/_row.html.slim +1 -1
- data/app/views/renalware/hd/sessions/dna/_row.html.slim +1 -1
- data/app/views/renalware/problems/problems/_current_table.html.slim +1 -1
- data/app/views/renalware/problems/problems/_summary_part.html.slim +21 -5
- data/app/views/renalware/surveys/_pos_s_summary_part.html.slim +43 -7
- data/db/migrate/20191205185835_update_survey_views.rb +12 -0
- data/db/migrate/20191209160151_add_patient_question_text_to_survey_responses.rb +7 -0
- data/db/migrate/20191209163151_update_survey_views_to_allow_free_text.rb +12 -0
- data/db/views/survey_pos_s_pivoted_responses_v02.sql +37 -0
- data/db/views/survey_pos_s_pivoted_responses_v03.sql +39 -0
- data/lib/renalware/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 334da5d5d7e32ed650c55379a33eedf5d4bba077a4480f987aece96dcb498ac9
|
4
|
+
data.tar.gz: 97f0bce7f1420f0d3f87b32e56bab92847c8f4efc61f7b2ba187a55749cd22fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f83bf5d9b6e63e5ba23ba024b61aafc74bf92658bb9a80662d204bd1e5bd3cf75096ba5ebe7dc4ca58a988694d371b8b070cddf95298870dd21aa206f68c1525
|
7
|
+
data.tar.gz: 62f72f50326cb5275faa9205f0dff4e75c6f8efa7bd84b1a11047e6b3d9a495dc16049fd3e77544d64c93b8bb47cf59a3e8b4c379107a80f5eba88c7d67043af
|
@@ -61,7 +61,7 @@ $drug-type-default-colour: none;
|
|
61
61
|
$drug-type-esa-colour: #ff9;
|
62
62
|
$drug-type-immunosuppressant-colour: #ccfeff;
|
63
63
|
|
64
|
-
$tab-border-color:
|
64
|
+
$tab-border-color: #ddd;
|
65
65
|
|
66
66
|
// Patient header/banner
|
67
67
|
$patient-header-muted-color: #777;
|
@@ -102,7 +102,7 @@ $letter-preview-background-colour: #ddd;
|
|
102
102
|
|
103
103
|
// tables
|
104
104
|
$table-even-row-colour: #fcfcfc;
|
105
|
-
$table-border-colour: #
|
105
|
+
$table-border-colour: #ddd;
|
106
106
|
$table-toggled-content-colour: #fefff1;
|
107
107
|
$table-urgent-colour: $nhs-yellow;
|
108
108
|
$table-row-hover-colour: #f9f9f9;
|
@@ -51,7 +51,7 @@ article.clinical-allergies {
|
|
51
51
|
}
|
52
52
|
|
53
53
|
.clinical-header {
|
54
|
-
background-color: $
|
54
|
+
background-color: $disabled-colour;
|
55
55
|
padding: 0 .2em .2em .6em;
|
56
56
|
|
57
57
|
@media print {
|
@@ -85,7 +85,7 @@ article.clinical-allergies {
|
|
85
85
|
padding: 0;
|
86
86
|
|
87
87
|
li {
|
88
|
-
border-bottom: 1px
|
88
|
+
border-bottom: 1px solid $winter-sky;
|
89
89
|
display: inline-block;
|
90
90
|
margin: 0.2rem .6rem .2rem 0;
|
91
91
|
padding: 0
|
@@ -182,7 +182,7 @@ article.clinical-allergies {
|
|
182
182
|
}
|
183
183
|
|
184
184
|
a {
|
185
|
-
border-bottom: 1px
|
185
|
+
border-bottom: 1px solid $white;;
|
186
186
|
color: $white
|
187
187
|
}
|
188
188
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// Somewhat specialised for use in eg POS-S survey results table because
|
2
|
+
// the attributes are quite finicky to get it to look right.
|
3
|
+
// If you need to use these classes elsewhere and the look is not right,
|
4
|
+
// please make sure PROMS survey results still look OK.
|
5
|
+
.table-header-rotated {
|
6
|
+
width: auto;
|
7
|
+
|
8
|
+
th.rotate {
|
9
|
+
height: 138px;
|
10
|
+
white-space: nowrap;
|
11
|
+
|
12
|
+
// Firefox needs the extra DIV for some reason, otherwise the text disappears if you rotate
|
13
|
+
> div {
|
14
|
+
transform:
|
15
|
+
// Magic Numbers
|
16
|
+
translate(25px, 51px)
|
17
|
+
// 45 is really 360-45
|
18
|
+
rotate(315deg);
|
19
|
+
width: 2rem;
|
20
|
+
}
|
21
|
+
|
22
|
+
> div > span {
|
23
|
+
border-bottom: 1px solid #ccc ;
|
24
|
+
display: inline-block;
|
25
|
+
padding: .4rem .0rem;
|
26
|
+
margin: 0 0 1.1rem -0.5rem;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
th.row-header {
|
31
|
+
padding: 0 10px;
|
32
|
+
border-bottom: 1px solid #ccc;
|
33
|
+
}
|
34
|
+
|
35
|
+
th {
|
36
|
+
overflow: visible;
|
37
|
+
vertical-align: inherit;
|
38
|
+
}
|
39
|
+
}
|
@@ -5,8 +5,8 @@ table tbody tr th,
|
|
5
5
|
table tbody tr td,
|
6
6
|
table tr td {
|
7
7
|
display: table-cell;
|
8
|
-
line-height:
|
9
|
-
padding: 0.
|
8
|
+
line-height: 1.3rem;
|
9
|
+
padding: 0.2rem 0.28571rem;
|
10
10
|
}
|
11
11
|
|
12
12
|
table thead th {
|
@@ -202,7 +202,7 @@ table {
|
|
202
202
|
|
203
203
|
tr th,
|
204
204
|
tr td {
|
205
|
-
border-bottom: 1px
|
205
|
+
border-bottom: 1px solid $table-border-colour;
|
206
206
|
border-left-width: 0;
|
207
207
|
border-right: solid 1px $white;
|
208
208
|
font-size: 1rem;
|
@@ -498,3 +498,9 @@ table tr.alt,
|
|
498
498
|
table tr:nth-of-type(even) {
|
499
499
|
background: transparent;
|
500
500
|
}
|
501
|
+
|
502
|
+
th, td {
|
503
|
+
&.valign-bottom {
|
504
|
+
vertical-align: bottom;
|
505
|
+
}
|
506
|
+
}
|
@@ -16,7 +16,7 @@
|
|
16
16
|
.ui-tabs-tab.ui-tabs-active,
|
17
17
|
.ui-tabs-tab.ui-state-active {
|
18
18
|
background-color: $white;
|
19
|
-
border-color: $
|
19
|
+
border-color: $disabled-colour;
|
20
20
|
}
|
21
21
|
|
22
22
|
.ui-tabs-anchor {
|
@@ -66,7 +66,7 @@
|
|
66
66
|
|
67
67
|
&.active {
|
68
68
|
background-color: $smoke;
|
69
|
-
border: solid 1px $
|
69
|
+
border: solid 1px $disabled-colour;
|
70
70
|
border-bottom: solid 1px $smoke;
|
71
71
|
}
|
72
72
|
}
|
@@ -99,8 +99,8 @@
|
|
99
99
|
position: relative;
|
100
100
|
display: block;
|
101
101
|
z-index: 0;
|
102
|
-
color: $
|
103
|
-
background-color: $
|
102
|
+
color: $disabled-colour;
|
103
|
+
background-color: $disabled-colour;
|
104
104
|
padding: 0;
|
105
105
|
margin: 0;
|
106
106
|
margin-bottom: 1rem;
|
@@ -16,6 +16,7 @@
|
|
16
16
|
}
|
17
17
|
}
|
18
18
|
|
19
|
+
// Toggle-all
|
19
20
|
th.togglers .toggler {
|
20
21
|
i:before {
|
21
22
|
content: asset-data-url("renalware/icons/chevrons-down.svg");
|
@@ -37,7 +38,23 @@ th.togglers {
|
|
37
38
|
width: 1rem;
|
38
39
|
}
|
39
40
|
|
40
|
-
//
|
41
|
+
// Classes to be used when toggling open an initially hidden tr.
|
42
|
+
// The expected structure
|
43
|
+
// table.toggleable
|
44
|
+
// thead
|
45
|
+
// th.togglers
|
46
|
+
// a.toggler (link to toggle all rows)
|
47
|
+
// th ...
|
48
|
+
// (for each thing)
|
49
|
+
// tbody
|
50
|
+
// tr (visible)
|
51
|
+
// td.toggleable--toggler-container
|
52
|
+
// a.toggler (link to toggle thos tobody's last row)
|
53
|
+
// td ...
|
54
|
+
// tr (will be initially hidden as its the last tr)
|
55
|
+
// td
|
56
|
+
// td Content to display when toggled
|
57
|
+
//
|
41
58
|
.toggleable {
|
42
59
|
.toggleable--open {
|
43
60
|
td .toggler i:before {
|
@@ -57,5 +74,38 @@ th.togglers {
|
|
57
74
|
&.toggleable--open tr:last-child {
|
58
75
|
display: table-row;
|
59
76
|
}
|
77
|
+
|
78
|
+
// Add this class to a toggleable tbody if there is nothing to toggle open to see.
|
79
|
+
// It prevents an empty row expanding down and taking up valuable space.
|
80
|
+
// An alternative could be to display 'No notes' or whatever, but that seems slightly odd.
|
81
|
+
&.toggleable--no-toggleable-content {
|
82
|
+
tr:last-child {
|
83
|
+
display: none;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
&.toggleable--without-border-between-toggled-and-non-toggled-tr {
|
89
|
+
tbody.toggleable--open:not(.no-toggleable-content) {
|
90
|
+
td {
|
91
|
+
border-top: solid 1px $table-border-colour;
|
92
|
+
}
|
93
|
+
|
94
|
+
tr:first-child td {
|
95
|
+
border-bottom: none;
|
96
|
+
}
|
97
|
+
|
98
|
+
tr:last-child:not(.no-toggleable-content) td {
|
99
|
+
border-top: none;
|
100
|
+
padding-top: 0;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
.toggleable--toggler-container {
|
106
|
+
padding: 0;
|
107
|
+
margin: 0;
|
108
|
+
text-align: center;
|
109
|
+
vertical-align: middle;
|
60
110
|
}
|
61
111
|
}
|
@@ -9,38 +9,29 @@ module Renalware
|
|
9
9
|
# message type.
|
10
10
|
#
|
11
11
|
class CommandFactory
|
12
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
13
|
+
# Note that for now most of these mapped methods will only try and
|
14
|
+
# update the patient info and master patient index, and not actually
|
15
|
+
# try and create an admission/transfer etc
|
12
16
|
def for(message)
|
13
17
|
case message.action
|
14
|
-
when :add_person_information
|
18
|
+
when :add_person_information then make_add_patient(message)
|
15
19
|
when :update_person_information then make_update_patient(message)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
# when :
|
20
|
+
when :admit_patient then make_admit_patient(message)
|
21
|
+
when :update_admission then make_update_admission(message)
|
22
|
+
when :cancel_admission then make_cancel_admission(message)
|
23
|
+
when :transfer_patient then make_transfer_patient(message)
|
24
|
+
when :discharge_patient then make_discharge_patient(message)
|
25
|
+
when :cancel_discharge then make_cancel_discharge(message)
|
26
|
+
# when :merge_patient then make_merge_patient(message) # complex so ignore for now.
|
23
27
|
# when :add_consultant then make_add_consultant(message)
|
24
28
|
else noop
|
25
29
|
end
|
26
30
|
end
|
31
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
27
32
|
|
28
33
|
private
|
29
34
|
|
30
|
-
# def make_add_patient_with_finder(message)
|
31
|
-
# CommandWithFinder.new(
|
32
|
-
# make_add_patient(message),
|
33
|
-
# message, finder: Finder::Patient.new
|
34
|
-
# )
|
35
|
-
# end
|
36
|
-
|
37
|
-
# def make_add_patient_with_finder(message)
|
38
|
-
# CommandWithFinder.new(
|
39
|
-
# make_add_patient(message),
|
40
|
-
# message, finder: Finder::Patient.new
|
41
|
-
# )
|
42
|
-
# end
|
43
|
-
|
44
35
|
def make_add_patient(message)
|
45
36
|
Commands::AddOrUpdatePatient.new(message)
|
46
37
|
end
|
@@ -53,40 +44,40 @@ module Renalware
|
|
53
44
|
NullObject.instance
|
54
45
|
end
|
55
46
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# def make_admit_patient(message)
|
63
|
-
# Commands::AdmitPatient.new(message,
|
64
|
-
# patient_finder: make_patient_finder_with_add_if_missing)
|
65
|
-
# end
|
47
|
+
def make_admit_patient(message)
|
48
|
+
Commands::AddOrUpdatePatient.new(message)
|
49
|
+
# Commands::AdmitPatient.new(message,
|
50
|
+
# patient_finder: make_patient_finder_with_add_if_missing)
|
51
|
+
end
|
66
52
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
53
|
+
def make_update_admission(message)
|
54
|
+
Commands::AddOrUpdatePatient.new(message)
|
55
|
+
# Commands::UpdateAdmission.new(message,
|
56
|
+
# admission_finder: make_admission_finder_with_logging_if_missing)
|
57
|
+
end
|
71
58
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
59
|
+
def make_cancel_admission(message)
|
60
|
+
Commands::AddOrUpdatePatient.new(message)
|
61
|
+
# Commands::CancelAdmission.new(message,
|
62
|
+
# admission_finder: make_admission_finder_with_logging_if_missing)
|
63
|
+
end
|
76
64
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
65
|
+
def make_transfer_patient(message)
|
66
|
+
Commands::AddOrUpdatePatient.new(message)
|
67
|
+
# Commands::TransferPatient.new(message,
|
68
|
+
# admission_finder: make_admission_finder_with_admit_if_missing)
|
69
|
+
end
|
81
70
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
71
|
+
def make_discharge_patient(message)
|
72
|
+
Commands::AddOrUpdatePatient.new(message)
|
73
|
+
# Commands::DischargePatient.new(message,
|
74
|
+
# admission_finder: make_admission_finder_with_logging_if_missing)
|
75
|
+
end
|
86
76
|
|
87
|
-
|
88
|
-
|
89
|
-
|
77
|
+
def make_cancel_discharge(message)
|
78
|
+
Commands::AddOrUpdatePatient.new(message)
|
79
|
+
# Commands::CancelDischarge.new(message)
|
80
|
+
end
|
90
81
|
|
91
82
|
# def make_add_consultant(message)
|
92
83
|
# Commands::AddConsultant.new(message)
|
@@ -133,6 +124,27 @@ module Renalware
|
|
133
124
|
# make_admit_patient(message).call
|
134
125
|
# }
|
135
126
|
# end
|
127
|
+
#
|
128
|
+
#
|
129
|
+
# def make_add_patient_with_finder(message)
|
130
|
+
# CommandWithFinder.new(
|
131
|
+
# make_add_patient(message),
|
132
|
+
# message, finder: Finder::Patient.new
|
133
|
+
# )
|
134
|
+
# end
|
135
|
+
|
136
|
+
# def make_add_patient_with_finder(message)
|
137
|
+
# CommandWithFinder.new(
|
138
|
+
# make_add_patient(message),
|
139
|
+
# message, finder: Finder::Patient.new
|
140
|
+
# )
|
141
|
+
# end
|
142
|
+
#
|
143
|
+
# def make_merge_patient(message)
|
144
|
+
# Commands::MergePatient.new(message,
|
145
|
+
# major_patient_finder: make_patient_finder_with_add_if_missing,
|
146
|
+
# minor_patient_finder: make_minor_patient_finder_with_add_if_missing)
|
147
|
+
# end
|
136
148
|
end
|
137
149
|
end
|
138
150
|
end
|
@@ -48,23 +48,6 @@ module Renalware
|
|
48
48
|
attrs.reject! { |_key, value| value.blank? }
|
49
49
|
patient.attributes = attrs
|
50
50
|
|
51
|
-
# patient.given_name = patient_identification.given_name
|
52
|
-
# patient.family_name = patient_identification.family_name
|
53
|
-
# patient.suffix = patient_identification.suffix
|
54
|
-
# patient.title = patient_identification.title
|
55
|
-
# patient.attributes = {
|
56
|
-
# local_patient_id: patient_identification.internal_id,
|
57
|
-
# nhs_number: patient_identification.nhs_number,
|
58
|
-
# given_name: patient_identification.given_name,
|
59
|
-
# family_name: patient_identification.family_name,
|
60
|
-
# suffix: patient_identification.suffix,
|
61
|
-
# title: patient_identification.title,
|
62
|
-
# born_on: Time.zone.parse(patient_identification.dob)&.to_date,
|
63
|
-
# died_on: Time.zone.parse(patient_identification.death_date)&.to_date,
|
64
|
-
# sex: patient_identification.sex,
|
65
|
-
# practice: find_practice(message.practice_code) || patient.practice,
|
66
|
-
# primary_care_physician: find_primary_care_physician(message.gp_code)
|
67
|
-
# }
|
68
51
|
patient.build_current_address if patient.current_address.blank?
|
69
52
|
patient.current_address.attributes = {
|
70
53
|
street_1: address[0],
|
@@ -5,18 +5,22 @@ require_dependency "renalware/surveys"
|
|
5
5
|
module Renalware
|
6
6
|
module Surveys
|
7
7
|
class POSSSummaryPart < Renalware::SummaryPart
|
8
|
+
# Backed by a SQL view
|
8
9
|
def rows
|
9
10
|
@rows ||= POSSPivotedResponse.where(patient_id: patient.id)
|
10
11
|
end
|
11
12
|
|
12
13
|
def question_labels
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
@question_labels ||= begin
|
15
|
+
survey
|
16
|
+
.questions
|
17
|
+
.order(:position)
|
18
|
+
.select(:code, :label)
|
19
|
+
.each_with_object({}) { |q, hash| hash[q.code] = q.label }
|
20
|
+
end
|
18
21
|
end
|
19
22
|
|
23
|
+
# Return data for charting
|
20
24
|
def data_for_question_code(_code)
|
21
25
|
Renalware::Surveys::Response
|
22
26
|
.where(patient_id: patient.id, question_id: 1)
|
@@ -9,14 +9,18 @@ module Renalware
|
|
9
9
|
class ImportSurvey
|
10
10
|
pattr_initialize [:patient, :survey_hash]
|
11
11
|
|
12
|
+
# Note that each question's answer may be a value like "1" or be an array where the second
|
13
|
+
# element is the user-entered question text e.g. ["1", "Paranoia"]
|
14
|
+
# This is used in POS-S so that a user can enter their own question text.
|
12
15
|
def call
|
13
16
|
responses.each do |question_code, answer|
|
14
17
|
question = question_having_code(question_code)
|
15
|
-
|
18
|
+
answer = Array(answer)
|
16
19
|
Surveys::Response.create!(
|
17
20
|
patient_id: patient.id,
|
18
21
|
question: question,
|
19
|
-
value: answer,
|
22
|
+
value: answer[0],
|
23
|
+
patient_question_text: answer[1],
|
20
24
|
answered_on: answered_on
|
21
25
|
)
|
22
26
|
end
|
@@ -54,12 +54,22 @@ module Renalware
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
# Note that if a response has a QuestionText this can be some text the user entered
|
58
|
+
# (presumably so they can then assign it a response value) so we need to store the
|
59
|
+
# question text (e.g. Paranoia) as well as the response (eg 4).
|
60
|
+
# If we find a QuestionText we store an array containing it and the response in the hash
|
61
|
+
# otherwise we just add the response.
|
57
62
|
def question_hash_from(survey_node)
|
58
63
|
question_nodes = survey_node.xpath("Questions/Question")
|
59
64
|
question_nodes.each_with_object({}) do |question_node, responses|
|
60
65
|
code = question_node.xpath("string(QuestionType/Code)")
|
61
66
|
response = question_node.xpath("string(Response)")
|
62
|
-
|
67
|
+
question_text = question_node.xpath("string(QuestionText)")
|
68
|
+
responses[code] = if question_text.present?
|
69
|
+
[response, question_text]
|
70
|
+
else
|
71
|
+
response
|
72
|
+
end
|
63
73
|
end
|
64
74
|
end
|
65
75
|
end
|
@@ -33,6 +33,12 @@ module Renalware
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def dry_weights
|
37
|
+
@dry_weights ||= begin
|
38
|
+
Clinical::DryWeight.for_patient(patient).ordered.includes(:assessor).limit(5)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
36
42
|
def preference_set
|
37
43
|
@preference_set ||= PreferenceSet.for_patient(patient).first || NullObject.instance
|
38
44
|
end
|
@@ -1,13 +1,22 @@
|
|
1
|
-
.columns.small-12.medium-6
|
1
|
+
.columns.small-12.medium-6
|
2
2
|
= render "renalware/hd/current_profile/summary", profile: mdm.hd_profile, patient: mdm.patient
|
3
|
+
|
4
|
+
.columns.medium-6
|
5
|
+
= render "renalware/clinical/dry_weights/list",
|
6
|
+
dry_weights: mdm.dry_weights,
|
7
|
+
patient: mdm.patient,
|
8
|
+
limit: true
|
9
|
+
|
3
10
|
.columns.small-12.medium-6.large-3
|
4
11
|
- if mdm.access.present?
|
5
12
|
= render "renalware/hd/accesses/summary", access: mdm.access, patient: mdm.patient
|
6
|
-
|
13
|
+
|
14
|
+
.columns.medium-6
|
7
15
|
= render "renalware/virology/profiles/summary",
|
8
16
|
patient: mdm.patient,
|
9
17
|
positive_results_only: true
|
10
|
-
|
18
|
+
|
19
|
+
.columns.medium-6
|
11
20
|
= render "summary", mdm: mdm
|
12
21
|
= render "worryboard", mdm: mdm
|
13
22
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
tbody.hd-session-row(class=[session.state, stripe_class])
|
2
2
|
tr
|
3
|
-
td.noprint(rowspan=2)= row_toggler
|
3
|
+
td.toggleable--toggler-container.noprint(rowspan=2)= row_toggler
|
4
4
|
td.noprint(rowspan=2)= session.edit_or_view_url
|
5
5
|
td.col-width-date(rowspan=2)= session.performed_on
|
6
6
|
td= session.hospital_unit_unit_code
|
@@ -4,7 +4,7 @@ table#current_problems.manual-stripes.auto-layout
|
|
4
4
|
th.options.col-width-small
|
5
5
|
th Description
|
6
6
|
th.col-width-date Updated on
|
7
|
-
td.nowrap Updated by
|
7
|
+
td.col-width-medium.nowrap Updated by
|
8
8
|
th.col-width-tiny Reorder
|
9
9
|
= content_tag(:tbody, class: "sortables", data: { rel: sort_patient_problems_path(@patient) }) do
|
10
10
|
- problems.each do |problem|
|
@@ -20,8 +20,24 @@
|
|
20
20
|
= link_to patient_problems_path(summary_part.patient), class: "button" do
|
21
21
|
| Add
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
table#problems.toggleable.toggleable--without-border-between-toggled-and-non-toggled-tr
|
24
|
+
thead.toggleable--open
|
25
|
+
th.togglers.noprint =rows_toggler
|
26
|
+
th Description
|
27
|
+
th.col-width-date Date
|
28
|
+
|
29
|
+
- summary_part.problems.each_with_index do |problem|
|
30
|
+
tbody.toggleable--open(class=("toggleable--no-toggleable-content" if problem.notes.none?))
|
31
|
+
tr
|
32
|
+
td.toggleable--toggler-container.noprint = row_toggler
|
33
|
+
td
|
34
|
+
span= problem.full_description
|
35
|
+
td= problem.created_at.to_date
|
36
|
+
tr
|
37
|
+
td
|
38
|
+
td
|
39
|
+
- if problem.notes.any?
|
40
|
+
ol
|
41
|
+
- problem.notes.each do |note|
|
42
|
+
li= note.description
|
43
|
+
td
|
@@ -1,3 +1,6 @@
|
|
1
|
+
/
|
2
|
+
/ TODO: this could do with refactoring to move the formatting code into a helper or presenter.
|
3
|
+
/
|
1
4
|
.summary-part--pos_s
|
2
5
|
article
|
3
6
|
header
|
@@ -10,22 +13,55 @@
|
|
10
13
|
/ br
|
11
14
|
|
12
15
|
- return if pos_s_summary_part.rows.blank?
|
13
|
-
|
16
|
+
br
|
17
|
+
br
|
18
|
+
br
|
19
|
+
br
|
14
20
|
.xsss
|
15
|
-
table
|
21
|
+
table.table-header-rotated.toggleable
|
16
22
|
thead
|
17
23
|
tr
|
18
|
-
th.
|
24
|
+
th.togglers= rows_toggler
|
25
|
+
th.col-width-date.valign-bottom Date
|
26
|
+
th.col-width-tiny.valign-bottom Total
|
19
27
|
- pos_s_summary_part.question_labels.each do |code, label|
|
20
|
-
th
|
21
|
-
|
22
|
-
|
28
|
+
th.rotate
|
29
|
+
div
|
30
|
+
span= label
|
31
|
+
|
32
|
+
- superscript_char = 97
|
33
|
+
- pos_s_summary_part.rows.each do |row|
|
34
|
+
tbody
|
23
35
|
tr
|
36
|
+
td= row_toggler
|
24
37
|
td= row.answered_on
|
38
|
+
td= row.total_score
|
25
39
|
- pos_s_summary_part.question_labels.each do |code, label|
|
26
40
|
- value = row.send(code.to_sym)
|
27
|
-
|
41
|
+
- patient_question_text = row.try(:"#{code}_patient_question_text")
|
42
|
+
td(class="pos-s--#{value}")
|
43
|
+
- if patient_question_text
|
44
|
+
span(title="Toggle row for question text")= value
|
45
|
+
sup= superscript_char.chr
|
46
|
+
- superscript_char += 1
|
47
|
+
- else
|
48
|
+
= value
|
49
|
+
tr
|
50
|
+
td
|
51
|
+
td
|
52
|
+
td
|
53
|
+
td(class="summary-part--pos_s-patient-question-text" colspan=(pos_s_summary_part.question_labels.count ))
|
54
|
+
- superscript_char = 97
|
55
|
+
- pos_s_summary_part.question_labels.each do |code, label|
|
56
|
+
- patient_question_text = row.try(:"#{code}_patient_question_text")
|
57
|
+
- if patient_question_text
|
58
|
+
sup= superscript_char.chr
|
59
|
+
|
|
60
|
+
span= patient_question_text
|
61
|
+
|
|
62
|
+
- superscript_char += 1
|
28
63
|
|
64
|
+
/ Colour-coded key
|
29
65
|
dl.pos-s-key
|
30
66
|
dt.pos-s--0 0
|
31
67
|
dd Not at all
|
@@ -0,0 +1,37 @@
|
|
1
|
+
/*
|
2
|
+
This is a pivoted crosstab view taking POS-S renal questionnaire responses from
|
3
|
+
patients and returning them with the question codes as the column headings.
|
4
|
+
See also the eq5d_5l for comments about alternative use of crosstab function.
|
5
|
+
*/
|
6
|
+
SELECT r.answered_on,
|
7
|
+
r.patient_id,
|
8
|
+
sum(r.value::integer) as "total_score",
|
9
|
+
MAX(CASE WHEN q.code = 'YSQ1' THEN r.value ELSE NULL END) AS "YSQ1",
|
10
|
+
MAX(CASE WHEN q.code = 'YSQ2' THEN r.value ELSE NULL END) AS "YSQ2",
|
11
|
+
MAX(CASE WHEN q.code = 'YSQ3' THEN r.value ELSE NULL END) AS "YSQ3",
|
12
|
+
MAX(CASE WHEN q.code = 'YSQ4' THEN r.value ELSE NULL END) AS "YSQ4",
|
13
|
+
MAX(CASE WHEN q.code = 'YSQ5' THEN r.value ELSE NULL END) AS "YSQ5",
|
14
|
+
MAX(CASE WHEN q.code = 'YSQ6' THEN r.value ELSE NULL END) AS "YSQ6",
|
15
|
+
MAX(CASE WHEN q.code = 'YSQ7' THEN r.value ELSE NULL END) AS "YSQ7",
|
16
|
+
MAX(CASE WHEN q.code = 'YSQ8' THEN r.value ELSE NULL END) AS "YSQ8",
|
17
|
+
MAX(CASE WHEN q.code = 'YSQ9' THEN r.value ELSE NULL END) AS "YSQ9",
|
18
|
+
MAX(CASE WHEN q.code = 'YSQ10' THEN r.value ELSE NULL END) AS "YSQ10",
|
19
|
+
MAX(CASE WHEN q.code = 'YSQ11' THEN r.value ELSE NULL END) AS "YSQ11",
|
20
|
+
MAX(CASE WHEN q.code = 'YSQ12' THEN r.value ELSE NULL END) AS "YSQ12",
|
21
|
+
MAX(CASE WHEN q.code = 'YSQ13' THEN r.value ELSE NULL END) AS "YSQ13",
|
22
|
+
MAX(CASE WHEN q.code = 'YSQ14' THEN r.value ELSE NULL END) AS "YSQ14",
|
23
|
+
MAX(CASE WHEN q.code = 'YSQ15' THEN r.value ELSE NULL END) AS "YSQ15",
|
24
|
+
MAX(CASE WHEN q.code = 'YSQ16' THEN r.value ELSE NULL END) AS "YSQ16",
|
25
|
+
MAX(CASE WHEN q.code = 'YSQ17' THEN r.value ELSE NULL END) AS "YSQ17",
|
26
|
+
MAX(CASE WHEN q.code = 'YSQ18' THEN r.value ELSE NULL END) AS "YSQ18",
|
27
|
+
MAX(CASE WHEN q.code = 'YSQ19' THEN r.value ELSE NULL END) AS "YSQ19",
|
28
|
+
MAX(CASE WHEN q.code = 'YSQ20' THEN r.value ELSE NULL END) AS "YSQ20",
|
29
|
+
MAX(CASE WHEN q.code = 'YSQ21' THEN r.value ELSE NULL END) AS "YSQ21",
|
30
|
+
MAX(CASE WHEN q.code = 'YSQ22' THEN r.value ELSE NULL END) AS "YSQ22"
|
31
|
+
|
32
|
+
FROM survey_responses r
|
33
|
+
inner JOIN survey_questions q ON q.id = r.question_id
|
34
|
+
inner JOIN survey_surveys s ON s.id = q.survey_id
|
35
|
+
WHERE s.code = 'prom'
|
36
|
+
GROUP BY r.answered_on, r.patient_id
|
37
|
+
ORDER BY r.answered_on DESC;
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/*
|
2
|
+
This is a pivoted crosstab view taking POS-S renal questionnaire responses from
|
3
|
+
patients and returning them with the question codes as the column headings.
|
4
|
+
See also the eq5d_5l for comments about alternative use of crosstab function.
|
5
|
+
*/
|
6
|
+
SELECT r.answered_on,
|
7
|
+
r.patient_id,
|
8
|
+
sum(convert_to_float(r.value))::integer as "total_score",
|
9
|
+
MAX(CASE WHEN q.code = 'YSQ1' THEN r.value ELSE NULL END) AS "YSQ1",
|
10
|
+
MAX(CASE WHEN q.code = 'YSQ2' THEN r.value ELSE NULL END) AS "YSQ2",
|
11
|
+
MAX(CASE WHEN q.code = 'YSQ3' THEN r.value ELSE NULL END) AS "YSQ3",
|
12
|
+
MAX(CASE WHEN q.code = 'YSQ4' THEN r.value ELSE NULL END) AS "YSQ4",
|
13
|
+
MAX(CASE WHEN q.code = 'YSQ5' THEN r.value ELSE NULL END) AS "YSQ5",
|
14
|
+
MAX(CASE WHEN q.code = 'YSQ6' THEN r.value ELSE NULL END) AS "YSQ6",
|
15
|
+
MAX(CASE WHEN q.code = 'YSQ7' THEN r.value ELSE NULL END) AS "YSQ7",
|
16
|
+
MAX(CASE WHEN q.code = 'YSQ8' THEN r.value ELSE NULL END) AS "YSQ8",
|
17
|
+
MAX(CASE WHEN q.code = 'YSQ9' THEN r.value ELSE NULL END) AS "YSQ9",
|
18
|
+
MAX(CASE WHEN q.code = 'YSQ10' THEN r.value ELSE NULL END) AS "YSQ10",
|
19
|
+
MAX(CASE WHEN q.code = 'YSQ11' THEN r.value ELSE NULL END) AS "YSQ11",
|
20
|
+
MAX(CASE WHEN q.code = 'YSQ12' THEN r.value ELSE NULL END) AS "YSQ12",
|
21
|
+
MAX(CASE WHEN q.code = 'YSQ13' THEN r.value ELSE NULL END) AS "YSQ13",
|
22
|
+
MAX(CASE WHEN q.code = 'YSQ14' THEN r.value ELSE NULL END) AS "YSQ14",
|
23
|
+
MAX(CASE WHEN q.code = 'YSQ15' THEN r.value ELSE NULL END) AS "YSQ15",
|
24
|
+
MAX(CASE WHEN q.code = 'YSQ16' THEN r.value ELSE NULL END) AS "YSQ16",
|
25
|
+
MAX(CASE WHEN q.code = 'YSQ17' THEN r.value ELSE NULL END) AS "YSQ17",
|
26
|
+
MAX(CASE WHEN q.code = 'YSQ18' THEN r.value ELSE NULL END) AS "YSQ18",
|
27
|
+
MAX(CASE WHEN q.code = 'YSQ19' THEN r.value ELSE NULL END) AS "YSQ19",
|
28
|
+
MAX(CASE WHEN q.code = 'YSQ20' THEN r.value ELSE NULL END) AS "YSQ20",
|
29
|
+
MAX(CASE WHEN q.code = 'YSQ21' THEN r.value ELSE NULL END) AS "YSQ21",
|
30
|
+
MAX(CASE WHEN q.code = 'YSQ22' THEN r.value ELSE NULL END) AS "YSQ22",
|
31
|
+
MAX(CASE WHEN q.code = 'YSQ18' THEN r.patient_question_text ELSE NULL END) AS "YSQ18_patient_question_text",
|
32
|
+
MAX(CASE WHEN q.code = 'YSQ19' THEN r.patient_question_text ELSE NULL END) AS "YSQ19_patient_question_text",
|
33
|
+
MAX(CASE WHEN q.code = 'YSQ20' THEN r.patient_question_text ELSE NULL END) AS "YSQ20_patient_question_text"
|
34
|
+
FROM survey_responses r
|
35
|
+
inner JOIN survey_questions q ON q.id = r.question_id
|
36
|
+
inner JOIN survey_surveys s ON s.id = q.survey_id
|
37
|
+
WHERE s.code = 'prom'
|
38
|
+
GROUP BY r.answered_on, r.patient_id
|
39
|
+
ORDER BY r.answered_on DESC;
|
data/lib/renalware/version.rb
CHANGED
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.
|
4
|
+
version: 2.0.127
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airslie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionview-component
|
@@ -1084,6 +1084,7 @@ files:
|
|
1084
1084
|
- app/assets/stylesheets/renalware/modules/_problems.scss
|
1085
1085
|
- app/assets/stylesheets/renalware/modules/_renal.scss
|
1086
1086
|
- app/assets/stylesheets/renalware/modules/_reporting.scss
|
1087
|
+
- app/assets/stylesheets/renalware/modules/_rotated_tables_headings.scss
|
1087
1088
|
- app/assets/stylesheets/renalware/modules/_snippets.scss
|
1088
1089
|
- app/assets/stylesheets/renalware/modules/_surveys.scss
|
1089
1090
|
- app/assets/stylesheets/renalware/modules/_system.scss
|
@@ -3719,6 +3720,9 @@ files:
|
|
3719
3720
|
- db/migrate/20191105095304_update_views_to_exclude_deleted_sessions.rb
|
3720
3721
|
- db/migrate/20191108105923_add_named_consultant_to_patients.rb
|
3721
3722
|
- db/migrate/20191203112310_add_pg_stat_statements_extension.rb
|
3723
|
+
- db/migrate/20191205185835_update_survey_views.rb
|
3724
|
+
- db/migrate/20191209160151_add_patient_question_text_to_survey_responses.rb
|
3725
|
+
- db/migrate/20191209163151_update_survey_views_to_allow_free_text.rb
|
3722
3726
|
- db/seeds.rb
|
3723
3727
|
- db/seeds/default/accesses/access_pd_catheter_insertion_techniques.csv
|
3724
3728
|
- db/seeds/default/accesses/access_pd_catheter_insertion_techniques.rb
|
@@ -3851,6 +3855,8 @@ files:
|
|
3851
3855
|
- db/views/reporting_pd_audit_v01.sql
|
3852
3856
|
- db/views/survey_eq5d_pivoted_responses_v01.sql
|
3853
3857
|
- db/views/survey_pos_s_pivoted_responses_v01.sql
|
3858
|
+
- db/views/survey_pos_s_pivoted_responses_v02.sql
|
3859
|
+
- db/views/survey_pos_s_pivoted_responses_v03.sql
|
3854
3860
|
- lib/age_calculator.rb
|
3855
3861
|
- lib/array_stringifier.rb
|
3856
3862
|
- lib/breadcrumb.rb
|