@mcp-b/react-components 0.47.0 → 0.48.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/{CodeBlock-DMHZiw86.js → CodeBlock-BSJl682D.js} +1 -1
- package/dist/Correspondent-7K6uNLUm.d.ts +64 -0
- package/dist/{FileTree-BHebfvkK.js → FileTree-DvE0hNZu.js} +1 -1
- package/dist/{SetupChecklist-CwRjIDH4.js → SetupChecklist-DeTU9YpW.js} +1 -1
- package/dist/{ThinkChat-DLDta57t.js → ThinkChat-DiI6hhDP.js} +3 -3
- package/dist/{Workspace-C_zHq9KZ.d.ts → Workspace-LIoU30n7.d.ts} +13 -2
- package/dist/{WorkspaceFileView-ChIJz-fl.js → WorkspaceFileView-C_WnYm-a.js} +3 -3
- package/dist/{WorkspaceLive-DLGhtIly.d.ts → WorkspaceLive-DfjH1Ypm.d.ts} +12 -0
- package/dist/{WorkspaceMessageResponse-Dg_aNpoj.js → WorkspaceMessageResponse-BqOezptB.js} +4 -1
- package/dist/components/agents-sdk/AgentActivity.js +1 -1
- package/dist/components/agents-sdk/AgentChat.js +10 -10
- package/dist/components/agents-sdk/AgentEvent.js +1 -1
- package/dist/components/agents-sdk/BrowserLiveScreen.js +1 -1
- package/dist/components/agents-sdk/BrowserLiveView.js +1 -1
- package/dist/components/agents-sdk/BrowserReplay.js +1 -1
- package/dist/components/agents-sdk/BrowserRunPanel.js +1 -1
- package/dist/components/agents-sdk/ManagerOffice.d.ts +41 -50
- package/dist/components/agents-sdk/ManagerOffice.js +360 -979
- package/dist/components/agents-sdk/McpConnectionRequest.js +2 -2
- package/dist/components/agents-sdk/McpConnectorForm.js +1 -1
- package/dist/components/agents-sdk/McpPluginCatalog.js +2 -2
- package/dist/components/agents-sdk/McpServerPicker.js +2 -2
- package/dist/components/agents-sdk/ModelSelector.js +3 -3
- package/dist/components/agents-sdk/PromptInputApproval.js +1 -1
- package/dist/components/agents-sdk/PromptInputCommands.js +1 -1
- package/dist/components/agents-sdk/SubagentRunIndicator.js +1 -1
- package/dist/components/agents-sdk/SubagentRunSelector.js +1 -1
- package/dist/components/agents-sdk/ThinkChat.js +1 -1
- package/dist/components/agents-sdk/ThinkChatActivity.js +1 -1
- package/dist/components/agents-sdk/ThinkChatToolPanels.js +2 -2
- package/dist/components/agents-sdk/ThinkExecutionDetail.js +2 -2
- package/dist/components/agents-sdk/ThinkExecutionStatus.js +1 -1
- package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +3 -3
- package/dist/components/agents-sdk/ThinkFullApp.d.ts +3 -3
- package/dist/components/agents-sdk/ThinkFullApp.js +9 -4
- package/dist/components/agents-sdk/ThinkFullAppViewSwitch.js +1 -1
- package/dist/components/agents-sdk/ThinkRecoveryNotice.js +1 -1
- package/dist/components/agents-sdk/ThinkRoutineBrowser.js +2 -2
- package/dist/components/agents-sdk/ThinkRoutineDetail.js +1 -1
- package/dist/components/agents-sdk/ThinkRoutineForm.js +4 -4
- package/dist/components/agents-sdk/ThinkRoutineLibrary.js +3 -3
- package/dist/components/agents-sdk/ThinkRoutineRuns.js +1 -1
- package/dist/components/agents-sdk/ThinkSidepanel.js +10 -10
- package/dist/components/agents-sdk/ThinkThreadPicker.js +4 -4
- package/dist/components/agents-sdk/Workspace.d.ts +2 -2
- package/dist/components/agents-sdk/Workspace.js +13 -10
- package/dist/components/agents-sdk/WorkspaceBrowser.d.ts +1 -1
- package/dist/components/agents-sdk/WorkspaceBrowser.js +1 -1
- package/dist/components/agents-sdk/WorkspaceConcept.d.ts +3 -2
- package/dist/components/agents-sdk/WorkspaceConcept.js +3 -3
- package/dist/components/agents-sdk/WorkspaceCorrespondence.d.ts +5 -9
- package/dist/components/agents-sdk/WorkspaceCorrespondence.js +44 -44
- package/dist/components/agents-sdk/WorkspaceExecution.d.ts +30 -21
- package/dist/components/agents-sdk/WorkspaceExecution.js +104 -167
- package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +1 -1
- package/dist/components/agents-sdk/WorkspaceExplorer.js +1 -1
- package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
- package/dist/components/agents-sdk/WorkspaceHeader.js +1 -1
- package/dist/components/agents-sdk/WorkspaceLive.d.ts +1 -1
- package/dist/components/agents-sdk/WorkspaceLive.js +33 -5
- package/dist/components/agents-sdk/WorkspaceMessageResponse.js +1 -1
- package/dist/components/agents-sdk/WorkspaceMountManager.js +2 -2
- package/dist/components/agents-sdk/WorkspaceProject.d.ts +43 -5
- package/dist/components/agents-sdk/WorkspaceProject.js +62 -25
- package/dist/components/agents-sdk/WorkspaceUserScript.js +4 -4
- package/dist/components/ai-sdk/Activity.js +1 -1
- package/dist/components/ai-sdk/AgentChatStartScreen.js +1 -1
- package/dist/components/ai-sdk/Approval.js +2 -2
- package/dist/components/ai-sdk/Artifact.js +3 -3
- package/dist/components/ai-sdk/ChainOfThought.js +1 -1
- package/dist/components/ai-sdk/Checkpoint.js +1 -1
- package/dist/components/ai-sdk/CodeBlock.js +1 -1
- package/dist/components/ai-sdk/ComposerLink.js +1 -1
- package/dist/components/ai-sdk/ConnectedAppCards.d.ts +7 -0
- package/dist/components/ai-sdk/ConnectedAppCards.js +48 -80
- package/dist/components/ai-sdk/Conversation.js +1 -1
- package/dist/components/ai-sdk/Correspondent.d.ts +2 -0
- package/dist/components/ai-sdk/Correspondent.js +145 -0
- package/dist/components/ai-sdk/Goal.js +1 -1
- package/dist/components/ai-sdk/InlineCitation.js +1 -1
- package/dist/components/ai-sdk/MediaPreviewCard.js +1 -1
- package/dist/components/ai-sdk/Message.js +1 -1
- package/dist/components/ai-sdk/MessageScroller.js +1 -1
- package/dist/components/ai-sdk/MessageScrollerVirtual.js +1 -1
- package/dist/components/ai-sdk/Plan.js +1 -1
- package/dist/components/ai-sdk/PromptInput.js +5 -5
- package/dist/components/ai-sdk/Queue.js +1 -1
- package/dist/components/ai-sdk/Reasoning.js +1 -1
- package/dist/components/ai-sdk/Sources.js +1 -1
- package/dist/components/ai-sdk/Task.js +1 -1
- package/dist/components/extension/ChatGptSignInScreen.js +1 -1
- package/dist/components/extension/CodexModelSelector.js +2 -2
- package/dist/components/extension/ConversationTabPicker.js +2 -2
- package/dist/components/foundations/Checkbox.js +1 -1
- package/dist/components/foundations/Collapsible.js +1 -1
- package/dist/components/foundations/ContextMenu.js +1 -1
- package/dist/components/foundations/Menubar.js +1 -1
- package/dist/components/foundations/SearchField.js +1 -1
- package/dist/components/foundations/Select.js +1 -1
- package/dist/components/foundations/Stepper.js +1 -1
- package/dist/components/foundations/Toast.js +1 -1
- package/dist/components/foundations/ToggleGroup.d.ts +1 -1
- package/dist/components/foundations/ToggleGroup.js +1 -1
- package/dist/components/foundations/icons.js +1 -1
- package/dist/components/general-purpose/Commit.js +2 -2
- package/dist/components/general-purpose/EnvironmentVariables.js +2 -2
- package/dist/components/general-purpose/FileTree.js +1 -1
- package/dist/components/general-purpose/PricingBillingToggle.js +1 -1
- package/dist/components/general-purpose/PricingPlanCard.js +2 -2
- package/dist/components/general-purpose/PricingUsageCalculator.js +2 -2
- package/dist/components/general-purpose/ResponsiveSidebarShell.js +1 -1
- package/dist/components/general-purpose/SettingsFormDialog.js +2 -2
- package/dist/components/general-purpose/SetupChecklist.js +1 -1
- package/dist/components/general-purpose/Terminal.js +2 -2
- package/dist/components/general-purpose/TestResults.js +1 -1
- package/dist/components/general-purpose/ThemeModeControl.js +2 -2
- package/dist/components/general-purpose/WebPreview.js +2 -2
- package/dist/components/nanites/AgentConnection.js +2 -2
- package/dist/components/nanites/AgentToolDetail.js +5 -5
- package/dist/{copy-button-CSDuDfdP.js → copy-button-Dk2vRe9j.js} +1 -1
- package/dist/styles/base.css +2 -2
- package/dist/styles/correspondent.css +73 -0
- package/dist/styles/index.css +1 -0
- package/dist/styles/manager-office.css +380 -1086
- package/dist/{workspace-assets-CxpEHsac.js → workspace-assets-GqsCYxqT.js} +16 -2
- package/package.json +2 -2
- package/dist/{icons-cuEtsgj9.js → icons-CeGfXO21.js} +1 -1
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { t as cx } from "../../class-names-BiMDVpUo.js";
|
|
2
|
-
import { S as FileIcon, d as CheckIcon } from "../../icons-
|
|
2
|
+
import { S as FileIcon, d as CheckIcon } from "../../icons-CeGfXO21.js";
|
|
3
3
|
import { Button } from "../foundations/Button.js";
|
|
4
|
-
import { IconButton } from "../foundations/IconButton.js";
|
|
5
|
-
import { a as formatErrorMessage } from "../../format-COCyV98Z.js";
|
|
6
4
|
import { Field } from "../foundations/Field.js";
|
|
7
5
|
import { Textarea } from "../foundations/Textarea.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { IconButton } from "../foundations/IconButton.js";
|
|
7
|
+
import { a as formatErrorMessage } from "../../format-COCyV98Z.js";
|
|
10
8
|
import { Card, CardAction, CardContent, CardFooter, CardHeader, CardTitle } from "../foundations/Card.js";
|
|
9
|
+
import { DescriptionList } from "../foundations/DescriptionList.js";
|
|
10
|
+
import { Input } from "../foundations/Input.js";
|
|
11
11
|
import { EmailMessageCard, SlackMessageCard } from "../ai-sdk/ConnectedAppCards.js";
|
|
12
|
-
import { i as WorkspaceDeleteControl, r as httpUrl, t as FaviconMark } from "../../workspace-assets-
|
|
12
|
+
import { i as WorkspaceDeleteControl, r as httpUrl, t as FaviconMark } from "../../workspace-assets-GqsCYxqT.js";
|
|
13
13
|
import * as React from "react";
|
|
14
|
+
import { createElement } from "react";
|
|
14
15
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
-
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
16
|
+
import { hashKey, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
16
17
|
//#region src/components/agents-sdk/WorkspaceCorrespondence.tsx
|
|
17
18
|
const SAVE_DEBOUNCE_MS = 400;
|
|
18
19
|
const SEND_BLOCKED_MESSAGE = "Your edit has not saved, so nothing was sent. Retry the save first.";
|
|
19
20
|
const FILE_MISSING_MESSAGE = "The file is no longer in the workspace.";
|
|
21
|
+
const SAVE_UNAVAILABLE_MESSAGE = "Saving is no longer available.";
|
|
22
|
+
const SEND_UNAVAILABLE_MESSAGE = "Sending is no longer available.";
|
|
20
23
|
function fieldValue(fields, name) {
|
|
21
24
|
return fields.find((field) => field.name === name)?.value;
|
|
22
25
|
}
|
|
@@ -298,11 +301,17 @@ function WorkspaceCorrespondenceCard({ body, fields, kind, path, icon, saveState
|
|
|
298
301
|
* flushes the outstanding edit first and refuses when that save fails — the
|
|
299
302
|
* agent must never be told to send content the workspace does not hold.
|
|
300
303
|
*
|
|
301
|
-
* Interaction state belongs to one
|
|
302
|
-
* source
|
|
303
|
-
*
|
|
304
|
+
* Interaction state belongs to one query identity. The keyed session makes a
|
|
305
|
+
* source swap a real unmount, so an old save or send cannot settle onto the
|
|
306
|
+
* next file.
|
|
304
307
|
*/
|
|
305
|
-
function WorkspaceCorrespondenceFile(
|
|
308
|
+
function WorkspaceCorrespondenceFile(props) {
|
|
309
|
+
return /* @__PURE__ */ createElement(WorkspaceCorrespondenceFileSession, {
|
|
310
|
+
...props,
|
|
311
|
+
key: hashKey(props.source.queryOptions.queryKey)
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
function WorkspaceCorrespondenceFileSession({ fallback = null, source, ...props }) {
|
|
306
315
|
const queryClient = useQueryClient();
|
|
307
316
|
const persisted = useQuery(source.queryOptions).data ?? null;
|
|
308
317
|
const path = persisted?.path;
|
|
@@ -316,20 +325,9 @@ function WorkspaceCorrespondenceFile({ fallback = null, source, ...props }) {
|
|
|
316
325
|
const savePromiseRef = React.useRef(null);
|
|
317
326
|
/** The last projection this card rendered, kept for the sent snapshot. */
|
|
318
327
|
const lastShownRef = React.useRef(null);
|
|
319
|
-
const identity = String(source.queryOptions.queryKey);
|
|
320
|
-
const [seenIdentity, setSeenIdentity] = React.useState(identity);
|
|
321
|
-
if (identity !== seenIdentity) {
|
|
322
|
-
setSeenIdentity(identity);
|
|
323
|
-
setDraft(null);
|
|
324
|
-
setSessionSent(false);
|
|
325
|
-
attemptedDraftRef.current = null;
|
|
326
|
-
savedDraftRef.current = null;
|
|
327
|
-
savePromiseRef.current = null;
|
|
328
|
-
lastShownRef.current = null;
|
|
329
|
-
}
|
|
330
328
|
const saveMutation = useMutation({
|
|
331
329
|
mutationFn: async (next) => {
|
|
332
|
-
if (!source.onChange)
|
|
330
|
+
if (!source.onChange) throw new Error(SAVE_UNAVAILABLE_MESSAGE);
|
|
333
331
|
if (path === void 0) throw new Error(FILE_MISSING_MESSAGE);
|
|
334
332
|
await source.onChange(path, next);
|
|
335
333
|
},
|
|
@@ -357,36 +355,34 @@ function WorkspaceCorrespondenceFile({ fallback = null, source, ...props }) {
|
|
|
357
355
|
savePromiseRef.current = settled;
|
|
358
356
|
return settled;
|
|
359
357
|
}, [mutateSaveAsync]);
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
358
|
+
const { mutateAsync: mutateSendAsync } = useMutation({
|
|
359
|
+
mutationFn: async () => {
|
|
360
|
+
if (!source.onSend) throw new Error(SEND_UNAVAILABLE_MESSAGE);
|
|
361
|
+
if (path === void 0) throw new Error(FILE_MISSING_MESSAGE);
|
|
362
|
+
await source.onSend(path);
|
|
363
|
+
},
|
|
364
|
+
onSuccess: () => queryClient.invalidateQueries({
|
|
365
|
+
queryKey: source.queryOptions.queryKey,
|
|
366
|
+
exact: true
|
|
367
|
+
})
|
|
368
|
+
});
|
|
366
369
|
const canSave = source.onChange != null;
|
|
370
|
+
const settled = persisted?.state === "sent" || persisted?.state === void 0 && sessionSent;
|
|
371
|
+
const runDebouncedSave = React.useEffectEvent((next) => {
|
|
372
|
+
runSave(next);
|
|
373
|
+
});
|
|
367
374
|
React.useEffect(() => {
|
|
368
|
-
if (!canSave || path === void 0 ||
|
|
375
|
+
if (!canSave || path === void 0 || settled || draft === null) return;
|
|
369
376
|
if (draft === savedDraftRef.current || draft === attemptedDraftRef.current) return;
|
|
370
377
|
if (savePending) return;
|
|
371
|
-
const timer = setTimeout(() =>
|
|
378
|
+
const timer = setTimeout(() => runDebouncedSave(draft), SAVE_DEBOUNCE_MS);
|
|
372
379
|
return () => clearTimeout(timer);
|
|
373
380
|
}, [
|
|
374
381
|
canSave,
|
|
375
382
|
draft,
|
|
376
383
|
path,
|
|
377
|
-
runSave,
|
|
378
384
|
savePending,
|
|
379
|
-
|
|
380
|
-
]);
|
|
381
|
-
const { reset: resetSave } = saveMutation;
|
|
382
|
-
const { reset: resetSend } = sendMutation;
|
|
383
|
-
React.useEffect(() => {
|
|
384
|
-
resetSave();
|
|
385
|
-
resetSend();
|
|
386
|
-
}, [
|
|
387
|
-
identity,
|
|
388
|
-
resetSave,
|
|
389
|
-
resetSend
|
|
385
|
+
settled
|
|
390
386
|
]);
|
|
391
387
|
const send = React.useCallback(async () => {
|
|
392
388
|
if (savePromiseRef.current !== null && !await savePromiseRef.current) throw new Error(SEND_BLOCKED_MESSAGE);
|
|
@@ -395,13 +391,17 @@ function WorkspaceCorrespondenceFile({ fallback = null, source, ...props }) {
|
|
|
395
391
|
if (!await runSave(outstanding)) throw new Error(SEND_BLOCKED_MESSAGE);
|
|
396
392
|
}
|
|
397
393
|
await mutateSendAsync();
|
|
394
|
+
if (persisted) lastShownRef.current = draft === null ? persisted : {
|
|
395
|
+
...persisted,
|
|
396
|
+
...draft
|
|
397
|
+
};
|
|
398
398
|
setSessionSent(true);
|
|
399
399
|
}, [
|
|
400
400
|
draft,
|
|
401
401
|
mutateSendAsync,
|
|
402
|
+
persisted,
|
|
402
403
|
runSave
|
|
403
404
|
]);
|
|
404
|
-
if (persisted) lastShownRef.current = persisted;
|
|
405
405
|
const shown = persisted ?? (sessionSent ? lastShownRef.current : null);
|
|
406
406
|
if (!shown) return fallback;
|
|
407
407
|
const visible = draft ?? shown;
|
|
@@ -10,51 +10,60 @@ interface WorkspaceExecutionParam {
|
|
|
10
10
|
label: string;
|
|
11
11
|
type: WorkspaceExecutionParamType;
|
|
12
12
|
/**
|
|
13
|
-
* Whether the module's schema lists this property as required.
|
|
14
|
-
*
|
|
15
|
-
* values; required ones refuse the run until filled.
|
|
13
|
+
* Whether the module's schema lists this property as required. This is a
|
|
14
|
+
* presentation hint only; the execution runtime owns argument validation.
|
|
16
15
|
*/
|
|
17
16
|
required: boolean;
|
|
18
|
-
value
|
|
17
|
+
value?: string | number | boolean;
|
|
19
18
|
}
|
|
20
19
|
interface WorkspaceExecutionRun {
|
|
21
20
|
path: string;
|
|
22
21
|
label: string;
|
|
22
|
+
}
|
|
23
|
+
interface WorkspaceExecutionRunView extends WorkspaceExecutionRun {
|
|
23
24
|
onOpen?: () => void;
|
|
24
25
|
}
|
|
26
|
+
interface WorkspaceExecutionOutcome {
|
|
27
|
+
/** Serialized return value from the existing execution runtime. */
|
|
28
|
+
result: unknown;
|
|
29
|
+
logs: readonly string[];
|
|
30
|
+
/** Result and log files emitted when the runtime overflowed its inline bounds. */
|
|
31
|
+
runs: readonly WorkspaceExecutionRun[];
|
|
32
|
+
}
|
|
33
|
+
interface WorkspaceExecutionViewOutcome extends Omit<WorkspaceExecutionOutcome, "runs"> {
|
|
34
|
+
runs: readonly WorkspaceExecutionRunView[];
|
|
35
|
+
}
|
|
25
36
|
interface WorkspaceExecution {
|
|
26
37
|
/** Workspace path of the module file. */
|
|
27
38
|
path: string;
|
|
28
39
|
name: string;
|
|
29
40
|
description?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Hostnames or URLs the model said this operates on. Shown like user-script
|
|
32
|
-
* Sites. Not a run argument and not parsed from the JavaScript.
|
|
33
|
-
*/
|
|
34
|
-
sites?: readonly string[];
|
|
35
|
-
/** Brand mark. Defaults to the first site favicon, then `TerminalIcon`. */
|
|
41
|
+
/** Brand mark. Defaults to `TerminalIcon`. */
|
|
36
42
|
icon?: React.ReactNode;
|
|
37
43
|
parameters: readonly WorkspaceExecutionParam[];
|
|
38
44
|
/** Recent result peeks, newest first. Not a results directory. */
|
|
39
45
|
runs?: readonly WorkspaceExecutionRun[];
|
|
46
|
+
}
|
|
47
|
+
/** Data-only execution projection hydrated with card actions outside Query. */
|
|
48
|
+
interface WorkspaceExecutionView extends WorkspaceExecution {
|
|
49
|
+
runs?: readonly WorkspaceExecutionRunView[];
|
|
40
50
|
/**
|
|
41
|
-
* Runs the module with the submitted values
|
|
42
|
-
*
|
|
43
|
-
* completed run even when the array is empty; returned files enrich that row.
|
|
51
|
+
* Runs the module with the submitted values. The card owns the run lifecycle;
|
|
52
|
+
* inline output and any overflow files enrich the completed row.
|
|
44
53
|
*/
|
|
45
|
-
onRun?: (parameters: readonly WorkspaceExecutionParam[]) => Promise<
|
|
54
|
+
onRun?: (parameters: readonly WorkspaceExecutionParam[]) => Promise<WorkspaceExecutionViewOutcome>;
|
|
46
55
|
onOpen?: () => void;
|
|
47
56
|
onDelete?: () => void | Promise<void>;
|
|
48
57
|
}
|
|
49
58
|
interface WorkspaceExecutionSource {
|
|
50
59
|
queryOptions: WorkspaceConceptQueryOptions<readonly WorkspaceExecution[]>;
|
|
51
|
-
/** Runs the module with the submitted values and returns its visible
|
|
52
|
-
onRun?: (path: string, parameters: readonly WorkspaceExecutionParam[]) => Promise<
|
|
60
|
+
/** Runs the module with the submitted values and returns its visible outcome. */
|
|
61
|
+
onRun?: (path: string, parameters: readonly WorkspaceExecutionParam[]) => Promise<WorkspaceExecutionOutcome>;
|
|
53
62
|
onOpen?: (path: string) => void;
|
|
54
63
|
onDelete?: (path: string) => void | Promise<void>;
|
|
55
64
|
}
|
|
56
65
|
interface WorkspaceExecutionCardProps extends Omit<CardProps, "children" | "hover" | "size" | "title"> {
|
|
57
|
-
module:
|
|
66
|
+
module: WorkspaceExecutionView;
|
|
58
67
|
}
|
|
59
68
|
interface WorkspaceExecutionFileProps extends Omit<WorkspaceExecutionCardProps, "module"> {
|
|
60
69
|
path: string;
|
|
@@ -62,15 +71,14 @@ interface WorkspaceExecutionFileProps extends Omit<WorkspaceExecutionCardProps,
|
|
|
62
71
|
fallback?: React.ReactNode;
|
|
63
72
|
}
|
|
64
73
|
interface WorkspaceExecutionsPanelProps extends Omit<React.HTMLAttributes<HTMLElement>, "children"> {
|
|
65
|
-
modules: readonly
|
|
74
|
+
modules: readonly WorkspaceExecutionView[];
|
|
75
|
+
loading?: boolean;
|
|
66
76
|
/** Query failure to show instead of the empty state. Loaded modules win. */
|
|
67
77
|
error?: string;
|
|
68
78
|
onRetry?: () => void;
|
|
69
79
|
}
|
|
70
80
|
declare function WorkspaceExecutionCard({
|
|
71
|
-
className,
|
|
72
81
|
module,
|
|
73
|
-
ref,
|
|
74
82
|
...props
|
|
75
83
|
}: WorkspaceExecutionCardProps & {
|
|
76
84
|
ref?: React.Ref<HTMLDivElement>;
|
|
@@ -93,6 +101,7 @@ declare function WorkspaceExecutionFile({
|
|
|
93
101
|
declare function WorkspaceExecutionsPanel({
|
|
94
102
|
className,
|
|
95
103
|
error,
|
|
104
|
+
loading,
|
|
96
105
|
modules,
|
|
97
106
|
onRetry,
|
|
98
107
|
ref,
|
|
@@ -103,4 +112,4 @@ declare function WorkspaceExecutionsPanel({
|
|
|
103
112
|
/** Canonical workbench descriptor; hosts supply only the source adapter. */
|
|
104
113
|
declare function workspaceExecutionsPanel(source: WorkspaceExecutionSource): ThinkFullAppPanel;
|
|
105
114
|
//#endregion
|
|
106
|
-
export { WorkspaceExecution, WorkspaceExecutionCard, WorkspaceExecutionCardProps, WorkspaceExecutionFile, WorkspaceExecutionFileProps, WorkspaceExecutionParam, WorkspaceExecutionParamType, WorkspaceExecutionRun, WorkspaceExecutionSource, WorkspaceExecutionsPanel, WorkspaceExecutionsPanelProps, workspaceExecutionsPanel };
|
|
115
|
+
export { WorkspaceExecution, WorkspaceExecutionCard, WorkspaceExecutionCardProps, WorkspaceExecutionFile, WorkspaceExecutionFileProps, WorkspaceExecutionOutcome, WorkspaceExecutionParam, WorkspaceExecutionParamType, WorkspaceExecutionRun, WorkspaceExecutionRunView, WorkspaceExecutionSource, WorkspaceExecutionView, WorkspaceExecutionViewOutcome, WorkspaceExecutionsPanel, WorkspaceExecutionsPanelProps, workspaceExecutionsPanel };
|
|
@@ -1,34 +1,33 @@
|
|
|
1
1
|
import { t as cx } from "../../class-names-BiMDVpUo.js";
|
|
2
|
-
import {
|
|
2
|
+
import { K as SpinnerIcon, S as FileIcon, Z as TerminalIcon, d as CheckIcon, z as PlayIcon } from "../../icons-CeGfXO21.js";
|
|
3
3
|
import { Button } from "../foundations/Button.js";
|
|
4
|
-
import { IconButton } from "../foundations/IconButton.js";
|
|
5
|
-
import { a as formatErrorMessage } from "../../format-COCyV98Z.js";
|
|
6
|
-
import { EmptyState } from "../foundations/EmptyState.js";
|
|
7
4
|
import { Field } from "../foundations/Field.js";
|
|
8
5
|
import { Form } from "../foundations/Form.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { Switch } from "../foundations/Switch.js";
|
|
6
|
+
import { IconButton } from "../foundations/IconButton.js";
|
|
7
|
+
import { a as formatErrorMessage, o as formatUnknownValue, r as firstLine } from "../../format-COCyV98Z.js";
|
|
12
8
|
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "../foundations/Card.js";
|
|
13
|
-
import {
|
|
9
|
+
import { DescriptionList } from "../foundations/DescriptionList.js";
|
|
10
|
+
import { Input } from "../foundations/Input.js";
|
|
11
|
+
import { Checkbox } from "../foundations/Checkbox.js";
|
|
12
|
+
import { EmptyState } from "../foundations/EmptyState.js";
|
|
13
|
+
import { i as WorkspaceDeleteControl, n as WorkspaceComposerLink, r as httpUrl, t as FaviconMark } from "../../workspace-assets-GqsCYxqT.js";
|
|
14
14
|
import * as React from "react";
|
|
15
|
+
import { createElement } from "react";
|
|
15
16
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
import { useQuery } from "@tanstack/react-query";
|
|
17
|
+
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
17
18
|
//#region src/components/agents-sdk/WorkspaceExecution.tsx
|
|
18
19
|
function draftFrom(parameters) {
|
|
19
|
-
return Object.fromEntries(parameters.
|
|
20
|
+
return Object.fromEntries(parameters.flatMap((parameter) => parameter.value === void 0 ? [] : [[parameter.name, parameter.type === "boolean" ? Boolean(parameter.value) : String(parameter.value)]]));
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* fields and non-numeric numbers refuse the run with a field-level message.
|
|
23
|
+
* Values for one run. Empty and untouched fields stay absent so module
|
|
24
|
+
* defaults work. Schema types improve the input but never gate execution.
|
|
25
25
|
*/
|
|
26
26
|
function collectRunParameters(parameters, draft) {
|
|
27
27
|
const collected = [];
|
|
28
|
-
const problems = [];
|
|
29
28
|
for (const parameter of parameters) {
|
|
30
29
|
if (parameter.type === "boolean") {
|
|
31
|
-
collected.push({
|
|
30
|
+
if (Object.hasOwn(draft, parameter.name)) collected.push({
|
|
32
31
|
...parameter,
|
|
33
32
|
value: Boolean(draft[parameter.name])
|
|
34
33
|
});
|
|
@@ -36,19 +35,12 @@ function collectRunParameters(parameters, draft) {
|
|
|
36
35
|
}
|
|
37
36
|
const raw = draft[parameter.name];
|
|
38
37
|
const text = (typeof raw === "string" ? raw : String(raw ?? "")).trim();
|
|
39
|
-
if (text === "")
|
|
40
|
-
if (parameter.required) problems.push(`${parameter.label} is required.`);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
38
|
+
if (text === "") continue;
|
|
43
39
|
if (parameter.type === "number") {
|
|
44
40
|
const numeric = Number(text);
|
|
45
|
-
if (!Number.isFinite(numeric)) {
|
|
46
|
-
problems.push(`${parameter.label} must be a number.`);
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
41
|
collected.push({
|
|
50
42
|
...parameter,
|
|
51
|
-
value: numeric
|
|
43
|
+
value: Number.isFinite(numeric) ? numeric : text
|
|
52
44
|
});
|
|
53
45
|
continue;
|
|
54
46
|
}
|
|
@@ -57,66 +49,15 @@ function collectRunParameters(parameters, draft) {
|
|
|
57
49
|
value: text
|
|
58
50
|
});
|
|
59
51
|
}
|
|
60
|
-
return
|
|
61
|
-
status: "invalid",
|
|
62
|
-
message: problems.join(" ")
|
|
63
|
-
} : {
|
|
64
|
-
status: "ok",
|
|
65
|
-
parameters: collected
|
|
66
|
-
};
|
|
52
|
+
return collected;
|
|
67
53
|
}
|
|
68
54
|
function snapshotValue(parameter) {
|
|
55
|
+
if (parameter.value === void 0) return "";
|
|
69
56
|
if (parameter.type === "boolean") return parameter.value ? "Yes" : "No";
|
|
70
|
-
return String(parameter.value
|
|
71
|
-
}
|
|
72
|
-
function siteHref(value) {
|
|
73
|
-
return httpUrl(value.includes("://") ? value : `https://${value}`);
|
|
74
|
-
}
|
|
75
|
-
function siteMarks(values) {
|
|
76
|
-
const marks = [];
|
|
77
|
-
for (const value of values) {
|
|
78
|
-
const trimmed = value.trim();
|
|
79
|
-
if (!trimmed) continue;
|
|
80
|
-
const href = siteHref(trimmed);
|
|
81
|
-
let site = trimmed;
|
|
82
|
-
if (href) try {
|
|
83
|
-
site = new URL(href).hostname.replace(/^www\./, "");
|
|
84
|
-
} catch {
|
|
85
|
-
site = trimmed;
|
|
86
|
-
}
|
|
87
|
-
if (!site || marks.some((mark) => mark.site === site)) continue;
|
|
88
|
-
marks.push({
|
|
89
|
-
site,
|
|
90
|
-
href,
|
|
91
|
-
hint: trimmed
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return marks;
|
|
57
|
+
return String(parameter.value);
|
|
95
58
|
}
|
|
96
59
|
function ExecutionIcon({ module }) {
|
|
97
|
-
|
|
98
|
-
const href = siteMarks(module.sites ?? []).find((mark) => mark.href)?.href;
|
|
99
|
-
return href ? /* @__PURE__ */ jsx(FaviconMark, {
|
|
100
|
-
href,
|
|
101
|
-
fallback: /* @__PURE__ */ jsx(TerminalIcon, {})
|
|
102
|
-
}) : /* @__PURE__ */ jsx(TerminalIcon, {});
|
|
103
|
-
}
|
|
104
|
-
function SiteDetails({ sites }) {
|
|
105
|
-
const marks = siteMarks(sites);
|
|
106
|
-
if (marks.length === 0) return null;
|
|
107
|
-
return /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: "Sites" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: /* @__PURE__ */ jsx("div", {
|
|
108
|
-
className: "sigvelo-cluster",
|
|
109
|
-
children: marks.map(({ href, hint, site }) => /* @__PURE__ */ jsx(WorkspaceComposerLink, {
|
|
110
|
-
kind: "tab",
|
|
111
|
-
value: site,
|
|
112
|
-
label: site,
|
|
113
|
-
hint: hint === site ? void 0 : hint,
|
|
114
|
-
icon: /* @__PURE__ */ jsx(FaviconMark, {
|
|
115
|
-
href,
|
|
116
|
-
fallback: /* @__PURE__ */ jsx(MonitorIcon, {})
|
|
117
|
-
})
|
|
118
|
-
}, site))
|
|
119
|
-
}) })] });
|
|
60
|
+
return module.icon ?? /* @__PURE__ */ jsx(TerminalIcon, {});
|
|
120
61
|
}
|
|
121
62
|
function RunLinks({ runs }) {
|
|
122
63
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -129,61 +70,63 @@ function RunLinks({ runs }) {
|
|
|
129
70
|
}, run.path))
|
|
130
71
|
});
|
|
131
72
|
}
|
|
132
|
-
function RunDetails({
|
|
133
|
-
const completed =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
73
|
+
function RunDetails({ outcome, runs }) {
|
|
74
|
+
const completed = outcome !== void 0;
|
|
75
|
+
const result = outcome?.result != null ? firstLine(formatUnknownValue(outcome.result)) : "";
|
|
76
|
+
const log = outcome ? firstLine(outcome.logs.join("\n")) : "";
|
|
77
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
78
|
+
completed ? /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: "Last run" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: /* @__PURE__ */ jsxs("div", {
|
|
79
|
+
className: "sigvelo-cluster",
|
|
80
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
81
|
+
className: "workspace-execution-outcome",
|
|
82
|
+
children: [/* @__PURE__ */ jsx(CheckIcon, { size: 14 }), "Completed"]
|
|
83
|
+
}), outcome.runs.length > 0 ? /* @__PURE__ */ jsx(RunLinks, { runs: outcome.runs }) : null]
|
|
84
|
+
}) })] }) : null,
|
|
85
|
+
result ? /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: "Result" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: result })] }) : null,
|
|
86
|
+
log ? /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: "Log" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: log })] }) : null,
|
|
87
|
+
runs.length > 0 ? /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsx(DescriptionList.Term, { children: completed ? "Earlier" : runs.length === 1 ? "Last" : "Runs" }), /* @__PURE__ */ jsx(DescriptionList.Details, { children: /* @__PURE__ */ jsx(RunLinks, { runs }) })] }) : null
|
|
88
|
+
] });
|
|
141
89
|
}
|
|
142
|
-
function ExecutionFields({ draft,
|
|
90
|
+
function ExecutionFields({ draft, outcome, parameters, runs, onDraftChange }) {
|
|
143
91
|
const fieldId = React.useId();
|
|
144
92
|
const editing = draft != null && onDraftChange != null;
|
|
145
|
-
const siteItems = siteMarks(sites ?? []);
|
|
146
93
|
const runItems = runs ?? [];
|
|
147
94
|
const visibleParameters = editing ? parameters : parameters.filter((parameter) => snapshotValue(parameter) !== "");
|
|
148
|
-
if (visibleParameters.length === 0 &&
|
|
95
|
+
if (visibleParameters.length === 0 && runItems.length === 0 && outcome === void 0) return null;
|
|
149
96
|
return /* @__PURE__ */ jsxs(DescriptionList.Root, {
|
|
150
97
|
align: "start",
|
|
151
98
|
variant: "divided",
|
|
152
|
-
children: [
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
runState,
|
|
184
|
-
runs: runItems
|
|
185
|
-
})
|
|
186
|
-
]
|
|
99
|
+
children: [visibleParameters.map((parameter) => {
|
|
100
|
+
const id = `${fieldId}-${parameter.name}`;
|
|
101
|
+
const parameterLabel = editing && parameter.required ? `${parameter.label} (required)` : parameter.label;
|
|
102
|
+
const href = parameter.type === "string" ? httpUrl(String(editing ? draft?.[parameter.name] ?? parameter.value : parameter.value)) : void 0;
|
|
103
|
+
return /* @__PURE__ */ jsxs(DescriptionList.Item, { children: [/* @__PURE__ */ jsxs(DescriptionList.Term, {
|
|
104
|
+
id: parameter.type === "boolean" ? id : void 0,
|
|
105
|
+
children: [href ? /* @__PURE__ */ jsx(FaviconMark, { href }) : null, editing && parameter.type !== "boolean" ? /* @__PURE__ */ jsx("label", {
|
|
106
|
+
htmlFor: id,
|
|
107
|
+
children: parameterLabel
|
|
108
|
+
}) : parameterLabel]
|
|
109
|
+
}), /* @__PURE__ */ jsx(DescriptionList.Details, { children: editing && parameter.type === "boolean" ? /* @__PURE__ */ jsx(Checkbox.Root, {
|
|
110
|
+
checked: draft?.[parameter.name] === true,
|
|
111
|
+
indeterminate: draft?.[parameter.name] === void 0,
|
|
112
|
+
"aria-labelledby": id,
|
|
113
|
+
onCheckedChange: (checked) => {
|
|
114
|
+
if (typeof checked === "boolean") onDraftChange?.(parameter.name, checked);
|
|
115
|
+
},
|
|
116
|
+
children: /* @__PURE__ */ jsx(Checkbox.Indicator, {})
|
|
117
|
+
}) : editing ? /* @__PURE__ */ jsx(Input, {
|
|
118
|
+
id,
|
|
119
|
+
name: parameter.name,
|
|
120
|
+
type: href ? "url" : void 0,
|
|
121
|
+
value: String(draft?.[parameter.name] ?? ""),
|
|
122
|
+
autoComplete: "off",
|
|
123
|
+
inputMode: parameter.type === "number" ? "decimal" : void 0,
|
|
124
|
+
onChange: (event) => onDraftChange?.(parameter.name, event.currentTarget.value)
|
|
125
|
+
}) : snapshotValue(parameter) })] }, parameter.name);
|
|
126
|
+
}), /* @__PURE__ */ jsx(RunDetails, {
|
|
127
|
+
outcome,
|
|
128
|
+
runs: runItems
|
|
129
|
+
})]
|
|
187
130
|
});
|
|
188
131
|
}
|
|
189
132
|
function ExecutionActions({ busy, module }) {
|
|
@@ -218,45 +161,32 @@ function ExecutionActions({ busy, module }) {
|
|
|
218
161
|
function executionFormKey(module) {
|
|
219
162
|
return `${module.path}:${JSON.stringify(module.parameters)}`;
|
|
220
163
|
}
|
|
221
|
-
function WorkspaceExecutionCard({
|
|
164
|
+
function WorkspaceExecutionCard({ module, ...props }) {
|
|
165
|
+
return /* @__PURE__ */ createElement(WorkspaceExecutionCardSession, {
|
|
166
|
+
...props,
|
|
167
|
+
key: module.path,
|
|
168
|
+
module
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function WorkspaceExecutionCardSession({ className, module, ref, ...props }) {
|
|
222
172
|
const titleId = React.useId();
|
|
223
173
|
const ariaLabel = props["aria-label"];
|
|
224
174
|
const ariaLabelledBy = props["aria-labelledby"] ?? (ariaLabel ? void 0 : titleId);
|
|
225
175
|
const editing = module.onRun != null;
|
|
226
176
|
const [draft, setDraft] = React.useState(() => draftFrom(module.parameters));
|
|
227
|
-
const [runState, setRunState] = React.useState({ status: "idle" });
|
|
228
|
-
const [validationMessage, setValidationMessage] = React.useState("");
|
|
229
177
|
const formKey = executionFormKey(module);
|
|
230
178
|
const [seenFormKey, setSeenFormKey] = React.useState(formKey);
|
|
231
179
|
if (formKey !== seenFormKey) {
|
|
232
180
|
setSeenFormKey(formKey);
|
|
233
181
|
setDraft(draftFrom(module.parameters));
|
|
234
|
-
setValidationMessage("");
|
|
235
182
|
}
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
setValidationMessage("");
|
|
245
|
-
setRunState({ status: "running" });
|
|
246
|
-
try {
|
|
247
|
-
setRunState({
|
|
248
|
-
status: "completed",
|
|
249
|
-
runs: await module.onRun(submission.parameters)
|
|
250
|
-
});
|
|
251
|
-
} catch (error) {
|
|
252
|
-
setRunState({
|
|
253
|
-
status: "failed",
|
|
254
|
-
message: formatErrorMessage(error)
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
const errorMessage = validationMessage || (runState.status === "failed" ? runState.message : "");
|
|
259
|
-
const hasBody = module.parameters.length > 0 || (module.sites?.length ?? 0) > 0 || (module.runs?.length ?? 0) > 0 || runState.status === "completed" || editing || Boolean(errorMessage);
|
|
183
|
+
const runMutation = useMutation({ mutationFn: async () => {
|
|
184
|
+
if (!module.onRun) throw new Error("Execution is no longer available.");
|
|
185
|
+
return module.onRun(collectRunParameters(module.parameters, draft));
|
|
186
|
+
} });
|
|
187
|
+
const busy = runMutation.isPending;
|
|
188
|
+
const errorMessage = runMutation.isError ? formatErrorMessage(runMutation.error) : "";
|
|
189
|
+
const hasBody = module.parameters.length > 0 || (module.runs?.length ?? 0) > 0 || runMutation.isSuccess || editing || Boolean(errorMessage);
|
|
260
190
|
const header = /* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
261
191
|
/* @__PURE__ */ jsxs(CardTitle, {
|
|
262
192
|
id: titleId,
|
|
@@ -277,30 +207,27 @@ function WorkspaceExecutionCard({ className, module, ref, ...props }) {
|
|
|
277
207
|
const body = hasBody ? /* @__PURE__ */ jsxs(CardContent, { children: [
|
|
278
208
|
/* @__PURE__ */ jsx(ExecutionFields, {
|
|
279
209
|
draft: editing ? draft : void 0,
|
|
210
|
+
outcome: runMutation.isSuccess ? runMutation.data : void 0,
|
|
280
211
|
parameters: module.parameters,
|
|
281
|
-
runState,
|
|
282
212
|
runs: module.runs,
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
...current,
|
|
288
|
-
[name]: value
|
|
289
|
-
}));
|
|
290
|
-
} : void 0
|
|
213
|
+
onDraftChange: editing ? (name, value) => setDraft((current) => ({
|
|
214
|
+
...current,
|
|
215
|
+
[name]: value
|
|
216
|
+
})) : void 0
|
|
291
217
|
}),
|
|
292
218
|
errorMessage ? /* @__PURE__ */ jsx(Field.Errors, { errors: [errorMessage] }) : null,
|
|
293
219
|
/* @__PURE__ */ jsx("span", {
|
|
294
220
|
className: "sigvelo-visually-hidden",
|
|
295
221
|
role: "status",
|
|
296
222
|
"aria-atomic": "true",
|
|
297
|
-
children: errorMessage || (busy ? "Running" :
|
|
223
|
+
children: errorMessage || (busy ? "Running" : runMutation.isSuccess ? "Completed" : "")
|
|
298
224
|
})
|
|
299
225
|
] }) : null;
|
|
300
226
|
const inner = editing ? /* @__PURE__ */ jsxs(Form, {
|
|
227
|
+
noValidate: true,
|
|
301
228
|
onSubmit: (event) => {
|
|
302
229
|
event.preventDefault();
|
|
303
|
-
|
|
230
|
+
if (!busy) runMutation.mutate();
|
|
304
231
|
},
|
|
305
232
|
children: [header, body]
|
|
306
233
|
}) : /* @__PURE__ */ jsxs(Fragment, { children: [header, body] });
|
|
@@ -330,7 +257,7 @@ function WorkspaceExecutionFile({ fallback = null, path, source, ...props }) {
|
|
|
330
257
|
* Workbench library. Same card as the inline placement. A query failure with
|
|
331
258
|
* nothing loaded renders as a quiet inline error, never as an empty library.
|
|
332
259
|
*/
|
|
333
|
-
function WorkspaceExecutionsPanel({ className, error, modules, onRetry, ref, ...props }) {
|
|
260
|
+
function WorkspaceExecutionsPanel({ className, error, loading = false, modules, onRetry, ref, ...props }) {
|
|
334
261
|
return /* @__PURE__ */ jsx("section", {
|
|
335
262
|
ref,
|
|
336
263
|
"data-slot": "workspace-executions-panel",
|
|
@@ -351,6 +278,9 @@ function WorkspaceExecutionsPanel({ className, error, modules, onRetry, ref, ...
|
|
|
351
278
|
onClick: onRetry,
|
|
352
279
|
children: "Retry"
|
|
353
280
|
}) : null
|
|
281
|
+
}) : loading ? /* @__PURE__ */ jsx(EmptyState, {
|
|
282
|
+
icon: /* @__PURE__ */ jsx(SpinnerIcon, {}),
|
|
283
|
+
title: "Loading modules"
|
|
354
284
|
}) : /* @__PURE__ */ jsx(EmptyState, {
|
|
355
285
|
icon: /* @__PURE__ */ jsx(TerminalIcon, {}),
|
|
356
286
|
title: "No modules"
|
|
@@ -366,7 +296,13 @@ function executionWithSource(module, source) {
|
|
|
366
296
|
return {
|
|
367
297
|
...module,
|
|
368
298
|
runs: module.runs?.map(withOpen),
|
|
369
|
-
onRun: onRun ? async (parameters) =>
|
|
299
|
+
onRun: onRun ? async (parameters) => {
|
|
300
|
+
const outcome = await onRun(module.path, parameters);
|
|
301
|
+
return {
|
|
302
|
+
...outcome,
|
|
303
|
+
runs: outcome.runs.map(withOpen)
|
|
304
|
+
};
|
|
305
|
+
} : void 0,
|
|
370
306
|
onOpen: onOpen ? () => onOpen(module.path) : void 0,
|
|
371
307
|
onDelete: onDelete ? () => onDelete(module.path) : void 0
|
|
372
308
|
};
|
|
@@ -376,6 +312,7 @@ function WorkspaceExecutionSourcePanel({ source }) {
|
|
|
376
312
|
return /* @__PURE__ */ jsx(WorkspaceExecutionsPanel, {
|
|
377
313
|
modules: (query.data ?? []).map((module) => executionWithSource(module, source)),
|
|
378
314
|
error: query.isError ? formatErrorMessage(query.error) : void 0,
|
|
315
|
+
loading: query.isPending,
|
|
379
316
|
onRetry: query.isError ? () => void query.refetch() : void 0,
|
|
380
317
|
"aria-busy": query.isFetching || void 0
|
|
381
318
|
});
|