@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.11
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 +156 -0
- package/README.md +23 -8
- package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-CHDVZHHK.js} +38 -23
- package/dist/AgentCodeSnippets-CHDVZHHK.js.map +1 -0
- package/dist/AgentMetricChart-6RGWFMJE.js +15 -0
- package/dist/AgentOverview-3LJZ6MO7.js +311 -0
- package/dist/AgentOverview-3LJZ6MO7.js.map +1 -0
- package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-5GOJKT7D.js} +19 -10
- package/dist/AgentSessionEventTimeline-5GOJKT7D.js.map +1 -0
- package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-UYG3JQMP.js} +144 -57
- package/dist/AgentSessionEventTimelineChart-UYG3JQMP.js.map +1 -0
- package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-KUABCQ4W.js} +140 -27
- package/dist/AgentSessions-KUABCQ4W.js.map +1 -0
- package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-PED5C2P7.js} +162 -126
- package/dist/ConnectorSettings-PED5C2P7.js.map +1 -0
- package/dist/{DockLayout-LM4AFMFY.js → DockLayout-ACM7BVIH.js} +10 -10
- package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-SGBYRKHI.js} +14 -12
- package/dist/DrawerLayout-SGBYRKHI.js.map +1 -0
- package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-GJTVFXFY.js} +22 -28
- package/dist/ModelSettings-GJTVFXFY.js.map +1 -0
- package/dist/OpenUiFenceBlock-MJTC2VJ5.js +9 -0
- package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-VETQ7UPE.js} +17 -21
- package/dist/SandboxSettings-VETQ7UPE.js.map +1 -0
- package/dist/SchedulesPage-LHJ3U2VM.js +15 -0
- package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-5ZCU66FF.js} +9 -9
- package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-5ZCU66FF.js.map} +1 -1
- package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-SJXFKUAJ.js} +171 -26
- package/dist/ShellRouteSync-SJXFKUAJ.js.map +1 -0
- package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-TR5CAB6Q.js} +80 -58
- package/dist/SidebarLayout-TR5CAB6Q.js.map +1 -0
- package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-TRTY2YH3.js} +24 -22
- package/dist/SkillSettings-TRTY2YH3.js.map +1 -0
- package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-GZUSRZIR.js} +9 -9
- package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-2TM6I4LJ.js} +10 -10
- package/dist/{chunk-U7KURWW3.js → chunk-2GIZY3JJ.js} +276 -54
- package/dist/chunk-2GIZY3JJ.js.map +1 -0
- package/dist/{chunk-ZKNUMH2M.js → chunk-2MUK3SMR.js} +13 -11
- package/dist/chunk-2MUK3SMR.js.map +1 -0
- package/dist/{chunk-WVE3F724.js → chunk-2QTH6JHX.js} +21 -4
- package/dist/chunk-2QTH6JHX.js.map +1 -0
- package/dist/{chunk-XAU7QFG3.js → chunk-5N5V7YLO.js} +72 -256
- package/dist/chunk-5N5V7YLO.js.map +1 -0
- package/dist/{chunk-CYHJDKFB.js → chunk-75YEQUUD.js} +189 -52
- package/dist/chunk-75YEQUUD.js.map +1 -0
- package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
- package/dist/chunk-7AAO4UDQ.js.map +1 -0
- package/dist/{chunk-M62XY4NC.js → chunk-BXG6XN2S.js} +235 -108
- package/dist/chunk-BXG6XN2S.js.map +1 -0
- package/dist/chunk-GKXDRULM.js +587 -0
- package/dist/chunk-GKXDRULM.js.map +1 -0
- package/dist/{chunk-ZTMKFZQ3.js → chunk-OH357IHR.js} +5572 -3367
- package/dist/chunk-OH357IHR.js.map +1 -0
- package/dist/{chunk-DMMZSZTN.js → chunk-P6MZDITS.js} +60 -16
- package/dist/chunk-P6MZDITS.js.map +1 -0
- package/dist/{chunk-MPNSO7E6.js → chunk-SLMFEG7X.js} +2 -2
- package/dist/chunk-T6QQV5LK.js +238 -0
- package/dist/chunk-T6QQV5LK.js.map +1 -0
- package/dist/{chunk-6O6FWUDW.js → chunk-UWLL327M.js} +641 -388
- package/dist/chunk-UWLL327M.js.map +1 -0
- package/dist/{chunk-FJW36PD7.js → chunk-VAOCM3QQ.js} +28 -24
- package/dist/chunk-VAOCM3QQ.js.map +1 -0
- package/dist/chunk-Y7O6CMC7.js +517 -0
- package/dist/chunk-Y7O6CMC7.js.map +1 -0
- package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
- package/dist/index.d.ts +377 -108
- package/dist/index.js +69 -488
- package/dist/index.js.map +1 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +49 -14
- package/dist/plugins/trueforge-agent-server-adapter/index.js +161 -60
- package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -4
- package/dist/AgentCodeSnippets-NZOFJE57.js.map +0 -1
- package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
- package/dist/AgentOverview-EEBHJC32.js +0 -167
- package/dist/AgentOverview-EEBHJC32.js.map +0 -1
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
- package/dist/AgentSessions-3MPDZASK.js.map +0 -1
- package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
- package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
- package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
- package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
- package/dist/SchedulesPage-KKLUDO6B.js +0 -15
- package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
- package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
- package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
- package/dist/chunk-2XPPBEYF.js +0 -74
- package/dist/chunk-2XPPBEYF.js.map +0 -1
- package/dist/chunk-6O6FWUDW.js.map +0 -1
- package/dist/chunk-7Z2C2K7F.js +0 -578
- package/dist/chunk-7Z2C2K7F.js.map +0 -1
- package/dist/chunk-CYHJDKFB.js.map +0 -1
- package/dist/chunk-DMMZSZTN.js.map +0 -1
- package/dist/chunk-FJW36PD7.js.map +0 -1
- package/dist/chunk-M62XY4NC.js.map +0 -1
- package/dist/chunk-QC42MLAK.js.map +0 -1
- package/dist/chunk-SFZNIO6U.js +0 -18
- package/dist/chunk-SFZNIO6U.js.map +0 -1
- package/dist/chunk-U7KURWW3.js.map +0 -1
- package/dist/chunk-WVE3F724.js.map +0 -1
- package/dist/chunk-XAU7QFG3.js.map +0 -1
- package/dist/chunk-ZKNUMH2M.js.map +0 -1
- package/dist/chunk-ZTMKFZQ3.js.map +0 -1
- /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-6RGWFMJE.js.map} +0 -0
- /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-ACM7BVIH.js.map} +0 -0
- /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-MJTC2VJ5.js.map} +0 -0
- /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-LHJ3U2VM.js.map} +0 -0
- /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-GZUSRZIR.js.map} +0 -0
- /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-2TM6I4LJ.js.map} +0 -0
- /package/dist/{chunk-MPNSO7E6.js.map → chunk-SLMFEG7X.js.map} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button,
|
|
3
3
|
ConnectorConnectButton,
|
|
4
|
+
CreatedByCell,
|
|
4
5
|
DEFAULT_TABLE_PAGE_SIZE,
|
|
5
6
|
Dialog,
|
|
6
7
|
DialogContent,
|
|
@@ -23,33 +24,266 @@ import {
|
|
|
23
24
|
TableTokenPagination,
|
|
24
25
|
Tooltip,
|
|
25
26
|
auiInputClass,
|
|
27
|
+
auiSelectMenuClass,
|
|
28
|
+
auiSelectOptionClass,
|
|
29
|
+
auiSelectTriggerClass,
|
|
30
|
+
hasCreatedBySubject,
|
|
26
31
|
mountName,
|
|
27
|
-
|
|
32
|
+
themePortalRoot,
|
|
33
|
+
useResourcePermissions,
|
|
34
|
+
useSlot,
|
|
28
35
|
useToasterOptional
|
|
29
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-OH357IHR.js";
|
|
30
37
|
import {
|
|
38
|
+
findLibraryAgent,
|
|
31
39
|
readScheduleShareSearch,
|
|
32
|
-
replaceScheduleShareSearch
|
|
33
|
-
|
|
40
|
+
replaceScheduleShareSearch,
|
|
41
|
+
useSearchAgentsList
|
|
42
|
+
} from "./chunk-T6QQV5LK.js";
|
|
34
43
|
import {
|
|
35
44
|
DraftCatalogProvider,
|
|
36
45
|
Icon,
|
|
37
46
|
PageHeader,
|
|
38
47
|
auiButtonClass,
|
|
39
48
|
useDraftCatalog
|
|
40
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-5N5V7YLO.js";
|
|
41
50
|
import {
|
|
42
51
|
libraryAgentId,
|
|
43
52
|
useOptionalCatalogServer,
|
|
53
|
+
useOptionalShellMode,
|
|
44
54
|
useScheduleServer,
|
|
45
55
|
useServer
|
|
46
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-2GIZY3JJ.js";
|
|
47
57
|
import {
|
|
48
58
|
cn
|
|
49
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-GKXDRULM.js";
|
|
50
60
|
|
|
51
61
|
// src/atoms/schedules/SchedulesPage.tsx
|
|
52
|
-
import { useCallback, useEffect as
|
|
62
|
+
import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
|
|
63
|
+
|
|
64
|
+
// src/atoms/AgentSearchPicker.tsx
|
|
65
|
+
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
66
|
+
import { createPortal } from "react-dom";
|
|
67
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
68
|
+
function AgentSearchPicker({
|
|
69
|
+
value,
|
|
70
|
+
selectedLabel,
|
|
71
|
+
onValueChange,
|
|
72
|
+
onAgentPicked,
|
|
73
|
+
disabled = false,
|
|
74
|
+
onBuildAgent,
|
|
75
|
+
allOption,
|
|
76
|
+
"aria-label": ariaLabel = "Agent",
|
|
77
|
+
placeholder = "Search agent",
|
|
78
|
+
className
|
|
79
|
+
}) {
|
|
80
|
+
const [open, setOpen] = useState(false);
|
|
81
|
+
const [query, setQuery] = useState("");
|
|
82
|
+
const [pos, setPos] = useState(null);
|
|
83
|
+
const rootRef = useRef(null);
|
|
84
|
+
const triggerRef = useRef(null);
|
|
85
|
+
const inputRef = useRef(null);
|
|
86
|
+
const menuRef = useRef(null);
|
|
87
|
+
const listboxId = useId();
|
|
88
|
+
const { agents, isInitialLoading, isSearching, loadingMore, hasMore, error, listRef, sentinelRef } = useSearchAgentsList({
|
|
89
|
+
enabled: open && !disabled,
|
|
90
|
+
query
|
|
91
|
+
});
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (!open) setQuery("");
|
|
94
|
+
}, [open]);
|
|
95
|
+
useLayoutEffect(() => {
|
|
96
|
+
if (!open) {
|
|
97
|
+
setPos(null);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const update = () => {
|
|
101
|
+
const el = triggerRef.current;
|
|
102
|
+
if (!el) return;
|
|
103
|
+
const rect = el.getBoundingClientRect();
|
|
104
|
+
setPos({
|
|
105
|
+
top: rect.bottom + 4,
|
|
106
|
+
left: rect.left,
|
|
107
|
+
width: rect.width
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
update();
|
|
111
|
+
window.addEventListener("scroll", update, true);
|
|
112
|
+
window.addEventListener("resize", update);
|
|
113
|
+
return () => {
|
|
114
|
+
window.removeEventListener("scroll", update, true);
|
|
115
|
+
window.removeEventListener("resize", update);
|
|
116
|
+
};
|
|
117
|
+
}, [open]);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (!open) return;
|
|
120
|
+
const handlePointerDown = (event) => {
|
|
121
|
+
if (!(event.target instanceof Node)) return;
|
|
122
|
+
if (rootRef.current?.contains(event.target)) return;
|
|
123
|
+
if (menuRef.current?.contains(event.target)) return;
|
|
124
|
+
setOpen(false);
|
|
125
|
+
};
|
|
126
|
+
document.addEventListener("mousedown", handlePointerDown);
|
|
127
|
+
return () => document.removeEventListener("mousedown", handlePointerDown);
|
|
128
|
+
}, [open]);
|
|
129
|
+
const close = () => {
|
|
130
|
+
setOpen(false);
|
|
131
|
+
setQuery("");
|
|
132
|
+
inputRef.current?.blur();
|
|
133
|
+
};
|
|
134
|
+
const pick = (agent) => {
|
|
135
|
+
const id = libraryAgentId(agent);
|
|
136
|
+
onValueChange(id);
|
|
137
|
+
onAgentPicked?.(agent);
|
|
138
|
+
close();
|
|
139
|
+
};
|
|
140
|
+
const pickAll = () => {
|
|
141
|
+
if (allOption == null) return;
|
|
142
|
+
onValueChange(allOption.value);
|
|
143
|
+
close();
|
|
144
|
+
};
|
|
145
|
+
const inputValue = open ? query : selectedLabel;
|
|
146
|
+
const queryTrimmed = query.trim();
|
|
147
|
+
const showError = !isInitialLoading && error != null;
|
|
148
|
+
const showEmptyCatalog = !isInitialLoading && error == null && agents.length === 0 && queryTrimmed === "";
|
|
149
|
+
const showNoMatch = !isInitialLoading && error == null && agents.length === 0 && queryTrimmed !== "";
|
|
150
|
+
const menu = open && pos != null && !disabled ? createPortal(
|
|
151
|
+
/* @__PURE__ */ jsxs(
|
|
152
|
+
"div",
|
|
153
|
+
{
|
|
154
|
+
ref: menuRef,
|
|
155
|
+
className: auiSelectMenuClass("fixed z-[200] flex max-h-64 flex-col overflow-hidden"),
|
|
156
|
+
style: {
|
|
157
|
+
top: pos.top,
|
|
158
|
+
left: pos.left,
|
|
159
|
+
width: pos.width
|
|
160
|
+
},
|
|
161
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
162
|
+
children: [
|
|
163
|
+
/* @__PURE__ */ jsxs(
|
|
164
|
+
"div",
|
|
165
|
+
{
|
|
166
|
+
ref: listRef,
|
|
167
|
+
id: listboxId,
|
|
168
|
+
role: "listbox",
|
|
169
|
+
"aria-label": ariaLabel,
|
|
170
|
+
className: "min-h-0 flex-1 overflow-y-auto p-1",
|
|
171
|
+
children: [
|
|
172
|
+
allOption != null && queryTrimmed === "" ? /* @__PURE__ */ jsxs(
|
|
173
|
+
"button",
|
|
174
|
+
{
|
|
175
|
+
type: "button",
|
|
176
|
+
role: "option",
|
|
177
|
+
"aria-selected": value === allOption.value,
|
|
178
|
+
className: auiSelectOptionClass(),
|
|
179
|
+
onClick: pickAll,
|
|
180
|
+
children: [
|
|
181
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: allOption.label }),
|
|
182
|
+
/* @__PURE__ */ jsx(
|
|
183
|
+
Icon,
|
|
184
|
+
{
|
|
185
|
+
name: "check",
|
|
186
|
+
className: cn("ml-auto size-4 shrink-0", value === allOption.value ? "opacity-100" : "opacity-0")
|
|
187
|
+
}
|
|
188
|
+
)
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
) : null,
|
|
192
|
+
isInitialLoading ? /* @__PURE__ */ jsx("p", { className: "text-text-secondary px-3 py-5 text-center text-sm", role: "status", children: "Loading\u2026" }) : showError ? /* @__PURE__ */ jsx("p", { className: "text-failure-bg px-3 py-5 text-center text-sm", role: "alert", children: error }) : showEmptyCatalog ? /* @__PURE__ */ jsx("p", { className: "text-text-secondary px-3 py-5 text-center text-sm", children: "No Agents created yet" }) : showNoMatch ? /* @__PURE__ */ jsxs("p", { className: "text-text-secondary px-3 py-5 text-center text-sm", role: "status", children: [
|
|
193
|
+
'No agents match "',
|
|
194
|
+
queryTrimmed,
|
|
195
|
+
'".'
|
|
196
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
197
|
+
isSearching ? /* @__PURE__ */ jsx("p", { className: "sr-only", role: "status", children: "Searching\u2026" }) : null,
|
|
198
|
+
agents.map((agent) => {
|
|
199
|
+
const id = libraryAgentId(agent);
|
|
200
|
+
const selected = value === id;
|
|
201
|
+
return /* @__PURE__ */ jsxs(
|
|
202
|
+
"button",
|
|
203
|
+
{
|
|
204
|
+
type: "button",
|
|
205
|
+
role: "option",
|
|
206
|
+
"aria-selected": selected,
|
|
207
|
+
className: auiSelectOptionClass(),
|
|
208
|
+
onClick: () => pick(agent),
|
|
209
|
+
children: [
|
|
210
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: agent.name }),
|
|
211
|
+
/* @__PURE__ */ jsx(
|
|
212
|
+
Icon,
|
|
213
|
+
{
|
|
214
|
+
name: "check",
|
|
215
|
+
className: cn("ml-auto size-4 shrink-0", selected ? "opacity-100" : "opacity-0")
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
id
|
|
221
|
+
);
|
|
222
|
+
}),
|
|
223
|
+
hasMore ? /* @__PURE__ */ jsx("div", { ref: sentinelRef, className: "flex h-6 shrink-0 items-center justify-center", "aria-hidden": true, children: loadingMore ? /* @__PURE__ */ jsx("span", { className: "text-text-secondary text-[11px]", role: "status", children: "Loading more\u2026" }) : null }) : null
|
|
224
|
+
] })
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
),
|
|
228
|
+
showEmptyCatalog && onBuildAgent != null ? /* @__PURE__ */ jsx("div", { className: "flex justify-end border-t border-border px-2 pt-2", children: /* @__PURE__ */ jsxs(Button.Ghost, { type: "button", onClick: onBuildAgent, children: [
|
|
229
|
+
/* @__PURE__ */ jsx(Icon, { name: "plus", className: "size-3.5" }),
|
|
230
|
+
"Build Agent"
|
|
231
|
+
] }) }) : null
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
),
|
|
235
|
+
themePortalRoot(rootRef.current)
|
|
236
|
+
) : null;
|
|
237
|
+
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative", className), children: [
|
|
238
|
+
/* @__PURE__ */ jsxs(
|
|
239
|
+
"div",
|
|
240
|
+
{
|
|
241
|
+
ref: triggerRef,
|
|
242
|
+
className: auiSelectTriggerClass(disabled ? "cursor-not-allowed opacity-50" : "cursor-text"),
|
|
243
|
+
children: [
|
|
244
|
+
/* @__PURE__ */ jsx(
|
|
245
|
+
"input",
|
|
246
|
+
{
|
|
247
|
+
ref: inputRef,
|
|
248
|
+
type: "text",
|
|
249
|
+
role: "combobox",
|
|
250
|
+
"aria-label": ariaLabel,
|
|
251
|
+
"aria-expanded": open,
|
|
252
|
+
"aria-controls": open ? listboxId : void 0,
|
|
253
|
+
"aria-autocomplete": "list",
|
|
254
|
+
disabled,
|
|
255
|
+
placeholder,
|
|
256
|
+
value: inputValue,
|
|
257
|
+
className: "min-w-0 flex-1 bg-transparent outline-none placeholder:text-text-secondary/70 disabled:cursor-not-allowed",
|
|
258
|
+
onFocus: () => {
|
|
259
|
+
if (!disabled) setOpen(true);
|
|
260
|
+
},
|
|
261
|
+
onChange: (event) => {
|
|
262
|
+
if (disabled) return;
|
|
263
|
+
setQuery(event.target.value);
|
|
264
|
+
setOpen(true);
|
|
265
|
+
},
|
|
266
|
+
onKeyDown: (event) => {
|
|
267
|
+
if (event.key === "Escape") {
|
|
268
|
+
event.preventDefault();
|
|
269
|
+
setOpen(false);
|
|
270
|
+
inputRef.current?.blur();
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (event.key === "ArrowDown" && !open && !disabled) {
|
|
274
|
+
event.preventDefault();
|
|
275
|
+
setOpen(true);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
),
|
|
280
|
+
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", className: "size-4 shrink-0 text-text-secondary" })
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
),
|
|
284
|
+
menu
|
|
285
|
+
] });
|
|
286
|
+
}
|
|
53
287
|
|
|
54
288
|
// src/atoms/schedules/cadence.ts
|
|
55
289
|
var TIMEZONE_OPTIONS = [
|
|
@@ -255,10 +489,10 @@ function formatRelativeTime(iso, nowMs = Date.now()) {
|
|
|
255
489
|
}
|
|
256
490
|
|
|
257
491
|
// src/atoms/schedules/ScheduleFormDrawer.tsx
|
|
258
|
-
import { useEffect as
|
|
492
|
+
import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
|
|
259
493
|
|
|
260
494
|
// src/atoms/schedules/ScheduleFormFields.tsx
|
|
261
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
495
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
262
496
|
var RECURRENCE_OPTIONS = [
|
|
263
497
|
{ value: "hourly", label: "Hourly" },
|
|
264
498
|
{ value: "daily", label: "Daily" },
|
|
@@ -276,9 +510,11 @@ function ScheduleFormFields({
|
|
|
276
510
|
values,
|
|
277
511
|
onChange,
|
|
278
512
|
agentId,
|
|
513
|
+
agentLabel,
|
|
279
514
|
onAgentIdChange,
|
|
280
|
-
|
|
281
|
-
agentPickerDisabled = false
|
|
515
|
+
onAgentPicked,
|
|
516
|
+
agentPickerDisabled = false,
|
|
517
|
+
onBuildAgent
|
|
282
518
|
}) {
|
|
283
519
|
const cron = valuesToCron(values);
|
|
284
520
|
const cadence = formatCadenceSummary({ cron, timezone: values.timezone });
|
|
@@ -291,37 +527,39 @@ function ScheduleFormFields({
|
|
|
291
527
|
const weekdays = has ? values.weekdays.filter((d) => d !== day) : [...values.weekdays, day];
|
|
292
528
|
onChange({ ...values, weekdays: weekdays.length > 0 ? weekdays : [day] });
|
|
293
529
|
};
|
|
294
|
-
return /* @__PURE__ */
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
/* @__PURE__ */
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
|
|
530
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-4 px-5 py-4", children: [
|
|
531
|
+
/* @__PURE__ */ jsxs2("div", { className: "block", children: [
|
|
532
|
+
/* @__PURE__ */ jsx2("span", { className: "mb-1.5 block text-sm font-medium", children: "Agent" }),
|
|
533
|
+
/* @__PURE__ */ jsx2(
|
|
534
|
+
AgentSearchPicker,
|
|
299
535
|
{
|
|
300
536
|
"aria-label": "Agent",
|
|
301
|
-
placeholder: "
|
|
537
|
+
placeholder: "Search agent",
|
|
302
538
|
value: agentId,
|
|
303
|
-
|
|
539
|
+
selectedLabel: agentLabel,
|
|
304
540
|
onValueChange: (value) => onAgentIdChange?.(value),
|
|
305
|
-
|
|
541
|
+
onAgentPicked,
|
|
542
|
+
disabled: agentPickerDisabled || onAgentIdChange == null,
|
|
543
|
+
onBuildAgent
|
|
306
544
|
}
|
|
307
545
|
)
|
|
308
546
|
] }),
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
/* @__PURE__ */
|
|
311
|
-
/* @__PURE__ */
|
|
547
|
+
/* @__PURE__ */ jsxs2("label", { className: "block", children: [
|
|
548
|
+
/* @__PURE__ */ jsx2("span", { className: "mb-1.5 block text-sm font-medium", children: "Name" }),
|
|
549
|
+
/* @__PURE__ */ jsx2(
|
|
312
550
|
"input",
|
|
313
551
|
{
|
|
314
552
|
value: values.name,
|
|
315
553
|
onChange: (e) => set("name", e.target.value),
|
|
316
554
|
placeholder: "harness-daily-digest",
|
|
317
|
-
className: auiInputClass("h-
|
|
555
|
+
className: auiInputClass("h-8"),
|
|
318
556
|
required: true
|
|
319
557
|
}
|
|
320
558
|
)
|
|
321
559
|
] }),
|
|
322
|
-
/* @__PURE__ */
|
|
323
|
-
/* @__PURE__ */
|
|
324
|
-
/* @__PURE__ */
|
|
560
|
+
/* @__PURE__ */ jsxs2("label", { className: "block", children: [
|
|
561
|
+
/* @__PURE__ */ jsx2("span", { className: "mb-1.5 block text-sm font-medium", children: "Task" }),
|
|
562
|
+
/* @__PURE__ */ jsx2(
|
|
325
563
|
"textarea",
|
|
326
564
|
{
|
|
327
565
|
value: values.task,
|
|
@@ -333,114 +571,103 @@ function ScheduleFormFields({
|
|
|
333
571
|
}
|
|
334
572
|
)
|
|
335
573
|
] }),
|
|
336
|
-
/* @__PURE__ */
|
|
337
|
-
/* @__PURE__ */
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
/* @__PURE__ */
|
|
422
|
-
|
|
423
|
-
{
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
onValueChange: (value) => set("timezone", value),
|
|
428
|
-
menuPlacement: "top"
|
|
429
|
-
}
|
|
430
|
-
)
|
|
431
|
-
] }),
|
|
432
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-secondary-bg/40 px-3 py-3", children: [
|
|
433
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
434
|
-
/* @__PURE__ */ jsx("span", { className: "text-text-secondary text-[10px] font-semibold tracking-wide uppercase", children: "Frequency" }),
|
|
435
|
-
/* @__PURE__ */ jsx("code", { className: "text-text-secondary font-mono text-xs", children: cron || "\u2014" })
|
|
436
|
-
] }),
|
|
437
|
-
/* @__PURE__ */ jsx("p", { className: "text-text-primary mt-1 text-sm font-semibold", children: cadence || "\u2014" })
|
|
574
|
+
/* @__PURE__ */ jsxs2("fieldset", { children: [
|
|
575
|
+
/* @__PURE__ */ jsx2("legend", { className: "mb-1.5 text-sm font-medium", children: "Frequency" }),
|
|
576
|
+
/* @__PURE__ */ jsx2("div", { className: "rounded-t-lg border border-border p-4", children: /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-4", children: [
|
|
577
|
+
/* @__PURE__ */ jsx2("div", { className: "grid grid-cols-3 gap-1 rounded-lg border border-border bg-primary-bg p-1", children: RECURRENCE_OPTIONS.map((opt) => {
|
|
578
|
+
const selected = values.recurrence === opt.value;
|
|
579
|
+
return /* @__PURE__ */ jsx2(
|
|
580
|
+
"button",
|
|
581
|
+
{
|
|
582
|
+
type: "button",
|
|
583
|
+
className: cn(
|
|
584
|
+
"rounded-md border px-2 py-2 text-sm font-medium transition-colors",
|
|
585
|
+
selected ? "border-primary-button-bg/40 bg-primary-button-bg/10 font-semibold text-primary-button-bg" : "border-transparent text-text-secondary hover:bg-ghost-button-hover"
|
|
586
|
+
),
|
|
587
|
+
"aria-pressed": selected,
|
|
588
|
+
onClick: () => set("recurrence", opt.value),
|
|
589
|
+
children: opt.label
|
|
590
|
+
},
|
|
591
|
+
opt.value
|
|
592
|
+
);
|
|
593
|
+
}) }),
|
|
594
|
+
values.recurrence === "custom" ? /* @__PURE__ */ jsxs2("div", { className: "rounded-md border border-border bg-secondary-bg/40 px-3 py-2", children: [
|
|
595
|
+
/* @__PURE__ */ jsx2("span", { className: "block text-xs text-text-secondary", children: "Existing custom schedule" }),
|
|
596
|
+
/* @__PURE__ */ jsx2("code", { className: "mt-1 block font-mono text-sm text-text-primary", children: values.customCron }),
|
|
597
|
+
/* @__PURE__ */ jsx2("span", { className: "mt-1 block text-xs text-text-secondary", children: "Select Hourly, Daily, or Weekly to replace this schedule." })
|
|
598
|
+
] }) : null,
|
|
599
|
+
values.recurrence === "weekly" ? /* @__PURE__ */ jsxs2("fieldset", { children: [
|
|
600
|
+
/* @__PURE__ */ jsx2("legend", { className: "mb-2 text-sm font-medium", children: "Days" }),
|
|
601
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: WEEKDAY_OPTIONS.map((day) => {
|
|
602
|
+
const selected = values.weekdays.includes(day.value);
|
|
603
|
+
return /* @__PURE__ */ jsx2(
|
|
604
|
+
"button",
|
|
605
|
+
{
|
|
606
|
+
type: "button",
|
|
607
|
+
className: cn(
|
|
608
|
+
"min-w-0 flex-1 rounded-md border px-3 py-2 text-[0.8125rem] font-medium",
|
|
609
|
+
selected ? "border-primary-button-bg/40 bg-primary-button-bg/10 font-semibold text-primary-button-bg" : "border-border text-text-secondary hover:bg-ghost-button-hover"
|
|
610
|
+
),
|
|
611
|
+
"aria-pressed": selected,
|
|
612
|
+
onClick: () => toggleWeekday(day.value),
|
|
613
|
+
children: day.label
|
|
614
|
+
},
|
|
615
|
+
day.value
|
|
616
|
+
);
|
|
617
|
+
}) })
|
|
618
|
+
] }) : null,
|
|
619
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex gap-4", children: [
|
|
620
|
+
values.recurrence === "daily" || values.recurrence === "weekly" ? /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
621
|
+
/* @__PURE__ */ jsx2("span", { className: "mb-1.5 block text-sm font-medium", children: "Hour" }),
|
|
622
|
+
/* @__PURE__ */ jsx2(
|
|
623
|
+
PopoverSelect,
|
|
624
|
+
{
|
|
625
|
+
"aria-label": "Hour",
|
|
626
|
+
value: String(values.hour),
|
|
627
|
+
options: HOUR_OPTIONS,
|
|
628
|
+
onValueChange: (value) => set("hour", Number(value))
|
|
629
|
+
}
|
|
630
|
+
)
|
|
631
|
+
] }) : null,
|
|
632
|
+
values.recurrence !== "custom" ? /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
633
|
+
/* @__PURE__ */ jsx2("span", { className: "mb-1.5 block text-sm font-medium", children: "Minute" }),
|
|
634
|
+
/* @__PURE__ */ jsx2(
|
|
635
|
+
PopoverSelect,
|
|
636
|
+
{
|
|
637
|
+
"aria-label": "Minute",
|
|
638
|
+
value: String(values.minute),
|
|
639
|
+
options: MINUTE_OPTIONS,
|
|
640
|
+
onValueChange: (value) => set("minute", Number(value))
|
|
641
|
+
}
|
|
642
|
+
)
|
|
643
|
+
] }) : null,
|
|
644
|
+
/* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
645
|
+
/* @__PURE__ */ jsx2("span", { className: "mb-1.5 block text-sm font-medium", children: "Timezone" }),
|
|
646
|
+
/* @__PURE__ */ jsx2(
|
|
647
|
+
PopoverSelect,
|
|
648
|
+
{
|
|
649
|
+
"aria-label": "Timezone",
|
|
650
|
+
value: values.timezone,
|
|
651
|
+
options: timezoneOptions,
|
|
652
|
+
onValueChange: (value) => set("timezone", value),
|
|
653
|
+
menuClassName: "w-full min-w-0"
|
|
654
|
+
}
|
|
655
|
+
)
|
|
656
|
+
] })
|
|
657
|
+
] })
|
|
658
|
+
] }) }),
|
|
659
|
+
/* @__PURE__ */ jsx2("div", { className: "rounded-b-lg border border-t-0 border-border bg-primary-button-bg/10 px-4 py-3", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
660
|
+
/* @__PURE__ */ jsx2(Icon, { name: "clock", className: "size-4 shrink-0 text-primary-button-bg" }),
|
|
661
|
+
/* @__PURE__ */ jsx2("span", { className: "shrink-0 text-xs font-medium text-text-secondary", children: "Schedule" }),
|
|
662
|
+
/* @__PURE__ */ jsx2("p", { className: "min-w-0 flex-1 truncate text-sm text-text-primary", children: cadence || "\u2014" }),
|
|
663
|
+
/* @__PURE__ */ jsx2("code", { className: "shrink-0 whitespace-nowrap font-mono text-[0.8125rem] font-bold text-text-secondary", children: cron || "\u2014" })
|
|
664
|
+
] }) })
|
|
438
665
|
] })
|
|
439
666
|
] });
|
|
440
667
|
}
|
|
441
668
|
|
|
442
669
|
// src/atoms/schedules/TestScheduleScreen.tsx
|
|
443
|
-
import { useEffect, useState } from "react";
|
|
670
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
444
671
|
|
|
445
672
|
// src/atoms/schedules/scheduleRuns.ts
|
|
446
673
|
function isManualRun(name) {
|
|
@@ -477,20 +704,20 @@ function formatScheduleRunInstant(iso) {
|
|
|
477
704
|
}
|
|
478
705
|
|
|
479
706
|
// src/atoms/schedules/ScheduleRunTooltip.tsx
|
|
480
|
-
import { jsx as
|
|
707
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
481
708
|
function ScheduleRunTooltip({ run }) {
|
|
482
|
-
return /* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
484
|
-
/* @__PURE__ */
|
|
485
|
-
/* @__PURE__ */
|
|
709
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1 text-left text-xs", children: [
|
|
710
|
+
/* @__PURE__ */ jsx3("p", { className: "text-text-primary font-medium", children: runStatusLabel(run.status) }),
|
|
711
|
+
/* @__PURE__ */ jsx3("p", { className: "text-text-secondary", children: runTypeLabel(run.name) }),
|
|
712
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-text-secondary", children: [
|
|
486
713
|
"Scheduled for: ",
|
|
487
714
|
formatScheduleRunInstant(run.scheduledFor)
|
|
488
715
|
] }),
|
|
489
|
-
run.triggeredAt != null ? /* @__PURE__ */
|
|
716
|
+
run.triggeredAt != null ? /* @__PURE__ */ jsxs3("p", { className: "text-text-secondary", children: [
|
|
490
717
|
"Triggered at: ",
|
|
491
718
|
formatScheduleRunInstant(run.triggeredAt)
|
|
492
719
|
] }) : null,
|
|
493
|
-
/* @__PURE__ */
|
|
720
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-text-secondary", children: [
|
|
494
721
|
"Triggered by: ",
|
|
495
722
|
run.triggeredBy
|
|
496
723
|
] })
|
|
@@ -498,7 +725,7 @@ function ScheduleRunTooltip({ run }) {
|
|
|
498
725
|
}
|
|
499
726
|
|
|
500
727
|
// src/atoms/schedules/ScheduleRunChip.tsx
|
|
501
|
-
import { jsx as
|
|
728
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
502
729
|
var CHIP_STYLES = {
|
|
503
730
|
success: "border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300",
|
|
504
731
|
failed: "border-red-600/30 bg-red-500/10 text-red-700 dark:border-red-400/35 dark:bg-red-500/15 dark:text-red-300"
|
|
@@ -506,34 +733,34 @@ var CHIP_STYLES = {
|
|
|
506
733
|
function ScheduleRunChip({ run }) {
|
|
507
734
|
const kind = runChipKind(run.status);
|
|
508
735
|
const when = formatScheduleRunInstant(run.triggeredAt ?? run.scheduledFor);
|
|
509
|
-
return /* @__PURE__ */
|
|
736
|
+
return /* @__PURE__ */ jsx4(Tooltip, { content: /* @__PURE__ */ jsx4(ScheduleRunTooltip, { run }), side: "top", children: /* @__PURE__ */ jsx4(
|
|
510
737
|
"span",
|
|
511
738
|
{
|
|
512
739
|
className: cn("inline-flex size-6 shrink-0 items-center justify-center rounded-md border", CHIP_STYLES[kind]),
|
|
513
740
|
"aria-label": `${runStatusLabel(run.status)} run at ${when}`,
|
|
514
|
-
children: /* @__PURE__ */
|
|
741
|
+
children: /* @__PURE__ */ jsx4(Icon, { name: kind === "failed" ? "triangle-exclamation" : "check", className: "size-3.5" })
|
|
515
742
|
}
|
|
516
743
|
) });
|
|
517
744
|
}
|
|
518
745
|
|
|
519
746
|
// src/atoms/schedules/ScheduleStatusBadge.tsx
|
|
520
|
-
import { jsx as
|
|
747
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
521
748
|
function ScheduleStatusBadge({ status }) {
|
|
522
749
|
const active = status === "active";
|
|
523
|
-
return /* @__PURE__ */
|
|
750
|
+
return /* @__PURE__ */ jsxs4(
|
|
524
751
|
"span",
|
|
525
752
|
{
|
|
526
753
|
className: cn(
|
|
527
754
|
"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium",
|
|
528
|
-
active ? "border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300" : "border-
|
|
755
|
+
active ? "border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300" : "border-amber-600/30 bg-amber-500/10 text-amber-800 dark:border-amber-400/35 dark:bg-amber-500/15 dark:text-amber-300"
|
|
529
756
|
),
|
|
530
757
|
children: [
|
|
531
|
-
/* @__PURE__ */
|
|
758
|
+
/* @__PURE__ */ jsx5(
|
|
532
759
|
"span",
|
|
533
760
|
{
|
|
534
761
|
className: cn(
|
|
535
762
|
"size-1.5 shrink-0 rounded-full",
|
|
536
|
-
active ? "bg-emerald-600 dark:bg-emerald-400" : "bg-
|
|
763
|
+
active ? "bg-emerald-600 dark:bg-emerald-400" : "bg-amber-600 dark:bg-amber-400"
|
|
537
764
|
),
|
|
538
765
|
"aria-hidden": true
|
|
539
766
|
}
|
|
@@ -545,7 +772,7 @@ function ScheduleStatusBadge({ status }) {
|
|
|
545
772
|
}
|
|
546
773
|
|
|
547
774
|
// src/atoms/schedules/TestScheduleScreen.tsx
|
|
548
|
-
import { jsx as
|
|
775
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
549
776
|
function mountConnector(connectors, name) {
|
|
550
777
|
return connectors.find((connector) => connector.name === name || connector.id === name) ?? null;
|
|
551
778
|
}
|
|
@@ -555,20 +782,20 @@ function ScheduleMcpConnect({
|
|
|
555
782
|
}) {
|
|
556
783
|
const catalog = useOptionalCatalogServer();
|
|
557
784
|
if (catalog == null) return null;
|
|
558
|
-
return /* @__PURE__ */
|
|
785
|
+
return /* @__PURE__ */ jsx6(ConnectorConnectButton, { connector, onConnected });
|
|
559
786
|
}
|
|
560
787
|
function DetailRow({ label, children }) {
|
|
561
|
-
return /* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
788
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex items-start justify-between gap-3 border-b border-border px-3 py-2.5 last:border-b-0", children: [
|
|
789
|
+
/* @__PURE__ */ jsx6("span", { className: "text-text-secondary shrink-0 text-[10px] font-semibold tracking-wide uppercase", children: label }),
|
|
790
|
+
/* @__PURE__ */ jsx6("div", { className: "min-w-0 text-right text-sm text-text-primary", children })
|
|
564
791
|
] });
|
|
565
792
|
}
|
|
566
793
|
function TestScheduleScreen({ schedule, agentName, mcpMounts, onEditConfiguration }) {
|
|
567
794
|
const scheduleServer = useScheduleServer();
|
|
568
795
|
const toaster = useToasterOptional();
|
|
569
796
|
const { connectors, ensureLoaded, refreshConnectors, loading, error } = useDraftCatalog();
|
|
570
|
-
const [running, setRunning] =
|
|
571
|
-
const [lastTestRun, setLastTestRun] =
|
|
797
|
+
const [running, setRunning] = useState2(false);
|
|
798
|
+
const [lastTestRun, setLastTestRun] = useState2(null);
|
|
572
799
|
const cadence = formatCadenceSummary({ cron: schedule.cron, timezone: schedule.timezone });
|
|
573
800
|
const handleRunTest = async () => {
|
|
574
801
|
setRunning(true);
|
|
@@ -582,35 +809,35 @@ function TestScheduleScreen({ schedule, agentName, mcpMounts, onEditConfiguratio
|
|
|
582
809
|
setRunning(false);
|
|
583
810
|
}
|
|
584
811
|
};
|
|
585
|
-
|
|
812
|
+
useEffect2(() => {
|
|
586
813
|
ensureLoaded();
|
|
587
814
|
}, [ensureLoaded]);
|
|
588
|
-
|
|
815
|
+
useEffect2(() => {
|
|
589
816
|
if (error != null) toaster?.showError(error);
|
|
590
817
|
}, [error, toaster]);
|
|
591
|
-
return /* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
593
|
-
/* @__PURE__ */
|
|
594
|
-
/* @__PURE__ */
|
|
595
|
-
/* @__PURE__ */
|
|
596
|
-
/* @__PURE__ */
|
|
597
|
-
|
|
598
|
-
/* @__PURE__ */
|
|
818
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-4 px-5 py-4", children: [
|
|
819
|
+
/* @__PURE__ */ jsxs5("section", { className: "overflow-hidden rounded-lg border border-border bg-card-bg", children: [
|
|
820
|
+
/* @__PURE__ */ jsx6(DetailRow, { label: "Agent", children: agentName }),
|
|
821
|
+
/* @__PURE__ */ jsx6(DetailRow, { label: "Name", children: schedule.name }),
|
|
822
|
+
/* @__PURE__ */ jsx6(DetailRow, { label: "Status", children: /* @__PURE__ */ jsx6(ScheduleStatusBadge, { status: schedule.status }) }),
|
|
823
|
+
/* @__PURE__ */ jsx6(DetailRow, { label: "Task", children: /* @__PURE__ */ jsx6("span", { className: "whitespace-pre-wrap break-words", children: schedule.task }) }),
|
|
824
|
+
/* @__PURE__ */ jsx6(DetailRow, { label: "Frequency", children: /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
|
|
825
|
+
/* @__PURE__ */ jsx6("span", { children: cadence }),
|
|
826
|
+
/* @__PURE__ */ jsx6("code", { className: "text-text-secondary font-mono text-xs", children: schedule.cron })
|
|
599
827
|
] }) }),
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
|
|
602
|
-
/* @__PURE__ */ jsx5(Icon, { name: "pencil", className: "size-3.5" }),
|
|
828
|
+
/* @__PURE__ */ jsx6("div", { className: "flex justify-end px-3 py-2.5", children: /* @__PURE__ */ jsxs5(Button.Secondary, { type: "button", size: "small", onClick: onEditConfiguration, children: [
|
|
829
|
+
/* @__PURE__ */ jsx6(Icon, { name: "pencil", className: "size-3.5" }),
|
|
603
830
|
"Edit Configuration"
|
|
604
831
|
] }) })
|
|
605
832
|
] }),
|
|
606
|
-
/* @__PURE__ */
|
|
607
|
-
/* @__PURE__ */
|
|
608
|
-
mcpMounts.length === 0 ? /* @__PURE__ */
|
|
833
|
+
/* @__PURE__ */ jsxs5("section", { className: "overflow-hidden rounded-lg border border-border bg-card-bg", children: [
|
|
834
|
+
/* @__PURE__ */ jsx6("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsx6("h3", { className: "text-text-secondary text-[10px] font-semibold tracking-wide uppercase", children: "Tool Authorization" }) }),
|
|
835
|
+
mcpMounts.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "text-text-secondary px-3 py-3 text-sm", children: "No MCP connectors configured for this agent." }) : /* @__PURE__ */ jsx6("ul", { className: "divide-y divide-border", children: mcpMounts.map((mount) => {
|
|
609
836
|
const connector = mountConnector(connectors, mount.name);
|
|
610
837
|
const authenticated = connector?.authenticated === true;
|
|
611
838
|
const unavailable = connector == null && !loading;
|
|
612
|
-
return /* @__PURE__ */
|
|
613
|
-
/* @__PURE__ */
|
|
839
|
+
return /* @__PURE__ */ jsxs5("li", { className: "flex items-center gap-2 px-3 py-2.5", children: [
|
|
840
|
+
/* @__PURE__ */ jsx6(
|
|
614
841
|
"span",
|
|
615
842
|
{
|
|
616
843
|
className: cn(
|
|
@@ -618,36 +845,27 @@ function TestScheduleScreen({ schedule, agentName, mcpMounts, onEditConfiguratio
|
|
|
618
845
|
authenticated ? "border-emerald-600/40 bg-emerald-500/15 text-emerald-700 dark:text-emerald-300" : "border-border text-transparent"
|
|
619
846
|
),
|
|
620
847
|
"aria-hidden": true,
|
|
621
|
-
children: authenticated ? /* @__PURE__ */
|
|
848
|
+
children: authenticated ? /* @__PURE__ */ jsx6(Icon, { name: "check", className: "size-3" }) : null
|
|
622
849
|
}
|
|
623
850
|
),
|
|
624
|
-
/* @__PURE__ */
|
|
625
|
-
authenticated ? /* @__PURE__ */
|
|
851
|
+
/* @__PURE__ */ jsx6("span", { className: "text-text-primary min-w-0 flex-1 truncate text-sm", children: mount.name }),
|
|
852
|
+
authenticated ? /* @__PURE__ */ jsx6("span", { className: "text-success-bg text-xs font-medium", children: "Connected" }) : unavailable ? /* @__PURE__ */ jsx6("span", { className: "text-text-secondary text-xs", children: "Unavailable" }) : connector != null && connector.authenticated === false ? /* @__PURE__ */ jsx6(ScheduleMcpConnect, { connector, onConnected: refreshConnectors }) : loading ? /* @__PURE__ */ jsx6("span", { className: "text-text-secondary text-xs", children: "Loading\u2026" }) : null
|
|
626
853
|
] }, mount.name);
|
|
627
854
|
}) })
|
|
628
855
|
] }),
|
|
629
|
-
/* @__PURE__ */
|
|
630
|
-
/* @__PURE__ */
|
|
631
|
-
/* @__PURE__ */
|
|
632
|
-
/* @__PURE__ */
|
|
633
|
-
"
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
disabled: running,
|
|
637
|
-
onClick: () => void handleRunTest(),
|
|
638
|
-
className: auiButtonClass({ variant: "default", size: "sm" }),
|
|
639
|
-
children: [
|
|
640
|
-
/* @__PURE__ */ jsx5(Icon, { name: running ? "loader" : "play", className: cn("size-3.5", running && "animate-spin") }),
|
|
641
|
-
"Run Test"
|
|
642
|
-
]
|
|
643
|
-
}
|
|
644
|
-
)
|
|
856
|
+
/* @__PURE__ */ jsxs5("section", { className: "overflow-hidden rounded-lg border border-border bg-card-bg", children: [
|
|
857
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
|
|
858
|
+
/* @__PURE__ */ jsx6("h3", { className: "text-text-secondary text-[10px] font-semibold tracking-wide uppercase", children: "Test Run" }),
|
|
859
|
+
/* @__PURE__ */ jsxs5(Button.Primary, { type: "button", disabled: running, size: "small", onClick: () => void handleRunTest(), children: [
|
|
860
|
+
/* @__PURE__ */ jsx6(Icon, { name: running ? "loader" : "play", className: cn("size-3.5", running && "animate-spin") }),
|
|
861
|
+
"Run Test"
|
|
862
|
+
] })
|
|
645
863
|
] }),
|
|
646
|
-
lastTestRun == null ? /* @__PURE__ */
|
|
647
|
-
/* @__PURE__ */
|
|
648
|
-
/* @__PURE__ */
|
|
649
|
-
/* @__PURE__ */
|
|
650
|
-
/* @__PURE__ */
|
|
864
|
+
lastTestRun == null ? /* @__PURE__ */ jsx6("p", { className: "text-text-secondary px-3 py-3 text-sm", children: "Run a one-off test using the schedule task. This does not change the cron pending run." }) : /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 px-3 py-3", children: [
|
|
865
|
+
/* @__PURE__ */ jsx6(ScheduleRunChip, { run: lastTestRun }),
|
|
866
|
+
/* @__PURE__ */ jsxs5("div", { className: "min-w-0 text-sm", children: [
|
|
867
|
+
/* @__PURE__ */ jsx6("p", { className: "text-text-primary font-medium", children: runTypeLabel(lastTestRun.name) }),
|
|
868
|
+
/* @__PURE__ */ jsx6("p", { className: "text-text-secondary", children: formatRelativeTime(lastTestRun.triggeredAt ?? lastTestRun.scheduledFor) })
|
|
651
869
|
] })
|
|
652
870
|
] })
|
|
653
871
|
] })
|
|
@@ -655,7 +873,7 @@ function TestScheduleScreen({ schedule, agentName, mcpMounts, onEditConfiguratio
|
|
|
655
873
|
}
|
|
656
874
|
|
|
657
875
|
// src/atoms/schedules/ScheduleFormDrawer.tsx
|
|
658
|
-
import { jsx as
|
|
876
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
659
877
|
function ScheduleFormDrawerBody({
|
|
660
878
|
open,
|
|
661
879
|
onOpenChange,
|
|
@@ -666,32 +884,30 @@ function ScheduleFormDrawerBody({
|
|
|
666
884
|
}) {
|
|
667
885
|
const scheduleServer = useScheduleServer();
|
|
668
886
|
const server = useServer();
|
|
887
|
+
const shell = useOptionalShellMode();
|
|
669
888
|
const toaster = useToasterOptional();
|
|
670
|
-
const [form, setForm] =
|
|
671
|
-
const [agentId, setAgentId] =
|
|
672
|
-
const [
|
|
673
|
-
const [view, setView] =
|
|
674
|
-
const [saving, setSaving] =
|
|
675
|
-
const [activating, setActivating] =
|
|
676
|
-
const [error, setError] =
|
|
889
|
+
const [form, setForm] = useState3(defaultScheduleFormValues);
|
|
890
|
+
const [agentId, setAgentId] = useState3(initialAgentId);
|
|
891
|
+
const [selectedAgent, setSelectedAgent] = useState3(null);
|
|
892
|
+
const [view, setView] = useState3({ kind: "form" });
|
|
893
|
+
const [saving, setSaving] = useState3(false);
|
|
894
|
+
const [activating, setActivating] = useState3(false);
|
|
895
|
+
const [error, setError] = useState3(null);
|
|
896
|
+
const agentIdRef = useRef2(agentId);
|
|
897
|
+
agentIdRef.current = agentId;
|
|
677
898
|
const savedFromCreate = view.kind === "form" ? view.saved : view.schedule;
|
|
678
899
|
const isExternalEdit = mode === "edit" && view.kind === "form" && view.saved == null && schedule != null;
|
|
679
900
|
const isCreatedEdit = view.kind === "form" && view.saved != null;
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
}).catch(() => void 0);
|
|
687
|
-
return () => {
|
|
688
|
-
cancelled = true;
|
|
689
|
-
};
|
|
690
|
-
}, [open, server]);
|
|
691
|
-
useEffect2(() => {
|
|
901
|
+
const isInitialCreate = mode === "create" && view.kind === "form" && view.saved == null;
|
|
902
|
+
const { allows: allowsAgent } = useResourcePermissions({
|
|
903
|
+
resourceType: "agent",
|
|
904
|
+
resourceIds: agentId.length === 0 ? [] : [agentId]
|
|
905
|
+
});
|
|
906
|
+
useEffect3(() => {
|
|
692
907
|
if (!open) {
|
|
693
908
|
setForm(defaultScheduleFormValues());
|
|
694
909
|
setAgentId(initialAgentId);
|
|
910
|
+
setSelectedAgent(null);
|
|
695
911
|
setError(null);
|
|
696
912
|
setView({ kind: "form" });
|
|
697
913
|
setActivating(false);
|
|
@@ -707,30 +923,38 @@ function ScheduleFormDrawerBody({
|
|
|
707
923
|
})
|
|
708
924
|
);
|
|
709
925
|
setAgentId(schedule.agentId);
|
|
926
|
+
setSelectedAgent(null);
|
|
710
927
|
setView({ kind: "form" });
|
|
711
928
|
return;
|
|
712
929
|
}
|
|
713
930
|
setForm(defaultScheduleFormValues());
|
|
714
931
|
setAgentId(initialAgentId);
|
|
932
|
+
setSelectedAgent(null);
|
|
715
933
|
setView({ kind: "form" });
|
|
716
934
|
}, [open, mode, schedule, initialAgentId]);
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
935
|
+
useEffect3(() => {
|
|
936
|
+
if (!open || mode !== "create" || initialAgentId.length === 0) return;
|
|
937
|
+
let cancelled = false;
|
|
938
|
+
const requestedId = initialAgentId;
|
|
939
|
+
void findLibraryAgent({ server, agentKey: requestedId }).then((agent) => {
|
|
940
|
+
if (cancelled || agent == null) return;
|
|
941
|
+
if (agentIdRef.current !== requestedId) return;
|
|
942
|
+
setSelectedAgent(agent);
|
|
943
|
+
setAgentId(libraryAgentId(agent));
|
|
944
|
+
}).catch(() => void 0);
|
|
945
|
+
return () => {
|
|
946
|
+
cancelled = true;
|
|
947
|
+
};
|
|
948
|
+
}, [open, mode, initialAgentId, server]);
|
|
949
|
+
const agentLabel = selectedAgent?.name ?? savedFromCreate?.agentName ?? schedule?.agentName ?? (agentId.length > 0 ? agentId : "");
|
|
726
950
|
const mcpMounts = useMemo(() => {
|
|
727
951
|
const mounts = selectedAgent?.agentSpec?.mcpServers ?? [];
|
|
728
952
|
return mounts.map(mountName).filter((name) => name != null).map((name) => ({ name }));
|
|
729
953
|
}, [selectedAgent]);
|
|
730
954
|
const canSubmit = useMemo(() => {
|
|
731
955
|
const cron = valuesToCron(form);
|
|
732
|
-
return form.name.trim().length > 0 && form.task.trim().length > 0 && cron.length > 0 && agentId.length > 0;
|
|
733
|
-
}, [form,
|
|
956
|
+
return form.name.trim().length > 0 && form.task.trim().length > 0 && cron.length > 0 && agentId.length > 0 && (!isInitialCreate || allowsAgent(agentId, "USE"));
|
|
957
|
+
}, [agentId, allowsAgent, form, isInitialCreate]);
|
|
734
958
|
const enterTestView = (saved) => {
|
|
735
959
|
setView({ kind: "test", schedule: saved });
|
|
736
960
|
setForm(
|
|
@@ -829,30 +1053,20 @@ function ScheduleFormDrawerBody({
|
|
|
829
1053
|
const description = view.kind === "test" ? `Recurring unattended runs of ${agentLabel}.` : isExternalEdit || isCreatedEdit ? "Update cadence and task for this schedule." : "Create a recurring unattended run for an agent.";
|
|
830
1054
|
let footer;
|
|
831
1055
|
if (view.kind === "test") {
|
|
832
|
-
footer = /* @__PURE__ */
|
|
833
|
-
error != null ? /* @__PURE__ */
|
|
834
|
-
/* @__PURE__ */
|
|
835
|
-
Button,
|
|
836
|
-
{
|
|
837
|
-
type: "button",
|
|
838
|
-
variant: "secondary",
|
|
839
|
-
className: "w-full",
|
|
840
|
-
disabled: activating,
|
|
841
|
-
onClick: () => void handleActivate(),
|
|
842
|
-
children: "Activate Anyway"
|
|
843
|
-
}
|
|
844
|
-
)
|
|
1056
|
+
footer = /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-2", children: [
|
|
1057
|
+
error != null ? /* @__PURE__ */ jsx7("p", { className: "text-failure-bg text-sm", children: error }) : null,
|
|
1058
|
+
/* @__PURE__ */ jsx7(Button.Secondary, { type: "button", className: "w-full", disabled: activating, onClick: () => void handleActivate(), children: "Activate Schedule" })
|
|
845
1059
|
] });
|
|
846
1060
|
} else {
|
|
847
|
-
footer = /* @__PURE__ */
|
|
848
|
-
error != null ? /* @__PURE__ */
|
|
849
|
-
/* @__PURE__ */
|
|
850
|
-
/* @__PURE__ */
|
|
851
|
-
/* @__PURE__ */
|
|
1061
|
+
footer = /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-2", children: [
|
|
1062
|
+
error != null ? /* @__PURE__ */ jsx7("p", { className: "text-failure-bg text-sm", children: error }) : null,
|
|
1063
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex justify-end gap-2", children: [
|
|
1064
|
+
/* @__PURE__ */ jsx7(Button.Secondary, { type: "button", onClick: () => onOpenChange(false), disabled: saving, children: "Cancel" }),
|
|
1065
|
+
/* @__PURE__ */ jsx7(Button.Primary, { type: "submit", form: "schedule-form", disabled: !canSubmit || saving, children: "Save" })
|
|
852
1066
|
] })
|
|
853
1067
|
] });
|
|
854
1068
|
}
|
|
855
|
-
return /* @__PURE__ */
|
|
1069
|
+
return /* @__PURE__ */ jsx7(
|
|
856
1070
|
SideDrawer,
|
|
857
1071
|
{
|
|
858
1072
|
open,
|
|
@@ -860,8 +1074,8 @@ function ScheduleFormDrawerBody({
|
|
|
860
1074
|
title,
|
|
861
1075
|
description,
|
|
862
1076
|
anchor: "right",
|
|
863
|
-
size: "
|
|
864
|
-
headerIcon: /* @__PURE__ */
|
|
1077
|
+
size: "xl",
|
|
1078
|
+
headerIcon: /* @__PURE__ */ jsx7("span", { className: "text-primary-button-bg inline-flex size-8 items-center justify-center", children: /* @__PURE__ */ jsx7(
|
|
865
1079
|
Icon,
|
|
866
1080
|
{
|
|
867
1081
|
name: view.kind === "test" || isExternalEdit || isCreatedEdit ? "calendar" : "calendar-plus",
|
|
@@ -869,7 +1083,7 @@ function ScheduleFormDrawerBody({
|
|
|
869
1083
|
}
|
|
870
1084
|
) }),
|
|
871
1085
|
footer,
|
|
872
|
-
children: view.kind === "test" ? /* @__PURE__ */
|
|
1086
|
+
children: view.kind === "test" ? /* @__PURE__ */ jsx7(
|
|
873
1087
|
TestScheduleScreen,
|
|
874
1088
|
{
|
|
875
1089
|
schedule: view.schedule,
|
|
@@ -880,36 +1094,44 @@ function ScheduleFormDrawerBody({
|
|
|
880
1094
|
setView({ kind: "form", saved: view.schedule });
|
|
881
1095
|
}
|
|
882
1096
|
}
|
|
883
|
-
) : /* @__PURE__ */
|
|
1097
|
+
) : /* @__PURE__ */ jsx7("form", { id: "schedule-form", onSubmit: (event) => void handleSave(event), children: /* @__PURE__ */ jsx7(
|
|
884
1098
|
ScheduleFormFields,
|
|
885
1099
|
{
|
|
886
1100
|
values: form,
|
|
887
1101
|
onChange: setForm,
|
|
888
1102
|
agentId,
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
1103
|
+
agentLabel,
|
|
1104
|
+
onAgentIdChange: isExternalEdit || isCreatedEdit ? void 0 : (nextId) => {
|
|
1105
|
+
setAgentId(nextId);
|
|
1106
|
+
if (nextId.length === 0) setSelectedAgent(null);
|
|
1107
|
+
},
|
|
1108
|
+
onAgentPicked: setSelectedAgent,
|
|
1109
|
+
agentPickerDisabled: isExternalEdit || isCreatedEdit,
|
|
1110
|
+
onBuildAgent: mode === "create" && shell?.isComposerEnabled === true ? () => {
|
|
1111
|
+
onOpenChange(false);
|
|
1112
|
+
shell.openAgentBuilder();
|
|
1113
|
+
} : void 0
|
|
892
1114
|
}
|
|
893
1115
|
) })
|
|
894
1116
|
}
|
|
895
1117
|
);
|
|
896
1118
|
}
|
|
897
1119
|
function ScheduleFormDrawer(props) {
|
|
898
|
-
return /* @__PURE__ */
|
|
1120
|
+
return /* @__PURE__ */ jsx7(DraftCatalogProvider, { children: /* @__PURE__ */ jsx7(ScheduleFormDrawerBody, { ...props }) });
|
|
899
1121
|
}
|
|
900
1122
|
|
|
901
1123
|
// src/atoms/schedules/ScheduleLastRunsCell.tsx
|
|
902
|
-
import { jsx as
|
|
1124
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
903
1125
|
function ScheduleLastRunsCell({ runs }) {
|
|
904
1126
|
const history = lastHistoricalRuns(runs);
|
|
905
1127
|
if (history.length === 0) {
|
|
906
|
-
return /* @__PURE__ */
|
|
1128
|
+
return /* @__PURE__ */ jsx8("span", { className: "text-text-secondary text-sm", children: "\u2014" });
|
|
907
1129
|
}
|
|
908
|
-
return /* @__PURE__ */
|
|
1130
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-1", children: history.map((run) => /* @__PURE__ */ jsx8(ScheduleRunChip, { run }, run.id)) });
|
|
909
1131
|
}
|
|
910
1132
|
|
|
911
1133
|
// src/atoms/schedules/SchedulesPage.tsx
|
|
912
|
-
import { Fragment, jsx as
|
|
1134
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
913
1135
|
var STATUS_FILTER_OPTIONS = [
|
|
914
1136
|
{ value: "all", label: "All statuses" },
|
|
915
1137
|
{ value: "active", label: "Active" },
|
|
@@ -927,84 +1149,108 @@ function filtersFromSearch(search) {
|
|
|
927
1149
|
agentFilter: share.agent ?? "all"
|
|
928
1150
|
};
|
|
929
1151
|
}
|
|
1152
|
+
function initialDrawerState(agentId) {
|
|
1153
|
+
const share = readScheduleShareSearch(window.location.search);
|
|
1154
|
+
if (!share.isNew) return { kind: "closed" };
|
|
1155
|
+
const initialAgentId = agentId ?? share.agent;
|
|
1156
|
+
return {
|
|
1157
|
+
kind: "create",
|
|
1158
|
+
...initialAgentId == null ? {} : { agentId: initialAgentId }
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
930
1161
|
function ScheduleRowActions({
|
|
931
1162
|
schedule,
|
|
932
1163
|
running,
|
|
1164
|
+
canManage,
|
|
1165
|
+
canDelete,
|
|
933
1166
|
onRunNow,
|
|
934
1167
|
onEdit,
|
|
935
1168
|
onTogglePause,
|
|
936
1169
|
onDelete
|
|
937
1170
|
}) {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1171
|
+
const PermissionGuard = useSlot("PermissionGuard");
|
|
1172
|
+
return /* @__PURE__ */ jsxs7("div", { className: "inline-flex items-center justify-end gap-1.5", children: [
|
|
1173
|
+
/* @__PURE__ */ jsx9(PermissionGuard, { allowed: canManage, children: /* @__PURE__ */ jsxs7(
|
|
1174
|
+
Button.Secondary,
|
|
941
1175
|
{
|
|
942
1176
|
type: "button",
|
|
943
1177
|
disabled: running,
|
|
944
1178
|
"aria-label": `Run now ${schedule.name}`,
|
|
945
|
-
|
|
1179
|
+
size: "large",
|
|
946
1180
|
onClick: onRunNow,
|
|
947
1181
|
children: [
|
|
948
|
-
/* @__PURE__ */
|
|
1182
|
+
/* @__PURE__ */ jsx9(Icon, { name: running ? "loader" : "play", className: cn("size-3.5", running && "animate-spin") }),
|
|
949
1183
|
"Run now"
|
|
950
1184
|
]
|
|
951
1185
|
}
|
|
952
|
-
),
|
|
953
|
-
/* @__PURE__ */
|
|
1186
|
+
) }),
|
|
1187
|
+
/* @__PURE__ */ jsxs7(
|
|
954
1188
|
DropdownMenu,
|
|
955
1189
|
{
|
|
956
1190
|
align: "end",
|
|
957
|
-
trigger: /* @__PURE__ */
|
|
1191
|
+
trigger: /* @__PURE__ */ jsx9(
|
|
958
1192
|
"button",
|
|
959
1193
|
{
|
|
960
1194
|
type: "button",
|
|
961
1195
|
className: auiButtonClass({ variant: "ghost", size: "icon" }),
|
|
962
1196
|
"aria-label": `Actions for ${schedule.name}`,
|
|
963
|
-
children: /* @__PURE__ */
|
|
1197
|
+
children: /* @__PURE__ */ jsx9(Icon, { name: "ellipsis" })
|
|
964
1198
|
}
|
|
965
1199
|
),
|
|
966
1200
|
children: [
|
|
967
|
-
/* @__PURE__ */
|
|
968
|
-
/* @__PURE__ */
|
|
1201
|
+
/* @__PURE__ */ jsx9(PermissionGuard, { allowed: canManage, children: /* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: onEdit, children: [
|
|
1202
|
+
/* @__PURE__ */ jsx9(Icon, { name: "pencil", className: "size-3.5" }),
|
|
969
1203
|
"Edit"
|
|
970
|
-
] }),
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
/* @__PURE__ */
|
|
1204
|
+
] }) }),
|
|
1205
|
+
/* @__PURE__ */ jsx9(PermissionGuard, { allowed: canManage, children: /* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: onTogglePause, children: [
|
|
1206
|
+
/* @__PURE__ */ jsx9(Icon, { name: schedule.status === "active" ? "pause" : "play", className: "size-3.5" }),
|
|
973
1207
|
schedule.status === "active" ? "Pause" : "Resume"
|
|
974
|
-
] }),
|
|
975
|
-
/* @__PURE__ */
|
|
976
|
-
/* @__PURE__ */
|
|
1208
|
+
] }) }),
|
|
1209
|
+
/* @__PURE__ */ jsx9(PermissionGuard, { allowed: canDelete, children: /* @__PURE__ */ jsxs7(DropdownMenuItem, { className: "text-failure-bg focus:text-failure-bg", onClick: onDelete, children: [
|
|
1210
|
+
/* @__PURE__ */ jsx9(Icon, { name: "trash", className: "size-3.5" }),
|
|
977
1211
|
"Delete"
|
|
978
|
-
] })
|
|
1212
|
+
] }) })
|
|
979
1213
|
]
|
|
980
1214
|
}
|
|
981
1215
|
)
|
|
982
1216
|
] });
|
|
983
1217
|
}
|
|
984
|
-
function SchedulesPage() {
|
|
1218
|
+
function SchedulesPage({ agentId }) {
|
|
985
1219
|
const scheduleServer = useScheduleServer();
|
|
986
1220
|
const server = useServer();
|
|
987
1221
|
const toaster = useToasterOptional();
|
|
988
|
-
const [schedules, setSchedules] =
|
|
989
|
-
const
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
const [
|
|
994
|
-
const [
|
|
995
|
-
const [
|
|
996
|
-
const [
|
|
1222
|
+
const [schedules, setSchedules] = useState4([]);
|
|
1223
|
+
const { allows } = useResourcePermissions({
|
|
1224
|
+
resourceType: "schedule",
|
|
1225
|
+
resourceIds: schedules.map((schedule) => schedule.id)
|
|
1226
|
+
});
|
|
1227
|
+
const [runsByScheduleId, setRunsByScheduleId] = useState4({});
|
|
1228
|
+
const [runsLoading, setRunsLoading] = useState4(false);
|
|
1229
|
+
const [runningScheduleIds, setRunningScheduleIds] = useState4(() => /* @__PURE__ */ new Set());
|
|
1230
|
+
const [agentLabelById, setAgentLabelById] = useState4({});
|
|
1231
|
+
const [loading, setLoading] = useState4(true);
|
|
1232
|
+
const [error, setError] = useState4(null);
|
|
1233
|
+
const [nameQuery, setNameQuery] = useState4(() => filtersFromSearch(window.location.search).nameQuery);
|
|
1234
|
+
const [statusFilter, setStatusFilter] = useState4(
|
|
997
1235
|
() => filtersFromSearch(window.location.search).statusFilter
|
|
998
1236
|
);
|
|
999
|
-
const [agentFilter, setAgentFilter] =
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
const
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
const
|
|
1237
|
+
const [agentFilter, setAgentFilter] = useState4(
|
|
1238
|
+
() => agentId ?? filtersFromSearch(window.location.search).agentFilter
|
|
1239
|
+
);
|
|
1240
|
+
const permissionAgentId = agentId ?? (agentFilter === "all" ? null : agentFilter);
|
|
1241
|
+
const { allows: allowsAgent } = useResourcePermissions({
|
|
1242
|
+
resourceType: "agent",
|
|
1243
|
+
resourceIds: permissionAgentId == null ? [] : [permissionAgentId]
|
|
1244
|
+
});
|
|
1245
|
+
const canCreateSchedule = server.permissions == null || permissionAgentId == null || allowsAgent(permissionAgentId, "USE");
|
|
1246
|
+
const [drawer, setDrawer] = useState4(() => initialDrawerState(agentId));
|
|
1247
|
+
const [pendingDelete, setPendingDelete] = useState4(null);
|
|
1248
|
+
const [pageSize, setPageSize] = useState4(() => clampPageSize(DEFAULT_TABLE_PAGE_SIZE));
|
|
1249
|
+
const [pageToken, setPageToken] = useState4(void 0);
|
|
1250
|
+
const [nextPageToken, setNextPageToken] = useState4(void 0);
|
|
1251
|
+
const [prevTokenStack, setPrevTokenStack] = useState4([]);
|
|
1252
|
+
const loadGenRef = useRef3(0);
|
|
1253
|
+
const didConsumeIsNewRef = useRef3(false);
|
|
1008
1254
|
const loadRunsForSchedules = useCallback(
|
|
1009
1255
|
async ({ rows, gen }) => {
|
|
1010
1256
|
if (rows.length === 0) {
|
|
@@ -1033,7 +1279,7 @@ function SchedulesPage() {
|
|
|
1033
1279
|
[scheduleServer]
|
|
1034
1280
|
);
|
|
1035
1281
|
const loadSchedules = useCallback(
|
|
1036
|
-
async ({ token, size, agentId }) => {
|
|
1282
|
+
async ({ token, size, agentId: agentId2 }) => {
|
|
1037
1283
|
const gen = ++loadGenRef.current;
|
|
1038
1284
|
setLoading(true);
|
|
1039
1285
|
setError(null);
|
|
@@ -1041,7 +1287,7 @@ function SchedulesPage() {
|
|
|
1041
1287
|
const page = await scheduleServer.listSchedules({
|
|
1042
1288
|
limit: clampPageSize(size),
|
|
1043
1289
|
...token === void 0 || token === "" ? {} : { pageToken: token },
|
|
1044
|
-
...
|
|
1290
|
+
...agentId2 === "all" ? {} : { agentIds: [agentId2] }
|
|
1045
1291
|
});
|
|
1046
1292
|
if (gen !== loadGenRef.current) return;
|
|
1047
1293
|
setSchedules(page.data);
|
|
@@ -1063,68 +1309,57 @@ function SchedulesPage() {
|
|
|
1063
1309
|
const resetToFirstPage = useCallback(
|
|
1064
1310
|
(next) => {
|
|
1065
1311
|
const size = next?.size ?? pageSize;
|
|
1066
|
-
const
|
|
1312
|
+
const agentId2 = next?.agentId ?? agentFilter;
|
|
1067
1313
|
setPageToken(void 0);
|
|
1068
1314
|
setPrevTokenStack([]);
|
|
1069
|
-
void loadSchedules({ token: void 0, size, agentId });
|
|
1315
|
+
void loadSchedules({ token: void 0, size, agentId: agentId2 });
|
|
1070
1316
|
},
|
|
1071
1317
|
[agentFilter, loadSchedules, pageSize]
|
|
1072
1318
|
);
|
|
1073
|
-
|
|
1319
|
+
useEffect4(() => {
|
|
1074
1320
|
replaceScheduleShareSearch({
|
|
1075
|
-
agent:
|
|
1321
|
+
agent: agentId === void 0 && agentFilter !== "all" ? agentFilter : null,
|
|
1076
1322
|
status: statusFilter === "all" ? null : statusFilter,
|
|
1077
1323
|
q: nameQuery.trim().length === 0 ? null : nameQuery
|
|
1078
1324
|
});
|
|
1079
|
-
}, [agentFilter, statusFilter, nameQuery]);
|
|
1080
|
-
|
|
1325
|
+
}, [agentFilter, agentId, statusFilter, nameQuery]);
|
|
1326
|
+
useEffect4(() => {
|
|
1327
|
+
if (agentId === void 0) return;
|
|
1328
|
+
setAgentFilter((current) => {
|
|
1329
|
+
if (current === agentId) return current;
|
|
1330
|
+
setPageToken(void 0);
|
|
1331
|
+
setPrevTokenStack([]);
|
|
1332
|
+
return agentId;
|
|
1333
|
+
});
|
|
1334
|
+
}, [agentId]);
|
|
1335
|
+
useEffect4(() => {
|
|
1081
1336
|
if (didConsumeIsNewRef.current) return;
|
|
1082
1337
|
const share = readScheduleShareSearch(window.location.search);
|
|
1083
1338
|
if (!share.isNew) return;
|
|
1084
1339
|
didConsumeIsNewRef.current = true;
|
|
1085
|
-
setDrawer({
|
|
1086
|
-
kind: "create",
|
|
1087
|
-
...share.agent != null ? { agentId: share.agent } : {}
|
|
1088
|
-
});
|
|
1089
1340
|
replaceScheduleShareSearch({ isNew: null });
|
|
1090
1341
|
}, []);
|
|
1091
|
-
|
|
1342
|
+
useEffect4(() => {
|
|
1092
1343
|
const syncFromUrl = () => {
|
|
1093
1344
|
const next = filtersFromSearch(window.location.search);
|
|
1094
1345
|
setNameQuery(next.nameQuery);
|
|
1095
1346
|
setStatusFilter(next.statusFilter);
|
|
1096
1347
|
setAgentFilter((current) => {
|
|
1097
|
-
|
|
1348
|
+
const nextAgentFilter = agentId ?? next.agentFilter;
|
|
1349
|
+
if (current === nextAgentFilter) return current;
|
|
1098
1350
|
setPageToken(void 0);
|
|
1099
1351
|
setPrevTokenStack([]);
|
|
1100
|
-
return
|
|
1352
|
+
return nextAgentFilter;
|
|
1101
1353
|
});
|
|
1102
1354
|
};
|
|
1103
1355
|
window.addEventListener("popstate", syncFromUrl);
|
|
1104
1356
|
return () => {
|
|
1105
1357
|
window.removeEventListener("popstate", syncFromUrl);
|
|
1106
1358
|
};
|
|
1107
|
-
}, []);
|
|
1108
|
-
|
|
1359
|
+
}, [agentId]);
|
|
1360
|
+
useEffect4(() => {
|
|
1109
1361
|
void loadSchedules({ token: pageToken, size: pageSize, agentId: agentFilter });
|
|
1110
1362
|
}, [agentFilter, pageSize, pageToken, loadSchedules]);
|
|
1111
|
-
useEffect3(() => {
|
|
1112
|
-
let cancelled = false;
|
|
1113
|
-
void searchAllAgents(server).then((rows) => {
|
|
1114
|
-
if (cancelled) return;
|
|
1115
|
-
setAgentOptions(rows.map((agent) => ({ agentId: libraryAgentId(agent), name: agent.name })));
|
|
1116
|
-
}).catch(() => void 0);
|
|
1117
|
-
return () => {
|
|
1118
|
-
cancelled = true;
|
|
1119
|
-
};
|
|
1120
|
-
}, [server]);
|
|
1121
|
-
const agentNameById = useMemo2(() => {
|
|
1122
|
-
const map = /* @__PURE__ */ new Map();
|
|
1123
|
-
for (const agent of agentOptions) {
|
|
1124
|
-
map.set(agent.agentId, agent.name);
|
|
1125
|
-
}
|
|
1126
|
-
return map;
|
|
1127
|
-
}, [agentOptions]);
|
|
1128
1363
|
const filtered = useMemo2(() => {
|
|
1129
1364
|
const q = nameQuery.trim().toLowerCase();
|
|
1130
1365
|
return schedules.filter((schedule) => {
|
|
@@ -1133,8 +1368,10 @@ function SchedulesPage() {
|
|
|
1133
1368
|
return true;
|
|
1134
1369
|
});
|
|
1135
1370
|
}, [schedules, nameQuery, statusFilter]);
|
|
1371
|
+
const showCreatedByColumn = hasCreatedBySubject(schedules);
|
|
1136
1372
|
const hasPageNav = prevTokenStack.length > 0 || nextPageToken != null;
|
|
1137
1373
|
const handleTogglePause = async (schedule) => {
|
|
1374
|
+
if (!allows(schedule.id, "MANAGE")) return;
|
|
1138
1375
|
const nextStatus = schedule.status === "active" ? "paused" : "active";
|
|
1139
1376
|
try {
|
|
1140
1377
|
await scheduleServer.updateSchedule({ ...schedule, status: nextStatus });
|
|
@@ -1144,6 +1381,7 @@ function SchedulesPage() {
|
|
|
1144
1381
|
}
|
|
1145
1382
|
};
|
|
1146
1383
|
const handleRunNow = async (schedule) => {
|
|
1384
|
+
if (!allows(schedule.id, "MANAGE")) return;
|
|
1147
1385
|
setRunningScheduleIds((prev) => new Set(prev).add(schedule.id));
|
|
1148
1386
|
try {
|
|
1149
1387
|
await scheduleServer.createScheduleRun({ scheduleId: schedule.id });
|
|
@@ -1161,6 +1399,7 @@ function SchedulesPage() {
|
|
|
1161
1399
|
}
|
|
1162
1400
|
};
|
|
1163
1401
|
const handleDelete = async (schedule) => {
|
|
1402
|
+
if (!allows(schedule.id, "DELETE")) return;
|
|
1164
1403
|
setPendingDelete(null);
|
|
1165
1404
|
try {
|
|
1166
1405
|
await scheduleServer.deleteSchedule({ id: schedule.id });
|
|
@@ -1181,14 +1420,14 @@ function SchedulesPage() {
|
|
|
1181
1420
|
setPrevTokenStack(stack);
|
|
1182
1421
|
setPageToken(prev === "" ? void 0 : prev);
|
|
1183
1422
|
};
|
|
1184
|
-
return /* @__PURE__ */
|
|
1185
|
-
/* @__PURE__ */
|
|
1423
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex h-full min-h-0 flex-col bg-primary-bg", children: [
|
|
1424
|
+
/* @__PURE__ */ jsx9(
|
|
1186
1425
|
PageHeader,
|
|
1187
1426
|
{
|
|
1188
|
-
title: "Scheduled Agents",
|
|
1189
|
-
end: /* @__PURE__ */
|
|
1190
|
-
/* @__PURE__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
1427
|
+
title: agentId === void 0 ? "Scheduled Agents" : void 0,
|
|
1428
|
+
end: /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1429
|
+
/* @__PURE__ */ jsx9("div", { className: "w-full sm:w-60", children: /* @__PURE__ */ jsx9(SearchInput_default, { query: nameQuery, setQuery: setNameQuery, placeholder: "Search schedules by name" }) }),
|
|
1430
|
+
/* @__PURE__ */ jsx9(
|
|
1192
1431
|
PopoverSelect,
|
|
1193
1432
|
{
|
|
1194
1433
|
value: statusFilter,
|
|
@@ -1198,33 +1437,39 @@ function SchedulesPage() {
|
|
|
1198
1437
|
"aria-label": "Filter by status"
|
|
1199
1438
|
}
|
|
1200
1439
|
),
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
|
|
1440
|
+
agentId === void 0 ? /* @__PURE__ */ jsx9(
|
|
1441
|
+
AgentSearchPicker,
|
|
1203
1442
|
{
|
|
1204
1443
|
value: agentFilter,
|
|
1444
|
+
selectedLabel: agentFilter === "all" ? "All agents" : agentLabelById[agentFilter] ?? agentFilter,
|
|
1205
1445
|
onValueChange: (value) => {
|
|
1206
1446
|
setAgentFilter(value);
|
|
1207
1447
|
setPageToken(void 0);
|
|
1208
1448
|
setPrevTokenStack([]);
|
|
1209
1449
|
},
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1450
|
+
onAgentPicked: (agent) => {
|
|
1451
|
+
setAgentLabelById((current) => ({
|
|
1452
|
+
...current,
|
|
1453
|
+
[libraryAgentId(agent)]: agent.name
|
|
1454
|
+
}));
|
|
1455
|
+
},
|
|
1456
|
+
allOption: { value: "all", label: "All agents" },
|
|
1457
|
+
className: "sm:w-48",
|
|
1458
|
+
"aria-label": "Filter by agent",
|
|
1459
|
+
placeholder: "Search agent"
|
|
1216
1460
|
}
|
|
1217
|
-
),
|
|
1218
|
-
/* @__PURE__ */
|
|
1219
|
-
Button,
|
|
1461
|
+
) : null,
|
|
1462
|
+
/* @__PURE__ */ jsxs7(
|
|
1463
|
+
Button.Primary,
|
|
1220
1464
|
{
|
|
1221
1465
|
type: "button",
|
|
1222
|
-
|
|
1466
|
+
disabled: !canCreateSchedule,
|
|
1467
|
+
onClick: () => canCreateSchedule && setDrawer({
|
|
1223
1468
|
kind: "create",
|
|
1224
1469
|
agentId: agentFilter !== "all" ? agentFilter : void 0
|
|
1225
1470
|
}),
|
|
1226
1471
|
children: [
|
|
1227
|
-
/* @__PURE__ */
|
|
1472
|
+
/* @__PURE__ */ jsx9(Icon, { name: "plus", className: "size-3.5" }),
|
|
1228
1473
|
"Create Schedule"
|
|
1229
1474
|
]
|
|
1230
1475
|
}
|
|
@@ -1232,9 +1477,9 @@ function SchedulesPage() {
|
|
|
1232
1477
|
] })
|
|
1233
1478
|
}
|
|
1234
1479
|
),
|
|
1235
|
-
/* @__PURE__ */
|
|
1236
|
-
/* @__PURE__ */
|
|
1237
|
-
hasPageNav ? /* @__PURE__ */
|
|
1480
|
+
/* @__PURE__ */ jsx9("div", { className: "min-h-0 flex-1 overflow-auto px-4 py-4", children: loading ? /* @__PURE__ */ jsx9("div", { className: "flex flex-col gap-2", role: "status", "aria-label": "Loading schedules", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx9(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : error != null ? /* @__PURE__ */ jsx9("p", { className: "text-failure-bg px-3 py-8 text-center text-sm", children: error }) : schedules.length === 0 ? /* @__PURE__ */ jsx9(EmptyScreen, { title: "No Schedules Found", description: "Create one to get started.", className: "min-h-full" }) : filtered.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "flex min-h-full flex-col", children: [
|
|
1481
|
+
/* @__PURE__ */ jsx9(EmptyScreen, { title: "No Schedules Found", description: "No schedules match your filters.", className: "flex-1" }),
|
|
1482
|
+
hasPageNav ? /* @__PURE__ */ jsx9(
|
|
1238
1483
|
TableTokenPagination,
|
|
1239
1484
|
{
|
|
1240
1485
|
pageSize,
|
|
@@ -1252,48 +1497,48 @@ function SchedulesPage() {
|
|
|
1252
1497
|
}
|
|
1253
1498
|
}
|
|
1254
1499
|
) : null
|
|
1255
|
-
] }) : /* @__PURE__ */
|
|
1256
|
-
/* @__PURE__ */
|
|
1257
|
-
/* @__PURE__ */
|
|
1258
|
-
/* @__PURE__ */
|
|
1259
|
-
/* @__PURE__ */
|
|
1260
|
-
/* @__PURE__ */
|
|
1261
|
-
/* @__PURE__ */
|
|
1262
|
-
/* @__PURE__ */
|
|
1263
|
-
/* @__PURE__ */
|
|
1500
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-lg border border-border", children: [
|
|
1501
|
+
/* @__PURE__ */ jsxs7(Table, { className: "min-w-[48rem]", children: [
|
|
1502
|
+
/* @__PURE__ */ jsx9(TableHeader, { children: /* @__PURE__ */ jsxs7(TableRow, { className: "hover:bg-transparent", children: [
|
|
1503
|
+
/* @__PURE__ */ jsx9(TableHead, { children: "Name" }),
|
|
1504
|
+
/* @__PURE__ */ jsx9(TableHead, { children: "Agent" }),
|
|
1505
|
+
showCreatedByColumn ? /* @__PURE__ */ jsx9(TableHead, { children: "Created by" }) : null,
|
|
1506
|
+
/* @__PURE__ */ jsx9(TableHead, { children: "Frequency" }),
|
|
1507
|
+
/* @__PURE__ */ jsx9(TableHead, { children: "Status" }),
|
|
1508
|
+
/* @__PURE__ */ jsx9(TableHead, { children: "Last 5 runs" }),
|
|
1509
|
+
/* @__PURE__ */ jsx9(TableHead, { children: /* @__PURE__ */ jsx9("span", { className: "sr-only", children: "Actions" }) })
|
|
1264
1510
|
] }) }),
|
|
1265
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsx9(TableBody, { children: filtered.map((schedule) => {
|
|
1266
1512
|
const cadence = formatCadenceSummary({ cron: schedule.cron, timezone: schedule.timezone });
|
|
1267
|
-
const agentLabel = schedule.agentName ??
|
|
1268
|
-
return /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
}
|
|
1277
|
-
) }),
|
|
1278
|
-
/* @__PURE__ */ jsx8(TableCell, { children: agentLabel }),
|
|
1279
|
-
/* @__PURE__ */ jsx8(TableCell, { children: cadence }),
|
|
1280
|
-
/* @__PURE__ */ jsx8(TableCell, { children: /* @__PURE__ */ jsx8(ScheduleStatusBadge, { status: schedule.status }) }),
|
|
1281
|
-
/* @__PURE__ */ jsx8(TableCell, { children: runsLoading ? /* @__PURE__ */ jsx8("span", { className: "text-text-secondary text-sm", children: "\u2026" }) : /* @__PURE__ */ jsx8(ScheduleLastRunsCell, { runs: runsByScheduleId[schedule.id] ?? [] }) }),
|
|
1282
|
-
/* @__PURE__ */ jsx8(TableCell, { className: "text-right", children: /* @__PURE__ */ jsx8(
|
|
1513
|
+
const agentLabel = schedule.agentName ?? agentLabelById[schedule.agentId] ?? schedule.agentId;
|
|
1514
|
+
return /* @__PURE__ */ jsxs7(TableRow, { children: [
|
|
1515
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-text-primary font-medium", children: /* @__PURE__ */ jsx9("span", { className: "text-left !no-underline", children: schedule.name }) }),
|
|
1516
|
+
/* @__PURE__ */ jsx9(TableCell, { children: agentLabel }),
|
|
1517
|
+
showCreatedByColumn ? /* @__PURE__ */ jsx9(TableCell, { children: /* @__PURE__ */ jsx9(CreatedByCell, { subject: schedule.createdBySubject }) }) : null,
|
|
1518
|
+
/* @__PURE__ */ jsx9(TableCell, { children: cadence }),
|
|
1519
|
+
/* @__PURE__ */ jsx9(TableCell, { children: /* @__PURE__ */ jsx9(ScheduleStatusBadge, { status: schedule.status }) }),
|
|
1520
|
+
/* @__PURE__ */ jsx9(TableCell, { children: runsLoading ? /* @__PURE__ */ jsx9("span", { className: "text-text-secondary text-sm", children: "\u2026" }) : /* @__PURE__ */ jsx9(ScheduleLastRunsCell, { runs: runsByScheduleId[schedule.id] ?? [] }) }),
|
|
1521
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-right", children: /* @__PURE__ */ jsx9(
|
|
1283
1522
|
ScheduleRowActions,
|
|
1284
1523
|
{
|
|
1285
1524
|
schedule,
|
|
1286
1525
|
running: runningScheduleIds.has(schedule.id),
|
|
1526
|
+
canManage: allows(schedule.id, "MANAGE"),
|
|
1527
|
+
canDelete: allows(schedule.id, "DELETE"),
|
|
1287
1528
|
onRunNow: () => void handleRunNow(schedule),
|
|
1288
|
-
onEdit: () =>
|
|
1529
|
+
onEdit: () => {
|
|
1530
|
+
if (allows(schedule.id, "MANAGE")) setDrawer({ kind: "edit", schedule });
|
|
1531
|
+
},
|
|
1289
1532
|
onTogglePause: () => void handleTogglePause(schedule),
|
|
1290
|
-
onDelete: () =>
|
|
1533
|
+
onDelete: () => {
|
|
1534
|
+
if (allows(schedule.id, "DELETE")) setPendingDelete(schedule);
|
|
1535
|
+
}
|
|
1291
1536
|
}
|
|
1292
1537
|
) })
|
|
1293
1538
|
] }, schedule.id);
|
|
1294
1539
|
}) })
|
|
1295
1540
|
] }),
|
|
1296
|
-
(filtered.length > 0 || hasPageNav) && /* @__PURE__ */
|
|
1541
|
+
(filtered.length > 0 || hasPageNav) && /* @__PURE__ */ jsx9(
|
|
1297
1542
|
TableTokenPagination,
|
|
1298
1543
|
{
|
|
1299
1544
|
pageSize,
|
|
@@ -1312,7 +1557,7 @@ function SchedulesPage() {
|
|
|
1312
1557
|
}
|
|
1313
1558
|
)
|
|
1314
1559
|
] }) }),
|
|
1315
|
-
drawer.kind === "create" ? /* @__PURE__ */
|
|
1560
|
+
drawer.kind === "create" ? /* @__PURE__ */ jsx9(
|
|
1316
1561
|
ScheduleFormDrawer,
|
|
1317
1562
|
{
|
|
1318
1563
|
open: true,
|
|
@@ -1324,7 +1569,7 @@ function SchedulesPage() {
|
|
|
1324
1569
|
onSaved: () => resetToFirstPage()
|
|
1325
1570
|
}
|
|
1326
1571
|
) : null,
|
|
1327
|
-
drawer.kind === "edit" ? /* @__PURE__ */
|
|
1572
|
+
drawer.kind === "edit" ? /* @__PURE__ */ jsx9(
|
|
1328
1573
|
ScheduleFormDrawer,
|
|
1329
1574
|
{
|
|
1330
1575
|
open: true,
|
|
@@ -1336,7 +1581,7 @@ function SchedulesPage() {
|
|
|
1336
1581
|
onSaved: () => void loadSchedules({ token: pageToken, size: pageSize, agentId: agentFilter })
|
|
1337
1582
|
}
|
|
1338
1583
|
) : null,
|
|
1339
|
-
pendingDelete != null ? /* @__PURE__ */
|
|
1584
|
+
pendingDelete != null ? /* @__PURE__ */ jsxs7(
|
|
1340
1585
|
Dialog,
|
|
1341
1586
|
{
|
|
1342
1587
|
open: true,
|
|
@@ -1346,17 +1591,25 @@ function SchedulesPage() {
|
|
|
1346
1591
|
"aria-label": "Delete schedule",
|
|
1347
1592
|
className: "max-w-md",
|
|
1348
1593
|
children: [
|
|
1349
|
-
/* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
/* @__PURE__ */
|
|
1594
|
+
/* @__PURE__ */ jsx9(DialogContent, { children: /* @__PURE__ */ jsxs7(DialogHeader, { children: [
|
|
1595
|
+
/* @__PURE__ */ jsx9(DialogTitle, { children: "Delete schedule" }),
|
|
1596
|
+
/* @__PURE__ */ jsxs7("p", { className: "text-text-secondary text-sm", children: [
|
|
1352
1597
|
"\u201C",
|
|
1353
1598
|
pendingDelete.name,
|
|
1354
1599
|
"\u201D will stop running. This cannot be undone."
|
|
1355
1600
|
] })
|
|
1356
1601
|
] }) }),
|
|
1357
|
-
/* @__PURE__ */
|
|
1358
|
-
/* @__PURE__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1602
|
+
/* @__PURE__ */ jsxs7(DialogFooter, { children: [
|
|
1603
|
+
/* @__PURE__ */ jsx9(Button.Secondary, { type: "button", onClick: () => setPendingDelete(null), children: "Cancel" }),
|
|
1604
|
+
/* @__PURE__ */ jsx9(
|
|
1605
|
+
Button.Destructive,
|
|
1606
|
+
{
|
|
1607
|
+
type: "button",
|
|
1608
|
+
disabled: !allows(pendingDelete.id, "DELETE"),
|
|
1609
|
+
onClick: () => void handleDelete(pendingDelete),
|
|
1610
|
+
children: "Delete"
|
|
1611
|
+
}
|
|
1612
|
+
)
|
|
1360
1613
|
] })
|
|
1361
1614
|
]
|
|
1362
1615
|
}
|
|
@@ -1373,4 +1626,4 @@ export {
|
|
|
1373
1626
|
ScheduleLastRunsCell,
|
|
1374
1627
|
SchedulesPage
|
|
1375
1628
|
};
|
|
1376
|
-
//# sourceMappingURL=chunk-
|
|
1629
|
+
//# sourceMappingURL=chunk-UWLL327M.js.map
|