rails_event_viewer 0.3.0 → 0.4.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/README.md +8 -0
  4. data/app/assets/javascripts/rails_event_viewer/application.js +2 -1
  5. data/app/assets/stylesheets/rails_event_viewer/application.css +1 -1
  6. data/app/controllers/rails_event_viewer/application_controller.rb +7 -16
  7. data/app/controllers/rails_event_viewer/events_controller.rb +16 -29
  8. data/app/controllers/rails_event_viewer/groups_controller.rb +0 -9
  9. data/app/helpers/rails_event_viewer/application_helper.rb +23 -77
  10. data/app/models/rails_event_viewer/entry.rb +0 -26
  11. data/app/models/rails_event_viewer/page.rb +9 -0
  12. data/app/views/layouts/rails_event_viewer/application.html.erb +11 -4
  13. data/app/views/rails_event_viewer/analytics/overview.html.erb +13 -9
  14. data/app/views/rails_event_viewer/dashboard/index.html.erb +16 -15
  15. data/app/views/rails_event_viewer/event_types/index.html.erb +7 -7
  16. data/app/views/rails_event_viewer/event_types/show.html.erb +18 -16
  17. data/app/views/rails_event_viewer/events/_event_row.html.erb +9 -9
  18. data/app/views/rails_event_viewer/events/_filters_sidebar.html.erb +18 -15
  19. data/app/views/rails_event_viewer/events/index.html.erb +10 -10
  20. data/app/views/rails_event_viewer/events/show.html.erb +28 -28
  21. data/app/views/rails_event_viewer/groups/index.html.erb +8 -8
  22. data/app/views/rails_event_viewer/groups/show.html.erb +12 -16
  23. data/app/views/rails_event_viewer/shared/_navigation.html.erb +13 -17
  24. data/app/views/rails_event_viewer/shared/_pagination.html.erb +10 -10
  25. data/app/views/rails_event_viewer/shared/_stat_card.html.erb +5 -5
  26. data/config/routes.rb +1 -5
  27. data/db/migrate/20261002121337_create_rails_event_viewer_entries.rb +0 -1
  28. data/lib/generators/rails_event_viewer/install/templates/create_rails_event_viewer_entries.rb.erb +0 -1
  29. data/lib/rails_event_viewer/adapter.rb +0 -8
  30. data/lib/rails_event_viewer/adapters/active_record.rb +12 -44
  31. data/lib/rails_event_viewer/adapters/concerns/in_memory_filtering.rb +7 -7
  32. data/lib/rails_event_viewer/adapters/memory.rb +0 -4
  33. data/lib/rails_event_viewer/adapters/null.rb +0 -8
  34. data/lib/rails_event_viewer/adapters/redis.rb +6 -20
  35. data/lib/rails_event_viewer/events_relation.rb +1 -1
  36. data/lib/rails_event_viewer/flusher.rb +5 -5
  37. data/lib/rails_event_viewer/logging.rb +1 -11
  38. data/lib/rails_event_viewer/version.rb +1 -1
  39. data/lib/rails_event_viewer.rb +5 -5
  40. data/lib/tasks/rails_event_viewer_tasks.rake +1 -1
  41. metadata +7 -2
  42. data/app/assets/stylesheets/rails_event_viewer/tailwind.css +0 -29
@@ -8,10 +8,12 @@
8
8
  <%= form_with url: rails_event_viewer.analytics_overview_path, method: :get, class: "flex items-center space-x-3" do |f| %>
9
9
  <%= f.date_field :start_date,
10
10
  value: @date_range.begin.to_date,
11
+ aria: { label: "Start date" },
11
12
  class: "rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
12
13
  <span class="text-gray-500">to</span>
13
14
  <%= f.date_field :end_date,
14
15
  value: @date_range.end.to_date,
16
+ aria: { label: "End date" },
15
17
  class: "rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
16
18
  <%= f.submit "Apply",
17
19
  class: "bg-indigo-600 text-white px-5 py-2.5 rounded-md font-medium hover:bg-indigo-700 cursor-pointer" %>
@@ -41,19 +43,20 @@
41
43
  <!-- Charts -->
42
44
  <div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
43
45
  <div class="bg-white rounded-lg shadow p-6 overflow-hidden">
