@michengai/dsh-automation 0.1.18 → 0.1.20
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/docs/03-/346/212/200/346/234/257/346/236/266/346/236/204/01-/350/260/203/345/272/246/344/270/216/346/211/247/350/241/214/346/250/241/345/236/213.md +3 -3
- package/lib/client.js +1141 -368
- package/lib/client.js.map +4 -4
- package/lib/index.js +54 -14
- package/lib/types/client/ScheduleRail.d.ts +4 -1
- package/lib/types/client/delete-confirmation.d.ts +11 -0
- package/lib/types/client/dropdown-menu.d.ts +22 -0
- package/lib/types/client/helpers.d.ts +14 -0
- package/lib/types/client/locales.d.ts +14 -0
- package/lib/types/client/native-group-actions.d.ts +7 -0
- package/lib/types/client/native-session-list.d.ts +2 -0
- package/lib/types/client/native-session-menu.d.ts +2 -1
- 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 {
|
|
@@ -70,6 +70,7 @@ function defaultFormState(now = /* @__PURE__ */ new Date(), workspaces = [], def
|
|
|
70
70
|
scheduleKind: "daily",
|
|
71
71
|
onceAt: localDateTimeValue(now),
|
|
72
72
|
everyMinutes: "60",
|
|
73
|
+
intervalAnchor: "",
|
|
73
74
|
time: "09:00",
|
|
74
75
|
weekdays: [1, 2, 3, 4, 5],
|
|
75
76
|
hourlyMinute: "00",
|
|
@@ -105,7 +106,12 @@ function buildCreateInput(form, workspaces, models, now = /* @__PURE__ */ new Da
|
|
|
105
106
|
if (!Number.isInteger(everyMinutes) || everyMinutes < 5 || everyMinutes > 43200) {
|
|
106
107
|
throw new AutomationFormError("form.error.interval");
|
|
107
108
|
}
|
|
108
|
-
schedule = {
|
|
109
|
+
schedule = {
|
|
110
|
+
kind: "interval",
|
|
111
|
+
everyMinutes,
|
|
112
|
+
anchor: form.intervalAnchor.trim() || now.toISOString(),
|
|
113
|
+
timeZone: form.timeZone
|
|
114
|
+
};
|
|
109
115
|
break;
|
|
110
116
|
}
|
|
111
117
|
case "daily":
|
|
@@ -187,6 +193,15 @@ function clockTime(iso) {
|
|
|
187
193
|
if (Number.isNaN(value.getTime())) return iso;
|
|
188
194
|
return value.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
189
195
|
}
|
|
196
|
+
var HISTORY_STATUS_OPTIONS = [
|
|
197
|
+
"succeeded",
|
|
198
|
+
"failed",
|
|
199
|
+
"interrupted",
|
|
200
|
+
"running",
|
|
201
|
+
"queued",
|
|
202
|
+
"skipped",
|
|
203
|
+
"cancelled"
|
|
204
|
+
];
|
|
190
205
|
function sortStamp(value) {
|
|
191
206
|
const parsed = Date.parse(value);
|
|
192
207
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
@@ -212,6 +227,24 @@ function sortAutomations(items, key, direction) {
|
|
|
212
227
|
return left.id.localeCompare(right.id);
|
|
213
228
|
});
|
|
214
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
|
+
}
|
|
215
248
|
function groupHistory(runs, range, now, t) {
|
|
216
249
|
const buckets = /* @__PURE__ */ new Map();
|
|
217
250
|
for (const run of runs) {
|
|
@@ -258,13 +291,19 @@ function formFromAutomation(item, workspaces = [], defaultModel, defaultPermissi
|
|
|
258
291
|
permission: item.permission,
|
|
259
292
|
workspaceId: item.workspaceId ?? base.workspaceId,
|
|
260
293
|
modelKey,
|
|
261
|
-
reasoningEffort: item.reasoningEffort ?? "none"
|
|
294
|
+
reasoningEffort: item.reasoningEffort ?? "none",
|
|
295
|
+
timeZone: item.timeZone || schedule.timeZone || base.timeZone
|
|
262
296
|
};
|
|
263
297
|
switch (schedule.kind) {
|
|
264
298
|
case "once":
|
|
265
299
|
return { ...common, scheduleKind: "once", onceAt: toLocalInput(schedule.at) };
|
|
266
300
|
case "interval":
|
|
267
|
-
return {
|
|
301
|
+
return {
|
|
302
|
+
...common,
|
|
303
|
+
scheduleKind: "interval",
|
|
304
|
+
everyMinutes: String(schedule.everyMinutes),
|
|
305
|
+
intervalAnchor: schedule.anchor ?? ""
|
|
306
|
+
};
|
|
268
307
|
case "hourly":
|
|
269
308
|
return { ...common, scheduleKind: "hourly", hourlyMinute: String(schedule.minute).padStart(2, "0") };
|
|
270
309
|
case "daily":
|
|
@@ -301,6 +340,9 @@ function RefreshIcon(props) {
|
|
|
301
340
|
function PlayIcon(props) {
|
|
302
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" }) });
|
|
303
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
|
+
}
|
|
304
346
|
function TrashIcon(props) {
|
|
305
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" }) });
|
|
306
348
|
}
|
|
@@ -310,6 +352,15 @@ function ShieldIcon(props) {
|
|
|
310
352
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m9.4 12 1.7 1.7 3.7-4" })
|
|
311
353
|
] });
|
|
312
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
|
+
}
|
|
313
364
|
function MoreIcon(props) {
|
|
314
365
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(IconFrame, { ...props, children: [
|
|
315
366
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6", cy: "12", r: "1.2", fill: "currentColor" }),
|
|
@@ -1101,6 +1152,176 @@ function clampOnceAt(value) {
|
|
|
1101
1152
|
return new Date(next.getTime() - offset).toISOString().slice(0, 16);
|
|
1102
1153
|
}
|
|
1103
1154
|
|
|
1155
|
+
// src/client/delete-confirmation.tsx
|
|
1156
|
+
var import_react3 = require("react");
|
|
1157
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1158
|
+
function DeleteConfirmation({
|
|
1159
|
+
target,
|
|
1160
|
+
t,
|
|
1161
|
+
busy,
|
|
1162
|
+
onCancel,
|
|
1163
|
+
onConfirm
|
|
1164
|
+
}) {
|
|
1165
|
+
(0, import_react3.useEffect)(() => {
|
|
1166
|
+
if (target === void 0 || busy) return;
|
|
1167
|
+
const onKeyDown = (event) => {
|
|
1168
|
+
if (event.key !== "Escape") return;
|
|
1169
|
+
event.preventDefault();
|
|
1170
|
+
onCancel();
|
|
1171
|
+
};
|
|
1172
|
+
document.addEventListener("keydown", onKeyDown);
|
|
1173
|
+
return () => {
|
|
1174
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
1175
|
+
};
|
|
1176
|
+
}, [busy, onCancel, target]);
|
|
1177
|
+
if (target === void 0) return null;
|
|
1178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-st-mask", onMouseDown: (event) => event.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1179
|
+
"section",
|
|
1180
|
+
{
|
|
1181
|
+
className: "dsh-st-confirm-modal",
|
|
1182
|
+
role: "alertdialog",
|
|
1183
|
+
"aria-modal": "true",
|
|
1184
|
+
"aria-labelledby": "dsh-st-confirm-delete-title",
|
|
1185
|
+
"aria-describedby": "dsh-st-confirm-delete-description",
|
|
1186
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1187
|
+
children: [
|
|
1188
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { id: "dsh-st-confirm-delete-title", children: t("card.confirmDelete") }),
|
|
1189
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "dsh-st-confirm-target", children: target.name }),
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { id: "dsh-st-confirm-delete-description", children: t("card.confirmDeleteHint") }),
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-st-modal-actions", children: [
|
|
1192
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "dsh-st-btn", autoFocus: true, disabled: busy, onClick: onCancel, children: t("card.cancel") }),
|
|
1193
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--danger", disabled: busy, onClick: onConfirm, children: t("card.confirm") })
|
|
1194
|
+
] })
|
|
1195
|
+
]
|
|
1196
|
+
}
|
|
1197
|
+
) });
|
|
1198
|
+
}
|
|
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
|
+
|
|
1104
1325
|
// src/client/prefill.ts
|
|
1105
1326
|
var pending = null;
|
|
1106
1327
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -1283,28 +1504,136 @@ function createAutomationRuntime(rpc) {
|
|
|
1283
1504
|
};
|
|
1284
1505
|
}
|
|
1285
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
|
+
return automations.find((item) => item.id === automationId) ?? automations.find((item) => item.name === request.name);
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1286
1611
|
// src/client/AutomationView.tsx
|
|
1287
|
-
var
|
|
1612
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1613
|
+
var SORT_STORAGE = typeof window === "undefined" ? void 0 : window.localStorage;
|
|
1614
|
+
var TASK_SETTINGS_STORAGE = typeof window === "undefined" ? void 0 : window.sessionStorage;
|
|
1288
1615
|
var EXAMPLES = [
|
|
1289
1616
|
{ name: "\u6BCF\u65E5\u56DE\u5F52\u68C0\u67E5", scheduleKind: "daily", time: "09:00", weekdays: [1, 2, 3, 4, 5] },
|
|
1290
1617
|
{ name: "\u6BCF\u5468\u4F9D\u8D56\u5DE1\u68C0", scheduleKind: "weekly", time: "10:00", weekdays: [1] },
|
|
1291
1618
|
{ name: "\u5DE5\u4F5C\u65E5\u65E9\u62A5", scheduleKind: "weekly", time: "08:00", weekdays: [1, 2, 3, 4, 5] }
|
|
1292
1619
|
];
|
|
1293
1620
|
function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
1294
|
-
const state = (0,
|
|
1295
|
-
const [tab, setTab] = (0,
|
|
1296
|
-
const [query, setQuery] = (0,
|
|
1297
|
-
const [creating, setCreating] = (0,
|
|
1298
|
-
const [editingId, setEditingId] = (0,
|
|
1299
|
-
const [
|
|
1300
|
-
const [
|
|
1301
|
-
const [
|
|
1302
|
-
const [
|
|
1303
|
-
const [
|
|
1304
|
-
const [
|
|
1305
|
-
const [
|
|
1306
|
-
const [
|
|
1307
|
-
const
|
|
1621
|
+
const state = (0, import_react6.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
1622
|
+
const [tab, setTab] = (0, import_react6.useState)("mine");
|
|
1623
|
+
const [query, setQuery] = (0, import_react6.useState)("");
|
|
1624
|
+
const [creating, setCreating] = (0, import_react6.useState)(false);
|
|
1625
|
+
const [editingId, setEditingId] = (0, import_react6.useState)();
|
|
1626
|
+
const [deleteTarget, setDeleteTarget] = (0, import_react6.useState)();
|
|
1627
|
+
const [draft, setDraft] = (0, import_react6.useState)();
|
|
1628
|
+
const [busy, setBusy] = (0, import_react6.useState)(false);
|
|
1629
|
+
const [error, setError] = (0, import_react6.useState)();
|
|
1630
|
+
const [historyRange, setHistoryRange] = (0, import_react6.useState)("day");
|
|
1631
|
+
const [historyTask, setHistoryTask] = (0, import_react6.useState)("all");
|
|
1632
|
+
const [historyStatus, setHistoryStatus] = (0, import_react6.useState)("all");
|
|
1633
|
+
const [sortKey, setSortKey] = (0, import_react6.useState)(() => readSortDefault(SORT_STORAGE, SETTINGS_SORT_DEFAULT_KEY)?.key ?? "created");
|
|
1634
|
+
const [sortDirection, setSortDirection] = (0, import_react6.useState)(() => readSortDefault(SORT_STORAGE, SETTINGS_SORT_DEFAULT_KEY)?.direction ?? "desc");
|
|
1635
|
+
const [taskSettingsRequest, setTaskSettingsRequest] = (0, import_react6.useState)(() => readAutomationTaskSettingsRequest(TASK_SETTINGS_STORAGE));
|
|
1636
|
+
const now = (0, import_react6.useMemo)(() => new Date(state.snapshot?.serverNow ?? Date.now()), [state.snapshot?.serverNow, state.refreshedAt]);
|
|
1308
1637
|
const snapshot = state.snapshot;
|
|
1309
1638
|
const workspaces = snapshot?.workspaces ?? [];
|
|
1310
1639
|
const models = snapshot?.models ?? [];
|
|
@@ -1348,37 +1677,61 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1348
1677
|
setDraft(formFromAutomation(item, workspaces, snapshot?.defaultModel ?? null, snapshot?.defaultPermission ?? item.permission));
|
|
1349
1678
|
setCreating(true);
|
|
1350
1679
|
};
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1680
|
+
(0, import_react6.useEffect)(() => {
|
|
1681
|
+
if (typeof window === "undefined") return;
|
|
1682
|
+
const onTaskSettings = (event) => {
|
|
1683
|
+
const request = parseAutomationTaskSettingsRequest(event.detail);
|
|
1684
|
+
if (request !== void 0) setTaskSettingsRequest(request);
|
|
1685
|
+
};
|
|
1686
|
+
window.addEventListener(AUTOMATION_TASK_SETTINGS_EVENT, onTaskSettings);
|
|
1687
|
+
return () => {
|
|
1688
|
+
window.removeEventListener(AUTOMATION_TASK_SETTINGS_EVENT, onTaskSettings);
|
|
1689
|
+
};
|
|
1690
|
+
}, []);
|
|
1691
|
+
(0, import_react6.useEffect)(() => {
|
|
1692
|
+
if (taskSettingsRequest === void 0 || snapshot === void 0) return;
|
|
1693
|
+
const item = resolveAutomationTaskSettings(taskSettingsRequest, snapshot.automations, snapshot.runs);
|
|
1694
|
+
clearAutomationTaskSettingsRequest(TASK_SETTINGS_STORAGE);
|
|
1695
|
+
setTaskSettingsRequest(void 0);
|
|
1696
|
+
setTab("mine");
|
|
1697
|
+
setQuery("");
|
|
1698
|
+
if (item === void 0) {
|
|
1699
|
+
setError(t("error.taskMissing"));
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
openEdit(item);
|
|
1703
|
+
}, [snapshot, taskSettingsRequest, t]);
|
|
1704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-shell", children: [
|
|
1705
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: "dsh-st-top", children: [
|
|
1706
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-heading", children: [
|
|
1707
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { children: t("tab") }),
|
|
1708
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: t("header.lead") })
|
|
1356
1709
|
] }),
|
|
1357
|
-
/* @__PURE__ */ (0,
|
|
1358
|
-
/* @__PURE__ */ (0,
|
|
1359
|
-
/* @__PURE__ */ (0,
|
|
1710
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-toolbar", children: [
|
|
1711
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { className: "dsh-st-search", value: query, placeholder: t("search.placeholder"), onChange: (event) => setQuery(event.target.value) }),
|
|
1712
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "dsh-st-btn", onClick: () => {
|
|
1360
1713
|
setChatPrefill(t("chat.prompt"));
|
|
1361
1714
|
closeSettings?.();
|
|
1362
1715
|
}, children: [
|
|
1363
|
-
/* @__PURE__ */ (0,
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChatIcon, {}),
|
|
1364
1717
|
t("action.chatCreate")
|
|
1365
1718
|
] }),
|
|
1366
|
-
/* @__PURE__ */ (0,
|
|
1367
|
-
/* @__PURE__ */ (0,
|
|
1719
|
+
/* @__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: [
|
|
1720
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlusIcon, {}),
|
|
1368
1721
|
t("action.create")
|
|
1369
1722
|
] }),
|
|
1370
|
-
/* @__PURE__ */ (0,
|
|
1723
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-icon", onClick: () => {
|
|
1371
1724
|
void runtime.refresh();
|
|
1372
|
-
}, "aria-label": t("section.refresh"), children: /* @__PURE__ */ (0,
|
|
1725
|
+
}, "aria-label": t("section.refresh"), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshIcon, {}) })
|
|
1373
1726
|
] })
|
|
1374
1727
|
] }),
|
|
1375
|
-
/* @__PURE__ */ (0,
|
|
1376
|
-
/* @__PURE__ */ (0,
|
|
1728
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-banner", role: "note", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
1729
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InfoIcon, {}),
|
|
1377
1730
|
t("banner.wake")
|
|
1378
1731
|
] }) }),
|
|
1379
|
-
/* @__PURE__ */ (0,
|
|
1380
|
-
/* @__PURE__ */ (0,
|
|
1381
|
-
/* @__PURE__ */ (0,
|
|
1732
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "dsh-st-examples", children: [
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-examples-head", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { children: t("examples.title") }) }),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-example-row", children: EXAMPLES.map((example, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1382
1735
|
"button",
|
|
1383
1736
|
{
|
|
1384
1737
|
type: "button",
|
|
@@ -1392,10 +1745,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1392
1745
|
weekdays: example.weekdays
|
|
1393
1746
|
}),
|
|
1394
1747
|
children: [
|
|
1395
|
-
/* @__PURE__ */ (0,
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1397
|
-
/* @__PURE__ */ (0,
|
|
1398
|
-
/* @__PURE__ */ (0,
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: t(`examples.${index + 1}.title`) }),
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: t(`examples.${index + 1}.body`) }),
|
|
1750
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-st-chip", children: [
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ClockIcon, {}),
|
|
1399
1752
|
t(`examples.${index + 1}.chip`)
|
|
1400
1753
|
] })
|
|
1401
1754
|
]
|
|
@@ -1403,22 +1756,24 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1403
1756
|
example.name
|
|
1404
1757
|
)) })
|
|
1405
1758
|
] }),
|
|
1406
|
-
error !== void 0 && /* @__PURE__ */ (0,
|
|
1407
|
-
(state.phase === "idle" || state.phase === "loading" && snapshot === void 0) && /* @__PURE__ */ (0,
|
|
1408
|
-
state.phase === "error" && snapshot === void 0 && /* @__PURE__ */ (0,
|
|
1409
|
-
/* @__PURE__ */ (0,
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1411
|
-
/* @__PURE__ */ (0,
|
|
1759
|
+
error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "dsh-st-error", children: error }),
|
|
1760
|
+
(state.phase === "idle" || state.phase === "loading" && snapshot === void 0) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "dsh-st-muted", children: t("loading") }),
|
|
1761
|
+
state.phase === "error" && snapshot === void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-empty", children: [
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: t("error.title") }),
|
|
1763
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: state.error }),
|
|
1764
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-btn dsh-st-btn--primary", onClick: () => {
|
|
1412
1765
|
void runtime.refresh();
|
|
1413
1766
|
}, children: t("error.retry") })
|
|
1414
1767
|
] }),
|
|
1415
|
-
/* @__PURE__ */ (0,
|
|
1416
|
-
/* @__PURE__ */ (0,
|
|
1417
|
-
/* @__PURE__ */ (0,
|
|
1418
|
-
tab === "mine" && /* @__PURE__ */ (0,
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-tabs", children: [
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: tab === "mine" ? "is-on" : "", onClick: () => setTab("mine"), children: t("tabs.mine") }),
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: tab === "runs" ? "is-on" : "", onClick: () => setTab("runs"), children: t("tabs.runs") }),
|
|
1771
|
+
tab === "mine" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-sort-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1419
1772
|
SortMenu,
|
|
1420
1773
|
{
|
|
1421
1774
|
t,
|
|
1775
|
+
...SORT_STORAGE === void 0 ? {} : { storage: SORT_STORAGE },
|
|
1776
|
+
storageKey: SETTINGS_SORT_DEFAULT_KEY,
|
|
1422
1777
|
sortKey,
|
|
1423
1778
|
sortDirection,
|
|
1424
1779
|
onSelect: (key, direction) => {
|
|
@@ -1426,10 +1781,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1426
1781
|
setSortDirection(direction);
|
|
1427
1782
|
}
|
|
1428
1783
|
}
|
|
1429
|
-
),
|
|
1430
|
-
tab === "runs" && /* @__PURE__ */ (0,
|
|
1431
|
-
["day", "week", "month"].map((range) => /* @__PURE__ */ (0,
|
|
1432
|
-
/* @__PURE__ */ (0,
|
|
1784
|
+
) }),
|
|
1785
|
+
tab === "runs" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-filters", children: [
|
|
1786
|
+
["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)),
|
|
1787
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1433
1788
|
DropdownMenu,
|
|
1434
1789
|
{
|
|
1435
1790
|
ariaLabel: t("history.allTasks"),
|
|
@@ -1444,13 +1799,13 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1444
1799
|
]
|
|
1445
1800
|
}
|
|
1446
1801
|
),
|
|
1447
|
-
/* @__PURE__ */ (0,
|
|
1802
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1448
1803
|
DropdownMenu,
|
|
1449
1804
|
{
|
|
1450
1805
|
ariaLabel: t("history.allStatus"),
|
|
1451
1806
|
options: [
|
|
1452
1807
|
{ key: "all", label: t("history.allStatus"), selected: historyStatus === "all", onSelect: () => setHistoryStatus("all") },
|
|
1453
|
-
...
|
|
1808
|
+
...HISTORY_STATUS_OPTIONS.map((status) => ({
|
|
1454
1809
|
key: status,
|
|
1455
1810
|
label: t(`status.${status}`),
|
|
1456
1811
|
selected: historyStatus === status,
|
|
@@ -1461,10 +1816,10 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1461
1816
|
)
|
|
1462
1817
|
] })
|
|
1463
1818
|
] }),
|
|
1464
|
-
tab === "mine" && (automations.length === 0 ? /* @__PURE__ */ (0,
|
|
1465
|
-
/* @__PURE__ */ (0,
|
|
1466
|
-
/* @__PURE__ */ (0,
|
|
1467
|
-
] }) : /* @__PURE__ */ (0,
|
|
1819
|
+
tab === "mine" && (automations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-empty", children: [
|
|
1820
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: t("empty.title") }),
|
|
1821
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: t("empty.body") })
|
|
1822
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-grid", children: automations.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1468
1823
|
TaskCard,
|
|
1469
1824
|
{
|
|
1470
1825
|
item,
|
|
@@ -1478,17 +1833,15 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1478
1833
|
onRun: () => {
|
|
1479
1834
|
void runAction(() => runtime.runNow(item.id));
|
|
1480
1835
|
},
|
|
1481
|
-
onDelete: () =>
|
|
1482
|
-
void runAction(() => runtime.mutateAutomation(item.id, "delete"));
|
|
1483
|
-
}
|
|
1836
|
+
onDelete: () => setDeleteTarget(item)
|
|
1484
1837
|
},
|
|
1485
1838
|
item.id
|
|
1486
1839
|
)) })),
|
|
1487
|
-
tab === "runs" && (groups.length === 0 ? /* @__PURE__ */ (0,
|
|
1488
|
-
/* @__PURE__ */ (0,
|
|
1489
|
-
group.items.map((run) => /* @__PURE__ */ (0,
|
|
1840
|
+
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: [
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: group.label }),
|
|
1842
|
+
group.items.map((run) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RunRow, { run, t }, run.id))
|
|
1490
1843
|
] }, group.key)) })),
|
|
1491
|
-
creating && /* @__PURE__ */ (0,
|
|
1844
|
+
creating && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1492
1845
|
CreateModal,
|
|
1493
1846
|
{
|
|
1494
1847
|
t,
|
|
@@ -1517,6 +1870,23 @@ function AutomationView({ t, permissionT, modelT, runtime, closeSettings }) {
|
|
|
1517
1870
|
}
|
|
1518
1871
|
},
|
|
1519
1872
|
editingId ?? "create"
|
|
1873
|
+
),
|
|
1874
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1875
|
+
DeleteConfirmation,
|
|
1876
|
+
{
|
|
1877
|
+
target: deleteTarget,
|
|
1878
|
+
t,
|
|
1879
|
+
busy,
|
|
1880
|
+
onCancel: () => setDeleteTarget(void 0),
|
|
1881
|
+
onConfirm: () => {
|
|
1882
|
+
const target = deleteTarget;
|
|
1883
|
+
if (target === void 0) return;
|
|
1884
|
+
void runAction(async () => {
|
|
1885
|
+
await runtime.mutateAutomation(target.id, "delete");
|
|
1886
|
+
setDeleteTarget(void 0);
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1520
1890
|
)
|
|
1521
1891
|
] });
|
|
1522
1892
|
}
|
|
@@ -1530,9 +1900,9 @@ function TaskCard({
|
|
|
1530
1900
|
onRun,
|
|
1531
1901
|
onDelete
|
|
1532
1902
|
}) {
|
|
1533
|
-
const [menu, setMenu] = (0,
|
|
1534
|
-
const root = (0,
|
|
1535
|
-
(0,
|
|
1903
|
+
const [menu, setMenu] = (0, import_react6.useState)(false);
|
|
1904
|
+
const root = (0, import_react6.useRef)(null);
|
|
1905
|
+
(0, import_react6.useEffect)(() => {
|
|
1536
1906
|
if (!menu) return;
|
|
1537
1907
|
const close = (event) => {
|
|
1538
1908
|
if (root.current !== null && !root.current.contains(event.target)) setMenu(false);
|
|
@@ -1542,131 +1912,59 @@ function TaskCard({
|
|
|
1542
1912
|
document.removeEventListener("mousedown", close);
|
|
1543
1913
|
};
|
|
1544
1914
|
}, [menu]);
|
|
1545
|
-
return /* @__PURE__ */ (0,
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
1915
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("article", { className: "dsh-st-card", ref: root, onClick: onEdit, children: [
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-card-head", children: [
|
|
1917
|
+
/* @__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) => {
|
|
1548
1918
|
event.stopPropagation();
|
|
1549
1919
|
onToggle();
|
|
1550
1920
|
} }),
|
|
1551
|
-
/* @__PURE__ */ (0,
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "dsh-st-more", onClick: (event) => {
|
|
1552
1922
|
event.stopPropagation();
|
|
1553
1923
|
setMenu((value) => !value);
|
|
1554
|
-
}, "aria-label": t("card.more"), children: /* @__PURE__ */ (0,
|
|
1555
|
-
menu && /* @__PURE__ */ (0,
|
|
1556
|
-
/* @__PURE__ */ (0,
|
|
1924
|
+
}, "aria-label": t("card.more"), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {}) }),
|
|
1925
|
+
menu && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-menu", onClick: (event) => event.stopPropagation(), children: [
|
|
1926
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", disabled: busy, onClick: () => {
|
|
1557
1927
|
setMenu(false);
|
|
1558
1928
|
onRun();
|
|
1559
1929
|
}, children: [
|
|
1560
|
-
/* @__PURE__ */ (0,
|
|
1930
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PlayIcon, { width: 16, height: 16 }),
|
|
1561
1931
|
t("menu.run")
|
|
1562
1932
|
] }),
|
|
1563
|
-
/* @__PURE__ */ (0,
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", disabled: busy, onClick: () => {
|
|
1564
1934
|
setMenu(false);
|
|
1565
1935
|
onEdit();
|
|
1566
1936
|
}, children: [
|
|
1567
|
-
/* @__PURE__ */ (0,
|
|
1937
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PencilIcon, { width: 16, height: 16 }),
|
|
1568
1938
|
t("menu.edit")
|
|
1569
1939
|
] }),
|
|
1570
|
-
/* @__PURE__ */ (0,
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "is-danger", disabled: busy, onClick: () => {
|
|
1571
1941
|
setMenu(false);
|
|
1572
1942
|
onDelete();
|
|
1573
1943
|
}, children: [
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TrashIcon, { width: 16, height: 16 }),
|
|
1575
1945
|
t("menu.delete")
|
|
1576
1946
|
] })
|
|
1577
1947
|
] })
|
|
1578
1948
|
] }),
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
1580
|
-
/* @__PURE__ */ (0,
|
|
1581
|
-
/* @__PURE__ */ (0,
|
|
1582
|
-
/* @__PURE__ */ (0,
|
|
1583
|
-
/* @__PURE__ */ (0,
|
|
1949
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { children: item.name }),
|
|
1950
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: item.prompt }),
|
|
1951
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-card-foot", children: [
|
|
1952
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-st-chip", children: [
|
|
1953
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ClockIcon, {}),
|
|
1584
1954
|
formatSchedule(item.schedule, t)
|
|
1585
1955
|
] }),
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
1956
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: item.nextRunAt === void 0 ? t("stats.noneScheduled") : t("history.nextApprox", { when: formatWithin(item.nextRunAt, now, t) }) })
|
|
1587
1957
|
] })
|
|
1588
1958
|
] });
|
|
1589
1959
|
}
|
|
1590
|
-
function SortMenu({
|
|
1591
|
-
t,
|
|
1592
|
-
sortKey,
|
|
1593
|
-
sortDirection,
|
|
1594
|
-
onSelect
|
|
1595
|
-
}) {
|
|
1596
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1597
|
-
DropdownMenu,
|
|
1598
|
-
{
|
|
1599
|
-
className: "dsh-st-sort",
|
|
1600
|
-
ariaLabel: t("sort.by"),
|
|
1601
|
-
options: [
|
|
1602
|
-
{ key: "created-desc", label: t("sort.created.desc"), selected: sortKey === "created" && sortDirection === "desc", onSelect: () => onSelect("created", "desc") },
|
|
1603
|
-
{ key: "created-asc", label: t("sort.created.asc"), selected: sortKey === "created" && sortDirection === "asc", onSelect: () => onSelect("created", "asc") },
|
|
1604
|
-
{ key: "planned-asc", label: t("sort.planned.asc"), selected: sortKey === "planned" && sortDirection === "asc", onSelect: () => onSelect("planned", "asc") },
|
|
1605
|
-
{ key: "planned-desc", label: t("sort.planned.desc"), selected: sortKey === "planned" && sortDirection === "desc", onSelect: () => onSelect("planned", "desc") }
|
|
1606
|
-
]
|
|
1607
|
-
}
|
|
1608
|
-
);
|
|
1609
|
-
}
|
|
1610
|
-
function DropdownMenu({
|
|
1611
|
-
ariaLabel,
|
|
1612
|
-
className,
|
|
1613
|
-
options
|
|
1614
|
-
}) {
|
|
1615
|
-
const [open, setOpen] = (0, import_react3.useState)(false);
|
|
1616
|
-
const root = (0, import_react3.useRef)(null);
|
|
1617
|
-
(0, import_react3.useEffect)(() => {
|
|
1618
|
-
if (!open) return;
|
|
1619
|
-
const close = (event) => {
|
|
1620
|
-
if (root.current !== null && !root.current.contains(event.target)) setOpen(false);
|
|
1621
|
-
};
|
|
1622
|
-
const closeOnEscape = (event) => {
|
|
1623
|
-
if (event.key === "Escape") setOpen(false);
|
|
1624
|
-
};
|
|
1625
|
-
document.addEventListener("mousedown", close);
|
|
1626
|
-
document.addEventListener("keydown", closeOnEscape);
|
|
1627
|
-
return () => {
|
|
1628
|
-
document.removeEventListener("mousedown", close);
|
|
1629
|
-
document.removeEventListener("keydown", closeOnEscape);
|
|
1630
|
-
};
|
|
1631
|
-
}, [open]);
|
|
1632
|
-
const selectedLabel = options.find((option) => option.selected)?.label ?? options[0]?.label ?? ariaLabel;
|
|
1633
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `dsh-st-dropdown${className === void 0 ? "" : ` ${className}`}`, ref: root, children: [
|
|
1634
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", className: `dsh-st-dropdown-btn${open ? " is-open" : ""}`, "aria-label": ariaLabel, "aria-expanded": open, onClick: () => setOpen((value) => !value), children: [
|
|
1635
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-st-dropdown-label", children: selectedLabel }),
|
|
1636
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChevronIcon, { width: 10, height: 10, className: "dsh-st-dropdown-chevron" })
|
|
1637
|
-
] }),
|
|
1638
|
-
open && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-st-dropdown-menu", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1639
|
-
DropdownRow,
|
|
1640
|
-
{
|
|
1641
|
-
label: option.label,
|
|
1642
|
-
selected: option.selected,
|
|
1643
|
-
onSelect: () => {
|
|
1644
|
-
setOpen(false);
|
|
1645
|
-
option.onSelect();
|
|
1646
|
-
}
|
|
1647
|
-
},
|
|
1648
|
-
option.key
|
|
1649
|
-
)) })
|
|
1650
|
-
] });
|
|
1651
|
-
}
|
|
1652
|
-
function DropdownRow({
|
|
1653
|
-
label,
|
|
1654
|
-
selected,
|
|
1655
|
-
onSelect
|
|
1656
|
-
}) {
|
|
1657
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", "aria-pressed": selected, className: selected ? "is-selected" : void 0, onClick: onSelect, children: [
|
|
1658
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: label }),
|
|
1659
|
-
selected ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckOutlineIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-st-sort-tick" })
|
|
1660
|
-
] });
|
|
1661
|
-
}
|
|
1662
1960
|
function RunRow({ run, t }) {
|
|
1663
1961
|
const duration = formatDuration(run.startedAt, run.finishedAt);
|
|
1664
|
-
return /* @__PURE__ */ (0,
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
1666
|
-
/* @__PURE__ */ (0,
|
|
1667
|
-
/* @__PURE__ */ (0,
|
|
1668
|
-
duration !== void 0 && /* @__PURE__ */ (0,
|
|
1669
|
-
/* @__PURE__ */ (0,
|
|
1962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("article", { className: `dsh-st-run is-${run.status}`, children: [
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: run.automationName }),
|
|
1964
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
|
|
1965
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: clockTime(run.startedAt ?? run.scheduledFor) }),
|
|
1966
|
+
duration !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: duration }),
|
|
1967
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: t("history.trigger") })
|
|
1670
1968
|
] })
|
|
1671
1969
|
] });
|
|
1672
1970
|
}
|
|
@@ -1679,6 +1977,8 @@ var en = {
|
|
|
1679
1977
|
"sidebar.tabs": "Workspace views",
|
|
1680
1978
|
"sidebar.tasksTab": "Tasks",
|
|
1681
1979
|
"sidebar.channelsTab": "Channels",
|
|
1980
|
+
"sidebar.views": "Scheduled views",
|
|
1981
|
+
"sidebar.viewOverview": "Task overview",
|
|
1682
1982
|
"sidebar.empty": "No scheduled runs yet.",
|
|
1683
1983
|
"sidebar.tasksEmpty": "No web tasks yet.",
|
|
1684
1984
|
"sidebar.ungrouped": "Ungrouped",
|
|
@@ -1713,6 +2013,15 @@ var en = {
|
|
|
1713
2013
|
"session.rename": "Rename",
|
|
1714
2014
|
"session.fork": "Fork session",
|
|
1715
2015
|
"session.archive": "Archive session",
|
|
2016
|
+
"session.groupActions": "Actions for {name}",
|
|
2017
|
+
"session.taskSettings": "Task settings",
|
|
2018
|
+
"session.archiveGroup": "Archive all conversations",
|
|
2019
|
+
"session.archiveGroupConfirm": "Archive all",
|
|
2020
|
+
"session.archiveGroupDescription": "Archive all {count} conversations for \u201C{name}\u201D. You can restore them later in Settings \u2192 Archived.",
|
|
2021
|
+
"session.archiveGroupPending": "Archiving conversations\u2026",
|
|
2022
|
+
"session.archiveGroupFailed": "Some conversations could not be archived: {message}",
|
|
2023
|
+
"session.archiveGroupClose": "Close",
|
|
2024
|
+
"session.archiveGroupCancel": "Cancel",
|
|
1716
2025
|
"session.idle": "Idle",
|
|
1717
2026
|
"session.runningStatus": "Running",
|
|
1718
2027
|
"session.delete": "Remove from Scheduled",
|
|
@@ -1746,6 +2055,7 @@ var en = {
|
|
|
1746
2055
|
"sort.created.desc": "Created time descending",
|
|
1747
2056
|
"sort.planned.asc": "Planned time ascending",
|
|
1748
2057
|
"sort.planned.desc": "Planned time descending",
|
|
2058
|
+
"sort.default.saved": "Default",
|
|
1749
2059
|
"form.workspace": "Workspace",
|
|
1750
2060
|
"form.workspacePath": "Folder path",
|
|
1751
2061
|
"form.workspacePathPlaceholder": "D:\\work\\project",
|
|
@@ -1782,6 +2092,7 @@ var en = {
|
|
|
1782
2092
|
"empty.body": "Save a self-contained task, a schedule, and a permission boundary. Every run starts in a new Session.",
|
|
1783
2093
|
"empty.action": "Create the first automation",
|
|
1784
2094
|
"runs.empty": "No runs yet. Run one now, or wait for the next scheduled occurrence.",
|
|
2095
|
+
"overview.empty": "No scheduled tasks yet. Create one in Settings.",
|
|
1785
2096
|
"form.title": "Create automation",
|
|
1786
2097
|
"form.subtitle": "Write a complete, standalone task. Scheduled runs do not inherit this conversation.",
|
|
1787
2098
|
"form.name": "Name",
|
|
@@ -1864,6 +2175,7 @@ var en = {
|
|
|
1864
2175
|
"error.title": "Automations could not be loaded",
|
|
1865
2176
|
"error.retry": "Try again",
|
|
1866
2177
|
"error.action": "The action failed. Please try again.",
|
|
2178
|
+
"error.taskMissing": "This scheduled task no longer exists.",
|
|
1867
2179
|
"error.offline": "Could not reach the local automation service. Check that DSH is still running and try again.",
|
|
1868
2180
|
"time.now": "now",
|
|
1869
2181
|
"time.minuteAgo": "{count}m ago",
|
|
@@ -1879,6 +2191,8 @@ var zh = {
|
|
|
1879
2191
|
"sidebar.tabs": "\u5DE5\u4F5C\u533A\u5206\u7C7B",
|
|
1880
2192
|
"sidebar.tasksTab": "\u4EFB\u52A1",
|
|
1881
2193
|
"sidebar.channelsTab": "\u9891\u9053",
|
|
2194
|
+
"sidebar.views": "\u5B9A\u65F6\u9875\u89C6\u56FE",
|
|
2195
|
+
"sidebar.viewOverview": "\u4EFB\u52A1\u603B\u89C8",
|
|
1882
2196
|
"sidebar.empty": "\u8FD8\u6CA1\u6709\u5B9A\u65F6\u4EFB\u52A1\u6267\u884C\u8BB0\u5F55\u3002",
|
|
1883
2197
|
"sidebar.tasksEmpty": "\u6682\u65E0\u7F51\u9875\u4EFB\u52A1",
|
|
1884
2198
|
"sidebar.ungrouped": "\u672A\u5206\u7EC4",
|
|
@@ -1913,6 +2227,15 @@ var zh = {
|
|
|
1913
2227
|
"session.rename": "\u91CD\u547D\u540D",
|
|
1914
2228
|
"session.fork": "\u5206\u53C9\u4F1A\u8BDD",
|
|
1915
2229
|
"session.archive": "\u5F52\u6863\u4F1A\u8BDD",
|
|
2230
|
+
"session.groupActions": "\u201C{name}\u201D\u7684\u4EFB\u52A1\u64CD\u4F5C",
|
|
2231
|
+
"session.taskSettings": "\u4EFB\u52A1\u8BBE\u7F6E",
|
|
2232
|
+
"session.archiveGroup": "\u5F52\u6863\u6574\u7EC4\u4F1A\u8BDD",
|
|
2233
|
+
"session.archiveGroupConfirm": "\u786E\u8BA4\u5F52\u6863",
|
|
2234
|
+
"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",
|
|
2235
|
+
"session.archiveGroupPending": "\u6B63\u5728\u5F52\u6863\u6574\u7EC4\u4F1A\u8BDD\u2026",
|
|
2236
|
+
"session.archiveGroupFailed": "\u90E8\u5206\u4F1A\u8BDD\u5F52\u6863\u5931\u8D25\uFF1A{message}",
|
|
2237
|
+
"session.archiveGroupClose": "\u5173\u95ED",
|
|
2238
|
+
"session.archiveGroupCancel": "\u53D6\u6D88",
|
|
1916
2239
|
"session.idle": "\u7A7A\u95F2",
|
|
1917
2240
|
"session.runningStatus": "\u8FD0\u884C\u4E2D",
|
|
1918
2241
|
"session.delete": "\u4ECE\u5B9A\u65F6\u9875\u79FB\u9664",
|
|
@@ -1946,6 +2269,7 @@ var zh = {
|
|
|
1946
2269
|
"sort.created.desc": "\u6309\u521B\u5EFA\u65F6\u95F4\u5012\u5E8F",
|
|
1947
2270
|
"sort.planned.asc": "\u6309\u8BA1\u5212\u65F6\u95F4\u5347\u5E8F",
|
|
1948
2271
|
"sort.planned.desc": "\u6309\u8BA1\u5212\u65F6\u95F4\u5012\u5E8F",
|
|
2272
|
+
"sort.default.saved": "\u9ED8\u8BA4",
|
|
1949
2273
|
"form.workspace": "\u5DE5\u4F5C\u76EE\u5F55",
|
|
1950
2274
|
"form.workspacePath": "\u76EE\u5F55\u8DEF\u5F84",
|
|
1951
2275
|
"form.workspacePathPlaceholder": "D:\\work\\project",
|
|
@@ -1982,6 +2306,7 @@ var zh = {
|
|
|
1982
2306
|
"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",
|
|
1983
2307
|
"empty.action": "\u521B\u5EFA\u7B2C\u4E00\u4E2A\u81EA\u52A8\u5316",
|
|
1984
2308
|
"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",
|
|
2309
|
+
"overview.empty": "\u6682\u65E0\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u53EF\u5230\u8BBE\u7F6E\u9875\u521B\u5EFA\u3002",
|
|
1985
2310
|
"form.title": "\u521B\u5EFA\u81EA\u52A8\u5316",
|
|
1986
2311
|
"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",
|
|
1987
2312
|
"form.name": "\u540D\u79F0",
|
|
@@ -2064,6 +2389,7 @@ var zh = {
|
|
|
2064
2389
|
"error.title": "\u65E0\u6CD5\u52A0\u8F7D\u81EA\u52A8\u5316",
|
|
2065
2390
|
"error.retry": "\u91CD\u8BD5",
|
|
2066
2391
|
"error.action": "\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
2392
|
+
"error.taskMissing": "\u8BE5\u5B9A\u65F6\u4EFB\u52A1\u5DF2\u4E0D\u5B58\u5728\u3002",
|
|
2067
2393
|
"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",
|
|
2068
2394
|
"time.now": "\u521A\u521A",
|
|
2069
2395
|
"time.minuteAgo": "{count} \u5206\u949F\u524D",
|
|
@@ -2151,8 +2477,9 @@ function isForeignSidebarHost(component) {
|
|
|
2151
2477
|
}
|
|
2152
2478
|
|
|
2153
2479
|
// src/client/native-session-list.tsx
|
|
2154
|
-
var
|
|
2155
|
-
var
|
|
2480
|
+
var import_react9 = require("react");
|
|
2481
|
+
var import_react_dom3 = require("react-dom");
|
|
2482
|
+
var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
2156
2483
|
|
|
2157
2484
|
// src/client/native-session-menu.ts
|
|
2158
2485
|
function resolveEventElement(target) {
|
|
@@ -2214,16 +2541,28 @@ function nativeSessionHoverStyle(row, card, viewport) {
|
|
|
2214
2541
|
top: `${Math.round(top)}px`
|
|
2215
2542
|
};
|
|
2216
2543
|
}
|
|
2217
|
-
function relativeTime(value) {
|
|
2544
|
+
function relativeTime(value, t, now = Date.now()) {
|
|
2218
2545
|
const ts = Date.parse(value || "");
|
|
2219
2546
|
if (!Number.isFinite(ts)) return "";
|
|
2220
|
-
const delta = Math.max(0,
|
|
2547
|
+
const delta = Math.max(0, now - ts);
|
|
2221
2548
|
const min = Math.floor(delta / 6e4);
|
|
2222
|
-
if (min < 1) return "
|
|
2223
|
-
if (min < 60) return
|
|
2549
|
+
if (min < 1) return t("time.now");
|
|
2550
|
+
if (min < 60) return t("time.minuteAgo", { count: min });
|
|
2224
2551
|
const hour = Math.floor(min / 60);
|
|
2225
|
-
if (hour < 24) return
|
|
2226
|
-
return
|
|
2552
|
+
if (hour < 24) return t("time.hourAgo", { count: hour });
|
|
2553
|
+
return t("time.dayAgo", { count: Math.floor(hour / 24) });
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
// src/client/native-group-actions.ts
|
|
2557
|
+
var ARCHIVE_MANAGER_PLUGIN = "@michengai/dsh-archive-manager";
|
|
2558
|
+
function hasArchiveManagerPlugin(root) {
|
|
2559
|
+
return root?.querySelector(`[data-plugin="${ARCHIVE_MANAGER_PLUGIN}"]`) != null;
|
|
2560
|
+
}
|
|
2561
|
+
function scheduledGroupShowsActiveFolder(expanded, sessionIds, selectedId) {
|
|
2562
|
+
return expanded && selectedId !== null && sessionIds.includes(selectedId);
|
|
2563
|
+
}
|
|
2564
|
+
async function archiveScheduledGroup(sessionIds, archiveSession) {
|
|
2565
|
+
for (const sessionId of sessionIds) await archiveSession(sessionId);
|
|
2227
2566
|
}
|
|
2228
2567
|
|
|
2229
2568
|
// src/run-title.ts
|
|
@@ -2272,6 +2611,26 @@ function groupScheduledSessions(automations, runs) {
|
|
|
2272
2611
|
};
|
|
2273
2612
|
}).filter((group) => group.sessions.length > 0);
|
|
2274
2613
|
}
|
|
2614
|
+
function deriveTaskOverviewRows(automations, runs) {
|
|
2615
|
+
const lastByAutomation = /* @__PURE__ */ new Map();
|
|
2616
|
+
for (const run of runs) {
|
|
2617
|
+
if (run.sessionId === void 0 || run.sessionId === "") continue;
|
|
2618
|
+
const current = lastByAutomation.get(run.automationId);
|
|
2619
|
+
const stamp = Date.parse(run.startedAt ?? run.scheduledFor);
|
|
2620
|
+
const currentStamp = current === void 0 ? Number.NaN : Date.parse(current.startedAt ?? current.scheduledFor);
|
|
2621
|
+
if (current === void 0 || stamp >= currentStamp) lastByAutomation.set(run.automationId, run);
|
|
2622
|
+
}
|
|
2623
|
+
return automations.map((item) => {
|
|
2624
|
+
const last = lastByAutomation.get(item.id);
|
|
2625
|
+
return {
|
|
2626
|
+
id: item.id,
|
|
2627
|
+
name: item.name,
|
|
2628
|
+
status: item.status,
|
|
2629
|
+
...item.nextRunAt === void 0 ? {} : { nextRunAt: item.nextRunAt },
|
|
2630
|
+
...last === void 0 ? {} : { lastSessionId: last.sessionId }
|
|
2631
|
+
};
|
|
2632
|
+
});
|
|
2633
|
+
}
|
|
2275
2634
|
function keepScheduledSessionLink(sessionId, archived, presentIds) {
|
|
2276
2635
|
if (sessionId === void 0 || sessionId === "") return false;
|
|
2277
2636
|
if (archived.has(sessionId)) return false;
|
|
@@ -2503,9 +2862,116 @@ function latestSessionTime(group) {
|
|
|
2503
2862
|
return latest;
|
|
2504
2863
|
}
|
|
2505
2864
|
|
|
2865
|
+
// src/client/schedule-overview.tsx
|
|
2866
|
+
var import_react7 = require("react");
|
|
2867
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2868
|
+
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
2869
|
+
var SORT_STORAGE2 = typeof window === "undefined" ? void 0 : window.localStorage;
|
|
2870
|
+
function ScheduleViewSwitch({
|
|
2871
|
+
t,
|
|
2872
|
+
view,
|
|
2873
|
+
onChange
|
|
2874
|
+
}) {
|
|
2875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-rail-views", role: "tablist", "aria-label": t("sidebar.views"), children: [
|
|
2876
|
+
/* @__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") }),
|
|
2877
|
+
/* @__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") })
|
|
2878
|
+
] });
|
|
2879
|
+
}
|
|
2880
|
+
function ScheduleOverview({
|
|
2881
|
+
t,
|
|
2882
|
+
automations,
|
|
2883
|
+
runs,
|
|
2884
|
+
openSession,
|
|
2885
|
+
serverNow,
|
|
2886
|
+
archived,
|
|
2887
|
+
presentIds
|
|
2888
|
+
}) {
|
|
2889
|
+
const [sortKey, setSortKey] = (0, import_react7.useState)(() => readSortDefault(SORT_STORAGE2, OVERVIEW_SORT_DEFAULT_KEY)?.key ?? "planned");
|
|
2890
|
+
const [sortDirection, setSortDirection] = (0, import_react7.useState)(() => readSortDefault(SORT_STORAGE2, OVERVIEW_SORT_DEFAULT_KEY)?.direction ?? "asc");
|
|
2891
|
+
const now = (0, import_react7.useMemo)(() => new Date(serverNow ?? Date.now()), [serverNow]);
|
|
2892
|
+
const rows = (0, import_react7.useMemo)(() => {
|
|
2893
|
+
const sorted = sortAutomations(automations, sortKey, sortDirection);
|
|
2894
|
+
return deriveTaskOverviewRows(sorted, runs).map((row) => {
|
|
2895
|
+
if (row.lastSessionId === void 0 || !keepScheduledSessionLink(row.lastSessionId, archived ?? EMPTY_SET, presentIds)) {
|
|
2896
|
+
const { lastSessionId: _dropped, ...rest } = row;
|
|
2897
|
+
return rest;
|
|
2898
|
+
}
|
|
2899
|
+
return row;
|
|
2900
|
+
});
|
|
2901
|
+
}, [archived, automations, presentIds, runs, sortDirection, sortKey]);
|
|
2902
|
+
const scheduleSummaries = (0, import_react7.useMemo)(() => new Map(automations.map((item) => [item.id, formatSchedule(item.schedule, t)])), [automations, t]);
|
|
2903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-overview", children: [
|
|
2904
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-overview-head", children: [
|
|
2905
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dsh-st-overview-title", children: [
|
|
2906
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: t("sidebar.viewOverview") }),
|
|
2907
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-label": `${rows.length}`, children: rows.length })
|
|
2908
|
+
] }),
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2910
|
+
SortMenu,
|
|
2911
|
+
{
|
|
2912
|
+
t,
|
|
2913
|
+
compact: true,
|
|
2914
|
+
iconOnly: true,
|
|
2915
|
+
className: "dsh-st-overview-sort",
|
|
2916
|
+
...SORT_STORAGE2 === void 0 ? {} : { storage: SORT_STORAGE2 },
|
|
2917
|
+
storageKey: OVERVIEW_SORT_DEFAULT_KEY,
|
|
2918
|
+
sortKey,
|
|
2919
|
+
sortDirection,
|
|
2920
|
+
onSelect: (key, direction) => {
|
|
2921
|
+
setSortKey(key);
|
|
2922
|
+
setSortDirection(direction);
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
)
|
|
2926
|
+
] }),
|
|
2927
|
+
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))
|
|
2928
|
+
] });
|
|
2929
|
+
}
|
|
2930
|
+
function OverviewRow({
|
|
2931
|
+
t,
|
|
2932
|
+
row,
|
|
2933
|
+
now,
|
|
2934
|
+
scheduleSummary,
|
|
2935
|
+
openSession
|
|
2936
|
+
}) {
|
|
2937
|
+
const paused = row.status !== "active";
|
|
2938
|
+
const nextRun = row.nextRunAt === void 0 ? t("stats.noneScheduled") : formatWithin(row.nextRunAt, now, t);
|
|
2939
|
+
const status = paused ? t("status.paused") : t("status.active");
|
|
2940
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2941
|
+
"button",
|
|
2942
|
+
{
|
|
2943
|
+
type: "button",
|
|
2944
|
+
className: `dsh-st-overview-row${paused ? " is-paused" : ""}`,
|
|
2945
|
+
disabled: row.lastSessionId === void 0,
|
|
2946
|
+
title: paused ? t("status.paused") : t("status.active"),
|
|
2947
|
+
onClick: () => {
|
|
2948
|
+
if (row.lastSessionId !== void 0) openSession?.(row.lastSessionId);
|
|
2949
|
+
},
|
|
2950
|
+
children: [
|
|
2951
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-copy", children: [
|
|
2952
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-status", children: [
|
|
2953
|
+
paused ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PauseIcon, { width: 14, height: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckIcon, { width: 14, height: 14 }),
|
|
2954
|
+
status
|
|
2955
|
+
] }),
|
|
2956
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dsh-st-overview-name", children: row.name }),
|
|
2957
|
+
scheduleSummary !== "" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-schedule", children: [
|
|
2958
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CalendarIcon, { width: 14, height: 14 }),
|
|
2959
|
+
scheduleSummary
|
|
2960
|
+
] })
|
|
2961
|
+
] }),
|
|
2962
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dsh-st-overview-next", children: [
|
|
2963
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: t("stats.next") }),
|
|
2964
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: nextRun })
|
|
2965
|
+
] }),
|
|
2966
|
+
row.lastSessionId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronIcon, { width: 12, height: 12, className: "dsh-st-overview-chevron" })
|
|
2967
|
+
]
|
|
2968
|
+
}
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2506
2972
|
// src/client/workspace-toolbar.tsx
|
|
2507
|
-
var
|
|
2508
|
-
var
|
|
2973
|
+
var import_react8 = require("react");
|
|
2974
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2509
2975
|
function officialSearchIconSize(expanded) {
|
|
2510
2976
|
return expanded ? 11 : 14;
|
|
2511
2977
|
}
|
|
@@ -2518,15 +2984,15 @@ function WorkspaceToolbar({
|
|
|
2518
2984
|
onSortChange,
|
|
2519
2985
|
onGroupModeChange
|
|
2520
2986
|
}) {
|
|
2521
|
-
const [searching, setSearching] = (0,
|
|
2522
|
-
const [filterOpen, setFilterOpen] = (0,
|
|
2523
|
-
const inputRef = (0,
|
|
2524
|
-
const rootRef = (0,
|
|
2987
|
+
const [searching, setSearching] = (0, import_react8.useState)(query.trim() !== "");
|
|
2988
|
+
const [filterOpen, setFilterOpen] = (0, import_react8.useState)(false);
|
|
2989
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
2990
|
+
const rootRef = (0, import_react8.useRef)(null);
|
|
2525
2991
|
const searchSize = officialSearchIconSize(searching);
|
|
2526
|
-
(0,
|
|
2992
|
+
(0, import_react8.useEffect)(() => {
|
|
2527
2993
|
if (searching) inputRef.current?.focus();
|
|
2528
2994
|
}, [searching]);
|
|
2529
|
-
(0,
|
|
2995
|
+
(0, import_react8.useEffect)(() => {
|
|
2530
2996
|
if (!filterOpen) return;
|
|
2531
2997
|
const close = (event) => {
|
|
2532
2998
|
const target = event.target;
|
|
@@ -2544,37 +3010,37 @@ function WorkspaceToolbar({
|
|
|
2544
3010
|
onQueryChange("");
|
|
2545
3011
|
setSearching(false);
|
|
2546
3012
|
};
|
|
2547
|
-
return /* @__PURE__ */ (0,
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2551
|
-
/* @__PURE__ */ (0,
|
|
3013
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: searching ? "dsh-st-n-toolbar is-search" : "dsh-st-n-toolbar", ref: rootRef, children: [
|
|
3014
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "dsh-st-n-head-label", children: t("sidebar.workspaces") }),
|
|
3015
|
+
/* @__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: [
|
|
3016
|
+
/* @__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 }) }),
|
|
3017
|
+
/* @__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) => {
|
|
2552
3018
|
if (event.key === "Escape") closeSearch();
|
|
2553
3019
|
} }),
|
|
2554
|
-
searching && /* @__PURE__ */ (0,
|
|
3020
|
+
searching && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "dsh-st-n-search-clear", "aria-label": t("sidebar.clearSearch"), onClick: (event) => {
|
|
2555
3021
|
event.stopPropagation();
|
|
2556
3022
|
closeSearch();
|
|
2557
|
-
}, children: /* @__PURE__ */ (0,
|
|
3023
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseOutlineIcon, { width: 14, height: 14 }) })
|
|
2558
3024
|
] }) }),
|
|
2559
|
-
/* @__PURE__ */ (0,
|
|
2560
|
-
/* @__PURE__ */ (0,
|
|
2561
|
-
filterOpen && /* @__PURE__ */ (0,
|
|
2562
|
-
/* @__PURE__ */ (0,
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
3025
|
+
/* @__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: [
|
|
3026
|
+
/* @__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 }) }),
|
|
3027
|
+
filterOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dsh-st-n-filter-menu", role: "menu", children: [
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.groupBy") }),
|
|
3029
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.groupWorkspace"), selected: groupMode === "workspace", onSelect: () => {
|
|
2564
3030
|
onGroupModeChange("workspace");
|
|
2565
3031
|
setFilterOpen(false);
|
|
2566
3032
|
} }),
|
|
2567
|
-
/* @__PURE__ */ (0,
|
|
3033
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.groupList"), selected: groupMode === "list", onSelect: () => {
|
|
2568
3034
|
onGroupModeChange("list");
|
|
2569
3035
|
setFilterOpen(false);
|
|
2570
3036
|
} }),
|
|
2571
|
-
/* @__PURE__ */ (0,
|
|
2572
|
-
/* @__PURE__ */ (0,
|
|
2573
|
-
/* @__PURE__ */ (0,
|
|
3037
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-filter-split" }),
|
|
3038
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.sortBy") }),
|
|
3039
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.sortManual"), selected: sort === "manual", onSelect: () => {
|
|
2574
3040
|
onSortChange("manual");
|
|
2575
3041
|
setFilterOpen(false);
|
|
2576
3042
|
} }),
|
|
2577
|
-
/* @__PURE__ */ (0,
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FilterRow, { label: t("sidebar.sortTime"), selected: sort === "time", onSelect: () => {
|
|
2578
3044
|
onSortChange("time");
|
|
2579
3045
|
setFilterOpen(false);
|
|
2580
3046
|
} })
|
|
@@ -2587,34 +3053,40 @@ function FilterRow({
|
|
|
2587
3053
|
selected,
|
|
2588
3054
|
onSelect
|
|
2589
3055
|
}) {
|
|
2590
|
-
return /* @__PURE__ */ (0,
|
|
2591
|
-
/* @__PURE__ */ (0,
|
|
2592
|
-
selected ? /* @__PURE__ */ (0,
|
|
3056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { type: "button", role: "menuitemradio", "aria-checked": selected, className: selected ? "is-on" : void 0, onClick: onSelect, children: [
|
|
3057
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: label }),
|
|
3058
|
+
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" })
|
|
2593
3059
|
] });
|
|
2594
3060
|
}
|
|
2595
3061
|
|
|
2596
3062
|
// src/client/native-session-list.tsx
|
|
2597
|
-
var
|
|
3063
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2598
3064
|
var EMPTY_SESSION_BY_ID = {};
|
|
2599
3065
|
function NativeScheduleSessionList(props) {
|
|
2600
|
-
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession, forkSession } = props;
|
|
2601
|
-
const state = (0,
|
|
3066
|
+
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession, forkSession, openTaskSettings } = props;
|
|
3067
|
+
const state = (0, import_react9.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
2602
3068
|
const selectedId = useSessions ? useSessions((snap) => snap?.current ?? null) : null;
|
|
2603
3069
|
const sessionById = useSessions ? useSessions((snap) => snap?.byId ?? EMPTY_SESSION_BY_ID) : EMPTY_SESSION_BY_ID;
|
|
2604
3070
|
const archivedIds = useWorkspaces ? useWorkspaces((snap) => snap?.archivedSessionIds ?? []) : [];
|
|
2605
|
-
const [folded, setFolded] = (0,
|
|
2606
|
-
const [openMenu, setOpenMenu] = (0,
|
|
2607
|
-
const [
|
|
2608
|
-
const [
|
|
2609
|
-
const [
|
|
2610
|
-
const
|
|
3071
|
+
const [folded, setFolded] = (0, import_react9.useState)({});
|
|
3072
|
+
const [openMenu, setOpenMenu] = (0, import_react9.useState)(null);
|
|
3073
|
+
const [openGroupMenu, setOpenGroupMenu] = (0, import_react9.useState)();
|
|
3074
|
+
const [archiveGroupTarget, setArchiveGroupTarget] = (0, import_react9.useState)();
|
|
3075
|
+
const [archiveGroupBusy, setArchiveGroupBusy] = (0, import_react9.useState)(false);
|
|
3076
|
+
const [archiveGroupError, setArchiveGroupError] = (0, import_react9.useState)();
|
|
3077
|
+
const [archiveManagerInstalled, setArchiveManagerInstalled] = (0, import_react9.useState)(() => typeof document !== "undefined" && hasArchiveManagerPlugin(document));
|
|
3078
|
+
const [query, setQuery] = (0, import_react9.useState)("");
|
|
3079
|
+
const [sort, setSort] = (0, import_react9.useState)("time");
|
|
3080
|
+
const [groupMode, setGroupMode] = (0, import_react9.useState)("workspace");
|
|
3081
|
+
const [view, setView] = (0, import_react9.useState)("runs");
|
|
3082
|
+
const archived = (0, import_react9.useMemo)(() => new Set(archivedIds), [archivedIds]);
|
|
2611
3083
|
const listedIds = useSessions ? useSessions((snap) => Array.isArray(snap?.ids) ? snap.ids : void 0) : void 0;
|
|
2612
|
-
const presentIds = (0,
|
|
3084
|
+
const presentIds = (0, import_react9.useMemo)(() => {
|
|
2613
3085
|
if (listedIds !== void 0) return new Set(listedIds);
|
|
2614
3086
|
const keys = Object.keys(sessionById);
|
|
2615
3087
|
return keys.length > 0 ? new Set(keys) : void 0;
|
|
2616
3088
|
}, [listedIds, sessionById]);
|
|
2617
|
-
const groups = (0,
|
|
3089
|
+
const groups = (0, import_react9.useMemo)(() => {
|
|
2618
3090
|
const snapshot = state.snapshot;
|
|
2619
3091
|
if (snapshot === void 0) return [];
|
|
2620
3092
|
return groupScheduledSessions(snapshot.automations, snapshot.runs).map((group) => ({
|
|
@@ -2630,63 +3102,212 @@ function NativeScheduleSessionList(props) {
|
|
|
2630
3102
|
})
|
|
2631
3103
|
})).filter((group) => group.sessions.length > 0);
|
|
2632
3104
|
}, [archived, presentIds, sessionById, state.snapshot]);
|
|
2633
|
-
const visibleGroups = (0,
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
3105
|
+
const visibleGroups = (0, import_react9.useMemo)(() => applyWorkspaceBrowserQuery(groups.map((group) => ({ ...group, name: group.name })), query, sort, groupMode), [groups, query, sort, groupMode]);
|
|
3106
|
+
(0, import_react9.useEffect)(() => {
|
|
3107
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
|
|
3108
|
+
const refresh = () => {
|
|
3109
|
+
setArchiveManagerInstalled(hasArchiveManagerPlugin(document));
|
|
3110
|
+
};
|
|
3111
|
+
refresh();
|
|
3112
|
+
const observer = new MutationObserver(refresh);
|
|
3113
|
+
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
3114
|
+
return () => {
|
|
3115
|
+
observer.disconnect();
|
|
3116
|
+
};
|
|
3117
|
+
}, []);
|
|
3118
|
+
const canArchiveGroup = archiveManagerInstalled && archiveSession !== void 0;
|
|
3119
|
+
const confirmArchiveGroup = () => {
|
|
3120
|
+
if (archiveGroupTarget === void 0 || archiveSession === void 0 || archiveGroupBusy) return;
|
|
3121
|
+
const target = archiveGroupTarget;
|
|
3122
|
+
setArchiveGroupBusy(true);
|
|
3123
|
+
setArchiveGroupError(void 0);
|
|
3124
|
+
void archiveScheduledGroup(target.sessionIds, archiveSession).then(() => {
|
|
3125
|
+
setArchiveGroupTarget(void 0);
|
|
3126
|
+
}).catch((caught) => {
|
|
3127
|
+
setArchiveGroupError(caught instanceof Error ? caught.message : t("error.action"));
|
|
3128
|
+
}).finally(() => {
|
|
3129
|
+
setArchiveGroupBusy(false);
|
|
3130
|
+
});
|
|
3131
|
+
};
|
|
3132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n", children: [
|
|
3133
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScheduleViewSwitch, { t, view, onChange: setView }),
|
|
3134
|
+
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)(
|
|
3135
|
+
ScheduleOverview,
|
|
3136
|
+
{
|
|
3137
|
+
t,
|
|
3138
|
+
automations: state.snapshot.automations,
|
|
3139
|
+
runs: state.snapshot.runs,
|
|
3140
|
+
...openSession === void 0 ? {} : { openSession },
|
|
3141
|
+
...state.snapshot.serverNow === void 0 ? {} : { serverNow: state.snapshot.serverNow },
|
|
3142
|
+
archived,
|
|
3143
|
+
...presentIds === void 0 ? {} : { presentIds }
|
|
3144
|
+
}
|
|
3145
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
3146
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(WorkspaceToolbar, { t, query, sort, groupMode, onQueryChange: setQuery, onSortChange: setSort, onGroupModeChange: setGroupMode }),
|
|
3147
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-tree", role: "tree", children: [
|
|
3148
|
+
state.phase === "loading" && visibleGroups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-empty", children: t("loading") }),
|
|
3149
|
+
visibleGroups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-empty", children: t("sidebar.empty") }),
|
|
3150
|
+
visibleGroups.map((group) => {
|
|
3151
|
+
const expanded = folded[group.id] !== true;
|
|
3152
|
+
const hasCurrentSession = scheduledGroupShowsActiveFolder(expanded, group.sessions.map((session) => session.id), selectedId);
|
|
3153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-group", children: [
|
|
3154
|
+
groupMode === "workspace" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3155
|
+
NativeScheduleGroupRow,
|
|
3156
|
+
{
|
|
3157
|
+
t,
|
|
3158
|
+
id: group.id,
|
|
3159
|
+
name: group.name,
|
|
3160
|
+
sessionIds: group.sessions.map((session) => session.id),
|
|
3161
|
+
expanded,
|
|
3162
|
+
hasCurrentSession,
|
|
3163
|
+
menuOpen: openGroupMenu === group.id,
|
|
3164
|
+
canArchiveGroup,
|
|
3165
|
+
onToggle: () => setFolded((current) => ({ ...current, [group.id]: expanded })),
|
|
3166
|
+
onMenuChange: (open) => {
|
|
3167
|
+
setOpenMenu(null);
|
|
3168
|
+
setOpenGroupMenu(open ? group.id : void 0);
|
|
3169
|
+
},
|
|
3170
|
+
onTaskSettings: () => {
|
|
3171
|
+
openTaskSettings?.({ automationId: group.id, name: group.name, sessionIds: group.sessions.map((session) => session.id) });
|
|
3172
|
+
},
|
|
3173
|
+
onArchiveGroup: () => {
|
|
3174
|
+
setArchiveGroupError(void 0);
|
|
3175
|
+
setArchiveGroupTarget({ id: group.id, name: group.name, sessionIds: group.sessions.map((session) => session.id) });
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
),
|
|
3179
|
+
(groupMode === "list" || expanded) && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3180
|
+
NativeSessionRow,
|
|
3181
|
+
{
|
|
3182
|
+
t,
|
|
3183
|
+
id: session.id,
|
|
3184
|
+
title: session.title,
|
|
3185
|
+
hoverTitle: String(sessionById[session.id]?.displayTitle ?? sessionById[session.id]?.title ?? group.name),
|
|
3186
|
+
updatedAt: session.updatedAt,
|
|
3187
|
+
running: session.running,
|
|
3188
|
+
selected: selectedId === session.id,
|
|
3189
|
+
menuOpen: openMenu?.id === session.id,
|
|
3190
|
+
menuPoint: openMenu === null || openMenu.id !== session.id ? { x: 8, y: 8 } : { x: openMenu.x, y: openMenu.y },
|
|
3191
|
+
onToggleMenu: (event) => {
|
|
3192
|
+
setOpenGroupMenu(void 0);
|
|
3193
|
+
setOpenMenu((current) => nextOpenSessionMenu(current, session.id, pointerPoint(event)));
|
|
3194
|
+
},
|
|
3195
|
+
onCloseMenu: () => setOpenMenu((current) => current?.id === session.id ? null : current),
|
|
3196
|
+
onOpen: () => {
|
|
3197
|
+
setOpenMenu(null);
|
|
3198
|
+
openSession?.(session.id);
|
|
3199
|
+
},
|
|
3200
|
+
...renameSession === void 0 ? {} : { renameSession },
|
|
3201
|
+
...archiveSession === void 0 ? {} : { archiveSession },
|
|
3202
|
+
...forkSession === void 0 ? {} : { forkSession }
|
|
2663
3203
|
},
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
3204
|
+
session.id
|
|
3205
|
+
))
|
|
3206
|
+
] }, group.id);
|
|
3207
|
+
})
|
|
3208
|
+
] })
|
|
3209
|
+
] }),
|
|
3210
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3211
|
+
import_dsh_client_ui_primitives2.Modal,
|
|
3212
|
+
{
|
|
3213
|
+
open: archiveGroupTarget !== void 0,
|
|
3214
|
+
onClose: () => {
|
|
3215
|
+
if (archiveGroupBusy) return;
|
|
3216
|
+
setArchiveGroupTarget(void 0);
|
|
3217
|
+
setArchiveGroupError(void 0);
|
|
3218
|
+
},
|
|
3219
|
+
closeLabel: t("session.archiveGroupClose"),
|
|
3220
|
+
title: t("session.archiveGroup"),
|
|
3221
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-dialog-actions", children: [
|
|
3222
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.Button, { variant: "outline", disabled: archiveGroupBusy, onClick: () => {
|
|
3223
|
+
setArchiveGroupTarget(void 0);
|
|
3224
|
+
setArchiveGroupError(void 0);
|
|
3225
|
+
}, children: t("session.archiveGroupCancel") }),
|
|
3226
|
+
/* @__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") })
|
|
3227
|
+
] }),
|
|
3228
|
+
children: [
|
|
3229
|
+
/* @__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 }) }),
|
|
3230
|
+
archiveGroupBusy && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-dialog-status", role: "status", children: t("session.archiveGroupPending") }),
|
|
3231
|
+
archiveGroupError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-dialog-error", role: "alert", children: t("session.archiveGroupFailed", { message: archiveGroupError }) })
|
|
3232
|
+
]
|
|
3233
|
+
}
|
|
3234
|
+
)
|
|
2673
3235
|
] });
|
|
2674
3236
|
}
|
|
3237
|
+
function NativeScheduleGroupRow(props) {
|
|
3238
|
+
const { t, id, name: name2, expanded, hasCurrentSession, menuOpen, canArchiveGroup, onToggle, onMenuChange, onTaskSettings, onArchiveGroup } = props;
|
|
3239
|
+
const items = [
|
|
3240
|
+
{ id: "task-settings", label: t("session.taskSettings"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.IconSettingsOutline16, { size: 16 }) },
|
|
3241
|
+
...canArchiveGroup ? [
|
|
3242
|
+
{ type: "separator", id: "archive-separator" },
|
|
3243
|
+
{ id: "archive-group", label: t("session.archiveGroup"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.IconArchiveOutline20, { size: 16 }), danger: true }
|
|
3244
|
+
] : []
|
|
3245
|
+
];
|
|
3246
|
+
const rowClass = "dsh-st-n-row" + (hasCurrentSession ? " has-current-session" : "") + (menuOpen ? " is-menu" : "");
|
|
3247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3248
|
+
"div",
|
|
3249
|
+
{
|
|
3250
|
+
className: rowClass,
|
|
3251
|
+
role: "treeitem",
|
|
3252
|
+
"aria-expanded": expanded,
|
|
3253
|
+
"data-n-group": id,
|
|
3254
|
+
onClick: onToggle,
|
|
3255
|
+
children: [
|
|
3256
|
+
/* @__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 }) }),
|
|
3257
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-title", children: name2 }),
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-acts", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3259
|
+
import_dsh_client_ui_primitives2.Menu,
|
|
3260
|
+
{
|
|
3261
|
+
open: menuOpen,
|
|
3262
|
+
onClose: () => {
|
|
3263
|
+
onMenuChange(false);
|
|
3264
|
+
},
|
|
3265
|
+
items,
|
|
3266
|
+
onSelect: (action) => {
|
|
3267
|
+
onMenuChange(false);
|
|
3268
|
+
if (action === "task-settings") onTaskSettings();
|
|
3269
|
+
if (action === "archive-group") onArchiveGroup();
|
|
3270
|
+
},
|
|
3271
|
+
portal: true,
|
|
3272
|
+
dense: true,
|
|
3273
|
+
compact: true,
|
|
3274
|
+
anchor: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3275
|
+
"button",
|
|
3276
|
+
{
|
|
3277
|
+
type: "button",
|
|
3278
|
+
className: "dsh-st-n-ico",
|
|
3279
|
+
"aria-label": t("session.groupActions", { name: name2 }),
|
|
3280
|
+
onMouseDown: (event) => {
|
|
3281
|
+
event.stopPropagation();
|
|
3282
|
+
},
|
|
3283
|
+
onClick: (event) => {
|
|
3284
|
+
event.stopPropagation();
|
|
3285
|
+
onMenuChange(!menuOpen);
|
|
3286
|
+
},
|
|
3287
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives2.IconEllipsisOutline16, { size: 16 })
|
|
3288
|
+
}
|
|
3289
|
+
)
|
|
3290
|
+
}
|
|
3291
|
+
) })
|
|
3292
|
+
]
|
|
3293
|
+
}
|
|
3294
|
+
);
|
|
3295
|
+
}
|
|
2675
3296
|
function NativeSessionRow(props) {
|
|
2676
3297
|
const { t, id, title, hoverTitle, updatedAt, running, selected, menuOpen, menuPoint, onToggleMenu, onCloseMenu, onOpen, renameSession, archiveSession, forkSession } = props;
|
|
2677
|
-
const rowRef = (0,
|
|
2678
|
-
const menuRef = (0,
|
|
2679
|
-
const hoverRef = (0,
|
|
2680
|
-
const [hoverOpen, setHoverOpen] = (0,
|
|
2681
|
-
const [hoverStyle, setHoverStyle] = (0,
|
|
2682
|
-
const hoverTimer = (0,
|
|
2683
|
-
const [renaming, setRenaming] = (0,
|
|
2684
|
-
const [draft, setDraft] = (0,
|
|
2685
|
-
const [menuStyle, setMenuStyle] = (0,
|
|
2686
|
-
(0,
|
|
3298
|
+
const rowRef = (0, import_react9.useRef)(null);
|
|
3299
|
+
const menuRef = (0, import_react9.useRef)(null);
|
|
3300
|
+
const hoverRef = (0, import_react9.useRef)(null);
|
|
3301
|
+
const [hoverOpen, setHoverOpen] = (0, import_react9.useState)(false);
|
|
3302
|
+
const [hoverStyle, setHoverStyle] = (0, import_react9.useState)({});
|
|
3303
|
+
const hoverTimer = (0, import_react9.useRef)(void 0);
|
|
3304
|
+
const [renaming, setRenaming] = (0, import_react9.useState)(false);
|
|
3305
|
+
const [draft, setDraft] = (0, import_react9.useState)(title);
|
|
3306
|
+
const [menuStyle, setMenuStyle] = (0, import_react9.useState)({});
|
|
3307
|
+
(0, import_react9.useEffect)(() => {
|
|
2687
3308
|
setDraft(title);
|
|
2688
3309
|
}, [title]);
|
|
2689
|
-
(0,
|
|
3310
|
+
(0, import_react9.useEffect)(() => {
|
|
2690
3311
|
if (!menuOpen) return;
|
|
2691
3312
|
const close = (event) => {
|
|
2692
3313
|
if (!shouldCloseNativeSessionMenu(event.target, [rowRef.current, menuRef.current])) return;
|
|
@@ -2702,7 +3323,7 @@ function NativeSessionRow(props) {
|
|
|
2702
3323
|
document.removeEventListener("keydown", onKey);
|
|
2703
3324
|
};
|
|
2704
3325
|
}, [menuOpen, onCloseMenu]);
|
|
2705
|
-
(0,
|
|
3326
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
2706
3327
|
if (!menuOpen) return;
|
|
2707
3328
|
const update = () => {
|
|
2708
3329
|
const el = menuRef.current;
|
|
@@ -2717,7 +3338,7 @@ function NativeSessionRow(props) {
|
|
|
2717
3338
|
document.removeEventListener("scroll", update, true);
|
|
2718
3339
|
};
|
|
2719
3340
|
}, [menuOpen, menuPoint]);
|
|
2720
|
-
(0,
|
|
3341
|
+
(0, import_react9.useEffect)(() => {
|
|
2721
3342
|
if (!hoverOpen || menuOpen) return;
|
|
2722
3343
|
const update = () => {
|
|
2723
3344
|
const row = rowRef.current?.getBoundingClientRect();
|
|
@@ -2734,7 +3355,7 @@ function NativeSessionRow(props) {
|
|
|
2734
3355
|
document.removeEventListener("scroll", update, true);
|
|
2735
3356
|
};
|
|
2736
3357
|
}, [hoverOpen, menuOpen, title, updatedAt, running]);
|
|
2737
|
-
(0,
|
|
3358
|
+
(0, import_react9.useEffect)(() => () => {
|
|
2738
3359
|
if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
|
|
2739
3360
|
}, []);
|
|
2740
3361
|
const run = (action) => {
|
|
@@ -2751,7 +3372,7 @@ function NativeSessionRow(props) {
|
|
|
2751
3372
|
};
|
|
2752
3373
|
const rowClass = "dsh-st-n-sess" + (selected ? " is-on" : "") + (menuOpen ? " is-menu" : "");
|
|
2753
3374
|
if (renaming) {
|
|
2754
|
-
return /* @__PURE__ */ (0,
|
|
3375
|
+
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) => {
|
|
2755
3376
|
if (event.key === "Enter") {
|
|
2756
3377
|
event.preventDefault();
|
|
2757
3378
|
setRenaming(false);
|
|
@@ -2768,23 +3389,23 @@ function NativeSessionRow(props) {
|
|
|
2768
3389
|
} }) });
|
|
2769
3390
|
}
|
|
2770
3391
|
const menuItems = [
|
|
2771
|
-
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0,
|
|
3392
|
+
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PencilIcon, { width: 16, height: 16 }), go: () => {
|
|
2772
3393
|
setRenaming(true);
|
|
2773
3394
|
} },
|
|
2774
|
-
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0,
|
|
2775
|
-
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0,
|
|
3395
|
+
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BranchIcon, { width: 16, height: 16 }), go: () => run(() => forkSession?.(id)) },
|
|
3396
|
+
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ArchiveIcon, { width: 16, height: 16 }), go: () => run(() => archiveSession?.(id)) }
|
|
2776
3397
|
];
|
|
2777
|
-
const menu = menuOpen && typeof document !== "undefined" ? (0,
|
|
2778
|
-
/* @__PURE__ */ (0,
|
|
3398
|
+
const menu = menuOpen && typeof document !== "undefined" ? (0, import_react_dom3.createPortal)(
|
|
3399
|
+
/* @__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: () => {
|
|
2779
3400
|
onCloseMenu();
|
|
2780
3401
|
item.go();
|
|
2781
3402
|
}, children: [
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-mi", children: item.icon }),
|
|
2783
3404
|
item.label
|
|
2784
3405
|
] }, item.id)) }),
|
|
2785
3406
|
document.body
|
|
2786
3407
|
) : null;
|
|
2787
|
-
return /* @__PURE__ */ (0,
|
|
3408
|
+
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) => {
|
|
2788
3409
|
if (event.key === "Enter" || event.key === " ") {
|
|
2789
3410
|
event.preventDefault();
|
|
2790
3411
|
onOpen();
|
|
@@ -2794,21 +3415,21 @@ function NativeSessionRow(props) {
|
|
|
2794
3415
|
event.stopPropagation();
|
|
2795
3416
|
onToggleMenu(event);
|
|
2796
3417
|
}, children: [
|
|
2797
|
-
/* @__PURE__ */ (0,
|
|
2798
|
-
/* @__PURE__ */ (0,
|
|
2799
|
-
/* @__PURE__ */ (0,
|
|
2800
|
-
/* @__PURE__ */ (0,
|
|
3418
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-slot", children: running ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RunningStateDot, {}) : null }),
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-title", children: title }),
|
|
3420
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dsh-st-n-time", children: relativeTime(updatedAt, t) }),
|
|
3421
|
+
/* @__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": title + " \u66F4\u591A", onMouseDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
2801
3422
|
event.stopPropagation();
|
|
2802
3423
|
hideHover();
|
|
2803
3424
|
onToggleMenu(event);
|
|
2804
|
-
}, children: /* @__PURE__ */ (0,
|
|
3425
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(EllipsisIcon, { width: 16, height: 16 }) }) }),
|
|
2805
3426
|
menu,
|
|
2806
|
-
hoverOpen && !menuOpen && typeof document !== "undefined" && (0,
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
2808
|
-
/* @__PURE__ */ (0,
|
|
2809
|
-
/* @__PURE__ */ (0,
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
3427
|
+
hoverOpen && !menuOpen && typeof document !== "undefined" && (0, import_react_dom3.createPortal)(
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref: hoverRef, className: "dsh-st-n-hover", style: hoverStyle, onMouseEnter: showHover, onMouseLeave: hideHover, children: [
|
|
3429
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-hover-title", children: (hoverTitle ?? title).trim() || title }),
|
|
3430
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dsh-st-n-hover-time", children: relativeTime(updatedAt, t) }),
|
|
3431
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dsh-st-n-hover-state", children: [
|
|
3432
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: running ? "dsh-st-n-hover-dot is-run" : "dsh-st-n-hover-dot" }),
|
|
2812
3433
|
running ? t("session.runningStatus") : t("session.idle")
|
|
2813
3434
|
] })
|
|
2814
3435
|
] }),
|
|
@@ -2818,11 +3439,11 @@ function NativeSessionRow(props) {
|
|
|
2818
3439
|
}
|
|
2819
3440
|
|
|
2820
3441
|
// src/client/ScheduleRail.tsx
|
|
2821
|
-
var
|
|
2822
|
-
var
|
|
3442
|
+
var import_react10 = require("react");
|
|
3443
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2823
3444
|
var EMPTY_EXTRA_TABS = [];
|
|
2824
3445
|
var noopSubscribe = (_listener) => () => void 0;
|
|
2825
|
-
var OfficialTreeGuard = class extends
|
|
3446
|
+
var OfficialTreeGuard = class extends import_react10.Component {
|
|
2826
3447
|
state = { failed: false };
|
|
2827
3448
|
static getDerivedStateFromError() {
|
|
2828
3449
|
return { failed: true };
|
|
@@ -2837,45 +3458,61 @@ var OfficialTreeGuard = class extends import_react6.Component {
|
|
|
2837
3458
|
function ScheduleRail({
|
|
2838
3459
|
t,
|
|
2839
3460
|
runtime,
|
|
2840
|
-
openSession
|
|
3461
|
+
openSession,
|
|
3462
|
+
view: controlledView,
|
|
3463
|
+
showViewSwitch = true
|
|
2841
3464
|
}) {
|
|
2842
|
-
const state = (0,
|
|
2843
|
-
const [folded, setFolded] = (0,
|
|
2844
|
-
const
|
|
2845
|
-
|
|
3465
|
+
const state = (0, import_react10.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
3466
|
+
const [folded, setFolded] = (0, import_react10.useState)({});
|
|
3467
|
+
const [localView, setLocalView] = (0, import_react10.useState)("runs");
|
|
3468
|
+
const view = controlledView ?? localView;
|
|
3469
|
+
const snapshot = state.snapshot;
|
|
3470
|
+
const groups = (0, import_react10.useMemo)(() => {
|
|
2846
3471
|
if (snapshot === void 0) return [];
|
|
2847
3472
|
return groupScheduledSessions(snapshot.automations, snapshot.runs);
|
|
2848
|
-
}, [
|
|
2849
|
-
return /* @__PURE__ */ (0,
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
session.
|
|
2877
|
-
|
|
2878
|
-
|
|
3473
|
+
}, [snapshot]);
|
|
3474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-st-rail", children: [
|
|
3475
|
+
showViewSwitch && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScheduleViewSwitch, { t, view, onChange: setLocalView }),
|
|
3476
|
+
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)(
|
|
3477
|
+
ScheduleOverview,
|
|
3478
|
+
{
|
|
3479
|
+
t,
|
|
3480
|
+
automations: snapshot.automations,
|
|
3481
|
+
runs: snapshot.runs,
|
|
3482
|
+
...openSession === void 0 ? {} : { openSession },
|
|
3483
|
+
...snapshot.serverNow === void 0 ? {} : { serverNow: snapshot.serverNow }
|
|
3484
|
+
}
|
|
3485
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3486
|
+
state.phase === "loading" && groups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: t("loading") }),
|
|
3487
|
+
groups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.empty") }),
|
|
3488
|
+
groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
3489
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3490
|
+
"button",
|
|
3491
|
+
{
|
|
3492
|
+
type: "button",
|
|
3493
|
+
className: "dsh-st-rail-head",
|
|
3494
|
+
onClick: () => setFolded((current) => ({ ...current, [group.id]: !current[group.id] })),
|
|
3495
|
+
children: [
|
|
3496
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dsh-st-rail-folder", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ClockIcon, { width: 16, height: 16 }) }),
|
|
3497
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dsh-st-rail-title", children: group.name })
|
|
3498
|
+
]
|
|
3499
|
+
}
|
|
3500
|
+
),
|
|
3501
|
+
folded[group.id] !== true && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3502
|
+
"button",
|
|
3503
|
+
{
|
|
3504
|
+
type: "button",
|
|
3505
|
+
className: "dsh-st-rail-session",
|
|
3506
|
+
onClick: () => openSession?.(session.id),
|
|
3507
|
+
children: [
|
|
3508
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: session.label }),
|
|
3509
|
+
session.running && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RunningStateDot, {})
|
|
3510
|
+
]
|
|
3511
|
+
},
|
|
3512
|
+
session.id
|
|
3513
|
+
))
|
|
3514
|
+
] }, group.id))
|
|
3515
|
+
] })
|
|
2879
3516
|
] });
|
|
2880
3517
|
}
|
|
2881
3518
|
function NativeScheduleShell({
|
|
@@ -2893,19 +3530,19 @@ function NativeScheduleShell({
|
|
|
2893
3530
|
wide
|
|
2894
3531
|
}) {
|
|
2895
3532
|
const Official = officialTree;
|
|
2896
|
-
const [tab, setTab] = (0,
|
|
3533
|
+
const [tab, setTab] = (0, import_react10.useState)(() => {
|
|
2897
3534
|
try {
|
|
2898
3535
|
return readNativeSidebarTab(window.localStorage.getItem(NATIVE_SIDEBAR_TAB_KEY));
|
|
2899
3536
|
} catch {
|
|
2900
3537
|
return "tasks";
|
|
2901
3538
|
}
|
|
2902
3539
|
});
|
|
2903
|
-
const extraTabs = (0,
|
|
3540
|
+
const extraTabs = (0, import_react10.useSyncExternalStore)(
|
|
2904
3541
|
tabRegistry?.subscribe ?? noopSubscribe,
|
|
2905
3542
|
() => tabRegistry?.getTabs() ?? EMPTY_EXTRA_TABS,
|
|
2906
3543
|
() => EMPTY_EXTRA_TABS
|
|
2907
3544
|
);
|
|
2908
|
-
const channelsReady = (0,
|
|
3545
|
+
const channelsReady = (0, import_react10.useSyncExternalStore)(
|
|
2909
3546
|
subscribeChannels ?? noopSubscribe,
|
|
2910
3547
|
() => {
|
|
2911
3548
|
try {
|
|
@@ -2917,25 +3554,25 @@ function NativeScheduleShell({
|
|
|
2917
3554
|
() => false
|
|
2918
3555
|
);
|
|
2919
3556
|
const currentId = useSessions?.((state) => state?.current ?? null);
|
|
2920
|
-
const automationState = (0,
|
|
2921
|
-
const scheduledIds = (0,
|
|
2922
|
-
const useFilteredSessions = (0,
|
|
3557
|
+
const automationState = (0, import_react10.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
3558
|
+
const scheduledIds = (0, import_react10.useMemo)(() => collectScheduledSessionIds(automationState.snapshot?.runs), [automationState.snapshot]);
|
|
3559
|
+
const useFilteredSessions = (0, import_react10.useCallback)((selector, eq) => {
|
|
2923
3560
|
if (useSessions === void 0) return selector({ ids: [], byId: {}, current: null });
|
|
2924
3561
|
return useSessions((state) => selector(filterTaskSessionState(state, scheduledIds)), eq);
|
|
2925
3562
|
}, [useSessions, scheduledIds]);
|
|
2926
|
-
const useFilteredWorkspaces = (0,
|
|
3563
|
+
const useFilteredWorkspaces = (0, import_react10.useCallback)((selector, eq) => {
|
|
2927
3564
|
if (useWorkspaces === void 0) return selector({ items: [], archivedSessionIds: [] });
|
|
2928
3565
|
return useWorkspaces((state) => selector(filterWorkspaceListState(state, scheduledIds)), eq);
|
|
2929
3566
|
}, [useWorkspaces, scheduledIds]);
|
|
2930
|
-
(0,
|
|
3567
|
+
(0, import_react10.useEffect)(() => {
|
|
2931
3568
|
try {
|
|
2932
3569
|
window.localStorage.setItem(NATIVE_SIDEBAR_TAB_KEY, tab);
|
|
2933
3570
|
} catch {
|
|
2934
3571
|
}
|
|
2935
3572
|
}, [tab]);
|
|
2936
|
-
const previousCurrentId = (0,
|
|
2937
|
-
const tabFollowReady = (0,
|
|
2938
|
-
(0,
|
|
3573
|
+
const previousCurrentId = (0, import_react10.useRef)(currentId);
|
|
3574
|
+
const tabFollowReady = (0, import_react10.useRef)(false);
|
|
3575
|
+
(0, import_react10.useEffect)(() => {
|
|
2939
3576
|
if (!tabFollowReady.current) {
|
|
2940
3577
|
tabFollowReady.current = true;
|
|
2941
3578
|
previousCurrentId.current = currentId;
|
|
@@ -2958,11 +3595,11 @@ function NativeScheduleShell({
|
|
|
2958
3595
|
};
|
|
2959
3596
|
const renderOfficial = (props) => {
|
|
2960
3597
|
if (Official === void 0) {
|
|
2961
|
-
return /* @__PURE__ */ (0,
|
|
3598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(NativeTaskRail, { t, ...openSession === void 0 ? {} : { openSession }, ...useSessions === void 0 ? {} : { useSessions: useFilteredSessions }, ...useWorkspaces === void 0 ? {} : { useWorkspaces } });
|
|
2962
3599
|
}
|
|
2963
|
-
return /* @__PURE__ */ (0,
|
|
3600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(OfficialTreeGuard, { fallback: (0, import_react10.createElement)(Official, rawOfficialProps), children: (0, import_react10.createElement)(Official, props) });
|
|
2964
3601
|
};
|
|
2965
|
-
if (wide === false) return /* @__PURE__ */ (0,
|
|
3602
|
+
if (wide === false) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: renderOfficial(filteredOfficialProps) });
|
|
2966
3603
|
const foreignTabs = extraTabs.filter((item) => item.id !== "schedule");
|
|
2967
3604
|
const visibleTab = resolveVisibleSidebarTab({
|
|
2968
3605
|
tab,
|
|
@@ -2970,15 +3607,15 @@ function NativeScheduleShell({
|
|
|
2970
3607
|
extraTabIds: ownedSidebarTabIds({ extraTabIds: foreignTabs.map((item) => item.id), channelsReady })
|
|
2971
3608
|
});
|
|
2972
3609
|
const hostedSchedule = extraTabs.find((item) => item.id === "schedule");
|
|
2973
|
-
const scheduleBody = hostedSchedule === void 0 ? /* @__PURE__ */ (0,
|
|
2974
|
-
return /* @__PURE__ */ (0,
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
2976
|
-
/* @__PURE__ */ (0,
|
|
2977
|
-
foreignTabs.map((item) => /* @__PURE__ */ (0,
|
|
2978
|
-
channelsReady && foreignTabs.every((item) => item.id !== "channels") && /* @__PURE__ */ (0,
|
|
2979
|
-
/* @__PURE__ */ (0,
|
|
3610
|
+
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 });
|
|
3611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-st-shell-rail", children: [
|
|
3612
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dsh-st-shell-tabs", role: "tablist", "aria-label": t("sidebar.tabs"), children: [
|
|
3613
|
+
/* @__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") }),
|
|
3614
|
+
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)),
|
|
3615
|
+
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") }),
|
|
3616
|
+
/* @__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") })
|
|
2980
3617
|
] }),
|
|
2981
|
-
visibleTab === "schedule" ? /* @__PURE__ */ (0,
|
|
3618
|
+
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) })
|
|
2982
3619
|
] });
|
|
2983
3620
|
}
|
|
2984
3621
|
function NativeTaskRail({
|
|
@@ -2990,10 +3627,10 @@ function NativeTaskRail({
|
|
|
2990
3627
|
const snap = useSessions === void 0 ? { ids: [], byId: {}, current: null } : useSessions((state) => state ?? { ids: [], byId: {}, current: null });
|
|
2991
3628
|
const workspaces = useWorkspaces === void 0 ? void 0 : useWorkspaces((state) => state ?? { items: [], archivedSessionIds: [] });
|
|
2992
3629
|
const groups = groupNativeTaskSessions(snap, workspaces, t("sidebar.ungrouped"));
|
|
2993
|
-
if (groups.length === 0) return /* @__PURE__ */ (0,
|
|
2994
|
-
return /* @__PURE__ */ (0,
|
|
2995
|
-
/* @__PURE__ */ (0,
|
|
2996
|
-
group.sessions.map((item) => /* @__PURE__ */ (0,
|
|
3630
|
+
if (groups.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.tasksEmpty") });
|
|
3631
|
+
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: [
|
|
3632
|
+
/* @__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 }) }),
|
|
3633
|
+
group.sessions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2997
3634
|
"button",
|
|
2998
3635
|
{
|
|
2999
3636
|
type: "button",
|
|
@@ -3001,7 +3638,7 @@ function NativeTaskRail({
|
|
|
3001
3638
|
onClick: () => {
|
|
3002
3639
|
if (item.id !== void 0) openSession?.(item.id);
|
|
3003
3640
|
},
|
|
3004
|
-
children: /* @__PURE__ */ (0,
|
|
3641
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: item.title || item.id })
|
|
3005
3642
|
},
|
|
3006
3643
|
item.id
|
|
3007
3644
|
))
|
|
@@ -3020,6 +3657,7 @@ var CSS_TEXT = `
|
|
|
3020
3657
|
.dsh-st-btn,.dsh-st-icon{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:inherit;font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}
|
|
3021
3658
|
.dsh-st-icon{width:32px;padding:0;flex:none}
|
|
3022
3659
|
.dsh-st-btn--primary{border-color:transparent;background:var(--dsw-alias-button-primary-fill,#fff);color:var(--dsw-alias-label-primary-foreground,#111)}
|
|
3660
|
+
.dsh-st-btn--danger{border-color:var(--dsw-alias-state-error-primary,#f85149);background:var(--dsw-alias-state-error-primary,#f85149);color:#fff}
|
|
3023
3661
|
.dsh-st-hint{margin:-6px 0 14px;padding:10px 12px;border-radius:12px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
3024
3662
|
.dsh-st-banner{display:flex;align-items:flex-start;gap:8px;margin-bottom:16px;padding:10px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}
|
|
3025
3663
|
.dsh-st-banner>span{display:inline-flex;align-items:flex-start;gap:8px}
|
|
@@ -3038,16 +3676,33 @@ var CSS_TEXT = `
|
|
|
3038
3676
|
.dsh-st-tabs>button{padding:8px 0;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer}
|
|
3039
3677
|
.dsh-st-tabs>button.is-on{border-bottom-color:currentColor;color:var(--dsw-alias-label-primary);font-weight:650}
|
|
3040
3678
|
.dsh-st-dropdown{position:relative;min-width:0}
|
|
3041
|
-
.dsh-st-sort{margin-left:auto}
|
|
3042
|
-
.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
|
|
3679
|
+
.dsh-st-sort-wrap{display:flex;align-items:center;gap:6px;margin-left:auto}
|
|
3680
|
+
.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}
|
|
3043
3681
|
.dsh-st-dropdown-btn:hover,.dsh-st-dropdown-btn.is-open{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.18))}
|
|
3044
3682
|
.dsh-st-dropdown-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3045
3683
|
.dsh-st-dropdown-chevron{flex:none;transition:transform .16s ease;transform:rotate(90deg)}
|
|
3046
3684
|
.dsh-st-dropdown-btn.is-open .dsh-st-dropdown-chevron{transform:rotate(-90deg)}
|
|
3047
|
-
.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))}
|
|
3048
|
-
.dsh-st-dropdown-menu
|
|
3049
|
-
.dsh-st-dropdown-menu
|
|
3050
|
-
.dsh-st-dropdown-
|
|
3685
|
+
.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))}
|
|
3686
|
+
.dsh-st-dropdown-menu.is-float{position:fixed;right:auto;top:auto;z-index:1200}
|
|
3687
|
+
.dsh-st-dropdown-menu.dsh-st-dropdown-sort{min-width:0;transition:width .12s ease}
|
|
3688
|
+
.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}
|
|
3689
|
+
.dsh-st-dropdown-label-cell{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3690
|
+
.dsh-st-dropdown-row:not(.has-trailing) .dsh-st-dropdown-label-cell{flex:1}
|
|
3691
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-label-cell{flex:none}
|
|
3692
|
+
.dsh-st-dropdown-spacer{min-width:0}
|
|
3693
|
+
.dsh-st-dropdown-row:not(.has-trailing) .dsh-st-dropdown-spacer{flex:0 0 0}
|
|
3694
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-spacer{flex:1 1 auto}
|
|
3695
|
+
.dsh-st-dropdown-row.has-trailing{gap:0}
|
|
3696
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-label-cell{margin-right:8px}
|
|
3697
|
+
.dsh-st-dropdown-row.has-trailing .dsh-st-dropdown-default{margin-right:4px}
|
|
3698
|
+
.dsh-st-dropdown-check{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex:none}
|
|
3699
|
+
.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)}
|
|
3700
|
+
.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}
|
|
3701
|
+
.dsh-st-dropdown-default:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.2))}
|
|
3702
|
+
.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}
|
|
3703
|
+
.dsh-st-dropdown.dsh-st-dropdown-compact .dsh-st-dropdown-btn{font-size:12px;line-height:18px}
|
|
3704
|
+
.dsh-st-dropdown-menu.dsh-st-dropdown-compact .dsh-st-dropdown-row{font-size:12px;line-height:18px}
|
|
3705
|
+
.dsh-st-dropdown-menu.dsh-st-dropdown-compact .dsh-st-dropdown-default{font-size:11px;line-height:16px}
|
|
3051
3706
|
.dsh-st-sort-tick{width:16px;height:16px;flex:none}
|
|
3052
3707
|
.dsh-st-filters{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-left:auto}
|
|
3053
3708
|
.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}
|
|
@@ -3081,6 +3736,7 @@ var CSS_TEXT = `
|
|
|
3081
3736
|
.dsh-st-muted{color:var(--dsw-alias-label-secondary)}
|
|
3082
3737
|
.dsh-st-mask{position:fixed;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:24px;overflow:auto;background:rgba(0,0,0,.45)}.dsh-st-flyout-root{position:absolute;inset:0;z-index:1200;overflow:visible;pointer-events:none}.dsh-st-flyout-root .dsh-st-select-menu,.dsh-st-flyout-root .dsh-st-model-select-menu{pointer-events:auto}
|
|
3083
3738
|
.dsh-st-modal,.dsh-st-modal *{box-sizing:border-box}.dsh-st-modal{display:flex;flex-direction:column;width:min(760px,calc(100vw - 48px));max-width:100%;max-height:min(92vh,900px);overflow:hidden;padding:24px;border:1px solid var(--dsw-alias-border-l2);border-radius:20px;background:var(--dsw-alias-bg-base)}
|
|
3739
|
+
.dsh-st-confirm-modal,.dsh-st-confirm-modal *{box-sizing:border-box}.dsh-st-confirm-modal{width:min(420px,calc(100vw - 48px));padding:24px;border:1px solid var(--dsw-alias-border-l2);border-radius:18px;background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv3,0 12px 36px rgba(0,0,0,.36))}.dsh-st-confirm-modal h2{margin:0 0 10px;font-size:18px}.dsh-st-confirm-modal p{margin:0 0 8px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}.dsh-st-confirm-modal .dsh-st-confirm-target{color:var(--dsw-alias-label-primary);font-weight:600;overflow-wrap:anywhere}
|
|
3084
3740
|
.dsh-st-modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
|
|
3085
3741
|
.dsh-st-modal-head h2{margin:0 0 4px;font-size:20px}
|
|
3086
3742
|
.dsh-st-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px;min-width:0;max-width:100%;font-size:13px}.dsh-st-field:has(.dsh-st-prompt-card){flex:1;min-height:0;margin-bottom:10px}
|
|
@@ -3142,6 +3798,29 @@ var CSS_TEXT = `
|
|
|
3142
3798
|
.dsh-st-menu-split{height:1px;margin:6px 8px;background:rgba(255,255,255,.08)}
|
|
3143
3799
|
.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)}
|
|
3144
3800
|
.dsh-st-subdialog>strong{display:block;margin:0 0 8px;font-size:13px}
|
|
3801
|
+
.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))}
|
|
3802
|
+
.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}
|
|
3803
|
+
.dsh-st-rail-views button:hover{color:var(--dsw-alias-label-primary,inherit)}
|
|
3804
|
+
.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)}
|
|
3805
|
+
.dsh-st-overview{display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto;padding:2px 8px 14px}
|
|
3806
|
+
.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}
|
|
3807
|
+
.dsh-st-overview-title{display:flex;align-items:baseline;min-width:0;gap:6px;color:var(--dsw-alias-label-tertiary,#81858C)}
|
|
3808
|
+
.dsh-st-overview-title strong{font-size:14px;font-weight:400;line-height:20px}
|
|
3809
|
+
.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}
|
|
3810
|
+
.dsh-st-overview-sort{display:flex;align-items:center}
|
|
3811
|
+
.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}
|
|
3812
|
+
.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))}
|
|
3813
|
+
.dsh-st-overview-row:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4c8dff);outline-offset:2px}
|
|
3814
|
+
.dsh-st-overview-row:disabled{cursor:default}
|
|
3815
|
+
.dsh-st-overview-copy{display:flex;flex:1;min-width:0;flex-direction:column;gap:4px}
|
|
3816
|
+
.dsh-st-overview-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;line-height:18px;font-weight:580}
|
|
3817
|
+
.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}
|
|
3818
|
+
.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)}
|
|
3819
|
+
.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}
|
|
3820
|
+
.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}
|
|
3821
|
+
.dsh-st-overview-next strong{color:var(--dsw-alias-label-secondary,#b6bac2);font-size:12px;font-weight:600;line-height:16px;white-space:nowrap}
|
|
3822
|
+
.dsh-st-overview-row:not(.is-paused) .dsh-st-overview-next strong{color:#45d483}
|
|
3823
|
+
.dsh-st-overview-chevron{flex:none;color:var(--dsw-alias-label-tertiary,#8b8f98)}
|
|
3145
3824
|
.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}
|
|
3146
3825
|
.dsh-st-rail-empty{padding:16px 10px;color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:12px}
|
|
3147
3826
|
.dsh-st-rail-group{margin:0 0 8px}
|
|
@@ -3154,14 +3833,26 @@ var CSS_TEXT = `
|
|
|
3154
3833
|
.dsh-st-rail-session span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3155
3834
|
.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}}
|
|
3156
3835
|
.dsh-st-shell-rail{display:flex;flex-direction:column;min-height:0;flex:1;height:100%;overflow:hidden}
|
|
3157
|
-
.dsh-st-shell-tabs{display:flex;flex:none;gap:18px;padding:
|
|
3158
|
-
.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}
|
|
3836
|
+
.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))}
|
|
3837
|
+
.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}
|
|
3159
3838
|
.dsh-st-shell-tabs button.is-on{color:var(--dsw-alias-label-primary,inherit);box-shadow:inset 0 -2px 0 currentColor}
|
|
3160
3839
|
.dsh-st-shell-body{display:flex;min-height:0;flex:1;overflow:hidden}
|
|
3161
3840
|
.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}
|
|
3162
3841
|
.dsh-st-rail-head.is-static{cursor:default;font-weight:600}
|
|
3163
3842
|
.dsh-st-rail-session.is-on{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}
|
|
3164
3843
|
.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}
|
|
3844
|
+
.dsh-st-n-row.is-menu{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}
|
|
3845
|
+
.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)}
|
|
3846
|
+
.dsh-st-n-row[aria-expanded="true"].has-current-session .dsh-st-n-folder{color:var(--dsw-static-deepseek-450,#4c8dff)}
|
|
3847
|
+
.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)}
|
|
3848
|
+
.dsh-st-n-row>.dsh-st-n-acts{display:inline-flex;opacity:0;visibility:hidden;pointer-events:none}
|
|
3849
|
+
.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}
|
|
3850
|
+
.dsh-st-n-dialog-actions{display:flex;justify-content:flex-end;gap:8px}
|
|
3851
|
+
.dsh-st-n-dialog-copy{margin:0;color:var(--dsw-alias-label-secondary);font-size:14px;line-height:22px}
|
|
3852
|
+
.dsh-st-n-dialog-status{margin-top:12px;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}
|
|
3853
|
+
.dsh-st-n-dialog-error{margin-top:12px;color:var(--dsw-alias-state-error-primary,#f85149);font-size:13px;line-height:20px}
|
|
3854
|
+
.dsh-st-n-danger-button{color:var(--dsw-alias-state-error-primary,#f85149)!important}
|
|
3855
|
+
.dsh-st-n-danger-button:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(248,81,73,.12))!important}
|
|
3165
3856
|
`;
|
|
3166
3857
|
function installStyles() {
|
|
3167
3858
|
const existing = document.getElementById(STYLE_ID);
|
|
@@ -3178,6 +3869,77 @@ function installStyles() {
|
|
|
3178
3869
|
};
|
|
3179
3870
|
}
|
|
3180
3871
|
|
|
3872
|
+
// src/client/settings-navigation.ts
|
|
3873
|
+
function pickSettingsSectionButton(buttons, labels) {
|
|
3874
|
+
for (const label of labels) {
|
|
3875
|
+
const target = label.trim();
|
|
3876
|
+
if (target === "") continue;
|
|
3877
|
+
const match = buttons.find((button) => button.textContent?.replace(/\s+/g, " ").trim() === target);
|
|
3878
|
+
if (match !== void 0) return match;
|
|
3879
|
+
}
|
|
3880
|
+
return void 0;
|
|
3881
|
+
}
|
|
3882
|
+
function pickSettingsLauncher(buttons) {
|
|
3883
|
+
const named = buttons.find((button) => {
|
|
3884
|
+
const label = `${button.textContent ?? ""} ${button.getAttribute("aria-label") ?? ""}`.trim();
|
|
3885
|
+
return /(^|\s)(设置|settings)(\s|$)/i.test(label);
|
|
3886
|
+
});
|
|
3887
|
+
return named ?? (buttons.length === 1 ? buttons[0] : void 0);
|
|
3888
|
+
}
|
|
3889
|
+
var cancelPendingNavigation;
|
|
3890
|
+
function openSettingsSection(labels, onSelected, onMissing) {
|
|
3891
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
3892
|
+
onMissing?.();
|
|
3893
|
+
return;
|
|
3894
|
+
}
|
|
3895
|
+
const launchers = [...document.querySelectorAll('button[aria-haspopup="dialog"]')];
|
|
3896
|
+
const launcher = pickSettingsLauncher(launchers);
|
|
3897
|
+
const dialogOpen = document.querySelector('[role="dialog"]') !== null;
|
|
3898
|
+
if (!dialogOpen && launcher === void 0) {
|
|
3899
|
+
onMissing?.();
|
|
3900
|
+
return;
|
|
3901
|
+
}
|
|
3902
|
+
cancelPendingNavigation?.();
|
|
3903
|
+
if (!dialogOpen) launcher?.click();
|
|
3904
|
+
let frame;
|
|
3905
|
+
let finished = false;
|
|
3906
|
+
const observer = new MutationObserver(() => {
|
|
3907
|
+
schedule();
|
|
3908
|
+
});
|
|
3909
|
+
const cleanup = () => {
|
|
3910
|
+
if (finished) return;
|
|
3911
|
+
finished = true;
|
|
3912
|
+
observer.disconnect();
|
|
3913
|
+
window.clearTimeout(timeout);
|
|
3914
|
+
if (frame !== void 0) window.cancelAnimationFrame(frame);
|
|
3915
|
+
if (cancelPendingNavigation === cleanup) cancelPendingNavigation = void 0;
|
|
3916
|
+
};
|
|
3917
|
+
const select = () => {
|
|
3918
|
+
const buttons = [...document.querySelectorAll('[role="dialog"] nav button')];
|
|
3919
|
+
const target = pickSettingsSectionButton(buttons, labels);
|
|
3920
|
+
if (target === void 0) return false;
|
|
3921
|
+
cleanup();
|
|
3922
|
+
target.click();
|
|
3923
|
+
onSelected?.();
|
|
3924
|
+
return true;
|
|
3925
|
+
};
|
|
3926
|
+
const schedule = () => {
|
|
3927
|
+
if (finished || frame !== void 0) return;
|
|
3928
|
+
frame = window.requestAnimationFrame(() => {
|
|
3929
|
+
frame = void 0;
|
|
3930
|
+
select();
|
|
3931
|
+
});
|
|
3932
|
+
};
|
|
3933
|
+
const timeout = window.setTimeout(() => {
|
|
3934
|
+
if (select()) return;
|
|
3935
|
+
cleanup();
|
|
3936
|
+
onMissing?.();
|
|
3937
|
+
}, 1500);
|
|
3938
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
3939
|
+
cancelPendingNavigation = cleanup;
|
|
3940
|
+
schedule();
|
|
3941
|
+
}
|
|
3942
|
+
|
|
3181
3943
|
// src/client/index.ts
|
|
3182
3944
|
var name = "dsh-automation-client";
|
|
3183
3945
|
var inject = ["slots", "locale", "connection", "sessions"];
|
|
@@ -3227,7 +3989,7 @@ function apply(ctx) {
|
|
|
3227
3989
|
label: () => t("tab"),
|
|
3228
3990
|
icon: "schedule"
|
|
3229
3991
|
}, function ScheduledTasksSettings(props) {
|
|
3230
|
-
return (0,
|
|
3992
|
+
return (0, import_react11.createElement)(AutomationView, { t, permissionT, modelT, runtime, ...props.close === void 0 ? {} : { closeSettings: props.close } });
|
|
3231
3993
|
}));
|
|
3232
3994
|
ctx.slots.inject("sidebar.schedule", () => ctx.slots.register({
|
|
3233
3995
|
name: "sidebar.schedule",
|
|
@@ -3236,10 +3998,12 @@ function apply(ctx) {
|
|
|
3236
3998
|
locale: NS,
|
|
3237
3999
|
label: () => t("sidebar.tab")
|
|
3238
4000
|
}, function AutomationScheduleRail(props) {
|
|
3239
|
-
return (0,
|
|
4001
|
+
return (0, import_react11.createElement)(ScheduleRail, {
|
|
3240
4002
|
t,
|
|
3241
4003
|
runtime,
|
|
3242
|
-
openSession: createScheduledSessionOpener(ctx, runtime, props.openSession)
|
|
4004
|
+
openSession: createScheduledSessionOpener(ctx, runtime, props.openSession),
|
|
4005
|
+
...props.view === void 0 ? {} : { view: props.view },
|
|
4006
|
+
...props.showViewSwitch === void 0 ? {} : { showViewSwitch: props.showViewSwitch }
|
|
3243
4007
|
});
|
|
3244
4008
|
}));
|
|
3245
4009
|
ctx.slots.inject("sidebar.workspaces", () => {
|
|
@@ -3282,7 +4046,7 @@ function apply(ctx) {
|
|
|
3282
4046
|
render: (props) => {
|
|
3283
4047
|
const hostOpen = typeof props.openSession === "function" ? props.openSession : typeof props.open === "function" ? props.open : openSession;
|
|
3284
4048
|
const opener = createScheduledSessionOpener(ctx, runtime, hostOpen);
|
|
3285
|
-
return (0,
|
|
4049
|
+
return (0, import_react11.createElement)(NativeScheduleSessionList, {
|
|
3286
4050
|
t,
|
|
3287
4051
|
runtime,
|
|
3288
4052
|
openSession: opener,
|
|
@@ -3291,7 +4055,16 @@ function apply(ctx) {
|
|
|
3291
4055
|
...typeof props.renameSession === "function" ? { renameSession: props.renameSession } : {},
|
|
3292
4056
|
...typeof props.archiveSession === "function" ? { archiveSession: props.archiveSession } : {},
|
|
3293
4057
|
...typeof props.deleteSession === "function" ? { deleteSession: props.deleteSession } : {},
|
|
3294
|
-
...typeof props.forkSession === "function" ? { forkSession: props.forkSession } : {}
|
|
4058
|
+
...typeof props.forkSession === "function" ? { forkSession: props.forkSession } : {},
|
|
4059
|
+
openTaskSettings: (request) => {
|
|
4060
|
+
requestAutomationTaskSettings(request);
|
|
4061
|
+
openSettingsSection(
|
|
4062
|
+
[t("tab"), "Scheduled tasks", "\u5B9A\u65F6\u4EFB\u52A1"],
|
|
4063
|
+
() => {
|
|
4064
|
+
requestAutomationTaskSettings(request);
|
|
4065
|
+
}
|
|
4066
|
+
);
|
|
4067
|
+
}
|
|
3295
4068
|
});
|
|
3296
4069
|
}
|
|
3297
4070
|
});
|
|
@@ -3323,7 +4096,7 @@ function apply(ctx) {
|
|
|
3323
4096
|
try {
|
|
3324
4097
|
let AutomationNativeWorkspaceShell2 = function(innerProps) {
|
|
3325
4098
|
const openSession = createScheduledSessionOpener(ctx, runtime, innerProps.openSession ?? innerProps.open);
|
|
3326
|
-
return (0,
|
|
4099
|
+
return (0, import_react11.createElement)(NativeScheduleShell, {
|
|
3327
4100
|
t,
|
|
3328
4101
|
runtime,
|
|
3329
4102
|
hostProps: innerProps,
|
|
@@ -3409,7 +4182,7 @@ function createScheduledSessionOpener(ctx, runtime, hostOpen) {
|
|
|
3409
4182
|
};
|
|
3410
4183
|
}
|
|
3411
4184
|
function PrefillBridge(props) {
|
|
3412
|
-
(0,
|
|
4185
|
+
(0, import_react11.useEffect)(() => {
|
|
3413
4186
|
const applyPrefill = (text) => {
|
|
3414
4187
|
if (text === null || text === "") return;
|
|
3415
4188
|
if (props.inputActions !== void 0) {
|