rails_error_dashboard 0.1.29 → 0.1.31

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -6
  3. data/app/controllers/rails_error_dashboard/errors_controller.rb +22 -0
  4. data/app/helpers/rails_error_dashboard/application_helper.rb +79 -7
  5. data/app/helpers/rails_error_dashboard/backtrace_helper.rb +149 -0
  6. data/app/models/rails_error_dashboard/application.rb +1 -1
  7. data/app/models/rails_error_dashboard/error_log.rb +44 -16
  8. data/app/views/layouts/rails_error_dashboard.html.erb +66 -1237
  9. data/app/views/rails_error_dashboard/errors/_error_row.html.erb +10 -2
  10. data/app/views/rails_error_dashboard/errors/_source_code.html.erb +76 -0
  11. data/app/views/rails_error_dashboard/errors/_timeline.html.erb +18 -82
  12. data/app/views/rails_error_dashboard/errors/index.html.erb +64 -31
  13. data/app/views/rails_error_dashboard/errors/overview.html.erb +181 -3
  14. data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +2 -1
  15. data/app/views/rails_error_dashboard/errors/settings/_value_badge.html.erb +286 -0
  16. data/app/views/rails_error_dashboard/errors/settings.html.erb +146 -480
  17. data/app/views/rails_error_dashboard/errors/show.html.erb +44 -20
  18. data/db/migrate/20251223000000_create_rails_error_dashboard_complete_schema.rb +188 -0
  19. data/db/migrate/20251224000001_create_rails_error_dashboard_error_logs.rb +5 -0
  20. data/db/migrate/20251224081522_add_better_tracking_to_error_logs.rb +3 -0
  21. data/db/migrate/20251224101217_add_controller_action_to_error_logs.rb +3 -0
  22. data/db/migrate/20251225071314_add_optimized_indexes_to_error_logs.rb +4 -0
  23. data/db/migrate/20251225074653_remove_environment_from_error_logs.rb +3 -0
  24. data/db/migrate/20251225085859_add_enhanced_metrics_to_error_logs.rb +3 -0
  25. data/db/migrate/20251225093603_add_similarity_tracking_to_error_logs.rb +3 -0
  26. data/db/migrate/20251225100236_create_error_occurrences.rb +3 -0
  27. data/db/migrate/20251225101920_create_cascade_patterns.rb +3 -0
  28. data/db/migrate/20251225102500_create_error_baselines.rb +3 -0
  29. data/db/migrate/20251226020000_add_workflow_fields_to_error_logs.rb +3 -0
  30. data/db/migrate/20251226020100_create_error_comments.rb +3 -0
  31. data/db/migrate/20251229111223_add_additional_performance_indexes.rb +4 -0
  32. data/db/migrate/20260106094220_create_rails_error_dashboard_applications.rb +3 -0
  33. data/db/migrate/20260106094233_add_application_to_error_logs.rb +3 -0
  34. data/db/migrate/20260106094318_finalize_application_foreign_key.rb +5 -0
  35. data/lib/generators/rails_error_dashboard/install/install_generator.rb +32 -0
  36. data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +37 -4
  37. data/lib/rails_error_dashboard/configuration.rb +160 -3
  38. data/lib/rails_error_dashboard/configuration_error.rb +24 -0
  39. data/lib/rails_error_dashboard/engine.rb +17 -0
  40. data/lib/rails_error_dashboard/helpers/user_model_detector.rb +138 -0
  41. data/lib/rails_error_dashboard/queries/dashboard_stats.rb +19 -4
  42. data/lib/rails_error_dashboard/queries/errors_list.rb +20 -8
  43. data/lib/rails_error_dashboard/services/error_normalizer.rb +143 -0
  44. data/lib/rails_error_dashboard/services/git_blame_reader.rb +195 -0
  45. data/lib/rails_error_dashboard/services/github_link_generator.rb +159 -0
  46. data/lib/rails_error_dashboard/services/source_code_reader.rb +214 -0
  47. data/lib/rails_error_dashboard/version.rb +1 -1
  48. data/lib/rails_error_dashboard.rb +6 -0
  49. metadata +16 -12
  50. data/app/assets/stylesheets/rails_error_dashboard/_catppuccin_mocha.scss +0 -107
  51. data/app/assets/stylesheets/rails_error_dashboard/_components.scss +0 -625
  52. data/app/assets/stylesheets/rails_error_dashboard/_layout.scss +0 -257
  53. data/app/assets/stylesheets/rails_error_dashboard/_theme_variables.scss +0 -203
  54. data/app/assets/stylesheets/rails_error_dashboard/application.css +0 -15
  55. data/app/assets/stylesheets/rails_error_dashboard/application.css.map +0 -7
  56. data/app/assets/stylesheets/rails_error_dashboard/application.scss +0 -61
  57. data/app/views/layouts/rails_error_dashboard/application.html.erb +0 -55
