dbwatcher 1.1.1 → 1.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -2
  3. data/app/assets/config/dbwatcher_manifest.js +1 -0
  4. data/app/assets/javascripts/dbwatcher/components/changes_table_hybrid.js +196 -119
  5. data/app/assets/javascripts/dbwatcher/components/dashboard.js +325 -0
  6. data/app/assets/javascripts/dbwatcher/components/timeline.js +211 -0
  7. data/app/assets/javascripts/dbwatcher/dbwatcher.js +5 -0
  8. data/app/assets/stylesheets/dbwatcher/application.css +691 -41
  9. data/app/assets/stylesheets/dbwatcher/application.scss +5 -0
  10. data/app/assets/stylesheets/dbwatcher/components/_badges.scss +68 -23
  11. data/app/assets/stylesheets/dbwatcher/components/_compact_table.scss +83 -26
  12. data/app/assets/stylesheets/dbwatcher/components/_diagrams.scss +3 -3
  13. data/app/assets/stylesheets/dbwatcher/components/_navigation.scss +9 -0
  14. data/app/assets/stylesheets/dbwatcher/components/_tabulator.scss +248 -0
  15. data/app/assets/stylesheets/dbwatcher/components/_timeline.scss +326 -0
  16. data/app/assets/stylesheets/dbwatcher/vendor/_tabulator_overrides.scss +37 -0
  17. data/app/controllers/dbwatcher/api/v1/sessions_controller.rb +18 -4
  18. data/app/controllers/dbwatcher/api/v1/system_info_controller.rb +180 -0
  19. data/app/controllers/dbwatcher/dashboard/system_info_controller.rb +64 -0
  20. data/app/controllers/dbwatcher/dashboard_controller.rb +17 -0
  21. data/app/controllers/dbwatcher/sessions_controller.rb +3 -19
  22. data/app/helpers/dbwatcher/application_helper.rb +43 -11
  23. data/app/helpers/dbwatcher/diagram_helper.rb +0 -88
  24. data/app/views/dbwatcher/dashboard/_layout.html.erb +27 -0
  25. data/app/views/dbwatcher/dashboard/_overview.html.erb +188 -0
  26. data/app/views/dbwatcher/dashboard/_system_info.html.erb +22 -0
  27. data/app/views/dbwatcher/dashboard/_system_info_content.html.erb +389 -0
  28. data/app/views/dbwatcher/dashboard/index.html.erb +8 -177
  29. data/app/views/dbwatcher/sessions/_layout.html.erb +26 -0
  30. data/app/views/dbwatcher/sessions/{_summary_tab.html.erb → _summary.html.erb} +1 -1
  31. data/app/views/dbwatcher/sessions/_tables.html.erb +170 -0
  32. data/app/views/dbwatcher/sessions/_timeline.html.erb +260 -0
  33. data/app/views/dbwatcher/sessions/index.html.erb +107 -87
  34. data/app/views/dbwatcher/sessions/show.html.erb +12 -4
  35. data/app/views/dbwatcher/tables/index.html.erb +32 -40
  36. data/app/views/layouts/dbwatcher/application.html.erb +101 -48
  37. data/config/routes.rb +25 -7
  38. data/lib/dbwatcher/configuration.rb +18 -1
  39. data/lib/dbwatcher/services/analyzers/table_summary_builder.rb +102 -1
  40. data/lib/dbwatcher/services/api/{changes_data_service.rb → tables_data_service.rb} +6 -6
  41. data/lib/dbwatcher/services/base_service.rb +2 -0
  42. data/lib/dbwatcher/services/system_info/database_info_collector.rb +263 -0
  43. data/lib/dbwatcher/services/system_info/machine_info_collector.rb +387 -0
  44. data/lib/dbwatcher/services/system_info/runtime_info_collector.rb +328 -0
  45. data/lib/dbwatcher/services/system_info/system_info_collector.rb +114 -0
  46. data/lib/dbwatcher/services/timeline_data_service/enhancement_utilities.rb +100 -0
  47. data/lib/dbwatcher/services/timeline_data_service/entry_builder.rb +125 -0
  48. data/lib/dbwatcher/services/timeline_data_service/metadata_builder.rb +93 -0
  49. data/lib/dbwatcher/services/timeline_data_service.rb +130 -0
  50. data/lib/dbwatcher/storage/api/concerns/table_analyzer.rb +1 -1
  51. data/lib/dbwatcher/storage/concerns/error_handler.rb +6 -6
  52. data/lib/dbwatcher/storage/session.rb +5 -0
  53. data/lib/dbwatcher/storage/system_info_storage.rb +242 -0
  54. data/lib/dbwatcher/storage.rb +12 -0
  55. data/lib/dbwatcher/version.rb +1 -1
  56. data/lib/dbwatcher.rb +16 -2
  57. metadata +28 -16
  58. data/app/helpers/dbwatcher/component_helper.rb +0 -29
  59. data/app/views/dbwatcher/sessions/_changes_tab.html.erb +0 -265
  60. data/app/views/dbwatcher/sessions/_tab_navigation.html.erb +0 -12
  61. data/app/views/dbwatcher/sessions/changes.html.erb +0 -21
  62. data/app/views/dbwatcher/sessions/components/changes/_filters.html.erb +0 -44
  63. data/app/views/dbwatcher/sessions/components/changes/_table_list.html.erb +0 -96
  64. data/app/views/dbwatcher/sessions/diagrams.html.erb +0 -21
  65. data/app/views/dbwatcher/sessions/shared/_layout.html.erb +0 -8
  66. data/app/views/dbwatcher/sessions/shared/_navigation.html.erb +0 -35
  67. data/app/views/dbwatcher/sessions/shared/_session_header.html.erb +0 -25
  68. data/app/views/dbwatcher/sessions/summary.html.erb +0 -21
  69. /data/app/views/dbwatcher/sessions/{_diagrams_tab.html.erb → _diagrams.html.erb} +0 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * DBWatcher Application Styles
