ion_orders_engine_mockingjay 1.0.1.SNAPSHOT

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +0 -0
  3. data/Rakefile +4 -0
  4. data/app/assets/images/rails.png +0 -0
  5. data/app/assets/javascripts/application.js +16 -0
  6. data/app/assets/javascripts/bootstrap_additions.js.coffee +4 -0
  7. data/app/assets/javascripts/interchange/patients.js.coffee +3 -0
  8. data/app/assets/javascripts/interchange/physicians.js.coffee +3 -0
  9. data/app/assets/javascripts/mock/allergies.js.coffee +3 -0
  10. data/app/assets/javascripts/mock/appointments.js.coffee +3 -0
  11. data/app/assets/javascripts/mock/assignments.js.coffee +17 -0
  12. data/app/assets/javascripts/mock/chart_reviews.js.coffee +3 -0
  13. data/app/assets/javascripts/mock/comments.js.coffee +3 -0
  14. data/app/assets/javascripts/mock/conditions.js.coffee +3 -0
  15. data/app/assets/javascripts/mock/diagnoses.js.coffee +3 -0
  16. data/app/assets/javascripts/mock/documents.js.coffee +3 -0
  17. data/app/assets/javascripts/mock/employments.js.coffee +3 -0
  18. data/app/assets/javascripts/mock/encounters.js.coffee +3 -0
  19. data/app/assets/javascripts/mock/family_contacts.js.coffee +3 -0
  20. data/app/assets/javascripts/mock/family_histories.js.coffee +3 -0
  21. data/app/assets/javascripts/mock/guarantors.js.coffee +3 -0
  22. data/app/assets/javascripts/mock/insurance_plans.js.coffee +3 -0
  23. data/app/assets/javascripts/mock/lab_concepts.js.coffee +4 -0
  24. data/app/assets/javascripts/mock/lab_results.js.coffee +3 -0
  25. data/app/assets/javascripts/mock/locations.js.coffee +3 -0
  26. data/app/assets/javascripts/mock/medical_record_numbers.js.coffee +3 -0
  27. data/app/assets/javascripts/mock/metadata_keywords.js.coffee +3 -0
  28. data/app/assets/javascripts/mock/pharmacies.js.coffee +3 -0
  29. data/app/assets/javascripts/mock/phone_numbers.js.coffee +3 -0
  30. data/app/assets/javascripts/mock/physicians.js.coffee +3 -0
  31. data/app/assets/javascripts/mock/procedure_histories.js.coffee +3 -0
  32. data/app/assets/javascripts/mock/providers.js.coffee +14 -0
  33. data/app/assets/javascripts/mock/questions.js.coffee +3 -0
  34. data/app/assets/javascripts/mock/reference_range.js.coffee +3 -0
  35. data/app/assets/javascripts/mock/sections.js.coffee +3 -0
  36. data/app/assets/javascripts/mock/social_histories.js.coffee +3 -0
  37. data/app/assets/javascripts/mock/state_health_identifiers.js.coffee +3 -0
  38. data/app/assets/javascripts/mock/statistics.js.coffee +3 -0
  39. data/app/assets/javascripts/mock/test_assertions.js.coffee +3 -0
  40. data/app/assets/javascripts/mock/visit.js.coffee +3 -0
  41. data/app/assets/javascripts/mock/vitals_measurement.js.coffee +3 -0
  42. data/app/assets/javascripts/reference/data_elements.js.coffee +3 -0
  43. data/app/assets/javascripts/reference/data_lists.js.coffee +3 -0
  44. data/app/assets/javascripts/reference/data_sets.js.coffee +3 -0
  45. data/app/assets/stylesheets/application.css.scss +13 -0
  46. data/app/assets/stylesheets/bootstrap_and_overrides.css.scss +79 -0
  47. data/app/assets/stylesheets/forms.css.scss +67 -0
  48. data/app/assets/stylesheets/interchange/patients.css.scss +3 -0
  49. data/app/assets/stylesheets/interchange/physicians.css.scss +3 -0
  50. data/app/assets/stylesheets/mock/allergies.css.scss +3 -0
  51. data/app/assets/stylesheets/mock/appointments.css.scss +3 -0
  52. data/app/assets/stylesheets/mock/chart_reviews.css.scss +3 -0
  53. data/app/assets/stylesheets/mock/comments.css.scss +3 -0
  54. data/app/assets/stylesheets/mock/conditions.css.scss +3 -0
  55. data/app/assets/stylesheets/mock/diagnoses.css.scss +3 -0
  56. data/app/assets/stylesheets/mock/documents.css.scss +3 -0
  57. data/app/assets/stylesheets/mock/employments.css.scss +3 -0
  58. data/app/assets/stylesheets/mock/encounters.css.scss +3 -0
  59. data/app/assets/stylesheets/mock/family_contacts.css.scss +3 -0
  60. data/app/assets/stylesheets/mock/family_histories.css.scss +3 -0
  61. data/app/assets/stylesheets/mock/guarantors.css.scss +3 -0
  62. data/app/assets/stylesheets/mock/insurance_plans.css.scss +3 -0
  63. data/app/assets/stylesheets/mock/lab_concepts.css.scss +3 -0
  64. data/app/assets/stylesheets/mock/lab_results.css.scss +3 -0
  65. data/app/assets/stylesheets/mock/locations.css.scss +3 -0
  66. data/app/assets/stylesheets/mock/medical_record_numbers.css.scss +3 -0
  67. data/app/assets/stylesheets/mock/metadata_keywords.css.scss +3 -0
  68. data/app/assets/stylesheets/mock/pharmacies.css.scss +3 -0
  69. data/app/assets/stylesheets/mock/phone_numbers.css.scss +3 -0
  70. data/app/assets/stylesheets/mock/physicians.css.scss +3 -0
  71. data/app/assets/stylesheets/mock/procedure_histories.css.scss +3 -0
  72. data/app/assets/stylesheets/mock/providers.css.scss +3 -0
  73. data/app/assets/stylesheets/mock/questions.css.scss +3 -0
  74. data/app/assets/stylesheets/mock/reference_range.css.scss +3 -0
  75. data/app/assets/stylesheets/mock/sections.css.scss +3 -0
  76. data/app/assets/stylesheets/mock/social_histories.css.scss +3 -0
  77. data/app/assets/stylesheets/mock/state_health_identifiers.css.scss +3 -0
  78. data/app/assets/stylesheets/mock/statistics.css.scss +3 -0
  79. data/app/assets/stylesheets/mock/test_assertions.css.scss +3 -0
  80. data/app/assets/stylesheets/mock/visit.css.scss +3 -0
  81. data/app/assets/stylesheets/mock/vitals_measurement.css.scss +3 -0
  82. data/app/assets/stylesheets/reference/data_elements.css.scss +3 -0
  83. data/app/assets/stylesheets/reference/data_lists.css.scss +3 -0
  84. data/app/assets/stylesheets/reference/data_sets.css.scss +3 -0
  85. data/app/assets/stylesheets/scaffolds.css.scss +66 -0
  86. data/app/controllers/api/base_controller.rb +78 -0
  87. data/app/controllers/api/ion_orders_engine/order_by_id/order_by_id_controller.rb +3220 -0
  88. data/app/controllers/api/ion_orders_engine/order_profile/inpatient_order_profile_controller.rb +3156 -0
  89. data/app/controllers/application_controller.rb +25 -0
  90. data/app/controllers/crud/base_controller.rb +90 -0
  91. data/app/controllers/interchange/base_controller.rb +63 -0
  92. data/app/controllers/interchange/data_sets_controller.rb +40 -0
  93. data/app/controllers/interchange/exports_controller.rb +120 -0
  94. data/app/controllers/interchange/imports_controller.rb +141 -0
  95. data/app/controllers/reference/base_controller.rb +7 -0
  96. data/app/controllers/reference/data_lists_controller.rb +177 -0
  97. data/app/controllers/reference/data_options_controller.rb +147 -0
  98. data/app/controllers/reference/data_sets_controller.rb +160 -0
  99. data/app/helpers/application_helper.rb +389 -0
  100. data/app/helpers/error_messages_helper.rb +23 -0
  101. data/app/helpers/interchange/exports_helper.rb +9 -0
  102. data/app/helpers/interchange/imports_helper.rb +31 -0
  103. data/app/helpers/layout_helper.rb +40 -0
  104. data/app/helpers/reference/data_elements_helper.rb +2 -0
  105. data/app/helpers/reference/data_lists_helper.rb +2 -0
  106. data/app/helpers/reference/data_sets_helper.rb +2 -0
  107. data/app/views/interchange/common/_database_info.json.jbuilder +6 -0
  108. data/app/views/interchange/common/_metadata_keywords.json.jbuilder +13 -0
  109. data/app/views/interchange/common/_test_assertions.json.jbuilder +17 -0
  110. data/app/views/interchange/data_sets/_data_list.json.jbuilder +14 -0
  111. data/app/views/interchange/data_sets/_data_option.json.jbuilder +12 -0
  112. data/app/views/interchange/data_sets/_data_set.json.jbuilder +17 -0
  113. data/app/views/interchange/data_sets/_nested_data_list.json.jbuilder +12 -0
  114. data/app/views/interchange/data_sets/show.json.jbuilder +10 -0
  115. data/app/views/interchange/document_templates/_document_template.json.jbuilder +23 -0
  116. data/app/views/interchange/document_templates/_section.json.jbuilder +11 -0
  117. data/app/views/interchange/document_templates/show.json.jbuilder +10 -0
  118. data/app/views/interchange/exports/_export_summary.html.erb +49 -0
  119. data/app/views/interchange/exports/show.html.erb +35 -0
  120. data/app/views/interchange/imports/_import_summary.html.erb +72 -0
  121. data/app/views/interchange/imports/show.html.erb +37 -0
  122. data/app/views/layouts/_flashbar.html.erb +6 -0
  123. data/app/views/layouts/_navbar.html.erb +38 -0
  124. data/app/views/layouts/_protected_warning.html.erb +7 -0
  125. data/app/views/layouts/_root_model_layout.erb +33 -0
  126. data/app/views/layouts/application.html.erb +39 -0
  127. data/app/views/layouts/reference/data_sets.html.erb +5 -0
  128. data/app/views/reference/data_lists/_data_options.html.erb +31 -0
  129. data/app/views/reference/data_lists/_form.html.erb +23 -0
  130. data/app/views/reference/data_lists/edit.html.erb +6 -0
  131. data/app/views/reference/data_lists/index.html.erb +31 -0
  132. data/app/views/reference/data_lists/new.html.erb +6 -0
  133. data/app/views/reference/data_lists/show.html.erb +55 -0
  134. data/app/views/reference/data_options/_form.html.erb +23 -0
  135. data/app/views/reference/data_options/edit.html.erb +5 -0
  136. data/app/views/reference/data_options/index.html.erb +38 -0
  137. data/app/views/reference/data_options/new.html.erb +5 -0
  138. data/app/views/reference/data_options/show.html.erb +33 -0
  139. data/app/views/reference/data_sets/_form.html.erb +25 -0
  140. data/app/views/reference/data_sets/edit.html.erb +5 -0
  141. data/app/views/reference/data_sets/index.html.erb +40 -0
  142. data/app/views/reference/data_sets/new.html.erb +5 -0
  143. data/app/views/reference/data_sets/show.html.erb +38 -0
  144. data/config/application.rb +100 -0
  145. data/config/boot.rb +6 -0
  146. data/config/database.yml +25 -0
  147. data/config/environment.rb +5 -0
  148. data/config/environments/development.rb +42 -0
  149. data/config/environments/production.rb +64 -0
  150. data/config/environments/test.rb +35 -0
  151. data/config/initializers/backtrace_silencers.rb +7 -0
  152. data/config/initializers/extensions/active_record.rb +13 -0
  153. data/config/initializers/extensions/hash.rb +11 -0
  154. data/config/initializers/extensions/string.rb +15 -0
  155. data/config/initializers/inflections.rb +15 -0
  156. data/config/initializers/mime_types.rb +5 -0
  157. data/config/initializers/reference.rb +77 -0
  158. data/config/initializers/secret_token.rb +7 -0
  159. data/config/initializers/session_store.rb +8 -0
  160. data/config/initializers/simple_form.rb +142 -0
  161. data/config/initializers/simple_form_bootstrap.rb +45 -0
  162. data/config/initializers/wrap_parameters.rb +10 -0
  163. data/config/locales/en.yml +207 -0
  164. data/config/locales/simple_form.en.yml +26 -0
  165. data/config/mongo.yml +18 -0
  166. data/config/routes.rb +4 -0
  167. data/db/schema.rb +16 -0
  168. data/db/seeds.rb +66 -0
  169. data/lib/ion_orders_engine_mockingjay/engine.rb +13 -0
  170. data/lib/ion_orders_engine_mockingjay/version.rb +3 -0
  171. data/lib/ion_orders_engine_mockingjay.rb +4 -0
  172. data/lib/tasks/ion_orders_engine_mockingjay_tasks.rake +4 -0
  173. metadata +215 -0
