ahoy_captain 0.10.1 → 0.11.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/Rakefile +23 -2
- data/app/assets/javascript/ahoy_captain/controllers/application_controller.js +12 -0
- data/app/assets/javascript/ahoy_captain/controllers/combobox_controller.js +50 -20
- data/app/assets/javascript/ahoy_captain/controllers/frame_link_controller.js +20 -0
- data/app/assets/javascript/ahoy_captain/controllers/line_chart_controller.js +67 -4
- data/app/assets/javascript/ahoy_captain/controllers/map_controller.js +47 -0
- data/app/assets/javascript/ahoy_captain/controllers/predicate_select_controller.js +1 -0
- data/app/assets/javascript/ahoy_captain/helpers/countries.js +2261 -0
- data/app/components/ahoy_captain/combobox_component.html.erb +2 -2
- data/app/components/ahoy_captain/combobox_component.rb +1 -1
- data/app/components/ahoy_captain/dropdown_link_component.html.erb +2 -4
- data/app/components/ahoy_captain/dropdown_link_component.rb +4 -0
- data/app/components/ahoy_captain/previous_next_component.html.erb +8 -0
- data/app/components/ahoy_captain/previous_next_component.rb +11 -0
- data/app/components/ahoy_captain/stats/comparable_container_component.html.erb +1 -1
- data/app/components/ahoy_captain/stats/container_component.html.erb +1 -1
- data/app/components/ahoy_captain/sticky_nav_component.html.erb +26 -22
- data/app/components/ahoy_captain/sticky_nav_component.rb +8 -0
- data/app/components/ahoy_captain/tile_component.rb +7 -0
- data/app/controllers/ahoy_captain/locations/cities_controller.rb +22 -0
- data/app/controllers/ahoy_captain/locations/countries_controller.rb +22 -0
- data/app/controllers/ahoy_captain/locations/maps_controller.rb +24 -0
- data/app/controllers/ahoy_captain/locations/regions_controller.rb +22 -0
- data/app/helpers/ahoy_captain/application_helper.rb +0 -2
- data/app/models/ahoy_captain/range_from_params.rb +4 -0
- data/app/views/ahoy_captain/locations/maps/show.html.erb +3 -0
- data/app/views/ahoy_captain/properties/_form.html.erb +1 -1
- data/app/views/ahoy_captain/roots/show.html.erb +46 -54
- data/app/views/ahoy_captain/stats/base/index.html.erb +1 -0
- data/app/views/ahoy_captain/stats/show.html.erb +11 -6
- data/config/routes.rb +7 -3
- data/lib/ahoy_captain/filters_configuration.rb +5 -5
- data/lib/ahoy_captain/version.rb +1 -1
- data/lib/ahoy_captain.rb +1 -0
- metadata +102 -12
- data/app/assets/javascript/ahoy_captain/controllers/active_links_controller.js +0 -30
- data/app/controllers/ahoy_captain/cities_controller.rb +0 -20
- data/app/controllers/ahoy_captain/countries_controller.rb +0 -20
- data/app/controllers/ahoy_captain/regions_controller.rb +0 -20
- /data/app/views/ahoy_captain/{cities → locations/cities}/index.html+details.erb +0 -0
- /data/app/views/ahoy_captain/{cities → locations/cities}/index.html.erb +0 -0
- /data/app/views/ahoy_captain/{countries → locations/countries}/index.html+details.erb +0 -0
- /data/app/views/ahoy_captain/{countries → locations/countries}/index.html.erb +0 -0
- /data/app/views/ahoy_captain/{regions → locations/regions}/index.html+details.erb +0 -0
- /data/app/views/ahoy_captain/{regions → locations/regions}/index.html.erb +0 -0
@@ -10,7 +10,7 @@
|
|
10
10
|
>
|
11
11
|
<div data-action="click->combobox#toggleOpen" data-combobox-target="box"
|
12
12
|
class="
|
13
|
-
bg-gray-900 ring-0 focus-within:ring-0 focus-within:ring-0 focus:ring-0 focus:outline-none w-full rounded-md
|
13
|
+
bg-gray-900 ring-0 focus-within:ring-0 focus-within:ring-0 focus:ring-0 focus:outline-none w-full rounded-md py-2 text-sm
|
14
14
|
w-full"
|
15
15
|
data-combobox-box-open-class="border-secondary-500 ring-1 ring-secondary-500">
|
16
16
|
<select data-combobox-target="select" style="display:none;"
|
@@ -19,7 +19,7 @@
|
|
19
19
|
id="<%= @select_html[:id] || "filter_#{@name}" %>"
|
20
20
|
<% @select_html.each do |k,v| %><%=k %>="<%=v %>"<% end %>
|
21
21
|
><% @value.each do |value| %><option value="<%= value %>" selected><%= value %></option><% end %></select>
|
22
|
-
<div data-combobox-target="selected" class="" style="display:none;"></div>
|
22
|
+
<div data-combobox-target="selected" class="px-2" style="display:none;"></div>
|
23
23
|
<input data-combobox-target="input"
|
24
24
|
data-action="input->combobox#onInput"
|
25
25
|
class="input input-sm input-ghost w-full inline-block rounded-md focus:outline-none focus:ring-0 focus:bg-gray-900"
|
@@ -1,13 +1,11 @@
|
|
1
|
-
<div class="dropdown dropdown-end
|
1
|
+
<div class="dropdown dropdown-end" data-controller='dropdown-label'>
|
2
2
|
<label
|
3
3
|
tabindex="0"
|
4
4
|
class="cursor-pointer flex <%= classes %>"
|
5
5
|
data-action='click->dropdown-label#removeHidden'
|
6
6
|
>
|
7
7
|
<span data-dropdown-label-target="label"><%= title %></span>
|
8
|
-
|
9
|
-
<path fill="currentColor" d="M16.53 8.97a.75.75 0 0 1 0 1.06l-4 4a.75.75 0 0 1-1.06 0l-4-4a.75.75 0 1 1 1.06-1.06L12 12.44l3.47-3.47a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" />
|
10
|
-
</svg>
|
8
|
+
|
11
9
|
</label>
|
12
10
|
<ul class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52" data-dropdown-label-target="close">
|
13
11
|
<% options.each do |option| %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div class="rounded shadow bg-white cursor-pointer dark:bg-gray-800 flex h-8">
|
2
|
+
<button class="flex items-center px-1 sm:px-2 border-r border-gray-300 rounded-l dark:border-gray-500 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-900" type="button">
|
3
|
+
<svg class="feather h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
4
|
+
</button>
|
5
|
+
<button class="flex items-center px-1 sm:px-2 rounded-r dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-900" type="button">
|
6
|
+
<svg class="feather h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
|
7
|
+
</button>
|
8
|
+
</div>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<a href="<%= @url %>" class="relative px-4 md:px-6 w-1/2 my-4 w-auto group cursor-pointer"
|
1
|
+
<a href="<%= @url %>" class="relative px-4 md:px-6 w-1/2 my-4 w-auto group cursor-pointer" data-controller="frame-link" data-turbo-frame="chart">
|
2
2
|
<div>
|
3
3
|
<h5 class="text-sm font-bold uppercase whitespace-nowrap flex w-content border-transparent tooltip tooltip-bottom "
|
4
4
|
data-active-links-target="link" data-tip="<%= tooltip %>">
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<a href="<%= @url %>" class="relative px-4 md:px-6 w-1/2 my-4 lg:w-auto group cursor-pointer"
|
1
|
+
<a href="<%= @url %>" class="relative px-4 md:px-6 w-1/2 my-4 lg:w-auto group cursor-pointer" data-controller="frame-link" data-turbo-frame="chart">
|
2
2
|
<div>
|
3
3
|
<h5 class="text-sm font-bold uppercase whitespace-nowrap flex w-content border-transparent tooltip tooltip-bottom "
|
4
4
|
data-active-links-target="link">
|
@@ -1,28 +1,32 @@
|
|
1
|
-
<div class="
|
2
|
-
<div class="flex
|
3
|
-
<
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
<div class=" sticky top-0 min-h-sm z-[99999] py-4 bg-base-100 pb-4">
|
2
|
+
<div class="max-w-6xl mx-auto max-w-6xl flex justify-between ">
|
3
|
+
<div class="flex items-center">
|
4
|
+
<a href="/">
|
5
|
+
<img src="<%= image_path "ahoy_captain/logo.png" %>" alt="AhoyCaptainLogo" class='max-h-20 md:h-16 rounded-full'>
|
6
|
+
</a>
|
7
|
+
<% if tag_list_hidden? %>
|
8
|
+
<%= render AhoyCaptain::Filter::TagContainerComponent.new %>
|
9
|
+
<% else %>
|
10
|
+
<%= realtime_update %>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
<div class="flex flex-row-reverse col-span-2 items-center gap-3">
|
14
|
+
<%= render AhoyCaptain::ComparisonLinkComponent.new %>
|
15
|
+
<%= render AhoyCaptain::PreviousNextComponent.new(range) %>
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
<%= render AhoyCaptain::DropdownLinkComponent.new(title: params[:start_date] ? custom_range_label : (AhoyCaptain.config.ranges.find(params[:period] || AhoyCaptain.config.ranges.default).try(:label) || "Period"), classes: 'btn btn-sm btn-base-100 no-underline hover:bg-base-100') do |dropdown| %>
|
18
|
+
<% dropdown.with_option do %>
|
19
|
+
<% AhoyCaptain.config.ranges.each do |param, range| %>
|
20
|
+
<a class='link no-underline' href="<%= request.path %>?<%= request.query_parameters.except("start_date", "end_date", "date", "compare_to_start_date", "compare_to_end_date").merge("period" => param).to_query %>"><%= range.label %></a>
|
21
|
+
<% end %>
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
+
<a class='link no-underline ' href='#' onclick="event.preventDefault(); customRangeModal.showModal()">Custom Range</a>
|
24
|
+
<a class='link no-underline ' href='<%= AhoyCaptain::Engine.routes.url_helpers.root_path(**helpers.search_params.merge(comparison: !compare_mode?)) %>'><%= compare_mode? ? "Disable Comparison" : "Compare" %></a>
|
25
|
+
<% end %>
|
23
26
|
<% end %>
|
24
|
-
<% end %>
|
25
27
|
|
26
|
-
|
28
|
+
<%= render AhoyCaptain::Filter::DropdownComponent.new(filters: filters) %>
|
29
|
+
</div>
|
27
30
|
</div>
|
31
|
+
|
28
32
|
</div>
|
@@ -10,6 +10,14 @@ class AhoyCaptain::StickyNavComponent < ViewComponent::Base
|
|
10
10
|
@filters ||= ::AhoyCaptain::FilterParser.parse(request)
|
11
11
|
end
|
12
12
|
|
13
|
+
def custom_range_label
|
14
|
+
if range.custom?
|
15
|
+
[range.starts_at, range.ends_at].map { |date| date.strftime('%b %d, %Y') }.join("-")
|
16
|
+
else
|
17
|
+
"Custom Range"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
def tag_list_hidden?
|
14
22
|
filters.values.map(&:values).flatten.size < ::AhoyCaptain::FilterParser::FILTER_MENU_MAX_SIZE
|
15
23
|
end
|
@@ -11,6 +11,13 @@ class AhoyCaptain::TileComponent < ViewComponent::Base
|
|
11
11
|
@wide = wide
|
12
12
|
end
|
13
13
|
|
14
|
+
def link_to(name, url, **options)
|
15
|
+
options[:class] = "inline-block h-5 font-semibold"
|
16
|
+
options[:data] ||= {}
|
17
|
+
options[:data].merge!(controller: "frame-link")
|
18
|
+
view_context.link_to name, url, **options
|
19
|
+
end
|
20
|
+
|
14
21
|
private
|
15
22
|
|
16
23
|
attr_reader :title, :wide
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module AhoyCaptain
|
2
|
+
module Locations
|
3
|
+
class CitiesController < ApplicationController
|
4
|
+
include AhoyCaptain::Limitable
|
5
|
+
|
6
|
+
before_action do
|
7
|
+
if Widget.disabled?(:locations, :cities)
|
8
|
+
raise Widget::WidgetDisabled.new("Widget disabled", :geography)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def index
|
13
|
+
results = cached(:cities) do
|
14
|
+
CityQuery.call(params)
|
15
|
+
.limit(limit)
|
16
|
+
end
|
17
|
+
|
18
|
+
@cities = paginate(results).map { |city| CityDecorator.new(city, self) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module AhoyCaptain
|
2
|
+
module Locations
|
3
|
+
class CountriesController < ApplicationController
|
4
|
+
include Limitable
|
5
|
+
|
6
|
+
before_action do
|
7
|
+
if Widget.disabled?(:locations, :countries)
|
8
|
+
raise Widget::WidgetDisabled.new("Widget disabled", :geography)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def index
|
13
|
+
results = cached(:countries) do
|
14
|
+
CountryQuery.call(params)
|
15
|
+
.limit(limit)
|
16
|
+
end
|
17
|
+
|
18
|
+
@countries = paginate(results).map { |country| CountryDecorator.new(country, self) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module AhoyCaptain
|
2
|
+
module Locations
|
3
|
+
class MapsController < ApplicationController
|
4
|
+
include Limitable
|
5
|
+
|
6
|
+
before_action do
|
7
|
+
if Widget.disabled?(:locations, :map)
|
8
|
+
raise Widget::WidgetDisabled.new("Widget disabled", :geography)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def show
|
13
|
+
if request.variant.include?(:details)
|
14
|
+
results = CountryQuery.call(params)
|
15
|
+
results = results.limit(limit)
|
16
|
+
@countries = paginate(results).map { |country| CountryDecorator.new(country, self) }
|
17
|
+
render template: 'ahoy_captain/locations/countries/index'
|
18
|
+
else
|
19
|
+
@countries = visit_query.group("country").count
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module AhoyCaptain
|
2
|
+
module Locations
|
3
|
+
class RegionsController < ApplicationController
|
4
|
+
include Limitable
|
5
|
+
|
6
|
+
before_action do
|
7
|
+
if Widget.disabled?(:locations, :regions)
|
8
|
+
raise Widget::WidgetDisabled.new("Widget disabled", :geography)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def index
|
13
|
+
results = cached(:regions) do
|
14
|
+
RegionQuery.call(params)
|
15
|
+
.limit(limit)
|
16
|
+
end
|
17
|
+
|
18
|
+
@regions = paginate(results).map { |region| RegionDecorator.new(region, self) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<select class="select text-accent-
|
1
|
+
<select class="select text-accent select-sm w-full max-w-sm" data-controller="properties" data-action="change->properties#handleChange">
|
2
2
|
<option></option>
|
3
3
|
<% @options.each do |key, value| %>
|
4
4
|
<option value="<%= property_path(id: key) %>" <%= 'selected' if local_assigns[:selected] == value %>><%= value %></option>
|
@@ -1,15 +1,14 @@
|
|
1
|
-
<main class='
|
1
|
+
<main class='w-screen overflow-hidden' data-action="combobox:init@window->application#comboboxInit">
|
2
2
|
<%= render AhoyCaptain::StickyNavComponent.new do |nav| %>
|
3
3
|
<% nav.with_realtime_update do %>
|
4
4
|
<%= turbo_frame_tag :realtime, src: realtime_path, data: { controller: "realtime", "realtime-interval-value" => AhoyCaptain.config.realtime_interval.to_i }, loading: :lazy %>
|
5
5
|
<% end %>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<div class="grid grid-cols-1 lg:grid-cols-2 grid-flow-row gap-4">
|
8
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 grid-flow-row gap-4 min-h-screen pb-4 max-w-6xl mx-auto">
|
9
9
|
<%= render AhoyCaptain::TileComponent.new(wide: true, classes: "p-4 m-2") do |component| %>
|
10
10
|
<% component.with_statistic_display do %>
|
11
11
|
<%= turbo_frame_tag :stats, src: stats_path(search_params), loading: :lazy %>
|
12
|
-
|
13
12
|
<%= turbo_frame_tag :chart, src: stats_unique_visitors_path(search_params) do %>
|
14
13
|
<% end %>
|
15
14
|
<% end %>
|
@@ -17,21 +16,19 @@
|
|
17
16
|
<% end %>
|
18
17
|
|
19
18
|
<%= render AhoyCaptain::TileComponent.new(title: 'Top Sources') do |component| %>
|
20
|
-
<% component.with_display_links do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
data-active-links-target="link">
|
29
|
-
<%= source.titleize.gsub("Utm", "UTM") %>
|
30
|
-
</a>
|
19
|
+
<% component.with_display_links do %>
|
20
|
+
<div class="flex text-xs font-medium text-gray-400 space-x-2">
|
21
|
+
<div class="relative inline-block text-left">
|
22
|
+
<%= component.link_to "All", sources_path(search_params), data: { turbo_frame: "sources" } %>
|
23
|
+
<%= render AhoyCaptain::DropdownLinkComponent.new(title: "Campaign") do |dropdown| %>
|
24
|
+
<% %w{utm_source utm_medium utm_term utm_content utm_campaign}.each do |source| %>
|
25
|
+
<%= dropdown.link_to source.titleize.gsub("Utm", "UTM"), public_send("campaign_#{source}_path".to_sym, **search_params), data: { turbo_frame: "sources" } %>
|
26
|
+
<% end %>
|
31
27
|
<% end %>
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
|
35
32
|
<% end %>
|
36
33
|
<% component.with_statistic_display do %>
|
37
34
|
<%= turbo_frame_tag :sources, src: sources_path(search_params), loading: :lazy %>
|
@@ -44,14 +41,10 @@
|
|
44
41
|
<%= render AhoyCaptain::TileComponent.new(title: 'Top Pages') do |component| %>
|
45
42
|
<% component.with_display_links do %>
|
46
43
|
<div class="flex text-xs font-medium text-gray-400 space-x-2">
|
47
|
-
<div class="relative inline-block text-left"
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
data-active-links-target="link"
|
52
|
-
data-action="click->tile#setTitle">Top Pages</a>
|
53
|
-
<a href="<%= entry_pages_path(search_params) %>" data-turbo-frame="pages" class="inline-block h-5 font-semibold" data-active-links-target="link" data-action="click->tile#setTitle">Entry Pages</a>
|
54
|
-
<a href="<%= exit_pages_path(search_params) %>" data-turbo-frame="pages" class="inline-block h-5 font-semibold" data-active-links-target="link" data-action="click->tile#setTitle">Exit Pages</a>
|
44
|
+
<div class="relative inline-block text-left"><div>
|
45
|
+
<%= component.link_to "Top Pages", top_pages_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "pages" } %>
|
46
|
+
<%= component.link_to "Entry Pages", entry_pages_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "pages" } %>
|
47
|
+
<%= component.link_to "Exit Pages", exit_pages_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "pages" } %>
|
55
48
|
</div>
|
56
49
|
</div>
|
57
50
|
</div>
|
@@ -65,33 +58,32 @@
|
|
65
58
|
<% end %>
|
66
59
|
<% end %>
|
67
60
|
|
68
|
-
<%= render AhoyCaptain::TileComponent.new(title: '
|
61
|
+
<%= render AhoyCaptain::TileComponent.new(title: 'Map') do |component| %>
|
69
62
|
<% component.with_display_links do %>
|
70
63
|
<div class="flex text-xs font-medium text-gray-400 space-x-2">
|
71
|
-
<div class="relative inline-block text-left"
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
<div class="relative inline-block text-left">
|
65
|
+
<%= component.link_to "Map", locations_map_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "geography" } %>
|
66
|
+
<%= component.link_to "Countries", locations_countries_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "geography" } %>
|
67
|
+
<%= component.link_to "Regions", locations_regions_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "geography" } %>
|
68
|
+
<%= component.link_to "Cities", locations_cities_path(search_params), data: { action: "click->tile#setTitle", turbo_frame: "geography" } %>
|
76
69
|
</div>
|
77
70
|
</div>
|
78
71
|
<% end %>
|
79
72
|
<% component.with_statistic_display do %>
|
80
|
-
<%= turbo_frame_tag :geography, src:
|
73
|
+
<%= turbo_frame_tag :geography, src: locations_map_path(search_params), loading: :lazy %>
|
81
74
|
<% end %>
|
82
75
|
<% component.with_details_cta do %>
|
83
|
-
<button data-action="click->details-modal#openModal" data-controller="details-modal"
|
76
|
+
<button data-action="click->details-modal#openModal" data-controller="details-modal" data-details-modal-target-value="#geography" class="link no-underline ">Details</button>
|
84
77
|
<% end %>
|
85
78
|
<% end %>
|
86
79
|
|
87
80
|
<%= render AhoyCaptain::TileComponent.new(title: 'Devices') do |component| %>
|
88
81
|
<% component.with_display_links do %>
|
89
82
|
<div class="flex text-xs font-medium text-gray-400 space-x-2">
|
90
|
-
<div class="relative inline-block text-left"
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
<a href="<%= devices_device_types_path(search_params) %>" data-turbo-frame="devices" class="inline-block h-5 font-semibold" data-active-links-target="link">Size</a>
|
83
|
+
<div class="relative inline-block text-left">
|
84
|
+
<%= component.link_to "Browser", devices_browsers_path(search_params), data: { turbo_frame: "devices" } %>
|
85
|
+
<%= component.link_to "OS", devices_operating_systems_path(search_params), data: { turbo_frame: "devices" } %>
|
86
|
+
<%= component.link_to "Size", devices_device_types_path(search_params), data: { turbo_frame: "devices" } %>
|
95
87
|
</div>
|
96
88
|
</div>
|
97
89
|
<% end %>
|
@@ -105,23 +97,23 @@
|
|
105
97
|
<%= render AhoyCaptain::TileComponent.new(title: "Goals and Funnels", wide: true, classes: "p-4 m-2") do |component| %>
|
106
98
|
<% component.with_display_links do %>
|
107
99
|
<div>
|
108
|
-
<div
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
</a>
|
100
|
+
<div >
|
101
|
+
<div class="flex text-xs font-medium text-gray-400 space-x-2">
|
102
|
+
<div class="relative inline-block text-left">
|
103
|
+
<a href="<%= goals_path(search_params) %>" data-turbo-frame="goals" class="inline-block h-5 font-semibold" data-controller="frame-link" data-action="click->tile#setTitle">Goals</a>
|
104
|
+
<a href="<%= properties_path(search_params) %>" data-turbo-frame="goals" class="inline-block h-5 font-semibold" data-controller="frame-link" data-action="click->tile#setTitle">Properties</a>
|
105
|
+
<%= render AhoyCaptain::DropdownLinkComponent.new(title: "Funnels") do |dropdown| %>
|
106
|
+
<% AhoyCaptain.config.funnels.each do |id, funnel| %>
|
107
|
+
<% dropdown.with_option do %>
|
108
|
+
<a href="<%= funnel_path(id, search_params) %>" data-turbo-frame="goals" class="link " data-action="click->tile#setTitle" title="<%= funnel.title %> Funnel">
|
109
|
+
<%= funnel.title %>
|
110
|
+
</a>
|
111
|
+
<% end %>
|
112
|
+
<% end %>
|
122
113
|
<% end %>
|
123
|
-
|
124
|
-
|
114
|
+
</div>
|
115
|
+
</div>
|
116
|
+
|
125
117
|
</div>
|
126
118
|
</div>
|
127
119
|
<% end %>
|
@@ -1,10 +1,15 @@
|
|
1
1
|
<%= turbo_frame_tag :stats, data: { controller: "active-frame-link" } do %>
|
2
2
|
<dl class="grid grid-cols-1 divide-y divide-base-200 overflow-hidden rounded-lg grid-cols-2 md:grid-cols-6 md:divide-y-0" data-controller="active-links" data-active-links-classes-value='["text-primary"]'>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
<% if @presenter.send(:range).realtime? %>
|
4
|
+
<%= render stats_container(@presenter.unique_visitors, stats_unique_visitors_url(search_params), "Unique Visits (30 min)", :number_with_delimiter, true) %>
|
5
|
+
<%= render stats_container(@presenter.total_pageviews, stats_total_pageviews_path(search_params), "Total Pageviews (30 min)", :number_with_delimiter) %>
|
6
|
+
<% else %>
|
7
|
+
<%= render stats_container(@presenter.unique_visitors, stats_unique_visitors_url(search_params), "Unique Visits", :number_with_delimiter, true) %>
|
8
|
+
<%= render stats_container(@presenter.total_visits, stats_total_visits_path(search_params), "Total Visits", :number_with_delimiter) %>
|
9
|
+
<%= render stats_container(@presenter.total_pageviews, stats_total_pageviews_path(search_params), "Total Pageviews", :number_with_delimiter) %>
|
10
|
+
<%= render stats_container(@presenter.views_per_visit, stats_views_per_visits_path(search_params), "Views per Visit", :number_with_delimiter) %>
|
11
|
+
<%= render stats_container(@presenter.bounce_rate, stats_bounce_rates_path(search_params), "Bounce Rate", :number_with_delimiter) %>
|
12
|
+
<%= render stats_container(@presenter.visit_duration, stats_visit_durations_url(search_params), "Visit Duration", :number_to_duration) %>
|
13
|
+
<% end %>
|
9
14
|
</dl>
|
10
15
|
<% end %>
|
data/config/routes.rb
CHANGED
@@ -12,15 +12,19 @@ AhoyCaptain::Engine.routes.draw do
|
|
12
12
|
get "/devices/#{k}" => 'devices#index', defaults: { devices_type: v }, as: "devices_#{k}"
|
13
13
|
end
|
14
14
|
|
15
|
+
namespace :locations do
|
16
|
+
resource :map, only: [:show]
|
17
|
+
resources :countries, only: [:index]
|
18
|
+
resources :regions, only: [:index]
|
19
|
+
resources :cities, only: [:index]
|
20
|
+
end
|
21
|
+
|
15
22
|
resources :properties, only: [:index, :show]
|
16
23
|
resource :export, only: [:show]
|
17
24
|
resource :realtime, only: [:show]
|
18
25
|
resources :funnels, only: [:show]
|
19
26
|
resources :goals, only: [:index]
|
20
27
|
resource :stats, only: [:show]
|
21
|
-
resources :countries, only: [:index]
|
22
|
-
resources :regions, only: [:index]
|
23
|
-
resources :cities, only: [:index]
|
24
28
|
resources :campaigns, only: [:index]
|
25
29
|
resources :sources, only: [:index]
|
26
30
|
resources :exit_pages, only: [:index]
|
@@ -31,11 +31,11 @@ module AhoyCaptain
|
|
31
31
|
end
|
32
32
|
|
33
33
|
config.register("UTM Tags") do
|
34
|
-
filter column: :utm_medium, label: "UTM Medium", url: :filters_utm_mediums_path, predicates: [:in, :not_in]
|
35
|
-
filter column: :utm_source, label: "UTM Source", url: :filters_utm_sources_path, predicates: [:in, :not_in]
|
36
|
-
filter column: :utm_campaign, label: "UTM Campaign", url: :filters_utm_campaigns_path, predicates: [:in, :not_in]
|
37
|
-
filter column: :utm_term, label: "UTM Term", url: :filters_utm_terms_path, predicates: [:in, :not_in]
|
38
|
-
filter column: :utm_content, label: "UTM Content", url: :filters_utm_contents_path, predicates: [:in, :not_in]
|
34
|
+
filter column: :utm_medium, label: "UTM Medium", url: :filters_utm_mediums_path, predicates: [:in, :not_in, :cont]
|
35
|
+
filter column: :utm_source, label: "UTM Source", url: :filters_utm_sources_path, predicates: [:in, :not_in, :cont]
|
36
|
+
filter column: :utm_campaign, label: "UTM Campaign", url: :filters_utm_campaigns_path, predicates: [:in, :not_in, :cont]
|
37
|
+
filter column: :utm_term, label: "UTM Term", url: :filters_utm_terms_path, predicates: [:in, :not_in, :cont]
|
38
|
+
filter column: :utm_content, label: "UTM Content", url: :filters_utm_contents_path, predicates: [:in, :not_in, :cont]
|
39
39
|
end
|
40
40
|
|
41
41
|
config.register("Goal") do
|
data/lib/ahoy_captain/version.rb
CHANGED
data/lib/ahoy_captain.rb
CHANGED
@@ -32,6 +32,7 @@ module AhoyCaptain
|
|
32
32
|
pin "Chart.bundle", to: "Chart.bundle.js"
|
33
33
|
pin "chartjs-plugin-datalabels", to: "https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2", preload: true
|
34
34
|
pin "classnames", to: "https://cdnjs.cloudflare.com/ajax/libs/classnames/2.3.2/index.min.js", preload: true
|
35
|
+
pin "chartjs-chart-geo", to: "https://unpkg.com/chartjs-chart-geo@4", preload: true
|
35
36
|
pin_all_from AhoyCaptain::Engine.root.join("app/assets/javascript/ahoy_captain/controllers"), under: "controllers", to: "ahoy_captain/controllers"
|
36
37
|
pin_all_from AhoyCaptain::Engine.root.join("app/assets/javascript/ahoy_captain/helpers"), under: "helpers", to: "ahoy_captain/helpers"
|
37
38
|
end
|