3
3
  * Compiled CSS for all components
4
- * Generated at 2025-07-04 17:05:33 +0700
4
+ * Generated at 2025-07-11 21:59:56 +0700
5
5
  */
6
6
 
7
7
  /**
@@ -97,6 +97,7 @@
97
97
  border-spacing: 0;
98
98
  }
99
99
 
100
+ /* Header styles */
100
101
  .compact-table th {
101
102
  padding: 4px 8px;
102
103
  font-weight: 500;
@@ -112,6 +113,18 @@
112
113
  height: 32px;
113
114
  }
114
115
 
116
+ /* Cell styles */
117
+ .compact-table td {
118
+ padding: 2px 8px;
119
+ border-right: 1px solid var(--border-light);
120
+ border-bottom: 1px solid var(--border-light);
121
+ overflow: hidden;
122
+ text-overflow: ellipsis;
123
+ white-space: nowrap;
124
+ vertical-align: top;
125
+ }
126
+
127
+ /* Sticky columns */
115
128
  /* Enhanced sticky header styling */
116
129
  .compact-table th.sticky-left-0 {
117
130
  position: sticky;
@@ -136,16 +149,6 @@
136
149
  box-shadow: 2px 0px 3px rgba(0, 0, 0, 0.05);
137
150
  }
138
151
 
139
- .compact-table td {
140
- padding: 2px 8px;
141
- border-right: 1px solid var(--border-light);
142
- border-bottom: 1px solid var(--border-light);
143
- overflow: hidden;
144
- text-overflow: ellipsis;
145
- white-space: nowrap;
146
- vertical-align: top;
147
- }
148
-
149
152
  /* Enhanced sticky cell styling */
150
153
  .compact-table td.sticky-left-0 {
151
154
  position: sticky;
@@ -173,19 +176,6 @@
173
176
  box-shadow: 2px 0px 3px rgba(0, 0, 0, 0.05);
174
177
  }
175
178
 
