ahoy_captain 0.1.0 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +55 -14
  4. data/Rakefile +1 -10
  5. data/app/assets/images/ahoy_captain/apple-touch-icon.png +0 -0
  6. data/app/assets/images/ahoy_captain/favicon-16x16.png +0 -0
  7. data/app/assets/images/ahoy_captain/favicon-32x32.png +0 -0
  8. data/app/assets/images/ahoy_captain/logo.png +0 -0
  9. data/app/assets/images/ahoy_captain/safari-pinned-tab.svg +199 -0
  10. data/app/assets/javascript/ahoy_captain/application.js +4 -0
  11. data/app/assets/javascript/ahoy_captain/controllers/application.js +9 -0
  12. data/app/assets/javascript/ahoy_captain/controllers/application_controller.js +14 -0
  13. data/app/assets/javascript/ahoy_captain/controllers/details_modal_controller.js +18 -0
  14. data/app/assets/javascript/ahoy_captain/controllers/dropdown_label_controller.js +14 -0
  15. data/app/assets/javascript/ahoy_captain/controllers/filter_controller.js +145 -0
  16. data/app/assets/javascript/ahoy_captain/controllers/filter_tag_controller.js +17 -0
  17. data/app/assets/javascript/ahoy_captain/controllers/funnel_chart_controller.js +117 -0
  18. data/app/assets/javascript/ahoy_captain/controllers/index.js +3 -0
  19. data/app/assets/javascript/ahoy_captain/controllers/interval_controller.js +10 -0
  20. data/app/assets/javascript/ahoy_captain/controllers/link_controller.js +43 -0
  21. data/app/assets/javascript/ahoy_captain/controllers/navigation_controller.js +25 -0
  22. data/app/assets/javascript/ahoy_captain/controllers/realtime_controller.js +27 -0
  23. data/app/assets/manifest/ahoy_captain/manifest.js +2 -0
  24. data/app/components/ahoy_captain/dropdown_button_component.html.erb +16 -0
  25. data/app/components/ahoy_captain/dropdown_button_component.rb +14 -0
  26. data/app/components/ahoy_captain/dropdown_link_component.html.erb +19 -0
  27. data/app/components/ahoy_captain/dropdown_link_component.rb +15 -0
  28. data/app/components/ahoy_captain/filter/modal_component.html.erb +13 -0
  29. data/app/components/ahoy_captain/filter/modal_component.rb +13 -0
  30. data/app/components/ahoy_captain/filter/select_component.html.erb +21 -0
  31. data/app/components/ahoy_captain/filter/select_component.rb +32 -0
  32. data/app/components/ahoy_captain/filter/tag_component.html.erb +9 -0
  33. data/app/components/ahoy_captain/filter/tag_component.rb +38 -0
  34. data/app/components/ahoy_captain/filter/tag_container_component.html.erb +5 -0
  35. data/app/components/ahoy_captain/filter/tag_container_component.rb +13 -0
  36. data/app/components/ahoy_captain/sticky_nav_component.html.erb +37 -0
  37. data/app/components/ahoy_captain/sticky_nav_component.rb +5 -0
  38. data/app/components/ahoy_captain/table_component.html.erb +49 -0
  39. data/app/components/ahoy_captain/table_component.rb +28 -0
  40. data/app/components/ahoy_captain/tile_component.html.erb +12 -0
  41. data/app/components/ahoy_captain/tile_component.rb +16 -0
  42. data/app/components/ahoy_captain/tooltip_component.html.erb +3 -0
  43. data/app/components/ahoy_captain/tooltip_component.rb +18 -0
  44. data/app/controllers/ahoy_captain/application_controller.rb +86 -0
  45. data/app/controllers/ahoy_captain/campaigns_controller.rb +27 -0
  46. data/app/controllers/ahoy_captain/cities_controller.rb +24 -0
  47. data/app/controllers/ahoy_captain/countries_controller.rb +24 -0
  48. data/app/controllers/ahoy_captain/devices_controller.rb +23 -0
  49. data/app/controllers/ahoy_captain/entry_pages_controller.rb +21 -0
  50. data/app/controllers/ahoy_captain/exit_pages_controller.rb +20 -0
  51. data/app/controllers/ahoy_captain/filters/base_controller.rb +17 -0
  52. data/app/controllers/ahoy_captain/filters/locations_controller.rb +11 -0
  53. data/app/controllers/ahoy_captain/filters/operating_systems/names_controller.rb +13 -0
  54. data/app/controllers/ahoy_captain/filters/operating_systems/versions_controller.rb +13 -0
  55. data/app/controllers/ahoy_captain/filters/pages/actions_controller.rb +13 -0
  56. data/app/controllers/ahoy_captain/filters/pages/entry_pages_controller.rb +14 -0
  57. data/app/controllers/ahoy_captain/filters/pages/exit_pages_controller.rb +16 -0
  58. data/app/controllers/ahoy_captain/filters/screens_controller.rb +11 -0
  59. data/app/controllers/ahoy_captain/filters/sources_controller.rb +11 -0
  60. data/app/controllers/ahoy_captain/filters/utms_controller.rb +10 -0
  61. data/app/controllers/ahoy_captain/funnels_controller.rb +8 -0
  62. data/app/controllers/ahoy_captain/goals_controller.rb +7 -0
  63. data/app/controllers/ahoy_captain/realtimes_controller.rb +7 -0
  64. data/app/controllers/ahoy_captain/regions_controller.rb +24 -0
  65. data/app/controllers/ahoy_captain/roots_controller.rb +6 -0
  66. data/app/controllers/ahoy_captain/sources_controller.rb +24 -0
  67. data/app/controllers/ahoy_captain/stats/base_controller.rb +67 -0
  68. data/app/controllers/ahoy_captain/stats/bounce_rates_controller.rb +11 -0
  69. data/app/controllers/ahoy_captain/stats/total_pageviews_controller.rb +9 -0
  70. data/app/controllers/ahoy_captain/stats/total_visits_controller.rb +9 -0
  71. data/app/controllers/ahoy_captain/stats/unique_visitors_controller.rb +9 -0
  72. data/app/controllers/ahoy_captain/stats/views_per_visits_controller.rb +19 -0
  73. data/app/controllers/ahoy_captain/stats/visit_durations_controller.rb +9 -0
  74. data/app/controllers/ahoy_captain/stats_controller.rb +7 -0
  75. data/app/controllers/ahoy_captain/top_pages_controller.rb +26 -0
  76. data/app/decorators/ahoy_captain/application_decorator.rb +34 -0
  77. data/app/decorators/ahoy_captain/campaign_decorator.rb +19 -0
  78. data/app/decorators/ahoy_captain/city_decorator.rb +12 -0
  79. data/app/decorators/ahoy_captain/country_decorator.rb +28 -0
  80. data/app/decorators/ahoy_captain/device_decorator.rb +16 -0
  81. data/app/decorators/ahoy_captain/entry_page_decorator.rb +7 -0
  82. data/app/decorators/ahoy_captain/exit_page_decorator.rb +7 -0
  83. data/app/decorators/ahoy_captain/page_decorator.rb +16 -0
  84. data/app/decorators/ahoy_captain/region_decorator.rb +12 -0
  85. data/app/decorators/ahoy_captain/source_decorator.rb +20 -0
  86. data/app/decorators/ahoy_captain/top_page_decorator.rb +7 -0
  87. data/app/helpers/ahoy_captain/application_helper.rb +32 -0
  88. data/app/models/ahoy_captain/current.rb +9 -0
  89. data/app/models/ahoy_captain/rangeable.rb +10 -0
  90. data/app/models/ahoy_captain/url_helpers.rb +6 -0
  91. data/app/models/ahoy_captain/widget.rb +15 -0
  92. data/app/models/concerns/ahoy_captain/range_options.rb +21 -0
  93. data/app/presenters/ahoy_captain/dashboard_presenter.rb +84 -0
  94. data/app/presenters/ahoy_captain/funnel_presenter.rb +68 -0
  95. data/app/presenters/ahoy_captain/goals_presenter.rb +69 -0
  96. data/app/queries/ahoy_captain/application_query.rb +121 -0
  97. data/app/queries/ahoy_captain/entry_pages_query.rb +17 -0
  98. data/app/queries/ahoy_captain/event_query.rb +35 -0
  99. data/app/queries/ahoy_captain/exit_pages_query.rb +17 -0
  100. data/app/queries/ahoy_captain/stats/average_views_per_visit_query.rb +13 -0
  101. data/app/queries/ahoy_captain/stats/average_visit_duration_query.rb +11 -0
  102. data/app/queries/ahoy_captain/stats/bounce_rates_query.rb +17 -0
  103. data/app/queries/ahoy_captain/stats/total_pageviews_query.rb +9 -0
  104. data/app/queries/ahoy_captain/stats/total_visitors_query.rb +9 -0
  105. data/app/queries/ahoy_captain/stats/unique_visitors_query.rb +9 -0
  106. data/app/queries/ahoy_captain/stats/views_per_visit_query.rb +17 -0
  107. data/app/queries/ahoy_captain/stats/visit_duration_query.rb +16 -0
  108. data/app/queries/ahoy_captain/visit_query.rb +32 -0
  109. data/app/views/ahoy_captain/campaigns/index.html+details.erb +4 -0
  110. data/app/views/ahoy_captain/campaigns/index.html.erb +3 -0
  111. data/app/views/ahoy_captain/cities/index.html+details.erb +4 -0
  112. data/app/views/ahoy_captain/cities/index.html.erb +3 -0
  113. data/app/views/ahoy_captain/countries/index.html+details.erb +5 -0
  114. data/app/views/ahoy_captain/countries/index.html.erb +3 -0
  115. data/app/views/ahoy_captain/devices/index.html+details.erb +4 -0
  116. data/app/views/ahoy_captain/devices/index.html.erb +3 -0
  117. data/app/views/ahoy_captain/entry_pages/index.html+details.erb +4 -0
  118. data/app/views/ahoy_captain/entry_pages/index.html.erb +3 -0
  119. data/app/views/ahoy_captain/exit_pages/index.html+details.erb +4 -0
  120. data/app/views/ahoy_captain/exit_pages/index.html.erb +3 -0
  121. data/app/views/ahoy_captain/funnels/index.html.erb +7 -0
  122. data/app/views/ahoy_captain/funnels/show.html.erb +6 -0
  123. data/app/views/ahoy_captain/goals/index.html.erb +39 -0
  124. data/app/views/ahoy_captain/layouts/application.html.erb +127 -0
  125. data/app/views/ahoy_captain/realtimes/show.html.erb +9 -0
  126. data/app/views/ahoy_captain/regions/index.html+details.erb +4 -0
  127. data/app/views/ahoy_captain/regions/index.html.erb +3 -0
  128. data/app/views/ahoy_captain/roots/show.html.erb +179 -0
  129. data/app/views/ahoy_captain/sources/index.html+details.erb +4 -0
  130. data/app/views/ahoy_captain/sources/index.html.erb +3 -0
  131. data/app/views/ahoy_captain/stats/base/index.html.erb +14 -0
  132. data/app/views/ahoy_captain/stats/show.html.erb +57 -0
  133. data/app/views/ahoy_captain/top_pages/index.html+details.erb +4 -0
  134. data/app/views/ahoy_captain/top_pages/index.html.erb +3 -0
  135. data/config/routes.rb +56 -0
  136. data/lib/ahoy_captain/active_record.rb +108 -0
  137. data/lib/ahoy_captain/ahoy/event_methods.rb +114 -0
  138. data/lib/ahoy_captain/ahoy/visit_methods.rb +23 -0
  139. data/lib/ahoy_captain/configuration.rb +43 -0
  140. data/lib/ahoy_captain/engine.rb +24 -0
  141. data/lib/ahoy_captain/funnels.rb +44 -0
  142. data/lib/ahoy_captain/goals.rb +43 -0
  143. data/lib/ahoy_captain/period_collection.rb +115 -0
  144. data/lib/ahoy_captain/railtie.rb +7 -0
  145. data/lib/ahoy_captain/version.rb +1 -3
  146. data/lib/ahoy_captain.rb +50 -4
  147. data/lib/generators/ahoy_captain/install_generator.rb +18 -0
  148. data/lib/generators/ahoy_captain/migration_generator.rb +21 -0
  149. data/lib/generators/ahoy_captain/templates/config.rb.tt +138 -0
  150. data/lib/generators/ahoy_captain/templates/migration.rb.tt +7 -0
  151. metadata +410 -17
  152. data/.rspec +0 -3
  153. data/.rubocop.yml +0 -13
  154. data/CHANGELOG.md +0 -5
  155. data/Gemfile +0 -12
  156. data/ahoy_captain.gemspec +0 -37
  157. data/sig/ahoy_captain.rbs +0 -4
