@tangle-network/sandbox-ui 0.49.0 → 0.51.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/dist/assistant.js +187 -113
- package/dist/{chunk-4HLWA2VN.js → chunk-MGIOO3RL.js} +1 -1
- package/dist/{chunk-3WUSPCPC.js → chunk-RT4MLYYM.js} +57 -21
- package/dist/dashboard.d.ts +3 -0
- package/dist/dashboard.js +1 -1
- package/dist/globals.css +55 -0
- package/dist/index.js +2 -2
- package/dist/integrations.d.ts +19 -1
- package/dist/integrations.js +111 -40
- package/dist/pages.d.ts +1 -1
- package/dist/styles.css +55 -0
- package/dist/workbench.js +2 -2
- package/package.json +1 -1
package/dist/assistant.js
CHANGED
|
@@ -4,6 +4,10 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
providerLabel
|
|
6
6
|
} from "./chunk-7JLB7UZ3.js";
|
|
7
|
+
import {
|
|
8
|
+
ModelPicker
|
|
9
|
+
} from "./chunk-LQHTCM56.js";
|
|
10
|
+
import "./chunk-EI44GEQ5.js";
|
|
7
11
|
import "./chunk-U67V476Y.js";
|
|
8
12
|
|
|
9
13
|
// src/assistant/sse.ts
|
|
@@ -1532,14 +1536,14 @@ function useAssistantThreads(userId) {
|
|
|
1532
1536
|
// src/assistant/AssistantDock.tsx
|
|
1533
1537
|
import { MessageSquare } from "lucide-react";
|
|
1534
1538
|
import {
|
|
1535
|
-
useEffect as
|
|
1539
|
+
useEffect as useEffect6,
|
|
1536
1540
|
useRef as useRef6
|
|
1537
1541
|
} from "react";
|
|
1538
1542
|
|
|
1539
1543
|
// src/assistant/AssistantPanel.tsx
|
|
1540
1544
|
import { AgentTimeline, ChatInput, ThinkingIndicator } from "@tangle-network/ui/chat";
|
|
1541
1545
|
import { History, MessageSquarePlus, Minus, Plus, Trash2, X } from "lucide-react";
|
|
1542
|
-
import { useRef as useRef4, useState as useState5 } from "react";
|
|
1546
|
+
import { useEffect as useEffect5, useMemo, useRef as useRef4, useState as useState5 } from "react";
|
|
1543
1547
|
|
|
1544
1548
|
// src/assistant/build-timeline.tsx
|
|
1545
1549
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
@@ -1910,6 +1914,23 @@ function defaultFormatMoney(usd) {
|
|
|
1910
1914
|
currency: "USD"
|
|
1911
1915
|
}).format(usd);
|
|
1912
1916
|
}
|
|
1917
|
+
function toPickerModels(models, selected) {
|
|
1918
|
+
const mapped = models.models.map((m) => ({
|
|
1919
|
+
id: m.slug,
|
|
1920
|
+
name: m.label,
|
|
1921
|
+
...m.contextTokens != null ? { context_length: m.contextTokens } : {}
|
|
1922
|
+
}));
|
|
1923
|
+
for (const slug of [models.default, selected]) {
|
|
1924
|
+
if (slug && !mapped.some((m) => m.id === slug)) {
|
|
1925
|
+
mapped.push({ id: slug, name: slug });
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
return mapped;
|
|
1929
|
+
}
|
|
1930
|
+
function nextModelSelection(id, defaultSlug) {
|
|
1931
|
+
if (defaultSlug != null && id === defaultSlug) return null;
|
|
1932
|
+
return id || null;
|
|
1933
|
+
}
|
|
1913
1934
|
function AssistantPanel({
|
|
1914
1935
|
chat,
|
|
1915
1936
|
userId,
|
|
@@ -1924,9 +1945,41 @@ function AssistantPanel({
|
|
|
1924
1945
|
const threads = useAssistantThreads(userId);
|
|
1925
1946
|
const font = useFontScale();
|
|
1926
1947
|
const [historyOpen, setHistoryOpen] = useState5(false);
|
|
1948
|
+
const historyRef = useRef4(null);
|
|
1949
|
+
const historyButtonRef = useRef4(null);
|
|
1950
|
+
const pickerModels = useMemo(
|
|
1951
|
+
() => toPickerModels(models, chat.selectedModel),
|
|
1952
|
+
[models, chat.selectedModel]
|
|
1953
|
+
);
|
|
1954
|
+
const pickerValue = chat.selectedModel ?? models.default ?? "";
|
|
1927
1955
|
const { state } = chat;
|
|
1928
1956
|
const chatRef = useRef4(chat);
|
|
1929
1957
|
chatRef.current = chat;
|
|
1958
|
+
useEffect5(() => {
|
|
1959
|
+
if (!historyOpen) return;
|
|
1960
|
+
const onPointerDown = (e) => {
|
|
1961
|
+
const target = e.target;
|
|
1962
|
+
if (historyRef.current?.contains(target)) return;
|
|
1963
|
+
if (historyButtonRef.current?.contains(target)) return;
|
|
1964
|
+
setHistoryOpen(false);
|
|
1965
|
+
};
|
|
1966
|
+
const onKeyDownCapture = (e) => {
|
|
1967
|
+
if (e.key !== "Escape") return;
|
|
1968
|
+
if (!historyRef.current?.contains(e.target)) return;
|
|
1969
|
+
e.stopImmediatePropagation();
|
|
1970
|
+
setHistoryOpen(false);
|
|
1971
|
+
historyButtonRef.current?.focus();
|
|
1972
|
+
};
|
|
1973
|
+
document.addEventListener("pointerdown", onPointerDown);
|
|
1974
|
+
document.addEventListener("keydown", onKeyDownCapture, true);
|
|
1975
|
+
return () => {
|
|
1976
|
+
document.removeEventListener("pointerdown", onPointerDown);
|
|
1977
|
+
document.removeEventListener("keydown", onKeyDownCapture, true);
|
|
1978
|
+
};
|
|
1979
|
+
}, [historyOpen]);
|
|
1980
|
+
useEffect5(() => {
|
|
1981
|
+
if (historyOpen) historyRef.current?.focus();
|
|
1982
|
+
}, [historyOpen]);
|
|
1930
1983
|
const effectiveBalance = state.usage?.balanceUsd ?? balanceUsd;
|
|
1931
1984
|
const errorView = state.error ? presentError(state.error.code, state.error.message) : null;
|
|
1932
1985
|
const low = isLowBalance(effectiveBalance) && !errorView;
|
|
@@ -1965,140 +2018,161 @@ function AssistantPanel({
|
|
|
1965
2018
|
chatRef.current.reset();
|
|
1966
2019
|
}
|
|
1967
2020
|
};
|
|
1968
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex h-full flex-col bg-background", children: [
|
|
1969
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1970
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex
|
|
1971
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex
|
|
1972
|
-
/* @__PURE__ */
|
|
1973
|
-
|
|
2021
|
+
return /* @__PURE__ */ jsxs2("div", { className: "relative flex h-full flex-col bg-background", children: [
|
|
2022
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative z-10 border-border border-b", children: [
|
|
2023
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 px-4 pt-3 pb-1.5", children: [
|
|
2024
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-col", children: [
|
|
2025
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-baseline gap-2", children: [
|
|
2026
|
+
/* @__PURE__ */ jsx4("span", { className: "font-medium text-foreground text-sm", children: "Assistant" }),
|
|
2027
|
+
/* @__PURE__ */ jsx4(
|
|
2028
|
+
"span",
|
|
2029
|
+
{
|
|
2030
|
+
"aria-label": "Your credit balance",
|
|
2031
|
+
className: "text-muted-foreground text-xs",
|
|
2032
|
+
children: formatMoney(effectiveBalance)
|
|
2033
|
+
}
|
|
2034
|
+
)
|
|
2035
|
+
] }),
|
|
2036
|
+
conversationTitle && /* @__PURE__ */ jsx4(
|
|
1974
2037
|
"span",
|
|
1975
2038
|
{
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
children:
|
|
2039
|
+
className: "truncate text-muted-foreground text-xs",
|
|
2040
|
+
title: conversationTitle,
|
|
2041
|
+
children: conversationTitle
|
|
1979
2042
|
}
|
|
1980
2043
|
)
|
|
1981
2044
|
] }),
|
|
1982
|
-
|
|
1983
|
-
"span",
|
|
1984
|
-
{
|
|
1985
|
-
className: "truncate text-muted-foreground text-xs",
|
|
1986
|
-
title: conversationTitle,
|
|
1987
|
-
children: conversationTitle
|
|
1988
|
-
}
|
|
1989
|
-
)
|
|
1990
|
-
] }),
|
|
1991
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1992
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex items-center", role: "group", "aria-label": "Text size", children: [
|
|
2045
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-0.5", children: [
|
|
1993
2046
|
/* @__PURE__ */ jsx4(
|
|
1994
2047
|
"button",
|
|
1995
2048
|
{
|
|
2049
|
+
ref: historyButtonRef,
|
|
1996
2050
|
type: "button",
|
|
1997
|
-
onClick:
|
|
1998
|
-
|
|
1999
|
-
"aria-
|
|
2000
|
-
className:
|
|
2001
|
-
children: /* @__PURE__ */ jsx4(
|
|
2051
|
+
onClick: openHistory,
|
|
2052
|
+
"aria-label": "Chat history",
|
|
2053
|
+
"aria-pressed": historyOpen,
|
|
2054
|
+
className: `rounded-md p-1.5 transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${historyOpen ? "bg-muted text-foreground" : "text-muted-foreground"}`,
|
|
2055
|
+
children: /* @__PURE__ */ jsx4(History, { className: "h-4 w-4" })
|
|
2002
2056
|
}
|
|
2003
2057
|
),
|
|
2004
2058
|
/* @__PURE__ */ jsx4(
|
|
2005
2059
|
"button",
|
|
2006
2060
|
{
|
|
2007
2061
|
type: "button",
|
|
2008
|
-
onClick:
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
className: "rounded p-1 text-muted-foreground hover:text-foreground
|
|
2012
|
-
children: /* @__PURE__ */ jsx4(
|
|
2062
|
+
onClick: chat.reset,
|
|
2063
|
+
"aria-label": "New chat",
|
|
2064
|
+
title: "New chat",
|
|
2065
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
2066
|
+
children: /* @__PURE__ */ jsx4(MessageSquarePlus, { className: "h-4 w-4" })
|
|
2067
|
+
}
|
|
2068
|
+
),
|
|
2069
|
+
/* @__PURE__ */ jsx4(
|
|
2070
|
+
"button",
|
|
2071
|
+
{
|
|
2072
|
+
type: "button",
|
|
2073
|
+
onClick: onClose,
|
|
2074
|
+
"aria-label": "Close assistant",
|
|
2075
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
2076
|
+
children: /* @__PURE__ */ jsx4(X, { className: "h-4 w-4" })
|
|
2013
2077
|
}
|
|
2014
2078
|
)
|
|
2015
|
-
] })
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
onClick: openHistory,
|
|
2021
|
-
"aria-label": "Chat history",
|
|
2022
|
-
"aria-pressed": historyOpen,
|
|
2023
|
-
className: "rounded p-1 text-muted-foreground hover:text-foreground",
|
|
2024
|
-
children: /* @__PURE__ */ jsx4(History, { className: "h-4 w-4" })
|
|
2025
|
-
}
|
|
2026
|
-
),
|
|
2027
|
-
/* @__PURE__ */ jsx4(
|
|
2028
|
-
"button",
|
|
2079
|
+
] })
|
|
2080
|
+
] }),
|
|
2081
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 px-3 pb-2", children: [
|
|
2082
|
+
pickerModels.length > 0 ? /* @__PURE__ */ jsx4(
|
|
2083
|
+
ModelPicker,
|
|
2029
2084
|
{
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
children: /* @__PURE__ */ jsx4(MessageSquarePlus, { className: "h-4 w-4" })
|
|
2085
|
+
variant: "pill",
|
|
2086
|
+
label: "Model",
|
|
2087
|
+
value: pickerValue,
|
|
2088
|
+
onChange: (id) => chat.setModel(nextModelSelection(id, models.default)),
|
|
2089
|
+
models: pickerModels
|
|
2036
2090
|
}
|
|
2037
|
-
),
|
|
2038
|
-
/* @__PURE__ */
|
|
2039
|
-
"
|
|
2091
|
+
) : /* @__PURE__ */ jsx4("span", { className: "px-1 text-muted-foreground text-xs", children: "Default model" }),
|
|
2092
|
+
/* @__PURE__ */ jsxs2(
|
|
2093
|
+
"div",
|
|
2040
2094
|
{
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
"aria-label": "
|
|
2044
|
-
|
|
2045
|
-
|
|
2095
|
+
className: "flex items-center overflow-hidden rounded-md border border-border",
|
|
2096
|
+
role: "group",
|
|
2097
|
+
"aria-label": "Text size",
|
|
2098
|
+
children: [
|
|
2099
|
+
/* @__PURE__ */ jsx4(
|
|
2100
|
+
"button",
|
|
2101
|
+
{
|
|
2102
|
+
type: "button",
|
|
2103
|
+
onClick: font.decrease,
|
|
2104
|
+
disabled: !font.canDecrease,
|
|
2105
|
+
"aria-label": "Decrease text size",
|
|
2106
|
+
className: "px-1.5 py-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:hover:bg-transparent",
|
|
2107
|
+
children: /* @__PURE__ */ jsx4(Minus, { className: "h-3.5 w-3.5" })
|
|
2108
|
+
}
|
|
2109
|
+
),
|
|
2110
|
+
/* @__PURE__ */ jsx4(
|
|
2111
|
+
"button",
|
|
2112
|
+
{
|
|
2113
|
+
type: "button",
|
|
2114
|
+
onClick: font.increase,
|
|
2115
|
+
disabled: !font.canIncrease,
|
|
2116
|
+
"aria-label": "Increase text size",
|
|
2117
|
+
className: "border-border border-l px-1.5 py-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:hover:bg-transparent",
|
|
2118
|
+
children: /* @__PURE__ */ jsx4(Plus, { className: "h-3.5 w-3.5" })
|
|
2119
|
+
}
|
|
2120
|
+
)
|
|
2121
|
+
]
|
|
2046
2122
|
}
|
|
2047
2123
|
)
|
|
2048
|
-
] })
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
/* @__PURE__ */ jsx4(
|
|
2052
|
-
"label",
|
|
2053
|
-
{
|
|
2054
|
-
htmlFor: "assistant-model",
|
|
2055
|
-
className: "text-muted-foreground text-xs",
|
|
2056
|
-
children: "Model"
|
|
2057
|
-
}
|
|
2058
|
-
),
|
|
2059
|
-
/* @__PURE__ */ jsxs2(
|
|
2060
|
-
"select",
|
|
2124
|
+
] }),
|
|
2125
|
+
historyOpen && /* @__PURE__ */ jsxs2(
|
|
2126
|
+
"div",
|
|
2061
2127
|
{
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2128
|
+
ref: historyRef,
|
|
2129
|
+
role: "dialog",
|
|
2130
|
+
"aria-label": "Recent conversations",
|
|
2131
|
+
tabIndex: -1,
|
|
2132
|
+
className: "absolute inset-x-2 top-full z-30 mt-1 overflow-hidden rounded-lg border border-border bg-surface-container-highest shadow-xl ring-1 ring-black/5 focus:outline-none",
|
|
2066
2133
|
children: [
|
|
2067
|
-
/* @__PURE__ */ jsx4("
|
|
2068
|
-
|
|
2134
|
+
/* @__PURE__ */ jsx4("div", { className: "border-border border-b bg-surface-container-high px-3 py-2 font-medium text-[11px] text-muted-foreground uppercase tracking-wide", children: "Recent conversations" }),
|
|
2135
|
+
/* @__PURE__ */ jsx4("div", { className: "max-h-[min(18rem,50vh)] overflow-y-auto", children: threads.threads.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "px-3 py-3 text-muted-foreground text-xs", children: threads.loaded ? "No past conversations." : "Loading\u2026" }) : /* @__PURE__ */ jsx4("ul", { className: "py-1", children: threads.threads.map((t) => {
|
|
2136
|
+
const busyActive = state.threadId === t.id && state.status !== "idle";
|
|
2137
|
+
const active = state.threadId === t.id;
|
|
2138
|
+
return /* @__PURE__ */ jsxs2(
|
|
2139
|
+
"li",
|
|
2140
|
+
{
|
|
2141
|
+
className: `group flex items-center transition-colors hover:bg-muted/60 ${active ? "bg-primary/10" : ""}`,
|
|
2142
|
+
children: [
|
|
2143
|
+
/* @__PURE__ */ jsx4(
|
|
2144
|
+
"button",
|
|
2145
|
+
{
|
|
2146
|
+
type: "button",
|
|
2147
|
+
onClick: () => {
|
|
2148
|
+
chat.switchThread(t.id);
|
|
2149
|
+
setHistoryOpen(false);
|
|
2150
|
+
},
|
|
2151
|
+
className: `min-w-0 flex-1 truncate px-3 py-2 text-left text-xs ${active ? "font-medium text-foreground" : "text-foreground"}`,
|
|
2152
|
+
children: t.title ?? "Untitled conversation"
|
|
2153
|
+
}
|
|
2154
|
+
),
|
|
2155
|
+
threads.canRemove && /* @__PURE__ */ jsx4(
|
|
2156
|
+
"button",
|
|
2157
|
+
{
|
|
2158
|
+
type: "button",
|
|
2159
|
+
onClick: () => void deleteThread(t.id),
|
|
2160
|
+
disabled: busyActive,
|
|
2161
|
+
"aria-label": "Delete conversation",
|
|
2162
|
+
title: busyActive ? "Can't delete while this conversation is active" : "Delete conversation",
|
|
2163
|
+
className: "shrink-0 p-2 text-muted-foreground opacity-0 transition hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100 disabled:cursor-not-allowed disabled:opacity-30",
|
|
2164
|
+
children: /* @__PURE__ */ jsx4(Trash2, { className: "h-3.5 w-3.5" })
|
|
2165
|
+
}
|
|
2166
|
+
)
|
|
2167
|
+
]
|
|
2168
|
+
},
|
|
2169
|
+
t.id
|
|
2170
|
+
);
|
|
2171
|
+
}) }) })
|
|
2069
2172
|
]
|
|
2070
2173
|
}
|
|
2071
2174
|
)
|
|
2072
2175
|
] }),
|
|
2073
|
-
historyOpen && /* @__PURE__ */ jsx4("div", { className: "max-h-48 overflow-y-auto border-border border-b", children: threads.threads.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "px-4 py-3 text-muted-foreground text-xs", children: threads.loaded ? "No past conversations." : "Loading\u2026" }) : /* @__PURE__ */ jsx4("ul", { children: threads.threads.map((t) => {
|
|
2074
|
-
const busyActive = state.threadId === t.id && state.status !== "idle";
|
|
2075
|
-
return /* @__PURE__ */ jsxs2("li", { className: "group flex items-center hover:bg-muted/50", children: [
|
|
2076
|
-
/* @__PURE__ */ jsx4(
|
|
2077
|
-
"button",
|
|
2078
|
-
{
|
|
2079
|
-
type: "button",
|
|
2080
|
-
onClick: () => {
|
|
2081
|
-
chat.switchThread(t.id);
|
|
2082
|
-
setHistoryOpen(false);
|
|
2083
|
-
},
|
|
2084
|
-
className: "min-w-0 flex-1 truncate px-4 py-2 text-left text-foreground text-xs",
|
|
2085
|
-
children: t.title ?? "Untitled conversation"
|
|
2086
|
-
}
|
|
2087
|
-
),
|
|
2088
|
-
threads.canRemove && /* @__PURE__ */ jsx4(
|
|
2089
|
-
"button",
|
|
2090
|
-
{
|
|
2091
|
-
type: "button",
|
|
2092
|
-
onClick: () => void deleteThread(t.id),
|
|
2093
|
-
disabled: busyActive,
|
|
2094
|
-
"aria-label": "Delete conversation",
|
|
2095
|
-
title: busyActive ? "Can't delete while this conversation is active" : "Delete conversation",
|
|
2096
|
-
className: "shrink-0 p-2 text-muted-foreground opacity-0 transition hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100 disabled:cursor-not-allowed disabled:opacity-30",
|
|
2097
|
-
children: /* @__PURE__ */ jsx4(Trash2, { className: "h-3.5 w-3.5" })
|
|
2098
|
-
}
|
|
2099
|
-
)
|
|
2100
|
-
] }, t.id);
|
|
2101
|
-
}) }) }),
|
|
2102
2176
|
/* @__PURE__ */ jsx4(
|
|
2103
2177
|
"div",
|
|
2104
2178
|
{
|
|
@@ -2106,7 +2180,7 @@ function AssistantPanel({
|
|
|
2106
2180
|
"aria-label": "Conversation",
|
|
2107
2181
|
"aria-live": "polite",
|
|
2108
2182
|
className: "min-h-0 flex-1 overflow-y-auto px-2 py-3",
|
|
2109
|
-
style: {
|
|
2183
|
+
style: { zoom: font.scale },
|
|
2110
2184
|
children: renderTranscript ? renderTranscript({
|
|
2111
2185
|
messages: state.messages,
|
|
2112
2186
|
reasoning: state.reasoning,
|
|
@@ -2192,7 +2266,7 @@ import {
|
|
|
2192
2266
|
createContext as createContext2,
|
|
2193
2267
|
useCallback as useCallback4,
|
|
2194
2268
|
useContext as useContext2,
|
|
2195
|
-
useMemo,
|
|
2269
|
+
useMemo as useMemo2,
|
|
2196
2270
|
useState as useState6
|
|
2197
2271
|
} from "react";
|
|
2198
2272
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
@@ -2208,7 +2282,7 @@ function AssistantLauncherProvider({
|
|
|
2208
2282
|
}, []);
|
|
2209
2283
|
const closeAssistant = useCallback4(() => setOpen(false), []);
|
|
2210
2284
|
const clearSeed = useCallback4(() => setSeed(null), []);
|
|
2211
|
-
const value =
|
|
2285
|
+
const value = useMemo2(
|
|
2212
2286
|
() => ({ open, seed, openAssistant, closeAssistant, clearSeed }),
|
|
2213
2287
|
[open, seed, openAssistant, closeAssistant, clearSeed]
|
|
2214
2288
|
);
|
|
@@ -2327,7 +2401,7 @@ function AssistantDock({
|
|
|
2327
2401
|
const dialogRef = useRef6(null);
|
|
2328
2402
|
const returnFocusRef = useRef6(null);
|
|
2329
2403
|
const wasOpenRef = useRef6(false);
|
|
2330
|
-
|
|
2404
|
+
useEffect6(() => {
|
|
2331
2405
|
if (!open) return;
|
|
2332
2406
|
const onKeyDown = (e) => {
|
|
2333
2407
|
if (e.key === "Escape") closeAssistant();
|
|
@@ -2335,7 +2409,7 @@ function AssistantDock({
|
|
|
2335
2409
|
document.addEventListener("keydown", onKeyDown);
|
|
2336
2410
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
2337
2411
|
}, [open, closeAssistant]);
|
|
2338
|
-
|
|
2412
|
+
useEffect6(() => {
|
|
2339
2413
|
if (open) {
|
|
2340
2414
|
if (!wasOpenRef.current && !returnFocusRef.current) {
|
|
2341
2415
|
returnFocusRef.current = document.activeElement;
|
|
@@ -1516,7 +1516,7 @@ function PlanCards({ plans, className }) {
|
|
|
1516
1516
|
|
|
1517
1517
|
// src/dashboard/dashboard-layout.tsx
|
|
1518
1518
|
import * as React7 from "react";
|
|
1519
|
-
import { Plus as Plus2, Bell } from "lucide-react";
|
|
1519
|
+
import { Plus as Plus2, Bell, ChevronsLeft, ChevronsRight } from "lucide-react";
|
|
1520
1520
|
import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1521
1521
|
function SettingsIconSmall({ className }) {
|
|
1522
1522
|
return /* @__PURE__ */ jsxs13("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
@@ -1571,6 +1571,7 @@ function DashboardLayoutInner({
|
|
|
1571
1571
|
contentClassName,
|
|
1572
1572
|
topNavLinks,
|
|
1573
1573
|
activeTopNavHref,
|
|
1574
|
+
topBarLeading,
|
|
1574
1575
|
LinkComponent = DefaultLink2,
|
|
1575
1576
|
logoHref = "/",
|
|
1576
1577
|
onLogoClick,
|
|
@@ -1621,16 +1622,29 @@ function DashboardLayoutInner({
|
|
|
1621
1622
|
className: "p-1 rounded-md transition-colors hover:bg-surface-container-high",
|
|
1622
1623
|
children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true })
|
|
1623
1624
|
}
|
|
1624
|
-
) :
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1625
|
+
) : allowCollapse ? (
|
|
1626
|
+
// The logo IS the collapse/expand control on the desktop rail
|
|
1627
|
+
// (allowCollapse). The mobile drawer never collapses, so it falls
|
|
1628
|
+
// through to the plain logo link. Expanded: full logotype with a
|
|
1629
|
+
// collapse chevron that fades in on hover. Collapsed: the mark,
|
|
1630
|
+
// with an expand chevron overlay on hover.
|
|
1631
|
+
/* @__PURE__ */ jsxs13(
|
|
1632
|
+
"button",
|
|
1633
|
+
{
|
|
1634
|
+
type: "button",
|
|
1635
|
+
onClick: toggleRail,
|
|
1636
|
+
"aria-label": railCollapsed ? "Expand navigation" : "Collapse navigation",
|
|
1637
|
+
"aria-expanded": !railCollapsed,
|
|
1638
|
+
className: cn(
|
|
1639
|
+
"group/logo relative flex items-center gap-2 rounded-md p-1 transition-colors hover:bg-surface-container-high",
|
|
1640
|
+
showLabels && "w-full"
|
|
1641
|
+
),
|
|
1642
|
+
children: [
|
|
1643
|
+
/* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: !showLabels }),
|
|
1644
|
+
showLabels ? /* @__PURE__ */ jsx14(ChevronsLeft, { className: "ml-auto h-4 w-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover/logo:opacity-100" }) : /* @__PURE__ */ jsx14("span", { className: "absolute inset-0 flex items-center justify-center rounded-md bg-surface-container-high opacity-0 transition-opacity group-hover/logo:opacity-100", children: /* @__PURE__ */ jsx14(ChevronsRight, { className: "h-4 w-4 text-foreground" }) })
|
|
1645
|
+
]
|
|
1646
|
+
}
|
|
1647
|
+
)
|
|
1634
1648
|
) : /* @__PURE__ */ jsx14(
|
|
1635
1649
|
Link,
|
|
1636
1650
|
{
|
|
@@ -1674,18 +1688,39 @@ function DashboardLayoutInner({
|
|
|
1674
1688
|
] }, item.id);
|
|
1675
1689
|
}) }),
|
|
1676
1690
|
/* @__PURE__ */ jsxs13(SidebarRailFooter, { className: cn(showLabels && "items-stretch px-2"), children: [
|
|
1677
|
-
allowCollapse && /* @__PURE__ */ jsx14(
|
|
1678
|
-
RailCollapseToggle,
|
|
1679
|
-
{
|
|
1680
|
-
collapsed: railCollapsed,
|
|
1681
|
-
showLabel: showLabels,
|
|
1682
|
-
onToggle: toggleRail
|
|
1683
|
-
}
|
|
1684
|
-
),
|
|
1685
1691
|
onSettingsClick ? /* @__PURE__ */ jsx14(RailButton, { icon: SettingsIconSmall, label: "Settings", onClick: onSettingsClick, showLabel: showLabels }) : /* @__PURE__ */ jsx14(RailButton, { icon: SettingsIconSmall, label: "Settings", showLabel: showLabels, asChild: true, children: /* @__PURE__ */ jsx14(Link, { href: settingsHref, to: settingsHref }) }),
|
|
1686
|
-
railFooter,
|
|
1687
1692
|
/* @__PURE__ */ jsx14(RailSeparator, { className: showLabels ? "w-full" : void 0 }),
|
|
1688
|
-
/* @__PURE__ */
|
|
1693
|
+
railFooter !== void 0 ? showLabels ? /* @__PURE__ */ jsxs13("div", { className: "flex w-full items-center gap-1", children: [
|
|
1694
|
+
/* @__PURE__ */ jsx14("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx14(
|
|
1695
|
+
ProfileAvatar,
|
|
1696
|
+
{
|
|
1697
|
+
user: sidebarUser,
|
|
1698
|
+
isLoading,
|
|
1699
|
+
onLogout,
|
|
1700
|
+
onSettingsClick,
|
|
1701
|
+
settingsHref,
|
|
1702
|
+
showDetails: showLabels,
|
|
1703
|
+
LinkComponent,
|
|
1704
|
+
children: profileMenuItems
|
|
1705
|
+
}
|
|
1706
|
+
) }),
|
|
1707
|
+
/* @__PURE__ */ jsx14("div", { className: "shrink-0", children: railFooter })
|
|
1708
|
+
] }) : /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-1", children: [
|
|
1709
|
+
railFooter,
|
|
1710
|
+
/* @__PURE__ */ jsx14(
|
|
1711
|
+
ProfileAvatar,
|
|
1712
|
+
{
|
|
1713
|
+
user: sidebarUser,
|
|
1714
|
+
isLoading,
|
|
1715
|
+
onLogout,
|
|
1716
|
+
onSettingsClick,
|
|
1717
|
+
settingsHref,
|
|
1718
|
+
showDetails: showLabels,
|
|
1719
|
+
LinkComponent,
|
|
1720
|
+
children: profileMenuItems
|
|
1721
|
+
}
|
|
1722
|
+
)
|
|
1723
|
+
] }) : /* @__PURE__ */ jsx14(
|
|
1689
1724
|
ProfileAvatar,
|
|
1690
1725
|
{
|
|
1691
1726
|
user: sidebarUser,
|
|
@@ -1748,6 +1783,7 @@ function DashboardLayoutInner({
|
|
|
1748
1783
|
children: [
|
|
1749
1784
|
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-8", children: [
|
|
1750
1785
|
/* @__PURE__ */ jsx14(Link, { href: logoHref, to: logoHref, className: "lg:hidden flex items-center p-1 rounded-md hover:bg-surface-container-high transition-colors", children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true }) }),
|
|
1786
|
+
topBarLeading,
|
|
1751
1787
|
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx14("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx14(
|
|
1752
1788
|
Link,
|
|
1753
1789
|
{
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -688,6 +688,9 @@ interface DashboardLayoutProps {
|
|
|
688
688
|
contentClassName?: string;
|
|
689
689
|
topNavLinks?: TopNavLink[];
|
|
690
690
|
activeTopNavHref?: string;
|
|
691
|
+
/** Arbitrary content rendered at the leading (left) edge of the top bar —
|
|
692
|
+
* e.g. a workspace/team switcher — so consumers don't need a second bar. */
|
|
693
|
+
topBarLeading?: React.ReactNode;
|
|
691
694
|
LinkComponent?: React.ComponentType<any>;
|
|
692
695
|
/**
|
|
693
696
|
* Where the in-app logo links. Defaults to "/" (backward compatible);
|
package/dist/dashboard.js
CHANGED
package/dist/globals.css
CHANGED
|
@@ -317,6 +317,9 @@
|
|
|
317
317
|
.inset-x-0 {
|
|
318
318
|
inset-inline: calc(var(--spacing) * 0);
|
|
319
319
|
}
|
|
320
|
+
.inset-x-2 {
|
|
321
|
+
inset-inline: calc(var(--spacing) * 2);
|
|
322
|
+
}
|
|
320
323
|
.inset-y-0 {
|
|
321
324
|
inset-block: calc(var(--spacing) * 0);
|
|
322
325
|
}
|
|
@@ -392,6 +395,9 @@
|
|
|
392
395
|
.bottom-1 {
|
|
393
396
|
bottom: calc(var(--spacing) * 1);
|
|
394
397
|
}
|
|
398
|
+
.bottom-1\.5 {
|
|
399
|
+
bottom: calc(var(--spacing) * 1.5);
|
|
400
|
+
}
|
|
395
401
|
.bottom-2 {
|
|
396
402
|
bottom: calc(var(--spacing) * 2);
|
|
397
403
|
}
|
|
@@ -437,6 +443,9 @@
|
|
|
437
443
|
.z-10 {
|
|
438
444
|
z-index: 10;
|
|
439
445
|
}
|
|
446
|
+
.z-20 {
|
|
447
|
+
z-index: 20;
|
|
448
|
+
}
|
|
440
449
|
.z-30 {
|
|
441
450
|
z-index: 30;
|
|
442
451
|
}
|
|
@@ -753,6 +762,9 @@
|
|
|
753
762
|
.h-\[640px\] {
|
|
754
763
|
height: 640px;
|
|
755
764
|
}
|
|
765
|
+
.h-\[720px\] {
|
|
766
|
+
height: 720px;
|
|
767
|
+
}
|
|
756
768
|
.h-\[var\(--avatar-size\)\] {
|
|
757
769
|
height: var(--avatar-size);
|
|
758
770
|
}
|
|
@@ -816,6 +828,9 @@
|
|
|
816
828
|
.max-h-\[440px\] {
|
|
817
829
|
max-height: 440px;
|
|
818
830
|
}
|
|
831
|
+
.max-h-\[min\(18rem\,50vh\)\] {
|
|
832
|
+
max-height: min(18rem, 50vh);
|
|
833
|
+
}
|
|
819
834
|
.min-h-0 {
|
|
820
835
|
min-height: calc(var(--spacing) * 0);
|
|
821
836
|
}
|
|
@@ -1026,6 +1041,9 @@
|
|
|
1026
1041
|
.w-\[420px\] {
|
|
1027
1042
|
width: 420px;
|
|
1028
1043
|
}
|
|
1044
|
+
.w-\[460px\] {
|
|
1045
|
+
width: 460px;
|
|
1046
|
+
}
|
|
1029
1047
|
.w-\[480px\] {
|
|
1030
1048
|
width: 480px;
|
|
1031
1049
|
}
|
|
@@ -3452,6 +3470,12 @@
|
|
|
3452
3470
|
.ring-\[var\(--md3-outline-variant\)\] {
|
|
3453
3471
|
--tw-ring-color: var(--md3-outline-variant);
|
|
3454
3472
|
}
|
|
3473
|
+
.ring-black\/5 {
|
|
3474
|
+
--tw-ring-color: color-mix(in srgb, #000 5%, transparent);
|
|
3475
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
3476
|
+
--tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent);
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3455
3479
|
.ring-border {
|
|
3456
3480
|
--tw-ring-color: var(--color-border);
|
|
3457
3481
|
}
|
|
@@ -3626,6 +3650,11 @@
|
|
|
3626
3650
|
rotate: 180deg;
|
|
3627
3651
|
}
|
|
3628
3652
|
}
|
|
3653
|
+
.group-focus-within\:opacity-100 {
|
|
3654
|
+
&:is(:where(.group):focus-within *) {
|
|
3655
|
+
opacity: 100%;
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3629
3658
|
.group-focus-within\/tip\:translate-x-0 {
|
|
3630
3659
|
&:is(:where(.group\/tip):focus-within *) {
|
|
3631
3660
|
--tw-translate-x: calc(var(--spacing) * 0);
|
|
@@ -3676,6 +3705,13 @@
|
|
|
3676
3705
|
}
|
|
3677
3706
|
}
|
|
3678
3707
|
}
|
|
3708
|
+
.group-hover\/logo\:opacity-100 {
|
|
3709
|
+
&:is(:where(.group\/logo):hover *) {
|
|
3710
|
+
@media (hover: hover) {
|
|
3711
|
+
opacity: 100%;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3679
3715
|
.group-hover\/tip\:translate-x-0 {
|
|
3680
3716
|
&:is(:where(.group\/tip):hover *) {
|
|
3681
3717
|
@media (hover: hover) {
|
|
@@ -4188,6 +4224,16 @@
|
|
|
4188
4224
|
}
|
|
4189
4225
|
}
|
|
4190
4226
|
}
|
|
4227
|
+
.hover\:bg-muted\/60 {
|
|
4228
|
+
&:hover {
|
|
4229
|
+
@media (hover: hover) {
|
|
4230
|
+
background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
|
|
4231
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
4232
|
+
background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4191
4237
|
.hover\:bg-muted\/80 {
|
|
4192
4238
|
&:hover {
|
|
4193
4239
|
@media (hover: hover) {
|
|
@@ -4755,6 +4801,15 @@
|
|
|
4755
4801
|
opacity: 60%;
|
|
4756
4802
|
}
|
|
4757
4803
|
}
|
|
4804
|
+
.disabled\:hover\:bg-transparent {
|
|
4805
|
+
&:disabled {
|
|
4806
|
+
&:hover {
|
|
4807
|
+
@media (hover: hover) {
|
|
4808
|
+
background-color: transparent;
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4758
4813
|
.data-\[disabled\]\:pointer-events-none {
|
|
4759
4814
|
&[data-disabled] {
|
|
4760
4815
|
pointer-events: none;
|
package/dist/index.js
CHANGED
|
@@ -148,7 +148,7 @@ import {
|
|
|
148
148
|
buildUnifiedPatch,
|
|
149
149
|
computeDiffStats,
|
|
150
150
|
resolveLanguage
|
|
151
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-MGIOO3RL.js";
|
|
152
152
|
import {
|
|
153
153
|
FileArtifactPane,
|
|
154
154
|
FilePreview,
|
|
@@ -211,7 +211,7 @@ import {
|
|
|
211
211
|
canAdminSandbox,
|
|
212
212
|
parseInsufficientBalance,
|
|
213
213
|
useSidebar
|
|
214
|
-
} from "./chunk-
|
|
214
|
+
} from "./chunk-RT4MLYYM.js";
|
|
215
215
|
import {
|
|
216
216
|
BillingDashboard,
|
|
217
217
|
InfoPanel,
|
package/dist/integrations.d.ts
CHANGED
|
@@ -60,6 +60,24 @@ interface IntegrationsPanelProps {
|
|
|
60
60
|
* thrown error inline.
|
|
61
61
|
*/
|
|
62
62
|
onDisconnect: (connectionId: string) => void | Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Resolver for a connected app's management page URL. When it returns a URL,
|
|
65
|
+
* the connected tile's body and the overflow menu's "Manage" item become a
|
|
66
|
+
* real link opened in a new tab (so cmd/middle-click and "open in new tab"
|
|
67
|
+
* work). Return undefined to omit Manage for a given connection. Preferred
|
|
68
|
+
* over `onManage` — only fall back to the callback when the URL must be minted
|
|
69
|
+
* imperatively on click (e.g. a one-time token).
|
|
70
|
+
*/
|
|
71
|
+
getManageHref?: (connection: IntegrationConnection) => string | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Imperative fallback for opening a connected app's management page, used only
|
|
74
|
+
* when `getManageHref` is not supplied (or returns undefined). The consumer is
|
|
75
|
+
* responsible for opening the page (e.g. `window.open(...)`).
|
|
76
|
+
*/
|
|
77
|
+
onManage?: (input: {
|
|
78
|
+
connectionId: string;
|
|
79
|
+
providerId: string;
|
|
80
|
+
}) => void | Promise<void>;
|
|
63
81
|
/** Empty-state message when the catalog hasn't loaded any providers. */
|
|
64
82
|
emptyCatalogLabel?: string;
|
|
65
83
|
/**
|
|
@@ -72,7 +90,7 @@ interface IntegrationsPanelProps {
|
|
|
72
90
|
defaultSort?: IntegrationSort;
|
|
73
91
|
className?: string;
|
|
74
92
|
}
|
|
75
|
-
declare function IntegrationsPanel({ catalog, connections, healthByConnectionId, isLoading, error, onConnect, onDisconnect, emptyCatalogLabel, featuredIds, defaultSort, className, }: IntegrationsPanelProps): react_jsx_runtime.JSX.Element;
|
|
93
|
+
declare function IntegrationsPanel({ catalog, connections, healthByConnectionId, isLoading, error, onConnect, onDisconnect, getManageHref, onManage, emptyCatalogLabel, featuredIds, defaultSort, className, }: IntegrationsPanelProps): react_jsx_runtime.JSX.Element;
|
|
76
94
|
|
|
77
95
|
/**
|
|
78
96
|
* Endpoint contract expected on the consumer app's server (which
|
package/dist/integrations.js
CHANGED
|
@@ -16,10 +16,15 @@ import {
|
|
|
16
16
|
DialogFooter,
|
|
17
17
|
DialogHeader,
|
|
18
18
|
DialogTitle,
|
|
19
|
+
DropdownMenu,
|
|
20
|
+
DropdownMenuContent,
|
|
21
|
+
DropdownMenuItem,
|
|
22
|
+
DropdownMenuSeparator,
|
|
23
|
+
DropdownMenuTrigger,
|
|
19
24
|
EmptyState
|
|
20
25
|
} from "@tangle-network/ui/primitives";
|
|
21
26
|
import { cn } from "@tangle-network/ui/utils";
|
|
22
|
-
import { Check, Search, Unplug } from "lucide-react";
|
|
27
|
+
import { Check, ExternalLink, MoreVertical, Search, Unplug } from "lucide-react";
|
|
23
28
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24
29
|
var DEFAULT_FEATURED_IDS = [
|
|
25
30
|
"gmail",
|
|
@@ -99,6 +104,8 @@ function IntegrationsPanel({
|
|
|
99
104
|
error,
|
|
100
105
|
onConnect,
|
|
101
106
|
onDisconnect,
|
|
107
|
+
getManageHref,
|
|
108
|
+
onManage,
|
|
102
109
|
emptyCatalogLabel = "No integrations available yet.",
|
|
103
110
|
featuredIds = DEFAULT_FEATURED_IDS,
|
|
104
111
|
defaultSort = "featured",
|
|
@@ -252,6 +259,8 @@ function IntegrationsPanel({
|
|
|
252
259
|
const name = displayNameOf(provider);
|
|
253
260
|
const connected = Boolean(live);
|
|
254
261
|
if (connected && live) {
|
|
262
|
+
const manageHref = getManageHref?.(live);
|
|
263
|
+
const canManage = Boolean(manageHref) || Boolean(onManage);
|
|
255
264
|
return /* @__PURE__ */ jsxs(
|
|
256
265
|
"div",
|
|
257
266
|
{
|
|
@@ -259,56 +268,118 @@ function IntegrationsPanel({
|
|
|
259
268
|
"data-connected": "true",
|
|
260
269
|
title: live.accountDisplay ? `${name} \u2014 ${live.accountDisplay}` : name,
|
|
261
270
|
className: cn(
|
|
262
|
-
"relative flex aspect-square flex-col items-center justify-center gap-2 rounded-xl border p-3 text-center",
|
|
271
|
+
"group relative flex aspect-square flex-col items-center justify-center gap-2 rounded-xl border p-3 text-center",
|
|
263
272
|
"border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]"
|
|
264
273
|
),
|
|
265
274
|
children: [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
"button",
|
|
275
|
+
manageHref ? /* @__PURE__ */ jsx(
|
|
276
|
+
"a",
|
|
269
277
|
{
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
"data-testid": `disconnect-${provider.providerId}`,
|
|
277
|
-
"aria-label": `Disconnect ${name}`,
|
|
278
|
-
title: "Disconnect",
|
|
279
|
-
className: "absolute right-1.5 top-1.5 flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground/70 transition-colors hover:bg-background hover:text-foreground focus-visible:bg-background focus-visible:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
280
|
-
children: /* @__PURE__ */ jsx(Unplug, { className: "h-3.5 w-3.5" })
|
|
278
|
+
href: manageHref,
|
|
279
|
+
target: "_blank",
|
|
280
|
+
rel: "noopener noreferrer",
|
|
281
|
+
"aria-label": `Manage ${name} (opens in new window)`,
|
|
282
|
+
"data-testid": `manage-${provider.providerId}`,
|
|
283
|
+
className: "absolute inset-0 z-10 rounded-xl focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
|
|
281
284
|
}
|
|
282
|
-
),
|
|
283
|
-
/* @__PURE__ */ jsx(
|
|
284
|
-
|
|
285
|
-
{
|
|
286
|
-
id: provider.providerId,
|
|
287
|
-
iconUrl: provider.iconUrl,
|
|
288
|
-
displayName: provider.displayName,
|
|
289
|
-
size: LOGO_SIZE,
|
|
290
|
-
className: "rounded-2xl"
|
|
291
|
-
}
|
|
292
|
-
),
|
|
293
|
-
/* @__PURE__ */ jsxs("div", { className: "flex h-8 w-full flex-col justify-center leading-4", children: [
|
|
285
|
+
) : null,
|
|
286
|
+
/* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 top-2 flex h-4 w-4 items-center justify-center rounded-full bg-[var(--surface-success-text)] text-white", children: /* @__PURE__ */ jsx(Check, { className: "h-3 w-3", strokeWidth: 3 }) }),
|
|
287
|
+
/* @__PURE__ */ jsxs("div", { className: "pointer-events-none flex flex-col items-center gap-2", children: [
|
|
294
288
|
/* @__PURE__ */ jsx(
|
|
295
|
-
|
|
289
|
+
ProviderIcon,
|
|
296
290
|
{
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
291
|
+
id: provider.providerId,
|
|
292
|
+
iconUrl: provider.iconUrl,
|
|
293
|
+
displayName: provider.displayName,
|
|
294
|
+
size: LOGO_SIZE,
|
|
295
|
+
className: "rounded-2xl"
|
|
302
296
|
}
|
|
303
297
|
),
|
|
304
|
-
|
|
305
|
-
|
|
298
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-8 w-full flex-col justify-center leading-4", children: [
|
|
299
|
+
/* @__PURE__ */ jsx(
|
|
300
|
+
"span",
|
|
301
|
+
{
|
|
302
|
+
className: cn(
|
|
303
|
+
"w-full text-xs font-medium text-foreground",
|
|
304
|
+
live.accountDisplay ? "truncate" : "line-clamp-2"
|
|
305
|
+
),
|
|
306
|
+
children: name
|
|
307
|
+
}
|
|
308
|
+
),
|
|
309
|
+
live.accountDisplay ? /* @__PURE__ */ jsx(
|
|
310
|
+
"span",
|
|
311
|
+
{
|
|
312
|
+
className: "w-full truncate text-[11px] leading-4 text-muted-foreground",
|
|
313
|
+
"data-testid": `account-${provider.providerId}`,
|
|
314
|
+
children: live.accountDisplay
|
|
315
|
+
}
|
|
316
|
+
) : null
|
|
317
|
+
] })
|
|
318
|
+
] }),
|
|
319
|
+
manageHref ? /* @__PURE__ */ jsx(
|
|
320
|
+
ExternalLink,
|
|
321
|
+
{
|
|
322
|
+
"aria-hidden": true,
|
|
323
|
+
className: "pointer-events-none absolute bottom-1.5 right-1.5 h-3.5 w-3.5 text-muted-foreground/70 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100"
|
|
324
|
+
}
|
|
325
|
+
) : null,
|
|
326
|
+
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
327
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
328
|
+
"button",
|
|
306
329
|
{
|
|
307
|
-
|
|
308
|
-
"data-testid": `
|
|
309
|
-
|
|
330
|
+
type: "button",
|
|
331
|
+
"data-testid": `menu-${provider.providerId}`,
|
|
332
|
+
"aria-label": `More actions for ${name}`,
|
|
333
|
+
title: "More actions",
|
|
334
|
+
className: "absolute right-1.5 top-1.5 z-20 flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground/70 transition-colors hover:bg-background hover:text-foreground focus-visible:bg-background focus-visible:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
335
|
+
children: /* @__PURE__ */ jsx(MoreVertical, { className: "h-3.5 w-3.5" })
|
|
310
336
|
}
|
|
311
|
-
)
|
|
337
|
+
) }),
|
|
338
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
|
|
339
|
+
manageHref ? /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
340
|
+
"a",
|
|
341
|
+
{
|
|
342
|
+
href: manageHref,
|
|
343
|
+
target: "_blank",
|
|
344
|
+
rel: "noopener noreferrer",
|
|
345
|
+
"data-testid": `manage-item-${provider.providerId}`,
|
|
346
|
+
children: [
|
|
347
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "mr-2 h-4 w-4" }),
|
|
348
|
+
" Manage"
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
) }) : onManage ? /* @__PURE__ */ jsxs(
|
|
352
|
+
DropdownMenuItem,
|
|
353
|
+
{
|
|
354
|
+
"data-testid": `manage-item-${provider.providerId}`,
|
|
355
|
+
onClick: () => onManage({
|
|
356
|
+
connectionId: live.id,
|
|
357
|
+
providerId: provider.providerId
|
|
358
|
+
}),
|
|
359
|
+
children: [
|
|
360
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "mr-2 h-4 w-4" }),
|
|
361
|
+
" Manage"
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
) : null,
|
|
365
|
+
canManage ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
|
|
366
|
+
/* @__PURE__ */ jsxs(
|
|
367
|
+
DropdownMenuItem,
|
|
368
|
+
{
|
|
369
|
+
"data-testid": `disconnect-${provider.providerId}`,
|
|
370
|
+
className: "text-destructive focus:text-destructive",
|
|
371
|
+
onClick: () => setDisconnectTarget({
|
|
372
|
+
connectionId: live.id,
|
|
373
|
+
name,
|
|
374
|
+
accountDisplay: live.accountDisplay
|
|
375
|
+
}),
|
|
376
|
+
children: [
|
|
377
|
+
/* @__PURE__ */ jsx(Unplug, { className: "mr-2 h-4 w-4" }),
|
|
378
|
+
" Disconnect"
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
] })
|
|
312
383
|
] })
|
|
313
384
|
]
|
|
314
385
|
},
|
package/dist/pages.d.ts
CHANGED
|
@@ -202,7 +202,7 @@ interface ProvisioningConfig {
|
|
|
202
202
|
key: string;
|
|
203
203
|
value: string;
|
|
204
204
|
}[];
|
|
205
|
-
driver: "docker" | "firecracker" | "host-agent
|
|
205
|
+
driver: "docker" | "firecracker" | "host-agent" | "tangle";
|
|
206
206
|
bare: boolean;
|
|
207
207
|
startupScriptIds?: string[];
|
|
208
208
|
}
|
package/dist/styles.css
CHANGED
|
@@ -317,6 +317,9 @@
|
|
|
317
317
|
.inset-x-0 {
|
|
318
318
|
inset-inline: calc(var(--spacing) * 0);
|
|
319
319
|
}
|
|
320
|
+
.inset-x-2 {
|
|
321
|
+
inset-inline: calc(var(--spacing) * 2);
|
|
322
|
+
}
|
|
320
323
|
.inset-y-0 {
|
|
321
324
|
inset-block: calc(var(--spacing) * 0);
|
|
322
325
|
}
|
|
@@ -392,6 +395,9 @@
|
|
|
392
395
|
.bottom-1 {
|
|
393
396
|
bottom: calc(var(--spacing) * 1);
|
|
394
397
|
}
|
|
398
|
+
.bottom-1\.5 {
|
|
399
|
+
bottom: calc(var(--spacing) * 1.5);
|
|
400
|
+
}
|
|
395
401
|
.bottom-2 {
|
|
396
402
|
bottom: calc(var(--spacing) * 2);
|
|
397
403
|
}
|
|
@@ -437,6 +443,9 @@
|
|
|
437
443
|
.z-10 {
|
|
438
444
|
z-index: 10;
|
|
439
445
|
}
|
|
446
|
+
.z-20 {
|
|
447
|
+
z-index: 20;
|
|
448
|
+
}
|
|
440
449
|
.z-30 {
|
|
441
450
|
z-index: 30;
|
|
442
451
|
}
|
|
@@ -753,6 +762,9 @@
|
|
|
753
762
|
.h-\[640px\] {
|
|
754
763
|
height: 640px;
|
|
755
764
|
}
|
|
765
|
+
.h-\[720px\] {
|
|
766
|
+
height: 720px;
|
|
767
|
+
}
|
|
756
768
|
.h-\[var\(--avatar-size\)\] {
|
|
757
769
|
height: var(--avatar-size);
|
|
758
770
|
}
|
|
@@ -816,6 +828,9 @@
|
|
|
816
828
|
.max-h-\[440px\] {
|
|
817
829
|
max-height: 440px;
|
|
818
830
|
}
|
|
831
|
+
.max-h-\[min\(18rem\,50vh\)\] {
|
|
832
|
+
max-height: min(18rem, 50vh);
|
|
833
|
+
}
|
|
819
834
|
.min-h-0 {
|
|
820
835
|
min-height: calc(var(--spacing) * 0);
|
|
821
836
|
}
|
|
@@ -1026,6 +1041,9 @@
|
|
|
1026
1041
|
.w-\[420px\] {
|
|
1027
1042
|
width: 420px;
|
|
1028
1043
|
}
|
|
1044
|
+
.w-\[460px\] {
|
|
1045
|
+
width: 460px;
|
|
1046
|
+
}
|
|
1029
1047
|
.w-\[480px\] {
|
|
1030
1048
|
width: 480px;
|
|
1031
1049
|
}
|
|
@@ -3452,6 +3470,12 @@
|
|
|
3452
3470
|
.ring-\[var\(--md3-outline-variant\)\] {
|
|
3453
3471
|
--tw-ring-color: var(--md3-outline-variant);
|
|
3454
3472
|
}
|
|
3473
|
+
.ring-black\/5 {
|
|
3474
|
+
--tw-ring-color: color-mix(in srgb, #000 5%, transparent);
|
|
3475
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
3476
|
+
--tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent);
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3455
3479
|
.ring-border {
|
|
3456
3480
|
--tw-ring-color: var(--color-border);
|
|
3457
3481
|
}
|
|
@@ -3626,6 +3650,11 @@
|
|
|
3626
3650
|
rotate: 180deg;
|
|
3627
3651
|
}
|
|
3628
3652
|
}
|
|
3653
|
+
.group-focus-within\:opacity-100 {
|
|
3654
|
+
&:is(:where(.group):focus-within *) {
|
|
3655
|
+
opacity: 100%;
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3629
3658
|
.group-focus-within\/tip\:translate-x-0 {
|
|
3630
3659
|
&:is(:where(.group\/tip):focus-within *) {
|
|
3631
3660
|
--tw-translate-x: calc(var(--spacing) * 0);
|
|
@@ -3676,6 +3705,13 @@
|
|
|
3676
3705
|
}
|
|
3677
3706
|
}
|
|
3678
3707
|
}
|
|
3708
|
+
.group-hover\/logo\:opacity-100 {
|
|
3709
|
+
&:is(:where(.group\/logo):hover *) {
|
|
3710
|
+
@media (hover: hover) {
|
|
3711
|
+
opacity: 100%;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3679
3715
|
.group-hover\/tip\:translate-x-0 {
|
|
3680
3716
|
&:is(:where(.group\/tip):hover *) {
|
|
3681
3717
|
@media (hover: hover) {
|
|
@@ -4188,6 +4224,16 @@
|
|
|
4188
4224
|
}
|
|
4189
4225
|
}
|
|
4190
4226
|
}
|
|
4227
|
+
.hover\:bg-muted\/60 {
|
|
4228
|
+
&:hover {
|
|
4229
|
+
@media (hover: hover) {
|
|
4230
|
+
background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
|
|
4231
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
4232
|
+
background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4191
4237
|
.hover\:bg-muted\/80 {
|
|
4192
4238
|
&:hover {
|
|
4193
4239
|
@media (hover: hover) {
|
|
@@ -4755,6 +4801,15 @@
|
|
|
4755
4801
|
opacity: 60%;
|
|
4756
4802
|
}
|
|
4757
4803
|
}
|
|
4804
|
+
.disabled\:hover\:bg-transparent {
|
|
4805
|
+
&:disabled {
|
|
4806
|
+
&:hover {
|
|
4807
|
+
@media (hover: hover) {
|
|
4808
|
+
background-color: transparent;
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4758
4813
|
.data-\[disabled\]\:pointer-events-none {
|
|
4759
4814
|
&[data-disabled] {
|
|
4760
4815
|
pointer-events: none;
|
package/dist/workbench.js
CHANGED
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
buildUnifiedPatch,
|
|
13
13
|
computeDiffStats,
|
|
14
14
|
resolveLanguage
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-MGIOO3RL.js";
|
|
16
16
|
import "./chunk-3J6FG3FJ.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-RT4MLYYM.js";
|
|
18
18
|
import "./chunk-OMUIPJQZ.js";
|
|
19
19
|
import "./chunk-VIREDUBF.js";
|
|
20
20
|
import "./chunk-77WVVJA4.js";
|
package/package.json
CHANGED