176
- /* Special cell formatting */
177
- .compact-table td.highlight-change {
178
- background-color: var(--highlight-change);
179
- }
180
-
181
- .compact-table td.highlight-new {
182
- color: #047857;
183
- }
184
-
185
- .compact-table td.highlight-deleted {
186
- color: #b91c1c;
187
- }
188
-
189
179
  /* Row styles */
190
180
  .compact-table tr:hover td:not(.sticky-left-0):not(.sticky-left-1):not(.sticky-left-2) {
191
181
  background-color: rgba(243, 244, 246, 0.7);
@@ -207,7 +197,7 @@
207
197
  background-color: #e6f3ff;
208
198
  }
209
199
 
210
- /* Smart column width distribution */
200
+ /* Text overflow handling */
211
201
  .compact-table th,
212
202
  .compact-table td {
213
203
  overflow: hidden;
@@ -215,7 +205,7 @@
215
205
  white-space: nowrap;
216
206
  }
217
207
 
218
- /* Fixed widths for sticky columns only */
208
+ /* Fixed widths for common columns */
219
209
  .compact-table th:first-child,
220
210
  .compact-table td:first-child {
221
211
  width: 60px;
@@ -240,11 +230,78 @@
240
230
  font-size: 11px;
241
231
  }
242
232
 
233
+ /* Sessions table specific overrides */
234
+ .sessions-table th:nth-child(2),
235
+ .sessions-table td:nth-child(2) {
236
+ width: 22%;
237
+ min-width: 160px;
238
+ max-width: 260px;
239
+ text-align: left;
240
+ padding-left: 16px;
241
+ }
242
+
243
+ /* Enhanced sessions table styling */
244
+ .sessions-table tr {
245
+ border-bottom: 1px solid var(--border-light);
246
+ transition: all 0.15s ease;
247
+ }
248
+
249
+ .sessions-table tr:hover {
250
+ background-color: rgba(230, 243, 255, 0.5);
251
+ }
252
+
253
+ .sessions-table td {
254
+ padding: 6px 8px;
255
+ vertical-align: middle;
256
+ }
257
+
258
+ .sessions-table td:first-child .font-mono {
259
+ color: var(--navy-dark);
260
+ font-weight: 500;
261
+ background: var(--gray-50);
262
+ padding: 2px 4px;
263
+ border-radius: 3px;
264
+ border: 1px solid var(--border-medium);
265
+ display: inline-block;
266
+ }
267
+
268
+ .sessions-table .badge {
269
+ min-width: 60px;
270
+ width: auto;
271
+ height: auto;
272
+ padding: 2px 8px;
273
+ }
274
+
275
+ .sessions-table .actions-cell {
276
+ width: 80px;
277
+ }
278
+
279
+ .sessions-table .actions-cell .compact-button {
280
+ transition: transform 0.15s ease, background-color 0.15s ease;
281
+ }
282
+
283
+ .sessions-table .actions-cell .compact-button:hover {
284
+ transform: translateY(-1px);
285
+ }
286
+
243
287
  /* Font styling for specific column types */
244
288
  .compact-table .text-right {
245
289
  font-family: monospace;
246
290
  }
247
291
 
292
+ /* Special cell formatting */
293
+ .compact-table td.highlight-change {
294
+ background-color: var(--highlight-change);
295
+ }
296
+
297
+ .compact-table td.highlight-new {
298
+ color: #047857;
299
+ }
300
+
301
+ .compact-table td.highlight-deleted {
302
+ color: #b91c1c;
303
+ }
304
+
248
305
  /* Highlight colors */
249
306
  .highlight-change {
250
307
  background: var(--highlight-change);
@@ -313,6 +370,15 @@
313
370
  font-weight: 500;
314
371
  }
315
372
 
373
+ /* Tab content styles */
374
+ .tab-content {
375
+ display: none;
376
+ }
377
+
378
+ .tab-content.active {
379
+ display: block;
380
+ }
381
+
316
382
  /**
317
383
  * Form Controls
318
384
  * Input fields, selects, buttons
@@ -344,43 +410,89 @@
344
410
  * Status Badges
345
411
  * Operation and status indicators
346
412
  */
