rails_error_dashboard 0.1.1 → 0.1.3

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +66 -21
  3. data/app/assets/stylesheets/rails_error_dashboard/_catppuccin_mocha.scss +107 -0
  4. data/app/assets/stylesheets/rails_error_dashboard/_components.scss +625 -0
  5. data/app/assets/stylesheets/rails_error_dashboard/_layout.scss +257 -0
  6. data/app/assets/stylesheets/rails_error_dashboard/_theme_variables.scss +203 -0
  7. data/app/assets/stylesheets/rails_error_dashboard/application.css +926 -15
  8. data/app/assets/stylesheets/rails_error_dashboard/application.css.map +7 -0
  9. data/app/assets/stylesheets/rails_error_dashboard/application.scss +61 -0
  10. data/app/controllers/rails_error_dashboard/errors_controller.rb +94 -1
  11. data/app/helpers/rails_error_dashboard/application_helper.rb +42 -4
  12. data/app/helpers/rails_error_dashboard/backtrace_helper.rb +91 -0
  13. data/app/helpers/rails_error_dashboard/overview_helper.rb +78 -0
  14. data/app/helpers/rails_error_dashboard/user_agent_helper.rb +118 -0
  15. data/app/models/rails_error_dashboard/error_comment.rb +27 -0
  16. data/app/models/rails_error_dashboard/error_log.rb +145 -0
  17. data/app/views/layouts/rails_error_dashboard.html.erb +796 -299
  18. data/app/views/layouts/rails_error_dashboard_old_backup.html.erb +383 -0
  19. data/app/views/rails_error_dashboard/errors/_error_row.html.erb +2 -0
  20. data/app/views/rails_error_dashboard/errors/_pattern_insights.html.erb +4 -4
  21. data/app/views/rails_error_dashboard/errors/_timeline.html.erb +167 -0
  22. data/app/views/rails_error_dashboard/errors/analytics.html.erb +138 -22
  23. data/app/views/rails_error_dashboard/errors/index.html.erb +83 -4
  24. data/app/views/rails_error_dashboard/errors/overview.html.erb +253 -0
  25. data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +29 -18
  26. data/app/views/rails_error_dashboard/errors/show.html.erb +353 -54
  27. data/config/routes.rb +7 -0
  28. data/db/migrate/20251226020000_add_workflow_fields_to_error_logs.rb +27 -0
  29. data/db/migrate/20251226020100_create_error_comments.rb +18 -0
  30. data/lib/generators/rails_error_dashboard/install/install_generator.rb +8 -2
  31. data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +21 -0
  32. data/lib/rails_error_dashboard/commands/batch_delete_errors.rb +1 -1
  33. data/lib/rails_error_dashboard/commands/batch_resolve_errors.rb +2 -2
  34. data/lib/rails_error_dashboard/commands/log_error.rb +47 -9
  35. data/lib/rails_error_dashboard/commands/resolve_error.rb +1 -1
  36. data/lib/rails_error_dashboard/configuration.rb +8 -0
  37. data/lib/rails_error_dashboard/error_reporter.rb +4 -4
  38. data/lib/rails_error_dashboard/logger.rb +105 -0
  39. data/lib/rails_error_dashboard/middleware/error_catcher.rb +2 -2
  40. data/lib/rails_error_dashboard/plugin.rb +3 -3
  41. data/lib/rails_error_dashboard/plugin_registry.rb +2 -2
  42. data/lib/rails_error_dashboard/plugins/jira_integration_plugin.rb +1 -1
  43. data/lib/rails_error_dashboard/plugins/metrics_plugin.rb +1 -1
  44. data/lib/rails_error_dashboard/queries/dashboard_stats.rb +109 -1
  45. data/lib/rails_error_dashboard/queries/errors_list.rb +61 -6
  46. data/lib/rails_error_dashboard/services/backtrace_parser.rb +113 -0
  47. data/lib/rails_error_dashboard/version.rb +1 -1
  48. data/lib/rails_error_dashboard.rb +2 -0
  49. metadata +18 -2
  50. data/lib/tasks/rails_error_dashboard_tasks.rake +0 -4