@@ -1,5 +1,120 @@
1
1
  <% content_for :page_title, "Settings" %>
2
2
 
3
+ <%
4
+ # Define setting groups with metadata
5
+ setting_groups = {
6
+ "Core Features" => {
7
+ icon: "bi-shield-check",
8
+ color: "primary",
9
+ settings: {
10
+ enable_middleware: { label: "Error Middleware", description: "Catches unhandled exceptions", type: :boolean },
11
+ enable_error_subscriber: { label: "Rails.error Subscriber", description: "Subscribes to Rails error events", type: :boolean },
12
+ retention_days: { label: "Data Retention", description: "Manual cleanup only (run: rails error_dashboard:cleanup_resolved DAYS=90)", type: :retention_days },
13
+ max_backtrace_lines: { label: "Max Backtrace Lines", description: "Stack trace depth limit", type: :integer, unit: "lines" },
14
+ sampling_rate: { label: "Sampling Rate", description: "Percentage of errors captured", type: :percentage }
15
+ }
16
+ },
17
+ "Multi-App Support" => {
18
+ icon: "bi-collection",
19
+ color: "info",
20
+ settings: {
21
+ application_name: { label: "Application Name", description: "Name of this application (auto-detected if not set)", type: :application_name },
22
+ database: { label: "Database Connection", description: "Active database for error logs", type: :database_name },
23
+ use_separate_database: { label: "Separate Database", description: "Use dedicated DB for error logs", type: :boolean }
24
+ }
25
+ },
26
+ "User Integration" => {
27
+ icon: "bi-people",
28
+ color: "secondary",
29
+ settings: {
30
+ user_model: { label: "User Model", description: "Model name for user associations (auto-detected if not set)", type: :user_model },
31
+ total_users_for_impact: { label: "Total Users", description: "For impact % calculation (auto-detected if not set)", type: :total_users }
32
+ }
33
+ },
34
+ "Performance Settings" => {
35
+ icon: "bi-lightning-charge",
36
+ color: "dark",
37
+ settings: {
38
+ async_logging: { label: "Async Logging", description: "Background job processing", type: :boolean, extra: :async_adapter },
39
+ async_adapter: { label: "Async Adapter", description: "Job queue adapter", type: :symbol, show_if: :async_logging },
40
+ enable_rate_limiting: { label: "Rate Limiting", description: "Throttle API requests", type: :boolean },
41
+ rate_limit_per_minute: { label: "Rate Limit Threshold", description: "Requests per minute per IP", type: :integer, show_if: :enable_rate_limiting }
42
+ }
43
+ },
44
+ "Notification Channels" => {
45
+ icon: "bi-bell",
46
+ color: "info",
47
+ settings: {
48
+ enable_slack_notifications: { label: "Slack", description: "Real-time notifications", type: :boolean },
49
+ slack_webhook_url: { label: "Slack Webhook URL", description: "Slack webhook endpoint", type: :url, show_if: :enable_slack_notifications },
50
+ enable_email_notifications: { label: "Email", description: "Email alerts", type: :boolean },
51
+ notification_email_recipients: { label: "Email Recipients", description: "Recipient addresses", type: :array, show_if: :enable_email_notifications },
52
+ notification_email_from: { label: "Email From", description: "Sender address", type: :string, show_if: :enable_email_notifications },
53
+ enable_discord_notifications: { label: "Discord", description: "Discord webhook notifications", type: :boolean },
54
+ discord_webhook_url: { label: "Discord Webhook URL", description: "Discord webhook endpoint", type: :url, show_if: :enable_discord_notifications },
55
+ enable_pagerduty_notifications: { label: "PagerDuty", description: "Critical error escalation", type: :boolean },
56
+ pagerduty_integration_key: { label: "PagerDuty Integration Key", description: "PagerDuty API key", type: :string, show_if: :enable_pagerduty_notifications },
57
+ enable_webhook_notifications: { label: "Custom Webhooks", description: "Generic webhook endpoints", type: :boolean },
58
+ webhook_urls: { label: "Webhook URLs", description: "Custom webhook endpoints", type: :array, show_if: :enable_webhook_notifications }
59
+ }
60
+ },
61
+ "Advanced Analytics Features" => {
62
+ icon: "bi-graph-up",
63
+ color: "success",
64
+ settings: {
65
+ enable_similar_errors: { label: "Similar Errors (Fuzzy Matching)", description: "Find related errors by similarity", type: :boolean },
66
+ enable_co_occurring_errors: { label: "Co-occurring Errors", description: "Errors happening together", type: :boolean },
67
+ enable_error_cascades: { label: "Error Cascades", description: "Parent→child error chains", type: :boolean },
68
+ enable_error_correlation: { label: "Error Correlation", description: "Version/user/time analysis", type: :boolean },
69
+ enable_platform_comparison: { label: "Platform Comparison", description: "iOS vs Android analytics", type: :boolean },
70
+ enable_occurrence_patterns: { label: "Occurrence Patterns", description: "Cyclical/burst detection", type: :boolean },
71
+ enable_baseline_alerts: { label: "Baseline Alerts", description: "Anomaly detection", type: :boolean },
72
+ baseline_alert_threshold_std_devs: { label: "Alert Threshold", description: "Standard deviations to trigger alert", type: :float, show_if: :enable_baseline_alerts, unit: "σ" },
73
+ baseline_alert_severities: { label: "Alert Severities", description: "Severities to alert on", type: :array, show_if: :enable_baseline_alerts },
74
+ baseline_alert_cooldown_minutes: { label: "Alert Cooldown", description: "Minutes between alerts for same error type", type: :integer, show_if: :enable_baseline_alerts, unit: "minutes" }
75
+ }
76
+ },
77
+ "Source Code Integration" => {
78
+ icon: "bi-code-square",
79
+ color: "dark",
80
+ settings: {
81
+ enable_source_code_integration: { label: "Source Code Integration", description: "Show code in backtrace", type: :boolean },
82
+ source_code_context_lines: { label: "Context Lines", description: "Lines before/after target line", type: :integer, show_if: :enable_source_code_integration },
83
+ enable_git_blame: { label: "Git Blame", description: "Show git blame info", type: :boolean, show_if: :enable_source_code_integration },
84
+ source_code_cache_ttl: { label: "Cache TTL", description: "Source code cache duration", type: :integer, show_if: :enable_source_code_integration, unit: "seconds" },
85
+ only_show_app_code_source: { label: "Only App Code", description: "Hide gems/stdlib for security", type: :boolean, show_if: :enable_source_code_integration },
86
+ git_branch_strategy: { label: "Git Branch Strategy", description: "Branch resolution strategy", type: :symbol, show_if: :enable_source_code_integration }
87
+ }
88
+ },
89
+ "Enhanced Metrics" => {
90
+ icon: "bi-speedometer",
91
+ color: "secondary",
92
+ settings: {
93
+ app_version: { label: "App Version", description: "Current application version", type: :string },
94
+ git_sha: { label: "Git SHA", description: "Deployed commit", type: :git_sha },
95
+ git_repository_url: { label: "Git Repository URL", description: "GitHub/GitLab repo URL", type: :url },
96
+ dashboard_base_url: { label: "Dashboard Base URL", description: "Base URL for dashboard links", type: :url }
97
+ }
98
+ },
99
+ "Advanced Configuration" => {
100
+ icon: "bi-sliders",
101
+ color: "secondary",
102
+ settings: {
103
+ custom_severity_rules: { label: "Custom Severity Rules", description: "Error type → severity mapping", type: :hash },
104
+ ignored_exceptions: { label: "Ignored Exceptions", description: "Exceptions to ignore", type: :array }
105
+ }
106
+ },
107
+ "Internal Logging" => {
108
+ icon: "bi-terminal",
109
+ color: "light",
110
+ settings: {
111
+ enable_internal_logging: { label: "Internal Logging", description: "Gem debugging output", type: :boolean },
112
+ log_level: { label: "Log Level", description: "Verbosity level", type: :symbol, show_if: :enable_internal_logging }
113
+ }
114
+ }
115
+ }
116
+ %>
117
+
3
118
  <div class="container-fluid py-4">
