@agent-native/dispatch 0.40.17 → 0.40.18-nightly-20261008065100
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/CHANGELOG.md +31 -0
- package/dist/actions/provider-api-register.d.ts +13 -13
- package/dist/components/automation-details-panel.d.ts.map +1 -1
- package/dist/components/automation-details-panel.js +8 -2
- package/dist/components/automation-details-panel.js.map +1 -1
- package/dist/lib/automation-display.d.ts.map +1 -1
- package/dist/lib/automation-display.js +3 -7
- package/dist/lib/automation-display.js.map +1 -1
- package/dist/routes/pages/automations.d.ts.map +1 -1
- package/dist/routes/pages/automations.js +4 -3
- package/dist/routes/pages/automations.js.map +1 -1
- package/package.json +4 -4
- package/src/components/automation-details-panel.tsx +25 -5
- package/src/lib/automation-display.spec.ts +26 -3
- package/src/lib/automation-display.ts +3 -9
- package/src/routes/pages/automations.tsx +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @agent-native/dispatch
|
|
2
2
|
|
|
3
|
+
## 0.40.18-nightly-20261008065100
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1b1d976: Distinguish confirmed automation work, explicitly declared no-op skips, and undelivered failures in run history and automation status. Preserve failure causes and recovery codes without pausing legitimate no-op runs.
|
|
8
|
+
- Updated dependencies [b7e32e4]
|
|
9
|
+
- Updated dependencies [b7e32e4]
|
|
10
|
+
- Updated dependencies [ab41d2b]
|
|
11
|
+
- Updated dependencies [a881977]
|
|
12
|
+
- Updated dependencies [e16da0c]
|
|
13
|
+
- Updated dependencies [947f911]
|
|
14
|
+
- Updated dependencies [b7e32e4]
|
|
15
|
+
- Updated dependencies [e453592]
|
|
16
|
+
- Updated dependencies [ae5aed6]
|
|
17
|
+
- Updated dependencies [1b1d976]
|
|
18
|
+
- Updated dependencies [76d00e9]
|
|
19
|
+
- Updated dependencies [ae5aed6]
|
|
20
|
+
- Updated dependencies [f325447]
|
|
21
|
+
- Updated dependencies [e453592]
|
|
22
|
+
- Updated dependencies [ae5aed6]
|
|
23
|
+
- Updated dependencies [8418b84]
|
|
24
|
+
- Updated dependencies [e453592]
|
|
25
|
+
- Updated dependencies [ae5aed6]
|
|
26
|
+
- Updated dependencies [b7e32e4]
|
|
27
|
+
- Updated dependencies [004f2a9]
|
|
28
|
+
- Updated dependencies [701c672]
|
|
29
|
+
- Updated dependencies [ae5aed6]
|
|
30
|
+
- Updated dependencies [ae5aed6]
|
|
31
|
+
- @agent-native/core@0.204.1-nightly-20261008065100
|
|
32
|
+
- @agent-native/toolkit@0.204.1-nightly-20261008065100
|
|
33
|
+
|
|
3
34
|
## 0.40.17
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
|
@@ -47,9 +47,8 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
47
47
|
notes?: string | undefined;
|
|
48
48
|
scope?: "org" | "user" | undefined;
|
|
49
49
|
}, {
|
|
50
|
-
|
|
50
|
+
id?: undefined;
|
|
51
51
|
message?: undefined;
|
|
52
|
-
found?: undefined;
|
|
53
52
|
providers: {
|
|
54
53
|
id: string;
|
|
55
54
|
label: string;
|
|
@@ -61,45 +60,46 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
61
60
|
}[];
|
|
62
61
|
count: number;
|
|
63
62
|
provider?: undefined;
|
|
63
|
+
found?: undefined;
|
|
64
|
+
deleted?: undefined;
|
|
64
65
|
registered?: undefined;
|
|
65
|
-
id?: undefined;
|
|
66
66
|
label?: undefined;
|
|
67
67
|
} | {
|
|
68
|
-
|
|
68
|
+
id?: undefined;
|
|
69
|
+
count?: undefined;
|
|
69
70
|
message?: undefined;
|
|
70
71
|
providers?: undefined;
|
|
71
|
-
count?: undefined;
|
|
72
72
|
found: boolean;
|
|
73
73
|
provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
|
|
74
|
+
deleted?: undefined;
|
|
74
75
|
registered?: undefined;
|
|
75
|
-
id?: undefined;
|
|
76
76
|
label?: undefined;
|
|
77
77
|
} | {
|
|
78
|
-
|
|
78
|
+
count?: undefined;
|
|
79
79
|
message?: undefined;
|
|
80
80
|
providers?: undefined;
|
|
81
|
-
count?: undefined;
|
|
82
81
|
provider?: undefined;
|
|
83
82
|
found: boolean;
|
|
84
83
|
id: string;
|
|
84
|
+
deleted?: undefined;
|
|
85
85
|
registered?: undefined;
|
|
86
86
|
label?: undefined;
|
|
87
87
|
} | {
|
|
88
|
+
count?: undefined;
|
|
88
89
|
message?: undefined;
|
|
89
|
-
found?: undefined;
|
|
90
90
|
providers?: undefined;
|
|
91
|
-
count?: undefined;
|
|
92
91
|
provider?: undefined;
|
|
92
|
+
found?: undefined;
|
|
93
93
|
deleted: boolean;
|
|
94
94
|
id: string;
|
|
95
95
|
registered?: undefined;
|
|
96
96
|
label?: undefined;
|
|
97
97
|
} | {
|
|
98
|
-
deleted?: undefined;
|
|
99
|
-
found?: undefined;
|
|
100
|
-
providers?: undefined;
|
|
101
98
|
count?: undefined;
|
|
99
|
+
providers?: undefined;
|
|
102
100
|
provider?: undefined;
|
|
101
|
+
found?: undefined;
|
|
102
|
+
deleted?: undefined;
|
|
103
103
|
registered: boolean;
|
|
104
104
|
id: string;
|
|
105
105
|
label: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-details-panel.d.ts","sourceRoot":"","sources":["../../src/components/automation-details-panel.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAgB5B,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,sBAAsB,CAAC;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAkED,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,UAAkB,EAClB,QAAQ,GACT,EAAE,2BAA2B,
|
|
1
|
+
{"version":3,"file":"automation-details-panel.d.ts","sourceRoot":"","sources":["../../src/components/automation-details-panel.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAgB5B,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,sBAAsB,CAAC;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAkED,wBAAgB,sBAAsB,CAAC,EACrC,UAAU,EACV,UAAkB,EAClB,QAAQ,GACT,EAAE,2BAA2B,mDAyY7B"}
|
|
@@ -102,10 +102,16 @@ export function AutomationDetailsPanel({ automation, isToggling = false, onToggl
|
|
|
102
102
|
defaultValue: "Paste this URL into a service that sends HTTP POST webhooks.",
|
|
103
103
|
}) })] })) : null, _jsx(DetailField, { label: "Condition", value: automation.condition || "Always" }), _jsx(DetailField, { label: "Domain", value: automation.domain || "Default" }), _jsx(DetailField, { label: "Model", value: automation.model || "Default model" }), _jsx(DetailField, { label: "Mode", value: automation.mode || "Agentic" }), _jsx(DetailField, { label: "Runs as", value: runAsLabel(automation.runAs) }), isScheduled ? (_jsx(DetailField, { label: "Next run", value: automation.enabled
|
|
104
104
|
? formatTimestamp(automation.nextRun)
|
|
105
|
-
: "Paused" })) : null, _jsx(DetailField, { label: "Last run", value: formatTimestamp(automation.lastRun) }), _jsx(DetailField, { label: "Last checked", value: formatTimestamp(automation.lastCheck) }), _jsx(DetailField, { label: "Created by", value: automation.createdBy || "Unknown" })] })] }), _jsxs("section", { className: "border-t pt-5", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Capabilities" }), automation.mcpTools && automation.mcpTools.length > 0 ? (_jsx("div", { className: "mt-2 flex flex-wrap gap-1.5", children: automation.mcpTools.map((toolName) => (_jsx("code", { className: "max-w-full break-all rounded bg-muted px-1.5 py-1 text-[11px] text-muted-foreground", children: toolName }, toolName))) })) : (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "No explicit tool allowlist." }))] }), hasExecutionTarget ? (_jsxs("section", { className: "border-t pt-5", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Execution target" }), _jsxs("dl", { className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-4", children: [_jsx(DetailField, { label: "Host", value: automation.executionHostId || "Server default", mono: Boolean(automation.executionHostId) }), _jsx(DetailField, { label: "Engine", value: automation.executionEngine || "Default" }), automation.executionCwd ? (_jsx(DetailField, { label: "Working directory", value: automation.executionCwd, mono: true })) : null] })] })) : null, hasDelivery ? (_jsxs("section", { className: "border-t pt-5", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Delivery" }), _jsxs("dl", { className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-4", children: [automation.deliveryPlatform ? (_jsx(DetailField, { label: "Platform", value: automation.deliveryPlatform })) : null, automation.deliveryDestination ? (_jsx(DetailField, { label: "Destination", value: automation.deliveryDestination })) : null, automation.deliveryThreadRef ? (_jsx(DetailField, { label: "Thread reference", value: automation.deliveryThreadRef, mono: true })) : null] })] })) : null, automation.lastError ? (_jsxs("section", { className:
|
|
105
|
+
: "Paused" })) : null, _jsx(DetailField, { label: "Last run", value: formatTimestamp(automation.lastRun) }), _jsx(DetailField, { label: "Last checked", value: formatTimestamp(automation.lastCheck) }), _jsx(DetailField, { label: "Created by", value: automation.createdBy || "Unknown" })] })] }), _jsxs("section", { className: "border-t pt-5", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Capabilities" }), automation.mcpTools && automation.mcpTools.length > 0 ? (_jsx("div", { className: "mt-2 flex flex-wrap gap-1.5", children: automation.mcpTools.map((toolName) => (_jsx("code", { className: "max-w-full break-all rounded bg-muted px-1.5 py-1 text-[11px] text-muted-foreground", children: toolName }, toolName))) })) : (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "No explicit tool allowlist." }))] }), hasExecutionTarget ? (_jsxs("section", { className: "border-t pt-5", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Execution target" }), _jsxs("dl", { className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-4", children: [_jsx(DetailField, { label: "Host", value: automation.executionHostId || "Server default", mono: Boolean(automation.executionHostId) }), _jsx(DetailField, { label: "Engine", value: automation.executionEngine || "Default" }), automation.executionCwd ? (_jsx(DetailField, { label: "Working directory", value: automation.executionCwd, mono: true })) : null] })] })) : null, hasDelivery ? (_jsxs("section", { className: "border-t pt-5", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Delivery" }), _jsxs("dl", { className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-4", children: [automation.deliveryPlatform ? (_jsx(DetailField, { label: "Platform", value: automation.deliveryPlatform })) : null, automation.deliveryDestination ? (_jsx(DetailField, { label: "Destination", value: automation.deliveryDestination })) : null, automation.deliveryThreadRef ? (_jsx(DetailField, { label: "Thread reference", value: automation.deliveryThreadRef, mono: true })) : null] })] })) : null, automation.lastError ? (_jsxs("section", { className: automation.lastStatus === "skipped"
|
|
106
|
+
? "flex items-start gap-2 border-t pt-5"
|
|
107
|
+
: "flex items-start gap-2 border-t border-destructive/30 pt-5", children: [automation.lastStatus !== "skipped" ? (_jsx(IconAlertTriangle, { className: "mt-0.5 size-4 shrink-0 text-destructive" })) : null, _jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: automation.lastStatus === "skipped"
|
|
108
|
+
? "text-sm font-semibold text-muted-foreground"
|
|
109
|
+
: "text-sm font-semibold text-destructive", children: "Latest scheduler result" }), _jsx("p", { className: "mt-1 break-words text-sm text-muted-foreground", children: automation.lastError })] })] })) : null, _jsxs("section", { className: "border-t pt-5", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Past runs" }), runs.length > 0 ? (_jsxs(Badge, { variant: "outline", children: [runs.length, " shown"] })) : null] }), _jsx("div", { className: "mt-3", children: runsQuery.isLoading ? (_jsx("div", { className: "space-y-3 rounded-md border p-3", children: Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-2/3" }), _jsx(Skeleton, { className: "h-3 w-1/2" })] }, index))) })) : runsQuery.isError ? (_jsx(ActionQueryError, { error: runsQuery.error, onRetry: () => void runsQuery.refetch() })) : runs.length === 0 ? (_jsx("p", { className: "rounded-md border border-dashed p-3 text-sm text-muted-foreground", children: "No execution recorded yet." })) : (_jsx("ul", { className: "divide-y rounded-md border", children: runs.map((run) => {
|
|
106
110
|
const debugPath = runDebugPath(run);
|
|
107
111
|
const duration = formatDuration(run);
|
|
108
|
-
return (_jsxs("li", { className: "space-y-2 p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 text-sm", children: [_jsx(Badge, { variant: runStatusVariant(run.status), children: run.status }), _jsx("span", { className: "text-muted-foreground", children: formatTimestamp(run.startedAt) }), duration ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconClock, { className: "size-3.5" }), duration] })) : null, debugPath ? (_jsxs(Link, { to: debugPath, className: "ml-auto inline-flex items-center gap-1 text-xs font-medium text-foreground underline-offset-4 hover:underline", children: [_jsx(IconExternalLink, { className: "size-3.5" }), "Open debug"] })) : null] }), run.error ? (_jsx("p", { className:
|
|
112
|
+
return (_jsxs("li", { className: "space-y-2 p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 text-sm", children: [_jsx(Badge, { variant: runStatusVariant(run.status), children: run.status }), _jsx("span", { className: "text-muted-foreground", children: formatTimestamp(run.startedAt) }), duration ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconClock, { className: "size-3.5" }), duration] })) : null, debugPath ? (_jsxs(Link, { to: debugPath, className: "ml-auto inline-flex items-center gap-1 text-xs font-medium text-foreground underline-offset-4 hover:underline", children: [_jsx(IconExternalLink, { className: "size-3.5" }), "Open debug"] })) : null] }), run.error ? (_jsx("p", { className: run.status === "skipped"
|
|
113
|
+
? "break-words text-sm text-muted-foreground"
|
|
114
|
+
: "break-words text-sm text-destructive", children: run.error })) : null] }, run.id));
|
|
109
115
|
}) })) })] })] }), _jsxs("footer", { className: "flex flex-wrap items-center gap-2 border-t p-4", children: [_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: onToggle, disabled: automation.canUpdate === false || isToggling, children: [automation.enabled ? _jsx(IconPlayerPause, {}) : _jsx(IconPlayerPlay, {}), automation.enabled ? "Pause" : "Resume"] }), automation.canUpdate === false ? (_jsx("span", { className: "text-xs text-muted-foreground", children: "Read-only" })) : null] })] }));
|
|
110
116
|
}
|
|
111
117
|
//# sourceMappingURL=automation-details-panel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-details-panel.js","sourceRoot":"","sources":["../../src/components/automation-details-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { appPath } from \"@agent-native/core/client/api-path\";\nimport { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { writeClipboardText } from \"@agent-native/toolkit/clipboard\";\nimport {\n IconAlertTriangle,\n IconCheck,\n IconCopy,\n IconClock,\n IconExternalLink,\n IconPlayerPause,\n IconPlayerPlay,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport {\n automationScopeLabel,\n automationStatus,\n automationTarget,\n} from \"../lib/automation-display\";\nimport {\n automationRunScope,\n type DispatchAutomationItem,\n} from \"../lib/automations\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\n\ninterface AutomationRun {\n id: string;\n runId: string | null;\n threadId: string | null;\n status: \"running\" | \"success\" | \"error\" | \"interrupted\";\n startedAt: number;\n finishedAt: number | null;\n error: string | null;\n}\n\nexport interface AutomationDetailsPanelProps {\n automation: DispatchAutomationItem;\n isToggling?: boolean;\n onToggle: () => void;\n}\n\nfunction formatTimestamp(value: number | string | null | undefined): string {\n if (value == null) return \"Not recorded\";\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? \"Unknown time\" : date.toLocaleString();\n}\n\nfunction formatDuration(run: AutomationRun): string | null {\n if (!run.finishedAt) return null;\n const seconds = Math.max(\n 0,\n Math.round((run.finishedAt - run.startedAt) / 1000),\n );\n return `${seconds}s`;\n}\n\nfunction runDebugPath(run: AutomationRun): string | null {\n const params = new URLSearchParams();\n if (run.runId) params.set(\"runId\", run.runId);\n else if (run.threadId) params.set(\"threadId\", run.threadId);\n else return null;\n return `/admin/thread-debug?${params.toString()}`;\n}\n\nfunction runStatusVariant(\n status: AutomationRun[\"status\"],\n): \"default\" | \"destructive\" | \"outline\" {\n if (status === \"error\") return \"destructive\";\n if (status === \"success\") return \"default\";\n return \"outline\";\n}\n\nfunction DetailField({\n label,\n value,\n mono = false,\n}: {\n label: string;\n value: string;\n mono?: boolean;\n}) {\n return (\n <div className=\"min-w-0\">\n <dt className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">\n {label}\n </dt>\n <dd\n className={\n mono\n ? \"mt-1 break-words font-mono text-xs text-foreground\"\n : \"mt-1 break-words text-sm text-foreground\"\n }\n >\n {value}\n </dd>\n </div>\n );\n}\n\nfunction runAsLabel(value: DispatchAutomationItem[\"runAs\"]): string {\n if (value === \"creator\") return \"Creator identity\";\n if (value === \"shared\") return \"Shared identity\";\n return \"Default identity\";\n}\n\nexport function AutomationDetailsPanel({\n automation,\n isToggling = false,\n onToggle,\n}: AutomationDetailsPanelProps) {\n const t = useT();\n const runsQuery = useActionQuery<AutomationRun[]>(\n \"list-automation-runs\",\n {\n name: automation.name,\n scope: automationRunScope(automation),\n appId: automation.appId ?? \"dispatch\",\n },\n { staleTime: 5_000 },\n );\n const runs = runsQuery.data ?? [];\n const status = automationStatus(automation);\n const isScheduled = automation.triggerType === \"schedule\";\n const [copied, setCopied] = useState(false);\n const webhookUrl =\n automation.webhookPath && typeof window !== \"undefined\"\n ? window.location.origin + appPath(automation.webhookPath)\n : null;\n const triggerLabel =\n automation.triggerType === \"webhook\"\n ? t(\"jobs.webhook\", { defaultValue: \"Webhook\" })\n : isScheduled\n ? \"Schedule\"\n : \"Event\";\n const prompt = automation.body?.trim();\n const hasExecutionTarget = Boolean(\n automation.executionHostId ||\n automation.executionEngine ||\n automation.executionCwd,\n );\n const hasDelivery = Boolean(\n automation.deliveryPlatform ||\n automation.deliveryDestination ||\n automation.deliveryThreadRef,\n );\n\n return (\n <aside className=\"flex min-h-[34rem] min-w-0 flex-col overflow-hidden rounded-lg border bg-card\">\n <header className=\"flex items-start justify-between gap-3 border-b p-5\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span\n className={\n status.tone === \"danger\"\n ? \"size-2 shrink-0 rounded-full bg-destructive\"\n : status.tone === \"default\"\n ? \"size-2 shrink-0 rounded-full bg-primary\"\n : \"size-2 shrink-0 rounded-full bg-muted-foreground/40\"\n }\n />\n <Badge\n variant={status.tone === \"danger\" ? \"destructive\" : \"outline\"}\n className=\"h-5\"\n >\n {status.label}\n </Badge>\n </div>\n <h2 className=\"mt-2 break-words text-base font-semibold text-foreground\">\n {automation.name}\n </h2>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {triggerLabel} · {automationScopeLabel(automation)}\n </p>\n </div>\n </header>\n\n <div className=\"min-h-0 flex-1 space-y-5 overflow-y-auto p-5\">\n <section>\n <h3 className=\"text-sm font-semibold text-foreground\">Prompt</h3>\n {prompt ? (\n <pre className=\"mt-2 max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/40 p-3 font-sans text-sm leading-6 text-foreground\">\n {prompt}\n </pre>\n ) : (\n <p className=\"mt-2 rounded-md border border-dashed p-3 text-sm text-muted-foreground\">\n No prompt recorded.\n </p>\n )}\n </section>\n\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Configuration\n </h3>\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-4\">\n <DetailField\n label=\"Trigger\"\n value={\n automation.triggerType === \"webhook\"\n ? t(\"jobs.webhookTrigger\", {\n defaultValue: \"Webhook-triggered\",\n })\n : isScheduled\n ? \"Scheduled\"\n : \"Event-triggered\"\n }\n />\n <DetailField\n label={isScheduled ? \"Schedule\" : \"Event\"}\n value={automationTarget(automation)}\n />\n {isScheduled ? (\n <>\n {automation.schedule ? (\n <DetailField\n label=\"Cron expression\"\n value={automation.schedule}\n mono\n />\n ) : null}\n <DetailField\n label=\"Timezone\"\n value={automation.timezone || \"Account default\"}\n />\n </>\n ) : null}\n {webhookUrl ? (\n <div className=\"col-span-2 rounded-md border border-primary/20 bg-primary/5 p-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.webhookUrl\", { defaultValue: \"Webhook URL\" })}\n </span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 shrink-0 gap-1.5 text-xs\"\n onClick={() => {\n void writeClipboardText(webhookUrl).then((didCopy) => {\n setCopied(didCopy);\n if (didCopy) {\n window.setTimeout(() => setCopied(false), 1800);\n }\n });\n }}\n >\n {copied ? (\n <IconCheck className=\"size-3.5\" />\n ) : (\n <IconCopy className=\"size-3.5\" />\n )}\n {copied\n ? t(\"common.copied\", { defaultValue: \"Copied\" })\n : t(\"common.copy\", { defaultValue: \"Copy URL\" })}\n </Button>\n </div>\n <code className=\"mt-2 block break-all text-[11px] leading-5 text-muted-foreground\">\n {webhookUrl}\n </code>\n <p className=\"mt-2 text-xs text-muted-foreground\">\n {t(\"jobs.webhookUrlHint\", {\n defaultValue:\n \"Paste this URL into a service that sends HTTP POST webhooks.\",\n })}\n </p>\n </div>\n ) : null}\n <DetailField\n label=\"Condition\"\n value={automation.condition || \"Always\"}\n />\n <DetailField\n label=\"Domain\"\n value={automation.domain || \"Default\"}\n />\n <DetailField\n label=\"Model\"\n value={automation.model || \"Default model\"}\n />\n <DetailField label=\"Mode\" value={automation.mode || \"Agentic\"} />\n <DetailField label=\"Runs as\" value={runAsLabel(automation.runAs)} />\n {isScheduled ? (\n <DetailField\n label=\"Next run\"\n value={\n automation.enabled\n ? formatTimestamp(automation.nextRun)\n : \"Paused\"\n }\n />\n ) : null}\n <DetailField\n label=\"Last run\"\n value={formatTimestamp(automation.lastRun)}\n />\n <DetailField\n label=\"Last checked\"\n value={formatTimestamp(automation.lastCheck)}\n />\n <DetailField\n label=\"Created by\"\n value={automation.createdBy || \"Unknown\"}\n />\n </dl>\n </section>\n\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Capabilities\n </h3>\n {automation.mcpTools && automation.mcpTools.length > 0 ? (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {automation.mcpTools.map((toolName) => (\n <code\n key={toolName}\n className=\"max-w-full break-all rounded bg-muted px-1.5 py-1 text-[11px] text-muted-foreground\"\n >\n {toolName}\n </code>\n ))}\n </div>\n ) : (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n No explicit tool allowlist.\n </p>\n )}\n </section>\n\n {hasExecutionTarget ? (\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Execution target\n </h3>\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-4\">\n <DetailField\n label=\"Host\"\n value={automation.executionHostId || \"Server default\"}\n mono={Boolean(automation.executionHostId)}\n />\n <DetailField\n label=\"Engine\"\n value={automation.executionEngine || \"Default\"}\n />\n {automation.executionCwd ? (\n <DetailField\n label=\"Working directory\"\n value={automation.executionCwd}\n mono\n />\n ) : null}\n </dl>\n </section>\n ) : null}\n\n {hasDelivery ? (\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">Delivery</h3>\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-4\">\n {automation.deliveryPlatform ? (\n <DetailField\n label=\"Platform\"\n value={automation.deliveryPlatform}\n />\n ) : null}\n {automation.deliveryDestination ? (\n <DetailField\n label=\"Destination\"\n value={automation.deliveryDestination}\n />\n ) : null}\n {automation.deliveryThreadRef ? (\n <DetailField\n label=\"Thread reference\"\n value={automation.deliveryThreadRef}\n mono\n />\n ) : null}\n </dl>\n </section>\n ) : null}\n\n {automation.lastError ? (\n <section className=\"flex items-start gap-2 border-t border-destructive/30 pt-5\">\n <IconAlertTriangle className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n <div className=\"min-w-0\">\n <h3 className=\"text-sm font-semibold text-destructive\">\n Latest scheduler result\n </h3>\n <p className=\"mt-1 break-words text-sm text-muted-foreground\">\n {automation.lastError}\n </p>\n </div>\n </section>\n ) : null}\n\n <section className=\"border-t pt-5\">\n <div className=\"flex items-center justify-between gap-3\">\n <h3 className=\"text-sm font-semibold text-foreground\">Past runs</h3>\n {runs.length > 0 ? (\n <Badge variant=\"outline\">{runs.length} shown</Badge>\n ) : null}\n </div>\n <div className=\"mt-3\">\n {runsQuery.isLoading ? (\n <div className=\"space-y-3 rounded-md border p-3\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"space-y-2\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n ))}\n </div>\n ) : runsQuery.isError ? (\n <ActionQueryError\n error={runsQuery.error}\n onRetry={() => void runsQuery.refetch()}\n />\n ) : runs.length === 0 ? (\n <p className=\"rounded-md border border-dashed p-3 text-sm text-muted-foreground\">\n No execution recorded yet.\n </p>\n ) : (\n <ul className=\"divide-y rounded-md border\">\n {runs.map((run) => {\n const debugPath = runDebugPath(run);\n const duration = formatDuration(run);\n return (\n <li key={run.id} className=\"space-y-2 p-3\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <Badge variant={runStatusVariant(run.status)}>\n {run.status}\n </Badge>\n <span className=\"text-muted-foreground\">\n {formatTimestamp(run.startedAt)}\n </span>\n {duration ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n <IconClock className=\"size-3.5\" />\n {duration}\n </span>\n ) : null}\n {debugPath ? (\n <Link\n to={debugPath}\n className=\"ml-auto inline-flex items-center gap-1 text-xs font-medium text-foreground underline-offset-4 hover:underline\"\n >\n <IconExternalLink className=\"size-3.5\" />\n Open debug\n </Link>\n ) : null}\n </div>\n {run.error ? (\n <p className=\"break-words text-sm text-destructive\">\n {run.error}\n </p>\n ) : null}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </section>\n </div>\n\n <footer className=\"flex flex-wrap items-center gap-2 border-t p-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onToggle}\n disabled={automation.canUpdate === false || isToggling}\n >\n {automation.enabled ? <IconPlayerPause /> : <IconPlayerPlay />}\n {automation.enabled ? \"Pause\" : \"Resume\"}\n </Button>\n {automation.canUpdate === false ? (\n <span className=\"text-xs text-muted-foreground\">Read-only</span>\n ) : null}\n </footer>\n </aside>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"automation-details-panel.js","sourceRoot":"","sources":["../../src/components/automation-details-panel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAkBzC,SAAS,eAAe,CAAC,KAAyC;IAChE,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,cAAc,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;AAC/E,CAAC;AAED,SAAS,cAAc,CAAC,GAAkB;IACxC,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,CAAC,EACD,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CACpD,CAAC;IACF,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC;AAED,SAAS,YAAY,CAAC,GAAkB;IACtC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,IAAI,GAAG,CAAC,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;SACzC,IAAI,GAAG,CAAC,QAAQ;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;;QACvD,OAAO,IAAI,CAAC;IACjB,OAAO,uBAAuB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,gBAAgB,CACvB,MAA+B;IAE/B,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,aAAa,CAAC;IAC7C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,KAAK,EACL,KAAK,EACL,IAAI,GAAG,KAAK,GAKb;IACC,OAAO,CACL,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,2DAA2D,YACtE,KAAK,GACH,EACL,aACE,SAAS,EACP,IAAI;oBACF,CAAC,CAAC,oDAAoD;oBACtD,CAAC,CAAC,0CAA0C,YAG/C,KAAK,GACH,IACD,CACP,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAsC;IACxD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,kBAAkB,CAAC;IACnD,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,iBAAiB,CAAC;IACjD,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,EACrC,UAAU,EACV,UAAU,GAAG,KAAK,EAClB,QAAQ,GACoB;IAC5B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,SAAS,GAAG,cAAc,CAC9B,sBAAsB,EACtB;QACE,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,KAAK,EAAE,kBAAkB,CAAC,UAAU,CAAC;QACrC,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,UAAU;KACtC,EACD,EAAE,SAAS,EAAE,KAAK,EAAE,CACrB,CAAC;IACF,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,KAAK,UAAU,CAAC;IAC1D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,UAAU,GACd,UAAU,CAAC,WAAW,IAAI,OAAO,MAAM,KAAK,WAAW;QACrD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;QAC1D,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,YAAY,GAChB,UAAU,CAAC,WAAW,KAAK,SAAS;QAClC,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;QAChD,CAAC,CAAC,WAAW;YACX,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,OAAO,CAAC;IAChB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IACvC,MAAM,kBAAkB,GAAG,OAAO,CAChC,UAAU,CAAC,eAAe;QAC1B,UAAU,CAAC,eAAe;QAC1B,UAAU,CAAC,YAAY,CACxB,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CACzB,UAAU,CAAC,gBAAgB;QAC3B,UAAU,CAAC,mBAAmB;QAC9B,UAAU,CAAC,iBAAiB,CAC7B,CAAC;IAEF,OAAO,CACL,iBAAO,SAAS,EAAC,+EAA+E,aAC9F,iBAAQ,SAAS,EAAC,qDAAqD,YACrE,eAAK,SAAS,EAAC,SAAS,aACtB,eAAK,SAAS,EAAC,yBAAyB,aACtC,eACE,SAAS,EACP,MAAM,CAAC,IAAI,KAAK,QAAQ;wCACtB,CAAC,CAAC,6CAA6C;wCAC/C,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS;4CACzB,CAAC,CAAC,yCAAyC;4CAC3C,CAAC,CAAC,qDAAqD,GAE7D,EACF,KAAC,KAAK,IACJ,OAAO,EAAE,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAC7D,SAAS,EAAC,KAAK,YAEd,MAAM,CAAC,KAAK,GACP,IACJ,EACN,aAAI,SAAS,EAAC,0DAA0D,YACrE,UAAU,CAAC,IAAI,GACb,EACL,aAAG,SAAS,EAAC,oCAAoC,aAC9C,YAAY,cAAK,oBAAoB,CAAC,UAAU,CAAC,IAChD,IACA,GACC,EAET,eAAK,SAAS,EAAC,8CAA8C,aAC3D,8BACE,aAAI,SAAS,EAAC,uCAAuC,uBAAY,EAChE,MAAM,CAAC,CAAC,CAAC,CACR,cAAK,SAAS,EAAC,oIAAoI,YAChJ,MAAM,GACH,CACP,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAC,wEAAwE,oCAEjF,CACL,IACO,EAEV,mBAAS,SAAS,EAAC,eAAe,aAChC,aAAI,SAAS,EAAC,uCAAuC,8BAEhD,EACL,cAAI,SAAS,EAAC,uCAAuC,aACnD,KAAC,WAAW,IACV,KAAK,EAAC,SAAS,EACf,KAAK,EACH,UAAU,CAAC,WAAW,KAAK,SAAS;4CAClC,CAAC,CAAC,CAAC,CAAC,qBAAqB,EAAE;gDACvB,YAAY,EAAE,mBAAmB;6CAClC,CAAC;4CACJ,CAAC,CAAC,WAAW;gDACX,CAAC,CAAC,WAAW;gDACb,CAAC,CAAC,iBAAiB,GAEzB,EACF,KAAC,WAAW,IACV,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EACzC,KAAK,EAAE,gBAAgB,CAAC,UAAU,CAAC,GACnC,EACD,WAAW,CAAC,CAAC,CAAC,CACb,8BACG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CACrB,KAAC,WAAW,IACV,KAAK,EAAC,iBAAiB,EACvB,KAAK,EAAE,UAAU,CAAC,QAAQ,EAC1B,IAAI,SACJ,CACH,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,WAAW,IACV,KAAK,EAAC,UAAU,EAChB,KAAK,EAAE,UAAU,CAAC,QAAQ,IAAI,iBAAiB,GAC/C,IACD,CACJ,CAAC,CAAC,CAAC,IAAI,EACP,UAAU,CAAC,CAAC,CAAC,CACZ,eAAK,SAAS,EAAC,iEAAiE,aAC9E,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAM,SAAS,EAAC,qCAAqC,YAClD,CAAC,CAAC,iBAAiB,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,GACjD,EACP,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,8BAA8B,EACxC,OAAO,EAAE,GAAG,EAAE;4DACZ,KAAK,kBAAkB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gEACnD,SAAS,CAAC,OAAO,CAAC,CAAC;gEACnB,IAAI,OAAO,EAAE,CAAC;oEACZ,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;gEAClD,CAAC;4DACH,CAAC,CAAC,CAAC;wDACL,CAAC,aAEA,MAAM,CAAC,CAAC,CAAC,CACR,KAAC,SAAS,IAAC,SAAS,EAAC,UAAU,GAAG,CACnC,CAAC,CAAC,CAAC,CACF,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,CAClC,EACA,MAAM;gEACL,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;gEAChD,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,IAC3C,IACL,EACN,eAAM,SAAS,EAAC,kEAAkE,YAC/E,UAAU,GACN,EACP,YAAG,SAAS,EAAC,oCAAoC,YAC9C,CAAC,CAAC,qBAAqB,EAAE;oDACxB,YAAY,EACV,8DAA8D;iDACjE,CAAC,GACA,IACA,CACP,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,WAAW,IACV,KAAK,EAAC,WAAW,EACjB,KAAK,EAAE,UAAU,CAAC,SAAS,IAAI,QAAQ,GACvC,EACF,KAAC,WAAW,IACV,KAAK,EAAC,QAAQ,EACd,KAAK,EAAE,UAAU,CAAC,MAAM,IAAI,SAAS,GACrC,EACF,KAAC,WAAW,IACV,KAAK,EAAC,OAAO,EACb,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,eAAe,GAC1C,EACF,KAAC,WAAW,IAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAE,UAAU,CAAC,IAAI,IAAI,SAAS,GAAI,EACjE,KAAC,WAAW,IAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,GAAI,EACnE,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,WAAW,IACV,KAAK,EAAC,UAAU,EAChB,KAAK,EACH,UAAU,CAAC,OAAO;4CAChB,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC;4CACrC,CAAC,CAAC,QAAQ,GAEd,CACH,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,WAAW,IACV,KAAK,EAAC,UAAU,EAChB,KAAK,EAAE,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,GAC1C,EACF,KAAC,WAAW,IACV,KAAK,EAAC,cAAc,EACpB,KAAK,EAAE,eAAe,CAAC,UAAU,CAAC,SAAS,CAAC,GAC5C,EACF,KAAC,WAAW,IACV,KAAK,EAAC,YAAY,EAClB,KAAK,EAAE,UAAU,CAAC,SAAS,IAAI,SAAS,GACxC,IACC,IACG,EAEV,mBAAS,SAAS,EAAC,eAAe,aAChC,aAAI,SAAS,EAAC,uCAAuC,6BAEhD,EACJ,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACvD,cAAK,SAAS,EAAC,6BAA6B,YACzC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CACrC,eAEE,SAAS,EAAC,qFAAqF,YAE9F,QAAQ,IAHJ,QAAQ,CAIR,CACR,CAAC,GACE,CACP,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAC,oCAAoC,4CAE7C,CACL,IACO,EAET,kBAAkB,CAAC,CAAC,CAAC,CACpB,mBAAS,SAAS,EAAC,eAAe,aAChC,aAAI,SAAS,EAAC,uCAAuC,iCAEhD,EACL,cAAI,SAAS,EAAC,uCAAuC,aACnD,KAAC,WAAW,IACV,KAAK,EAAC,MAAM,EACZ,KAAK,EAAE,UAAU,CAAC,eAAe,IAAI,gBAAgB,EACrD,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,GACzC,EACF,KAAC,WAAW,IACV,KAAK,EAAC,QAAQ,EACd,KAAK,EAAE,UAAU,CAAC,eAAe,IAAI,SAAS,GAC9C,EACD,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CACzB,KAAC,WAAW,IACV,KAAK,EAAC,mBAAmB,EACzB,KAAK,EAAE,UAAU,CAAC,YAAY,EAC9B,IAAI,SACJ,CACH,CAAC,CAAC,CAAC,IAAI,IACL,IACG,CACX,CAAC,CAAC,CAAC,IAAI,EAEP,WAAW,CAAC,CAAC,CAAC,CACb,mBAAS,SAAS,EAAC,eAAe,aAChC,aAAI,SAAS,EAAC,uCAAuC,yBAAc,EACnE,cAAI,SAAS,EAAC,uCAAuC,aAClD,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAC7B,KAAC,WAAW,IACV,KAAK,EAAC,UAAU,EAChB,KAAK,EAAE,UAAU,CAAC,gBAAgB,GAClC,CACH,CAAC,CAAC,CAAC,IAAI,EACP,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAChC,KAAC,WAAW,IACV,KAAK,EAAC,aAAa,EACnB,KAAK,EAAE,UAAU,CAAC,mBAAmB,GACrC,CACH,CAAC,CAAC,CAAC,IAAI,EACP,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAC9B,KAAC,WAAW,IACV,KAAK,EAAC,kBAAkB,EACxB,KAAK,EAAE,UAAU,CAAC,iBAAiB,EACnC,IAAI,SACJ,CACH,CAAC,CAAC,CAAC,IAAI,IACL,IACG,CACX,CAAC,CAAC,CAAC,IAAI,EAEP,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CACtB,mBACE,SAAS,EACP,UAAU,CAAC,UAAU,KAAK,SAAS;4BACjC,CAAC,CAAC,sCAAsC;4BACxC,CAAC,CAAC,4DAA4D,aAGjE,UAAU,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CACrC,KAAC,iBAAiB,IAAC,SAAS,EAAC,yCAAyC,GAAG,CAC1E,CAAC,CAAC,CAAC,IAAI,EACR,eAAK,SAAS,EAAC,SAAS,aACtB,aACE,SAAS,EACP,UAAU,CAAC,UAAU,KAAK,SAAS;4CACjC,CAAC,CAAC,6CAA6C;4CAC/C,CAAC,CAAC,wCAAwC,wCAI3C,EACL,YAAG,SAAS,EAAC,gDAAgD,YAC1D,UAAU,CAAC,SAAS,GACnB,IACA,IACE,CACX,CAAC,CAAC,CAAC,IAAI,EAER,mBAAS,SAAS,EAAC,eAAe,aAChC,eAAK,SAAS,EAAC,yCAAyC,aACtD,aAAI,SAAS,EAAC,uCAAuC,0BAAe,EACnE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACjB,MAAC,KAAK,IAAC,OAAO,EAAC,SAAS,aAAE,IAAI,CAAC,MAAM,cAAe,CACrD,CAAC,CAAC,CAAC,IAAI,IACJ,EACN,cAAK,SAAS,EAAC,MAAM,YAClB,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CACrB,cAAK,SAAS,EAAC,iCAAiC,YAC7C,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3C,eAAiB,SAAS,EAAC,WAAW,aACpC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,EAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,KAF1B,KAAK,CAGT,CACP,CAAC,GACE,CACP,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CACtB,KAAC,gBAAgB,IACf,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,OAAO,EAAE,GACvC,CACH,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACtB,YAAG,SAAS,EAAC,mEAAmE,2CAE5E,CACL,CAAC,CAAC,CAAC,CACF,aAAI,SAAS,EAAC,4BAA4B,YACvC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;wCAChB,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;wCACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;wCACrC,OAAO,CACL,cAAiB,SAAS,EAAC,eAAe,aACxC,eAAK,SAAS,EAAC,2CAA2C,aACxD,KAAC,KAAK,IAAC,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,YACzC,GAAG,CAAC,MAAM,GACL,EACR,eAAM,SAAS,EAAC,uBAAuB,YACpC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,GAC1B,EACN,QAAQ,CAAC,CAAC,CAAC,CACV,gBAAM,SAAS,EAAC,8DAA8D,aAC5E,KAAC,SAAS,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,QAAQ,IACJ,CACR,CAAC,CAAC,CAAC,IAAI,EACP,SAAS,CAAC,CAAC,CAAC,CACX,MAAC,IAAI,IACH,EAAE,EAAE,SAAS,EACb,SAAS,EAAC,+GAA+G,aAEzH,KAAC,gBAAgB,IAAC,SAAS,EAAC,UAAU,GAAG,kBAEpC,CACR,CAAC,CAAC,CAAC,IAAI,IACJ,EACL,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CACX,YACE,SAAS,EACP,GAAG,CAAC,MAAM,KAAK,SAAS;wDACtB,CAAC,CAAC,2CAA2C;wDAC7C,CAAC,CAAC,sCAAsC,YAG3C,GAAG,CAAC,KAAK,GACR,CACL,CAAC,CAAC,CAAC,IAAI,KAlCD,GAAG,CAAC,EAAE,CAmCV,CACN,CAAC;oCACJ,CAAC,CAAC,GACC,CACN,GACG,IACE,IACN,EAEN,kBAAQ,SAAS,EAAC,gDAAgD,aAChE,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,UAAU,CAAC,SAAS,KAAK,KAAK,IAAI,UAAU,aAErD,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAC,eAAe,KAAG,CAAC,CAAC,CAAC,KAAC,cAAc,KAAG,EAC7D,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,IACjC,EACR,UAAU,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAChC,eAAM,SAAS,EAAC,+BAA+B,0BAAiB,CACjE,CAAC,CAAC,CAAC,IAAI,IACD,IACH,CACT,CAAC;AACJ,CAAC","sourcesContent":["import { appPath } from \"@agent-native/core/client/api-path\";\nimport { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { writeClipboardText } from \"@agent-native/toolkit/clipboard\";\nimport {\n IconAlertTriangle,\n IconCheck,\n IconCopy,\n IconClock,\n IconExternalLink,\n IconPlayerPause,\n IconPlayerPlay,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport {\n automationScopeLabel,\n automationStatus,\n automationTarget,\n} from \"../lib/automation-display\";\nimport {\n automationRunScope,\n type DispatchAutomationItem,\n} from \"../lib/automations\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\n\ninterface AutomationRun {\n id: string;\n runId: string | null;\n threadId: string | null;\n status: \"running\" | \"success\" | \"error\" | \"interrupted\" | \"skipped\";\n startedAt: number;\n finishedAt: number | null;\n error: string | null;\n}\n\nexport interface AutomationDetailsPanelProps {\n automation: DispatchAutomationItem;\n isToggling?: boolean;\n onToggle: () => void;\n}\n\nfunction formatTimestamp(value: number | string | null | undefined): string {\n if (value == null) return \"Not recorded\";\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? \"Unknown time\" : date.toLocaleString();\n}\n\nfunction formatDuration(run: AutomationRun): string | null {\n if (!run.finishedAt) return null;\n const seconds = Math.max(\n 0,\n Math.round((run.finishedAt - run.startedAt) / 1000),\n );\n return `${seconds}s`;\n}\n\nfunction runDebugPath(run: AutomationRun): string | null {\n const params = new URLSearchParams();\n if (run.runId) params.set(\"runId\", run.runId);\n else if (run.threadId) params.set(\"threadId\", run.threadId);\n else return null;\n return `/admin/thread-debug?${params.toString()}`;\n}\n\nfunction runStatusVariant(\n status: AutomationRun[\"status\"],\n): \"default\" | \"destructive\" | \"outline\" {\n if (status === \"error\") return \"destructive\";\n if (status === \"success\") return \"default\";\n return \"outline\";\n}\n\nfunction DetailField({\n label,\n value,\n mono = false,\n}: {\n label: string;\n value: string;\n mono?: boolean;\n}) {\n return (\n <div className=\"min-w-0\">\n <dt className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">\n {label}\n </dt>\n <dd\n className={\n mono\n ? \"mt-1 break-words font-mono text-xs text-foreground\"\n : \"mt-1 break-words text-sm text-foreground\"\n }\n >\n {value}\n </dd>\n </div>\n );\n}\n\nfunction runAsLabel(value: DispatchAutomationItem[\"runAs\"]): string {\n if (value === \"creator\") return \"Creator identity\";\n if (value === \"shared\") return \"Shared identity\";\n return \"Default identity\";\n}\n\nexport function AutomationDetailsPanel({\n automation,\n isToggling = false,\n onToggle,\n}: AutomationDetailsPanelProps) {\n const t = useT();\n const runsQuery = useActionQuery<AutomationRun[]>(\n \"list-automation-runs\",\n {\n name: automation.name,\n scope: automationRunScope(automation),\n appId: automation.appId ?? \"dispatch\",\n },\n { staleTime: 5_000 },\n );\n const runs = runsQuery.data ?? [];\n const status = automationStatus(automation);\n const isScheduled = automation.triggerType === \"schedule\";\n const [copied, setCopied] = useState(false);\n const webhookUrl =\n automation.webhookPath && typeof window !== \"undefined\"\n ? window.location.origin + appPath(automation.webhookPath)\n : null;\n const triggerLabel =\n automation.triggerType === \"webhook\"\n ? t(\"jobs.webhook\", { defaultValue: \"Webhook\" })\n : isScheduled\n ? \"Schedule\"\n : \"Event\";\n const prompt = automation.body?.trim();\n const hasExecutionTarget = Boolean(\n automation.executionHostId ||\n automation.executionEngine ||\n automation.executionCwd,\n );\n const hasDelivery = Boolean(\n automation.deliveryPlatform ||\n automation.deliveryDestination ||\n automation.deliveryThreadRef,\n );\n\n return (\n <aside className=\"flex min-h-[34rem] min-w-0 flex-col overflow-hidden rounded-lg border bg-card\">\n <header className=\"flex items-start justify-between gap-3 border-b p-5\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span\n className={\n status.tone === \"danger\"\n ? \"size-2 shrink-0 rounded-full bg-destructive\"\n : status.tone === \"default\"\n ? \"size-2 shrink-0 rounded-full bg-primary\"\n : \"size-2 shrink-0 rounded-full bg-muted-foreground/40\"\n }\n />\n <Badge\n variant={status.tone === \"danger\" ? \"destructive\" : \"outline\"}\n className=\"h-5\"\n >\n {status.label}\n </Badge>\n </div>\n <h2 className=\"mt-2 break-words text-base font-semibold text-foreground\">\n {automation.name}\n </h2>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {triggerLabel} · {automationScopeLabel(automation)}\n </p>\n </div>\n </header>\n\n <div className=\"min-h-0 flex-1 space-y-5 overflow-y-auto p-5\">\n <section>\n <h3 className=\"text-sm font-semibold text-foreground\">Prompt</h3>\n {prompt ? (\n <pre className=\"mt-2 max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/40 p-3 font-sans text-sm leading-6 text-foreground\">\n {prompt}\n </pre>\n ) : (\n <p className=\"mt-2 rounded-md border border-dashed p-3 text-sm text-muted-foreground\">\n No prompt recorded.\n </p>\n )}\n </section>\n\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Configuration\n </h3>\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-4\">\n <DetailField\n label=\"Trigger\"\n value={\n automation.triggerType === \"webhook\"\n ? t(\"jobs.webhookTrigger\", {\n defaultValue: \"Webhook-triggered\",\n })\n : isScheduled\n ? \"Scheduled\"\n : \"Event-triggered\"\n }\n />\n <DetailField\n label={isScheduled ? \"Schedule\" : \"Event\"}\n value={automationTarget(automation)}\n />\n {isScheduled ? (\n <>\n {automation.schedule ? (\n <DetailField\n label=\"Cron expression\"\n value={automation.schedule}\n mono\n />\n ) : null}\n <DetailField\n label=\"Timezone\"\n value={automation.timezone || \"Account default\"}\n />\n </>\n ) : null}\n {webhookUrl ? (\n <div className=\"col-span-2 rounded-md border border-primary/20 bg-primary/5 p-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-xs font-medium text-foreground\">\n {t(\"jobs.webhookUrl\", { defaultValue: \"Webhook URL\" })}\n </span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 shrink-0 gap-1.5 text-xs\"\n onClick={() => {\n void writeClipboardText(webhookUrl).then((didCopy) => {\n setCopied(didCopy);\n if (didCopy) {\n window.setTimeout(() => setCopied(false), 1800);\n }\n });\n }}\n >\n {copied ? (\n <IconCheck className=\"size-3.5\" />\n ) : (\n <IconCopy className=\"size-3.5\" />\n )}\n {copied\n ? t(\"common.copied\", { defaultValue: \"Copied\" })\n : t(\"common.copy\", { defaultValue: \"Copy URL\" })}\n </Button>\n </div>\n <code className=\"mt-2 block break-all text-[11px] leading-5 text-muted-foreground\">\n {webhookUrl}\n </code>\n <p className=\"mt-2 text-xs text-muted-foreground\">\n {t(\"jobs.webhookUrlHint\", {\n defaultValue:\n \"Paste this URL into a service that sends HTTP POST webhooks.\",\n })}\n </p>\n </div>\n ) : null}\n <DetailField\n label=\"Condition\"\n value={automation.condition || \"Always\"}\n />\n <DetailField\n label=\"Domain\"\n value={automation.domain || \"Default\"}\n />\n <DetailField\n label=\"Model\"\n value={automation.model || \"Default model\"}\n />\n <DetailField label=\"Mode\" value={automation.mode || \"Agentic\"} />\n <DetailField label=\"Runs as\" value={runAsLabel(automation.runAs)} />\n {isScheduled ? (\n <DetailField\n label=\"Next run\"\n value={\n automation.enabled\n ? formatTimestamp(automation.nextRun)\n : \"Paused\"\n }\n />\n ) : null}\n <DetailField\n label=\"Last run\"\n value={formatTimestamp(automation.lastRun)}\n />\n <DetailField\n label=\"Last checked\"\n value={formatTimestamp(automation.lastCheck)}\n />\n <DetailField\n label=\"Created by\"\n value={automation.createdBy || \"Unknown\"}\n />\n </dl>\n </section>\n\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Capabilities\n </h3>\n {automation.mcpTools && automation.mcpTools.length > 0 ? (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {automation.mcpTools.map((toolName) => (\n <code\n key={toolName}\n className=\"max-w-full break-all rounded bg-muted px-1.5 py-1 text-[11px] text-muted-foreground\"\n >\n {toolName}\n </code>\n ))}\n </div>\n ) : (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n No explicit tool allowlist.\n </p>\n )}\n </section>\n\n {hasExecutionTarget ? (\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Execution target\n </h3>\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-4\">\n <DetailField\n label=\"Host\"\n value={automation.executionHostId || \"Server default\"}\n mono={Boolean(automation.executionHostId)}\n />\n <DetailField\n label=\"Engine\"\n value={automation.executionEngine || \"Default\"}\n />\n {automation.executionCwd ? (\n <DetailField\n label=\"Working directory\"\n value={automation.executionCwd}\n mono\n />\n ) : null}\n </dl>\n </section>\n ) : null}\n\n {hasDelivery ? (\n <section className=\"border-t pt-5\">\n <h3 className=\"text-sm font-semibold text-foreground\">Delivery</h3>\n <dl className=\"mt-3 grid grid-cols-2 gap-x-4 gap-y-4\">\n {automation.deliveryPlatform ? (\n <DetailField\n label=\"Platform\"\n value={automation.deliveryPlatform}\n />\n ) : null}\n {automation.deliveryDestination ? (\n <DetailField\n label=\"Destination\"\n value={automation.deliveryDestination}\n />\n ) : null}\n {automation.deliveryThreadRef ? (\n <DetailField\n label=\"Thread reference\"\n value={automation.deliveryThreadRef}\n mono\n />\n ) : null}\n </dl>\n </section>\n ) : null}\n\n {automation.lastError ? (\n <section\n className={\n automation.lastStatus === \"skipped\"\n ? \"flex items-start gap-2 border-t pt-5\"\n : \"flex items-start gap-2 border-t border-destructive/30 pt-5\"\n }\n >\n {automation.lastStatus !== \"skipped\" ? (\n <IconAlertTriangle className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n ) : null}\n <div className=\"min-w-0\">\n <h3\n className={\n automation.lastStatus === \"skipped\"\n ? \"text-sm font-semibold text-muted-foreground\"\n : \"text-sm font-semibold text-destructive\"\n }\n >\n Latest scheduler result\n </h3>\n <p className=\"mt-1 break-words text-sm text-muted-foreground\">\n {automation.lastError}\n </p>\n </div>\n </section>\n ) : null}\n\n <section className=\"border-t pt-5\">\n <div className=\"flex items-center justify-between gap-3\">\n <h3 className=\"text-sm font-semibold text-foreground\">Past runs</h3>\n {runs.length > 0 ? (\n <Badge variant=\"outline\">{runs.length} shown</Badge>\n ) : null}\n </div>\n <div className=\"mt-3\">\n {runsQuery.isLoading ? (\n <div className=\"space-y-3 rounded-md border p-3\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"space-y-2\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n ))}\n </div>\n ) : runsQuery.isError ? (\n <ActionQueryError\n error={runsQuery.error}\n onRetry={() => void runsQuery.refetch()}\n />\n ) : runs.length === 0 ? (\n <p className=\"rounded-md border border-dashed p-3 text-sm text-muted-foreground\">\n No execution recorded yet.\n </p>\n ) : (\n <ul className=\"divide-y rounded-md border\">\n {runs.map((run) => {\n const debugPath = runDebugPath(run);\n const duration = formatDuration(run);\n return (\n <li key={run.id} className=\"space-y-2 p-3\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <Badge variant={runStatusVariant(run.status)}>\n {run.status}\n </Badge>\n <span className=\"text-muted-foreground\">\n {formatTimestamp(run.startedAt)}\n </span>\n {duration ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n <IconClock className=\"size-3.5\" />\n {duration}\n </span>\n ) : null}\n {debugPath ? (\n <Link\n to={debugPath}\n className=\"ml-auto inline-flex items-center gap-1 text-xs font-medium text-foreground underline-offset-4 hover:underline\"\n >\n <IconExternalLink className=\"size-3.5\" />\n Open debug\n </Link>\n ) : null}\n </div>\n {run.error ? (\n <p\n className={\n run.status === \"skipped\"\n ? \"break-words text-sm text-muted-foreground\"\n : \"break-words text-sm text-destructive\"\n }\n >\n {run.error}\n </p>\n ) : null}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </section>\n </div>\n\n <footer className=\"flex flex-wrap items-center gap-2 border-t p-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onToggle}\n disabled={automation.canUpdate === false || isToggling}\n >\n {automation.enabled ? <IconPlayerPause /> : <IconPlayerPlay />}\n {automation.enabled ? \"Pause\" : \"Resume\"}\n </Button>\n {automation.canUpdate === false ? (\n <span className=\"text-xs text-muted-foreground\">Read-only</span>\n ) : null}\n </footer>\n </aside>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-display.d.ts","sourceRoot":"","sources":["../../src/lib/automation-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,SAAS,GACT,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,MAAM,CAAC,GACnD,MAAM,CAER;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC,GAC1C,OAAO,CAET;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,GACzC,MAAM,CAGR;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAMrE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,OAAO,CAAC,GACpD,MAAM,CAMR;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAWxE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAEtE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAExE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAKtE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,sBAAsB,GAAG;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAUA;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,sBAAsB,EAAE,GACpC,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"automation-display.d.ts","sourceRoot":"","sources":["../../src/lib/automation-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,SAAS,GACT,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,MAAM,CAAC,GACnD,MAAM,CAER;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC,GAC1C,OAAO,CAET;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,GACzC,MAAM,CAGR;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAMrE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,OAAO,CAAC,GACpD,MAAM,CAMR;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAWxE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAEtE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAExE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAKtE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,sBAAsB,GAAG;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAUA;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,sBAAsB,EAAE,GACpC,sBAAsB,EAAE,CAO1B"}
|
|
@@ -66,19 +66,15 @@ export function automationStatus(item) {
|
|
|
66
66
|
if (item.lastStatus === "running")
|
|
67
67
|
return { label: "Running", tone: "warning" };
|
|
68
68
|
if (item.lastStatus === "skipped")
|
|
69
|
-
return { label:
|
|
69
|
+
return { label: item.lastStatus, tone: "muted" };
|
|
70
70
|
if (item.lastStatus === "success")
|
|
71
71
|
return { label: "Healthy", tone: "success" };
|
|
72
72
|
return { label: "Ready", tone: "default" };
|
|
73
73
|
}
|
|
74
74
|
export function sortAutomations(automations) {
|
|
75
75
|
return [...automations].sort((a, b) => {
|
|
76
|
-
const aError = a.enabled &&
|
|
77
|
-
|
|
78
|
-
: 0;
|
|
79
|
-
const bError = b.enabled && (b.lastStatus === "error" || b.lastStatus === "skipped")
|
|
80
|
-
? 1
|
|
81
|
-
: 0;
|
|
76
|
+
const aError = a.enabled && a.lastStatus === "error" ? 1 : 0;
|
|
77
|
+
const bError = b.enabled && b.lastStatus === "error" ? 1 : 0;
|
|
82
78
|
if (aError !== bError)
|
|
83
79
|
return bError - aError;
|
|
84
80
|
return (b.lastRun || "").localeCompare(a.lastRun || "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-display.js","sourceRoot":"","sources":["../../src/lib/automation-display.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"automation-display.js","sourceRoot":"","sources":["../../src/lib/automation-display.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DispatchAutomationItem } from \"./automations.js\";\n\nexport type AutomationStatusTone =\n | \"default\"\n | \"success\"\n | \"warning\"\n | \"danger\"\n | \"muted\";\n\nexport function automationIdentity(\n item: Pick<DispatchAutomationItem, \"owner\" | \"path\">,\n): string {\n return `${item.owner}:${item.path}`;\n}\n\nexport function belongsToDispatch(\n item: Pick<DispatchAutomationItem, \"appId\">,\n): boolean {\n return !item.appId || item.appId === \"dispatch\";\n}\n\nexport function automationTroubleshootPath(\n item: Pick<DispatchAutomationItem, \"name\">,\n): string {\n const params = new URLSearchParams({ mode: \"threads\", query: item.name });\n return `/admin/thread-debug?${params.toString()}`;\n}\n\nexport function automationTarget(item: DispatchAutomationItem): string {\n if (item.triggerType === \"event\" && item.event) return item.event;\n if (item.triggerType === \"webhook\") return \"On webhook\";\n if (item.scheduleDescription) return item.scheduleDescription;\n if (item.schedule) return item.schedule;\n return item.triggerType || \"schedule\";\n}\n\nexport function automationScopeLabel(\n item: Pick<DispatchAutomationItem, \"owner\" | \"scope\">,\n): string {\n return item.scope === \"organization\" ||\n item.owner.startsWith(\"__organization__:\") ||\n item.owner === \"__shared__\"\n ? \"Organization\"\n : \"Personal\";\n}\n\nexport function relativeRunTime(value: string | null | undefined): string {\n if (!value) return \"never\";\n const timestamp = new Date(value).getTime();\n if (!Number.isFinite(timestamp)) return \"never\";\n const diff = timestamp - Date.now();\n const abs = Math.abs(diff);\n const suffix = diff >= 0 ? \"from now\" : \"ago\";\n if (abs < 60_000) return diff >= 0 ? \"soon\" : \"now\";\n if (abs < 3_600_000) return `${Math.floor(abs / 60_000)}m ${suffix}`;\n if (abs < 86_400_000) return `${Math.floor(abs / 3_600_000)}h ${suffix}`;\n return `${Math.floor(abs / 86_400_000)}d ${suffix}`;\n}\n\nexport function automationLastRun(item: DispatchAutomationItem): string {\n return item.lastRun ? relativeRunTime(item.lastRun) : \"never\";\n}\n\nexport function automationLastCheck(item: DispatchAutomationItem): string {\n return item.lastCheck ? relativeRunTime(item.lastCheck) : \"never\";\n}\n\nexport function automationNextRun(item: DispatchAutomationItem): string {\n if (!item.enabled) return \"paused\";\n if (item.triggerType === \"event\") return \"on event\";\n if (item.triggerType === \"webhook\") return \"on webhook\";\n return item.nextRun ? relativeRunTime(item.nextRun) : \"not scheduled\";\n}\n\nexport function automationStatus(item: DispatchAutomationItem): {\n label: string;\n tone: AutomationStatusTone;\n} {\n if (!item.enabled) return { label: \"Paused\", tone: \"muted\" };\n if (item.lastStatus === \"error\") return { label: \"Error\", tone: \"danger\" };\n if (item.lastStatus === \"running\")\n return { label: \"Running\", tone: \"warning\" };\n if (item.lastStatus === \"skipped\")\n return { label: item.lastStatus, tone: \"muted\" };\n if (item.lastStatus === \"success\")\n return { label: \"Healthy\", tone: \"success\" };\n return { label: \"Ready\", tone: \"default\" };\n}\n\nexport function sortAutomations(\n automations: DispatchAutomationItem[],\n): DispatchAutomationItem[] {\n return [...automations].sort((a, b) => {\n const aError = a.enabled && a.lastStatus === \"error\" ? 1 : 0;\n const bError = b.enabled && b.lastStatus === \"error\" ? 1 : 0;\n if (aError !== bError) return bError - aError;\n return (b.lastRun || \"\").localeCompare(a.lastRun || \"\");\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,IAAI;;IAEnB;AAkGD,MAAM,CAAC,OAAO,UAAU,gBAAgB,
|
|
1
|
+
{"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,IAAI;;IAEnB;AAkGD,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDA4QvC"}
|
|
@@ -102,8 +102,7 @@ export default function AutomationsRoute() {
|
|
|
102
102
|
.includes(normalized));
|
|
103
103
|
}, [ordered, query]);
|
|
104
104
|
const enabledCount = visibleAutomations.filter((item) => item.enabled).length;
|
|
105
|
-
const errorCount = visibleAutomations.filter((item) => item.enabled &&
|
|
106
|
-
(item.lastStatus === "error" || item.lastStatus === "skipped")).length;
|
|
105
|
+
const errorCount = visibleAutomations.filter((item) => item.enabled && item.lastStatus === "error").length;
|
|
107
106
|
const pendingToggleIdentity = toggleAutomation.isPending
|
|
108
107
|
? toggleAutomation.variables
|
|
109
108
|
? automationIdentity(toggleAutomation.variables)
|
|
@@ -133,7 +132,9 @@ export default function AutomationsRoute() {
|
|
|
133
132
|
const isSelected = detailsTarget !== null &&
|
|
134
133
|
automationIdentity(detailsTarget) ===
|
|
135
134
|
automationIdentity(item);
|
|
136
|
-
return (_jsxs("div", { className: cn("grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3 transition-colors", isSelected && "bg-accent/40"), children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("button", { type: "button", className: "w-full min-w-0 cursor-pointer text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card", "aria-pressed": isSelected, onClick: () => selectAutomation(item), children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(StatusDot, { tone: status.tone }), _jsx("span", { className: "truncate text-sm font-medium text-foreground", children: item.name })] }), _jsx("div", { className: "mt-1 truncate text-xs text-muted-foreground", children: automationTarget(item) }), _jsxs("div", { className: "mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground", children: [_jsxs("span", { children: ["Last ", automationLastRun(item)] }), _jsxs("span", { children: ["Next ", automationNextRun(item)] }), _jsx("span", { children: automationScopeLabel(item) }), item.lastCheck ? (_jsxs("span", { children: ["Checked ", automationLastCheck(item)] })) : null] })] }), item.lastError ? (_jsxs("div", { className: "mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs
|
|
135
|
+
return (_jsxs("div", { className: cn("grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3 transition-colors", isSelected && "bg-accent/40"), children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("button", { type: "button", className: "w-full min-w-0 cursor-pointer text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card", "aria-pressed": isSelected, onClick: () => selectAutomation(item), children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(StatusDot, { tone: status.tone }), _jsx("span", { className: "truncate text-sm font-medium text-foreground", children: item.name })] }), _jsx("div", { className: "mt-1 truncate text-xs text-muted-foreground", children: automationTarget(item) }), _jsxs("div", { className: "mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground", children: [_jsxs("span", { children: ["Last ", automationLastRun(item)] }), _jsxs("span", { children: ["Next ", automationNextRun(item)] }), _jsx("span", { children: automationScopeLabel(item) }), item.lastCheck ? (_jsxs("span", { children: ["Checked ", automationLastCheck(item)] })) : null] })] }), item.lastError ? (_jsxs("div", { className: cn("mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs", item.lastStatus === "skipped"
|
|
136
|
+
? "text-muted-foreground"
|
|
137
|
+
: "text-destructive"), children: [_jsx("span", { className: "min-w-0 break-words", children: item.lastError }), _jsxs(Link, { to: automationTroubleshootPath(item), className: "inline-flex shrink-0 items-center gap-1 font-medium text-foreground underline-offset-4 hover:underline", "aria-label": `Troubleshoot ${item.name} in Thread Debug`, children: [_jsx(IconFileSearch, { size: 13, "aria-hidden": "true" }), "Troubleshoot in Thread Debug"] })] })) : null] }), _jsxs("div", { className: "flex flex-col items-end gap-2", children: [_jsx(Badge, { variant: status.tone === "danger" ? "destructive" : "outline", className: "h-5", children: status.label }), _jsx(Switch, { checked: !!item.enabled, disabled: !canUpdate || isToggling, "aria-label": `${item.enabled ? "Disable" : "Enable"} automation ${item.name}`, onCheckedChange: (checked) => toggleAutomation.mutate({
|
|
137
138
|
owner: item.owner,
|
|
138
139
|
path: item.path,
|
|
139
140
|
enabled: checked,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automations.js","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useChangeVersions } from \"@agent-native/core/client/hooks\";\nimport {\n IconFileSearch,\n IconListDetails,\n IconPlus,\n IconSearch,\n IconSettingsAutomation,\n} from \"@tabler/icons-react\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMemo, useState } from \"react\";\nimport { Link, useSearchParams } from \"react-router\";\nimport { toast } from \"sonner\";\n\nimport { AutomationCreateDialog } from \"../../components/automation-create-dialog\";\nimport { AutomationDetailsPanel } from \"../../components/automation-details-panel\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Input } from \"../../components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n automationIdentity,\n automationLastCheck,\n automationLastRun,\n automationNextRun,\n automationScopeLabel,\n automationStatus,\n automationTarget,\n automationTroubleshootPath,\n belongsToDispatch,\n sortAutomations,\n type AutomationStatusTone,\n} from \"../../lib/automation-display\";\nimport {\n listDispatchAutomations,\n setDispatchAutomationEnabled,\n type DispatchAutomationItem,\n type SetDispatchAutomationEnabledInput,\n} from \"../../lib/automations\";\nimport { cn } from \"../../lib/utils\";\n\nconst AUTOMATIONS_QUERY_KEY = [\"dispatch-automations\"] as const;\n\nexport function meta() {\n return [{ title: \"Automations — Dispatch\" }];\n}\n\nfunction StatusDot({ tone }: { tone: AutomationStatusTone }) {\n return (\n <span\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n tone === \"success\" && \"bg-emerald-500\",\n tone === \"warning\" && \"bg-amber-500\",\n tone === \"danger\" && \"bg-destructive\",\n tone === \"muted\" && \"bg-muted-foreground/35\",\n tone === \"default\" && \"bg-primary\",\n )}\n />\n );\n}\n\nfunction useAutomations() {\n const version = useChangeVersions([\"action\", \"screen-refresh\"]);\n return useQuery<DispatchAutomationItem[]>({\n queryKey: [...AUTOMATIONS_QUERY_KEY, version],\n queryFn: listDispatchAutomations,\n placeholderData: (prev) => prev,\n staleTime: 5_000,\n });\n}\n\nfunction useToggleAutomation() {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: setDispatchAutomationEnabled,\n onMutate: async (input: SetDispatchAutomationEnabledInput) => {\n await queryClient.cancelQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n const snapshots = queryClient.getQueriesData<DispatchAutomationItem[]>({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(input)\n ? { ...item, enabled: input.enabled }\n : item,\n ),\n );\n\n return { snapshots };\n },\n onError: (err, _input, context) => {\n for (const [queryKey, data] of context?.snapshots ?? []) {\n queryClient.setQueryData(queryKey, data);\n }\n toast.error(\n `Could not update automation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n },\n onSuccess: (updated) => {\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(updated)\n ? updated\n : item,\n ),\n );\n },\n onSettled: () => {\n void queryClient.invalidateQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n },\n });\n}\n\nfunction CreateAutomationButton({ onCreated }: { onCreated: () => void }) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <Button size=\"sm\" onClick={() => setOpen(true)}>\n <IconPlus size={14} />\n New automation\n </Button>\n <AutomationCreateDialog\n open={open}\n onOpenChange={setOpen}\n onCreated={() => {\n setOpen(false);\n onCreated();\n }}\n />\n </>\n );\n}\n\nexport default function AutomationsRoute() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [view, setView] = useState<\"dispatch\" | \"all\">(\"dispatch\");\n const [query, setQuery] = useState(\"\");\n const automationsQuery = useAutomations();\n const toggleAutomation = useToggleAutomation();\n const queryClient = useQueryClient();\n const automations = automationsQuery.data ?? [];\n const visibleAutomations = useMemo(\n () =>\n view === \"all\"\n ? automations\n : automations.filter((item) => belongsToDispatch(item)),\n [automations, view],\n );\n const ordered = useMemo(\n () => sortAutomations(visibleAutomations),\n [visibleAutomations],\n );\n const filtered = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return ordered;\n return ordered.filter((item) =>\n [\n item.name,\n item.event,\n item.schedule,\n item.scheduleDescription,\n item.webhookPath,\n item.body,\n item.model,\n item.domain,\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase()\n .includes(normalized),\n );\n }, [ordered, query]);\n const enabledCount = visibleAutomations.filter((item) => item.enabled).length;\n const errorCount = visibleAutomations.filter(\n (item) =>\n item.enabled &&\n (item.lastStatus === \"error\" || item.lastStatus === \"skipped\"),\n ).length;\n const pendingToggleIdentity = toggleAutomation.isPending\n ? toggleAutomation.variables\n ? automationIdentity(toggleAutomation.variables)\n : null\n : null;\n\n const selectedAutomationId = searchParams.get(\"automationId\");\n const detailsTarget = selectedAutomationId\n ? (filtered.find(\n (item) => automationIdentity(item) === selectedAutomationId,\n ) ?? null)\n : null;\n\n function selectAutomation(item: DispatchAutomationItem) {\n const next = new URLSearchParams(searchParams);\n next.set(\"automationId\", automationIdentity(item));\n setSearchParams(next);\n }\n\n return (\n <DispatchShell\n title=\"Automations\"\n description=\"Create schedule, webhook, or app-event automations, then inspect their checks and past runs.\"\n >\n <section className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-3\">\n <div className=\"relative w-full max-w-sm\">\n <IconSearch\n size={15}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n size=\"sm\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search automations\"\n aria-label=\"Search automations\"\n className=\"pl-8 text-xs\"\n />\n </div>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <IconSettingsAutomation size={16} className=\"shrink-0\" />\n <span>\n {enabledCount} enabled\n {errorCount > 0 ? ` · ${errorCount} errors` : \"\"}\n </span>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <Select\n value={view}\n onValueChange={(value) => {\n if (value === \"dispatch\" || value === \"all\") setView(value);\n }}\n >\n <SelectTrigger\n size=\"sm\"\n className=\"w-[10.5rem] text-xs\"\n aria-label=\"Automation view\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"dispatch\">Dispatch automations</SelectItem>\n <SelectItem value=\"all\">All apps</SelectItem>\n </SelectContent>\n </Select>\n <CreateAutomationButton\n onCreated={() => {\n toast.success(\"Automation created\");\n void queryClient.invalidateQueries({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n }}\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(24rem,32rem)]\">\n <div className=\"min-w-0 divide-y rounded-lg bg-card\">\n {automationsQuery.isLoading && ordered.length === 0 ? (\n Array.from({ length: 4 }).map((_, index) => (\n <div key={index} className=\"px-4 py-3\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-2 h-3 w-28\" />\n </div>\n ))\n ) : filtered.length > 0 ? (\n filtered.map((item) => {\n const status = automationStatus(item);\n const canUpdate = item.canUpdate !== false;\n const isToggling =\n pendingToggleIdentity === automationIdentity(item);\n const isSelected =\n detailsTarget !== null &&\n automationIdentity(detailsTarget) ===\n automationIdentity(item);\n return (\n <div\n key={item.id}\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3 transition-colors\",\n isSelected && \"bg-accent/40\",\n )}\n >\n <div className=\"min-w-0\">\n <button\n type=\"button\"\n className=\"w-full min-w-0 cursor-pointer text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card\"\n aria-pressed={isSelected}\n onClick={() => selectAutomation(item)}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <StatusDot tone={status.tone} />\n <span className=\"truncate text-sm font-medium text-foreground\">\n {item.name}\n </span>\n </div>\n <div className=\"mt-1 truncate text-xs text-muted-foreground\">\n {automationTarget(item)}\n </div>\n <div className=\"mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground\">\n <span>Last {automationLastRun(item)}</span>\n <span>Next {automationNextRun(item)}</span>\n <span>{automationScopeLabel(item)}</span>\n {item.lastCheck ? (\n <span>Checked {automationLastCheck(item)}</span>\n ) : null}\n </div>\n </button>\n {item.lastError ? (\n <div className=\"mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs text-destructive\">\n <span className=\"min-w-0 break-words\">\n {item.lastError}\n </span>\n <Link\n to={automationTroubleshootPath(item)}\n className=\"inline-flex shrink-0 items-center gap-1 font-medium text-foreground underline-offset-4 hover:underline\"\n aria-label={`Troubleshoot ${item.name} in Thread Debug`}\n >\n <IconFileSearch size={13} aria-hidden=\"true\" />\n Troubleshoot in Thread Debug\n </Link>\n </div>\n ) : null}\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Badge\n variant={\n status.tone === \"danger\" ? \"destructive\" : \"outline\"\n }\n className=\"h-5\"\n >\n {status.label}\n </Badge>\n <Switch\n checked={!!item.enabled}\n disabled={!canUpdate || isToggling}\n aria-label={`${item.enabled ? \"Disable\" : \"Enable\"} automation ${item.name}`}\n onCheckedChange={(checked) =>\n toggleAutomation.mutate({\n owner: item.owner,\n path: item.path,\n enabled: checked,\n })\n }\n />\n </div>\n </div>\n );\n })\n ) : (\n <div className=\"px-4 py-10 text-center text-sm text-muted-foreground\">\n {query\n ? \"No matching automations.\"\n : view === \"all\"\n ? \"No automations yet. Create one here, or ask Dispatch to set up a scheduled or event-triggered job.\"\n : \"No Dispatch automations yet. Switch to All apps to inspect workspace automations.\"}\n </div>\n )}\n </div>\n\n {detailsTarget ? (\n <AutomationDetailsPanel\n automation={detailsTarget}\n isToggling={\n pendingToggleIdentity === automationIdentity(detailsTarget)\n }\n onToggle={() =>\n toggleAutomation.mutate({\n owner: detailsTarget.owner,\n path: detailsTarget.path,\n enabled: !detailsTarget.enabled,\n })\n }\n />\n ) : (\n <div className=\"flex min-h-[34rem] flex-col items-center justify-center rounded-lg border border-dashed bg-card p-6 text-center\">\n <IconListDetails\n size={24}\n strokeWidth={1.6}\n className=\"text-muted-foreground\"\n />\n <p className=\"mt-3 text-sm font-medium text-foreground\">\n Select an automation\n </p>\n <p className=\"mt-1 max-w-xs text-sm text-muted-foreground\">\n Inspect its prompt, configuration, capabilities, and run\n history.\n </p>\n </div>\n )}\n </div>\n </section>\n </DispatchShell>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"automations.js","sourceRoot":"","sources":["../../../src/routes/pages/automations.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useChangeVersions } from \"@agent-native/core/client/hooks\";\nimport {\n IconFileSearch,\n IconListDetails,\n IconPlus,\n IconSearch,\n IconSettingsAutomation,\n} from \"@tabler/icons-react\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMemo, useState } from \"react\";\nimport { Link, useSearchParams } from \"react-router\";\nimport { toast } from \"sonner\";\n\nimport { AutomationCreateDialog } from \"../../components/automation-create-dialog\";\nimport { AutomationDetailsPanel } from \"../../components/automation-details-panel\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Input } from \"../../components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n automationIdentity,\n automationLastCheck,\n automationLastRun,\n automationNextRun,\n automationScopeLabel,\n automationStatus,\n automationTarget,\n automationTroubleshootPath,\n belongsToDispatch,\n sortAutomations,\n type AutomationStatusTone,\n} from \"../../lib/automation-display\";\nimport {\n listDispatchAutomations,\n setDispatchAutomationEnabled,\n type DispatchAutomationItem,\n type SetDispatchAutomationEnabledInput,\n} from \"../../lib/automations\";\nimport { cn } from \"../../lib/utils\";\n\nconst AUTOMATIONS_QUERY_KEY = [\"dispatch-automations\"] as const;\n\nexport function meta() {\n return [{ title: \"Automations — Dispatch\" }];\n}\n\nfunction StatusDot({ tone }: { tone: AutomationStatusTone }) {\n return (\n <span\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n tone === \"success\" && \"bg-emerald-500\",\n tone === \"warning\" && \"bg-amber-500\",\n tone === \"danger\" && \"bg-destructive\",\n tone === \"muted\" && \"bg-muted-foreground/35\",\n tone === \"default\" && \"bg-primary\",\n )}\n />\n );\n}\n\nfunction useAutomations() {\n const version = useChangeVersions([\"action\", \"screen-refresh\"]);\n return useQuery<DispatchAutomationItem[]>({\n queryKey: [...AUTOMATIONS_QUERY_KEY, version],\n queryFn: listDispatchAutomations,\n placeholderData: (prev) => prev,\n staleTime: 5_000,\n });\n}\n\nfunction useToggleAutomation() {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: setDispatchAutomationEnabled,\n onMutate: async (input: SetDispatchAutomationEnabledInput) => {\n await queryClient.cancelQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n const snapshots = queryClient.getQueriesData<DispatchAutomationItem[]>({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(input)\n ? { ...item, enabled: input.enabled }\n : item,\n ),\n );\n\n return { snapshots };\n },\n onError: (err, _input, context) => {\n for (const [queryKey, data] of context?.snapshots ?? []) {\n queryClient.setQueryData(queryKey, data);\n }\n toast.error(\n `Could not update automation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n },\n onSuccess: (updated) => {\n queryClient.setQueriesData<DispatchAutomationItem[]>(\n { queryKey: AUTOMATIONS_QUERY_KEY },\n (rows) =>\n rows?.map((item) =>\n automationIdentity(item) === automationIdentity(updated)\n ? updated\n : item,\n ),\n );\n },\n onSettled: () => {\n void queryClient.invalidateQueries({ queryKey: AUTOMATIONS_QUERY_KEY });\n },\n });\n}\n\nfunction CreateAutomationButton({ onCreated }: { onCreated: () => void }) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n <Button size=\"sm\" onClick={() => setOpen(true)}>\n <IconPlus size={14} />\n New automation\n </Button>\n <AutomationCreateDialog\n open={open}\n onOpenChange={setOpen}\n onCreated={() => {\n setOpen(false);\n onCreated();\n }}\n />\n </>\n );\n}\n\nexport default function AutomationsRoute() {\n const [searchParams, setSearchParams] = useSearchParams();\n const [view, setView] = useState<\"dispatch\" | \"all\">(\"dispatch\");\n const [query, setQuery] = useState(\"\");\n const automationsQuery = useAutomations();\n const toggleAutomation = useToggleAutomation();\n const queryClient = useQueryClient();\n const automations = automationsQuery.data ?? [];\n const visibleAutomations = useMemo(\n () =>\n view === \"all\"\n ? automations\n : automations.filter((item) => belongsToDispatch(item)),\n [automations, view],\n );\n const ordered = useMemo(\n () => sortAutomations(visibleAutomations),\n [visibleAutomations],\n );\n const filtered = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return ordered;\n return ordered.filter((item) =>\n [\n item.name,\n item.event,\n item.schedule,\n item.scheduleDescription,\n item.webhookPath,\n item.body,\n item.model,\n item.domain,\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase()\n .includes(normalized),\n );\n }, [ordered, query]);\n const enabledCount = visibleAutomations.filter((item) => item.enabled).length;\n const errorCount = visibleAutomations.filter(\n (item) => item.enabled && item.lastStatus === \"error\",\n ).length;\n const pendingToggleIdentity = toggleAutomation.isPending\n ? toggleAutomation.variables\n ? automationIdentity(toggleAutomation.variables)\n : null\n : null;\n\n const selectedAutomationId = searchParams.get(\"automationId\");\n const detailsTarget = selectedAutomationId\n ? (filtered.find(\n (item) => automationIdentity(item) === selectedAutomationId,\n ) ?? null)\n : null;\n\n function selectAutomation(item: DispatchAutomationItem) {\n const next = new URLSearchParams(searchParams);\n next.set(\"automationId\", automationIdentity(item));\n setSearchParams(next);\n }\n\n return (\n <DispatchShell\n title=\"Automations\"\n description=\"Create schedule, webhook, or app-event automations, then inspect their checks and past runs.\"\n >\n <section className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-3\">\n <div className=\"relative w-full max-w-sm\">\n <IconSearch\n size={15}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n size=\"sm\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search automations\"\n aria-label=\"Search automations\"\n className=\"pl-8 text-xs\"\n />\n </div>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <IconSettingsAutomation size={16} className=\"shrink-0\" />\n <span>\n {enabledCount} enabled\n {errorCount > 0 ? ` · ${errorCount} errors` : \"\"}\n </span>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <Select\n value={view}\n onValueChange={(value) => {\n if (value === \"dispatch\" || value === \"all\") setView(value);\n }}\n >\n <SelectTrigger\n size=\"sm\"\n className=\"w-[10.5rem] text-xs\"\n aria-label=\"Automation view\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"dispatch\">Dispatch automations</SelectItem>\n <SelectItem value=\"all\">All apps</SelectItem>\n </SelectContent>\n </Select>\n <CreateAutomationButton\n onCreated={() => {\n toast.success(\"Automation created\");\n void queryClient.invalidateQueries({\n queryKey: AUTOMATIONS_QUERY_KEY,\n });\n }}\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(24rem,32rem)]\">\n <div className=\"min-w-0 divide-y rounded-lg bg-card\">\n {automationsQuery.isLoading && ordered.length === 0 ? (\n Array.from({ length: 4 }).map((_, index) => (\n <div key={index} className=\"px-4 py-3\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-2 h-3 w-28\" />\n </div>\n ))\n ) : filtered.length > 0 ? (\n filtered.map((item) => {\n const status = automationStatus(item);\n const canUpdate = item.canUpdate !== false;\n const isToggling =\n pendingToggleIdentity === automationIdentity(item);\n const isSelected =\n detailsTarget !== null &&\n automationIdentity(detailsTarget) ===\n automationIdentity(item);\n return (\n <div\n key={item.id}\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] gap-3 px-4 py-3 transition-colors\",\n isSelected && \"bg-accent/40\",\n )}\n >\n <div className=\"min-w-0\">\n <button\n type=\"button\"\n className=\"w-full min-w-0 cursor-pointer text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card\"\n aria-pressed={isSelected}\n onClick={() => selectAutomation(item)}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <StatusDot tone={status.tone} />\n <span className=\"truncate text-sm font-medium text-foreground\">\n {item.name}\n </span>\n </div>\n <div className=\"mt-1 truncate text-xs text-muted-foreground\">\n {automationTarget(item)}\n </div>\n <div className=\"mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground\">\n <span>Last {automationLastRun(item)}</span>\n <span>Next {automationNextRun(item)}</span>\n <span>{automationScopeLabel(item)}</span>\n {item.lastCheck ? (\n <span>Checked {automationLastCheck(item)}</span>\n ) : null}\n </div>\n </button>\n {item.lastError ? (\n <div\n className={cn(\n \"mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs\",\n item.lastStatus === \"skipped\"\n ? \"text-muted-foreground\"\n : \"text-destructive\",\n )}\n >\n <span className=\"min-w-0 break-words\">\n {item.lastError}\n </span>\n <Link\n to={automationTroubleshootPath(item)}\n className=\"inline-flex shrink-0 items-center gap-1 font-medium text-foreground underline-offset-4 hover:underline\"\n aria-label={`Troubleshoot ${item.name} in Thread Debug`}\n >\n <IconFileSearch size={13} aria-hidden=\"true\" />\n Troubleshoot in Thread Debug\n </Link>\n </div>\n ) : null}\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Badge\n variant={\n status.tone === \"danger\" ? \"destructive\" : \"outline\"\n }\n className=\"h-5\"\n >\n {status.label}\n </Badge>\n <Switch\n checked={!!item.enabled}\n disabled={!canUpdate || isToggling}\n aria-label={`${item.enabled ? \"Disable\" : \"Enable\"} automation ${item.name}`}\n onCheckedChange={(checked) =>\n toggleAutomation.mutate({\n owner: item.owner,\n path: item.path,\n enabled: checked,\n })\n }\n />\n </div>\n </div>\n );\n })\n ) : (\n <div className=\"px-4 py-10 text-center text-sm text-muted-foreground\">\n {query\n ? \"No matching automations.\"\n : view === \"all\"\n ? \"No automations yet. Create one here, or ask Dispatch to set up a scheduled or event-triggered job.\"\n : \"No Dispatch automations yet. Switch to All apps to inspect workspace automations.\"}\n </div>\n )}\n </div>\n\n {detailsTarget ? (\n <AutomationDetailsPanel\n automation={detailsTarget}\n isToggling={\n pendingToggleIdentity === automationIdentity(detailsTarget)\n }\n onToggle={() =>\n toggleAutomation.mutate({\n owner: detailsTarget.owner,\n path: detailsTarget.path,\n enabled: !detailsTarget.enabled,\n })\n }\n />\n ) : (\n <div className=\"flex min-h-[34rem] flex-col items-center justify-center rounded-lg border border-dashed bg-card p-6 text-center\">\n <IconListDetails\n size={24}\n strokeWidth={1.6}\n className=\"text-muted-foreground\"\n />\n <p className=\"mt-3 text-sm font-medium text-foreground\">\n Select an automation\n </p>\n <p className=\"mt-1 max-w-xs text-sm text-muted-foreground\">\n Inspect its prompt, configuration, capabilities, and run\n history.\n </p>\n </div>\n )}\n </div>\n </section>\n </DispatchShell>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.18-nightly-20261008065100",
|
|
4
4
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"tailwind-merge": "^3.5.0",
|
|
90
90
|
"vaul": "^1.1.2",
|
|
91
91
|
"zod": "^4.3.6",
|
|
92
|
-
"@agent-native/toolkit": "0.204.
|
|
92
|
+
"@agent-native/toolkit": "0.204.1-nightly-20261008065100"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@react-router/dev": "^8.1.0",
|
|
@@ -103,10 +103,10 @@
|
|
|
103
103
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
104
104
|
"vite": "8.1.0",
|
|
105
105
|
"vitest": "^4.1.5",
|
|
106
|
-
"@agent-native/core": "0.204.
|
|
106
|
+
"@agent-native/core": "0.204.1-nightly-20261008065100"
|
|
107
107
|
},
|
|
108
108
|
"peerDependencies": {
|
|
109
|
-
"@agent-native/core": "
|
|
109
|
+
"@agent-native/core": "0.204.1-nightly-20261008065100",
|
|
110
110
|
"react": ">=19.2.7",
|
|
111
111
|
"react-dom": ">=19.2.7",
|
|
112
112
|
"react-router": ">=8"
|
|
@@ -32,7 +32,7 @@ interface AutomationRun {
|
|
|
32
32
|
id: string;
|
|
33
33
|
runId: string | null;
|
|
34
34
|
threadId: string | null;
|
|
35
|
-
status: "running" | "success" | "error" | "interrupted";
|
|
35
|
+
status: "running" | "success" | "error" | "interrupted" | "skipped";
|
|
36
36
|
startedAt: number;
|
|
37
37
|
finishedAt: number | null;
|
|
38
38
|
error: string | null;
|
|
@@ -385,10 +385,24 @@ export function AutomationDetailsPanel({
|
|
|
385
385
|
) : null}
|
|
386
386
|
|
|
387
387
|
{automation.lastError ? (
|
|
388
|
-
<section
|
|
389
|
-
|
|
388
|
+
<section
|
|
389
|
+
className={
|
|
390
|
+
automation.lastStatus === "skipped"
|
|
391
|
+
? "flex items-start gap-2 border-t pt-5"
|
|
392
|
+
: "flex items-start gap-2 border-t border-destructive/30 pt-5"
|
|
393
|
+
}
|
|
394
|
+
>
|
|
395
|
+
{automation.lastStatus !== "skipped" ? (
|
|
396
|
+
<IconAlertTriangle className="mt-0.5 size-4 shrink-0 text-destructive" />
|
|
397
|
+
) : null}
|
|
390
398
|
<div className="min-w-0">
|
|
391
|
-
<h3
|
|
399
|
+
<h3
|
|
400
|
+
className={
|
|
401
|
+
automation.lastStatus === "skipped"
|
|
402
|
+
? "text-sm font-semibold text-muted-foreground"
|
|
403
|
+
: "text-sm font-semibold text-destructive"
|
|
404
|
+
}
|
|
405
|
+
>
|
|
392
406
|
Latest scheduler result
|
|
393
407
|
</h3>
|
|
394
408
|
<p className="mt-1 break-words text-sm text-muted-foreground">
|
|
@@ -455,7 +469,13 @@ export function AutomationDetailsPanel({
|
|
|
455
469
|
) : null}
|
|
456
470
|
</div>
|
|
457
471
|
{run.error ? (
|
|
458
|
-
<p
|
|
472
|
+
<p
|
|
473
|
+
className={
|
|
474
|
+
run.status === "skipped"
|
|
475
|
+
? "break-words text-sm text-muted-foreground"
|
|
476
|
+
: "break-words text-sm text-destructive"
|
|
477
|
+
}
|
|
478
|
+
>
|
|
459
479
|
{run.error}
|
|
460
480
|
</p>
|
|
461
481
|
) : null}
|
|
@@ -85,7 +85,7 @@ describe("automation-display", () => {
|
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
it("
|
|
88
|
+
it("shows skipped runs without a failure warning", () => {
|
|
89
89
|
const blocked = item({
|
|
90
90
|
id: "blocked",
|
|
91
91
|
name: "Blocked",
|
|
@@ -96,9 +96,32 @@ describe("automation-display", () => {
|
|
|
96
96
|
});
|
|
97
97
|
|
|
98
98
|
expect(automationStatus(blocked)).toEqual({
|
|
99
|
-
label: "
|
|
100
|
-
tone: "
|
|
99
|
+
label: "skipped",
|
|
100
|
+
tone: "muted",
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("does not sort skipped runs as errors", () => {
|
|
105
|
+
const base = {
|
|
106
|
+
name: "Check inbox",
|
|
107
|
+
path: "jobs/check-inbox.md",
|
|
108
|
+
owner: "user@example.com",
|
|
109
|
+
};
|
|
110
|
+
const skipped = item({
|
|
111
|
+
...base,
|
|
112
|
+
id: "skipped",
|
|
113
|
+
lastStatus: "skipped",
|
|
114
|
+
lastRun: "2026-10-05T08:00:00.000Z",
|
|
115
|
+
});
|
|
116
|
+
const successful = item({
|
|
117
|
+
...base,
|
|
118
|
+
id: "success",
|
|
119
|
+
lastStatus: "success",
|
|
120
|
+
lastRun: "2026-10-05T09:00:00.000Z",
|
|
101
121
|
});
|
|
122
|
+
expect(sortAutomations([skipped, successful]).map((row) => row.id)).toEqual(
|
|
123
|
+
["success", "skipped"],
|
|
124
|
+
);
|
|
102
125
|
});
|
|
103
126
|
|
|
104
127
|
it("identifies personal and organization ownership in the UI", () => {
|
|
@@ -81,7 +81,7 @@ export function automationStatus(item: DispatchAutomationItem): {
|
|
|
81
81
|
if (item.lastStatus === "running")
|
|
82
82
|
return { label: "Running", tone: "warning" };
|
|
83
83
|
if (item.lastStatus === "skipped")
|
|
84
|
-
return { label:
|
|
84
|
+
return { label: item.lastStatus, tone: "muted" };
|
|
85
85
|
if (item.lastStatus === "success")
|
|
86
86
|
return { label: "Healthy", tone: "success" };
|
|
87
87
|
return { label: "Ready", tone: "default" };
|
|
@@ -91,14 +91,8 @@ export function sortAutomations(
|
|
|
91
91
|
automations: DispatchAutomationItem[],
|
|
92
92
|
): DispatchAutomationItem[] {
|
|
93
93
|
return [...automations].sort((a, b) => {
|
|
94
|
-
const aError =
|
|
95
|
-
|
|
96
|
-
? 1
|
|
97
|
-
: 0;
|
|
98
|
-
const bError =
|
|
99
|
-
b.enabled && (b.lastStatus === "error" || b.lastStatus === "skipped")
|
|
100
|
-
? 1
|
|
101
|
-
: 0;
|
|
94
|
+
const aError = a.enabled && a.lastStatus === "error" ? 1 : 0;
|
|
95
|
+
const bError = b.enabled && b.lastStatus === "error" ? 1 : 0;
|
|
102
96
|
if (aError !== bError) return bError - aError;
|
|
103
97
|
return (b.lastRun || "").localeCompare(a.lastRun || "");
|
|
104
98
|
});
|
|
@@ -190,9 +190,7 @@ export default function AutomationsRoute() {
|
|
|
190
190
|
}, [ordered, query]);
|
|
191
191
|
const enabledCount = visibleAutomations.filter((item) => item.enabled).length;
|
|
192
192
|
const errorCount = visibleAutomations.filter(
|
|
193
|
-
(item) =>
|
|
194
|
-
item.enabled &&
|
|
195
|
-
(item.lastStatus === "error" || item.lastStatus === "skipped"),
|
|
193
|
+
(item) => item.enabled && item.lastStatus === "error",
|
|
196
194
|
).length;
|
|
197
195
|
const pendingToggleIdentity = toggleAutomation.isPending
|
|
198
196
|
? toggleAutomation.variables
|
|
@@ -327,7 +325,14 @@ export default function AutomationsRoute() {
|
|
|
327
325
|
</div>
|
|
328
326
|
</button>
|
|
329
327
|
{item.lastError ? (
|
|
330
|
-
<div
|
|
328
|
+
<div
|
|
329
|
+
className={cn(
|
|
330
|
+
"mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs",
|
|
331
|
+
item.lastStatus === "skipped"
|
|
332
|
+
? "text-muted-foreground"
|
|
333
|
+
: "text-destructive",
|
|
334
|
+
)}
|
|
335
|
+
>
|
|
331
336
|
<span className="min-w-0 break-words">
|
|
332
337
|
{item.lastError}
|
|
333
338
|
</span>
|