@@ -0,0 +1,44 @@
1
+ module AhoyCaptain
2
+ class Funnel
3
+ attr_accessor :id
4
+ attr_reader :goals
5
+
6
+ def initialize
7
+ @id = nil
8
+ @label = nil
9
+ @goals = []
10
+ end
11
+
12
+ def goal(id)
13
+ @goals << AhoyCaptain.config.goals[id]
14
+ end
15
+
16
+ def label(value)
17
+ @label = value
18
+ end
19
+
20
+ def title
21
+ @label
22
+ end
23
+ end
24
+
25
+ class FunnelCollection
26
+ include Enumerable
27
+
28
+ def initialize
29
+ @funnels = {}
30
+ end
31
+
32
+ def register(funnel)
33
+ @funnels[funnel.id] = funnel
34
+ end
35
+
36
+ def each(&block)
37
+ @funnels.each(&block)
38
+ end
39
+
40
+ def [](value)
41
+ @funnels[value.to_sym]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,43 @@
1
+ module AhoyCaptain
2
+ class Goal
3
+ attr_accessor :id
4
+ attr_reader :title, :event_query
5
+ def initialize
6
+ @id = nil
7
+ @title = nil
8
+ @event_query = nil
9
+ end
10
+
11
+ def label(value)
12
+ @title = value
13
+ end
14
+
15
+ def name(value)
16
+ @event_query = -> { AhoyCaptain.event.where(name: value) }
17
+ end
18
+
19
+ def query(&block)
20
+ @event_query = block
21
+ end
22
+ end
23
+
24
+ class GoalCollection
25
+ include Enumerable
26
+
27
+ def initialize
28
+ @goals = {}
29
+ end
30
+
31
+ def register(goal)
32
+ @goals[goal.id] = goal
33
+ end
34
+
35
+ def each(&block)
36
+ @goals.values.each(&block)
37
+ end
38
+
39
+ def [](value)
40
+ @goals[value]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,115 @@
1
+ module AhoyCaptain
2
+ class PeriodCollection
3
+ class Period
4
+ attr_reader :param, :label, :range
5
+ def initialize(param:, label:, range:)
6
+ @param = param
7
+ @label = label
8
+ @range = range
9
+ end
10
+ end
11
+
12
+ def self.load_default
13
+ instance = new
14
+ {
15
+ realtime: {
16
+ label: "Realtime",
17
+ range: -> { [1.minute.ago] },
18
+ },
19
+ day: {
20
+ label: "Day",
21
+ range: -> { [Time.current.beginning_of_day, Time.current] },
22
+ },
23
+ '7d': {
24
+ label: "7 Days",
25
+ range: -> { [7.days.ago, Time.current] },
26
+ },
27
+ '30d': {
28
+ label: "30 Days",
29
+ range: -> { [30.days.ago, Time.current] },
30
+ },
31
+ mtd: {
32
+ label: "Month-to-date",
33
+ range: -> { [Time.current.beginning_of_month, Time.current] },
34
+ },
35
+ lastmonth: {
36
+ label: "Last month",
37
+ range: -> { [1.month.ago.beginning_of_month, 1.month.ago.end_of_month] },
38
+ },
39
+ ytd: {
40
+ label: "This year",
41
+ range: -> { [Time.current.beginning_of_year, Time.current] },
42
+ },
43
+ '12mo': {
44
+ label: "12 months",
45
+ range: -> { [12.months.ago.to_datetime, Time.current] },
46
+ },
47
+ all: {
48
+ label: "All-time",
49
+ range: -> { [Date.new(2004, 8, 1).to_datetime, Time.current] },
50
+ },
51
+ }.each do |param, options|
52
+ instance.add(param, options[:label], options[:range])
53
+ end
54
+ instance.default = :mtd
55
+ instance
56
+ end
57
+
58
+ attr_reader :default, :max
59
+ def initialize
60
+ @periods = {}
61
+ @default = nil
62
+ @max = nil
63
+ end
64
+
65
+ def add(param, label, range_proc)
66
+ raise ArgumentError, "range must be a proc, or respond to .call" unless range_proc.respond_to?(:call)
67
+ raise ArgumentError, "range.call must return a range or an array" unless range_proc.call.is_a?(Range) || range_proc.call.is_a?(Array)
68
+
69
+ @periods[param.to_sym] = Period.new(param: param, label: label, range: range_proc)
70
+ end
71
+
72
+ def delete(param)
73
+ @periods.delete(param.to_sym)
74
+ end
75
+
76
+ def reset
77
+ @periods = {}
78
+ @default = nil
79
+ end
80
+
81
+ def each(&block)
82
+ @periods.each(&block)
83
+ end
84
+
85
+ def find(value)
86
+ @periods[value.try(:to_sym)]
87
+ end
88
+
89
+ def all
90
+ @periods
91
+ end
92
+
93
+ def default=(val)
94
+ @default = val.to_sym
95
+ end
96
+
97
+ def max=(amount)
98
+ @max = amount
99
+ end
100
+
101
+ def for(value)
102
+ if value.nil?
103
+ period = @periods[@default]
104
+ else
105
+ period = (@periods[value.to_sym] || @periods[@default])
106
+ end
107
+
108
+ if period
109
+ period.range.call
110
+ else
111
+ nil
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,7 @@
1
+ module AhoyCaptain
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "ahoy_captain.assets.precompile" do |app|
4
+ app.config.assets.precompile += %w[ahoy_captain/manifest]
5
+ end
6
+ end
7
+ end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module AhoyCaptain
4
- VERSION = "0.1.0"
2
+ VERSION = "0.8"
5
3
  end
