@visns-studio/visns-components 5.15.9 → 5.15.11

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.
@@ -0,0 +1,658 @@
1
+ // DataPreviewModal.module.scss
2
+ // Professional, stable modal for comprehensive data preview with no resizing issues
3
+
4
+ .modalOverlay {
5
+ position: fixed;
6
+ top: 0;
7
+ left: 0;
8
+ right: 0;
9
+ bottom: 0;
10
+ background: rgba(0, 0, 0, 0.75);
11
+ backdrop-filter: blur(4px);
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ z-index: 10000;
16
+ padding: 20px;
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ .modalContainer {
21
+ background: white;
22
+ border-radius: 16px;
23
+ box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
24
+ width: 100%;
25
+ max-width: 1400px;
26
+ max-height: 90vh;
27
+ min-height: 600px;
28
+ display: flex;
29
+ flex-direction: column;
30
+ overflow: hidden;
31
+ animation: modalSlideIn 0.3s ease-out;
32
+ }
33
+
34
+ @keyframes modalSlideIn {
35
+ from {
36
+ opacity: 0;
37
+ transform: scale(0.95) translateY(20px);
38
+ }
39
+ to {
40
+ opacity: 1;
41
+ transform: scale(1) translateY(0);
42
+ }
43
+ }
44
+
45
+ // Header Section
46
+ .modalHeader {
47
+ flex-shrink: 0;
48
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
49
+ color: white;
50
+ padding: 24px 30px;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: space-between;
54
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
55
+ }
56
+
57
+ .headerContent h2 {
58
+ margin: 0 0 8px 0;
59
+ font-size: 24px;
60
+ font-weight: 600;
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 12px;
64
+
65
+ svg {
66
+ color: rgba(255, 255, 255, 0.9);
67
+ }
68
+ }
69
+
70
+ .subtitle {
71
+ margin: 0;
72
+ color: rgba(255, 255, 255, 0.8);
73
+ font-size: 14px;
74
+ font-weight: 400;
75
+ }
76
+
77
+ .closeButton {
78
+ background: rgba(255, 255, 255, 0.1);
79
+ border: 1px solid rgba(255, 255, 255, 0.2);
80
+ color: white;
81
+ width: 40px;
82
+ height: 40px;
83
+ border-radius: 8px;
84
+ display: flex;
85
+ align-items: center;
86
+ justify-content: center;
87
+ cursor: pointer;
88
+ transition: all 0.2s ease;
89
+
90
+ &:hover {
91
+ background: rgba(255, 255, 255, 0.2);
92
+ transform: translateY(-1px);
93
+ }
94
+ }
95
+
96
+ // Content Section - Fixed height to prevent resizing
97
+ .modalContent {
98
+ flex: 1;
99
+ display: flex;
100
+ flex-direction: column;
101
+ overflow: hidden;
102
+ min-height: 0; // Critical for flex child to be scrollable
103
+ }
104
+
105
+ // Loading and Error States
106
+ .loadingState, .errorState {
107
+ flex: 1;
108
+ display: flex;
109
+ flex-direction: column;
110
+ align-items: center;
111
+ justify-content: center;
112
+ padding: 60px 20px;
113
+ text-align: center;
114
+ color: #666;
115
+ }
116
+
117
+ .spinner {
118
+ animation: spin 1s linear infinite;
119
+ color: #667eea;
120
+ margin-bottom: 16px;
121
+ }
122
+
123
+ @keyframes spin {
124
+ from { transform: rotate(0deg); }
125
+ to { transform: rotate(360deg); }
126
+ }
127
+
128
+ .errorState {
129
+ color: #e74c3c;
130
+
131
+ h3 {
132
+ margin: 16px 0 8px 0;
133
+ color: #c0392b;
134
+ }
135
+
136
+ svg {
137
+ color: #e74c3c;
138
+ margin-bottom: 16px;
139
+ }
140
+ }
141
+
142
+ .retryButton {
143
+ margin-top: 16px;
144
+ background: #e74c3c;
145
+ color: white;
146
+ border: none;
147
+ padding: 12px 24px;
148
+ border-radius: 8px;
149
+ cursor: pointer;
150
+ font-weight: 500;
151
+ transition: background-color 0.2s ease;
152
+
153
+ &:hover {
154
+ background: #c0392b;
155
+ }
156
+ }
157
+
158
+ // Summary Section
159
+ .summarySection {
160
+ flex-shrink: 0;
161
+ padding: 24px 30px;
162
+ background: #f8f9ff;
163
+ border-bottom: 1px solid #e5e7eb;
164
+ }
165
+
166
+ .summaryGrid {
167
+ display: grid;
168
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
169
+ gap: 16px;
170
+ }
171
+
172
+ .summaryCard {
173
+ background: white;
174
+ border: 1px solid #e5e7eb;
175
+ border-radius: 12px;
176
+ padding: 20px;
177
+ display: flex;
178
+ align-items: center;
179
+ gap: 16px;
180
+ transition: all 0.2s ease;
181
+
182
+ &:hover {
183
+ border-color: #667eea;
184
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.1);
185
+ transform: translateY(-1px);
186
+ }
187
+ }
188
+
189
+ .summaryIcon {
190
+ width: 48px;
191
+ height: 48px;
192
+ border-radius: 8px;
193
+ display: flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
197
+ color: white;
198
+ }
199
+
200
+ .summaryContent {
201
+ flex: 1;
202
+ }
203
+
204
+ .summaryNumber {
205
+ display: block;
206
+ font-size: 28px;
207
+ font-weight: 700;
208
+ color: #1f2937;
209
+ line-height: 1;
210
+ }
211
+
212
+ .summaryLabel {
213
+ display: block;
214
+ font-size: 14px;
215
+ color: #6b7280;
216
+ margin-top: 4px;
217
+ }
218
+
219
+ // Filters Section
220
+ .filtersSection {
221
+ flex-shrink: 0;
222
+ padding: 20px 30px;
223
+ background: white;
224
+ border-bottom: 1px solid #e5e7eb;
225
+ display: flex;
226
+ gap: 20px;
227
+ align-items: center;
228
+ }
229
+
230
+ .searchBox, .filterBox {
231
+ position: relative;
232
+ display: flex;
233
+ align-items: center;
234
+
235
+ svg {
236
+ position: absolute;
237
+ left: 12px;
238
+ color: #6b7280;
239
+ z-index: 1;
240
+ }
241
+
242
+ input, select {
243
+ padding: 10px 12px 10px 40px;
244
+ border: 1px solid #d1d5db;
245
+ border-radius: 8px;
246
+ font-size: 14px;
247
+ width: 240px;
248
+ transition: all 0.2s ease;
249
+
250
+ &:focus {
251
+ outline: none;
252
+ border-color: #667eea;
253
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
254
+ }
255
+ }
256
+ }
257
+
258
+ // Records Section - Scrollable area with fixed height
259
+ .recordsSection {
260
+ flex: 1;
261
+ overflow-y: auto;
262
+ padding: 0 30px;
263
+ min-height: 0; // Critical for scrolling
264
+
265
+ // Custom scrollbar
266
+ &::-webkit-scrollbar {
267
+ width: 8px;
268
+ }
269
+
270
+ &::-webkit-scrollbar-track {
271
+ background: #f1f1f1;
272
+ border-radius: 4px;
273
+ }
274
+
275
+ &::-webkit-scrollbar-thumb {
276
+ background: #c1c1c1;
277
+ border-radius: 4px;
278
+
279
+ &:hover {
280
+ background: #a1a1a1;
281
+ }
282
+ }
283
+ }
284
+
285
+ .emptyState {
286
+ text-align: center;
287
+ padding: 60px 20px;
288
+ color: #6b7280;
289
+ font-size: 16px;
290
+ }
291
+
292
+ // Record Cards
293
+ .recordCard {
294
+ background: white;
295
+ border: 1px solid #e5e7eb;
296
+ border-radius: 12px;
297
+ margin-bottom: 16px;
298
+ overflow: hidden;
299
+ transition: all 0.2s ease;
300
+
301
+ &:hover {
302
+ border-color: #667eea;
303
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.1);
304
+ }
305
+
306
+ &:last-child {
307
+ margin-bottom: 0;
308
+ }
309
+ }
310
+
311
+ .recordHeader {
312
+ padding: 16px 20px;
313
+ display: flex;
314
+ align-items: center;
315
+ justify-content: space-between;
316
+ background: #fafbfc;
317
+ border-bottom: 1px solid #e5e7eb;
318
+ }
319
+
320
+ .recordInfo {
321
+ display: flex;
322
+ align-items: center;
323
+ gap: 12px;
324
+ }
325
+
326
+ .statusBadge {
327
+ display: inline-flex;
328
+ align-items: center;
329
+ gap: 6px;
330
+ padding: 4px 8px;
331
+ border-radius: 6px;
332
+ font-size: 11px;
333
+ font-weight: 600;
334
+ text-transform: uppercase;
335
+ letter-spacing: 0.5px;
336
+ }
337
+
338
+ .statusNew {
339
+ background: #dcfce7;
340
+ color: #166534;
341
+ }
342
+
343
+ .statusUpdate {
344
+ background: #dbeafe;
345
+ color: #1e40af;
346
+ }
347
+
348
+ .statusSkip {
349
+ background: #fef3c7;
350
+ color: #92400e;
351
+ }
352
+
353
+ .statusDefault {
354
+ background: #f3f4f6;
355
+ color: #374151;
356
+ }
357
+
358
+ .statusIconNew { color: #16a34a; }
359
+ .statusIconUpdate { color: #2563eb; }
360
+ .statusIconSkip { color: #ca8a04; }
361
+ .statusIconDefault { color: #6b7280; }
362
+
363
+ .recordTitle {
364
+ font-weight: 500;
365
+ color: #1f2937;
366
+ font-size: 14px;
367
+ }
368
+
369
+ .toggleButton {
370
+ background: #f3f4f6;
371
+ border: 1px solid #d1d5db;
372
+ color: #374151;
373
+ padding: 6px 12px;
374
+ border-radius: 6px;
375
+ font-size: 12px;
376
+ cursor: pointer;
377
+ display: flex;
378
+ align-items: center;
379
+ gap: 6px;
380
+ transition: all 0.2s ease;
381
+
382
+ &:hover {
383
+ background: #e5e7eb;
384
+ border-color: #9ca3af;
385
+ }
386
+ }
387
+
388
+ // Changes Preview
389
+ .changesPreview {
390
+ padding: 16px 20px;
391
+ background: #f0f9ff;
392
+ border-bottom: 1px solid #e0f2fe;
393
+
394
+ strong {
395
+ color: #0c4a6e;
396
+ font-size: 13px;
397
+ display: block;
398
+ margin-bottom: 8px;
399
+ }
400
+
401
+ ul {
402
+ margin: 0;
403
+ padding-left: 0;
404
+ list-style: none;
405
+ }
406
+
407
+ li {
408
+ font-size: 12px;
409
+ color: #374151;
410
+ margin-bottom: 4px;
411
+ display: flex;
412
+ align-items: center;
413
+ gap: 8px;
414
+ }
415
+ }
416
+
417
+ .fieldName {
418
+ font-weight: 500;
419
+ color: #1f2937;
420
+ min-width: 100px;
421
+ }
422
+
423
+ .oldValue {
424
+ background: #fee2e2;
425
+ color: #991b1b;
426
+ padding: 2px 6px;
427
+ border-radius: 4px;
428
+ font-family: monospace;
429
+ font-size: 11px;
430
+ }
431
+
432
+ .newValue {
433
+ background: #dcfce7;
434
+ color: #166534;
435
+ padding: 2px 6px;
436
+ border-radius: 4px;
437
+ font-family: monospace;
438
+ font-size: 11px;
439
+ }
440
+
441
+ // Record Details
442
+ .recordDetails {
443
+ padding: 20px;
444
+ background: #fafbfc;
445
+ }
446
+
447
+ .dataSection {
448
+ margin-bottom: 20px;
449
+
450
+ &:last-child {
451
+ margin-bottom: 0;
452
+ }
453
+
454
+ h4 {
455
+ margin: 0 0 12px 0;
456
+ font-size: 14px;
457
+ font-weight: 600;
458
+ color: #374151;
459
+ padding-bottom: 8px;
460
+ border-bottom: 1px solid #e5e7eb;
461
+ }
462
+ }
463
+
464
+ .jsonData {
465
+ background: #1f2937;
466
+ color: #f9fafb;
467
+ padding: 16px;
468
+ border-radius: 8px;
469
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
470
+ font-size: 12px;
471
+ line-height: 1.5;
472
+ overflow-x: auto;
473
+ margin: 0;
474
+ white-space: pre-wrap;
475
+ word-break: break-word;
476
+ max-height: 300px;
477
+ overflow-y: auto;
478
+
479
+ // Custom scrollbar for JSON
480
+ &::-webkit-scrollbar {
481
+ width: 6px;
482
+ height: 6px;
483
+ }
484
+
485
+ &::-webkit-scrollbar-track {
486
+ background: #374151;
487
+ border-radius: 3px;
488
+ }
489
+
490
+ &::-webkit-scrollbar-thumb {
491
+ background: #6b7280;
492
+ border-radius: 3px;
493
+
494
+ &:hover {
495
+ background: #9ca3af;
496
+ }
497
+ }
498
+ }
499
+
500
+ // Pagination Section
501
+ .paginationSection {
502
+ flex-shrink: 0;
503
+ padding: 20px 30px;
504
+ background: #f8f9ff;
505
+ border-top: 1px solid #e5e7eb;
506
+ display: flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ gap: 16px;
510
+ }
511
+
512
+ .paginationButton {
513
+ background: white;
514
+ border: 1px solid #d1d5db;
515
+ color: #374151;
516
+ padding: 8px 16px;
517
+ border-radius: 6px;
518
+ cursor: pointer;
519
+ font-size: 14px;
520
+ transition: all 0.2s ease;
521
+
522
+ &:hover:not(:disabled) {
523
+ background: #f3f4f6;
524
+ border-color: #9ca3af;
525
+ }
526
+
527
+ &:disabled {
528
+ opacity: 0.5;
529
+ cursor: not-allowed;
530
+ }
531
+ }
532
+
533
+ .paginationInfo {
534
+ color: #6b7280;
535
+ font-size: 14px;
536
+ font-weight: 500;
537
+ }
538
+
539
+ // Footer Section
540
+ .modalFooter {
541
+ flex-shrink: 0;
542
+ padding: 24px 30px;
543
+ background: #f8f9ff;
544
+ border-top: 1px solid #e5e7eb;
545
+ display: flex;
546
+ align-items: center;
547
+ justify-content: flex-end;
548
+ gap: 16px;
549
+ }
550
+
551
+ .cancelButton {
552
+ background: white;
553
+ border: 1px solid #d1d5db;
554
+ color: #374151;
555
+ padding: 12px 24px;
556
+ border-radius: 8px;
557
+ cursor: pointer;
558
+ font-size: 14px;
559
+ font-weight: 500;
560
+ transition: all 0.2s ease;
561
+
562
+ &:hover {
563
+ background: #f3f4f6;
564
+ border-color: #9ca3af;
565
+ }
566
+ }
567
+
568
+ .confirmButton {
569
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
570
+ border: none;
571
+ color: white;
572
+ padding: 12px 24px;
573
+ border-radius: 8px;
574
+ cursor: pointer;
575
+ font-size: 14px;
576
+ font-weight: 500;
577
+ display: flex;
578
+ align-items: center;
579
+ gap: 8px;
580
+ transition: all 0.2s ease;
581
+
582
+ &:hover:not(:disabled) {
583
+ background: linear-gradient(135deg, #059669 0%, #047857 100%);
584
+ transform: translateY(-1px);
585
+ box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
586
+ }
587
+
588
+ &:disabled {
589
+ opacity: 0.6;
590
+ cursor: not-allowed;
591
+ transform: none;
592
+ box-shadow: none;
593
+ }
594
+ }
595
+
596
+ // Responsive Design
597
+ @media (max-width: 768px) {
598
+ .modalOverlay {
599
+ padding: 10px;
600
+ }
601
+
602
+ .modalContainer {
603
+ max-height: 95vh;
604
+ min-height: 500px;
605
+ }
606
+
607
+ .modalHeader {
608
+ padding: 16px 20px;
609
+
610
+ h2 {
611
+ font-size: 20px;
612
+ }
613
+ }
614
+
615
+ .summaryGrid {
616
+ grid-template-columns: 1fr;
617
+ }
618
+
619
+ .filtersSection {
620
+ padding: 16px 20px;
621
+ flex-direction: column;
622
+ align-items: stretch;
623
+ gap: 12px;
624
+
625
+ .searchBox, .filterBox {
626
+ input, select {
627
+ width: 100%;
628
+ }
629
+ }
630
+ }
631
+
632
+ .recordsSection {
633
+ padding: 0 20px;
634
+ }
635
+
636
+ .recordHeader {
637
+ padding: 12px 16px;
638
+ flex-direction: column;
639
+ align-items: flex-start;
640
+ gap: 12px;
641
+ }
642
+
643
+ .paginationSection {
644
+ padding: 16px 20px;
645
+ flex-direction: column;
646
+ gap: 12px;
647
+ }
648
+
649
+ .modalFooter {
650
+ padding: 16px 20px;
651
+ flex-direction: column-reverse;
652
+ gap: 12px;
653
+
654
+ button {
655
+ width: 100%;
656
+ }
657
+ }
658
+ }