@@ -0,0 +1,625 @@
1
+ // =============================================================================
2
+ // Component Styles - Catppuccin Mocha Theme
3
+ // =============================================================================
4
+ // Component-specific styling using Catppuccin color palette
5
+ // Ensures proper contrast and visibility in dark theme
6
+ // =============================================================================
7
+
8
+ @import 'catppuccin_mocha';
9
+ @import 'theme_variables';
10
+
11
+ // =============================================================================
12
+ // BADGE COMPONENTS
13
+ // =============================================================================
14
+ // Platform and status badges with proper contrast
15
+
16
+ .badge {
17
+ // iOS Badge - Light text on dark background (dark theme)
18
+ &.badge-ios {
19
+ [data-theme="dark"] & {
20
+ background-color: var(--ctp-overlay0);
21
+ color: var(--ctp-text);
22
+ border: 1px solid var(--ctp-surface2);
23
+ }
24
+ }
25
+
26
+ // Android Badge - Green theme
27
+ &.badge-android {
28
+ [data-theme="dark"] & {
29
+ background-color: #{ctp-opacity($ctp-green, 0.2)};
30
+ color: var(--ctp-green);
31
+ border: 1px solid var(--ctp-green);
32
+ }
33
+ }
34
+
35
+ // Web Badge - Blue theme
36
+ &.badge-web {
37
+ [data-theme="dark"] & {
38
+ background-color: #{ctp-opacity($ctp-blue, 0.2)};
39
+ color: var(--ctp-blue);
40
+ border: 1px solid var(--ctp-blue);
41
+ }
42
+ }
43
+
44
+ // API Badge - Sapphire theme
45
+ &.badge-api {
46
+ [data-theme="dark"] & {
47
+ background-color: #{ctp-opacity($ctp-sapphire, 0.2)};
48
+ color: var(--ctp-sapphire);
49
+ border: 1px solid var(--ctp-sapphire);
50
+ }
51
+ }
52
+
53
+ // Severity Badges
54
+ &.bg-danger {
55
+ [data-theme="dark"] & {
56
+ background-color: var(--ctp-red) !important;
57
+ color: var(--ctp-base) !important;
58
+ }
59
+ }
60
+
61
+ &.bg-warning {
62
+ [data-theme="dark"] & {
63
+ background-color: var(--ctp-peach) !important;
64
+ color: var(--ctp-base) !important;
65
+ }
66
+ }
67
+
68
+ &.bg-success {
69
+ [data-theme="dark"] & {
70
+ background-color: var(--ctp-green) !important;
71
+ color: var(--ctp-base) !important;
72
+ }
73
+ }
74
+
75
+ &.bg-info {
76
+ [data-theme="dark"] & {
77
+ background-color: var(--ctp-blue) !important;
78
+ color: var(--ctp-base) !important;
79
+ }
80
+ }
81
+
82
+ &.bg-secondary {
83
+ [data-theme="dark"] & {
84
+ background-color: var(--ctp-overlay1) !important;
85
+ color: var(--ctp-text) !important;
86
+ }
87
+ }
88
+ }
89
+
90
+ // =============================================================================
91
+ // CARD COMPONENTS
92
+ // =============================================================================
93
+
94
+ .card {
95
+ [data-theme="dark"] & {
96
+ background-color: var(--card-bg);
97
+ border-color: var(--border-color);
98
+ color: var(--text-color);
99
+
100
+ .card-header {
101
+ background-color: var(--card-bg);
102
+ border-bottom-color: var(--border-color);
103
+ color: var(--text-color);
104
+
105
+ // Override all bg-white instances
106
+ &.bg-white {
107
+ background-color: var(--card-bg) !important;
108
+ color: var(--text-color) !important;
109
+ }
110
+
111
+ &.bg-danger {
112
+ background-color: var(--ctp-red) !important;
113
+ color: var(--ctp-base) !important;
114
+ }
115
+
116
+ &.bg-warning {
117
+ background-color: var(--ctp-peach) !important;
118
+ color: var(--ctp-base) !important;
119
+ }
120
+
121
+ &.bg-success {
122
+ background-color: var(--ctp-green) !important;
123
+ color: var(--ctp-base) !important;
124
+ }
125
+
126
+ &.bg-info {
127
+ background-color: var(--ctp-blue) !important;
128
+ color: var(--ctp-base) !important;
129
+ }
130
+ }
131
+
132
+ .card-body {
133
+ color: var(--text-color);
134
+ }
135
+
136
+ .card-footer {
137
+ background-color: var(--card-bg);
138
+ border-top-color: var(--border-color);
139
+ color: var(--text-secondary);
140
+ }
141
+ }
142
+ }
143
+
144
+ // =============================================================================
145
+ // CODE BLOCKS & SYNTAX HIGHLIGHTING
146
+ // =============================================================================
147
+
148
+ code, pre {
149
+ [data-theme="dark"] & {
150
+ background-color: var(--code-bg) !important;
151
+ color: var(--text-color) !important;
152
+ border-color: var(--border-color);
153
+ }
154
+ }
155
+
156
+ .code-block {
157
+ [data-theme="dark"] & {
158
+ background-color: var(--code-bg);
159
+ color: var(--text-color);
160
+ border: 1px solid var(--border-color);
161
+ }
162
+ }
163
+
164
+ // Override Bootstrap's bg-dark for code blocks
165
+ .bg-dark.code-block {
166
+ [data-theme="dark"] & {
167
+ background-color: var(--code-bg) !important;
168
+ color: var(--text-color) !important;
169
+ }
170
+ }
171
+
172
+ code.bg-dark,
173
+ pre.bg-dark {
174
+ [data-theme="dark"] & {
175
+ background-color: var(--code-bg) !important;
176
+ color: var(--text-color) !important;
177
+ }
178
+ }
179
+
180
+ // =============================================================================
181
+ // BACKTRACE FRAMES
182
+ // =============================================================================
183
+ // Syntax highlighting for stack traces
184
+
185
+ .backtrace-frame {
186
+ [data-theme="dark"] & {
187
+ padding: $spacing-sm $spacing-md;
188
+ margin-bottom: 2px;
189
+ border-radius: $radius-sm;
190
+ font-family: 'Courier New', monospace;
191
+ font-size: 0.875rem;
192
+
193
+ // App code - Most important, use green
194
+ &.frame-app {
195
+ background-color: #{ctp-opacity($ctp-green, 0.1)} !important;
196
+ color: var(--ctp-green) !important;
197
+ border-left: 3px solid var(--ctp-green);
198
+ font-weight: 600;
199
+ }
200
+
201
+ // Gem code - Library code, use blue
202
+ &.frame-gem {
203
+ background-color: #{ctp-opacity($ctp-blue, 0.1)} !important;
204
+ color: var(--ctp-blue) !important;
205
+ border-left: 3px solid var(--ctp-blue);
206
+ }
207
+
208
+ // Framework code - Rails/framework, use yellow
209
+ &.frame-framework {
210
+ background-color: #{ctp-opacity($ctp-yellow, 0.1)} !important;
211
+ color: var(--ctp-yellow) !important;
212
+ border-left: 3px solid var(--ctp-yellow);
213
+ }
214
+
215
+ // Ruby core - System code, muted
216
+ &.frame-ruby-core {
217
+ background-color: #{ctp-opacity($ctp-overlay0, 0.1)} !important;
218
+ color: var(--ctp-subtext0) !important;
219
+ border-left: 3px solid var(--ctp-overlay0);
220
+ }
221
+ }
222
+ }
223
+
224
+ // =============================================================================
225
+ // HEATMAP VISUALIZATION
226
+ // =============================================================================
227
+
228
+ .heatmap-cell {
229
+ [data-theme="dark"] & {
230
+ background-color: var(--ctp-red);
231
+ color: var(--text-color);
232
+ border: 1px solid var(--border-subtle);
233
+ transition: all $transition-fast;
234
+
235
+ &:hover {
236
+ border-color: var(--border-color);
237
+ transform: scale(1.05);
238
+ }
239
+
240
+ // Intensity-based opacity set via inline style
241
+ // Example: style="--heatmap-intensity: 0.5; opacity: 0.5"
242
+ }
243
+ }
244
+
245
+ // =============================================================================
246
+ // TABLE COMPONENTS
247
+ // =============================================================================
248
+
249
+ .table {
250
+ [data-theme="dark"] & {
251
+ color: var(--text-color);
252
+ border-color: var(--border-color);
253
+
254
+ thead {
255
+ th {
256
+ background-color: var(--card-bg);
257
+ border-bottom-color: var(--border-color);
258
+ color: var(--text-color);
259
+ }
260
+ }
261
+
262
+ tbody {
263
+ tr {
264
+ background-color: transparent;
265
+ border-bottom-color: var(--border-subtle);
266
+
267
+ &:hover {
268
+ background-color: var(--table-hover);
269
+ }
270
+
271
+ td {
272
+ border-color: var(--border-subtle);
273
+ color: var(--text-color);
274
+ }
275
+ }
276
+ }
277
+
278
+ // Striped tables
279
+ &.table-striped {
280
+ tbody tr:nth-of-type(odd) {
281
+ background-color: #{ctp-opacity($ctp-surface0, 0.5)};
282
+ }
283
+ }
284
+
285
+ // Bordered tables
286
+ &.table-bordered {
287
+ border-color: var(--border-color);
288
+
289
+ th, td {
290
+ border-color: var(--border-color);
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+ // =============================================================================
297
+ // FORM CONTROLS
298
+ // =============================================================================
299
+
300
+ .form-control,
301
+ .form-select {
302
+ [data-theme="dark"] & {
303
+ background-color: var(--card-bg);
304
+ color: var(--text-color);
305
+ border-color: var(--border-color);
306
+
307
+ &:focus {
308
+ background-color: var(--card-bg);
309
+ border-color: var(--primary-color);
310
+ color: var(--text-color);
311
+ box-shadow: 0 0 0 0.2rem #{ctp-opacity($ctp-mauve, 0.25)};
312
+ }
313
+
314
+ &::placeholder {
315
+ color: var(--text-muted);
316
+ }
317
+
318
+ &:disabled {
319
+ background-color: var(--ctp-surface1);
320
+ color: var(--text-muted);
321
+ }
322
+ }
323
+ }
324
+
325
+ .form-check-input {
326
+ [data-theme="dark"] & {
327
+ background-color: var(--card-bg);
328
+ border-color: var(--border-color);
329
+
330
+ &:checked {
331
+ background-color: var(--primary-color);
332
+ border-color: var(--primary-color);
333
+ }
334
+
335
+ &:focus {
336
+ border-color: var(--primary-color);
337
+ box-shadow: 0 0 0 0.2rem #{ctp-opacity($ctp-mauve, 0.25)};
338
+ }
339
+ }
340
+ }
341
+
342
+ // =============================================================================
343
+ // BUTTON COMPONENTS
344
+ // =============================================================================
345
+
346
+ .btn {
347
+ [data-theme="dark"] & {
348
+ // Primary button
349
+ &.btn-primary {
350
+ background-color: var(--ctp-mauve);
351
+ border-color: var(--ctp-mauve);
352
+ color: var(--ctp-base);
353
+
354
+ &:hover {
355
+ background-color: #{ctp-lighten($ctp-mauve, 5%)};
356
+ border-color: #{ctp-lighten($ctp-mauve, 5%)};
357
+ }
358
+
359
+ &:active {
360
+ background-color: #{ctp-darken($ctp-mauve, 5%)};
361
+ border-color: #{ctp-darken($ctp-mauve, 5%)};
362
+ }
363
+ }
364
+
365
+ // Danger button
366
+ &.btn-danger {
367
+ background-color: var(--ctp-red);
368
+ border-color: var(--ctp-red);
369
+ color: var(--ctp-base);
370
+
371
+ &:hover {
372
+ background-color: #{ctp-lighten($ctp-red, 5%)};
373
+ border-color: #{ctp-lighten($ctp-red, 5%)};
374
+ }
375
+ }
376
+
377
+ // Success button
378
+ &.btn-success {
379
+ background-color: var(--ctp-green);
380
+ border-color: var(--ctp-green);
381
+ color: var(--ctp-base);
382
+
383
+ &:hover {
384
+ background-color: #{ctp-lighten($ctp-green, 5%)};
385
+ border-color: #{ctp-lighten($ctp-green, 5%)};
386
+ }
387
+ }
388
+
389
+ // Warning button
390
+ &.btn-warning {
391
+ background-color: var(--ctp-peach);
392
+ border-color: var(--ctp-peach);
393
+ color: var(--ctp-base);
394
+
395
+ &:hover {
396
+ background-color: #{ctp-lighten($ctp-peach, 5%)};
397
+ border-color: #{ctp-lighten($ctp-peach, 5%)};
398
+ }
399
+ }
400
+
401
+ // Info button
402
+ &.btn-info {
403
+ background-color: var(--ctp-blue);
404
+ border-color: var(--ctp-blue);
405
+ color: var(--ctp-base);
406
+
407
+ &:hover {
408
+ background-color: #{ctp-lighten($ctp-blue, 5%)};
409
+ border-color: #{ctp-lighten($ctp-blue, 5%)};
410
+ }
411
+ }
412
+
413
+ // Secondary button
414
+ &.btn-secondary {
415
+ background-color: var(--ctp-overlay1);
416
+ border-color: var(--ctp-overlay1);
417
+ color: var(--ctp-text);
418
+
419
+ &:hover {
420
+ background-color: var(--ctp-overlay2);
421
+ border-color: var(--ctp-overlay2);
422
+ }
423
+ }
424
+
425
+ // Outline variants
426
+ &.btn-outline-primary {
427
+ color: var(--ctp-mauve);
428
+ border-color: var(--ctp-mauve);
429
+
430
+ &:hover {
431
+ background-color: var(--ctp-mauve);
432
+ color: var(--ctp-base);
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ // =============================================================================
439
+ // MODAL COMPONENTS
440
+ // =============================================================================
441
+
442
+ .modal {
443
+ [data-theme="dark"] & {
444
+ .modal-content {
445
+ background-color: var(--card-bg);
446
+ color: var(--text-color);
447
+ border-color: var(--border-color);
448
+
449
+ .modal-header {
450
+ background-color: var(--card-bg);
451
+ border-bottom-color: var(--border-color);
452
+ color: var(--text-color);
453
+
454
+ .btn-close {
455
+ filter: invert(1) grayscale(100%) brightness(200%);
456
+ }
457
+ }
458
+
459
+ .modal-body {
460
+ color: var(--text-color);
461
+ }
462
+
463
+ .modal-footer {
464
+ background-color: var(--card-bg);
465
+ border-top-color: var(--border-color);
466
+ }
467
+ }
468
+ }
469
+ }
470
+
471
+ // =============================================================================
472
+ // DROPDOWN COMPONENTS
473
+ // =============================================================================
474
+
475
+ .dropdown-menu {
476
+ [data-theme="dark"] & {
477
+ background-color: var(--card-bg);
478
+ border-color: var(--border-color);
479
+
480
+ .dropdown-item {
481
+ color: var(--text-color);
482
+
483
+ &:hover,
484
+ &:focus {
485
+ background-color: var(--table-hover);
486
+ color: var(--text-color);
487
+ }
488
+
489
+ &.active {
490
+ background-color: var(--primary-color);
491
+ color: var(--ctp-base);
492
+ }
493
+ }
494
+
495
+ .dropdown-divider {
496
+ border-top-color: var(--border-color);
497
+ }
498
+ }
499
+ }
500
+
501
+ // =============================================================================
502
+ // PROGRESS BARS
503
+ // =============================================================================
504
+
505
+ .progress {
506
+ [data-theme="dark"] & {
507
+ background-color: var(--ctp-surface1);
508
+
509
+ .progress-bar {
510
+ &.bg-success {
511
+ background-color: var(--ctp-green) !important;
512
+ }
513
+
514
+ &.bg-danger {
515
+ background-color: var(--ctp-red) !important;
516
+ }
517
+
518
+ &.bg-warning {
519
+ background-color: var(--ctp-peach) !important;
520
+ }
521
+
522
+ &.bg-info {
523
+ background-color: var(--ctp-blue) !important;
524
+ }
525
+ }
526
+ }
527
+ }
528
+
529
+ // =============================================================================
530
+ // ALERTS
531
+ // =============================================================================
532
+
533
+ .alert {
534
+ [data-theme="dark"] & {
535
+ &.alert-danger {
536
+ background-color: #{ctp-opacity($ctp-red, 0.2)};
537
+ border-color: var(--ctp-red);
538
+ color: var(--ctp-red);
539
+ }
540
+
541
+ &.alert-warning {
542
+ background-color: #{ctp-opacity($ctp-peach, 0.2)};
543
+ border-color: var(--ctp-peach);
544
+ color: var(--ctp-peach);
545
+ }
546
+
547
+ &.alert-success {
548
+ background-color: #{ctp-opacity($ctp-green, 0.2)};
549
+ border-color: var(--ctp-green);
550
+ color: var(--ctp-green);
551
+ }
552
+
553
+ &.alert-info {
554
+ background-color: #{ctp-opacity($ctp-blue, 0.2)};
555
+ border-color: var(--ctp-blue);
556
+ color: var(--ctp-blue);
557
+ }
558
+ }
559
+ }
560
+
561
+ // =============================================================================
562
+ // LIST GROUP
563
+ // =============================================================================
564
+
565
+ .list-group {
566
+ [data-theme="dark"] & {
567
+ .list-group-item {
568
+ background-color: var(--card-bg);
569
+ border-color: var(--border-color);
570
+ color: var(--text-color);
571
+
572
+ &:hover {
573
+ background-color: var(--table-hover);
574
+ }
575
+
576
+ &.active {
577
+ background-color: var(--primary-color);
578
+ border-color: var(--primary-color);
579
+ color: var(--ctp-base);
580
+ }
581
+ }
582
+ }
583
+ }
584
+
585
+ // =============================================================================
586
+ // TEXT COLOR UTILITIES
587
+ // =============================================================================
588
+
589
+ [data-theme="dark"] {
590
+ .text-muted {
591
+ color: var(--text-muted) !important;
592
+ }
593
+
594
+ .text-primary {
595
+ color: var(--primary-color) !important;
596
+ }
597
+
598
+ .text-success {
599
+ color: var(--success-color) !important;
600
+ }
601
+
602
+ .text-danger {
603
+ color: var(--danger-color) !important;
604
+ }
605
+
606
+ .text-warning {
607
+ color: var(--warning-color) !important;
608
+ }
609
+
610
+ .text-info {
611
+ color: var(--info-color) !important;
612
+ }
613
+
614
+ .text-secondary {
615
+ color: var(--secondary-color) !important;
616
+ }
617
+
618
+ .text-light {
619
+ color: var(--text-color) !important;
620
+ }
621
+
622
+ .text-dark {
623
+ color: var(--text-muted) !important;
624
+ }
625
+ }