44
- <h3 class="text-lg font-medium text-gray-900 mb-4">Events Over Time</h3>
46
+ <h2 class="text-lg font-medium text-gray-900 mb-4">Events Over Time</h2>
45
47
  <div class="h-72 overflow-hidden">
46
48
  <% if @events_over_time.any? %>
47
49
  <%= line_chart @events_over_time,
48
50
  id: "analytics-timeline",
49
51
  html: '<div id="%{id}" class="h-full w-full">%{loading}</div>',
52
+ content_for: nil,
50
53
  colors: ["#4F46E5"],
51
54
  library: {
52
55
  plugins: { legend: { display: false } },
53
56
  scales: { y: { beginAtZero: true } }
54
57
  } %>
55
58
  <% else %>
56
- <div class="flex items-center justify-center h-full text-gray-400">
59
+ <div class="flex items-center justify-center h-full text-gray-500">
57
60
  No data for the selected period
58
61
  </div>
59
62
  <% end %>
@@ -61,19 +64,20 @@
61
64
  </div>
62
65
 
63
66
  <div class="bg-white rounded-lg shadow p-6 overflow-hidden">
64
- <h3 class="text-lg font-medium text-gray-900 mb-4">Events by Type</h3>
67
+ <h2 class="text-lg font-medium text-gray-900 mb-4">Events by Type</h2>
65
68
  <div class="h-72 overflow-hidden">
66
69
  <% if @events_by_type.any? %>
67
70
  <%= bar_chart @events_by_type,
68
71
  id: "analytics-by-type",
69
72
  html: '<div id="%{id}" class="h-full w-full">%{loading}</div>',
73
+ content_for: nil,
70
74
  colors: ["#4F46E5"],
71
75
  library: {
72
76
  indexAxis: 'y',
73
77
  plugins: { legend: { display: false } }
74
78
  } %>
75
79
  <% else %>
76
- <div class="flex items-center justify-center h-full text-gray-400">
80
+ <div class="flex items-center justify-center h-full text-gray-500">
77
81
  No data for the selected period
78
82
  </div>
79
83
  <% end %>
@@ -84,7 +88,7 @@
84
88
  <!-- Event type breakdown table -->
85
89
  <div class="bg-white rounded-lg shadow">
86
90
  <div class="px-6 py-4 border-b border-gray-200">
87
- <h3 class="text-lg font-medium text-gray-900">Event Type Breakdown</h3>
91
+ <h2 class="text-lg font-medium text-gray-900">Event Type Breakdown</h2>
88
92
  </div>
89
93
 
90
94
  <% if @events_by_type.any? %>
@@ -92,10 +96,10 @@
92
96
  <table class="min-w-full divide-y divide-gray-200">
93
97
  <thead class="bg-gray-50">
94
98
  <tr>
95
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event Type</th>
96
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Count</th>
97
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Percentage</th>
98
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Distribution</th>
99
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event Type</th>
100
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Count</th>
101
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Percentage</th>
102
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Distribution</th>
99
103
  </tr>
100
104
  </thead>
101
105
  <tbody class="divide-y divide-gray-200">
@@ -28,16 +28,17 @@
28
28
  <div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
29
29
  <!-- Events over time chart -->
30
30
  <div class="bg-white rounded-lg shadow p-6 overflow-hidden">
31
- <h3 class="text-lg font-medium text-gray-900 mb-4">Events (Last 24 Hours)</h3>
31
+ <h2 class="text-lg font-medium text-gray-900 mb-4">Events (Last 24 Hours)</h2>
32
32
  <div class="h-72 overflow-hidden">
33
33
  <% if @events_over_time.any? %>
34
34
  <%= line_chart @events_over_time,
35
35
  id: "events-timeline",
36
36
  html: '<div id="%{id}" class="h-full w-full">%{loading}</div>',
37
+ content_for: nil,
37
38
  colors: ["#4F46E5"],
38
39
  library: { plugins: { legend: { display: false } } } %>
39
40
  <% else %>
40
- <div class="flex items-center justify-center h-full text-gray-400">
41
+ <div class="flex items-center justify-center h-full text-gray-500">
41
42
  No events in the last 24 hours
42
43
  </div>