4
119
  <!-- Page Header -->
5
120
  <div class="d-flex justify-content-between align-items-center mb-4">
@@ -20,399 +135,42 @@
20
135
  <code>config/initializers/rails_error_dashboard.rb</code>
21
136
  </div>
22
137
 
23
- <!-- Core Features -->
24
- <div class="card mb-4">
25
- <div class="card-header bg-primary text-white">
26
- <h5 class="mb-0">
27
- <i class="bi bi-shield-check"></i> Core Features
28
- </h5>
29
- </div>
30
- <div class="card-body">
31
- <div class="row">
32
- <div class="col-md-6 mb-3">
33
- <div class="d-flex justify-content-between align-items-center">
34
- <div>
35
- <strong>Error Middleware</strong>
36
- <br><small class="text-muted">Catches unhandled exceptions</small>
37
- </div>
38
- <% if @config.enable_middleware %>
39
- <span class="badge bg-success fs-6">
40
- <i class="bi bi-check-circle"></i> Enabled
41
- </span>
42
- <% else %>
43
- <span class="badge bg-secondary fs-6">
44
- <i class="bi bi-x-circle"></i> Disabled
45
- </span>
46
- <% end %>
47
- </div>
48
- </div>
49
-
50
- <div class="col-md-6 mb-3">
51
- <div class="d-flex justify-content-between align-items-center">
52
- <div>
53
- <strong>Rails.error Subscriber</strong>
54
- <br><small class="text-muted">Subscribes to Rails error events</small>
55
- </div>
56
- <% if @config.enable_error_subscriber %>
57
- <span class="badge bg-success fs-6">
58
- <i class="bi bi-check-circle"></i> Enabled
59
- </span>
60
- <% else %>
61
- <span class="badge bg-secondary fs-6">
62
- <i class="bi bi-x-circle"></i> Disabled
63
- </span>
64
- <% end %>
65
- </div>
66
- </div>
67
-
68
- <div class="col-md-6 mb-3">
69
- <div class="d-flex justify-content-between align-items-center">
70
- <div>
71
- <strong>Authentication</strong>
72
- <br><small class="text-muted">HTTP Basic Auth protection (always enforced)</small>
73
- </div>
74
- <span class="badge bg-success fs-6">
75
- <i class="bi bi-lock-fill"></i> Always Required
76
- </span>
77
- </div>
78
- </div>
79
-
80
- <div class="col-md-6 mb-3">
81
- <div class="d-flex justify-content-between align-items-center">
82
- <div>
83
- <strong>Data Retention</strong>
84
- <br><small class="text-muted">How long errors are kept</small>
85
- </div>
86
- <span class="badge bg-info fs-6">
87
- <%= @config.retention_days %> days
88
- </span>
89
- </div>
90
- </div>
91
-
92
- <div class="col-md-6 mb-3">
93
- <div class="d-flex justify-content-between align-items-center">
94
- <div>
95
- <strong>Max Backtrace Lines</strong>
96
- <br><small class="text-muted">Stack trace depth limit</small>
97
- </div>
98
- <span class="badge bg-info fs-6">
99
- <%= @config.max_backtrace_lines %> lines
100
- </span>
101
- </div>
102
- </div>
103
-
104
- <div class="col-md-6 mb-3">
105
- <div class="d-flex justify-content-between align-items-center">
106
- <div>
107
- <strong>Sampling Rate</strong>
108
- <br><small class="text-muted">Percentage of errors captured</small>
109
- </div>
110
- <span class="badge bg-info fs-6">
111
- <%= (@config.sampling_rate * 100).to_i %>%
112
- </span>
113
- </div>
114
- </div>
115
- </div>
116
- </div>
117
- </div>
118
-
119
- <!-- Performance Settings -->
120
- <div class="card mb-4">
121
- <div class="card-header bg-warning text-dark">
122
- <h5 class="mb-0">
123
- <i class="bi bi-lightning-charge"></i> Performance Settings
124
- </h5>
125
- </div>
126
- <div class="card-body">
127
- <div class="row">
128
- <div class="col-md-6 mb-3">
129
- <div class="d-flex justify-content-between align-items-center">
130
- <div>
131
- <strong>Async Logging</strong>
132
- <br><small class="text-muted">Background job processing</small>
133
- </div>
134
- <% if @config.async_logging %>
135
- <span class="badge bg-success fs-6">
136
- <i class="bi bi-check-circle"></i> Enabled
137
- <% if @config.async_adapter %>
138
- (<%= @config.async_adapter %>)
139
- <% end %>
140
- </span>
141
- <% else %>
142
- <span class="badge bg-secondary fs-6">
143
- <i class="bi bi-x-circle"></i> Disabled
144
- </span>
145
- <% end %>
146
- </div>
147
- </div>
148
-
149
- <div class="col-md-6 mb-3">
150
- <div class="d-flex justify-content-between align-items-center">
151
- <div>
152
- <strong>Separate Database</strong>
153
- <br><small class="text-muted">Dedicated DB for error logs</small>
154
- </div>
155
- <% if @config.use_separate_database %>
156
- <span class="badge bg-success fs-6">
157
- <i class="bi bi-check-circle"></i> Enabled
158
- </span>
159
- <% else %>
160
- <span class="badge bg-secondary fs-6">
161
- <i class="bi bi-x-circle"></i> Disabled
162
- </span>
163
- <% end %>
164
- </div>
165
- </div>
166
- </div>
167
- </div>
168
- </div>
169
-
170
- <!-- Notification Channels -->
171
- <div class="card mb-4">
172
- <div class="card-header bg-info text-white">
173
- <h5 class="mb-0">
174
- <i class="bi bi-bell"></i> Notification Channels
175
- </h5>
176
- </div>
177
- <div class="card-body">
178
- <div class="row">
179
- <div class="col-md-6 mb-3">
180
- <div class="d-flex justify-content-between align-items-center">
181
- <div>
182
- <strong>Slack</strong>
183
- <br><small class="text-muted">Real-time notifications</small>
184
- </div>
185
- <% if @config.enable_slack_notifications %>
186
- <span class="badge bg-success fs-6">
187
- <i class="bi bi-check-circle"></i> Enabled
188
- </span>
189
- <% else %>
190
- <span class="badge bg-secondary fs-6">
191
- <i class="bi bi-x-circle"></i> Disabled
192
- </span>
193
- <% end %>
194
- </div>
195
- </div>
196
-
197
- <div class="col-md-6 mb-3">
198
- <div class="d-flex justify-content-between align-items-center">
199
- <div>
200
- <strong>Email</strong>
201
- <br><small class="text-muted">Email alerts</small>
202
- </div>
203
- <% if @config.enable_email_notifications %>
204
- <span class="badge bg-success fs-6">
205
- <i class="bi bi-check-circle"></i> Enabled
206
- <% if @config.notification_email_recipients&.any? %>
207
- (<%= @config.notification_email_recipients.count %> recipient<%= @config.notification_email_recipients.count != 1 ? 's' : '' %>)
208
- <% end %>
209
- </span>
210
- <% else %>
211
- <span class="badge bg-secondary fs-6">
212
- <i class="bi bi-x-circle"></i> Disabled
213
- </span>
214
- <% end %>
215
- </div>
216
- </div>
217
-
218
- <div class="col-md-6 mb-3">
219
- <div class="d-flex justify-content-between align-items-center">
220
- <div>
221
- <strong>Discord</strong>
222
- <br><small class="text-muted">Discord webhook notifications</small>
223
- </div>
224
- <% if @config.enable_discord_notifications %>
225
- <span class="badge bg-success fs-6">
226
- <i class="bi bi-check-circle"></i> Enabled
227
- </span>
228
- <% else %>
229
- <span class="badge bg-secondary fs-6">
230
- <i class="bi bi-x-circle"></i> Disabled
231
- </span>
232
- <% end %>
233
- </div>
234
- </div>
235
-
236
- <div class="col-md-6 mb-3">
237
- <div class="d-flex justify-content-between align-items-center">
238
- <div>
239
- <strong>PagerDuty</strong>
240
- <br><small class="text-muted">Critical error escalation</small>
241
- </div>
242
- <% if @config.enable_pagerduty_notifications %>
243
- <span class="badge bg-success fs-6">
244
- <i class="bi bi-check-circle"></i> Enabled
245
- </span>
246
- <% else %>
247
- <span class="badge bg-secondary fs-6">
248
- <i class="bi bi-x-circle"></i> Disabled
249
- </span>
250
- <% end %>
251
- </div>
252
- </div>
253
-
254
- <div class="col-md-6 mb-3">
255
- <div class="d-flex justify-content-between align-items-center">
256
- <div>
257
- <strong>Custom Webhooks</strong>
258
- <br><small class="text-muted">Generic webhook endpoints</small>
259
- </div>
260
- <% if @config.enable_webhook_notifications %>
261
- <span class="badge bg-success fs-6">
262
- <i class="bi bi-check-circle"></i> Enabled
263
- <% if @config.webhook_urls&.any? %>
264
- (<%= @config.webhook_urls.count %> URL<%= @config.webhook_urls.count != 1 ? 's' : '' %>)
265
- <% end %>
266
- </span>
267
- <% else %>
268
- <span class="badge bg-secondary fs-6">
269
- <i class="bi bi-x-circle"></i> Disabled
270
- </span>
271
- <% end %>
272
- </div>
273
- </div>
138
+ <!-- Dynamically render setting groups -->
139
+ <% setting_groups.each do |group_name, group_config| %>
140
+ <div class="card mb-4">
141
+ <div class="card-header bg-<%= group_config[:color] %> <%= group_config[:color] == 'light' ? 'text-dark' : 'text-white' %>">
142
+ <h5 class="mb-0">
143
+ <i class="<%= group_config[:icon] %>"></i> <%= group_name %>
144
+ </h5>
274
145
  </div>
