@arronqzy/react-view 1.0.32 → 1.0.35
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.
- package/dist/styles.css +215 -0
- package/package.json +8 -8
- package/readme.md +70 -82
- package/src/index.ts +2 -0
- package/src/panel/ReactViewPanel.tsx +52 -1
- package/src/panel/components/PanelMenubar.tsx +6 -0
- package/src/panel/components/scope-config/ScopeTemplateAutocompleteHost.tsx +4 -8
- package/src/panel/components/scope-config/ScopeTemplateUsageHint.tsx +1 -0
- package/src/panel/library/event-subscription.ts +20 -0
- package/src/panel/utils/scope-template.ts +20 -8
package/dist/styles.css
CHANGED
|
@@ -637,6 +637,10 @@ video {
|
|
|
637
637
|
bottom: 0.375rem;
|
|
638
638
|
}
|
|
639
639
|
|
|
640
|
+
.bottom-3 {
|
|
641
|
+
bottom: 0.75rem;
|
|
642
|
+
}
|
|
643
|
+
|
|
640
644
|
.bottom-\[var\(--rv-ruler-size\)\] {
|
|
641
645
|
bottom: var(--rv-ruler-size);
|
|
642
646
|
}
|
|
@@ -673,6 +677,10 @@ video {
|
|
|
673
677
|
right: 0px;
|
|
674
678
|
}
|
|
675
679
|
|
|
680
|
+
.right-1\.5 {
|
|
681
|
+
right: 0.375rem;
|
|
682
|
+
}
|
|
683
|
+
|
|
676
684
|
.right-2 {
|
|
677
685
|
right: 0.5rem;
|
|
678
686
|
}
|
|
@@ -693,6 +701,10 @@ video {
|
|
|
693
701
|
top: 0.25rem;
|
|
694
702
|
}
|
|
695
703
|
|
|
704
|
+
.top-1\.5 {
|
|
705
|
+
top: 0.375rem;
|
|
706
|
+
}
|
|
707
|
+
|
|
696
708
|
.top-2 {
|
|
697
709
|
top: 0.5rem;
|
|
698
710
|
}
|
|
@@ -701,6 +713,10 @@ video {
|
|
|
701
713
|
top: 1rem;
|
|
702
714
|
}
|
|
703
715
|
|
|
716
|
+
.top-\[calc\(100\%\+4px\)\] {
|
|
717
|
+
top: calc(100% + 4px);
|
|
718
|
+
}
|
|
719
|
+
|
|
704
720
|
.top-\[calc\(100\%\+6px\)\] {
|
|
705
721
|
top: calc(100% + 6px);
|
|
706
722
|
}
|
|
@@ -713,6 +729,10 @@ video {
|
|
|
713
729
|
isolation: isolate;
|
|
714
730
|
}
|
|
715
731
|
|
|
732
|
+
.z-10 {
|
|
733
|
+
z-index: 10;
|
|
734
|
+
}
|
|
735
|
+
|
|
716
736
|
.z-20 {
|
|
717
737
|
z-index: 20;
|
|
718
738
|
}
|
|
@@ -725,6 +745,10 @@ video {
|
|
|
725
745
|
z-index: 10000;
|
|
726
746
|
}
|
|
727
747
|
|
|
748
|
+
.z-\[10090\] {
|
|
749
|
+
z-index: 10090;
|
|
750
|
+
}
|
|
751
|
+
|
|
728
752
|
.z-\[10100\] {
|
|
729
753
|
z-index: 10100;
|
|
730
754
|
}
|
|
@@ -737,6 +761,14 @@ video {
|
|
|
737
761
|
z-index: 10150;
|
|
738
762
|
}
|
|
739
763
|
|
|
764
|
+
.z-\[10200\] {
|
|
765
|
+
z-index: 10200;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
.z-\[10300\] {
|
|
769
|
+
z-index: 10300;
|
|
770
|
+
}
|
|
771
|
+
|
|
740
772
|
.z-\[70\] {
|
|
741
773
|
z-index: 70;
|
|
742
774
|
}
|
|
@@ -978,10 +1010,26 @@ video {
|
|
|
978
1010
|
height: 100%;
|
|
979
1011
|
}
|
|
980
1012
|
|
|
1013
|
+
.h-px {
|
|
1014
|
+
height: 1px;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.max-h-24 {
|
|
1018
|
+
max-height: 6rem;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
981
1021
|
.max-h-28 {
|
|
982
1022
|
max-height: 7rem;
|
|
983
1023
|
}
|
|
984
1024
|
|
|
1025
|
+
.max-h-32 {
|
|
1026
|
+
max-height: 8rem;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.max-h-40 {
|
|
1030
|
+
max-height: 10rem;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
985
1033
|
.max-h-44 {
|
|
986
1034
|
max-height: 11rem;
|
|
987
1035
|
}
|
|
@@ -990,10 +1038,18 @@ video {
|
|
|
990
1038
|
max-height: 13rem;
|
|
991
1039
|
}
|
|
992
1040
|
|
|
1041
|
+
.max-h-56 {
|
|
1042
|
+
max-height: 14rem;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
993
1045
|
.max-h-\[160px\] {
|
|
994
1046
|
max-height: 160px;
|
|
995
1047
|
}
|
|
996
1048
|
|
|
1049
|
+
.max-h-\[180px\] {
|
|
1050
|
+
max-height: 180px;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
997
1053
|
.max-h-\[200px\] {
|
|
998
1054
|
max-height: 200px;
|
|
999
1055
|
}
|
|
@@ -1002,6 +1058,10 @@ video {
|
|
|
1002
1058
|
max-height: 78vh;
|
|
1003
1059
|
}
|
|
1004
1060
|
|
|
1061
|
+
.max-h-\[90vh\] {
|
|
1062
|
+
max-height: 90vh;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1005
1065
|
.max-h-\[min\(78vh\2c 560px\)\] {
|
|
1006
1066
|
max-height: min(78vh, 560px);
|
|
1007
1067
|
}
|
|
@@ -1034,6 +1094,10 @@ video {
|
|
|
1034
1094
|
min-height: 68px;
|
|
1035
1095
|
}
|
|
1036
1096
|
|
|
1097
|
+
.min-h-\[min\(62vh\2c 640px\)\] {
|
|
1098
|
+
min-height: min(62vh, 640px);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1037
1101
|
.min-h-full {
|
|
1038
1102
|
min-height: 100%;
|
|
1039
1103
|
}
|
|
@@ -1122,10 +1186,22 @@ video {
|
|
|
1122
1186
|
width: 108px;
|
|
1123
1187
|
}
|
|
1124
1188
|
|
|
1189
|
+
.w-\[148px\] {
|
|
1190
|
+
width: 148px;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
.w-\[168px\] {
|
|
1194
|
+
width: 168px;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1125
1197
|
.w-\[220px\] {
|
|
1126
1198
|
width: 220px;
|
|
1127
1199
|
}
|
|
1128
1200
|
|
|
1201
|
+
.w-\[240px\] {
|
|
1202
|
+
width: 240px;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1129
1205
|
.w-\[280px\] {
|
|
1130
1206
|
width: 280px;
|
|
1131
1207
|
}
|
|
@@ -1138,6 +1214,18 @@ video {
|
|
|
1138
1214
|
width: min(94vw, 680px);
|
|
1139
1215
|
}
|
|
1140
1216
|
|
|
1217
|
+
.w-\[min\(96vw\2c 1100px\)\] {
|
|
1218
|
+
width: min(96vw, 1100px);
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
.w-\[min\(96vw\2c 960px\)\] {
|
|
1222
|
+
width: min(96vw, 960px);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.w-\[var\(--radix-popover-trigger-width\)\] {
|
|
1226
|
+
width: var(--radix-popover-trigger-width);
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1141
1229
|
.w-\[var\(--rv-ruler-size\)\] {
|
|
1142
1230
|
width: var(--rv-ruler-size);
|
|
1143
1231
|
}
|
|
@@ -1174,10 +1262,18 @@ video {
|
|
|
1174
1262
|
max-width: 140px;
|
|
1175
1263
|
}
|
|
1176
1264
|
|
|
1265
|
+
.max-w-\[180px\] {
|
|
1266
|
+
max-width: 180px;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1177
1269
|
.max-w-\[200px\] {
|
|
1178
1270
|
max-width: 200px;
|
|
1179
1271
|
}
|
|
1180
1272
|
|
|
1273
|
+
.max-w-\[260px\] {
|
|
1274
|
+
max-width: 260px;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1181
1277
|
.max-w-\[360px\] {
|
|
1182
1278
|
max-width: 360px;
|
|
1183
1279
|
}
|
|
@@ -1210,6 +1306,10 @@ video {
|
|
|
1210
1306
|
max-width: 90%;
|
|
1211
1307
|
}
|
|
1212
1308
|
|
|
1309
|
+
.max-w-full {
|
|
1310
|
+
max-width: 100%;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1213
1313
|
.max-w-lg {
|
|
1214
1314
|
max-width: 32rem;
|
|
1215
1315
|
}
|
|
@@ -1253,6 +1353,11 @@ video {
|
|
|
1253
1353
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
1254
1354
|
}
|
|
1255
1355
|
|
|
1356
|
+
.rotate-180 {
|
|
1357
|
+
--tw-rotate: 180deg;
|
|
1358
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1256
1361
|
.transform {
|
|
1257
1362
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
1258
1363
|
}
|
|
@@ -1320,6 +1425,10 @@ video {
|
|
|
1320
1425
|
resize: none;
|
|
1321
1426
|
}
|
|
1322
1427
|
|
|
1428
|
+
.resize-y {
|
|
1429
|
+
resize: vertical;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1323
1432
|
.resize {
|
|
1324
1433
|
resize: both;
|
|
1325
1434
|
}
|
|
@@ -1436,6 +1545,11 @@ video {
|
|
|
1436
1545
|
gap: 1.25rem;
|
|
1437
1546
|
}
|
|
1438
1547
|
|
|
1548
|
+
.gap-x-2 {
|
|
1549
|
+
-moz-column-gap: 0.5rem;
|
|
1550
|
+
column-gap: 0.5rem;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1439
1553
|
.gap-x-4 {
|
|
1440
1554
|
-moz-column-gap: 1rem;
|
|
1441
1555
|
column-gap: 1rem;
|
|
@@ -1672,10 +1786,18 @@ video {
|
|
|
1672
1786
|
border-color: hsl(var(--border) / 0.8);
|
|
1673
1787
|
}
|
|
1674
1788
|
|
|
1789
|
+
.border-destructive {
|
|
1790
|
+
border-color: hsl(var(--destructive));
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1675
1793
|
.border-destructive\/20 {
|
|
1676
1794
|
border-color: hsl(var(--destructive) / 0.2);
|
|
1677
1795
|
}
|
|
1678
1796
|
|
|
1797
|
+
.border-destructive\/30 {
|
|
1798
|
+
border-color: hsl(var(--destructive) / 0.3);
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1679
1801
|
.border-destructive\/40 {
|
|
1680
1802
|
border-color: hsl(var(--destructive) / 0.4);
|
|
1681
1803
|
}
|
|
@@ -1684,6 +1806,10 @@ video {
|
|
|
1684
1806
|
border-color: hsl(var(--destructive) / 0.5);
|
|
1685
1807
|
}
|
|
1686
1808
|
|
|
1809
|
+
.border-destructive\/60 {
|
|
1810
|
+
border-color: hsl(var(--destructive) / 0.6);
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1687
1813
|
.border-emerald-500\/30 {
|
|
1688
1814
|
border-color: rgb(16 185 129 / 0.3);
|
|
1689
1815
|
}
|
|
@@ -1701,10 +1827,18 @@ video {
|
|
|
1701
1827
|
border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
|
|
1702
1828
|
}
|
|
1703
1829
|
|
|
1830
|
+
.border-input {
|
|
1831
|
+
border-color: hsl(var(--input));
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1704
1834
|
.border-primary\/25 {
|
|
1705
1835
|
border-color: hsl(var(--primary) / 0.25);
|
|
1706
1836
|
}
|
|
1707
1837
|
|
|
1838
|
+
.border-primary\/30 {
|
|
1839
|
+
border-color: hsl(var(--primary) / 0.3);
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1708
1842
|
.border-primary\/40 {
|
|
1709
1843
|
border-color: hsl(var(--primary) / 0.4);
|
|
1710
1844
|
}
|
|
@@ -1725,6 +1859,10 @@ video {
|
|
|
1725
1859
|
border-color: hsl(var(--primary) / 0.8);
|
|
1726
1860
|
}
|
|
1727
1861
|
|
|
1862
|
+
.border-rose-500\/50 {
|
|
1863
|
+
border-color: rgb(244 63 94 / 0.5);
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1728
1866
|
.border-sky-500\/40 {
|
|
1729
1867
|
border-color: rgb(14 165 233 / 0.4);
|
|
1730
1868
|
}
|
|
@@ -1872,6 +2010,10 @@ video {
|
|
|
1872
2010
|
background-color: hsl(var(--destructive) / 0.15);
|
|
1873
2011
|
}
|
|
1874
2012
|
|
|
2013
|
+
.bg-destructive\/5 {
|
|
2014
|
+
background-color: hsl(var(--destructive) / 0.05);
|
|
2015
|
+
}
|
|
2016
|
+
|
|
1875
2017
|
.bg-emerald-500 {
|
|
1876
2018
|
--tw-bg-opacity: 1;
|
|
1877
2019
|
background-color: rgb(16 185 129 / var(--tw-bg-opacity, 1));
|
|
@@ -1881,6 +2023,10 @@ video {
|
|
|
1881
2023
|
background-color: rgb(16 185 129 / 0.1);
|
|
1882
2024
|
}
|
|
1883
2025
|
|
|
2026
|
+
.bg-emerald-500\/15 {
|
|
2027
|
+
background-color: rgb(16 185 129 / 0.15);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
1884
2030
|
.bg-muted {
|
|
1885
2031
|
background-color: hsl(var(--muted));
|
|
1886
2032
|
}
|
|
@@ -1993,6 +2139,10 @@ video {
|
|
|
1993
2139
|
background-color: hsl(var(--primary) / 0.9);
|
|
1994
2140
|
}
|
|
1995
2141
|
|
|
2142
|
+
.bg-rose-500\/15 {
|
|
2143
|
+
background-color: rgb(244 63 94 / 0.15);
|
|
2144
|
+
}
|
|
2145
|
+
|
|
1996
2146
|
.bg-secondary {
|
|
1997
2147
|
background-color: hsl(var(--secondary));
|
|
1998
2148
|
}
|
|
@@ -2139,6 +2289,10 @@ video {
|
|
|
2139
2289
|
padding: 0px;
|
|
2140
2290
|
}
|
|
2141
2291
|
|
|
2292
|
+
.p-0\.5 {
|
|
2293
|
+
padding: 0.125rem;
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2142
2296
|
.p-1 {
|
|
2143
2297
|
padding: 0.25rem;
|
|
2144
2298
|
}
|
|
@@ -2259,6 +2413,11 @@ video {
|
|
|
2259
2413
|
padding-bottom: 1.75rem;
|
|
2260
2414
|
}
|
|
2261
2415
|
|
|
2416
|
+
.py-8 {
|
|
2417
|
+
padding-top: 2rem;
|
|
2418
|
+
padding-bottom: 2rem;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2262
2421
|
.py-px {
|
|
2263
2422
|
padding-top: 1px;
|
|
2264
2423
|
padding-bottom: 1px;
|
|
@@ -2308,6 +2467,10 @@ video {
|
|
|
2308
2467
|
padding-left: 1.25rem;
|
|
2309
2468
|
}
|
|
2310
2469
|
|
|
2470
|
+
.pr-0\.5 {
|
|
2471
|
+
padding-right: 0.125rem;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2311
2474
|
.pr-1 {
|
|
2312
2475
|
padding-right: 0.25rem;
|
|
2313
2476
|
}
|
|
@@ -2478,6 +2641,11 @@ video {
|
|
|
2478
2641
|
color: rgb(4 120 87 / var(--tw-text-opacity, 1));
|
|
2479
2642
|
}
|
|
2480
2643
|
|
|
2644
|
+
.text-emerald-800 {
|
|
2645
|
+
--tw-text-opacity: 1;
|
|
2646
|
+
color: rgb(6 95 70 / var(--tw-text-opacity, 1));
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2481
2649
|
.text-foreground {
|
|
2482
2650
|
color: hsl(var(--foreground));
|
|
2483
2651
|
}
|
|
@@ -2533,6 +2701,11 @@ video {
|
|
|
2533
2701
|
color: hsl(var(--primary) / 0.8);
|
|
2534
2702
|
}
|
|
2535
2703
|
|
|
2704
|
+
.text-rose-600 {
|
|
2705
|
+
--tw-text-opacity: 1;
|
|
2706
|
+
color: rgb(225 29 72 / var(--tw-text-opacity, 1));
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2536
2709
|
.text-secondary-foreground {
|
|
2537
2710
|
color: hsl(var(--secondary-foreground));
|
|
2538
2711
|
}
|
|
@@ -2617,6 +2790,10 @@ video {
|
|
|
2617
2790
|
opacity: 0.6;
|
|
2618
2791
|
}
|
|
2619
2792
|
|
|
2793
|
+
.opacity-90 {
|
|
2794
|
+
opacity: 0.9;
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2620
2797
|
.shadow {
|
|
2621
2798
|
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
2622
2799
|
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
|
@@ -2962,6 +3139,10 @@ video {
|
|
|
2962
3139
|
background-color: rgb(245 158 11 / 0.15);
|
|
2963
3140
|
}
|
|
2964
3141
|
|
|
3142
|
+
.hover\:bg-destructive\/10:hover {
|
|
3143
|
+
background-color: hsl(var(--destructive) / 0.1);
|
|
3144
|
+
}
|
|
3145
|
+
|
|
2965
3146
|
.hover\:bg-destructive\/90:hover {
|
|
2966
3147
|
background-color: hsl(var(--destructive) / 0.9);
|
|
2967
3148
|
}
|
|
@@ -2986,6 +3167,10 @@ video {
|
|
|
2986
3167
|
background-color: hsl(var(--primary) / 0.9);
|
|
2987
3168
|
}
|
|
2988
3169
|
|
|
3170
|
+
.hover\:bg-rose-500\/25:hover {
|
|
3171
|
+
background-color: rgb(244 63 94 / 0.25);
|
|
3172
|
+
}
|
|
3173
|
+
|
|
2989
3174
|
.hover\:bg-secondary\/80:hover {
|
|
2990
3175
|
background-color: hsl(var(--secondary) / 0.8);
|
|
2991
3176
|
}
|
|
@@ -3146,11 +3331,21 @@ video {
|
|
|
3146
3331
|
color: rgb(252 211 77 / var(--tw-text-opacity, 1));
|
|
3147
3332
|
}
|
|
3148
3333
|
|
|
3334
|
+
.dark\:text-emerald-200:is(.dark *) {
|
|
3335
|
+
--tw-text-opacity: 1;
|
|
3336
|
+
color: rgb(167 243 208 / var(--tw-text-opacity, 1));
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3149
3339
|
.dark\:text-emerald-300:is(.dark *) {
|
|
3150
3340
|
--tw-text-opacity: 1;
|
|
3151
3341
|
color: rgb(110 231 183 / var(--tw-text-opacity, 1));
|
|
3152
3342
|
}
|
|
3153
3343
|
|
|
3344
|
+
.dark\:text-rose-300:is(.dark *) {
|
|
3345
|
+
--tw-text-opacity: 1;
|
|
3346
|
+
color: rgb(253 164 175 / var(--tw-text-opacity, 1));
|
|
3347
|
+
}
|
|
3348
|
+
|
|
3154
3349
|
.dark\:text-sky-300:is(.dark *) {
|
|
3155
3350
|
--tw-text-opacity: 1;
|
|
3156
3351
|
color: rgb(125 211 252 / var(--tw-text-opacity, 1));
|
|
@@ -3184,6 +3379,10 @@ video {
|
|
|
3184
3379
|
display: flex;
|
|
3185
3380
|
}
|
|
3186
3381
|
|
|
3382
|
+
.sm\:max-w-\[1100px\] {
|
|
3383
|
+
max-width: 1100px;
|
|
3384
|
+
}
|
|
3385
|
+
|
|
3187
3386
|
.sm\:max-w-\[520px\] {
|
|
3188
3387
|
max-width: 520px;
|
|
3189
3388
|
}
|
|
@@ -3192,6 +3391,18 @@ video {
|
|
|
3192
3391
|
max-width: 860px;
|
|
3193
3392
|
}
|
|
3194
3393
|
|
|
3394
|
+
.sm\:max-w-\[960px\] {
|
|
3395
|
+
max-width: 960px;
|
|
3396
|
+
}
|
|
3397
|
+
|
|
3398
|
+
.sm\:max-w-md {
|
|
3399
|
+
max-width: 28rem;
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
.sm\:max-w-sm {
|
|
3403
|
+
max-width: 24rem;
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3195
3406
|
.sm\:grid-cols-2 {
|
|
3196
3407
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
3197
3408
|
}
|
|
@@ -3200,6 +3411,10 @@ video {
|
|
|
3200
3411
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
3201
3412
|
}
|
|
3202
3413
|
|
|
3414
|
+
.sm\:gap-0 {
|
|
3415
|
+
gap: 0px;
|
|
3416
|
+
}
|
|
3417
|
+
|
|
3203
3418
|
.sm\:space-x-0 > :not([hidden]) ~ :not([hidden]) {
|
|
3204
3419
|
--tw-space-x-reverse: 0;
|
|
3205
3420
|
margin-right: calc(0px * var(--tw-space-x-reverse));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arronqzy/react-view",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"files": [
|
|
5
5
|
"src",
|
|
6
6
|
"dist",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
32
32
|
"@codemirror/view": "^6.36.2",
|
|
33
33
|
"@arronqzy/ui": "1.0.9",
|
|
34
|
-
"@arronqzy/i18n": "0.1.
|
|
35
|
-
"@arronqzy/blueprint
|
|
36
|
-
"@arronqzy/
|
|
34
|
+
"@arronqzy/i18n": "0.1.16",
|
|
35
|
+
"@arronqzy/react-blueprint": "1.0.21",
|
|
36
|
+
"@arronqzy/blueprint-dsl": "1.0.16",
|
|
37
37
|
"@arronqzy/view-scene3d": "0.1.5",
|
|
38
38
|
"@arronqzy/rx-store": "1.0.8",
|
|
39
|
-
"@arronqzy/
|
|
40
|
-
"@arronqzy/
|
|
39
|
+
"@arronqzy/view-table": "0.1.8",
|
|
40
|
+
"@arronqzy/webllm-assistant": "0.1.16"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/react": "^19.0.1",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"eslint": "^8.57.0",
|
|
47
47
|
"typescript": "^5.5.4",
|
|
48
48
|
"@arronqzy/eslint-config": "0.0.0",
|
|
49
|
-
"@arronqzy/
|
|
50
|
-
"@arronqzy/
|
|
49
|
+
"@arronqzy/tailwind": "1.0.2",
|
|
50
|
+
"@arronqzy/typescript-config": "1.0.0"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
package/readme.md
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
# @arronqzy/react-view
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
视图编辑器。物料、无限画布、图层、配置侧栏、工作区和在线预览都在这个包。蓝图分屏通过依赖的 `@arronqzy/react-blueprint` 嵌进来。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
大多数 React 宿主应直接用 [`@arronqzy/abuilder`](../abuilder/README.md) 的 `<App />`。只有要把面板拆进已有布局时才引本包。
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## 画布上有什么
|
|
10
|
+
|
|
11
|
+
- **无限画布**:平移、缩放、标尺、框选,Moveable 拖拽 / 缩放 / 旋转
|
|
12
|
+
- **物料**:ECharts 图表、可视化表格、文本、图片、音视频、几何、网格、视口、三维、引用节点
|
|
13
|
+
- **图层**:多图层、映射图层、主图层、锁定、显示、合并
|
|
14
|
+
- **配置**:按类型展开;可搜字段;展开状态按节点记住
|
|
15
|
+
- **Scope**:属性可写 `{scope.xxx}`,蓝图执行后展开
|
|
16
|
+
- **工作区**:IndexedDB 多项目、导入导出、跨标签同步
|
|
17
|
+
|
|
18
|
+
表格是物料里配置最多的一类,列、条件样式和外观都在右侧:
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
打开蓝图后,本包把画布拆成上下两块,下面交给蓝图编辑器:
|
|
23
|
+
|
|
24
|
+

|
|
14
25
|
|
|
15
26
|
## 安装
|
|
16
27
|
|
|
@@ -18,15 +29,13 @@ Abuilder 的**视图编辑器** React 包,提供可视化画布、图层、物
|
|
|
18
29
|
pnpm add @arronqzy/react-view
|
|
19
30
|
```
|
|
20
31
|
|
|
21
|
-
依赖 React 19,并需引入样式:
|
|
22
|
-
|
|
23
32
|
```ts
|
|
24
33
|
import "@arronqzy/react-view/styles.css";
|
|
25
34
|
```
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
Vite 宿主还要加 `@arronqzy/abuilder/vite` 的 `webllmAssistant()`,见 abuilder 的 README。否则打包 WebLLM 会失败。
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
## 编辑面板
|
|
30
39
|
|
|
31
40
|
```tsx
|
|
32
41
|
import { ReactViewPanel } from "@arronqzy/react-view";
|
|
@@ -44,15 +53,15 @@ export function Editor({ workspace }: { workspace?: WorkspaceProjectRecord | nul
|
|
|
44
53
|
}
|
|
45
54
|
```
|
|
46
55
|
|
|
47
|
-
|
|
|
48
|
-
|
|
56
|
+
| 参数 | 说明 | 默认 |
|
|
57
|
+
|------|------|------|
|
|
49
58
|
| `className` | 根节点 class | — |
|
|
50
59
|
| `initialZoom` | 初始缩放 | `1` |
|
|
51
|
-
| `initialWorkspace` |
|
|
60
|
+
| `initialWorkspace` | 挂载后加载的完整工作区。空则空白画布 | — |
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
## 在线预览
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
按 ID 从 IndexedDB / 缓存加载:
|
|
56
65
|
|
|
57
66
|
```tsx
|
|
58
67
|
import { ReactViewOnlinePreview } from "@arronqzy/react-view";
|
|
@@ -60,65 +69,62 @@ import { ReactViewOnlinePreview } from "@arronqzy/react-view";
|
|
|
60
69
|
<ReactViewOnlinePreview projectId="your-project-id" />
|
|
61
70
|
```
|
|
62
71
|
|
|
63
|
-
|
|
72
|
+
直接给数据(优先于 `projectId`):
|
|
64
73
|
|
|
65
74
|
```tsx
|
|
66
75
|
<ReactViewOnlinePreview workspace={savedWorkspace} />
|
|
67
76
|
```
|
|
68
77
|
|
|
69
|
-
URL 参数解析:
|
|
70
|
-
|
|
71
78
|
```ts
|
|
72
79
|
import { parseOnlinePreviewSearchParams } from "@arronqzy/react-view";
|
|
73
80
|
|
|
74
|
-
|
|
81
|
+
parseOnlinePreviewSearchParams("?preview=online&projectId=xxx");
|
|
75
82
|
```
|
|
76
83
|
|
|
77
|
-
|
|
|
78
|
-
|
|
79
|
-
| `projectId` | 从 IndexedDB
|
|
80
|
-
| `workspace` |
|
|
84
|
+
| 参数 | 说明 |
|
|
85
|
+
|------|------|
|
|
86
|
+
| `projectId` | 从 IndexedDB 加载 |
|
|
87
|
+
| `workspace` | 宿主传入的完整工作区,优先 |
|
|
81
88
|
| `previewInstanceId` | 预览实例 ID(可选) |
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
## 工作区事件
|
|
84
91
|
|
|
85
|
-
|
|
92
|
+
回调带完整工作区,用来写自己的后端。IndexedDB 的增删改查不导出。
|
|
86
93
|
|
|
87
94
|
```ts
|
|
88
95
|
import {
|
|
89
96
|
addEventSubscription,
|
|
90
97
|
AbuilderEvents,
|
|
98
|
+
parseWorkspaceData,
|
|
91
99
|
type WorkspaceData,
|
|
92
100
|
} from "@arronqzy/react-view";
|
|
93
101
|
|
|
94
|
-
const addSub = addEventSubscription(
|
|
95
|
-
AbuilderEvents.workspaceAdd,
|
|
96
|
-
async (workspace: WorkspaceData) => {
|
|
97
|
-
await saveToServer(workspace);
|
|
98
|
-
}
|
|
99
|
-
);
|
|
100
|
-
|
|
101
102
|
const syncSub = addEventSubscription(
|
|
102
103
|
AbuilderEvents.workspaceSync,
|
|
103
|
-
async (workspace) => {
|
|
104
|
+
async (workspace: WorkspaceData) => {
|
|
104
105
|
await saveToServer(workspace);
|
|
105
106
|
}
|
|
106
107
|
);
|
|
107
|
-
|
|
108
|
-
addSub.unsubscribe();
|
|
109
108
|
syncSub.unsubscribe();
|
|
110
109
|
```
|
|
111
110
|
|
|
112
|
-
| 事件 | 常量 |
|
|
111
|
+
| 事件 | 常量 | 何时触发 |
|
|
113
112
|
|------|------|----------|
|
|
114
|
-
| `workspace:add` | `AbuilderEvents.workspaceAdd` |
|
|
115
|
-
| `workspace:sync` | `AbuilderEvents.workspaceSync` |
|
|
113
|
+
| `workspace:add` | `AbuilderEvents.workspaceAdd` | 创建成功 |
|
|
114
|
+
| `workspace:sync` | `AbuilderEvents.workspaceSync` | 同步成功 |
|
|
115
|
+
|
|
116
|
+
字段:`id`、`name`、`createdAt`、`updatedAt`、`panelState`、`blueprintDocument`、`blueprintMeta`、`productName`、`titleIconDataUrl`。
|
|
117
|
+
|
|
118
|
+
校验:
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
- `validateViewData` / `parseViewData` — 视图 `panelState`
|
|
121
|
+
- `validateBlueprintData` / `parseBlueprintData` — 蓝图文档
|
|
122
|
+
- `validateWorkspaceData` / `parseWorkspaceData` — 两边都要合法;`parse` 的 `value` 可作 `initialWorkspace`
|
|
123
|
+
- `createEmptyWorkspace` / `createWorkspaceProjectId` — 空白记录和 ID
|
|
118
124
|
|
|
119
|
-
|
|
125
|
+
## 预览缩略图
|
|
120
126
|
|
|
121
|
-
|
|
127
|
+
编辑器或预览页已挂载且画布有内容时:
|
|
122
128
|
|
|
123
129
|
```ts
|
|
124
130
|
import { getPreviewSnapshot } from "@arronqzy/react-view";
|
|
@@ -131,56 +137,38 @@ const dataUrl = await getPreviewSnapshot({
|
|
|
131
137
|
});
|
|
132
138
|
```
|
|
133
139
|
|
|
134
|
-
| 参数 | 说明 |
|
|
135
|
-
|
|
136
|
-
| `maxWidth` / `maxHeight` |
|
|
137
|
-
| `mimeType` |
|
|
138
|
-
| `quality` | JPEG
|
|
140
|
+
| 参数 | 说明 | 默认 |
|
|
141
|
+
|------|------|------|
|
|
142
|
+
| `maxWidth` / `maxHeight` | 等比上限 | 不限制 |
|
|
143
|
+
| `mimeType` | png 或 jpeg | `"image/png"` |
|
|
144
|
+
| `quality` | JPEG 0–1 | `0.92` |
|
|
139
145
|
| `backgroundColor` | 背景色 | `"#ffffff"` |
|
|
140
146
|
|
|
141
|
-
##
|
|
147
|
+
## 主要导出
|
|
142
148
|
|
|
143
149
|
| 导出 | 说明 |
|
|
144
150
|
|------|------|
|
|
145
|
-
| `ReactViewPanel` |
|
|
146
|
-
| `ReactViewOnlinePreview` |
|
|
147
|
-
| `parseOnlinePreviewSearchParams` | 解析预览 URL
|
|
148
|
-
| `addEventSubscription`
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
| `WorkspaceData` / `WorkspaceProjectRecord` | 完整工作区数据类型 |
|
|
157
|
-
| `createView` / `createAction` 等 | 视图 DSL 与指令扩展(`src/core`) |
|
|
158
|
-
|
|
159
|
-
相关类型:`AbuilderEventName`、`AbuilderEventPayloadMap`、`WorkspaceAddEventPayload`、`WorkspaceSyncEventPayload`、`GetPreviewSnapshotOptions`。
|
|
160
|
-
|
|
161
|
-
## 样式与 Tailwind
|
|
162
|
-
|
|
163
|
-
本包内置 Tailwind 配置,构建产物为 `dist/styles.css`:
|
|
151
|
+
| `ReactViewPanel` | 主面板(画布 + 配置 + 蓝图分屏) |
|
|
152
|
+
| `ReactViewOnlinePreview` | 只读预览 |
|
|
153
|
+
| `parseOnlinePreviewSearchParams` | 解析预览 URL |
|
|
154
|
+
| `addEventSubscription` / `AbuilderEvents` | 工作区事件 |
|
|
155
|
+
| `getPreviewSnapshot` | 预览截图 data URL |
|
|
156
|
+
| `parseWorkspaceData` 等 | 校验 / 解析 / 空工作区 |
|
|
157
|
+
| `createView` / `createAction` | 视图 DSL 扩展点(`src/core`) |
|
|
158
|
+
|
|
159
|
+
## 样式
|
|
160
|
+
|
|
161
|
+
产物是 `dist/styles.css`。本仓库构建:
|
|
164
162
|
|
|
165
163
|
```bash
|
|
166
164
|
pnpm -C packages/react-view build:css
|
|
167
165
|
```
|
|
168
166
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
```ts
|
|
172
|
-
content: [
|
|
173
|
-
"./src/**/*.{ts,tsx}",
|
|
174
|
-
"./node_modules/@arronqzy/react-view/src/**/*.{ts,tsx}",
|
|
175
|
-
]
|
|
176
|
-
```
|
|
167
|
+
若应用自己的 Tailwind 要扫描本包源码,把 `node_modules/@arronqzy/react-view/src/**/*.{ts,tsx}` 加进 `content`。
|
|
177
168
|
|
|
178
|
-
##
|
|
169
|
+
## 依赖
|
|
179
170
|
|
|
180
|
-
|
|
181
|
-
- `@arronqzy/rx-store` — 画布状态与历史
|
|
182
|
-
- `@arronqzy/react-blueprint` — 蓝图编辑与执行
|
|
183
|
-
- `@arronqzy/blueprint-dsl` — 蓝图运行时
|
|
171
|
+
`@arronqzy/ui`、`@arronqzy/rx-store`、`@arronqzy/react-blueprint`、`@arronqzy/blueprint-dsl`、`@arronqzy/view-table`、`@arronqzy/view-scene3d`。
|
|
184
172
|
|
|
185
173
|
## 许可证
|
|
186
174
|
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,8 @@ export type {
|
|
|
14
14
|
AbuilderEventPayloadMap,
|
|
15
15
|
WorkspaceAddEventPayload,
|
|
16
16
|
WorkspaceSyncEventPayload,
|
|
17
|
+
ApiCollectionUploadStartEventPayload,
|
|
18
|
+
ApiCollectionUploadSuccessEventPayload,
|
|
17
19
|
WorkspaceData,
|
|
18
20
|
} from "./panel/library/event-subscription";
|
|
19
21
|
export type { WorkspaceProjectRecord } from "./panel/library/workspace-project-db";
|
|
@@ -46,6 +46,7 @@ import { revealPanelConfigFromPatch } from "./ai/revealConfigField";
|
|
|
46
46
|
import {
|
|
47
47
|
BlueprintGraph,
|
|
48
48
|
BlueprintMetaDialog,
|
|
49
|
+
ApiCollectionManagerDialog,
|
|
49
50
|
BlueprintNodeSwitchTaskDialog,
|
|
50
51
|
blueprintDocumentsEqual,
|
|
51
52
|
buildBlueprintExportPayload,
|
|
@@ -55,6 +56,7 @@ import {
|
|
|
55
56
|
downloadBlueprintExport,
|
|
56
57
|
documentToRunnableGraph,
|
|
57
58
|
getBlueprintLibraryRecord,
|
|
59
|
+
hydrateApiCollections,
|
|
58
60
|
libraryRecordFromImport,
|
|
59
61
|
listBlueprintLibrary,
|
|
60
62
|
parseBlueprintImportFile,
|
|
@@ -72,12 +74,16 @@ import {
|
|
|
72
74
|
type BlueprintMetaDraft,
|
|
73
75
|
} from "@arronqzy/react-blueprint";
|
|
74
76
|
import type { LibraryBlueprintResolver } from "@arronqzy/blueprint-dsl";
|
|
75
|
-
import { abortClockNode, appStorageKey, collectArmedViewEventBindings, EVENT_NODE_TYPE, LIFECYCLE_NODE_TYPE } from "@arronqzy/blueprint-dsl";
|
|
77
|
+
import { abortClockNode, appStorageKey, buildApiCollectionSyncPatches, toApiCollectionSyncResult, collectArmedViewEventBindings, EVENT_NODE_TYPE, LIFECYCLE_NODE_TYPE } from "@arronqzy/blueprint-dsl";
|
|
76
78
|
import { WorkspaceStageSplit } from "./components/WorkspaceStageSplit";
|
|
77
79
|
import {
|
|
78
80
|
WorkspaceConfigSidebar,
|
|
79
81
|
type WorkspaceConfigFocus,
|
|
80
82
|
} from "./components/WorkspaceConfigSidebar";
|
|
83
|
+
import {
|
|
84
|
+
AbuilderEvents,
|
|
85
|
+
emitAbuilderEvent,
|
|
86
|
+
} from "./library/event-subscription";
|
|
81
87
|
import {
|
|
82
88
|
getViewElementScope,
|
|
83
89
|
setViewElementScopes,
|
|
@@ -295,6 +301,7 @@ function ReactViewPanelInner({
|
|
|
295
301
|
const [blueprintMetaDialogMode, setBlueprintMetaDialogMode] = useState<
|
|
296
302
|
"export" | "save"
|
|
297
303
|
>("save");
|
|
304
|
+
const [apiCollectionManagerOpen, setApiCollectionManagerOpen] = useState(false);
|
|
298
305
|
const [selectedBlueprintNodeId, setSelectedBlueprintNodeId] = useState<string | null>(
|
|
299
306
|
null
|
|
300
307
|
);
|
|
@@ -655,6 +662,12 @@ function ReactViewPanelInner({
|
|
|
655
662
|
[nameSpace]
|
|
656
663
|
);
|
|
657
664
|
|
|
665
|
+
useEffect(() => {
|
|
666
|
+
void hydrateApiCollections(nameSpace).catch((error) => {
|
|
667
|
+
console.error("[abuilder] hydrate api collections failed", error);
|
|
668
|
+
});
|
|
669
|
+
}, [nameSpace]);
|
|
670
|
+
|
|
658
671
|
const handleBlueprintExecutionBlocked = useCallback((message: string) => {
|
|
659
672
|
toast({ title: message });
|
|
660
673
|
}, []);
|
|
@@ -1904,6 +1917,7 @@ function ReactViewPanelInner({
|
|
|
1904
1917
|
applyTheme={applyTheme}
|
|
1905
1918
|
isDark={isDark}
|
|
1906
1919
|
openBlueprintExportDialog={openBlueprintExportDialog}
|
|
1920
|
+
openApiCollectionManager={() => setApiCollectionManagerOpen(true)}
|
|
1907
1921
|
panelFontSize={panelFontSize}
|
|
1908
1922
|
setPanelFontSize={setPanelFontSize}
|
|
1909
1923
|
locale={locale}
|
|
@@ -2768,6 +2782,43 @@ function ReactViewPanelInner({
|
|
|
2768
2782
|
void handleBlueprintMetaConfirm(meta);
|
|
2769
2783
|
}}
|
|
2770
2784
|
/>
|
|
2785
|
+
<ApiCollectionManagerDialog
|
|
2786
|
+
open={apiCollectionManagerOpen}
|
|
2787
|
+
onOpenChange={setApiCollectionManagerOpen}
|
|
2788
|
+
onUploadStart={(info) => {
|
|
2789
|
+
emitAbuilderEvent(AbuilderEvents.apiCollectionUploadStart, info);
|
|
2790
|
+
}}
|
|
2791
|
+
onUploadSuccess={(info) => {
|
|
2792
|
+
emitAbuilderEvent(AbuilderEvents.apiCollectionUploadSuccess, info);
|
|
2793
|
+
}}
|
|
2794
|
+
onSyncCollection={(record) => {
|
|
2795
|
+
const patches = buildApiCollectionSyncPatches({
|
|
2796
|
+
collectionId: record.id,
|
|
2797
|
+
document: record.document,
|
|
2798
|
+
nodes: blueprintGraph.document.nodes
|
|
2799
|
+
.filter((node) => node.role === "fetch" || Boolean(node.fetchConfig))
|
|
2800
|
+
.map((node) => ({
|
|
2801
|
+
id: node.id,
|
|
2802
|
+
label: node.label,
|
|
2803
|
+
fetchConfig: node.fetchConfig,
|
|
2804
|
+
})),
|
|
2805
|
+
});
|
|
2806
|
+
if (patches.length === 0) {
|
|
2807
|
+
return toApiCollectionSyncResult([]);
|
|
2808
|
+
}
|
|
2809
|
+
setBlueprintGraph((graph) => {
|
|
2810
|
+
let next = graph;
|
|
2811
|
+
for (const patch of patches) {
|
|
2812
|
+
next = next.updateNode(patch.nodeId, {
|
|
2813
|
+
fetchConfig:
|
|
2814
|
+
patch.fetchConfigPatch as import("@arronqzy/blueprint-dsl").FetchRequestConfig,
|
|
2815
|
+
});
|
|
2816
|
+
}
|
|
2817
|
+
return next;
|
|
2818
|
+
});
|
|
2819
|
+
return toApiCollectionSyncResult(patches);
|
|
2820
|
+
}}
|
|
2821
|
+
/>
|
|
2771
2822
|
{pendingBlueprintNodeSwitch ? (
|
|
2772
2823
|
<BlueprintNodeSwitchTaskDialog
|
|
2773
2824
|
open
|
|
@@ -34,6 +34,7 @@ export type PanelMenubarProps = {
|
|
|
34
34
|
applyTheme: (dark: boolean) => void;
|
|
35
35
|
isDark: boolean;
|
|
36
36
|
openBlueprintExportDialog: () => void;
|
|
37
|
+
openApiCollectionManager: () => void;
|
|
37
38
|
panelFontSize: "sm" | "md" | "lg";
|
|
38
39
|
setPanelFontSize: (value: "sm" | "md" | "lg") => void;
|
|
39
40
|
locale: Locale;
|
|
@@ -65,6 +66,7 @@ export function PanelMenubar({
|
|
|
65
66
|
applyTheme,
|
|
66
67
|
isDark,
|
|
67
68
|
openBlueprintExportDialog,
|
|
69
|
+
openApiCollectionManager,
|
|
68
70
|
panelFontSize,
|
|
69
71
|
setPanelFontSize,
|
|
70
72
|
locale,
|
|
@@ -121,6 +123,10 @@ export function PanelMenubar({
|
|
|
121
123
|
<MenubarItem onClick={() => blueprintImportInputRef.current?.click()}>
|
|
122
124
|
{t("panel.menubar.import")}
|
|
123
125
|
</MenubarItem>
|
|
126
|
+
<MenubarSeparator />
|
|
127
|
+
<MenubarItem onClick={openApiCollectionManager}>
|
|
128
|
+
{t("panel.menubar.apiCollections")}
|
|
129
|
+
</MenubarItem>
|
|
124
130
|
</MenubarContent>
|
|
125
131
|
</MenubarMenu>
|
|
126
132
|
<MenubarMenu>
|
|
@@ -73,17 +73,13 @@ export function ScopeTemplateAutocompleteHost({
|
|
|
73
73
|
|
|
74
74
|
const refreshForInput = useCallback(
|
|
75
75
|
(input: HTMLInputElement | HTMLTextAreaElement) => {
|
|
76
|
-
if (scope === undefined) {
|
|
77
|
-
closeDropdown();
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
76
|
const cursor = input.selectionStart ?? input.value.length;
|
|
81
|
-
const parsed = parseScopeAutocomplete(input.value, cursor, scope);
|
|
77
|
+
const parsed = parseScopeAutocomplete(input.value, cursor, scope ?? {});
|
|
82
78
|
if (!parsed) {
|
|
83
79
|
closeDropdown();
|
|
84
80
|
return;
|
|
85
81
|
}
|
|
86
|
-
const suggestions = getScopeAutocompleteSuggestions(scope, parsed);
|
|
82
|
+
const suggestions = getScopeAutocompleteSuggestions(scope ?? {}, parsed);
|
|
87
83
|
if (suggestions.length === 0) {
|
|
88
84
|
closeDropdown();
|
|
89
85
|
return;
|
|
@@ -124,7 +120,7 @@ export function ScopeTemplateAutocompleteHost({
|
|
|
124
120
|
|
|
125
121
|
useEffect(() => {
|
|
126
122
|
const container = containerRef?.current;
|
|
127
|
-
if (!container
|
|
123
|
+
if (!container) return;
|
|
128
124
|
|
|
129
125
|
const onFocusIn = (event: FocusEvent) => {
|
|
130
126
|
if (!isAutocompleteTarget(event.target)) return;
|
|
@@ -213,7 +209,7 @@ export function ScopeTemplateAutocompleteHost({
|
|
|
213
209
|
scope,
|
|
214
210
|
]);
|
|
215
211
|
|
|
216
|
-
if (!dropdown
|
|
212
|
+
if (!dropdown) return null;
|
|
217
213
|
|
|
218
214
|
return createPortal(
|
|
219
215
|
<div
|
|
@@ -5,6 +5,10 @@ export const AbuilderEvents = {
|
|
|
5
5
|
workspaceAdd: "workspace:add",
|
|
6
6
|
/** 同步工作区 */
|
|
7
7
|
workspaceSync: "workspace:sync",
|
|
8
|
+
/** 开始上传接口集合 */
|
|
9
|
+
apiCollectionUploadStart: "api-collection:upload-start",
|
|
10
|
+
/** 上传接口集合成功 */
|
|
11
|
+
apiCollectionUploadSuccess: "api-collection:upload-success",
|
|
8
12
|
} as const;
|
|
9
13
|
|
|
10
14
|
export type AbuilderEventName = (typeof AbuilderEvents)[keyof typeof AbuilderEvents];
|
|
@@ -15,9 +19,25 @@ export type WorkspaceData = WorkspaceProjectRecord;
|
|
|
15
19
|
export type WorkspaceAddEventPayload = WorkspaceData;
|
|
16
20
|
export type WorkspaceSyncEventPayload = WorkspaceData;
|
|
17
21
|
|
|
22
|
+
export type ApiCollectionUploadStartEventPayload = {
|
|
23
|
+
fileNames: string[];
|
|
24
|
+
count: number;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type ApiCollectionUploadSuccessEventPayload = {
|
|
28
|
+
collections: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
apiCount: number;
|
|
32
|
+
persistLocal: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
|
|
18
36
|
export type AbuilderEventPayloadMap = {
|
|
19
37
|
[AbuilderEvents.workspaceAdd]: WorkspaceAddEventPayload;
|
|
20
38
|
[AbuilderEvents.workspaceSync]: WorkspaceSyncEventPayload;
|
|
39
|
+
[AbuilderEvents.apiCollectionUploadStart]: ApiCollectionUploadStartEventPayload;
|
|
40
|
+
[AbuilderEvents.apiCollectionUploadSuccess]: ApiCollectionUploadSuccessEventPayload;
|
|
21
41
|
};
|
|
22
42
|
|
|
23
43
|
type EventCallback = (payload: unknown) => void;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { PanelElement } from "../types";
|
|
2
2
|
import type { PanelTableConfig } from "@arronqzy/view-table";
|
|
3
3
|
import { isUsableTableRawData } from "@arronqzy/view-table";
|
|
4
|
+
import {
|
|
5
|
+
createSystemRoot,
|
|
6
|
+
isDayjsValue,
|
|
7
|
+
} from "@arronqzy/blueprint-dsl";
|
|
4
8
|
import { materializeChartLabelsFromScope, materializeChartValuesFromScope } from "./scope-template-chart";
|
|
5
9
|
import {
|
|
6
10
|
SCOPE_SPREAD_TEMPLATE_RE,
|
|
@@ -11,12 +15,12 @@ import {
|
|
|
11
15
|
resolveSpreadScopePath,
|
|
12
16
|
} from "./scope-template-spread";
|
|
13
17
|
|
|
14
|
-
const
|
|
18
|
+
const TEMPLATE_TOKEN_RE = /\{((?:scope|system)[^}]*)\}/g;
|
|
15
19
|
|
|
16
20
|
export function hasScopeTemplate(value: string): boolean {
|
|
17
|
-
|
|
21
|
+
TEMPLATE_TOKEN_RE.lastIndex = 0;
|
|
18
22
|
SCOPE_SPREAD_TEMPLATE_RE.lastIndex = 0;
|
|
19
|
-
return
|
|
23
|
+
return TEMPLATE_TOKEN_RE.test(value) || SCOPE_SPREAD_TEMPLATE_RE.test(value);
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export function evaluateScopeExpression(
|
|
@@ -26,8 +30,13 @@ export function evaluateScopeExpression(
|
|
|
26
30
|
const trimmed = expression.trim();
|
|
27
31
|
if (!trimmed) return undefined;
|
|
28
32
|
try {
|
|
29
|
-
const
|
|
30
|
-
|
|
33
|
+
const system = createSystemRoot();
|
|
34
|
+
const fn = new Function(
|
|
35
|
+
"scope",
|
|
36
|
+
"system",
|
|
37
|
+
`"use strict"; return (${trimmed});`
|
|
38
|
+
);
|
|
39
|
+
return fn(scope, system);
|
|
31
40
|
} catch {
|
|
32
41
|
return undefined;
|
|
33
42
|
}
|
|
@@ -39,6 +48,9 @@ function stringifyScopeValue(value: unknown): string {
|
|
|
39
48
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
40
49
|
return String(value);
|
|
41
50
|
}
|
|
51
|
+
if (isDayjsValue(value)) {
|
|
52
|
+
return value.toISOString();
|
|
53
|
+
}
|
|
42
54
|
try {
|
|
43
55
|
return JSON.stringify(value);
|
|
44
56
|
} catch {
|
|
@@ -60,8 +72,8 @@ export function evaluateScopeTemplate(
|
|
|
60
72
|
}
|
|
61
73
|
);
|
|
62
74
|
|
|
63
|
-
// Only `{scope...}`
|
|
64
|
-
return withSpread.replace(
|
|
75
|
+
// Only `{scope...}` / `{system...}` — keep ECharts / CSS braces like `{b}` intact.
|
|
76
|
+
return withSpread.replace(TEMPLATE_TOKEN_RE, (_: string, rawExpr: string) =>
|
|
65
77
|
stringifyScopeValue(evaluateScopeExpression(rawExpr, scope))
|
|
66
78
|
);
|
|
67
79
|
}
|
|
@@ -91,7 +103,7 @@ function materializeTemplateValue(template: string, scope: unknown): unknown {
|
|
|
91
103
|
);
|
|
92
104
|
}
|
|
93
105
|
|
|
94
|
-
const singleMatch = /^\{(scope[^}]*)\}$/.exec(trimmed);
|
|
106
|
+
const singleMatch = /^\{((?:scope|system)[^}]*)\}$/.exec(trimmed);
|
|
95
107
|
if (singleMatch) {
|
|
96
108
|
return evaluateScopeExpression(singleMatch[1]!, scope);
|
|
97
109
|
}
|