dbviewer 0.6.6 → 0.6.8

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -36
  3. data/app/assets/javascripts/dbviewer/entity_relationship_diagram.js +553 -0
  4. data/app/assets/javascripts/dbviewer/home.js +287 -0
  5. data/app/assets/javascripts/dbviewer/layout.js +194 -0
  6. data/app/assets/javascripts/dbviewer/query.js +277 -0
  7. data/app/assets/javascripts/dbviewer/table.js +1563 -0
  8. data/app/assets/stylesheets/dbviewer/application.css +1460 -21
  9. data/app/assets/stylesheets/dbviewer/entity_relationship_diagram.css +181 -0
  10. data/app/assets/stylesheets/dbviewer/home.css +229 -0
  11. data/app/assets/stylesheets/dbviewer/logs.css +64 -0
  12. data/app/assets/stylesheets/dbviewer/query.css +171 -0
  13. data/app/assets/stylesheets/dbviewer/table.css +1144 -0
  14. data/app/views/dbviewer/connections/index.html.erb +0 -30
  15. data/app/views/dbviewer/entity_relationship_diagrams/index.html.erb +14 -713
  16. data/app/views/dbviewer/home/index.html.erb +9 -499
  17. data/app/views/dbviewer/logs/index.html.erb +22 -221
  18. data/app/views/dbviewer/tables/index.html.erb +0 -65
  19. data/app/views/dbviewer/tables/query.html.erb +129 -565
  20. data/app/views/dbviewer/tables/show.html.erb +4 -2429
  21. data/app/views/layouts/dbviewer/application.html.erb +13 -1544
  22. data/lib/dbviewer/version.rb +1 -1
  23. metadata +12 -7
  24. data/app/assets/javascripts/dbviewer/connections.js +0 -70
  25. data/app/assets/stylesheets/dbviewer/dbviewer.css +0 -0
  26. data/app/assets/stylesheets/dbviewer/enhanced.css +0 -0
  27. data/app/views/dbviewer/connections/new.html.erb +0 -79
  28. data/app/views/dbviewer/tables/mini_erd.html.erb +0 -517