data/lib/ahoy_captain.rb CHANGED
@@ -1,8 +1,54 @@
1
- # frozen_string_literal: true
1
+ require "ahoy_captain/version"
2
+ require "ahoy_captain/railtie"
3
+ require "ahoy_captain/engine"
4
+ require "ahoy_captain/goals"
5
+ require "ahoy_captain/funnels"
6
+ require "ahoy_captain/configuration"
7
+ require 'ahoy_captain/ahoy/visit_methods'
8
+ require 'ahoy_captain/ahoy/event_methods'
2
9
 
3
- require_relative "ahoy_captain/version"
10
+ require 'importmap-rails'
4
11
 
5
12
  module AhoyCaptain
6
- class Error < StandardError; end
7
- # Your code goes here...
13
+ class << self
14
+ attr_accessor :configuration
15
+
16
+ def cache
17
+ @cache ||= if config.cache[:enabled]
18
+ config.cache[:store]
19
+ else
20
+ ActiveSupport::Cache::NullStore.new
21
+ end
22
+ end
23
+
24
+ def importmap
25
+ Importmap::Map.new.draw do
26
+ pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
27
+ pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
28
+ pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
29
+ pin "application", to: "ahoy_captain/application.js", preload: true
30
+ pin "slim-select", to: "https://ga.jspm.io/npm:slim-select@2.6.0/dist/slimselect.es.js", preload: true
31
+ pin "chartkick", to: "chartkick.js"
32
+ pin "Chart.bundle", to: "Chart.bundle.js"
33
+ pin "chartjs-plugin-datalabels", to: "https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2", preload: true
34
+ pin_all_from AhoyCaptain::Engine.root.join("app/assets/javascript/ahoy_captain/controllers"), under: "controllers", to: "ahoy_captain/controllers"
35
+ end
36
+ end
37
+
38
+ def config
39
+ self.configuration ||= Configuration.new
40
+ end
41
+
42
+ def configure
43
+ yield config
44
+ end
45
+
46
+ def event
47
+ @event ||= config.models[:event].constantize
48
+ end
49
+
50
+ def visit
51
+ @visit ||= config.models[:visit].constantize
52
+ end
53
+ end
8
54
  end
