Allinea i KPI su due righe e aggiunge lo storico orario degli invii confermati.
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / scan_ruby (push) Has been cancelled

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-07 12:53:38 +02:00
co-authored by Cursor
parent 390cb0e657
commit 1c6b4bbabe
4 changed files with 61 additions and 1 deletions
@@ -1,6 +1,7 @@
class Mailings::HourlyThroughput
HOUR = 1.hour
RECENT = 15.minutes
HISTORY_HOURS = 12
def initialize(project, now: Time.current)
@project = project
@@ -23,6 +24,31 @@ class Mailings::HourlyThroughput
sent + failed
end
def hourly_history
@hourly_history ||= begin
from = (@now - (HISTORY_HOURS - 1).hours).beginning_of_hour
keyed = recipients.sent
.where(sent_at: from..@now)
.pluck(:sent_at)
.each_with_object(Hash.new(0)) do |sent_at, counts|
counts[sent_at.in_time_zone.beginning_of_hour] += 1
end
HISTORY_HOURS.times.map do |index|
at = from + index.hours
{ at: at, count: keyed[at] || 0 }
end
end
end
def history_total
hourly_history.sum { |bucket| bucket[:count] }
end
def history_max
[hourly_history.map { |bucket| bucket[:count] }.max, 1].max
end
private
def sent_since(window)
+13 -1
View File
@@ -26,7 +26,7 @@
</div>
<% end %>
<div class="grid grid-cols-2 gap-3 md:grid-cols-3 xl:grid-cols-5">
<div class="grid grid-cols-2 gap-3 md:grid-cols-3">
<div class="<%= card_class %> p-4">
<div class="text-xs uppercase tracking-wide text-zinc-500">In corso</div>
<div class="mt-1 text-2xl font-semibold tabular-nums"><%= @active_mailings.size %></div>
@@ -41,6 +41,18 @@
<% end %>
</div>
</div>
<div class="<%= card_class %> p-4">
<div class="text-xs uppercase tracking-wide text-zinc-500">Storico invio</div>
<div class="mt-2 flex items-end gap-0.5" style="height: 2.5rem" role="img" aria-label="Invii confermati nelle ultime 12 ore">
<% @hourly_throughput.hourly_history.each do |bucket| %>
<% pct = (bucket[:count].to_f / @hourly_throughput.history_max * 100).round %>
<div class="flex-1 rounded <%= bucket[:count].positive? ? "bg-emerald-500" : "bg-zinc-200 dark:bg-zinc-700" %>"
style="height: <%= bucket[:count].positive? ? [pct, 12].max : 8 %>%"
title="<%= bucket[:at].strftime("%H:%M") %>: <%= bucket[:count] %>"></div>
<% end %>
</div>
<div class="mt-1 text-xs text-zinc-500"><%= @hourly_throughput.history_total %> inviate · ultime 12 ore</div>
</div>
<div class="<%= card_class %> p-4">
<div class="text-xs uppercase tracking-wide text-zinc-500">In pausa (fascia)</div>
<div class="mt-1 text-2xl font-semibold tabular-nums"><%= @paused_mailings.size %></div>