quick_search-core 0.1.1 → 0.2.0

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 (136) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -6
  3. data/app/assets/javascripts/quick_search.js.erb +9 -0
  4. data/app/assets/javascripts/quick_search/appstats.js.erb +73 -0
  5. data/app/assets/javascripts/quick_search/appstats_best_bets.js.erb +905 -0
  6. data/app/assets/javascripts/quick_search/appstats_clicks_overview.js.erb +719 -0
  7. data/app/assets/javascripts/quick_search/appstats_general_statistics.js.erb +908 -0
  8. data/app/assets/javascripts/quick_search/appstats_sessions_details.js.erb +660 -0
  9. data/app/assets/javascripts/quick_search/appstats_sessions_overview.js.erb +481 -0
  10. data/app/assets/javascripts/quick_search/appstats_spelling_suggestions.js.erb +902 -0
  11. data/app/assets/javascripts/quick_search/appstats_top_searches.js.erb +633 -0
  12. data/app/assets/javascripts/quick_search/event_tracking.js.erb +22 -33
  13. data/app/assets/javascripts/quick_search/xhr_search.js +7 -3
  14. data/app/assets/stylesheets/quick_search/appstats.scss +148 -0
  15. data/app/assets/stylesheets/quick_search/quick_search.scss +0 -16
  16. data/app/controllers/concerns/quick_search/doi_trap.rb +1 -1
  17. data/app/controllers/quick_search/appstats_controller.rb +267 -144
  18. data/app/controllers/quick_search/logging_controller.rb +165 -0
  19. data/app/controllers/quick_search/search_controller.rb +1 -23
  20. data/app/controllers/quick_search/typeahead_controller.rb +48 -0
  21. data/app/models/event.rb +6 -0
  22. data/app/models/search.rb +7 -0
  23. data/app/models/session.rb +9 -0
  24. data/app/searchers/quick_search/best_bets_searcher.rb +1 -1
  25. data/app/views/layouts/quick_search/_google_analytics.html.erb +4 -9
  26. data/app/views/layouts/quick_search/_search_form.html.erb +2 -2
  27. data/app/views/layouts/quick_search/application.html.erb +4 -0
  28. data/app/views/quick_search/appstats/_date_range.html.erb +14 -13
  29. data/app/views/quick_search/appstats/_graph_best_bets.html.erb +6 -0
  30. data/app/views/quick_search/appstats/_graph_clicks_overview.html.erb +12 -0
  31. data/app/views/quick_search/appstats/_graph_general_statistics.html.erb +19 -0
  32. data/app/views/quick_search/appstats/_graph_sessions_details.html.erb +19 -0
  33. data/app/views/quick_search/appstats/_graph_sessions_overview.html.erb +9 -0
  34. data/app/views/quick_search/appstats/_graph_spelling_suggestions.html.erb +6 -0
  35. data/app/views/quick_search/appstats/_graph_top_searches.html.erb +6 -0
  36. data/app/views/quick_search/appstats/_menu.html.erb +16 -3
  37. data/app/views/quick_search/appstats/_sessions_details_device_filters.html.erb +9 -0
  38. data/app/views/quick_search/appstats/_sessions_details_location_filters.html.erb +9 -0
  39. data/app/views/quick_search/appstats/_sessions_overview_graph_filters.html.erb +9 -0
  40. data/app/views/quick_search/appstats/clicks_overview.html.erb +3 -14
  41. data/app/views/quick_search/appstats/index.html.erb +3 -23
  42. data/app/views/quick_search/appstats/sessions_details.html.erb +9 -0
  43. data/app/views/quick_search/appstats/sessions_overview.html.erb +9 -0
  44. data/app/views/quick_search/appstats/top_searches.html.erb +3 -32
  45. data/app/views/quick_search/appstats/top_spot.html.erb +7 -7
  46. data/app/views/quick_search/search/_module_with_paging.html.erb +1 -1
  47. data/app/views/quick_search/search/_result_title.html.erb +1 -1
  48. data/config/quicksearch_config.yml.example +3 -0
  49. data/config/routes.rb +31 -3
  50. data/db/migrate/20161201141003_create_sessions.rb +12 -0
  51. data/db/migrate/20161201142811_change_event_columns.rb +11 -0
  52. data/db/migrate/20161201143901_add_session_id_to_searches.rb +5 -0
  53. data/db/migrate/20161212192454_add_date_string_columns.rb +11 -0
  54. data/db/seeds.rb +83 -7
  55. data/lib/generators/quick_search/templates/quick_search_typeahead.js +253 -0
  56. data/lib/generators/quick_search/typeahead_generator.rb +162 -0
  57. data/lib/quick_search/engine.rb +1 -0
  58. data/lib/quick_search/version.rb +1 -1
  59. data/test/dummy/db/schema.rb +25 -6
  60. data/test/dummy/log/benchmark.log +121 -241
  61. data/test/dummy/log/development.log +236 -0
  62. data/test/dummy/tmp/cache/assets/sprockets/v3.0/0b/0bXp2nnjPLNuYQRAMo1RkhNr8RSC8vqZo_7soo0XZTE.cache +1 -0
  63. data/test/dummy/tmp/cache/assets/sprockets/v3.0/3p/3pAfj3gt9c9rLmOrDkMvW2r6Swm5YhuGQ1EN3va9LDE.cache +6 -0
  64. data/test/dummy/tmp/cache/assets/sprockets/v3.0/3r/3r7qg-LCIcD5882b6GKgRTZycpAlhoSNJccVH06yRCQ.cache +3 -0
  65. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{UA/UAOIipK_ejTAUFI6XxASoweyUiC3t64VfVzV-MfsFD8.cache → 4h/4hLiHzJdffGLMZCeIkbisOdFQSyqs54YkoZpBpGotVk.cache} +0 -0
  66. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Hr/Hr-kCuPY72nIKAdnsDTz9JqXd_z1WL6FSGMAq4HppZg.cache → 5Y/5Yh8GnSzywqhuMWMloKnL9FnuIxa9rBw6hN2Ecv0urw.cache} +0 -0
  67. data/test/dummy/tmp/cache/assets/sprockets/v3.0/8h/8hHsBZ0Il3GVKNj0HgTh-s-XpPVkHrcSY0EJ4v548sk.cache +4 -0
  68. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{fI/fInu_Gja7ik39t207tqj4CtlL0akQRbjD2T7qEtd0zE.cache → 8n/8nKAboU_CeVIX30-Q9BtSV5TXdE07WU8hO0OQ0N3KOs.cache} +0 -0
  69. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{dz/dzCaa80YgyvJINTgsyrVhKv9UQ1OC82GfAsA-IP96iQ.cache → Af/Afug8duevWkZFPkOMnZ5z_IbRT6JMZo4jw1QFmLiXXA.cache} +0 -0
  70. data/test/dummy/tmp/cache/assets/sprockets/v3.0/C2/C24SLDoUbdiHRmPZx5lIZ3XPXmn9FDq7j7gZmbpDtcE.cache +1 -0
  71. data/test/dummy/tmp/cache/assets/sprockets/v3.0/CH/CHuDjj47dHGqRD3uN1JNwnlFyjjEKB09KR6WVsLj2Do.cache +3 -0
  72. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ci/Cif3NOwhu5i6Qm3iRv2gNJLi_cu8yDVz0Nrq8TZu1tc.cache +3 -0
  73. data/test/dummy/tmp/cache/assets/sprockets/v3.0/FQ/FQWd8V-Pek1LBAfW9vzcG-FpWySsPRhMVzH9DlPxLWU.cache +1 -0
  74. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fa/FaYEz8CfLTkxVZvnbgKGvJMhhBwNvEgsZgUwaHNRlaQ.cache +0 -0
  75. data/test/dummy/tmp/cache/assets/sprockets/v3.0/IA/IALQq6ICbs3VBSRsaUmGuN73Qv5wDfWTP86VmMh_sVs.cache +0 -0
  76. data/test/dummy/tmp/cache/assets/sprockets/v3.0/K1/K1jnTrW-_s64kqCA6fnoQ-ID-rDaGX34J-TNPyzDbLs.cache +1 -0
  77. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Mz/MzXE1Go_GKyu6AvJPhw394BtPM_jVTf0hMwobBi15tk.cache +1 -0
  78. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Os/OsIhoBDw5N2AWGQ-EMK79tgwPS1AC6Dy_gMSJdOv2Ss.cache +0 -0
  79. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{B5/B5ptGSZGmgHvoK2UDCAtpMhWxJEKxKFhyL9ACeBfzQk.cache → PC/PCth9nzoRrp5GI3Ut8FxlGpXjH63V7k2p4PRwfyu2sQ.cache} +0 -0
  80. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pw/Pw3Jv2p7MsQz6pttCZig6VMVQ30sRyIDRS-2nM32yqY.cache +3 -0
  81. data/test/dummy/tmp/cache/assets/sprockets/v3.0/RI/RIOgtcuvLAJZl62RvAzqine3jCO3i2qyhswiW2G1bw8.cache +3 -0
  82. data/test/dummy/tmp/cache/assets/sprockets/v3.0/R_/R_6WhfFaPUAOAFfFd4bgUonI5aB4Fa6iOMY2J6G3U98.cache +4 -0
  83. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pj/pjJDYrBipDo6Tr9_-W4UDzfZZ4UPTy9YpXrBQFRXnlo.cache → S3/S3gPdA-Zqya5r6wNhnlwqGV3B3-GDaA8i1fL_jo66AI.cache} +0 -0
  84. data/test/dummy/tmp/cache/assets/sprockets/v3.0/SS/SS3eYrFE6ghi5G_3POW760Y4BWo5OAaK5QjDrRGXOcs.cache +1 -0
  85. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{jj/jjdQCKZsewws2eRP7b2AVxRMvseOp8djjlDkB8UOtac.cache → Sq/SqjdxmYsdurpx9xk1ks32WEtf3D9_2BysE7RMxnOlmU.cache} +1 -1
  86. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{os/os0qWv3yDfep0e7vVSGTgfn_n3xc4C4QZgmMzLQn0Ks.cache → Ta/TaJnQ_l0sfSsDOyVoi-S-KZQ6vIwzBhmS6hmNA_n8ug.cache} +0 -0
  87. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{o6/o6ZQbq1aBFuVrE2xLbSbyZH2736sWM3Yj4ky9chT1bI.cache → X_/X_CxFXEdZo2C_in7FopAuAbplHn6W_V0SXyVQAMnTzI.cache} +0 -0
  88. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{sR/sRU-UT8qK_38kkiFDXKBPogO1oOZuSvJFH-pgqPL_Ms.cache → Yh/YhRWll6bzgYE6Dmc5fVKbHyv5om4y3-27UrWeUbQcGk.cache} +0 -0
  89. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{OD/ODHapE0li3WI1laVJoksoI5nmQd-8dDJXq_VxS4XefE.cache → _u/_uiA10I5HyJR94Tbc4a06CzdrQCAXX7Iz86WS5PKDQo.cache} +0 -0
  90. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ai/ainCVF4dxXf85KoOLUSHvMMGg0qBNc7Vg-s-9v2ENJI.cache +4 -0
  91. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cQ/cQqt0ri9GFvVnIs1pJUugIJs5tDuGQMMntW5CwpK6YY.cache +1 -0
  92. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{1n/1nStVaWIQEwAlksUpB1fInwq6v3TikPvuRaSwwCnCLQ.cache → e0/e0Y2Gz8ftaW2O0RjoN2iWguitI-JQZckScAZqlQYkng.cache} +0 -0
  93. data/test/dummy/tmp/cache/assets/sprockets/v3.0/iH/iHnlNNY3rfdbVqt8LZBfcDQYONR8dA8LmxA9fv5paro.cache +2 -0
  94. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{F0/F0oWBwLHpGFYNNtnGav-dJFH8rMDpNA5L8_aWm5Wq34.cache → ir/irxgIDPIY6Wz6fHWYp1dIrqAT1_8oa6-oiwqbFE_e-w.cache} +0 -0
  95. data/test/dummy/tmp/cache/assets/sprockets/v3.0/kn/knUtyVrg7nMIPldZa4MHhe7cC9eMchLZS4mc5HDWgDY.cache +1 -0
  96. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ks/ks4DoIuUV6oUzoiXoPh7sW1k5ExNoUkR7ICjwuRnAT0.cache +1 -0
  97. data/test/dummy/tmp/cache/assets/sprockets/v3.0/m3/m375QQakjXd_2Trpvdot-i90nmeCCh0HWtzS66ZvxUU.cache +1 -0
  98. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rQ/rQ_FgYkT2hdw9A6XmJKGgVb2dMtCrWWHwtS0X1_kdl0.cache +1 -0
  99. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pw/pwiIhcWPwTuy5Miz5zqOQGYFx-K3TbaCVQ6ls7EBkk0.cache → rU/rUqFWwHqrT5jeIFCEezOPsMMZiAU7ri6RKBGS2ezAfg.cache} +0 -0
  100. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pO/pO8hHVwybv1ZJBdPa2YC6bjqmk020OYFl85TYxtmrWQ.cache → rq/rqf5-J6k_zLc9ZlUgMj28nviKtRsko3-iEp_m_uNeY0.cache} +0 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  107. metadata +143 -119
  108. data/app/assets/javascripts/quick_search/appstats.js +0 -8
  109. data/app/views/quick_search/appstats/_click_count_table.html.erb +0 -23
  110. data/app/views/quick_search/appstats/_top_spot_report_table.html.erb +0 -33
  111. data/app/views/quick_search/appstats/module_click_detail.html.erb +0 -32
  112. data/app/views/quick_search/appstats/top_spot_detail.html.erb +0 -35
  113. data/test/dummy/tmp/cache/assets/sprockets/v3.0/0_/0_w_ydOOEFQOoETxJa-IxKppQocaiDwM5V08djCPYso.cache +0 -3
  114. data/test/dummy/tmp/cache/assets/sprockets/v3.0/3m/3mWfBeEpm_bJvaPQZYvnnAVtE_2helOWh_Tv-cEflrk.cache +0 -5
  115. data/test/dummy/tmp/cache/assets/sprockets/v3.0/4s/4sg52OgD5l4qx4GnojCVxg2itqwqb-KRanEdmdMus3Y.cache +0 -0
  116. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5U/5UPnsccuZFLk9OqbmFMvB55mbvGptApx9Z55HWjEN90.cache +0 -3
  117. data/test/dummy/tmp/cache/assets/sprockets/v3.0/9a/9acKNgyVD8_WK401tMy6Ce98g-LS4VpwFvGQdzCV9mI.cache +0 -0
  118. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ba/BaymviI8cwAJQMOIzWCf6Lt-PM2sNFTvY9hQKsfDNNw.cache +0 -3
  119. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dd/DdFHg3C_voetfvKGKX7t8PGzZlkO45-huHNtaou5rxg.cache +0 -1
  120. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fp/FprCQeeZguht46WNSpA3Y3JHKehovFXrj63nDrvvwFE.cache +0 -1
  121. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GJ/GJrfWiarIi0Dt6sdKVMfUF1cdZ6NbqZxXHhzNbFtpBw.cache +0 -1
  122. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gp/GpoziOxxB-hisco0rl7Nnsnw0UWud7R9Yge2Q3o1eN4.cache +0 -2
  123. data/test/dummy/tmp/cache/assets/sprockets/v3.0/It/It5VkJv-53-LICLKZWWyp2WcbD86DGotAL0MY3hhfpg.cache +0 -6
  124. data/test/dummy/tmp/cache/assets/sprockets/v3.0/O6/O6dw148Xya7NYlsRFMEzJyvRcySM6iOL1jRUpdQo9B8.cache +0 -1
  125. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Oj/OjMkKTW7OkthjJAQHDID8GV30IZC9F0dJ1zGiFame9U.cache +0 -4
  126. data/test/dummy/tmp/cache/assets/sprockets/v3.0/SU/SUtZ_ltPqy9A9A-_zqNPhNPvjxCOnrdqXHSZv5S9mOk.cache +0 -1
  127. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tv/TvZgmm69VEMHUJQIBoij61oXMkgzp6whVo7l8mJ9qpw.cache +0 -3
  128. data/test/dummy/tmp/cache/assets/sprockets/v3.0/YJ/YJZdK01T1KTS84Mb6p_2TasmJNZeGZc4FMtBPCKGr_M.cache +0 -3
  129. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ah/ahhhd3ysbQmVDNzq2L_rb4t6rqqdnqeY6ujztBoZDA8.cache +0 -1
  130. data/test/dummy/tmp/cache/assets/sprockets/v3.0/gv/gvZKkbgiExbcQrT4eo0HB-j4JoDRAxdmDjKRxeEdK0Y.cache +0 -1
  131. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hj/hj_r-O1QjHJIPcZVnlB_FGPdIRAi9NkxpT2oXDRIsGE.cache +0 -1
  132. data/test/dummy/tmp/cache/assets/sprockets/v3.0/o2/o2V1ahk8vFR6sXWNh5BB7w6MBj04zCyX-o1xFZONydE.cache +0 -1
  133. data/test/dummy/tmp/cache/assets/sprockets/v3.0/tE/tEO71oPPFXN_2c4p39nU0OiF9ARg13fjdQlnPqAx1KY.cache +0 -4
  134. data/test/dummy/tmp/cache/assets/sprockets/v3.0/tW/tWFRsAv4WWu2ch-x3AJZd3KOvBXG3MwH6Q6Xn-tFBtw.cache +0 -1
  135. data/test/dummy/tmp/cache/assets/sprockets/v3.0/x6/x6W754ylumshr3wBUHHmcgyWs8UR3Od7FaI6tqvjKmk.cache +0 -1
  136. data/test/dummy/tmp/cache/assets/sprockets/v3.0/yy/yyJ1P7RQciOiW8TgQiu1RMDdbWd4rqxd2BGU9HkY3L8.cache +0 -0
