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.
- checksums.yaml +4 -4
- data/README.md +7 -6
- data/app/assets/javascripts/quick_search.js.erb +9 -0
- data/app/assets/javascripts/quick_search/appstats.js.erb +73 -0
- data/app/assets/javascripts/quick_search/appstats_best_bets.js.erb +905 -0
- data/app/assets/javascripts/quick_search/appstats_clicks_overview.js.erb +719 -0
- data/app/assets/javascripts/quick_search/appstats_general_statistics.js.erb +908 -0
- data/app/assets/javascripts/quick_search/appstats_sessions_details.js.erb +660 -0
- data/app/assets/javascripts/quick_search/appstats_sessions_overview.js.erb +481 -0
- data/app/assets/javascripts/quick_search/appstats_spelling_suggestions.js.erb +902 -0
- data/app/assets/javascripts/quick_search/appstats_top_searches.js.erb +633 -0
- data/app/assets/javascripts/quick_search/event_tracking.js.erb +22 -33
- data/app/assets/javascripts/quick_search/xhr_search.js +7 -3
- data/app/assets/stylesheets/quick_search/appstats.scss +148 -0
- data/app/assets/stylesheets/quick_search/quick_search.scss +0 -16
- data/app/controllers/concerns/quick_search/doi_trap.rb +1 -1
- data/app/controllers/quick_search/appstats_controller.rb +267 -144
- data/app/controllers/quick_search/logging_controller.rb +165 -0
- data/app/controllers/quick_search/search_controller.rb +1 -23
- data/app/controllers/quick_search/typeahead_controller.rb +48 -0
- data/app/models/event.rb +6 -0
- data/app/models/search.rb +7 -0
- data/app/models/session.rb +9 -0
- data/app/searchers/quick_search/best_bets_searcher.rb +1 -1
- data/app/views/layouts/quick_search/_google_analytics.html.erb +4 -9
- data/app/views/layouts/quick_search/_search_form.html.erb +2 -2
- data/app/views/layouts/quick_search/application.html.erb +4 -0
- data/app/views/quick_search/appstats/_date_range.html.erb +14 -13
- data/app/views/quick_search/appstats/_graph_best_bets.html.erb +6 -0
- data/app/views/quick_search/appstats/_graph_clicks_overview.html.erb +12 -0
- data/app/views/quick_search/appstats/_graph_general_statistics.html.erb +19 -0
- data/app/views/quick_search/appstats/_graph_sessions_details.html.erb +19 -0
- data/app/views/quick_search/appstats/_graph_sessions_overview.html.erb +9 -0
- data/app/views/quick_search/appstats/_graph_spelling_suggestions.html.erb +6 -0
- data/app/views/quick_search/appstats/_graph_top_searches.html.erb +6 -0
- data/app/views/quick_search/appstats/_menu.html.erb +16 -3
- data/app/views/quick_search/appstats/_sessions_details_device_filters.html.erb +9 -0
- data/app/views/quick_search/appstats/_sessions_details_location_filters.html.erb +9 -0
- data/app/views/quick_search/appstats/_sessions_overview_graph_filters.html.erb +9 -0
- data/app/views/quick_search/appstats/clicks_overview.html.erb +3 -14
- data/app/views/quick_search/appstats/index.html.erb +3 -23
- data/app/views/quick_search/appstats/sessions_details.html.erb +9 -0
- data/app/views/quick_search/appstats/sessions_overview.html.erb +9 -0
- data/app/views/quick_search/appstats/top_searches.html.erb +3 -32
- data/app/views/quick_search/appstats/top_spot.html.erb +7 -7
- data/app/views/quick_search/search/_module_with_paging.html.erb +1 -1
- data/app/views/quick_search/search/_result_title.html.erb +1 -1
- data/config/quicksearch_config.yml.example +3 -0
- data/config/routes.rb +31 -3
- data/db/migrate/20161201141003_create_sessions.rb +12 -0
- data/db/migrate/20161201142811_change_event_columns.rb +11 -0
- data/db/migrate/20161201143901_add_session_id_to_searches.rb +5 -0
- data/db/migrate/20161212192454_add_date_string_columns.rb +11 -0
- data/db/seeds.rb +83 -7
- data/lib/generators/quick_search/templates/quick_search_typeahead.js +253 -0
- data/lib/generators/quick_search/typeahead_generator.rb +162 -0
- data/lib/quick_search/engine.rb +1 -0
- data/lib/quick_search/version.rb +1 -1
- data/test/dummy/db/schema.rb +25 -6
- data/test/dummy/log/benchmark.log +121 -241
- data/test/dummy/log/development.log +236 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0b/0bXp2nnjPLNuYQRAMo1RkhNr8RSC8vqZo_7soo0XZTE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3p/3pAfj3gt9c9rLmOrDkMvW2r6Swm5YhuGQ1EN3va9LDE.cache +6 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3r/3r7qg-LCIcD5882b6GKgRTZycpAlhoSNJccVH06yRCQ.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{UA/UAOIipK_ejTAUFI6XxASoweyUiC3t64VfVzV-MfsFD8.cache → 4h/4hLiHzJdffGLMZCeIkbisOdFQSyqs54YkoZpBpGotVk.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Hr/Hr-kCuPY72nIKAdnsDTz9JqXd_z1WL6FSGMAq4HppZg.cache → 5Y/5Yh8GnSzywqhuMWMloKnL9FnuIxa9rBw6hN2Ecv0urw.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/8h/8hHsBZ0Il3GVKNj0HgTh-s-XpPVkHrcSY0EJ4v548sk.cache +4 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{fI/fInu_Gja7ik39t207tqj4CtlL0akQRbjD2T7qEtd0zE.cache → 8n/8nKAboU_CeVIX30-Q9BtSV5TXdE07WU8hO0OQ0N3KOs.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{dz/dzCaa80YgyvJINTgsyrVhKv9UQ1OC82GfAsA-IP96iQ.cache → Af/Afug8duevWkZFPkOMnZ5z_IbRT6JMZo4jw1QFmLiXXA.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/C2/C24SLDoUbdiHRmPZx5lIZ3XPXmn9FDq7j7gZmbpDtcE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CH/CHuDjj47dHGqRD3uN1JNwnlFyjjEKB09KR6WVsLj2Do.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ci/Cif3NOwhu5i6Qm3iRv2gNJLi_cu8yDVz0Nrq8TZu1tc.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/FQ/FQWd8V-Pek1LBAfW9vzcG-FpWySsPRhMVzH9DlPxLWU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fa/FaYEz8CfLTkxVZvnbgKGvJMhhBwNvEgsZgUwaHNRlaQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/IA/IALQq6ICbs3VBSRsaUmGuN73Qv5wDfWTP86VmMh_sVs.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/K1/K1jnTrW-_s64kqCA6fnoQ-ID-rDaGX34J-TNPyzDbLs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Mz/MzXE1Go_GKyu6AvJPhw394BtPM_jVTf0hMwobBi15tk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Os/OsIhoBDw5N2AWGQ-EMK79tgwPS1AC6Dy_gMSJdOv2Ss.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{B5/B5ptGSZGmgHvoK2UDCAtpMhWxJEKxKFhyL9ACeBfzQk.cache → PC/PCth9nzoRrp5GI3Ut8FxlGpXjH63V7k2p4PRwfyu2sQ.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pw/Pw3Jv2p7MsQz6pttCZig6VMVQ30sRyIDRS-2nM32yqY.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/RI/RIOgtcuvLAJZl62RvAzqine3jCO3i2qyhswiW2G1bw8.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/R_/R_6WhfFaPUAOAFfFd4bgUonI5aB4Fa6iOMY2J6G3U98.cache +4 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pj/pjJDYrBipDo6Tr9_-W4UDzfZZ4UPTy9YpXrBQFRXnlo.cache → S3/S3gPdA-Zqya5r6wNhnlwqGV3B3-GDaA8i1fL_jo66AI.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/SS/SS3eYrFE6ghi5G_3POW760Y4BWo5OAaK5QjDrRGXOcs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{jj/jjdQCKZsewws2eRP7b2AVxRMvseOp8djjlDkB8UOtac.cache → Sq/SqjdxmYsdurpx9xk1ks32WEtf3D9_2BysE7RMxnOlmU.cache} +1 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{os/os0qWv3yDfep0e7vVSGTgfn_n3xc4C4QZgmMzLQn0Ks.cache → Ta/TaJnQ_l0sfSsDOyVoi-S-KZQ6vIwzBhmS6hmNA_n8ug.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{o6/o6ZQbq1aBFuVrE2xLbSbyZH2736sWM3Yj4ky9chT1bI.cache → X_/X_CxFXEdZo2C_in7FopAuAbplHn6W_V0SXyVQAMnTzI.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{sR/sRU-UT8qK_38kkiFDXKBPogO1oOZuSvJFH-pgqPL_Ms.cache → Yh/YhRWll6bzgYE6Dmc5fVKbHyv5om4y3-27UrWeUbQcGk.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{OD/ODHapE0li3WI1laVJoksoI5nmQd-8dDJXq_VxS4XefE.cache → _u/_uiA10I5HyJR94Tbc4a06CzdrQCAXX7Iz86WS5PKDQo.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ai/ainCVF4dxXf85KoOLUSHvMMGg0qBNc7Vg-s-9v2ENJI.cache +4 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/cQ/cQqt0ri9GFvVnIs1pJUugIJs5tDuGQMMntW5CwpK6YY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{1n/1nStVaWIQEwAlksUpB1fInwq6v3TikPvuRaSwwCnCLQ.cache → e0/e0Y2Gz8ftaW2O0RjoN2iWguitI-JQZckScAZqlQYkng.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/iH/iHnlNNY3rfdbVqt8LZBfcDQYONR8dA8LmxA9fv5paro.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{F0/F0oWBwLHpGFYNNtnGav-dJFH8rMDpNA5L8_aWm5Wq34.cache → ir/irxgIDPIY6Wz6fHWYp1dIrqAT1_8oa6-oiwqbFE_e-w.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/kn/knUtyVrg7nMIPldZa4MHhe7cC9eMchLZS4mc5HDWgDY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ks/ks4DoIuUV6oUzoiXoPh7sW1k5ExNoUkR7ICjwuRnAT0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/m3/m375QQakjXd_2Trpvdot-i90nmeCCh0HWtzS66ZvxUU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/rQ/rQ_FgYkT2hdw9A6XmJKGgVb2dMtCrWWHwtS0X1_kdl0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pw/pwiIhcWPwTuy5Miz5zqOQGYFx-K3TbaCVQ6ls7EBkk0.cache → rU/rUqFWwHqrT5jeIFCEezOPsMMZiAU7ri6RKBGS2ezAfg.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pO/pO8hHVwybv1ZJBdPa2YC6bjqmk020OYFl85TYxtmrWQ.cache → rq/rqf5-J6k_zLc9ZlUgMj28nviKtRsko3-iEp_m_uNeY0.cache} +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- metadata +143 -119
- data/app/assets/javascripts/quick_search/appstats.js +0 -8
- data/app/views/quick_search/appstats/_click_count_table.html.erb +0 -23
- data/app/views/quick_search/appstats/_top_spot_report_table.html.erb +0 -33
- data/app/views/quick_search/appstats/module_click_detail.html.erb +0 -32
- data/app/views/quick_search/appstats/top_spot_detail.html.erb +0 -35
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0_/0_w_ydOOEFQOoETxJa-IxKppQocaiDwM5V08djCPYso.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3m/3mWfBeEpm_bJvaPQZYvnnAVtE_2helOWh_Tv-cEflrk.cache +0 -5
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/4s/4sg52OgD5l4qx4GnojCVxg2itqwqb-KRanEdmdMus3Y.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/5U/5UPnsccuZFLk9OqbmFMvB55mbvGptApx9Z55HWjEN90.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/9a/9acKNgyVD8_WK401tMy6Ce98g-LS4VpwFvGQdzCV9mI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ba/BaymviI8cwAJQMOIzWCf6Lt-PM2sNFTvY9hQKsfDNNw.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dd/DdFHg3C_voetfvKGKX7t8PGzZlkO45-huHNtaou5rxg.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fp/FprCQeeZguht46WNSpA3Y3JHKehovFXrj63nDrvvwFE.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/GJ/GJrfWiarIi0Dt6sdKVMfUF1cdZ6NbqZxXHhzNbFtpBw.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gp/GpoziOxxB-hisco0rl7Nnsnw0UWud7R9Yge2Q3o1eN4.cache +0 -2
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/It/It5VkJv-53-LICLKZWWyp2WcbD86DGotAL0MY3hhfpg.cache +0 -6
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/O6/O6dw148Xya7NYlsRFMEzJyvRcySM6iOL1jRUpdQo9B8.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Oj/OjMkKTW7OkthjJAQHDID8GV30IZC9F0dJ1zGiFame9U.cache +0 -4
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/SU/SUtZ_ltPqy9A9A-_zqNPhNPvjxCOnrdqXHSZv5S9mOk.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tv/TvZgmm69VEMHUJQIBoij61oXMkgzp6whVo7l8mJ9qpw.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/YJ/YJZdK01T1KTS84Mb6p_2TasmJNZeGZc4FMtBPCKGr_M.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ah/ahhhd3ysbQmVDNzq2L_rb4t6rqqdnqeY6ujztBoZDA8.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/gv/gvZKkbgiExbcQrT4eo0HB-j4JoDRAxdmDjKRxeEdK0Y.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/hj/hj_r-O1QjHJIPcZVnlB_FGPdIRAi9NkxpT2oXDRIsGE.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/o2/o2V1ahk8vFR6sXWNh5BB7w6MBj04zCyX-o1xFZONydE.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tE/tEO71oPPFXN_2c4p39nU0OiF9ARg13fjdQlnPqAx1KY.cache +0 -4
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tW/tWFRsAv4WWu2ch-x3AJZd3KOvBXG3MwH6Q6Xn-tFBtw.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/x6/x6W754ylumshr3wBUHHmcgyWs8UR3Od7FaI6tqvjKmk.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/yy/yyJ1P7RQciOiW8TgQiu1RMDdbWd4rqxd2BGU9HkY3L8.cache +0 -0
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
<
|
|
1
|
+
<style>
|
|
2
|
+
/*FIX LATER: TOO HACKY*/
|
|
3
|
+
#main-content {
|
|
4
|
+
max-width: 100% !important;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.medium-8, .columns {
|
|
8
|
+
float: left !important;
|
|
9
|
+
}
|
|
10
|
+
</style>
|
|
11
|
+
|
|
12
|
+
<aside id="subnav" role="complementary" class="medium-2 columns sidebar">
|
|
2
13
|
<section class="block block-menu">
|
|
3
|
-
<h3>External Services</
|
|
14
|
+
<h3>External Services</h3>
|
|
4
15
|
<ul class="side-nav">
|
|
5
16
|
<li><%= link_to "Google Analytics", "https://www.google.com/analytics/web/", :target => "_blank" %></li>
|
|
6
17
|
</ul>
|
|
7
|
-
<h3>Internal Reports</
|
|
18
|
+
<h3>Internal Reports</h3>
|
|
8
19
|
<ul class="side-nav">
|
|
9
20
|
<li><%= link_to "General Statistics", appstats_path(:start_date => params[:start_date], :end_date => params[:end_date]) %></li>
|
|
10
21
|
<li><%= link_to "Clicks Overview", clicks_overview_path(:start_date => params[:start_date], :end_date => params[:end_date]) %></li>
|
|
11
22
|
<li><%= link_to "Top Searches", top_searches_path(:start_date => params[:start_date], :end_date => params[:end_date]) %></li>
|
|
12
23
|
<li><%= link_to "Best Bets", top_spot_path(:start_date => params[:start_date], :end_date => params[:end_date], :ga_top_spot_module => 'best-bets-regular') %></li>
|
|
13
24
|
<li><%= link_to "Spelling Suggestions", top_spot_path(:start_date => params[:start_date], :end_date => params[:end_date], :ga_top_spot_module => 'spelling-suggestion') %></li>
|
|
25
|
+
<li><%= link_to "Sessions Overview", sessions_overview_path(:start_date => params[:start_date], :end_date => params[:end_date]) %></li>
|
|
26
|
+
<li><%= link_to "Sessions Details", sessions_details_path(:start_date => params[:start_date], :end_date => params[:end_date]) %></li>
|
|
14
27
|
</ul>
|
|
15
28
|
</section>
|
|
16
29
|
</aside>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div style="float: left; display: inline-block;">
|
|
2
|
+
<h4>Device Graph Filters</h4>
|
|
3
|
+
<ul class="side-nav" id="filter_list">
|
|
4
|
+
<form>
|
|
5
|
+
<li> <input class="session_device_filter" type="radio" name="dev" value="num" checked="checked"> Count </li>
|
|
6
|
+
<li> <input class="session_device_filter" type="radio" name="dev" value="perc"> Percent </li>
|
|
7
|
+
</form>
|
|
8
|
+
</ul>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div style="float: left; display: inline-block;">
|
|
2
|
+
<h4>Location Graph Filters</h4>
|
|
3
|
+
<ul class="side-nav" id="filter_list">
|
|
4
|
+
<form>
|
|
5
|
+
<li> <input class="session_location_filter" type="radio" name="loc" value="num" checked="checked"> Count </li>
|
|
6
|
+
<li> <input class="session_location_filter" type="radio" name="loc" value="perc"> Percent </li>
|
|
7
|
+
</form>
|
|
8
|
+
</ul>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div style="float: left; display: inline-block;">
|
|
2
|
+
<h3>Graph Filters</h2>
|
|
3
|
+
<ul id="filter_list">
|
|
4
|
+
<li> <input type="checkbox" id="onCampus"> On Campus </li>
|
|
5
|
+
<li> <input type="checkbox" id="offCampus"> Off Campus </li>
|
|
6
|
+
<li> <input type="checkbox" id="isMobile"> Mobile Connection </li>
|
|
7
|
+
<li> <input type="checkbox" id="notMobile"> Non-mobile Connection </li>
|
|
8
|
+
</ul>
|
|
9
|
+
</div>
|
|
@@ -2,19 +2,8 @@
|
|
|
2
2
|
<%= render partial: 'datatables' %>
|
|
3
3
|
<div class="row">
|
|
4
4
|
<%= render partial: 'menu' %>
|
|
5
|
-
<div class="medium-
|
|
6
|
-
<%= render partial:
|
|
7
|
-
</div>
|
|
8
|
-
<div class="medium-9 columns">
|
|
9
|
-
<h2>Module Clicks</h2>
|
|
10
|
-
<%= render partial: 'click_count_table', locals: { :clicks => @module_clicks, :total_clicks => @module_click_total} %>
|
|
11
|
-
<h2>Result Types Guide Clicks</h2>
|
|
12
|
-
<%= render partial: 'click_count_table', locals: { :clicks => @result_types_clicks, :total_clicks => @result_types_click_total} %>
|
|
13
|
-
<table>
|
|
14
|
-
<tr>
|
|
15
|
-
<td>Result Type Guide Click/Search</td>
|
|
16
|
-
<td><%= number_to_percentage((@result_types_click_total / @searches_count.to_f)*100, precision: 2) %></td>
|
|
17
|
-
</tr>
|
|
18
|
-
</table>
|
|
5
|
+
<div class="medium-8 columns">
|
|
6
|
+
<%= render partial: 'graph_clicks_overview' %>
|
|
19
7
|
</div>
|
|
8
|
+
<%= render partial: "date_range" %>
|
|
20
9
|
</div>
|
|
@@ -3,29 +3,9 @@
|
|
|
3
3
|
<div class="row">
|
|
4
4
|
<%= render partial: 'menu' %>
|
|
5
5
|
<div class="medium-8 columns">
|
|
6
|
-
<%= render partial: 'date_range' %>
|
|
7
6
|
<h2>General Statistics</h2>
|
|
8
|
-
|
|
9
|
-
<tr>
|
|
10
|
-
<td>Total Searches</td>
|
|
11
|
-
<td><%= number_with_delimiter(@searches_count) %></td>
|
|
12
|
-
</tr>
|
|
13
|
-
<tr>
|
|
14
|
-
<td>Total Clicks</td>
|
|
15
|
-
<td><%= number_with_delimiter(@clicks_count) %></td>
|
|
16
|
-
</tr>
|
|
17
|
-
<tr>
|
|
18
|
-
<td>Searches per Day</td>
|
|
19
|
-
<td><%= number_with_delimiter(@searches_count / @days_in_sample) %></td>
|
|
20
|
-
</tr>
|
|
21
|
-
<tr>
|
|
22
|
-
<td>Clicks per Day</td>
|
|
23
|
-
<td><%= number_with_delimiter(@clicks_count / @days_in_sample) %></td>
|
|
24
|
-
</tr>
|
|
25
|
-
<tr>
|
|
26
|
-
<td>Click/Search</td>
|
|
27
|
-
<td><%= number_to_percentage(@click_serve_ratio, precision: 2) %></td>
|
|
28
|
-
</tr>
|
|
29
|
-
</table>
|
|
7
|
+
<%= render partial: 'graph_general_statistics' %>
|
|
30
8
|
</div>
|
|
9
|
+
<%= render partial: "date_range" %>
|
|
31
10
|
</div>
|
|
11
|
+
|
|
@@ -2,37 +2,8 @@
|
|
|
2
2
|
<%= render partial: 'datatables' %>
|
|
3
3
|
<div class="row">
|
|
4
4
|
<%= render partial: "menu" %>
|
|
5
|
-
<div class="
|
|
6
|
-
<%= render partial:
|
|
7
|
-
</div>
|
|
8
|
-
<div class="small-9 columns">
|
|
9
|
-
<h2>Most Frequent Searches</h2>
|
|
10
|
-
<table class="datatable">
|
|
11
|
-
<thead>
|
|
12
|
-
<tr>
|
|
13
|
-
<th>Rank</th>
|
|
14
|
-
<th>Query</th>
|
|
15
|
-
<th>Total</th>
|
|
16
|
-
<th>Percent of Total</th>
|
|
17
|
-
<th>Cumulative Percent</th>
|
|
18
|
-
</tr>
|
|
19
|
-
</thead>
|
|
20
|
-
<tbody>
|
|
21
|
-
<% it_count = 0 %>
|
|
22
|
-
<% total_percent = 0 %>
|
|
23
|
-
<% @query_counts.each do |query, count| %>
|
|
24
|
-
<% it_count += 1 %>
|
|
25
|
-
<% term_percent = (count / @searches_count.to_f)*100 %>
|
|
26
|
-
<% total_percent += term_percent %>
|
|
27
|
-
<tr>
|
|
28
|
-
<td><%= it_count %></td>
|
|
29
|
-
<td><%= link_to query, root_path(q: query) %></td>
|
|
30
|
-
<td><%= number_with_delimiter(count) %></td>
|
|
31
|
-
<td><%= number_to_percentage(term_percent, precision: 2) %></td>
|
|
32
|
-
<td><%= number_to_percentage(total_percent, precision: 2)%></td>
|
|
33
|
-
</tr>
|
|
34
|
-
<% end %>
|
|
35
|
-
</tbody>
|
|
36
|
-
</table>
|
|
5
|
+
<div class="medium-8 columns">
|
|
6
|
+
<%= render partial: 'graph_top_searches' %>
|
|
37
7
|
</div>
|
|
8
|
+
<%= render partial: "date_range" %>
|
|
38
9
|
</div>
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
<%= render partial: 'datatables' %>
|
|
3
3
|
<div class="row">
|
|
4
4
|
<%= render partial: "menu" %>
|
|
5
|
-
<div class="
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<%= render partial: 'top_spot_report_table', locals: { report: report } %>
|
|
5
|
+
<div class="medium-8 columns">
|
|
6
|
+
<% if @page_title=='spelling-suggestion' %>
|
|
7
|
+
<%= render partial: 'graph_spelling_suggestions' %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% if @page_title=='best-bets-regular' %>
|
|
10
|
+
<%= render partial: 'graph_best_bets' %>
|
|
12
11
|
<% end %>
|
|
13
12
|
</div>
|
|
13
|
+
<%= render partial: "date_range" %>
|
|
14
14
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div id="<%= service_name.dasherize %>" class="module-contents">
|
|
1
|
+
<div id="<%= service_name.dasherize %>" class="module-contents" data-turbolinks="false">
|
|
2
2
|
<% if searcher.is_a? StandardError %>
|
|
3
3
|
<%= render partial: '/quick_search/search/search_error', locals: { service_name: service_name, page: page, template: 'with_paging' } %>
|
|
4
4
|
<% elsif searcher.results.blank? %>
|
|
@@ -15,6 +15,9 @@ defaults: &defaults
|
|
|
15
15
|
xhr_http_timeout: 15
|
|
16
16
|
# Google Analytics tracking ID
|
|
17
17
|
google_analytics_tracking_id: "my_tracking_id"
|
|
18
|
+
# Google Analytics client ID
|
|
19
|
+
# Needed for server-side GA calls (if used). Should be a random UUID
|
|
20
|
+
google_analytics_client_id: "a_random_uuid"
|
|
18
21
|
|
|
19
22
|
# Username/password for QuickSearch stats view
|
|
20
23
|
user: "stats"
|
data/config/routes.rb
CHANGED
|
@@ -3,8 +3,9 @@ QuickSearch::Engine.routes.draw do
|
|
|
3
3
|
root 'search#index'
|
|
4
4
|
|
|
5
5
|
get 'xhr_search' => 'search#xhr_search', :defaults => { :format => 'html' }
|
|
6
|
-
get 'log_event' => '
|
|
7
|
-
get 'log_search' => '
|
|
6
|
+
get 'log_event' => 'logging#log_event'
|
|
7
|
+
get 'log_search' => 'logging#log_search'
|
|
8
|
+
get 'typeahead' => 'typeahead#typeahead'
|
|
8
9
|
|
|
9
10
|
get 'searcher/:searcher_name' => 'search#single_searcher'
|
|
10
11
|
get 'searcher/:searcher_name/xhr_search' => 'search#xhr_search', :defaults => { :format => 'html' }
|
|
@@ -16,13 +17,40 @@ QuickSearch::Engine.routes.draw do
|
|
|
16
17
|
|
|
17
18
|
get 'about' => 'pages#about'
|
|
18
19
|
get 'realtime' => 'pages#realtime'
|
|
20
|
+
get 'data_general_statistics' => 'appstats#data_general_statistics'
|
|
21
|
+
get 'data_general_table' => 'appstats#data_general_table'
|
|
22
|
+
get 'data_module_clicks' => 'appstats#data_module_clicks'
|
|
23
|
+
get 'data_result_clicks' => 'appstats#data_result_clicks'
|
|
24
|
+
get 'data_module_details' => 'appstats#data_module_details'
|
|
25
|
+
get 'data_top_searches' => 'appstats#data_top_searches'
|
|
26
|
+
get 'data_spelling_suggestions' => 'appstats#data_spelling_suggestions'
|
|
27
|
+
get 'data_spelling_details' => 'appstats#data_spelling_details'
|
|
28
|
+
get 'data_best_bets' => 'appstats#data_best_bets'
|
|
29
|
+
get 'data_best_bets_details' => 'appstats#data_best_bets_details'
|
|
30
|
+
get 'data_sessions_overview' => 'appstats#data_sessions_overview'
|
|
31
|
+
get 'data_sessions_location' => 'appstats#data_sessions_location'
|
|
32
|
+
get 'data_sessions_device' => 'appstats#data_sessions_device'
|
|
19
33
|
|
|
20
34
|
match 'appstats', to: 'appstats#index', via: [:get, :post]
|
|
21
35
|
match 'appstats/clicks_overview', to: 'appstats#clicks_overview', as: 'clicks_overview', via: [:get, :post]
|
|
22
36
|
match 'appstats/top_searches', to: 'appstats#top_searches', as: 'top_searches', via: [:get, :post]
|
|
23
37
|
match 'appstats/top_spot', to: 'appstats#top_spot', as: 'top_spot', via: [:get, :post]
|
|
24
|
-
match 'appstats/
|
|
38
|
+
match 'appstats/sessions_overview', to: 'appstats#sessions_overview', as: 'sessions_overview', via: [:get, :post]
|
|
39
|
+
match 'appstats/sessions_details', to: 'appstats#sessions_details', as: 'sessions_details', via: [:get, :post]
|
|
25
40
|
get 'appstats/realtime' => 'appstats#realtime'
|
|
41
|
+
get 'appstats/data_general_statistics', :defaults => { :format => 'json' }
|
|
42
|
+
get 'appstats/data_general_table', :defaults => { :format => 'json' }
|
|
43
|
+
get 'appstats/data_module_clicks', :defaults => { :format => 'json' }
|
|
44
|
+
get 'appstats/data_result_clicks', :defaults => { :format => 'json' }
|
|
45
|
+
get 'appstats/data_module_details', :defaults => { :format => 'json' }
|
|
46
|
+
get 'appstats/data_top_searches', :defaults => { :format => 'json' }
|
|
47
|
+
get 'appstats/data_spelling_suggestions', :defaults => { :format => 'json' }
|
|
48
|
+
get 'appstats/data_spelling_details', :defaults => { :format => 'json' }
|
|
49
|
+
get 'appstats/data_best_bets', :defaults => { :format => 'json' }
|
|
50
|
+
get 'appstats/data_best_bets_details', :defaults => { :format => 'json' }
|
|
51
|
+
get 'appstats/data_sessions_overview', :defaults => { :format => 'json' }
|
|
52
|
+
get 'appstats/data_sessions_location', :defaults => { :format => 'json' }
|
|
53
|
+
get 'appstats/data_sessions_device', :defaults => { :format => 'json' }
|
|
26
54
|
|
|
27
55
|
# The priority is based upon order of creation: first created -> highest priority.
|
|
28
56
|
# See how all your routes lay out with "rake routes".
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class ChangeEventColumns < ActiveRecord::Migration[5.0]
|
|
2
|
+
def change
|
|
3
|
+
change_table :events do |t|
|
|
4
|
+
t.rename :action, :item
|
|
5
|
+
t.rename :label, :query
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
add_column :events, :action, :string
|
|
9
|
+
add_reference :events, :session, foreign_key: true
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class AddDateStringColumns < ActiveRecord::Migration[5.0]
|
|
2
|
+
def change
|
|
3
|
+
add_column :events, :created_at_string, :string
|
|
4
|
+
add_column :sessions, :created_at_string, :string
|
|
5
|
+
add_column :searches, :created_at_string, :string
|
|
6
|
+
|
|
7
|
+
add_index :events, :created_at_string
|
|
8
|
+
add_index :sessions, :created_at_string
|
|
9
|
+
add_index :searches, :created_at_string
|
|
10
|
+
end
|
|
11
|
+
end
|
data/db/seeds.rb
CHANGED
|
@@ -1,7 +1,83 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
|
|
1
|
+
##
|
|
2
|
+
# Generates a random query
|
|
3
|
+
|
|
4
|
+
def random_query
|
|
5
|
+
# Use a fake query
|
|
6
|
+
# TODO: better random queries
|
|
7
|
+
'query ' + (rand*5000).to_i.to_s
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Generates a random (category, action) pair for an event
|
|
12
|
+
|
|
13
|
+
def random_category_action
|
|
14
|
+
category = (QuickSearch::Engine::APP_CONFIG['searchers'] + ['spelling-suggestion', 'result-types', 'doi-trap', 'more-options']).sample.dasherize
|
|
15
|
+
# Default action is a click
|
|
16
|
+
action = 'click'
|
|
17
|
+
|
|
18
|
+
# Typically, serves only happen for these categories
|
|
19
|
+
if category == 'best-bets' || category == 'spelling-suggestion'
|
|
20
|
+
action = ['click', 'serve'].sample
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
return category, action
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Generates a random item for an event, based on the category
|
|
28
|
+
|
|
29
|
+
def random_item(category)
|
|
30
|
+
if category == 'best-bets'
|
|
31
|
+
# Sample a random Best Bet type from a static list
|
|
32
|
+
['webofscience', 'googlescholar', 'ieee', 'pubmed', 'morningstar', 'wgsn', 'standards', 'dissertation', 'refworks', 'ibis', 'proquest',
|
|
33
|
+
'psychinfo', 'sciencemagazine', 'sciencedirect', 'petition', 'compendex', 'jstor', 'software', 'naturejournal'].sample
|
|
34
|
+
elsif category == 'doi-trap'
|
|
35
|
+
# Sample a random DOI from a static list
|
|
36
|
+
['10.1080/10510974.2013.797483', '10.1111/j.1468-2958.1996.tb00379.x', 'http://dx.doi.org/10.1063/1.2741534', 'DOI: 10.1007/BF02887151',
|
|
37
|
+
'10.1039/C4RA16247A', '10.1002/sce.3730670213', 'DOI: 10.1007/s40596-014-0241-5', '10.1080/15348423.2012.697437',
|
|
38
|
+
'http://dx.doi.org/10.3168/jds.S0022-0302(86)80552-5', 'DOI: 10.1023/A:1005204727421', '10.1039/C3TA00019B', 'doi:10.1038/leu.2016.163',
|
|
39
|
+
'DOI: 10.1007/s10853-013-7374-x', 'doi: 10.1016/0167-2738(91)90233-2', 'doi: 10.1179/000705992798268927', '10.1038/nphys3794',
|
|
40
|
+
'doi: 10.1149/1.1393288', '10.1080/1554480X.2014.926052', '10.1002/adma.201506234', '10.1080/00958972.2016.1176158'].sample
|
|
41
|
+
elsif category == 'result-types'
|
|
42
|
+
# Use a defined searcher for found types
|
|
43
|
+
(QuickSearch::Engine::APP_CONFIG['searchers']).sample.dasherize
|
|
44
|
+
elsif category == 'more-options'
|
|
45
|
+
# Use a result number for more-options
|
|
46
|
+
['result-1', 'result-2', 'result-3', 'result-4'].sample
|
|
47
|
+
elsif category == 'spelling-suggestion'
|
|
48
|
+
# Use a fake string
|
|
49
|
+
'spelling suggestion ' + (rand*200).to_i.to_s
|
|
50
|
+
else
|
|
51
|
+
# Use one of the typical options for a searcher click (or anything else we haven't handled above)
|
|
52
|
+
['heading', 'result-1', 'result-2', 'result-3', 'see-all-results', 'no-results', 'error'].sample
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# Creates 15,000 random sessions to seed the QS stats database. Each session will have between 0-8 random queries and
|
|
60
|
+
# 0-15 random events. Measures are taken to make random data somewhat realistic. Session occur at random times over the
|
|
61
|
+
# past 2 years
|
|
62
|
+
|
|
63
|
+
15000.times do |i|
|
|
64
|
+
# Create session with random parameters. Simulate 2 years worth of data
|
|
65
|
+
session = Session.create(session_uuid: SecureRandom.uuid, expiry: rand(2.years).seconds.ago, on_campus: [true, false].sample, is_mobile: [true, false].sample)
|
|
66
|
+
# Update created_at (since we use this as session start time) to be within 10 minutes of the expiry of the session
|
|
67
|
+
session.created_at = session.expiry - (rand*10).minutes
|
|
68
|
+
session.save
|
|
69
|
+
|
|
70
|
+
# Generate 0-8 random searches, occuring at random times during the current session
|
|
71
|
+
(rand*8).to_i.times do |j|
|
|
72
|
+
session.searches.create(query: random_query, page: '/', created_at: Time.at((session.expiry.to_f - session.created_at.to_f)*rand + session.created_at.to_f))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Generate 0-15 random events, occuring at random times during the current session
|
|
76
|
+
(rand*15).to_i.times do |k|
|
|
77
|
+
category, action = random_category_action
|
|
78
|
+
item = random_item(category)
|
|
79
|
+
session.events.create(category: category, item: item, query: random_query, action: action, created_at: Time.at((session.expiry.to_f - session.created_at.to_f)*rand + session.created_at.to_f))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Typeahead front-end configuration & setup
|
|
3
|
+
*/
|
|
4
|
+
jQuery(document).ready(function () {
|
|
5
|
+
|
|
6
|
+
//var bangs_prefetch_url = '/direct_searches/list'
|
|
7
|
+
|
|
8
|
+
// define the datasets for the typeahead
|
|
9
|
+
|
|
10
|
+
/*var bangs = new Dataset({
|
|
11
|
+
valuekey: 'value',
|
|
12
|
+
prefetch: bangs_prefetch_url,
|
|
13
|
+
}).initialize();
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var bestbets = new Bloodhound({
|
|
17
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
18
|
+
datumTokenizer: function (datum) {
|
|
19
|
+
return datum.title.split(" ");
|
|
20
|
+
},
|
|
21
|
+
sorter: function (a,b) {
|
|
22
|
+
if (a.title.toLowerCase() < b.title.toLowerCase()) {
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
if (a.title.toLowerCase() > b.title.toLowerCase()) {
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
return 0;
|
|
29
|
+
},
|
|
30
|
+
prefetch: '/typeahead?searcher=best_bets',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
var titles = new Bloodhound({
|
|
34
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
35
|
+
datumTokenizer: Bloodhound.tokenizers.whitespace,
|
|
36
|
+
remote: {
|
|
37
|
+
url: '//autosuggest.trln.org/suggestservice/?source=ncsu&index=title&q=' + '%QUERY',
|
|
38
|
+
prepare: function(query, settings) {
|
|
39
|
+
settings.dataType = 'jsonp';
|
|
40
|
+
settings.url = settings.url.replace('%QUERY', query);
|
|
41
|
+
return settings;
|
|
42
|
+
},
|
|
43
|
+
filter: function(response){
|
|
44
|
+
return response.response.docs;
|
|
45
|
+
},
|
|
46
|
+
rateLimitWait: 100,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
var spaces = new Bloodhound({
|
|
51
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
52
|
+
datumTokenizer: function (datum) {
|
|
53
|
+
return datum.name.split(" ");
|
|
54
|
+
},
|
|
55
|
+
valueKey: 'name',
|
|
56
|
+
prefetch: '/typeahead?searcher=ncsu_spaces',
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
var faqs = new Bloodhound({
|
|
60
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
61
|
+
datumTokenizer: function (datum) {
|
|
62
|
+
return datum.question.split(" ");
|
|
63
|
+
},
|
|
64
|
+
valueKey: 'question',
|
|
65
|
+
prefetch: '/typeahead?searcher=faq',
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// pre-compile the suggestion templates
|
|
69
|
+
|
|
70
|
+
var bangs_template = Handlebars.compile([
|
|
71
|
+
'<div class="row">',
|
|
72
|
+
'<div class="small-12 columns bestbet-container">',
|
|
73
|
+
'<span class="suggestion-title">{{value}}</span>',
|
|
74
|
+
'{{#if desc}}<p class="bestbet-description">{{desc}}</p>{{/if}}',
|
|
75
|
+
'</div>',
|
|
76
|
+
'</div>',
|
|
77
|
+
].join(''));
|
|
78
|
+
|
|
79
|
+
var bestbets_template = Handlebars.compile([
|
|
80
|
+
'<div class="row">',
|
|
81
|
+
'<div class="small-12 columns bestbet-container">',
|
|
82
|
+
'<span class="suggestion-title">{{title}}</span>',
|
|
83
|
+
'{{#if description}}<p class="bestbet-description">{{description}}</p>{{/if}}',
|
|
84
|
+
'</div>',
|
|
85
|
+
'</div>',
|
|
86
|
+
].join(''));
|
|
87
|
+
|
|
88
|
+
var spaces_template = Handlebars.compile([
|
|
89
|
+
'<div class="row space-container">',
|
|
90
|
+
'<div class="large-2 medium-2 small-2 columns">',
|
|
91
|
+
'{{#if image_url}}<img class="space-image" src="{{image_url}}" width="100%" />',
|
|
92
|
+
'{{else}}<img src="//www.lib.ncsu.edu/sites/all/themes/ncsulib_foundation/images/greybox.png" class="space-image" alt="" >',
|
|
93
|
+
'{{/if}}',
|
|
94
|
+
'</div>',
|
|
95
|
+
'<div class="large-10 medium-10 small-10 columns">',
|
|
96
|
+
'<span class="suggestion-title">{{name}}</span>',
|
|
97
|
+
'</div>',
|
|
98
|
+
'</div>'
|
|
99
|
+
].join(''));
|
|
100
|
+
|
|
101
|
+
var faqs_template = Handlebars.compile('<span class="suggestion-title">{{question}}</span>');
|
|
102
|
+
|
|
103
|
+
// Initialize typeahead
|
|
104
|
+
|
|
105
|
+
jQuery('.quicksearch-typeahead').typeahead(
|
|
106
|
+
{
|
|
107
|
+
// Don't show a hint in the search bar
|
|
108
|
+
hint: false,
|
|
109
|
+
// Wait for at least 3 characters input before making suggestions
|
|
110
|
+
minLength: 3,
|
|
111
|
+
},
|
|
112
|
+
// Best Bets config
|
|
113
|
+
{
|
|
114
|
+
name: 'bestbets',
|
|
115
|
+
source: bestbets,
|
|
116
|
+
display: 'title',
|
|
117
|
+
limit: 2,
|
|
118
|
+
templates: {
|
|
119
|
+
header: '<div class="cat-header"><span>Best Bets</span></div>',
|
|
120
|
+
suggestion: bestbets_template,
|
|
121
|
+
footer: '<hr>'
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
// FAQs
|
|
125
|
+
{
|
|
126
|
+
name: 'faqs',
|
|
127
|
+
source: faqs,
|
|
128
|
+
display: 'question',
|
|
129
|
+
limit: 3,
|
|
130
|
+
templates: {
|
|
131
|
+
header: '<div class="cat-header"><span>FAQs</span></div>',
|
|
132
|
+
suggestion: faqs_template,
|
|
133
|
+
footer: '<hr>'
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
// Search Suggestions / Titles
|
|
137
|
+
{
|
|
138
|
+
name: 'titles',
|
|
139
|
+
source: titles,
|
|
140
|
+
limit: 5,
|
|
141
|
+
display: 'ac',
|
|
142
|
+
templates: {
|
|
143
|
+
header: '<div class="cat-header"><span>Search Suggestions</span></div>',
|
|
144
|
+
footer: '<hr>'
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
// Spaces
|
|
148
|
+
{
|
|
149
|
+
name: 'spaces',
|
|
150
|
+
source: spaces,
|
|
151
|
+
display: 'name',
|
|
152
|
+
limit: 1,
|
|
153
|
+
templates: {
|
|
154
|
+
header: '<div class="cat-header"><span>Spaces</span></div>',
|
|
155
|
+
suggestion: spaces_template,
|
|
156
|
+
footer: '<div class="space-footer"><a href="http://www.lib.ncsu.edu/reservearoom">See more spaces...</a></div>',
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
typeaheadUtility.listenForTypeaheadClicks();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* Typeahead utility functions, currently handles: known vs. unknown item clicks, FAQ URL construction, logging.
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
var typeaheadUtility = (function () {
|
|
170
|
+
|
|
171
|
+
var environment = 'production'; //development or production
|
|
172
|
+
|
|
173
|
+
function listenForTypeaheadClicks() {
|
|
174
|
+
jQuery('.quicksearch-typeahead').on('typeahead:selected', function (e, datum, dataset) {
|
|
175
|
+
|
|
176
|
+
var link = { href: handleTypeaheadClick(datum, dataset) };
|
|
177
|
+
|
|
178
|
+
var eventValuesDefined = {
|
|
179
|
+
category: 'typeahead-' + dataset,
|
|
180
|
+
action: datum.value,
|
|
181
|
+
label: window.location.href
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
sendEventData(eventValuesDefined, link);
|
|
185
|
+
|
|
186
|
+
setTimeout(function() {
|
|
187
|
+
document.location.href = link.href;
|
|
188
|
+
}, 200);
|
|
189
|
+
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function sendEventData (eventValues, link) {
|
|
194
|
+
if (environment == 'development') {
|
|
195
|
+
// console.log('click_tracking', [eventValues.category, eventValues.action, eventValues.label]);
|
|
196
|
+
jQuery.when(logEventToDatabase(eventValues)).then(function () {
|
|
197
|
+
if (link !== '') {
|
|
198
|
+
document.location.href = link.href;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
jQuery.when(logEventToDatabase(eventValues)).then(function () {
|
|
204
|
+
sendDataToGoogleAnalytics(eventValues, link)
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function sendDataToGoogleAnalytics (eventValues, link) {
|
|
210
|
+
_gaq.push(['_set','hitCallback',function() {
|
|
211
|
+
if (link !== '') {
|
|
212
|
+
document.location = link;
|
|
213
|
+
}
|
|
214
|
+
}]);
|
|
215
|
+
// _gaq.push(['_trackEvent', eventValues.category, eventValues.action, eventValues.label]);
|
|
216
|
+
ga('send', eventValues.category, eventValues.action, eventValues.label);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
function logEventToDatabase(eventValues) {
|
|
221
|
+
//TODO: have rails replace URL with current QS root
|
|
222
|
+
var url = '/log_event';
|
|
223
|
+
|
|
224
|
+
return jQuery.ajax({
|
|
225
|
+
url: url,
|
|
226
|
+
data: {
|
|
227
|
+
category: eventValues.category,
|
|
228
|
+
event_action: eventValues.action,
|
|
229
|
+
label: eventValues.label
|
|
230
|
+
},
|
|
231
|
+
jsonp: 'callback',
|
|
232
|
+
dataType: 'jsonp'
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function handleTypeaheadClick(datum, dataset) {
|
|
237
|
+
if (datum.url || datum.path) {
|
|
238
|
+
return datum.url || datum.path;
|
|
239
|
+
}
|
|
240
|
+
else if (datum.question_id) {
|
|
241
|
+
return "//www.lib.ncsu.edu/faq/faq.php?id=" + datum.question_id;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// Fire off a search when an unknown element is selected
|
|
245
|
+
|
|
246
|
+
return '/?q=' + datum.ac;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
listenForTypeaheadClicks: listenForTypeaheadClicks
|
|
252
|
+
};
|
|
253
|
+
})();
|