275
- </div>
276
- </div>
277
-
278
- <!-- Advanced Analytics Features -->
279
- <div class="card mb-4">
280
- <div class="card-header bg-success text-white">
281
- <h5 class="mb-0">
282
- <i class="bi bi-graph-up"></i> Advanced Analytics Features
283
- </h5>
284
- </div>
285
- <div class="card-body">
286
- <div class="row">
287
- <div class="col-md-6 mb-3">
288
- <div class="d-flex justify-content-between align-items-center">
289
- <div>
290
- <strong>Similar Errors (Fuzzy Matching)</strong>
291
- <br><small class="text-muted">Find related errors by similarity</small>
292
- </div>
293
- <% if @config.enable_similar_errors %>
294
- <span class="badge bg-success fs-6">
295
- <i class="bi bi-check-circle"></i> Enabled
296
- </span>
297
- <% else %>
298
- <span class="badge bg-secondary fs-6">
299
- <i class="bi bi-x-circle"></i> Disabled
300
- </span>
301
- <% end %>
302
- </div>
303
- </div>
304
-
305
- <div class="col-md-6 mb-3">
306
- <div class="d-flex justify-content-between align-items-center">
307
- <div>
308
- <strong>Co-occurring Errors</strong>
309
- <br><small class="text-muted">Errors happening together</small>
310
- </div>
311
- <% if @config.enable_co_occurring_errors %>
312
- <span class="badge bg-success fs-6">
313
- <i class="bi bi-check-circle"></i> Enabled
314
- </span>
315
- <% else %>
316
- <span class="badge bg-secondary fs-6">
317
- <i class="bi bi-x-circle"></i> Disabled
318
- </span>
319
- <% end %>
320
- </div>
321
- </div>
322
-
323
- <div class="col-md-6 mb-3">
324
- <div class="d-flex justify-content-between align-items-center">
325
- <div>
326
- <strong>Error Cascades</strong>
327
- <br><small class="text-muted">Parent→child error chains</small>
328
- </div>
329
- <% if @config.enable_error_cascades %>
330
- <span class="badge bg-success fs-6">
331
- <i class="bi bi-check-circle"></i> Enabled
332
- </span>
333
- <% else %>
334
- <span class="badge bg-secondary fs-6">
335
- <i class="bi bi-x-circle"></i> Disabled
336
- </span>
337
- <% end %>
338
- </div>
339
- </div>
340
-
341
- <div class="col-md-6 mb-3">
342
- <div class="d-flex justify-content-between align-items-center">
343
- <div>
344
- <strong>Error Correlation</strong>
345
- <br><small class="text-muted">Version/user/time analysis</small>
346
- </div>
347
- <% if @config.enable_error_correlation %>
348
- <span class="badge bg-success fs-6">
349
- <i class="bi bi-check-circle"></i> Enabled
350
- </span>
351
- <% else %>
352
- <span class="badge bg-secondary fs-6">
353
- <i class="bi bi-x-circle"></i> Disabled
354
- </span>
355
- <% end %>
356
- </div>
357
- </div>
358
-
359
- <div class="col-md-6 mb-3">
360
- <div class="d-flex justify-content-between align-items-center">
361
- <div>
362
- <strong>Platform Comparison</strong>
363
- <br><small class="text-muted">iOS vs Android analytics</small>
364
- </div>
365
- <% if @config.enable_platform_comparison %>
366
- <span class="badge bg-success fs-6">
367
- <i class="bi bi-check-circle"></i> Enabled
368
- </span>
369
- <% else %>
370
- <span class="badge bg-secondary fs-6">
371
- <i class="bi bi-x-circle"></i> Disabled
372
- </span>
373
- <% end %>
374
- </div>
375
- </div>
376
-
377
- <div class="col-md-6 mb-3">
378
- <div class="d-flex justify-content-between align-items-center">
379
- <div>
380
- <strong>Occurrence Patterns</strong>
381
- <br><small class="text-muted">Cyclical/burst detection</small>
382
- </div>
383
- <% if @config.enable_occurrence_patterns %>
384
- <span class="badge bg-success fs-6">
385
- <i class="bi bi-check-circle"></i> Enabled
386
- </span>
387
- <% else %>
388
- <span class="badge bg-secondary fs-6">
389
- <i class="bi bi-x-circle"></i> Disabled
390
- </span>
391
- <% end %>
392
- </div>
393
- </div>
394
-
395
- <div class="col-md-6 mb-3">
396
- <div class="d-flex justify-content-between align-items-center">
397
- <div>
398
- <strong>Baseline Alerts</strong>
399
- <br><small class="text-muted">Anomaly detection</small>
146
+ <div class="card-body">
147
+ <div class="row">
148
+ <% group_config[:settings].each do |setting_key, setting_meta| %>
149
+ <%
150
+ # Check if this setting should be displayed based on show_if condition
151
+ show_if_key = setting_meta[:show_if]
152
+ should_show = show_if_key.nil? || @config.send(show_if_key)
153
+ next unless should_show
154
+
155
+ value = @config.send(setting_key)
156
+ %>
157
+ <div class="col-md-6 mb-3">
158
+ <div class="d-flex justify-content-between align-items-center">
159
+ <div>
160
+ <strong><%= setting_meta[:label] %></strong>
161
+ <br><small class="text-muted"><%= setting_meta[:description] %></small>
162
+ </div>
163
+ <div class="text-end">
164
+ <%= render partial: 'rails_error_dashboard/errors/settings/value_badge',
165
+ locals: { value: value, type: setting_meta[:type], unit: setting_meta[:unit] } %>
166
+ </div>
167
+ </div>
400
168
  </div>