43
44
  <% end %>
@@ -46,16 +47,17 @@
46
47
 
47
48
  <!-- Events by type chart -->
48
49
  <div class="bg-white rounded-lg shadow p-6 overflow-hidden">
49
- <h3 class="text-lg font-medium text-gray-900 mb-4">Events by Type</h3>
50
+ <h2 class="text-lg font-medium text-gray-900 mb-4">Events by Type</h2>
50
51
  <div class="h-72 overflow-hidden">
51
52
  <% if @events_by_type.any? %>
52
53
  <%= pie_chart @events_by_type,
53
54
  id: "events-by-type",
54
55
  html: '<div id="%{id}" class="h-full w-full">%{loading}</div>',
56
+ content_for: nil,
55
57
  donut: true,
56
58
  colors: ["#4F46E5", "#10B981", "#F59E0B", "#EF4444", "#8B5CF6", "#EC4899", "#06B6D4", "#84CC16"] %>
57
59
  <% else %>
58
- <div class="flex items-center justify-center h-full text-gray-400">
60
+ <div class="flex items-center justify-center h-full text-gray-500">
59
61
  No events to display
60
62
  </div>
61
63
  <% end %>
@@ -67,7 +69,7 @@
67
69
  <!-- Recent events -->
68
70
  <div class="bg-white rounded-lg shadow">
69
71
  <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
70
- <h3 class="text-lg font-medium text-gray-900">Recent Events</h3>
72
+ <h2 class="text-lg font-medium text-gray-900">Recent Events</h2>
71
73
  <%= link_to "View all", rails_event_viewer.events_path, class: "text-indigo-600 hover:text-indigo-500 text-sm font-medium" %>
72
74
  </div>
73
75
 
@@ -76,24 +78,23 @@
76
78
  <table class="min-w-full divide-y divide-gray-200">
77
79
  <thead class="bg-gray-50">
78
80
  <tr>
79
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
80
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Payload</th>
81
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
81
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
82
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Payload</th>
83
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
82
84
  </tr>
83
85
  </thead>
84
86
  <tbody class="bg-white divide-y divide-gray-200">
85
87
  <% @recent_events.each do |event| %>
86
- <tr class="hover:bg-gray-50 cursor-pointer" data-event-viewer-href="<%= rails_event_viewer.event_path(event_id(event)) %>">
88
+ <tr class="hover:bg-gray-50 cursor-pointer" data-event-viewer-href="<%= rails_event_viewer.event_path(event[:id]) %>">
87
89
  <td class="px-6 py-4 whitespace-nowrap">
88
- <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800">
89
- <%= event_name(event) %>
90
- </span>
90
+ <%= link_to event[:name], rails_event_viewer.event_path(event[:id]),
91
+ class: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800" %>
91
92
  </td>
92
93
  <td class="px-6 py-4 text-sm text-gray-500">
93
94
  <code class="text-xs bg-gray-100 px-2 py-1 rounded"><%= truncate_json(event_payload(event), length: 60) %></code>
94
95
  </td>
95
96
  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
96
- <%= time_ago_with_title(event_occurred_at(event)) %>
97
+ <%= time_ago_with_title(event[:occurred_at]) %>
97
98
  </td>
98
99
  </tr>
99
100
  <% end %>
@@ -102,10 +103,10 @@
102
103
  </div>
103
104
  <% else %>
104
105
  <div class="px-6 py-12 text-center text-gray-500">
105
- <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
106
+ <svg aria-hidden="true" class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
106
107
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
107
108
  </svg>
108
- <h3 class="mt-2 text-sm font-medium text-gray-900">No events yet</h3>
109
+ <h2 class="mt-2 text-sm font-medium text-gray-900">No events yet</h2>
109
110
  <p class="mt-1 text-sm text-gray-500">Events will appear here once they are captured.</p>
110
111
  </div>
111
112
  <% end %>
@@ -9,14 +9,14 @@
9
9
  </div>
10
10
 
11
11
  <% if @event_types.any? %>
12
- <div class="bg-white shadow rounded-lg overflow-hidden">
12
+ <div class="bg-white shadow rounded-lg overflow-x-auto">
13
13
  <table class="min-w-full divide-y divide-gray-200">
