@michengai/dsh-automation 0.1.19 → 0.1.21
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 +18 -0
- package/CHANGELOG.zh-CN.md +18 -0
- package/lib/client.js +1063 -363
- package/lib/client.js.map +4 -4
- package/lib/types/client/ScheduleRail.d.ts +5 -13
- package/lib/types/client/contracts.d.ts +5 -2
- package/lib/types/client/dropdown-menu.d.ts +22 -0
- package/lib/types/client/helpers.d.ts +12 -0
- package/lib/types/client/locales.d.ts +15 -0
- package/lib/types/client/native-group-actions.d.ts +7 -0
- package/lib/types/client/native-session-list.d.ts +5 -3
- package/lib/types/client/schedule-overview.d.ts +19 -0
- package/lib/types/client/schedule-rail-model.d.ts +15 -0
- package/lib/types/client/settings-navigation.d.ts +10 -0
- package/lib/types/client/sort-menu.d.ts +14 -0
- package/lib/types/client/task-settings-request.d.ts +14 -0
- 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_react11 = require("react");
|
|
31
31
|
|
|
32
32
|
// src/client/AutomationView.tsx
|
|
33
|
-
var
|
|
33
|
+
var import_react6 = require("react");
|
|
34
34
|
|
|
35
35
|
// src/client/helpers.ts
|
|
36
36
|
var AutomationFormError = class extends Error {
|
|
@@ -227,6 +227,24 @@ function sortAutomations(items, key, direction) {
|
|
|
227
227
|
return left.id.localeCompare(right.id);
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
|
+
var SETTINGS_SORT_DEFAULT_KEY = "dsh-automation.sort-default.settings";
|
|
231
|
+
var OVERVIEW_SORT_DEFAULT_KEY = "dsh-automation.sort-default.overview";
|
|
232
|
+
function readSortDefault(storage, storageKey) {
|
|
233
|
+
if (storage === void 0) return void 0;
|
|
234
|
+
try {
|
|
235
|
+
const raw = storage.getItem(storageKey);
|
|
236
|
+
if (raw === null) return void 0;
|
|
237
|
+
const parsed = JSON.parse(raw);
|
|
238
|
+
if (parsed.key !== "created" && parsed.key !== "planned") return void 0;
|
|
239
|
+
if (parsed.direction !== "asc" && parsed.direction !== "desc") return void 0;
|
|
240
|
+
return { key: parsed.key, direction: parsed.direction };
|
|
241
|
+
} catch {
|
|
242
|
+
return void 0;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function writeSortDefault(storage, storageKey, key, direction) {
|
|
246
|
+
storage.setItem(storageKey, JSON.stringify({ key, direction }));
|
|
247
|
+
}
|
|
230
248
|
function groupHistory(runs, range, now, t) {
|
|
231
249
|
const buckets = /* @__PURE__ */ new Map();
|
|
232
250
|
for (const run of runs) {
|
|
@@ -322,6 +340,9 @@ function RefreshIcon(props) {
|
|
|
322
340
|
function PlayIcon(props) {
|
|
323
341
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 16 16", width: 16, height: 16, fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4.6 3.4 11.7 8l-7.1 4.6V3.4Z", fill: "currentColor", stroke: "currentColor", strokeWidth: "1.6", strokeLinejoin: "round" }) });
|
|
324
342
|
}
|
|
343
|
+
function PauseIcon(props) {
|
|
344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconFrame, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 7v10M15 7v10" }) });
|
|
345
|
+
}
|
|
325
346
|
function TrashIcon(props) {
|
|
326
347
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FillIcon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M14.478 4.841 14.214 10.115c-.104 2.072-.147 2.896-.827 3.846a3.53 3.53 0 0 1-1.044.993c-.519.333-1.101.478-1.784.546-.671.067-1.509.066-2.559.066s-1.887.001-2.558-.066c-.683-.068-1.266-.213-1.784-.546a3.53 3.53 0 0 1-1.044-.993c-.681-.95-.724-1.774-.828-3.846L1.522 4.841l1.368-.068.263 5.273c.109 2.176.171 2.556.573 3.117a2.16 2.16 0 0 0 .673.64c.263.169.603.277 1.179.334.587.059 1.345.06 2.422.06s1.834-.001 2.422-.06c.575-.057.916-.165 1.179-.335.262-.168.49-.386.672-.64.402-.56.464-.94.573-3.116l.263-5.273 1.369.068ZM5.43 6.228h1.37v5.163H5.43V6.228Zm3.77 0h1.37v5.163H9.2V6.228ZM8.536.434c.644 0 1.116-.007 1.56.137.14.045.276.101.406.168.416.212.745.552 1.2 1.007l.796.795h2.876v1.37H.626V2.541h2.876l.796-.795c.456-.455.784-.795 1.2-1.007.13-.067.266-.123.405-.168C6.348.427 6.82.434 7.464.434h1.072Zm-1.072 1.37c-.732 0-.948.008-1.138.07a2.2 2.2 0 0 0-.206.085c-.156.08-.296.204-.678.583h5.117c-.382-.379-.522-.503-.679-.583a2.2 2.2 0 0 0-.205-.085c-.191-.062-.406-.07-1.138-.07H7.464Z" }) });
|
|
327
348
|
}
|
|
@@ -331,6 +352,15 @@ function ShieldIcon(props) {
|
|
|
331
352
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m9.4 12 1.7 1.7 3.7-4" })
|
|
332
353
|
] });
|
|
333
354
|
}
|
|
355
|
+
function CalendarIcon(props) {
|
|
356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(IconFrame, { ...props, children: [
|
|
357
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "4", y: "5.5", width: "16", height: "14", rx: "2" }),
|
|
358
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 3.8v3.4M16 3.8v3.4M4 9.5h16" })
|
|
359
|
+
] });
|
|
360
|
+
}
|
|
361
|
+
function CheckIcon(props) {
|
|
362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconFrame, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m5.5 12.5 4 4 9-9" }) });
|
|
363
|
+
}
|
|
334
364
|
function MoreIcon(props) {
|
|
335
365
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(IconFrame, { ...props, children: [
|
|
336
366
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6", cy: "12", r: "1.2", fill: "currentColor" }),
|
|
@@ -1167,6 +1197,131 @@ function DeleteConfirmation({
|
|
|
1167
1197
|
) });
|
|
1168
1198
|
}
|
|
1169
1199
|
|
|
1200
|
+
// src/client/dropdown-menu.tsx
|
|
1201
|
+
var import_react4 = require("react");
|
|
1202
|
+
var import_react_dom2 = require("react-dom");
|
|
1203
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1204
|
+
function DropdownMenu({
|
|
1205
|
+
ariaLabel,
|
|
1206
|
+
className,
|
|
1207
|
+
buttonClassName,
|
|
1208
|
+
menuClassName,
|
|
1209
|
+
options,
|
|
1210
|
+
trigger
|
|
1211
|
+
}) {
|
|
1212
|
+
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1213
|
+
const root = (0, import_react4.useRef)(null);
|
|
1214
|
+
const menuRef = (0, import_react4.useRef)(null);
|
|
1215
|
+
const [menuStyle, setMenuStyle] = (0, import_react4.useState)({});
|
|
1216
|
+
const selectedLabel = options.find((option) => option.selected)?.label ?? options[0]?.label ?? ariaLabel;
|
|
1217
|
+
(0, import_react4.useEffect)(() => {
|
|
1218
|
+
if (!open) return;
|
|
1219
|
+
const close = (event) => {
|
|
1220
|
+
if (root.current !== null && root.current.contains(event.target)) return;
|
|
1221
|
+
if (menuRef.current?.contains(event.target) === true) return;
|
|
1222
|
+
setOpen(false);
|
|
1223
|
+
};
|
|
1224
|
+
const closeOnEscape = (event) => {
|
|
1225
|
+
if (event.key === "Escape") setOpen(false);
|
|
1226
|
+
};
|
|
1227
|
+
document.addEventListener("mousedown", close);
|
|
1228
|
+
document.addEventListener("keydown", closeOnEscape);
|
|
1229
|
+
return () => {
|
|
1230
|
+
document.removeEventListener("mousedown", close);
|
|
1231
|
+
document.removeEventListener("keydown", closeOnEscape);
|
|
1232
|
+
};
|
|
1233
|
+
}, [open]);
|
|
1234
|
+
(0, import_react4.useLayoutEffect)(() => {
|
|
1235
|
+
if (!open) return;
|
|
1236
|
+
const update = () => {
|
|
1237
|
+
const button = root.current?.querySelector(".dsh-st-dropdown-btn");
|
|
1238
|
+
const rect = button?.getBoundingClientRect();
|
|
1239
|
+
if (rect === void 0) return;
|
|
1240
|
+
const height = menuRef.current?.offsetHeight ?? 220;
|
|
1241
|
+
const margin = 8;
|
|
1242
|
+
let top = rect.bottom + 6;
|
|
1243
|
+
if (top + height > window.innerHeight - margin) top = Math.max(margin, rect.top - height - 6);
|
|
1244
|
+
const right = Math.max(margin, window.innerWidth - rect.right);
|
|
1245
|
+
setMenuStyle((current) => current.top === top && current.right === right ? current : { position: "fixed", top, right });
|
|
1246
|
+
};
|
|
1247
|
+
const onScroll = (event) => {
|
|
1248
|
+
if (event.target instanceof Node && menuRef.current?.contains(event.target)) return;
|
|
1249
|
+
update();
|
|
1250
|
+
};
|
|
1251
|
+
update();
|
|
1252
|
+
window.addEventListener("resize", update);
|
|
1253
|
+
document.addEventListener("scroll", onScroll, true);
|
|
1254
|
+
return () => {
|
|
1255
|
+
window.removeEventListener("resize", update);
|
|
1256
|
+
document.removeEventListener("scroll", onScroll, true);
|
|
1257
|
+
};
|
|
1258
|
+
}, [open, selectedLabel]);
|
|
1259
|
+
const menu = open && typeof document !== "undefined" ? (0, import_react_dom2.createPortal)(
|
|
1260
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: menuRef, className: `dsh-st-dropdown-menu is-float${menuClassName === void 0 ? "" : ` ${menuClassName}`}`, style: menuStyle, children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1261
|
+
DropdownRow,
|
|
1262
|
+
{
|
|
1263
|
+
label: option.label,
|
|
1264
|
+
selected: option.selected,
|
|
1265
|
+
trailing: option.trailing,
|
|
1266
|
+
onSelect: () => {
|
|
1267
|
+
if (option.keepOpen !== true) setOpen(false);
|
|
1268
|
+
option.onSelect();
|
|
1269
|
+
}
|
|
1270
|
+
},
|
|
1271
|
+
option.key
|
|
1272
|
+
)) }),
|
|
1273
|
+
document.body
|
|
1274
|
+
) : null;
|
|
1275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `dsh-st-dropdown${className === void 0 ? "" : ` ${className}`}`, ref: root, children: [
|
|
1276
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: `dsh-st-dropdown-btn${buttonClassName === void 0 ? "" : ` ${buttonClassName}`}${open ? " is-open" : ""}`, "aria-label": ariaLabel, "aria-expanded": open, onClick: () => setOpen((value) => !value), children: trigger ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1277
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-dropdown-label", children: selectedLabel }),
|
|
1278
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronIcon, { width: 10, height: 10, className: "dsh-st-dropdown-chevron" })
|
|
1279
|
+
] }) }),
|
|
1280
|
+
menu
|
|
1281
|
+
] });
|
|
1282
|
+
}
|
|
1283
|
+
function DropdownRow({
|
|
1284
|
+
label,
|
|
1285
|
+
selected,
|
|
1286
|
+
trailing,
|
|
1287
|
+
onSelect
|
|
1288
|
+
}) {
|
|
1289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1290
|
+
"div",
|
|
1291
|
+
{
|
|
1292
|
+
className: `dsh-st-dropdown-row${selected ? " is-selected" : ""}${trailing === void 0 ? "" : " has-trailing"}`,
|
|
1293
|
+
role: "menuitemradio",
|
|
1294
|
+
"aria-checked": selected,
|
|
1295
|
+
tabIndex: 0,
|
|
1296
|
+
onClick: onSelect,
|
|
1297
|
+
onKeyDown: (event) => {
|
|
1298
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1299
|
+
event.preventDefault();
|
|
1300
|
+
onSelect();
|
|
1301
|
+
}
|
|
1302
|
+
},
|
|
1303
|
+
children: [
|
|
1304
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-dropdown-label-cell", children: label }),
|
|
1305
|
+
trailing !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1306
|
+
"button",
|
|
1307
|
+
{
|
|
1308
|
+
type: "button",
|
|
1309
|
+
className: `dsh-st-dropdown-default${trailing.active ? " is-on" : ""}`,
|
|
1310
|
+
disabled: trailing.active,
|
|
1311
|
+
onClick: (event) => {
|
|
1312
|
+
event.stopPropagation();
|
|
1313
|
+
trailing.onSelect();
|
|
1314
|
+
},
|
|
1315
|
+
children: trailing.label
|
|
1316
|
+
}
|
|
1317
|
+
),
|
|
1318
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-dropdown-spacer" }),
|
|
1319
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-dropdown-check", children: selected ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CheckOutlineIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-sort-tick" }) })
|
|
1320
|
+
]
|
|
1321
|
+
}
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1170
1325
|
// src/client/prefill.ts
|
|
1171
1326
|
var pending = null;
|
|
1172
1327
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -1349,29 +1504,139 @@ function createAutomationRuntime(rpc) {
|
|
|
1349
1504
|
};
|
|
1350
1505
|
}
|
|
1351
1506
|
|
|
1507
|
+
// src/client/sort-menu.tsx
|
|
1508
|
+
var import_react5 = require("react");
|
|
1509
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1510
|
+
var SORT_OPTIONS = [
|
|
1511
|
+
["created", "desc"],
|
|
1512
|
+
["created", "asc"],
|
|
1513
|
+
["planned", "asc"],
|
|
1514
|
+
["planned", "desc"]
|
|
1515
|
+
];
|
|
1516
|
+
function SortMenu({
|
|
1517
|
+
t,
|
|
1518
|
+
storage,
|
|
1519
|
+
storageKey,
|
|
1520
|
+
sortKey,
|
|
1521
|
+
sortDirection,
|
|
1522
|
+
onSelect,
|
|
1523
|
+
compact = false,
|
|
1524
|
+
iconOnly = false,
|
|
1525
|
+
className
|
|
1526
|
+
}) {
|
|
1527
|
+
const [saved, setSaved] = (0, import_react5.useState)(() => readSortDefault(storage, storageKey));
|
|
1528
|
+
const options = SORT_OPTIONS.map(([key, direction]) => {
|
|
1529
|
+
const selected = sortKey === key && sortDirection === direction;
|
|
1530
|
+
const isDefault = saved?.key === key && saved.direction === direction;
|
|
1531
|
+
return {
|
|
1532
|
+
key: `${key}-${direction}`,
|
|
1533
|
+
label: t(key === "planned" ? `sort.planned.${direction}` : `sort.created.${direction}`),
|
|
1534
|
+
selected,
|
|
1535
|
+
keepOpen: true,
|
|
1536
|
+
onSelect: () => onSelect(key, direction),
|
|
1537
|
+
...selected && storage !== void 0 ? {
|
|
1538
|
+
trailing: {
|
|
1539
|
+
label: t("sort.default.saved"),
|
|
1540
|
+
active: isDefault,
|
|
1541
|
+
onSelect: () => {
|
|
1542
|
+
writeSortDefault(storage, storageKey, key, direction);
|
|
1543
|
+
setSaved({ key, direction });
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
} : {}
|
|
1547
|
+
};
|
|
1548
|
+
});
|
|
1549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1550
|
+
DropdownMenu,
|
|
1551
|
+
{
|
|
1552
|
+
ariaLabel: t("sort.by"),
|
|
1553
|
+
...compact || className !== void 0 ? { className: [compact ? "dsh-st-dropdown-compact" : "", className ?? ""].filter(Boolean).join(" ") } : {},
|
|
1554
|
+
...iconOnly ? { buttonClassName: "dsh-st-n-head-btn", trigger: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SlidersIcon, { width: 16, height: 16 }) } : {},
|
|
1555
|
+
menuClassName: compact ? "dsh-st-dropdown-sort dsh-st-dropdown-compact" : "dsh-st-dropdown-sort",
|
|
1556
|
+
options
|
|
1557
|
+
}
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
// src/client/task-settings-request.ts
|
|
1562
|
+
var AUTOMATION_TASK_SETTINGS_EVENT = "dsh-automation:open-task-settings";
|
|
1563
|
+
var AUTOMATION_TASK_SETTINGS_STORAGE_KEY = "dsh-automation:pending-task-settings";
|
|
1564
|
+
function parseAutomationTaskSettingsRequest(value) {
|
|
1565
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
1566
|
+
const record = value;
|
|
1567
|
+
if (typeof record.name !== "string" || record.name.trim() === "" || !Array.isArray(record.sessionIds) || record.sessionIds.some((id) => typeof id !== "string")) return void 0;
|
|
1568
|
+
if (record.automationId !== void 0 && (typeof record.automationId !== "string" || record.automationId.trim() === "")) return void 0;
|
|
1569
|
+
return {
|
|
1570
|
+
...typeof record.automationId === "string" ? { automationId: record.automationId } : {},
|
|
1571
|
+
name: record.name,
|
|
1572
|
+
sessionIds: [...record.sessionIds]
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
function writeAutomationTaskSettingsRequest(storage, request) {
|
|
1576
|
+
try {
|
|
1577
|
+
storage?.setItem(AUTOMATION_TASK_SETTINGS_STORAGE_KEY, JSON.stringify(request));
|
|
1578
|
+
} catch {
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
function requestAutomationTaskSettings(request) {
|
|
1582
|
+
if (typeof window === "undefined") return;
|
|
1583
|
+
writeAutomationTaskSettingsRequest(window.sessionStorage, request);
|
|
1584
|
+
window.dispatchEvent(new CustomEvent(AUTOMATION_TASK_SETTINGS_EVENT, { detail: request }));
|
|
1585
|
+
}
|
|
1586
|
+
function readAutomationTaskSettingsRequest(storage) {
|
|
1587
|
+
if (storage === void 0) return void 0;
|
|
1588
|
+
try {
|
|
1589
|
+
const raw = storage.getItem(AUTOMATION_TASK_SETTINGS_STORAGE_KEY);
|
|
1590
|
+
return raw === null ? void 0 : parseAutomationTaskSettingsRequest(JSON.parse(raw));
|
|
1591
|
+
} catch {
|
|
1592
|
+
return void 0;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
function clearAutomationTaskSettingsRequest(storage) {
|
|
1596
|
+
try {
|
|
1597
|
+
storage?.removeItem(AUTOMATION_TASK_SETTINGS_STORAGE_KEY);
|
|
1598
|
+
} catch {
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
function resolveAutomationTaskSettings(request, automations, runs) {
|
|
1602
|
+
if (request.automationId !== void 0) {
|
|
1603
|
+
const exact = automations.find((item) => item.id === request.automationId);
|
|
1604
|
+
if (exact !== void 0) return exact;
|
|
1605
|
+
}
|
|
1606
|
+
const sessionIds = new Set(request.sessionIds);
|
|
1607
|
+
const automationId = runs.find((run) => run.sessionId !== void 0 && sessionIds.has(run.sessionId))?.automationId;
|
|
1608
|
+
const mapped = automations.find((item) => item.id === automationId);
|
|
1609
|
+
if (mapped !== void 0) return mapped;
|
|
1610
|
+
const named = automations.filter((item) => item.name === request.name);
|
|
1611
|
+
return named.length === 1 ? named[0] : void 0;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1352
1614
|
// src/client/AutomationView.tsx
|
|
1353
|
-
var
|
|
1615
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1616
|
+
var SORT_STORAGE = typeof window === "undefined" ? void 0 : window.localStorage;
|
|
1617
|
+
var TASK_SETTINGS_STORAGE = typeof window === "undefined" ? void 0 : window.sessionStorage;
|
|
1354
1618
|
var EXAMPLES = [
|
|
1355
1619
|
{ name: "\u6BCF\u65E5\u56DE\u5F52\u68C0\u67E5", scheduleKind: "daily", time: "09:00", weekdays: [1, 2, 3, 4, 5] },
|
|
1356
1620
|
{ name: "\u6BCF\u5468\u4F9D\u8D56\u5DE1\u68C0", scheduleKind: "weekly", time: "10:00", weekdays: [1] },
|
|
1357
1621
|
{ name: "\u5DE5\u4F5C\u65E5\u65E9\u62A5", scheduleKind: "weekly", time: "08:00", weekdays: [1, 2, 3, 4, 5] }
|
|
1358
1622
|
];
|
|
1359
1623
|
function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
1360
|
-
const state = (0,
|
|
1361
|
-
const [tab, setTab] = (0,
|
|
1362
|
-
const [query, setQuery] = (0,
|
|
1363
|
-
const [creating, setCreating] = (0,
|
|
1364
|
-
const [editingId, setEditingId] = (0,
|
|
1365
|
-
const [deleteTarget, setDeleteTarget] = (0,
|
|
1366
|
-
const [draft, setDraft] = (0,
|
|
1367
|
-
const [busy, setBusy] = (0,
|
|
1368
|
-
const [error, setError] = (0,
|
|
1369
|
-
const [historyRange, setHistoryRange] = (0,
|
|
1370
|
-
const [historyTask, setHistoryTask] = (0,
|
|
1371
|
-
const [historyStatus, setHistoryStatus] = (0,
|
|
1372
|
-
const [sortKey, setSortKey] = (0,
|
|
1373
|
-
const [sortDirection, setSortDirection] = (0,
|
|
1374
|
-
const
|
|
1624
|
+
const state = (0, import_react6.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
1625
|
+
const [tab, setTab] = (0, import_react6.useState)("mine");
|
|
1626
|
+
const [query, setQuery] = (0, import_react6.useState)("");
|
|
1627
|
+
const [creating, setCreating] = (0, import_react6.useState)(false);
|
|
1628
|
+
const [editingId, setEditingId] = (0, import_react6.useState)();
|
|
1629
|
+
const [deleteTarget, setDeleteTarget] = (0, import_react6.useState)();
|
|
1630
|
+
const [draft, setDraft] = (0, import_react6.useState)();
|
|
1631
|
+
const [busy, setBusy] = (0, import_react6.useState)(false);
|
|
1632
|
+
const [error, setError] = (0, import_react6.useState)();
|
|
1633
|
+
const [historyRange, setHistoryRange] = (0, import_react6.useState)("day");
|
|
1634
|
+
const [historyTask, setHistoryTask] = (0, import_react6.useState)("all");
|
|
1635
|
+
const [historyStatus, setHistoryStatus] = (0, import_react6.useState)("all");
|
|
1636
|
+
const [sortKey, setSortKey] = (0, import_react6.useState)(() => readSortDefault(SORT_STORAGE, SETTINGS_SORT_DEFAULT_KEY)?.key ?? "created");
|
|
1637
|
+
const [sortDirection, setSortDirection] = (0, import_react6.useState)(() => readSortDefault(SORT_STORAGE, SETTINGS_SORT_DEFAULT_KEY)?.direction ?? "desc");
|
|
1638
|
+
const [taskSettingsRequest, setTaskSettingsRequest] = (0, import_react6.useState)(() => readAutomationTaskSettingsRequest(TASK_SETTINGS_STORAGE));
|
|
1639
|
+
const now = (0, import_react6.useMemo)(() => new Date(state.snapshot?.serverNow ?? Date.now()), [state.snapshot?.serverNow, state.refreshedAt]);
|
|
1375
1640
|
const snapshot = state.snapshot;
|
|
1376
1641
|
const workspaces = snapshot?.workspaces ?? [];
|
|
1377
1642
|
const models = snapshot?.models ?? [];
|
|
@@ -1415,37 +1680,61 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1415
1680
|
setDraft(formFromAutomation(item, workspaces, snapshot?.defaultModel ?? null, snapshot?.defaultPermission ?? item.permission));
|
|
1416
1681
|
setCreating(true);
|
|
1417
1682
|
};
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1683
|
+
(0, import_react6.useEffect)(() => {
|
|
1684
|
+
if (typeof window === "undefined") return;
|
|
1685
|
+
const onTaskSettings = (event) => {
|
|
1686
|
+
const request = parseAutomationTaskSettingsRequest(event.detail);
|
|
1687
|
+
if (request !== void 0) setTaskSettingsRequest(request);
|
|
1688
|
+
};
|
|
1689
|
+
window.addEventListener(AUTOMATION_TASK_SETTINGS_EVENT, onTaskSettings);
|
|
1690
|
+
return () => {
|
|
1691
|
+
window.removeEventListener(AUTOMATION_TASK_SETTINGS_EVENT, onTaskSettings);
|
|
1692
|
+
};
|
|
1693
|
+
}, []);
|
|
1694
|
+
(0, import_react6.useEffect)(() => {
|
|
1695
|
+
if (taskSettingsRequest === void 0 || snapshot === void 0) return;
|
|
1696
|
+
const item = resolveAutomationTaskSettings(taskSettingsRequest, snapshot.automations, snapshot.runs);
|
|
1697
|
+
clearAutomationTaskSettingsRequest(TASK_SETTINGS_STORAGE);
|
|
1698
|
+
setTaskSettingsRequest(void 0);
|
|
1699
|
+
setTab("mine");
|
|
1700
|
+
setQuery("");
|
|
1701
|
+
if (item === void 0) {
|
|
1702
|
+
setError(t("error.taskMissing"));
|
|
1703
|
+
return;
|
|
1704
|
+
}
|
|
1705
|
+
openEdit(item);
|
|
1706
|
+
}, [snapshot, taskSettingsRequest, t]);
|
|
1707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-shell", children: [
|
|
1708
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: "dsh-st-top", children: [
|
|
1709
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-heading", children: [
|
|
1710
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { children: t("tab") }),
|
|
1711
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: t("header.lead") })
|
|
1423
1712
|
] }),
|
|
1424
|
-
/* @__PURE__ */ (0,
|
|
1425
|
-
/* @__PURE__ */ (0,
|
|
1426
|
-
/* @__PURE__ */ (0,
|
|
1713
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-toolbar", children: [
|
|
1714
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { className: "dsh-st-search", value: query, placeholder: t("search.placeholder"), onChange: (event) => setQuery(event.target.value) }),
|
|
1715
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "dsh-st-btn", onClick: () => {
|
|
1427
1716
|
setChatPrefill(t("chat.prompt"));
|
|
1428
1717
|
closeSettings?.();
|
|
1429
1718
|
}, children: [
|
|
1430
|
-
/* @__PURE__ */ (0,
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChatIcon, {}),
|
|
1431
1720
|
t("action.chatCreate")
|
|
1432
1721
|
] }),
|
|
1433
|
-
/* @__PURE__ */ (0,
|
|
1434
|
-
/* @__PURE__ */ (0,
|
|
1722
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--primary", disabled: defaultPermission === "" || permissions.length === 0, onClick: () => openCreate(), children: [
|
|
1723
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlusIcon, {}),
|
|
1435
1724
|
t("action.create")
|
|
1436
1725
|
] }),
|
|
1437
|
-
/* @__PURE__ */ (0,
|
|
1726
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-icon", onClick: () => {
|
|
1438
1727
|
void runtime.refresh();
|
|
1439
|
-
}, "aria-label": t("section.refresh"), children: /* @__PURE__ */ (0,
|
|
1728
|
+
}, "aria-label": t("section.refresh"), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshIcon, {}) })
|
|
1440
1729
|
] })
|
|
1441
1730
|
] }),
|
|
1442
|
-
/* @__PURE__ */ (0,
|
|
1443
|
-
/* @__PURE__ */ (0,
|
|
1731
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-banner", role: "note", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
1732
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InfoIcon, {}),
|
|
1444
1733
|
t("banner.wake")
|
|
1445
1734
|
] }) }),
|
|
1446
|
-
/* @__PURE__ */ (0,
|
|
1447
|
-
/* @__PURE__ */ (0,
|
|
1448
|
-
/* @__PURE__ */ (0,
|
|
1735
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "dsh-st-examples", children: [
|
|
1736
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-examples-head", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { children: t("examples.title") }) }),
|
|
1737
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-example-row", children: EXAMPLES.map((example, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1449
1738
|
"button",
|
|
1450
1739
|
{
|
|
1451
1740
|
type: "button",
|
|
@@ -1459,10 +1748,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1459
1748
|
weekdays: example.weekdays
|
|
1460
1749
|
}),
|
|
1461
1750
|
children: [
|
|
1462
|
-
/* @__PURE__ */ (0,
|
|
1463
|
-
/* @__PURE__ */ (0,
|
|
1464
|
-
/* @__PURE__ */ (0,
|
|
1465
|
-
/* @__PURE__ */ (0,
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: t(`examples.${index + 1}.title`) }),
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: t(`examples.${index + 1}.body`) }),
|
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-st-chip", children: [
|
|
1754
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ClockIcon, {}),
|
|
1466
1755
|
t(`examples.${index + 1}.chip`)
|
|
1467
1756
|
] })
|
|
1468
1757
|
]
|
|
@@ -1470,22 +1759,24 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1470
1759
|
example.name
|
|
1471
1760
|
)) })
|
|
1472
1761
|
] }),
|
|
1473
|
-
error !== void 0 && /* @__PURE__ */ (0,
|
|
1474
|
-
(state.phase === "idle" || state.phase === "loading" && snapshot === void 0) && /* @__PURE__ */ (0,
|
|
1475
|
-
state.phase === "error" && snapshot === void 0 && /* @__PURE__ */ (0,
|
|
1476
|
-
/* @__PURE__ */ (0,
|
|
1477
|
-
/* @__PURE__ */ (0,
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1762
|
+
error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "dsh-st-error", children: error }),
|
|
1763
|
+
(state.phase === "idle" || state.phase === "loading" && snapshot === void 0) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "dsh-st-muted", children: t("loading") }),
|
|
1764
|
+
state.phase === "error" && snapshot === void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-empty", children: [
|
|
1765
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: t("error.title") }),
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: state.error }),
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--primary", onClick: () => {
|
|
1479
1768
|
void runtime.refresh();
|
|
1480
1769
|
}, children: t("error.retry") })
|
|
1481
1770
|
] }),
|
|
1482
|
-
/* @__PURE__ */ (0,
|
|
1483
|
-
/* @__PURE__ */ (0,
|
|
1484
|
-
/* @__PURE__ */ (0,
|
|
1485
|
-
tab === "mine" && /* @__PURE__ */ (0,
|
|
1771
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-tabs", children: [
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: tab === "mine" ? "is-on" : "", onClick: () => setTab("mine"), children: t("tabs.mine") }),
|
|
1773
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: tab === "runs" ? "is-on" : "", onClick: () => setTab("runs"), children: t("tabs.runs") }),
|
|
1774
|
+
tab === "mine" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-sort-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1486
1775
|
SortMenu,
|
|
1487
1776
|
{
|
|
1488
1777
|
t,
|
|
1778
|
+
...SORT_STORAGE === void 0 ? {} : { storage: SORT_STORAGE },
|
|
1779
|
+
storageKey: SETTINGS_SORT_DEFAULT_KEY,
|
|
1489
1780
|
sortKey,
|
|
1490
1781
|
sortDirection,
|
|
1491
1782
|
onSelect: (key, direction) => {
|
|
@@ -1493,10 +1784,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1493
1784
|
setSortDirection(direction);
|
|
1494
1785
|
}
|
|
1495
1786
|
}
|
|
1496
|
-
),
|
|
1497
|
-
tab === "runs" && /* @__PURE__ */ (0,
|
|
1498
|
-
["day", "week", "month"].map((range) => /* @__PURE__ */ (0,
|
|
1499
|
-
/* @__PURE__ */ (0,
|
|
1787
|
+
) }),
|
|
1788
|
+
tab === "runs" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-filters", children: [
|
|
1789
|
+
["day", "week", "month"].map((range) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: historyRange === range ? "is-on" : "", onClick: () => setHistoryRange(range), children: t(`history.range.${range}`) }, range)),
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1500
1791
|
DropdownMenu,
|
|
1501
1792
|
{
|
|
1502
1793
|
ariaLabel: t("history.allTasks"),
|
|
@@ -1511,7 +1802,7 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1511
1802
|
]
|
|
1512
1803
|
}
|
|
1513
1804
|
),
|
|
1514
|
-
/* @__PURE__ */ (0,
|
|
1805
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1515
1806
|
DropdownMenu,
|
|
1516
1807
|
{
|
|
1517
1808
|
ariaLabel: t("history.allStatus"),
|
|
@@ -1528,10 +1819,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1528
1819
|
)
|
|
1529
1820
|
] })
|
|
1530
1821
|
] }),
|
|
1531
|
-
tab === "mine" && (automations.length === 0 ? /* @__PURE__ */ (0,
|
|
1532
|
-
/* @__PURE__ */ (0,
|
|
1533
|
-
/* @__PURE__ */ (0,
|
|
1534
|
-
] }) : /* @__PURE__ */ (0,
|
|
1822
|
+
tab === "mine" && (automations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-empty", children: [
|
|
1823
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: t("empty.title") }),
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: t("empty.body") })
|
|
1825
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-grid", children: automations.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1535
1826
|
TaskCard,
|
|
1536
1827
|
{
|
|
1537
1828
|
item,
|
|
@@ -1549,11 +1840,11 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1549
1840
|
},
|
|
1550
1841
|
item.id
|
|
1551
1842
|
)) })),
|
|
1552
|
-
tab === "runs" && (groups.length === 0 ? /* @__PURE__ */ (0,
|
|
1553
|
-
/* @__PURE__ */ (0,
|
|
1554
|
-
group.items.map((run) => /* @__PURE__ */ (0,
|
|
1843
|
+
tab === "runs" && (groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-empty", children: t("runs.empty") }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-timeline", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "dsh-st-group", children: [
|
|
1844
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: group.label }),
|
|
1845
|
+
group.items.map((run) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RunRow, { run, t }, run.id))
|
|
1555
1846
|
] }, group.key)) })),
|
|
1556
|
-
creating && /* @__PURE__ */ (0,
|
|
1847
|
+
creating && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1557
1848
|
CreateModal,
|
|
1558
1849
|
{
|
|
1559
1850
|
t,
|
|
@@ -1583,7 +1874,7 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1583
1874
|
},
|
|
1584
1875
|
editingId ?? "create"
|
|
1585
1876
|
),
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1587
1878
|
DeleteConfirmation,
|
|
1588
1879
|
{
|
|
1589
1880
|
target: deleteTarget,
|
|
@@ -1612,9 +1903,9 @@ function TaskCard({
|
|
|
1612
1903
|
onRun,
|
|
1613
1904
|
onDelete
|
|
1614
1905
|
}) {
|
|
1615
|
-
const [menu, setMenu] = (0,
|
|
1616
|
-
const root = (0,
|
|
1617
|
-
(0,
|
|
1906
|
+
const [menu, setMenu] = (0, import_react6.useState)(false);
|
|
1907
|
+
const root = (0, import_react6.useRef)(null);
|
|
1908
|
+
(0, import_react6.useEffect)(() => {
|
|
1618
1909
|
if (!menu) return;
|
|
1619
1910
|
const close = (event) => {
|
|
1620
1911
|
if (root.current !== null && !root.current.contains(event.target)) setMenu(false);
|
|
@@ -1624,131 +1915,59 @@ function TaskCard({
|
|
|
1624
1915
|
document.removeEventListener("mousedown", close);
|
|
1625
1916
|
};
|
|
1626
1917
|
}, [menu]);
|
|
1627
|
-
return /* @__PURE__ */ (0,
|
|
1628
|
-
/* @__PURE__ */ (0,
|
|
1629
|
-
/* @__PURE__ */ (0,
|
|
1918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("article", { className: "dsh-st-card", ref: root, onClick: onEdit, children: [
|
|
1919
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-card-head", children: [
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: `dsh-st-switch ${item.status === "active" ? "is-on" : ""}`, role: "switch", "aria-checked": item.status === "active", disabled: busy, onClick: (event) => {
|
|
1630
1921
|
event.stopPropagation();
|
|
1631
1922
|
onToggle();
|
|
1632
1923
|
} }),
|
|
1633
|
-
/* @__PURE__ */ (0,
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-more", onClick: (event) => {
|
|
1634
1925
|
event.stopPropagation();
|
|
1635
1926
|
setMenu((value) => !value);
|
|
1636
|
-
}, "aria-label": t("card.more"), children: /* @__PURE__ */ (0,
|
|
1637
|
-
menu && /* @__PURE__ */ (0,
|
|
1638
|
-
/* @__PURE__ */ (0,
|
|
1927
|
+
}, "aria-label": t("card.more"), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {}) }),
|
|
1928
|
+
menu && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-menu", onClick: (event) => event.stopPropagation(), children: [
|
|
1929
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", disabled: busy, onClick: () => {
|
|
1639
1930
|
setMenu(false);
|
|
1640
1931
|
onRun();
|
|
1641
1932
|
}, children: [
|
|
1642
|
-
/* @__PURE__ */ (0,
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlayIcon, { width: 16, height: 16 }),
|
|
1643
1934
|
t("menu.run")
|
|
1644
1935
|
] }),
|
|
1645
|
-
/* @__PURE__ */ (0,
|
|
1936
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", disabled: busy, onClick: () => {
|
|
1646
1937
|
setMenu(false);
|
|
1647
1938
|
onEdit();
|
|
1648
1939
|
}, children: [
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PencilIcon, { width: 16, height: 16 }),
|
|
1650
1941
|
t("menu.edit")
|
|
1651
1942
|
] }),
|
|
1652
|
-
/* @__PURE__ */ (0,
|
|
1943
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "is-danger", disabled: busy, onClick: () => {
|
|
1653
1944
|
setMenu(false);
|
|
1654
1945
|
onDelete();
|
|
1655
1946
|
}, children: [
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1947
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TrashIcon, { width: 16, height: 16 }),
|
|
1657
1948
|
t("menu.delete")
|
|
1658
1949
|
] })
|
|
1659
1950
|
] })
|
|
1660
1951
|
] }),
|
|
1661
|
-
/* @__PURE__ */ (0,
|
|
1662
|
-
/* @__PURE__ */ (0,
|
|
1663
|
-
/* @__PURE__ */ (0,
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
1952
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: item.name }),
|
|
1953
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: item.prompt }),
|
|
1954
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-card-foot", children: [
|
|
1955
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-st-chip", children: [
|
|
1956
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ClockIcon, {}),
|
|
1666
1957
|
formatSchedule(item.schedule, t)
|
|
1667
1958
|
] }),
|
|
1668
|
-
/* @__PURE__ */ (0,
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: item.nextRunAt === void 0 ? t("stats.noneScheduled") : t("history.nextApprox", { when: formatWithin(item.nextRunAt, now, t) }) })
|
|
1669
1960
|
] })
|
|
1670
1961
|
] });
|
|
1671
1962
|
}
|
|
1672
|
-
function SortMenu({
|
|
1673
|
-
t,
|
|
1674
|
-
sortKey,
|
|
1675
|
-
sortDirection,
|
|
1676
|
-
onSelect
|
|
1677
|
-
}) {
|
|
1678
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1679
|
-
DropdownMenu,
|
|
1680
|
-
{
|
|
1681
|
-
className: "dsh-st-sort",
|
|
1682
|
-
ariaLabel: t("sort.by"),
|
|
1683
|
-
options: [
|
|
1684
|
-
{ key: "created-desc", label: t("sort.created.desc"), selected: sortKey === "created" && sortDirection === "desc", onSelect: () => onSelect("created", "desc") },
|
|
1685
|
-
{ key: "created-asc", label: t("sort.created.asc"), selected: sortKey === "created" && sortDirection === "asc", onSelect: () => onSelect("created", "asc") },
|
|
1686
|
-
{ key: "planned-asc", label: t("sort.planned.asc"), selected: sortKey === "planned" && sortDirection === "asc", onSelect: () => onSelect("planned", "asc") },
|
|
1687
|
-
{ key: "planned-desc", label: t("sort.planned.desc"), selected: sortKey === "planned" && sortDirection === "desc", onSelect: () => onSelect("planned", "desc") }
|
|
1688
|
-
]
|
|
1689
|
-
}
|
|
1690
|
-
);
|
|
1691
|
-
}
|
|
1692
|
-
function DropdownMenu({
|
|
1693
|
-
ariaLabel,
|
|
1694
|
-
className,
|
|
1695
|
-
options
|
|
1696
|
-
}) {
|
|
1697
|
-
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1698
|
-
const root = (0, import_react4.useRef)(null);
|
|
1699
|
-
(0, import_react4.useEffect)(() => {
|
|
1700
|
-
if (!open) return;
|
|
1701
|
-
const close = (event) => {
|
|
1702
|
-
if (root.current !== null && !root.current.contains(event.target)) setOpen(false);
|
|
1703
|
-
};
|
|
1704
|
-
const closeOnEscape = (event) => {
|
|
1705
|
-
if (event.key === "Escape") setOpen(false);
|
|
1706
|
-
};
|
|
1707
|
-
document.addEventListener("mousedown", close);
|
|
1708
|
-
document.addEventListener("keydown", closeOnEscape);
|
|
1709
|
-
return () => {
|
|
1710
|
-
document.removeEventListener("mousedown", close);
|
|
1711
|
-
document.removeEventListener("keydown", closeOnEscape);
|
|
1712
|
-
};
|
|
1713
|
-
}, [open]);
|
|
1714
|
-
const selectedLabel = options.find((option) => option.selected)?.label ?? options[0]?.label ?? ariaLabel;
|
|
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" })
|
|
1719
|
-
] }),
|
|
1720
|
-
open && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-dropdown-menu", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1721
|
-
DropdownRow,
|
|
1722
|
-
{
|
|
1723
|
-
label: option.label,
|
|
1724
|
-
selected: option.selected,
|
|
1725
|
-
onSelect: () => {
|
|
1726
|
-
setOpen(false);
|
|
1727
|
-
option.onSelect();
|
|
1728
|
-
}
|
|
1729
|
-
},
|
|
1730
|
-
option.key
|
|
1731
|
-
)) })
|
|
1732
|
-
] });
|
|
1733
|
-
}
|
|
1734
|
-
function DropdownRow({
|
|
1735
|
-
label,
|
|
1736
|
-
selected,
|
|
1737
|
-
onSelect
|
|
1738
|
-
}) {
|
|
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" })
|
|
1742
|
-
] });
|
|
1743
|
-
}
|
|
1744
1963
|
function RunRow({ run, t }) {
|
|
1745
1964
|
const duration = formatDuration(run.startedAt, run.finishedAt);
|
|
1746
|
-
return /* @__PURE__ */ (0,
|
|
1747
|
-
/* @__PURE__ */ (0,
|
|
1748
|
-
/* @__PURE__ */ (0,
|
|
1749
|
-
/* @__PURE__ */ (0,
|
|
1750
|
-
duration !== void 0 && /* @__PURE__ */ (0,
|
|
1751
|
-
/* @__PURE__ */ (0,
|
|
1965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("article", { className: `dsh-st-run is-${run.status}`, children: [
|
|
1966
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: run.automationName }),
|
|
1967
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: clockTime(run.startedAt ?? run.scheduledFor) }),
|
|
1969
|
+
duration !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: duration }),
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: t("history.trigger") })
|
|
1752
1971
|
] })
|
|
1753
1972
|
] });
|
|
1754
1973
|
}
|
|
@@ -1761,6 +1980,8 @@ var en = {
|
|
|
1761
1980
|
"sidebar.tabs": "Workspace views",
|
|
1762
1981
|
"sidebar.tasksTab": "Tasks",
|
|
1763
1982
|
"sidebar.channelsTab": "Channels",
|
|
1983
|
+
"sidebar.views": "Scheduled views",
|
|
1984
|
+
"sidebar.viewOverview": "Task overview",
|
|
1764
1985
|
"sidebar.empty": "No scheduled runs yet.",
|
|
1765
1986
|
"sidebar.tasksEmpty": "No web tasks yet.",
|
|
1766
1987
|
"sidebar.ungrouped": "Ungrouped",
|
|
@@ -1795,6 +2016,16 @@ var en = {
|
|
|
1795
2016
|
"session.rename": "Rename",
|
|
1796
2017
|
"session.fork": "Fork session",
|
|
1797
2018
|
"session.archive": "Archive session",
|
|
2019
|
+
"session.moreActions": "More actions for {title}",
|
|
2020
|
+
"session.groupActions": "Actions for {name}",
|
|
2021
|
+
"session.taskSettings": "Task settings",
|
|
2022
|
+
"session.archiveGroup": "Archive all conversations",
|
|
2023
|
+
"session.archiveGroupConfirm": "Archive all",
|
|
2024
|
+
"session.archiveGroupDescription": "Archive all {count} conversations for \u201C{name}\u201D. You can restore them later in Settings \u2192 Archived.",
|
|
2025
|
+
"session.archiveGroupPending": "Archiving conversations\u2026",
|
|
2026
|
+
"session.archiveGroupFailed": "Some conversations could not be archived: {message}",
|
|
2027
|
+
"session.archiveGroupClose": "Close",
|
|
2028
|
+
"session.archiveGroupCancel": "Cancel",
|
|
1798
2029
|
"session.idle": "Idle",
|
|
1799
2030
|
"session.runningStatus": "Running",
|
|
1800
2031
|
"session.delete": "Remove from Scheduled",
|
|
@@ -1828,6 +2059,7 @@ var en = {
|
|
|
1828
2059
|
"sort.created.desc": "Created time descending",
|
|
1829
2060
|
"sort.planned.asc": "Planned time ascending",
|
|
1830
2061
|
"sort.planned.desc": "Planned time descending",
|
|
2062
|
+
"sort.default.saved": "Default",
|
|
1831
2063
|
"form.workspace": "Workspace",
|
|
1832
2064
|
"form.workspacePath": "Folder path",
|
|
1833
2065
|
"form.workspacePathPlaceholder": "D:\\work\\project",
|
|
@@ -1864,6 +2096,7 @@ var en = {
|
|
|
1864
2096
|
"empty.body": "Save a self-contained task, a schedule, and a permission boundary. Every run starts in a new Session.",
|
|
1865
2097
|
"empty.action": "Create the first automation",
|
|
1866
2098
|
"runs.empty": "No runs yet. Run one now, or wait for the next scheduled occurrence.",
|
|
2099
|
+
"overview.empty": "No scheduled tasks yet. Create one in Settings.",
|
|
1867
2100
|
"form.title": "Create automation",
|
|
1868
2101
|
"form.subtitle": "Write a complete, standalone task. Scheduled runs do not inherit this conversation.",
|
|
1869
2102
|
"form.name": "Name",
|
|
@@ -1946,6 +2179,7 @@ var en = {
|
|
|
1946
2179
|
"error.title": "Automations could not be loaded",
|
|
1947
2180
|
"error.retry": "Try again",
|
|
1948
2181
|
"error.action": "The action failed. Please try again.",
|
|
2182
|
+
"error.taskMissing": "This scheduled task no longer exists.",
|
|
1949
2183
|
"error.offline": "Could not reach the local automation service. Check that DSH is still running and try again.",
|
|
1950
2184
|
"time.now": "now",
|
|
1951
2185
|
"time.minuteAgo": "{count}m ago",
|
|
@@ -1961,6 +2195,8 @@ var zh = {
|
|
|
1961
2195
|
"sidebar.tabs": "\u5DE5\u4F5C\u533A\u5206\u7C7B",
|
|
1962
2196
|
"sidebar.tasksTab": "\u4EFB\u52A1",
|
|
1963
2197
|
"sidebar.channelsTab": "\u9891\u9053",
|
|
2198
|
+
"sidebar.views": "\u5B9A\u65F6\u9875\u89C6\u56FE",
|
|
2199
|
+
"sidebar.viewOverview": "\u4EFB\u52A1\u603B\u89C8",
|
|
1964
2200
|
"sidebar.empty": "\u8FD8\u6CA1\u6709\u5B9A\u65F6\u4EFB\u52A1\u6267\u884C\u8BB0\u5F55\u3002",
|
|
1965
2201
|
"sidebar.tasksEmpty": "\u6682\u65E0\u7F51\u9875\u4EFB\u52A1",
|
|
1966
2202
|
"sidebar.ungrouped": "\u672A\u5206\u7EC4",
|
|
@@ -1995,6 +2231,16 @@ var zh = {
|
|
|
1995
2231
|
"session.rename": "\u91CD\u547D\u540D",
|
|
1996
2232
|
"session.fork": "\u5206\u53C9\u4F1A\u8BDD",
|
|
1997
2233
|
"session.archive": "\u5F52\u6863\u4F1A\u8BDD",
|
|
2234
|
+
"session.moreActions": "\u201C{title}\u201D\u7684\u66F4\u591A\u64CD\u4F5C",
|
|
2235
|
+
"session.groupActions": "\u201C{name}\u201D\u7684\u4EFB\u52A1\u64CD\u4F5C",
|
|
2236
|
+
"session.taskSettings": "\u4EFB\u52A1\u8BBE\u7F6E",
|
|
2237
|
+
"session.archiveGroup": "\u5F52\u6863\u6574\u7EC4\u4F1A\u8BDD",
|
|
2238
|
+
"session.archiveGroupConfirm": "\u786E\u8BA4\u5F52\u6863",
|
|
2239
|
+
"session.archiveGroupDescription": "\u5C06\u5F52\u6863\u201C{name}\u201D\u4E0B\u7684 {count} \u4E2A\u4F1A\u8BDD\u3002\u5F52\u6863\u540E\u53EF\u4EE5\u5728\u201C\u8BBE\u7F6E \u2192 \u5DF2\u5F52\u6863\u201D\u4E2D\u6062\u590D\u3002",
|
|
2240
|
+
"session.archiveGroupPending": "\u6B63\u5728\u5F52\u6863\u6574\u7EC4\u4F1A\u8BDD\u2026",
|
|
2241
|
+
"session.archiveGroupFailed": "\u90E8\u5206\u4F1A\u8BDD\u5F52\u6863\u5931\u8D25\uFF1A{message}",
|
|
2242
|
+
"session.archiveGroupClose": "\u5173\u95ED",
|
|
2243
|
+
"session.archiveGroupCancel": "\u53D6\u6D88",
|
|
1998
2244
|
"session.idle": "\u7A7A\u95F2",
|
|
1999
2245
|
"session.runningStatus": "\u8FD0\u884C\u4E2D",
|
|
2000
2246
|
"session.delete": "\u4ECE\u5B9A\u65F6\u9875\u79FB\u9664",
|
|
@@ -2028,6 +2274,7 @@ var zh = {
|
|
|
2028
2274
|
"sort.created.desc": "\u6309\u521B\u5EFA\u65F6\u95F4\u5012\u5E8F",
|
|
2029
2275
|
"sort.planned.asc": "\u6309\u8BA1\u5212\u65F6\u95F4\u5347\u5E8F",
|
|
2030
2276
|
"sort.planned.desc": "\u6309\u8BA1\u5212\u65F6\u95F4\u5012\u5E8F",
|
|
2277
|
+
"sort.default.saved": "\u9ED8\u8BA4",
|
|
2031
2278
|
"form.workspace": "\u5DE5\u4F5C\u76EE\u5F55",
|
|
2032
2279
|
"form.workspacePath": "\u76EE\u5F55\u8DEF\u5F84",
|
|
2033
2280
|
"form.workspacePathPlaceholder": "D:\\work\\project",
|
|
@@ -2064,6 +2311,7 @@ var zh = {
|
|
|
2064
2311
|
"empty.body": "\u8BBE\u7F6E\u4E00\u4E2A\u76EE\u6807\u660E\u786E\u7684\u4EFB\u52A1\u3001\u8FD0\u884C\u65F6\u95F4\u548C\u6743\u9650\u8FB9\u754C\u3002\u6BCF\u6B21\u8FD0\u884C\u90FD\u4ECE\u5168\u65B0 Session \u5F00\u59CB\u3002",
|
|
2065
2312
|
"empty.action": "\u521B\u5EFA\u7B2C\u4E00\u4E2A\u81EA\u52A8\u5316",
|
|
2066
2313
|
"runs.empty": "\u8FD8\u6CA1\u6709\u8FD0\u884C\u8BB0\u5F55\u3002\u4F60\u53EF\u4EE5\u7ACB\u5373\u8FD0\u884C\u4E00\u6B21\uFF0C\u6216\u7B49\u5F85\u8BA1\u5212\u89E6\u53D1\u3002",
|
|
2314
|
+
"overview.empty": "\u6682\u65E0\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u53EF\u5230\u8BBE\u7F6E\u9875\u521B\u5EFA\u3002",
|
|
2067
2315
|
"form.title": "\u521B\u5EFA\u81EA\u52A8\u5316",
|
|
2068
2316
|
"form.subtitle": "\u8BF7\u5199\u5B8C\u6574\u3001\u72EC\u7ACB\u7684\u4EFB\u52A1\u8BF4\u660E\uFF1A\u5B9A\u65F6\u8FD0\u884C\u4E0D\u4F1A\u7EE7\u627F\u5F53\u524D\u5BF9\u8BDD\u3002",
|
|
2069
2317
|
"form.name": "\u540D\u79F0",
|
|
@@ -2146,6 +2394,7 @@ var zh = {
|
|
|
2146
2394
|
"error.title": "\u65E0\u6CD5\u52A0\u8F7D\u81EA\u52A8\u5316",
|
|
2147
2395
|
"error.retry": "\u91CD\u8BD5",
|
|
2148
2396
|
"error.action": "\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
2397
|
+
"error.taskMissing": "\u8BE5\u5B9A\u65F6\u4EFB\u52A1\u5DF2\u4E0D\u5B58\u5728\u3002",
|
|
2149
2398
|
"error.offline": "\u65E0\u6CD5\u8FDE\u63A5\u672C\u673A\u81EA\u52A8\u5316\u670D\u52A1\uFF0C\u8BF7\u786E\u8BA4 DSH \u4ECD\u5728\u8FD0\u884C\u540E\u91CD\u8BD5\u3002",
|
|
2150
2399
|
"time.now": "\u521A\u521A",
|
|
2151
2400
|
"time.minuteAgo": "{count} \u5206\u949F\u524D",
|
|
@@ -2233,8 +2482,9 @@ function isForeignSidebarHost(component) {
|
|
|
2233
2482
|
}
|
|
2234
2483
|
|
|
2235
2484
|
// src/client/native-session-list.tsx
|
|
2236
|
-
var
|
|
2237
|
-
var
|
|
2485
|
+
var import_react9 = require("react");
|
|
2486
|
+
var import_react_dom3 = require("react-dom");
|
|
2487
|
+
var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
2238
2488
|
|
|
2239
2489
|
// src/client/native-session-menu.ts
|
|
2240
2490
|
function resolveEventElement(target) {
|
|
@@ -2308,6 +2558,18 @@ function relativeTime(value, t, now = Date.now()) {
|
|
|
2308
2558
|
return t("time.dayAgo", { count: Math.floor(hour / 24) });
|
|
2309
2559
|
}
|
|
2310
2560
|
|
|
2561
|
+
// src/client/native-group-actions.ts
|
|
2562
|
+
var ARCHIVE_MANAGER_PLUGIN = "@michengai/dsh-archive-manager";
|
|
2563
|
+
function hasArchiveManagerPlugin(root) {
|
|
2564
|
+
return root?.querySelector(`[data-plugin="${ARCHIVE_MANAGER_PLUGIN}"]`) != null;
|
|
2565
|
+
}
|
|
2566
|
+
function scheduledGroupShowsActiveFolder(expanded, sessionIds, selectedId) {
|
|
2567
|
+
return expanded && selectedId !== null && sessionIds.includes(selectedId);
|
|
2568
|
+
}
|
|
2569
|
+
async function archiveScheduledGroup(sessionIds, archiveSession) {
|
|
2570
|
+
for (const sessionId of sessionIds) await archiveSession(sessionId);
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2311
2573
|
// src/run-title.ts
|
|
2312
2574
|
function formatRunStamp(iso) {
|
|
2313
2575
|
const value = new Date(iso);
|
|
@@ -2354,6 +2616,26 @@ function groupScheduledSessions(automations, runs) {
|
|
|
2354
2616
|
};
|
|
2355
2617
|
}).filter((group) => group.sessions.length > 0);
|
|
2356
2618
|
}
|
|
2619
|
+
function deriveTaskOverviewRows(automations, runs) {
|
|
2620
|
+
const lastByAutomation = /* @__PURE__ */ new Map();
|
|
2621
|
+
for (const run of runs) {
|
|
2622
|
+
if (run.sessionId === void 0 || run.sessionId === "") continue;
|
|
2623
|
+
const current = lastByAutomation.get(run.automationId);
|
|
2624
|
+
const stamp = Date.parse(run.startedAt ?? run.scheduledFor);
|
|
2625
|
+
const currentStamp = current === void 0 ? Number.NaN : Date.parse(current.startedAt ?? current.scheduledFor);
|
|
2626
|
+
if (current === void 0 || stamp >= currentStamp) lastByAutomation.set(run.automationId, run);
|
|
2627
|
+
}
|
|
2628
|
+
return automations.map((item) => {
|
|
2629
|
+
const last = lastByAutomation.get(item.id);
|
|
2630
|
+
return {
|
|
2631
|
+
id: item.id,
|
|
2632
|
+
name: item.name,
|
|
2633
|
+
status: item.status,
|
|
2634
|
+
...item.nextRunAt === void 0 ? {} : { nextRunAt: item.nextRunAt },
|
|
2635
|
+
...last === void 0 ? {} : { lastSessionId: last.sessionId }
|
|
2636
|
+
};
|
|
2637
|
+
});
|
|
2638
|
+
}
|
|
2357
2639
|
function keepScheduledSessionLink(sessionId, archived, presentIds) {
|
|
2358
2640
|
if (sessionId === void 0 || sessionId === "") return false;
|
|
2359
2641
|
if (archived.has(sessionId)) return false;
|
|
@@ -2585,9 +2867,116 @@ function latestSessionTime(group) {
|
|
|
2585
2867
|
return latest;
|
|
2586
2868
|
}
|
|
2587
2869
|
|
|
2870
|
+
// src/client/schedule-overview.tsx
|
|
2871
|
+
var import_react7 = require("react");
|
|
2872
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2873
|
+
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
2874
|
+
var SORT_STORAGE2 = typeof window === "undefined" ? void 0 : window.localStorage;
|
|
2875
|
+
function ScheduleViewSwitch({
|
|
2876
|
+
t,
|
|
2877
|
+
view,
|
|
2878
|
+
onChange
|
|
2879
|
+
}) {
|
|
2880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-rail-views", role: "tablist", "aria-label": t("sidebar.views"), children: [
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", role: "tab", "aria-selected": view === "runs", className: view === "runs" ? "is-on" : void 0, onClick: () => onChange("runs"), children: t("tabs.runs") }),
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", role: "tab", "aria-selected": view === "overview", className: view === "overview" ? "is-on" : void 0, onClick: () => onChange("overview"), children: t("sidebar.viewOverview") })
|
|
2883
|
+
] });
|
|
2884
|
+
}
|
|
2885
|
+
function ScheduleOverview({
|
|
2886
|
+
t,
|
|
2887
|
+
automations,
|
|
2888
|
+
runs,
|
|
2889
|
+
openSession,
|
|
2890
|
+
serverNow,
|
|
2891
|
+
archived,
|
|
2892
|
+
presentIds
|
|
2893
|
+
}) {
|
|
2894
|
+
const [sortKey, setSortKey] = (0, import_react7.useState)(() => readSortDefault(SORT_STORAGE2, OVERVIEW_SORT_DEFAULT_KEY)?.key ?? "planned");
|
|
2895
|
+
const [sortDirection, setSortDirection] = (0, import_react7.useState)(() => readSortDefault(SORT_STORAGE2, OVERVIEW_SORT_DEFAULT_KEY)?.direction ?? "asc");
|
|
2896
|
+
const now = (0, import_react7.useMemo)(() => new Date(serverNow ?? Date.now()), [serverNow]);
|
|
2897
|
+
const rows = (0, import_react7.useMemo)(() => {
|
|
2898
|
+
const sorted = sortAutomations(automations, sortKey, sortDirection);
|
|
2899
|
+
return deriveTaskOverviewRows(sorted, runs).map((row) => {
|
|
2900
|
+
if (row.lastSessionId === void 0 || !keepScheduledSessionLink(row.lastSessionId, archived ?? EMPTY_SET, presentIds)) {
|
|
2901
|
+
const { lastSessionId: _dropped, ...rest } = row;
|
|
2902
|
+
return rest;
|
|
2903
|
+
}
|
|
2904
|
+
return row;
|
|
2905
|
+
});
|
|
2906
|
+
}, [archived, automations, presentIds, runs, sortDirection, sortKey]);
|
|
2907
|
+
const scheduleSummaries = (0, import_react7.useMemo)(() => new Map(automations.map((item) => [item.id, formatSchedule(item.schedule, t)])), [automations, t]);
|
|
2908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-overview", children: [
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-overview-head", children: [
|
|
2910
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-overview-title", children: [
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: t("sidebar.viewOverview") }),
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-label": `${rows.length}`, children: rows.length })
|
|
2913
|
+
] }),
|
|
2914
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2915
|
+
SortMenu,
|
|
2916
|
+
{
|
|
2917
|
+
t,
|
|
2918
|
+
compact: true,
|
|
2919
|
+
iconOnly: true,
|
|
2920
|
+
className: "dsh-st-overview-sort",
|
|
2921
|
+
...SORT_STORAGE2 === void 0 ? {} : { storage: SORT_STORAGE2 },
|
|
2922
|
+
storageKey: OVERVIEW_SORT_DEFAULT_KEY,
|
|
2923
|
+
sortKey,
|
|
2924
|
+
sortDirection,
|
|
2925
|
+
onSelect: (key, direction) => {
|
|
2926
|
+
setSortKey(key);
|
|
2927
|
+
setSortDirection(direction);
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
)
|
|
2931
|
+
] }),
|
|
2932
|
+
rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dsh-st-rail-empty", children: t("overview.empty") }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(OverviewRow, { t, row, now, scheduleSummary: scheduleSummaries.get(row.id) ?? "", ...openSession === void 0 ? {} : { openSession } }, row.id))
|
|
2933
|
+
] });
|
|
2934
|
+
}
|
|
2935
|
+
function OverviewRow({
|
|
2936
|
+
t,
|
|
2937
|
+
row,
|
|
2938
|
+
now,
|
|
2939
|
+
scheduleSummary,
|
|
2940
|
+
openSession
|
|
2941
|
+
}) {
|
|
2942
|
+
const paused = row.status !== "active";
|
|
2943
|
+
const nextRun = row.nextRunAt === void 0 ? t("stats.noneScheduled") : formatWithin(row.nextRunAt, now, t);
|
|
2944
|
+
const status = paused ? t("status.paused") : t("status.active");
|
|
2945
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2946
|
+
"button",
|
|
2947
|
+
{
|
|
2948
|
+
type: "button",
|
|
2949
|
+
className: `dsh-st-overview-row${paused ? " is-paused" : ""}`,
|
|
2950
|
+
disabled: row.lastSessionId === void 0,
|
|
2951
|
+
title: paused ? t("status.paused") : t("status.active"),
|
|
2952
|
+
onClick: () => {
|
|
2953
|
+
if (row.lastSessionId !== void 0) openSession?.(row.lastSessionId);
|
|
2954
|
+
},
|
|
2955
|
+
children: [
|
|
2956
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-copy", children: [
|
|
2957
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-status", children: [
|
|
2958
|
+
paused ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PauseIcon, { width: 14, height: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckIcon, { width: 14, height: 14 }),
|
|
2959
|
+
status
|
|
2960
|
+
] }),
|
|
2961
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dsh-st-overview-name", children: row.name }),
|
|
2962
|
+
scheduleSummary !== "" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-schedule", children: [
|
|
2963
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CalendarIcon, { width: 14, height: 14 }),
|
|
2964
|
+
scheduleSummary
|
|
2965
|
+
] })
|
|
2966
|
+
] }),
|
|
2967
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-next", children: [
|
|
2968
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: t("stats.next") }),
|
|
2969
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: nextRun })
|
|
2970
|
+
] }),
|
|
2971
|
+
row.lastSessionId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronIcon, { width: 12, height: 12, className: "dsh-st-overview-chevron" })
|
|
2972
|
+
]
|
|
2973
|
+
}
|
|
2974
|
+
);
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2588
2977
|
// src/client/workspace-toolbar.tsx
|
|
2589
|
-
var
|
|
2590
|
-
var
|
|
2978
|
+
var import_react8 = require("react");
|
|
2979
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2591
2980
|
function officialSearchIconSize(expanded) {
|
|
2592
2981
|
return expanded ? 11 : 14;
|
|
2593
2982
|
}
|
|
@@ -2600,15 +2989,15 @@ function WorkspaceToolbar({
|
|
|
2600
2989
|
onSortChange,
|
|
2601
2990
|
onGroupModeChange
|
|
2602
2991
|
}) {
|
|
2603
|
-
const [searching, setSearching] = (0,
|
|
2604
|
-
const [filterOpen, setFilterOpen] = (0,
|
|
2605
|
-
const inputRef = (0,
|
|
2606
|
-
const rootRef = (0,
|
|
2992
|
+
const [searching, setSearching] = (0, import_react8.useState)(query.trim() !== "");
|
|
2993
|
+
const [filterOpen, setFilterOpen] = (0, import_react8.useState)(false);
|
|
2994
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
2995
|
+
const rootRef = (0, import_react8.useRef)(null);
|
|
2607
2996
|
const searchSize = officialSearchIconSize(searching);
|
|
2608
|
-
(0,
|
|
2997
|
+
(0, import_react8.useEffect)(() => {
|
|
2609
2998
|
if (searching) inputRef.current?.focus();
|
|
2610
2999
|
}, [searching]);
|
|
2611
|
-
(0,
|
|
3000
|
+
(0, import_react8.useEffect)(() => {
|
|
2612
3001
|
if (!filterOpen) return;
|
|
2613
3002
|
const close = (event) => {
|
|
2614
3003
|
const target = event.target;
|
|
@@ -2626,37 +3015,37 @@ function WorkspaceToolbar({
|
|
|
2626
3015
|
onQueryChange("");
|
|
2627
3016
|
setSearching(false);
|
|
2628
3017
|
};
|
|
2629
|
-
return /* @__PURE__ */ (0,
|
|
2630
|
-
/* @__PURE__ */ (0,
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2632
|
-
/* @__PURE__ */ (0,
|
|
2633
|
-
/* @__PURE__ */ (0,
|
|
3018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: searching ? "dsh-st-n-toolbar is-search" : "dsh-st-n-toolbar", ref: rootRef, children: [
|
|
3019
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "dsh-st-n-head-label", children: t("sidebar.workspaces") }),
|
|
3020
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-search-slot", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dsh-st-n-search", onClick: openSearch, children: [
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.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_runtime9.jsx)(SearchOutlineIcon, { width: searchSize, height: searchSize }) }),
|
|
3022
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.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) => {
|
|
2634
3023
|
if (event.key === "Escape") closeSearch();
|
|
2635
3024
|
} }),
|
|
2636
|
-
searching && /* @__PURE__ */ (0,
|
|
3025
|
+
searching && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "dsh-st-n-search-clear", "aria-label": t("sidebar.clearSearch"), onClick: (event) => {
|
|
2637
3026
|
event.stopPropagation();
|
|
2638
3027
|
closeSearch();
|
|
2639
|
-
}, children: /* @__PURE__ */ (0,
|
|
3028
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseOutlineIcon, { width: 14, height: 14 }) })
|
|
2640
3029
|
] }) }),
|
|
2641
|
-
/* @__PURE__ */ (0,
|
|
2642
|
-
/* @__PURE__ */ (0,
|
|
2643
|
-
filterOpen && /* @__PURE__ */ (0,
|
|
2644
|
-
/* @__PURE__ */ (0,
|
|
2645
|
-
/* @__PURE__ */ (0,
|
|
3030
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-head-acts", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dsh-st-n-head-filter", children: [
|
|
3031
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.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_runtime9.jsx)(SlidersIcon, { width: 16, height: 16 }) }),
|
|
3032
|
+
filterOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dsh-st-n-filter-menu", role: "menu", children: [
|
|
3033
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.groupBy") }),
|
|
3034
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.groupWorkspace"), selected: groupMode === "workspace", onSelect: () => {
|
|
2646
3035
|
onGroupModeChange("workspace");
|
|
2647
3036
|
setFilterOpen(false);
|
|
2648
3037
|
} }),
|
|
2649
|
-
/* @__PURE__ */ (0,
|
|
3038
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.groupList"), selected: groupMode === "list", onSelect: () => {
|
|
2650
3039
|
onGroupModeChange("list");
|
|
2651
3040
|
setFilterOpen(false);
|
|
2652
3041
|
} }),
|
|
2653
|
-
/* @__PURE__ */ (0,
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
3042
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-filter-split" }),
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.sortBy") }),
|
|
3044
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.sortManual"), selected: sort === "manual", onSelect: () => {
|
|
2656
3045
|
onSortChange("manual");
|
|
2657
3046
|
setFilterOpen(false);
|
|
2658
3047
|
} }),
|
|
2659
|
-
/* @__PURE__ */ (0,
|
|
3048
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.sortTime"), selected: sort === "time", onSelect: () => {
|
|
2660
3049
|
onSortChange("time");
|
|
2661
3050
|
setFilterOpen(false);
|
|
2662
3051
|
} })
|
|
@@ -2669,34 +3058,40 @@ function FilterRow({
|
|
|
2669
3058
|
selected,
|
|
2670
3059
|
onSelect
|
|
2671
3060
|
}) {
|
|
2672
|
-
return /* @__PURE__ */ (0,
|
|
2673
|
-
/* @__PURE__ */ (0,
|
|
2674
|
-
selected ? /* @__PURE__ */ (0,
|
|
3061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { type: "button", role: "menuitemradio", "aria-checked": selected, className: selected ? "is-on" : void 0, onClick: onSelect, children: [
|
|
3062
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: label }),
|
|
3063
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CheckOutlineIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "dsh-st-n-filter-tick" })
|
|
2675
3064
|
] });
|
|
2676
3065
|
}
|
|
2677
3066
|
|
|
2678
3067
|
// src/client/native-session-list.tsx
|
|
2679
|
-
var
|
|
3068
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2680
3069
|
var EMPTY_SESSION_BY_ID = {};
|
|
2681
3070
|
function NativeScheduleSessionList(props) {
|
|
2682
|
-
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession, forkSession } = props;
|
|
2683
|
-
const state = (0,
|
|
2684
|
-
const selectedId = useSessions ? useSessions((snap) => snap
|
|
2685
|
-
const sessionById = useSessions ? useSessions((snap) => snap
|
|
2686
|
-
const archivedIds = useWorkspaces ? useWorkspaces((snap) => snap
|
|
2687
|
-
const [folded, setFolded] = (0,
|
|
2688
|
-
const [openMenu, setOpenMenu] = (0,
|
|
2689
|
-
const [
|
|
2690
|
-
const [
|
|
2691
|
-
const [
|
|
2692
|
-
const
|
|
2693
|
-
const
|
|
2694
|
-
const
|
|
3071
|
+
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession, forkSession, openTaskSettings } = props;
|
|
3072
|
+
const state = (0, import_react9.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
3073
|
+
const selectedId = useSessions ? useSessions((snap) => snap.current ?? null) : null;
|
|
3074
|
+
const sessionById = useSessions ? useSessions((snap) => snap.byId ?? EMPTY_SESSION_BY_ID) : EMPTY_SESSION_BY_ID;
|
|
3075
|
+
const archivedIds = useWorkspaces ? useWorkspaces((snap) => snap.archivedSessionIds ?? []) : [];
|
|
3076
|
+
const [folded, setFolded] = (0, import_react9.useState)({});
|
|
3077
|
+
const [openMenu, setOpenMenu] = (0, import_react9.useState)(null);
|
|
3078
|
+
const [openGroupMenu, setOpenGroupMenu] = (0, import_react9.useState)();
|
|
3079
|
+
const [archiveGroupTarget, setArchiveGroupTarget] = (0, import_react9.useState)();
|
|
3080
|
+
const [archiveGroupBusy, setArchiveGroupBusy] = (0, import_react9.useState)(false);
|
|
3081
|
+
const [archiveGroupError, setArchiveGroupError] = (0, import_react9.useState)();
|
|
3082
|
+
const [archiveManagerInstalled, setArchiveManagerInstalled] = (0, import_react9.useState)(() => typeof document !== "undefined" && hasArchiveManagerPlugin(document));
|
|
3083
|
+
const [query, setQuery] = (0, import_react9.useState)("");
|
|
3084
|
+
const [sort, setSort] = (0, import_react9.useState)("time");
|
|
3085
|
+
const [groupMode, setGroupMode] = (0, import_react9.useState)("workspace");
|
|
3086
|
+
const [view, setView] = (0, import_react9.useState)("runs");
|
|
3087
|
+
const archived = (0, import_react9.useMemo)(() => new Set(archivedIds), [archivedIds]);
|
|
3088
|
+
const listedIds = useSessions ? useSessions((snap) => Array.isArray(snap.ids) ? snap.ids : void 0) : void 0;
|
|
3089
|
+
const presentIds = (0, import_react9.useMemo)(() => {
|
|
2695
3090
|
if (listedIds !== void 0) return new Set(listedIds);
|
|
2696
3091
|
const keys = Object.keys(sessionById);
|
|
2697
3092
|
return keys.length > 0 ? new Set(keys) : void 0;
|
|
2698
3093
|
}, [listedIds, sessionById]);
|
|
2699
|
-
const groups = (0,
|
|
3094
|
+
const groups = (0, import_react9.useMemo)(() => {
|
|
2700
3095
|
const snapshot = state.snapshot;
|
|
2701
3096
|
if (snapshot === void 0) return [];
|
|
2702
3097
|
return groupScheduledSessions(snapshot.automations, snapshot.runs).map((group) => ({
|
|
@@ -2712,63 +3107,212 @@ function NativeScheduleSessionList(props) {
|
|
|
2712
3107
|
})
|
|
2713
3108
|
})).filter((group) => group.sessions.length > 0);
|
|
2714
3109
|
}, [archived, presentIds, sessionById, state.snapshot]);
|
|
2715
|
-
const visibleGroups = (0,
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
3110
|
+
const visibleGroups = (0, import_react9.useMemo)(() => applyWorkspaceBrowserQuery(groups.map((group) => ({ ...group, name: group.name })), query, sort, groupMode), [groups, query, sort, groupMode]);
|
|
3111
|
+
(0, import_react9.useEffect)(() => {
|
|
3112
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
|
|
3113
|
+
const refresh = () => {
|
|
3114
|
+
setArchiveManagerInstalled(hasArchiveManagerPlugin(document));
|
|
3115
|
+
};
|
|
3116
|
+
refresh();
|
|
3117
|
+
const observer = new MutationObserver(refresh);
|
|
3118
|
+
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
3119
|
+
return () => {
|
|
3120
|
+
observer.disconnect();
|
|
3121
|
+
};
|
|
3122
|
+
}, []);
|
|
3123
|
+
const canArchiveGroup = archiveManagerInstalled && archiveSession !== void 0;
|
|
3124
|
+
const confirmArchiveGroup = () => {
|
|
3125
|
+
if (archiveGroupTarget === void 0 || archiveSession === void 0 || archiveGroupBusy) return;
|
|
3126
|
+
const target = archiveGroupTarget;
|
|
3127
|
+
setArchiveGroupBusy(true);
|
|
3128
|
+
setArchiveGroupError(void 0);
|
|
3129
|
+
void archiveScheduledGroup(target.sessionIds, archiveSession).then(() => {
|
|
3130
|
+
setArchiveGroupTarget(void 0);
|
|
3131
|
+
}).catch((caught) => {
|
|
3132
|
+
setArchiveGroupError(caught instanceof Error ? caught.message : t("error.action"));
|
|
3133
|
+
}).finally(() => {
|
|
3134
|
+
setArchiveGroupBusy(false);
|
|
3135
|
+
});
|
|
3136
|
+
};
|
|
3137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n", children: [
|
|
3138
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScheduleViewSwitch, { t, view, onChange: setView }),
|
|
3139
|
+
view === "overview" ? state.snapshot === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-empty", children: state.phase === "loading" ? t("loading") : t("overview.empty") }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3140
|
+
ScheduleOverview,
|
|
3141
|
+
{
|
|
3142
|
+
t,
|
|
3143
|
+
automations: state.snapshot.automations,
|
|
3144
|
+
runs: state.snapshot.runs,
|
|
3145
|
+
...openSession === void 0 ? {} : { openSession },
|
|
3146
|
+
...state.snapshot.serverNow === void 0 ? {} : { serverNow: state.snapshot.serverNow },
|
|
3147
|
+
archived,
|
|
3148
|
+
...presentIds === void 0 ? {} : { presentIds }
|
|
3149
|
+
}
|
|
3150
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
3151
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(WorkspaceToolbar, { t, query, sort, groupMode, onQueryChange: setQuery, onSortChange: setSort, onGroupModeChange: setGroupMode }),
|
|
3152
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-tree", role: "tree", children: [
|
|
3153
|
+
state.phase === "loading" && visibleGroups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-empty", children: t("loading") }),
|
|
3154
|
+
visibleGroups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-empty", children: t("sidebar.empty") }),
|
|
3155
|
+
visibleGroups.map((group) => {
|
|
3156
|
+
const expanded = folded[group.id] !== true;
|
|
3157
|
+
const hasCurrentSession = scheduledGroupShowsActiveFolder(expanded, group.sessions.map((session) => session.id), selectedId);
|
|
3158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-group", children: [
|
|
3159
|
+
groupMode === "workspace" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3160
|
+
NativeScheduleGroupRow,
|
|
3161
|
+
{
|
|
3162
|
+
t,
|
|
3163
|
+
id: group.id,
|
|
3164
|
+
name: group.name,
|
|
3165
|
+
sessionIds: group.sessions.map((session) => session.id),
|
|
3166
|
+
expanded,
|
|
3167
|
+
hasCurrentSession,
|
|
3168
|
+
menuOpen: openGroupMenu === group.id,
|
|
3169
|
+
canArchiveGroup,
|
|
3170
|
+
onToggle: () => setFolded((current) => ({ ...current, [group.id]: expanded })),
|
|
3171
|
+
onMenuChange: (open) => {
|
|
3172
|
+
setOpenMenu(null);
|
|
3173
|
+
setOpenGroupMenu(open ? group.id : void 0);
|
|
3174
|
+
},
|
|
3175
|
+
onTaskSettings: () => {
|
|
3176
|
+
openTaskSettings?.({ automationId: group.id, name: group.name, sessionIds: group.sessions.map((session) => session.id) });
|
|
3177
|
+
},
|
|
3178
|
+
onArchiveGroup: () => {
|
|
3179
|
+
setArchiveGroupError(void 0);
|
|
3180
|
+
setArchiveGroupTarget({ id: group.id, name: group.name, sessionIds: group.sessions.map((session) => session.id) });
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
),
|
|
3184
|
+
(groupMode === "list" || expanded) && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3185
|
+
NativeSessionRow,
|
|
3186
|
+
{
|
|
3187
|
+
t,
|
|
3188
|
+
id: session.id,
|
|
3189
|
+
title: session.title,
|
|
3190
|
+
hoverTitle: String(sessionById[session.id]?.displayTitle ?? sessionById[session.id]?.title ?? group.name),
|
|
3191
|
+
updatedAt: session.updatedAt,
|
|
3192
|
+
running: session.running,
|
|
3193
|
+
selected: selectedId === session.id,
|
|
3194
|
+
menuOpen: openMenu?.id === session.id,
|
|
3195
|
+
menuPoint: openMenu === null || openMenu.id !== session.id ? { x: 8, y: 8 } : { x: openMenu.x, y: openMenu.y },
|
|
3196
|
+
onToggleMenu: (event) => {
|
|
3197
|
+
setOpenGroupMenu(void 0);
|
|
3198
|
+
setOpenMenu((current) => nextOpenSessionMenu(current, session.id, pointerPoint(event)));
|
|
3199
|
+
},
|
|
3200
|
+
onCloseMenu: () => setOpenMenu((current) => current?.id === session.id ? null : current),
|
|
3201
|
+
onOpen: () => {
|
|
3202
|
+
setOpenMenu(null);
|
|
3203
|
+
openSession?.(session.id);
|
|
3204
|
+
},
|
|
3205
|
+
...renameSession === void 0 ? {} : { renameSession },
|
|
3206
|
+
...archiveSession === void 0 ? {} : { archiveSession },
|
|
3207
|
+
...forkSession === void 0 ? {} : { forkSession }
|
|
2745
3208
|
},
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
3209
|
+
session.id
|
|
3210
|
+
))
|
|
3211
|
+
] }, group.id);
|
|
3212
|
+
})
|
|
3213
|
+
] })
|
|
3214
|
+
] }),
|
|
3215
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3216
|
+
import_dsh_client_ui_primitives2.Modal,
|
|
3217
|
+
{
|
|
3218
|
+
open: archiveGroupTarget !== void 0,
|
|
3219
|
+
onClose: () => {
|
|
3220
|
+
if (archiveGroupBusy) return;
|
|
3221
|
+
setArchiveGroupTarget(void 0);
|
|
3222
|
+
setArchiveGroupError(void 0);
|
|
3223
|
+
},
|
|
3224
|
+
closeLabel: t("session.archiveGroupClose"),
|
|
3225
|
+
title: t("session.archiveGroup"),
|
|
3226
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-dialog-actions", children: [
|
|
3227
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.Button, { variant: "outline", disabled: archiveGroupBusy, onClick: () => {
|
|
3228
|
+
setArchiveGroupTarget(void 0);
|
|
3229
|
+
setArchiveGroupError(void 0);
|
|
3230
|
+
}, children: t("session.archiveGroupCancel") }),
|
|
3231
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.Button, { variant: "outline", className: "dsh-st-n-danger-button", disabled: archiveGroupBusy, onClick: confirmArchiveGroup, children: t("session.archiveGroupConfirm") })
|
|
3232
|
+
] }),
|
|
3233
|
+
children: [
|
|
3234
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "dsh-st-n-dialog-copy", children: archiveGroupTarget === void 0 ? "" : t("session.archiveGroupDescription", { name: archiveGroupTarget.name, count: archiveGroupTarget.sessionIds.length }) }),
|
|
3235
|
+
archiveGroupBusy && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-dialog-status", role: "status", children: t("session.archiveGroupPending") }),
|
|
3236
|
+
archiveGroupError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-dialog-error", role: "alert", children: t("session.archiveGroupFailed", { message: archiveGroupError }) })
|
|
3237
|
+
]
|
|
3238
|
+
}
|
|
3239
|
+
)
|
|
2755
3240
|
] });
|
|
2756
3241
|
}
|
|
3242
|
+
function NativeScheduleGroupRow(props) {
|
|
3243
|
+
const { t, id, name: name2, expanded, hasCurrentSession, menuOpen, canArchiveGroup, onToggle, onMenuChange, onTaskSettings, onArchiveGroup } = props;
|
|
3244
|
+
const items = [
|
|
3245
|
+
{ id: "task-settings", label: t("session.taskSettings"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.IconSettingsOutline16, { size: 16 }) },
|
|
3246
|
+
...canArchiveGroup ? [
|
|
3247
|
+
{ type: "separator", id: "archive-separator" },
|
|
3248
|
+
{ id: "archive-group", label: t("session.archiveGroup"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.IconArchiveOutline20, { size: 16 }), danger: true }
|
|
3249
|
+
] : []
|
|
3250
|
+
];
|
|
3251
|
+
const rowClass = "dsh-st-n-row" + (hasCurrentSession ? " has-current-session" : "") + (menuOpen ? " is-menu" : "");
|
|
3252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3253
|
+
"div",
|
|
3254
|
+
{
|
|
3255
|
+
className: rowClass,
|
|
3256
|
+
role: "treeitem",
|
|
3257
|
+
"aria-expanded": expanded,
|
|
3258
|
+
"data-n-group": id,
|
|
3259
|
+
onClick: onToggle,
|
|
3260
|
+
children: [
|
|
3261
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-slot dsh-st-n-folder", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FolderOpenIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FolderClosedIcon, { width: 16, height: 16 }) }),
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-title", children: name2 }),
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-acts", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3264
|
+
import_dsh_client_ui_primitives2.Menu,
|
|
3265
|
+
{
|
|
3266
|
+
open: menuOpen,
|
|
3267
|
+
onClose: () => {
|
|
3268
|
+
onMenuChange(false);
|
|
3269
|
+
},
|
|
3270
|
+
items,
|
|
3271
|
+
onSelect: (action) => {
|
|
3272
|
+
onMenuChange(false);
|
|
3273
|
+
if (action === "task-settings") onTaskSettings();
|
|
3274
|
+
if (action === "archive-group") onArchiveGroup();
|
|
3275
|
+
},
|
|
3276
|
+
portal: true,
|
|
3277
|
+
dense: true,
|
|
3278
|
+
compact: true,
|
|
3279
|
+
anchor: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3280
|
+
"button",
|
|
3281
|
+
{
|
|
3282
|
+
type: "button",
|
|
3283
|
+
className: "dsh-st-n-ico",
|
|
3284
|
+
"aria-label": t("session.groupActions", { name: name2 }),
|
|
3285
|
+
onMouseDown: (event) => {
|
|
3286
|
+
event.stopPropagation();
|
|
3287
|
+
},
|
|
3288
|
+
onClick: (event) => {
|
|
3289
|
+
event.stopPropagation();
|
|
3290
|
+
onMenuChange(!menuOpen);
|
|
3291
|
+
},
|
|
3292
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.IconEllipsisOutline16, { size: 16 })
|
|
3293
|
+
}
|
|
3294
|
+
)
|
|
3295
|
+
}
|
|
3296
|
+
) })
|
|
3297
|
+
]
|
|
3298
|
+
}
|
|
3299
|
+
);
|
|
3300
|
+
}
|
|
2757
3301
|
function NativeSessionRow(props) {
|
|
2758
3302
|
const { t, id, title, hoverTitle, updatedAt, running, selected, menuOpen, menuPoint, onToggleMenu, onCloseMenu, onOpen, renameSession, archiveSession, forkSession } = props;
|
|
2759
|
-
const rowRef = (0,
|
|
2760
|
-
const menuRef = (0,
|
|
2761
|
-
const hoverRef = (0,
|
|
2762
|
-
const [hoverOpen, setHoverOpen] = (0,
|
|
2763
|
-
const [hoverStyle, setHoverStyle] = (0,
|
|
2764
|
-
const hoverTimer = (0,
|
|
2765
|
-
const [renaming, setRenaming] = (0,
|
|
2766
|
-
const [draft, setDraft] = (0,
|
|
2767
|
-
const [menuStyle, setMenuStyle] = (0,
|
|
2768
|
-
(0,
|
|
3303
|
+
const rowRef = (0, import_react9.useRef)(null);
|
|
3304
|
+
const menuRef = (0, import_react9.useRef)(null);
|
|
3305
|
+
const hoverRef = (0, import_react9.useRef)(null);
|
|
3306
|
+
const [hoverOpen, setHoverOpen] = (0, import_react9.useState)(false);
|
|
3307
|
+
const [hoverStyle, setHoverStyle] = (0, import_react9.useState)({});
|
|
3308
|
+
const hoverTimer = (0, import_react9.useRef)(void 0);
|
|
3309
|
+
const [renaming, setRenaming] = (0, import_react9.useState)(false);
|
|
3310
|
+
const [draft, setDraft] = (0, import_react9.useState)(title);
|
|
3311
|
+
const [menuStyle, setMenuStyle] = (0, import_react9.useState)({});
|
|
3312
|
+
(0, import_react9.useEffect)(() => {
|
|
2769
3313
|
setDraft(title);
|
|
2770
3314
|
}, [title]);
|
|
2771
|
-
(0,
|
|
3315
|
+
(0, import_react9.useEffect)(() => {
|
|
2772
3316
|
if (!menuOpen) return;
|
|
2773
3317
|
const close = (event) => {
|
|
2774
3318
|
if (!shouldCloseNativeSessionMenu(event.target, [rowRef.current, menuRef.current])) return;
|
|
@@ -2784,7 +3328,7 @@ function NativeSessionRow(props) {
|
|
|
2784
3328
|
document.removeEventListener("keydown", onKey);
|
|
2785
3329
|
};
|
|
2786
3330
|
}, [menuOpen, onCloseMenu]);
|
|
2787
|
-
(0,
|
|
3331
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
2788
3332
|
if (!menuOpen) return;
|
|
2789
3333
|
const update = () => {
|
|
2790
3334
|
const el = menuRef.current;
|
|
@@ -2799,7 +3343,7 @@ function NativeSessionRow(props) {
|
|
|
2799
3343
|
document.removeEventListener("scroll", update, true);
|
|
2800
3344
|
};
|
|
2801
3345
|
}, [menuOpen, menuPoint]);
|
|
2802
|
-
(0,
|
|
3346
|
+
(0, import_react9.useEffect)(() => {
|
|
2803
3347
|
if (!hoverOpen || menuOpen) return;
|
|
2804
3348
|
const update = () => {
|
|
2805
3349
|
const row = rowRef.current?.getBoundingClientRect();
|
|
@@ -2816,7 +3360,7 @@ function NativeSessionRow(props) {
|
|
|
2816
3360
|
document.removeEventListener("scroll", update, true);
|
|
2817
3361
|
};
|
|
2818
3362
|
}, [hoverOpen, menuOpen, title, updatedAt, running]);
|
|
2819
|
-
(0,
|
|
3363
|
+
(0, import_react9.useEffect)(() => () => {
|
|
2820
3364
|
if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
|
|
2821
3365
|
}, []);
|
|
2822
3366
|
const run = (action) => {
|
|
@@ -2833,7 +3377,7 @@ function NativeSessionRow(props) {
|
|
|
2833
3377
|
};
|
|
2834
3378
|
const rowClass = "dsh-st-n-sess" + (selected ? " is-on" : "") + (menuOpen ? " is-menu" : "");
|
|
2835
3379
|
if (renaming) {
|
|
2836
|
-
return /* @__PURE__ */ (0,
|
|
3380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: rowClass, ref: rowRef, children: /* @__PURE__ */ (0, import_jsx_runtime10.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) => {
|
|
2837
3381
|
if (event.key === "Enter") {
|
|
2838
3382
|
event.preventDefault();
|
|
2839
3383
|
setRenaming(false);
|
|
@@ -2850,23 +3394,23 @@ function NativeSessionRow(props) {
|
|
|
2850
3394
|
} }) });
|
|
2851
3395
|
}
|
|
2852
3396
|
const menuItems = [
|
|
2853
|
-
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0,
|
|
3397
|
+
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PencilIcon, { width: 16, height: 16 }), go: () => {
|
|
2854
3398
|
setRenaming(true);
|
|
2855
3399
|
} },
|
|
2856
|
-
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0,
|
|
2857
|
-
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0,
|
|
3400
|
+
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BranchIcon, { width: 16, height: 16 }), go: () => run(() => forkSession?.(id)) },
|
|
3401
|
+
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ArchiveIcon, { width: 16, height: 16 }), go: () => run(() => archiveSession?.(id)) }
|
|
2858
3402
|
];
|
|
2859
|
-
const menu = menuOpen && typeof document !== "undefined" ? (0,
|
|
2860
|
-
/* @__PURE__ */ (0,
|
|
3403
|
+
const menu = menuOpen && typeof document !== "undefined" ? (0, import_react_dom3.createPortal)(
|
|
3404
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.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_runtime10.jsxs)("button", { type: "button", className: void 0, onClick: () => {
|
|
2861
3405
|
onCloseMenu();
|
|
2862
3406
|
item.go();
|
|
2863
3407
|
}, children: [
|
|
2864
|
-
/* @__PURE__ */ (0,
|
|
3408
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-mi", children: item.icon }),
|
|
2865
3409
|
item.label
|
|
2866
3410
|
] }, item.id)) }),
|
|
2867
3411
|
document.body
|
|
2868
3412
|
) : null;
|
|
2869
|
-
return /* @__PURE__ */ (0,
|
|
3413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.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) => {
|
|
2870
3414
|
if (event.key === "Enter" || event.key === " ") {
|
|
2871
3415
|
event.preventDefault();
|
|
2872
3416
|
onOpen();
|
|
@@ -2876,21 +3420,21 @@ function NativeSessionRow(props) {
|
|
|
2876
3420
|
event.stopPropagation();
|
|
2877
3421
|
onToggleMenu(event);
|
|
2878
3422
|
}, children: [
|
|
2879
|
-
/* @__PURE__ */ (0,
|
|
2880
|
-
/* @__PURE__ */ (0,
|
|
2881
|
-
/* @__PURE__ */ (0,
|
|
2882
|
-
/* @__PURE__ */ (0,
|
|
3423
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-slot", children: running ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RunningStateDot, {}) : null }),
|
|
3424
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-title", children: title }),
|
|
3425
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-time", children: relativeTime(updatedAt, t) }),
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-acts", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "dsh-st-n-ico", "aria-label": t("session.moreActions", { title }), onMouseDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
2883
3427
|
event.stopPropagation();
|
|
2884
3428
|
hideHover();
|
|
2885
3429
|
onToggleMenu(event);
|
|
2886
|
-
}, children: /* @__PURE__ */ (0,
|
|
3430
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(EllipsisIcon, { width: 16, height: 16 }) }) }),
|
|
2887
3431
|
menu,
|
|
2888
|
-
hoverOpen && !menuOpen && typeof document !== "undefined" && (0,
|
|
2889
|
-
/* @__PURE__ */ (0,
|
|
2890
|
-
/* @__PURE__ */ (0,
|
|
2891
|
-
/* @__PURE__ */ (0,
|
|
2892
|
-
/* @__PURE__ */ (0,
|
|
2893
|
-
/* @__PURE__ */ (0,
|
|
3432
|
+
hoverOpen && !menuOpen && typeof document !== "undefined" && (0, import_react_dom3.createPortal)(
|
|
3433
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref: hoverRef, className: "dsh-st-n-hover", style: hoverStyle, onMouseEnter: showHover, onMouseLeave: hideHover, children: [
|
|
3434
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-hover-title", children: (hoverTitle ?? title).trim() || title }),
|
|
3435
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-hover-time", children: relativeTime(updatedAt, t) }),
|
|
3436
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-hover-state", children: [
|
|
3437
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: running ? "dsh-st-n-hover-dot is-run" : "dsh-st-n-hover-dot" }),
|
|
2894
3438
|
running ? t("session.runningStatus") : t("session.idle")
|
|
2895
3439
|
] })
|
|
2896
3440
|
] }),
|
|
@@ -2900,11 +3444,11 @@ function NativeSessionRow(props) {
|
|
|
2900
3444
|
}
|
|
2901
3445
|
|
|
2902
3446
|
// src/client/ScheduleRail.tsx
|
|
2903
|
-
var
|
|
2904
|
-
var
|
|
3447
|
+
var import_react10 = require("react");
|
|
3448
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2905
3449
|
var EMPTY_EXTRA_TABS = [];
|
|
2906
3450
|
var noopSubscribe = (_listener) => () => void 0;
|
|
2907
|
-
var OfficialTreeGuard = class extends
|
|
3451
|
+
var OfficialTreeGuard = class extends import_react10.Component {
|
|
2908
3452
|
state = { failed: false };
|
|
2909
3453
|
static getDerivedStateFromError() {
|
|
2910
3454
|
return { failed: true };
|
|
@@ -2919,45 +3463,61 @@ var OfficialTreeGuard = class extends import_react7.Component {
|
|
|
2919
3463
|
function ScheduleRail({
|
|
2920
3464
|
t,
|
|
2921
3465
|
runtime,
|
|
2922
|
-
openSession
|
|
3466
|
+
openSession,
|
|
3467
|
+
view: controlledView,
|
|
3468
|
+
showViewSwitch = true
|
|
2923
3469
|
}) {
|
|
2924
|
-
const state = (0,
|
|
2925
|
-
const [folded, setFolded] = (0,
|
|
2926
|
-
const
|
|
2927
|
-
|
|
3470
|
+
const state = (0, import_react10.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
3471
|
+
const [folded, setFolded] = (0, import_react10.useState)({});
|
|
3472
|
+
const [localView, setLocalView] = (0, import_react10.useState)("runs");
|
|
3473
|
+
const view = controlledView ?? localView;
|
|
3474
|
+
const snapshot = state.snapshot;
|
|
3475
|
+
const groups = (0, import_react10.useMemo)(() => {
|
|
2928
3476
|
if (snapshot === void 0) return [];
|
|
2929
3477
|
return groupScheduledSessions(snapshot.automations, snapshot.runs);
|
|
2930
|
-
}, [
|
|
2931
|
-
return /* @__PURE__ */ (0,
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
session.
|
|
2959
|
-
|
|
2960
|
-
|
|
3478
|
+
}, [snapshot]);
|
|
3479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-st-rail", children: [
|
|
3480
|
+
showViewSwitch && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScheduleViewSwitch, { t, view, onChange: setLocalView }),
|
|
3481
|
+
view === "overview" ? snapshot === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: state.phase === "loading" ? t("loading") : t("overview.empty") }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3482
|
+
ScheduleOverview,
|
|
3483
|
+
{
|
|
3484
|
+
t,
|
|
3485
|
+
automations: snapshot.automations,
|
|
3486
|
+
runs: snapshot.runs,
|
|
3487
|
+
...openSession === void 0 ? {} : { openSession },
|
|
3488
|
+
...snapshot.serverNow === void 0 ? {} : { serverNow: snapshot.serverNow }
|
|
3489
|
+
}
|
|
3490
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3491
|
+
state.phase === "loading" && groups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: t("loading") }),
|
|
3492
|
+
groups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.empty") }),
|
|
3493
|
+
groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
3494
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3495
|
+
"button",
|
|
3496
|
+
{
|
|
3497
|
+
type: "button",
|
|
3498
|
+
className: "dsh-st-rail-head",
|
|
3499
|
+
onClick: () => setFolded((current) => ({ ...current, [group.id]: !current[group.id] })),
|
|
3500
|
+
children: [
|
|
3501
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dsh-st-rail-folder", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ClockIcon, { width: 16, height: 16 }) }),
|
|
3502
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dsh-st-rail-title", children: group.name })
|
|
3503
|
+
]
|
|
3504
|
+
}
|
|
3505
|
+
),
|
|
3506
|
+
folded[group.id] !== true && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3507
|
+
"button",
|
|
3508
|
+
{
|
|
3509
|
+
type: "button",
|
|
3510
|
+
className: "dsh-st-rail-session",
|
|
3511
|
+
onClick: () => openSession?.(session.id),
|
|
3512
|
+
children: [
|
|
3513
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: session.label }),
|
|
3514
|
+
session.running && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RunningStateDot, {})
|
|
3515
|
+
]
|
|
3516
|
+
},
|
|
3517
|
+
session.id
|
|
3518
|
+
))
|
|
3519
|
+
] }, group.id))
|
|
3520
|
+
] })
|
|
2961
3521
|
] });
|
|
2962
3522
|
}
|
|
2963
3523
|
function NativeScheduleShell({
|
|
@@ -2975,19 +3535,19 @@ function NativeScheduleShell({
|
|
|
2975
3535
|
wide
|
|
2976
3536
|
}) {
|
|
2977
3537
|
const Official = officialTree;
|
|
2978
|
-
const [tab, setTab] = (0,
|
|
3538
|
+
const [tab, setTab] = (0, import_react10.useState)(() => {
|
|
2979
3539
|
try {
|
|
2980
3540
|
return readNativeSidebarTab(window.localStorage.getItem(NATIVE_SIDEBAR_TAB_KEY));
|
|
2981
3541
|
} catch {
|
|
2982
3542
|
return "tasks";
|
|
2983
3543
|
}
|
|
2984
3544
|
});
|
|
2985
|
-
const extraTabs = (0,
|
|
3545
|
+
const extraTabs = (0, import_react10.useSyncExternalStore)(
|
|
2986
3546
|
tabRegistry?.subscribe ?? noopSubscribe,
|
|
2987
3547
|
() => tabRegistry?.getTabs() ?? EMPTY_EXTRA_TABS,
|
|
2988
3548
|
() => EMPTY_EXTRA_TABS
|
|
2989
3549
|
);
|
|
2990
|
-
const channelsReady = (0,
|
|
3550
|
+
const channelsReady = (0, import_react10.useSyncExternalStore)(
|
|
2991
3551
|
subscribeChannels ?? noopSubscribe,
|
|
2992
3552
|
() => {
|
|
2993
3553
|
try {
|
|
@@ -2999,25 +3559,25 @@ function NativeScheduleShell({
|
|
|
2999
3559
|
() => false
|
|
3000
3560
|
);
|
|
3001
3561
|
const currentId = useSessions?.((state) => state?.current ?? null);
|
|
3002
|
-
const automationState = (0,
|
|
3003
|
-
const scheduledIds = (0,
|
|
3004
|
-
const useFilteredSessions = (0,
|
|
3562
|
+
const automationState = (0, import_react10.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
3563
|
+
const scheduledIds = (0, import_react10.useMemo)(() => collectScheduledSessionIds(automationState.snapshot?.runs), [automationState.snapshot]);
|
|
3564
|
+
const useFilteredSessions = (0, import_react10.useCallback)((selector, eq) => {
|
|
3005
3565
|
if (useSessions === void 0) return selector({ ids: [], byId: {}, current: null });
|
|
3006
3566
|
return useSessions((state) => selector(filterTaskSessionState(state, scheduledIds)), eq);
|
|
3007
3567
|
}, [useSessions, scheduledIds]);
|
|
3008
|
-
const useFilteredWorkspaces = (0,
|
|
3568
|
+
const useFilteredWorkspaces = (0, import_react10.useCallback)((selector, eq) => {
|
|
3009
3569
|
if (useWorkspaces === void 0) return selector({ items: [], archivedSessionIds: [] });
|
|
3010
3570
|
return useWorkspaces((state) => selector(filterWorkspaceListState(state, scheduledIds)), eq);
|
|
3011
3571
|
}, [useWorkspaces, scheduledIds]);
|
|
3012
|
-
(0,
|
|
3572
|
+
(0, import_react10.useEffect)(() => {
|
|
3013
3573
|
try {
|
|
3014
3574
|
window.localStorage.setItem(NATIVE_SIDEBAR_TAB_KEY, tab);
|
|
3015
3575
|
} catch {
|
|
3016
3576
|
}
|
|
3017
3577
|
}, [tab]);
|
|
3018
|
-
const previousCurrentId = (0,
|
|
3019
|
-
const tabFollowReady = (0,
|
|
3020
|
-
(0,
|
|
3578
|
+
const previousCurrentId = (0, import_react10.useRef)(currentId);
|
|
3579
|
+
const tabFollowReady = (0, import_react10.useRef)(false);
|
|
3580
|
+
(0, import_react10.useEffect)(() => {
|
|
3021
3581
|
if (!tabFollowReady.current) {
|
|
3022
3582
|
tabFollowReady.current = true;
|
|
3023
3583
|
previousCurrentId.current = currentId;
|
|
@@ -3040,11 +3600,11 @@ function NativeScheduleShell({
|
|
|
3040
3600
|
};
|
|
3041
3601
|
const renderOfficial = (props) => {
|
|
3042
3602
|
if (Official === void 0) {
|
|
3043
|
-
return /* @__PURE__ */ (0,
|
|
3603
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NativeTaskRail, { t, ...openSession === void 0 ? {} : { openSession }, ...useSessions === void 0 ? {} : { useSessions: useFilteredSessions }, ...useWorkspaces === void 0 ? {} : { useWorkspaces } });
|
|
3044
3604
|
}
|
|
3045
|
-
return /* @__PURE__ */ (0,
|
|
3605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(OfficialTreeGuard, { fallback: (0, import_react10.createElement)(Official, rawOfficialProps), children: (0, import_react10.createElement)(Official, props) });
|
|
3046
3606
|
};
|
|
3047
|
-
if (wide === false) return /* @__PURE__ */ (0,
|
|
3607
|
+
if (wide === false) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: renderOfficial(filteredOfficialProps) });
|
|
3048
3608
|
const foreignTabs = extraTabs.filter((item) => item.id !== "schedule");
|
|
3049
3609
|
const visibleTab = resolveVisibleSidebarTab({
|
|
3050
3610
|
tab,
|
|
@@ -3052,15 +3612,15 @@ function NativeScheduleShell({
|
|
|
3052
3612
|
extraTabIds: ownedSidebarTabIds({ extraTabIds: foreignTabs.map((item) => item.id), channelsReady })
|
|
3053
3613
|
});
|
|
3054
3614
|
const hostedSchedule = extraTabs.find((item) => item.id === "schedule");
|
|
3055
|
-
const scheduleBody = hostedSchedule === void 0 ? /* @__PURE__ */ (0,
|
|
3056
|
-
return /* @__PURE__ */ (0,
|
|
3057
|
-
/* @__PURE__ */ (0,
|
|
3058
|
-
/* @__PURE__ */ (0,
|
|
3059
|
-
foreignTabs.map((item) => /* @__PURE__ */ (0,
|
|
3060
|
-
channelsReady && foreignTabs.every((item) => item.id !== "channels") && /* @__PURE__ */ (0,
|
|
3061
|
-
/* @__PURE__ */ (0,
|
|
3615
|
+
const scheduleBody = hostedSchedule === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.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 });
|
|
3616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-st-shell-rail", children: [
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-st-shell-tabs", role: "tablist", "aria-label": t("sidebar.tabs"), children: [
|
|
3618
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "tasks", className: visibleTab === "tasks" ? "is-on" : void 0, onClick: () => setTab("tasks"), children: t("sidebar.tasksTab") }),
|
|
3619
|
+
foreignTabs.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.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)),
|
|
3620
|
+
channelsReady && foreignTabs.every((item) => item.id !== "channels") && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "channels", className: visibleTab === "channels" ? "is-on" : void 0, onClick: () => setTab("channels"), children: t("sidebar.channelsTab") }),
|
|
3621
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "schedule", className: visibleTab === "schedule" ? "is-on" : void 0, onClick: () => setTab("schedule"), children: t("sidebar.tab") })
|
|
3062
3622
|
] }),
|
|
3063
|
-
visibleTab === "schedule" ? /* @__PURE__ */ (0,
|
|
3623
|
+
visibleTab === "schedule" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-shell-body", children: scheduleBody }) : foreignTabs.find((item) => item.id === visibleTab) !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsx)("div", { className: "dsh-st-shell-body", children: renderSlot?.("sidebar.channels", { ...hostProps ?? {}, openSession, open: openSession, useSessions, wide: true, skin: "native" }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-official-tree", children: renderOfficial(filteredOfficialProps) })
|
|
3064
3624
|
] });
|
|
3065
3625
|
}
|
|
3066
3626
|
function NativeTaskRail({
|
|
@@ -3072,10 +3632,10 @@ function NativeTaskRail({
|
|
|
3072
3632
|
const snap = useSessions === void 0 ? { ids: [], byId: {}, current: null } : useSessions((state) => state ?? { ids: [], byId: {}, current: null });
|
|
3073
3633
|
const workspaces = useWorkspaces === void 0 ? void 0 : useWorkspaces((state) => state ?? { items: [], archivedSessionIds: [] });
|
|
3074
3634
|
const groups = groupNativeTaskSessions(snap, workspaces, t("sidebar.ungrouped"));
|
|
3075
|
-
if (groups.length === 0) return /* @__PURE__ */ (0,
|
|
3076
|
-
return /* @__PURE__ */ (0,
|
|
3077
|
-
/* @__PURE__ */ (0,
|
|
3078
|
-
group.sessions.map((item) => /* @__PURE__ */ (0,
|
|
3635
|
+
if (groups.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.tasksEmpty") });
|
|
3636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-head is-static", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dsh-st-rail-title", children: group.label }) }),
|
|
3638
|
+
group.sessions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3079
3639
|
"button",
|
|
3080
3640
|
{
|
|
3081
3641
|
type: "button",
|
|
@@ -3083,7 +3643,7 @@ function NativeTaskRail({
|
|
|
3083
3643
|
onClick: () => {
|
|
3084
3644
|
if (item.id !== void 0) openSession?.(item.id);
|
|
3085
3645
|
},
|
|
3086
|
-
children: /* @__PURE__ */ (0,
|
|
3646
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: item.title || item.id })
|
|
3087
3647
|
},
|
|
3088
3648
|
item.id
|
|
3089
3649
|
))
|
|
@@ -3121,16 +3681,33 @@ var CSS_TEXT = `
|
|
|
3121
3681
|
.dsh-st-tabs>button{padding:8px 0;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer}
|
|
3122
3682
|
.dsh-st-tabs>button.is-on{border-bottom-color:currentColor;color:var(--dsw-alias-label-primary);font-weight:650}
|
|
3123
3683
|
.dsh-st-dropdown{position:relative;min-width:0}
|
|
3124
|
-
.dsh-st-sort{margin-left:auto}
|
|
3125
|
-
.dsh-st-dropdown-btn{display:inline-flex;align-items:center;gap:4px;max-width:220px;height:28px;padding:0 10px;border:0;border-radius:999px;background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.14));color:var(--dsw-alias-label-primary,inherit);font:13px
|
|
3684
|
+
.dsh-st-sort-wrap{display:flex;align-items:center;gap:6px;margin-left:auto}
|
|
3685
|
+
.dsh-st-dropdown-btn{display:inline-flex;align-items:center;gap:4px;max-width:220px;height:28px;padding:0 10px;border:0;border-radius:999px;background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.14));color:var(--dsw-alias-label-primary,inherit);font-family:inherit;font-size:13px;line-height:20px;cursor:pointer;white-space:nowrap}
|
|
3126
3686
|
.dsh-st-dropdown-btn:hover,.dsh-st-dropdown-btn.is-open{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.18))}
|
|
3127
3687
|
.dsh-st-dropdown-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3128
3688
|
.dsh-st-dropdown-chevron{flex:none;transition:transform .16s ease;transform:rotate(90deg)}
|
|
3129
3689
|
.dsh-st-dropdown-btn.is-open .dsh-st-dropdown-chevron{transform:rotate(-90deg)}
|
|
3130
|
-
.dsh-st-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:30;width:180px;max-height:260px;overflow:auto;padding:6px;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.12));border-radius:12px;background:var(--dsw-alias-bg-layer-3,#303033);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.32))}
|
|
3131
|
-
.dsh-st-dropdown-menu
|
|
3132
|
-
.dsh-st-dropdown-menu
|
|
3133
|
-
.dsh-st-dropdown-
|
|
3690
|
+
.dsh-st-dropdown-menu{box-sizing:border-box;position:absolute;right:0;top:calc(100% + 6px);z-index:30;width:max-content;min-width:180px;max-width:calc(100vw - 16px);max-height:260px;overflow-x:hidden;overflow-y:auto;padding:6px;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.12));border-radius:12px;background:var(--dsw-alias-bg-layer-3,#303033);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.32))}
|
|
3691
|
+
.dsh-st-dropdown-menu.is-float{position:fixed;right:auto;top:auto;z-index:1200}
|
|
3692
|
+
.dsh-st-dropdown-menu.dsh-st-dropdown-sort{min-width:0;transition:width .12s ease}
|
|
3693
|
+
.dsh-st-dropdown-row{box-sizing:border-box;display:flex;align-items:center;justify-content:flex-start;gap:8px;width:100%;min-height:36px;padding:6px 10px;border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary,inherit);font-family:inherit;font-size:13px;line-height:20px;cursor:pointer;text-align:left}
|
|
3694
|
+
.dsh-st-dropdown-label-cell{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3695
|
+
.dsh-st-dropdown-row:not(.has-trailing) .dsh-st-dropdown-label-cell{flex:1}
|
|
3696
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-label-cell{flex:none}
|
|
3697
|
+
.dsh-st-dropdown-spacer{min-width:0}
|
|
3698
|
+
.dsh-st-dropdown-row:not(.has-trailing) .dsh-st-dropdown-spacer{flex:0 0 0}
|
|
3699
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-spacer{flex:1 1 auto}
|
|
3700
|
+
.dsh-st-dropdown-row.has-trailing{gap:0}
|
|
3701
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-label-cell{margin-right:8px}
|
|
3702
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-default{margin-right:4px}
|
|
3703
|
+
.dsh-st-dropdown-check{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex:none}
|
|
3704
|
+
.dsh-st-dropdown-row:hover,.dsh-st-dropdown-row.is-selected{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.08));color:var(--dsw-alias-label-primary,inherit)}
|
|
3705
|
+
.dsh-st-dropdown-default{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;width:auto;min-width:0;height:22px;padding:0 6px;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.14));border-radius:999px;background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.14));color:var(--dsw-alias-label-primary,inherit);font-family:inherit;font-size:12px;line-height:18px;cursor:pointer;white-space:nowrap;overflow:hidden}
|
|
3706
|
+
.dsh-st-dropdown-default:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.2))}
|
|
3707
|
+
.dsh-st-dropdown-default:disabled,.dsh-st-dropdown-default.is-on{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.08);color:var(--dsw-alias-label-tertiary,#8b8f98);cursor:default}
|
|
3708
|
+
.dsh-st-dropdown.dsh-st-dropdown-compact .dsh-st-dropdown-btn{font-size:12px;line-height:18px}
|
|
3709
|
+
.dsh-st-dropdown-menu.dsh-st-dropdown-compact .dsh-st-dropdown-row{font-size:12px;line-height:18px}
|
|
3710
|
+
.dsh-st-dropdown-menu.dsh-st-dropdown-compact .dsh-st-dropdown-default{font-size:11px;line-height:16px}
|
|
3134
3711
|
.dsh-st-sort-tick{width:16px;height:16px;flex:none}
|
|
3135
3712
|
.dsh-st-filters{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-left:auto}
|
|
3136
3713
|
.dsh-st-filters>button{height:28px;padding:0 10px;border:0;border-radius:999px;background:rgba(255,255,255,.06);color:inherit;font-size:12px}
|
|
@@ -3226,6 +3803,29 @@ var CSS_TEXT = `
|
|
|
3226
3803
|
.dsh-st-menu-split{height:1px;margin:6px 8px;background:rgba(255,255,255,.08)}
|
|
3227
3804
|
.dsh-st-subdialog{margin:0 0 12px;padding:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:rgba(255,255,255,.03)}
|
|
3228
3805
|
.dsh-st-subdialog>strong{display:block;margin:0 0 8px;font-size:13px}
|
|
3806
|
+
.dsh-st-rail-views{display:flex;flex:none;gap:3px;margin:16px 8px 10px;padding:2px;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.1));border-radius:9px;background:var(--dsw-alias-bg-layer-2,rgba(255,255,255,.035))}
|
|
3807
|
+
.dsh-st-rail-views button{flex:1;appearance:none;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--dsw-alias-label-secondary,#9ca3af);padding:3px 7px;font-size:12px;line-height:18px;cursor:pointer;transition:background .16s ease,border-color .16s ease,color .16s ease,box-shadow .16s ease}
|
|
3808
|
+
.dsh-st-rail-views button:hover{color:var(--dsw-alias-label-primary,inherit)}
|
|
3809
|
+
.dsh-st-rail-views button.is-on{border-color:var(--dsw-alias-border-l2,rgba(255,255,255,.18));background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.15));color:var(--dsw-alias-label-primary,#fff);font-weight:650;box-shadow:0 1px 3px rgba(0,0,0,.34),inset 0 1px rgba(255,255,255,.06)}
|
|
3810
|
+
.dsh-st-overview{display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto;padding:2px 8px 14px}
|
|
3811
|
+
.dsh-st-overview-head{display:flex;flex:none;align-items:center;justify-content:space-between;gap:8px;height:36px;min-height:36px;margin-bottom:4px;padding:6px 0}
|
|
3812
|
+
.dsh-st-overview-title{display:flex;align-items:baseline;min-width:0;gap:6px;color:var(--dsw-alias-label-tertiary,#81858C)}
|
|
3813
|
+
.dsh-st-overview-title strong{font-size:14px;font-weight:400;line-height:20px}
|
|
3814
|
+
.dsh-st-overview-title span{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.1));color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:11px;line-height:18px}
|
|
3815
|
+
.dsh-st-overview-sort{display:flex;align-items:center}
|
|
3816
|
+
.dsh-st-overview-row{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto 12px;align-items:center;gap:8px;width:100%;min-height:88px;margin:0 0 8px;padding:9px 10px;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.1));border-radius:9px;background:var(--dsw-alias-bg-layer-2,rgba(255,255,255,.035));color:var(--dsw-alias-label-primary,inherit);text-align:left;cursor:pointer;box-shadow:inset 0 1px rgba(255,255,255,.025);transition:background .14s ease,border-color .14s ease}
|
|
3817
|
+
.dsh-st-overview-row:hover:not(:disabled){border-color:var(--dsw-alias-border-inverted,rgba(255,255,255,.18));background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.06))}
|
|
3818
|
+
.dsh-st-overview-row:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4c8dff);outline-offset:2px}
|
|
3819
|
+
.dsh-st-overview-row:disabled{cursor:default}
|
|
3820
|
+
.dsh-st-overview-copy{display:flex;flex:1;min-width:0;flex-direction:column;gap:4px}
|
|
3821
|
+
.dsh-st-overview-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;line-height:18px;font-weight:580}
|
|
3822
|
+
.dsh-st-overview-status{display:inline-flex;align-self:flex-start;align-items:center;gap:4px;padding:2px 6px;border-radius:999px;background:rgba(50,205,143,.12);color:#45d483;font-size:11px;line-height:16px}
|
|
3823
|
+
.dsh-st-overview-row.is-paused .dsh-st-overview-status{background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.08));color:var(--dsw-alias-label-secondary,#aeb3bd)}
|
|
3824
|
+
.dsh-st-overview-schedule{display:inline-flex;align-items:center;gap:5px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:12px;line-height:16px}
|
|
3825
|
+
.dsh-st-overview-next{display:flex;flex:none;min-width:50px;flex-direction:column;align-items:flex-end;gap:2px;color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:10px;line-height:14px}
|
|
3826
|
+
.dsh-st-overview-next strong{color:var(--dsw-alias-label-secondary,#b6bac2);font-size:12px;font-weight:600;line-height:16px;white-space:nowrap}
|
|
3827
|
+
.dsh-st-overview-row:not(.is-paused) .dsh-st-overview-next strong{color:#45d483}
|
|
3828
|
+
.dsh-st-overview-chevron{flex:none;color:var(--dsw-alias-label-tertiary,#8b8f98)}
|
|
3229
3829
|
.dsh-st-rail{box-sizing:border-box;height:100%;overflow:auto;padding:4px var(--dsh-sidebar-inline-padding,12px) 18px 8px;color:inherit;scrollbar-gutter:stable}
|
|
3230
3830
|
.dsh-st-rail-empty{padding:16px 10px;color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:12px}
|
|
3231
3831
|
.dsh-st-rail-group{margin:0 0 8px}
|
|
@@ -3238,14 +3838,26 @@ var CSS_TEXT = `
|
|
|
3238
3838
|
.dsh-st-rail-session span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3239
3839
|
.dsh-st-rail-dot{width:6px;height:6px;margin-left:auto;border-radius:50%;background:#34c759;flex:none}.dsh-st-run-dot{flex:none;color:var(--dsw-static-deepseek-450,#4c8dff)}.dsh-st-run-dot-cell{fill:currentColor;opacity:.15;animation:dsh-st-run-chase 1s infinite}@keyframes dsh-st-run-chase{0%,12.4%{opacity:1}12.5%,24.9%{opacity:.6}25%,37.4%{opacity:.35}37.5%,100%{opacity:.15}}
|
|
3240
3840
|
.dsh-st-shell-rail{display:flex;flex-direction:column;min-height:0;flex:1;height:100%;overflow:hidden}
|
|
3241
|
-
.dsh-st-shell-tabs{display:flex;flex:none;gap:18px;padding:
|
|
3242
|
-
.dsh-st-shell-tabs button{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-secondary,#8b8f98);padding:8px 0;font-size:13px;cursor:pointer}
|
|
3841
|
+
.dsh-st-shell-tabs{display:flex;flex:none;gap:18px;padding:6px 12px 0;border-bottom:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.08))}
|
|
3842
|
+
.dsh-st-shell-tabs button{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-secondary,#8b8f98);padding:8px 0 9px;font-size:13px;cursor:pointer}
|
|
3243
3843
|
.dsh-st-shell-tabs button.is-on{color:var(--dsw-alias-label-primary,inherit);box-shadow:inset 0 -2px 0 currentColor}
|
|
3244
3844
|
.dsh-st-shell-body{display:flex;min-height:0;flex:1;overflow:hidden}
|
|
3245
3845
|
.dsh-st-shell-body>*{min-width:0;flex:1}.dsh-st-official-tree{display:flex;min-height:0;flex:1;overflow:hidden}.dsh-st-official-tree>*{min-width:0;flex:1}
|
|
3246
3846
|
.dsh-st-rail-head.is-static{cursor:default;font-weight:600}
|
|
3247
3847
|
.dsh-st-rail-session.is-on{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}
|
|
3248
3848
|
.dsh-st-n,.dsh-st-n *{box-sizing:border-box}.dsh-st-n{box-sizing:border-box;display:flex;flex:1;min-width:0;max-width:100%;min-height:0;flex-direction:column;padding:0;padding-right:var(--dsh-sidebar-inline-padding,12px);color:var(--dsw-alias-label-primary,inherit);font:14px/20px inherit;overflow:hidden}.dsh-st-n-toolbar{box-sizing:border-box;flex:none;height:36px;margin:2px -4px 4px 0;padding-left:4px;display:flex;justify-content:flex-end;align-items:center;gap:4px;overflow:visible;position:relative;z-index:2;color:var(--dsw-alias-label-tertiary,#81858C);border-radius:12px}.dsh-st-n-head-label{white-space:nowrap;min-width:0;max-width:45%;flex:none;line-height:20px;font-size:14px;overflow:hidden;transition:max-width .18s var(--ds-ease-in-out,ease),margin-right .18s var(--ds-ease-in-out,ease),opacity .12s var(--ds-ease-in-out,ease),transform .18s var(--ds-ease-in-out,ease),visibility 0s linear}.dsh-st-n-toolbar.is-search .dsh-st-n-head-label{opacity:0;visibility:hidden;max-width:0;margin-right:-4px;transform:translate(-4px);transition-delay:0s,0s,0s,0s,.18s}.dsh-st-n-search-slot{box-sizing:border-box;min-width:28px;max-width:28px;transition:max-width .18s var(--ds-ease-in-out,ease);flex:none;align-items:center;margin-left:auto;display:flex;position:relative;z-index:2}.dsh-st-n-toolbar.is-search .dsh-st-n-search-slot{flex:1;min-width:0;max-width:100%}.dsh-st-n-search{box-sizing:border-box;cursor:text;width:100%;height:28px;color:var(--dsw-alias-label-secondary);transition:width .18s var(--ds-ease-in-out,ease),padding .18s var(--ds-ease-in-out,ease),border-color .18s var(--ds-ease-in-out,ease);background:transparent;border:none;border-radius:50%;flex:none;align-items:center;margin:0;padding:0;display:flex;overflow:hidden}.dsh-st-n-toolbar.is-search .dsh-st-n-search{border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,.10));width:calc(100% + 4px);height:30px;border-radius:10px;margin-inline:-2px;padding:0 4px 0 0}.dsh-st-n-search-btn,.dsh-st-n-head-btn{cursor:pointer;width:28px;height:28px;min-width:28px;min-height:28px;position:relative;z-index:1;color:var(--dsw-alias-label-secondary);background:transparent;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.dsh-st-n-toolbar.is-search .dsh-st-n-search-btn{width:28px;height:30px}.dsh-st-n-search-btn:hover,.dsh-st-n-head-btn:hover,.dsh-st-n-head-btn.is-on{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06));color:var(--dsw-alias-label-primary,inherit)}.dsh-st-n-toolbar.is-search .dsh-st-n-search-btn:hover{background:transparent}.dsh-st-n-head-acts{opacity:1;visibility:visible;max-width:32px;transition:max-width .18s var(--ds-ease-in-out,ease),opacity .12s var(--ds-ease-in-out,ease),transform .18s var(--ds-ease-in-out,ease),visibility 0s linear;flex:none;align-items:center;gap:4px;display:flex;overflow:visible;position:relative}.dsh-st-n-toolbar.is-search .dsh-st-n-head-acts{opacity:0;visibility:hidden;pointer-events:none;max-width:0;transform:translate(4px);transition-delay:0s,0s,0s,.18s}.dsh-st-n-head-filter{position:relative}.dsh-st-n-search-input{display:none;opacity:0;pointer-events:none;width:0;min-width:0;flex:none;color:var(--dsw-alias-label-primary,inherit);transition:opacity .12s var(--ds-ease-in-out,ease);background:transparent;border:none;outline:none;flex:1;font-size:13px;line-height:18px}.dsh-st-n-toolbar.is-search .dsh-st-n-search-input{display:block;opacity:1;pointer-events:auto;margin-left:-2px;width:auto;flex:1;min-width:0}.dsh-st-n-search-input::placeholder{color:var(--dsw-alias-label-tertiary,#81858C)}.dsh-st-n-search-clear{cursor:pointer;width:24px;height:24px;color:var(--dsw-alias-label-secondary);background:transparent;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.dsh-st-n-search-clear:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}@media (prefers-reduced-motion:reduce){.dsh-st-n-head-label,.dsh-st-n-search-slot,.dsh-st-n-search,.dsh-st-n-head-acts,.dsh-st-n-search-input{transition:none}}.dsh-st-n-filter-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:30;min-width:196px;padding:8px 6px;border:1px solid var(--dsw-alias-border-inverted,rgba(255,255,255,.12));border-radius:12px;background:var(--dsw-specific-menu,#1c2128);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.36))}.dsh-st-n-filter-label{padding:6px 10px 4px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary,#81858C)}.dsh-st-n-filter-split{height:1px;margin:6px 8px;background:var(--dsw-alias-border-l2,rgba(255,255,255,.1))}.dsh-st-n-filter-menu button{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:36px;padding:6px 10px;border:0;border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary,inherit);font:14px/20px inherit;cursor:pointer;text-align:left}.dsh-st-n-filter-menu button:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}.dsh-st-n-filter-tick{width:16px;height:16px;flex:none}.dsh-st-n-tree{flex:1;min-width:0;max-width:100%;min-height:0;overflow-x:hidden;overflow-y:auto;padding:0 0 16px;user-select:none}.dsh-st-n-empty{padding:14px 8px;color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:12px}.dsh-st-n-group{min-width:0;max-width:100%}.dsh-st-n-row,.dsh-st-n-sess{display:flex;align-items:center;max-width:100%;border-radius:8px;padding:0 8px 0 12px;cursor:pointer;border:0;background:transparent;color:var(--dsw-alias-label-primary,inherit);text-align:left;font:14px/20px inherit}.dsh-st-n-row{height:34px;gap:6px}.dsh-st-n-sess{height:32px;gap:0;position:relative;width:100%;appearance:none}.dsh-st-n-row:hover,.dsh-st-n-sess:hover,.dsh-st-n-sess.is-on,.dsh-st-n-sess.is-menu{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}.dsh-st-n-slot{flex:none;width:16px;height:20px;display:inline-flex;align-items:center;justify-content:center}.dsh-st-n-folder{color:var(--dsw-alias-label-secondary,#9ca39f)}.dsh-st-n-lead{color:var(--dsw-alias-label-tertiary,#81858C)}.dsh-st-n-corner{color:var(--dsw-alias-label-caption,#ADB2B8);width:8px}.dsh-st-n-title{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px}.dsh-st-n-sess .dsh-st-n-title{margin:0 6px 0 4px}.dsh-st-n-time{flex:none;font-size:12px;line-height:20px;color:var(--dsw-alias-label-tertiary,#81858C);white-space:nowrap}.dsh-st-n-acts{flex:none;display:none;align-items:center;gap:12px}.dsh-st-n-row:hover .dsh-st-n-acts,.dsh-st-n-sess:hover .dsh-st-n-acts,.dsh-st-n-row.is-menu .dsh-st-n-acts,.dsh-st-n-sess.is-menu .dsh-st-n-acts{display:inline-flex}.dsh-st-n-sess:hover .dsh-st-n-time,.dsh-st-n-sess.is-menu .dsh-st-n-time{display:none}.dsh-st-n-ico{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border:0;border-radius:4px;background:transparent;color:var(--dsw-alias-label-tertiary,#81858C);padding:0;cursor:pointer}.dsh-st-n-ico:hover{color:var(--dsw-alias-label-primary,inherit)}.dsh-st-n-menu.is-float{position:fixed;z-index:4000;right:auto;top:auto}.dsh-st-n-menu{position:absolute;right:8px;top:calc(100% + 4px);z-index:1100;min-width:218px;max-width:360px;box-sizing:border-box;padding:4px;display:flex;flex-direction:column;border:1px solid var(--dsw-alias-border-inverted,rgba(255,255,255,.12));border-radius:12px;background:var(--dsw-specific-menu,#1c2128);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.36))}.dsh-st-n-menu button{display:flex;align-items:center;gap:8px;width:100%;min-height:40px;padding:8px 10px;border:0;border-radius:10px;background:transparent;cursor:pointer;font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary,inherit);text-align:left}.dsh-st-n-menu button:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}.dsh-st-n-mi{display:inline-flex;flex:none;width:16px;height:16px;align-items:center;justify-content:center;color:var(--dsw-alias-label-tertiary,#81858C)}.dsh-st-n-menu button.danger{color:var(--dsw-alias-state-error-primary,#f85149)}.dsh-st-n-menu button.danger .dsh-st-n-mi{color:inherit}.dsh-st-n-menu button.danger:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(248,81,73,.12))}.dsh-st-n-hover{position:fixed;z-index:4100;min-width:188px;max-width:280px;padding:12px 14px;border:1px solid var(--dsw-alias-border-inverted,rgba(255,255,255,.12));border-radius:12px;background:var(--dsw-specific-menu,#1c2128);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.36));color:var(--dsw-alias-label-primary,inherit)}.dsh-st-n-hover-title{font-size:14px;line-height:20px;font-weight:500}.dsh-st-n-hover-time{margin-top:4px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary,#81858C)}.dsh-st-n-hover-state{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#9ca39f)}.dsh-st-n-hover-dot{width:8px;height:8px;border-radius:50%;background:#34c759;flex:none}.dsh-st-n-hover-dot.is-run{background:#4c8dff}.dsh-st-n-rename{flex:1;min-width:0;margin:0 6px 0 4px;border:1px solid var(--dsw-alias-border-l2);border-radius:4px;background:var(--dsw-alias-button-elevated-fill,rgba(255,255,255,.04));color:inherit;font:inherit;padding:0 2px}
|
|
3849
|
+
.dsh-st-n-row.is-menu{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}
|
|
3850
|
+
.dsh-st-overview-sort .dsh-st-n-head-btn.is-open{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06));color:var(--dsw-alias-label-primary,inherit)}
|
|
3851
|
+
.dsh-st-n-row[aria-expanded="true"].has-current-session .dsh-st-n-folder{color:var(--dsw-static-deepseek-450,#4c8dff)}
|
|
3852
|
+
.dsh-st-n-sess:focus{outline:none}.dsh-st-n-sess:focus-visible:not(.is-on){box-shadow:inset 0 0 0 2px var(--dsw-alias-state-business-primary,#4c8dff)}
|
|
3853
|
+
.dsh-st-n-row>.dsh-st-n-acts{display:inline-flex;opacity:0;visibility:hidden;pointer-events:none}
|
|
3854
|
+
.dsh-st-n-row:hover>.dsh-st-n-acts,.dsh-st-n-row:focus-within>.dsh-st-n-acts,.dsh-st-n-row.is-menu>.dsh-st-n-acts{opacity:1;visibility:visible;pointer-events:auto}
|
|
3855
|
+
.dsh-st-n-dialog-actions{display:flex;justify-content:flex-end;gap:8px}
|
|
3856
|
+
.dsh-st-n-dialog-copy{margin:0;color:var(--dsw-alias-label-secondary);font-size:14px;line-height:22px}
|
|
3857
|
+
.dsh-st-n-dialog-status{margin-top:12px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}
|
|
3858
|
+
.dsh-st-n-dialog-error{margin-top:12px;color:var(--dsw-alias-state-error-primary,#f85149);font-size:13px;line-height:20px}
|
|
3859
|
+
.dsh-st-n-danger-button{color:var(--dsw-alias-state-error-primary,#f85149)!important}
|
|
3860
|
+
.dsh-st-n-danger-button:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(248,81,73,.12))!important}
|
|
3249
3861
|
`;
|
|
3250
3862
|
function installStyles() {
|
|
3251
3863
|
const existing = document.getElementById(STYLE_ID);
|
|
@@ -3262,10 +3874,87 @@ function installStyles() {
|
|
|
3262
3874
|
};
|
|
3263
3875
|
}
|
|
3264
3876
|
|
|
3877
|
+
// src/client/settings-navigation.ts
|
|
3878
|
+
function pickSettingsSectionButton(buttons, labels) {
|
|
3879
|
+
for (const label of labels) {
|
|
3880
|
+
const target = label.trim();
|
|
3881
|
+
if (target === "") continue;
|
|
3882
|
+
const match = buttons.find((button) => button.textContent?.replace(/\s+/g, " ").trim() === target);
|
|
3883
|
+
if (match !== void 0) return match;
|
|
3884
|
+
}
|
|
3885
|
+
return void 0;
|
|
3886
|
+
}
|
|
3887
|
+
function pickSettingsLauncher(buttons) {
|
|
3888
|
+
const named = buttons.find((button) => {
|
|
3889
|
+
const label = `${button.textContent ?? ""} ${button.getAttribute("aria-label") ?? ""}`.trim();
|
|
3890
|
+
return /(^|\s)(设置|settings)(\s|$)/i.test(label);
|
|
3891
|
+
});
|
|
3892
|
+
return named ?? (buttons.length === 1 ? buttons[0] : void 0);
|
|
3893
|
+
}
|
|
3894
|
+
var cancelPendingNavigation;
|
|
3895
|
+
function openSettingsSection(labels, onSelected, onMissing) {
|
|
3896
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
3897
|
+
onMissing?.();
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
const launchers = [...document.querySelectorAll('button[aria-haspopup="dialog"]')];
|
|
3901
|
+
const launcher = pickSettingsLauncher(launchers);
|
|
3902
|
+
const dialogOpen = document.querySelector('[role="dialog"]') !== null;
|
|
3903
|
+
if (!dialogOpen && launcher === void 0) {
|
|
3904
|
+
onMissing?.();
|
|
3905
|
+
return;
|
|
3906
|
+
}
|
|
3907
|
+
cancelPendingNavigation?.();
|
|
3908
|
+
if (!dialogOpen) launcher?.click();
|
|
3909
|
+
let frame;
|
|
3910
|
+
let finished = false;
|
|
3911
|
+
const observer = new MutationObserver(() => {
|
|
3912
|
+
schedule();
|
|
3913
|
+
});
|
|
3914
|
+
const cleanup = () => {
|
|
3915
|
+
if (finished) return;
|
|
3916
|
+
finished = true;
|
|
3917
|
+
observer.disconnect();
|
|
3918
|
+
window.clearTimeout(timeout);
|
|
3919
|
+
if (frame !== void 0) window.cancelAnimationFrame(frame);
|
|
3920
|
+
if (cancelPendingNavigation === cleanup) cancelPendingNavigation = void 0;
|
|
3921
|
+
};
|
|
3922
|
+
const select = () => {
|
|
3923
|
+
const buttons = [...document.querySelectorAll('[role="dialog"] nav button')];
|
|
3924
|
+
const target = pickSettingsSectionButton(buttons, labels);
|
|
3925
|
+
if (target === void 0) return false;
|
|
3926
|
+
cleanup();
|
|
3927
|
+
target.click();
|
|
3928
|
+
onSelected?.();
|
|
3929
|
+
return true;
|
|
3930
|
+
};
|
|
3931
|
+
const schedule = () => {
|
|
3932
|
+
if (finished || frame !== void 0) return;
|
|
3933
|
+
frame = window.requestAnimationFrame(() => {
|
|
3934
|
+
frame = void 0;
|
|
3935
|
+
select();
|
|
3936
|
+
});
|
|
3937
|
+
};
|
|
3938
|
+
const timeout = window.setTimeout(() => {
|
|
3939
|
+
if (select()) return;
|
|
3940
|
+
cleanup();
|
|
3941
|
+
onMissing?.();
|
|
3942
|
+
}, 1500);
|
|
3943
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
3944
|
+
cancelPendingNavigation = cleanup;
|
|
3945
|
+
schedule();
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3265
3948
|
// src/client/index.ts
|
|
3266
3949
|
var name = "dsh-automation-client";
|
|
3267
3950
|
var inject = ["slots", "locale", "connection", "sessions"];
|
|
3268
3951
|
var SETTINGS_CLOCK_SVG = '<svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true" data-dsh-schedule-icon="1"><path fill="currentColor" d="M8 1.15A6.85 6.85 0 1 0 8 14.85 6.85 6.85 0 0 0 8 1.15Zm0 1.4a5.45 5.45 0 1 1 0 10.9 5.45 5.45 0 0 1 0-10.9Z"/><path fill="currentColor" d="M8.62 4.35H7.28v4.2l3.02 1.78.67-1.13-2.35-1.39V4.35Z"/></svg>';
|
|
3952
|
+
function isSessionSelector(value) {
|
|
3953
|
+
return typeof value === "function";
|
|
3954
|
+
}
|
|
3955
|
+
function isWorkspaceSelector(value) {
|
|
3956
|
+
return typeof value === "function";
|
|
3957
|
+
}
|
|
3269
3958
|
function installSettingsNavIcon(labels) {
|
|
3270
3959
|
const wanted = new Set(labels().map((item) => item.trim()).filter((item) => item !== ""));
|
|
3271
3960
|
const applyButton = (button) => {
|
|
@@ -3311,7 +4000,7 @@ function apply(ctx) {
|
|
|
3311
4000
|
label: () => t("tab"),
|
|
3312
4001
|
icon: "schedule"
|
|
3313
4002
|
}, function ScheduledTasksSettings(props) {
|
|
3314
|
-
return (0,
|
|
4003
|
+
return (0, import_react11.createElement)(AutomationView, { t, permissionT, modelT, runtime, ...props.close === void 0 ? {} : { closeSettings: props.close } });
|
|
3315
4004
|
}));
|
|
3316
4005
|
ctx.slots.inject("sidebar.schedule", () => ctx.slots.register({
|
|
3317
4006
|
name: "sidebar.schedule",
|
|
@@ -3320,10 +4009,12 @@ function apply(ctx) {
|
|
|
3320
4009
|
locale: NS,
|
|
3321
4010
|
label: () => t("sidebar.tab")
|
|
3322
4011
|
}, function AutomationScheduleRail(props) {
|
|
3323
|
-
return (0,
|
|
4012
|
+
return (0, import_react11.createElement)(ScheduleRail, {
|
|
3324
4013
|
t,
|
|
3325
4014
|
runtime,
|
|
3326
|
-
openSession: createScheduledSessionOpener(ctx, runtime, props.openSession)
|
|
4015
|
+
openSession: createScheduledSessionOpener(ctx, runtime, props.openSession),
|
|
4016
|
+
...props.view === void 0 ? {} : { view: props.view },
|
|
4017
|
+
...props.showViewSwitch === void 0 ? {} : { showViewSwitch: props.showViewSwitch }
|
|
3327
4018
|
});
|
|
3328
4019
|
}));
|
|
3329
4020
|
ctx.slots.inject("sidebar.workspaces", () => {
|
|
@@ -3366,16 +4057,25 @@ function apply(ctx) {
|
|
|
3366
4057
|
render: (props) => {
|
|
3367
4058
|
const hostOpen = typeof props.openSession === "function" ? props.openSession : typeof props.open === "function" ? props.open : openSession;
|
|
3368
4059
|
const opener = createScheduledSessionOpener(ctx, runtime, hostOpen);
|
|
3369
|
-
return (0,
|
|
4060
|
+
return (0, import_react11.createElement)(NativeScheduleSessionList, {
|
|
3370
4061
|
t,
|
|
3371
4062
|
runtime,
|
|
3372
4063
|
openSession: opener,
|
|
3373
|
-
...
|
|
3374
|
-
...
|
|
4064
|
+
...isSessionSelector(props.useSessions) ? { useSessions: props.useSessions } : {},
|
|
4065
|
+
...isWorkspaceSelector(props.useWorkspaces) ? { useWorkspaces: props.useWorkspaces } : {},
|
|
3375
4066
|
...typeof props.renameSession === "function" ? { renameSession: props.renameSession } : {},
|
|
3376
4067
|
...typeof props.archiveSession === "function" ? { archiveSession: props.archiveSession } : {},
|
|
3377
4068
|
...typeof props.deleteSession === "function" ? { deleteSession: props.deleteSession } : {},
|
|
3378
|
-
...typeof props.forkSession === "function" ? { forkSession: props.forkSession } : {}
|
|
4069
|
+
...typeof props.forkSession === "function" ? { forkSession: props.forkSession } : {},
|
|
4070
|
+
openTaskSettings: (request) => {
|
|
4071
|
+
requestAutomationTaskSettings(request);
|
|
4072
|
+
openSettingsSection(
|
|
4073
|
+
[t("tab"), "Scheduled tasks", "\u5B9A\u65F6\u4EFB\u52A1"],
|
|
4074
|
+
() => {
|
|
4075
|
+
requestAutomationTaskSettings(request);
|
|
4076
|
+
}
|
|
4077
|
+
);
|
|
4078
|
+
}
|
|
3379
4079
|
});
|
|
3380
4080
|
}
|
|
3381
4081
|
});
|
|
@@ -3407,7 +4107,7 @@ function apply(ctx) {
|
|
|
3407
4107
|
try {
|
|
3408
4108
|
let AutomationNativeWorkspaceShell2 = function(innerProps) {
|
|
3409
4109
|
const openSession = createScheduledSessionOpener(ctx, runtime, innerProps.openSession ?? innerProps.open);
|
|
3410
|
-
return (0,
|
|
4110
|
+
return (0, import_react11.createElement)(NativeScheduleShell, {
|
|
3411
4111
|
t,
|
|
3412
4112
|
runtime,
|
|
3413
4113
|
hostProps: innerProps,
|
|
@@ -3493,7 +4193,7 @@ function createScheduledSessionOpener(ctx, runtime, hostOpen) {
|
|
|
3493
4193
|
};
|
|
3494
4194
|
}
|
|
3495
4195
|
function PrefillBridge(props) {
|
|
3496
|
-
(0,
|
|
4196
|
+
(0, import_react11.useEffect)(() => {
|
|
3497
4197
|
const applyPrefill = (text) => {
|
|
3498
4198
|
if (text === null || text === "") return;
|
|
3499
4199
|
if (props.inputActions !== void 0) {
|