@michengai/dsh-automation 0.1.18 → 0.1.19
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 +9 -0
- package/CHANGELOG.zh-CN.md +9 -0
- package/docs/03-/346/212/200/346/234/257/346/236/266/346/236/204/01-/350/260/203/345/272/246/344/270/216/346/211/247/350/241/214/346/250/241/345/236/213.md +3 -3
- package/lib/client.js +326 -242
- package/lib/client.js.map +4 -4
- package/lib/index.js +54 -14
- package/lib/types/client/delete-confirmation.d.ts +11 -0
- package/lib/types/client/helpers.d.ts +2 -0
- package/lib/types/client/native-session-menu.d.ts +2 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -27,10 +27,10 @@ __export(index_exports, {
|
|
|
27
27
|
name: () => name
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(index_exports);
|
|
30
|
-
var
|
|
30
|
+
var import_react8 = require("react");
|
|
31
31
|
|
|
32
32
|
// src/client/AutomationView.tsx
|
|
33
|
-
var
|
|
33
|
+
var import_react4 = require("react");
|
|
34
34
|
|
|
35
35
|
// src/client/helpers.ts
|
|
36
36
|
var AutomationFormError = class extends Error {
|
|
@@ -70,6 +70,7 @@ function defaultFormState(now = /* @__PURE__ */ new Date(), workspaces = [], def
|
|
|
70
70
|
scheduleKind: "daily",
|
|
71
71
|
onceAt: localDateTimeValue(now),
|
|
72
72
|
everyMinutes: "60",
|
|
73
|
+
intervalAnchor: "",
|
|
73
74
|
time: "09:00",
|
|
74
75
|
weekdays: [1, 2, 3, 4, 5],
|
|
75
76
|
hourlyMinute: "00",
|
|
@@ -105,7 +106,12 @@ function buildCreateInput(form, workspaces, models, now = /* @__PURE__ */ new Da
|
|
|
105
106
|
if (!Number.isInteger(everyMinutes) || everyMinutes < 5 || everyMinutes > 43200) {
|
|
106
107
|
throw new AutomationFormError("form.error.interval");
|
|
107
108
|
}
|
|
108
|
-
schedule = {
|
|
109
|
+
schedule = {
|
|
110
|
+
kind: "interval",
|
|
111
|
+
everyMinutes,
|
|
112
|
+
anchor: form.intervalAnchor.trim() || now.toISOString(),
|
|
113
|
+
timeZone: form.timeZone
|
|
114
|
+
};
|
|
109
115
|
break;
|
|
110
116
|
}
|
|
111
117
|
case "daily":
|
|
@@ -187,6 +193,15 @@ function clockTime(iso) {
|
|
|
187
193
|
if (Number.isNaN(value.getTime())) return iso;
|
|
188
194
|
return value.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
189
195
|
}
|
|
196
|
+
var HISTORY_STATUS_OPTIONS = [
|
|
197
|
+
"succeeded",
|
|
198
|
+
"failed",
|
|
199
|
+
"interrupted",
|
|
200
|
+
"running",
|
|
201
|
+
"queued",
|
|
202
|
+
"skipped",
|
|
203
|
+
"cancelled"
|
|
204
|
+
];
|
|
190
205
|
function sortStamp(value) {
|
|
191
206
|
const parsed = Date.parse(value);
|
|
192
207
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
@@ -258,13 +273,19 @@ function formFromAutomation(item, workspaces = [], defaultModel, defaultPermissi
|
|
|
258
273
|
permission: item.permission,
|
|
259
274
|
workspaceId: item.workspaceId ?? base.workspaceId,
|
|
260
275
|
modelKey,
|
|
261
|
-
reasoningEffort: item.reasoningEffort ?? "none"
|
|
276
|
+
reasoningEffort: item.reasoningEffort ?? "none",
|
|
277
|
+
timeZone: item.timeZone || schedule.timeZone || base.timeZone
|
|
262
278
|
};
|
|
263
279
|
switch (schedule.kind) {
|
|
264
280
|
case "once":
|
|
265
281
|
return { ...common, scheduleKind: "once", onceAt: toLocalInput(schedule.at) };
|
|
266
282
|
case "interval":
|
|
267
|
-
return {
|
|
283
|
+
return {
|
|
284
|
+
...common,
|
|
285
|
+
scheduleKind: "interval",
|
|
286
|
+
everyMinutes: String(schedule.everyMinutes),
|
|
287
|
+
intervalAnchor: schedule.anchor ?? ""
|
|
288
|
+
};
|
|
268
289
|
case "hourly":
|
|
269
290
|
return { ...common, scheduleKind: "hourly", hourlyMinute: String(schedule.minute).padStart(2, "0") };
|
|
270
291
|
case "daily":
|
|
@@ -1101,6 +1122,51 @@ function clampOnceAt(value) {
|
|
|
1101
1122
|
return new Date(next.getTime() - offset).toISOString().slice(0, 16);
|
|
1102
1123
|
}
|
|
1103
1124
|
|
|
1125
|
+
// src/client/delete-confirmation.tsx
|
|
1126
|
+
var import_react3 = require("react");
|
|
1127
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1128
|
+
function DeleteConfirmation({
|
|
1129
|
+
target,
|
|
1130
|
+
t,
|
|
1131
|
+
busy,
|
|
1132
|
+
onCancel,
|
|
1133
|
+
onConfirm
|
|
1134
|
+
}) {
|
|
1135
|
+
(0, import_react3.useEffect)(() => {
|
|
1136
|
+
if (target === void 0 || busy) return;
|
|
1137
|
+
const onKeyDown = (event) => {
|
|
1138
|
+
if (event.key !== "Escape") return;
|
|
1139
|
+
event.preventDefault();
|
|
1140
|
+
onCancel();
|
|
1141
|
+
};
|
|
1142
|
+
document.addEventListener("keydown", onKeyDown);
|
|
1143
|
+
return () => {
|
|
1144
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
1145
|
+
};
|
|
1146
|
+
}, [busy, onCancel, target]);
|
|
1147
|
+
if (target === void 0) return null;
|
|
1148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-st-mask", onMouseDown: (event) => event.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1149
|
+
"section",
|
|
1150
|
+
{
|
|
1151
|
+
className: "dsh-st-confirm-modal",
|
|
1152
|
+
role: "alertdialog",
|
|
1153
|
+
"aria-modal": "true",
|
|
1154
|
+
"aria-labelledby": "dsh-st-confirm-delete-title",
|
|
1155
|
+
"aria-describedby": "dsh-st-confirm-delete-description",
|
|
1156
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1157
|
+
children: [
|
|
1158
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { id: "dsh-st-confirm-delete-title", children: t("card.confirmDelete") }),
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "dsh-st-confirm-target", children: target.name }),
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { id: "dsh-st-confirm-delete-description", children: t("card.confirmDeleteHint") }),
|
|
1161
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-st-modal-actions", children: [
|
|
1162
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "dsh-st-btn", autoFocus: true, disabled: busy, onClick: onCancel, children: t("card.cancel") }),
|
|
1163
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--danger", disabled: busy, onClick: onConfirm, children: t("card.confirm") })
|
|
1164
|
+
] })
|
|
1165
|
+
]
|
|
1166
|
+
}
|
|
1167
|
+
) });
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1104
1170
|
// src/client/prefill.ts
|
|
1105
1171
|
var pending = null;
|
|
1106
1172
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -1284,27 +1350,28 @@ function createAutomationRuntime(rpc) {
|
|
|
1284
1350
|
}
|
|
1285
1351
|
|
|
1286
1352
|
// src/client/AutomationView.tsx
|
|
1287
|
-
var
|
|
1353
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1288
1354
|
var EXAMPLES = [
|
|
1289
1355
|
{ name: "\u6BCF\u65E5\u56DE\u5F52\u68C0\u67E5", scheduleKind: "daily", time: "09:00", weekdays: [1, 2, 3, 4, 5] },
|
|
1290
1356
|
{ name: "\u6BCF\u5468\u4F9D\u8D56\u5DE1\u68C0", scheduleKind: "weekly", time: "10:00", weekdays: [1] },
|
|
1291
1357
|
{ name: "\u5DE5\u4F5C\u65E5\u65E9\u62A5", scheduleKind: "weekly", time: "08:00", weekdays: [1, 2, 3, 4, 5] }
|
|
1292
1358
|
];
|
|
1293
1359
|
function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
1294
|
-
const state = (0,
|
|
1295
|
-
const [tab, setTab] = (0,
|
|
1296
|
-
const [query, setQuery] = (0,
|
|
1297
|
-
const [creating, setCreating] = (0,
|
|
1298
|
-
const [editingId, setEditingId] = (0,
|
|
1299
|
-
const [
|
|
1300
|
-
const [
|
|
1301
|
-
const [
|
|
1302
|
-
const [
|
|
1303
|
-
const [
|
|
1304
|
-
const [
|
|
1305
|
-
const [
|
|
1306
|
-
const [
|
|
1307
|
-
const
|
|
1360
|
+
const state = (0, import_react4.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
1361
|
+
const [tab, setTab] = (0, import_react4.useState)("mine");
|
|
1362
|
+
const [query, setQuery] = (0, import_react4.useState)("");
|
|
1363
|
+
const [creating, setCreating] = (0, import_react4.useState)(false);
|
|
1364
|
+
const [editingId, setEditingId] = (0, import_react4.useState)();
|
|
1365
|
+
const [deleteTarget, setDeleteTarget] = (0, import_react4.useState)();
|
|
1366
|
+
const [draft, setDraft] = (0, import_react4.useState)();
|
|
1367
|
+
const [busy, setBusy] = (0, import_react4.useState)(false);
|
|
1368
|
+
const [error, setError] = (0, import_react4.useState)();
|
|
1369
|
+
const [historyRange, setHistoryRange] = (0, import_react4.useState)("day");
|
|
1370
|
+
const [historyTask, setHistoryTask] = (0, import_react4.useState)("all");
|
|
1371
|
+
const [historyStatus, setHistoryStatus] = (0, import_react4.useState)("all");
|
|
1372
|
+
const [sortKey, setSortKey] = (0, import_react4.useState)("created");
|
|
1373
|
+
const [sortDirection, setSortDirection] = (0, import_react4.useState)("desc");
|
|
1374
|
+
const now = (0, import_react4.useMemo)(() => new Date(state.snapshot?.serverNow ?? Date.now()), [state.snapshot?.serverNow, state.refreshedAt]);
|
|
1308
1375
|
const snapshot = state.snapshot;
|
|
1309
1376
|
const workspaces = snapshot?.workspaces ?? [];
|
|
1310
1377
|
const models = snapshot?.models ?? [];
|
|
@@ -1348,37 +1415,37 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1348
1415
|
setDraft(formFromAutomation(item, workspaces, snapshot?.defaultModel ?? null, snapshot?.defaultPermission ?? item.permission));
|
|
1349
1416
|
setCreating(true);
|
|
1350
1417
|
};
|
|
1351
|
-
return /* @__PURE__ */ (0,
|
|
1352
|
-
/* @__PURE__ */ (0,
|
|
1353
|
-
/* @__PURE__ */ (0,
|
|
1354
|
-
/* @__PURE__ */ (0,
|
|
1355
|
-
/* @__PURE__ */ (0,
|
|
1418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-shell", children: [
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("header", { className: "dsh-st-top", children: [
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-heading", children: [
|
|
1421
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", { children: t("tab") }),
|
|
1422
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: t("header.lead") })
|
|
1356
1423
|
] }),
|
|
1357
|
-
/* @__PURE__ */ (0,
|
|
1358
|
-
/* @__PURE__ */ (0,
|
|
1359
|
-
/* @__PURE__ */ (0,
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-toolbar", children: [
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { className: "dsh-st-search", value: query, placeholder: t("search.placeholder"), onChange: (event) => setQuery(event.target.value) }),
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", className: "dsh-st-btn", onClick: () => {
|
|
1360
1427
|
setChatPrefill(t("chat.prompt"));
|
|
1361
1428
|
closeSettings?.();
|
|
1362
1429
|
}, children: [
|
|
1363
|
-
/* @__PURE__ */ (0,
|
|
1430
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatIcon, {}),
|
|
1364
1431
|
t("action.chatCreate")
|
|
1365
1432
|
] }),
|
|
1366
|
-
/* @__PURE__ */ (0,
|
|
1367
|
-
/* @__PURE__ */ (0,
|
|
1433
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--primary", disabled: defaultPermission === "" || permissions.length === 0, onClick: () => openCreate(), children: [
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PlusIcon, {}),
|
|
1368
1435
|
t("action.create")
|
|
1369
1436
|
] }),
|
|
1370
|
-
/* @__PURE__ */ (0,
|
|
1437
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "dsh-st-icon", onClick: () => {
|
|
1371
1438
|
void runtime.refresh();
|
|
1372
|
-
}, "aria-label": t("section.refresh"), children: /* @__PURE__ */ (0,
|
|
1439
|
+
}, "aria-label": t("section.refresh"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RefreshIcon, {}) })
|
|
1373
1440
|
] })
|
|
1374
1441
|
] }),
|
|
1375
|
-
/* @__PURE__ */ (0,
|
|
1376
|
-
/* @__PURE__ */ (0,
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-banner", role: "note", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
1443
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoIcon, {}),
|
|
1377
1444
|
t("banner.wake")
|
|
1378
1445
|
] }) }),
|
|
1379
|
-
/* @__PURE__ */ (0,
|
|
1380
|
-
/* @__PURE__ */ (0,
|
|
1381
|
-
/* @__PURE__ */ (0,
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "dsh-st-examples", children: [
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-examples-head", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: t("examples.title") }) }),
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-example-row", children: EXAMPLES.map((example, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1382
1449
|
"button",
|
|
1383
1450
|
{
|
|
1384
1451
|
type: "button",
|
|
@@ -1392,10 +1459,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1392
1459
|
weekdays: example.weekdays
|
|
1393
1460
|
}),
|
|
1394
1461
|
children: [
|
|
1395
|
-
/* @__PURE__ */ (0,
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1397
|
-
/* @__PURE__ */ (0,
|
|
1398
|
-
/* @__PURE__ */ (0,
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: t(`examples.${index + 1}.title`) }),
|
|
1463
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: t(`examples.${index + 1}.body`) }),
|
|
1464
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "dsh-st-chip", children: [
|
|
1465
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ClockIcon, {}),
|
|
1399
1466
|
t(`examples.${index + 1}.chip`)
|
|
1400
1467
|
] })
|
|
1401
1468
|
]
|
|
@@ -1403,19 +1470,19 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1403
1470
|
example.name
|
|
1404
1471
|
)) })
|
|
1405
1472
|
] }),
|
|
1406
|
-
error !== void 0 && /* @__PURE__ */ (0,
|
|
1407
|
-
(state.phase === "idle" || state.phase === "loading" && snapshot === void 0) && /* @__PURE__ */ (0,
|
|
1408
|
-
state.phase === "error" && snapshot === void 0 && /* @__PURE__ */ (0,
|
|
1409
|
-
/* @__PURE__ */ (0,
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1411
|
-
/* @__PURE__ */ (0,
|
|
1473
|
+
error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dsh-st-error", children: error }),
|
|
1474
|
+
(state.phase === "idle" || state.phase === "loading" && snapshot === void 0) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dsh-st-muted", children: t("loading") }),
|
|
1475
|
+
state.phase === "error" && snapshot === void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-empty", children: [
|
|
1476
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t("error.title") }),
|
|
1477
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: state.error }),
|
|
1478
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--primary", onClick: () => {
|
|
1412
1479
|
void runtime.refresh();
|
|
1413
1480
|
}, children: t("error.retry") })
|
|
1414
1481
|
] }),
|
|
1415
|
-
/* @__PURE__ */ (0,
|
|
1416
|
-
/* @__PURE__ */ (0,
|
|
1417
|
-
/* @__PURE__ */ (0,
|
|
1418
|
-
tab === "mine" && /* @__PURE__ */ (0,
|
|
1482
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-tabs", children: [
|
|
1483
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: tab === "mine" ? "is-on" : "", onClick: () => setTab("mine"), children: t("tabs.mine") }),
|
|
1484
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: tab === "runs" ? "is-on" : "", onClick: () => setTab("runs"), children: t("tabs.runs") }),
|
|
1485
|
+
tab === "mine" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1419
1486
|
SortMenu,
|
|
1420
1487
|
{
|
|
1421
1488
|
t,
|
|
@@ -1427,9 +1494,9 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1427
1494
|
}
|
|
1428
1495
|
}
|
|
1429
1496
|
),
|
|
1430
|
-
tab === "runs" && /* @__PURE__ */ (0,
|
|
1431
|
-
["day", "week", "month"].map((range) => /* @__PURE__ */ (0,
|
|
1432
|
-
/* @__PURE__ */ (0,
|
|
1497
|
+
tab === "runs" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-filters", children: [
|
|
1498
|
+
["day", "week", "month"].map((range) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: historyRange === range ? "is-on" : "", onClick: () => setHistoryRange(range), children: t(`history.range.${range}`) }, range)),
|
|
1499
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1433
1500
|
DropdownMenu,
|
|
1434
1501
|
{
|
|
1435
1502
|
ariaLabel: t("history.allTasks"),
|
|
@@ -1444,13 +1511,13 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1444
1511
|
]
|
|
1445
1512
|
}
|
|
1446
1513
|
),
|
|
1447
|
-
/* @__PURE__ */ (0,
|
|
1514
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1448
1515
|
DropdownMenu,
|
|
1449
1516
|
{
|
|
1450
1517
|
ariaLabel: t("history.allStatus"),
|
|
1451
1518
|
options: [
|
|
1452
1519
|
{ key: "all", label: t("history.allStatus"), selected: historyStatus === "all", onSelect: () => setHistoryStatus("all") },
|
|
1453
|
-
...
|
|
1520
|
+
...HISTORY_STATUS_OPTIONS.map((status) => ({
|
|
1454
1521
|
key: status,
|
|
1455
1522
|
label: t(`status.${status}`),
|
|
1456
1523
|
selected: historyStatus === status,
|
|
@@ -1461,10 +1528,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1461
1528
|
)
|
|
1462
1529
|
] })
|
|
1463
1530
|
] }),
|
|
1464
|
-
tab === "mine" && (automations.length === 0 ? /* @__PURE__ */ (0,
|
|
1465
|
-
/* @__PURE__ */ (0,
|
|
1466
|
-
/* @__PURE__ */ (0,
|
|
1467
|
-
] }) : /* @__PURE__ */ (0,
|
|
1531
|
+
tab === "mine" && (automations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-empty", children: [
|
|
1532
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t("empty.title") }),
|
|
1533
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: t("empty.body") })
|
|
1534
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-grid", children: automations.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1468
1535
|
TaskCard,
|
|
1469
1536
|
{
|
|
1470
1537
|
item,
|
|
@@ -1478,17 +1545,15 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1478
1545
|
onRun: () => {
|
|
1479
1546
|
void runAction(() => runtime.runNow(item.id));
|
|
1480
1547
|
},
|
|
1481
|
-
onDelete: () =>
|
|
1482
|
-
void runAction(() => runtime.mutateAutomation(item.id, "delete"));
|
|
1483
|
-
}
|
|
1548
|
+
onDelete: () => setDeleteTarget(item)
|
|
1484
1549
|
},
|
|
1485
1550
|
item.id
|
|
1486
1551
|
)) })),
|
|
1487
|
-
tab === "runs" && (groups.length === 0 ? /* @__PURE__ */ (0,
|
|
1488
|
-
/* @__PURE__ */ (0,
|
|
1489
|
-
group.items.map((run) => /* @__PURE__ */ (0,
|
|
1552
|
+
tab === "runs" && (groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-empty", children: t("runs.empty") }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-timeline", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "dsh-st-group", children: [
|
|
1553
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: group.label }),
|
|
1554
|
+
group.items.map((run) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RunRow, { run, t }, run.id))
|
|
1490
1555
|
] }, group.key)) })),
|
|
1491
|
-
creating && /* @__PURE__ */ (0,
|
|
1556
|
+
creating && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1492
1557
|
CreateModal,
|
|
1493
1558
|
{
|
|
1494
1559
|
t,
|
|
@@ -1517,6 +1582,23 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1517
1582
|
}
|
|
1518
1583
|
},
|
|
1519
1584
|
editingId ?? "create"
|
|
1585
|
+
),
|
|
1586
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1587
|
+
DeleteConfirmation,
|
|
1588
|
+
{
|
|
1589
|
+
target: deleteTarget,
|
|
1590
|
+
t,
|
|
1591
|
+
busy,
|
|
1592
|
+
onCancel: () => setDeleteTarget(void 0),
|
|
1593
|
+
onConfirm: () => {
|
|
1594
|
+
const target = deleteTarget;
|
|
1595
|
+
if (target === void 0) return;
|
|
1596
|
+
void runAction(async () => {
|
|
1597
|
+
await runtime.mutateAutomation(target.id, "delete");
|
|
1598
|
+
setDeleteTarget(void 0);
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1520
1602
|
)
|
|
1521
1603
|
] });
|
|
1522
1604
|
}
|
|
@@ -1530,9 +1612,9 @@ function TaskCard({
|
|
|
1530
1612
|
onRun,
|
|
1531
1613
|
onDelete
|
|
1532
1614
|
}) {
|
|
1533
|
-
const [menu, setMenu] = (0,
|
|
1534
|
-
const root = (0,
|
|
1535
|
-
(0,
|
|
1615
|
+
const [menu, setMenu] = (0, import_react4.useState)(false);
|
|
1616
|
+
const root = (0, import_react4.useRef)(null);
|
|
1617
|
+
(0, import_react4.useEffect)(() => {
|
|
1536
1618
|
if (!menu) return;
|
|
1537
1619
|
const close = (event) => {
|
|
1538
1620
|
if (root.current !== null && !root.current.contains(event.target)) setMenu(false);
|
|
@@ -1542,48 +1624,48 @@ function TaskCard({
|
|
|
1542
1624
|
document.removeEventListener("mousedown", close);
|
|
1543
1625
|
};
|
|
1544
1626
|
}, [menu]);
|
|
1545
|
-
return /* @__PURE__ */ (0,
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
1627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { className: "dsh-st-card", ref: root, onClick: onEdit, children: [
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-card-head", children: [
|
|
1629
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: `dsh-st-switch ${item.status === "active" ? "is-on" : ""}`, role: "switch", "aria-checked": item.status === "active", disabled: busy, onClick: (event) => {
|
|
1548
1630
|
event.stopPropagation();
|
|
1549
1631
|
onToggle();
|
|
1550
1632
|
} }),
|
|
1551
|
-
/* @__PURE__ */ (0,
|
|
1633
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "dsh-st-more", onClick: (event) => {
|
|
1552
1634
|
event.stopPropagation();
|
|
1553
1635
|
setMenu((value) => !value);
|
|
1554
|
-
}, "aria-label": t("card.more"), children: /* @__PURE__ */ (0,
|
|
1555
|
-
menu && /* @__PURE__ */ (0,
|
|
1556
|
-
/* @__PURE__ */ (0,
|
|
1636
|
+
}, "aria-label": t("card.more"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MoreIcon, {}) }),
|
|
1637
|
+
menu && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-menu", onClick: (event) => event.stopPropagation(), children: [
|
|
1638
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", disabled: busy, onClick: () => {
|
|
1557
1639
|
setMenu(false);
|
|
1558
1640
|
onRun();
|
|
1559
1641
|
}, children: [
|
|
1560
|
-
/* @__PURE__ */ (0,
|
|
1642
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PlayIcon, { width: 16, height: 16 }),
|
|
1561
1643
|
t("menu.run")
|
|
1562
1644
|
] }),
|
|
1563
|
-
/* @__PURE__ */ (0,
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", disabled: busy, onClick: () => {
|
|
1564
1646
|
setMenu(false);
|
|
1565
1647
|
onEdit();
|
|
1566
1648
|
}, children: [
|
|
1567
|
-
/* @__PURE__ */ (0,
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PencilIcon, { width: 16, height: 16 }),
|
|
1568
1650
|
t("menu.edit")
|
|
1569
1651
|
] }),
|
|
1570
|
-
/* @__PURE__ */ (0,
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", className: "is-danger", disabled: busy, onClick: () => {
|
|
1571
1653
|
setMenu(false);
|
|
1572
1654
|
onDelete();
|
|
1573
1655
|
}, children: [
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TrashIcon, { width: 16, height: 16 }),
|
|
1575
1657
|
t("menu.delete")
|
|
1576
1658
|
] })
|
|
1577
1659
|
] })
|
|
1578
1660
|
] }),
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
1580
|
-
/* @__PURE__ */ (0,
|
|
1581
|
-
/* @__PURE__ */ (0,
|
|
1582
|
-
/* @__PURE__ */ (0,
|
|
1583
|
-
/* @__PURE__ */ (0,
|
|
1661
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: item.name }),
|
|
1662
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: item.prompt }),
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-card-foot", children: [
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "dsh-st-chip", children: [
|
|
1665
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ClockIcon, {}),
|
|
1584
1666
|
formatSchedule(item.schedule, t)
|
|
1585
1667
|
] }),
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: item.nextRunAt === void 0 ? t("stats.noneScheduled") : t("history.nextApprox", { when: formatWithin(item.nextRunAt, now, t) }) })
|
|
1587
1669
|
] })
|
|
1588
1670
|
] });
|
|
1589
1671
|
}
|
|
@@ -1593,7 +1675,7 @@ function SortMenu({
|
|
|
1593
1675
|
sortDirection,
|
|
1594
1676
|
onSelect
|
|
1595
1677
|
}) {
|
|
1596
|
-
return /* @__PURE__ */ (0,
|
|
1678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1597
1679
|
DropdownMenu,
|
|
1598
1680
|
{
|
|
1599
1681
|
className: "dsh-st-sort",
|
|
@@ -1612,9 +1694,9 @@ function DropdownMenu({
|
|
|
1612
1694
|
className,
|
|
1613
1695
|
options
|
|
1614
1696
|
}) {
|
|
1615
|
-
const [open, setOpen] = (0,
|
|
1616
|
-
const root = (0,
|
|
1617
|
-
(0,
|
|
1697
|
+
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1698
|
+
const root = (0, import_react4.useRef)(null);
|
|
1699
|
+
(0, import_react4.useEffect)(() => {
|
|
1618
1700
|
if (!open) return;
|
|
1619
1701
|
const close = (event) => {
|
|
1620
1702
|
if (root.current !== null && !root.current.contains(event.target)) setOpen(false);
|
|
@@ -1630,12 +1712,12 @@ function DropdownMenu({
|
|
|
1630
1712
|
};
|
|
1631
1713
|
}, [open]);
|
|
1632
1714
|
const selectedLabel = options.find((option) => option.selected)?.label ?? options[0]?.label ?? ariaLabel;
|
|
1633
|
-
return /* @__PURE__ */ (0,
|
|
1634
|
-
/* @__PURE__ */ (0,
|
|
1635
|
-
/* @__PURE__ */ (0,
|
|
1636
|
-
/* @__PURE__ */ (0,
|
|
1715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `dsh-st-dropdown${className === void 0 ? "" : ` ${className}`}`, ref: root, children: [
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", className: `dsh-st-dropdown-btn${open ? " is-open" : ""}`, "aria-label": ariaLabel, "aria-expanded": open, onClick: () => setOpen((value) => !value), children: [
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-dropdown-label", children: selectedLabel }),
|
|
1718
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronIcon, { width: 10, height: 10, className: "dsh-st-dropdown-chevron" })
|
|
1637
1719
|
] }),
|
|
1638
|
-
open && /* @__PURE__ */ (0,
|
|
1720
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-dropdown-menu", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1639
1721
|
DropdownRow,
|
|
1640
1722
|
{
|
|
1641
1723
|
label: option.label,
|
|
@@ -1654,19 +1736,19 @@ function DropdownRow({
|
|
|
1654
1736
|
selected,
|
|
1655
1737
|
onSelect
|
|
1656
1738
|
}) {
|
|
1657
|
-
return /* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
1659
|
-
selected ? /* @__PURE__ */ (0,
|
|
1739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", "aria-pressed": selected, className: selected ? "is-selected" : void 0, onClick: onSelect, children: [
|
|
1740
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: label }),
|
|
1741
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CheckOutlineIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-sort-tick" })
|
|
1660
1742
|
] });
|
|
1661
1743
|
}
|
|
1662
1744
|
function RunRow({ run, t }) {
|
|
1663
1745
|
const duration = formatDuration(run.startedAt, run.finishedAt);
|
|
1664
|
-
return /* @__PURE__ */ (0,
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
1666
|
-
/* @__PURE__ */ (0,
|
|
1667
|
-
/* @__PURE__ */ (0,
|
|
1668
|
-
duration !== void 0 && /* @__PURE__ */ (0,
|
|
1669
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { className: `dsh-st-run is-${run.status}`, children: [
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: run.automationName }),
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: clockTime(run.startedAt ?? run.scheduledFor) }),
|
|
1750
|
+
duration !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: duration }),
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: t("history.trigger") })
|
|
1670
1752
|
] })
|
|
1671
1753
|
] });
|
|
1672
1754
|
}
|
|
@@ -2151,7 +2233,7 @@ function isForeignSidebarHost(component) {
|
|
|
2151
2233
|
}
|
|
2152
2234
|
|
|
2153
2235
|
// src/client/native-session-list.tsx
|
|
2154
|
-
var
|
|
2236
|
+
var import_react6 = require("react");
|
|
2155
2237
|
var import_react_dom2 = require("react-dom");
|
|
2156
2238
|
|
|
2157
2239
|
// src/client/native-session-menu.ts
|
|
@@ -2214,16 +2296,16 @@ function nativeSessionHoverStyle(row, card, viewport) {
|
|
|
2214
2296
|
top: `${Math.round(top)}px`
|
|
2215
2297
|
};
|
|
2216
2298
|
}
|
|
2217
|
-
function relativeTime(value) {
|
|
2299
|
+
function relativeTime(value, t, now = Date.now()) {
|
|
2218
2300
|
const ts = Date.parse(value || "");
|
|
2219
2301
|
if (!Number.isFinite(ts)) return "";
|
|
2220
|
-
const delta = Math.max(0,
|
|
2302
|
+
const delta = Math.max(0, now - ts);
|
|
2221
2303
|
const min = Math.floor(delta / 6e4);
|
|
2222
|
-
if (min < 1) return "
|
|
2223
|
-
if (min < 60) return
|
|
2304
|
+
if (min < 1) return t("time.now");
|
|
2305
|
+
if (min < 60) return t("time.minuteAgo", { count: min });
|
|
2224
2306
|
const hour = Math.floor(min / 60);
|
|
2225
|
-
if (hour < 24) return
|
|
2226
|
-
return
|
|
2307
|
+
if (hour < 24) return t("time.hourAgo", { count: hour });
|
|
2308
|
+
return t("time.dayAgo", { count: Math.floor(hour / 24) });
|
|
2227
2309
|
}
|
|
2228
2310
|
|
|
2229
2311
|
// src/run-title.ts
|
|
@@ -2504,8 +2586,8 @@ function latestSessionTime(group) {
|
|
|
2504
2586
|
}
|
|
2505
2587
|
|
|
2506
2588
|
// src/client/workspace-toolbar.tsx
|
|
2507
|
-
var
|
|
2508
|
-
var
|
|
2589
|
+
var import_react5 = require("react");
|
|
2590
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2509
2591
|
function officialSearchIconSize(expanded) {
|
|
2510
2592
|
return expanded ? 11 : 14;
|
|
2511
2593
|
}
|
|
@@ -2518,15 +2600,15 @@ function WorkspaceToolbar({
|
|
|
2518
2600
|
onSortChange,
|
|
2519
2601
|
onGroupModeChange
|
|
2520
2602
|
}) {
|
|
2521
|
-
const [searching, setSearching] = (0,
|
|
2522
|
-
const [filterOpen, setFilterOpen] = (0,
|
|
2523
|
-
const inputRef = (0,
|
|
2524
|
-
const rootRef = (0,
|
|
2603
|
+
const [searching, setSearching] = (0, import_react5.useState)(query.trim() !== "");
|
|
2604
|
+
const [filterOpen, setFilterOpen] = (0, import_react5.useState)(false);
|
|
2605
|
+
const inputRef = (0, import_react5.useRef)(null);
|
|
2606
|
+
const rootRef = (0, import_react5.useRef)(null);
|
|
2525
2607
|
const searchSize = officialSearchIconSize(searching);
|
|
2526
|
-
(0,
|
|
2608
|
+
(0, import_react5.useEffect)(() => {
|
|
2527
2609
|
if (searching) inputRef.current?.focus();
|
|
2528
2610
|
}, [searching]);
|
|
2529
|
-
(0,
|
|
2611
|
+
(0, import_react5.useEffect)(() => {
|
|
2530
2612
|
if (!filterOpen) return;
|
|
2531
2613
|
const close = (event) => {
|
|
2532
2614
|
const target = event.target;
|
|
@@ -2544,37 +2626,37 @@ function WorkspaceToolbar({
|
|
|
2544
2626
|
onQueryChange("");
|
|
2545
2627
|
setSearching(false);
|
|
2546
2628
|
};
|
|
2547
|
-
return /* @__PURE__ */ (0,
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2551
|
-
/* @__PURE__ */ (0,
|
|
2629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: searching ? "dsh-st-n-toolbar is-search" : "dsh-st-n-toolbar", ref: rootRef, children: [
|
|
2630
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-head-label", children: t("sidebar.workspaces") }),
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-search-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-search", onClick: openSearch, children: [
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dsh-st-n-search-btn", "aria-label": t("sidebar.search"), "aria-expanded": searching, onClick: openSearch, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SearchOutlineIcon, { width: searchSize, height: searchSize }) }),
|
|
2633
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { ref: inputRef, className: "dsh-st-n-search-input", value: query, placeholder: t("sidebar.searchSessions"), "aria-label": t("sidebar.searchSessions"), tabIndex: searching ? 0 : -1, "aria-hidden": !searching, onChange: (event) => onQueryChange(event.target.value), onKeyDown: (event) => {
|
|
2552
2634
|
if (event.key === "Escape") closeSearch();
|
|
2553
2635
|
} }),
|
|
2554
|
-
searching && /* @__PURE__ */ (0,
|
|
2636
|
+
searching && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dsh-st-n-search-clear", "aria-label": t("sidebar.clearSearch"), onClick: (event) => {
|
|
2555
2637
|
event.stopPropagation();
|
|
2556
2638
|
closeSearch();
|
|
2557
|
-
}, children: /* @__PURE__ */ (0,
|
|
2639
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseOutlineIcon, { width: 14, height: 14 }) })
|
|
2558
2640
|
] }) }),
|
|
2559
|
-
/* @__PURE__ */ (0,
|
|
2560
|
-
/* @__PURE__ */ (0,
|
|
2561
|
-
filterOpen && /* @__PURE__ */ (0,
|
|
2562
|
-
/* @__PURE__ */ (0,
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2641
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-head-acts", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-head-filter", children: [
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: filterOpen ? "dsh-st-n-head-btn is-on" : "dsh-st-n-head-btn", "aria-label": t("sidebar.filter"), "aria-expanded": filterOpen, onClick: () => setFilterOpen((open) => !open), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SlidersIcon, { width: 16, height: 16 }) }),
|
|
2643
|
+
filterOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-filter-menu", role: "menu", children: [
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.groupBy") }),
|
|
2645
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FilterRow, { label: t("sidebar.groupWorkspace"), selected: groupMode === "workspace", onSelect: () => {
|
|
2564
2646
|
onGroupModeChange("workspace");
|
|
2565
2647
|
setFilterOpen(false);
|
|
2566
2648
|
} }),
|
|
2567
|
-
/* @__PURE__ */ (0,
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FilterRow, { label: t("sidebar.groupList"), selected: groupMode === "list", onSelect: () => {
|
|
2568
2650
|
onGroupModeChange("list");
|
|
2569
2651
|
setFilterOpen(false);
|
|
2570
2652
|
} }),
|
|
2571
|
-
/* @__PURE__ */ (0,
|
|
2572
|
-
/* @__PURE__ */ (0,
|
|
2573
|
-
/* @__PURE__ */ (0,
|
|
2653
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-filter-split" }),
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.sortBy") }),
|
|
2655
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FilterRow, { label: t("sidebar.sortManual"), selected: sort === "manual", onSelect: () => {
|
|
2574
2656
|
onSortChange("manual");
|
|
2575
2657
|
setFilterOpen(false);
|
|
2576
2658
|
} }),
|
|
2577
|
-
/* @__PURE__ */ (0,
|
|
2659
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FilterRow, { label: t("sidebar.sortTime"), selected: sort === "time", onSelect: () => {
|
|
2578
2660
|
onSortChange("time");
|
|
2579
2661
|
setFilterOpen(false);
|
|
2580
2662
|
} })
|
|
@@ -2587,34 +2669,34 @@ function FilterRow({
|
|
|
2587
2669
|
selected,
|
|
2588
2670
|
onSelect
|
|
2589
2671
|
}) {
|
|
2590
|
-
return /* @__PURE__ */ (0,
|
|
2591
|
-
/* @__PURE__ */ (0,
|
|
2592
|
-
selected ? /* @__PURE__ */ (0,
|
|
2672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", role: "menuitemradio", "aria-checked": selected, className: selected ? "is-on" : void 0, onClick: onSelect, children: [
|
|
2673
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: label }),
|
|
2674
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckOutlineIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-filter-tick" })
|
|
2593
2675
|
] });
|
|
2594
2676
|
}
|
|
2595
2677
|
|
|
2596
2678
|
// src/client/native-session-list.tsx
|
|
2597
|
-
var
|
|
2679
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2598
2680
|
var EMPTY_SESSION_BY_ID = {};
|
|
2599
2681
|
function NativeScheduleSessionList(props) {
|
|
2600
2682
|
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession, forkSession } = props;
|
|
2601
|
-
const state = (0,
|
|
2683
|
+
const state = (0, import_react6.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
2602
2684
|
const selectedId = useSessions ? useSessions((snap) => snap?.current ?? null) : null;
|
|
2603
2685
|
const sessionById = useSessions ? useSessions((snap) => snap?.byId ?? EMPTY_SESSION_BY_ID) : EMPTY_SESSION_BY_ID;
|
|
2604
2686
|
const archivedIds = useWorkspaces ? useWorkspaces((snap) => snap?.archivedSessionIds ?? []) : [];
|
|
2605
|
-
const [folded, setFolded] = (0,
|
|
2606
|
-
const [openMenu, setOpenMenu] = (0,
|
|
2607
|
-
const [query, setQuery] = (0,
|
|
2608
|
-
const [sort, setSort] = (0,
|
|
2609
|
-
const [groupMode, setGroupMode] = (0,
|
|
2610
|
-
const archived = (0,
|
|
2687
|
+
const [folded, setFolded] = (0, import_react6.useState)({});
|
|
2688
|
+
const [openMenu, setOpenMenu] = (0, import_react6.useState)(null);
|
|
2689
|
+
const [query, setQuery] = (0, import_react6.useState)("");
|
|
2690
|
+
const [sort, setSort] = (0, import_react6.useState)("time");
|
|
2691
|
+
const [groupMode, setGroupMode] = (0, import_react6.useState)("workspace");
|
|
2692
|
+
const archived = (0, import_react6.useMemo)(() => new Set(archivedIds), [archivedIds]);
|
|
2611
2693
|
const listedIds = useSessions ? useSessions((snap) => Array.isArray(snap?.ids) ? snap.ids : void 0) : void 0;
|
|
2612
|
-
const presentIds = (0,
|
|
2694
|
+
const presentIds = (0, import_react6.useMemo)(() => {
|
|
2613
2695
|
if (listedIds !== void 0) return new Set(listedIds);
|
|
2614
2696
|
const keys = Object.keys(sessionById);
|
|
2615
2697
|
return keys.length > 0 ? new Set(keys) : void 0;
|
|
2616
2698
|
}, [listedIds, sessionById]);
|
|
2617
|
-
const groups = (0,
|
|
2699
|
+
const groups = (0, import_react6.useMemo)(() => {
|
|
2618
2700
|
const snapshot = state.snapshot;
|
|
2619
2701
|
if (snapshot === void 0) return [];
|
|
2620
2702
|
return groupScheduledSessions(snapshot.automations, snapshot.runs).map((group) => ({
|
|
@@ -2630,20 +2712,20 @@ function NativeScheduleSessionList(props) {
|
|
|
2630
2712
|
})
|
|
2631
2713
|
})).filter((group) => group.sessions.length > 0);
|
|
2632
2714
|
}, [archived, presentIds, sessionById, state.snapshot]);
|
|
2633
|
-
const visibleGroups = (0,
|
|
2634
|
-
return /* @__PURE__ */ (0,
|
|
2635
|
-
/* @__PURE__ */ (0,
|
|
2636
|
-
/* @__PURE__ */ (0,
|
|
2637
|
-
state.phase === "loading" && visibleGroups.length === 0 && /* @__PURE__ */ (0,
|
|
2638
|
-
visibleGroups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0,
|
|
2715
|
+
const visibleGroups = (0, import_react6.useMemo)(() => applyWorkspaceBrowserQuery(groups.map((group) => ({ ...group, name: group.name })), query, sort, groupMode), [groups, query, sort, groupMode]);
|
|
2716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-n", children: [
|
|
2717
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(WorkspaceToolbar, { t, query, sort, groupMode, onQueryChange: setQuery, onSortChange: setSort, onGroupModeChange: setGroupMode }),
|
|
2718
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-n-tree", role: "tree", children: [
|
|
2719
|
+
state.phase === "loading" && visibleGroups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-n-empty", children: t("loading") }),
|
|
2720
|
+
visibleGroups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-n-empty", children: t("sidebar.empty") }),
|
|
2639
2721
|
visibleGroups.map((group) => {
|
|
2640
2722
|
const expanded = folded[group.id] !== true;
|
|
2641
|
-
return /* @__PURE__ */ (0,
|
|
2642
|
-
groupMode === "workspace" && /* @__PURE__ */ (0,
|
|
2643
|
-
/* @__PURE__ */ (0,
|
|
2644
|
-
/* @__PURE__ */ (0,
|
|
2723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-n-group", children: [
|
|
2724
|
+
groupMode === "workspace" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-n-row", role: "treeitem", "aria-expanded": expanded, onClick: () => setFolded((current) => ({ ...current, [group.id]: expanded })), children: [
|
|
2725
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-slot dsh-st-n-folder", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FolderOpenIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FolderClosedIcon, { width: 16, height: 16 }) }),
|
|
2726
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-title", children: group.name })
|
|
2645
2727
|
] }),
|
|
2646
|
-
(groupMode === "list" || expanded) && group.sessions.map((session) => /* @__PURE__ */ (0,
|
|
2728
|
+
(groupMode === "list" || expanded) && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2647
2729
|
NativeSessionRow,
|
|
2648
2730
|
{
|
|
2649
2731
|
t,
|
|
@@ -2674,19 +2756,19 @@ function NativeScheduleSessionList(props) {
|
|
|
2674
2756
|
}
|
|
2675
2757
|
function NativeSessionRow(props) {
|
|
2676
2758
|
const { t, id, title, hoverTitle, updatedAt, running, selected, menuOpen, menuPoint, onToggleMenu, onCloseMenu, onOpen, renameSession, archiveSession, forkSession } = props;
|
|
2677
|
-
const rowRef = (0,
|
|
2678
|
-
const menuRef = (0,
|
|
2679
|
-
const hoverRef = (0,
|
|
2680
|
-
const [hoverOpen, setHoverOpen] = (0,
|
|
2681
|
-
const [hoverStyle, setHoverStyle] = (0,
|
|
2682
|
-
const hoverTimer = (0,
|
|
2683
|
-
const [renaming, setRenaming] = (0,
|
|
2684
|
-
const [draft, setDraft] = (0,
|
|
2685
|
-
const [menuStyle, setMenuStyle] = (0,
|
|
2686
|
-
(0,
|
|
2759
|
+
const rowRef = (0, import_react6.useRef)(null);
|
|
2760
|
+
const menuRef = (0, import_react6.useRef)(null);
|
|
2761
|
+
const hoverRef = (0, import_react6.useRef)(null);
|
|
2762
|
+
const [hoverOpen, setHoverOpen] = (0, import_react6.useState)(false);
|
|
2763
|
+
const [hoverStyle, setHoverStyle] = (0, import_react6.useState)({});
|
|
2764
|
+
const hoverTimer = (0, import_react6.useRef)(void 0);
|
|
2765
|
+
const [renaming, setRenaming] = (0, import_react6.useState)(false);
|
|
2766
|
+
const [draft, setDraft] = (0, import_react6.useState)(title);
|
|
2767
|
+
const [menuStyle, setMenuStyle] = (0, import_react6.useState)({});
|
|
2768
|
+
(0, import_react6.useEffect)(() => {
|
|
2687
2769
|
setDraft(title);
|
|
2688
2770
|
}, [title]);
|
|
2689
|
-
(0,
|
|
2771
|
+
(0, import_react6.useEffect)(() => {
|
|
2690
2772
|
if (!menuOpen) return;
|
|
2691
2773
|
const close = (event) => {
|
|
2692
2774
|
if (!shouldCloseNativeSessionMenu(event.target, [rowRef.current, menuRef.current])) return;
|
|
@@ -2702,7 +2784,7 @@ function NativeSessionRow(props) {
|
|
|
2702
2784
|
document.removeEventListener("keydown", onKey);
|
|
2703
2785
|
};
|
|
2704
2786
|
}, [menuOpen, onCloseMenu]);
|
|
2705
|
-
(0,
|
|
2787
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
2706
2788
|
if (!menuOpen) return;
|
|
2707
2789
|
const update = () => {
|
|
2708
2790
|
const el = menuRef.current;
|
|
@@ -2717,7 +2799,7 @@ function NativeSessionRow(props) {
|
|
|
2717
2799
|
document.removeEventListener("scroll", update, true);
|
|
2718
2800
|
};
|
|
2719
2801
|
}, [menuOpen, menuPoint]);
|
|
2720
|
-
(0,
|
|
2802
|
+
(0, import_react6.useEffect)(() => {
|
|
2721
2803
|
if (!hoverOpen || menuOpen) return;
|
|
2722
2804
|
const update = () => {
|
|
2723
2805
|
const row = rowRef.current?.getBoundingClientRect();
|
|
@@ -2734,7 +2816,7 @@ function NativeSessionRow(props) {
|
|
|
2734
2816
|
document.removeEventListener("scroll", update, true);
|
|
2735
2817
|
};
|
|
2736
2818
|
}, [hoverOpen, menuOpen, title, updatedAt, running]);
|
|
2737
|
-
(0,
|
|
2819
|
+
(0, import_react6.useEffect)(() => () => {
|
|
2738
2820
|
if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
|
|
2739
2821
|
}, []);
|
|
2740
2822
|
const run = (action) => {
|
|
@@ -2751,7 +2833,7 @@ function NativeSessionRow(props) {
|
|
|
2751
2833
|
};
|
|
2752
2834
|
const rowClass = "dsh-st-n-sess" + (selected ? " is-on" : "") + (menuOpen ? " is-menu" : "");
|
|
2753
2835
|
if (renaming) {
|
|
2754
|
-
return /* @__PURE__ */ (0,
|
|
2836
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: rowClass, ref: rowRef, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { className: "dsh-st-n-rename", value: draft, autoFocus: true, "aria-label": t("session.rename"), onChange: (event) => setDraft(event.target.value), onClick: (event) => event.stopPropagation(), onKeyDown: (event) => {
|
|
2755
2837
|
if (event.key === "Enter") {
|
|
2756
2838
|
event.preventDefault();
|
|
2757
2839
|
setRenaming(false);
|
|
@@ -2768,23 +2850,23 @@ function NativeSessionRow(props) {
|
|
|
2768
2850
|
} }) });
|
|
2769
2851
|
}
|
|
2770
2852
|
const menuItems = [
|
|
2771
|
-
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0,
|
|
2853
|
+
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PencilIcon, { width: 16, height: 16 }), go: () => {
|
|
2772
2854
|
setRenaming(true);
|
|
2773
2855
|
} },
|
|
2774
|
-
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0,
|
|
2775
|
-
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0,
|
|
2856
|
+
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BranchIcon, { width: 16, height: 16 }), go: () => run(() => forkSession?.(id)) },
|
|
2857
|
+
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ArchiveIcon, { width: 16, height: 16 }), go: () => run(() => archiveSession?.(id)) }
|
|
2776
2858
|
];
|
|
2777
2859
|
const menu = menuOpen && typeof document !== "undefined" ? (0, import_react_dom2.createPortal)(
|
|
2778
|
-
/* @__PURE__ */ (0,
|
|
2860
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: menuRef, className: "dsh-st-n-menu is-float", "data-n-menu": id, style: menuStyle, onMouseDown: (event) => event.stopPropagation(), onClick: (event) => event.stopPropagation(), children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: void 0, onClick: () => {
|
|
2779
2861
|
onCloseMenu();
|
|
2780
2862
|
item.go();
|
|
2781
2863
|
}, children: [
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
2864
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-mi", children: item.icon }),
|
|
2783
2865
|
item.label
|
|
2784
2866
|
] }, item.id)) }),
|
|
2785
2867
|
document.body
|
|
2786
2868
|
) : null;
|
|
2787
|
-
return /* @__PURE__ */ (0,
|
|
2869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: rowClass, ref: rowRef, role: "treeitem", tabIndex: 0, "aria-selected": selected, "data-n-menu-root": id, onClick: onOpen, onMouseEnter: showHover, onMouseLeave: hideHover, onKeyDown: (event) => {
|
|
2788
2870
|
if (event.key === "Enter" || event.key === " ") {
|
|
2789
2871
|
event.preventDefault();
|
|
2790
2872
|
onOpen();
|
|
@@ -2794,21 +2876,21 @@ function NativeSessionRow(props) {
|
|
|
2794
2876
|
event.stopPropagation();
|
|
2795
2877
|
onToggleMenu(event);
|
|
2796
2878
|
}, children: [
|
|
2797
|
-
/* @__PURE__ */ (0,
|
|
2798
|
-
/* @__PURE__ */ (0,
|
|
2799
|
-
/* @__PURE__ */ (0,
|
|
2800
|
-
/* @__PURE__ */ (0,
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-slot", children: running ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RunningStateDot, {}) : null }),
|
|
2880
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-title", children: title }),
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-time", children: relativeTime(updatedAt, t) }),
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-n-acts", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-n-ico", "aria-label": title + " \u66F4\u591A", onMouseDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
2801
2883
|
event.stopPropagation();
|
|
2802
2884
|
hideHover();
|
|
2803
2885
|
onToggleMenu(event);
|
|
2804
|
-
}, children: /* @__PURE__ */ (0,
|
|
2886
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EllipsisIcon, { width: 16, height: 16 }) }) }),
|
|
2805
2887
|
menu,
|
|
2806
2888
|
hoverOpen && !menuOpen && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
2808
|
-
/* @__PURE__ */ (0,
|
|
2809
|
-
/* @__PURE__ */ (0,
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref: hoverRef, className: "dsh-st-n-hover", style: hoverStyle, onMouseEnter: showHover, onMouseLeave: hideHover, children: [
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-n-hover-title", children: (hoverTitle ?? title).trim() || title }),
|
|
2891
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-n-hover-time", children: relativeTime(updatedAt, t) }),
|
|
2892
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-n-hover-state", children: [
|
|
2893
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: running ? "dsh-st-n-hover-dot is-run" : "dsh-st-n-hover-dot" }),
|
|
2812
2894
|
running ? t("session.runningStatus") : t("session.idle")
|
|
2813
2895
|
] })
|
|
2814
2896
|
] }),
|
|
@@ -2818,11 +2900,11 @@ function NativeSessionRow(props) {
|
|
|
2818
2900
|
}
|
|
2819
2901
|
|
|
2820
2902
|
// src/client/ScheduleRail.tsx
|
|
2821
|
-
var
|
|
2822
|
-
var
|
|
2903
|
+
var import_react7 = require("react");
|
|
2904
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2823
2905
|
var EMPTY_EXTRA_TABS = [];
|
|
2824
2906
|
var noopSubscribe = (_listener) => () => void 0;
|
|
2825
|
-
var OfficialTreeGuard = class extends
|
|
2907
|
+
var OfficialTreeGuard = class extends import_react7.Component {
|
|
2826
2908
|
state = { failed: false };
|
|
2827
2909
|
static getDerivedStateFromError() {
|
|
2828
2910
|
return { failed: true };
|
|
@@ -2839,38 +2921,38 @@ function ScheduleRail({
|
|
|
2839
2921
|
runtime,
|
|
2840
2922
|
openSession
|
|
2841
2923
|
}) {
|
|
2842
|
-
const state = (0,
|
|
2843
|
-
const [folded, setFolded] = (0,
|
|
2844
|
-
const groups = (0,
|
|
2924
|
+
const state = (0, import_react7.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
2925
|
+
const [folded, setFolded] = (0, import_react7.useState)({});
|
|
2926
|
+
const groups = (0, import_react7.useMemo)(() => {
|
|
2845
2927
|
const snapshot = state.snapshot;
|
|
2846
2928
|
if (snapshot === void 0) return [];
|
|
2847
2929
|
return groupScheduledSessions(snapshot.automations, snapshot.runs);
|
|
2848
2930
|
}, [state.snapshot]);
|
|
2849
|
-
return /* @__PURE__ */ (0,
|
|
2850
|
-
state.phase === "loading" && groups.length === 0 && /* @__PURE__ */ (0,
|
|
2851
|
-
groups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0,
|
|
2852
|
-
groups.map((group) => /* @__PURE__ */ (0,
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
2931
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-rail", children: [
|
|
2932
|
+
state.phase === "loading" && groups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-rail-empty", children: t("loading") }),
|
|
2933
|
+
groups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.empty") }),
|
|
2934
|
+
groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
2935
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2854
2936
|
"button",
|
|
2855
2937
|
{
|
|
2856
2938
|
type: "button",
|
|
2857
2939
|
className: "dsh-st-rail-head",
|
|
2858
2940
|
onClick: () => setFolded((current) => ({ ...current, [group.id]: !current[group.id] })),
|
|
2859
2941
|
children: [
|
|
2860
|
-
/* @__PURE__ */ (0,
|
|
2861
|
-
/* @__PURE__ */ (0,
|
|
2942
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dsh-st-rail-folder", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ClockIcon, { width: 16, height: 16 }) }),
|
|
2943
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dsh-st-rail-title", children: group.name })
|
|
2862
2944
|
]
|
|
2863
2945
|
}
|
|
2864
2946
|
),
|
|
2865
|
-
folded[group.id] !== true && group.sessions.map((session) => /* @__PURE__ */ (0,
|
|
2947
|
+
folded[group.id] !== true && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2866
2948
|
"button",
|
|
2867
2949
|
{
|
|
2868
2950
|
type: "button",
|
|
2869
2951
|
className: "dsh-st-rail-session",
|
|
2870
2952
|
onClick: () => openSession?.(session.id),
|
|
2871
2953
|
children: [
|
|
2872
|
-
/* @__PURE__ */ (0,
|
|
2873
|
-
session.running && /* @__PURE__ */ (0,
|
|
2954
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: session.label }),
|
|
2955
|
+
session.running && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RunningStateDot, {})
|
|
2874
2956
|
]
|
|
2875
2957
|
},
|
|
2876
2958
|
session.id
|
|
@@ -2893,19 +2975,19 @@ function NativeScheduleShell({
|
|
|
2893
2975
|
wide
|
|
2894
2976
|
}) {
|
|
2895
2977
|
const Official = officialTree;
|
|
2896
|
-
const [tab, setTab] = (0,
|
|
2978
|
+
const [tab, setTab] = (0, import_react7.useState)(() => {
|
|
2897
2979
|
try {
|
|
2898
2980
|
return readNativeSidebarTab(window.localStorage.getItem(NATIVE_SIDEBAR_TAB_KEY));
|
|
2899
2981
|
} catch {
|
|
2900
2982
|
return "tasks";
|
|
2901
2983
|
}
|
|
2902
2984
|
});
|
|
2903
|
-
const extraTabs = (0,
|
|
2985
|
+
const extraTabs = (0, import_react7.useSyncExternalStore)(
|
|
2904
2986
|
tabRegistry?.subscribe ?? noopSubscribe,
|
|
2905
2987
|
() => tabRegistry?.getTabs() ?? EMPTY_EXTRA_TABS,
|
|
2906
2988
|
() => EMPTY_EXTRA_TABS
|
|
2907
2989
|
);
|
|
2908
|
-
const channelsReady = (0,
|
|
2990
|
+
const channelsReady = (0, import_react7.useSyncExternalStore)(
|
|
2909
2991
|
subscribeChannels ?? noopSubscribe,
|
|
2910
2992
|
() => {
|
|
2911
2993
|
try {
|
|
@@ -2917,25 +2999,25 @@ function NativeScheduleShell({
|
|
|
2917
2999
|
() => false
|
|
2918
3000
|
);
|
|
2919
3001
|
const currentId = useSessions?.((state) => state?.current ?? null);
|
|
2920
|
-
const automationState = (0,
|
|
2921
|
-
const scheduledIds = (0,
|
|
2922
|
-
const useFilteredSessions = (0,
|
|
3002
|
+
const automationState = (0, import_react7.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
3003
|
+
const scheduledIds = (0, import_react7.useMemo)(() => collectScheduledSessionIds(automationState.snapshot?.runs), [automationState.snapshot]);
|
|
3004
|
+
const useFilteredSessions = (0, import_react7.useCallback)((selector, eq) => {
|
|
2923
3005
|
if (useSessions === void 0) return selector({ ids: [], byId: {}, current: null });
|
|
2924
3006
|
return useSessions((state) => selector(filterTaskSessionState(state, scheduledIds)), eq);
|
|
2925
3007
|
}, [useSessions, scheduledIds]);
|
|
2926
|
-
const useFilteredWorkspaces = (0,
|
|
3008
|
+
const useFilteredWorkspaces = (0, import_react7.useCallback)((selector, eq) => {
|
|
2927
3009
|
if (useWorkspaces === void 0) return selector({ items: [], archivedSessionIds: [] });
|
|
2928
3010
|
return useWorkspaces((state) => selector(filterWorkspaceListState(state, scheduledIds)), eq);
|
|
2929
3011
|
}, [useWorkspaces, scheduledIds]);
|
|
2930
|
-
(0,
|
|
3012
|
+
(0, import_react7.useEffect)(() => {
|
|
2931
3013
|
try {
|
|
2932
3014
|
window.localStorage.setItem(NATIVE_SIDEBAR_TAB_KEY, tab);
|
|
2933
3015
|
} catch {
|
|
2934
3016
|
}
|
|
2935
3017
|
}, [tab]);
|
|
2936
|
-
const previousCurrentId = (0,
|
|
2937
|
-
const tabFollowReady = (0,
|
|
2938
|
-
(0,
|
|
3018
|
+
const previousCurrentId = (0, import_react7.useRef)(currentId);
|
|
3019
|
+
const tabFollowReady = (0, import_react7.useRef)(false);
|
|
3020
|
+
(0, import_react7.useEffect)(() => {
|
|
2939
3021
|
if (!tabFollowReady.current) {
|
|
2940
3022
|
tabFollowReady.current = true;
|
|
2941
3023
|
previousCurrentId.current = currentId;
|
|
@@ -2958,11 +3040,11 @@ function NativeScheduleShell({
|
|
|
2958
3040
|
};
|
|
2959
3041
|
const renderOfficial = (props) => {
|
|
2960
3042
|
if (Official === void 0) {
|
|
2961
|
-
return /* @__PURE__ */ (0,
|
|
3043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NativeTaskRail, { t, ...openSession === void 0 ? {} : { openSession }, ...useSessions === void 0 ? {} : { useSessions: useFilteredSessions }, ...useWorkspaces === void 0 ? {} : { useWorkspaces } });
|
|
2962
3044
|
}
|
|
2963
|
-
return /* @__PURE__ */ (0,
|
|
3045
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(OfficialTreeGuard, { fallback: (0, import_react7.createElement)(Official, rawOfficialProps), children: (0, import_react7.createElement)(Official, props) });
|
|
2964
3046
|
};
|
|
2965
|
-
if (wide === false) return /* @__PURE__ */ (0,
|
|
3047
|
+
if (wide === false) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: renderOfficial(filteredOfficialProps) });
|
|
2966
3048
|
const foreignTabs = extraTabs.filter((item) => item.id !== "schedule");
|
|
2967
3049
|
const visibleTab = resolveVisibleSidebarTab({
|
|
2968
3050
|
tab,
|
|
@@ -2970,15 +3052,15 @@ function NativeScheduleShell({
|
|
|
2970
3052
|
extraTabIds: ownedSidebarTabIds({ extraTabIds: foreignTabs.map((item) => item.id), channelsReady })
|
|
2971
3053
|
});
|
|
2972
3054
|
const hostedSchedule = extraTabs.find((item) => item.id === "schedule");
|
|
2973
|
-
const scheduleBody = hostedSchedule === void 0 ? /* @__PURE__ */ (0,
|
|
2974
|
-
return /* @__PURE__ */ (0,
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
2976
|
-
/* @__PURE__ */ (0,
|
|
2977
|
-
foreignTabs.map((item) => /* @__PURE__ */ (0,
|
|
2978
|
-
channelsReady && foreignTabs.every((item) => item.id !== "channels") && /* @__PURE__ */ (0,
|
|
2979
|
-
/* @__PURE__ */ (0,
|
|
3055
|
+
const scheduleBody = hostedSchedule === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NativeScheduleSessionList, { t, runtime, ...openSession === void 0 ? {} : { openSession }, ...useSessions === void 0 ? {} : { useSessions }, ...useWorkspaces === void 0 ? {} : { useWorkspaces } }) : hostedSchedule.render({ ...hostProps ?? {}, openSession, open: openSession, useSessions, wide: true });
|
|
3056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-shell-rail", children: [
|
|
3057
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-shell-tabs", role: "tablist", "aria-label": t("sidebar.tabs"), children: [
|
|
3058
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "tasks", className: visibleTab === "tasks" ? "is-on" : void 0, onClick: () => setTab("tasks"), children: t("sidebar.tasksTab") }),
|
|
3059
|
+
foreignTabs.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === item.id, className: visibleTab === item.id ? "is-on" : void 0, onClick: () => setTab(item.id), children: item.label }, item.id)),
|
|
3060
|
+
channelsReady && foreignTabs.every((item) => item.id !== "channels") && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "channels", className: visibleTab === "channels" ? "is-on" : void 0, onClick: () => setTab("channels"), children: t("sidebar.channelsTab") }),
|
|
3061
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "schedule", className: visibleTab === "schedule" ? "is-on" : void 0, onClick: () => setTab("schedule"), children: t("sidebar.tab") })
|
|
2980
3062
|
] }),
|
|
2981
|
-
visibleTab === "schedule" ? /* @__PURE__ */ (0,
|
|
3063
|
+
visibleTab === "schedule" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-shell-body", children: scheduleBody }) : foreignTabs.find((item) => item.id === visibleTab) !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-shell-body", children: foreignTabs.find((item) => item.id === visibleTab)?.render({ ...hostProps ?? {}, openSession, open: openSession, useSessions, wide: true }) }) : visibleTab === "channels" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-shell-body", children: renderSlot?.("sidebar.channels", { ...hostProps ?? {}, openSession, open: openSession, useSessions, wide: true, skin: "native" }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-official-tree", children: renderOfficial(filteredOfficialProps) })
|
|
2982
3064
|
] });
|
|
2983
3065
|
}
|
|
2984
3066
|
function NativeTaskRail({
|
|
@@ -2990,10 +3072,10 @@ function NativeTaskRail({
|
|
|
2990
3072
|
const snap = useSessions === void 0 ? { ids: [], byId: {}, current: null } : useSessions((state) => state ?? { ids: [], byId: {}, current: null });
|
|
2991
3073
|
const workspaces = useWorkspaces === void 0 ? void 0 : useWorkspaces((state) => state ?? { items: [], archivedSessionIds: [] });
|
|
2992
3074
|
const groups = groupNativeTaskSessions(snap, workspaces, t("sidebar.ungrouped"));
|
|
2993
|
-
if (groups.length === 0) return /* @__PURE__ */ (0,
|
|
2994
|
-
return /* @__PURE__ */ (0,
|
|
2995
|
-
/* @__PURE__ */ (0,
|
|
2996
|
-
group.sessions.map((item) => /* @__PURE__ */ (0,
|
|
3075
|
+
if (groups.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.tasksEmpty") });
|
|
3076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-rail", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
3077
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-rail-head is-static", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dsh-st-rail-title", children: group.label }) }),
|
|
3078
|
+
group.sessions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2997
3079
|
"button",
|
|
2998
3080
|
{
|
|
2999
3081
|
type: "button",
|
|
@@ -3001,7 +3083,7 @@ function NativeTaskRail({
|
|
|
3001
3083
|
onClick: () => {
|
|
3002
3084
|
if (item.id !== void 0) openSession?.(item.id);
|
|
3003
3085
|
},
|
|
3004
|
-
children: /* @__PURE__ */ (0,
|
|
3086
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: item.title || item.id })
|
|
3005
3087
|
},
|
|
3006
3088
|
item.id
|
|
3007
3089
|
))
|
|
@@ -3020,6 +3102,7 @@ var CSS_TEXT = `
|
|
|
3020
3102
|
.dsh-st-btn,.dsh-st-icon{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:inherit;font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}
|
|
3021
3103
|
.dsh-st-icon{width:32px;padding:0;flex:none}
|
|
3022
3104
|
.dsh-st-btn--primary{border-color:transparent;background:var(--dsw-alias-button-primary-fill,#fff);color:var(--dsw-alias-label-primary-foreground,#111)}
|
|
3105
|
+
.dsh-st-btn--danger{border-color:var(--dsw-alias-state-error-primary,#f85149);background:var(--dsw-alias-state-error-primary,#f85149);color:#fff}
|
|
3023
3106
|
.dsh-st-hint{margin:-6px 0 14px;padding:10px 12px;border-radius:12px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
3024
3107
|
.dsh-st-banner{display:flex;align-items:flex-start;gap:8px;margin-bottom:16px;padding:10px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}
|
|
3025
3108
|
.dsh-st-banner>span{display:inline-flex;align-items:flex-start;gap:8px}
|
|
@@ -3081,6 +3164,7 @@ var CSS_TEXT = `
|
|
|
3081
3164
|
.dsh-st-muted{color:var(--dsw-alias-label-secondary)}
|
|
3082
3165
|
.dsh-st-mask{position:fixed;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:24px;overflow:auto;background:rgba(0,0,0,.45)}.dsh-st-flyout-root{position:absolute;inset:0;z-index:1200;overflow:visible;pointer-events:none}.dsh-st-flyout-root .dsh-st-select-menu,.dsh-st-flyout-root .dsh-st-model-select-menu{pointer-events:auto}
|
|
3083
3166
|
.dsh-st-modal,.dsh-st-modal *{box-sizing:border-box}.dsh-st-modal{display:flex;flex-direction:column;width:min(760px,calc(100vw - 48px));max-width:100%;max-height:min(92vh,900px);overflow:hidden;padding:24px;border:1px solid var(--dsw-alias-border-l2);border-radius:20px;background:var(--dsw-alias-bg-base)}
|
|
3167
|
+
.dsh-st-confirm-modal,.dsh-st-confirm-modal *{box-sizing:border-box}.dsh-st-confirm-modal{width:min(420px,calc(100vw - 48px));padding:24px;border:1px solid var(--dsw-alias-border-l2);border-radius:18px;background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv3,0 12px 36px rgba(0,0,0,.36))}.dsh-st-confirm-modal h2{margin:0 0 10px;font-size:18px}.dsh-st-confirm-modal p{margin:0 0 8px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}.dsh-st-confirm-modal .dsh-st-confirm-target{color:var(--dsw-alias-label-primary);font-weight:600;overflow-wrap:anywhere}
|
|
3084
3168
|
.dsh-st-modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
|
|
3085
3169
|
.dsh-st-modal-head h2{margin:0 0 4px;font-size:20px}
|
|
3086
3170
|
.dsh-st-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px;min-width:0;max-width:100%;font-size:13px}.dsh-st-field:has(.dsh-st-prompt-card){flex:1;min-height:0;margin-bottom:10px}
|
|
@@ -3227,7 +3311,7 @@ function apply(ctx) {
|
|
|
3227
3311
|
label: () => t("tab"),
|
|
3228
3312
|
icon: "schedule"
|
|
3229
3313
|
}, function ScheduledTasksSettings(props) {
|
|
3230
|
-
return (0,
|
|
3314
|
+
return (0, import_react8.createElement)(AutomationView, { t, permissionT, modelT, runtime, ...props.close === void 0 ? {} : { closeSettings: props.close } });
|
|
3231
3315
|
}));
|
|
3232
3316
|
ctx.slots.inject("sidebar.schedule", () => ctx.slots.register({
|
|
3233
3317
|
name: "sidebar.schedule",
|
|
@@ -3236,7 +3320,7 @@ function apply(ctx) {
|
|
|
3236
3320
|
locale: NS,
|
|
3237
3321
|
label: () => t("sidebar.tab")
|
|
3238
3322
|
}, function AutomationScheduleRail(props) {
|
|
3239
|
-
return (0,
|
|
3323
|
+
return (0, import_react8.createElement)(ScheduleRail, {
|
|
3240
3324
|
t,
|
|
3241
3325
|
runtime,
|
|
3242
3326
|
openSession: createScheduledSessionOpener(ctx, runtime, props.openSession)
|
|
@@ -3282,7 +3366,7 @@ function apply(ctx) {
|
|
|
3282
3366
|
render: (props) => {
|
|
3283
3367
|
const hostOpen = typeof props.openSession === "function" ? props.openSession : typeof props.open === "function" ? props.open : openSession;
|
|
3284
3368
|
const opener = createScheduledSessionOpener(ctx, runtime, hostOpen);
|
|
3285
|
-
return (0,
|
|
3369
|
+
return (0, import_react8.createElement)(NativeScheduleSessionList, {
|
|
3286
3370
|
t,
|
|
3287
3371
|
runtime,
|
|
3288
3372
|
openSession: opener,
|
|
@@ -3323,7 +3407,7 @@ function apply(ctx) {
|
|
|
3323
3407
|
try {
|
|
3324
3408
|
let AutomationNativeWorkspaceShell2 = function(innerProps) {
|
|
3325
3409
|
const openSession = createScheduledSessionOpener(ctx, runtime, innerProps.openSession ?? innerProps.open);
|
|
3326
|
-
return (0,
|
|
3410
|
+
return (0, import_react8.createElement)(NativeScheduleShell, {
|
|
3327
3411
|
t,
|
|
3328
3412
|
runtime,
|
|
3329
3413
|
hostProps: innerProps,
|
|
@@ -3409,7 +3493,7 @@ function createScheduledSessionOpener(ctx, runtime, hostOpen) {
|
|
|
3409
3493
|
};
|
|
3410
3494
|
}
|
|
3411
3495
|
function PrefillBridge(props) {
|
|
3412
|
-
(0,
|
|
3496
|
+
(0, import_react8.useEffect)(() => {
|
|
3413
3497
|
const applyPrefill = (text) => {
|
|
3414
3498
|
if (text === null || text === "") return;
|
|
3415
3499
|
if (props.inputActions !== void 0) {
|