14
14
  <thead class="bg-gray-50">
15
15
  <tr>
16
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event Type</th>
17
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Count</th>
18
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Last Event</th>
19
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
16
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event Type</th>
17
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Count</th>
18
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Last Event</th>
19
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"><span class="sr-only">Actions</span></th>
20
20
  </tr>
21
21
  </thead>
22
22
  <tbody class="bg-white divide-y divide-gray-200">
@@ -49,10 +49,10 @@
49
49
  </div>
50
50
  <% else %>
51
51
  <div class="bg-white rounded-lg shadow px-6 py-12 text-center text-gray-500">
52
- <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
52
+ <svg aria-hidden="true" class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
53
53
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A2 2 0 013 12V7a4 4 0 014-4z" />
54
54
  </svg>
55
- <h3 class="mt-2 text-sm font-medium text-gray-900">No event types</h3>
55
+ <h2 class="mt-2 text-sm font-medium text-gray-900">No event types</h2>
56
56
  <p class="mt-1 text-sm text-gray-500">Event types will appear here once events are captured.</p>
57
57
  </div>
58
58
  <% end %>
@@ -4,14 +4,14 @@
4
4
  <!-- Header -->
5
5
  <div class="flex items-center justify-between">
6
6
  <div class="flex items-center space-x-4">
7
- <%= link_to rails_event_viewer.event_types_path, class: "text-gray-400 hover:text-gray-600" do %>
8
- <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
7
+ <%= link_to rails_event_viewer.event_types_path, class: "text-gray-500 hover:text-gray-700", aria: { label: "Back to event types" } do %>
8
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
9
9
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
10
10
  </svg>
11
11
  <% end %>
12
- <div>
12
+ <div class="min-w-0">
13
13
  <h1 class="text-2xl font-bold text-gray-900">
14
- <span class="inline-flex items-center px-3 py-1 rounded-full text-xl font-medium bg-indigo-100 text-indigo-800">
14
+ <span class="inline-block max-w-full break-words px-3 py-1 rounded-full text-xl font-medium bg-indigo-100 text-indigo-800">
15
15
  <%= @event_type_name %>
16
16
  </span>
17
17
  </h1>
@@ -38,7 +38,7 @@
38
38
  <!-- Events list -->
39
39
  <div class="bg-white shadow rounded-lg overflow-hidden">
40
40
  <div class="px-6 py-4 border-b border-gray-200">
41
- <h3 class="text-lg font-medium text-gray-900">Events</h3>
41
+ <h2 class="text-lg font-medium text-gray-900">Events</h2>
42
42
  </div>
43
43
 
44
44
  <% if @events.any? %>
@@ -46,17 +46,19 @@
46
46
  <table class="min-w-full divide-y divide-gray-200">
47
47
  <thead class="bg-gray-50">
48
48
  <tr>
49
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Payload</th>
50
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tags</th>
51
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
52
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Source</th>
49
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Payload</th>
50
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tags</th>
51
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
52
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Source</th>
53
53
  </tr>
54
54
  </thead>
55
55
  <tbody class="bg-white divide-y divide-gray-200">
56
56
  <% @events.each do |event| %>
57
- <tr class="hover:bg-gray-50 cursor-pointer" data-event-viewer-href="<%= rails_event_viewer.event_path(event_id(event)) %>">
57
+ <tr class="hover:bg-gray-50 cursor-pointer" data-event-viewer-href="<%= rails_event_viewer.event_path(event[:id]) %>">
58
58
  <td class="px-6 py-4">
59
- <code class="text-xs bg-gray-100 px-2 py-1 rounded"><%= truncate_json(event_payload(event), length: 80) %></code>
59
+ <%= link_to rails_event_viewer.event_path(event[:id]) do %>
60
+ <code class="text-xs bg-gray-100 px-2 py-1 rounded"><%= truncate_json(event_payload(event), length: 80) %></code>
61
+ <% end %>
60
62
  </td>
61
63
  <td class="px-6 py-4 whitespace-nowrap">
62
64
  <% tags = event_tags(event) %>
@@ -72,18 +74,18 @@
72
74
  <% end %>
73
75
  </div>
74
76
  <% else %>
