renalware-core 2.0.126 → 2.0.127

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/renalware/base/_variables.scss +2 -2
  3. data/app/assets/stylesheets/renalware/modules/_clinical.scss +3 -3
  4. data/app/assets/stylesheets/renalware/modules/_problems.scss +4 -1
  5. data/app/assets/stylesheets/renalware/modules/_rotated_tables_headings.scss +39 -0
  6. data/app/assets/stylesheets/renalware/modules/_surveys.scss +4 -0
  7. data/app/assets/stylesheets/renalware/partials/_forms.scss +1 -1
  8. data/app/assets/stylesheets/renalware/partials/_tables.scss +9 -3
  9. data/app/assets/stylesheets/renalware/partials/_tabs.scss +4 -4
  10. data/app/assets/stylesheets/renalware/partials/_toggling.scss +51 -1
  11. data/app/models/renalware/patients/ingestion/command_factory.rb +63 -51
  12. data/app/models/renalware/patients/ingestion/message_mappers/patient.rb +0 -17
  13. data/app/models/renalware/surveys/pos_s_summary_part.rb +9 -5
  14. data/app/models/renalware/ukrdc/incoming/import_survey.rb +6 -2
  15. data/app/models/renalware/ukrdc/incoming/xml_document.rb +11 -1
  16. data/app/presenters/renalware/hd/mdm_presenter.rb +6 -0
  17. data/app/presenters/renalware/problems/summary_part.rb +1 -1
  18. data/app/views/renalware/hd/mdm/_top.html.slim +12 -3
  19. data/app/views/renalware/hd/sessions/_row.html.slim +1 -1
  20. data/app/views/renalware/hd/sessions/dna/_row.html.slim +1 -1
  21. data/app/views/renalware/problems/problems/_current_table.html.slim +1 -1
  22. data/app/views/renalware/problems/problems/_summary_part.html.slim +21 -5
  23. data/app/views/renalware/surveys/_pos_s_summary_part.html.slim +43 -7
  24. data/db/migrate/20191205185835_update_survey_views.rb +12 -0
  25. data/db/migrate/20191209160151_add_patient_question_text_to_survey_responses.rb +7 -0
  26. data/db/migrate/20191209163151_update_survey_views_to_allow_free_text.rb +12 -0
  27. data/db/views/survey_pos_s_pivoted_responses_v02.sql +37 -0
  28. data/db/views/survey_pos_s_pivoted_responses_v03.sql +39 -0
  29. data/lib/renalware/version.rb +1 -1
  30. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c1b4b5e0615d605d093018e57c295da81fa8b2c7b51bd83b8ab02065ce357c91
4
- data.tar.gz: f78640822218ff8dfbae7ef9281d0cb9c5636791222fbb06a37cd36001b41ee8
3
+ metadata.gz: 334da5d5d7e32ed650c55379a33eedf5d4bba077a4480f987aece96dcb498ac9
4
+ data.tar.gz: 97f0bce7f1420f0d3f87b32e56bab92847c8f4efc61f7b2ba187a55749cd22fb
5
5
  SHA512:
6
- metadata.gz: a4074e24c734e3c38efb99687920d41ab1ac0e555dc6663a7cc356fc8035465b94ffa18be1ddcf8c2bbafd2e347a77caf0cf7806cd7d201980e699d8077bfcb6
7
- data.tar.gz: 680f524d251700a637fec7a8900a4c242cc691fad41d868254a773bd8de314859fbd7510bcb67fc01481cb300456b1bbebfee17aac0df95f0d86b63671ddd18e
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: $off-white;
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: #ccc;
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: $table-border-colour;
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 dotted $winter-sky;
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 dotted $white;;
185
+ border-bottom: 1px solid $white;;
186
186
  color: $white
187
187
  }
188
188
 
@@ -2,7 +2,10 @@ table#problems,
2
2
  table#current_problems,
3
3
  table#archived_problems {
4
4
  td {
5
- vertical-align: top;
5
+ // vertical-align: top;
6
+ span {
7
+ line-height: 1.1rem;
8
+ }
6
9
 
7
10
  ol {
8
11
  font-size: 1em;
@@ -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
+ }
@@ -55,4 +55,8 @@ dl.pos-s-key {
55
55
  text-align: left;
56
56
  }
57
57
  }
58
+
59
+ .summary-part--pos_s-patient-question-text {
60
+ text-align: right;
61
+ }
58
62
  }
