@opengeni/react 5.0.4 → 5.0.5-canary.1
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 +3 -0
- package/dist/{chunk-SCZ6SUBW.js → chunk-H63SQTGI.js} +1258 -1837
- package/dist/chunk-H63SQTGI.js.map +1 -0
- package/dist/chunk-HQV2I5HV.js +124 -0
- package/dist/chunk-HQV2I5HV.js.map +1 -0
- package/dist/chunk-M2HNWZYR.js +835 -0
- package/dist/chunk-M2HNWZYR.js.map +1 -0
- package/dist/{chunk-Z7WBDB4E.js → chunk-V3WX3TQG.js} +283 -391
- package/dist/chunk-V3WX3TQG.js.map +1 -0
- package/dist/components/message-timeline.d.ts +3 -1
- package/dist/components/sandbox-workspace.d.ts +5 -0
- package/dist/composer.js +2 -1
- package/dist/connect-chooser.d.ts +1 -0
- package/dist/connect-panel.d.ts +2 -1
- package/dist/connect.d.ts +7 -0
- package/dist/connect.js +792 -183
- package/dist/connect.js.map +1 -1
- package/dist/connection-catalog.d.ts +33 -0
- package/dist/connection-installed.d.ts +15 -0
- package/dist/connection-logo.d.ts +6 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/device-authorization.d.ts +9 -1
- package/dist/index.js +39 -12
- package/dist/index.js.map +1 -1
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +14 -0
- package/dist/session-ui.d.ts +3 -0
- package/dist/session-ui.js +113 -2
- package/dist/session-ui.js.map +1 -1
- package/dist/skill-discovery.d.ts +29 -0
- package/dist/timeline/activity-rail.d.ts +3 -1
- package/dist/timeline/genie-loading.d.ts +24 -0
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/package.json +4 -3
- package/src/components/message-timeline.tsx +127 -20
- package/src/components/sandbox-workspace.tsx +29 -0
- package/src/connect-chooser.tsx +81 -21
- package/src/connect-panel.tsx +7 -1
- package/src/connect.ts +21 -0
- package/src/connection-catalog.tsx +153 -0
- package/src/connection-installed.tsx +45 -0
- package/src/connection-logo.tsx +29 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/device-authorization.tsx +9 -1
- package/src/hooks/use-codex-accounts.ts +1 -0
- package/src/plugin-details.tsx +182 -0
- package/src/plugin-discovery.tsx +161 -0
- package/src/session-ui.ts +3 -0
- package/src/skill-discovery.tsx +152 -0
- package/src/timeline/activity-rail.tsx +75 -4
- package/src/timeline/genie-loading.tsx +112 -0
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/turn-summary.tsx +8 -3
- package/styles/compiled.css +73 -0
- package/styles/connect.css +149 -1
- package/styles/index.css +15 -0
- package/dist/chunk-SCZ6SUBW.js.map +0 -1
- package/dist/chunk-Z7WBDB4E.js.map +0 -1
package/dist/connect.js
CHANGED
|
@@ -1,14 +1,125 @@
|
|
|
1
1
|
import "./chunk-IWIDV7SB.js";
|
|
2
|
+
import {
|
|
3
|
+
Markdown
|
|
4
|
+
} from "./chunk-M2HNWZYR.js";
|
|
2
5
|
import {
|
|
3
6
|
copyTextToClipboard
|
|
4
7
|
} from "./chunk-JVYQRRC4.js";
|
|
8
|
+
import "./chunk-HQV2I5HV.js";
|
|
9
|
+
import "./chunk-VZTQ73XT.js";
|
|
10
|
+
import "./chunk-22KP6LR5.js";
|
|
5
11
|
|
|
6
12
|
// src/connect.ts
|
|
7
13
|
import { useMemo, useSyncExternalStore } from "react";
|
|
8
14
|
|
|
9
|
-
// src/
|
|
10
|
-
import { useState } from "react";
|
|
15
|
+
// src/skill-discovery.tsx
|
|
16
|
+
import { useEffect, useState } from "react";
|
|
11
17
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
18
|
+
function SkillDiscovery(props) {
|
|
19
|
+
const query = props.query.trim();
|
|
20
|
+
return /* @__PURE__ */ jsxs("section", { className: "og-skill-discovery", "aria-label": "Discover skills", children: [
|
|
21
|
+
/* @__PURE__ */ jsxs("header", { children: [
|
|
22
|
+
/* @__PURE__ */ jsx("h3", { children: "Discover skills" }),
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
"a",
|
|
25
|
+
{
|
|
26
|
+
href: "https://skills.sh/",
|
|
27
|
+
target: "_blank",
|
|
28
|
+
rel: "noopener noreferrer",
|
|
29
|
+
className: "og-skill-discovery-browse",
|
|
30
|
+
children: "Browse skills.sh \u2197"
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] }),
|
|
34
|
+
!query && props.onSearch ? /* @__PURE__ */ jsx("button", { type: "button", className: "og-skill-discovery-search", onClick: props.onSearch, children: "Search skills" }) : null,
|
|
35
|
+
/* @__PURE__ */ jsx(DiscoveryResults, { ...props, query }, `${props.workspaceId}:${query}`)
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
var EMPTY_INSTALLED_SKILLS = [];
|
|
39
|
+
function DiscoveryResults({
|
|
40
|
+
client,
|
|
41
|
+
workspaceId,
|
|
42
|
+
query,
|
|
43
|
+
canManage,
|
|
44
|
+
onImport,
|
|
45
|
+
installedSkills = EMPTY_INSTALLED_SKILLS
|
|
46
|
+
}) {
|
|
47
|
+
const [result, setResult] = useState(null);
|
|
48
|
+
const [loading, setLoading] = useState(query.length >= 2);
|
|
49
|
+
const [error, setError] = useState(false);
|
|
50
|
+
const [retry, setRetry] = useState(0);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
let active = true;
|
|
53
|
+
setError(false);
|
|
54
|
+
if (query.length < 2) return;
|
|
55
|
+
setLoading(true);
|
|
56
|
+
let timer;
|
|
57
|
+
const search = async (attempt) => {
|
|
58
|
+
try {
|
|
59
|
+
const data = await client.searchPublicSkills(workspaceId, query);
|
|
60
|
+
if (!active) return;
|
|
61
|
+
setResult(data);
|
|
62
|
+
setLoading(false);
|
|
63
|
+
} catch (cause) {
|
|
64
|
+
if (!active) return;
|
|
65
|
+
const status = typeof cause === "object" && cause !== null && "status" in cause ? cause.status : void 0;
|
|
66
|
+
const transient = cause instanceof TypeError || typeof status === "number" && status >= 500 && status <= 599;
|
|
67
|
+
if (attempt === 0 && transient) {
|
|
68
|
+
timer = setTimeout(() => void search(1), 750);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
setError(true);
|
|
72
|
+
setLoading(false);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
timer = setTimeout(() => void search(0), 300);
|
|
76
|
+
return () => {
|
|
77
|
+
active = false;
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
};
|
|
80
|
+
}, [client, workspaceId, query, retry]);
|
|
81
|
+
return /* @__PURE__ */ jsxs("div", { "aria-busy": loading, children: [
|
|
82
|
+
/* @__PURE__ */ jsx("div", { className: "og-skill-discovery-grid", children: result?.items.map((skill) => {
|
|
83
|
+
const installed = installedSkills.some(
|
|
84
|
+
(entry) => entry.sourceUrl.replace(/\/$/, "").toLowerCase() === skill.url.toLowerCase() || entry.repositoryUrl.replace(/\/$/, "").toLowerCase() === `https://github.com/${skill.source}`.toLowerCase() && entry.name.toLowerCase() === skill.name.toLowerCase()
|
|
85
|
+
);
|
|
86
|
+
return /* @__PURE__ */ jsxs(
|
|
87
|
+
"button",
|
|
88
|
+
{
|
|
89
|
+
type: "button",
|
|
90
|
+
className: "og-skill-discovery-item",
|
|
91
|
+
disabled: !canManage,
|
|
92
|
+
onClick: () => onImport(skill.url),
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsxs("span", { className: "og-skill-discovery-copy", children: [
|
|
95
|
+
/* @__PURE__ */ jsx("strong", { children: skill.name }),
|
|
96
|
+
/* @__PURE__ */ jsx("span", { children: skill.source }),
|
|
97
|
+
/* @__PURE__ */ jsxs("small", { children: [
|
|
98
|
+
skill.installs.toLocaleString(),
|
|
99
|
+
" installs"
|
|
100
|
+
] })
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsx("span", { className: "og-skill-discovery-action", children: installed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
103
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2713 " }),
|
|
104
|
+
"Installed"
|
|
105
|
+
] }) : !canManage ? "Admin required" : "Preview \u2192" })
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
skill.id
|
|
109
|
+
);
|
|
110
|
+
}) }),
|
|
111
|
+
loading ? /* @__PURE__ */ jsx("p", { role: "status", children: "Loading skills\u2026" }) : null,
|
|
112
|
+
error ? /* @__PURE__ */ jsxs("div", { role: "alert", className: "og-skill-discovery-error", children: [
|
|
113
|
+
"Could not load skills.",
|
|
114
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "Retry" })
|
|
115
|
+
] }) : null,
|
|
116
|
+
result && !result.items.length && !loading && !error ? /* @__PURE__ */ jsx("p", { role: "status", children: "No skills found. Try a different search." }) : null
|
|
117
|
+
] });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/connect-setup.tsx
|
|
121
|
+
import { useState as useState2 } from "react";
|
|
122
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
12
123
|
var setupStatus = {
|
|
13
124
|
ready: "Ready to connect",
|
|
14
125
|
requires_user_action: "Authorize your account",
|
|
@@ -35,17 +146,17 @@ function deviceVerificationUrl(action) {
|
|
|
35
146
|
}
|
|
36
147
|
}
|
|
37
148
|
function ConnectSetup(props) {
|
|
38
|
-
const [scope, setScope] =
|
|
39
|
-
const [generation, setGeneration] =
|
|
149
|
+
const [scope, setScope] = useState2(props.controller);
|
|
150
|
+
const [generation, setGeneration] = useState2(0);
|
|
40
151
|
if (scope !== props.controller) {
|
|
41
152
|
setScope(props.controller);
|
|
42
153
|
setGeneration(generation + 1);
|
|
43
154
|
}
|
|
44
|
-
return /* @__PURE__ */
|
|
155
|
+
return /* @__PURE__ */ jsx2(ScopedSetup, { ...props }, generation);
|
|
45
156
|
}
|
|
46
157
|
function ScopedSetup({ controller, onAuthorize, onBrowseResources, className }) {
|
|
47
158
|
const view = useConnect(controller);
|
|
48
|
-
const [localError, setLocalError] =
|
|
159
|
+
const [localError, setLocalError] = useState2(false);
|
|
49
160
|
const invoke = (operation) => {
|
|
50
161
|
setLocalError(false);
|
|
51
162
|
try {
|
|
@@ -56,7 +167,7 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
56
167
|
};
|
|
57
168
|
const attempt = view.attempt;
|
|
58
169
|
if (!attempt)
|
|
59
|
-
return /* @__PURE__ */
|
|
170
|
+
return /* @__PURE__ */ jsx2("section", { className, "aria-label": "Connection setup", children: /* @__PURE__ */ jsx2("p", { role: "status", children: "Choose a connection to begin." }) });
|
|
60
171
|
const action = attempt.nextAction;
|
|
61
172
|
const verificationUrl = deviceVerificationUrl(action);
|
|
62
173
|
const terminal = ["complete", "cancelled", "expired"].includes(attempt.state);
|
|
@@ -95,20 +206,20 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
95
206
|
);
|
|
96
207
|
}
|
|
97
208
|
};
|
|
98
|
-
return /* @__PURE__ */
|
|
99
|
-
/* @__PURE__ */
|
|
209
|
+
return /* @__PURE__ */ jsxs2("section", { className, "aria-label": "Connection setup", "aria-busy": view.busy, children: [
|
|
210
|
+
/* @__PURE__ */ jsxs2("p", { children: [
|
|
100
211
|
"Ownership: ",
|
|
101
212
|
attempt.ownership === "personal" ? "Personal" : "Workspace"
|
|
102
213
|
] }),
|
|
103
|
-
/* @__PURE__ */
|
|
104
|
-
attempt.account && /* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ jsx2("p", { role: "status", children: setupStatus[attempt.state] }),
|
|
215
|
+
attempt.account && /* @__PURE__ */ jsxs2("p", { children: [
|
|
105
216
|
"Account: ",
|
|
106
217
|
attempt.account.label
|
|
107
218
|
] }),
|
|
108
|
-
(localError || view.error || attempt.error) && /* @__PURE__ */
|
|
109
|
-
!terminal && /* @__PURE__ */
|
|
110
|
-
/* @__PURE__ */
|
|
111
|
-
attempt.state === "connected_but_incomplete" && action.type === "none" && /* @__PURE__ */
|
|
219
|
+
(localError || view.error || attempt.error) && /* @__PURE__ */ jsx2("p", { role: "alert", children: attempt.error?.code === "source_changed" ? "The integration source changed. Review the new operations before installing." : "Connection setup could not continue. Refresh its status before trying again." }),
|
|
220
|
+
!terminal && /* @__PURE__ */ jsx2("form", { onSubmit: submit, autoComplete: "off", children: /* @__PURE__ */ jsxs2("fieldset", { disabled: view.busy, children: [
|
|
221
|
+
/* @__PURE__ */ jsx2("legend", { children: "Connection details" }),
|
|
222
|
+
attempt.state === "connected_but_incomplete" && action.type === "none" && /* @__PURE__ */ jsx2(
|
|
112
223
|
"button",
|
|
113
224
|
{
|
|
114
225
|
type: "button",
|
|
@@ -116,12 +227,12 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
116
227
|
children: "Review integration operations"
|
|
117
228
|
}
|
|
118
229
|
),
|
|
119
|
-
action.type === "credentials" && action.fields.map((field, i) => /* @__PURE__ */
|
|
230
|
+
action.type === "credentials" && action.fields.map((field, i) => /* @__PURE__ */ jsxs2("label", { children: [
|
|
120
231
|
field.label,
|
|
121
|
-
field.options ? /* @__PURE__ */
|
|
122
|
-
/* @__PURE__ */
|
|
123
|
-
field.options.map((option) => /* @__PURE__ */
|
|
124
|
-
] }) : /* @__PURE__ */
|
|
232
|
+
field.options ? /* @__PURE__ */ jsxs2("select", { name: `field-${i}`, required: field.required, defaultValue: "", children: [
|
|
233
|
+
/* @__PURE__ */ jsx2("option", { value: "", children: field.required ? "Choose an option" : "No account (public service)" }),
|
|
234
|
+
field.options.map((option) => /* @__PURE__ */ jsx2("option", { value: option.value, children: option.label }, option.value))
|
|
235
|
+
] }) : /* @__PURE__ */ jsx2(
|
|
125
236
|
"input",
|
|
126
237
|
{
|
|
127
238
|
name: `field-${i}`,
|
|
@@ -131,11 +242,11 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
131
242
|
}
|
|
132
243
|
)
|
|
133
244
|
] }, field.name)),
|
|
134
|
-
action.type === "select_account" && /* @__PURE__ */
|
|
245
|
+
action.type === "select_account" && /* @__PURE__ */ jsxs2("label", { children: [
|
|
135
246
|
"Account",
|
|
136
|
-
/* @__PURE__ */
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
action.accounts.map((account) => /* @__PURE__ */
|
|
247
|
+
/* @__PURE__ */ jsxs2("select", { name: "account", required: true, defaultValue: "", children: [
|
|
248
|
+
/* @__PURE__ */ jsx2("option", { value: "", disabled: true, children: "Choose an account" }),
|
|
249
|
+
action.accounts.map((account) => /* @__PURE__ */ jsxs2(
|
|
139
250
|
"option",
|
|
140
251
|
{
|
|
141
252
|
value: account.id,
|
|
@@ -153,16 +264,16 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
153
264
|
))
|
|
154
265
|
] })
|
|
155
266
|
] }),
|
|
156
|
-
action.type === "select_resources" && action.resources.map((resource) => /* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
267
|
+
action.type === "select_resources" && action.resources.map((resource) => /* @__PURE__ */ jsxs2("label", { children: [
|
|
268
|
+
/* @__PURE__ */ jsx2("input", { type: "checkbox", name: "resource", value: resource.id }),
|
|
158
269
|
resource.label,
|
|
159
270
|
" (",
|
|
160
271
|
resource.kind,
|
|
161
272
|
")"
|
|
162
273
|
] }, resource.id)),
|
|
163
|
-
action.type === "select_resources" && action.cursor && /* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
onBrowseResources && /* @__PURE__ */
|
|
274
|
+
action.type === "select_resources" && action.cursor && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
275
|
+
/* @__PURE__ */ jsx2("p", { children: "More resources are available. Review all pages before submitting a selection." }),
|
|
276
|
+
onBrowseResources && /* @__PURE__ */ jsx2(
|
|
166
277
|
"button",
|
|
167
278
|
{
|
|
168
279
|
type: "button",
|
|
@@ -171,10 +282,10 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
171
282
|
}
|
|
172
283
|
)
|
|
173
284
|
] }),
|
|
174
|
-
action.type === "preview" && /* @__PURE__ */
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
-
action.operations.map((operation) => /* @__PURE__ */
|
|
177
|
-
/* @__PURE__ */
|
|
285
|
+
action.type === "preview" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
286
|
+
/* @__PURE__ */ jsx2("p", { children: "Select the operations to install." }),
|
|
287
|
+
action.operations.map((operation) => /* @__PURE__ */ jsxs2("label", { children: [
|
|
288
|
+
/* @__PURE__ */ jsx2("input", { type: "checkbox", name: "operation", value: operation.id }),
|
|
178
289
|
operation.label,
|
|
179
290
|
" (",
|
|
180
291
|
operation.kind,
|
|
@@ -183,7 +294,7 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
183
294
|
] }),
|
|
184
295
|
["credentials", "select_account", "select_resources", "preview"].includes(
|
|
185
296
|
action.type
|
|
186
|
-
) && /* @__PURE__ */
|
|
297
|
+
) && /* @__PURE__ */ jsx2(
|
|
187
298
|
"button",
|
|
188
299
|
{
|
|
189
300
|
type: "submit",
|
|
@@ -191,7 +302,7 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
191
302
|
children: action.type === "preview" ? "Install selected operations" : "Continue"
|
|
192
303
|
}
|
|
193
304
|
),
|
|
194
|
-
action.type === "authorize" && /* @__PURE__ */
|
|
305
|
+
action.type === "authorize" && /* @__PURE__ */ jsx2(
|
|
195
306
|
"button",
|
|
196
307
|
{
|
|
197
308
|
type: "button",
|
|
@@ -199,40 +310,128 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
|
|
|
199
310
|
children: "Authorize connection"
|
|
200
311
|
}
|
|
201
312
|
),
|
|
202
|
-
action.type === "wait" && /* @__PURE__ */
|
|
203
|
-
action.userCode && /* @__PURE__ */
|
|
313
|
+
action.type === "wait" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
314
|
+
action.userCode && /* @__PURE__ */ jsxs2("p", { children: [
|
|
204
315
|
"Verification code: ",
|
|
205
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ jsx2("code", { children: action.userCode })
|
|
206
317
|
] }),
|
|
207
|
-
/* @__PURE__ */
|
|
208
|
-
verificationUrl && /* @__PURE__ */
|
|
318
|
+
/* @__PURE__ */ jsx2("p", { children: "Complete provider authorization, then check the connection status." }),
|
|
319
|
+
verificationUrl && /* @__PURE__ */ jsx2("a", { href: verificationUrl, target: "_blank", rel: "noopener noreferrer", children: "Open provider verification page (new tab)" })
|
|
209
320
|
] }),
|
|
210
|
-
/* @__PURE__ */
|
|
211
|
-
/* @__PURE__ */
|
|
321
|
+
/* @__PURE__ */ jsx2("button", { type: "button", onClick: () => invoke(() => view.refresh()), children: "Check status" }),
|
|
322
|
+
/* @__PURE__ */ jsx2("button", { type: "button", onClick: () => invoke(() => view.cancel(crypto.randomUUID())), children: "Cancel setup" })
|
|
212
323
|
] }) }, `${attempt.id}:${attempt.revision}`)
|
|
213
324
|
] });
|
|
214
325
|
}
|
|
215
326
|
|
|
327
|
+
// src/connection-catalog.tsx
|
|
328
|
+
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
329
|
+
function ConnectionDetailsAction({
|
|
330
|
+
option,
|
|
331
|
+
name = option.name
|
|
332
|
+
}) {
|
|
333
|
+
return /* @__PURE__ */ jsx3(
|
|
334
|
+
"button",
|
|
335
|
+
{
|
|
336
|
+
type: "button",
|
|
337
|
+
className: "og-connection-details-action",
|
|
338
|
+
"aria-label": `View ${name} details`,
|
|
339
|
+
onClick: option.onOpen,
|
|
340
|
+
children: /* @__PURE__ */ jsx3("span", { "aria-hidden": true, children: option.connected ? "\u203A" : "+" })
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
function ConnectionOptionRow({ option }) {
|
|
345
|
+
return /* @__PURE__ */ jsxs3("div", { className: "og-connection-catalog-action-row og-connection-option", children: [
|
|
346
|
+
/* @__PURE__ */ jsxs3("button", { type: "button", className: "og-connection-catalog-row", onClick: option.onOpen, children: [
|
|
347
|
+
/* @__PURE__ */ jsxs3("span", { className: "og-connection-catalog-copy", children: [
|
|
348
|
+
/* @__PURE__ */ jsx3("strong", { children: option.name }),
|
|
349
|
+
/* @__PURE__ */ jsx3("span", { children: option.description })
|
|
350
|
+
] }),
|
|
351
|
+
/* @__PURE__ */ jsx3("span", { className: "og-connection-catalog-status", children: option.status })
|
|
352
|
+
] }),
|
|
353
|
+
/* @__PURE__ */ jsx3("span", { className: "og-connection-option-action", children: option.action ?? /* @__PURE__ */ jsx3(ConnectionDetailsAction, { option }) })
|
|
354
|
+
] });
|
|
355
|
+
}
|
|
356
|
+
function ConnectionServiceRow({ service }) {
|
|
357
|
+
if (!service.options.length) return null;
|
|
358
|
+
const connected = service.options.filter((option) => option.connected).length;
|
|
359
|
+
const identity = /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
360
|
+
/* @__PURE__ */ jsx3("span", { className: "og-connection-catalog-logo", children: service.logo }),
|
|
361
|
+
/* @__PURE__ */ jsxs3("span", { className: "og-connection-catalog-copy", children: [
|
|
362
|
+
/* @__PURE__ */ jsx3("strong", { children: service.name }),
|
|
363
|
+
/* @__PURE__ */ jsx3("span", { children: service.options.length === 1 ? service.options[0]?.description : service.options.map((option) => option.name).join(" \xB7 ") })
|
|
364
|
+
] }),
|
|
365
|
+
/* @__PURE__ */ jsx3("span", { className: "og-connection-catalog-status", children: service.options.length === 1 ? service.options[0]?.status : `${connected} of ${service.options.length} connected` })
|
|
366
|
+
] });
|
|
367
|
+
return service.options.length === 1 ? /* @__PURE__ */ jsxs3("div", { className: "og-connection-catalog-action-row", children: [
|
|
368
|
+
/* @__PURE__ */ jsx3(
|
|
369
|
+
"button",
|
|
370
|
+
{
|
|
371
|
+
type: "button",
|
|
372
|
+
className: "og-connection-catalog-row",
|
|
373
|
+
onClick: service.options[0].onOpen,
|
|
374
|
+
children: identity
|
|
375
|
+
}
|
|
376
|
+
),
|
|
377
|
+
service.options[0]?.action ?? /* @__PURE__ */ jsx3(ConnectionDetailsAction, { option: service.options[0], name: service.name })
|
|
378
|
+
] }) : /* @__PURE__ */ jsxs3("details", { className: "og-connection-catalog-service", children: [
|
|
379
|
+
/* @__PURE__ */ jsxs3("summary", { className: "og-connection-catalog-row", children: [
|
|
380
|
+
identity,
|
|
381
|
+
/* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: "og-connection-group-chevron", children: "\u2304" })
|
|
382
|
+
] }),
|
|
383
|
+
/* @__PURE__ */ jsx3("div", { className: "og-connection-catalog-options", children: service.options.map((option) => /* @__PURE__ */ jsx3(ConnectionOptionRow, { option }, option.id)) })
|
|
384
|
+
] });
|
|
385
|
+
}
|
|
386
|
+
function ConnectionCatalog({
|
|
387
|
+
services,
|
|
388
|
+
query = "",
|
|
389
|
+
columns = 1,
|
|
390
|
+
grouped = true,
|
|
391
|
+
className = "",
|
|
392
|
+
emptyMessage = "No connections match your search."
|
|
393
|
+
}) {
|
|
394
|
+
const search = query.trim().toLowerCase();
|
|
395
|
+
const entries = grouped ? services : services.flatMap(
|
|
396
|
+
(service) => service.options.map((option) => ({
|
|
397
|
+
...service,
|
|
398
|
+
id: `${service.id}/${option.id}`,
|
|
399
|
+
name: service.options.length > 1 && option.name !== service.name ? `${service.name} \xB7 ${option.name}` : service.name,
|
|
400
|
+
options: [option]
|
|
401
|
+
}))
|
|
402
|
+
);
|
|
403
|
+
const visible = entries.filter(
|
|
404
|
+
(service) => [service.name, ...service.options.flatMap((option) => [option.name, option.description ?? ""])].join(" ").toLowerCase().includes(search)
|
|
405
|
+
);
|
|
406
|
+
return /* @__PURE__ */ jsx3("div", { className: `og-connection-catalog ${className}`, "data-columns": columns, children: visible.length ? visible.map((service) => /* @__PURE__ */ jsx3(ConnectionServiceRow, { service }, service.id)) : /* @__PURE__ */ jsx3("p", { role: "status", children: emptyMessage }) });
|
|
407
|
+
}
|
|
408
|
+
|
|
216
409
|
// src/connect-chooser.tsx
|
|
217
|
-
import { useEffect, useState as
|
|
218
|
-
import { jsx as
|
|
410
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
411
|
+
import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
219
412
|
function ConnectChooser(props) {
|
|
220
|
-
const [scope, setScope] =
|
|
221
|
-
const [generation, setGeneration] =
|
|
413
|
+
const [scope, setScope] = useState3(props.controller);
|
|
414
|
+
const [generation, setGeneration] = useState3(0);
|
|
222
415
|
if (scope !== props.controller) {
|
|
223
416
|
setScope(props.controller);
|
|
224
417
|
setGeneration(generation + 1);
|
|
225
418
|
}
|
|
226
|
-
return /* @__PURE__ */
|
|
419
|
+
return /* @__PURE__ */ jsx4(ScopedChooser, { ...props }, generation);
|
|
227
420
|
}
|
|
228
|
-
function ScopedChooser({
|
|
421
|
+
function ScopedChooser({
|
|
422
|
+
controller,
|
|
423
|
+
returnUrl,
|
|
424
|
+
className,
|
|
425
|
+
presentation = "select"
|
|
426
|
+
}) {
|
|
229
427
|
const view = useConnect(controller);
|
|
230
|
-
const [catalog, setCatalog] =
|
|
231
|
-
const [failed, setFailed] =
|
|
232
|
-
const [load, setLoad] =
|
|
233
|
-
const [
|
|
234
|
-
const [
|
|
235
|
-
|
|
428
|
+
const [catalog, setCatalog] = useState3(null);
|
|
429
|
+
const [failed, setFailed] = useState3(false);
|
|
430
|
+
const [load, setLoad] = useState3(0);
|
|
431
|
+
const [query, setQuery] = useState3("");
|
|
432
|
+
const [providerId, setProviderId] = useState3("");
|
|
433
|
+
const [ownership, setOwnership] = useState3("");
|
|
434
|
+
useEffect2(() => {
|
|
236
435
|
const abort = new AbortController();
|
|
237
436
|
setCatalog(null);
|
|
238
437
|
setFailed(false);
|
|
@@ -260,21 +459,70 @@ function ScopedChooser({ controller, returnUrl, className }) {
|
|
|
260
459
|
setFailed(true);
|
|
261
460
|
}
|
|
262
461
|
};
|
|
263
|
-
return /* @__PURE__ */
|
|
462
|
+
return /* @__PURE__ */ jsxs4(
|
|
264
463
|
"section",
|
|
265
464
|
{
|
|
266
465
|
className,
|
|
267
466
|
"aria-label": "Choose a connection",
|
|
268
467
|
"aria-busy": view.busy || !catalog && !failed,
|
|
269
468
|
children: [
|
|
270
|
-
failed && /* @__PURE__ */
|
|
271
|
-
!catalog && !failed && /* @__PURE__ */
|
|
272
|
-
catalog?.length === 0 && /* @__PURE__ */
|
|
273
|
-
Boolean(catalog?.length) && /* @__PURE__ */
|
|
274
|
-
/* @__PURE__ */
|
|
275
|
-
/* @__PURE__ */
|
|
469
|
+
failed && /* @__PURE__ */ jsx4("p", { role: "alert", children: "Connections could not be loaded or started. Check setup status before retrying." }),
|
|
470
|
+
!catalog && !failed && /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading connections\u2026" }),
|
|
471
|
+
catalog?.length === 0 && /* @__PURE__ */ jsx4("p", { role: "status", children: "No connections are available." }),
|
|
472
|
+
Boolean(catalog?.length) && /* @__PURE__ */ jsx4("form", { onSubmit: submit, children: /* @__PURE__ */ jsxs4("fieldset", { disabled: view.busy, children: [
|
|
473
|
+
/* @__PURE__ */ jsx4("legend", { children: "Provider and ownership" }),
|
|
474
|
+
presentation === "catalog" && !provider ? /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
475
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
476
|
+
"Search connections",
|
|
477
|
+
/* @__PURE__ */ jsx4(
|
|
478
|
+
"input",
|
|
479
|
+
{
|
|
480
|
+
type: "search",
|
|
481
|
+
value: query,
|
|
482
|
+
onChange: (event) => setQuery(event.target.value)
|
|
483
|
+
}
|
|
484
|
+
)
|
|
485
|
+
] }),
|
|
486
|
+
/* @__PURE__ */ jsx4(
|
|
487
|
+
ConnectionCatalog,
|
|
488
|
+
{
|
|
489
|
+
query,
|
|
490
|
+
services: catalog.map((entry) => ({
|
|
491
|
+
id: entry.id,
|
|
492
|
+
name: entry.label,
|
|
493
|
+
options: [
|
|
494
|
+
{
|
|
495
|
+
id: entry.id,
|
|
496
|
+
name: entry.label,
|
|
497
|
+
description: entry.reason,
|
|
498
|
+
status: entry.readiness.replaceAll("_", " "),
|
|
499
|
+
connected: false,
|
|
500
|
+
onOpen: () => {
|
|
501
|
+
if (!view.busy) {
|
|
502
|
+
setProviderId(entry.id);
|
|
503
|
+
setOwnership(entry.ownership.length === 1 ? entry.ownership[0] : "");
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
]
|
|
508
|
+
}))
|
|
509
|
+
}
|
|
510
|
+
)
|
|
511
|
+
] }) : null,
|
|
512
|
+
presentation === "catalog" && provider ? /* @__PURE__ */ jsx4(
|
|
513
|
+
"button",
|
|
514
|
+
{
|
|
515
|
+
type: "button",
|
|
516
|
+
onClick: () => {
|
|
517
|
+
setProviderId("");
|
|
518
|
+
setOwnership("");
|
|
519
|
+
},
|
|
520
|
+
children: "Back to connections"
|
|
521
|
+
}
|
|
522
|
+
) : null,
|
|
523
|
+
/* @__PURE__ */ jsxs4("label", { hidden: presentation === "catalog", children: [
|
|
276
524
|
"Provider",
|
|
277
|
-
/* @__PURE__ */
|
|
525
|
+
/* @__PURE__ */ jsxs4(
|
|
278
526
|
"select",
|
|
279
527
|
{
|
|
280
528
|
required: true,
|
|
@@ -284,8 +532,8 @@ function ScopedChooser({ controller, returnUrl, className }) {
|
|
|
284
532
|
setOwnership("");
|
|
285
533
|
},
|
|
286
534
|
children: [
|
|
287
|
-
/* @__PURE__ */
|
|
288
|
-
catalog.map((entry) => /* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ jsx4("option", { value: "", disabled: true, children: "Choose a provider" }),
|
|
536
|
+
catalog.map((entry) => /* @__PURE__ */ jsxs4(
|
|
289
537
|
"option",
|
|
290
538
|
{
|
|
291
539
|
value: entry.id,
|
|
@@ -305,51 +553,62 @@ function ScopedChooser({ controller, returnUrl, className }) {
|
|
|
305
553
|
}
|
|
306
554
|
)
|
|
307
555
|
] }),
|
|
308
|
-
provider && /* @__PURE__ */
|
|
309
|
-
"
|
|
310
|
-
/* @__PURE__ */
|
|
311
|
-
"
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
556
|
+
provider && /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
557
|
+
/* @__PURE__ */ jsx4("strong", { children: presentation === "catalog" ? provider.label : null }),
|
|
558
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
559
|
+
"Ownership",
|
|
560
|
+
/* @__PURE__ */ jsxs4(
|
|
561
|
+
"select",
|
|
562
|
+
{
|
|
563
|
+
required: true,
|
|
564
|
+
value: ownership,
|
|
565
|
+
onChange: (event) => setOwnership(event.target.value),
|
|
566
|
+
children: [
|
|
567
|
+
/* @__PURE__ */ jsx4("option", { value: "", disabled: true, children: "Choose ownership" }),
|
|
568
|
+
provider.ownership.map((choice) => /* @__PURE__ */ jsx4("option", { value: choice, children: choice === "personal" ? "Personal \u2014 owned by you" : "Workspace \u2014 shared connection" }, choice))
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
)
|
|
572
|
+
] })
|
|
322
573
|
] }),
|
|
323
|
-
/* @__PURE__ */
|
|
574
|
+
/* @__PURE__ */ jsx4(
|
|
575
|
+
"button",
|
|
576
|
+
{
|
|
577
|
+
hidden: presentation === "catalog" && !provider,
|
|
578
|
+
type: "submit",
|
|
579
|
+
disabled: !canBegin,
|
|
580
|
+
children: "Start setup"
|
|
581
|
+
}
|
|
582
|
+
)
|
|
324
583
|
] }) }),
|
|
325
|
-
/* @__PURE__ */
|
|
584
|
+
/* @__PURE__ */ jsx4("button", { type: "button", disabled: view.busy, onClick: () => setLoad(load + 1), children: "Reload providers" })
|
|
326
585
|
]
|
|
327
586
|
}
|
|
328
587
|
);
|
|
329
588
|
}
|
|
330
589
|
|
|
331
590
|
// src/connect-accounts.tsx
|
|
332
|
-
import { useEffect as
|
|
333
|
-
import { jsx as
|
|
591
|
+
import { useEffect as useEffect3, useRef, useState as useState4 } from "react";
|
|
592
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
334
593
|
function ConnectAccounts(props) {
|
|
335
|
-
const [scope, setScope] =
|
|
336
|
-
const [generation, setGeneration] =
|
|
594
|
+
const [scope, setScope] = useState4(props.controller);
|
|
595
|
+
const [generation, setGeneration] = useState4(0);
|
|
337
596
|
if (scope !== props.controller) {
|
|
338
597
|
setScope(props.controller);
|
|
339
598
|
setGeneration(generation + 1);
|
|
340
599
|
}
|
|
341
|
-
return /* @__PURE__ */
|
|
600
|
+
return /* @__PURE__ */ jsx5(ScopedAccounts, { ...props }, generation);
|
|
342
601
|
}
|
|
343
602
|
function ScopedAccounts({ controller, className, returnUrl }) {
|
|
344
603
|
const view = useConnect(controller);
|
|
345
|
-
const [accounts, setAccounts] =
|
|
346
|
-
const [selected, setSelected] =
|
|
347
|
-
const [busy, setBusy] =
|
|
348
|
-
const [error, setError] =
|
|
349
|
-
const [reload, setReload] =
|
|
604
|
+
const [accounts, setAccounts] = useState4(null);
|
|
605
|
+
const [selected, setSelected] = useState4(null);
|
|
606
|
+
const [busy, setBusy] = useState4(false);
|
|
607
|
+
const [error, setError] = useState4(false);
|
|
608
|
+
const [reload, setReload] = useState4(0);
|
|
350
609
|
const mutation = useRef(null);
|
|
351
|
-
|
|
352
|
-
|
|
610
|
+
useEffect3(() => () => mutation.current?.abort(), []);
|
|
611
|
+
useEffect3(() => {
|
|
353
612
|
const abort = new AbortController();
|
|
354
613
|
setAccounts(null);
|
|
355
614
|
setSelected(null);
|
|
@@ -406,18 +665,18 @@ function ScopedAccounts({ controller, className, returnUrl }) {
|
|
|
406
665
|
setError(true);
|
|
407
666
|
}
|
|
408
667
|
};
|
|
409
|
-
return /* @__PURE__ */
|
|
668
|
+
return /* @__PURE__ */ jsxs5(
|
|
410
669
|
"section",
|
|
411
670
|
{
|
|
412
671
|
className,
|
|
413
672
|
"aria-label": "Connected accounts",
|
|
414
673
|
"aria-busy": busy || view.busy || !accounts && !error,
|
|
415
674
|
children: [
|
|
416
|
-
error && /* @__PURE__ */
|
|
417
|
-
!accounts && !error && /* @__PURE__ */
|
|
418
|
-
accounts?.length === 0 && /* @__PURE__ */
|
|
419
|
-
accounts && accounts.length > 0 && /* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
675
|
+
error && /* @__PURE__ */ jsx5("p", { role: "alert", children: "Account state could not be confirmed. Reload before trying again." }),
|
|
676
|
+
!accounts && !error && /* @__PURE__ */ jsx5("p", { role: "status", children: "Loading accounts\u2026" }),
|
|
677
|
+
accounts?.length === 0 && /* @__PURE__ */ jsx5("p", { role: "status", children: "No connected accounts." }),
|
|
678
|
+
accounts && accounts.length > 0 && /* @__PURE__ */ jsx5("ul", { children: accounts.map((account) => /* @__PURE__ */ jsxs5("li", { children: [
|
|
679
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
421
680
|
account.label,
|
|
422
681
|
" \u2014 ",
|
|
423
682
|
account.providerId,
|
|
@@ -427,7 +686,7 @@ function ScopedAccounts({ controller, className, returnUrl }) {
|
|
|
427
686
|
" ",
|
|
428
687
|
account.status.replaceAll("_", " ")
|
|
429
688
|
] }),
|
|
430
|
-
returnUrl && /* @__PURE__ */
|
|
689
|
+
returnUrl && /* @__PURE__ */ jsxs5(
|
|
431
690
|
"button",
|
|
432
691
|
{
|
|
433
692
|
type: "button",
|
|
@@ -439,9 +698,9 @@ function ScopedAccounts({ controller, className, returnUrl }) {
|
|
|
439
698
|
]
|
|
440
699
|
}
|
|
441
700
|
),
|
|
442
|
-
selected === `${account.providerId}:${account.id}` ? /* @__PURE__ */
|
|
443
|
-
/* @__PURE__ */
|
|
444
|
-
/* @__PURE__ */
|
|
701
|
+
selected === `${account.providerId}:${account.id}` ? /* @__PURE__ */ jsxs5("div", { role: "group", "aria-label": `Disconnect ${account.label}`, children: [
|
|
702
|
+
/* @__PURE__ */ jsx5("p", { children: "This removes local OpenGeni access. It does not revoke consent at the provider." }),
|
|
703
|
+
/* @__PURE__ */ jsx5(
|
|
445
704
|
"button",
|
|
446
705
|
{
|
|
447
706
|
type: "button",
|
|
@@ -450,8 +709,8 @@ function ScopedAccounts({ controller, className, returnUrl }) {
|
|
|
450
709
|
children: "Confirm disconnect"
|
|
451
710
|
}
|
|
452
711
|
),
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
] }) : /* @__PURE__ */
|
|
712
|
+
/* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => setSelected(null), children: "Keep account" })
|
|
713
|
+
] }) : /* @__PURE__ */ jsxs5(
|
|
455
714
|
"button",
|
|
456
715
|
{
|
|
457
716
|
type: "button",
|
|
@@ -464,38 +723,46 @@ function ScopedAccounts({ controller, className, returnUrl }) {
|
|
|
464
723
|
}
|
|
465
724
|
)
|
|
466
725
|
] }, `${account.providerId}:${account.id}`)) }),
|
|
467
|
-
/* @__PURE__ */
|
|
726
|
+
/* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => setReload((value) => value + 1), children: "Reload accounts" })
|
|
468
727
|
]
|
|
469
728
|
}
|
|
470
729
|
);
|
|
471
730
|
}
|
|
472
731
|
|
|
473
732
|
// src/connect-panel.tsx
|
|
474
|
-
import { jsx as
|
|
733
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
475
734
|
function ConnectPanel({
|
|
476
735
|
returnUrl,
|
|
477
736
|
title = "Connections",
|
|
478
737
|
showAccounts = true,
|
|
738
|
+
presentation = "select",
|
|
479
739
|
className,
|
|
480
740
|
...setup
|
|
481
741
|
}) {
|
|
482
|
-
return /* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
484
|
-
/* @__PURE__ */
|
|
485
|
-
|
|
486
|
-
|
|
742
|
+
return /* @__PURE__ */ jsxs6("div", { className: ["og-connect", className].filter(Boolean).join(" "), children: [
|
|
743
|
+
/* @__PURE__ */ jsx6("h2", { children: title }),
|
|
744
|
+
/* @__PURE__ */ jsx6(
|
|
745
|
+
ConnectChooser,
|
|
746
|
+
{
|
|
747
|
+
presentation,
|
|
748
|
+
controller: setup.controller,
|
|
749
|
+
returnUrl
|
|
750
|
+
}
|
|
751
|
+
),
|
|
752
|
+
/* @__PURE__ */ jsx6(ConnectSetup, { ...setup }),
|
|
753
|
+
showAccounts && /* @__PURE__ */ jsx6(ConnectAccounts, { controller: setup.controller, returnUrl })
|
|
487
754
|
] });
|
|
488
755
|
}
|
|
489
756
|
|
|
490
757
|
// src/device-authorization.tsx
|
|
491
|
-
import { useEffect as
|
|
492
|
-
import { jsx as
|
|
758
|
+
import { useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
759
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
493
760
|
function DeviceAuthorization(props) {
|
|
494
|
-
const [copied, setCopied] =
|
|
495
|
-
const [copyError, setCopyError] =
|
|
761
|
+
const [copied, setCopied] = useState5(false);
|
|
762
|
+
const [copyError, setCopyError] = useState5(false);
|
|
496
763
|
const generation = useRef2(0);
|
|
497
764
|
const timer = useRef2(null);
|
|
498
|
-
|
|
765
|
+
useEffect4(() => {
|
|
499
766
|
generation.current++;
|
|
500
767
|
setCopied(false);
|
|
501
768
|
setCopyError(false);
|
|
@@ -534,11 +801,12 @@ function DeviceAuthorization(props) {
|
|
|
534
801
|
href = props.verificationUri;
|
|
535
802
|
} catch {
|
|
536
803
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
/* @__PURE__ */
|
|
540
|
-
|
|
541
|
-
/* @__PURE__ */
|
|
804
|
+
if (props.render) return props.render({ copied, copyError, copy, verificationHref: href });
|
|
805
|
+
return /* @__PURE__ */ jsxs7("section", { className: `og-connect ${props.className ?? ""}`, "aria-label": "Device authorization", children: [
|
|
806
|
+
/* @__PURE__ */ jsx7("p", { children: props.description ?? `Enter this code at ${props.providerLabel ?? "the provider"}.` }),
|
|
807
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem", alignItems: "center" }, children: [
|
|
808
|
+
/* @__PURE__ */ jsx7("code", { ...props.codeAttributes, style: { overflowWrap: "anywhere" }, children: props.userCode }),
|
|
809
|
+
/* @__PURE__ */ jsx7(
|
|
542
810
|
"button",
|
|
543
811
|
{
|
|
544
812
|
type: "button",
|
|
@@ -547,19 +815,19 @@ function DeviceAuthorization(props) {
|
|
|
547
815
|
children: copied ? "Copied" : "Copy code"
|
|
548
816
|
}
|
|
549
817
|
),
|
|
550
|
-
href ? /* @__PURE__ */
|
|
818
|
+
href ? /* @__PURE__ */ jsxs7("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
|
|
551
819
|
"Open ",
|
|
552
820
|
props.providerLabel ?? "auth page"
|
|
553
|
-
] }) : /* @__PURE__ */
|
|
821
|
+
] }) : /* @__PURE__ */ jsx7("span", { role: "alert", children: "Authorization address unavailable." })
|
|
554
822
|
] }),
|
|
555
|
-
copyError ? /* @__PURE__ */
|
|
556
|
-
/* @__PURE__ */
|
|
823
|
+
copyError ? /* @__PURE__ */ jsx7("p", { role: "alert", children: "Couldn't copy the code. Copy it manually instead." }) : null,
|
|
824
|
+
/* @__PURE__ */ jsx7("p", { role: "status", children: "Waiting for authorization\u2026" })
|
|
557
825
|
] });
|
|
558
826
|
}
|
|
559
827
|
|
|
560
828
|
// src/identity-link-consent.tsx
|
|
561
|
-
import { useEffect as
|
|
562
|
-
import { Fragment as
|
|
829
|
+
import { useEffect as useEffect5, useRef as useRef3, useState as useState6 } from "react";
|
|
830
|
+
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
563
831
|
function IdentityLinkConsent({
|
|
564
832
|
client,
|
|
565
833
|
workspaceId,
|
|
@@ -568,14 +836,14 @@ function IdentityLinkConsent({
|
|
|
568
836
|
className,
|
|
569
837
|
onComplete
|
|
570
838
|
}) {
|
|
571
|
-
const [link, setLink] =
|
|
572
|
-
const [preview, setPreview] =
|
|
573
|
-
const [selected, setSelected] =
|
|
574
|
-
const [busy, setBusy] =
|
|
575
|
-
const [error, setError] =
|
|
576
|
-
const [retry, setRetry] =
|
|
839
|
+
const [link, setLink] = useState6(null);
|
|
840
|
+
const [preview, setPreview] = useState6(null);
|
|
841
|
+
const [selected, setSelected] = useState6([]);
|
|
842
|
+
const [busy, setBusy] = useState6(false);
|
|
843
|
+
const [error, setError] = useState6(false);
|
|
844
|
+
const [retry, setRetry] = useState6(0);
|
|
577
845
|
const generation = useRef3(0);
|
|
578
|
-
|
|
846
|
+
useEffect5(() => {
|
|
579
847
|
const current = ++generation.current;
|
|
580
848
|
setLink(null);
|
|
581
849
|
setPreview(null);
|
|
@@ -619,43 +887,43 @@ function IdentityLinkConsent({
|
|
|
619
887
|
if (generation.current === current) setBusy(false);
|
|
620
888
|
}
|
|
621
889
|
}
|
|
622
|
-
return /* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsxs8(
|
|
623
891
|
"section",
|
|
624
892
|
{
|
|
625
893
|
className: ["og-connect og-identity-link", className].filter(Boolean).join(" "),
|
|
626
894
|
"aria-label": "Link your account",
|
|
627
895
|
"aria-busy": busy,
|
|
628
896
|
children: [
|
|
629
|
-
/* @__PURE__ */
|
|
630
|
-
/* @__PURE__ */
|
|
631
|
-
preview && /* @__PURE__ */
|
|
632
|
-
/* @__PURE__ */
|
|
633
|
-
/* @__PURE__ */
|
|
634
|
-
/* @__PURE__ */
|
|
635
|
-
/* @__PURE__ */
|
|
897
|
+
/* @__PURE__ */ jsx8("h2", { children: "Link your OpenGeni account" }),
|
|
898
|
+
/* @__PURE__ */ jsx8("p", { children: "Only continue if you started this request in a product you trust. Linking lets that product act as your account with the permissions you select. It does not merge accounts or move existing work." }),
|
|
899
|
+
preview && /* @__PURE__ */ jsxs8("dl", { children: [
|
|
900
|
+
/* @__PURE__ */ jsx8("dt", { children: "Organization" }),
|
|
901
|
+
/* @__PURE__ */ jsx8("dd", { children: preview.organizationId }),
|
|
902
|
+
/* @__PURE__ */ jsx8("dt", { children: "Product user" }),
|
|
903
|
+
/* @__PURE__ */ jsxs8("dd", { children: [
|
|
636
904
|
preview.externalIdentity.externalId,
|
|
637
905
|
" (",
|
|
638
906
|
preview.externalIdentity.source,
|
|
639
907
|
")"
|
|
640
908
|
] }),
|
|
641
|
-
/* @__PURE__ */
|
|
642
|
-
/* @__PURE__ */
|
|
909
|
+
/* @__PURE__ */ jsx8("dt", { children: "Your OpenGeni identity" }),
|
|
910
|
+
/* @__PURE__ */ jsx8("dd", { children: preview.nativeSubjectId })
|
|
643
911
|
] }),
|
|
644
|
-
error && /* @__PURE__ */
|
|
912
|
+
error && /* @__PURE__ */ jsxs8("div", { role: "alert", children: [
|
|
645
913
|
"This request could not be completed. It may have expired, changed, or require you to sign in to the right organization.",
|
|
646
|
-
!link && /* @__PURE__ */
|
|
914
|
+
!link && /* @__PURE__ */ jsx8("button", { type: "button", disabled: busy, onClick: () => setRetry((value) => value + 1), children: "Try again" })
|
|
647
915
|
] }),
|
|
648
|
-
!link && busy && /* @__PURE__ */
|
|
649
|
-
link?.status === "pending" && /* @__PURE__ */
|
|
650
|
-
/* @__PURE__ */
|
|
916
|
+
!link && busy && /* @__PURE__ */ jsx8("p", { role: "status", children: "Loading the account-link request\u2026" }),
|
|
917
|
+
link?.status === "pending" && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
918
|
+
/* @__PURE__ */ jsxs8("p", { children: [
|
|
651
919
|
link.expiresAt ? `Access ends ${new Date(link.expiresAt).toLocaleString()}.` : "Access lasts until you or the product revoke this link.",
|
|
652
920
|
" ",
|
|
653
921
|
"Your current permissions still apply."
|
|
654
922
|
] }),
|
|
655
|
-
/* @__PURE__ */
|
|
656
|
-
/* @__PURE__ */
|
|
657
|
-
link.permissions.map((permission) => /* @__PURE__ */
|
|
658
|
-
/* @__PURE__ */
|
|
923
|
+
/* @__PURE__ */ jsxs8("fieldset", { disabled: busy, children: [
|
|
924
|
+
/* @__PURE__ */ jsx8("legend", { children: "Allow these permissions" }),
|
|
925
|
+
link.permissions.map((permission) => /* @__PURE__ */ jsxs8("label", { children: [
|
|
926
|
+
/* @__PURE__ */ jsx8(
|
|
659
927
|
"input",
|
|
660
928
|
{
|
|
661
929
|
type: "checkbox",
|
|
@@ -665,10 +933,10 @@ function IdentityLinkConsent({
|
|
|
665
933
|
)
|
|
666
934
|
}
|
|
667
935
|
),
|
|
668
|
-
/* @__PURE__ */
|
|
936
|
+
/* @__PURE__ */ jsx8("span", { children: permission.replaceAll(":", " \xB7 ") })
|
|
669
937
|
] }, permission))
|
|
670
938
|
] }),
|
|
671
|
-
/* @__PURE__ */
|
|
939
|
+
/* @__PURE__ */ jsx8(
|
|
672
940
|
"button",
|
|
673
941
|
{
|
|
674
942
|
type: "button",
|
|
@@ -677,34 +945,34 @@ function IdentityLinkConsent({
|
|
|
677
945
|
children: busy ? "Saving\u2026" : "Allow selected access"
|
|
678
946
|
}
|
|
679
947
|
),
|
|
680
|
-
/* @__PURE__ */
|
|
948
|
+
/* @__PURE__ */ jsx8("p", { children: "You can close this page without granting access." })
|
|
681
949
|
] }),
|
|
682
|
-
link?.status === "active" && /* @__PURE__ */
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
/* @__PURE__ */
|
|
950
|
+
link?.status === "active" && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
951
|
+
/* @__PURE__ */ jsx8("p", { role: "status", children: "Account linked. Return to your product to continue." }),
|
|
952
|
+
/* @__PURE__ */ jsx8("button", { type: "button", disabled: busy, onClick: () => void mutate(true), children: "Revoke this link" })
|
|
685
953
|
] }),
|
|
686
|
-
link?.status === "revoked" && /* @__PURE__ */
|
|
687
|
-
link?.status === "expired" && /* @__PURE__ */
|
|
954
|
+
link?.status === "revoked" && /* @__PURE__ */ jsx8("p", { role: "status", children: "Link revoked. Your OpenGeni account and existing work are unchanged." }),
|
|
955
|
+
link?.status === "expired" && /* @__PURE__ */ jsx8("p", { role: "status", children: "This request has expired. Start a new request from your product." })
|
|
688
956
|
]
|
|
689
957
|
}
|
|
690
958
|
);
|
|
691
959
|
}
|
|
692
960
|
|
|
693
961
|
// src/identity-link-accounts.tsx
|
|
694
|
-
import { useEffect as
|
|
695
|
-
import { jsx as
|
|
962
|
+
import { useEffect as useEffect6, useRef as useRef4, useState as useState7 } from "react";
|
|
963
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
696
964
|
function IdentityLinkAccounts({
|
|
697
965
|
client,
|
|
698
966
|
workspaceId
|
|
699
967
|
}) {
|
|
700
|
-
const [links, setLinks] =
|
|
701
|
-
const [cursor, setCursor] =
|
|
702
|
-
const [busy, setBusy] =
|
|
703
|
-
const [error, setError] =
|
|
704
|
-
const [revision, setRevision] =
|
|
968
|
+
const [links, setLinks] = useState7([]);
|
|
969
|
+
const [cursor, setCursor] = useState7(null);
|
|
970
|
+
const [busy, setBusy] = useState7(true);
|
|
971
|
+
const [error, setError] = useState7(false);
|
|
972
|
+
const [revision, setRevision] = useState7(0);
|
|
705
973
|
const generation = useRef4(0);
|
|
706
974
|
const inFlight = useRef4(false);
|
|
707
|
-
|
|
975
|
+
useEffect6(() => {
|
|
708
976
|
const current = ++generation.current;
|
|
709
977
|
inFlight.current = true;
|
|
710
978
|
setLinks([]);
|
|
@@ -761,43 +1029,375 @@ function IdentityLinkAccounts({
|
|
|
761
1029
|
}
|
|
762
1030
|
}
|
|
763
1031
|
}
|
|
764
|
-
return /* @__PURE__ */
|
|
1032
|
+
return /* @__PURE__ */ jsxs9(
|
|
765
1033
|
"section",
|
|
766
1034
|
{
|
|
767
1035
|
className: "og-connect og-identity-link",
|
|
768
1036
|
"aria-label": "Linked product access",
|
|
769
1037
|
"aria-busy": busy,
|
|
770
1038
|
children: [
|
|
771
|
-
/* @__PURE__ */
|
|
772
|
-
/* @__PURE__ */
|
|
773
|
-
error && /* @__PURE__ */
|
|
1039
|
+
/* @__PURE__ */ jsx9("h2", { children: "Linked product access" }),
|
|
1040
|
+
/* @__PURE__ */ jsx9("p", { children: "Manage products allowed to act as your account in this organization. Revoking a link stops future linked access; it does not delete your work or undo an operation already started." }),
|
|
1041
|
+
error && /* @__PURE__ */ jsxs9("div", { role: "alert", children: [
|
|
774
1042
|
"Could not update account links. Reload to see current access.",
|
|
775
|
-
/* @__PURE__ */
|
|
1043
|
+
/* @__PURE__ */ jsx9("button", { type: "button", disabled: busy, onClick: () => setRevision((value) => value + 1), children: "Reload links" })
|
|
776
1044
|
] }),
|
|
777
|
-
busy && /* @__PURE__ */
|
|
778
|
-
!busy && !error && links.length === 0 && /* @__PURE__ */
|
|
779
|
-
/* @__PURE__ */
|
|
780
|
-
/* @__PURE__ */
|
|
1045
|
+
busy && /* @__PURE__ */ jsx9("p", { role: "status", children: "Loading account links\u2026" }),
|
|
1046
|
+
!busy && !error && links.length === 0 && /* @__PURE__ */ jsx9("p", { children: "No products have linked access to this account." }),
|
|
1047
|
+
/* @__PURE__ */ jsx9("ul", { children: links.map((link) => /* @__PURE__ */ jsxs9("li", { children: [
|
|
1048
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
781
1049
|
link.externalIdentity?.source || "Product identity",
|
|
782
1050
|
" ",
|
|
783
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsx9("code", { children: link.externalIdentity?.externalId ?? link.externalIdentityId })
|
|
784
1052
|
] }),
|
|
785
|
-
/* @__PURE__ */
|
|
1053
|
+
/* @__PURE__ */ jsxs9("p", { children: [
|
|
786
1054
|
"Status: ",
|
|
787
1055
|
link.status,
|
|
788
1056
|
".",
|
|
789
1057
|
" ",
|
|
790
1058
|
link.expiresAt ? `Expires ${new Date(link.expiresAt).toLocaleString()}.` : "No automatic expiry."
|
|
791
1059
|
] }),
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
(link.status === "active" || link.status === "pending") && /* @__PURE__ */
|
|
1060
|
+
/* @__PURE__ */ jsx9("p", { children: link.permissions.join(", ") }),
|
|
1061
|
+
(link.status === "active" || link.status === "pending") && /* @__PURE__ */ jsx9("button", { type: "button", disabled: busy, onClick: () => void act(link), children: "Revoke access" })
|
|
794
1062
|
] }, link.id)) }),
|
|
795
|
-
cursor && /* @__PURE__ */
|
|
1063
|
+
cursor && /* @__PURE__ */ jsx9("button", { type: "button", disabled: busy, onClick: () => void act(), children: "Load more links" })
|
|
796
1064
|
]
|
|
797
1065
|
}
|
|
798
1066
|
);
|
|
799
1067
|
}
|
|
800
1068
|
|
|
1069
|
+
// src/connection-installed.tsx
|
|
1070
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1071
|
+
function ConnectionInstalled({
|
|
1072
|
+
items,
|
|
1073
|
+
title = "Connected",
|
|
1074
|
+
className = ""
|
|
1075
|
+
}) {
|
|
1076
|
+
if (!items.length) return null;
|
|
1077
|
+
return /* @__PURE__ */ jsxs10("section", { "aria-label": title, className: `og-connection-installed ${className}`, children: [
|
|
1078
|
+
/* @__PURE__ */ jsxs10("h2", { children: [
|
|
1079
|
+
title,
|
|
1080
|
+
" ",
|
|
1081
|
+
/* @__PURE__ */ jsx10("span", { children: items.length })
|
|
1082
|
+
] }),
|
|
1083
|
+
/* @__PURE__ */ jsx10("div", { children: items.map((item) => /* @__PURE__ */ jsxs10(
|
|
1084
|
+
"button",
|
|
1085
|
+
{
|
|
1086
|
+
type: "button",
|
|
1087
|
+
onClick: item.onOpen,
|
|
1088
|
+
title: item.status,
|
|
1089
|
+
"aria-label": `${item.name} \xB7 ${item.status}`,
|
|
1090
|
+
children: [
|
|
1091
|
+
item.icon,
|
|
1092
|
+
/* @__PURE__ */ jsx10("span", { children: item.name }),
|
|
1093
|
+
item.needsAttention ? /* @__PURE__ */ jsx10("span", { "aria-label": "Needs attention", children: "!" }) : null
|
|
1094
|
+
]
|
|
1095
|
+
},
|
|
1096
|
+
item.id
|
|
1097
|
+
)) })
|
|
1098
|
+
] });
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
// src/connection-type-picker.tsx
|
|
1102
|
+
import { useId } from "react";
|
|
1103
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1104
|
+
function ConnectionTypePicker({
|
|
1105
|
+
value,
|
|
1106
|
+
onChange,
|
|
1107
|
+
disabled = false
|
|
1108
|
+
}) {
|
|
1109
|
+
const name = useId();
|
|
1110
|
+
return /* @__PURE__ */ jsxs11("fieldset", { className: "og-connection-type-picker", disabled, children: [
|
|
1111
|
+
/* @__PURE__ */ jsx11("legend", { children: "Connection type" }),
|
|
1112
|
+
[
|
|
1113
|
+
["mcp", "MCP server"],
|
|
1114
|
+
["openapi", "OpenAPI"],
|
|
1115
|
+
["graphql", "GraphQL"]
|
|
1116
|
+
].map(([type, label]) => /* @__PURE__ */ jsxs11("label", { "data-selected": value === type, children: [
|
|
1117
|
+
/* @__PURE__ */ jsx11(
|
|
1118
|
+
"input",
|
|
1119
|
+
{
|
|
1120
|
+
type: "radio",
|
|
1121
|
+
name,
|
|
1122
|
+
value: type,
|
|
1123
|
+
checked: value === type,
|
|
1124
|
+
onChange: () => onChange(type)
|
|
1125
|
+
}
|
|
1126
|
+
),
|
|
1127
|
+
label
|
|
1128
|
+
] }, type))
|
|
1129
|
+
] });
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// src/connection-logo.tsx
|
|
1133
|
+
import { useState as useState8 } from "react";
|
|
1134
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1135
|
+
function ConnectionLogo({
|
|
1136
|
+
src,
|
|
1137
|
+
name,
|
|
1138
|
+
size = 40
|
|
1139
|
+
}) {
|
|
1140
|
+
const [failedSrc, setFailedSrc] = useState8(null);
|
|
1141
|
+
return /* @__PURE__ */ jsx12("span", { className: "og-connection-logo", "aria-hidden": "true", style: { width: size, height: size }, children: src && src !== failedSrc ? /* @__PURE__ */ jsx12("img", { src, alt: "", loading: "lazy", decoding: "async", onError: () => setFailedSrc(src) }) : /* @__PURE__ */ jsx12("span", { children: name.split(/\s+/).map((part) => part[0]).join("").slice(0, 2).toUpperCase() }) });
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// src/plugin-discovery.tsx
|
|
1145
|
+
import { useEffect as useEffect7, useRef as useRef5, useState as useState9 } from "react";
|
|
1146
|
+
import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1147
|
+
function PluginDiscovery(props) {
|
|
1148
|
+
const [provider, setProvider] = useState9("");
|
|
1149
|
+
return /* @__PURE__ */ jsxs12("section", { className: "og-plugin-discovery", "aria-label": "Discover plugins", children: [
|
|
1150
|
+
/* @__PURE__ */ jsxs12("header", { children: [
|
|
1151
|
+
/* @__PURE__ */ jsx13("h3", { children: "Browse plugins" }),
|
|
1152
|
+
/* @__PURE__ */ jsx13("div", { className: "og-plugin-filters", role: "group", "aria-label": "Plugin registry", children: [
|
|
1153
|
+
{ value: "", label: "All" },
|
|
1154
|
+
{ value: "openai", label: "OpenAI plugin registry" },
|
|
1155
|
+
{ value: "anthropic", label: "Anthropic plugin registry" }
|
|
1156
|
+
].map((option) => /* @__PURE__ */ jsx13(
|
|
1157
|
+
"button",
|
|
1158
|
+
{
|
|
1159
|
+
type: "button",
|
|
1160
|
+
"aria-pressed": provider === option.value,
|
|
1161
|
+
onClick: () => setProvider(option.value),
|
|
1162
|
+
children: option.label
|
|
1163
|
+
},
|
|
1164
|
+
option.value
|
|
1165
|
+
)) })
|
|
1166
|
+
] }),
|
|
1167
|
+
/* @__PURE__ */ jsx13(
|
|
1168
|
+
Results,
|
|
1169
|
+
{
|
|
1170
|
+
...props,
|
|
1171
|
+
provider
|
|
1172
|
+
},
|
|
1173
|
+
`${props.workspaceId}:${props.query}:${provider}`
|
|
1174
|
+
)
|
|
1175
|
+
] });
|
|
1176
|
+
}
|
|
1177
|
+
function Results({
|
|
1178
|
+
client,
|
|
1179
|
+
workspaceId,
|
|
1180
|
+
query,
|
|
1181
|
+
provider,
|
|
1182
|
+
onOpen
|
|
1183
|
+
}) {
|
|
1184
|
+
const [items, setItems] = useState9([]);
|
|
1185
|
+
const [offset, setOffset] = useState9(0);
|
|
1186
|
+
const [next, setNext] = useState9(null);
|
|
1187
|
+
const [total, setTotal] = useState9(0);
|
|
1188
|
+
const [loading, setLoading] = useState9(true);
|
|
1189
|
+
const [error, setError] = useState9(false);
|
|
1190
|
+
const [retry, setRetry] = useState9(0);
|
|
1191
|
+
const sentinel = useRef5(null);
|
|
1192
|
+
useEffect7(() => {
|
|
1193
|
+
let active = true;
|
|
1194
|
+
setLoading(true);
|
|
1195
|
+
setError(false);
|
|
1196
|
+
const timer = setTimeout(
|
|
1197
|
+
() => {
|
|
1198
|
+
void client.discoverPlugins(workspaceId, { query, provider, offset }).then(
|
|
1199
|
+
(page) => {
|
|
1200
|
+
if (!active) return;
|
|
1201
|
+
setItems((previous) => offset ? [...previous, ...page.items] : page.items);
|
|
1202
|
+
setTotal(page.total);
|
|
1203
|
+
setNext(page.nextOffset);
|
|
1204
|
+
setLoading(false);
|
|
1205
|
+
},
|
|
1206
|
+
() => {
|
|
1207
|
+
if (active) {
|
|
1208
|
+
setError(true);
|
|
1209
|
+
setLoading(false);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
);
|
|
1213
|
+
},
|
|
1214
|
+
offset ? 0 : 200
|
|
1215
|
+
);
|
|
1216
|
+
return () => {
|
|
1217
|
+
active = false;
|
|
1218
|
+
clearTimeout(timer);
|
|
1219
|
+
};
|
|
1220
|
+
}, [client, workspaceId, query, provider, offset, retry]);
|
|
1221
|
+
useEffect7(() => {
|
|
1222
|
+
if (loading || error || next === null || !sentinel.current) return;
|
|
1223
|
+
const observer = new IntersectionObserver(
|
|
1224
|
+
(entries) => {
|
|
1225
|
+
if (entries.some((entry) => entry.isIntersecting)) setOffset(next);
|
|
1226
|
+
},
|
|
1227
|
+
{ rootMargin: "200px" }
|
|
1228
|
+
);
|
|
1229
|
+
observer.observe(sentinel.current);
|
|
1230
|
+
return () => observer.disconnect();
|
|
1231
|
+
}, [loading, error, next]);
|
|
1232
|
+
return /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
1233
|
+
!loading && !error ? /* @__PURE__ */ jsx13("p", { role: "status", children: total ? `${total} plugins` : "No matching plugins. Try another search or registry." }) : null,
|
|
1234
|
+
/* @__PURE__ */ jsx13("div", { className: "og-plugin-discovery-grid", children: items.map((item) => /* @__PURE__ */ jsxs12(
|
|
1235
|
+
"button",
|
|
1236
|
+
{
|
|
1237
|
+
className: "og-plugin-discovery-row",
|
|
1238
|
+
type: "button",
|
|
1239
|
+
onClick: () => onOpen(item),
|
|
1240
|
+
children: [
|
|
1241
|
+
item.logoUrl ? /* @__PURE__ */ jsx13(
|
|
1242
|
+
"img",
|
|
1243
|
+
{
|
|
1244
|
+
src: item.logoUrl,
|
|
1245
|
+
alt: "",
|
|
1246
|
+
loading: "lazy",
|
|
1247
|
+
onError: (event) => {
|
|
1248
|
+
event.currentTarget.style.display = "none";
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
) : null,
|
|
1252
|
+
/* @__PURE__ */ jsxs12("span", { className: "og-plugin-copy", children: [
|
|
1253
|
+
/* @__PURE__ */ jsxs12("span", { className: "og-plugin-title", children: [
|
|
1254
|
+
/* @__PURE__ */ jsx13("strong", { children: item.displayName.replace(/-/g, " ") }),
|
|
1255
|
+
/* @__PURE__ */ jsx13("small", { children: item.provider === "openai" ? "OpenAI plugin registry" : "Anthropic plugin registry" })
|
|
1256
|
+
] }),
|
|
1257
|
+
/* @__PURE__ */ jsx13("span", { className: "og-plugin-description", children: item.description }),
|
|
1258
|
+
item.category ? /* @__PURE__ */ jsx13("span", { className: "og-plugin-category", children: item.category }) : null
|
|
1259
|
+
] }),
|
|
1260
|
+
/* @__PURE__ */ jsx13("span", { className: "og-plugin-open", "aria-hidden": "true", children: "\u203A" })
|
|
1261
|
+
]
|
|
1262
|
+
},
|
|
1263
|
+
item.id
|
|
1264
|
+
)) }),
|
|
1265
|
+
loading ? /* @__PURE__ */ jsx13("p", { role: "status", children: "Loading plugins\u2026" }) : null,
|
|
1266
|
+
error ? /* @__PURE__ */ jsxs12("p", { role: "alert", children: [
|
|
1267
|
+
"Couldn\u2019t load plugins.",
|
|
1268
|
+
" ",
|
|
1269
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "Retry" })
|
|
1270
|
+
] }) : null,
|
|
1271
|
+
/* @__PURE__ */ jsx13("div", { ref: sentinel, children: next !== null && !loading && !error ? /* @__PURE__ */ jsx13("button", { className: "og-plugin-more", type: "button", onClick: () => setOffset(next), children: "Show more plugins" }) : null })
|
|
1272
|
+
] });
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// src/plugin-details.tsx
|
|
1276
|
+
import { useState as useState10 } from "react";
|
|
1277
|
+
import { pluginMcpUnavailableReason } from "@opengeni/sdk";
|
|
1278
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1279
|
+
var componentLabels = {
|
|
1280
|
+
skills: "Skills",
|
|
1281
|
+
mcp: "MCP connections",
|
|
1282
|
+
apps: "Hosted apps",
|
|
1283
|
+
hooks: "Hooks",
|
|
1284
|
+
agents: "Agents",
|
|
1285
|
+
commands: "Commands",
|
|
1286
|
+
lsp: "Language servers"
|
|
1287
|
+
};
|
|
1288
|
+
var EMPTY_CONNECTIONS = {};
|
|
1289
|
+
function PluginDetails({
|
|
1290
|
+
item,
|
|
1291
|
+
onInstall,
|
|
1292
|
+
busy = false,
|
|
1293
|
+
installed = false,
|
|
1294
|
+
error,
|
|
1295
|
+
connections = EMPTY_CONNECTIONS,
|
|
1296
|
+
onConnect
|
|
1297
|
+
}) {
|
|
1298
|
+
const supported = (server) => pluginMcpUnavailableReason(server) === null;
|
|
1299
|
+
const contentsUnknown = item.skills == null || item.mcpServers == null;
|
|
1300
|
+
const installableCount = (item.skills?.length ?? 0) + (item.mcpServers?.filter(supported).length ?? 0);
|
|
1301
|
+
const exceedsInstallLimit = installableCount > 64;
|
|
1302
|
+
const installable = installableCount > 0 && !exceedsInstallLimit;
|
|
1303
|
+
const [expanded, setExpanded] = useState10(false);
|
|
1304
|
+
const [logoFailed, setLogoFailed] = useState10(false);
|
|
1305
|
+
const description = item.longDescription || item.description;
|
|
1306
|
+
const lengthy = description.length > 700;
|
|
1307
|
+
const registryLabel = item.provider === "openai" ? "OpenAI plugin registry" : item.provider === "anthropic" ? "Anthropic plugin registry" : "Custom source";
|
|
1308
|
+
return /* @__PURE__ */ jsxs13("article", { className: "og-plugin-details", children: [
|
|
1309
|
+
/* @__PURE__ */ jsxs13("header", { className: "og-plugin-details-header", children: [
|
|
1310
|
+
item.logoUrl && !logoFailed ? /* @__PURE__ */ jsx14("img", { src: item.logoUrl, alt: "", onError: () => setLogoFailed(true) }) : null,
|
|
1311
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
1312
|
+
/* @__PURE__ */ jsx14("h2", { children: item.displayName.replace(/-/g, " ") }),
|
|
1313
|
+
item.author?.name ? /* @__PURE__ */ jsxs13("p", { children: [
|
|
1314
|
+
"By ",
|
|
1315
|
+
item.author.name
|
|
1316
|
+
] }) : null
|
|
1317
|
+
] })
|
|
1318
|
+
] }),
|
|
1319
|
+
/* @__PURE__ */ jsxs13("div", { className: "og-plugin-details-meta", children: [
|
|
1320
|
+
/* @__PURE__ */ jsx14("span", { children: registryLabel }),
|
|
1321
|
+
item.category ? /* @__PURE__ */ jsx14("span", { children: item.category }) : null,
|
|
1322
|
+
item.version ? /* @__PURE__ */ jsxs13("span", { children: [
|
|
1323
|
+
"v",
|
|
1324
|
+
item.version
|
|
1325
|
+
] }) : null
|
|
1326
|
+
] }),
|
|
1327
|
+
/* @__PURE__ */ jsxs13("section", { className: "og-plugin-details-members", children: [
|
|
1328
|
+
/* @__PURE__ */ jsxs13("h3", { children: [
|
|
1329
|
+
"Skills ",
|
|
1330
|
+
/* @__PURE__ */ jsx14("span", { children: item.skills?.length ?? "\u2014" })
|
|
1331
|
+
] }),
|
|
1332
|
+
item.skills?.length ? /* @__PURE__ */ jsx14("ul", { children: item.skills.map((skill) => /* @__PURE__ */ jsx14("li", { children: /* @__PURE__ */ jsxs13("a", { href: skill.sourceUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
1333
|
+
/* @__PURE__ */ jsx14("strong", { children: skill.name }),
|
|
1334
|
+
/* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2197" })
|
|
1335
|
+
] }) }, skill.sourceUrl)) }) : /* @__PURE__ */ jsx14("p", { children: item.skills ? "No bundled skills." : "Contents haven\u2019t been indexed for this repository." }),
|
|
1336
|
+
/* @__PURE__ */ jsxs13("h3", { children: [
|
|
1337
|
+
"MCP servers ",
|
|
1338
|
+
/* @__PURE__ */ jsx14("span", { children: item.mcpServers?.length ?? "\u2014" })
|
|
1339
|
+
] }),
|
|
1340
|
+
item.mcpServers?.length ? /* @__PURE__ */ jsx14("ul", { children: item.mcpServers.map((server) => {
|
|
1341
|
+
const connected = Boolean(server.endpoint && connections[server.endpoint]);
|
|
1342
|
+
const unavailableReason = connected ? null : pluginMcpUnavailableReason(server);
|
|
1343
|
+
return /* @__PURE__ */ jsxs13(
|
|
1344
|
+
"li",
|
|
1345
|
+
{
|
|
1346
|
+
className: unavailableReason ? "og-plugin-member-disabled" : void 0,
|
|
1347
|
+
children: [
|
|
1348
|
+
/* @__PURE__ */ jsxs13("div", { className: "og-plugin-server-heading", children: [
|
|
1349
|
+
/* @__PURE__ */ jsx14("strong", { children: server.name }),
|
|
1350
|
+
!unavailableReason && onConnect ? /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: () => onConnect(server), children: connected ? "Manage" : "Connect" }) : null
|
|
1351
|
+
] }),
|
|
1352
|
+
/* @__PURE__ */ jsxs13("small", { children: [
|
|
1353
|
+
connected ? "Connected \xB7 " : "",
|
|
1354
|
+
unavailableReason ?? server.endpoint
|
|
1355
|
+
] })
|
|
1356
|
+
]
|
|
1357
|
+
},
|
|
1358
|
+
server.name
|
|
1359
|
+
);
|
|
1360
|
+
}) }) : /* @__PURE__ */ jsx14("p", { children: item.mcpServers ? "No bundled MCP servers." : "Server details haven\u2019t been indexed." }),
|
|
1361
|
+
item.components?.some((component) => !["skills", "mcp"].includes(component)) ? /* @__PURE__ */ jsxs13("div", { className: "og-plugin-details-other", children: [
|
|
1362
|
+
"Not installed here:",
|
|
1363
|
+
" ",
|
|
1364
|
+
item.components.filter((component) => !["skills", "mcp"].includes(component)).map((component) => componentLabels[component] ?? component).join(", ")
|
|
1365
|
+
] }) : null
|
|
1366
|
+
] }),
|
|
1367
|
+
/* @__PURE__ */ jsxs13("section", { className: "og-plugin-details-overview", "aria-label": "Overview", children: [
|
|
1368
|
+
/* @__PURE__ */ jsx14("div", { className: lengthy && !expanded ? "og-plugin-details-excerpt" : void 0, children: /* @__PURE__ */ jsx14(Markdown, { children: description }) }),
|
|
1369
|
+
lengthy ? /* @__PURE__ */ jsx14(
|
|
1370
|
+
"button",
|
|
1371
|
+
{
|
|
1372
|
+
type: "button",
|
|
1373
|
+
className: "og-plugin-details-more",
|
|
1374
|
+
"aria-expanded": expanded,
|
|
1375
|
+
onClick: () => setExpanded((value) => !value),
|
|
1376
|
+
children: expanded ? "Show less" : "Read more"
|
|
1377
|
+
}
|
|
1378
|
+
) : null
|
|
1379
|
+
] }),
|
|
1380
|
+
/* @__PURE__ */ jsxs13("footer", { children: [
|
|
1381
|
+
item.sourceUrl ? /* @__PURE__ */ jsxs13("a", { href: item.sourceUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
1382
|
+
"View repository ",
|
|
1383
|
+
/* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2197" })
|
|
1384
|
+
] }) : null,
|
|
1385
|
+
onInstall ? /* @__PURE__ */ jsx14(
|
|
1386
|
+
"button",
|
|
1387
|
+
{
|
|
1388
|
+
className: "og-plugin-install",
|
|
1389
|
+
type: "button",
|
|
1390
|
+
disabled: !installable || busy || installed,
|
|
1391
|
+
onClick: onInstall,
|
|
1392
|
+
children: installed ? "Installed" : busy ? "Installing\u2026" : "Install plugin"
|
|
1393
|
+
}
|
|
1394
|
+
) : null,
|
|
1395
|
+
error ? /* @__PURE__ */ jsx14("p", { role: "alert", children: error }) : null,
|
|
1396
|
+
exceedsInstallLimit ? /* @__PURE__ */ jsx14("p", { children: "This plugin exceeds the current 64-component installation limit." }) : contentsUnknown ? /* @__PURE__ */ jsx14("p", { children: "Plugin contents are unavailable. Installation is disabled until the repository can be inspected." }) : !installable ? /* @__PURE__ */ jsx14("p", { children: "No installable skills or remote MCP servers." }) : /* @__PURE__ */ jsx14("p", { children: "Installs skills and adds connection references. Connect each server separately." })
|
|
1397
|
+
] })
|
|
1398
|
+
] });
|
|
1399
|
+
}
|
|
1400
|
+
|
|
801
1401
|
// src/connect.ts
|
|
802
1402
|
function useConnect(controller) {
|
|
803
1403
|
const snapshot = useSyncExternalStore(
|
|
@@ -823,9 +1423,18 @@ export {
|
|
|
823
1423
|
ConnectChooser,
|
|
824
1424
|
ConnectPanel,
|
|
825
1425
|
ConnectSetup,
|
|
1426
|
+
ConnectionCatalog,
|
|
1427
|
+
ConnectionInstalled,
|
|
1428
|
+
ConnectionLogo,
|
|
1429
|
+
ConnectionOptionRow,
|
|
1430
|
+
ConnectionServiceRow,
|
|
1431
|
+
ConnectionTypePicker,
|
|
826
1432
|
DeviceAuthorization,
|
|
827
1433
|
IdentityLinkAccounts,
|
|
828
1434
|
IdentityLinkConsent,
|
|
1435
|
+
PluginDetails,
|
|
1436
|
+
PluginDiscovery,
|
|
1437
|
+
SkillDiscovery,
|
|
829
1438
|
useConnect
|
|
830
1439
|
};
|
|
831
1440
|
//# sourceMappingURL=connect.js.map
|