75
- <span class="text-gray-400 text-sm">-</span>
77
+ <span class="text-gray-500 text-sm">-</span>
76
78
  <% end %>
77
79
  </td>
78
80
  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
79
- <%= time_ago_with_title(event_occurred_at(event)) %>
81
+ <%= time_ago_with_title(event[:occurred_at]) %>
80
82
  </td>
81
83
  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
82
- <% filepath = event_source_file(event) %>
84
+ <% filepath = event[:source_file] %>
83
85
  <% if filepath.present? %>
84
- <code class="text-xs"><%= event_short_filepath(event) %>:<%= event_source_line(event) %></code>
86
+ <code class="text-xs"><%= event_short_filepath(event) %>:<%= event[:source_line] %></code>
85
87
  <% else %>
86
- <span class="text-gray-400">-</span>
88
+ <span class="text-gray-500">-</span>
87
89
  <% end %>
88
90
  </td>
89
91
  </tr>
@@ -1,9 +1,9 @@
1
- <tr class="hover:bg-gray-50 cursor-pointer" data-event-viewer-href="<%= rails_event_viewer.event_path(event_id(event)) %>">
1
+ <tr class="hover:bg-gray-50 cursor-pointer" data-event-viewer-href="<%= rails_event_viewer.event_path(event[:id]) %>">
2
2
  <td class="px-6 py-4">
3
3
  <div class="flex flex-col max-w-md">
4
- <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800 w-fit">
5
- <%= event_name(event) %>
6
- </span>
4
+ <%= link_to event[:name], rails_event_viewer.event_path(event[:id]),
5
+ title: event[:name],
6
+ class: "inline-block max-w-full truncate px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800 w-fit" %>
7
7
  <div class="text-sm text-gray-500 mt-1 truncate">
8
8
  <code class="text-xs"><%= truncate_json(event_payload(event), length: 50) %></code>
9
9
  </div>
@@ -23,20 +23,20 @@
23
23
  <% end %>
24
24
  </div>
25
25
  <% else %>
26
- <span class="text-gray-400 text-sm">-</span>
26
+ <span class="text-gray-500 text-sm">-</span>
27
27
  <% end %>
28
28
  </td>
29
29
  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
30
- <%= time_ago_with_title(event_occurred_at(event)) %>
30
+ <%= time_ago_with_title(event[:occurred_at]) %>
31
31
  </td>
32
32
  <td class="px-6 py-4 text-sm text-gray-500">
33
- <% filepath = event_source_file(event) %>
33
+ <% filepath = event[:source_file] %>
34
34
  <% if filepath.present? %>
35
35
  <code class="text-xs bg-gray-100 px-2 py-1 rounded block truncate max-w-xs" title="<%= filepath %>">
36
- <%= truncate(event_short_filepath(event), length: 30) %>:<%= event_source_line(event) %>
36
+ <%= truncate(event_short_filepath(event), length: 30) %>:<%= event[:source_line] %>
37
37
  </code>
38
38
  <% else %>
39
- <span class="text-gray-400">-</span>
39
+ <span class="text-gray-500">-</span>
40
40
  <% end %>
41
41
  </td>
42
42
  </tr>
@@ -1,9 +1,9 @@
1
1
  <div class="bg-white rounded-lg shadow p-5 space-y-5">
2
- <h3 class="font-medium text-gray-900">Filters</h3>
2
+ <h2 class="font-medium text-gray-900">Filters</h2>
3
3
 
4
- <%= form_with url: rails_event_viewer.events_path, method: :get, data: { turbo_frame: "events_list" }, class: "space-y-5" do |f| %>
4
+ <%= form_with url: rails_event_viewer.events_path, method: :get, class: "space-y-5" do |f| %>
5
+ <%= f.hidden_field :q, value: @query if @query %>
5
6
 
6
- <!-- Event name filter -->
7
7
  <div>
8
8
  <label for="name" class="block text-sm font-medium text-gray-700 mb-2">Event Name</label>
9
9
  <%= f.select :name,
@@ -12,48 +12,51 @@
12
12
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
13
13
  </div>
14
14
 
15
- <!-- Date range -->
16
- <div>
17
- <label class="block text-sm font-medium text-gray-700 mb-2">Date Range</label>
15
+ <fieldset>
16
+ <legend class="block text-sm font-medium text-gray-700 mb-2">Date Range</legend>
18
17
  <div class="space-y-2">