@@ -0,0 +1,18 @@
1
+ require "rails/generators"
2
+
3
+ module AhoyCaptain
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.join(__dir__, "templates")
7
+
8
+ def copy_templates
9
+ insert_into_file ::Rails.root.join("app/models/ahoy/event.rb").to_s, " include AhoyCaptain::Ahoy::EventMethods\n", after: "class Ahoy::Event < ApplicationRecord\n"
10
+ insert_into_file ::Rails.root.join("app/models/ahoy/visit.rb").to_s, " include AhoyCaptain::Ahoy::VisitMethods\n", after: "class Ahoy::Visit < ApplicationRecord\n"
11
+
12
+ template "config.rb", "config/initializers/ahoy_captain.rb"
13
+
14
+ route "mount AhoyCaptain::Engine => '/ahoy_captain'"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require "rails/generators"
2
+ require "rails/generators/active_record"
3
+
4
+ module AhoyCaptain
5
+ module Generators
6
+ class MigrationGenerator < Rails::Generators::Base
7
+ include ActiveRecord::Generators::Migration
8
+ source_root File.join(__dir__, "templates")
9
+
10
+ def copy_templates
11
+ migration_template "migration.rb", "db/migrate/create_ahoy_captain_indexes.rb", migration_version: migration_version
12
+ end
13
+
14
+ private
15
+
16
+ def migration_version
17
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,138 @@
1
+ AhoyCaptain.configure do |config|
2
+ # ==> Event tracking
3
+ #
4
+ # View name
5
+ # The event you use to dictate if a page view occurred
6
+ # config.event.view_name = "$view"
7
+ #
8
+ # URL column
9
+ # The properties that indicate what URL was viewed. Ahoy suggested tracking the
10
+ # controller and action for each view by default, so we use that here.
11
+ # config.event.url_column = "CONCAT(properties->>'controller', '#', properties->>'action')"
12
+ #
13
+ # If you have a `url` key in your `properties`, you could:
14
+ # config.event.url_column = "properties->>'url'"
15
+ #
16
+ # URL exists
17
+ # A query that indicates if a view event has the correct properties for a page view.
18
+ # config.event.url_exists = "JSONB_EXISTS(properties, 'controller') AND JSONB_EXISTS(properties, 'action')"
19
+ #
20
+ # ==> Models
21
+ #
22
+ # Ahoy::Event model
23
+ # config.models.event = '::Ahoy::Event'
24
+ #
25
+ # Ahoy::Visit model
26
+ # config.models.visit = '::Ahoy::Visit'
27
+ #
28
+ #
29
+ # ==> Theme
30
+ #
31
+ # https://daisyui.com/docs/themes/
32
+ # config.theme = "dark"
33
+
34
+ # ==> Disabled widgets
35
+ # Some widgets are more expensive than others. You can disable them here.
36
+ #
37
+ # Here's the list of widgets:
38
+ # * sources
39
+ # * campaigns.utm_medium
40
+ # * campaigns.utm_source
41
+ # * campaigns.utm_term
42
+ # * campaigns.utm_content
43
+ # * campaigns.utm_campaign
44
+ # * top_pages
45
+ # * entry_pages
46
+ # * landing_pages
47
+ # * locations.countries
48
+ # * locations.regions
49
+ # * locations.cities
50
+ # * devices.browsers
51
+ # * devices.operating_systems
52
+ # * devices.device_types
53
+ #
54
+ # config.disabled_widgets = []
55
+
56
+ # ==> Time periods
57
+ #
58
+ # Defaults come from lib/ahoy_captain/period_collection.rb
59
+ #
60
+ # If you want your own entirely, first call reset.
61
+ # config.ranges.reset
62
+ #
63
+ # Then you can add your own.
64
+ # config.ranges.add :param_name, "Label", -> { [3.days.ago, Date.today] }
65
+ #
66
+ # You can also remove an existing one:
67
+ # config.ranges.delete(:mtd)
68
+ #
69
+ # Or add to the defaults:
70
+ # config.ranges.add :custom, "Custom", -> { [6.hours.ago, 2.minutes.ago] }
71
+ #
72
+ # Or overwrite the defaults:
73
+ # config.ranges.add :mtd, "Custom MTD", -> { [2.weeks.ago, Time.current] }
74
+ #
75
+ # And handle the default range, which will be used if no range is given:
76
+ # config.ranges.default = '3d'
77
+ #
78
+ # The max range if a custom range is sent
79
+ # config.ranges.max = 180.days
80
+ #
81
+ # Set to false to disable custom ranges
82
+ # config.ranges.custom = true
83
+
84
+ # ==> Caching
85
+ # config.cache.enabled = false
86
+ #
87
+ # Cache store should be an ActiveSupport::Cache::Store instance
88
+ # config.cache.store = Rails.cache
89
+ #
90
+ # TTL
91
+ # config.cache.ttl = 1.minute
92
+
93
+ #==> Goal tracking
94
+ # Your mother told you to have goals. Track those goals.
95
+ #
96
+ # Basically:
97
+ #
98
+ # config.goal :unique_id do
99
+ # label "Some label here"
100
+ # name "The event name you're tracking in your Ahoy::Event table"
101
+ # end
102
+ #
103
+ # Real-world example:
104
+ #
105
+ # config.goal :appointment_paid do
106
+ # label "Appointment Paid"
107
+ # name "$appointment.paid"
108
+ # end
109
+ #
110
+ # You can also use queries:
111
+ #
112
+ # config.goal :appointment_paid do
113
+ # label "Appointment Paid"
114
+ # query do
115
+ # ::Ahoy::Event.where(...)
116
+ # end
117
+ # end
118
+
119
+ # ==> Funnels
120
+ # Your mother definitely didn't tell you about conversation rate.
121
+ # Except, you're here, so...
122
+ #
123
+ # Basically:
124
+ #
125
+ # config.funnel :id do
126
+ # label "Some label"
127
+ # goal :goal_id_1
128
+ # goal :goal_id_2
129
+ # end
130
+ #
131
+ # Real-world example:
132
+ #
133
+ # config.funnel :appointments do
134
+ # label "Appointment Workflow"
135
+ # goal :appointment_created
136
+ # goal :appointment_paid
137
+ # end
138
+ end
@@ -0,0 +1,7 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ add_index :<%= ::AhoyCaptain.visit.table_name %>, :started_at unless index_exists?(:<%= ::AhoyCaptain.visit.table_name %>, :started_at)
4
+ add_index :<%= ::AhoyCaptain.event.table_name %>, :visit_id unless index_exists?(:<%= ::AhoyCaptain.event.table_name %>, :visit_id)
5
+ add_index :<%= ::AhoyCaptain.event.table_name %>, :time unless index_exists?(:<%= ::AhoyCaptain.event.table_name %>, :time)
6
+ end
7
+ end