@@ -14,6 +14,8 @@ var quickSearchEventTracking = (function () {
14
14
  logQueryDataAttribute: 'quicksearch-ga-query'
15
15
  }
16
16
 
17
+ <% url_helper = QuickSearch::Engine.routes.url_helpers %>
18
+
17
19
  // Public Methods
18
20
 
19
21
  function listenForClicks () {
@@ -53,7 +55,7 @@ var quickSearchEventTracking = (function () {
53
55
  function checkForServes(val) {
54
56
  var link = $(val).find('a');
55
57
  var eventValuesDefined = eventValues(link);
56
- eventValuesDefined.category = eventValuesDefined.category + '-serve';
58
+ eventValuesDefined.action_type = 'serve';
57
59
  sendEventData(eventValuesDefined, '');
58
60
  }
59
61
 
@@ -67,6 +69,7 @@ var quickSearchEventTracking = (function () {
67
69
  ga_event.category = eventCategory(link);
68
70
  ga_event.action = eventAction(link);
69
71
  ga_event.label = eventLabel(link);
72
+ ga_event.action_type = 'click';
70
73
  return ga_event;
71
74
  }
72
75
 
@@ -142,37 +145,34 @@ var quickSearchEventTracking = (function () {
142
145
 
143
146
  // Universal Analytics
144
147
 
145
- // ga('send', 'event', {
146
- // 'hitType': 'event',
147
- // 'eventCategory': eventValues.category,
148
- // 'eventAction': eventValues.action,
149
- // 'eventLabel': eventValues.label,
150
- // 'hitCallback': function () {
151
- // if (link !== '') {
152
- // document.location = link;
153
- // }
154
- // }
155
- // });
148
+ var category = eventValues.action_type == 'serve' ? eventValues.category + '-serve' : eventValues.category;
149
+
150
+
151
+ ga('send', {
152
+ hitType: 'event',
153
+ eventCategory: category,
154
+ eventAction: eventValues.action,
155
+ eventLabel: eventValues.label,
156
+ hitCallback: function () {
157
+ if (link !== '') {
158
+ document.location = link;
159
+ }
160
+ }
161
+ });
156
162
 
157
- // Classic Analytics
158
- _gaq.push(['_set','hitCallback',function() {
159
- if (link !== '') {
160
- document.location = link;
161
- }
162
- }]);
163
- _gaq.push(['_trackEvent', eventValues.category, eventValues.action, eventValues.label]);
164
163
  }
165
164
 
166
165
  function logEventToDatabase(eventValues) {
167
166
 
168
- url = logging_url('log_event');
167
+ url = '<%= url_helper.log_event_path %>';
169
168
 
170
169
  return $.ajax({
171
170
  url: url,
172
171
  data: {
173
172
  category: eventValues.category,
174
173
  event_action: eventValues.action,
175
- label: eventValues.label
174
+ label: eventValues.label,
175
+ action_type: eventValues.action_type
176
176
  }
177
177
  });
178
178
  }
@@ -204,7 +204,7 @@ var quickSearchEventTracking = (function () {
204
204
 
205
205
  function logSearchToDatabase(searchValues) {
206
206
  console.log(searchValues);
207
- url = logging_url('log_search');
207
+ url = '<%= url_helper.log_search_path %>';
208
208
 
209
209
  return $.ajax({
210
210
  url: url,
@@ -215,17 +215,6 @@ var quickSearchEventTracking = (function () {
215
215
  });
216
216
  }
217
217
 
218
- function logging_url(log_path) {
219
- var pathname = window.location.pathname;
220
- var url = pathname;
221
- if (url.substr(-1) != '/'){
222
- url += '/';
223
- }
224
- url += log_path;
225
-
226
- return url;
227
- }
228
-
229
218
 
230
219
  return {
231
220
 
@@ -3,11 +3,15 @@ function remove_timedout_spinners(){
3
3
  $('#no-results-trying-again').remove();
4
4
  }
5
5
 
6
- function add_found_item_types(endpoint) {
6
+ function add_found_item_types(endpoint, result_count) {
7
+ var result_count_display = "";
8
+ if (result_count) {
9
+ result_count_display = " (" + String(result_count) + ")";
10
+ }
7
11
  var dasherized_endpoint = endpoint.replace("_", "-")
8
12
  $('.result-types li.' + dasherized_endpoint + " .no-results-label")
9
13
  .replaceWith('<a href="#' + dasherized_endpoint + '" data-quicksearch-ga-action="' +
10
- dasherized_endpoint + '">' + I18n["en"][endpoint + "_search"]["display_name"]);
14
+ dasherized_endpoint + '">' + I18n["en"][endpoint + "_search"]["display_name"] + result_count_display);
11
15
  }
12
16
 
13
17
  var xhr_searches = function(){
@@ -79,4 +83,4 @@ var xhr_searches = function(){
79
83
 
80
84
  $(document).ready(function() {
81
85
  xhr_searches();
82
- });
86
+ });
@@ -5,3 +5,151 @@
5
5
  #appstats-date-filter {
6
6
  display: none;
7
7
  }
8
+
9
+ // Added for appstats graph styling
10
+ // Icon and general graph styling
11
+ .graphGroup {
12
+ position: relative;
13
+ }
14
+
15
+ .graph {
16
+ position: relative;
17
+ }
18
+
19
+ .graph_mini {
20
+ float: left;
21
+ }
22
+
23
+ .iconContainer {
24
+ position: absolute;
25
+ z-index: 1;
26
+ }
27
+
28
+ .big-icon {
29
+ font-size: 15em !important;
30
+ }
31
+
32
+ .big-icon::before {
33
+ opacity: .5;
34
+ }
35
+
36
+ .clearfix {
37
+ clear: both;
38
+ }
39
+
40
+ .zoom {
41
+ cursor: move;
42
+ fill: none;
43
+ pointer-events: all;
44
+ }
45
+
46
+ // Date range styling
47
+ #dateButton {
48
+ width: 100%;
49
+ }
50
+
51
+ .inputLabel, #datePickerText, #numDays {
52
+ width: 50%;
53
+ float: left;
54
+ color: #000;
55
+ font-size: 20px;
56
+ }
57
+
58
+ #datePickerText {
59
+ width: 60%;
60
+ }
61
+
62
+ #numDays {
63
+ width: 40%;
64
+ text-align: right;
65
+ }
66
+
67
+ #from, #to, #num {
68
+ float: left;
69
+ width: 50%;
70
+ }
71
+
72
+ // Text styling
73
+ .chartTitle {
74
+ text-anchor: middle;
75
+ fill: #333333;
76
+ font-size: 30px;
77
+ font-family: "Lucida Console";
78
+ pointer-events: none;
79
+ }
80
+
81
+ .headText, .totalText, .perDayText, .perClickText, .perServeText, .perSearchText, .perSessionText, .dataRank, .dataLabel, .dataClick, .dataServe, .dataRatio,
82
+ .percentText, .dataPercent, .dataCumPercent, .legendText
83
+ {
84
+ text-anchor: start;
85
+ fill: #000000;
86
+ font-size: 13px;
87
+ font-family: "Lucida Console";
88
+ }
89
+
90
+ .headText, .percentText, .legendText {
91
+ font-size: 16px;
92
+ }
93
+
94
+ .percentText, .dataPercent {
95
+ text-anchor: end;
96
+ }
97
+
98
+ // Data bars and areas
99
+ .area {
100
+ fill: steelblue;
101
+ clip-path: url(#clip);
102
+ }
103
+
104
+ .areaLight {
105
+ fill: lightsteelblue;
106
+ clip-path: url(#clip);
107
+ }
108
+
109
+ .areaMini {
110
+ fill: steelblue;
111
+ clip-path: url(#clipMini);
112
+ pointer-events: none;
113
+ }
114
+
115
+ .dataBar, .serveBar, .clickBar, .ratioBar, .percBar, .cumPercBar, .legendRect {
116
+ fill: steelblue;
117
+ }
118
+
119
+ .lightLegendRect, .lightDataBar, .lightServeBar, .lightClickBar, .lightRatioBar, .lightPercBar, .lightCumPercBar,
120
+ .dataBar:hover, .serveBar:hover, .clickBar:hover, .ratioBar:hover, .percBar:hover, .cumPercBar:hover {
121
+ fill: lightsteelblue;
122
+ }
123
+
124
+ // Background rects, borders, and lines
125
+ .sortRect {
126
+ cursor: pointer;
127
+ opacity: 0.000001;
128
+ }
129
+
130
+ .darkBorder {
131
+ fill: none;
132
+ stroke-width: 2px;
133
+ stroke: #333;
134
+ }
135
+
136
+ .lightBorder {
137
+ fill: none;
138
+ stroke-width: 2px;
139
+ stroke: #DDD;
140
+ }
141
+
142
+ .darkBar {
143
+ fill: #F5F5F5;
144
+ stroke-width: 1px;
145
+ stroke: #DDD;
146
+ }
147
+
148
+ .lightBar {
149
+ fill: none;
150
+ }
151
+
152
+ .gridLine {
153
+ stroke: #333;
154
+ stroke-width: 1px;
155
+ }
@@ -9,22 +9,6 @@
9
9
  #main-content {
10
10
  #quicksearch {
11
11
 
12
- .twitter-typeahead {
13
- width: 100%;
14
-
15
- img {
16
- max-width: 79.578125px;
17
- }
18
- .space-container {
19
- max-width: 438.3125px;
20
- }
21
-
22
- .bestbet-container {
23
- padding: 0;
24
- }
25
-
26
- }
27
-
28
12
  h3 {
29
13
  padding-top: 0;
30
14
  font-weight: normal;
@@ -8,7 +8,7 @@ module QuickSearch::DoiTrap
8
8
  def doi_trap
9
9
  unless params_q_scrubbed.nil?
10
10
  if is_a_doi?(doi_query)
11
- Event.create(category: 'doi-trap', action: doi_query, label: '')
11
+ Event.create(category: 'doi-trap', query: doi_query, action: 'click')
12
12
  redirect_to doi_loaded_link
13
13
  # Alternately insert a loaded link into the results interface
14
14
  # @doi_loaded_link = loaded_link
@@ -2,193 +2,303 @@ module QuickSearch
2
2
  class AppstatsController < ApplicationController
3
3
  include Auth
4
4
 
5
- before_action :auth, :start_date, :end_date, :days_in_sample
5
+ before_action :auth, :get_dates, :days_in_sample
6
6
 
7
- def index
8
- @page_title = 'Search Statistics'
9
- search_click_ratio
10
- end
7
+ def data_general_statistics
8
+ @result = []
11
9
 
12
- def clicks_overview
13
- @page_title = 'Clicks Overview'
14
- module_clicks
15
- result_types_clicks
16
- typeahead_clicks
17
- end
10
+ clicks = Event.where(@range).where(:action => 'click').group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
11
+ @result << process_time_query(clicks)
18
12
 
19
- def top_searches
20
- @page_title = 'Top Searches'
21
- searches_count
22
- searches = Search.where(page: '/').where(date_range)
23
- queries = []
24
- searches.each do |search|
25
- queries << search["query"].downcase
26
- end
27
- @query_counts = Hash.new(0)
28
- queries.each do |query|
29
- @query_counts[query] += 1
30
- end
31
- @query_counts = @query_counts.sort_by {|k,v| v}.reverse[0..199]
13
+ sessions = Session.where(@range).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
14
+ @result << process_time_query(sessions)
15
+
16
+ searches = Search.where(@range).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
17
+ @result << process_time_query(searches)
18
+
19
+ render_data
32
20
  end
33
21
 
34
- def top_spot
35
- @page_title = params[:ga_top_spot_module]
36
- top_spot_reporting(params[:ga_top_spot_module])
37
- end
38
-
39
- def detail
40
- start_date
41
- end_date
42
- @category = params[:ga_category]
43
- if params[:ga_scope] == 'action'
44
- @action = params[:ga_action]
45
- @page_title = "#{@category} (#{URI.decode(@action)})"
46
- top_spot_detail(@category, @action)
47
- render "top_spot_detail"
48
- elsif params[:ga_scope] == 'category'
49
- @page_title = "#{@category}"
50
- module_click_detail(@category)
51
- render "module_click_detail"
52
- end
22
+ def data_general_table
23
+ @result = []
24
+
25
+ @result << { "clicks" => Event.where(@range).where(:action => 'click').count }
26
+ @result << { "searches" => Search.where(@range).count }
27
+ @result << { "sessions" => Session.where(@range).count }
28
+
29
+ render_data
53
30
  end
54
31
 
55
- def realtime
32
+ def data_module_clicks
33
+ clicks = Event.where(@range).where(excluded_categories).where(:action => 'click').group(:category).order("count_category DESC").count(:category)
34
+ total_clicks = clicks.values.sum
35
+
36
+ @result = process_module_result_query(clicks, "module", 0, 100, total_clicks)
37
+
38
+ render_data
56
39
  end
57
40
 
58
- private
41
+ def data_result_clicks
42
+ clicks = Event.where(@range).where(:category => "result-types").where(:action => 'click').group(:item).order("count_item DESC").count(:item)
43
+ total_clicks = clicks.values.sum
44
+
45
+ @result = process_module_result_query(clicks, "result", 0, 100, total_clicks)
59
46
 
60
- def module_clicks
61
- @module_clicks = Event.where(date_range).where(excluded_categories).group(:category).order("count_category DESC").count(:category)
62
- @module_click_total = calculate_total_clicks(@module_clicks)
47
+ render_data
63
48
  end
64
49
 
65
- def typeahead_clicks
66
- searches_count
67
- @typeahead_clicks = Event.where(date_range).where("category LIKE 'typeahead-%'").group(:category).order("count_category DESC").count(:category)
68
- @typeahead_clicks_total = calculate_total_clicks(@typeahead_clicks)
50
+ def data_module_details
51
+ category = params[:category]
52
+ clicks = Event.where(:category => category).where(:action => 'click').where(@range).group(:item).order('count_category DESC').count(:category)
53
+ total_clicks = clicks.values.sum
54
+
55
+ @result = process_module_result_query(clicks, "module_details", category, 15, total_clicks)
56
+
57
+ render_data
69
58
  end
70
59
 
71
- def result_types_clicks
72
- @result_types_clicks = Event.where(date_range).where(:category => "result-types").group(:action).order("count_action DESC").count(:action)
73
- @result_types_click_total = calculate_total_clicks(@result_types_clicks)
60
+ def data_top_searches
61
+ num_results = params[:num_results] ? params[:num_results].to_i : 20
62
+ searches = Search.where(:page => '/').where(@range).group(:query).order('count_query DESC').count(:query)
63
+ total_searches = searches.sum {|k,v| v}
64
+
65
+ @result = process_searches_query(searches, num_results, total_searches)
66
+
67
+ render_data
74
68
  end
75
69
 
76
- def calculate_total_clicks(clicks)
77
- click_total = 0
78
- clicks.each do |module_name, click_count|
79
- click_total += click_count
80
- end
70
+ def data_spelling_suggestions
71
+ num_results = params[:num_results] ? params[:num_results].to_i : 20
72
+ serves = Event.where(@range).where(:category => "spelling-suggestion", :action => 'serve').group(:item).order("count_category DESC").count(:category)
73
+ clicks = Event.where(@range).where(:category => "spelling-suggestion", :action => 'click').group(:item).count(:category)
81
74
 
82
- click_total
75
+ @result = process_spelling_best_bets_query(serves, clicks, "spelling_suggestion", 0, num_results)
76
+
77
+ render_data
83
78
  end
84
79
 
85
- def searches_count
86
- @searches_count = Search.where(page: '/').where(date_range).count
80
+ def data_spelling_details
81
+ item = params[:item]
82
+ serves = Event.where(@range).where(:category => "spelling-suggestion", :action => 'serve', :item => item).group(:query).order("count_query DESC").count(:query)
83
+ clicks = Event.where(@range).where(:category => "spelling-suggestion", :action => 'click', :item => item).group(:query).count(:query)
84
+
85
+ @result = process_spelling_best_bets_query(serves, clicks, "spelling_details", item, 15)
86
+
87
+ render_data
87
88
  end
88
89
 
89
- def search_click_ratio
90
- searches_count
91
- @clicks_count = Event.where(excluded_categories).where(date_range).count
92
- @click_serve_ratio = (@clicks_count / @searches_count.to_f)*100
90
+ def data_best_bets
91
+ num_results = params[:num_results] ? params[:num_results].to_i : 20
92
+ serves = Event.where(@range).where(:category => "best-bets-regular", :action => 'serve').group(:item).order("count_category DESC").count(:category)
93
+ clicks = Event.where(@range).where(:category => "best-bets-regular", :action => 'click').group(:item).count(:category)
94
+
95
+ @result = process_spelling_best_bets_query(serves, clicks, "best_bet", 0, num_results)
96
+
97
+ render_data
93
98
  end
94
99
 
95
- def top_spot_reporting(top_spot_module)
96
- reports = {"best-bets-regular" => {:category_title => "Best Bets Regular"},
97
- "best-bets-algorithmic-journal" => {:category_title => "Journal Algorithmic Best Bets"},
98
- "best-bets-algorithmic-database" => {:category_title => "Database Algorithmic Best Bets"},
99
- "best-bets-course-tools" => {:category_title => "Course Tools Best Bets"},
100
- "spelling-suggestion" => {:category_title => "Spelling Suggestions"}
101
- }
102
- @top_spot_reporting = []
103
- top_spot_report = base_query(top_spot_module)
104
- @top_spot_reporting << {:category => top_spot_module, :category_title => reports[top_spot_module][:category_title], :report => top_spot_report}
105
- # reports.each do |key, report|
106
- # top_spot_report = base_query(key)
107
- # @top_spot_reporting << {:category => key, :category_title => report[:category_title], :report => top_spot_report}
108
- # end
100
+ def data_best_bets_details
101
+ item = params[:item]
102
+ serves = Event.where(@range).where(:category => "best-bets-regular", :action => 'serve', :item => item).group(:query).order("count_query DESC").count(:query)
103
+ clicks = Event.where(@range).where(:category => "best-bets-regular", :action => 'click', :item => item).group(:query).count(:query)
104
+
105
+ @result = process_spelling_best_bets_query(serves, clicks, "best_bet_details", item, 15)
106
+
107
+ render_data
109
108
  end
110
109
 
111
- def module_click_detail(category)
112
- modules_clicks = Event.where(:category => "#{category}").where(date_range).group(:action).order('count_category DESC').count(:category)
113
- total_clicks = modules_clicks.values.sum
114
- @modules_clicks_report = []
115
- modules_clicks.each do |module_clicks|
116
- @modules_clicks_report << {:module => module_clicks[0], :clicks => module_clicks[1], :percent => (module_clicks[1]/total_clicks.to_f)*100}
110
+ # In order to obtain all filter cases, an integer corresponding to the following truth table is formed:
111
+ # rowNumber onCampus offCampus isMobile notMobile | filters
112
+ # 0 0 0 0 0 | Neither filter applied (default)
113
+ # 1 0 0 0 1 | where(is_mobile=>false)
114
+ # 2 0 0 1 0 | where(is_mobile=>true)
115
+ # 3 0 0 1 1 | INVALID (isMobile & notMobile asserted)
116
+ # 4 0 1 0 0 | where(on_campus=>false)
117
+ # 5 0 1 0 1 | where(on_campus=>false, is_mobile=>false)
118
+ # 6 0 1 1 0 | where(on_campus=>false, is_mobile=>true)
119
+ # 7 0 1 1 1 | INVALID (isMobile & notMobile asserted)
120
+ # 8 1 0 0 0 | where(on_campus=>true)
121
+ # 9 1 0 0 1 | where(on_campus=>true, is_mobile=>false)
122
+ # 10 1 0 1 0 | where(on_campus=>true, is_mobile=>true)
123
+ # 11 1 0 1 1 | INVALID (isMobile & notMobile asserted)
124
+ # 12 1 1 0 0 | INVALID (onCampus & offCampus asserted)
125
+ # 13 1 1 0 1 | INVALID (onCampus & offCampus asserted)
126
+ # 14 1 1 1 0 | INVALID (onCampus & offCampus asserted)
127
+ # 15 1 1 1 1 | INVALID (onCampus & offCampus asserted)
128
+ # Thus, the integer filterCase, which corresponds to the rowNumber, can be formed by converting 4 bit
129
+ # binary term formed by the concatenation {onCampus, offCampus, isMobile, notMobile} into an integer.
130
+ # Note: This filtering cannot be obtained by passing two boolean values (one for on_campus and one for is_mobile)
131
+ # as this would fail to account for cases where no filter is applied to one variable (ie. where we don't care about
132
+ # either location or device)
133
+ def data_sessions_overview
134
+ onCampus = params[:onCampus] ? params[:onCampus].to_i : 0
135
+ offCampus = params[:offCampus] ? params[:offCampus].to_i : 0
136
+ isMobile = params[:isMobile] ? params[:isMobile].to_i : 0
137
+ notMobile = params[:notMobile] ? params[:notMobile].to_i : 0
138
+ filterCase = (2**3)*onCampus + (2**2)*offCampus + (2**1)*isMobile + notMobile
139
+
140
+ case filterCase
141
+ when 1 #mobile=f
142
+ sessions = Session.where(@range).where(:is_mobile => false).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
143
+ when 2 #mobile=t
144
+ sessions = Session.where(@range).where(:is_mobile => true).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
145
+ when 4 #campus=f
146
+ sessions = Session.where(@range).where(:on_campus => false).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
147
+ when 5 #campus=f, mobile=f
148
+ sessions = Session.where(@range).where(:on_campus => false, :is_mobile => false).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
149
+ when 6 #campus=f, mobile=t
150
+ sessions = Session.where(@range).where(:on_campus => false, :is_mobile => true).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
151
+ when 8 #campus=t
152
+ sessions = Session.where(@range).where(:on_campus => true).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
153
+ when 9 #campus=t, mobile=f
154
+ sessions = Session.where(@range).where(:on_campus => true, :is_mobile => false).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
155
+ when 10 #campus=t, mobile=t
156
+ sessions = Session.where(@range).where(:on_campus => true, :is_mobile => true).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
157
+ else
158
+ sessions = Session.where(@range).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
117
159
  end
160
+
161
+ @result = process_time_query(sessions)
162
+
163
+ render_data
118
164
  end
119
165
 
120
- def top_spot_detail(category, action)
121
- # Use a join here?
122
- action = URI.decode(action)
123
- serves = Event.where(:category => "#{category}-serve", :action => "#{action}").where(date_range).group(:label).order("count_label DESC").count(:label)
124
- clicks = Event.where(:category => "#{category}", :action => "#{action}").where(date_range).group(:label).order("count_label DESC").count(:label)
166
+ def data_sessions_location
167
+ use_perc = params[:use_perc]=="true" ? true : false
168
+ sessions_on = Session.where(@range).where(:on_campus => true).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
169
+ sessions_off = Session.where(@range).where(:on_campus => false).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
125
170
 
126
- @top_spot_detail = {}
171
+ @result = process_stacked_time_query(sessions_on, sessions_off, use_perc)
172
+
173
+ render_data
174
+ end
127
175
 
176
+ def data_sessions_device
177
+ use_perc = params[:use_perc]=="true" ? true : false
178
+ sessions_on = Session.where(@range).where(:is_mobile => true).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
179
+ sessions_off = Session.where(@range).where(:is_mobile => false).group(:created_at_string).order("created_at_string ASC").count(:created_at_string)
128
180
 
129
- serves.each do |label|
130
- serve_count = label[1].nil? ? 0:label[1]
131
- click_count = clicks[label[0].downcase].nil? ? 0:clicks[label[0].downcase]
132
- @top_spot_detail[label[0]] = [serve_count, click_count, (click_count/serve_count.to_f)*100]
133
- end
181
+ @result = process_stacked_time_query(sessions_on, sessions_off, use_perc)
182
+
183
+ render_data
134
184
  end
135
185
 
136
- def base_query(category)
137
- serves = Event.where(date_range).where(:category => "#{category}-serve").group(:action).order("count_category DESC").count(:category)
138
- clicks = Event.where(date_range).where(:category => "#{category}").group(:action).count(:category)
186
+ def process_time_query(query)
187
+ sub = []
188
+ query.each do |date , count|
189
+ row = { "date" => date ,
190
+ "count" => count}
191
+ sub << row
192
+ end
193
+ return sub
194
+ end
139
195
 
140
- result = []
141
- serves.each do |data, count|
142
- unless clicks[data].nil?
143
- click_count = clicks[data]
144
- else
145
- click_count = 0
146
- end
196
+ def process_stacked_time_query(query1, query2, use_perc)
197
+ sub = []
198
+ query1.each do |date , count1|
199
+ count2 = query2[date] ? query2[date] : 0
200
+ row = { "date" => date ,
201
+ "on" => use_perc ? count1.to_f/(count1+count2) : count1,
202
+ "off" => use_perc ? count2.to_f/(count1+count2) : count2}
203
+ sub << row
204
+ end
205
+ return sub
206
+ end
147
207
 
148
- row = {"action" => data,
149
- "servecount" => count,
150
- "clickcount" => click_count,
151
- "click_serve_ratio" => (click_count/count)*100 }
152
- result << row
208
+ def process_module_result_query(query, keyHeading, parent, num_results, total_clicks)
209
+ sub = []
210
+ query.to_a[0..num_results-1].each_with_index do |d, i|
211
+ label = d[0]
212
+ count = d[1]
213
+ row = {"rank" => i+1,
214
+ "label" => (label.blank? ? "(blank)" : label),
215
+ "clickcount" => count,
216
+ "percentage" => ((100.0*count)/total_clicks).round(2),
217
+ "parent" => parent,
218
+ "expanded" => 0,
219
+ "key" => keyHeading + (label.blank? ? "(blank)" : label) + parent.to_s}
220
+ sub << row
153
221
  end
222
+ return sub
223
+ end
154
224
 
155
- result
225
+ def process_spelling_best_bets_query(serves, clicks, keyHeading, parent, num_results)
226
+ sub = []
227
+ serves.to_a[0..num_results-1].each_with_index do |d , i|
228
+ label = d[0]
229
+ serve_count = d[1]
230
+ click_count = clicks[label] ? clicks[label] : 0
231
+ row = {"rank" => i+1,
232
+ "label" => label,
233
+ "serves" => serve_count,
234
+ "clicks" => click_count,
235
+ "ratio" => (100.0*click_count/serve_count).round(2),
236
+ "parent" => parent,
237
+ "expanded" => 0,
238
+ "key" => keyHeading + label + parent.to_s}
239
+ sub << row
240
+ end
241
+ return sub
156
242
  end
157
243
 
158
- def start_date
159
- if params[:start_date]
160
- # If there's a specified start date, use it
161
- @start_date = convert_to_time(params[:start_date])
162
- else
163
- # otherwise use 6 months ago as a default, or the earliest event date if logs are younger
164
- first_date = Event.first[:created_at]
165
- start = Time.current - 6.months
166
-
167
- if start < first_date
168
- @start_date = first_date
169
- else
170
- @start_date = start
244
+ def process_searches_query(searches, num_results, total_searches)
245
+ sub = []
246
+ last_row = {}
247
+ searches.to_a[0..num_results-1].each_with_index do |d, i|
248
+ query = d[0]
249
+ count = d[1]
250
+ if (last_row=={})
251
+ last_cum_percentage = 0
252
+ else
253
+ last_cum_percentage = last_row["cum_perc"]
171
254
  end
255
+ row = {"rank" => i+1,
256
+ "label" => query,
257
+ "count" => count,
258
+ "percentage" => ((100.0*count)/total_searches).round(2),
259
+ "cum_perc" => (last_cum_percentage + ((100.0*count)/total_searches)),
260
+ "cum_percentage" => (last_cum_percentage + ((100.0*count)/total_searches)).round(2),
261
+ "key" => "top_search" + query}
262
+ sub << row
263
+ last_row = row
172
264
  end
173
-
265
+ return sub
174
266
  end
175
267
 
176
- def end_date
177
- if params[:end_date]
178
- # use end date, if specified
179
- @end_date = convert_to_time(params[:end_date])
180
- else
181
- # otherwise use the current date as default
182
- @end_date = Time.current
268
+ def render_data
269
+ respond_to do |format|
270
+ format.json {
271
+ render :json => @result
272
+ }
183
273
  end
184
274
  end
185
275
 
186
- def convert_to_time(date_input)
187
- year = date_input[:year]
188
- month = date_input[:month]
189
- day = date_input[:day]
276
+ def index
277
+ @page_title = 'Search Statistics'
278
+ end
279
+
280
+ def clicks_overview
281
+ @page_title = 'Clicks Overview'
282
+ end
283
+
284
+ def top_searches
285
+ @page_title = 'Top Searches'
286
+ end
287
+
288
+ def top_spot
289
+ @page_title = params[:ga_top_spot_module]
290
+ end
291
+
292
+ def sessions_overview
293
+ @page_title = 'Sessions Overview'
294
+ end
190
295
 
191
- Time.new(year, month, day)
296
+ def sessions_details
297
+ @page_title = 'Sessions Details'
298
+ end
299
+
300
+ def convert_to_time(date_input)
301
+ Time.parse(date_input)
192
302
  end
193
303
 
194
304
  def days_in_sample
@@ -196,14 +306,27 @@ module QuickSearch
196
306
  if @days_in_sample < 1
197
307
  @days_in_sample = 1
198
308
  end
309
+
199
310
  end
200
311
 
201
- def excluded_categories
202
- "category NOT LIKE \"%serve\" AND category <> \"common-searches\" AND category <> \"result-types\"AND category NOT LIKE \"typeahead-%\""
312
+ def get_dates
313
+ start = params[:start_date]
314
+ stop = params[:end_date]
315
+ if (!start.blank?)
316
+ @start_date = convert_to_time(start)
317
+ else
318
+ @start_date = Time.current - 180.days
319
+ end
320
+ if (!stop.blank?)
321
+ @end_date = convert_to_time(stop)
322
+ else
323
+ @end_date = Time.current
324
+ end
325
+ @range = { :created_at => @start_date..@end_date }
203
326
  end
204
327
 
205
- def date_range
206
- { :created_at => start_date.beginning_of_day..end_date.end_of_day }
328
+ def excluded_categories
329
+ "category <> \"common-searches\" AND category <> \"result-types\"AND category <> \"typeahead\""
207
330
  end
208
331
 
209
332
  end