19
18
  <%= f.date_field :start_date,
20
19
  value: @start_date,
21
20
  placeholder: "From",
21
+ aria: { label: "From date" },
22
22
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
23
23
  <%= f.date_field :end_date,
24
24
  value: @end_date,
25
25
  placeholder: "To",
26
+ aria: { label: "To date" },
26
27
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
27
28
  </div>
28
- </div>
29
+ </fieldset>
29
30
 
30
- <!-- Tag filter -->
31
- <div>
32
- <label class="block text-sm font-medium text-gray-700 mb-1">Tag</label>
31
+ <fieldset>
32
+ <legend class="block text-sm font-medium text-gray-700 mb-1">Tag</legend>
33
33
  <p class="text-xs text-gray-500 mb-2">Filter by event tags (e.g., env, user_id)</p>
34
34
  <%= f.text_field :tag_key,
35
35
  value: params[:tag_key],
36
36
  placeholder: "e.g., environment",
37
+ aria: { label: "Tag key" },
37
38
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3 mb-2" %>
38
39
  <%= f.text_field :tag_value,
39
40
  value: params[:tag_value],
40
41
  placeholder: "e.g., production",
42
+ aria: { label: "Tag value" },
41
43
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
42
- </div>
44
+ </fieldset>
43
45
 
44
- <!-- Context filter -->
45
- <div>
46
- <label class="block text-sm font-medium text-gray-700 mb-1">Context</label>
46
+ <fieldset>
47
+ <legend class="block text-sm font-medium text-gray-700 mb-1">Context</legend>
47
48
  <p class="text-xs text-gray-500 mb-2">Filter by request context (e.g., request_id)</p>
48
49
  <%= f.text_field :context_key,
49
50
  value: params[:context_key],
50
51
  placeholder: "e.g., request_id",
52
+ aria: { label: "Context key" },
51
53
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3 mb-2" %>
52
54
  <%= f.text_field :context_value,
53
55
  value: params[:context_value],
54
56
  placeholder: "e.g., abc-123",
57
+ aria: { label: "Context value" },
55
58
  class: "block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 py-2 px-3" %>
56
- </div>
59
+ </fieldset>
57
60
 
58
61
  <div class="flex space-x-3 pt-3">
59
62
  <%= f.submit "Apply",
@@ -11,13 +11,13 @@
11
11
  <% end %>
12
12
  </h1>
13
13
  <div class="text-sm text-gray-500">
14
- <%= @pagination.count %> total events
14
+ <%= @pagination.count %> events
15
15
  </div>
16
16
  </div>
17
17
 
18
- <div class="flex gap-6">
18
+ <div class="flex flex-col lg:flex-row gap-6">
19
19
  <!-- Filters sidebar -->
20
- <aside class="w-72 flex-shrink-0">
20
+ <aside class="w-full lg:w-72 flex-shrink-0">
21
21
  <%= render "rails_event_viewer/events/filters_sidebar", event_names: @event_names %>
22
22
  </aside>
23
23
 
@@ -29,10 +29,10 @@
29
29
  <table class="w-full divide-y divide-gray-200 table-fixed">
30
30
  <thead class="bg-gray-50">
31
31
  <tr>
32
- <th class="w-2/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
33
- <th class="w-1/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tags</th>
34
- <th class="w-1/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
35
- <th class="w-1/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Source</th>
32
+ <th scope="col" class="w-2/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
33
+ <th scope="col" class="w-1/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tags</th>
34
+ <th scope="col" class="w-1/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
35
+ <th scope="col" class="w-1/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Source</th>
36
36
  </tr>
37
37
  </thead>
38
38
  <tbody class="bg-white divide-y divide-gray-200">
@@ -46,12 +46,12 @@
46
46
  <%= render "rails_event_viewer/shared/pagination", pagination: @pagination %>
47
47
  <% else %>
48
48
  <div class="px-6 py-12 text-center text-gray-500">
49
- <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
49
+ <svg aria-hidden="true" class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
50
50
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
51
51
  </svg>