@@ -0,0 +1,1144 @@
1
+ /* Column sorting styles */
2
+ .sortable-column {
3
+ cursor: pointer;
4
+ position: relative;
5
+ transition: background-color 0.2s ease;
6
+ background-color: inherit;
7
+ }
8
+
9
+ .sortable-column:hover {
10
+ background-color: #f5f5f5;
11
+ }
12
+
13
+ .sortable-column.sorted {
14
+ background-color: #f0f0f0;
15
+ }
16
+
17
+ .sortable-column .column-sort-link {
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: space-between;
21
+ width: 100%;
22
+ height: 100%;
23
+ padding: 4px 0;
24
+ }
25
+
26
+ .sortable-column .column-name {
27
+ flex: 1;
28
+ overflow: hidden;
29
+ text-overflow: ellipsis;
30
+ white-space: nowrap;
31
+ }
32
+
33
+ .sortable-column .sort-icon-container {
34
+ flex: 0 0 auto;
35
+ width: 20px;
36
+ text-align: center;
37
+ margin-left: 4px;
38
+ }
39
+
40
+ .sortable-column .sort-icon {
41
+ font-size: 0.8em;
42
+ opacity: 0.7;
43
+ transition: opacity 0.2s ease, color 0.2s ease;
44
+ }
45
+
46
+ .sortable-column:hover .sort-icon.invisible {
47
+ visibility: visible !important;
48
+ opacity: 0.3;
49
+ }
50
+
51
+ /* Fix scrolling issues with sticky header */
52
+ .dbviewer-table-header {
53
+ position: sticky !important;
54
+ top: 0;
55
+ z-index: 10;
56
+ background-color: var(--bs-table-striped-bg, #f2f2f2) !important;
57
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
58
+ }
59
+
60
+ [data-bs-theme="dark"] .dbviewer-table-header {
61
+ background-color: var(--bs-dark-bg-subtle, #343a40) !important;
62
+ }
63
+
64
+ /* Ensure proper layering for sticky elements */
65
+ .dbviewer-table-header th {
66
+ position: sticky;
67
+ top: 0;
68
+ z-index: 20;
69
+ }
70
+
71
+ /* Increase z-index for the intersection point of sticky header and sticky column */
72
+ .dbviewer-table-header th.action-column {
73
+ z-index: 40 !important;
74
+ box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
75
+ }
76
+
77
+ /* Ensure thead has higher z-index than tbody */
78
+ thead tr th.action-column {
79
+ z-index: 40 !important;
80
+ }
81
+
82
+ tbody tr td.action-column {
83
+ z-index: 30 !important;
84
+ }
85
+
86
+ /* Improve mobile display for sort headers */
87
+ @media (max-width: 767.98px) {
88
+ .sortable-column .column-sort-link {
89
+ flex-direction: row;
90
+ align-items: center;
91
+ }
92
+
93
+ .sortable-column .sort-icon-container {
94
+ width: 16px;
95
+ }
96
+ }
97
+
98
+ /* Dark mode compatibility */
99
+ [data-bs-theme="dark"] .sortable-column:hover {
100
+ background-color: rgba(255, 255, 255, 0.05);
101
+ }
102
+
103
+ [data-bs-theme="dark"] .sortable-column.sorted {
104
+ background-color: rgba(255, 255, 255, 0.1);
105
+ }
106
+
107
+ /* Column filter styling */
108
+ .column-filters td {
109
+ padding: 0.5rem;
110
+ background-color: var(--bs-tertiary-bg, #f8f9fa);
111
+ }
112
+
113
+ /* Styling for disabled input fields (IS NULL, IS NOT NULL) */
114
+ .column-filter:disabled,
115
+ .disabled-filter {
116
+ background-color: var(--bs-tertiary-bg, #f0f0f0);
117
+ border-color: var(--bs-border-color, #dee2e6);
118
+ color: var(--bs-secondary-color, #6c757d);
119
+ opacity: 0.6;
120
+ cursor: not-allowed;
121
+ }
122
+
123
+ /* Action column styling */
124
+ .action-column {
125
+ width: 100px; /* Increased from 60px to accommodate two buttons */
126
+ min-width: 100px; /* Ensure minimum width */
127
+ white-space: nowrap;
128
+ position: sticky;
129
+ left: 0;
130
+ z-index: 15;
131
+ background-color: var(--bs-table-striped-bg, #f2f2f2);
132
+ box-shadow: 2px 0 4px rgba(0, 0, 0, 0.05);
133
+ }
134
+
135
+ .copy-factory-btn {
136
+ padding: 0.1rem 0.4rem;
137
+ width: 32px;
138
+ }
139
+
140
+ .copy-factory-btn:hover {
141
+ opacity: 0.85;
142
+ transform: translateY(-1px);
143
+ }
144
+
145
+ /* Ensure proper background color for actions column in dark mode */
146
+ [data-bs-theme="dark"] .action-column {
147
+ background-color: var(--bs-dark-bg-subtle, #343a40);
148
+ }
149
+
150
+ /* Maintain zebra striping with sticky action column */
151
+ .table-striped > tbody > tr:nth-of-type(odd) > .action-column {
152
+ background-color: var(--bs-table-striped-bg, #f8f9fa);
153
+ }
154
+
155
+ [data-bs-theme="dark"]
156
+ .table-striped
157
+ > tbody
158
+ > tr:nth-of-type(odd)
159
+ > .action-column {
160
+ background-color: var(--bs-dark-bg-subtle, #343a40);
161
+ }
162
+
163
+ .view-record-btn {
164
+ padding: 0.1rem 0.4rem;
165
+ width: 32px;
166
+ }
167
+
168
+ .view-record-btn:hover {
169
+ opacity: 0.85;
170
+ transform: translateY(-1px);
171
+ }
172
+
173
+ /* Make action column header sticky as well */
174
+ .action-column-header {
175
+ position: sticky;
176
+ left: 0;
177
+ z-index: 40 !important; /* Even higher z-index to stay on top of everything */
178
+ background-color: var(--bs-tertiary-bg, #f8f9fa) !important;
179
+ box-shadow: 2px 0 6px rgba(0, 0, 0, 0.04) !important;
180
+ }
181
+
182
+ [data-bs-theme="dark"] .action-column-header {
183
+ background-color: var(--bs-dark-bg-subtle, #343a40) !important;
184
+ }
185
+
186
+ [data-bs-theme="dark"] .action-column-header {
187
+ background-color: var(--bs-dark-bg-subtle, #343a40) !important;
188
+ }
189
+
190
+ /* Make action column filter cell sticky as well */
191
+ .action-column-filter {
192
+ position: sticky;
193
+ left: 0;
194
+ z-index: 40 !important;
195
+ background-color: var(--bs-tertiary-bg, #f8f9fa) !important;
196
+ }
197
+
198
+ [data-bs-theme="dark"] .action-column-filter {
199
+ background-color: var(--bs-tertiary-bg, #2b3035) !important;
200
+ }
201
+
202
+ /* Fix action column for entire table */
203
+ .action-column {
204
+ box-shadow: 2px 0 6px rgba(0, 0, 0, 0.04);
205
+ }
206
+
207
+ /* Ensure equal padding for all cells */
208
+ .action-column-header,
209
+ .action-column-filter {
210
+ padding-left: 8px !important;
211
+ padding-right: 8px !important;
212
+ }
213
+
214
+ /* Relationship section styles */
215
+ #relationshipsSection {
216
+ border-top: 1px solid var(--bs-border-color, #dee2e6);
217
+ margin-top: 1.5rem;
218
+ padding-top: 1.5rem;
219
+ }
220
+
221
+ #relationshipsSection h6 {
222
+ color: var(--bs-primary, #0d6efd);
223
+ font-weight: 600;
224
+ border-bottom: 2px solid var(--bs-primary, #0d6efd);
225
+ padding-bottom: 0.5rem;
226
+ margin-bottom: 1rem;
227
+ }
228
+
229
+ .relationship-section h6 {
230
+ font-size: 0.95rem;
231
+ margin-bottom: 0.75rem;
232
+ padding: 0.5rem 0.75rem;
233
+ background: linear-gradient(
234
+ 135deg,
235
+ var(--bs-primary-bg-subtle, #cfe2ff),
236
+ transparent
237
+ );
238
+ border-left: 3px solid var(--bs-primary, #0d6efd);
239
+ border-radius: 0.25rem;
240
+ }
241
+
242
+ .relationship-section .table {
243
+ margin-bottom: 0;
244
+ border: 1px solid var(--bs-border-color, #dee2e6);
245
+ }
246
+
247
+ .relationship-section .table th {
248
+ background-color: var(--bs-light, #f8f9fa);
249
+ font-weight: 600;
250
+ font-size: 0.875rem;
251
+ border-bottom: 2px solid var(--bs-border-color, #dee2e6);
252
+ }
253
+
254
+ .relationship-section .table td {
255
+ vertical-align: middle;
256
+ font-size: 0.875rem;
257
+ }
258
+
259
+ .relationship-section .btn {
260
+ font-size: 0.8rem;
261
+ padding: 0.375rem 0.75rem;
262
+ }
263
+
264
+ .relationship-section .btn-outline-primary:hover {
265
+ transform: translateX(2px);
266
+ transition: transform 0.2s ease;
267
+ }
268
+
269
+ .relationship-section .btn-outline-success:hover {
270
+ transform: translateX(2px);
271
+ transition: transform 0.2s ease;
272
+ }
273
+
274
+ /* Dark mode relationship styles */
275
+ [data-bs-theme="dark"] #relationshipsSection {
276
+ border-top-color: var(--bs-border-color, #495057);
277
+ }
278
+
279
+ [data-bs-theme="dark"] .relationship-section h6 {
280
+ background: linear-gradient(
281
+ 135deg,
282
+ var(--bs-primary-bg-subtle, #031633),
283
+ transparent
284
+ );
285
+ }
286
+
287
+ [data-bs-theme="dark"] .relationship-section .table th {
288
+ background-color: var(--bs-dark-bg-subtle, #343a40);
289
+ color: var(--bs-light, #f8f9fa);
290
+ }
291
+
292
+ [data-bs-theme="dark"] .relationship-section .table {
293
+ border-color: var(--bs-border-color, #495057);
294
+ }
295
+
296
+ /* Responsive relationship tables */
297
+ @media (max-width: 767.98px) {
298
+ .relationship-section .table th,
299
+ .relationship-section .table td {
300
+ font-size: 0.8rem;
301
+ padding: 0.5rem 0.25rem;
302
+ }
303
+
304
+ .relationship-section .btn {
305
+ font-size: 0.75rem;
306
+ padding: 0.25rem 0.5rem;
307
+ }
308
+ }
309
+
310
+ /* Borderless table styling */
311
+ .table {
312
+ border-collapse: separate;
313
+ border-spacing: 0;
314
+ }
315
+
316
+ .table th,
317
+ .table td {
318
+ border: none;
319
+ border-bottom: 1px solid var(--bs-border-subtle, rgba(0, 0, 0, 0.05));
320
+ }
321
+
322
+ .table thead th {
323
+ border-bottom: 2px solid var(--bs-border-subtle, rgba(0, 0, 0, 0.08));
324
+ font-weight: 500;
325
+ }
326
+
327
+ /* Add a subtle hover effect on table rows */
328
+ .table tbody tr:hover {
329
+ background-color: var(--bs-tertiary-bg, rgba(0, 0, 0, 0.02));
330
+ }
331
+
332
+ /* Dark mode compatibility */
333
+ [data-bs-theme="dark"] .table th,
334
+ [data-bs-theme="dark"] .table td {
335
+ border-bottom: 1px solid var(--bs-border-subtle, rgba(255, 255, 255, 0.05));
336
+ }
337
+
338
+ [data-bs-theme="dark"] .table thead th {
339
+ border-bottom: 2px solid var(--bs-border-subtle, rgba(255, 255, 255, 0.08));
340
+ }
341
+
342
+ [data-bs-theme="dark"] .table tbody tr:hover {
343
+ background-color: var(--bs-tertiary-bg, rgba(255, 255, 255, 0.03));
344
+ }
345
+
346
+ /* Column filter styling */
347
+ .column-filters td {
348
+ padding: 0.5rem;
349
+ background-color: var(--bs-tertiary-bg, #f8f9fa);
350
+ }
351
+
352
+ /* Action column styling */
353
+ .action-column {
354
+ width: 100px; /* Increased from 60px to accommodate two buttons */
355
+ min-width: 100px; /* Ensure minimum width */
356
+ white-space: nowrap;
357
+ position: sticky;
358
+ left: 0;
359
+ z-index: 30; /* Increased z-index to ensure it stays on top */
360
+ background-color: var(--bs-body-bg, #fff); /* Use body background color */
361
+ box-shadow: 2px 0 6px rgba(0, 0, 0, 0.04);
362
+ }
363
+
364
+ .copy-factory-btn {
365
+ padding: 0.1rem 0.4rem;
366
+ width: 32px;
367
+ }
368
+
369
+ .copy-factory-btn:hover {
370
+ opacity: 0.85;
371
+ transform: translateY(-1px);
372
+ }
373
+
374
+ /* Ensure proper background color for actions column in dark mode */
375
+ [data-bs-theme="dark"] .action-column {
376
+ background-color: var(
377
+ --bs-body-bg,
378
+ #212529
379
+ ); /* Use body background in dark mode */
380
+ }
381
+
382
+ /* Maintain zebra striping with sticky action column */
383
+ .table-striped > tbody > tr:nth-of-type(odd) > .action-column {
384
+ background-color: var(--bs-tertiary-bg, #f8f9fa);
385
+ }
386
+
387
+ .table-striped > tbody > tr:nth-of-type(even) > .action-column {
388
+ background-color: var(--bs-body-bg, #fff);
389
+ }
390
+
391
+ [data-bs-theme="dark"]
392
+ .table-striped
393
+ > tbody
394
+ > tr:nth-of-type(odd)
395
+ > .action-column {
396
+ background-color: var(--bs-tertiary-bg, #2b3035);
397
+ }
398
+
399
+ [data-bs-theme="dark"]
400
+ .table-striped
401
+ > tbody
402
+ > tr:nth-of-type(even)
403
+ > .action-column {
404
+ background-color: var(--bs-body-bg, #212529);
405
+ }
406
+
407
+ .view-record-btn {
408
+ padding: 0.1rem 0.4rem;
409
+ width: 32px;
410
+ }
411
+
412
+ .view-record-btn:hover {
413
+ opacity: 0.85;
414
+ transform: translateY(-1px);
415
+ }
416
+
417
+ /* Record detail modal styling */
418
+ .record-detail-table tr:first-child th,
419
+ .record-detail-table tr:first-child td {
420
+ border-top: none;
421
+ }
422
+
423
+ .record-detail-table .code-block {
424
+ background-color: var(--bs-light);
425
+ padding: 0.5rem;
426
+ border-radius: 0.25rem;
427
+ overflow-x: auto;
428
+ max-height: 200px;
429
+ }
430
+
431
+ /* Relationships section styling */
432
+ #relationshipsSection {
433
+ border-top: 1px solid var(--bs-border-color);
434
+ padding-top: 1rem;
435
+ }
436
+
437
+ #relationshipsSection h6 {
438
+ color: var(--bs-emphasis-color);
439
+ margin-bottom: 1rem;
440
+ }
441
+
442
+ [data-bs-theme="dark"] #relationshipsSection {
443
+ border-top-color: #495057;
444
+ }
445
+
446
+ .relationships-table .btn-outline-primary {
447
+ font-size: 0.75rem;
448
+ padding: 0.25rem 0.5rem;
449
+ }
450
+
451
+ .relationships-table code {
452
+ background-color: var(--bs-gray-100);
453
+ padding: 0.125rem 0.25rem;
454
+ border-radius: 0.125rem;
455
+ font-size: 0.875rem;
456
+ }
457
+
458
+ [data-bs-theme="dark"] .relationships-table code {
459
+ background-color: var(--bs-gray-800);
460
+ color: var(--bs-gray-100);
461
+ }
462
+
463
+ [data-bs-theme="dark"] .record-detail-table .code-block {
464
+ background-color: var(--bs-dark);
465
+ }
466
+
467
+ /* Fullscreen table styles */
468
+ .table-fullscreen {
469
+ position: fixed !important;
470
+ top: 0 !important;
471
+ left: 0 !important;
472
+ width: 100vw !important;
473
+ height: 100vh !important;
474
+ z-index: 9999 !important;
475
+ background: var(--bs-body-bg) !important;
476
+ margin: 0 !important;
477
+ border-radius: 0 !important;
478
+ overflow: hidden !important;
479
+ display: flex !important;
480
+ flex-direction: column !important;
481
+ }
482
+
483
+ .table-fullscreen .card-body {
484
+ flex: 1 !important;
485
+ overflow: hidden !important;
486
+ display: flex !important;
487
+ flex-direction: column !important;
488
+ }
489
+
490
+ .table-fullscreen .table-responsive {
491
+ flex: 1 !important;
492
+ overflow: auto !important;
493
+ }
494
+
495
+ .table-fullscreen .card-header {
496
+ flex-shrink: 0 !important;
497
+ position: sticky !important;
498
+ top: 0 !important;
499
+ z-index: 10000 !important;
500
+ background: var(--bs-body-bg) !important;
501
+ border-bottom: 1px solid var(--bs-border-color) !important;
502
+ }
503
+
504
+ /* Hide pagination in fullscreen mode */
505
+ .table-fullscreen .pagination-container {
506
+ display: none !important;
507
+ }
508
+
509
+ /* Adjust table header in fullscreen */
510
+ .table-fullscreen .dbviewer-table-header {
511
+ position: sticky !important;
512
+ top: 0 !important;
513
+ z-index: 100 !important;
514
+ }
515
+
516
+ /* Ensure body doesn't scroll when table is fullscreen */
517
+ body.table-fullscreen-active {
518
+ overflow: hidden !important;
519
+ }
520
+
521
+ /* Fullscreen button hover effect */
522
+ #fullscreen-toggle:hover {
523
+ background-color: var(--bs-secondary-bg) !important;
524
+ border-color: var(--bs-secondary-border-subtle) !important;
525
+ }
526
+
527
+ /* Smooth transitions */
528
+ #table-section {
529
+ transition: all 0.3s ease-in-out;
530
+ }
531
+
532
+ /* Floating creation filter button */
533
+ .floating-creation-filter {
534
+ position: fixed;
535
+ bottom: 30px;
536
+ right: 30px;
537
+ z-index: 1050;
538
+ }
539
+
540
+ .floating-filter-btn {
541
+ width: 60px;
542
+ height: 60px;
543
+ border-radius: 50%;
544
+ display: flex;
545
+ align-items: center;
546
+ justify-content: center;
547
+ font-size: 1.2rem;
548
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
549
+ border: none;
550
+ position: relative;
551
+ background: var(--bs-primary);
552
+ color: white;
553
+ box-shadow: 0 4px 12px rgba(var(--bs-primary-rgb), 0.4);
554
+ }
555
+
556
+ .floating-filter-btn:hover {
557
+ transform: translateY(-3px) scale(1.05);
558
+ box-shadow: 0 8px 25px rgba(var(--bs-primary-rgb), 0.5) !important;
559
+ background: var(--bs-primary) !important;
560
+ color: white !important;
561
+ }
562
+
563
+ .floating-filter-btn:active {
564
+ transform: translateY(-1px) scale(1.02);
565
+ transition: all 0.1s ease;
566
+ }
567
+
568
+ .floating-filter-btn:focus {
569
+ outline: 2px solid rgba(var(--bs-primary-rgb), 0.5);
570
+ outline-offset: 2px;
571
+ }
572
+
573
+ /* Badge for active filter indicator */
574
+ .floating-filter-btn .badge {
575
+ font-size: 0.6rem;
576
+ width: 18px;
577
+ height: 18px;
578
+ display: flex;
579
+ align-items: center;
580
+ justify-content: center;
581
+ background: var(--bs-success) !important;
582
+ animation: pulse 2s infinite;
583
+ }
584
+
585
+ @keyframes pulse {
586
+ 0% {
587
+ transform: scale(1);
588
+ }
589
+ 50% {
590
+ transform: scale(1.1);
591
+ }
592
+ 100% {
593
+ transform: scale(1);
594
+ }
595
+ }
596
+
597
+ /* Better datetime input styling for the floating filter */
598
+ #creationFilterOffcanvas .form-control {
599
+ border-radius: 6px;
600
+ border: 1px solid var(--bs-border-color);
601
+ background-color: var(--bs-body-bg);
602
+ color: var(--bs-body-color);
603
+ transition: all 0.15s ease-in-out;
604
+ }
605
+
606
+ #creationFilterOffcanvas .form-control:focus {
607
+ border-color: var(--bs-primary);
608
+ box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
609
+ background-color: var(--bs-body-bg);
610
+ }
611
+
612
+ /* Offcanvas enhancements */
613
+ #creationFilterOffcanvas {
614
+ backdrop-filter: blur(10px);
615
+ }
616
+
617
+ #creationFilterOffcanvas .offcanvas-header {
618
+ background: var(--bs-body-bg);
619
+ border-bottom: 1px solid var(--bs-border-color);
620
+ padding: 1.25rem;
621
+ }
622
+
623
+ #creationFilterOffcanvas .offcanvas-body {
624
+ background: var(--bs-body-bg);
625
+ padding: 1.25rem;
626
+ }
627
+
628
+ #creationFilterOffcanvas .offcanvas-title {
629
+ color: var(--bs-body-color);
630
+ font-weight: 600;
631
+ }
632
+
633
+ /* Dark mode specific enhancements */
634
+ [data-bs-theme="dark"] .floating-filter-btn {
635
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3),
636
+ 0 0 0 1px rgba(var(--bs-primary-rgb), 0.2);
637
+ }
638
+
639
+ [data-bs-theme="dark"] .floating-filter-btn:hover {
640
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4),
641
+ 0 0 0 1px rgba(var(--bs-primary-rgb), 0.3) !important;
642
+ }
643
+
644
+ [data-bs-theme="dark"] #creationFilterOffcanvas .offcanvas-header {
645
+ background: var(--bs-dark);
646
+ border-bottom-color: var(--bs-border-color-translucent);
647
+ }
648
+
649
+ [data-bs-theme="dark"] #creationFilterOffcanvas .offcanvas-body {
650
+ background: var(--bs-dark);
651
+ }
652
+
653
+ [data-bs-theme="dark"] #creationFilterOffcanvas .form-control {
654
+ background-color: var(--bs-body-bg);
655
+ border-color: var(--bs-border-color-translucent);
656
+ }
657
+
658
+ [data-bs-theme="dark"] #creationFilterOffcanvas .form-control:focus {
659
+ background-color: var(--bs-body-bg);
660
+ border-color: var(--bs-primary);
661
+ }
662
+
663
+ /* Date range picker styling */
664
+ #floatingCreationFilterRange {
665
+ cursor: pointer;
666
+ background-color: var(--bs-body-bg);
667
+ color: var(--bs-body-color);
668
+ border: 1px solid var(--bs-border-color);
669
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out,
670
+ background-color 0.15s ease-in-out;
671
+ }
672
+
673
+ #floatingCreationFilterRange:focus {
674
+ border-color: var(--bs-primary);
675
+ box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
676
+ background-color: var(--bs-body-bg);
677
+ }
678
+
679
+ #floatingCreationFilterRange::placeholder {
680
+ color: var(--bs-secondary-color);
681
+ opacity: 0.7;
682
+ }
683
+
684
+ /* Enhanced dark mode support for input */
685
+ [data-bs-theme="dark"] #floatingCreationFilterRange {
686
+ background-color: var(--bs-body-bg);
687
+ border-color: var(--bs-border-color-translucent);
688
+ color: var(--bs-body-color);
689
+ }
690
+
691
+ [data-bs-theme="dark"] #floatingCreationFilterRange:focus {
692
+ background-color: var(--bs-body-bg);
693
+ border-color: var(--bs-primary);
694
+ box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
695
+ }
696
+
697
+ /* Preset buttons styling */
698
+ .preset-btn {
699
+ font-size: 0.8rem;
700
+ padding: 0.35rem 0.75rem;
701
+ text-align: left;
702
+ justify-content: flex-start;
703
+ border: 1px solid var(--bs-border-color);
704
+ background-color: var(--bs-body-bg);
705
+ color: var(--bs-body-color);
706
+ transition: all 0.2s ease;
707
+ position: relative;
708
+ overflow: hidden;
709
+ }
710
+
711
+ .preset-btn::before {
712
+ content: "";
713
+ position: absolute;
714
+ top: 0;
715
+ left: -100%;
716
+ width: 100%;
717
+ height: 100%;
718
+ background: linear-gradient(
719
+ 90deg,
720
+ transparent,
721
+ rgba(var(--bs-primary-rgb), 0.1),
722
+ transparent
723
+ );
724
+ transition: left 0.3s ease;
725
+ }
726
+
727
+ .preset-btn:hover {
728
+ background-color: var(--bs-primary);
729
+ color: white;
730
+ border-color: var(--bs-primary);
731
+ transform: translateY(-1px);
732
+ box-shadow: 0 2px 4px rgba(var(--bs-primary-rgb), 0.2);
733
+ }
734
+
735
+ .preset-btn:hover::before {
736
+ left: 100%;
737
+ }
738
+
739
+ .preset-btn:active {
740
+ transform: translateY(0);
741
+ box-shadow: 0 1px 2px rgba(var(--bs-primary-rgb), 0.2);
742
+ }
743
+
744
+ .preset-btn i {
745
+ opacity: 0.8;
746
+ transition: opacity 0.2s ease;
747
+ }
748
+
749
+ .preset-btn:hover i {
750
+ opacity: 1;
751
+ }
752
+
753
+ /* Dark mode enhancements for preset buttons */
754
+ [data-bs-theme="dark"] .preset-btn {
755
+ background-color: var(--bs-dark);
756
+ border-color: var(--bs-border-color-translucent);
757
+ color: var(--bs-body-color);
758
+ }
759
+
760
+ [data-bs-theme="dark"] .preset-btn:hover {
761
+ background-color: var(--bs-primary);
762
+ color: white;
763
+ border-color: var(--bs-primary);
764
+ box-shadow: 0 2px 8px rgba(var(--bs-primary-rgb), 0.3);
765
+ }
766
+
767
+ /* Flatpickr theme adjustments */
768
+ .flatpickr-calendar {
769
+ border-radius: 8px;
770
+ box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.2);
771
+ border: 1px solid var(--bs-border-color);
772
+ background: var(--bs-body-bg);
773
+ font-family: var(--bs-body-font-family);
774
+ }
775
+
776
+ .flatpickr-months {
777
+ background: var(--bs-body-bg);
778
+ border-bottom: 1px solid var(--bs-border-color);
779
+ border-radius: 8px 8px 0 0;
780
+ }
781
+
782
+ .flatpickr-month {
783
+ color: var(--bs-body-color);
784
+ fill: var(--bs-body-color);
785
+ }
786
+
787
+ .flatpickr-current-month {
788
+ color: var(--bs-body-color);
789
+ }
790
+
791
+ .flatpickr-current-month .flatpickr-monthDropdown-month {
792
+ background: var(--bs-body-bg);
793
+ color: var(--bs-body-color);
794
+ }
795
+
796
+ .flatpickr-weekdays {
797
+ background: var(--bs-body-bg);
798
+ }
799
+
800
+ .flatpickr-weekday {
801
+ color: var(--bs-secondary-color);
802
+ font-weight: 600;
803
+ font-size: 0.75rem;
804
+ }
805
+
806
+ .flatpickr-day {
807
+ color: var(--bs-body-color);
808
+ border-radius: 4px;
809
+ transition: all 0.2s ease;
810
+ }
811
+
812
+ .flatpickr-day:hover {
813
+ background: var(--bs-primary-bg-subtle);
814
+ color: var(--bs-primary);
815
+ border-color: var(--bs-primary-border-subtle);
816
+ }
817
+
818
+ .flatpickr-day.selected {
819
+ background: var(--bs-primary);
820
+ color: white;
821
+ border-color: var(--bs-primary);
822
+ box-shadow: 0 2px 4px rgba(var(--bs-primary-rgb), 0.3);
823
+ }
824
+
825
+ .flatpickr-day.selected:hover {
826
+ background: var(--bs-primary);
827
+ color: white;
828
+ }
829
+
830
+ .flatpickr-day.inRange {
831
+ background: var(--bs-primary-bg-subtle);
832
+ color: var(--bs-primary);
833
+ border-color: transparent;
834
+ }
835
+
836
+ .flatpickr-day.startRange {
837
+ background: var(--bs-primary);
838
+ color: white;
839
+ border-radius: 4px 0 0 4px;
840
+ }
841
+
842
+ .flatpickr-day.endRange {
843
+ background: var(--bs-primary);
844
+ color: white;
845
+ border-radius: 0 4px 4px 0;
846
+ }
847
+
848
+ .flatpickr-day.startRange.endRange {
849
+ border-radius: 4px;
850
+ }
851
+
852
+ .flatpickr-day.today {
853
+ border-color: var(--bs-primary);
854
+ color: var(--bs-primary);
855
+ font-weight: 600;
856
+ }
857
+
858
+ .flatpickr-day.today:hover {
859
+ background: var(--bs-primary);
860
+ color: white;
861
+ }
862
+
863
+ .flatpickr-day.disabled {
864
+ color: var(--bs-secondary-color);
865
+ opacity: 0.5;
866
+ }
867
+
868
+ .flatpickr-time {
869
+ background: var(--bs-body-bg);
870
+ border-radius: 0 0 8px 8px;
871
+ }
872
+
873
+ .flatpickr-time input {
874
+ background: var(--bs-body-bg);
875
+ color: var(--bs-body-color);
876
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
877
+ }
878
+
879
+ .flatpickr-time input:focus {
880
+ border-color: var(--bs-primary);
881
+ box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
882
+ outline: 0;
883
+ }
884
+
885
+ .flatpickr-time .flatpickr-time-separator {
886
+ color: var(--bs-body-color);
887
+ }
888
+
889
+ .flatpickr-prev-month,
890
+ .flatpickr-next-month {
891
+ color: var(--bs-body-color);
892
+ fill: var(--bs-body-color);
893
+ transition: color 0.2s ease;
894
+ }
895
+
896
+ .flatpickr-prev-month:hover,
897
+ .flatpickr-next-month:hover {
898
+ color: var(--bs-primary);
899
+ fill: var(--bs-primary);
900
+ }
901
+
902
+ /* Dark mode specific enhancements */
903
+ [data-bs-theme="dark"] .flatpickr-calendar {
904
+ background: var(--bs-dark);
905
+ border-color: var(--bs-border-color-translucent);
906
+ box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.4);
907
+ }
908
+
909
+ [data-bs-theme="dark"] .flatpickr-months {
910
+ background: var(--bs-dark);
911
+ border-bottom-color: var(--bs-border-color-translucent);
912
+ }
913
+
914
+ [data-bs-theme="dark"] .flatpickr-weekdays {
915
+ background: var(--bs-dark);
916
+ }
917
+
918
+ /* Enhanced dark mode day styling for better contrast */
919
+ [data-bs-theme="dark"] .flatpickr-day {
920
+ color: #e9ecef !important;
921
+ background: transparent;
922
+ border: 1px solid transparent;
923
+ }
924
+
925
+ [data-bs-theme="dark"] .flatpickr-day:hover {
926
+ background: rgba(var(--bs-primary-rgb), 0.25) !important;
927
+ color: #ffffff !important;
928
+ border-color: rgba(var(--bs-primary-rgb), 0.4);
929
+ }
930
+
931
+ [data-bs-theme="dark"] .flatpickr-day.inRange {
932
+ background: rgba(var(--bs-primary-rgb), 0.2) !important;
933
+ color: #ffffff !important;
934
+ border-color: transparent;
935
+ }
936
+
937
+ [data-bs-theme="dark"] .flatpickr-day.selected {
938
+ background: var(--bs-primary) !important;
939
+ color: #ffffff !important;
940
+ border-color: var(--bs-primary);
941
+ box-shadow: 0 2px 6px rgba(var(--bs-primary-rgb), 0.4);
942
+ }
943
+
944
+ [data-bs-theme="dark"] .flatpickr-day.selected:hover {
945
+ background: var(--bs-primary) !important;
946
+ color: #ffffff !important;
947
+ }
948
+
949
+ [data-bs-theme="dark"] .flatpickr-day.startRange {
950
+ background: var(--bs-primary) !important;
951
+ color: #ffffff !important;
952
+ border-radius: 4px 0 0 4px;
953
+ }
954
+
955
+ [data-bs-theme="dark"] .flatpickr-day.endRange {
956
+ background: var(--bs-primary) !important;
957
+ color: #ffffff !important;
958
+ border-radius: 0 4px 4px 0;
959
+ }
960
+
961
+ [data-bs-theme="dark"] .flatpickr-day.startRange.endRange {
962
+ border-radius: 4px;
963
+ }
964
+
965
+ [data-bs-theme="dark"] .flatpickr-day.today {
966
+ border-color: var(--bs-primary) !important;
967
+ color: var(--bs-primary) !important;
968
+ font-weight: 600;
969
+ background: rgba(var(--bs-primary-rgb), 0.1);
970
+ }
971
+
972
+ [data-bs-theme="dark"] .flatpickr-day.today:hover {
973
+ background: var(--bs-primary) !important;
974
+ color: #ffffff !important;
975
+ }
976
+
977
+ [data-bs-theme="dark"] .flatpickr-day.disabled {
978
+ color: #6c757d !important;
979
+ opacity: 0.4;
980
+ background: transparent !important;
981
+ }
982
+
983
+ /* Dark mode other day states */
984
+ [data-bs-theme="dark"] .flatpickr-day.nextMonthDay,
985
+ [data-bs-theme="dark"] .flatpickr-day.prevMonthDay {
986
+ color: #6c757d !important;
987
+ opacity: 0.6;
988
+ }
989
+
990
+ [data-bs-theme="dark"] .flatpickr-day.nextMonthDay:hover,
991
+ [data-bs-theme="dark"] .flatpickr-day.prevMonthDay:hover {
992
+ background: rgba(var(--bs-primary-rgb), 0.15) !important;
993
+ color: #adb5bd !important;
994
+ }
995
+
996
+ [data-bs-theme="dark"] .flatpickr-time {
997
+ background: var(--bs-dark);
998
+ border-top-color: var(--bs-border-color-translucent);
999
+ }
1000
+
1001
+ [data-bs-theme="dark"] .flatpickr-time input {
1002
+ background: var(--bs-body-bg);
1003
+ border-color: var(--bs-border-color-translucent);
1004
+ color: #e9ecef !important;
1005
+ }
1006
+
1007
+ .flatpickr-calendar.hasTime .flatpickr-time {
1008
+ border-top: var(--bs-border-color-translucent);
1009
+ }
1010
+
1011
+ .flatpickr-next-month {
1012
+ color: var(--bs-body-color);
1013
+ fill: var(--bs-body-color);
1014
+ }
1015
+
1016
+ span.flatpickr-weekday {
1017
+ color: var(--bs-secondary-color);
1018
+ font-weight: 600;
1019
+ font-size: 0.75rem;
1020
+ }
1021
+
1022
+ [data-bs-theme="dark"] .flatpickr-time input:focus {
1023
+ border-color: var(--bs-primary);
1024
+ background: var(--bs-body-bg);
1025
+ color: #ffffff !important;
1026
+ }
1027
+
1028
+ [data-bs-theme="dark"] .flatpickr-time .flatpickr-time-separator {
1029
+ color: #e9ecef !important;
1030
+ }
1031
+
1032
+ /* Better focus states */
1033
+ .flatpickr-day:focus {
1034
+ outline: 2px solid var(--bs-primary);
1035
+ outline-offset: -2px;
1036
+ z-index: 10;
1037
+ }
1038
+
1039
+ /* Animation for calendar appearance */
1040
+ .flatpickr-calendar.open {
1041
+ animation: flatpickr-slideDown 0.2s ease-out;
1042
+ }
1043
+
1044
+ @keyframes flatpickr-slideDown {
1045
+ from {
1046
+ opacity: 0;
1047
+ transform: translateY(-10px) scale(0.98);
1048
+ }
1049
+ to {
1050
+ opacity: 1;
1051
+ transform: translateY(0) scale(1);
1052
+ }
1053
+ }
1054
+
1055
+ /* Small alert styling */
1056
+ .alert-sm {
1057
+ padding: 0.5rem;
1058
+ font-size: 0.875rem;
1059
+ }
1060
+
1061
+ /* Responsive adjustments - hide on smaller screens */
1062
+ @media (max-width: 991.98px) {
1063
+ .floating-creation-filter {
1064
+ display: none !important;
1065
+ }
1066
+ }
1067
+
1068
+ /* Flatpickr positioning and responsive adjustments */
1069
+ .flatpickr-calendar.arrowTop:before,
1070
+ .flatpickr-calendar.arrowTop:after {
1071
+ border-bottom-color: var(--bs-border-color);
1072
+ }
1073
+
1074
+ .flatpickr-calendar.arrowBottom:before,
1075
+ .flatpickr-calendar.arrowBottom:after {
1076
+ border-top-color: var(--bs-border-color);
1077
+ }
1078
+
1079
+ [data-bs-theme="dark"] .flatpickr-calendar.arrowTop:before,
1080
+ [data-bs-theme="dark"] .flatpickr-calendar.arrowTop:after {
1081
+ border-bottom-color: var(--bs-border-color-translucent);
1082
+ }
1083
+
1084
+ [data-bs-theme="dark"] .flatpickr-calendar.arrowBottom:before,
1085
+ [data-bs-theme="dark"] .flatpickr-calendar.arrowBottom:after {
1086
+ border-top-color: var(--bs-border-color-translucent);
1087
+ }
1088
+
1089
+ /* Ensure calendar stays within viewport on mobile */
1090
+ @media (max-width: 576px) {
1091
+ .flatpickr-calendar {
1092
+ max-width: calc(100vw - 20px);
1093
+ font-size: 14px;
1094
+ }
1095
+
1096
+ .flatpickr-day {
1097
+ height: 35px;
1098
+ line-height: 35px;
1099
+ }
1100
+
1101
+ .flatpickr-time input {
1102
+ font-size: 14px;
1103
+ }
1104
+ }
1105
+
1106
+ /* Improved accessibility */
1107
+ .flatpickr-calendar {
1108
+ font-family: inherit;
1109
+ }
1110
+
1111
+ .flatpickr-day[aria-label] {
1112
+ position: relative;
1113
+ }
1114
+
1115
+ /* Smooth scroll behavior for time inputs */
1116
+ .flatpickr-time input {
1117
+ scroll-behavior: smooth;
1118
+ }
1119
+
1120
+ /* Enhanced visual feedback for interactive elements */
1121
+ .flatpickr-prev-month,
1122
+ .flatpickr-next-month {
1123
+ border-radius: 4px;
1124
+ padding: 4px;
1125
+ margin: 2px;
1126
+ }
1127
+
1128
+ .flatpickr-prev-month:hover,
1129
+ .flatpickr-next-month:hover {
1130
+ background: rgba(var(--bs-primary-rgb), 0.1);
1131
+ }
1132
+
1133
+ /* Relationship count styling */
1134
+ .relationship-count .badge {
1135
+ min-width: 80px;
1136
+ display: inline-flex;
1137
+ align-items: center;
1138
+ justify-content: center;
1139
+ }
1140
+
1141
+ .relationship-count .spinner-border-sm {
1142
+ width: 0.875rem;
1143
+ height: 0.875rem;
1144
+ }