@michengai/dsh-automation 0.1.1 → 0.1.3
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/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/02-/345/275/223/345/211/215/347/212/266/346/200/201.md +2 -3
- package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/03-/345/276/205/345/212/236/344/270/216/351/230/273/345/241/236.md +2 -2
- package/docs/01-/345/275/223/345/211/215/345/267/245/344/275/234/I001-/344/273/273/345/212/241/350/207/252/345/212/250/345/214/226/346/217/222/344/273/266/00-/350/277/255/344/273/243/346/200/273/350/247/210.md +11 -4
- package/lib/client.js +808 -423
- package/lib/client.js.map +4 -4
- package/lib/index.js +46 -5
- package/lib/types/client/AutomationView.d.ts +1 -1
- package/lib/types/client/ScheduleRail.d.ts +2 -2
- package/lib/types/client/contracts.d.ts +12 -0
- package/lib/types/client/create-modal-logic.d.ts +7 -0
- package/lib/types/client/create-modal.d.ts +2 -1
- package/lib/types/client/icons.d.ts +6 -0
- package/lib/types/client/locales.d.ts +18 -2
- package/lib/types/client/native-session-list.d.ts +1 -1
- package/lib/types/client/native-session-menu.d.ts +52 -0
- package/lib/types/client/schedule-rail-model.d.ts +46 -7
- package/lib/types/client/workspace-toolbar.d.ts +13 -0
- package/lib/types/index.d.ts +18 -1
- package/lib/types/prompt.d.ts +6 -0
- package/package.json +2 -6
package/lib/client.js
CHANGED
|
@@ -27,7 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
name: () => name
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(index_exports);
|
|
30
|
-
var
|
|
30
|
+
var import_react7 = require("react");
|
|
31
31
|
|
|
32
32
|
// src/client/AutomationView.tsx
|
|
33
33
|
var import_react3 = require("react");
|
|
@@ -323,14 +323,32 @@ function SparkleIcon(props) {
|
|
|
323
323
|
function FillIcon({ children, width = 16, height = 16 }) {
|
|
324
324
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 16 16", width, height, fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children });
|
|
325
325
|
}
|
|
326
|
+
function CloseOutlineIcon(props) {
|
|
327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(FillIcon, { ...props, children: [
|
|
328
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M14.1168 13.197L13.197 14.1167L1.8833 2.80303L2.80309 1.88324L14.1168 13.197Z" }),
|
|
329
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M13.197 1.88326L14.1168 2.80305L2.80309 14.1168L1.8833 13.197L13.197 1.88326Z" })
|
|
330
|
+
] });
|
|
331
|
+
}
|
|
332
|
+
function CheckOutlineIcon(props) {
|
|
333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FillIcon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M15.0498 3.92579L8.49512 12.3818C8.25774 12.6881 8.04517 12.9645 7.84668 13.1689C7.63957 13.3823 7.38732 13.5841 7.04492 13.6719C6.86373 13.7183 6.6757 13.7346 6.48926 13.7197C6.13666 13.6915 5.8528 13.5355 5.6123 13.3604C5.38201 13.1926 5.12573 12.9567 4.83984 12.6953L1.03125 9.21289L1.96875 8.1875L5.77734 11.6699C6.08684 11.9529 6.27773 12.1249 6.43066 12.2363C6.50183 12.2882 6.54699 12.3135 6.57324 12.3252C6.58525 12.3305 6.59269 12.3322 6.5957 12.333C6.59802 12.3336 6.59961 12.334 6.59961 12.334C6.63317 12.3367 6.66758 12.3335 6.7002 12.3252C6.7002 12.3252 6.70211 12.3251 6.7041 12.3242C6.70698 12.3229 6.71348 12.319 6.72461 12.3115C6.74849 12.2956 6.78843 12.2642 6.84961 12.2012C6.98138 12.0654 7.13957 11.8628 7.39648 11.5313L13.9502 3.07422L15.0498 3.92579Z" }) });
|
|
334
|
+
}
|
|
335
|
+
function SearchOutlineIcon(props) {
|
|
336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(FillIcon, { ...props, children: [
|
|
337
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M11.894845 6.647401C11.894845 3.725463 9.534486 1.356779 6.623219 1.35657C3.711786 1.35657 1.351635 3.725338 1.351635 6.647401C1.351843 9.569296 3.711911 11.938273 6.623219 11.938273C9.534361 11.938064 11.894637 9.569171 11.894845 6.647401ZM13.245462 6.647401C13.245254 10.317935 10.280401 13.293613 6.623219 13.293821C2.965871 13.293821 0.000204 10.31806 0 6.647401C0 2.976574 2.965746 0 6.623219 0C10.280526 0.000205 13.245462 2.9767 13.245462 6.647401Z" }),
|
|
338
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M16.000417 15.041079L15.044449 16.000433L11.530434 12.473588L12.486298 11.514234L16.000417 15.041079Z" })
|
|
339
|
+
] });
|
|
340
|
+
}
|
|
341
|
+
function SlidersIcon(props) {
|
|
342
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FillIcon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M2.2 3.4h6.05a1.85 1.85 0 0 0 3.5 0H13.8v1.3H11.75a1.85 1.85 0 0 0-3.5 0H2.2V3.4Zm8.6 1.15A.75.75 0 1 1 10.05 4.55.75.75 0 0 1 10.8 4.55ZM2.2 7.35h2.35a1.85 1.85 0 0 0 3.5 0H13.8v1.3H8.05a1.85 1.85 0 0 0-3.5 0H2.2V7.35Zm4.1 1.15A.75.75 0 1 1 5.55 8.5a.75.75 0 0 1 .75-.75ZM2.2 11.3h7.35a1.85 1.85 0 0 0 3.5 0H13.8v1.3h-.75a1.85 1.85 0 0 0-3.5 0H2.2v-1.3Zm9.9 1.15a.75.75 0 1 1-.75-.75.75.75 0 0 1 .75.75Z" }) });
|
|
343
|
+
}
|
|
326
344
|
function FolderClosedIcon(props) {
|
|
327
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FillIcon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor",
|
|
345
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FillIcon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", transform: "translate(1.5 2.429)", d: "M5.05582 0.518756L4.50669 0.86654L5.05582 0.518756ZM13 9.4837L13.65 9.4837L13.65 3.53962L13 3.53962L12.35 3.53962L12.35 9.4837L13 9.4837ZM11.3264 1.86603L11.3264 1.21603L6.52313 1.21603L6.52313 1.86603L6.52313 2.51603L11.3264 2.51603L11.3264 1.86603ZM5.58054 1.34727L6.12968 0.999489L5.60495 0.170972L5.05582 0.518756L4.50669 0.86654L5.03141 1.69506L5.58054 1.34727ZM4.11323 1.23058e-13L4.11323 -0.65L1.67359 -0.65L1.67359 5.00699e-14L1.67359 0.65L4.11323 0.65L4.11323 1.23058e-13ZM0 1.67359L-0.65 1.67359L-0.65 9.4837L0 9.4837L0.65 9.4837L0.65 1.67359L0 1.67359ZM11.3264 11.1573L11.3264 10.5073L1.67359 10.5073L1.67359 11.1573L1.67359 11.8073L11.3264 11.8073L11.3264 11.1573ZM0 9.4837L-0.65 9.4837C-0.65 10.767 0.390308 11.8073 1.67359 11.8073L1.67359 11.1573L1.67359 10.5073C1.10828 10.5073 0.65 10.049 0.65 9.4837L0 9.4837ZM1.67359 5.00699e-14L1.67359 -0.65C0.390307 -0.65 -0.65 0.390309 -0.65 1.67359L0 1.67359L0.65 1.67359C0.65 1.10828 1.10828 0.65 1.67359 0.65L1.67359 5.00699e-14ZM5.05582 0.518756L5.60495 0.170972C5.28121 -0.340193 4.71829 -0.65 4.11323 -0.65L4.11323 1.23058e-13L4.11323 0.65C4.27282 0.65 4.4213 0.731715 4.50669 0.86654L5.05582 0.518756ZM6.52313 1.86603L6.52313 1.21603C6.36354 1.21603 6.21507 1.13431 6.12968 0.999489L5.58054 1.34727L5.03141 1.69506C5.35515 2.20622 5.91808 2.51603 6.52313 2.51603L6.52313 1.86603ZM13 3.53962L13.65 3.53962C13.65 2.25634 12.6097 1.21603 11.3264 1.21603L11.3264 1.86603L11.3264 2.51603C11.8917 2.51603 12.35 2.97431 12.35 3.53962L13 3.53962ZM13 9.4837L12.35 9.4837C12.35 10.049 11.8917 10.5073 11.3264 10.5073L11.3264 11.1573L11.3264 11.8073C12.6097 11.8073 13.65 10.767 13.65 9.4837L13 9.4837Z" }) });
|
|
328
346
|
}
|
|
329
347
|
function FolderOpenIcon(props) {
|
|
330
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
348
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(FillIcon, { ...props, children: [
|
|
349
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: "M5.19629 1.57104C5.81144 1.5711 6.38623 1.8786 6.72754 2.39038L7.19922 3.09839C7.28454 3.22635 7.42824 3.30344 7.58203 3.30347H12.1699C13.5039 3.30348 14.5859 4.38548 14.5859 5.71948V6.62671C15.2694 7.02689 15.6605 7.85012 15.4385 8.68726L14.3848 12.658C14.1037 13.7164 13.1449 14.4527 12.0498 14.4529H2.91699C1.51651 14.4529 0.451662 13.2814 0.501954 11.9519V3.98706C0.501954 2.65305 1.58396 1.57104 2.91797 1.57104H5.19629ZM3.7793 7.75562C3.30994 7.75562 2.89883 8.07153 2.77832 8.52515L1.91602 11.7722C1.74167 12.4291 2.23734 13.073 2.91699 13.073H12.0498C12.5191 13.0728 12.9304 12.757 13.0508 12.3035L14.1045 8.33374C14.1819 8.04202 13.9619 7.756 13.6602 7.75562H3.7793ZM2.91797 2.9519C2.34625 2.9519 1.88281 3.41534 1.88281 3.98706V7.2937C2.33068 6.7269 3.02249 6.37476 3.7793 6.37476H13.2051V5.71948C13.2051 5.14777 12.7416 4.68434 12.1699 4.68433H7.58203C6.96675 4.6843 6.39209 4.37595 6.05078 3.86401L5.5791 3.15601C5.49379 3.02821 5.34995 2.95196 5.19629 2.9519H2.91797Z" }),
|
|
350
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", opacity: "0.2", d: "M13.6602 7.75525C13.9618 7.7556 14.1815 8.04179 14.1045 8.33337L13.0508 12.3031C12.9304 12.7567 12.5191 13.0725 12.0498 13.0726H2.91701C2.23744 13.0725 1.7417 12.4287 1.91603 11.7719L2.77834 8.52478C2.89898 8.07146 3.31018 7.75532 3.77931 7.75525H13.6602ZM5.1963 2.95154C5.34985 2.95159 5.49377 3.02803 5.57912 3.15564L6.0508 3.86365C6.39205 4.37553 6.96685 4.68385 7.58205 4.68396H12.1699C12.7416 4.68396 13.2049 5.14754 13.2051 5.71912V6.37439H3.77931C3.02267 6.37444 2.33067 6.72671 1.88283 7.29333V3.98669C1.88299 3.4152 2.34649 2.95168 2.91798 2.95154H5.1963Z" })
|
|
351
|
+
] });
|
|
334
352
|
}
|
|
335
353
|
function EllipsisIcon(props) {
|
|
336
354
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(FillIcon, { ...props, children: [
|
|
@@ -379,6 +397,13 @@ function RunningStateDot() {
|
|
|
379
397
|
// src/client/create-modal.tsx
|
|
380
398
|
var import_react2 = require("react");
|
|
381
399
|
|
|
400
|
+
// src/client/create-modal-logic.ts
|
|
401
|
+
async function adoptPickedWorkspace(input) {
|
|
402
|
+
const path = await input.pick();
|
|
403
|
+
if (path == null || path.trim() === "") return null;
|
|
404
|
+
return input.add(path.trim());
|
|
405
|
+
}
|
|
406
|
+
|
|
382
407
|
// src/client/menu.tsx
|
|
383
408
|
var import_react = require("react");
|
|
384
409
|
var import_react_dom = require("react-dom");
|
|
@@ -598,12 +623,11 @@ function CreateModal({
|
|
|
598
623
|
editing,
|
|
599
624
|
onClose,
|
|
600
625
|
onSubmit,
|
|
601
|
-
onAddWorkspace
|
|
626
|
+
onAddWorkspace,
|
|
627
|
+
pickWorkspaceDirectory
|
|
602
628
|
}) {
|
|
603
629
|
const [form, setForm] = (0, import_react2.useState)(() => ({ ...defaultFormState(/* @__PURE__ */ new Date(), workspaces, defaultModel), ...draft }));
|
|
604
630
|
const [validationError, setValidationError] = (0, import_react2.useState)();
|
|
605
|
-
const [addingWorkspace, setAddingWorkspace] = (0, import_react2.useState)(false);
|
|
606
|
-
const [workspacePath, setWorkspacePath] = (0, import_react2.useState)("");
|
|
607
631
|
const update = (patch) => {
|
|
608
632
|
setForm((current) => ({ ...current, ...patch }));
|
|
609
633
|
setValidationError(void 0);
|
|
@@ -656,206 +680,177 @@ function CreateModal({
|
|
|
656
680
|
caretRef.current = next.caret;
|
|
657
681
|
});
|
|
658
682
|
};
|
|
659
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
660
|
-
"
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
onClose()
|
|
667
|
-
},
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
683
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-mask", role: "presentation", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuHostProvider, { host: menuHost, children: [
|
|
684
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { className: "dsh-st-modal", onClick: (event) => event.stopPropagation(), onSubmit: handleSubmit, children: [
|
|
685
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-modal-head", children: [
|
|
686
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
687
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { children: editing === true ? t("modal.edit") : t("modal.title") }),
|
|
688
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: t("form.subtitle") })
|
|
689
|
+
] }),
|
|
690
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "dsh-st-icon", onClick: onClose, "aria-label": t("form.cancel"), children: "\xD7" })
|
|
691
|
+
] }),
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "dsh-st-field", children: [
|
|
693
|
+
t("form.name"),
|
|
694
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { value: form.name, placeholder: t("form.namePlaceholder"), onChange: (event) => update({ name: event.target.value }) })
|
|
695
|
+
] }),
|
|
696
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-field", children: [
|
|
697
|
+
t("form.planTime"),
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-inline", children: [
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
700
|
+
MenuSelect,
|
|
701
|
+
{
|
|
702
|
+
value: form.scheduleKind,
|
|
703
|
+
options: KINDS.map((kind) => ({ value: kind, label: t(`form.${kind}`) })),
|
|
704
|
+
onChange: (value) => update({ scheduleKind: value })
|
|
705
|
+
}
|
|
706
|
+
),
|
|
707
|
+
form.scheduleKind === "once" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
708
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "date", min: today, value: datePart, onChange: (event) => update({ onceAt: clampOnceAt(`${event.target.value}T${timePart}`) }) }),
|
|
709
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: timePart, ...minOnceTime === void 0 ? {} : { minTime: minOnceTime }, onChange: (value) => update({ onceAt: clampOnceAt(`${datePart}T${value}`) }) })
|
|
676
710
|
] }),
|
|
677
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
678
|
-
|
|
679
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
711
|
+
form.scheduleKind === "interval" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { className: "is-narrow", type: "number", min: 5, value: form.everyMinutes, onChange: (event) => update({ everyMinutes: event.target.value }) }),
|
|
713
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-st-suffix", children: t("form.minutesShort") })
|
|
680
714
|
] }),
|
|
681
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
682
|
-
|
|
683
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.
|
|
684
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
685
|
-
MenuSelect,
|
|
686
|
-
{
|
|
687
|
-
value: form.scheduleKind,
|
|
688
|
-
options: KINDS.map((kind) => ({ value: kind, label: t(`form.${kind}`) })),
|
|
689
|
-
onChange: (value) => update({ scheduleKind: value })
|
|
690
|
-
}
|
|
691
|
-
),
|
|
692
|
-
form.scheduleKind === "once" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
693
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "date", min: today, value: datePart, onChange: (event) => update({ onceAt: clampOnceAt(`${event.target.value}T${timePart}`) }) }),
|
|
694
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: timePart, ...minOnceTime === void 0 ? {} : { minTime: minOnceTime }, onChange: (value) => update({ onceAt: clampOnceAt(`${datePart}T${value}`) }) })
|
|
695
|
-
] }),
|
|
696
|
-
form.scheduleKind === "interval" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
697
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { className: "is-narrow", type: "number", min: 5, value: form.everyMinutes, onChange: (event) => update({ everyMinutes: event.target.value }) }),
|
|
698
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-st-suffix", children: t("form.minutesShort") })
|
|
699
|
-
] }),
|
|
700
|
-
form.scheduleKind === "hourly" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
701
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuSelect, { value: form.hourlyMinute, options: MINUTES.map((item) => ({ value: item, label: item })), onChange: (value) => update({ hourlyMinute: value }) }),
|
|
702
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-st-suffix", children: t("form.minutesShort") })
|
|
703
|
-
] }),
|
|
704
|
-
(form.scheduleKind === "daily" || form.scheduleKind === "weekly") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: form.time, onChange: (value) => update({ time: value }) }),
|
|
705
|
-
form.scheduleKind === "monthly" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
706
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
707
|
-
MenuSelect,
|
|
708
|
-
{
|
|
709
|
-
value: form.monthDay,
|
|
710
|
-
options: Array.from({ length: 31 }, (_, index) => {
|
|
711
|
-
const day = String(index + 1);
|
|
712
|
-
return { value: day, label: t("form.monthDay", { day }) };
|
|
713
|
-
}),
|
|
714
|
-
onChange: (value) => update({ monthDay: value })
|
|
715
|
-
}
|
|
716
|
-
),
|
|
717
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: form.time, onChange: (value) => update({ time: value }) })
|
|
718
|
-
] }),
|
|
719
|
-
form.scheduleKind === "custom" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
720
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { className: "is-narrow", type: "number", min: 1, value: form.customDays, onChange: (event) => update({ customDays: event.target.value }) }),
|
|
721
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-st-suffix", children: t("form.daysShort") }),
|
|
722
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: form.time, onChange: (value) => update({ time: value }) })
|
|
723
|
-
] })
|
|
724
|
-
] })
|
|
715
|
+
form.scheduleKind === "hourly" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuSelect, { value: form.hourlyMinute, options: MINUTES.map((item) => ({ value: item, label: item })), onChange: (value) => update({ hourlyMinute: value }) }),
|
|
717
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-st-suffix", children: t("form.minutesShort") })
|
|
725
718
|
] }),
|
|
726
|
-
form.scheduleKind === "weekly" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
},
|
|
787
|
-
item.id
|
|
788
|
-
))
|
|
789
|
-
] }),
|
|
719
|
+
(form.scheduleKind === "daily" || form.scheduleKind === "weekly") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: form.time, onChange: (value) => update({ time: value }) }),
|
|
720
|
+
form.scheduleKind === "monthly" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
721
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
722
|
+
MenuSelect,
|
|
723
|
+
{
|
|
724
|
+
value: form.monthDay,
|
|
725
|
+
options: Array.from({ length: 31 }, (_, index) => {
|
|
726
|
+
const day = String(index + 1);
|
|
727
|
+
return { value: day, label: t("form.monthDay", { day }) };
|
|
728
|
+
}),
|
|
729
|
+
onChange: (value) => update({ monthDay: value })
|
|
730
|
+
}
|
|
731
|
+
),
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: form.time, onChange: (value) => update({ time: value }) })
|
|
733
|
+
] }),
|
|
734
|
+
form.scheduleKind === "custom" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { className: "is-narrow", type: "number", min: 1, value: form.customDays, onChange: (event) => update({ customDays: event.target.value }) }),
|
|
736
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-st-suffix", children: t("form.daysShort") }),
|
|
737
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TimeSelect, { value: form.time, onChange: (value) => update({ time: value }) })
|
|
738
|
+
] })
|
|
739
|
+
] })
|
|
740
|
+
] }),
|
|
741
|
+
form.scheduleKind === "weekly" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-weekdays", children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
742
|
+
"button",
|
|
743
|
+
{
|
|
744
|
+
type: "button",
|
|
745
|
+
className: form.weekdays.includes(day) ? "is-on" : "",
|
|
746
|
+
onClick: () => update({
|
|
747
|
+
weekdays: form.weekdays.includes(day) ? form.weekdays.filter((value) => value !== day) : [...form.weekdays, day]
|
|
748
|
+
}),
|
|
749
|
+
children: t(`day.${day}`)
|
|
750
|
+
},
|
|
751
|
+
day
|
|
752
|
+
)) }),
|
|
753
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-field", children: [
|
|
754
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: t("form.prompt") }),
|
|
755
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-prompt-card", children: [
|
|
756
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("textarea", { ref: promptRef, value: form.prompt, placeholder: t("form.promptPlaceholder"), onChange: (event) => {
|
|
757
|
+
rememberCaret();
|
|
758
|
+
update({ prompt: event.target.value });
|
|
759
|
+
}, onSelect: rememberCaret, onClick: rememberCaret, onKeyUp: rememberCaret }),
|
|
760
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-composer", children: [
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-composer-left", children: [
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuPanel, { ghost: true, up: true, label: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
763
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FolderIcon, { width: 14, height: 14 }),
|
|
764
|
+
workspace?.title || t("form.workspace")
|
|
765
|
+
] }), children: [
|
|
766
|
+
workspaces.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-select-empty", children: t("form.error.workspace") }),
|
|
767
|
+
workspaces.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
768
|
+
MenuRow,
|
|
769
|
+
{
|
|
770
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FolderIcon, { width: 14, height: 14 }),
|
|
771
|
+
label: item.title,
|
|
772
|
+
active: item.id === form.workspaceId,
|
|
773
|
+
onClick: () => update({ workspaceId: item.id })
|
|
774
|
+
},
|
|
775
|
+
item.id
|
|
776
|
+
)),
|
|
777
|
+
pickWorkspaceDirectory !== void 0 && onAddWorkspace !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-menu-split" }),
|
|
790
779
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
791
|
-
|
|
780
|
+
MenuRow,
|
|
792
781
|
{
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
782
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PlusIcon, { width: 14, height: 14 }),
|
|
783
|
+
label: t("form.addWorkspace"),
|
|
784
|
+
onClick: () => {
|
|
785
|
+
void (async () => {
|
|
786
|
+
try {
|
|
787
|
+
const id = await adoptPickedWorkspace({
|
|
788
|
+
pick: pickWorkspaceDirectory,
|
|
789
|
+
add: onAddWorkspace
|
|
790
|
+
});
|
|
791
|
+
if (id !== null) update({ workspaceId: id });
|
|
792
|
+
} catch (caught) {
|
|
793
|
+
setValidationError(caught instanceof Error ? caught.message : t("error.action"));
|
|
794
|
+
}
|
|
795
|
+
})();
|
|
796
|
+
}
|
|
803
797
|
}
|
|
804
798
|
)
|
|
805
|
-
] })
|
|
806
|
-
|
|
807
|
-
|
|
799
|
+
] })
|
|
800
|
+
] }),
|
|
801
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuPanel, { ghost: true, up: true, label: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
802
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, { width: 14, height: 14 }),
|
|
803
|
+
t("form.skills")
|
|
804
|
+
] }), children: [
|
|
805
|
+
skills.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-select-empty", children: t("form.skillsEmpty") }),
|
|
806
|
+
skills.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
807
|
+
MenuRow,
|
|
808
808
|
{
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
) })
|
|
817
|
-
] })
|
|
818
|
-
] })
|
|
819
|
-
] }),
|
|
820
|
-
addingWorkspace && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-subdialog", children: [
|
|
821
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: t("form.addWorkspace") }),
|
|
822
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "dsh-st-field", children: [
|
|
823
|
-
t("form.workspacePath"),
|
|
824
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { value: workspacePath, placeholder: t("form.workspacePathPlaceholder"), onChange: (event) => setWorkspacePath(event.target.value) })
|
|
825
|
-
] }),
|
|
826
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-modal-actions", children: [
|
|
827
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "dsh-st-btn", onClick: () => setAddingWorkspace(false), children: t("form.cancel") }),
|
|
809
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, { width: 14, height: 14 }),
|
|
810
|
+
label: item.name,
|
|
811
|
+
onClick: () => insertSkill(item)
|
|
812
|
+
},
|
|
813
|
+
item.id
|
|
814
|
+
))
|
|
815
|
+
] }),
|
|
828
816
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
829
|
-
|
|
817
|
+
MenuSelect,
|
|
830
818
|
{
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
setValidationError(caught instanceof Error ? caught.message : t("error.action"));
|
|
842
|
-
}
|
|
843
|
-
},
|
|
844
|
-
children: t("modal.save")
|
|
819
|
+
pill: true,
|
|
820
|
+
up: true,
|
|
821
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShieldIcon, { width: 14, height: 14 }),
|
|
822
|
+
value: form.permission,
|
|
823
|
+
options: [
|
|
824
|
+
{ value: "read-only", label: t("form.readOnly"), icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShieldIcon, { width: 14, height: 14 }) },
|
|
825
|
+
{ value: "workspace-write", label: t("form.workspaceWrite"), icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShieldIcon, { width: 14, height: 14 }) },
|
|
826
|
+
{ value: "full-access", label: t("form.fullAccess"), icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShieldIcon, { width: 14, height: 14 }) }
|
|
827
|
+
],
|
|
828
|
+
onChange: (value) => update({ permission: value })
|
|
845
829
|
}
|
|
846
830
|
)
|
|
847
|
-
] })
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
831
|
+
] }),
|
|
832
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-composer-right", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
833
|
+
ModelPicker,
|
|
834
|
+
{
|
|
835
|
+
t,
|
|
836
|
+
models,
|
|
837
|
+
modelKey: form.modelKey,
|
|
838
|
+
effort: form.reasoningEffort,
|
|
839
|
+
onModelKey: (value) => update({ modelKey: value }),
|
|
840
|
+
onEffort: (value) => update({ reasoningEffort: value })
|
|
841
|
+
}
|
|
842
|
+
) })
|
|
853
843
|
] })
|
|
854
|
-
] })
|
|
855
|
-
|
|
844
|
+
] })
|
|
845
|
+
] }),
|
|
846
|
+
validationError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "dsh-st-error", children: validationError }),
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-st-modal-actions", children: [
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "dsh-st-btn", onClick: onClose, disabled: busy, children: t("form.cancel") }),
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "dsh-st-btn dsh-st-btn--primary", disabled: busy, children: t("modal.save") })
|
|
856
850
|
] })
|
|
857
|
-
}
|
|
858
|
-
|
|
851
|
+
] }),
|
|
852
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-st-flyout-root", ref: setMenuHost })
|
|
853
|
+
] }) });
|
|
859
854
|
}
|
|
860
855
|
function ModelPicker({
|
|
861
856
|
t,
|
|
@@ -1160,7 +1155,7 @@ var EXAMPLES = [
|
|
|
1160
1155
|
{ name: "\u6BCF\u5468\u4F9D\u8D56\u5DE1\u68C0", scheduleKind: "weekly", time: "10:00", weekdays: [1] },
|
|
1161
1156
|
{ name: "\u5DE5\u4F5C\u65E5\u65E9\u62A5", scheduleKind: "weekly", time: "08:00", weekdays: [1, 2, 3, 4, 5] }
|
|
1162
1157
|
];
|
|
1163
|
-
function AutomationView({ t, runtime, closeSettings }) {
|
|
1158
|
+
function AutomationView({ t, runtime, closeSettings, pickWorkspaceDirectory }) {
|
|
1164
1159
|
const state = (0, import_react3.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
1165
1160
|
const [tab, setTab] = (0, import_react3.useState)("mine");
|
|
1166
1161
|
const [query, setQuery] = (0, import_react3.useState)("");
|
|
@@ -1334,6 +1329,7 @@ function AutomationView({ t, runtime, closeSettings }) {
|
|
|
1334
1329
|
defaultModel: snapshot?.defaultModel ?? null,
|
|
1335
1330
|
skills: snapshot?.skills ?? [],
|
|
1336
1331
|
onAddWorkspace: async (path) => runtime.addWorkspace(path).then((value) => value.id),
|
|
1332
|
+
...pickWorkspaceDirectory === void 0 ? {} : { pickWorkspaceDirectory },
|
|
1337
1333
|
editing: editingId !== void 0,
|
|
1338
1334
|
...draft === void 0 ? {} : { draft },
|
|
1339
1335
|
onClose: closeModal,
|
|
@@ -1436,6 +1432,17 @@ var en = {
|
|
|
1436
1432
|
"sidebar.tasksEmpty": "No web tasks yet.",
|
|
1437
1433
|
"sidebar.ungrouped": "Ungrouped",
|
|
1438
1434
|
"sidebar.section": "Scheduled",
|
|
1435
|
+
"sidebar.workspaces": "Workspaces",
|
|
1436
|
+
"sidebar.search": "Search",
|
|
1437
|
+
"sidebar.searchSessions": "Search sessions...",
|
|
1438
|
+
"sidebar.clearSearch": "Clear search",
|
|
1439
|
+
"sidebar.filter": "Filter",
|
|
1440
|
+
"sidebar.groupBy": "Group by",
|
|
1441
|
+
"sidebar.groupWorkspace": "By workspace",
|
|
1442
|
+
"sidebar.groupList": "Single list",
|
|
1443
|
+
"sidebar.sortBy": "Sort by",
|
|
1444
|
+
"sidebar.sortManual": "Manual",
|
|
1445
|
+
"sidebar.sortTime": "Recently updated",
|
|
1439
1446
|
"header.lead": "Plan automatic tasks, or trigger them by hand. Describe the recurring work in any chat to create it quickly.",
|
|
1440
1447
|
"examples.title": "Recommended examples",
|
|
1441
1448
|
"examples.1.title": "Daily regression check",
|
|
@@ -1454,8 +1461,13 @@ var en = {
|
|
|
1454
1461
|
"session.rename": "Rename",
|
|
1455
1462
|
"session.fork": "Fork session",
|
|
1456
1463
|
"session.archive": "Archive session",
|
|
1457
|
-
"session.
|
|
1458
|
-
"session.
|
|
1464
|
+
"session.idle": "Idle",
|
|
1465
|
+
"session.runningStatus": "Running",
|
|
1466
|
+
"session.delete": "Remove from Scheduled",
|
|
1467
|
+
"session.deleteFolder": "Remove folder",
|
|
1468
|
+
"session.confirmDeleteFolder": "Remove this folder from Scheduled?",
|
|
1469
|
+
"session.confirmDeleteFolderHint": 'This only unlists {count} session(s) in "{name}" from Scheduled. Host sessions are not deleted and they stay hidden from Tasks.',
|
|
1470
|
+
"session.confirmDeleteFolderAction": "Remove from Scheduled",
|
|
1459
1471
|
"history.range.day": "By day",
|
|
1460
1472
|
"history.range.week": "By week",
|
|
1461
1473
|
"history.range.month": "By month",
|
|
@@ -1620,6 +1632,17 @@ var zh = {
|
|
|
1620
1632
|
"sidebar.tasksEmpty": "\u6682\u65E0\u7F51\u9875\u4EFB\u52A1",
|
|
1621
1633
|
"sidebar.ungrouped": "\u672A\u5206\u7EC4",
|
|
1622
1634
|
"sidebar.section": "\u5B9A\u65F6\u4EFB\u52A1",
|
|
1635
|
+
"sidebar.workspaces": "\u5DE5\u4F5C\u533A",
|
|
1636
|
+
"sidebar.search": "\u641C\u7D22",
|
|
1637
|
+
"sidebar.searchSessions": "\u641C\u7D22\u4F1A\u8BDD...",
|
|
1638
|
+
"sidebar.clearSearch": "\u6E05\u9664\u641C\u7D22",
|
|
1639
|
+
"sidebar.filter": "\u7B5B\u9009",
|
|
1640
|
+
"sidebar.groupBy": "\u5206\u7EC4\u65B9\u5F0F",
|
|
1641
|
+
"sidebar.groupWorkspace": "\u6309\u5DE5\u4F5C\u533A",
|
|
1642
|
+
"sidebar.groupList": "\u5355\u5217\u8868",
|
|
1643
|
+
"sidebar.sortBy": "\u6392\u5E8F\u65B9\u5F0F",
|
|
1644
|
+
"sidebar.sortManual": "\u624B\u52A8\u6392\u5E8F",
|
|
1645
|
+
"sidebar.sortTime": "\u6700\u8FD1\u66F4\u65B0",
|
|
1623
1646
|
"header.lead": "\u6309\u8BA1\u5212\u81EA\u52A8\u6267\u884C\u4EFB\u52A1\uFF0C\u4E5F\u53EF\u968F\u65F6\u624B\u52A8\u89E6\u53D1\u3002\u5728\u4EFB\u610F\u5BF9\u8BDD\u4E2D\u63CF\u8FF0\u4F60\u60F3\u5B9A\u671F\u505A\u7684\u4E8B\uFF0C\u5373\u53EF\u5FEB\u901F\u521B\u5EFA",
|
|
1624
1647
|
"examples.title": "\u63A8\u8350\u6848\u4F8B",
|
|
1625
1648
|
"examples.1.title": "\u6BCF\u65E5\u56DE\u5F52\u68C0\u67E5",
|
|
@@ -1638,8 +1661,13 @@ var zh = {
|
|
|
1638
1661
|
"session.rename": "\u91CD\u547D\u540D",
|
|
1639
1662
|
"session.fork": "\u5206\u53C9\u4F1A\u8BDD",
|
|
1640
1663
|
"session.archive": "\u5F52\u6863\u4F1A\u8BDD",
|
|
1641
|
-
"session.
|
|
1642
|
-
"session.
|
|
1664
|
+
"session.idle": "\u7A7A\u95F2",
|
|
1665
|
+
"session.runningStatus": "\u8FD0\u884C\u4E2D",
|
|
1666
|
+
"session.delete": "\u4ECE\u5B9A\u65F6\u9875\u79FB\u9664",
|
|
1667
|
+
"session.deleteFolder": "\u4ECE\u5B9A\u65F6\u9875\u79FB\u9664\u6587\u4EF6\u5939",
|
|
1668
|
+
"session.confirmDeleteFolder": "\u4ECE\u5B9A\u65F6\u9875\u79FB\u9664\u8FD9\u4E2A\u6587\u4EF6\u5939\uFF1F",
|
|
1669
|
+
"session.confirmDeleteFolderHint": "\u53EA\u4F1A\u628A\u300C{name}\u300D\u4E0B\u7684 {count} \u6761\u4F1A\u8BDD\u4ECE\u5B9A\u65F6\u9875\u6458\u6389\uFF0C\u4E0D\u4F1A\u5220\u9664\u5BBF\u4E3B Session\u3002\u4EFB\u52A1\u9875\u672C\u6765\u4E5F\u4E0D\u5C55\u793A\u8FD9\u4E9B\u81EA\u52A8\u5316\u4F1A\u8BDD\u3002",
|
|
1670
|
+
"session.confirmDeleteFolderAction": "\u4ECE\u5B9A\u65F6\u9875\u79FB\u9664",
|
|
1643
1671
|
"history.range.day": "\u6309\u5929",
|
|
1644
1672
|
"history.range.week": "\u6309\u5468",
|
|
1645
1673
|
"history.range.month": "\u6309\u6708",
|
|
@@ -1872,7 +1900,80 @@ function isForeignSidebarHost(component) {
|
|
|
1872
1900
|
}
|
|
1873
1901
|
|
|
1874
1902
|
// src/client/native-session-list.tsx
|
|
1875
|
-
var
|
|
1903
|
+
var import_react5 = require("react");
|
|
1904
|
+
var import_react_dom2 = require("react-dom");
|
|
1905
|
+
|
|
1906
|
+
// src/client/native-session-menu.ts
|
|
1907
|
+
function resolveEventElement(target) {
|
|
1908
|
+
if (target == null || typeof target !== "object") return null;
|
|
1909
|
+
const node = target;
|
|
1910
|
+
if (node.nodeType === 3 || node.nodeType === 8) {
|
|
1911
|
+
return node.parentElement ?? null;
|
|
1912
|
+
}
|
|
1913
|
+
return node;
|
|
1914
|
+
}
|
|
1915
|
+
function shouldCloseNativeSessionMenu(target, keepInside) {
|
|
1916
|
+
const el = resolveEventElement(target);
|
|
1917
|
+
if (el == null) return true;
|
|
1918
|
+
return !keepInside.some((root) => {
|
|
1919
|
+
if (root == null || typeof root !== "object") return false;
|
|
1920
|
+
if (root === el) return true;
|
|
1921
|
+
const box = root;
|
|
1922
|
+
return typeof box.contains === "function" && box.contains(el);
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
function pointerPoint(event) {
|
|
1926
|
+
const x = Number(event?.clientX);
|
|
1927
|
+
const y = Number(event?.clientY);
|
|
1928
|
+
return {
|
|
1929
|
+
x: Number.isFinite(x) ? x : 8,
|
|
1930
|
+
y: Number.isFinite(y) ? y : 8
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
function clampMenuPoint(x, y, width, height, viewport) {
|
|
1934
|
+
const pad = 8;
|
|
1935
|
+
const vw = viewport.width || width + pad * 2;
|
|
1936
|
+
const vh = viewport.height || height + pad * 2;
|
|
1937
|
+
return {
|
|
1938
|
+
x: Math.max(pad, Math.min(x, Math.max(pad, vw - width - pad))),
|
|
1939
|
+
y: Math.max(pad, Math.min(y, Math.max(pad, vh - height - pad)))
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
function nextOpenSessionMenu(current, clicked, point) {
|
|
1943
|
+
if (current?.id === clicked) return null;
|
|
1944
|
+
return { id: clicked, x: point.x, y: point.y };
|
|
1945
|
+
}
|
|
1946
|
+
function nativeSessionMenuStyle(point, size = { width: 218, height: 176 }, viewport = { width: 1e3, height: 800 }) {
|
|
1947
|
+
const pos = clampMenuPoint(point.x, point.y, size.width, size.height, viewport);
|
|
1948
|
+
return {
|
|
1949
|
+
position: "fixed",
|
|
1950
|
+
zIndex: 4e3,
|
|
1951
|
+
left: `${Math.round(pos.x)}px`,
|
|
1952
|
+
top: `${Math.round(pos.y)}px`
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
function nativeSessionHoverStyle(row, card, viewport) {
|
|
1956
|
+
const pad = 8;
|
|
1957
|
+
const left = row.right + pad;
|
|
1958
|
+
const top = row.top + card.height > viewport.height - pad ? Math.max(pad, viewport.height - card.height - pad) : Math.max(pad, row.top);
|
|
1959
|
+
return {
|
|
1960
|
+
position: "fixed",
|
|
1961
|
+
zIndex: 4100,
|
|
1962
|
+
left: `${Math.round(left)}px`,
|
|
1963
|
+
top: `${Math.round(top)}px`
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
function relativeTime(value) {
|
|
1967
|
+
const ts = Date.parse(value || "");
|
|
1968
|
+
if (!Number.isFinite(ts)) return "";
|
|
1969
|
+
const delta = Math.max(0, Date.now() - ts);
|
|
1970
|
+
const min = Math.floor(delta / 6e4);
|
|
1971
|
+
if (min < 1) return "\u521A\u521A";
|
|
1972
|
+
if (min < 60) return String(min) + "\u5206\u949F\u524D";
|
|
1973
|
+
const hour = Math.floor(min / 60);
|
|
1974
|
+
if (hour < 24) return String(hour) + "\u5C0F\u65F6\u524D";
|
|
1975
|
+
return String(Math.floor(hour / 24)) + "\u5929\u524D";
|
|
1976
|
+
}
|
|
1876
1977
|
|
|
1877
1978
|
// src/run-title.ts
|
|
1878
1979
|
function formatRunStamp(iso) {
|
|
@@ -1920,21 +2021,35 @@ function groupScheduledSessions(automations, runs) {
|
|
|
1920
2021
|
};
|
|
1921
2022
|
}).filter((group) => group.sessions.length > 0);
|
|
1922
2023
|
}
|
|
1923
|
-
function
|
|
2024
|
+
function collectScheduledSessionIds(runs) {
|
|
2025
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2026
|
+
for (const run of runs ?? []) {
|
|
2027
|
+
const id = run.sessionId;
|
|
2028
|
+
if (typeof id === "string" && id !== "") ids.add(id);
|
|
2029
|
+
}
|
|
2030
|
+
return ids;
|
|
2031
|
+
}
|
|
2032
|
+
var AUTOMATION_TITLE_RE = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}/;
|
|
2033
|
+
function isAutomationSidebarSession(id, item, scheduledIds = /* @__PURE__ */ new Set()) {
|
|
2034
|
+
if (id.startsWith(AUTOMATION_SESSION_PREFIX) || scheduledIds.has(id)) return true;
|
|
2035
|
+
const title = String(item?.title ?? item?.displayTitle ?? "");
|
|
2036
|
+
return AUTOMATION_TITLE_RE.test(title);
|
|
2037
|
+
}
|
|
2038
|
+
function isNativeTaskSession(item, scheduledIds = /* @__PURE__ */ new Set()) {
|
|
1924
2039
|
if (item === void 0 || item.blank === true) return false;
|
|
1925
2040
|
if (item.origin === "im" || item.origin === "subagent") return false;
|
|
1926
2041
|
const id = item.id ?? "";
|
|
1927
2042
|
if (id.startsWith("im:")) return false;
|
|
1928
|
-
if (id
|
|
2043
|
+
if (isAutomationSidebarSession(id, item, scheduledIds)) return false;
|
|
1929
2044
|
return true;
|
|
1930
2045
|
}
|
|
1931
|
-
function groupNativeTaskSessions(sessions, workspaces, ungroupedLabel) {
|
|
2046
|
+
function groupNativeTaskSessions(sessions, workspaces, ungroupedLabel, scheduledIds = /* @__PURE__ */ new Set()) {
|
|
1932
2047
|
const byId = sessions.byId ?? {};
|
|
1933
2048
|
const archived = new Set(workspaces?.archivedSessionIds ?? []);
|
|
1934
2049
|
const assigned = /* @__PURE__ */ new Set();
|
|
1935
2050
|
const groups = [];
|
|
1936
2051
|
for (const workspace of workspaces?.items ?? []) {
|
|
1937
|
-
const items = (workspace.sessionIds ?? []).map((id) => byId[id]).filter((item) => item !== void 0 && item.id !== void 0 && isNativeTaskSession(item) && !archived.has(item.id));
|
|
2052
|
+
const items = (workspace.sessionIds ?? []).map((id) => byId[id]).filter((item) => item !== void 0 && item.id !== void 0 && isNativeTaskSession(item, scheduledIds) && !archived.has(item.id));
|
|
1938
2053
|
for (const item of items) {
|
|
1939
2054
|
if (item.id !== void 0) assigned.add(item.id);
|
|
1940
2055
|
}
|
|
@@ -1946,7 +2061,7 @@ function groupNativeTaskSessions(sessions, workspaces, ungroupedLabel) {
|
|
|
1946
2061
|
});
|
|
1947
2062
|
}
|
|
1948
2063
|
}
|
|
1949
|
-
const ungrouped = (sessions.ids ?? []).map((id) => byId[id]).filter((item) => item !== void 0 && item.id !== void 0 && !assigned.has(item.id) && isNativeTaskSession(item) && !archived.has(item.id));
|
|
2064
|
+
const ungrouped = (sessions.ids ?? []).map((id) => byId[id]).filter((item) => item !== void 0 && item.id !== void 0 && !assigned.has(item.id) && isNativeTaskSession(item, scheduledIds) && !archived.has(item.id));
|
|
1950
2065
|
if (ungrouped.length > 0) groups.push({ id: "", label: ungroupedLabel, sessions: ungrouped });
|
|
1951
2066
|
return groups;
|
|
1952
2067
|
}
|
|
@@ -1954,9 +2069,29 @@ function readNativeSidebarTab(raw) {
|
|
|
1954
2069
|
if (raw === "channels" || raw === "schedule" || raw === "tasks") return raw;
|
|
1955
2070
|
return "tasks";
|
|
1956
2071
|
}
|
|
1957
|
-
function
|
|
2072
|
+
function shouldFollowSessionTab(previousCurrent, current) {
|
|
2073
|
+
const prev = previousCurrent ?? "";
|
|
2074
|
+
const next = current ?? "";
|
|
2075
|
+
return next !== "" && prev !== next;
|
|
2076
|
+
}
|
|
2077
|
+
function ownedSidebarTabIds(input) {
|
|
2078
|
+
const ids = ["tasks"];
|
|
2079
|
+
for (const id of input.extraTabIds) {
|
|
2080
|
+
if (id === "" || id === "tasks" || id === "schedule" || ids.includes(id)) continue;
|
|
2081
|
+
ids.push(id);
|
|
2082
|
+
}
|
|
2083
|
+
if (input.channelsReady && !ids.includes("channels")) ids.push("channels");
|
|
2084
|
+
ids.push("schedule");
|
|
2085
|
+
return ids;
|
|
2086
|
+
}
|
|
2087
|
+
function resolveVisibleSidebarTab(input) {
|
|
2088
|
+
if (input.extraTabIds.includes(input.tab)) return input.tab;
|
|
2089
|
+
if (input.tab === "channels" && !input.channelsReady) return "tasks";
|
|
2090
|
+
return input.tab;
|
|
2091
|
+
}
|
|
2092
|
+
function tabForSessionId(sessionId, scheduledIds) {
|
|
1958
2093
|
if (sessionId === void 0 || sessionId === null || sessionId === "") return void 0;
|
|
1959
|
-
if (sessionId.startsWith(AUTOMATION_SESSION_PREFIX)) return "schedule";
|
|
2094
|
+
if (scheduledIds !== void 0 ? scheduledIds.has(sessionId) : sessionId.startsWith(AUTOMATION_SESSION_PREFIX)) return "schedule";
|
|
1960
2095
|
if (sessionId.startsWith("im:")) return "channels";
|
|
1961
2096
|
return void 0;
|
|
1962
2097
|
}
|
|
@@ -1972,41 +2107,77 @@ function slotOccupantName(item) {
|
|
|
1972
2107
|
function hasCodexUiSidebar(entries) {
|
|
1973
2108
|
return (entries ?? []).some((item) => occupantLooksLikeCodexUi(slotOccupantName(item)));
|
|
1974
2109
|
}
|
|
1975
|
-
|
|
2110
|
+
var taskFilterCache = /* @__PURE__ */ new WeakMap();
|
|
2111
|
+
var workspaceFilterCache = /* @__PURE__ */ new WeakMap();
|
|
2112
|
+
function scheduledCacheKey(scheduledIds) {
|
|
2113
|
+
if (scheduledIds.size === 0) return "";
|
|
2114
|
+
return [...scheduledIds].sort().join("\0");
|
|
2115
|
+
}
|
|
2116
|
+
function filterTaskSessionState(state, scheduledIds = /* @__PURE__ */ new Set()) {
|
|
1976
2117
|
const src = state ?? { ids: [], byId: {}, current: null };
|
|
2118
|
+
const key = scheduledCacheKey(scheduledIds);
|
|
2119
|
+
if (typeof src === "object" && src !== null) {
|
|
2120
|
+
const hit = taskFilterCache.get(src);
|
|
2121
|
+
if (hit !== void 0 && hit.key === key) return hit.result;
|
|
2122
|
+
}
|
|
1977
2123
|
const ids = (src.ids ?? []).filter((id) => {
|
|
1978
2124
|
const value = String(id);
|
|
1979
|
-
return !value.startsWith(
|
|
2125
|
+
return !value.startsWith("im:") && !isAutomationSidebarSession(value, src.byId?.[value], scheduledIds);
|
|
1980
2126
|
});
|
|
1981
|
-
const
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
}
|
|
1986
|
-
return { ...src, ids, byId };
|
|
2127
|
+
const unchanged = ids.length === (src.ids ?? []).length;
|
|
2128
|
+
const result = unchanged ? src : { ...src, ids, byId: Object.fromEntries(ids.map((id) => [id, src.byId?.[id]]).filter((entry) => entry[1] !== void 0)) };
|
|
2129
|
+
if (typeof src === "object" && src !== null) taskFilterCache.set(src, { key, result });
|
|
2130
|
+
return result;
|
|
1987
2131
|
}
|
|
1988
2132
|
function openScheduledSession(id, openRuntime, openHost) {
|
|
1989
|
-
if (id === "") return;
|
|
2133
|
+
if (id === "") return false;
|
|
1990
2134
|
const attempts = id.startsWith(AUTOMATION_SESSION_PREFIX) || id.startsWith("im:") ? [openRuntime, openHost] : [openHost, openRuntime];
|
|
1991
2135
|
for (const attempt of attempts) {
|
|
1992
2136
|
if (typeof attempt !== "function") continue;
|
|
1993
2137
|
try {
|
|
1994
2138
|
attempt(id);
|
|
1995
|
-
return;
|
|
2139
|
+
return true;
|
|
1996
2140
|
} catch {
|
|
1997
2141
|
}
|
|
1998
2142
|
}
|
|
2143
|
+
return false;
|
|
2144
|
+
}
|
|
2145
|
+
async function ensureOpenScheduledSession(input) {
|
|
2146
|
+
const id = input.id.trim();
|
|
2147
|
+
if (id === "") return false;
|
|
2148
|
+
await input.adopt?.(id).catch(() => void 0);
|
|
2149
|
+
const listed = () => input.listed?.(id) === true;
|
|
2150
|
+
if (!listed() && input.refresh !== void 0) {
|
|
2151
|
+
await input.refresh().catch(() => void 0);
|
|
2152
|
+
}
|
|
2153
|
+
if (openScheduledSession(id, input.openRuntime, input.openHost)) return true;
|
|
2154
|
+
if (input.refresh !== void 0) {
|
|
2155
|
+
await input.refresh().catch(() => void 0);
|
|
2156
|
+
}
|
|
2157
|
+
return openScheduledSession(id, input.openRuntime, input.openHost);
|
|
1999
2158
|
}
|
|
2000
|
-
function isHiddenSidebarSessionId(id) {
|
|
2001
|
-
return id.startsWith(
|
|
2159
|
+
function isHiddenSidebarSessionId(id, scheduledIds = /* @__PURE__ */ new Set()) {
|
|
2160
|
+
return id.startsWith("im:") || isAutomationSidebarSession(id, void 0, scheduledIds);
|
|
2002
2161
|
}
|
|
2003
|
-
function filterWorkspaceListState(state) {
|
|
2162
|
+
function filterWorkspaceListState(state, scheduledIds = /* @__PURE__ */ new Set()) {
|
|
2004
2163
|
const src = state ?? { items: [], archivedSessionIds: [] };
|
|
2005
|
-
const
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2164
|
+
const key = scheduledCacheKey(scheduledIds);
|
|
2165
|
+
if (typeof src === "object" && src !== null) {
|
|
2166
|
+
const hit = workspaceFilterCache.get(src);
|
|
2167
|
+
if (hit !== void 0 && hit.key === key) return hit.result;
|
|
2168
|
+
}
|
|
2169
|
+
let changed = false;
|
|
2170
|
+
const items = (src.items ?? []).map((workspace) => {
|
|
2171
|
+
const sessionIds = (workspace.sessionIds ?? []).filter((sid) => !isHiddenSidebarSessionId(String(sid), scheduledIds));
|
|
2172
|
+
if (sessionIds.length !== (workspace.sessionIds ?? []).length) {
|
|
2173
|
+
changed = true;
|
|
2174
|
+
return { ...workspace, sessionIds };
|
|
2175
|
+
}
|
|
2176
|
+
return workspace;
|
|
2177
|
+
});
|
|
2178
|
+
const result = changed ? { ...src, items } : src;
|
|
2179
|
+
if (typeof src === "object" && src !== null) workspaceFilterCache.set(src, { key, result });
|
|
2180
|
+
return result;
|
|
2010
2181
|
}
|
|
2011
2182
|
function wrapperFlags(component) {
|
|
2012
2183
|
if (component === void 0 || component === null || typeof component !== "function" && typeof component !== "object") return {};
|
|
@@ -2046,29 +2217,140 @@ function pickWrappableWorkspacesEntry(entries) {
|
|
|
2046
2217
|
}
|
|
2047
2218
|
return void 0;
|
|
2048
2219
|
}
|
|
2220
|
+
function applyWorkspaceBrowserQuery(groups, query, sort, groupMode = "workspace") {
|
|
2221
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
2222
|
+
const filtered = groups.map((group) => {
|
|
2223
|
+
if (needle === "") return group;
|
|
2224
|
+
if (group.name.toLocaleLowerCase().includes(needle)) return group;
|
|
2225
|
+
const sessions = group.sessions.filter((session) => `${session.title ?? ""} ${session.label ?? ""}`.toLocaleLowerCase().includes(needle));
|
|
2226
|
+
return { ...group, sessions };
|
|
2227
|
+
}).filter((group) => group.sessions.length > 0 || needle !== "" && group.name.toLocaleLowerCase().includes(needle));
|
|
2228
|
+
if (groupMode === "list") {
|
|
2229
|
+
const sessions = filtered.flatMap((group) => [...group.sessions]);
|
|
2230
|
+
if (sort === "time") sessions.sort((left, right) => sessionTime(right) - sessionTime(left));
|
|
2231
|
+
return sessions.length === 0 ? [] : [{ ...filtered[0], name: "", sessions }];
|
|
2232
|
+
}
|
|
2233
|
+
if (sort === "manual") return filtered;
|
|
2234
|
+
return [...filtered].sort((left, right) => latestSessionTime(right) - latestSessionTime(left));
|
|
2235
|
+
}
|
|
2236
|
+
function sessionTime(session) {
|
|
2237
|
+
const ts = Date.parse(session.updatedAt ?? "");
|
|
2238
|
+
return Number.isFinite(ts) ? ts : 0;
|
|
2239
|
+
}
|
|
2240
|
+
function latestSessionTime(group) {
|
|
2241
|
+
let latest = 0;
|
|
2242
|
+
for (const session of group.sessions) {
|
|
2243
|
+
const ts = sessionTime(session);
|
|
2244
|
+
if (ts > latest) latest = ts;
|
|
2245
|
+
}
|
|
2246
|
+
return latest;
|
|
2247
|
+
}
|
|
2049
2248
|
|
|
2050
|
-
// src/client/
|
|
2249
|
+
// src/client/workspace-toolbar.tsx
|
|
2250
|
+
var import_react4 = require("react");
|
|
2051
2251
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
const ts = Date.parse(value || "");
|
|
2055
|
-
if (!Number.isFinite(ts)) return "";
|
|
2056
|
-
const delta = Math.max(0, Date.now() - ts);
|
|
2057
|
-
const min = Math.floor(delta / 6e4);
|
|
2058
|
-
if (min < 1) return "\u521A\u521A";
|
|
2059
|
-
if (min < 60) return String(min) + "\u5206\u949F";
|
|
2060
|
-
const hour = Math.floor(min / 60);
|
|
2061
|
-
if (hour < 24) return String(hour) + "\u5C0F\u65F6";
|
|
2062
|
-
return String(Math.floor(hour / 24)) + "\u5929";
|
|
2252
|
+
function officialSearchIconSize(expanded) {
|
|
2253
|
+
return expanded ? 11 : 14;
|
|
2063
2254
|
}
|
|
2255
|
+
function WorkspaceToolbar({
|
|
2256
|
+
t,
|
|
2257
|
+
query,
|
|
2258
|
+
sort,
|
|
2259
|
+
groupMode,
|
|
2260
|
+
onQueryChange,
|
|
2261
|
+
onSortChange,
|
|
2262
|
+
onGroupModeChange
|
|
2263
|
+
}) {
|
|
2264
|
+
const [searching, setSearching] = (0, import_react4.useState)(query.trim() !== "");
|
|
2265
|
+
const [filterOpen, setFilterOpen] = (0, import_react4.useState)(false);
|
|
2266
|
+
const inputRef = (0, import_react4.useRef)(null);
|
|
2267
|
+
const rootRef = (0, import_react4.useRef)(null);
|
|
2268
|
+
const searchSize = officialSearchIconSize(searching);
|
|
2269
|
+
(0, import_react4.useEffect)(() => {
|
|
2270
|
+
if (searching) inputRef.current?.focus();
|
|
2271
|
+
}, [searching]);
|
|
2272
|
+
(0, import_react4.useEffect)(() => {
|
|
2273
|
+
if (!filterOpen) return;
|
|
2274
|
+
const close = (event) => {
|
|
2275
|
+
const target = event.target;
|
|
2276
|
+
if (target instanceof Node && rootRef.current?.contains(target)) return;
|
|
2277
|
+
setFilterOpen(false);
|
|
2278
|
+
};
|
|
2279
|
+
document.addEventListener("mousedown", close);
|
|
2280
|
+
return () => document.removeEventListener("mousedown", close);
|
|
2281
|
+
}, [filterOpen]);
|
|
2282
|
+
const openSearch = () => {
|
|
2283
|
+
setFilterOpen(false);
|
|
2284
|
+
setSearching(true);
|
|
2285
|
+
};
|
|
2286
|
+
const closeSearch = () => {
|
|
2287
|
+
onQueryChange("");
|
|
2288
|
+
setSearching(false);
|
|
2289
|
+
};
|
|
2290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: searching ? "dsh-st-n-toolbar is-search" : "dsh-st-n-toolbar", ref: rootRef, children: [
|
|
2291
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-n-head-label", children: t("sidebar.workspaces") }),
|
|
2292
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-n-search-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-n-search", onClick: openSearch, children: [
|
|
2293
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.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_runtime5.jsx)(SearchOutlineIcon, { width: searchSize, height: searchSize }) }),
|
|
2294
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.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) => {
|
|
2295
|
+
if (event.key === "Escape") closeSearch();
|
|
2296
|
+
} }),
|
|
2297
|
+
searching && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "dsh-st-n-search-clear", "aria-label": t("sidebar.clearSearch"), onClick: (event) => {
|
|
2298
|
+
event.stopPropagation();
|
|
2299
|
+
closeSearch();
|
|
2300
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseOutlineIcon, { width: 14, height: 14 }) })
|
|
2301
|
+
] }) }),
|
|
2302
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-n-head-acts", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-n-head-filter", children: [
|
|
2303
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.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_runtime5.jsx)(SlidersIcon, { width: 16, height: 16 }) }),
|
|
2304
|
+
filterOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dsh-st-n-filter-menu", role: "menu", children: [
|
|
2305
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.groupBy") }),
|
|
2306
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FilterRow, { label: t("sidebar.groupWorkspace"), selected: groupMode === "workspace", onSelect: () => {
|
|
2307
|
+
onGroupModeChange("workspace");
|
|
2308
|
+
setFilterOpen(false);
|
|
2309
|
+
} }),
|
|
2310
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FilterRow, { label: t("sidebar.groupList"), selected: groupMode === "list", onSelect: () => {
|
|
2311
|
+
onGroupModeChange("list");
|
|
2312
|
+
setFilterOpen(false);
|
|
2313
|
+
} }),
|
|
2314
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-n-filter-split" }),
|
|
2315
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dsh-st-n-filter-label", children: t("sidebar.sortBy") }),
|
|
2316
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FilterRow, { label: t("sidebar.sortManual"), selected: sort === "manual", onSelect: () => {
|
|
2317
|
+
onSortChange("manual");
|
|
2318
|
+
setFilterOpen(false);
|
|
2319
|
+
} }),
|
|
2320
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FilterRow, { label: t("sidebar.sortTime"), selected: sort === "time", onSelect: () => {
|
|
2321
|
+
onSortChange("time");
|
|
2322
|
+
setFilterOpen(false);
|
|
2323
|
+
} })
|
|
2324
|
+
] })
|
|
2325
|
+
] }) })
|
|
2326
|
+
] });
|
|
2327
|
+
}
|
|
2328
|
+
function FilterRow({
|
|
2329
|
+
label,
|
|
2330
|
+
selected,
|
|
2331
|
+
onSelect
|
|
2332
|
+
}) {
|
|
2333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", role: "menuitemradio", "aria-checked": selected, className: selected ? "is-on" : void 0, onClick: onSelect, children: [
|
|
2334
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: label }),
|
|
2335
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CheckOutlineIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dsh-st-n-filter-tick" })
|
|
2336
|
+
] });
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
// src/client/native-session-list.tsx
|
|
2340
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2341
|
+
var EMPTY_SESSION_BY_ID = {};
|
|
2064
2342
|
function NativeScheduleSessionList(props) {
|
|
2065
|
-
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession,
|
|
2066
|
-
const state = (0,
|
|
2343
|
+
const { t, runtime, openSession, useSessions, useWorkspaces, renameSession, archiveSession, forkSession } = props;
|
|
2344
|
+
const state = (0, import_react5.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
2067
2345
|
const selectedId = useSessions ? useSessions((snap) => snap?.current ?? null) : null;
|
|
2068
2346
|
const sessionById = useSessions ? useSessions((snap) => snap?.byId ?? EMPTY_SESSION_BY_ID) : EMPTY_SESSION_BY_ID;
|
|
2069
2347
|
const archivedIds = useWorkspaces ? useWorkspaces((snap) => snap?.archivedSessionIds ?? []) : [];
|
|
2070
|
-
const [folded, setFolded] = (0,
|
|
2071
|
-
(0,
|
|
2348
|
+
const [folded, setFolded] = (0, import_react5.useState)({});
|
|
2349
|
+
const [openMenu, setOpenMenu] = (0, import_react5.useState)(null);
|
|
2350
|
+
const [query, setQuery] = (0, import_react5.useState)("");
|
|
2351
|
+
const [sort, setSort] = (0, import_react5.useState)("time");
|
|
2352
|
+
const [groupMode, setGroupMode] = (0, import_react5.useState)("workspace");
|
|
2353
|
+
(0, import_react5.useEffect)(() => {
|
|
2072
2354
|
void runtime.refresh().catch(() => void 0);
|
|
2073
2355
|
const timer = window.setInterval(() => {
|
|
2074
2356
|
void runtime.refresh().catch(() => void 0);
|
|
@@ -2077,8 +2359,8 @@ function NativeScheduleSessionList(props) {
|
|
|
2077
2359
|
window.clearInterval(timer);
|
|
2078
2360
|
};
|
|
2079
2361
|
}, [runtime]);
|
|
2080
|
-
const archived = (0,
|
|
2081
|
-
const groups = (0,
|
|
2362
|
+
const archived = (0, import_react5.useMemo)(() => new Set(archivedIds), [archivedIds]);
|
|
2363
|
+
const groups = (0, import_react5.useMemo)(() => {
|
|
2082
2364
|
const snapshot = state.snapshot;
|
|
2083
2365
|
if (snapshot === void 0) return [];
|
|
2084
2366
|
return groupScheduledSessions(snapshot.automations, snapshot.runs).map((group) => ({
|
|
@@ -2094,94 +2376,128 @@ function NativeScheduleSessionList(props) {
|
|
|
2094
2376
|
})
|
|
2095
2377
|
})).filter((group) => group.sessions.length > 0);
|
|
2096
2378
|
}, [archived, sessionById, state.snapshot]);
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2107
|
-
|
|
2108
|
-
"
|
|
2379
|
+
const visibleGroups = (0, import_react5.useMemo)(() => applyWorkspaceBrowserQuery(groups.map((group) => ({ ...group, name: group.name })), query, sort, groupMode), [groups, query, sort, groupMode]);
|
|
2380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n", children: [
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(WorkspaceToolbar, { t, query, sort, groupMode, onQueryChange: setQuery, onSortChange: setSort, onGroupModeChange: setGroupMode }),
|
|
2382
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-tree", role: "tree", children: [
|
|
2383
|
+
state.phase === "loading" && visibleGroups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-empty", children: t("loading") }),
|
|
2384
|
+
visibleGroups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-empty", children: t("sidebar.empty") }),
|
|
2385
|
+
visibleGroups.map((group) => {
|
|
2386
|
+
const expanded = folded[group.id] !== true;
|
|
2387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-group", children: [
|
|
2388
|
+
groupMode === "workspace" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-row", role: "treeitem", "aria-expanded": expanded, onClick: () => setFolded((current) => ({ ...current, [group.id]: expanded })), children: [
|
|
2389
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-slot dsh-st-n-folder", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FolderOpenIcon, { width: 16, height: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FolderClosedIcon, { width: 16, height: 16 }) }),
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-title", children: group.name })
|
|
2391
|
+
] }),
|
|
2392
|
+
(groupMode === "list" || expanded) && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2393
|
+
NativeSessionRow,
|
|
2109
2394
|
{
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2395
|
+
t,
|
|
2396
|
+
id: session.id,
|
|
2397
|
+
title: session.title,
|
|
2398
|
+
hoverTitle: String(sessionById[session.id]?.displayTitle ?? sessionById[session.id]?.title ?? group.name),
|
|
2399
|
+
updatedAt: session.updatedAt,
|
|
2400
|
+
running: session.running,
|
|
2401
|
+
selected: selectedId === session.id,
|
|
2402
|
+
menuOpen: openMenu?.id === session.id,
|
|
2403
|
+
menuPoint: openMenu === null || openMenu.id !== session.id ? { x: 8, y: 8 } : { x: openMenu.x, y: openMenu.y },
|
|
2404
|
+
onToggleMenu: (event) => setOpenMenu((current) => nextOpenSessionMenu(current, session.id, pointerPoint(event))),
|
|
2405
|
+
onCloseMenu: () => setOpenMenu((current) => current?.id === session.id ? null : current),
|
|
2406
|
+
onOpen: () => {
|
|
2407
|
+
setOpenMenu(null);
|
|
2408
|
+
openSession?.(session.id);
|
|
2124
2409
|
},
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
] }),
|
|
2129
|
-
expanded && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2130
|
-
NativeSessionRow,
|
|
2131
|
-
{
|
|
2132
|
-
t,
|
|
2133
|
-
id: session.id,
|
|
2134
|
-
title: session.title,
|
|
2135
|
-
updatedAt: session.updatedAt,
|
|
2136
|
-
running: session.running,
|
|
2137
|
-
selected: selectedId === session.id,
|
|
2138
|
-
onOpen: () => {
|
|
2139
|
-
openSession?.(session.id);
|
|
2140
|
-
void runtime.adoptSession?.(session.id).catch(() => void 0);
|
|
2141
|
-
},
|
|
2142
|
-
onDelete: async () => {
|
|
2143
|
-
try {
|
|
2144
|
-
await deleteSession?.(session.id);
|
|
2145
|
-
} catch {
|
|
2146
|
-
}
|
|
2147
|
-
await runtime.forgetSession(session.id);
|
|
2410
|
+
...renameSession === void 0 ? {} : { renameSession },
|
|
2411
|
+
...archiveSession === void 0 ? {} : { archiveSession },
|
|
2412
|
+
...forkSession === void 0 ? {} : { forkSession }
|
|
2148
2413
|
},
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
] }, group.id);
|
|
2156
|
-
})
|
|
2157
|
-
] }) });
|
|
2414
|
+
session.id
|
|
2415
|
+
))
|
|
2416
|
+
] }, group.id);
|
|
2417
|
+
})
|
|
2418
|
+
] })
|
|
2419
|
+
] });
|
|
2158
2420
|
}
|
|
2159
2421
|
function NativeSessionRow(props) {
|
|
2160
|
-
const { t, id, title, updatedAt, running, selected,
|
|
2161
|
-
const
|
|
2162
|
-
const
|
|
2163
|
-
const
|
|
2164
|
-
(0,
|
|
2422
|
+
const { t, id, title, hoverTitle, updatedAt, running, selected, menuOpen, menuPoint, onToggleMenu, onCloseMenu, onOpen, renameSession, archiveSession, forkSession } = props;
|
|
2423
|
+
const rowRef = (0, import_react5.useRef)(null);
|
|
2424
|
+
const menuRef = (0, import_react5.useRef)(null);
|
|
2425
|
+
const hoverRef = (0, import_react5.useRef)(null);
|
|
2426
|
+
const [hoverOpen, setHoverOpen] = (0, import_react5.useState)(false);
|
|
2427
|
+
const [hoverStyle, setHoverStyle] = (0, import_react5.useState)({});
|
|
2428
|
+
const hoverTimer = (0, import_react5.useRef)(void 0);
|
|
2429
|
+
const [renaming, setRenaming] = (0, import_react5.useState)(false);
|
|
2430
|
+
const [draft, setDraft] = (0, import_react5.useState)(title);
|
|
2431
|
+
const [menuStyle, setMenuStyle] = (0, import_react5.useState)({});
|
|
2432
|
+
(0, import_react5.useEffect)(() => {
|
|
2165
2433
|
setDraft(title);
|
|
2166
2434
|
}, [title]);
|
|
2167
|
-
(0,
|
|
2168
|
-
if (!
|
|
2435
|
+
(0, import_react5.useEffect)(() => {
|
|
2436
|
+
if (!menuOpen) return;
|
|
2169
2437
|
const close = (event) => {
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2438
|
+
if (!shouldCloseNativeSessionMenu(event.target, [rowRef.current, menuRef.current])) return;
|
|
2439
|
+
onCloseMenu();
|
|
2440
|
+
};
|
|
2441
|
+
const onKey = (event) => {
|
|
2442
|
+
if (event.key === "Escape") onCloseMenu();
|
|
2173
2443
|
};
|
|
2174
2444
|
document.addEventListener("mousedown", close);
|
|
2445
|
+
document.addEventListener("keydown", onKey);
|
|
2175
2446
|
return () => {
|
|
2176
2447
|
document.removeEventListener("mousedown", close);
|
|
2448
|
+
document.removeEventListener("keydown", onKey);
|
|
2177
2449
|
};
|
|
2178
|
-
}, [
|
|
2450
|
+
}, [menuOpen, onCloseMenu]);
|
|
2451
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
2452
|
+
if (!menuOpen) return;
|
|
2453
|
+
const update = () => {
|
|
2454
|
+
const el = menuRef.current;
|
|
2455
|
+
const size = el === null ? { width: 218, height: 176 } : { width: el.offsetWidth, height: el.offsetHeight };
|
|
2456
|
+
setMenuStyle(nativeSessionMenuStyle(menuPoint, size, { width: window.innerWidth, height: window.innerHeight }));
|
|
2457
|
+
};
|
|
2458
|
+
update();
|
|
2459
|
+
window.addEventListener("resize", update);
|
|
2460
|
+
document.addEventListener("scroll", update, true);
|
|
2461
|
+
return () => {
|
|
2462
|
+
window.removeEventListener("resize", update);
|
|
2463
|
+
document.removeEventListener("scroll", update, true);
|
|
2464
|
+
};
|
|
2465
|
+
}, [menuOpen, menuPoint]);
|
|
2466
|
+
(0, import_react5.useEffect)(() => {
|
|
2467
|
+
if (!hoverOpen || menuOpen) return;
|
|
2468
|
+
const update = () => {
|
|
2469
|
+
const row = rowRef.current?.getBoundingClientRect();
|
|
2470
|
+
const card = hoverRef.current;
|
|
2471
|
+
if (row === void 0) return;
|
|
2472
|
+
const size = card === null ? { width: 220, height: 96 } : { width: card.offsetWidth, height: card.offsetHeight };
|
|
2473
|
+
setHoverStyle(nativeSessionHoverStyle({ right: row.right, top: row.top }, size, { width: window.innerWidth, height: window.innerHeight }));
|
|
2474
|
+
};
|
|
2475
|
+
update();
|
|
2476
|
+
window.addEventListener("resize", update);
|
|
2477
|
+
document.addEventListener("scroll", update, true);
|
|
2478
|
+
return () => {
|
|
2479
|
+
window.removeEventListener("resize", update);
|
|
2480
|
+
document.removeEventListener("scroll", update, true);
|
|
2481
|
+
};
|
|
2482
|
+
}, [hoverOpen, menuOpen, title, updatedAt, running]);
|
|
2483
|
+
(0, import_react5.useEffect)(() => () => {
|
|
2484
|
+
if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
|
|
2485
|
+
}, []);
|
|
2179
2486
|
const run = (action) => {
|
|
2180
2487
|
void Promise.resolve(action()).catch(() => void 0);
|
|
2181
2488
|
};
|
|
2182
|
-
const
|
|
2489
|
+
const showHover = () => {
|
|
2490
|
+
if (menuOpen) return;
|
|
2491
|
+
if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
|
|
2492
|
+
hoverTimer.current = window.setTimeout(() => setHoverOpen(true), 500);
|
|
2493
|
+
};
|
|
2494
|
+
const hideHover = () => {
|
|
2495
|
+
if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
|
|
2496
|
+
setHoverOpen(false);
|
|
2497
|
+
};
|
|
2498
|
+
const rowClass = "dsh-st-n-sess" + (selected ? " is-on" : "") + (menuOpen ? " is-menu" : "");
|
|
2183
2499
|
if (renaming) {
|
|
2184
|
-
return /* @__PURE__ */ (0,
|
|
2500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: rowClass, ref: rowRef, children: /* @__PURE__ */ (0, import_jsx_runtime6.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) => {
|
|
2185
2501
|
if (event.key === "Enter") {
|
|
2186
2502
|
event.preventDefault();
|
|
2187
2503
|
setRenaming(false);
|
|
@@ -2198,14 +2514,23 @@ function NativeSessionRow(props) {
|
|
|
2198
2514
|
} }) });
|
|
2199
2515
|
}
|
|
2200
2516
|
const menuItems = [
|
|
2201
|
-
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0,
|
|
2517
|
+
{ id: "rename", label: t("session.rename"), icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PencilIcon, { width: 16, height: 16 }), go: () => {
|
|
2202
2518
|
setRenaming(true);
|
|
2203
2519
|
} },
|
|
2204
|
-
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0,
|
|
2205
|
-
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0,
|
|
2206
|
-
{ id: "delete", label: t("session.delete"), icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TrashIcon, { width: 16, height: 16 }), danger: true, go: () => run(() => onDelete()) }
|
|
2520
|
+
{ id: "fork", label: t("session.fork"), icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(BranchIcon, { width: 16, height: 16 }), go: () => run(() => forkSession?.(id)) },
|
|
2521
|
+
{ id: "archive", label: t("session.archive"), icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArchiveIcon, { width: 16, height: 16 }), go: () => run(() => archiveSession?.(id)) }
|
|
2207
2522
|
];
|
|
2208
|
-
|
|
2523
|
+
const menu = menuOpen && typeof document !== "undefined" ? (0, import_react_dom2.createPortal)(
|
|
2524
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsxs)("button", { type: "button", className: void 0, onClick: () => {
|
|
2525
|
+
onCloseMenu();
|
|
2526
|
+
item.go();
|
|
2527
|
+
}, children: [
|
|
2528
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-mi", children: item.icon }),
|
|
2529
|
+
item.label
|
|
2530
|
+
] }, item.id)) }),
|
|
2531
|
+
document.body
|
|
2532
|
+
) : null;
|
|
2533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.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) => {
|
|
2209
2534
|
if (event.key === "Enter" || event.key === " ") {
|
|
2210
2535
|
event.preventDefault();
|
|
2211
2536
|
onOpen();
|
|
@@ -2213,30 +2538,37 @@ function NativeSessionRow(props) {
|
|
|
2213
2538
|
}, onContextMenu: (event) => {
|
|
2214
2539
|
event.preventDefault();
|
|
2215
2540
|
event.stopPropagation();
|
|
2216
|
-
|
|
2541
|
+
onToggleMenu(event);
|
|
2217
2542
|
}, children: [
|
|
2218
|
-
/* @__PURE__ */ (0,
|
|
2219
|
-
/* @__PURE__ */ (0,
|
|
2220
|
-
/* @__PURE__ */ (0,
|
|
2221
|
-
/* @__PURE__ */ (0,
|
|
2543
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-slot", children: running ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RunningStateDot, {}) : null }),
|
|
2544
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-title", children: title }),
|
|
2545
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-time", children: relativeTime(updatedAt) }),
|
|
2546
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dsh-st-n-acts", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dsh-st-n-ico", "aria-label": title + " \u66F4\u591A", onMouseDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
2222
2547
|
event.stopPropagation();
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2548
|
+
hideHover();
|
|
2549
|
+
onToggleMenu(event);
|
|
2550
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EllipsisIcon, { width: 16, height: 16 }) }) }),
|
|
2551
|
+
menu,
|
|
2552
|
+
hoverOpen && !menuOpen && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
|
|
2553
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: hoverRef, className: "dsh-st-n-hover", style: hoverStyle, onMouseEnter: showHover, onMouseLeave: hideHover, children: [
|
|
2554
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-hover-title", children: (hoverTitle ?? title).trim() || title }),
|
|
2555
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dsh-st-n-hover-time", children: relativeTime(updatedAt) }),
|
|
2556
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dsh-st-n-hover-state", children: [
|
|
2557
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: running ? "dsh-st-n-hover-dot is-run" : "dsh-st-n-hover-dot" }),
|
|
2558
|
+
running ? t("session.runningStatus") : t("session.idle")
|
|
2559
|
+
] })
|
|
2560
|
+
] }),
|
|
2561
|
+
document.body
|
|
2562
|
+
)
|
|
2232
2563
|
] });
|
|
2233
2564
|
}
|
|
2234
2565
|
|
|
2235
2566
|
// src/client/ScheduleRail.tsx
|
|
2236
|
-
var
|
|
2237
|
-
var
|
|
2567
|
+
var import_react6 = require("react");
|
|
2568
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2238
2569
|
var EMPTY_EXTRA_TABS = [];
|
|
2239
|
-
var
|
|
2570
|
+
var noopSubscribe = (_listener) => () => void 0;
|
|
2571
|
+
var OfficialTreeGuard = class extends import_react6.Component {
|
|
2240
2572
|
state = { failed: false };
|
|
2241
2573
|
static getDerivedStateFromError() {
|
|
2242
2574
|
return { failed: true };
|
|
@@ -2253,9 +2585,9 @@ function ScheduleRail({
|
|
|
2253
2585
|
runtime,
|
|
2254
2586
|
openSession
|
|
2255
2587
|
}) {
|
|
2256
|
-
const state = (0,
|
|
2257
|
-
const [folded, setFolded] = (0,
|
|
2258
|
-
(0,
|
|
2588
|
+
const state = (0, import_react6.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
2589
|
+
const [folded, setFolded] = (0, import_react6.useState)({});
|
|
2590
|
+
(0, import_react6.useEffect)(() => {
|
|
2259
2591
|
void runtime.refresh().catch(() => void 0);
|
|
2260
2592
|
const timer = window.setInterval(() => {
|
|
2261
2593
|
void runtime.refresh().catch(() => void 0);
|
|
@@ -2264,36 +2596,36 @@ function ScheduleRail({
|
|
|
2264
2596
|
window.clearInterval(timer);
|
|
2265
2597
|
};
|
|
2266
2598
|
}, [runtime]);
|
|
2267
|
-
const groups = (0,
|
|
2599
|
+
const groups = (0, import_react6.useMemo)(() => {
|
|
2268
2600
|
const snapshot = state.snapshot;
|
|
2269
2601
|
if (snapshot === void 0) return [];
|
|
2270
2602
|
return groupScheduledSessions(snapshot.automations, snapshot.runs);
|
|
2271
2603
|
}, [state.snapshot]);
|
|
2272
|
-
return /* @__PURE__ */ (0,
|
|
2273
|
-
state.phase === "loading" && groups.length === 0 && /* @__PURE__ */ (0,
|
|
2274
|
-
groups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0,
|
|
2275
|
-
groups.map((group) => /* @__PURE__ */ (0,
|
|
2276
|
-
/* @__PURE__ */ (0,
|
|
2604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-rail", children: [
|
|
2605
|
+
state.phase === "loading" && groups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-rail-empty", children: t("loading") }),
|
|
2606
|
+
groups.length === 0 && state.phase !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.empty") }),
|
|
2607
|
+
groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
2608
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2277
2609
|
"button",
|
|
2278
2610
|
{
|
|
2279
2611
|
type: "button",
|
|
2280
2612
|
className: "dsh-st-rail-head",
|
|
2281
2613
|
onClick: () => setFolded((current) => ({ ...current, [group.id]: !current[group.id] })),
|
|
2282
2614
|
children: [
|
|
2283
|
-
/* @__PURE__ */ (0,
|
|
2284
|
-
/* @__PURE__ */ (0,
|
|
2615
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-rail-folder", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ClockIcon, { width: 16, height: 16 }) }),
|
|
2616
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-rail-title", children: group.name })
|
|
2285
2617
|
]
|
|
2286
2618
|
}
|
|
2287
2619
|
),
|
|
2288
|
-
folded[group.id] !== true && group.sessions.map((session) => /* @__PURE__ */ (0,
|
|
2620
|
+
folded[group.id] !== true && group.sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2289
2621
|
"button",
|
|
2290
2622
|
{
|
|
2291
2623
|
type: "button",
|
|
2292
2624
|
className: "dsh-st-rail-session",
|
|
2293
2625
|
onClick: () => openSession?.(session.id),
|
|
2294
2626
|
children: [
|
|
2295
|
-
/* @__PURE__ */ (0,
|
|
2296
|
-
session.running && /* @__PURE__ */ (0,
|
|
2627
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: session.label }),
|
|
2628
|
+
session.running && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RunningStateDot, {})
|
|
2297
2629
|
]
|
|
2298
2630
|
},
|
|
2299
2631
|
session.id
|
|
@@ -2316,26 +2648,20 @@ function NativeScheduleShell({
|
|
|
2316
2648
|
wide
|
|
2317
2649
|
}) {
|
|
2318
2650
|
const Official = officialTree;
|
|
2319
|
-
const [tab, setTab] = (0,
|
|
2651
|
+
const [tab, setTab] = (0, import_react6.useState)(() => {
|
|
2320
2652
|
try {
|
|
2321
2653
|
return readNativeSidebarTab(window.localStorage.getItem(NATIVE_SIDEBAR_TAB_KEY));
|
|
2322
2654
|
} catch {
|
|
2323
2655
|
return "tasks";
|
|
2324
2656
|
}
|
|
2325
2657
|
});
|
|
2326
|
-
const extraTabs = (0,
|
|
2327
|
-
tabRegistry?.subscribe ??
|
|
2328
|
-
listener();
|
|
2329
|
-
return () => void 0;
|
|
2330
|
-
}),
|
|
2658
|
+
const extraTabs = (0, import_react6.useSyncExternalStore)(
|
|
2659
|
+
tabRegistry?.subscribe ?? noopSubscribe,
|
|
2331
2660
|
() => tabRegistry?.getTabs() ?? EMPTY_EXTRA_TABS,
|
|
2332
2661
|
() => EMPTY_EXTRA_TABS
|
|
2333
2662
|
);
|
|
2334
|
-
const channelsReady = (0,
|
|
2335
|
-
subscribeChannels ??
|
|
2336
|
-
listener();
|
|
2337
|
-
return () => void 0;
|
|
2338
|
-
}),
|
|
2663
|
+
const channelsReady = (0, import_react6.useSyncExternalStore)(
|
|
2664
|
+
subscribeChannels ?? noopSubscribe,
|
|
2339
2665
|
() => {
|
|
2340
2666
|
try {
|
|
2341
2667
|
return hasChannels?.() === true;
|
|
@@ -2346,26 +2672,39 @@ function NativeScheduleShell({
|
|
|
2346
2672
|
() => false
|
|
2347
2673
|
);
|
|
2348
2674
|
const currentId = useSessions?.((state) => state?.current ?? null);
|
|
2349
|
-
const
|
|
2675
|
+
const automationState = (0, import_react6.useSyncExternalStore)(runtime.source.subscribe, runtime.source.getSnapshot, runtime.source.getSnapshot);
|
|
2676
|
+
const scheduledIds = (0, import_react6.useMemo)(() => collectScheduledSessionIds(automationState.snapshot?.runs), [automationState.snapshot]);
|
|
2677
|
+
const useFilteredSessions = (0, import_react6.useCallback)((selector, eq) => {
|
|
2350
2678
|
if (useSessions === void 0) return selector({ ids: [], byId: {}, current: null });
|
|
2351
|
-
return useSessions((state) => selector(filterTaskSessionState(state)));
|
|
2352
|
-
}, [useSessions]);
|
|
2353
|
-
const useFilteredWorkspaces = (0,
|
|
2679
|
+
return useSessions((state) => selector(filterTaskSessionState(state, scheduledIds)), eq);
|
|
2680
|
+
}, [useSessions, scheduledIds]);
|
|
2681
|
+
const useFilteredWorkspaces = (0, import_react6.useCallback)((selector, eq) => {
|
|
2354
2682
|
if (useWorkspaces === void 0) return selector({ items: [], archivedSessionIds: [] });
|
|
2355
|
-
return useWorkspaces((state) => selector(filterWorkspaceListState(state)));
|
|
2356
|
-
}, [useWorkspaces]);
|
|
2357
|
-
(0,
|
|
2683
|
+
return useWorkspaces((state) => selector(filterWorkspaceListState(state, scheduledIds)), eq);
|
|
2684
|
+
}, [useWorkspaces, scheduledIds]);
|
|
2685
|
+
(0, import_react6.useEffect)(() => {
|
|
2358
2686
|
try {
|
|
2359
2687
|
window.localStorage.setItem(NATIVE_SIDEBAR_TAB_KEY, tab);
|
|
2360
2688
|
} catch {
|
|
2361
2689
|
}
|
|
2362
2690
|
}, [tab]);
|
|
2363
|
-
(0,
|
|
2364
|
-
|
|
2365
|
-
|
|
2691
|
+
const previousCurrentId = (0, import_react6.useRef)(currentId);
|
|
2692
|
+
const tabFollowReady = (0, import_react6.useRef)(false);
|
|
2693
|
+
(0, import_react6.useEffect)(() => {
|
|
2694
|
+
if (!tabFollowReady.current) {
|
|
2695
|
+
tabFollowReady.current = true;
|
|
2696
|
+
previousCurrentId.current = currentId;
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
const previous = previousCurrentId.current;
|
|
2700
|
+
previousCurrentId.current = currentId;
|
|
2701
|
+
if (!shouldFollowSessionTab(previous, currentId)) return;
|
|
2702
|
+
const next = tabForSessionId(currentId ?? void 0, scheduledIds);
|
|
2703
|
+
const extraIds = extraTabs.map((item) => item.id);
|
|
2704
|
+
if (next === "channels" && (channelsReady || extraIds.includes("channels"))) setTab("channels");
|
|
2366
2705
|
const matched = extraTabs.find((item) => currentId !== void 0 && currentId !== null && item.matchSession?.(String(currentId)) === true);
|
|
2367
|
-
if (matched !== void 0) setTab(matched.id);
|
|
2368
|
-
}, [currentId, channelsReady, extraTabs]);
|
|
2706
|
+
if (matched !== void 0 && matched.id !== "schedule") setTab(matched.id);
|
|
2707
|
+
}, [currentId, channelsReady, extraTabs, scheduledIds]);
|
|
2369
2708
|
const rawOfficialProps = { ...hostProps ?? {}, ...wide === void 0 ? {} : { wide } };
|
|
2370
2709
|
const filteredOfficialProps = {
|
|
2371
2710
|
...rawOfficialProps,
|
|
@@ -2374,19 +2713,27 @@ function NativeScheduleShell({
|
|
|
2374
2713
|
};
|
|
2375
2714
|
const renderOfficial = (props) => {
|
|
2376
2715
|
if (Official === void 0) {
|
|
2377
|
-
return /* @__PURE__ */ (0,
|
|
2716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NativeTaskRail, { t, ...openSession === void 0 ? {} : { openSession }, ...useSessions === void 0 ? {} : { useSessions: useFilteredSessions }, ...useWorkspaces === void 0 ? {} : { useWorkspaces } });
|
|
2378
2717
|
}
|
|
2379
|
-
return /* @__PURE__ */ (0,
|
|
2718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(OfficialTreeGuard, { fallback: (0, import_react6.createElement)(Official, rawOfficialProps), children: (0, import_react6.createElement)(Official, props) });
|
|
2380
2719
|
};
|
|
2381
|
-
if (wide === false) return /* @__PURE__ */ (0,
|
|
2382
|
-
const
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2720
|
+
if (wide === false) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: renderOfficial(filteredOfficialProps) });
|
|
2721
|
+
const foreignTabs = extraTabs.filter((item) => item.id !== "schedule");
|
|
2722
|
+
const visibleTab = resolveVisibleSidebarTab({
|
|
2723
|
+
tab,
|
|
2724
|
+
channelsReady,
|
|
2725
|
+
extraTabIds: ownedSidebarTabIds({ extraTabIds: foreignTabs.map((item) => item.id), channelsReady })
|
|
2726
|
+
});
|
|
2727
|
+
const hostedSchedule = extraTabs.find((item) => item.id === "schedule");
|
|
2728
|
+
const scheduleBody = hostedSchedule === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.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 });
|
|
2729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-shell-rail", children: [
|
|
2730
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-st-shell-tabs", role: "tablist", "aria-label": t("sidebar.tabs"), children: [
|
|
2731
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "tasks", className: visibleTab === "tasks" ? "is-on" : void 0, onClick: () => setTab("tasks"), children: t("sidebar.tasksTab") }),
|
|
2732
|
+
foreignTabs.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.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)),
|
|
2733
|
+
channelsReady && foreignTabs.every((item) => item.id !== "channels") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "channels", className: visibleTab === "channels" ? "is-on" : void 0, onClick: () => setTab("channels"), children: t("sidebar.channelsTab") }),
|
|
2734
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", role: "tab", "aria-selected": visibleTab === "schedule", className: visibleTab === "schedule" ? "is-on" : void 0, onClick: () => setTab("schedule"), children: t("sidebar.tab") })
|
|
2388
2735
|
] }),
|
|
2389
|
-
|
|
2736
|
+
visibleTab === "schedule" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-shell-body", children: scheduleBody }) : foreignTabs.find((item) => item.id === visibleTab) !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.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_runtime7.jsx)("div", { className: "dsh-st-shell-body", children: renderSlot?.("sidebar.channels", { ...hostProps ?? {}, openSession, open: openSession, useSessions, wide: true, skin: "native" }) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-official-tree", children: renderOfficial(filteredOfficialProps) })
|
|
2390
2737
|
] });
|
|
2391
2738
|
}
|
|
2392
2739
|
function NativeTaskRail({
|
|
@@ -2398,10 +2745,10 @@ function NativeTaskRail({
|
|
|
2398
2745
|
const snap = useSessions === void 0 ? { ids: [], byId: {}, current: null } : useSessions((state) => state ?? { ids: [], byId: {}, current: null });
|
|
2399
2746
|
const workspaces = useWorkspaces === void 0 ? void 0 : useWorkspaces((state) => state ?? { items: [], archivedSessionIds: [] });
|
|
2400
2747
|
const groups = groupNativeTaskSessions(snap, workspaces, t("sidebar.ungrouped"));
|
|
2401
|
-
if (groups.length === 0) return /* @__PURE__ */ (0,
|
|
2402
|
-
return /* @__PURE__ */ (0,
|
|
2403
|
-
/* @__PURE__ */ (0,
|
|
2404
|
-
group.sessions.map((item) => /* @__PURE__ */ (0,
|
|
2748
|
+
if (groups.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-rail-empty", children: t("sidebar.tasksEmpty") });
|
|
2749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-rail", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "dsh-st-rail-group", children: [
|
|
2750
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-st-rail-head is-static", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-st-rail-title", children: group.label }) }),
|
|
2751
|
+
group.sessions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2405
2752
|
"button",
|
|
2406
2753
|
{
|
|
2407
2754
|
type: "button",
|
|
@@ -2409,7 +2756,7 @@ function NativeTaskRail({
|
|
|
2409
2756
|
onClick: () => {
|
|
2410
2757
|
if (item.id !== void 0) openSession?.(item.id);
|
|
2411
2758
|
},
|
|
2412
|
-
children: /* @__PURE__ */ (0,
|
|
2759
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: item.title || item.id })
|
|
2413
2760
|
},
|
|
2414
2761
|
item.id
|
|
2415
2762
|
))
|
|
@@ -2556,7 +2903,7 @@ var CSS_TEXT = `
|
|
|
2556
2903
|
.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}
|
|
2557
2904
|
.dsh-st-rail-head.is-static{cursor:default;font-weight:600}
|
|
2558
2905
|
.dsh-st-rail-session.is-on{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06))}
|
|
2559
|
-
.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-
|
|
2906
|
+
.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}
|
|
2560
2907
|
`;
|
|
2561
2908
|
function installStyles() {
|
|
2562
2909
|
const existing = document.getElementById(STYLE_ID);
|
|
@@ -2610,7 +2957,8 @@ function apply(ctx) {
|
|
|
2610
2957
|
label: () => t("tab"),
|
|
2611
2958
|
icon: "schedule"
|
|
2612
2959
|
}, function ScheduledTasksSettings(props) {
|
|
2613
|
-
|
|
2960
|
+
const workspacesApi = readOptionalWorkspaces(ctx);
|
|
2961
|
+
return (0, import_react7.createElement)(AutomationView, { t, runtime, ...props.close === void 0 ? {} : { closeSettings: props.close }, ...workspacesApi === void 0 ? {} : { pickWorkspaceDirectory: () => workspacesApi.pickDirectory() } });
|
|
2614
2962
|
}));
|
|
2615
2963
|
ctx.slots.inject("sidebar.schedule", () => ctx.slots.register({
|
|
2616
2964
|
name: "sidebar.schedule",
|
|
@@ -2619,27 +2967,30 @@ function apply(ctx) {
|
|
|
2619
2967
|
locale: NS,
|
|
2620
2968
|
label: () => t("sidebar.tab")
|
|
2621
2969
|
}, function AutomationScheduleRail(props) {
|
|
2622
|
-
return (0,
|
|
2970
|
+
return (0, import_react7.createElement)(ScheduleRail, {
|
|
2623
2971
|
t,
|
|
2624
2972
|
runtime,
|
|
2625
|
-
openSession: (
|
|
2626
|
-
openScheduledSession(id, (sessionId) => {
|
|
2627
|
-
ctx.sessions?.open(sessionId);
|
|
2628
|
-
}, props.openSession);
|
|
2629
|
-
}
|
|
2973
|
+
openSession: createScheduledSessionOpener(ctx, runtime, props.openSession)
|
|
2630
2974
|
});
|
|
2631
2975
|
}));
|
|
2632
2976
|
ctx.slots.inject("sidebar.workspaces", () => {
|
|
2633
2977
|
let wrappedEntry;
|
|
2634
2978
|
let originalComp;
|
|
2635
2979
|
let removeInsertedTab = () => void 0;
|
|
2636
|
-
let
|
|
2980
|
+
let wrapped = false;
|
|
2637
2981
|
let syncing = false;
|
|
2982
|
+
let retryTimer;
|
|
2983
|
+
const listenChannels = (listener) => ctx.slots.subscribe?.("sidebar.channels", listener) ?? (() => void 0);
|
|
2984
|
+
const stopRetry = () => {
|
|
2985
|
+
if (retryTimer !== void 0) {
|
|
2986
|
+
window.clearInterval(retryTimer);
|
|
2987
|
+
retryTimer = void 0;
|
|
2988
|
+
}
|
|
2989
|
+
};
|
|
2638
2990
|
const unwrap = () => {
|
|
2991
|
+
stopRetry();
|
|
2639
2992
|
removeInsertedTab();
|
|
2640
2993
|
removeInsertedTab = () => void 0;
|
|
2641
|
-
removeFilter();
|
|
2642
|
-
removeFilter = () => void 0;
|
|
2643
2994
|
if (wrappedEntry !== void 0 && originalComp !== void 0) {
|
|
2644
2995
|
try {
|
|
2645
2996
|
wrappedEntry.component = originalComp;
|
|
@@ -2648,12 +2999,12 @@ function apply(ctx) {
|
|
|
2648
2999
|
}
|
|
2649
3000
|
wrappedEntry = void 0;
|
|
2650
3001
|
originalComp = void 0;
|
|
3002
|
+
wrapped = false;
|
|
2651
3003
|
};
|
|
2652
3004
|
const insertScheduleTab = (entry, openSession) => {
|
|
2653
3005
|
const registry = findNativeTabRegistry(entry);
|
|
2654
3006
|
if (registry === void 0) return false;
|
|
2655
3007
|
if (registry.getTabs().some((item) => item.id === "schedule")) return true;
|
|
2656
|
-
removeInsertedTab();
|
|
2657
3008
|
removeInsertedTab = registry.insert({
|
|
2658
3009
|
id: "schedule",
|
|
2659
3010
|
label: t("sidebar.tab"),
|
|
@@ -2661,12 +3012,8 @@ function apply(ctx) {
|
|
|
2661
3012
|
matchSession: (sessionId) => sessionId.startsWith(AUTOMATION_SESSION_PREFIX),
|
|
2662
3013
|
render: (props) => {
|
|
2663
3014
|
const hostOpen = typeof props.openSession === "function" ? props.openSession : typeof props.open === "function" ? props.open : openSession;
|
|
2664
|
-
const opener = (
|
|
2665
|
-
|
|
2666
|
-
ctx.sessions?.open(sessionId);
|
|
2667
|
-
}, hostOpen);
|
|
2668
|
-
};
|
|
2669
|
-
return (0, import_react6.createElement)(NativeScheduleSessionList, {
|
|
3015
|
+
const opener = createScheduledSessionOpener(ctx, runtime, hostOpen);
|
|
3016
|
+
return (0, import_react7.createElement)(NativeScheduleSessionList, {
|
|
2670
3017
|
t,
|
|
2671
3018
|
runtime,
|
|
2672
3019
|
openSession: opener,
|
|
@@ -2679,21 +3026,35 @@ function apply(ctx) {
|
|
|
2679
3026
|
});
|
|
2680
3027
|
}
|
|
2681
3028
|
});
|
|
2682
|
-
removeFilter();
|
|
2683
|
-
removeFilter = registry.addSessionFilter((id) => !id.startsWith(AUTOMATION_SESSION_PREFIX));
|
|
2684
3029
|
return true;
|
|
2685
3030
|
};
|
|
3031
|
+
const insertIntoKnownHosts = () => {
|
|
3032
|
+
const entries = readSlotEntries(ctx, "sidebar.workspaces");
|
|
3033
|
+
for (const entry of entries) {
|
|
3034
|
+
const record = entry;
|
|
3035
|
+
if (insertScheduleTab(entry) || insertScheduleTab(record.component)) return true;
|
|
3036
|
+
}
|
|
3037
|
+
return wrappedEntry !== void 0 && insertScheduleTab(wrappedEntry);
|
|
3038
|
+
};
|
|
3039
|
+
const ensureScheduleTab = () => {
|
|
3040
|
+
if (insertIntoKnownHosts()) {
|
|
3041
|
+
stopRetry();
|
|
3042
|
+
return;
|
|
3043
|
+
}
|
|
3044
|
+
if (retryTimer !== void 0) return;
|
|
3045
|
+
let tries = 0;
|
|
3046
|
+
retryTimer = window.setInterval(() => {
|
|
3047
|
+
tries += 1;
|
|
3048
|
+
if (insertIntoKnownHosts() || tries >= 20) stopRetry();
|
|
3049
|
+
}, 250);
|
|
3050
|
+
};
|
|
2686
3051
|
const sync = () => {
|
|
2687
3052
|
if (syncing) return;
|
|
2688
3053
|
syncing = true;
|
|
2689
3054
|
try {
|
|
2690
3055
|
let AutomationNativeWorkspaceShell2 = function(innerProps) {
|
|
2691
|
-
const openSession = (
|
|
2692
|
-
|
|
2693
|
-
ctx.sessions?.open(sessionId);
|
|
2694
|
-
}, innerProps.openSession ?? innerProps.open);
|
|
2695
|
-
};
|
|
2696
|
-
return (0, import_react6.createElement)(NativeScheduleShell, {
|
|
3056
|
+
const openSession = createScheduledSessionOpener(ctx, runtime, innerProps.openSession ?? innerProps.open);
|
|
3057
|
+
return (0, import_react7.createElement)(NativeScheduleShell, {
|
|
2697
3058
|
t,
|
|
2698
3059
|
runtime,
|
|
2699
3060
|
hostProps: innerProps,
|
|
@@ -2701,7 +3062,7 @@ function apply(ctx) {
|
|
|
2701
3062
|
tabRegistry: registry,
|
|
2702
3063
|
...innerProps.wide === void 0 ? {} : { wide: innerProps.wide },
|
|
2703
3064
|
hasChannels: () => slotHasEntries(ctx, "sidebar.channels"),
|
|
2704
|
-
subscribeChannels:
|
|
3065
|
+
subscribeChannels: listenChannels,
|
|
2705
3066
|
...innerProps.useSessions === void 0 ? {} : { useSessions: innerProps.useSessions },
|
|
2706
3067
|
...innerProps.useWorkspaces === void 0 ? {} : { useWorkspaces: innerProps.useWorkspaces },
|
|
2707
3068
|
...innerProps.renderSlot === void 0 ? {} : { renderSlot: innerProps.renderSlot },
|
|
@@ -2717,14 +3078,14 @@ function apply(ctx) {
|
|
|
2717
3078
|
const occupant = pickWrappableWorkspacesEntry(entries);
|
|
2718
3079
|
const current = occupant?.component;
|
|
2719
3080
|
if (current !== void 0 && isForeignSidebarHost(current)) {
|
|
2720
|
-
|
|
3081
|
+
ensureScheduleTab();
|
|
2721
3082
|
return;
|
|
2722
3083
|
}
|
|
2723
3084
|
if (wrappedEntry?.component !== void 0 && wrappedEntry.component.__dshAutomationWrapped === true) {
|
|
2724
|
-
|
|
3085
|
+
ensureScheduleTab();
|
|
2725
3086
|
return;
|
|
2726
3087
|
}
|
|
2727
|
-
if (occupant?.component === void 0) return;
|
|
3088
|
+
if (occupant?.component === void 0 || wrapped) return;
|
|
2728
3089
|
const resolved = resolveOfficialTreeComponent(occupant.component);
|
|
2729
3090
|
if (resolved === void 0) return;
|
|
2730
3091
|
originalComp = resolved;
|
|
@@ -2738,9 +3099,8 @@ function apply(ctx) {
|
|
|
2738
3099
|
attachNativeTabRegistry(marked, registry);
|
|
2739
3100
|
occupant.component = marked;
|
|
2740
3101
|
wrappedEntry = occupant;
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
});
|
|
3102
|
+
wrapped = true;
|
|
3103
|
+
ensureScheduleTab();
|
|
2744
3104
|
} catch (error) {
|
|
2745
3105
|
console.warn("[dsh-automation] \u5305\u88F9\u5B98\u65B9\u4EFB\u52A1\u6811\u5931\u8D25", error);
|
|
2746
3106
|
} finally {
|
|
@@ -2749,6 +3109,7 @@ function apply(ctx) {
|
|
|
2749
3109
|
};
|
|
2750
3110
|
sync();
|
|
2751
3111
|
const unsub = typeof ctx.slots.subscribe === "function" ? ctx.slots.subscribe("sidebar.workspaces", sync) : () => void 0;
|
|
3112
|
+
ensureScheduleTab();
|
|
2752
3113
|
return () => {
|
|
2753
3114
|
unsub();
|
|
2754
3115
|
unwrap();
|
|
@@ -2761,8 +3122,25 @@ function apply(ctx) {
|
|
|
2761
3122
|
locale: NS
|
|
2762
3123
|
}, PrefillBridge));
|
|
2763
3124
|
}
|
|
3125
|
+
function createScheduledSessionOpener(ctx, runtime, hostOpen) {
|
|
3126
|
+
return (sessionId) => {
|
|
3127
|
+
void ensureOpenScheduledSession({
|
|
3128
|
+
id: sessionId,
|
|
3129
|
+
adopt: (id) => runtime.adoptSession(id),
|
|
3130
|
+
listed: (id) => {
|
|
3131
|
+
const snap = ctx.sessions?.list?.getSnapshot();
|
|
3132
|
+
return snap?.byId?.[id] !== void 0 || (snap?.ids ?? []).some((item) => item === id);
|
|
3133
|
+
},
|
|
3134
|
+
...ctx.sessions?.refresh === void 0 ? {} : { refresh: () => ctx.sessions.refresh() },
|
|
3135
|
+
...ctx.sessions === void 0 ? {} : { openRuntime: (id) => {
|
|
3136
|
+
ctx.sessions.open(id);
|
|
3137
|
+
} },
|
|
3138
|
+
...hostOpen === void 0 ? {} : { openHost: hostOpen }
|
|
3139
|
+
});
|
|
3140
|
+
};
|
|
3141
|
+
}
|
|
2764
3142
|
function PrefillBridge(props) {
|
|
2765
|
-
(0,
|
|
3143
|
+
(0, import_react7.useEffect)(() => {
|
|
2766
3144
|
const applyPrefill = (text) => {
|
|
2767
3145
|
if (text === null || text === "") return;
|
|
2768
3146
|
if (props.inputActions !== void 0) {
|
|
@@ -2788,5 +3166,12 @@ function readSlotEntries(ctx, name2) {
|
|
|
2788
3166
|
function slotHasEntries(ctx, name2) {
|
|
2789
3167
|
return readSlotEntries(ctx, name2).length > 0;
|
|
2790
3168
|
}
|
|
3169
|
+
function readOptionalWorkspaces(ctx) {
|
|
3170
|
+
try {
|
|
3171
|
+
return ctx.workspaces;
|
|
3172
|
+
} catch {
|
|
3173
|
+
return void 0;
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
2791
3176
|
return module.exports; } });
|
|
2792
3177
|
//# sourceMappingURL=client.js.map
|