Permette di filtrare il grafico analytics su una singola pagina.

Aggiunge il filtro Pagina (grafico) e il link Grafico in tabella, mantenendo Da/A/Device.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-08 22:14:35 +02:00
co-authored by Cursor
parent 81e7e3c9af
commit adfea01cdb
10 changed files with 112 additions and 27 deletions
@@ -6,7 +6,8 @@ module Admin
@filters = {
from: parse_date(params[:from]) || 7.days.ago.to_date,
to: parse_date(params[:to]) || Time.zone.today,
device: params[:device].presence
device: params[:device].presence,
chart_path: params[:chart_path].presence
}
@analytics_preview_active = analytics_preview_active?
@@ -37,21 +38,22 @@ module Admin
}
end.sort_by { |r| [-r[:pageviews], -r[:moves], -r[:clicks], r[:page_path]] }
pageviews_by_day = scope.group(:day).sum(:pageview_count)
clicks_by_day = cell_scope.group(:day).sum(:click_count)
moves_by_day = cell_scope.group(:day).sum(:move_count)
@chart_path_options = @pages.map { |row| row[:page_path] }
if @filters[:chart_path].present? && @chart_path_options.exclude?(@filters[:chart_path])
@filters[:chart_path] = nil
end
trend_scope = scope
trend_scope = trend_scope.where(page_path: @filters[:chart_path]) if @filters[:chart_path].present?
pageviews_by_day = trend_scope.group(:day).sum(:pageview_count)
@trend = (@filters[:from]..@filters[:to]).map do |day|
{
day: day.iso8601,
pageviews: pageviews_by_day[day].to_i,
clicks: clicks_by_day[day].to_i,
moves: moves_by_day[day].to_i
pageviews: pageviews_by_day[day].to_i
}
end
@trend_totals = {
pageviews: @trend.sum { |r| r[:pageviews] },
clicks: @trend.sum { |r| r[:clicks] },
moves: @trend.sum { |r| r[:moves] }
pageviews: @trend.sum { |r| r[:pageviews] }
}
end
@@ -50,6 +50,14 @@
@filters[:device]
) %>
</label>
<label class="admin-filter-field">
<span><%= t("admin.analytics.filters.chart_path") %></span>
<%= select_tag :chart_path,
options_for_select(
[[t("admin.analytics.filters.chart_path_all"), ""]] + @chart_path_options.map { |p| [p, p] },
@filters[:chart_path]
) %>
</label>
</div>
<div class="admin-filter-actions">
<%= submit_tag t("admin.analytics.filters.apply"), class: "admin-btn admin-btn--primary admin-btn--sm" %>
@@ -63,7 +71,13 @@
<div class="admin-analytics-trend__head">
<div>
<h3><%= t("admin.analytics.index.trend_title") %></h3>
<p class="muted admin-table-sub"><%= t("admin.analytics.index.trend_lead") %></p>
<p class="muted admin-table-sub">
<% if @filters[:chart_path].present? %>
<%= t("admin.analytics.index.trend_lead_path", path: @filters[:chart_path]) %>
<% else %>
<%= t("admin.analytics.index.trend_lead") %>
<% end %>
</p>
</div>
<button type="button"
id="admin-analytics-trend-toggle"
@@ -74,9 +88,21 @@
<div id="admin-analytics-trend-body">
<div class="kpi-grid admin-analytics-trend__kpi">
<div class="kpi">
<div class="kpi-label"><%= t("admin.analytics.index.trend_total_label") %></div>
<div class="kpi-label">
<% if @filters[:chart_path].present? %>
<%= t("admin.analytics.index.trend_total_label_path") %>
<% else %>
<%= t("admin.analytics.index.trend_total_label") %>
<% end %>
</div>
<div class="kpi-value"><%= @trend_totals[:pageviews] %></div>
<div class="kpi-sub muted"><%= t("admin.analytics.index.trend_total_hint", from: l(@filters[:from]), to: l(@filters[:to])) %></div>
<div class="kpi-sub muted">
<% if @filters[:chart_path].present? %>
<code class="admin-mono"><%= @filters[:chart_path] %></code>
·
<% end %>
<%= t("admin.analytics.index.trend_total_hint", from: l(@filters[:from]), to: l(@filters[:to])) %>
</div>
</div>
</div>
<div class="chart-wrap chart-wrap--analytics">
@@ -93,7 +119,7 @@
};
</script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js" crossorigin="anonymous"></script>
<script src="/admin-analytics.js?v=2" defer></script>
<script src="/admin-analytics.js?v=3" defer></script>
<% end %>
<div class="panel">
@@ -116,14 +142,18 @@
<tbody>
<% @pages.each do |row| %>
<% avg = row[:scroll_samples].positive? ? (row[:scroll_sum].to_f / row[:scroll_samples]).round : 0 %>
<tr>
<% chart_params = { from: @filters[:from], to: @filters[:to], chart_path: row[:page_path] } %>
<% chart_params[:device] = @filters[:device] if @filters[:device].present? %>
<tr class="<%= "is-chart-focus" if @filters[:chart_path] == row[:page_path] %>">
<td><code class="admin-mono"><%= row[:page_path] %></code></td>
<td><%= row[:pageviews] %></td>
<td><%= row[:moves] %></td>
<td><%= row[:clicks] %></td>
<td class="muted"><%= avg %>%</td>
<td class="muted"><%= row[:max_scroll] %>%</td>
<td>
<td class="admin-analytics-row-actions">
<%= link_to t("admin.analytics.index.chart_for_path"), admin_analytics_path(chart_params) %>
·
<% heatmap_params = { page_path: row[:page_path], from: @filters[:from], to: @filters[:to] } %>
<% heatmap_params[:device] = @filters[:device] if @filters[:device].present? %>
<%= link_to t("admin.analytics.index.heatmap"), admin_analytics_page_path(heatmap_params) %>
+1 -1
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<%= csrf_meta_tags %>
<link rel="stylesheet" href="/admin.css?v=18">
<link rel="stylesheet" href="/admin.css?v=19">
<%= yield :head %>
<% if content_for?(:replay_archive_styles) %>
<link rel="stylesheet" href="/marketing.css?v=42">