@mongoosejs/studio 0.2.11 → 0.2.13
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/backend/actions/Model/getEstimatedDocumentCounts.js +38 -0
- package/backend/actions/Model/index.js +1 -0
- package/backend/actions/Model/streamDocumentChanges.js +8 -7
- package/backend/actions/Task/getTasks.js +9 -6
- package/backend/authorize.js +1 -0
- package/backend/index.js +11 -3
- package/eslint.config.js +2 -1
- package/express.js +1 -0
- package/frontend/public/app.js +644 -129
- package/frontend/public/tw.css +181 -12
- package/frontend/src/api.js +6 -0
- package/frontend/src/chat/chat.html +13 -7
- package/frontend/src/document/document.html +26 -0
- package/frontend/src/document/document.js +27 -1
- package/frontend/src/models/models.html +8 -2
- package/frontend/src/models/models.js +34 -0
- package/frontend/src/navbar/navbar.js +1 -1
- package/frontend/src/routes.js +20 -4
- package/frontend/src/task-by-name/task-by-name.html +15 -0
- package/frontend/src/task-by-name/task-by-name.js +78 -0
- package/frontend/src/task-single/task-single.html +157 -0
- package/frontend/src/task-single/task-single.js +116 -0
- package/frontend/src/tasks/task-details/task-details.html +101 -50
- package/frontend/src/tasks/task-details/task-details.js +161 -10
- package/frontend/src/tasks/tasks.html +1 -13
- package/frontend/src/tasks/tasks.js +9 -25
- package/package.json +2 -1
package/frontend/public/tw.css
CHANGED
|
@@ -647,10 +647,22 @@ video {
|
|
|
647
647
|
left: -0.75rem;
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
+
.bottom-4 {
|
|
651
|
+
bottom: 1rem;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.bottom-full {
|
|
655
|
+
bottom: 100%;
|
|
656
|
+
}
|
|
657
|
+
|
|
650
658
|
.left-0 {
|
|
651
659
|
left: 0px;
|
|
652
660
|
}
|
|
653
661
|
|
|
662
|
+
.left-4 {
|
|
663
|
+
left: 1rem;
|
|
664
|
+
}
|
|
665
|
+
|
|
654
666
|
.left-full {
|
|
655
667
|
left: 100%;
|
|
656
668
|
}
|
|
@@ -1002,6 +1014,10 @@ video {
|
|
|
1002
1014
|
height: 1.25em;
|
|
1003
1015
|
}
|
|
1004
1016
|
|
|
1017
|
+
.h-\[240px\] {
|
|
1018
|
+
height: 240px;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1005
1021
|
.h-\[300px\] {
|
|
1006
1022
|
height: 300px;
|
|
1007
1023
|
}
|
|
@@ -1058,10 +1074,6 @@ video {
|
|
|
1058
1074
|
width: 12rem !important;
|
|
1059
1075
|
}
|
|
1060
1076
|
|
|
1061
|
-
.\!w-64 {
|
|
1062
|
-
width: 16rem !important;
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
1077
|
.\!w-\[90vw\] {
|
|
1066
1078
|
width: 90vw !important;
|
|
1067
1079
|
}
|
|
@@ -1122,6 +1134,10 @@ video {
|
|
|
1122
1134
|
width: 2rem;
|
|
1123
1135
|
}
|
|
1124
1136
|
|
|
1137
|
+
.w-\[240px\] {
|
|
1138
|
+
width: 240px;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1125
1141
|
.w-\[50\%\] {
|
|
1126
1142
|
width: 50%;
|
|
1127
1143
|
}
|
|
@@ -1138,6 +1154,10 @@ video {
|
|
|
1138
1154
|
min-width: 140px;
|
|
1139
1155
|
}
|
|
1140
1156
|
|
|
1157
|
+
.min-w-\[220px\] {
|
|
1158
|
+
min-width: 220px;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1141
1161
|
.min-w-\[80px\] {
|
|
1142
1162
|
min-width: 80px;
|
|
1143
1163
|
}
|
|
@@ -1150,6 +1170,10 @@ video {
|
|
|
1150
1170
|
max-width: 28rem !important;
|
|
1151
1171
|
}
|
|
1152
1172
|
|
|
1173
|
+
.max-w-4xl {
|
|
1174
|
+
max-width: 56rem;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1153
1177
|
.max-w-5xl {
|
|
1154
1178
|
max-width: 64rem;
|
|
1155
1179
|
}
|
|
@@ -1206,6 +1230,11 @@ video {
|
|
|
1206
1230
|
transform-origin: top right;
|
|
1207
1231
|
}
|
|
1208
1232
|
|
|
1233
|
+
.-translate-x-full {
|
|
1234
|
+
--tw-translate-x: -100%;
|
|
1235
|
+
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));
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1209
1238
|
.-translate-y-1\/2 {
|
|
1210
1239
|
--tw-translate-y: -50%;
|
|
1211
1240
|
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));
|
|
@@ -1221,6 +1250,11 @@ video {
|
|
|
1221
1250
|
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));
|
|
1222
1251
|
}
|
|
1223
1252
|
|
|
1253
|
+
.translate-y-1 {
|
|
1254
|
+
--tw-translate-y: 0.25rem;
|
|
1255
|
+
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));
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1224
1258
|
.rotate-0 {
|
|
1225
1259
|
--tw-rotate: 0deg;
|
|
1226
1260
|
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));
|
|
@@ -1348,6 +1382,10 @@ video {
|
|
|
1348
1382
|
gap: 1rem;
|
|
1349
1383
|
}
|
|
1350
1384
|
|
|
1385
|
+
.gap-6 {
|
|
1386
|
+
gap: 1.5rem;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1351
1389
|
.gap-8 {
|
|
1352
1390
|
gap: 2rem;
|
|
1353
1391
|
}
|
|
@@ -1563,6 +1601,10 @@ video {
|
|
|
1563
1601
|
border-bottom-width: 4px;
|
|
1564
1602
|
}
|
|
1565
1603
|
|
|
1604
|
+
.border-l-0 {
|
|
1605
|
+
border-left-width: 0px;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1566
1608
|
.border-l-\[3px\] {
|
|
1567
1609
|
border-left-width: 3px;
|
|
1568
1610
|
}
|
|
@@ -1636,6 +1678,11 @@ video {
|
|
|
1636
1678
|
border-color: rgb(241 245 249 / var(--tw-border-opacity));
|
|
1637
1679
|
}
|
|
1638
1680
|
|
|
1681
|
+
.border-slate-300 {
|
|
1682
|
+
--tw-border-opacity: 1;
|
|
1683
|
+
border-color: rgb(203 213 225 / var(--tw-border-opacity));
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1639
1686
|
.border-transparent {
|
|
1640
1687
|
border-color: transparent;
|
|
1641
1688
|
}
|
|
@@ -1645,6 +1692,11 @@ video {
|
|
|
1645
1692
|
border-color: rgb(63 83 255 / var(--tw-border-opacity));
|
|
1646
1693
|
}
|
|
1647
1694
|
|
|
1695
|
+
.border-ultramarine-600 {
|
|
1696
|
+
--tw-border-opacity: 1;
|
|
1697
|
+
border-color: rgb(24 35 255 / var(--tw-border-opacity));
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1648
1700
|
.border-yellow-200 {
|
|
1649
1701
|
--tw-border-opacity: 1;
|
|
1650
1702
|
border-color: rgb(254 240 138 / var(--tw-border-opacity));
|
|
@@ -1774,6 +1826,11 @@ video {
|
|
|
1774
1826
|
background-color: rgb(220 252 231 / var(--tw-bg-opacity));
|
|
1775
1827
|
}
|
|
1776
1828
|
|
|
1829
|
+
.bg-green-200 {
|
|
1830
|
+
--tw-bg-opacity: 1;
|
|
1831
|
+
background-color: rgb(187 247 208 / var(--tw-bg-opacity));
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1777
1834
|
.bg-green-50 {
|
|
1778
1835
|
--tw-bg-opacity: 1;
|
|
1779
1836
|
background-color: rgb(240 253 244 / var(--tw-bg-opacity));
|
|
@@ -1794,6 +1851,11 @@ video {
|
|
|
1794
1851
|
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
|
|
1795
1852
|
}
|
|
1796
1853
|
|
|
1854
|
+
.bg-red-200 {
|
|
1855
|
+
--tw-bg-opacity: 1;
|
|
1856
|
+
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1797
1859
|
.bg-red-400 {
|
|
1798
1860
|
--tw-bg-opacity: 1;
|
|
1799
1861
|
background-color: rgb(248 113 113 / var(--tw-bg-opacity));
|
|
@@ -1819,6 +1881,11 @@ video {
|
|
|
1819
1881
|
background-color: rgb(241 245 249 / var(--tw-bg-opacity));
|
|
1820
1882
|
}
|
|
1821
1883
|
|
|
1884
|
+
.bg-slate-200 {
|
|
1885
|
+
--tw-bg-opacity: 1;
|
|
1886
|
+
background-color: rgb(226 232 240 / var(--tw-bg-opacity));
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1822
1889
|
.bg-slate-300 {
|
|
1823
1890
|
--tw-bg-opacity: 1;
|
|
1824
1891
|
background-color: rgb(203 213 225 / var(--tw-bg-opacity));
|
|
@@ -1839,6 +1906,11 @@ video {
|
|
|
1839
1906
|
background-color: rgb(71 85 105 / var(--tw-bg-opacity));
|
|
1840
1907
|
}
|
|
1841
1908
|
|
|
1909
|
+
.bg-slate-900 {
|
|
1910
|
+
--tw-bg-opacity: 1;
|
|
1911
|
+
background-color: rgb(15 23 42 / var(--tw-bg-opacity));
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1842
1914
|
.bg-teal-600 {
|
|
1843
1915
|
--tw-bg-opacity: 1;
|
|
1844
1916
|
background-color: rgb(0 168 165 / var(--tw-bg-opacity));
|
|
@@ -1883,6 +1955,11 @@ video {
|
|
|
1883
1955
|
background-color: rgb(254 249 195 / var(--tw-bg-opacity));
|
|
1884
1956
|
}
|
|
1885
1957
|
|
|
1958
|
+
.bg-yellow-200 {
|
|
1959
|
+
--tw-bg-opacity: 1;
|
|
1960
|
+
background-color: rgb(254 240 138 / var(--tw-bg-opacity));
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1886
1963
|
.bg-yellow-400 {
|
|
1887
1964
|
--tw-bg-opacity: 1;
|
|
1888
1965
|
background-color: rgb(250 204 21 / var(--tw-bg-opacity));
|
|
@@ -2062,6 +2139,11 @@ video {
|
|
|
2062
2139
|
padding-bottom: 2rem;
|
|
2063
2140
|
}
|
|
2064
2141
|
|
|
2142
|
+
.py-\[2px\] {
|
|
2143
|
+
padding-top: 2px;
|
|
2144
|
+
padding-bottom: 2px;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2065
2147
|
.pb-16 {
|
|
2066
2148
|
padding-bottom: 4rem;
|
|
2067
2149
|
}
|
|
@@ -2198,10 +2280,6 @@ video {
|
|
|
2198
2280
|
font-weight: 500;
|
|
2199
2281
|
}
|
|
2200
2282
|
|
|
2201
|
-
.font-normal {
|
|
2202
|
-
font-weight: 400;
|
|
2203
|
-
}
|
|
2204
|
-
|
|
2205
2283
|
.font-semibold {
|
|
2206
2284
|
font-weight: 600;
|
|
2207
2285
|
}
|
|
@@ -2319,6 +2397,11 @@ video {
|
|
|
2319
2397
|
color: rgb(22 101 52 / var(--tw-text-opacity));
|
|
2320
2398
|
}
|
|
2321
2399
|
|
|
2400
|
+
.text-green-900 {
|
|
2401
|
+
--tw-text-opacity: 1;
|
|
2402
|
+
color: rgb(20 83 45 / var(--tw-text-opacity));
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2322
2405
|
.text-purple-600 {
|
|
2323
2406
|
--tw-text-opacity: 1;
|
|
2324
2407
|
color: rgb(147 51 234 / var(--tw-text-opacity));
|
|
@@ -2344,6 +2427,11 @@ video {
|
|
|
2344
2427
|
color: rgb(153 27 27 / var(--tw-text-opacity));
|
|
2345
2428
|
}
|
|
2346
2429
|
|
|
2430
|
+
.text-red-900 {
|
|
2431
|
+
--tw-text-opacity: 1;
|
|
2432
|
+
color: rgb(127 29 29 / var(--tw-text-opacity));
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2347
2435
|
.text-sky-600 {
|
|
2348
2436
|
--tw-text-opacity: 1;
|
|
2349
2437
|
color: rgb(2 132 199 / var(--tw-text-opacity));
|
|
@@ -2359,11 +2447,26 @@ video {
|
|
|
2359
2447
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
2360
2448
|
}
|
|
2361
2449
|
|
|
2450
|
+
.text-slate-200 {
|
|
2451
|
+
--tw-text-opacity: 1;
|
|
2452
|
+
color: rgb(226 232 240 / var(--tw-text-opacity));
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
.text-slate-300 {
|
|
2456
|
+
--tw-text-opacity: 1;
|
|
2457
|
+
color: rgb(203 213 225 / var(--tw-text-opacity));
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2362
2460
|
.text-slate-400 {
|
|
2363
2461
|
--tw-text-opacity: 1;
|
|
2364
2462
|
color: rgb(148 163 184 / var(--tw-text-opacity));
|
|
2365
2463
|
}
|
|
2366
2464
|
|
|
2465
|
+
.text-slate-50 {
|
|
2466
|
+
--tw-text-opacity: 1;
|
|
2467
|
+
color: rgb(248 250 252 / var(--tw-text-opacity));
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2367
2470
|
.text-slate-500 {
|
|
2368
2471
|
--tw-text-opacity: 1;
|
|
2369
2472
|
color: rgb(100 116 139 / var(--tw-text-opacity));
|
|
@@ -2384,6 +2487,11 @@ video {
|
|
|
2384
2487
|
color: rgb(30 41 59 / var(--tw-text-opacity));
|
|
2385
2488
|
}
|
|
2386
2489
|
|
|
2490
|
+
.text-slate-900 {
|
|
2491
|
+
--tw-text-opacity: 1;
|
|
2492
|
+
color: rgb(15 23 42 / var(--tw-text-opacity));
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2387
2495
|
.text-ultramarine-600 {
|
|
2388
2496
|
--tw-text-opacity: 1;
|
|
2389
2497
|
color: rgb(24 35 255 / var(--tw-text-opacity));
|
|
@@ -2424,6 +2532,11 @@ video {
|
|
|
2424
2532
|
color: rgb(133 77 14 / var(--tw-text-opacity));
|
|
2425
2533
|
}
|
|
2426
2534
|
|
|
2535
|
+
.text-yellow-900 {
|
|
2536
|
+
--tw-text-opacity: 1;
|
|
2537
|
+
color: rgb(113 63 18 / var(--tw-text-opacity));
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2427
2540
|
.underline {
|
|
2428
2541
|
text-decoration-line: underline;
|
|
2429
2542
|
}
|
|
@@ -2556,6 +2669,11 @@ video {
|
|
|
2556
2669
|
--tw-ring-color: rgb(156 163 175 / var(--tw-ring-opacity));
|
|
2557
2670
|
}
|
|
2558
2671
|
|
|
2672
|
+
.ring-gray-500 {
|
|
2673
|
+
--tw-ring-opacity: 1;
|
|
2674
|
+
--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity));
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2559
2677
|
.ring-gray-600\/20 {
|
|
2560
2678
|
--tw-ring-color: rgb(75 85 99 / 0.2);
|
|
2561
2679
|
}
|
|
@@ -2569,6 +2687,11 @@ video {
|
|
|
2569
2687
|
--tw-ring-color: rgb(74 222 128 / var(--tw-ring-opacity));
|
|
2570
2688
|
}
|
|
2571
2689
|
|
|
2690
|
+
.ring-green-500 {
|
|
2691
|
+
--tw-ring-opacity: 1;
|
|
2692
|
+
--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity));
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2572
2695
|
.ring-green-600\/20 {
|
|
2573
2696
|
--tw-ring-color: rgb(22 163 74 / 0.2);
|
|
2574
2697
|
}
|
|
@@ -2578,11 +2701,26 @@ video {
|
|
|
2578
2701
|
--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity));
|
|
2579
2702
|
}
|
|
2580
2703
|
|
|
2704
|
+
.ring-red-500 {
|
|
2705
|
+
--tw-ring-opacity: 1;
|
|
2706
|
+
--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity));
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
.ring-slate-500 {
|
|
2710
|
+
--tw-ring-opacity: 1;
|
|
2711
|
+
--tw-ring-color: rgb(100 116 139 / var(--tw-ring-opacity));
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2581
2714
|
.ring-yellow-400 {
|
|
2582
2715
|
--tw-ring-opacity: 1;
|
|
2583
2716
|
--tw-ring-color: rgb(250 204 21 / var(--tw-ring-opacity));
|
|
2584
2717
|
}
|
|
2585
2718
|
|
|
2719
|
+
.ring-yellow-500 {
|
|
2720
|
+
--tw-ring-opacity: 1;
|
|
2721
|
+
--tw-ring-color: rgb(234 179 8 / var(--tw-ring-opacity));
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2586
2724
|
.ring-opacity-5 {
|
|
2587
2725
|
--tw-ring-opacity: 0.05;
|
|
2588
2726
|
}
|
|
@@ -3258,6 +3396,28 @@ video {
|
|
|
3258
3396
|
opacity: 0.5;
|
|
3259
3397
|
}
|
|
3260
3398
|
|
|
3399
|
+
.group:focus-within .group-focus-within\:pointer-events-auto {
|
|
3400
|
+
pointer-events: auto;
|
|
3401
|
+
}
|
|
3402
|
+
|
|
3403
|
+
.group:focus-within .group-focus-within\:translate-y-0 {
|
|
3404
|
+
--tw-translate-y: 0px;
|
|
3405
|
+
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));
|
|
3406
|
+
}
|
|
3407
|
+
|
|
3408
|
+
.group:focus-within .group-focus-within\:opacity-100 {
|
|
3409
|
+
opacity: 1;
|
|
3410
|
+
}
|
|
3411
|
+
|
|
3412
|
+
.group:hover .group-hover\:pointer-events-auto {
|
|
3413
|
+
pointer-events: auto;
|
|
3414
|
+
}
|
|
3415
|
+
|
|
3416
|
+
.group:hover .group-hover\:translate-y-0 {
|
|
3417
|
+
--tw-translate-y: 0px;
|
|
3418
|
+
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));
|
|
3419
|
+
}
|
|
3420
|
+
|
|
3261
3421
|
.group:hover .group-hover\:text-gray-700 {
|
|
3262
3422
|
--tw-text-opacity: 1;
|
|
3263
3423
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
@@ -3394,6 +3554,10 @@ video {
|
|
|
3394
3554
|
gap: 1.5rem;
|
|
3395
3555
|
}
|
|
3396
3556
|
|
|
3557
|
+
.md\:p-8 {
|
|
3558
|
+
padding: 2rem;
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3397
3561
|
.md\:px-0 {
|
|
3398
3562
|
padding-left: 0px;
|
|
3399
3563
|
padding-right: 0px;
|
|
@@ -3410,12 +3574,12 @@ video {
|
|
|
3410
3574
|
margin-right: -2rem;
|
|
3411
3575
|
}
|
|
3412
3576
|
|
|
3413
|
-
.lg\:
|
|
3414
|
-
|
|
3577
|
+
.lg\:hidden {
|
|
3578
|
+
display: none;
|
|
3415
3579
|
}
|
|
3416
3580
|
|
|
3417
|
-
.lg\:w-
|
|
3418
|
-
width:
|
|
3581
|
+
.lg\:w-48 {
|
|
3582
|
+
width: 12rem;
|
|
3419
3583
|
}
|
|
3420
3584
|
|
|
3421
3585
|
.lg\:max-w-\[calc\(100vw-15rem\)\] {
|
|
@@ -3426,6 +3590,11 @@ video {
|
|
|
3426
3590
|
max-width: calc(100vw - 20rem);
|
|
3427
3591
|
}
|
|
3428
3592
|
|
|
3593
|
+
.lg\:translate-x-0 {
|
|
3594
|
+
--tw-translate-x: 0px;
|
|
3595
|
+
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));
|
|
3596
|
+
}
|
|
3597
|
+
|
|
3429
3598
|
.lg\:px-8 {
|
|
3430
3599
|
padding-left: 2rem;
|
|
3431
3600
|
padding-right: 2rem;
|
package/frontend/src/api.js
CHANGED
|
@@ -135,6 +135,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
135
135
|
yield { document: doc };
|
|
136
136
|
}
|
|
137
137
|
},
|
|
138
|
+
getEstimatedDocumentCounts: function getEstimatedDocumentCounts() {
|
|
139
|
+
return client.post('', { action: 'Model.getEstimatedDocumentCounts' }).then(res => res.data);
|
|
140
|
+
},
|
|
138
141
|
streamDocumentChanges: async function* streamDocumentChanges(params, options = {}) {
|
|
139
142
|
const pollIntervalMs = 5000;
|
|
140
143
|
while (!options.signal?.aborted) {
|
|
@@ -385,6 +388,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
385
388
|
}
|
|
386
389
|
}
|
|
387
390
|
},
|
|
391
|
+
getEstimatedDocumentCounts: function getEstimatedDocumentCounts() {
|
|
392
|
+
return client.post('/Model/getEstimatedDocumentCounts', {}).then(res => res.data);
|
|
393
|
+
},
|
|
388
394
|
streamDocumentChanges: async function* streamDocumentChanges(params, options = {}) {
|
|
389
395
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
390
396
|
const url = window.MONGOOSE_STUDIO_CONFIG.baseURL + '/Model/streamDocumentChanges?' + new URLSearchParams(params).toString();
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<div class="flex" style="height: calc(100vh - 55px); height: calc(100dvh - 55px)">
|
|
2
|
-
<
|
|
3
|
-
|
|
2
|
+
<button
|
|
3
|
+
type="button"
|
|
4
|
+
class="fixed top-[65px] left-0 cursor-pointer bg-gray-100 rounded-r-md z-10 p-1 lg:hidden"
|
|
4
5
|
@click="hideSidebar = false"
|
|
5
|
-
v-show="hideSidebar"
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
v-show="hideSidebar !== false"
|
|
7
|
+
aria-label="Open chat history"
|
|
8
|
+
title="Open chat history">
|
|
9
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" class="w-5 h-5" fill="#5f6368"><path d="M360-120v-720h80v720h-80Zm160-160v-400l200 200-200 200Z"/></svg>
|
|
10
|
+
</button>
|
|
8
11
|
<button
|
|
9
12
|
class="fixed top-[65px] right-4 z-10 p-2 rounded-md shadow bg-white"
|
|
10
13
|
:class="hasWorkspace ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed bg-gray-50'"
|
|
@@ -17,12 +20,15 @@
|
|
|
17
20
|
<svg v-else xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 1a5 5 0 00-5 5v3H6a2 2 0 00-2 2v9a2 2 0 002 2h12a2 2 0 002-2v-9a2 2 0 00-2-2h-1V6a5 5 0 00-5-5zm-3 8V6a3 3 0 016 0v3H9zm9 2v9H6v-9h12z"/></svg>
|
|
18
21
|
</button>
|
|
19
22
|
<!-- Sidebar: Chat Threads -->
|
|
20
|
-
<aside
|
|
23
|
+
<aside
|
|
24
|
+
class="bg-white border-r overflow-y-auto overflow-x-hidden h-full transition-transform duration-300 ease-in-out z-20 w-64 fixed lg:relative"
|
|
25
|
+
:class="hideSidebar === false ? 'translate-x-0' : hideSidebar === true ? '-translate-x-full lg:hidden' : '-translate-x-full lg:translate-x-0'"
|
|
26
|
+
style="z-index: 10000">
|
|
21
27
|
<div class="flex items-center border-b border-gray-100 w-64 overflow-x-hidden">
|
|
22
28
|
<div class="p-1 ml-2 font-bold">Chat Threads</div>
|
|
23
29
|
<button
|
|
24
30
|
@click="hideSidebar = true"
|
|
25
|
-
class="ml-auto mr-2 p-2 rounded hover:bg-gray-200 focus:outline-none"
|
|
31
|
+
class="ml-auto mr-2 p-2 rounded hover:bg-gray-200 focus:outline-none lg:hidden"
|
|
26
32
|
aria-label="Close sidebar"
|
|
27
33
|
>
|
|
28
34
|
<svg xmlns="http://www.w3.org/2000/svg" style="h-5 w-5" viewBox="0 -960 960 960" class="w-5" fill="currentColor"><path d="M660-320v-320L500-480l160 160ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm120-80v-560H200v560h120Zm80 0h360v-560H400v560Zm-80 0H200h120Z"/></svg>
|
|
@@ -289,5 +289,31 @@
|
|
|
289
289
|
@close="closeScriptDrawer"
|
|
290
290
|
@refresh="handleScriptRefresh"
|
|
291
291
|
></execute-script>
|
|
292
|
+
<div
|
|
293
|
+
v-if="keyboardShortcuts.length > 0"
|
|
294
|
+
class="fixed bottom-4 left-4 z-40 group"
|
|
295
|
+
>
|
|
296
|
+
<button
|
|
297
|
+
type="button"
|
|
298
|
+
aria-label="Keyboard shortcuts"
|
|
299
|
+
title="Keyboard shortcuts"
|
|
300
|
+
class="rounded-full border border-slate-300 bg-white p-2 text-slate-700 shadow-sm transition-colors hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-ultramarine-500"
|
|
301
|
+
>
|
|
302
|
+
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true">
|
|
303
|
+
<rect x="2.5" y="6.5" width="19" height="11" rx="2" stroke-width="1.5"></rect>
|
|
304
|
+
<path d="M6 10.5h1.5M9 10.5h1.5M12 10.5h1.5M15 10.5h1.5M18 10.5h.01M6 13.5h1.5M9 13.5h6M16.5 13.5h1.5" stroke-width="1.5" stroke-linecap="round"></path>
|
|
305
|
+
</svg>
|
|
306
|
+
</button>
|
|
307
|
+
<div class="pointer-events-none absolute left-0 bottom-full mb-2 min-w-[220px] translate-y-1 rounded-lg bg-slate-900 px-3 py-2.5 text-slate-200 opacity-0 shadow-xl transition-all duration-150 group-hover:pointer-events-auto group-hover:translate-y-0 group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:translate-y-0 group-focus-within:opacity-100">
|
|
308
|
+
<div
|
|
309
|
+
v-for="shortcut in keyboardShortcuts"
|
|
310
|
+
:key="shortcut.command + shortcut.description"
|
|
311
|
+
class="flex items-center justify-between gap-3 text-xs"
|
|
312
|
+
>
|
|
313
|
+
<span class="font-mono font-semibold text-slate-50">{{shortcut.command}}</span>
|
|
314
|
+
<span class="text-slate-300">{{shortcut.description}}</span>
|
|
315
|
+
</div>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
292
318
|
</div>
|
|
293
319
|
</div>
|
|
@@ -40,11 +40,17 @@ module.exports = app => app.component('document', {
|
|
|
40
40
|
}),
|
|
41
41
|
async mounted() {
|
|
42
42
|
window.pageState = this;
|
|
43
|
+
if (typeof window !== 'undefined' && window.addEventListener) {
|
|
44
|
+
window.addEventListener('keydown', this.handleSaveShortcut);
|
|
45
|
+
}
|
|
43
46
|
// Store query parameters from the route (preserved from models page)
|
|
44
47
|
this.previousQuery = Object.assign({}, this.$route.query);
|
|
45
48
|
await this.refreshDocument({ force: true, source: 'initial' });
|
|
46
49
|
},
|
|
47
|
-
|
|
50
|
+
beforeUnmount() {
|
|
51
|
+
if (typeof window !== 'undefined' && window.removeEventListener) {
|
|
52
|
+
window.removeEventListener('keydown', this.handleSaveShortcut);
|
|
53
|
+
}
|
|
48
54
|
this.stopAutoRefresh();
|
|
49
55
|
},
|
|
50
56
|
computed: {
|
|
@@ -74,6 +80,13 @@ module.exports = app => app.component('document', {
|
|
|
74
80
|
canEdit() {
|
|
75
81
|
return this.canManipulate && this.viewMode === 'fields';
|
|
76
82
|
},
|
|
83
|
+
keyboardShortcuts() {
|
|
84
|
+
const shortcuts = [];
|
|
85
|
+
if (this.editting && this.canManipulate) {
|
|
86
|
+
shortcuts.push({ command: 'Ctrl + S', description: 'Save document' });
|
|
87
|
+
}
|
|
88
|
+
return shortcuts;
|
|
89
|
+
},
|
|
77
90
|
isLambda() {
|
|
78
91
|
return !!window?.MONGOOSE_STUDIO_CONFIG?.isLambda;
|
|
79
92
|
}
|
|
@@ -86,6 +99,19 @@ module.exports = app => app.component('document', {
|
|
|
86
99
|
}
|
|
87
100
|
},
|
|
88
101
|
methods: {
|
|
102
|
+
handleSaveShortcut(event) {
|
|
103
|
+
const key = typeof event?.key === 'string' ? event.key.toLowerCase() : '';
|
|
104
|
+
const isSaveShortcut = (event.ctrlKey || event.metaKey) && key === 's';
|
|
105
|
+
if (!isSaveShortcut) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!this.editting || !this.canManipulate) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
this.shouldShowConfirmModal = true;
|
|
114
|
+
},
|
|
89
115
|
cancelEdit() {
|
|
90
116
|
this.changes = {};
|
|
91
117
|
this.editting = false;
|
|
@@ -20,9 +20,15 @@
|
|
|
20
20
|
<li v-for="model in models">
|
|
21
21
|
<router-link
|
|
22
22
|
:to="'/model/' + model"
|
|
23
|
-
class="
|
|
23
|
+
class="flex items-center gap-2 rounded-md py-2 pr-2 pl-2 text-sm text-gray-700"
|
|
24
24
|
:class="model === currentModel ? 'bg-ultramarine-100 font-bold text-gray-900' : 'hover:bg-ultramarine-50'">
|
|
25
|
-
{{model}}
|
|
25
|
+
<span class="truncate">{{model}}</span>
|
|
26
|
+
<span
|
|
27
|
+
v-if="modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel"
|
|
28
|
+
class="ml-auto text-xs text-gray-500 bg-gray-100 rounded-md px-1 py-[2px]"
|
|
29
|
+
>
|
|
30
|
+
{{formatCompactCount(modelDocumentCounts[model])}}
|
|
31
|
+
</span>
|
|
26
32
|
</router-link>
|
|
27
33
|
</li>
|
|
28
34
|
</ul>
|
|
@@ -20,6 +20,7 @@ module.exports = app => app.component('models', {
|
|
|
20
20
|
data: () => ({
|
|
21
21
|
models: [],
|
|
22
22
|
currentModel: null,
|
|
23
|
+
modelDocumentCounts: {},
|
|
23
24
|
documents: [],
|
|
24
25
|
schemaPaths: [],
|
|
25
26
|
filteredPaths: [],
|
|
@@ -84,6 +85,7 @@ module.exports = app => app.component('models', {
|
|
|
84
85
|
document.addEventListener('click', this.onOutsideActionsMenuClick, true);
|
|
85
86
|
const { models, readyState } = await api.Model.listModels();
|
|
86
87
|
this.models = models;
|
|
88
|
+
await this.loadModelCounts();
|
|
87
89
|
if (this.currentModel == null && this.models.length > 0) {
|
|
88
90
|
this.currentModel = this.models[0];
|
|
89
91
|
}
|
|
@@ -589,6 +591,25 @@ module.exports = app => app.component('models', {
|
|
|
589
591
|
|
|
590
592
|
return value.toLocaleString();
|
|
591
593
|
},
|
|
594
|
+
formatCompactCount(value) {
|
|
595
|
+
if (typeof value !== 'number') {
|
|
596
|
+
return '—';
|
|
597
|
+
}
|
|
598
|
+
if (value < 1000) {
|
|
599
|
+
return `${value}`;
|
|
600
|
+
}
|
|
601
|
+
const formatValue = (number, suffix) => {
|
|
602
|
+
const rounded = (Math.round(number * 10) / 10).toFixed(1).replace(/\.0$/, '');
|
|
603
|
+
return `${rounded}${suffix}`;
|
|
604
|
+
};
|
|
605
|
+
if (value < 1000000) {
|
|
606
|
+
return formatValue(value / 1000, 'k');
|
|
607
|
+
}
|
|
608
|
+
if (value < 1000000000) {
|
|
609
|
+
return formatValue(value / 1000000, 'M');
|
|
610
|
+
}
|
|
611
|
+
return formatValue(value / 1000000000, 'B');
|
|
612
|
+
},
|
|
592
613
|
checkIndexLocation(indexName) {
|
|
593
614
|
if (this.schemaIndexes.find(x => x.name == indexName) && this.mongoDBIndexes.find(x => x.name == indexName)) {
|
|
594
615
|
return 'text-gray-500';
|
|
@@ -842,6 +863,19 @@ module.exports = app => app.component('models', {
|
|
|
842
863
|
} else {
|
|
843
864
|
this.selectMultiple = true;
|
|
844
865
|
}
|
|
866
|
+
},
|
|
867
|
+
async loadModelCounts() {
|
|
868
|
+
if (!Array.isArray(this.models) || this.models.length === 0) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
try {
|
|
872
|
+
const { counts } = await api.Model.getEstimatedDocumentCounts();
|
|
873
|
+
if (counts && typeof counts === 'object') {
|
|
874
|
+
this.modelDocumentCounts = counts;
|
|
875
|
+
}
|
|
876
|
+
} catch (err) {
|
|
877
|
+
console.error('Failed to load model document counts', err);
|
|
878
|
+
}
|
|
845
879
|
}
|
|
846
880
|
}
|
|
847
881
|
});
|
|
@@ -42,7 +42,7 @@ module.exports = app => app.component('navbar', {
|
|
|
42
42
|
return ['chat index', 'chat'].includes(this.$route.name);
|
|
43
43
|
},
|
|
44
44
|
taskView() {
|
|
45
|
-
return ['tasks'].includes(this.$route.name);
|
|
45
|
+
return ['tasks', 'taskByName', 'taskSingle'].includes(this.$route.name);
|
|
46
46
|
},
|
|
47
47
|
routeName() {
|
|
48
48
|
return this.$route.name;
|
package/frontend/src/routes.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
// Role-based access control configuration
|
|
4
4
|
const roleAccess = {
|
|
5
|
-
owner: ['root', 'model', 'document', 'dashboards', 'dashboard', 'team', 'chat'],
|
|
6
|
-
admin: ['root', 'model', 'document', 'dashboards', 'dashboard', 'team', 'chat'],
|
|
7
|
-
member: ['root', 'model', 'document', 'dashboards', 'dashboard', 'chat'],
|
|
5
|
+
owner: ['root', 'model', 'document', 'dashboards', 'dashboard', 'team', 'chat', 'tasks', 'taskByName', 'taskSingle'],
|
|
6
|
+
admin: ['root', 'model', 'document', 'dashboards', 'dashboard', 'team', 'chat', 'tasks', 'taskByName', 'taskSingle'],
|
|
7
|
+
member: ['root', 'model', 'document', 'dashboards', 'dashboard', 'chat', 'tasks', 'taskByName', 'taskSingle'],
|
|
8
8
|
readonly: ['root', 'model', 'document', 'chat'],
|
|
9
9
|
dashboards: ['dashboards', 'dashboard']
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const allowedRoutesForLocalDev = ['document', 'root', 'chat', 'model'];
|
|
12
|
+
const allowedRoutesForLocalDev = ['document', 'root', 'chat', 'model', 'tasks', 'taskByName', 'taskSingle'];
|
|
13
13
|
|
|
14
14
|
// Helper function to check if a role has access to a route
|
|
15
15
|
function hasAccess(roles, routeName) {
|
|
@@ -76,6 +76,22 @@ module.exports = {
|
|
|
76
76
|
authorized: true
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
|
+
{
|
|
80
|
+
path: '/tasks/:name',
|
|
81
|
+
name: 'taskByName',
|
|
82
|
+
component: 'task-by-name',
|
|
83
|
+
meta: {
|
|
84
|
+
authorized: true
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
path: '/tasks/:name/:id',
|
|
89
|
+
name: 'taskSingle',
|
|
90
|
+
component: 'task-single',
|
|
91
|
+
meta: {
|
|
92
|
+
authorized: true
|
|
93
|
+
}
|
|
94
|
+
},
|
|
79
95
|
{
|
|
80
96
|
path: '/chat',
|
|
81
97
|
name: 'chat index',
|