@tangle-network/sandbox-ui 0.43.0 → 0.45.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/{WorkflowGraph-5QO6WCY2.js → WorkflowGraph-7YYGIBNV.js} +15 -1
- package/dist/assistant.js +68 -31
- package/dist/chunk-H7GMPMPB.js +191 -0
- package/dist/globals.css +12 -2
- package/dist/integrations.js +13 -131
- package/dist/styles.css +12 -2
- package/dist/tokens.css +13 -2
- package/dist/workflows.js +51 -12
- package/package.json +3 -3
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProviderIcon
|
|
3
|
+
} from "./chunk-H7GMPMPB.js";
|
|
1
4
|
import {
|
|
2
5
|
buildWorkflowGraph
|
|
3
6
|
} from "./chunk-SUC6ZJZW.js";
|
|
@@ -75,7 +78,18 @@ function WorkflowNode({ data }) {
|
|
|
75
78
|
children: d.subtitle
|
|
76
79
|
}
|
|
77
80
|
),
|
|
78
|
-
d.provider && /* @__PURE__ */
|
|
81
|
+
d.provider && /* @__PURE__ */ jsxs("span", { className: "mt-1.5 inline-flex items-center gap-1 rounded bg-background-tertiary px-1.5 py-0.5 text-[10px] text-text-muted", children: [
|
|
82
|
+
/* @__PURE__ */ jsx(
|
|
83
|
+
ProviderIcon,
|
|
84
|
+
{
|
|
85
|
+
id: d.provider,
|
|
86
|
+
displayName: providerLabel(d.provider),
|
|
87
|
+
size: 12,
|
|
88
|
+
className: "rounded-[2px]"
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
providerLabel(d.provider)
|
|
92
|
+
] }),
|
|
79
93
|
/* @__PURE__ */ jsx(
|
|
80
94
|
Handle,
|
|
81
95
|
{
|
package/dist/assistant.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProviderIcon
|
|
3
|
+
} from "./chunk-H7GMPMPB.js";
|
|
1
4
|
import {
|
|
2
5
|
providerLabel
|
|
3
6
|
} from "./chunk-7JLB7UZ3.js";
|
|
@@ -1533,8 +1536,8 @@ import {
|
|
|
1533
1536
|
} from "react";
|
|
1534
1537
|
|
|
1535
1538
|
// src/assistant/AssistantPanel.tsx
|
|
1536
|
-
import { AgentTimeline, ChatInput } from "@tangle-network/ui/chat";
|
|
1537
|
-
import { History, Minus, Plus,
|
|
1539
|
+
import { AgentTimeline, ChatInput, ThinkingIndicator } from "@tangle-network/ui/chat";
|
|
1540
|
+
import { History, MessageSquarePlus, Minus, Plus, Trash2, X } from "lucide-react";
|
|
1538
1541
|
import { useRef as useRef4, useState as useState5 } from "react";
|
|
1539
1542
|
|
|
1540
1543
|
// src/assistant/build-timeline.tsx
|
|
@@ -1670,7 +1673,7 @@ function ProposalCard({
|
|
|
1670
1673
|
)
|
|
1671
1674
|
] })
|
|
1672
1675
|
] }),
|
|
1673
|
-
showGraph && tab === "graph" ? /* @__PURE__ */ jsx3("div", { className: "mt-1 h-
|
|
1676
|
+
showGraph && tab === "graph" ? /* @__PURE__ */ jsx3("div", { className: "mt-1 h-64 overflow-hidden rounded border border-border", children: renderGraph?.(view.preview.content) }) : /* @__PURE__ */ jsx3("pre", { className: "mt-1 max-h-48 overflow-auto rounded border border-border bg-muted/50 p-2 text-xs", children: /* @__PURE__ */ jsx3("code", { children: view.preview.content }) })
|
|
1674
1677
|
] }),
|
|
1675
1678
|
proposal.requirements && proposal.requirements.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-3 rounded border border-border p-2", children: [
|
|
1676
1679
|
/* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Integrations" }),
|
|
@@ -1737,16 +1740,33 @@ function RequirementRow({
|
|
|
1737
1740
|
const canConnect = !req.connected && req.connectUrl !== null;
|
|
1738
1741
|
const target = req.connectUrl ?? "/app/integrations";
|
|
1739
1742
|
return /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2 text-xs", children: [
|
|
1740
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
1743
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1741
1744
|
/* @__PURE__ */ jsx3(
|
|
1742
|
-
|
|
1745
|
+
ProviderIcon,
|
|
1743
1746
|
{
|
|
1744
|
-
|
|
1745
|
-
|
|
1747
|
+
id: req.provider,
|
|
1748
|
+
displayName: label,
|
|
1749
|
+
size: 16,
|
|
1750
|
+
className: "rounded"
|
|
1746
1751
|
}
|
|
1747
1752
|
),
|
|
1748
|
-
/* @__PURE__ */ jsx3("span", { className: "text-foreground", children: kindLabel }),
|
|
1749
|
-
/* @__PURE__ */
|
|
1753
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate text-foreground", children: kindLabel }),
|
|
1754
|
+
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1755
|
+
/* @__PURE__ */ jsx3(
|
|
1756
|
+
"span",
|
|
1757
|
+
{
|
|
1758
|
+
"aria-hidden": "true",
|
|
1759
|
+
className: `h-1.5 w-1.5 rounded-full ${req.connected ? "bg-primary" : "border border-muted-foreground"}`
|
|
1760
|
+
}
|
|
1761
|
+
),
|
|
1762
|
+
/* @__PURE__ */ jsx3(
|
|
1763
|
+
"span",
|
|
1764
|
+
{
|
|
1765
|
+
className: req.connected ? "text-primary" : "text-muted-foreground",
|
|
1766
|
+
children: statusText
|
|
1767
|
+
}
|
|
1768
|
+
)
|
|
1769
|
+
] })
|
|
1750
1770
|
] }),
|
|
1751
1771
|
canConnect && /* @__PURE__ */ jsxs(
|
|
1752
1772
|
"button",
|
|
@@ -1910,6 +1930,9 @@ function AssistantPanel({
|
|
|
1910
1930
|
const errorView = state.error ? presentError(state.error.code, state.error.message) : null;
|
|
1911
1931
|
const low = isLowBalance(effectiveBalance) && !errorView;
|
|
1912
1932
|
const streaming = state.status === "streaming";
|
|
1933
|
+
const firstUserText = state.messages.find((m) => m.role === "user")?.text.trim();
|
|
1934
|
+
const titleChars = firstUserText ? Array.from(firstUserText) : [];
|
|
1935
|
+
const conversationTitle = firstUserText ? titleChars.length > 60 ? `${titleChars.slice(0, 60).join("")}\u2026` : firstUserText : null;
|
|
1913
1936
|
const renderProposal = (proposal) => /* @__PURE__ */ jsx4(
|
|
1914
1937
|
ProposalCard,
|
|
1915
1938
|
{
|
|
@@ -1942,19 +1965,29 @@ function AssistantPanel({
|
|
|
1942
1965
|
}
|
|
1943
1966
|
};
|
|
1944
1967
|
return /* @__PURE__ */ jsxs2("div", { className: "flex h-full flex-col bg-background", children: [
|
|
1945
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between border-border border-b px-4 py-3", children: [
|
|
1946
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex
|
|
1947
|
-
/* @__PURE__ */
|
|
1948
|
-
|
|
1968
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 border-border border-b px-4 py-3", children: [
|
|
1969
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-col", children: [
|
|
1970
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-baseline gap-2", children: [
|
|
1971
|
+
/* @__PURE__ */ jsx4("span", { className: "font-medium text-foreground text-sm", children: "Assistant" }),
|
|
1972
|
+
/* @__PURE__ */ jsx4(
|
|
1973
|
+
"span",
|
|
1974
|
+
{
|
|
1975
|
+
"aria-label": "Your credit balance",
|
|
1976
|
+
className: "text-muted-foreground text-xs",
|
|
1977
|
+
children: formatMoney(effectiveBalance)
|
|
1978
|
+
}
|
|
1979
|
+
)
|
|
1980
|
+
] }),
|
|
1981
|
+
conversationTitle && /* @__PURE__ */ jsx4(
|
|
1949
1982
|
"span",
|
|
1950
1983
|
{
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
children:
|
|
1984
|
+
className: "truncate text-muted-foreground text-xs",
|
|
1985
|
+
title: conversationTitle,
|
|
1986
|
+
children: conversationTitle
|
|
1954
1987
|
}
|
|
1955
1988
|
)
|
|
1956
1989
|
] }),
|
|
1957
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1", children: [
|
|
1990
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1958
1991
|
/* @__PURE__ */ jsxs2("div", { className: "flex items-center", role: "group", "aria-label": "Text size", children: [
|
|
1959
1992
|
/* @__PURE__ */ jsx4(
|
|
1960
1993
|
"button",
|
|
@@ -1996,8 +2029,9 @@ function AssistantPanel({
|
|
|
1996
2029
|
type: "button",
|
|
1997
2030
|
onClick: chat.reset,
|
|
1998
2031
|
"aria-label": "New chat",
|
|
2032
|
+
title: "New chat",
|
|
1999
2033
|
className: "rounded p-1 text-muted-foreground hover:text-foreground",
|
|
2000
|
-
children: /* @__PURE__ */ jsx4(
|
|
2034
|
+
children: /* @__PURE__ */ jsx4(MessageSquarePlus, { className: "h-4 w-4" })
|
|
2001
2035
|
}
|
|
2002
2036
|
),
|
|
2003
2037
|
/* @__PURE__ */ jsx4(
|
|
@@ -2133,19 +2167,22 @@ function AssistantPanel({
|
|
|
2133
2167
|
]
|
|
2134
2168
|
}
|
|
2135
2169
|
),
|
|
2136
|
-
/* @__PURE__ */
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2170
|
+
/* @__PURE__ */ jsxs2("div", { className: "border-border border-t p-2", children: [
|
|
2171
|
+
streaming && /* @__PURE__ */ jsx4("div", { className: "px-2 pb-1.5", "aria-label": "Assistant is working", children: /* @__PURE__ */ jsx4(ThinkingIndicator, {}) }),
|
|
2172
|
+
/* @__PURE__ */ jsx4(
|
|
2173
|
+
ChatInput,
|
|
2174
|
+
{
|
|
2175
|
+
onSend: (message) => chat.send(message),
|
|
2176
|
+
onCancel: chat.stop,
|
|
2177
|
+
isStreaming: streaming,
|
|
2178
|
+
disabled: chat.restoring || state.status === "awaiting_confirm",
|
|
2179
|
+
placeholder: "Message the assistant\u2026",
|
|
2180
|
+
inputLabel: null,
|
|
2181
|
+
idleStatus: null,
|
|
2182
|
+
streamingStatus: null
|
|
2183
|
+
}
|
|
2184
|
+
)
|
|
2185
|
+
] })
|
|
2149
2186
|
] });
|
|
2150
2187
|
}
|
|
2151
2188
|
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// src/integrations/provider-logo.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
function normalizeProviderId(id) {
|
|
5
|
+
return id.toLowerCase().replace(/[_\s]+/g, "-").replace(/-(business|oauth|api|app|mail|sms|pack|connector|v\d+)$/g, "");
|
|
6
|
+
}
|
|
7
|
+
var PROVIDER_LOGO_SLUGS = {
|
|
8
|
+
gmail: "gmail",
|
|
9
|
+
googlemail: "gmail",
|
|
10
|
+
google: "google",
|
|
11
|
+
"google-drive": "googledrive",
|
|
12
|
+
"google-calendar": "googlecalendar",
|
|
13
|
+
"google-sheets": "googlesheets",
|
|
14
|
+
"google-docs": "googledocs",
|
|
15
|
+
"google-meet": "googlemeet",
|
|
16
|
+
"google-forms": "googleforms",
|
|
17
|
+
"google-ads": "googleads",
|
|
18
|
+
"google-analytics": "googleanalytics",
|
|
19
|
+
outlook: "microsoftoutlook",
|
|
20
|
+
"outlook-mail": "microsoftoutlook",
|
|
21
|
+
"microsoft-outlook": "microsoftoutlook",
|
|
22
|
+
"microsoft-calendar": "microsoftoutlook",
|
|
23
|
+
"microsoft-teams": "microsoftteams",
|
|
24
|
+
teams: "microsoftteams",
|
|
25
|
+
"microsoft-excel": "microsoftexcel",
|
|
26
|
+
excel: "microsoftexcel",
|
|
27
|
+
onedrive: "microsoftonedrive",
|
|
28
|
+
sharepoint: "microsoftsharepoint",
|
|
29
|
+
twitter: "x",
|
|
30
|
+
x: "x",
|
|
31
|
+
meta: "meta",
|
|
32
|
+
"stripe-pack": "stripe",
|
|
33
|
+
"twilio-sms": "twilio",
|
|
34
|
+
webhook: "webhooks",
|
|
35
|
+
webhooks: "webhooks",
|
|
36
|
+
hubspot: "hubspot",
|
|
37
|
+
salesforce: "salesforce",
|
|
38
|
+
pipedrive: "pipedrive",
|
|
39
|
+
zoho: "zoho",
|
|
40
|
+
quickbooks: "quickbooks",
|
|
41
|
+
intercom: "intercom",
|
|
42
|
+
zendesk: "zendesk",
|
|
43
|
+
freshdesk: "freshdesk",
|
|
44
|
+
monday: "mondaydotcom",
|
|
45
|
+
"monday-com": "mondaydotcom",
|
|
46
|
+
clickup: "clickup",
|
|
47
|
+
basecamp: "basecamp",
|
|
48
|
+
todoist: "todoist",
|
|
49
|
+
calendly: "calendly",
|
|
50
|
+
typeform: "typeform",
|
|
51
|
+
surveymonkey: "surveymonkey",
|
|
52
|
+
klaviyo: "klaviyo",
|
|
53
|
+
sendinblue: "brevo",
|
|
54
|
+
brevo: "brevo",
|
|
55
|
+
"constant-contact": "constantcontact",
|
|
56
|
+
"active-campaign": "activecampaign",
|
|
57
|
+
activecampaign: "activecampaign",
|
|
58
|
+
"google-chat": "googlechat",
|
|
59
|
+
whatsapp: "whatsapp",
|
|
60
|
+
telegram: "telegram",
|
|
61
|
+
bigquery: "googlebigquery",
|
|
62
|
+
snowflake: "snowflake",
|
|
63
|
+
postgres: "postgresql",
|
|
64
|
+
postgresql: "postgresql",
|
|
65
|
+
mysql: "mysql",
|
|
66
|
+
mongodb: "mongodb",
|
|
67
|
+
redis: "redis",
|
|
68
|
+
supabase: "supabase",
|
|
69
|
+
firebase: "firebase",
|
|
70
|
+
"aws-s3": "amazons3",
|
|
71
|
+
s3: "amazons3",
|
|
72
|
+
woocommerce: "woocommerce",
|
|
73
|
+
bigcommerce: "bigcommerce",
|
|
74
|
+
squarespace: "squarespace",
|
|
75
|
+
wix: "wix",
|
|
76
|
+
webflow: "webflow",
|
|
77
|
+
wordpress: "wordpress",
|
|
78
|
+
contentful: "contentful",
|
|
79
|
+
sanity: "sanity",
|
|
80
|
+
figma: "figma",
|
|
81
|
+
miro: "miro",
|
|
82
|
+
confluence: "confluence",
|
|
83
|
+
bitbucket: "bitbucket",
|
|
84
|
+
pagerduty: "pagerduty",
|
|
85
|
+
datadog: "datadog",
|
|
86
|
+
sentry: "sentry",
|
|
87
|
+
segment: "segment",
|
|
88
|
+
amplitude: "amplitude",
|
|
89
|
+
mixpanel: "mixpanel",
|
|
90
|
+
posthog: "posthog",
|
|
91
|
+
facebook: "facebook",
|
|
92
|
+
instagram: "instagram",
|
|
93
|
+
tiktok: "tiktok",
|
|
94
|
+
youtube: "youtube",
|
|
95
|
+
reddit: "reddit",
|
|
96
|
+
pinterest: "pinterest",
|
|
97
|
+
buffer: "buffer",
|
|
98
|
+
hootsuite: "hootsuite"
|
|
99
|
+
};
|
|
100
|
+
function providerLogoCandidates(opts) {
|
|
101
|
+
const out = [];
|
|
102
|
+
if (opts.iconUrl) out.push(opts.iconUrl);
|
|
103
|
+
const raw = opts.id.toLowerCase();
|
|
104
|
+
const norm = normalizeProviderId(raw);
|
|
105
|
+
const slugs = /* @__PURE__ */ new Set();
|
|
106
|
+
const curated = PROVIDER_LOGO_SLUGS[raw] ?? PROVIDER_LOGO_SLUGS[norm];
|
|
107
|
+
if (curated) slugs.add(curated);
|
|
108
|
+
slugs.add(norm.replace(/-/g, ""));
|
|
109
|
+
slugs.add(raw.replace(/[-_\s]/g, ""));
|
|
110
|
+
for (const slug of slugs) {
|
|
111
|
+
if (slug) out.push(`https://cdn.simpleicons.org/${slug}`);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
function monogramColor(seed) {
|
|
116
|
+
const palette = [
|
|
117
|
+
"#6366f1",
|
|
118
|
+
"#8b5cf6",
|
|
119
|
+
"#ec4899",
|
|
120
|
+
"#f43f5e",
|
|
121
|
+
"#f97316",
|
|
122
|
+
"#eab308",
|
|
123
|
+
"#22c55e",
|
|
124
|
+
"#14b8a6",
|
|
125
|
+
"#0ea5e9",
|
|
126
|
+
"#3b82f6"
|
|
127
|
+
];
|
|
128
|
+
let hash = 0;
|
|
129
|
+
for (let i = 0; i < seed.length; i += 1) {
|
|
130
|
+
hash = hash * 31 + seed.charCodeAt(i) >>> 0;
|
|
131
|
+
}
|
|
132
|
+
return palette[hash % palette.length];
|
|
133
|
+
}
|
|
134
|
+
function ProviderIcon({
|
|
135
|
+
id,
|
|
136
|
+
iconUrl,
|
|
137
|
+
displayName,
|
|
138
|
+
size = 24,
|
|
139
|
+
className
|
|
140
|
+
}) {
|
|
141
|
+
const candidates = React.useMemo(
|
|
142
|
+
() => providerLogoCandidates({ id, iconUrl }),
|
|
143
|
+
[id, iconUrl]
|
|
144
|
+
);
|
|
145
|
+
const [index, setIndex] = React.useState(0);
|
|
146
|
+
const candidateKey = `${id} ${iconUrl ?? ""}`;
|
|
147
|
+
const [seenKey, setSeenKey] = React.useState(candidateKey);
|
|
148
|
+
if (candidateKey !== seenKey) {
|
|
149
|
+
setSeenKey(candidateKey);
|
|
150
|
+
setIndex(0);
|
|
151
|
+
}
|
|
152
|
+
const label = (displayName ?? id).trim();
|
|
153
|
+
const initial = label.charAt(0).toUpperCase() || "?";
|
|
154
|
+
const src = candidates[index];
|
|
155
|
+
if (!src) {
|
|
156
|
+
return /* @__PURE__ */ jsx(
|
|
157
|
+
"span",
|
|
158
|
+
{
|
|
159
|
+
className: `flex shrink-0 items-center justify-center font-semibold text-white ${className ?? ""}`,
|
|
160
|
+
style: {
|
|
161
|
+
width: size,
|
|
162
|
+
height: size,
|
|
163
|
+
backgroundColor: monogramColor(id),
|
|
164
|
+
fontSize: Math.round(size * 0.42)
|
|
165
|
+
},
|
|
166
|
+
"aria-hidden": true,
|
|
167
|
+
children: initial
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return /* @__PURE__ */ jsx(
|
|
172
|
+
"img",
|
|
173
|
+
{
|
|
174
|
+
src,
|
|
175
|
+
alt: "",
|
|
176
|
+
width: size,
|
|
177
|
+
height: size,
|
|
178
|
+
loading: "lazy",
|
|
179
|
+
className: `shrink-0 object-contain ${className ?? ""}`,
|
|
180
|
+
style: { width: size, height: size },
|
|
181
|
+
onError: () => setIndex((i) => i + 1)
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export {
|
|
187
|
+
normalizeProviderId,
|
|
188
|
+
providerLogoCandidates,
|
|
189
|
+
monogramColor,
|
|
190
|
+
ProviderIcon
|
|
191
|
+
};
|
package/dist/globals.css
CHANGED
|
@@ -692,6 +692,9 @@
|
|
|
692
692
|
.h-56 {
|
|
693
693
|
height: calc(var(--spacing) * 56);
|
|
694
694
|
}
|
|
695
|
+
.h-64 {
|
|
696
|
+
height: calc(var(--spacing) * 64);
|
|
697
|
+
}
|
|
695
698
|
.h-\[3px\] {
|
|
696
699
|
height: 3px;
|
|
697
700
|
}
|
|
@@ -2378,6 +2381,9 @@
|
|
|
2378
2381
|
.pb-1 {
|
|
2379
2382
|
padding-bottom: calc(var(--spacing) * 1);
|
|
2380
2383
|
}
|
|
2384
|
+
.pb-1\.5 {
|
|
2385
|
+
padding-bottom: calc(var(--spacing) * 1.5);
|
|
2386
|
+
}
|
|
2381
2387
|
.pb-2 {
|
|
2382
2388
|
padding-bottom: calc(var(--spacing) * 2);
|
|
2383
2389
|
}
|
|
@@ -4163,7 +4169,9 @@
|
|
|
4163
4169
|
}
|
|
4164
4170
|
}
|
|
4165
4171
|
:root,
|
|
4166
|
-
[data-sandbox-ui]
|
|
4172
|
+
[data-sandbox-ui],
|
|
4173
|
+
[data-theme="dark"],
|
|
4174
|
+
.dark {
|
|
4167
4175
|
--md3-surface: #0a0a14;
|
|
4168
4176
|
--md3-surface-dim: #07070d;
|
|
4169
4177
|
--md3-surface-bright: #1b1a2c;
|
|
@@ -4406,7 +4414,9 @@
|
|
|
4406
4414
|
--font-display: "Inter", "Geist", sans-serif;
|
|
4407
4415
|
--font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
|
|
4408
4416
|
}
|
|
4409
|
-
[data-sandbox-theme="vault"]
|
|
4417
|
+
[data-sandbox-theme="vault"],
|
|
4418
|
+
[data-theme="light"],
|
|
4419
|
+
.light {
|
|
4410
4420
|
--md3-surface: #f8f9fb;
|
|
4411
4421
|
--md3-surface-dim: #d9dae0;
|
|
4412
4422
|
--md3-surface-bright: #f8f9fb;
|
package/dist/integrations.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
monogramColor,
|
|
3
|
+
normalizeProviderId,
|
|
4
|
+
providerLogoCandidates
|
|
5
|
+
} from "./chunk-H7GMPMPB.js";
|
|
6
|
+
|
|
1
7
|
// src/integrations/integrations-panel.tsx
|
|
2
8
|
import * as React from "react";
|
|
3
9
|
import { Card, CardContent, EmptyState } from "@tangle-network/ui/primitives";
|
|
@@ -42,141 +48,17 @@ var DEFAULT_FEATURED_IDS = [
|
|
|
42
48
|
function defaultConnectorOf(provider) {
|
|
43
49
|
return provider.connectors?.[0]?.connectorId ?? provider.providerId;
|
|
44
50
|
}
|
|
45
|
-
function normalizeProviderId(id) {
|
|
46
|
-
return id.toLowerCase().replace(/[_\s]+/g, "-").replace(/-(business|oauth|api|app|mail|sms|pack|connector|v\d+)$/g, "");
|
|
47
|
-
}
|
|
48
|
-
var PROVIDER_LOGO_SLUGS = {
|
|
49
|
-
gmail: "gmail",
|
|
50
|
-
googlemail: "gmail",
|
|
51
|
-
google: "google",
|
|
52
|
-
"google-drive": "googledrive",
|
|
53
|
-
"google-calendar": "googlecalendar",
|
|
54
|
-
"google-sheets": "googlesheets",
|
|
55
|
-
"google-docs": "googledocs",
|
|
56
|
-
"google-meet": "googlemeet",
|
|
57
|
-
"google-forms": "googleforms",
|
|
58
|
-
"google-ads": "googleads",
|
|
59
|
-
"google-analytics": "googleanalytics",
|
|
60
|
-
outlook: "microsoftoutlook",
|
|
61
|
-
"outlook-mail": "microsoftoutlook",
|
|
62
|
-
"microsoft-outlook": "microsoftoutlook",
|
|
63
|
-
"microsoft-calendar": "microsoftoutlook",
|
|
64
|
-
"microsoft-teams": "microsoftteams",
|
|
65
|
-
teams: "microsoftteams",
|
|
66
|
-
"microsoft-excel": "microsoftexcel",
|
|
67
|
-
excel: "microsoftexcel",
|
|
68
|
-
onedrive: "microsoftonedrive",
|
|
69
|
-
sharepoint: "microsoftsharepoint",
|
|
70
|
-
twitter: "x",
|
|
71
|
-
x: "x",
|
|
72
|
-
meta: "meta",
|
|
73
|
-
"stripe-pack": "stripe",
|
|
74
|
-
"twilio-sms": "twilio",
|
|
75
|
-
webhook: "webhooks",
|
|
76
|
-
webhooks: "webhooks",
|
|
77
|
-
hubspot: "hubspot",
|
|
78
|
-
salesforce: "salesforce",
|
|
79
|
-
pipedrive: "pipedrive",
|
|
80
|
-
zoho: "zoho",
|
|
81
|
-
quickbooks: "quickbooks",
|
|
82
|
-
intercom: "intercom",
|
|
83
|
-
zendesk: "zendesk",
|
|
84
|
-
freshdesk: "freshdesk",
|
|
85
|
-
monday: "mondaydotcom",
|
|
86
|
-
"monday-com": "mondaydotcom",
|
|
87
|
-
clickup: "clickup",
|
|
88
|
-
basecamp: "basecamp",
|
|
89
|
-
todoist: "todoist",
|
|
90
|
-
calendly: "calendly",
|
|
91
|
-
typeform: "typeform",
|
|
92
|
-
surveymonkey: "surveymonkey",
|
|
93
|
-
klaviyo: "klaviyo",
|
|
94
|
-
sendinblue: "brevo",
|
|
95
|
-
brevo: "brevo",
|
|
96
|
-
"constant-contact": "constantcontact",
|
|
97
|
-
"active-campaign": "activecampaign",
|
|
98
|
-
activecampaign: "activecampaign",
|
|
99
|
-
"google-chat": "googlechat",
|
|
100
|
-
whatsapp: "whatsapp",
|
|
101
|
-
telegram: "telegram",
|
|
102
|
-
bigquery: "googlebigquery",
|
|
103
|
-
snowflake: "snowflake",
|
|
104
|
-
postgres: "postgresql",
|
|
105
|
-
postgresql: "postgresql",
|
|
106
|
-
mysql: "mysql",
|
|
107
|
-
mongodb: "mongodb",
|
|
108
|
-
redis: "redis",
|
|
109
|
-
supabase: "supabase",
|
|
110
|
-
firebase: "firebase",
|
|
111
|
-
"aws-s3": "amazons3",
|
|
112
|
-
s3: "amazons3",
|
|
113
|
-
woocommerce: "woocommerce",
|
|
114
|
-
bigcommerce: "bigcommerce",
|
|
115
|
-
squarespace: "squarespace",
|
|
116
|
-
wix: "wix",
|
|
117
|
-
webflow: "webflow",
|
|
118
|
-
wordpress: "wordpress",
|
|
119
|
-
contentful: "contentful",
|
|
120
|
-
sanity: "sanity",
|
|
121
|
-
figma: "figma",
|
|
122
|
-
miro: "miro",
|
|
123
|
-
confluence: "confluence",
|
|
124
|
-
bitbucket: "bitbucket",
|
|
125
|
-
pagerduty: "pagerduty",
|
|
126
|
-
datadog: "datadog",
|
|
127
|
-
sentry: "sentry",
|
|
128
|
-
segment: "segment",
|
|
129
|
-
amplitude: "amplitude",
|
|
130
|
-
mixpanel: "mixpanel",
|
|
131
|
-
posthog: "posthog",
|
|
132
|
-
facebook: "facebook",
|
|
133
|
-
instagram: "instagram",
|
|
134
|
-
tiktok: "tiktok",
|
|
135
|
-
youtube: "youtube",
|
|
136
|
-
reddit: "reddit",
|
|
137
|
-
pinterest: "pinterest",
|
|
138
|
-
buffer: "buffer",
|
|
139
|
-
hootsuite: "hootsuite"
|
|
140
|
-
};
|
|
141
|
-
function logoCandidates(provider) {
|
|
142
|
-
const out = [];
|
|
143
|
-
if (provider.iconUrl) out.push(provider.iconUrl);
|
|
144
|
-
const raw = provider.providerId.toLowerCase();
|
|
145
|
-
const norm = normalizeProviderId(raw);
|
|
146
|
-
const slugs = /* @__PURE__ */ new Set();
|
|
147
|
-
const curated = PROVIDER_LOGO_SLUGS[raw] ?? PROVIDER_LOGO_SLUGS[norm];
|
|
148
|
-
if (curated) slugs.add(curated);
|
|
149
|
-
slugs.add(norm.replace(/-/g, ""));
|
|
150
|
-
slugs.add(raw.replace(/[-_\s]/g, ""));
|
|
151
|
-
for (const slug of slugs) {
|
|
152
|
-
if (slug) out.push(`https://cdn.simpleicons.org/${slug}`);
|
|
153
|
-
}
|
|
154
|
-
return out;
|
|
155
|
-
}
|
|
156
|
-
function monogramColor(seed) {
|
|
157
|
-
const palette = [
|
|
158
|
-
"#6366f1",
|
|
159
|
-
"#8b5cf6",
|
|
160
|
-
"#ec4899",
|
|
161
|
-
"#f43f5e",
|
|
162
|
-
"#f97316",
|
|
163
|
-
"#eab308",
|
|
164
|
-
"#22c55e",
|
|
165
|
-
"#14b8a6",
|
|
166
|
-
"#0ea5e9",
|
|
167
|
-
"#3b82f6"
|
|
168
|
-
];
|
|
169
|
-
let hash = 0;
|
|
170
|
-
for (let i = 0; i < seed.length; i += 1) {
|
|
171
|
-
hash = hash * 31 + seed.charCodeAt(i) >>> 0;
|
|
172
|
-
}
|
|
173
|
-
return palette[hash % palette.length];
|
|
174
|
-
}
|
|
175
51
|
function ProviderLogo({
|
|
176
52
|
provider,
|
|
177
53
|
size = 56
|
|
178
54
|
}) {
|
|
179
|
-
const candidates = React.useMemo(
|
|
55
|
+
const candidates = React.useMemo(
|
|
56
|
+
() => providerLogoCandidates({
|
|
57
|
+
id: provider.providerId,
|
|
58
|
+
iconUrl: provider.iconUrl
|
|
59
|
+
}),
|
|
60
|
+
[provider]
|
|
61
|
+
);
|
|
180
62
|
const [index, setIndex] = React.useState(0);
|
|
181
63
|
const label = (provider.displayName ?? provider.providerId).trim();
|
|
182
64
|
const initial = label.charAt(0).toUpperCase() || "?";
|
package/dist/styles.css
CHANGED
|
@@ -692,6 +692,9 @@
|
|
|
692
692
|
.h-56 {
|
|
693
693
|
height: calc(var(--spacing) * 56);
|
|
694
694
|
}
|
|
695
|
+
.h-64 {
|
|
696
|
+
height: calc(var(--spacing) * 64);
|
|
697
|
+
}
|
|
695
698
|
.h-\[3px\] {
|
|
696
699
|
height: 3px;
|
|
697
700
|
}
|
|
@@ -2378,6 +2381,9 @@
|
|
|
2378
2381
|
.pb-1 {
|
|
2379
2382
|
padding-bottom: calc(var(--spacing) * 1);
|
|
2380
2383
|
}
|
|
2384
|
+
.pb-1\.5 {
|
|
2385
|
+
padding-bottom: calc(var(--spacing) * 1.5);
|
|
2386
|
+
}
|
|
2381
2387
|
.pb-2 {
|
|
2382
2388
|
padding-bottom: calc(var(--spacing) * 2);
|
|
2383
2389
|
}
|
|
@@ -4163,7 +4169,9 @@
|
|
|
4163
4169
|
}
|
|
4164
4170
|
}
|
|
4165
4171
|
:root,
|
|
4166
|
-
[data-sandbox-ui]
|
|
4172
|
+
[data-sandbox-ui],
|
|
4173
|
+
[data-theme="dark"],
|
|
4174
|
+
.dark {
|
|
4167
4175
|
--md3-surface: #0a0a14;
|
|
4168
4176
|
--md3-surface-dim: #07070d;
|
|
4169
4177
|
--md3-surface-bright: #1b1a2c;
|
|
@@ -4406,7 +4414,9 @@
|
|
|
4406
4414
|
--font-display: "Inter", "Geist", sans-serif;
|
|
4407
4415
|
--font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
|
|
4408
4416
|
}
|
|
4409
|
-
[data-sandbox-theme="vault"]
|
|
4417
|
+
[data-sandbox-theme="vault"],
|
|
4418
|
+
[data-theme="light"],
|
|
4419
|
+
.light {
|
|
4410
4420
|
--md3-surface: #f8f9fb;
|
|
4411
4421
|
--md3-surface-dim: #d9dae0;
|
|
4412
4422
|
--md3-surface-bright: #f8f9fb;
|
package/dist/tokens.css
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
/* Brand: warm purple palette, #5B4ED4 primary */
|
|
3
3
|
|
|
4
4
|
/* MD3 surface hierarchy */
|
|
5
|
+
/* Dark is the default theme (`:root`/`[data-sandbox-ui]`). It also responds to
|
|
6
|
+
* the standard `[data-theme="dark"]` / `.dark` switch so any consumer can pin or
|
|
7
|
+
* toggle a theme without inventing an ad-hoc `data-sandbox-theme` name. */
|
|
5
8
|
:root,
|
|
6
|
-
[data-sandbox-ui]
|
|
9
|
+
[data-sandbox-ui],
|
|
10
|
+
[data-theme="dark"],
|
|
11
|
+
.dark {
|
|
7
12
|
--md3-surface: #0a0a14;
|
|
8
13
|
--md3-surface-dim: #07070d;
|
|
9
14
|
--md3-surface-bright: #1b1a2c;
|
|
@@ -304,7 +309,13 @@
|
|
|
304
309
|
--font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
|
|
305
310
|
}
|
|
306
311
|
|
|
307
|
-
|
|
312
|
+
/* Light theme — reachable via the named `vault` theme or the standard
|
|
313
|
+
* `[data-theme="light"]` / `.light` switch. Both blocks are single-attribute/
|
|
314
|
+
* class selectors, and this one is later in source order, so when an element
|
|
315
|
+
* carries both `data-sandbox-ui` (dark) and `data-theme="light"`, light wins. */
|
|
316
|
+
[data-sandbox-theme="vault"],
|
|
317
|
+
[data-theme="light"],
|
|
318
|
+
.light {
|
|
308
319
|
/* Light theme — clean professional, warm purple accents */
|
|
309
320
|
|
|
310
321
|
/* MD3 surface hierarchy */
|
package/dist/workflows.js
CHANGED
|
@@ -4,11 +4,32 @@ import {
|
|
|
4
4
|
import "./chunk-7JLB7UZ3.js";
|
|
5
5
|
|
|
6
6
|
// src/workflows/WorkflowGraphLazy.tsx
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Component,
|
|
9
|
+
lazy,
|
|
10
|
+
Suspense,
|
|
11
|
+
useMemo,
|
|
12
|
+
useState
|
|
13
|
+
} from "react";
|
|
8
14
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
);
|
|
15
|
+
function retryImport(factory, retries = 2, delayMs = 350) {
|
|
16
|
+
return factory().catch((err) => {
|
|
17
|
+
if (retries <= 0) throw err;
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
setTimeout(
|
|
20
|
+
() => retryImport(factory, retries - 1, delayMs).then(resolve, reject),
|
|
21
|
+
delayMs
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function lazyWorkflowGraph() {
|
|
27
|
+
return lazy(
|
|
28
|
+
() => retryImport(
|
|
29
|
+
() => import("./WorkflowGraph-7YYGIBNV.js").then((m) => ({ default: m.WorkflowGraph }))
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
12
33
|
var GraphErrorBoundary = class extends Component {
|
|
13
34
|
state = { hasError: false };
|
|
14
35
|
static getDerivedStateFromError() {
|
|
@@ -18,27 +39,45 @@ var GraphErrorBoundary = class extends Component {
|
|
|
18
39
|
return this.state.hasError ? this.props.fallback : this.props.children;
|
|
19
40
|
}
|
|
20
41
|
};
|
|
21
|
-
function GraphFallback({
|
|
42
|
+
function GraphFallback({
|
|
43
|
+
yaml,
|
|
44
|
+
className,
|
|
45
|
+
onRetry
|
|
46
|
+
}) {
|
|
22
47
|
return /* @__PURE__ */ jsxs(
|
|
23
48
|
"div",
|
|
24
49
|
{
|
|
25
50
|
className: `overflow-auto rounded-lg border border-border bg-background p-2 ${className ?? ""}`,
|
|
26
51
|
children: [
|
|
27
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [
|
|
53
|
+
/* @__PURE__ */ jsx("p", { className: "text-text-muted text-xs", children: "Couldn't render the graph \u2014 showing the definition." }),
|
|
54
|
+
/* @__PURE__ */ jsx(
|
|
55
|
+
"button",
|
|
56
|
+
{
|
|
57
|
+
type: "button",
|
|
58
|
+
onClick: onRetry,
|
|
59
|
+
className: "shrink-0 rounded border border-border px-1.5 py-0.5 text-text-muted text-xs transition hover:text-text",
|
|
60
|
+
children: "Retry"
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
] }),
|
|
28
64
|
/* @__PURE__ */ jsx("pre", { className: "text-text text-xs", children: /* @__PURE__ */ jsx("code", { children: yaml }) })
|
|
29
65
|
]
|
|
30
66
|
}
|
|
31
67
|
);
|
|
32
68
|
}
|
|
33
69
|
function WorkflowGraph(props) {
|
|
70
|
+
const [attempt, setAttempt] = useState(0);
|
|
71
|
+
const Impl = useMemo(() => lazyWorkflowGraph(), [attempt]);
|
|
34
72
|
return (
|
|
35
|
-
// Key the boundary by the workflow so a different/edited
|
|
36
|
-
// it and re-attempts the graph — a
|
|
37
|
-
// workflow doesn't permanently pin the
|
|
73
|
+
// Key the boundary by the workflow AND the attempt so a different/edited
|
|
74
|
+
// definition or a manual retry remounts it and re-attempts the graph — a
|
|
75
|
+
// transient chunk/render failure on one workflow doesn't permanently pin the
|
|
76
|
+
// YAML fallback.
|
|
38
77
|
/* @__PURE__ */ jsx(
|
|
39
78
|
GraphErrorBoundary,
|
|
40
79
|
{
|
|
41
|
-
fallback: /* @__PURE__ */ jsx(GraphFallback, { ...props }),
|
|
80
|
+
fallback: /* @__PURE__ */ jsx(GraphFallback, { ...props, onRetry: () => setAttempt((a) => a + 1) }),
|
|
42
81
|
children: /* @__PURE__ */ jsx(
|
|
43
82
|
Suspense,
|
|
44
83
|
{
|
|
@@ -49,11 +88,11 @@ function WorkflowGraph(props) {
|
|
|
49
88
|
children: "Loading graph\u2026"
|
|
50
89
|
}
|
|
51
90
|
),
|
|
52
|
-
children: /* @__PURE__ */ jsx(
|
|
91
|
+
children: /* @__PURE__ */ jsx(Impl, { ...props })
|
|
53
92
|
}
|
|
54
93
|
)
|
|
55
94
|
},
|
|
56
|
-
props.yaml
|
|
95
|
+
`${props.yaml}::${attempt}`
|
|
57
96
|
)
|
|
58
97
|
);
|
|
59
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
"test:bridge": "pnpm build && vitest run src/__tests__/re-export-identity.test.ts"
|
|
123
123
|
},
|
|
124
124
|
"peerDependencies": {
|
|
125
|
-
"@tangle-network/brand": "^0.
|
|
125
|
+
"@tangle-network/brand": "^0.6.0",
|
|
126
126
|
"@tangle-network/ui": "^4.0.0",
|
|
127
127
|
"react": "^18 || ^19",
|
|
128
128
|
"react-dom": "^18 || ^19",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"@storybook/react-vite": "^8.6.18",
|
|
177
177
|
"@tailwindcss/postcss": "^4.2.2",
|
|
178
178
|
"@tailwindcss/vite": "^4.2.2",
|
|
179
|
-
"@tangle-network/brand": "^0.
|
|
179
|
+
"@tangle-network/brand": "^0.6.0",
|
|
180
180
|
"@tangle-network/ui": "^4.1.0",
|
|
181
181
|
"@tanstack/react-query": "^5.91.0",
|
|
182
182
|
"@testing-library/dom": "^10.4.1",
|