52
- <h3 class="mt-2 text-sm font-medium text-gray-900">No events found</h3>
52
+ <h2 class="mt-2 text-sm font-medium text-gray-900">No events found</h2>
53
53
  <p class="mt-1 text-sm text-gray-500">
54
- <% if @query.present? || params[:name].present? %>
54
+ <% if @filtered %>
55
55
  Try adjusting your filters or search query.
56
56
  <% else %>
57
57
  Events will appear here once they are captured.
@@ -1,28 +1,28 @@
1
- <% content_for(:title, "#{event_name(@event)} - Rails Event Viewer") %>
1
+ <% content_for(:title, "#{@event[:name]} - Rails Event Viewer") %>
2
2
 
3
3
  <div class="space-y-6">
4
4
  <!-- Header -->
5
5
  <div class="flex items-center space-x-4">
6
- <%= link_to rails_event_viewer.events_path, class: "text-gray-400 hover:text-gray-600", aria: { label: "Back to events" } do %>
7
- <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
6
+ <%= link_to rails_event_viewer.events_path, class: "text-gray-500 hover:text-gray-700", aria: { label: "Back to events" } do %>
7
+ <svg aria-hidden="true" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
8
8
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
9
9
  </svg>
10
10
  <% end %>
11
- <div>
12
- <h1 class="text-2xl font-bold text-gray-900"><%= event_name(@event) %></h1>
13
- <p class="text-sm text-gray-500">Event ID: <%= event_id(@event) %></p>
11
+ <div class="min-w-0">
12
+ <h1 class="text-2xl font-bold text-gray-900 break-words"><%= @event[:name] %></h1>
13
+ <p class="text-sm text-gray-500">Event ID: <%= @event[:id] %></p>
14
14
  </div>
15
15
  </div>
16
16
 
17
17
  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
18
18
  <!-- Main content -->
19
- <div class="lg:col-span-2 space-y-6">
19
+ <div class="lg:col-span-2 space-y-6 min-w-0">
20
20
  <!-- Payload -->
21
21
  <div class="bg-white rounded-lg shadow">
22
22
  <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
23
- <h3 class="text-lg font-medium text-gray-900">Payload</h3>
23
+ <h2 class="text-lg font-medium text-gray-900">Payload</h2>
24
24
  <button type="button"
25
- data-event-viewer-copy="<%= event_payload(@event).to_json %>"
25
+ data-event-viewer-copy="<%= JSON.generate(event_payload(@event)) %>"
26
26
  class="text-indigo-600 hover:text-indigo-500 text-sm font-medium">
27
27
  Copy
28
28
  </button>
@@ -30,11 +30,11 @@
30
30
  <div class="p-6">
31
31
  <% payload = event_payload(@event) %>
32
32
  <% if payload.present? %>
33
- <div class="font-mono text-sm">
33
+ <div class="font-mono text-sm break-words">
34
34
  <%= json_tree(payload) %>
35
35
  </div>
36
36
  <% else %>
37
- <span class="text-gray-400">Empty payload</span>
37
+ <span class="text-gray-500">Empty payload</span>
38
38
  <% end %>
39
39
  </div>
40
40
  </div>
@@ -44,10 +44,10 @@
44
44
  <% if tags.present? %>
45
45
  <div class="bg-white rounded-lg shadow">
46
46
  <div class="px-6 py-4 border-b border-gray-200">
47
- <h3 class="text-lg font-medium text-gray-900">Tags</h3>
47
+ <h2 class="text-lg font-medium text-gray-900">Tags</h2>
48
48
  </div>
49
49
  <div class="p-6">
50
- <div class="font-mono text-sm">
50
+ <div class="font-mono text-sm break-words">
51
51
  <%= json_tree(tags) %>
52
52
  </div>
53
53
  </div>
@@ -59,10 +59,10 @@
59
59
  <% if context.present? %>
60
60
  <div class="bg-white rounded-lg shadow">
61
61
  <div class="px-6 py-4 border-b border-gray-200">
62
- <h3 class="text-lg font-medium text-gray-900">Context</h3>
62
+ <h2 class="text-lg font-medium text-gray-900">Context</h2>
63
63
  </div>
64
64
  <div class="p-6">
