searchjoy 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 807861a09661dcbcf5a2f4c580e189e3df4d7f67e3a1dbb863408ce7fc1091c3
4
- data.tar.gz: b901df59229c2a6daa3781a44b66b89d87d171aeede2acbd17f9ef135e78c7fd
3
+ metadata.gz: d828271eb123a378fe3491da733c10c097f083dcdc9b6586fd3947c032f064b7
4
+ data.tar.gz: e907e0cd11b7c68e9431184add27fe79d3f35f573d221318e25e34a33a99847e
5
5
  SHA512:
6
- metadata.gz: 4c7d96778f812145a132f8f756ac2ca1bb88429758db180402f47b0f56d68b9dfe63e461668b28a51162018f7f97f49c6f94100e3430a79bf54056cd2b4fcdbb
7
- data.tar.gz: 744e8fff8679dfc197d4439c7cda43cc21b23f38e12aec883a1b095481ae4f3db597b3f26bc2c409c51c07928a4f68a4a5114b387905b5c0c6f119611dbac7b1
6
+ metadata.gz: fdfc1fd30d7e31156d6891eee806933cead952c6bb0cca8eb1c9579b279b8629809ca08eaa7e01b8035b728ffc3f7c32a769822106c01422577a1c4830d1ab73
7
+ data.tar.gz: c04d0eb16545d44431e962d7bb1e2fb177bd717a53049f0924c565eccc7fe53966c58e8a1eb10cf7656813c6ca9d265825d010a1a1cad15365acdcd8d1c9f69a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.1.0 (2023-02-07)
2
+
3
+ - Improved dashboard labels
4
+ - Improved CSP support
5
+ - Dropped support for Ruby < 2.7 and Rails < 6
6
+
1
7
  ## 1.0.0 (2022-05-10)
2
8
 
