@meetreeve/ui 0.12.0 → 0.14.0
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/README.md +29 -0
- package/dist/index.d.mts +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.js +216 -199
- package/dist/index.mjs +215 -199
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -417,6 +417,44 @@ function useResponsivePlaceholder(desktop, mobile) {
|
|
|
417
417
|
return isDesktop ? desktop : mobile ?? desktop;
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
+
// src/info-tip.tsx
|
|
421
|
+
import { Popover } from "@base-ui/react/popover";
|
|
422
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
423
|
+
function InfoTip({ children, label = "More information", side = "top", align = "center", className }) {
|
|
424
|
+
return /* @__PURE__ */ jsxs3(Popover.Root, { children: [
|
|
425
|
+
/* @__PURE__ */ jsx3(
|
|
426
|
+
Popover.Trigger,
|
|
427
|
+
{
|
|
428
|
+
openOnHover: true,
|
|
429
|
+
delay: 150,
|
|
430
|
+
closeDelay: 100,
|
|
431
|
+
"aria-label": label,
|
|
432
|
+
style: TOUCH_TARGET_STYLE,
|
|
433
|
+
className: cn(
|
|
434
|
+
"group -my-3.5 inline-flex shrink-0 cursor-help items-center justify-center rounded-full align-middle text-muted-foreground outline-none transition-colors hover:text-foreground data-[popup-open]:text-foreground",
|
|
435
|
+
className
|
|
436
|
+
),
|
|
437
|
+
children: /* @__PURE__ */ jsx3(
|
|
438
|
+
"span",
|
|
439
|
+
{
|
|
440
|
+
"aria-hidden": "true",
|
|
441
|
+
className: "inline-flex size-4 items-center justify-center rounded-full border border-current text-[0.625rem] font-semibold leading-none group-focus-visible:ring-2 group-focus-visible:ring-ring/50",
|
|
442
|
+
children: "?"
|
|
443
|
+
}
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
),
|
|
447
|
+
/* @__PURE__ */ jsx3(Popover.Portal, { children: /* @__PURE__ */ jsx3(Popover.Positioner, { side, align, sideOffset: 8, collisionPadding: 16, className: "z-50", children: /* @__PURE__ */ jsx3(
|
|
448
|
+
Popover.Popup,
|
|
449
|
+
{
|
|
450
|
+
"aria-label": label,
|
|
451
|
+
className: "max-w-[min(20rem,calc(100vw-2rem))] origin-[var(--transform-origin)] rounded-md border border-border bg-popover px-3 py-2 text-left text-xs font-normal leading-relaxed text-popover-foreground shadow-md outline-none transition-[opacity,transform] duration-150 ease-out data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0 motion-reduce:transition-none",
|
|
452
|
+
children: /* @__PURE__ */ jsx3(Popover.Description, { children })
|
|
453
|
+
}
|
|
454
|
+
) }) })
|
|
455
|
+
] });
|
|
456
|
+
}
|
|
457
|
+
|
|
420
458
|
// src/app-sidebar.tsx
|
|
421
459
|
import { useCallback as useCallback3, useEffect as useEffect5, useId as useId3, useMemo, useRef as useRef4, useState as useState6 } from "react";
|
|
422
460
|
import { Menu as Menu2, PanelLeftClose, PanelLeftOpen, X as X2 } from "lucide-react";
|
|
@@ -699,7 +737,7 @@ function useLadderRung(ladder, containerRef, options = {}) {
|
|
|
699
737
|
|
|
700
738
|
// src/ladder/flyout.tsx
|
|
701
739
|
import { useCallback as useCallback2, useEffect as useEffect4, useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState5 } from "react";
|
|
702
|
-
import { jsx as
|
|
740
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
703
741
|
var PANEL_GAP = 4;
|
|
704
742
|
function Flyout({
|
|
705
743
|
label,
|
|
@@ -763,7 +801,7 @@ function Flyout({
|
|
|
763
801
|
useEffect4(() => {
|
|
764
802
|
if (clickOpen && panelPosition) firstItemRef.current?.focus();
|
|
765
803
|
}, [clickOpen, panelPosition]);
|
|
766
|
-
return /* @__PURE__ */
|
|
804
|
+
return /* @__PURE__ */ jsxs4(
|
|
767
805
|
"div",
|
|
768
806
|
{
|
|
769
807
|
"data-testid": "ladder-flyout",
|
|
@@ -771,7 +809,7 @@ function Flyout({
|
|
|
771
809
|
onMouseEnter: () => setHoverOpen(true),
|
|
772
810
|
onMouseLeave: () => setHoverOpen(false),
|
|
773
811
|
children: [
|
|
774
|
-
/* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ jsxs4(
|
|
775
813
|
"button",
|
|
776
814
|
{
|
|
777
815
|
ref: triggerRef,
|
|
@@ -794,7 +832,7 @@ function Flyout({
|
|
|
794
832
|
active ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground/70 hover:bg-sidebar-foreground/5 hover:text-sidebar-foreground"
|
|
795
833
|
),
|
|
796
834
|
children: [
|
|
797
|
-
/* @__PURE__ */
|
|
835
|
+
/* @__PURE__ */ jsx4(
|
|
798
836
|
Icon,
|
|
799
837
|
{
|
|
800
838
|
className: cn(
|
|
@@ -805,11 +843,11 @@ function Flyout({
|
|
|
805
843
|
"aria-hidden": "true"
|
|
806
844
|
}
|
|
807
845
|
),
|
|
808
|
-
/* @__PURE__ */
|
|
846
|
+
/* @__PURE__ */ jsx4("span", { className: cn("truncate", collapsed && "sr-only"), children: label })
|
|
809
847
|
]
|
|
810
848
|
}
|
|
811
849
|
),
|
|
812
|
-
open && panelPosition && /* @__PURE__ */
|
|
850
|
+
open && panelPosition && /* @__PURE__ */ jsx4(
|
|
813
851
|
"div",
|
|
814
852
|
{
|
|
815
853
|
ref: panelRef,
|
|
@@ -831,7 +869,7 @@ function Flyout({
|
|
|
831
869
|
// silently loses the focus-on-open behavior (a console ref
|
|
832
870
|
// warning, not a crash) — same tradeoff any Link-injection
|
|
833
871
|
// pattern accepts; not a regression from today's plain `<a>`.
|
|
834
|
-
/* @__PURE__ */
|
|
872
|
+
/* @__PURE__ */ jsx4(
|
|
835
873
|
LinkEl,
|
|
836
874
|
{
|
|
837
875
|
ref: i === 0 ? firstItemRef : void 0,
|
|
@@ -855,7 +893,7 @@ function Flyout({
|
|
|
855
893
|
}
|
|
856
894
|
|
|
857
895
|
// src/app-sidebar.tsx
|
|
858
|
-
import { Fragment as Fragment2, jsx as
|
|
896
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
859
897
|
var DEFAULT_COLLAPSE_STORAGE_KEY = "reeve-sidebar-collapsed";
|
|
860
898
|
var COLLAPSED_WIDTH_CLASS = "w-14";
|
|
861
899
|
var EXPANDED_WIDTH_CLASS = "w-64";
|
|
@@ -873,7 +911,7 @@ function NavLink({
|
|
|
873
911
|
}) {
|
|
874
912
|
const Icon = resolveIcon(icon);
|
|
875
913
|
const LinkEl = linkComponent ?? "a";
|
|
876
|
-
return /* @__PURE__ */
|
|
914
|
+
return /* @__PURE__ */ jsxs5(
|
|
877
915
|
LinkEl,
|
|
878
916
|
{
|
|
879
917
|
href,
|
|
@@ -893,7 +931,7 @@ function NavLink({
|
|
|
893
931
|
active ? "bg-sidebar-accent text-sidebar-accent-foreground" : "text-sidebar-foreground/70 hover:bg-sidebar-foreground/5 hover:text-sidebar-foreground"
|
|
894
932
|
),
|
|
895
933
|
children: [
|
|
896
|
-
/* @__PURE__ */
|
|
934
|
+
/* @__PURE__ */ jsx5(
|
|
897
935
|
Icon,
|
|
898
936
|
{
|
|
899
937
|
className: cn(
|
|
@@ -904,7 +942,7 @@ function NavLink({
|
|
|
904
942
|
"aria-hidden": "true"
|
|
905
943
|
}
|
|
906
944
|
),
|
|
907
|
-
/* @__PURE__ */
|
|
945
|
+
/* @__PURE__ */ jsx5("span", { className: cn("truncate", collapsed && "sr-only"), children: label })
|
|
908
946
|
]
|
|
909
947
|
}
|
|
910
948
|
);
|
|
@@ -992,7 +1030,7 @@ function AppSidebar({
|
|
|
992
1030
|
function renderAppItem(item, testIdPrefix, collapsedRow = false) {
|
|
993
1031
|
const def = moduleMap.get(item.moduleId);
|
|
994
1032
|
if (!def) return null;
|
|
995
|
-
return /* @__PURE__ */
|
|
1033
|
+
return /* @__PURE__ */ jsx5(
|
|
996
1034
|
NavLink,
|
|
997
1035
|
{
|
|
998
1036
|
href: def.href,
|
|
@@ -1018,7 +1056,7 @@ function AppSidebar({
|
|
|
1018
1056
|
};
|
|
1019
1057
|
});
|
|
1020
1058
|
const active = children.some((c) => c.active);
|
|
1021
|
-
return /* @__PURE__ */
|
|
1059
|
+
return /* @__PURE__ */ jsx5(
|
|
1022
1060
|
Flyout,
|
|
1023
1061
|
{
|
|
1024
1062
|
label: item.label,
|
|
@@ -1036,7 +1074,7 @@ function AppSidebar({
|
|
|
1036
1074
|
function brandBlockFor(collapsedMode) {
|
|
1037
1075
|
if (!brand) return null;
|
|
1038
1076
|
if (collapsedMode) {
|
|
1039
|
-
return /* @__PURE__ */
|
|
1077
|
+
return /* @__PURE__ */ jsxs5(
|
|
1040
1078
|
"a",
|
|
1041
1079
|
{
|
|
1042
1080
|
href: brand.href,
|
|
@@ -1044,28 +1082,28 @@ function AppSidebar({
|
|
|
1044
1082
|
title: brand.label,
|
|
1045
1083
|
className: "flex items-center justify-center border-b border-sidebar-border px-1 py-4",
|
|
1046
1084
|
children: [
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1085
|
+
/* @__PURE__ */ jsx5("span", { className: "sr-only", children: brand.label }),
|
|
1086
|
+
/* @__PURE__ */ jsx5(BrandGlyph, { brand: { name: brand.label }, size: "xl" })
|
|
1049
1087
|
]
|
|
1050
1088
|
}
|
|
1051
1089
|
);
|
|
1052
1090
|
}
|
|
1053
|
-
return /* @__PURE__ */
|
|
1091
|
+
return /* @__PURE__ */ jsxs5(
|
|
1054
1092
|
"a",
|
|
1055
1093
|
{
|
|
1056
1094
|
href: brand.href,
|
|
1057
1095
|
"data-testid": "app-sidebar-brand",
|
|
1058
1096
|
className: "flex items-center gap-2.5 border-b border-sidebar-border px-5 py-4 text-sidebar-foreground",
|
|
1059
1097
|
children: [
|
|
1060
|
-
/* @__PURE__ */
|
|
1061
|
-
/* @__PURE__ */
|
|
1098
|
+
/* @__PURE__ */ jsx5("span", { className: "grid size-7 place-items-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground", children: /* @__PURE__ */ jsx5("span", { className: "font-mono text-sm font-bold", children: (brand.label[0] ?? "r").toUpperCase() }) }),
|
|
1099
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate text-sm font-semibold tracking-tight", children: brand.label })
|
|
1062
1100
|
]
|
|
1063
1101
|
}
|
|
1064
1102
|
);
|
|
1065
1103
|
}
|
|
1066
1104
|
function topItemBlock(testId, collapsedMode = false) {
|
|
1067
1105
|
if (!topItem) return null;
|
|
1068
|
-
return /* @__PURE__ */
|
|
1106
|
+
return /* @__PURE__ */ jsx5("div", { className: cn("px-3 pt-4", collapsedMode && "flex justify-center px-0"), children: /* @__PURE__ */ jsx5(
|
|
1069
1107
|
NavLink,
|
|
1070
1108
|
{
|
|
1071
1109
|
href: topItem.href,
|
|
@@ -1078,8 +1116,8 @@ function AppSidebar({
|
|
|
1078
1116
|
}
|
|
1079
1117
|
) });
|
|
1080
1118
|
}
|
|
1081
|
-
return /* @__PURE__ */
|
|
1082
|
-
!isDesktop && /* @__PURE__ */
|
|
1119
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1120
|
+
!isDesktop && /* @__PURE__ */ jsx5(
|
|
1083
1121
|
"button",
|
|
1084
1122
|
{
|
|
1085
1123
|
ref: mobileTriggerRef,
|
|
@@ -1091,11 +1129,11 @@ function AppSidebar({
|
|
|
1091
1129
|
onClick: () => setMobileOpen((v) => !v),
|
|
1092
1130
|
style: TOUCH_TARGET_STYLE,
|
|
1093
1131
|
className: "flex items-center justify-center rounded-md border border-border p-2 text-foreground",
|
|
1094
|
-
children: mobileOpen ? /* @__PURE__ */
|
|
1132
|
+
children: mobileOpen ? /* @__PURE__ */ jsx5(X2, { className: "h-5 w-5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx5(Menu2, { className: "h-5 w-5", "aria-hidden": "true" })
|
|
1095
1133
|
}
|
|
1096
1134
|
),
|
|
1097
|
-
!isDesktop && mobileOpen && /* @__PURE__ */
|
|
1098
|
-
/* @__PURE__ */
|
|
1135
|
+
!isDesktop && mobileOpen && /* @__PURE__ */ jsxs5("div", { className: "fixed inset-0 z-50", children: [
|
|
1136
|
+
/* @__PURE__ */ jsx5(
|
|
1099
1137
|
"div",
|
|
1100
1138
|
{
|
|
1101
1139
|
"data-testid": "app-sidebar-mobile-scrim",
|
|
@@ -1104,7 +1142,7 @@ function AppSidebar({
|
|
|
1104
1142
|
onClick: () => setMobileOpen(false)
|
|
1105
1143
|
}
|
|
1106
1144
|
),
|
|
1107
|
-
/* @__PURE__ */
|
|
1145
|
+
/* @__PURE__ */ jsxs5(
|
|
1108
1146
|
"div",
|
|
1109
1147
|
{
|
|
1110
1148
|
ref: mobileDrawerRef,
|
|
@@ -1115,7 +1153,7 @@ function AppSidebar({
|
|
|
1115
1153
|
"data-testid": "app-sidebar-mobile-drawer",
|
|
1116
1154
|
className: "absolute inset-y-0 left-0 flex w-72 flex-col overflow-y-auto border-r border-sidebar-border bg-sidebar",
|
|
1117
1155
|
children: [
|
|
1118
|
-
/* @__PURE__ */
|
|
1156
|
+
/* @__PURE__ */ jsx5("div", { className: "sticky top-0 z-10 flex justify-end bg-sidebar p-2", children: /* @__PURE__ */ jsx5(
|
|
1119
1157
|
"button",
|
|
1120
1158
|
{
|
|
1121
1159
|
ref: mobileCloseRef,
|
|
@@ -1125,19 +1163,19 @@ function AppSidebar({
|
|
|
1125
1163
|
onClick: () => setMobileOpen(false),
|
|
1126
1164
|
style: TOUCH_TARGET_STYLE,
|
|
1127
1165
|
className: "flex items-center justify-center rounded-md p-2 text-sidebar-foreground/70 hover:bg-sidebar-foreground/5 hover:text-sidebar-foreground",
|
|
1128
|
-
children: /* @__PURE__ */
|
|
1166
|
+
children: /* @__PURE__ */ jsx5(X2, { className: "h-5 w-5", "aria-hidden": "true" })
|
|
1129
1167
|
}
|
|
1130
1168
|
) }),
|
|
1131
1169
|
brandBlockFor(false),
|
|
1132
1170
|
topItemBlock("app-sidebar-mobile-top-item"),
|
|
1133
|
-
/* @__PURE__ */
|
|
1171
|
+
/* @__PURE__ */ jsx5("nav", { className: "flex-1 px-3 py-4", children: /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", children: rung0.items.map(
|
|
1134
1172
|
(item) => item.type === "app" ? renderAppItem(item, "app-sidebar-mobile-navlink") : null
|
|
1135
1173
|
) }) })
|
|
1136
1174
|
]
|
|
1137
1175
|
}
|
|
1138
1176
|
)
|
|
1139
1177
|
] }),
|
|
1140
|
-
/* @__PURE__ */
|
|
1178
|
+
/* @__PURE__ */ jsxs5(
|
|
1141
1179
|
"aside",
|
|
1142
1180
|
{
|
|
1143
1181
|
"data-testid": "app-sidebar-desktop",
|
|
@@ -1152,18 +1190,18 @@ function AppSidebar({
|
|
|
1152
1190
|
children: [
|
|
1153
1191
|
brandBlockFor(collapsed),
|
|
1154
1192
|
topItemBlock("app-sidebar-top-item", collapsed),
|
|
1155
|
-
/* @__PURE__ */
|
|
1193
|
+
/* @__PURE__ */ jsx5(
|
|
1156
1194
|
"nav",
|
|
1157
1195
|
{
|
|
1158
1196
|
ref: containerRef,
|
|
1159
1197
|
"data-testid": "app-sidebar-nav",
|
|
1160
1198
|
className: "flex-1 overflow-y-auto px-3 py-4",
|
|
1161
|
-
children: /* @__PURE__ */
|
|
1199
|
+
children: /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", children: rung.items.map(
|
|
1162
1200
|
(item) => item.type === "app" ? renderAppItem(item, "app-sidebar-navlink", collapsed) : renderGroupItem(item, collapsed)
|
|
1163
1201
|
) })
|
|
1164
1202
|
}
|
|
1165
1203
|
),
|
|
1166
|
-
collapsible && /* @__PURE__ */
|
|
1204
|
+
collapsible && /* @__PURE__ */ jsx5("div", { className: "border-t border-sidebar-border px-2 py-2", children: /* @__PURE__ */ jsxs5(
|
|
1167
1205
|
"button",
|
|
1168
1206
|
{
|
|
1169
1207
|
type: "button",
|
|
@@ -1177,8 +1215,8 @@ function AppSidebar({
|
|
|
1177
1215
|
collapsed && "justify-center px-0"
|
|
1178
1216
|
),
|
|
1179
1217
|
children: [
|
|
1180
|
-
collapsed ? /* @__PURE__ */
|
|
1181
|
-
/* @__PURE__ */
|
|
1218
|
+
collapsed ? /* @__PURE__ */ jsx5(PanelLeftOpen, { className: "size-4 shrink-0", strokeWidth: 1.5, "aria-hidden": "true" }) : /* @__PURE__ */ jsx5(PanelLeftClose, { className: "size-4 shrink-0", strokeWidth: 1.5, "aria-hidden": "true" }),
|
|
1219
|
+
/* @__PURE__ */ jsx5("span", { className: cn("truncate", collapsed && "sr-only"), children: collapsed ? "Expand sidebar" : "Collapse sidebar" })
|
|
1182
1220
|
]
|
|
1183
1221
|
}
|
|
1184
1222
|
) })
|
|
@@ -1217,19 +1255,19 @@ function groupItemsByOrg(rows, get) {
|
|
|
1217
1255
|
|
|
1218
1256
|
// src/lib/dropdown-menu.tsx
|
|
1219
1257
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
1220
|
-
import { jsx as
|
|
1258
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1221
1259
|
function DropdownMenu(props) {
|
|
1222
|
-
return /* @__PURE__ */
|
|
1260
|
+
return /* @__PURE__ */ jsx6(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
1223
1261
|
}
|
|
1224
1262
|
function DropdownMenuTrigger(props) {
|
|
1225
|
-
return /* @__PURE__ */
|
|
1263
|
+
return /* @__PURE__ */ jsx6(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
1226
1264
|
}
|
|
1227
1265
|
function DropdownMenuContent({
|
|
1228
1266
|
className,
|
|
1229
1267
|
sideOffset = 4,
|
|
1230
1268
|
...props
|
|
1231
1269
|
}) {
|
|
1232
|
-
return /* @__PURE__ */
|
|
1270
|
+
return /* @__PURE__ */ jsx6(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx6(
|
|
1233
1271
|
DropdownMenuPrimitive.Content,
|
|
1234
1272
|
{
|
|
1235
1273
|
"data-slot": "dropdown-menu-content",
|
|
@@ -1246,7 +1284,7 @@ function DropdownMenuItem({
|
|
|
1246
1284
|
className,
|
|
1247
1285
|
...props
|
|
1248
1286
|
}) {
|
|
1249
|
-
return /* @__PURE__ */
|
|
1287
|
+
return /* @__PURE__ */ jsx6(
|
|
1250
1288
|
DropdownMenuPrimitive.Item,
|
|
1251
1289
|
{
|
|
1252
1290
|
"data-slot": "dropdown-menu-item",
|
|
@@ -1262,7 +1300,7 @@ function DropdownMenuLabel({
|
|
|
1262
1300
|
className,
|
|
1263
1301
|
...props
|
|
1264
1302
|
}) {
|
|
1265
|
-
return /* @__PURE__ */
|
|
1303
|
+
return /* @__PURE__ */ jsx6(
|
|
1266
1304
|
DropdownMenuPrimitive.Label,
|
|
1267
1305
|
{
|
|
1268
1306
|
"data-slot": "dropdown-menu-label",
|
|
@@ -1273,7 +1311,7 @@ function DropdownMenuLabel({
|
|
|
1273
1311
|
}
|
|
1274
1312
|
|
|
1275
1313
|
// src/context-switcher.tsx
|
|
1276
|
-
import { Fragment as Fragment3, jsx as
|
|
1314
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1277
1315
|
function groupByOrg(items) {
|
|
1278
1316
|
return groupItemsByOrg(items, {
|
|
1279
1317
|
orgId: (it) => it.orgId,
|
|
@@ -1304,29 +1342,29 @@ function ContextSwitcher({
|
|
|
1304
1342
|
const active = items.find((it) => it.refId === activeRefId) ?? null;
|
|
1305
1343
|
const groups = groupByOrg(items);
|
|
1306
1344
|
const showOrgHeaders = groups.length > 1;
|
|
1307
|
-
return /* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1345
|
+
return /* @__PURE__ */ jsxs6(DropdownMenu, { children: [
|
|
1346
|
+
/* @__PURE__ */ jsx7(DropdownMenuTrigger, { asChild: true, children: collapsed ? /* @__PURE__ */ jsx7(
|
|
1309
1347
|
"button",
|
|
1310
1348
|
{
|
|
1311
1349
|
type: "button",
|
|
1312
1350
|
title: active?.name || placeholder,
|
|
1313
1351
|
"aria-label": active?.name || placeholder,
|
|
1314
1352
|
className: "flex h-10 w-10 items-center justify-center rounded-lg text-sidebar-foreground/70 transition-colors hover:bg-sidebar-foreground/5 hover:text-sidebar-foreground",
|
|
1315
|
-
children: /* @__PURE__ */
|
|
1353
|
+
children: /* @__PURE__ */ jsx7(BrandGlyph, { brand: toBrand(active ?? { name: "" }), size: "lg" })
|
|
1316
1354
|
}
|
|
1317
|
-
) : /* @__PURE__ */
|
|
1355
|
+
) : /* @__PURE__ */ jsxs6(
|
|
1318
1356
|
"button",
|
|
1319
1357
|
{
|
|
1320
1358
|
type: "button",
|
|
1321
1359
|
className: "group flex items-center gap-2 rounded-md border border-sidebar-border bg-sidebar-accent/60 px-2.5 py-1.5 text-sm font-medium transition-colors hover:bg-sidebar",
|
|
1322
1360
|
children: [
|
|
1323
|
-
/* @__PURE__ */
|
|
1324
|
-
/* @__PURE__ */
|
|
1325
|
-
/* @__PURE__ */
|
|
1361
|
+
/* @__PURE__ */ jsx7(BrandGlyph, { brand: toBrand(active ?? { name: "" }) }),
|
|
1362
|
+
/* @__PURE__ */ jsx7("span", { className: "max-w-[140px] truncate text-sidebar-accent-foreground", children: active?.name || placeholder }),
|
|
1363
|
+
/* @__PURE__ */ jsx7(ChevronDown, { className: "h-3.5 w-3.5 text-sidebar-foreground/70 transition-transform group-data-[state=open]:rotate-180" })
|
|
1326
1364
|
]
|
|
1327
1365
|
}
|
|
1328
1366
|
) }),
|
|
1329
|
-
/* @__PURE__ */
|
|
1367
|
+
/* @__PURE__ */ jsxs6(
|
|
1330
1368
|
DropdownMenuContent,
|
|
1331
1369
|
{
|
|
1332
1370
|
side,
|
|
@@ -1335,31 +1373,31 @@ function ContextSwitcher({
|
|
|
1335
1373
|
collisionPadding: 8,
|
|
1336
1374
|
className: cn("w-60 overflow-hidden p-0", contentClassName),
|
|
1337
1375
|
children: [
|
|
1338
|
-
groups.map((group) => /* @__PURE__ */
|
|
1339
|
-
showOrgHeaders && /* @__PURE__ */
|
|
1340
|
-
/* @__PURE__ */
|
|
1376
|
+
groups.map((group) => /* @__PURE__ */ jsxs6("div", { children: [
|
|
1377
|
+
showOrgHeaders && /* @__PURE__ */ jsx7(DropdownMenuLabel, { className: "px-3 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: group.orgName ?? "Other" }),
|
|
1378
|
+
/* @__PURE__ */ jsx7("div", { className: cn(showOrgHeaders && "ml-5 border-l border-border/60"), children: group.items.map((item) => {
|
|
1341
1379
|
const isActive = item.refId === activeRefId;
|
|
1342
|
-
return /* @__PURE__ */
|
|
1380
|
+
return /* @__PURE__ */ jsxs6(
|
|
1343
1381
|
DropdownMenuItem,
|
|
1344
1382
|
{
|
|
1345
1383
|
"data-active": isActive || void 0,
|
|
1346
1384
|
onSelect: () => onSelect(item),
|
|
1347
1385
|
className: "flex w-full items-center gap-2.5 rounded-none px-3 py-2 text-sm",
|
|
1348
1386
|
children: [
|
|
1349
|
-
/* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
item.kindLabel && /* @__PURE__ */
|
|
1387
|
+
/* @__PURE__ */ jsx7(BrandGlyph, { brand: toBrand(item), subtle: true }),
|
|
1388
|
+
/* @__PURE__ */ jsx7("span", { className: "flex-1 truncate text-left text-foreground/90", children: item.name }),
|
|
1389
|
+
item.kindLabel && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1352
1390
|
" ",
|
|
1353
|
-
/* @__PURE__ */
|
|
1391
|
+
/* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: item.kindLabel })
|
|
1354
1392
|
] }),
|
|
1355
|
-
isActive && /* @__PURE__ */
|
|
1393
|
+
isActive && /* @__PURE__ */ jsx7(Check, { className: "size-3.5 text-emerald-500" })
|
|
1356
1394
|
]
|
|
1357
1395
|
},
|
|
1358
1396
|
item.refId
|
|
1359
1397
|
);
|
|
1360
1398
|
}) })
|
|
1361
1399
|
] }, group.orgId ?? "unattributed")),
|
|
1362
|
-
footer && /* @__PURE__ */
|
|
1400
|
+
footer && /* @__PURE__ */ jsx7("div", { className: "sticky bottom-0 border-t border-border bg-popover", children: footer })
|
|
1363
1401
|
]
|
|
1364
1402
|
}
|
|
1365
1403
|
)
|
|
@@ -1368,7 +1406,7 @@ function ContextSwitcher({
|
|
|
1368
1406
|
|
|
1369
1407
|
// src/connector-picker.tsx
|
|
1370
1408
|
import { useCallback as useCallback4, useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "react";
|
|
1371
|
-
import { Fragment as Fragment4, jsx as
|
|
1409
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1372
1410
|
var DEFAULT_CONNECT_ERROR = "Couldn't start the connection. Please try again.";
|
|
1373
1411
|
var MAX_RECONNECT_REFOCUS_CHECKS = 3;
|
|
1374
1412
|
var RECONNECT_UNCONFIRMED_ERROR = "Couldn't confirm the reconnect \u2014 the connection still reports unhealthy. Try again, or disconnect and reconnect.";
|
|
@@ -1377,7 +1415,6 @@ var DEFAULT_LOAD_ERROR = "Couldn't load connections. Please try again.";
|
|
|
1377
1415
|
var DEFAULT_GRANTS_LOAD_ERROR = "Couldn't load sharing. Please try again.";
|
|
1378
1416
|
var DEFAULT_GRANT_ERROR = "Couldn't share. Please try again.";
|
|
1379
1417
|
var DEFAULT_REVOKE_ERROR = "Couldn't revoke access. Please try again.";
|
|
1380
|
-
var DEFAULT_ORG_DISABLED_REASON = "Org-wide connections aren't available to you.";
|
|
1381
1418
|
var DEFAULT_CREDENTIAL_ERROR = "Couldn't save that credential. Please try again.";
|
|
1382
1419
|
var DEFAULT_CREDENTIAL_TEST_ERROR = "Couldn't test that credential. Please try again.";
|
|
1383
1420
|
var DEFAULT_RECONNECT_MESSAGE = "This connection needs to be reconnected to keep working.";
|
|
@@ -1396,11 +1433,6 @@ function capabilityLabel(capability) {
|
|
|
1396
1433
|
if (capability === "write") return "Write only";
|
|
1397
1434
|
return "Read & write";
|
|
1398
1435
|
}
|
|
1399
|
-
function formatSince(since) {
|
|
1400
|
-
const parsed = new Date(since);
|
|
1401
|
-
if (Number.isNaN(parsed.getTime())) return since;
|
|
1402
|
-
return parsed.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
1403
|
-
}
|
|
1404
1436
|
function errorMessageFrom(err, fallback) {
|
|
1405
1437
|
return err instanceof Error && err.message ? err.message : fallback;
|
|
1406
1438
|
}
|
|
@@ -1622,35 +1654,35 @@ function ConnectorPicker({
|
|
|
1622
1654
|
);
|
|
1623
1655
|
const ownEntries = entries?.filter((entry) => !isSharedWithViewer(entry)) ?? null;
|
|
1624
1656
|
const sharedEntries = entries?.filter(isSharedWithViewer) ?? [];
|
|
1625
|
-
return /* @__PURE__ */
|
|
1626
|
-
/* @__PURE__ */
|
|
1627
|
-
entries === null && !loadError && Array.from({ length: SKELETON_COUNT }).map((_, i) => /* @__PURE__ */
|
|
1657
|
+
return /* @__PURE__ */ jsxs7("div", { "data-testid": "connector-picker", "data-layout": layout, className: "flex flex-col gap-4", children: [
|
|
1658
|
+
/* @__PURE__ */ jsxs7("div", { className: containerClassName, children: [
|
|
1659
|
+
entries === null && !loadError && Array.from({ length: SKELETON_COUNT }).map((_, i) => /* @__PURE__ */ jsxs7(
|
|
1628
1660
|
"div",
|
|
1629
1661
|
{
|
|
1630
1662
|
"data-testid": "connector-picker-skeleton-item",
|
|
1631
1663
|
"aria-hidden": "true",
|
|
1632
1664
|
className: "flex items-center gap-3 rounded-lg border border-border p-3",
|
|
1633
1665
|
children: [
|
|
1634
|
-
/* @__PURE__ */
|
|
1635
|
-
/* @__PURE__ */
|
|
1666
|
+
/* @__PURE__ */ jsx8("span", { className: "h-8 w-8 shrink-0 animate-pulse rounded bg-foreground/10" }),
|
|
1667
|
+
/* @__PURE__ */ jsx8("span", { className: "h-3 flex-1 animate-pulse rounded bg-foreground/10" })
|
|
1636
1668
|
]
|
|
1637
1669
|
},
|
|
1638
1670
|
i
|
|
1639
1671
|
)),
|
|
1640
|
-
loadError && /* @__PURE__ */
|
|
1672
|
+
loadError && /* @__PURE__ */ jsxs7(
|
|
1641
1673
|
"div",
|
|
1642
1674
|
{
|
|
1643
1675
|
role: "alert",
|
|
1644
1676
|
"data-testid": "connector-picker-load-error",
|
|
1645
1677
|
className: "flex items-center justify-between gap-3 rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive",
|
|
1646
1678
|
children: [
|
|
1647
|
-
/* @__PURE__ */
|
|
1648
|
-
/* @__PURE__ */
|
|
1679
|
+
/* @__PURE__ */ jsx8("span", { children: loadError }),
|
|
1680
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: () => void load(), className: "shrink-0 underline", children: "Retry" })
|
|
1649
1681
|
]
|
|
1650
1682
|
}
|
|
1651
1683
|
),
|
|
1652
|
-
entries !== null && entries.length === 0 && !loadError && /* @__PURE__ */
|
|
1653
|
-
ownEntries?.map((entry) => /* @__PURE__ */
|
|
1684
|
+
entries !== null && entries.length === 0 && !loadError && /* @__PURE__ */ jsx8("p", { "data-testid": "connector-picker-empty", className: "text-sm text-muted-foreground", children: "No connections available." }),
|
|
1685
|
+
ownEntries?.map((entry) => /* @__PURE__ */ jsx8(
|
|
1654
1686
|
ConnectorTile,
|
|
1655
1687
|
{
|
|
1656
1688
|
entry,
|
|
@@ -1670,9 +1702,9 @@ function ConnectorPicker({
|
|
|
1670
1702
|
entry.slug
|
|
1671
1703
|
))
|
|
1672
1704
|
] }),
|
|
1673
|
-
sharedEntries.length > 0 && /* @__PURE__ */
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
/* @__PURE__ */
|
|
1705
|
+
sharedEntries.length > 0 && /* @__PURE__ */ jsxs7("section", { "data-testid": "connector-picker-shared-with-me", className: "flex flex-col gap-2", children: [
|
|
1706
|
+
/* @__PURE__ */ jsx8("h3", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Shared with me" }),
|
|
1707
|
+
/* @__PURE__ */ jsx8("div", { className: containerClassName, children: sharedEntries.map((entry) => /* @__PURE__ */ jsx8(
|
|
1676
1708
|
ConnectorTile,
|
|
1677
1709
|
{
|
|
1678
1710
|
entry,
|
|
@@ -1724,11 +1756,11 @@ function ConnectorTile({
|
|
|
1724
1756
|
const guide = entry.guide ?? null;
|
|
1725
1757
|
const canSetUp = !isConnected && (pasteSupported || guide !== null);
|
|
1726
1758
|
const orgPermitted = entry.org_connect?.permitted === true;
|
|
1727
|
-
const
|
|
1759
|
+
const connectKind = orgPermitted ? kind : "personal";
|
|
1728
1760
|
const attribution = ownerLabel(entry);
|
|
1729
1761
|
const canDisconnect = isConnected && !shared;
|
|
1730
1762
|
const canManageSharing = isConnected && entry.connection.owned_by_viewer === true && grantsSupported;
|
|
1731
|
-
return /* @__PURE__ */
|
|
1763
|
+
return /* @__PURE__ */ jsxs7(
|
|
1732
1764
|
"div",
|
|
1733
1765
|
{
|
|
1734
1766
|
"data-testid": `connector-tile-${entry.slug}`,
|
|
@@ -1736,12 +1768,12 @@ function ConnectorTile({
|
|
|
1736
1768
|
"data-deprecated": entry.deprecated || void 0,
|
|
1737
1769
|
className: cn("flex flex-col p-3", layout === "tiles" && "rounded-lg border border-border"),
|
|
1738
1770
|
children: [
|
|
1739
|
-
/* @__PURE__ */
|
|
1740
|
-
/* @__PURE__ */
|
|
1741
|
-
/* @__PURE__ */
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
/* @__PURE__ */
|
|
1744
|
-
entry.deprecated && /* @__PURE__ */
|
|
1771
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
1772
|
+
/* @__PURE__ */ jsx8(BrandGlyph, { brand: { name: entry.name, logo: entry.logo }, size: "lg" }),
|
|
1773
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
1774
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1775
|
+
/* @__PURE__ */ jsx8("p", { className: "truncate text-sm font-medium", children: entry.name }),
|
|
1776
|
+
entry.deprecated && /* @__PURE__ */ jsx8(
|
|
1745
1777
|
"span",
|
|
1746
1778
|
{
|
|
1747
1779
|
"data-testid": `connector-deprecated-${entry.slug}`,
|
|
@@ -1750,22 +1782,24 @@ function ConnectorTile({
|
|
|
1750
1782
|
}
|
|
1751
1783
|
)
|
|
1752
1784
|
] }),
|
|
1753
|
-
/* @__PURE__ */
|
|
1754
|
-
/* @__PURE__ */
|
|
1755
|
-
|
|
1756
|
-
/* @__PURE__ */
|
|
1757
|
-
/* @__PURE__ */
|
|
1785
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1786
|
+
/* @__PURE__ */ jsx8("span", { "data-testid": `connector-capability-${entry.slug}`, children: capabilityLabel(entry.capability) }),
|
|
1787
|
+
isConnected && /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1788
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
1789
|
+
/* @__PURE__ */ jsxs7(
|
|
1790
|
+
"span",
|
|
1791
|
+
{
|
|
1792
|
+
"data-testid": `connector-connected-${entry.slug}`,
|
|
1793
|
+
className: "inline-flex items-center gap-1",
|
|
1794
|
+
children: [
|
|
1795
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "h-1.5 w-1.5 rounded-full bg-emerald-500" }),
|
|
1796
|
+
"Connected"
|
|
1797
|
+
]
|
|
1798
|
+
}
|
|
1799
|
+
)
|
|
1758
1800
|
] })
|
|
1759
1801
|
] }),
|
|
1760
|
-
isConnected && /* @__PURE__ */
|
|
1761
|
-
"p",
|
|
1762
|
-
{
|
|
1763
|
-
"data-testid": `connector-connected-since-${entry.slug}`,
|
|
1764
|
-
className: "text-xs text-muted-foreground",
|
|
1765
|
-
children: entry.connection.since ? `Connected since ${formatSince(entry.connection.since)}` : "Connected"
|
|
1766
|
-
}
|
|
1767
|
-
),
|
|
1768
|
-
isConnected && !shared && entry.connection.account_label && /* @__PURE__ */ jsxs6(
|
|
1802
|
+
isConnected && !shared && entry.connection.account_label && /* @__PURE__ */ jsxs7(
|
|
1769
1803
|
"p",
|
|
1770
1804
|
{
|
|
1771
1805
|
"data-testid": `connector-account-${entry.slug}`,
|
|
@@ -1776,7 +1810,7 @@ function ConnectorTile({
|
|
|
1776
1810
|
]
|
|
1777
1811
|
}
|
|
1778
1812
|
),
|
|
1779
|
-
isConnected && entry.access_summary && /* @__PURE__ */
|
|
1813
|
+
isConnected && entry.access_summary && /* @__PURE__ */ jsx8(
|
|
1780
1814
|
"p",
|
|
1781
1815
|
{
|
|
1782
1816
|
"data-testid": `connector-access-summary-${entry.slug}`,
|
|
@@ -1784,7 +1818,7 @@ function ConnectorTile({
|
|
|
1784
1818
|
children: entry.access_summary
|
|
1785
1819
|
}
|
|
1786
1820
|
),
|
|
1787
|
-
unhealthy && /* @__PURE__ */
|
|
1821
|
+
unhealthy && /* @__PURE__ */ jsx8(
|
|
1788
1822
|
"p",
|
|
1789
1823
|
{
|
|
1790
1824
|
role: "alert",
|
|
@@ -1793,7 +1827,7 @@ function ConnectorTile({
|
|
|
1793
1827
|
children: DEFAULT_RECONNECT_MESSAGE
|
|
1794
1828
|
}
|
|
1795
1829
|
),
|
|
1796
|
-
attribution && /* @__PURE__ */
|
|
1830
|
+
attribution && /* @__PURE__ */ jsx8(
|
|
1797
1831
|
"p",
|
|
1798
1832
|
{
|
|
1799
1833
|
"data-testid": `connector-owner-${entry.slug}`,
|
|
@@ -1801,7 +1835,7 @@ function ConnectorTile({
|
|
|
1801
1835
|
children: attribution
|
|
1802
1836
|
}
|
|
1803
1837
|
),
|
|
1804
|
-
!isConnected && /* @__PURE__ */
|
|
1838
|
+
!isConnected && orgPermitted && /* @__PURE__ */ jsxs7(
|
|
1805
1839
|
"div",
|
|
1806
1840
|
{
|
|
1807
1841
|
"data-testid": `connector-kind-toggle-${entry.slug}`,
|
|
@@ -1809,13 +1843,14 @@ function ConnectorTile({
|
|
|
1809
1843
|
"aria-label": "Connect as",
|
|
1810
1844
|
className: "mt-1 flex items-center gap-1",
|
|
1811
1845
|
children: [
|
|
1812
|
-
/* @__PURE__ */
|
|
1846
|
+
/* @__PURE__ */ jsx8(
|
|
1813
1847
|
"button",
|
|
1814
1848
|
{
|
|
1815
1849
|
type: "button",
|
|
1816
1850
|
"data-testid": `connector-kind-personal-${entry.slug}`,
|
|
1817
1851
|
"aria-pressed": kind === "personal",
|
|
1818
1852
|
disabled: isConnecting,
|
|
1853
|
+
title: "Just for you",
|
|
1819
1854
|
onClick: () => setKind("personal"),
|
|
1820
1855
|
className: cn(
|
|
1821
1856
|
"rounded-full border px-2 py-0.5 text-[11px]",
|
|
@@ -1825,37 +1860,30 @@ function ConnectorTile({
|
|
|
1825
1860
|
children: "Personal"
|
|
1826
1861
|
}
|
|
1827
1862
|
),
|
|
1828
|
-
/* @__PURE__ */
|
|
1863
|
+
/* @__PURE__ */ jsx8(
|
|
1829
1864
|
"button",
|
|
1830
1865
|
{
|
|
1831
1866
|
type: "button",
|
|
1832
1867
|
"data-testid": `connector-kind-org-${entry.slug}`,
|
|
1833
1868
|
"aria-pressed": kind === "org",
|
|
1834
|
-
disabled: isConnecting
|
|
1835
|
-
title:
|
|
1869
|
+
disabled: isConnecting,
|
|
1870
|
+
title: "For your whole org",
|
|
1836
1871
|
onClick: () => setKind("org"),
|
|
1837
1872
|
className: cn(
|
|
1838
1873
|
"rounded-full border px-2 py-0.5 text-[11px]",
|
|
1839
1874
|
kind === "org" ? "border-primary bg-primary/10 font-medium" : "border-border text-muted-foreground",
|
|
1840
1875
|
"disabled:opacity-50"
|
|
1841
1876
|
),
|
|
1842
|
-
children:
|
|
1843
|
-
"Org",
|
|
1844
|
-
!orgPermitted && /* @__PURE__ */ jsxs6("span", { className: "sr-only", children: [
|
|
1845
|
-
" (",
|
|
1846
|
-
orgDisabledReason,
|
|
1847
|
-
")"
|
|
1848
|
-
] })
|
|
1849
|
-
]
|
|
1877
|
+
children: "Org"
|
|
1850
1878
|
}
|
|
1851
1879
|
)
|
|
1852
1880
|
]
|
|
1853
1881
|
}
|
|
1854
1882
|
),
|
|
1855
|
-
errorMessage && /* @__PURE__ */
|
|
1883
|
+
errorMessage && /* @__PURE__ */ jsx8("p", { role: "alert", "data-testid": `connector-error-${entry.slug}`, className: "text-xs text-destructive", children: errorMessage })
|
|
1856
1884
|
] }),
|
|
1857
|
-
isConnected ? /* @__PURE__ */
|
|
1858
|
-
unhealthy && !shared && /* @__PURE__ */
|
|
1885
|
+
isConnected ? /* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
|
|
1886
|
+
unhealthy && !shared && /* @__PURE__ */ jsx8(
|
|
1859
1887
|
"button",
|
|
1860
1888
|
{
|
|
1861
1889
|
type: "button",
|
|
@@ -1866,7 +1894,11 @@ function ConnectorTile({
|
|
|
1866
1894
|
children: isConnecting ? "Reconnecting\u2026" : "Reconnect"
|
|
1867
1895
|
}
|
|
1868
1896
|
),
|
|
1869
|
-
canDisconnect &&
|
|
1897
|
+
canDisconnect && // DEV-11580: the revoke reassurance lives in the title only —
|
|
1898
|
+
// as an always-visible paragraph it wrapped to four lines
|
|
1899
|
+
// beside every connected tile. Muted until hover so a
|
|
1900
|
+
// destructive action isn't the loudest thing on the tile.
|
|
1901
|
+
/* @__PURE__ */ jsx8(
|
|
1870
1902
|
"button",
|
|
1871
1903
|
{
|
|
1872
1904
|
type: "button",
|
|
@@ -1874,28 +1906,11 @@ function ConnectorTile({
|
|
|
1874
1906
|
title: DISCONNECT_REVOKES_HINT,
|
|
1875
1907
|
onClick: () => onDisconnect(entry),
|
|
1876
1908
|
disabled: isDisconnecting || isConnecting,
|
|
1877
|
-
className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-medium text-
|
|
1909
|
+
className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:opacity-50",
|
|
1878
1910
|
children: isDisconnecting ? "Disconnecting\u2026" : "Disconnect"
|
|
1879
1911
|
}
|
|
1880
1912
|
),
|
|
1881
|
-
|
|
1882
|
-
// paragraph's one long sentence forced the WHOLE shrink-0
|
|
1883
|
-
// button column to grow to its natural (unwrapped) width,
|
|
1884
|
-
// squeezing the sibling `min-w-0 flex-1` text column down to
|
|
1885
|
-
// one word per line at any realistic tile width. RTL's jsdom
|
|
1886
|
-
// tests never caught it — jsdom doesn't lay out real flexbox
|
|
1887
|
-
// sizing, so every textContent assertion still passed. A
|
|
1888
|
-
// narrow max-width forces the hint to wrap within the same
|
|
1889
|
-
// footprint as the button above it instead.
|
|
1890
|
-
/* @__PURE__ */ jsx7(
|
|
1891
|
-
"p",
|
|
1892
|
-
{
|
|
1893
|
-
"data-testid": `connector-disconnect-hint-${entry.slug}`,
|
|
1894
|
-
className: "max-w-28 text-right text-[11px] text-muted-foreground",
|
|
1895
|
-
children: DISCONNECT_REVOKES_HINT
|
|
1896
|
-
}
|
|
1897
|
-
),
|
|
1898
|
-
canManageSharing && /* @__PURE__ */ jsx7(
|
|
1913
|
+
canManageSharing && /* @__PURE__ */ jsx8(
|
|
1899
1914
|
"button",
|
|
1900
1915
|
{
|
|
1901
1916
|
type: "button",
|
|
@@ -1906,19 +1921,19 @@ function ConnectorTile({
|
|
|
1906
1921
|
children: sharingOpen ? "Hide sharing" : "Manage sharing"
|
|
1907
1922
|
}
|
|
1908
1923
|
)
|
|
1909
|
-
] }) : /* @__PURE__ */
|
|
1910
|
-
/* @__PURE__ */
|
|
1924
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
|
|
1925
|
+
/* @__PURE__ */ jsx8(
|
|
1911
1926
|
"button",
|
|
1912
1927
|
{
|
|
1913
1928
|
type: "button",
|
|
1914
1929
|
"data-testid": `connector-connect-${entry.slug}`,
|
|
1915
|
-
onClick: () => onConnect(entry,
|
|
1930
|
+
onClick: () => onConnect(entry, connectKind),
|
|
1916
1931
|
disabled: isConnecting,
|
|
1917
1932
|
className: "shrink-0 rounded-md bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground disabled:opacity-50",
|
|
1918
1933
|
children: isConnecting ? "Connecting\u2026" : "Connect"
|
|
1919
1934
|
}
|
|
1920
1935
|
),
|
|
1921
|
-
canSetUp && /* @__PURE__ */
|
|
1936
|
+
canSetUp && /* @__PURE__ */ jsx8(
|
|
1922
1937
|
"button",
|
|
1923
1938
|
{
|
|
1924
1939
|
type: "button",
|
|
@@ -1932,20 +1947,20 @@ function ConnectorTile({
|
|
|
1932
1947
|
)
|
|
1933
1948
|
] })
|
|
1934
1949
|
] }),
|
|
1935
|
-
canSetUp && setupOpen && /* @__PURE__ */
|
|
1950
|
+
canSetUp && setupOpen && /* @__PURE__ */ jsxs7(
|
|
1936
1951
|
"div",
|
|
1937
1952
|
{
|
|
1938
1953
|
id: `connector-setup-panel-${entry.slug}`,
|
|
1939
1954
|
"data-testid": `connector-setup-panel-${entry.slug}`,
|
|
1940
1955
|
className: "mt-2 flex flex-col gap-3 rounded-md border border-border bg-foreground/5 p-2",
|
|
1941
1956
|
children: [
|
|
1942
|
-
guide && /* @__PURE__ */
|
|
1943
|
-
pasteSupported && /* @__PURE__ */
|
|
1957
|
+
guide && /* @__PURE__ */ jsx8(SetupGuidePanel, { entry, guide, showVerify: !pasteSupported }),
|
|
1958
|
+
pasteSupported && /* @__PURE__ */ jsx8(
|
|
1944
1959
|
CredentialForm,
|
|
1945
1960
|
{
|
|
1946
1961
|
entry,
|
|
1947
1962
|
fields: credentialFields,
|
|
1948
|
-
kind,
|
|
1963
|
+
kind: connectKind,
|
|
1949
1964
|
verify: guide?.verify ?? null,
|
|
1950
1965
|
testSupported: credentialTestSupported,
|
|
1951
1966
|
onSubmitCredentials,
|
|
@@ -1955,7 +1970,7 @@ function ConnectorTile({
|
|
|
1955
1970
|
]
|
|
1956
1971
|
}
|
|
1957
1972
|
),
|
|
1958
|
-
canManageSharing && sharingOpen && /* @__PURE__ */
|
|
1973
|
+
canManageSharing && sharingOpen && /* @__PURE__ */ jsx8(
|
|
1959
1974
|
ManageSharing,
|
|
1960
1975
|
{
|
|
1961
1976
|
entry,
|
|
@@ -2005,8 +2020,8 @@ function CopyableValue({ value, testId }) {
|
|
|
2005
2020
|
setCopied(false);
|
|
2006
2021
|
}
|
|
2007
2022
|
}, [value]);
|
|
2008
|
-
return /* @__PURE__ */
|
|
2009
|
-
/* @__PURE__ */
|
|
2023
|
+
return /* @__PURE__ */ jsxs7("span", { className: "mt-1 flex items-center gap-1.5", children: [
|
|
2024
|
+
/* @__PURE__ */ jsx8(
|
|
2010
2025
|
"code",
|
|
2011
2026
|
{
|
|
2012
2027
|
"data-testid": `${testId}-value`,
|
|
@@ -2014,7 +2029,7 @@ function CopyableValue({ value, testId }) {
|
|
|
2014
2029
|
children: value
|
|
2015
2030
|
}
|
|
2016
2031
|
),
|
|
2017
|
-
/* @__PURE__ */
|
|
2032
|
+
/* @__PURE__ */ jsx8(
|
|
2018
2033
|
"button",
|
|
2019
2034
|
{
|
|
2020
2035
|
type: "button",
|
|
@@ -2040,8 +2055,8 @@ function SetupGuidePanel({
|
|
|
2040
2055
|
ungrounded
|
|
2041
2056
|
);
|
|
2042
2057
|
}, [entry.slug, guide, leaked]);
|
|
2043
|
-
return /* @__PURE__ */
|
|
2044
|
-
leaked && isDevEnvironment() && /* @__PURE__ */
|
|
2058
|
+
return /* @__PURE__ */ jsxs7("div", { "data-testid": `connector-guide-${entry.slug}`, className: "flex flex-col gap-2", children: [
|
|
2059
|
+
leaked && isDevEnvironment() && /* @__PURE__ */ jsxs7(
|
|
2045
2060
|
"p",
|
|
2046
2061
|
{
|
|
2047
2062
|
role: "alert",
|
|
@@ -2053,25 +2068,25 @@ function SetupGuidePanel({
|
|
|
2053
2068
|
]
|
|
2054
2069
|
}
|
|
2055
2070
|
),
|
|
2056
|
-
prerequisites.length > 0 && /* @__PURE__ */
|
|
2057
|
-
/* @__PURE__ */
|
|
2058
|
-
/* @__PURE__ */
|
|
2071
|
+
prerequisites.length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
|
|
2072
|
+
/* @__PURE__ */ jsx8("h4", { className: "text-xs font-medium", children: "Before you start" }),
|
|
2073
|
+
/* @__PURE__ */ jsx8(
|
|
2059
2074
|
"ul",
|
|
2060
2075
|
{
|
|
2061
2076
|
"data-testid": `connector-guide-prerequisites-${entry.slug}`,
|
|
2062
2077
|
className: "mt-1 list-disc pl-4 text-xs text-muted-foreground",
|
|
2063
|
-
children: prerequisites.map((item) => /* @__PURE__ */
|
|
2078
|
+
children: prerequisites.map((item) => /* @__PURE__ */ jsx8("li", { children: item }, item))
|
|
2064
2079
|
}
|
|
2065
2080
|
)
|
|
2066
2081
|
] }),
|
|
2067
|
-
steps.length > 0 && /* @__PURE__ */
|
|
2082
|
+
steps.length > 0 && /* @__PURE__ */ jsx8(
|
|
2068
2083
|
"ol",
|
|
2069
2084
|
{
|
|
2070
2085
|
"data-testid": `connector-guide-steps-${entry.slug}`,
|
|
2071
2086
|
className: "list-decimal pl-4 text-xs",
|
|
2072
|
-
children: steps.map((step, index) => /* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2074
|
-
step.copyable && /* @__PURE__ */
|
|
2087
|
+
children: steps.map((step, index) => /* @__PURE__ */ jsxs7("li", { className: "mt-1 first:mt-0", children: [
|
|
2088
|
+
/* @__PURE__ */ jsx8("span", { children: step.text }),
|
|
2089
|
+
step.copyable && /* @__PURE__ */ jsx8(
|
|
2075
2090
|
CopyableValue,
|
|
2076
2091
|
{
|
|
2077
2092
|
value: step.copyable,
|
|
@@ -2081,7 +2096,7 @@ function SetupGuidePanel({
|
|
|
2081
2096
|
] }, step.text))
|
|
2082
2097
|
}
|
|
2083
2098
|
),
|
|
2084
|
-
scopeNote && /* @__PURE__ */
|
|
2099
|
+
scopeNote && /* @__PURE__ */ jsx8(
|
|
2085
2100
|
"p",
|
|
2086
2101
|
{
|
|
2087
2102
|
"data-testid": `connector-guide-scope-note-${entry.slug}`,
|
|
@@ -2089,7 +2104,7 @@ function SetupGuidePanel({
|
|
|
2089
2104
|
children: scopeNote
|
|
2090
2105
|
}
|
|
2091
2106
|
),
|
|
2092
|
-
showVerify && verify && /* @__PURE__ */
|
|
2107
|
+
showVerify && verify && /* @__PURE__ */ jsx8(
|
|
2093
2108
|
"p",
|
|
2094
2109
|
{
|
|
2095
2110
|
"data-testid": `connector-guide-verify-${entry.slug}`,
|
|
@@ -2153,7 +2168,7 @@ function CredentialForm({
|
|
|
2153
2168
|
setBusy(false);
|
|
2154
2169
|
}
|
|
2155
2170
|
}, [kind, onSubmitCredentials, values]);
|
|
2156
|
-
return /* @__PURE__ */
|
|
2171
|
+
return /* @__PURE__ */ jsxs7(
|
|
2157
2172
|
"form",
|
|
2158
2173
|
{
|
|
2159
2174
|
"data-testid": `connector-credential-form-${entry.slug}`,
|
|
@@ -2167,12 +2182,12 @@ function CredentialForm({
|
|
|
2167
2182
|
fields.map((field) => {
|
|
2168
2183
|
const inputId = `connector-credential-${entry.slug}-${field.key}`;
|
|
2169
2184
|
const fieldError = fieldErrors?.[field.key] ?? null;
|
|
2170
|
-
return /* @__PURE__ */
|
|
2171
|
-
/* @__PURE__ */
|
|
2185
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1", children: [
|
|
2186
|
+
/* @__PURE__ */ jsxs7("label", { htmlFor: inputId, className: "text-xs font-medium", children: [
|
|
2172
2187
|
field.label,
|
|
2173
|
-
field.required !== false && /* @__PURE__ */
|
|
2188
|
+
field.required !== false && /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "ml-0.5 text-destructive", children: "*" })
|
|
2174
2189
|
] }),
|
|
2175
|
-
/* @__PURE__ */
|
|
2190
|
+
/* @__PURE__ */ jsx8(
|
|
2176
2191
|
"input",
|
|
2177
2192
|
{
|
|
2178
2193
|
id: inputId,
|
|
@@ -2192,7 +2207,7 @@ function CredentialForm({
|
|
|
2192
2207
|
)
|
|
2193
2208
|
}
|
|
2194
2209
|
),
|
|
2195
|
-
fieldError && /* @__PURE__ */
|
|
2210
|
+
fieldError && /* @__PURE__ */ jsx8(
|
|
2196
2211
|
"p",
|
|
2197
2212
|
{
|
|
2198
2213
|
id: `${inputId}-error`,
|
|
@@ -2203,7 +2218,7 @@ function CredentialForm({
|
|
|
2203
2218
|
)
|
|
2204
2219
|
] }, field.key);
|
|
2205
2220
|
}),
|
|
2206
|
-
verify && /* @__PURE__ */
|
|
2221
|
+
verify && /* @__PURE__ */ jsx8(
|
|
2207
2222
|
"p",
|
|
2208
2223
|
{
|
|
2209
2224
|
"data-testid": `connector-guide-verify-${entry.slug}`,
|
|
@@ -2211,8 +2226,8 @@ function CredentialForm({
|
|
|
2211
2226
|
children: verify
|
|
2212
2227
|
}
|
|
2213
2228
|
),
|
|
2214
|
-
result && /* @__PURE__ */
|
|
2215
|
-
error && /* @__PURE__ */
|
|
2229
|
+
result && /* @__PURE__ */ jsx8(CredentialTestResult, { entry, result }),
|
|
2230
|
+
error && /* @__PURE__ */ jsx8(
|
|
2216
2231
|
"p",
|
|
2217
2232
|
{
|
|
2218
2233
|
role: "alert",
|
|
@@ -2221,8 +2236,8 @@ function CredentialForm({
|
|
|
2221
2236
|
children: error
|
|
2222
2237
|
}
|
|
2223
2238
|
),
|
|
2224
|
-
/* @__PURE__ */
|
|
2225
|
-
testSupported && /* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-end gap-1.5", children: [
|
|
2240
|
+
testSupported && /* @__PURE__ */ jsx8(
|
|
2226
2241
|
"button",
|
|
2227
2242
|
{
|
|
2228
2243
|
type: "button",
|
|
@@ -2233,7 +2248,7 @@ function CredentialForm({
|
|
|
2233
2248
|
children: testing ? "Testing\u2026" : "Test connection"
|
|
2234
2249
|
}
|
|
2235
2250
|
),
|
|
2236
|
-
/* @__PURE__ */
|
|
2251
|
+
/* @__PURE__ */ jsx8(
|
|
2237
2252
|
"button",
|
|
2238
2253
|
{
|
|
2239
2254
|
type: "submit",
|
|
@@ -2254,15 +2269,15 @@ function CredentialTestResult({
|
|
|
2254
2269
|
result
|
|
2255
2270
|
}) {
|
|
2256
2271
|
if (result.valid === true) {
|
|
2257
|
-
return /* @__PURE__ */
|
|
2272
|
+
return /* @__PURE__ */ jsxs7(
|
|
2258
2273
|
"div",
|
|
2259
2274
|
{
|
|
2260
2275
|
role: "status",
|
|
2261
2276
|
"data-testid": `connector-credential-test-pass-${entry.slug}`,
|
|
2262
2277
|
className: "rounded-md border border-primary/30 bg-primary/5 px-2 py-1 text-xs",
|
|
2263
2278
|
children: [
|
|
2264
|
-
/* @__PURE__ */
|
|
2265
|
-
result.permissions_note && /* @__PURE__ */
|
|
2279
|
+
/* @__PURE__ */ jsx8("p", { children: result.account_name ? `Verified \u2014 connected as ${result.account_name}.` : "Verified \u2014 these credentials work." }),
|
|
2280
|
+
result.permissions_note && /* @__PURE__ */ jsx8(
|
|
2266
2281
|
"p",
|
|
2267
2282
|
{
|
|
2268
2283
|
"data-testid": `connector-credential-permissions-${entry.slug}`,
|
|
@@ -2275,7 +2290,7 @@ function CredentialTestResult({
|
|
|
2275
2290
|
);
|
|
2276
2291
|
}
|
|
2277
2292
|
if (result.valid === false) {
|
|
2278
|
-
return /* @__PURE__ */
|
|
2293
|
+
return /* @__PURE__ */ jsx8(
|
|
2279
2294
|
"p",
|
|
2280
2295
|
{
|
|
2281
2296
|
role: "alert",
|
|
@@ -2285,7 +2300,7 @@ function CredentialTestResult({
|
|
|
2285
2300
|
}
|
|
2286
2301
|
);
|
|
2287
2302
|
}
|
|
2288
|
-
return /* @__PURE__ */
|
|
2303
|
+
return /* @__PURE__ */ jsx8(
|
|
2289
2304
|
"p",
|
|
2290
2305
|
{
|
|
2291
2306
|
role: "status",
|
|
@@ -2348,13 +2363,13 @@ function ManageSharing({
|
|
|
2348
2363
|
},
|
|
2349
2364
|
[load, revokeGrant]
|
|
2350
2365
|
);
|
|
2351
|
-
return /* @__PURE__ */
|
|
2366
|
+
return /* @__PURE__ */ jsxs7(
|
|
2352
2367
|
"div",
|
|
2353
2368
|
{
|
|
2354
2369
|
"data-testid": `connector-sharing-panel-${entry.slug}`,
|
|
2355
2370
|
className: "mt-2 flex flex-col gap-2 rounded-md border border-border bg-foreground/5 p-2",
|
|
2356
2371
|
children: [
|
|
2357
|
-
grants === null && !error && /* @__PURE__ */
|
|
2372
|
+
grants === null && !error && /* @__PURE__ */ jsx8(
|
|
2358
2373
|
"p",
|
|
2359
2374
|
{
|
|
2360
2375
|
"data-testid": `connector-grants-loading-${entry.slug}`,
|
|
@@ -2362,7 +2377,7 @@ function ManageSharing({
|
|
|
2362
2377
|
children: "Loading sharing\u2026"
|
|
2363
2378
|
}
|
|
2364
2379
|
),
|
|
2365
|
-
error && /* @__PURE__ */
|
|
2380
|
+
error && /* @__PURE__ */ jsx8(
|
|
2366
2381
|
"p",
|
|
2367
2382
|
{
|
|
2368
2383
|
role: "alert",
|
|
@@ -2371,7 +2386,7 @@ function ManageSharing({
|
|
|
2371
2386
|
children: error
|
|
2372
2387
|
}
|
|
2373
2388
|
),
|
|
2374
|
-
grants !== null && grants.length === 0 && /* @__PURE__ */
|
|
2389
|
+
grants !== null && grants.length === 0 && /* @__PURE__ */ jsx8(
|
|
2375
2390
|
"p",
|
|
2376
2391
|
{
|
|
2377
2392
|
"data-testid": `connector-grants-empty-${entry.slug}`,
|
|
@@ -2379,21 +2394,21 @@ function ManageSharing({
|
|
|
2379
2394
|
children: "Not shared with anyone yet."
|
|
2380
2395
|
}
|
|
2381
2396
|
),
|
|
2382
|
-
grants?.map((grant) => /* @__PURE__ */
|
|
2397
|
+
grants?.map((grant) => /* @__PURE__ */ jsxs7(
|
|
2383
2398
|
"div",
|
|
2384
2399
|
{
|
|
2385
2400
|
"data-testid": `connector-grant-${entry.slug}-${grant.id}`,
|
|
2386
2401
|
className: "flex items-center justify-between gap-2 text-xs",
|
|
2387
2402
|
children: [
|
|
2388
|
-
/* @__PURE__ */
|
|
2403
|
+
/* @__PURE__ */ jsxs7("span", { className: "truncate", children: [
|
|
2389
2404
|
grant.grantee_name || grant.grantee_id,
|
|
2390
|
-
/* @__PURE__ */
|
|
2405
|
+
/* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
|
|
2391
2406
|
" ",
|
|
2392
2407
|
"\xB7 ",
|
|
2393
2408
|
grant.grantee_type === "role" ? "Role" : "User"
|
|
2394
2409
|
] })
|
|
2395
2410
|
] }),
|
|
2396
|
-
/* @__PURE__ */
|
|
2411
|
+
/* @__PURE__ */ jsx8(
|
|
2397
2412
|
"button",
|
|
2398
2413
|
{
|
|
2399
2414
|
type: "button",
|
|
@@ -2408,8 +2423,8 @@ function ManageSharing({
|
|
|
2408
2423
|
},
|
|
2409
2424
|
grant.id
|
|
2410
2425
|
)),
|
|
2411
|
-
/* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */
|
|
2426
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5", children: [
|
|
2427
|
+
/* @__PURE__ */ jsxs7(
|
|
2413
2428
|
"select",
|
|
2414
2429
|
{
|
|
2415
2430
|
"data-testid": `connector-grant-type-${entry.slug}`,
|
|
@@ -2422,12 +2437,12 @@ function ManageSharing({
|
|
|
2422
2437
|
disabled: busy,
|
|
2423
2438
|
className: "rounded-md border border-border bg-transparent px-1.5 py-1 text-xs disabled:opacity-50",
|
|
2424
2439
|
children: [
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2440
|
+
/* @__PURE__ */ jsx8("option", { value: "user", children: "User" }),
|
|
2441
|
+
/* @__PURE__ */ jsx8("option", { value: "role", children: "Role" })
|
|
2427
2442
|
]
|
|
2428
2443
|
}
|
|
2429
2444
|
),
|
|
2430
|
-
granteeType === "user" ? /* @__PURE__ */
|
|
2445
|
+
granteeType === "user" ? /* @__PURE__ */ jsx8(
|
|
2431
2446
|
"input",
|
|
2432
2447
|
{
|
|
2433
2448
|
"data-testid": `connector-grant-grantee-${entry.slug}`,
|
|
@@ -2438,7 +2453,7 @@ function ManageSharing({
|
|
|
2438
2453
|
disabled: busy,
|
|
2439
2454
|
className: "min-w-0 flex-1 rounded-md border border-border bg-transparent px-1.5 py-1 text-xs disabled:opacity-50"
|
|
2440
2455
|
}
|
|
2441
|
-
) : /* @__PURE__ */
|
|
2456
|
+
) : /* @__PURE__ */ jsxs7(
|
|
2442
2457
|
"select",
|
|
2443
2458
|
{
|
|
2444
2459
|
"data-testid": `connector-grant-role-${entry.slug}`,
|
|
@@ -2448,12 +2463,12 @@ function ManageSharing({
|
|
|
2448
2463
|
disabled: busy,
|
|
2449
2464
|
className: "min-w-0 flex-1 rounded-md border border-border bg-transparent px-1.5 py-1 text-xs disabled:opacity-50",
|
|
2450
2465
|
children: [
|
|
2451
|
-
/* @__PURE__ */
|
|
2452
|
-
roleOptions.map((role) => /* @__PURE__ */
|
|
2466
|
+
/* @__PURE__ */ jsx8("option", { value: "", children: "Select a role\u2026" }),
|
|
2467
|
+
roleOptions.map((role) => /* @__PURE__ */ jsx8("option", { value: role.id, children: role.name }, role.id))
|
|
2453
2468
|
]
|
|
2454
2469
|
}
|
|
2455
2470
|
),
|
|
2456
|
-
/* @__PURE__ */
|
|
2471
|
+
/* @__PURE__ */ jsx8(
|
|
2457
2472
|
"button",
|
|
2458
2473
|
{
|
|
2459
2474
|
type: "button",
|
|
@@ -2476,6 +2491,7 @@ export {
|
|
|
2476
2491
|
ContextSwitcher,
|
|
2477
2492
|
Flyout,
|
|
2478
2493
|
GLYPH_CANVAS_FILL,
|
|
2494
|
+
InfoTip,
|
|
2479
2495
|
LOCKUP_GAP,
|
|
2480
2496
|
LOCKUP_ROW,
|
|
2481
2497
|
MARK_CAP_RATIO,
|