@@ -0,0 +1,147 @@
1
+ class Reference::DataOptionsController < Reference::BaseController
2
+
3
+ before_filter :retrieve_data_list
4
+
5
+ # GET /reference/data_lists/:data_list_id/data_options
6
+ # GET /reference/data_lists/:data_list_id/data_options.json
7
+ def index
8
+ @data_options = @data_list.data_options
9
+ configure_breadcrumbs @data_list, :data_options
10
+
11
+ respond_to do |format|
12
+ format.html # index.html.erb
13
+ format.json { render json: @data_options }
14
+ end
15
+ end
16
+
17
+
18
+ # GET /reference/data_lists/:data_list_id/data_options/1
19
+ # GET /reference/data_lists/:data_list_id/data_options/1.json
20
+ def show
21
+ retrieve_data_option
22
+
23
+ respond_to do |format|
24
+ format.html # show.html.erb
25
+ format.json { render json: @data_option }
26
+ end
27
+ end
28
+
29
+
30
+ # GET /reference/data_lists/:data_list_id/data_options/new
31
+ # GET /reference/data_lists/:data_list_id/data_options/new.json
32
+ def new
33
+ @data_option = DataOption.new
34
+ configure_breadcrumbs @data_list, :data_option
35
+
36
+ respond_to do |format|
37
+ format.html # new.html.erb
38
+ format.json { render json: @data_option }
39
+ end
40
+ end
41
+
42
+
43
+ # GET /reference/data_lists/:data_list_id/data_options/1/edit
44
+ def edit
45
+ retrieve_data_option
46
+ end
47
+
48
+
49
+ # POST /reference/data_lists/:data_list_id/data_options
50
+ # POST /reference/data_lists/:data_list_id/data_options.json
51
+ def create
52
+ unless @data_list
53
+ raise 'No data_list could be retrieved for whom to associate the newly created DataOption'
54
+ end
55
+
56
+ @data_option = DataOption.new(params[:data_option])
57
+ @data_list.data_options << @data_option
58
+
59
+ respond_to do |format|
60
+ if @data_option.save
61
+ Reference::DataTypes.reload # Update all of our reference data, given the new DataOption
62
+
63
+ format.html { redirect_to [:reference, @data_list, @data_option],
64
+ notice: 'Data Option was successfully created.' }
65
+ format.json { render json: @data_option, status: :created, location: @data_option }
66
+ else
67
+ format.html do
68
+ # Set breadcrumbs again, otherwise they'd be lost on render of 'new' template:
69
+ configure_breadcrumbs @data_list, :data_option
70
+ render action: "new"
71
+ end
72
+ format.json { render json: @data_option.errors, status: :unprocessable_entity }
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ # PUT /reference/data_lists/:data_list_id/data_options/:id
79
+ # PUT /reference/data_lists/:data_list_id/data_options/:id.json
80
+ def update
81
+ retrieve_data_option
82
+
83
+ respond_to do |format|
84
+ if @data_option.update_attributes(params[:data_option])
85
+ Reference::DataTypes.reload # Update all of our reference data, given the updated DataOption
86
+
87
+ format.html { redirect_to [:reference, @data_list, @data_option],
88
+ notice: 'Data Option was successfully updated.' }
89
+ format.json { head :no_content }
90
+ else
91
+ format.html { render action: "edit" }
92
+ format.json { render json: @data_option.errors, status: :unprocessable_entity }
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ # DELETE /reference/data_lists/:data_list_id/data_options/1
99
+ # DELETE /reference/data_lists/:data_list_id/data_options/1.json
100
+ def destroy
101
+ retrieve_data_option
102
+ root_resource = @data_option.root_resource
103
+ @data_option.destroy
104
+ root_resource.export_update # Allow root resource to save update to disk
105
+ Reference::DataTypes.reload # Update all of our reference data, given the removed DataOption
106
+
107
+ respond_to do |format|
108
+ format.html { redirect_to [:reference, @data_list, :data_options],
109
+ notice: 'Data Option was successfully destroyed.' }
110
+ format.json { head :no_content }
111
+ end
112
+ end
113
+
114
+
115
+
116
+ private
117
+
118
+ # We retrieve the data_list implied by the current set of params.
119
+ def retrieve_data_list
120
+ return unless params[:data_list_id] # Nothing more to do if we don't have a data_list id.
121
+
122
+ @data_list = DataList.find(params[:data_list_id])
123
+
124
+ if @data_list
125
+ log_info "Found data_list with data_list_id: #{params[:data_list_id]}."
126
+ else
127
+ log_warn "Could not retrieve data_list with id: #{params[:data_list_id]}. The params were: #{params}"
128
+ end
129
+ end
130
+
131
+
132
+ def retrieve_data_option
133
+ @data_option = DataOption.find(params[:id])
134
+
135
+ unless @data_list
136
+ params[:data_list_id] = @data_option.data_list_id
137
+ retrieve_data_list
138
+ end
139
+
140
+ unless @data_option
141
+ log_warn "\nCould not retrieve data_option from data_list model with data_option id: #{params[:id]}. The params were: #{params}\n"
142
+ end
143
+
144
+ configure_breadcrumbs @data_option
145
+ end
146
+
147
+ end
@@ -0,0 +1,160 @@
1
+ class Reference::DataSetsController < Reference::BaseController
2
+
3
+ layout 'reference/data_sets' # we don't want to use the general layout that has a data_set sidebar to it
4
+
5
+ #before_filter :clear_data_set_sidebar
6
+
7
+ # Public: RESTful resource index operation. We additionally handle filtering the index based
8
+ # on any search parameters present.
9
+ #
10
+ # GET /reference/data_sets
11
+ # GET /reference/data_sets.json
12
+ def index
13
+ #params[:search] = nil if (params[:clear])
14
+ #search_string = params[:search]
15
+ #@data_sets = DataSet.search(search_string)
16
+ @data_sets = DataSet.all
17
+ configure_breadcrumbs :data_sets
18
+
19
+ respond_to do |format|
20
+ format.html # index.html.erb
21
+ format.json { render json: @data_sets }
22
+ end
23
+ end
24
+
25
+
26
+ # Public: RESTful resource show operation.
27
+ #
28
+ # GET /reference/data_sets/1
29
+ # GET /reference/data_sets/1.json
30
+ def show
31
+ retrieve_data_set
32
+
33
+ if @data_set
34
+ respond_to do |format|
35
+ format.html # show.html.erb
36
+ format.json { render json: @data_set }
37
+ end
38
+ else
39
+ redirect_to [:reference, :data_sets],
40
+ alert: "DataSet with id #{params[:id]} not found. You have been redirected to the DataSets listing."
41
+ end
42
+ end
43
+
44
+
45
+ # Public: RESTful resource new operation. We pre-fill the new DataSet with default options.
46
+ #
47
+ # GET /reference/data_sets/new
48
+ # GET /reference/data_sets/new.json
49
+ def new
50
+ @data_set = DataSet.new(DataSet.default_options)
51
+ configure_breadcrumbs :data_set
52
+
53
+ respond_to do |format|
54
+ format.html # new.html.erb
55
+ format.json { render json: @data_set }
56
+ end
57
+ end
58
+
59
+
60
+ # Public: RESTful resource edit operation.
61
+ #
62
+ # GET /reference/data_sets/1/edit
63
+ def edit
64
+ retrieve_data_set
65
+ end
66
+
67
+
68
+ # Public: RESTful resource create operation.
69
+ #
70
+ # POST /reference/data_sets
71
+ # POST /reference/data_sets.json
72
+ def create
73
+ @data_set = DataSet.new(params[:data_set])
74
+
75
+ respond_to do |format|
76
+ if @data_set.save
77
+ # Note: we don't reload reference data yet, since a new DataSet has no content at first creation.
78
+ format.html { redirect_to [:reference, @data_set], notice: 'Data Set was successfully created.' }
79
+ format.json { render json: @data_set, status: :created, location: @data_set }
80
+ else
81
+ format.html do
82
+ # Set breadcrumbs again, otherwise they'd be lost on render of 'new' template:
83
+ configure_breadcrumbs :data_set
84
+ render action: "new"
85
+ end
86
+ format.json { render json: @data_set.errors, status: :unprocessable_entity }
87
+ end
88
+ end
89
+ end
90
+
91
+
92
+ # Public: RESTful resource update operation.
93
+ #
94
+ # PUT /reference/data_sets/1
95
+ # PUT /reference/data_sets/1.json
96
+ def update
97
+ retrieve_data_set
98
+
99
+ respond_to do |format|
100
+ if @data_set.update_attributes(params[:data_set])
101
+ Reference::DataTypes.reload # Update all of our reference data, given the updated DataSet
102
+ format.html { redirect_to [:reference, @data_set], notice: 'Data Set was successfully updated.' }
103
+ format.json { head :no_content }
104
+ else
105
+ format.html { render action: "edit" }
106
+ format.json { render json: @data_set.errors, status: :unprocessable_entity }
107
+ end
108
+ end
109
+ end
110
+
111
+
112
+ # Public: RESTful resource destroy operation.
113
+ #
114
+ # DELETE /reference/data_sets/1
115
+ # DELETE /reference/data_sets/1.json
116
+ def destroy
117
+ retrieve_data_set
118
+ # Create the path to the reference file associated with this about to be deleted data set,
119
+ # so that we can delete it:
120
+ reference_filename = File.join(Rails.root, "data/reference/DataSets/#{@data_set.name}.js") # TODO: DRY up these path references to somewhere central
121
+ @data_set.destroy
122
+ # Now that the DataSet has been removed from the database, go ahead and delete the
123
+ # reference file:
124
+ File.delete(reference_filename) if File.exists?(reference_filename)
125
+ Reference::DataTypes.reload # Update all of our reference data, given the destroyed DataSet
126
+
127
+ respond_to do |format|
128
+ format.html { redirect_to [:reference, :data_sets], notice: 'Data Set was successfully destroyed.' }
129
+ format.json { head :no_content }
130
+ end
131
+ end
132
+
133
+
134
+
135
+ private
136
+
137
+ # Internal: We don't want to show duplicate information in the sidebar about a data_set
138
+ # when a user is interacting with this data_set specific controller.
139
+ #def clear_data_set_sidebar
140
+ # # Reset the sidebar to have no current data_set:
141
+ # @data_set = nil
142
+ # set_session_data_set
143
+ # update_recent_data_sets
144
+ #end
145
+
146
+
147
+ # Internal: Retrieves the DataSet model instance from params. Also updates breadcrumb
148
+ # navigation, reflecting the retrieved data_set. We also update the recent data_sets
149
+ # list such that this data_set is at the top of a reverse chronological list.
150
+ def retrieve_data_set
151
+ begin
152
+ @data_set = DataSet.find(params[:id])
153
+ configure_breadcrumbs @data_set
154
+ #update_recent_data_sets
155
+ rescue Exception => e
156
+ log_error "Couldn't retrieve data_set requested. Exception: #{e}"
157
+ end
158
+ end
159
+
160
+ end
@@ -0,0 +1,389 @@
1
+ module ApplicationHelper
2
+
3
+ # ---------- Reformatting ----------
4
+
5
+ # Replace newlines with HTML break tags to achieve the equivalent
6
+ # intention, targeting this web UI.
7
+ def format_newlines(text_with_newlines)
8
+ text_with_newlines.gsub('\n', '<br/>') if text_with_newlines
9
+ end
10
+
11
+ # Shows the last four characters of the provided value.
12
+ # Typically used to truncate unsightly Mongo DB BSON IDs.
13
+ def truncated_id(full_id)
14
+ "...#{full_id.to_s[-5..-1]}" if full_id
15
+ end
16
+
17
+
18
+ # A wrapper for link_to that uses a truncated value of the provided
19
+ # full text, surfacing the full_text in a tooltip that shows on-hover.
20
+ def truncated_link_to(full_text, path, html_options={})
21
+ tooltip_options = {rel: 'tooltip', title: full_text }
22
+ html_options.merge! tooltip_options
23
+ link_to truncated_id(full_text), path, html_options
24
+ end
25
+
26
+
27
+ # ---------- Headings: General ----------
28
+
29
+ # [model_class] An actual class, or a String title.
30
+ def show_resource_heading(model_class, resource_summary=nil)
31
+ default_heading =
32
+ if model_class.instance_of?(String)
33
+ model_class.titleize
34
+ else
35
+ model_class.model_name.human.titleize
36
+ end
37
+
38
+ optional_newline = default_heading.length > 15 ? '<br/>' : ''
39
+ default_heading.concat(" #{optional_newline}<small>#{resource_summary}</small>") if resource_summary
40
+ raw default_heading
41
+ end
42
+
43
+
44
+ def index_resource_heading(model_class, additional_text=nil)
45
+ default_heading = "#{model_class.model_name.human.pluralize.titleize}"
46
+ default_heading.concat(": #{additional_text}") if additional_text
47
+ t '.title', default: default_heading
48
+ end
49
+
50
+
51
+ def new_resource_heading(model_class)
52
+ t '.title', default: t('helpers.titles.new', model: model_class.model_name.human,
53
+ default: "New #{model_class.model_name.human.titleize}")
54
+ end
55
+
56
+
57
+ def edit_resource_heading(model_class)
58
+ t '.title', default: t('helpers.titles.edit', model: model_class.model_name.human,
59
+ default: "Edit #{model_class.model_name.human.titleize}")
60
+ end
61
+
62
+
63
+ def actions_table_heading
64
+ t '.actions', default: t("helpers.actions")
65
+ end
66
+
67
+
68
+
69
+ # ---------- Show Resource ----------
70
+
71
+ # Call this with a block, to which we'll yield a helper object, much like
72
+ # you would form_for or simple_form_for. We instantiate a ResourceDisplayHelper
73
+ # and yield it into the block, so like you would in building a form for
74
+ # editing an attribute, you have now have a convenient helper to show an attribute.
75
+ def display_for(model_object)
76
+ helper = ResourceDisplayHelper.new(model_object, self)
77
+ yield helper
78
+ end
79
+
80
+
81
+
82
+ # ---------- Button Links: General ----------
83
+
84
+ def export_button(model)
85
+ render partial: 'mock/common/export_button', locals: {model: model}
86
+ end
87
+
88
+
89
+ def search_submit_button_tag
90
+ submit_tag t('.search', default: t("helpers.links.search")),
91
+ name: nil, class: 'btn btn-primary'
92
+ end
93
+
94
+
95
+ def clear_form_submit_button_tag
96
+ submit_tag 'Clear', name: 'clear', class: 'btn btn-primary'
97
+ end
98
+
99
+
100
+ # Creates a submit button for the given form and model object passed in, handling the
101
+ # logic of 'Create' vs. 'Update' in the button title. We also handle titleizing the model name.
102
+ def submit_button(form, model_instance, singularize = true)
103
+ if singularize
104
+ resource_name = model_instance.class.model_name.underscore.singularize.humanize.titleize.split('/').last
105
+ else
106
+ resource_name = model_instance.class.model_name.underscore.humanize.titleize.split('/').last
107
+ end
108
+ operation_title = if model_instance.new_record? then 'Create' else 'Update' end
109
+ button_title = "#{operation_title} #{resource_name}"
110
+ form.button :submit, value: button_title, class: 'btn-primary'
111
+ end
112
+
113
+ # Generates a Back button, which is a back arrow followed by text inferred from the mandatory parameter
114
+ # provided, such as: [:mock, @commentable, :comments]
115
+ # We handle all the translate lookup and the CSS.
116
+ def back_button_link(path_as_array, options={})
117
+ last_element = path_as_array.last
118
+
119
+ # Are we dealing with a Ruby Symbol?
120
+ if last_element.is_a?(Symbol)
121
+ resource_name = last_element.to_s.humanize
122
+ else
123
+ resource_name = last_element.class.model_name.human
124
+ if last_element.is_singular_child_resource?
125
+ # YES. So we need to swap it out in the path array with
126
+ # a singular symbol of itself instead, so that when passed to url_for(),
127
+ # a correct URL path will be constructed.
128
+ # TODO: This has been used elsewhere; DRY it up by making this logic available somewhere common
129
+ path_as_array[-1] = path_as_array.last.class.to_s.tableize.singularize.to_sym
130
+ end
131
+ end
132
+
133
+ provided_resource_name = options[:resource_name] || resource_name
134
+
135
+ # Should we put an 'All' in front of the resource name?
136
+ if resource_name.plural?
137
+ button_text = "All #{provided_resource_name.pluralize}"
138
+ else
139
+ button_text = provided_resource_name
140
+ end
141
+
142
+
143
+ # Are we dealing with a non-nested resource path that isn't going back
144
+ # to the root? We always prefer using a parent/child nesting route.
145
+ if path_as_array.length == 2 && !root_model_titles.include?(resource_name.singularize.titleize)
146
+ Rails.logger.debug "ROOT_MODEL_NAMES did not include: #{resource_name.singularize.titleize}"
147
+ # We need to insert into the path as array, a parent object to the last element.
148
+ # e.g. if we received the array:
149
+ # [:mock, @phoneable]
150
+ # we would effectively convert it to:
151
+ # [:mock, <parent of @phoneable>, @phoneable]
152
+ path_as_array.insert(1, last_element.parent_resource_model_object)
153
+ end
154
+
155
+ # Build the actual link that will look like a button, thanks to CSS:
156
+ link_to( raw("&larr; #{button_text.titleize}"), path_as_array, class: 'btn')
157
+ end
158
+
159
+
160
+ # Generates the link_to for the Cancel button.
161
+ def cancel_button(path_as_array)
162
+ modifiable_object = resolved_last_object_from_path(path_as_array)
163
+
164
+ if modifiable_object && modifiable_object.new_record?
165
+ # YES: So turn the last element from a model object into a plural symbol.
166
+ last_element = path_as_array.last
167
+ cancel_path = path_as_array - [last_element]
168
+ cancel_path << last_element.class.model_name.tableize.gsub('/', '_').to_sym
169
+ else
170
+ cancel_path = path_as_array
171
+ end
172
+
173
+ link_to 'Cancel', cancel_path, class: 'btn'
174
+ end
175
+
176
+
177
+ # We display a button that says 'New <resource name>'. By definition, the array passed
178
+ # in will have the last element being a symbol representing the new thing to be created.
179
+ def new_button_link(path_as_array, options={})
180
+ resource_name = options[:resource_name] || path_as_array.last.to_s.humanize
181
+ operation_title = if options[:operation_title] then options[:operation_title] else 'New' end
182
+ button_text = "#{operation_title} #{resource_name.titleize}"
183
+
184
+ css_classes = 'btn btn-primary'
185
+ css_classes.concat(' btn-mini') if options[:as_mini]
186
+ css_classes.concat(' ').concat(options[:class]) if options[:class]
187
+
188
+ options = { class: css_classes }
189
+ parent_resource = path_as_array[-2] unless path_as_array.length < 2
190
+
191
+ # Do we need to indicate with a confirmation that the parent resource we'd create under, is protected?
192
+ if parent_resource && !parent_resource.is_a?(Symbol) && parent_resource.marked_as_protected?
193
+ options[:data] = { confirm: "This would add a new #{resource_name.titleize} to a PROTECTED record. Are you sure?" }
194
+ end
195
+
196
+ link_to button_text, path_as_array, options
197
+ end
198
+
199
+
200
+ # Variant of the new_button_link, but uses the title prefix 'Add Another' instead of 'New'
201
+ def add_another_button_link(path_as_array, options={})
202
+ options.merge!({ operation_title: 'Add Another' })
203
+ new_button_link(path_as_array, options)
204
+ end
205
+
206
+
207
+ # We assume the last element in the provided array is a Symbol, since this is a variant of New.
208
+ # We'll use that last element to be part of the title of the button.
209
+ def add_button_link(path_as_array, options={})
210
+ css_classes = 'btn btn-primary'
211
+ css_classes.concat(' btn-mini') if options[:as_mini]
212
+ resource_name = path_as_array.last.to_s.humanize.capitalize_words
213
+ button_text = "Add #{resource_name}"
214
+ link_to( button_text, path_as_array, class: css_classes)
215
+ end
216
+
217
+
218
+ # In the options hash, pass in as_mini: true if you want the smaller version.
219
+ def show_button_link(path_as_array, options={})
220
+ css_classes = 'btn btn-success '
221
+ css_classes.concat options[:class] if options[:class]
222
+ css_classes.concat(' btn-mini') if options[:as_mini]
223
+ button_text = options[:title] || t('.show', default: t("helpers.links.show"))
224
+ link_to button_text, path_as_array, class: css_classes
225
+ end
226
+
227
+
228
+ # In the options hash, pass in as_mini: true if you want the smaller version.
229
+ def go_button_link(path_as_array, options={})
230
+ css_classes = 'btn btn-success'
231
+ css_classes.concat(' btn-mini') if options[:as_mini]
232
+ display_title = options[:title] || 'Go'
233
+ link_to display_title, path_as_array, class: css_classes
234
+ end
235
+
236
+
237
+ # In the options hash, pass in as_mini: true if you want the smaller version.
238
+ def edit_button_link(path_as_array, options={})
239
+ css_classes = 'btn'
240
+ css_classes.concat(' btn-mini') if options[:as_mini]
241
+ display_title = t('.edit', default: t("helpers.links.edit"))
242
+ options = { class: css_classes }
243
+
244
+ # Determine whom the actual editable model object is, so we can determine if it
245
+ # claims to be marked as protected.
246
+ modifiable_object = resolved_last_object_from_path(path_as_array)
247
+ options[:data] = { confirm: 'This is a PROTECTED record. Are you sure?' } if modifiable_object.marked_as_protected?
248
+
249
+ link_to display_title, path_as_array, options
250
+ end
251
+
252
+
253
+ # In the options hash, pass in as_mini: true if you want the smaller version.
254
+ def destroy_button_link(path_as_array, options={})
255
+ css_classes = 'btn btn-danger'
256
+ css_classes.concat(' btn-mini') if options[:as_mini]
257
+
258
+ modifiable_object = resolved_last_object_from_path(path_as_array)
259
+ resource_name = modifiable_object.class.model_name.human.capitalize_words
260
+ default_confirmation_msg = "Are you sure you'd like to delete this #{resource_name}?"
261
+
262
+ if modifiable_object.marked_as_protected?
263
+ default_confirmation_msg.concat " This is a PROTECTED record."
264
+ end
265
+
266
+ link_to t('.destroy', default: t("helpers.links.destroy")),
267
+ path_as_array,
268
+ method: :delete,
269
+ data: { confirm: t('.confirm', default: t("helpers.links.confirm", default: default_confirmation_msg)) },
270
+ class: css_classes
271
+ end
272
+
273
+
274
+ # Public: In the options hash, you can provide a :class key to specify a string of additional
275
+ # CSS classes to use. For example, to have the button right aligned:
276
+ #
277
+ # {class: 'pull-right'}
278
+ #
279
+ # Returns String of HTML command to insert a link.
280
+ def view_api_response_button_link(path, options={})
281
+ css_classes = 'btn btn-info '
282
+ css_classes.concat(options[:class]) if options[:class]
283
+ title = options[:title] || 'View API Response'
284
+ link_to title, path, target: 'API Window', rel: 'tooltip', title: path, class: css_classes
285
+ end
286
+
287
+
288
+ def view_automation_data_button_link(path, options={})
289
+ css_classes = 'btn btn-info '
290
+ css_classes.concat(options[:class]) if options[:class]
291
+ title = options[:title] || 'View Automation Data'
292
+ link_to title, path, target: 'Data Window', rel: 'tooltip', title: path, class: css_classes
293
+ end
294
+
295
+
296
+ def view_content_button_link(path, options={})
297
+ css_classes = 'btn btn-info '
298
+ css_classes.concat(options[:class]) if options[:class]
299
+ title = options[:title] || 'Show'
300
+ tooltip_title = options[:tooltip_title] || 'View content in new tab'
301
+ link_to title, path, target: 'Content Window', rel: 'tooltip', title: tooltip_title, class: css_classes
302
+ end
303
+
304
+
305
+ # Public: This inserts a mini button entitled 'Modify List' inside a nested div structure that mimics our
306
+ # layout into rows and columns, per Twitter Bootstrap. The button is actually a styled hyperlink.
307
+ # Since the Twitter Bootstrap layout we have already adopted is rather tight, we don't have a good way to include
308
+ # a button to the side of an input form control. By default, anything we add goes to the next line.
309
+ #
310
+ # In the case of our modify list button, being on the next line would look out of place. So, although
311
+ # we are technically on the next line, we employ some inline CSS (via the 'style') attribute, to float
312
+ # our button back into the ideal position (only ever obscured if the user makes the browser window really tiny).
313
+ #
314
+ # reference_class - The Class object for the reference list we're making available for modification.
315
+ # An example would be Reference::LabGroup or Reference::AllergyReactionType.
316
+ # options - An optional Hash of values. Keys accepted:
317
+ # :class - A String of additional CSS classes to include for the underlying link.
318
+ # :tooltip_title - A String to override the tooltip shown when the user hovers over the
319
+ # button we render.
320
+ def modify_reference_list(reference_class, options = {})
321
+ root_data_list = reference_class.root_data_list
322
+
323
+ unless root_data_list
324
+ Rails.logger.debug "#{self.class.name} modify_reference_list(): Could not retrieve root_data_list. Skipping insertion of option."
325
+ return nil
326
+ end
327
+
328
+ data_set = root_data_list.data_listable
329
+ css_classes = 'btn btn-info btn-mini'
330
+ css_classes.concat(options[:class]) if options[:class]
331
+ tooltip_title = options[:tooltip_title] || "Manage the reference #{root_data_list.display_name} list in a new tab"
332
+
333
+ # Build the hyperlink, styled as a button.
334
+ # TODO: Move the inline style to actual CSS and then just refer to it with a CSS class
335
+ value = link_to 'Modify List', [:reference, data_set, root_data_list],
336
+ target: 'Reference Window',
337
+ rel: 'tooltip',
338
+ title: tooltip_title,
339
+ class: css_classes,
340
+ style: 'float: top; margin-top: -90px; margin-left: 10px'
341
+
342
+ # Now render the partial that has some templated DIV structures into which we'll insert the 'Modify List' button:
343
+ render partial: 'mock/common/modify_reference_list', locals: {value: value}
344
+ end
345
+
346
+
347
+
348
+ # ---------- Button Links: Resource Specific ----------
349
+
350
+ def back_button_to_patient
351
+ back_button_link [:mock, @patient]
352
+ end
353
+
354
+
355
+ # ---------- General Utilities ----------
356
+
357
+ # Since some path arrays for resources can have a singular symbol at the end to indicate
358
+ # a singular resource, this method checks for that and backs up a level to invoke that
359
+ # resource symbol as a method on the preceding object (presumably the parent) to ultimately
360
+ # get a handle to the object in question.
361
+ def resolved_last_object_from_path(path_as_array)
362
+ if path_as_array.last.is_a?(Symbol) && path_as_array.size > 2
363
+ # YES: A symbol in the last position means we must be editing a singular resource.
364
+ # We'll retrieve that resource by asking the object preceding it for the relation
365
+ # given by that last element (the symbol). E.g. if we're given a path_as_array of
366
+ # [:edit, :mock, @chart_reviewable, :chart_review], then we'll call
367
+ # @chart_reviewable.send(:chart_review) to get at the ChartReview singular object.
368
+ path_as_array[-2].send(path_as_array.last)
369
+ else
370
+ path_as_array.last
371
+ end
372
+ end
373
+
374
+
375
+ # Determines which of our models are root resources. We then return an Array of humanized model
376
+ # class titles for these.
377
+ def root_model_titles
378
+ Rails.application.eager_load! # Needed to ensure all models are loaded for our asking them if they are root resources.
379
+
380
+ all_model_classes = ActiveRecord::Base.descendants
381
+ root_model_classes = all_model_classes.select { |model_class| model_class.included_modules.include? Mock::RootModelConcern }
382
+ names = root_model_classes.collect { |model_class| model_class.to_s.titleize }
383
+ Rails.logger.debug "ApplicationHelper root_model_titles(): Returning #{names}"
384
+ names
385
+ end
386
+
387
+
388
+
389
+ end