3
9
  - Added support for multiple conversions per search
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2022 Andrew Kane
1
+ Copyright (c) 2013-2023 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -7,10 +7,10 @@ Search analytics made easy
7
7
  [![Screenshot](https://searchjoy.dokkuapp.com/assets/searchjoy-7be12d922ca8b31b7d7440e618b0c666698a4b15752653a0c5c45e3dd2737142.png)](https://searchjoy.dokkuapp.com/)
8
8
 
9
9
  - view searches in real-time
10
- - track conversions week over week
10
+ - track conversion rate week over week
11
11
  - monitor the performance of top searches
12
12
 
13
- Works with any search platform, including Elasticsearch, Sphinx, and Solr
13
+ Works with any search platform, including Elasticsearch, OpenSearch, Sphinx, and Solr
14
14
 
15
15
  :cupid: An amazing companion to [Searchkick](https://github.com/ankane/searchkick)
16
16
 
@@ -122,7 +122,11 @@ ENV["SEARCHJOY_PASSWORD"] = "secret"
122
122
  Data should only be retained for as long as it’s needed. Delete older data with:
123
123
 
124
124
  ```ruby
125
- Searchjoy::Search.where("created_at < ?", 1.year.ago).in_batches.delete_all
125
+ Searchjoy::Search.where("created_at < ?", 1.year.ago).find_in_batches do |searches|
126
+ search_ids = searches.map(&:id)
127
+ Searchjoy::Conversion.where(search_id: search_ids).delete_all
128
+ Searchjoy::Search.where(id: search_ids).delete_all
129
+ end
126
130
  ```
127
131
 
128
132
  You can use [Rollup](https://github.com/ankane/rollup) to aggregate important data before you do.
@@ -134,7 +138,10 @@ Searchjoy::Search.rollup("Searches")
134
138
  Delete data for a specific user with:
135
139
 
136
140
  ```ruby
137
- Searchjoy::Search.where(user_id: 1).delete_all
141
+ user_id = 123
142
+ search_ids = Searchjoy::Search.where(user_id: user_id).pluck(:id)
143
+ Searchjoy::Conversion.where(search_id: search_ids).delete_all
144
+ Searchjoy::Search.where(id: search_ids).delete_all
138
145
  ```
139
146
 
140
147
  ## Customize
@@ -34,12 +34,12 @@ module Searchjoy
34
34
 
35
35
  relation = Searchjoy::Search.where(search_type: params[:search_type])
36
36
  @searches_by_week = relation.group_by_period(period, :created_at, time_zone: @time_zone, range: @time_range).count
37
- @conversions_by_week = relation.where.not(converted_at: nil).group_by_period(period, :created_at, time_zone: @time_zone, range: @time_range).count
37
+ @converted_by_week = relation.where.not(converted_at: nil).group_by_period(period, :created_at, time_zone: @time_zone, range: @time_range).count
38
38
  @top_searches = @searches.first(5)
39
39
  @bad_conversion_rate = @searches.sort_by { |s| [s["conversion_rate"].to_f, s["query"]] }.first(5).select { |s| s["conversion_rate"] < 50 }
40
40
  @conversion_rate_by_week = {}
41
41
  @searches_by_week.each do |week, searches_count|
42
- @conversion_rate_by_week[week] = searches_count > 0 ? (100.0 * @conversions_by_week[week] / searches_count).round : 0
42
+ @conversion_rate_by_week[week] = searches_count > 0 ? (100.0 * @converted_by_week[week] / searches_count).round : 0
43
43
  end
44
44
  end
45
45
 
@@ -87,7 +87,7 @@ module Searchjoy
87
87
  def set_searches
88
88
  @limit = params[:limit] || Searchjoy.top_searches
89
89
  relation = Searchjoy::Search
90
- .select("normalized_query, COUNT(*) as searches_count, COUNT(converted_at) as conversions_count, AVG(results_count) as avg_results_count")
90
+ .select("normalized_query, COUNT(*) as searches_count, COUNT(converted_at) as converted_count, AVG(results_count) as avg_results_count")
91
91
  .where(created_at: @time_range, search_type: @search_type)
92
92
  .group(:normalized_query)
93
93
  .order(searches_count: :desc, normalized_query: :asc)
@@ -95,7 +95,7 @@ module Searchjoy
95
95
  # get array of hashes for performance
96
96
  @searches = Searchjoy::Search.connection.select_all(relation.to_sql).to_a
97
97
  @searches.each do |search|
98
- search["conversion_rate"] = 100 * search["conversions_count"].to_i / search["searches_count"].to_f
98
+ search["conversion_rate"] = 100 * search["converted_count"].to_i / search["searches_count"].to_f
99
99
  end
100
100
  end
101
101
  end
@@ -4,6 +4,7 @@
4
4
  <title>Searchjoy</title>
5
5
 
6
6
  <meta charset="utf-8" />
7
+ <%= csp_meta_tag %>
7
8
 
8
9
  <style>
9
10
  body {
@@ -289,9 +290,9 @@
289
290
  </style>
290
291
 
291
292
  <% if defined?(Propshaft::Railtie) %>
292
- <%= javascript_include_tag "chartkick", "Chart.bundle", "searchjoy/litepicker", "searchjoy/application" %>
293
+ <%= javascript_include_tag "chartkick", "Chart.bundle", "searchjoy/litepicker", "searchjoy/application", nonce: true %>
293
294
  <% else %>
294
- <%= javascript_include_tag "searchjoy/application" %>
295
+ <%= javascript_include_tag "searchjoy/application", nonce: true %>
295
296
  <% end %>
296
297
  </head>
297
298
  <body>
@@ -314,7 +315,7 @@
314
315
  <%= @time_range.first.strftime("%b %-e, %Y") %> to <%= @time_range.last.strftime("%b %-e, %Y") %>
315
316
  </span>
316
317
  <span class="text-muted"><%= @time_zone.name.sub(" (US & Canada)", "") %></span>
317
- <script>
318
+ <%= javascript_tag nonce: true do %>
318
319
  var startDate = <%= raw json_escape(@time_range.first.to_json) %>;
319
320
  var endDate = <%= raw json_escape(@time_range.last.to_json) %>;
320
321
  new Litepicker({
@@ -337,7 +338,7 @@
337
338
  window.location.href = window.location.pathname + "?" + params.toString();
338
339
  }
339
340
  });
340
- </script>
341
+ <% end %>
341
342
  <% end %>
342
343
  </div>
343
344
  </div>
@@ -8,7 +8,7 @@
8
8
  <tr>
9
9
  <th>Query</th>
10
10
  <th class="num" style="width: 20%;"><%= link_to "Searches", searches_path(search_type: params[:search_type], **@time_params), class: ("active" if params[:sort] != "conversion_rate") %></th>
11
- <th class="num" style="width: 20%;">Conversions</th>
11
+ <th class="num" style="width: 20%;">Converted</th>
12
12
  <th class="num" style="width: 20%;"><%= link_to "%", searches_path(search_type: params[:search_type], sort: "conversion_rate", **@time_params), class: ("active" if params[:sort] == "conversion_rate") %></th>
13
13
  <th class="num" style="width: 20%;">Avg Results</th>
14
14
  </tr>
@@ -18,7 +18,7 @@
18
18
  <tr>
19
19
  <td><%= search["normalized_query"] %></td>
20
20
  <td class="num"><%= search["searches_count"] %></td>
21
- <td class="num"><%= search["conversions_count"] %></td>
21
+ <td class="num"><%= search["converted_count"] %></td>
22
22
  <td class="num"><%= number_to_percentage search["conversion_rate"].to_f, precision: 0 %></td>
23
23
  <td class="num"><%= search["avg_results_count"].to_f.round %></td>
24
24
  </tr>
@@ -23,7 +23,7 @@
23
23
  <table>
24
24
  <thead>
25
25
  <tr>
26
- <th>Low Conversions</th>
26
+ <th>Low Conversion Rate</th>
27
27
  <th class="num"><%= link_to "View all", searches_path(search_type: @search_type, sort: "conversion_rate", **@time_params) %></th>
28
28
  </tr>
29
29
  </thead>
@@ -45,4 +45,4 @@
45
45
 
46
46
  <h2>Volume</h2>
47
47
 
48
- <%= line_chart [{name: "Searches", data: @searches_by_week}, {name: "Conversions", data: @conversions_by_week}] %>
48
+ <%= line_chart [{name: "Searches", data: @searches_by_week}, {name: "Converted", data: @converted_by_week}] %>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <table id="stream"></table>
4
4
 
5
- <script>
5
+ <%= javascript_tag nonce: true do %>
6
6
  function load(element, path) {
7
7
  var request = new XMLHttpRequest();
8
8
  request.open("GET", path, true);
@@ -20,4 +20,4 @@
20
20
  setTimeout(fetchRecentSearches, 5 * 1000);
21
21
  }
22
22
  fetchRecentSearches();
23
- </script>
23
+ <% end %>
@@ -4,7 +4,7 @@ module Searchjoy
4
4
 
5
5
  initializer "searchjoy" do |app|
6
6
  if app.config.respond_to?(:assets)
7
- if defined?(Sprockets) && Sprockets::VERSION >= "4"
7
+ if defined?(Sprockets) && Sprockets::VERSION.to_i >= 4
8
8
  app.config.assets.precompile << "searchjoy/application.js"
9
9
  else
10
10
  # use a proc instead of a string
@@ -1,3 +1,3 @@
1
1
  module Searchjoy
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/searchjoy.rb CHANGED
@@ -4,8 +4,8 @@ require "chartkick"
4
4
  require "groupdate"
5
5
 
6
6
  # modules
7
- require "searchjoy/track"
8
- require "searchjoy/version"
7
+ require_relative "searchjoy/track"
8
+ require_relative "searchjoy/version"
9
9
 
10
10
  module Searchjoy
11
11
  # time zone
@@ -44,19 +44,13 @@ module Searchjoy
44
44
  created_at: search.converted_at
45
45
  }
46
46
  end
47
- if ActiveRecord::VERSION::MAJOR >= 6
48
- Searchjoy::Conversion.insert_all(conversions)
49
- else
50
- Searchjoy::Conversion.transaction do
51
- Searchjoy::Conversion.create!(conversions)
52
- end
53
- end
47
+ Searchjoy::Conversion.insert_all(conversions)
54
48
  end
55
49
  end
56
50
  end
57
51
 
58
52
  if defined?(Rails)
59
- require "searchjoy/engine"
60
- else
61
- Searchjoy.attach_to_searchkick! if defined?(Searchkick)
53
+ require_relative "searchjoy/engine"
54
+ elsif defined?(Searchkick)
55
+ Searchjoy.attach_to_searchkick!
62
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchjoy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-10 00:00:00.000000000 Z
11
+ date: 2023-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chartkick
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '5.2'
47
+ version: '6'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '5.2'
54
+ version: '6'
55
55
  description:
56
56
  email: andrew@ankane.org
57
57
  executables: []
@@ -91,14 +91,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - ">="
93
93
  - !ruby/object:Gem::Version
94
- version: '2.6'
94
+ version: '2.7'
95
95
  required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  requirements:
97
97
  - - ">="
98
98
  - !ruby/object:Gem::Version
99
99
  version: '0'
100
100
  requirements: []
101
- rubygems_version: 3.3.7
101
+ rubygems_version: 3.4.6
102
102
  signing_key:
103
103
  specification_version: 4
104
104
  summary: Search analytics made easy