401
- <% if @config.enable_baseline_alerts %>
402
- <span class="badge bg-success fs-6">
403
- <i class="bi bi-check-circle"></i> Enabled
404
- (± <%= @config.baseline_alert_threshold_std_devs %>σ)
405
- </span>
406
- <% else %>
407
- <span class="badge bg-secondary fs-6">
408
- <i class="bi bi-x-circle"></i> Disabled
409
- </span>
410
- <% end %>
411
- </div>
169
+ <% end %>
412
170
  </div>
413
171
  </div>
414
172
  </div>
415
- </div>
173
+ <% end %>
416
174
 
417
175
  <!-- Active Plugins -->
418
176
  <div class="card mb-4">
@@ -464,98 +222,6 @@
464
222
  </div>
465
223
  </div>
466
224
 
467
- <!-- Enhanced Metrics -->
468
- <% if @config.app_version || @config.git_sha || @config.total_users_for_impact %>
469
- <div class="card mb-4">
470
- <div class="card-header bg-secondary text-white">
471
- <h5 class="mb-0">
472
- <i class="bi bi-speedometer"></i> Enhanced Metrics
473
- </h5>
474
- </div>
475
- <div class="card-body">
476
- <div class="row">
477
- <% if @config.app_version %>
478
- <div class="col-md-4 mb-3">
479
- <div class="d-flex justify-content-between align-items-center">
480
- <div>
481
- <strong>App Version</strong>
482
- <br><small class="text-muted">Current application version</small>
483
- </div>
484
- <code class="fs-6"><%= @config.app_version %></code>
485
- </div>
486
- </div>
487
- <% end %>
488
-
489
- <% if @config.git_sha %>
490
- <div class="col-md-4 mb-3">
491
- <div class="d-flex justify-content-between align-items-center">
492
- <div>
493
- <strong>Git SHA</strong>
494
- <br><small class="text-muted">Deployed commit</small>
495
- </div>
496
- <span class="fs-6"><%= git_commit_link(@config.git_sha) %></span>
497
- </div>
498
- </div>
499
- <% end %>
500
-
501
- <% if @config.total_users_for_impact %>
502
- <div class="col-md-4 mb-3">
503
- <div class="d-flex justify-content-between align-items-center">
504
- <div>
505
- <strong>Total Users</strong>
506
- <br><small class="text-muted">For impact % calculation</small>
507
- </div>
508
- <span class="badge bg-info fs-6"><%= @config.total_users_for_impact %></span>
509
- </div>
510
- </div>
511
- <% end %>
512
- </div>
513
- </div>
514
- </div>
515
- <% end %>
516
-
517
- <!-- Internal Logging -->
518
- <div class="card mb-4">
519
- <div class="card-header bg-light">
520
- <h5 class="mb-0">
521
- <i class="bi bi-terminal"></i> Internal Logging
522
- </h5>
523
- </div>
524
- <div class="card-body">
525
- <div class="row">
526
- <div class="col-md-6 mb-3">
527
- <div class="d-flex justify-content-between align-items-center">
528
- <div>
529
- <strong>Internal Logging</strong>
530
- <br><small class="text-muted">Gem debugging output</small>
531
- </div>
532
- <% if @config.enable_internal_logging %>
533
- <span class="badge bg-warning text-dark fs-6">
534
- <i class="bi bi-check-circle"></i> Enabled
535
- </span>
536
- <% else %>
537
- <span class="badge bg-secondary fs-6">
538
- <i class="bi bi-x-circle"></i> Disabled
539
- </span>
540
- <% end %>
541
- </div>
542
- </div>
543
-
544
- <div class="col-md-6 mb-3">
545
- <div class="d-flex justify-content-between align-items-center">
546
- <div>
547
- <strong>Log Level</strong>
548
- <br><small class="text-muted">Verbosity level</small>
549
- </div>
550
- <span class="badge bg-info fs-6">
551
- <%= @config.log_level.to_s.upcase %>
552
- </span>
553
- </div>
554
- </div>
555
- </div>
556
- </div>
557
- </div>
558
-
559
225
  <!-- Help Text -->
560
226
  <div class="alert alert-light border">
561
227
  <h6 class="alert-heading">