@@ -220,7 +220,7 @@ article {
220
220
  width: 100%;
221
221
 
222
222
  li {
223
- border-bottom: 1px dotted $iron;
223
+ border-bottom: 1px solid $table-border-color;
224
224
  // font-weight: bold;
225
225
  padding-bottom: 0.2rem;
226
226
 
@@ -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: 1rem;
9
- padding: 0.4rem 0.28571rem;
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 dotted $disabled-colour;
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: $table-border-colour;
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 $table-border-colour;
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: $table-border-colour;
103
- background-color: $table-border-colour;
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
- // row-toggler-controller classes
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 then make_add_patient(message)
18
+ when :add_person_information then make_add_patient(message)
15
19
  when :update_person_information then make_update_patient(message)
16
- # when :admit_patient then make_admit_patient(message)
17
- # when :merge_patient then make_merge_patient(message)
18
- # when :update_admission then make_update_admission(message)
19
- # when :cancel_admission then make_cancel_admission(message)
20
- # when :transfer_patient then make_transfer_patient(message)
21
- # when :discharge_patient then make_discharge_patient(message)
22
- # when :cancel_discharge then make_cancel_discharge(message)
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
- # def make_merge_patient(message)
57
- # Commands::MergePatient.new(message,
58
- # major_patient_finder: make_patient_finder_with_add_if_missing,
59
- # minor_patient_finder: make_minor_patient_finder_with_add_if_missing)
60
- # end
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
- # def make_update_admission(message)
68
- # Commands::UpdateAdmission.new(message,
69
- # admission_finder: make_admission_finder_with_logging_if_missing)
70
- # end
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
- # def make_cancel_admission(message)
73
- # Commands::CancelAdmission.new(message,
74
- # admission_finder: make_admission_finder_with_logging_if_missing)
75
- # end
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
- # def make_transfer_patient(message)
78
- # Commands::TransferPatient.new(message,
79
- # admission_finder: make_admission_finder_with_admit_if_missing)
80
- # end
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
- # def make_discharge_patient(message)
83
- # Commands::DischargePatient.new(message,
84
- # admission_finder: make_admission_finder_with_logging_if_missing)
85
- # end
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
- # def make_cancel_discharge(message)
88
- # Commands::CancelDischarge.new(message)
89
- # end
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
- survey
14
- .questions
15
- .order(:position)
16
- .select(:code, :label)
17
- .each_with_object({}) { |q, hash| hash[q.code] = q.label }
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
- responses[code] = response
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
@@ -6,7 +6,7 @@ module Renalware
6
6
  module Problems
7
7
  class SummaryPart < Renalware::SummaryPart
8
8
  def problems
9
- @problems ||= patient.problems.ordered
9
+ @problems ||= patient.problems.with_notes
10
10
  end
11
11
 
12
12
  def cache_key
@@ -1,13 +1,22 @@
1
- .columns.small-12.medium-6.large-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
- .columns.medium-6.large-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
- .columns.medium-6.large-6
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
@@ -1,6 +1,6 @@
1
1
  tbody(class=[session.state, stripe_class])
2
2
  tr
3
- td.noprint= row_toggler
3
+ td.toggleable--toggler-container.noprint= row_toggler
4
4
  td.noprint= session.edit_or_view_url
5
5
  td= 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
- ul.no-bullet
24
- - summary_part.problems.each do |problem|
25
- li
26
- = problem.full_description
27
- = " - #{l(problem.created_at.to_date)}"
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.col-width-date Date
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= label
21
- tbody
22
- - pos_s_summary_part.rows.each do |row|
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
- td(class="pos-s--#{value}") = value
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
+ | &nbsp;
60
+ span= patient_question_text
61
+ | &nbsp;&nbsp;
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,12 @@
1
+ class UpdateSurveyViews < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ update_view(
5
+ :survey_pos_s_pivoted_responses,
6
+ version: 2,
7
+ revert_to_version: 1,
8
+ materialized: false
9
+ )
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ class AddPatientQuestionTextToSurveyResponses < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ add_column :survey_responses, :patient_question_text, :text
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ class UpdateSurveyViewsToAllowFreeText < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ update_view(
5
+ :survey_pos_s_pivoted_responses,
6
+ version: 3,
7
+ revert_to_version: 2,
8
+ materialized: false
9
+ )
10
+ end
11
+ end
12
+ end
@@ -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;
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Renalware
4
- VERSION = "2.0.126"
4
+ VERSION = "2.0.127"
5
5
  end
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.126
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-04 00:00:00.000000000 Z
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