347
- /* Status badges */
413
+ /* Base badge style */
414
+ .badge {
415
+ padding: 1px 6px;
416
+ font-size: 10px;
417
+ border-radius: 3px;
418
+ font-weight: 500;
419
+ text-transform: uppercase;
420
+ display: inline-block;
421
+ min-width: 18px;
422
+ height: 18px;
423
+ line-height: 18px;
424
+ text-align: center;
425
+ }
426
+
427
+ /* Operation type badges */
348
428
  .badge-insert {
349
- background: var(--status-insert);
429
+ background: var(--status-insert, #10b981);
350
430
  color: white;
351
431
  }
352
432
 
353
433
  .badge-update {
354
- background: var(--status-update);
434
+ background: var(--status-update, #6CADDF);
355
435
  color: white;
356
436
  }
357
437
 
358
438
  .badge-delete {
359
- background: var(--status-delete);
439
+ background: var(--status-delete, #ef4444);
360
440
  color: white;
361
441
  }
362
442
 
363
443
  .badge-select {
364
- background: var(--status-select);
444
+ background: var(--status-select, #6b7280);
365
445
  color: white;
366
446
  }
367
447
 
368
- .badge {
369
- padding: 1px 6px;
370
- font-size: 10px;
371
- border-radius: 3px;
372
- font-weight: 500;
373
- text-transform: uppercase;
374
- display: inline-block;
448
+ /* Status badges */
449
+ .badge-success {
450
+ background: var(--status-insert, #10b981);
451
+ color: white;
452
+ }
453
+
454
+ .badge-primary {
455
+ background: var(--blue-medium, #3b82f6);
456
+ color: white;
457
+ }
458
+
459
+ .badge-warning {
460
+ background: var(--status-warning, #f59e0b);
461
+ color: white;
462
+ }
463
+
464
+ .badge-error {
465
+ background: var(--status-delete, #ef4444);
466
+ color: white;
467
+ }
468
+
469
+ /* Badge sizes */
470
+ .badge-sm {
471
+ font-size: 9px;
472
+ padding: 0px 4px;
473
+ height: 16px;
474
+ line-height: 16px;
475
+ }
476
+
477
+ .badge-lg {
478
+ font-size: 11px;
479
+ padding: 2px 8px;
480
+ height: 20px;
481
+ line-height: 16px;
482
+ }
483
+
484
+ /* Changes table specific badges */
485
+ .changes-table-badge {
375
486
  width: 18px;
376
- height: 18px;
377
- line-height: 18px;
378
- text-align: center;
487
+ display: inline-flex;
488
+ align-items: center;
489
+ justify-content: center;
379
490
  }
380
491
 
381
492
  /**
382
493
  * Diagram Component Styles
383
494
  */
495
+ /* Code view container */
384
496
  .diagram-code-view {
385
497
  position: relative;
386
498
  height: 100%;
@@ -398,11 +510,13 @@
398
510
  border-color: theme("colors.gray.300");
399
511
  }
400
512
 
513
+ /* Mermaid diagram container */
401
514
  [x-ref="diagramContainer"] .mermaid {
402
515
  overflow: auto;
403
516
  max-height: calc(100vh - 180px);
404
517
  }
405
518
 
519
+ /* Code container scrollbar styling */
406
520
  pre[x-ref="codeContainer"]::-webkit-scrollbar {
407
521
  width: 8px;
408
522
  height: 8px;
@@ -421,3 +535,539 @@ pre[x-ref="codeContainer"]::-webkit-scrollbar-thumb {
421
535
  pre[x-ref="codeContainer"]::-webkit-scrollbar-thumb:hover {
422
536
  background: theme("colors.gray.500");
423
537
  }
538
+
539
+ .tabulator {
540
+ font-family: 'Consolas', 'Monaco', 'Lucida Console', monospace;
541
+ font-size: 12px;
542
+ border: none;
543
+ background: white;
544
+ border-collapse: separate;
545
+ border-spacing: 0;
546
+ margin: 0;
547
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
548
+ }
549
+
550
+ .tabulator .tabulator-header {
551
+ background: #f3f3f3;
552
+ border-bottom: 2px solid #e8e8e8;
553
+ font-size: 11px;
554
+ }
555
+
556
+ .tabulator .tabulator-header .tabulator-col {
557
+ background: #f3f3f3;
558
+ border-right: 1px solid #e8e8e8;
559
+ padding: 4px 8px;
560
+ font-weight: 500;
561
+ text-transform: none;
562
+ height: 32px;
563
+ text-align: left;
564
+ position: sticky;
565
+ top: 0;
566
+ z-index: 10;
567
+ }
568
+
569
+ .tabulator .tabulator-header .tabulator-col.sticky-left-0 {
570
+ position: sticky;
571
+ left: 0;
572
+ z-index: 20;
573
+ background: #f3f3f3;
574
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
575
+ }
576
+
577
+ .tabulator .tabulator-header .tabulator-col.sticky-left-1 {
578
+ position: sticky;
579
+ left: 60px;
580
+ z-index: 19;
581
+ background: #f3f3f3;
582
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
583
+ }
584
+
585
+ .tabulator .tabulator-header .tabulator-col.sticky-left-2 {
586
+ position: sticky;
587
+ left: 108px;
588
+ z-index: 18;
589
+ background: #f3f3f3;
590
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
591
+ }
592
+
593
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row {
594
+ background: white;
595
+ border-bottom: 1px solid #f0f0f0;
596
+ min-height: auto;
597
+ transition: background-color 0.15s ease;
598
+ }
599
+
600
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover {
601
+ background: #f3f4f6;
602
+ }
603
+
604
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert {
605
+ background-color: rgba(16, 185, 129, 0.05);
606
+ }
607
+
608
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert:hover {
609
+ background-color: rgba(16, 185, 129, 0.1);
610
+ }
611
+
612
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update {
613
+ background-color: rgba(108, 173, 223, 0.05);
614
+ }
615
+
616
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update:hover {
617
+ background-color: rgba(108, 173, 223, 0.1);
618
+ }
619
+
620
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete {
621
+ background-color: rgba(239, 68, 68, 0.05);
622
+ }
623
+
624
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete:hover {
625
+ background-color: rgba(239, 68, 68, 0.1);
626
+ }
627
+
628
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell {
629
+ border-right: 1px solid #f0f0f0;
630
+ padding: 2px 8px;
631
+ overflow: hidden;
632
+ text-overflow: ellipsis;
633
+ white-space: nowrap;
634
+ vertical-align: top;
635
+ font-size: 12px;
636
+ height: auto;
637
+ min-height: 28px;
638
+ }
639
+
640
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell:has(.space-y-1) {
641
+ white-space: normal;
642
+ height: auto;
643
+ padding: 4px 8px;
644
+ }
645
+
646
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell.sticky-left-0 {
647
+ position: sticky;
648
+ left: 0;
649
+ background: white;
650
+ z-index: 5;
651
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.05);
652
+ }
653
+
654
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell.sticky-left-1 {
655
+ position: sticky;
656
+ left: 60px;
657
+ background: white;
658
+ z-index: 4;
659
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.05);
660
+ }
661
+
662
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell.sticky-left-2 {
663
+ position: sticky;
664
+ left: 108px;
665
+ background: white;
666
+ z-index: 3;
667
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.05);
668
+ }
669
+
670
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover .tabulator-cell.sticky-left-2 {
671
+ background: #f9fafb;
672
+ }
673
+
674
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert .tabulator-cell.sticky-left-2 {
675
+ background-color: rgba(16, 185, 129, 0.05);
676
+ }
677
+
678
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update .tabulator-cell.sticky-left-2 {
679
+ background-color: rgba(108, 173, 223, 0.05);
680
+ }
681
+
682
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete .tabulator-cell.sticky-left-2 {
683
+ background-color: rgba(239, 68, 68, 0.05);
684
+ }
685
+
686
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert:hover .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert:hover .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-insert:hover .tabulator-cell.sticky-left-2 {
687
+ background-color: rgba(16, 185, 129, 0.1);
688
+ }
689
+
690
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update:hover .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update:hover .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-update:hover .tabulator-cell.sticky-left-2 {
691
+ background-color: rgba(108, 173, 223, 0.1);
692
+ }
693
+
694
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete:hover .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete:hover .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row.operation-delete:hover .tabulator-cell.sticky-left-2 {
695
+ background-color: rgba(239, 68, 68, 0.1);
696
+ }
697
+
698
+ .row-detail {
699
+ border-top: 1px solid #e5e7eb;
700
+ background: #f9fafb;
701
+ padding: 0;
702
+ }
703
+
704
+ .row-detail td {
705
+ padding: 8px;
706
+ vertical-align: top;
707
+ border-right: 1px solid #e5e7eb;
708
+ }
709
+
710
+ .row-detail h4 {
711
+ font-weight: 600;
712
+ color: #374151;
713
+ margin-bottom: 8px;
714
+ }
715
+
716
+ .row-detail .sticky-left-0 {
717
+ position: sticky;
718
+ left: 0;
719
+ z-index: 5;
720
+ background: #f9fafb;
721
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
722
+ width: 268px;
723
+ min-width: 268px;
724
+ }
725
+
726
+ .expand-btn {
727
+ padding: 2px;
728
+ border-radius: 2px;
729
+ transition: all 0.15s ease;
730
+ }
731
+
732
+ .expand-btn:hover {
733
+ background-color: #f3f4f6;
734
+ }
735
+
736
+ .table-container {
737
+ min-height: 200px;
738
+ width: 100%;
739
+ overflow: auto;
740
+ border-bottom-left-radius: 0.25rem;
741
+ border-bottom-right-radius: 0.25rem;
742
+ }
743
+
744
+ .column-selector {
745
+ right: 1rem;
746
+ margin-top: -2px;
747
+ z-index: 100;
748
+ }
749
+
750
+ .timeline-container {
751
+ @apply h-full flex flex-col;
752
+ }
753
+
754
+ .timeline-controls {
755
+ @apply p-3 border-b border-gray-300 bg-gray-50;
756
+ }
757
+
758
+ .timeline-header {
759
+ @apply flex items-center justify-between mb-3;
760
+ }
761
+
762
+ .timeline-title {
763
+ @apply text-sm font-medium text-gray-900;
764
+ }
765
+
766
+ .timeline-zoom-controls {
767
+ @apply flex items-center gap-2;
768
+ }
769
+
770
+ .timeline-filter-controls {
771
+ @apply flex items-center gap-4 text-xs flex-wrap;
772
+ }
773
+
774
+ .timeline-filter-group {
775
+ @apply flex items-center gap-2;
776
+ }
777
+
778
+ .timeline-filter-label {
779
+ @apply text-gray-700 font-medium;
780
+ }
781
+
782
+ .timeline-visualization {
783
+ @apply flex-1 overflow-hidden;
784
+ }
785
+
786
+ .timeline-time-header {
787
+ @apply h-8 bg-gray-100 border-b border-gray-200 relative;
788
+ }
789
+
790
+ .timeline-time-scale {
791
+ @apply absolute inset-0 flex items-center px-4;
792
+ }
793
+
794
+ .timeline-content {
795
+ @apply flex-1 overflow-auto p-4 bg-white;
796
+ }
797
+
798
+ .timeline-track {
799
+ @apply relative h-16 bg-gray-50 rounded border border-gray-200 mb-4;
800
+ }
801
+
802
+ .timeline-line {
803
+ @apply absolute top-1/2 left-4 right-4 h-0.5 bg-gray-300 transform -translate-y-1/2;
804
+ }
805
+
806
+ .timeline-marker {
807
+ @apply absolute top-1/2 transform -translate-y-1/2 -translate-x-1/2 cursor-pointer;
808
+ }
809
+
810
+ .timeline-marker .timeline-marker-dot {
811
+ @apply w-3 h-3 rounded-full border-2 border-white shadow-sm transition-transform;
812
+ }
813
+
814
+ .timeline-marker .timeline-marker-dot:hover {
815
+ @apply scale-125;
816
+ }
817
+
818
+ .timeline-stats {
819
+ @apply grid grid-cols-2 gap-4 text-xs;
820
+ }
821
+
822
+ @screen md {
823
+ .timeline-stats {
824
+ @apply grid-cols-4;
825
+ }
826
+ }
827
+
828
+ .timeline-stat-card {
829
+ @apply bg-gray-50 p-3 rounded;
830
+ }
831
+
832
+ .timeline-stat-label {
833
+ @apply text-gray-500 font-medium;
834
+ }
835
+
836
+ .timeline-stat-value {
837
+ @apply text-lg font-bold text-gray-900;
838
+ }
839
+
840
+ .timeline-stat-detail {
841
+ @apply text-xs text-gray-500;
842
+ }
843
+
844
+ .timeline-operations {
845
+ @apply mt-6;
846
+ }
847
+
848
+ .timeline-operations-title {
849
+ @apply text-sm font-medium text-gray-900 mb-3;
850
+ }
851
+
852
+ .timeline-operations-list {
853
+ @apply space-y-2 max-h-64 overflow-auto;
854
+ }
855
+
856
+ .timeline-operation-item {
857
+ @apply flex items-center justify-between p-2 bg-gray-50 rounded hover:bg-gray-100 cursor-pointer text-xs;
858
+ }
859
+
860
+ .timeline-operation-info {
861
+ @apply flex items-center gap-3;
862
+ }
863
+
864
+ .timeline-operation-marker {
865
+ @apply w-2 h-2 rounded-full;
866
+ }
867
+
868
+ .timeline-operation-type {
869
+ @apply font-medium;
870
+ }
871
+
872
+ .timeline-operation-time {
873
+ @apply text-gray-500;
874
+ }
875
+
876
+ .timeline-operation-record {
877
+ @apply text-gray-500;
878
+ }
879
+
880
+ .timeline-empty {
881
+ @apply text-center py-8 text-gray-500;
882
+ }
883
+
884
+ .timeline-empty-icon {
885
+ @apply w-12 h-12 mx-auto mb-4 text-gray-300;
886
+ }
887
+
888
+ .timeline-empty-action {
889
+ @apply mt-2 text-blue-600 underline;
890
+ }
891
+
892
+ .timeline-loading {
893
+ @apply flex items-center justify-center h-64;
894
+ }
895
+
896
+ .timeline-loading-spinner {
897
+ @apply animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500;
898
+ }
899
+
900
+ .timeline-loading-text {
901
+ @apply ml-2 text-gray-600;
902
+ }
903
+
904
+ .timeline-error {
905
+ @apply p-4 bg-red-50 border border-red-200 rounded m-4;
906
+ }
907
+
908
+ .timeline-error-text {
909
+ @apply text-red-700;
910
+ }
911
+
912
+ .timeline-error-retry {
913
+ @apply mt-2 text-red-600 underline;
914
+ }
915
+
916
+ .timeline-modal-overlay {
917
+ @apply fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50;
918
+ }
919
+
920
+ .timeline-modal-content {
921
+ @apply bg-white rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-96 overflow-auto;
922
+ }
923
+
924
+ .timeline-modal-header {
925
+ @apply p-4 border-b border-gray-200 flex justify-between items-center;
926
+ }
927
+
928
+ .timeline-modal-title {
929
+ @apply text-lg font-medium;
930
+ }
931
+
932
+ .timeline-modal-close {
933
+ @apply text-gray-400 hover:text-gray-600;
934
+ }
935
+
936
+ .timeline-modal-body {
937
+ @apply p-4;
938
+ }
939
+
940
+ .timeline-operation-details {
941
+ @apply grid grid-cols-1 gap-4 text-sm;
942
+ }
943
+
944
+ @screen md {
945
+ .timeline-operation-details {
946
+ @apply grid-cols-2;
947
+ }
948
+ }
949
+
950
+ .timeline-operation-detail-label {
951
+ @apply font-medium;
952
+ }
953
+
954
+ .timeline-operation-detail-value {
955
+ @apply ml-2;
956
+ }
957
+
958
+ .timeline-operation-detail-value.operation-badge {
959
+ @apply px-2 py-1 rounded text-xs;
960
+ }
961
+
962
+ .timeline-operation-detail-value.monospace {
963
+ @apply font-mono;
964
+ }
965
+
966
+ .timeline-operation-detail-value.small {
967
+ @apply text-xs;
968
+ }
969
+
970
+ .timeline-changes-section {
971
+ @apply mt-4;
972
+ }
973
+
974
+ .timeline-changes-title {
975
+ @apply text-sm font-medium;
976
+ }
977
+
978
+ .timeline-changes-content {
979
+ @apply mt-2 p-3 bg-gray-50 rounded text-xs overflow-auto border max-h-32;
980
+ }
981
+
982
+ .timeline-metadata-section {
983
+ @apply mt-4;
984
+ }
985
+
986
+ .timeline-metadata-title {
987
+ @apply text-sm font-medium;
988
+ }
989
+
990
+ .timeline-metadata-grid {
991
+ @apply mt-2 grid grid-cols-2 gap-2 text-xs;
992
+ }
993
+
994
+ .timeline-metadata-key {
995
+ @apply font-medium capitalize;
996
+ }
997
+
998
+ @screen sm {
999
+ .timeline-filter-controls {
1000
+ @apply flex-nowrap;
1001
+ }
1002
+ .timeline-stats {
1003
+ @apply grid-cols-4;
1004
+ }
1005
+ }
1006
+
1007
+ .operation-insert {
1008
+ @apply text-green-600 bg-green-100;
1009
+ }
1010
+
1011
+ .operation-update {
1012
+ @apply text-blue-600 bg-blue-100;
1013
+ }
1014
+
1015
+ .operation-delete {
1016
+ @apply text-red-600 bg-red-100;
1017
+ }
1018
+
1019
+ .operation-select {
1020
+ @apply text-purple-600 bg-purple-100;
1021
+ }
1022
+
1023
+ .timeline-transition-enter {
1024
+ @apply transition ease-out duration-300;
1025
+ }
1026
+
1027
+ .timeline-transition-enter-start {
1028
+ @apply opacity-0;
1029
+ }
1030
+
1031
+ .timeline-transition-enter-end {
1032
+ @apply opacity-100;
1033
+ }
1034
+
1035
+ .timeline-transition-leave {
1036
+ @apply transition ease-in duration-200;
1037
+ }
1038
+
1039
+ .timeline-transition-leave-start {
1040
+ @apply opacity-100;
1041
+ }
1042
+
1043
+ .timeline-transition-leave-end {
1044
+ @apply opacity-0;
1045
+ }
1046
+
1047
+ /**
1048
+ * Tabulator Vendor Overrides
1049
+ * Overrides for the Tabulator.js vendor CSS
1050
+ */
1051
+ .tabulator {
1052
+ font-family: 'Consolas', 'Monaco', 'Lucida Console', monospace !important;
1053
+ }
1054
+
1055
+ .tabulator .tabulator-header {
1056
+ background: #f3f3f3 !important;
1057
+ }
1058
+
1059
+ .tabulator .tabulator-header .tabulator-col {
1060
+ background: #f3f3f3 !important;
1061
+ }
1062
+
1063
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row {
1064
+ background: white !important;
1065
+ }
1066
+
1067
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover {
1068
+ background: #f3f4f6 !important;
1069
+ }
1070
+
1071
+ .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover .tabulator-cell.sticky-left-0, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover .tabulator-cell.sticky-left-1, .tabulator .tabulator-tableholder .tabulator-table .tabulator-row:hover .tabulator-cell.sticky-left-2 {
1072
+ background: #f9fafb !important;
1073
+ }