65
- <div class="font-mono text-sm">
65
+ <div class="font-mono text-sm break-words">
66
66
  <%= json_tree(context) %>
67
67
  </div>
68
68
  </div>
@@ -75,7 +75,7 @@
75
75
  <!-- Metadata -->
76
76
  <div class="bg-white rounded-lg shadow">
77
77
  <div class="px-6 py-4 border-b border-gray-200">
78
- <h3 class="text-lg font-medium text-gray-900">Metadata</h3>
78
+ <h2 class="text-lg font-medium text-gray-900">Metadata</h2>
79
79
  </div>
80
80
  <dl class="divide-y divide-gray-200">
81
81
  <div class="px-6 py-4">
@@ -92,15 +92,15 @@
92
92
  </dd>
93
93
  </div>
94
94
  <% end %>
95
- <% filepath = event_source_file(@event) %>
95
+ <% filepath = @event[:source_file] %>
96
96
  <% if filepath.present? %>
97
97
  <div class="px-6 py-4">
98
98
  <dt class="text-sm font-medium text-gray-500">Source Location</dt>
99
99
  <dd class="mt-1 text-sm text-gray-900">
100
100
  <code class="bg-gray-100 px-2 py-1 rounded text-xs break-all">
101
- <%= filepath %>:<%= event_source_line(@event) %>
101
+ <%= filepath %>:<%= @event[:source_line] %>
102
102
  </code>
103
- <% label = event_source_label(@event) %>
103
+ <% label = @event[:source_label] %>
104
104
  <% if label.present? %>
105
105
  <div class="mt-1 text-gray-600 text-xs"><%= label %></div>
106
106
  <% end %>
@@ -114,18 +114,18 @@
114
114
  <% if @related_events.any? %>
115
115
  <div class="bg-white rounded-lg shadow">
116
116
  <div class="px-6 py-4 border-b border-gray-200">
117
- <h3 class="text-lg font-medium text-gray-900">Related Events</h3>
117
+ <h2 class="text-lg font-medium text-gray-900">Related Events</h2>
118
118
  <p class="text-xs text-gray-500">Same request context</p>
119
119
  </div>
120
120
  <ul class="divide-y divide-gray-200">
121
121
  <% @related_events.each do |related| %>
122
122
  <li class="px-6 py-3 hover:bg-gray-50">
123
- <%= link_to rails_event_viewer.event_path(event_id(related)), class: "block" do %>
123
+ <%= link_to rails_event_viewer.event_path(related[:id]), class: "block" do %>
124
124
  <div class="text-sm font-medium text-indigo-600 hover:text-indigo-500">
125
- <%= event_name(related) %>
125
+ <%= related[:name] %>
126
126
  </div>
127
127
  <div class="text-xs text-gray-500">
128
- <%= time_ago_with_title(event_occurred_at(related)) %>
128
+ <%= time_ago_with_title(related[:occurred_at]) %>
129
129
  </div>
130
130
  <% end %>
131
131
  </li>
@@ -137,16 +137,16 @@
137
137
  <!-- Quick Links -->
138
138
  <div class="bg-white rounded-lg shadow">
139
139
  <div class="px-6 py-4 border-b border-gray-200">
140
- <h3 class="text-lg font-medium text-gray-900">Quick Links</h3>
140
+ <h2 class="text-lg font-medium text-gray-900">Quick Links</h2>
141
141
  </div>
142
142
  <div class="p-4 space-y-2">
143
- <%= link_to rails_event_viewer.events_path(name: event_name(@event)),
143
+ <%= link_to rails_event_viewer.events_path(name: @event[:name]),
144
144
  class: "block text-sm text-indigo-600 hover:text-indigo-500" do %>
145
- View all "<%= event_name(@event) %>" events
145
+ View all "<%= @event[:name] %>" events
146
146
  <% end %>
147
- <%= link_to rails_event_viewer.event_type_path(name: event_name(@event)),
147
+ <%= link_to rails_event_viewer.event_type_path(name: @event[:name]),
148
148
  class: "block text-sm text-indigo-600 hover:text-indigo-500" do %>
149
- View "<%= event_name(@event) %>" event type
149
+ View "<%= @event[:name] %>" event type
150
150
  <% end %>
151
151
  </div>
152
152
  </div>