From 5851e04e062391b24a1d7fe349c4fe093ef416fd Mon Sep 17 00:00:00 2001 From: Dan Milne Date: Mon, 10 Nov 2025 07:53:20 +1100 Subject: [PATCH] Display local time in the browser --- Procfile.dev | 1 + app/controllers/analytics_controller.rb | 10 ++-- .../controllers/timeline_controller.js | 54 +++++++++++++++++++ app/models/rule.rb | 4 ++ app/views/analytics/index.html.erb | 16 +++--- app/views/events/index.html.erb | 5 +- config/environments/development.rb | 2 + config/environments/production.rb | 4 +- config/environments/test.rb | 4 +- 9 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 app/javascript/controllers/timeline_controller.js diff --git a/Procfile.dev b/Procfile.dev index 0ac4b20..9fa44e8 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,2 +1,3 @@ web: bin/rails server -b 0.0.0.0 -p 3041 +job: bin/jobs css: bin/rails tailwindcss:watch diff --git a/app/controllers/analytics_controller.rb b/app/controllers/analytics_controller.rb index e9b8135..4031a38 100644 --- a/app/controllers/analytics_controller.rb +++ b/app/controllers/analytics_controller.rb @@ -99,15 +99,17 @@ class AnalyticsController < ApplicationController .group("DATE_TRUNC('hour', timestamp)") .count - # Convert to chart format + # Convert to chart format - keep everything in UTC for consistency timeline_data = (0..23).map do |hour_ago| hour_time = hour_ago.hours.ago - hour_key = hour_time.strftime("%Y-%m-%d %H:00:00") + hour_key = hour_time.utc.beginning_of_hour + { - time: hour_time.strftime("%H:00"), + # Store as ISO string for JavaScript to handle timezone conversion + time_iso: hour_time.iso8601, total: events_by_hour[hour_key] || 0 } - end.reverse + end # Action distribution for pie chart action_distribution = @event_breakdown.map do |action, count| diff --git a/app/javascript/controllers/timeline_controller.js b/app/javascript/controllers/timeline_controller.js new file mode 100644 index 0000000..3a53404 --- /dev/null +++ b/app/javascript/controllers/timeline_controller.js @@ -0,0 +1,54 @@ +// Timeline controller for handling timezone conversion and animations +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["row", "time", "bar"] + + connect() { + this.maxTotal = this.calculateMaxTotal() + this.updateTimeline() + } + + calculateMaxTotal() { + const totals = this.rowTargets.map(row => parseInt(row.dataset.total)) + return Math.max(...totals, 1) + } + + updateTimeline() { + this.rowTargets.forEach((row, index) => { + this.updateRow(row, index) + }) + } + + updateRow(row, index) { + const timeIso = row.dataset.timeIso + const total = parseInt(row.dataset.total) + const timeElement = this.timeTargets.find(target => target.closest('[data-timeline-target="row"]') === row) + const barElement = this.barTargets.find(target => target.closest('[data-timeline-target="row"]') === row) + + // Convert ISO time to local time + const date = new Date(timeIso) + const localTime = date.toLocaleTimeString(undefined, { + hour: '2-digit', + minute: '2-digit', + hour12: false + }) + + timeElement.textContent = localTime + timeElement.title = date.toLocaleString(undefined, { + weekday: 'short', + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + timeZoneName: 'short' + }) + + // Animate the bar width with a slight delay for each row + const barWidth = Math.max((total / this.maxTotal) * 100, 5) + setTimeout(() => { + barElement.style.width = `${barWidth}%` + }, 100 + (index * 50)) + } +} \ No newline at end of file diff --git a/app/models/rule.rb b/app/models/rule.rb index 42fdb47..231665c 100644 --- a/app/models/rule.rb +++ b/app/models/rule.rb @@ -63,6 +63,10 @@ class Rule < ApplicationRecord end # Network-specific methods + def network_range? + network_range.present? + end + def cidr network_rule? ? network_range&.cidr : conditions&.dig("cidr") end diff --git a/app/views/analytics/index.html.erb b/app/views/analytics/index.html.erb index 2734268..20e1283 100644 --- a/app/views/analytics/index.html.erb +++ b/app/views/analytics/index.html.erb @@ -155,24 +155,26 @@
-

Events Timeline (Last 24 Hours)

+
+

Events Timeline (Last 24 Hours)

+ Times shown in your local timezone +
-
+
<% @chart_data[:timeline].each do |data| %> -
-
<%= data[:time] %>
+
+
--:--
-
-
+
<%= data[:total] %>
<% end %>
+
diff --git a/app/views/events/index.html.erb b/app/views/events/index.html.erb index 07753ed..6e490bc 100644 --- a/app/views/events/index.html.erb +++ b/app/views/events/index.html.erb @@ -24,7 +24,7 @@
<%= form.label :waf_action, "Action", class: "block text-sm font-medium text-gray-700" %> <%= form.select :waf_action, - options_for_select([['All', ''], ['Allow', 'allow'], ['Block', 'block'], ['Challenge', 'challenge']], params[:waf_action]), + options_for_select([['All', ''], ['Allow', 'allow'], ['Deny', 'deny'], ['Redirect', 'redirect'], ['Challenge', 'challenge']], params[:waf_action]), { }, { class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm" } %>
@@ -94,7 +94,8 @@ diff --git a/config/environments/development.rb b/config/environments/development.rb index 75243c3..6bafe50 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -75,4 +75,6 @@ Rails.application.configure do # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. # config.generators.apply_rubocop_autocorrect_after_generate! + config.active_job.queue_adapter = :solid_queue + config.solid_queue.connects_to = { database: { writing: :queue } } end diff --git a/config/environments/production.rb b/config/environments/production.rb index b44d856..ad16af7 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -58,7 +58,9 @@ Rails.application.configure do # config.action_mailer.raise_delivery_errors = false # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "example.com" } + config.action_mailer.default_url_options = { + host: ENV.fetch("BAFFLE_HOST", "example.com") + } # Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit. # config.action_mailer.smtp_settings = { diff --git a/config/environments/test.rb b/config/environments/test.rb index c2095b1..00c7b31 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -37,7 +37,9 @@ Rails.application.configure do config.action_mailer.delivery_method = :test # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "example.com" } + config.action_mailer.default_url_options = { + host: ENV.fetch("BAFFLE_HOST", "example.com") + } # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr