dsh-plugin-t-expert 0.3.90 → 0.3.92
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/README.md +1 -26
- package/icon.svg +17 -0
- package/lib/client.js +233 -1461
- package/lib/i18n.js +0 -26
- package/lib/index.js +3 -125
- package/lib/remote-schemas.js +0 -72
- package/lib/remote.js +2 -145
- package/package.json +3 -2
- package/lib/schedule.js +0 -509
package/lib/client.js
CHANGED
|
@@ -39,7 +39,7 @@ __export(index_exports, {
|
|
|
39
39
|
inject: () => inject
|
|
40
40
|
});
|
|
41
41
|
module.exports = __toCommonJS(index_exports);
|
|
42
|
-
var
|
|
42
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
43
43
|
|
|
44
44
|
// src/client/attention.jsx
|
|
45
45
|
var import_react2 = __toESM(require("react"), 1);
|
|
@@ -103,8 +103,8 @@ function subscribePopoverClaims(listener) {
|
|
|
103
103
|
// src/client/state.js
|
|
104
104
|
var import_react = __toESM(require("react"), 1);
|
|
105
105
|
var NS = "t-team";
|
|
106
|
-
var CLIENT_BUILD_VERSION = "0.3.
|
|
107
|
-
var uiPrefs = {
|
|
106
|
+
var CLIENT_BUILD_VERSION = "0.3.92";
|
|
107
|
+
var uiPrefs = { showActivePulse: true };
|
|
108
108
|
var UI_PREF_KEYS = Object.keys(uiPrefs);
|
|
109
109
|
var uiPrefsListeners = /* @__PURE__ */ new Set();
|
|
110
110
|
function setUiPrefs(next) {
|
|
@@ -118,13 +118,6 @@ function setUiPrefs(next) {
|
|
|
118
118
|
if (!changed) return;
|
|
119
119
|
for (const listener of uiPrefsListeners) listener();
|
|
120
120
|
}
|
|
121
|
-
function subscribeUiPrefs(listener) {
|
|
122
|
-
uiPrefsListeners.add(listener);
|
|
123
|
-
return () => uiPrefsListeners.delete(listener);
|
|
124
|
-
}
|
|
125
|
-
function scheduleEntryVisible() {
|
|
126
|
-
return uiPrefs.showScheduleButton !== false;
|
|
127
|
-
}
|
|
128
121
|
function useUiPref(key, fallback = true) {
|
|
129
122
|
return import_react.default.useSyncExternalStore(
|
|
130
123
|
(onChange) => {
|
|
@@ -135,9 +128,6 @@ function useUiPref(key, fallback = true) {
|
|
|
135
128
|
() => fallback
|
|
136
129
|
);
|
|
137
130
|
}
|
|
138
|
-
function useShowScheduleButton() {
|
|
139
|
-
return useUiPref("showScheduleButton", true);
|
|
140
|
-
}
|
|
141
131
|
function useShowActivePulse() {
|
|
142
132
|
return useUiPref("showActivePulse", true);
|
|
143
133
|
}
|
|
@@ -484,51 +474,6 @@ function displayDescription(expert, active) {
|
|
|
484
474
|
function divisionLabel(expert, active) {
|
|
485
475
|
return active === "en" ? expert.divisionEn || expert.division : expert.divisionZh || expert.division;
|
|
486
476
|
}
|
|
487
|
-
function matchExpertAtHead(text, experts, active) {
|
|
488
|
-
if (!text.startsWith("@")) return void 0;
|
|
489
|
-
let matched;
|
|
490
|
-
for (const expert of experts ?? []) {
|
|
491
|
-
const names = [displayName(expert, active), expert?.name, expert?.nameEn, expert?.slug].filter((name) => typeof name === "string" && name !== "");
|
|
492
|
-
for (const name of names) {
|
|
493
|
-
if (!text.startsWith(`@${name}`)) continue;
|
|
494
|
-
if (matched === void 0 || name.length > matched.name.length) {
|
|
495
|
-
matched = { name, display: displayName(expert, active) };
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
return matched;
|
|
500
|
-
}
|
|
501
|
-
function tokenizePrompt(text, experts, active) {
|
|
502
|
-
const raw = String(text ?? "");
|
|
503
|
-
const tokens = [];
|
|
504
|
-
let buffer = "";
|
|
505
|
-
let rest = raw;
|
|
506
|
-
const flush = () => {
|
|
507
|
-
if (buffer === "") return;
|
|
508
|
-
tokens.push({ type: "text", text: buffer });
|
|
509
|
-
buffer = "";
|
|
510
|
-
};
|
|
511
|
-
while (rest !== "") {
|
|
512
|
-
const hit = rest.startsWith("@") ? matchExpertAtHead(rest, experts, active) : void 0;
|
|
513
|
-
if (hit === void 0) {
|
|
514
|
-
buffer += rest[0];
|
|
515
|
-
rest = rest.slice(1);
|
|
516
|
-
continue;
|
|
517
|
-
}
|
|
518
|
-
flush();
|
|
519
|
-
tokens.push({ type: "expert", name: hit.display });
|
|
520
|
-
rest = rest.slice(hit.name.length + 1);
|
|
521
|
-
}
|
|
522
|
-
flush();
|
|
523
|
-
return tokens;
|
|
524
|
-
}
|
|
525
|
-
function collectExpertMentions(text, experts, active) {
|
|
526
|
-
const names = [];
|
|
527
|
-
for (const token of tokenizePrompt(text, experts, active)) {
|
|
528
|
-
if (token.type === "expert" && !names.includes(token.name)) names.push(token.name);
|
|
529
|
-
}
|
|
530
|
-
return names;
|
|
531
|
-
}
|
|
532
477
|
function matchExpert(expert, active, query) {
|
|
533
478
|
if (query === "") return true;
|
|
534
479
|
const haystack = `${expert.name} ${expert.nameEn} ${expert.description} ${expert.descriptionEn} ${expert.slug}`.toLowerCase();
|
|
@@ -662,9 +607,16 @@ var CSS = `
|
|
|
662
607
|
.t-team-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px 12px}
|
|
663
608
|
.t-team-group{margin-top:6px}
|
|
664
609
|
.t-team-division{font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary);margin:2px 0 6px}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
.
|
|
610
|
+
/* \u5361\u7247\u8FB9\u6846\uFF082026-09-26 \u7528\u6237\u53CD\u9988\u300C\u8FB9\u6846\u592A\u660E\u663E\u4E86\uFF0C\u4E0D\u534F\u8C03\u300D\uFF09\uFF1A
|
|
611
|
+
\u539F\u5148\u300C\u5DF2\u542F\u7528\u300D\u7684\u5361\u7247\u7528 button-primary-fill \u63CF\u8FB9\uFF0C\u4F46\u9010\u4E13\u5BB6\u542F\u505C\u5F00\u5173\u65E9\u5DF2\u4E0B\u7EBF
|
|
612
|
+
\uFF08\u89C1 settings.jsx \u91CC\u90A3\u6BB5\u6CE8\u91CA\uFF09\uFF0C\u540D\u5355\u9ED8\u8BA4\u5168\u90E8\u542F\u7528 \u2014\u2014 \u4E8E\u662F 323 \u5F20\u5361\u65E0\u4E00\u4F8B\u5916\u90FD\u6302\u4E0A
|
|
613
|
+
\u8FD1\u767D\u4E3B\u8272\u63CF\u8FB9\uFF08\u6DF1\u8272\u4E3B\u9898\u4E0B\u5C31\u662F --dsw-static-neutral-bluish-50 = #f9fafb\uFF09\uFF0C
|
|
614
|
+
\u5728 #2c2c2e \u7684\u5361\u7247\u5E95\u4E0A\u4EAE\u6210\u4E00\u6761\u6761\u767D\u6846\uFF0C\u65E2\u6CA1\u6709\u533A\u5206\u610F\u4E49\u53C8\u5F88\u624E\u773C\u3002
|
|
615
|
+
\u73B0\u5728\uFF1A\u5E38\u6001\u7528\u6700\u6DE1\u7684 border-l1\uFF0C\u60AC\u505C\u624D\u62AC\u5230 border-l2\uFF1B\u5361\u7247\u4E0E\u9875\u9762\u7684\u5C42\u6B21\u4EA4\u7ED9
|
|
616
|
+
bg-layer-2 \u672C\u8EAB\u53BB\u8868\u8FBE\u3002\u82E5\u4EE5\u540E\u6062\u590D\u300C\u6309\u4E13\u5BB6\u542F\u505C\u300D\uFF0C\u518D\u6309\u9700\u7ED9\u505C\u7528\u7684\u5361\u7247\u52A0\u533A\u5206
|
|
617
|
+
\uFF08\u522B\u518D\u7528\u4E3B\u8272\u63CF\u8FB9\uFF0C\u5B83\u662F\u7ED9\u6309\u94AE\u7528\u7684\uFF09\u3002 */
|
|
618
|
+
.t-team-card{position:relative;display:grid;min-width:0;min-height:132px;overflow:hidden;border:1px solid var(--dsw-alias-border-l1);border-radius:8px;background:var(--dsw-alias-bg-layer-2)}
|
|
619
|
+
.t-team-card:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l2)}
|
|
668
620
|
/* \u53F3\u4E0A\u89D2\u5DE5\u5177\u4F4D\uFF1A\u67E5\u770B\u63D0\u793A\u8BCD + \u542F\u505C\u5F00\u5173 */
|
|
669
621
|
.t-team-card-tools{position:absolute;top:8px;right:8px;display:flex;align-items:center;gap:6px;z-index:1}
|
|
670
622
|
.t-team-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:13px;line-height:1;cursor:pointer}
|
|
@@ -721,9 +673,12 @@ var CSS = `
|
|
|
721
673
|
.t-team-pop .t-team-input \u4E24\u6761\u89C4\u5219\u4E00\u8D77\u541E\u6389\uFF0C\u5F39\u7A97\u9000\u5316\u6210\u65E0\u6837\u5F0F\u5757\u7EA7\u5143\u7D20\uFF081265\xD712420\uFF09\uFF0C
|
|
722
674
|
\u5173\u95ED\u6309\u94AE\u88AB\u9876\u51FA\u5C4F\u5E55\u3002CSS \u6CE8\u91CA\u4E0D\u53EF\u5D4C\u5957\uFF0C\u4E22\u4E86\u7ED3\u5C3E\u5C31\u4F1A\u4E00\u8DEF\u541E\u5230\u4E0B\u4E00\u4E2A\u7ED3\u675F\u7B26\u3002
|
|
723
675
|
2026-09-23 \u7528\u6237\u53CD\u9988\u300C\u5F39\u7A97\u8FB9\u7EBF\u592A\u660E\u663E\u4E86\uFF0C\u592A\u7C97\u4E86\u300D\uFF1A\u8FB9\u6846\u4ECE 1px + border-l2 \u6539\u4E3A
|
|
724
|
-
.5px + border-l1\uFF08\u6D45\u8272\u4E0B alpha 10% \u2192 4%\uFF09\uFF0C\u8FB9\u6846\u4E0D\u518D\u62A2\u773C\
|
|
725
|
-
|
|
726
|
-
|
|
676
|
+
.5px + border-l1\uFF08\u6D45\u8272\u4E0B alpha 10% \u2192 4%\uFF09\uFF0C\u8FB9\u6846\u4E0D\u518D\u62A2\u773C\u3002
|
|
677
|
+
\u5F39\u7A97\u9634\u5F71\u539F\u7528 var(--dsw-shadow-lv3)\uFF0C\u5B83\u662F\u4E09\u5C42\u53E0\u52A0\uFF1A0 0 1px \u5747\u5300\u63CF\u8FB9\u30010 0 4px \u5747\u5300\u67D4\u5149\u3001
|
|
678
|
+
0 12px 32px \u5411\u4E0B\u504F\u79FB\u7684\u5927\u6295\u5F71\u3002\u7528\u6237\u8981\u6C42\u53BB\u6389\u300C\u5E95\u90E8\u300D\u7684\u6295\u5F71\u2014\u2014\u5373\u7B2C\u4E09\u5C42\u5411\u4E0B 12px \u90A3\u9053
|
|
679
|
+
\uFF08\u843D\u5728\u8F93\u5165\u6846\u4E0A\u5F88\u660E\u663E\uFF09\uFF0C\u6545\u8FD9\u91CC\u53EA\u4FDD\u7559\u524D\u4E24\u5C42\u5747\u5300\u63CF\u8FB9/\u67D4\u5149\uFF08\u5199\u6B7B\u6570\u503C\uFF0C\u5BBF\u4E3B\u6CA1\u6709\u53EA\u542B\u524D\u4E24\u5C42\u7684\u53D8\u91CF\uFF09\u3002
|
|
680
|
+
Retina \u4E0A .5px \u6B63\u597D\u662F\u4E00\u4E2A\u7269\u7406\u50CF\u7D20\uFF1B\u5BBF\u4E3B\u81EA\u5DF1\u7684\u6309\u94AE\u4E5F\u7528 .5px\u3002 */
|
|
681
|
+
.t-team-pop{position:fixed;z-index:60;width:var(--t-team-pop-w, 720px);max-width:calc(100vw - 16px);max-height:min(600px, calc(100vh - 16px));overflow:hidden;box-sizing:border-box;display:flex;flex-direction:column;gap:8px;padding:10px 0 10px 10px;border-radius:12px;border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3));backdrop-filter:var(--dsw-menu-backdrop-filter,blur(20px) saturate(1.4));box-shadow:0 0 1px 0 #0003, 0 0 4px 0 #00000005;color:var(--dsw-alias-label-primary)}
|
|
727
682
|
/* \u4E0D\u5199 width:100%\uFF1A\u5B83\u91CF\u7684\u662F\u5BB9\u5668 content \u5BBD\uFF0C\u518D\u53E0\u4E0A\u300C> *\u300D\u7684 margin-right \u5C31\u4F1A\u6A2A\u5411\u6EA2\u51FA\uFF1B
|
|
728
683
|
\u9760 flex \u5BB9\u5668\u9ED8\u8BA4\u7684 align-items:stretch \u81EA\u52A8\u6491\u6EE1\u51CF\u6389 margin \u540E\u7684\u5BBD\u5EA6\u3002 */
|
|
729
684
|
.t-team-pop .t-team-input{flex:0 0 auto;min-width:0}
|
|
@@ -782,100 +737,108 @@ var CSS = `
|
|
|
782
737
|
.t-team-pop-desc{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:36px;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-secondary)}
|
|
783
738
|
.t-team-pop-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:6px 2px}
|
|
784
739
|
.t-team-pop-head{display:flex;align-items:center;justify-content:space-between;font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary)}
|
|
785
|
-
/*
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
* \
|
|
792
|
-
* \
|
|
793
|
-
*
|
|
794
|
-
* \
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
.
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
.t-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
.t-
|
|
812
|
-
|
|
813
|
-
.t-team-sched-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
.t-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
.
|
|
822
|
-
|
|
823
|
-
.
|
|
824
|
-
|
|
825
|
-
.t-
|
|
826
|
-
.t-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
.t-
|
|
839
|
-
.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
/*
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
.
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
.t-
|
|
854
|
-
.
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
.t-team-sched-
|
|
861
|
-
/* \
|
|
862
|
-
|
|
863
|
-
.t-team-sched-
|
|
740
|
+
/* \u952E\u76D8\u7126\u70B9\u73AF\uFF1A\u5B98\u65B9\u7ED9\u6574\u9875\u4E00\u6761\u7EDF\u4E00\u89C4\u5219\uFF08.t-XoWW_page :focus-visible{outline:2px solid \u2026;offset:2px}\uFF09\uFF0C
|
|
741
|
+
\u53EA\u6709\u5927\u6807\u9898\u8F93\u5165\u6846\u4E0E\u63D0\u793A\u8BCD\u8F93\u5165\u533A\u4F8B\u5916\u2014\u2014\u5B83\u4EEC\u81EA\u5DF1\u6709 focus \u8868\u73B0\uFF08\u4E0B\u5212\u7EBF / \u5916\u6846\u53D8\u84DD\uFF09\u3002
|
|
742
|
+
\u7167\u6284\uFF0C\u514D\u5F97\u5404\u5904\u6309\u94AE\u4E0E\u8F93\u5165\u6846\u7684\u7126\u70B9\u6837\u5F0F\u5404\u5199\u5404\u7684\u3002 */
|
|
743
|
+
/* \u5DE6\u680F\uFF08\u5217\u8868\uFF09\uFF1Aflex:1 \u6491\u6EE1\uFF0C\u53F3\u4FA7\u6709\u8BE6\u60C5\u65F6\u81EA\u7136\u8BA9\u51FA\u4E00\u534A\uFF1B\u81EA\u5DF1\u4E0D\u5206\u680F\u6EDA\u52A8\uFF0C\u6EDA\u52A8\u4EA4\u7ED9\u91CC\u9762\u7684 pageScroll\u3002
|
|
744
|
+
2026-09-25 \u7528\u6237\u53E3\u5F84\uFF1A\u65B0\u5EFA/\u7F16\u8F91\u6539\u6210\u5B98\u65B9\u90A3\u79CD\u300C\u5DE6\u5217\u8868 + \u53F3\u8BE6\u60C5\u300D\u7684\u53CC\u680F\u3002 */
|
|
745
|
+
/* \u26A0\uFE0F \u6EDA\u52A8\u5BB9\u5668\u5FC5\u987B\u662F\u5DE6\u680F\u91CC**\u5168\u5BBD**\u7684\u8FD9\u4E00\u5C42\uFF0C\u5185\u5BB9\u5217\uFF08.t-team-sched-page\uFF09\u53EA\u8D1F\u8D23\u5C45\u4E2D\u3002
|
|
746
|
+
* 2026-09-25 \u7528\u6237\u53D1\u73B0\u300C\u6EDA\u52A8\u6761\u4E0D\u5728\u6700\u53F3\u8FB9\u300D\uFF1A\u6B64\u524D\u6EDA\u52A8\u6302\u5728 960px \u7684\u5C45\u4E2D\u5217\u4E0A\uFF0C\u6EDA\u52A8\u6761\u5C31\u957F\u5728
|
|
747
|
+
* \u90A3\u4E00\u5217\u7684\u53F3\u8FB9\u7F18\u3001\u79BB\u7A97\u53E3\u53F3\u8FB9\u8FD8\u6709\u4E00\u5927\u622A\u7A7A\u767D\u3002\u5B98\u65B9\u90A3\u4E00\u9875\u4E5F\u662F\u8FD9\u4E48\u5206\u7684\uFF1A
|
|
748
|
+
* .t-XoWW_pageScroll\uFF08flex:1 + overflow:auto + scrollbar-gutter:stable\uFF09\u5957 .t-XoWW_pageContent
|
|
749
|
+
* \uFF08max-width + margin auto\uFF09\u3002scrollbar-gutter:stable \u8BA9\u6709/\u65E0\u6EDA\u52A8\u6761\u65F6\u5185\u5BB9\u4E0D\u5DE6\u53F3\u8DF3\uFF1B
|
|
750
|
+
* 9px \u5BBD\u4E0E 2px \u5185\u7F29\u4E5F\u662F\u5B98\u65B9\u90A3\u4E24\u4E2A\u503C\uFF08\u6EDA\u52A8\u6761\u914D\u8272\u8D70\u5BBF\u4E3B\u7684 --dsh-scrollbar-* \u53D8\u91CF\uFF09\u3002
|
|
751
|
+
* \u26A0\uFE0F \u8FD9\u4E00\u5C42\u662F**\u5757\u7EA7**\u5BB9\u5668\uFF08\u4E0D\u52A0 display:flex\uFF09\uFF1A\u5B98\u65B9\u7684 pageScroll \u4E5F\u6CA1\u6709 display\uFF0C\u5185\u5BB9\u5217\u56E0\u6B64
|
|
752
|
+
* \u8D70\u5757\u7EA7\u7684 width:auto + max-width \u89C4\u5219\u3002\u7ED9\u5B83\u52A0 flex \u4F1A\u8BA9\u5B50\u9879\u7684\u81EA\u52A8\u5916\u8FB9\u8DDD\u6539\u53D8\u5BBD\u5EA6\u7B97\u6CD5\u3002 */
|
|
753
|
+
/* \u26A0\uFE0F \u5185\u5BB9\u5217\u4E0E\u5B98\u65B9 .t-XoWW_pageContent **\u9010\u5B57\u4E00\u81F4**\uFF1Amax-width:960px + padding\uFF0C\u5757\u7EA7\uFF08\u4E0D\u52A0 display:flex\uFF09\u3001
|
|
754
|
+
* **\u4E0D\u8981** box-sizing:border-box \u4E0E width:100%\uFF082026-09-25 \u7528\u6237\u62A5\u300C\u533A\u57DF\u5BBD\u548C\u5B98\u65B9\u4E0D\u4E00\u6837\u300D\u5C31\u662F\u90A3\u4E24\u6761\u6765\u7684\uFF09\uFF1A
|
|
755
|
+
* \xB7 \u5B98\u65B9 max-width \u9650\u7684\u662F**\u5185\u5BB9\u76D2** \u2192 \u6574\u5217\u6700\u5BBD 960 + 2\xD7padding\uFF08\u6700\u5927 1056\uFF09\uFF1B
|
|
756
|
+
* \xB7 \u52A0\u4E86 border-box + width:100% \u5C31\u53D8\u6210\u300C\u5185\u5BB9 + padding \u4E00\u5171 960\u300D\u2192 \u5185\u5BB9\u53EA\u6709 864\uFF0C\u7A84\u4E86 96px\u3002
|
|
757
|
+
* \u5757\u7EA7\u6D41\u91CC\u5404\u6BB5\u7684\u95F4\u8DDD\u7531\u5143\u7D20\u81EA\u5DF1\u7684 margin \u63D0\u4F9B\uFF08heading 24 / filters 14 / search 16\uFF09\uFF0C\u4E0E\u5B98\u65B9\u540C\u6B3E\uFF1B
|
|
758
|
+
* \u8FD9\u91CC\u4E0D\u7528 flex + gap \u2014\u2014 \u90A3\u4F1A\u8BA9\u540C\u4E00\u5904\u95F4\u8DDD\u7531\u4E24\u5957\u673A\u5236\u53E0\u52A0\uFF0C\u5B9E\u6D4B\u5C31\u4E0E\u5B98\u65B9\u5DEE 2px\u3002 */
|
|
759
|
+
/* \u53F3\u680F\uFF08\u8BE6\u60C5 / \u65B0\u5EFA / \u7F16\u8F91\uFF09\uFF1A\u5B98\u65B9 detail \u90A3\u5957 \u2014\u2014 47% \u5BBD\u3001\u5DE6\u4FA7 .5px \u5206\u9694\u7EBF\u3001\u9876\u90E8 tab \u884C\u3001
|
|
760
|
+
\u4E2D\u95F4\u6EDA\u52A8\u533A\u3001\u5E95\u90E8\u56FA\u5B9A\u52A8\u4F5C\u6761\u3002\u5DE6\u53F3\u7559\u767D\u7EDF\u4E00\u8D70\u5B98\u65B9\u7684 --detail-gutter\uFF0824 / 20 / 16 \u4E09\u6863\u65AD\u70B9\uFF09\uFF0C
|
|
761
|
+
\u7A84\u5C4F\uFF08<=760px\uFF09\u65F6\u53F3\u680F\u72EC\u5360\u6574\u9875\u3001\u5217\u8868\u8BA9\u4F4D\uFF08\u5B98\u65B9\u540C\u6B3E\u65AD\u70B9\uFF09\u3002 */
|
|
762
|
+
/* \u5E95\u90E8\u52A8\u4F5C\u6761\uFF1A\u5B98\u65B9 saveFooter \u7684 20px \u5185\u8FB9\u8DDD + \u6700\u540E\u4E00\u4E2A\u6309\u94AE\u53F3\u79FB 8px\uFF08\u89C6\u89C9\u53F3\u8FB9\u7F18\u4E0E\u5185\u5BB9\u5BF9\u9F50\uFF09\u3002 */
|
|
763
|
+
/* \u6807\u9898\u884C\uFF1A\u4E0E\u5B98\u65B9 .t-XoWW_pageHeading \u540C\u6B3E\uFF08padding-top 28 / margin-bottom 24 / gap 16\uFF09\u3002
|
|
764
|
+
\u5185\u5BB9\u5217\u6539\u6210\u5757\u7EA7\u6D41\u4E4B\u540E\uFF0C24px \u7531\u5B83\u81EA\u5DF1\u7ED9\uFF0C\u4E0D\u518D\u4E0E page \u7684 gap \u53E0\u52A0\u3002 */
|
|
765
|
+
/* \u63D0\u793A\u6587\u5B57\uFF08\u52A0\u8F7D\u4E2D\uFF09\uFF1A\u5B98\u65B9\u90A3\u9875\u6CA1\u6709\u8FD9\u4E00\u53E5\uFF0C\u7ED9\u5B83\u4E00\u4E2A\u4E0D\u8D34\u4F4F\u4E0B\u4E00\u6BB5\u7684\u4E0B\u8FB9\u8DDD\u3002 */
|
|
766
|
+
/* \u7A7A\u6001 / \u65E0\u5339\u914D\uFF1A\u5B98\u65B9 .t-XoWW_empty \u662F**\u5C45\u4E2D**\u7684\u4E00\u5757\uFF08flex column + \u5C45\u4E2D + 48px 20px \u5185\u8FB9\u8DDD\uFF09\u3002 */
|
|
767
|
+
/* \u9875\u5C3E\u4E0D\u518D\u6302\u300C\u5B89\u5168\u63D0\u793A\u300D\u4E0E\u300C\u6570\u636E\u6587\u4EF6\u8DEF\u5F84\u300D\u4E24\u884C\uFF082026-09-25 \u7528\u6237\u53E3\u5F84\uFF09\uFF1A
|
|
768
|
+
tip \u632A\u5230\u63D0\u793A\u8BCD\u8F93\u5165\u6846\u4E0B\u9762\uFF0C\u7528 .t-team-sched-hint\uFF1B\u8DEF\u5F84\u90A3\u884C\u6574\u4E2A\u5220\u6389\u3002 */
|
|
769
|
+
/* \u5217\u8868\u533A\u5BB9\u5668\uFF1A\u5B98\u65B9 pageContent \u91CC\u6CA1\u6709\u8FD9\u4E00\u5C42\uFF08heading/filters/search/list \u76F4\u63A5\u662F\u5144\u5F1F\uFF09\uFF0C
|
|
770
|
+
\u6240\u4EE5\u8FD9\u91CC**\u4E0D\u7ED9\u4EFB\u4F55\u95F4\u8DDD**\u2014\u2014\u95F4\u8DDD\u7531\u5404\u5143\u7D20\u81EA\u5DF1\u7684 margin \u63D0\u4F9B\uFF0C\u8DDF\u5B98\u65B9\u4E00\u6A21\u4E00\u6837\uFF0C\u907F\u514D\u4E24\u5957\u673A\u5236\u53E0\u52A0\u3002 */
|
|
771
|
+
/* \u8FC7\u6EE4\u6807\u7B7E\u884C + \u641C\u7D22\u6846\uFF1A\u5B98\u65B9\u9875\u9762\u7684\u90A3\u4E24\u884C\uFF0C\u6570\u503C\u7167\u6284\uFF0828px \u80F6\u56CA / 36px \u5706\u89D2 12px \u8F93\u5165\u6846\uFF09\uFF0C
|
|
772
|
+
* \u8FDE\u95F4\u8DDD\u7684**\u6765\u6E90**\u4E5F\u7167\u6284\uFF1Afilters{margin-bottom:14px}\u3001searchField{margin:0 0 16px}\u3002 */
|
|
773
|
+
/* \u26A0\uFE0F \u641C\u7D22\u6846\u9010\u6761\u5BF9\u9F50\u5B98\u65B9 .t-XoWW_searchField\uFF1A**content-box**\uFF08\u5B98\u65B9\u6CA1\u5199 box-sizing\uFF0C\u52A0\u4E86 border-box
|
|
774
|
+
* \u4F1A\u8BA9\u5916\u9AD8\u4ECE 37 \u53D8 36\uFF09\u3001**\u4E0D\u8BBE gap**\uFF08\u56FE\u6807\u4E0E\u8F93\u5165\u6846\u4E4B\u95F4\u90A3 6px \u5C5E\u4E8E\u5B98\u65B9\u7684 Input \u7EC4\u4EF6\uFF0C
|
|
775
|
+
* \u7531\u56FE\u6807\u76D2\u81EA\u5DF1\u7684 margin-right \u7ED9\uFF09\u3001margin 0 0 16px\u3002 */
|
|
776
|
+
/* \u56FE\u6807\u76D2\uFF1A\u5B98\u65B9 Input \u7684 .icon \u662F 16\xD716 \u7684 inline-flex \u5C45\u4E2D\u76D2\uFF08\u91CC\u9762\u7684 svg 14px\uFF09\uFF0C
|
|
777
|
+
\u56FE\u6807\u76D2\u4E0E\u8F93\u5165\u6846\u4E4B\u95F4 6px \u2014\u2014 \u7167\u6284\uFF0C\u5426\u5219\u6587\u5B57\u8D77\u59CB\u4F4D\u7F6E\u4F1A\u5DEE 2~4px\u3002 */
|
|
778
|
+
/* \u8F93\u5165\u5143\u7D20\uFF1A\u5B98\u65B9 .input \u53EA\u91CD\u7F6E\u4E86 border/outline/background\uFF0C**\u4FDD\u7559\u4E86 UA \u9ED8\u8BA4\u7684 padding:1px 2px**
|
|
779
|
+
* \uFF08\u6240\u4EE5\u5360\u4F4D\u6587\u5B57\u7684\u8D77\u59CB\u4F4D\u7F6E\u6BD4\u6211\u4EEC\u6309\u4F4F padding \u65F6\u591A 2px\uFF09\u3002\u7167\u6284\uFF1Apadding \u7528 UA \u9ED8\u8BA4\u503C\uFF0C\u522B\u6E05\u96F6\u3002 */
|
|
780
|
+
/* \u6E05\u7A7A\u6309\u94AE\uFF1A\u5B98\u65B9 .t-XoWW_searchClear \u662F 28\xD728\u3001\u53F3\u79FB 6px\uFF08\u56FE\u6807 14px\uFF09\u3002 */
|
|
781
|
+
/* \u4EFB\u52A1\u884C\uFF1A\u5B98\u65B9 .t-XoWW_row \u7684\u89C2\u611F \u2014\u2014 \u65E0\u8FB9\u6846\u3001\u60AC\u505C\u6D45\u7070\u3001\u56FE\u6807 + \u4E3B\u526F\u4E24\u884C\uFF1B\u64CD\u4F5C\u6309\u94AE\u56FA\u5B9A\u5728\u884C\u5C3E\u3002
|
|
782
|
+
* \u5B98\u65B9\u90A3\u884C\u662F content-box + width:100% + padding 8px\uFF08\u5BBF\u4E3B\u6CA1\u6709\u5168\u5C40 box-sizing reset\uFF1A\u5B98\u65B9\u5728
|
|
783
|
+
* instruction / zoneSearch / confirmDialog \u56DB\u5904\u90FD**\u663E\u5F0F**\u8865\u4E86 border-box\uFF0C\u6B63\u8BF4\u660E\u9ED8\u8BA4\u662F content-box\uFF09\u3002
|
|
784
|
+
* \u4E8E\u662F\u8FD9\u4E00\u884C\u7684 border box \u6BD4\u5185\u5BB9\u5217**\u53F3\u51FA\u8840 16px** \u2014\u2014 \u90A3 16px \u843D\u5728\u5185\u5BB9\u5217\u7684 padding\uFF08\u226524px\uFF09\u91CC\uFF0C
|
|
785
|
+
* \u4E0D\u4F1A\u6EA2\u51FA\u5230\u6EDA\u52A8\u5C42\uFF0C\u6240\u4EE5\u7167\u6284\u4E0D\u4F1A\u6709\u6A2A\u5411\u6EDA\u52A8\u6761\u3002\u522B\u6539\u56DE border-box\uFF0C\u90A3\u6837\u884C\u4F1A\u6BD4\u5B98\u65B9\u7A84 16px\u3002 */
|
|
786
|
+
/* \u56FE\u6807\u69FD\uFF1A\u5B98\u65B9\u53EA\u6709 width/height/margin-top\uFF08svg \u662F inline\uFF09\uFF0C\u8FD9\u91CC\u4E5F\u4E0D\u52A0 flex \u2014\u2014
|
|
787
|
+
\u52A0\u4E86\u4F1A\u8BA9\u56FE\u6807\u76F8\u5BF9\u884C\u6807\u9898\u7684\u5782\u76F4\u4F4D\u7F6E\u5DEE 1~2px\u3002 */
|
|
788
|
+
/* \u884C\u6807\u9898\u524D\u7684\u72B6\u6001\u56FE\u6807\uFF0814px\uFF0C\u4E0E 23px \u884C\u9AD8\u7684\u6587\u5B57\u5BF9\u9F50\uFF09\uFF1A
|
|
789
|
+
\u542F\u7528 = \u7EFF\uFF08state-success-primary\uFF09\uFF0C\u505C\u7528 = **\u6DE1\u7EA2**\uFF08state-error-secondary\uFF0C\u7528\u6237\u53E3\u5F84\u300C\u6DE1\u7EA2\u624D\u660E\u663E\u300D\uFF09\u3002
|
|
790
|
+
\u989C\u8272\u56FA\u5B9A\u3001\u4E0D\u968F\u884C\u7684\u60AC\u505C\u6001\u53D8\u5316 \u2014\u2014 \u60AC\u505C\u65F6\u6807\u9898\u62AC\u56DE\u6B63\u5E38\u8272\uFF0C\u56FE\u6807\u7EE7\u7EED\u8868\u793A\u8FD9\u6761\u4EFB\u52A1\u7684\u72B6\u6001\u3002 */
|
|
791
|
+
/* \u5DF2\u505C\u7528\u7684\u884C\u6309\u5B98\u65B9\u300C\u5DF2\u7ED3\u675F\u300D\u7684\u5904\u7406\u65B9\u5F0F\u538B\u6697\u6807\u9898\u4E0E\u6458\u8981\uFF08\u60AC\u505C\u65F6\u518D\u62AC\u56DE\u6765\uFF0C\u4FDD\u8BC1\u53EF\u8BFB\uFF09\u3002 */
|
|
792
|
+
/* ---- \u6267\u884C\u8BB0\u5F55\u9875\uFF08\u53F3\u680F\u7B2C\u4E8C\u4E2A tab\uFF09\uFF1A\u5B98\u65B9\u300C\u4EFB\u52A1\u8FD0\u884C\u8BB0\u5F55\u300D\u90A3\u5957\u65F6\u95F4\u7EBF ----
|
|
793
|
+
* \u5EA6\u91CF\u7167\u6284 .t-XoWW_delivery*\uFF1A\u6BCF\u6761 = \u56FE\u6807 + \u65F6\u95F4\uFF0814/500\uFF09+ \u7ED3\u679C\uFF0C\u5DE6\u4FA7\u4E00\u6761 .5px \u7AD6\u7EBF\u628A\u5404\u6761\u4E32\u8D77\u6765
|
|
794
|
+
* \uFF08left:15.75px \u662F\u56FE\u6807\u4E2D\u5FC3\uFF1A\u884C margin -8 + padding 8 \u2192 \u56FE\u6807\u4E2D\u5FC3 16\uFF09\u3002 */
|
|
795
|
+
/* \u72B6\u6001\u8DDF\u5728\u65F6\u95F4\u540E\u9762\uFF082026-09-25 \u7528\u6237\u53E3\u5F84\uFF09\uFF1A\u5C0F\u56FE\u6807 + \u6587\u5B57\uFF0C\u6210\u529F\u7EFF\u3001\u5931\u8D25\u7EA2\u3002
|
|
796
|
+
\u56FE\u6807\u7528 14px\uFF08\u5BBF\u4E3B\u90A3\u4E9B\u56FE\u6807\u672C\u8EAB\u662F 16px \u7684 viewBox\uFF0C\u8FD9\u91CC\u7F29\u653E\u4E00\u4E0B\u4E0E 14px \u7684\u65F6\u95F4\u5B57\u53F7\u66F4\u8D34\uFF09\u3002 */
|
|
797
|
+
/* \u5931\u8D25\u539F\u56E0\u5355\u72EC\u4E00\u884C\uFF08\u522B\u628A"\u65F6\u95F4 + \u72B6\u6001"\u90A3\u4E00\u884C\u6491\u957F\uFF09\u3002 */
|
|
798
|
+
/* \u4F1A\u8BDD\u884C\uFF1Aid + \u540E\u9762\u90A3\u679A\u300C\u5173\u8054\u4F1A\u8BDD \u203A\u300D\u6309\u94AE\uFF08\u5E76\u6392\uFF0C\u7A84\u4E86\u81EA\u52A8\u6362\u884C\uFF09\u3002 */
|
|
799
|
+
/* \u300C\u8FD9\u4E2A\u4F1A\u8BDD\u6253\u4E0D\u5F00\u300D\u7684\u63D0\u793A\u884C\uFF1A\u5F52\u6863\u8D70 warn \u8272\uFF08\u65C1\u8FB9\u8FD8\u6709\u4E00\u679A\u300C\u6062\u590D\u5E76\u6253\u5F00\u300D\uFF09\uFF0C\u5DF2\u5220\u8D70\u9519\u8BEF\u8272\u3002 */
|
|
800
|
+
/* \u90A3\u4E00\u6B21\u63D0\u4EA4\u7684\u63D0\u793A\u8BCD\uFF1A\u5B98\u65B9 savedPrompt \u90A3\u5957 \u2014\u2014 \u4E24\u884C\u622A\u65AD\uFF08line-clamp:2\uFF09\uFF0C\u70B9\u300C\u5C55\u5F00\u300D\u770B\u5168\u6587\u3002 */
|
|
801
|
+
/* \u672B\u5C3E\u4E00\u884C\uFF1A\u8BF4\u660E\u53EA\u7559\u6700\u8FD1\u591A\u5C11\u6B21\uFF08\u5B98\u65B9\u7684 retentionEnd \u540C\u6B3E\u5C0F\u5B57\uFF09\u3002 */
|
|
802
|
+
/* \u6309\u94AE\uFF1A\u5B98\u65B9\u90A3\u4E24\u6863 \u2014\u2014 \u6B21\u7EA7\u662F\u900F\u660E\u80F6\u56CA\uFF08h28 / r14\uFF09\uFF0C\u4E3B\u6309\u94AE\u6309\u5B98\u65B9 Button + newButton \u7684\u89C4\u683C\uFF1A
|
|
803
|
+
* \u80CC\u666F\u8D70 --dsw-alias-button-primary-fill\u3001\u6587\u5B57\u8D70 --dsw-alias-label-primary-foreground\uFF08\u4E0D\u662F\u6211\u4EEC\u81EA\u5DF1
|
|
804
|
+
* \u62FC\u7684 label-primary/bg-base \u2014\u2014 \u6362\u4E86\u54C1\u724C\u8272\u5C31\u4F1A\u770B\u51FA\u5DEE\u522B\uFF09\u3001h32 / r16 / padding 0 12px / gap 4px\u3002 */
|
|
805
|
+
/* \u53F3\u680F\u8868\u5355\u91CC\u7684\u5B57\u6BB5\u7EC4\u4E0E\u63A7\u4EF6\uFF1A\u5B98\u65B9\u8BE6\u60C5\u9875\u90A3\u5957\uFF08.5px \u63CF\u8FB9 + 12px \u5706\u89D2\u8F93\u5165\u6846\u300136px \u9AD8\u3001
|
|
806
|
+
\u805A\u7126\u6362\u6210\u4E3B\u9898\u84DD\uFF09\uFF1B\u5206\u7EC4\u6807\u9898\u662F\u5B98\u65B9 ruleCard h3 \u90A3\u4E2A 13px \u5C0F\u6807\u9898\u3002 */
|
|
807
|
+
/* cron \u9009\u62E9\u5668\uFF1A\u8FD0\u884C\u65F6\u95F4\u5361\u7247\uFF08\u5B98\u65B9 ruleRows \u90A3\u5957\uFF09+ \u5361\u7247\u4E0B\u65B9\u7684\u5E38\u7528\u6A21\u677F + \u6458\u8981 + \u6700\u8FD1\u51E0\u6B21\u9884\u89C8 */
|
|
808
|
+
/* \u8FD0\u884C\u65F6\u95F4\u5361\u7247\uFF1A\u5EA6\u91CF\u7167\u6284\u5B98\u65B9 .t-XoWW_ruleRows / ruleRow / ruleLabel / ruleValue / ruleInput \u2014\u2014
|
|
809
|
+
* .5px \u63CF\u8FB9 + 16px \u5706\u89D2\u5BB9\u5668\u3001\u6BCF\u884C min-height 48px\u3001\u884C\u95F4\u4E00\u6761 .5px \u5206\u9694\u7EBF\uFF08\u6700\u540E\u4E00\u884C\u4E0D\u8981\uFF09\uFF0C
|
|
810
|
+
* \u5DE6\u8FB9\u6807\u7B7E 14px\u3001\u53F3\u8FB9\u53D6\u503C\uFF08\u539F\u751F select / input \u505A\u6210\u65E0\u8FB9\u6846\u3001hover \u624D\u6D6E\u51FA\u6D45\u7070\u5706\u89D2\u5E95\uFF09\u3002 */
|
|
811
|
+
/* \u53D6\u503C\u9762\uFF08\u5B98\u65B9 ruleValue / ruleValueFace / pickerTrigger / pickerIcon \u7684\u5F62\u6001\uFF09\uFF1A\u4E00\u884C\u53F3\u4FA7\u662F
|
|
812
|
+
* \u300C\u5F53\u524D\u503C + \u4E00\u4E2A\u6307\u793A\u56FE\u6807\u300D\u7684\u53EF\u70B9\u9762\uFF0Chover \u65F6\u6574\u9762\u6D6E\u6D45\u7070\uFF0C\u70B9\u5F00\u4E00\u4E2A\u540C\u6E90\u5C0F\u9762\u677F\u3002
|
|
813
|
+
* \u26A0\uFE0F \u523B\u610F\u4E0D\u7528\u539F\u751F select\uFF1A\u5B83\u7684\u7BAD\u5934\u4E0E\u4E0B\u62C9\u5F39\u5C42\u7531\u6D4F\u89C8\u5668\u753B\uFF0C\u6DF1\u6D45\u4E3B\u9898\u4E0B\u90FD\u6CA1\u6CD5\u4E0E\u5B98\u65B9\u4E00\u81F4\u3002 */
|
|
814
|
+
/* \u70B9\u5F00\u7684\u5C0F\u9762\u677F\uFF1A\u4E0E ExpertPicker \u540C\u6E90\uFF08\u83DC\u5355\u5E95\u8272 + \u80CC\u666F\u6A21\u7CCA\uFF0C\u523B\u610F\u4E0D\u5E26\u6295\u5F71\uFF09\u3002
|
|
815
|
+
* \u5355\u5217\u7528 .t-team-sched-pickerList\uFF08\u7AD6\u6392\uFF09\uFF0C\u53CC\u5217\uFF08\u65F6/\u5206\uFF09\u76F4\u63A5\u662F\u4E24\u4E2A .t-team-sched-pickerCol \u5E76\u6392\u3002 */
|
|
816
|
+
/* \u81EA\u5B9A\u4E49\u8868\u8FBE\u5F0F\u7684\u8F93\u5165\u6846\uFF1A\u5B98\u65B9 ruleInput\uFF08\u65E0\u6846\u3001\u53F3\u5BF9\u9F50\u3001hover \u6D6E\u6D45\u7070\uFF09 */
|
|
817
|
+
/* \u5E38\u7528\u6A21\u677F\uFF1A\u5361\u7247\u4E0B\u65B9\u7684\u5C0F\u80F6\u56CA\uFF08\u4E0E\u5217\u8868\u9875\u7684\u8FC7\u6EE4\u6807\u7B7E\u540C\u6B3E\uFF09\u3002
|
|
818
|
+
* \u26A0\uFE0F \u7C7B\u540D\u5FC5\u987B\u662F .t-team-sched-preset\uFF1A.t-team-sched-chip \u5F52\u63D0\u793A\u8BCD\u91CC\u7684\u4E13\u5BB6\u82AF\u7247\uFF0C
|
|
819
|
+
* \u4E24\u8FB9\u540C\u540D\u65F6\u540E\u5B9A\u4E49\u7684\u90A3\u6761\u4F1A\u628A\u524D\u9762\u7684\u8986\u76D6\u6389\uFF08\u8E29\u8FC7\uFF1A\u6A21\u677F\u6309\u94AE\u957F\u6210\u84DD\u8272\u82AF\u7247\uFF09\u3002 */
|
|
820
|
+
/* \u63D0\u793A\u8BCD\u8F93\u5165\u533A\uFF1A\u6846\u5185\u7B2C\u4E00\u884C\u662F\u4E13\u5BB6\u82AF\u7247\uFF08\u6807\u7B7E\u89C2\u611F\uFF0C\u4E0E\u5BF9\u8BDD\u8F93\u5165\u6846\u4E00\u81F4\uFF09\uFF0C\u4E0B\u9762\u662F\u6B63\u6587\u3002
|
|
821
|
+
* \u5916\u6846\u5BF9\u9F50\u5B98\u65B9\u8BE6\u60C5\u9875\u7684\u63D0\u793A\u8BCD\u8F93\u5165\u6846\uFF1A\u5706\u89D2 16px\u3001.5px \u63CF\u8FB9\u3001\u805A\u7126\u65F6\u6362\u6210\u4E3B\u9898\u84DD\u3002 */
|
|
864
822
|
/* \u82AF\u7247\u89C2\u611F\u5BF9\u9F50\u5BF9\u8BDD\u8F93\u5165\u6846\u91CC\u7684\u5F15\u7528\u82AF\u7247\uFF1A\u6D45\u7070\u5E95\u3001\u5706\u89D2\u77E9\u5F62\uFF08\u4E0D\u662F\u5168\u80F6\u56CA\uFF09\u3001\u84DD\u8272\u6587\u5B57\u3001
|
|
865
823
|
* \u5DE6\u4FA7\u4E00\u4E2A\u5706\u5F62\u7EBF\u6761\u5C0F\u56FE\u6807\uFF1B\xD7 \u5E73\u65F6\u4E0D\u663E\u793A\uFF0C\u60AC\u505C\u624D\u6D6E\u51FA\u6765\uFF08\u622A\u56FE\u91CC\u5C31\u662F\u6CA1\u6709 \xD7 \u7684\u6837\u5B50\uFF09\u3002 */
|
|
866
|
-
.t-team-sched-chip{box-sizing:border-box;display:inline-flex;align-items:center;gap:3px;max-width:100%;margin:0 2px;padding:0 4px;border:1px solid transparent;border-radius:6px;background:color-mix(in srgb, var(--dsw-alias-label-primary) 10%, transparent);color:var(--dsw-alias-brand-primary, #1677ff);font-size:12px;line-height:18px;vertical-align:middle;user-select:none}
|
|
867
824
|
/* \u60AC\u505C\u7ED9\u4E00\u5708\u6DE1\u63CF\u8FB9\uFF1A\u8BA9"\u9F20\u6807\u5728\u8FD9\u679A\u82AF\u7247\u4E0A"\u8FD9\u4EF6\u4E8B\u6709\u786E\u5B9A\u7684\u89C6\u89C9\u53CD\u9988\uFF08\u522B\u9760\u6D4F\u89C8\u5668\u9ED8\u8BA4\uFF09\u3002 */
|
|
868
|
-
.t-team-sched-chip:hover{border-color:color-mix(in srgb, var(--dsw-alias-brand-primary, #1677ff) 35%, transparent)}
|
|
869
|
-
.t-team-sched-chip-icon{flex:none;display:block}
|
|
870
|
-
.t-team-sched-chip-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
871
|
-
.t-team-sched-chip-remove{padding:0 1px;border:0;background:transparent;color:inherit;font:inherit;font-size:12px;line-height:1;cursor:pointer;opacity:.6;transition:opacity .12s}
|
|
872
|
-
.t-team-sched-chip-remove:hover{opacity:1}
|
|
873
825
|
/* \u63D0\u793A\u8BCD\u7F16\u8F91\u533A\uFF1Acontenteditable \u7684\u5BCC\u6587\u672C\u6D41\uFF08\u7EAF\u6587\u5B57 + \u82AF\u7247\uFF09\uFF0C\u82AF\u7247\u56E0\u6B64\u80FD\u63D2\u5728\u6B63\u6587\u4EFB\u610F\u4F4D\u7F6E\u3002
|
|
874
|
-
* \u26A0\uFE0F \
|
|
875
|
-
* \u90A3\u7C7B\u89C4\u5219\uFF0C\u7F16\u8F91\u533A\u4F1A\u81EA\u5E26\u4E00\u5708\u8FB9\u6846\uFF08\u8E29\u8FC7\uFF1A\u6846\u91CC\u5957\u6846\uFF09\u3002 */
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
826
|
+
* \u26A0\uFE0F \u9009\u62E9\u5668\u8981\u5E26 .t-team-sched-promptbox \u524D\u7F00\uFF08\u539F\u6765\u662F .t-team-sched-field\uFF09\uFF1A\u5426\u5219\u7279\u5F02\u6027\u4F4E\u4E8E
|
|
827
|
+
* \u901A\u7528\u7684 ".t-team-sched-group textarea/input" \u90A3\u7C7B\u89C4\u5219\uFF0C\u7F16\u8F91\u533A\u4F1A\u81EA\u5E26\u4E00\u5708\u8FB9\u6846\uFF08\u8E29\u8FC7\uFF1A\u6846\u91CC\u5957\u6846\uFF09\u3002 */
|
|
828
|
+
/* \u7A84\u5C4F\uFF08\u4E0E\u5B98\u65B9\u540C\u6B3E\u65AD\u70B9\uFF09\uFF1A\u8BE6\u60C5/\u8868\u5355\u72EC\u5360\u6574\u9875\uFF0C\u5217\u8868\u8BA9\u4F4D \u2014\u2014 \u6324\u6210\u4E24\u680F\u4E24\u8FB9\u90FD\u6CA1\u6CD5\u7528\u3002 */
|
|
829
|
+
/* \u5B98\u65B9\u7684\u4E09\u6863\u65AD\u70B9\uFF08\u6570\u503C\u7167\u6284\uFF09\uFF1A\u53F3\u680F\u5DE6\u53F3\u7559\u767D 24 \u2192 20 \u2192 16\uFF1B<=760 \u65F6\u53F3\u680F\u72EC\u5360\u6574\u9875\u3002 */
|
|
830
|
+
@media (width<=1100px){
|
|
831
|
+
.t-team-sched-detailForm{--detail-gutter:20px}
|
|
832
|
+
}
|
|
833
|
+
@media (width<=760px){
|
|
834
|
+
.t-team-sched-listPane[data-detail="true"]{display:none}
|
|
835
|
+
.t-team-sched-detailForm{flex-basis:100%;border-left:0}
|
|
836
|
+
.t-team-sched-detailScroll{padding-top:20px}
|
|
837
|
+
}
|
|
838
|
+
@media (width<=400px){
|
|
839
|
+
.t-team-sched-detailForm{--detail-gutter:16px}
|
|
840
|
+
.t-team-sched-detailTabsBar{gap:16px}
|
|
841
|
+
}
|
|
879
842
|
/* \u63D0\u793A\u8BCD\u6846\u4E0B\u65B9\u7684\u300CT\u4E13\u5BB6\u300D\u6311\u9009\u5668\uFF1A\u6309\u94AE + \u53EA\u542B\u4E13\u5BB6\u5217\u8868\u7684\u6D6E\u5C42\uFF08\u7C7B\u540D\u72EC\u7ACB\uFF0C\u907F\u514D\u4E0E\u65E2\u6709\u7C7B\u4E92\u76F8\u8986\u76D6\uFF09 */
|
|
880
843
|
.t-team-expert-pick{position:relative;display:flex;align-items:center;gap:8px;margin-top:2px}
|
|
881
844
|
.t-team-expert-pick-hint{font-size:12px;color:var(--dsw-alias-label-secondary)}
|
|
@@ -993,97 +956,11 @@ var zh = {
|
|
|
993
956
|
"custom.deleteHint": "\u5220\u9664\u300C{name}\u300D\uFF1F\u53EA\u5220\u8FD9\u4E2A\u81EA\u5EFA\u4E13\u5BB6\u6587\u4EF6\uFF0C\u4E0D\u53EF\u64A4\u9500\u3002",
|
|
994
957
|
"custom.badge": "\u81EA\u5EFA",
|
|
995
958
|
"custom.loadingBody": "\u6B63\u5728\u8BFB\u53D6\u4EBA\u683C\u6B63\u6587\u2026",
|
|
996
|
-
"pop.title": "T\u4E13\u5BB6"
|
|
997
|
-
//
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
"sched.nav": "\u5B9A\u65F6\u4EFB\u52A1",
|
|
1001
|
-
"sched.title": "\u5B9A\u65F6\u4EFB\u52A1",
|
|
1002
|
-
"sched.intro": "\u7528 cron \u5B9A\u65F6\u5668\u628A\u63D0\u793A\u8BCD\u4EA4\u7ED9\u4E00\u4E2A\u5168\u65B0\u7684\u4F1A\u8BDD\u6267\u884C\u2014\u2014\u4E5F\u53EF\u4EE5\u7ACB\u5373\u6267\u884C\u3002\u6267\u884C\u4EA7\u751F\u7684\u4F1A\u8BDD\u51FA\u73B0\u5728\u5DE6\u4FA7\u5BF9\u5E94\u5DE5\u4F5C\u533A\u4E0B\u3002",
|
|
1003
|
-
"sched.tip": "\u542F\u7528\u7684\u4E8B\u9879\u4F1A\u5728\u540E\u53F0\u81EA\u52A8\u65B0\u5EFA\u4F1A\u8BDD\u5E76\u63D0\u4EA4\u63D0\u793A\u8BCD\uFF08\u7B49\u4E8E\u8BA9 agent \u81EA\u5DF1\u52A8\u624B\uFF09\uFF0C\u8BF7\u53EA\u5199\u4F60\u4FE1\u4EFB\u7684\u63D0\u793A\u8BCD\u3002",
|
|
1004
|
-
"sched.back": "\u8FD4\u56DE\u4F1A\u8BDD",
|
|
1005
|
-
"sched.refresh": "\u5237\u65B0",
|
|
1006
|
-
"sched.loading": "\u6B63\u5728\u52A0\u8F7D\u5B9A\u65F6\u4EFB\u52A1\u2026",
|
|
1007
|
-
"sched.error": "\u5B9A\u65F6\u4EFB\u52A1\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\u3002",
|
|
1008
|
-
"sched.empty": "\u8FD8\u6CA1\u6709\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u5148\u65B0\u5EFA\u4E00\u4E2A\u5427\u3002",
|
|
1009
|
-
"sched.retry": "\u91CD\u8BD5",
|
|
1010
|
-
"sched.new": "\u65B0\u5EFA\u5B9A\u65F6\u4EFB\u52A1",
|
|
1011
|
-
"sched.edit": "\u7F16\u8F91\u5B9A\u65F6\u4EFB\u52A1",
|
|
1012
|
-
"sched.save": "\u4FDD\u5B58",
|
|
1013
|
-
"sched.saving": "\u4FDD\u5B58\u4E2D\u2026",
|
|
1014
|
-
"sched.cancel": "\u53D6\u6D88",
|
|
1015
|
-
"sched.delete": "\u5220\u9664",
|
|
1016
|
-
"sched.deleteConfirm": "\u786E\u5B9A\u5220\u9664\u8FD9\u4E2A\u5B9A\u65F6\u4EFB\u52A1\uFF1F",
|
|
1017
|
-
"sched.runNow": "\u7ACB\u5373\u6267\u884C",
|
|
1018
|
-
"sched.running": "\u6267\u884C\u4E2D\u2026",
|
|
1019
|
-
"sched.runHistory": "\u6267\u884C\u8BB0\u5F55\uFF08{count}\uFF09",
|
|
1020
|
-
"sched.runOk": "\u6210\u529F",
|
|
1021
|
-
"sched.runFail": "\u5931\u8D25",
|
|
1022
|
-
"sched.lastRun": "\u4E0A\u6B21\u6267\u884C",
|
|
1023
|
-
"sched.neverRun": "\u4ECE\u672A\u6267\u884C",
|
|
1024
|
-
"sched.failed": "\u5931\u8D25",
|
|
1025
|
-
"sched.disabledTag": "\u5DF2\u505C\u7528",
|
|
1026
|
-
"sched.workspace": "\u5DE5\u4F5C\u533A",
|
|
1027
|
-
"sched.workspaceNone": "\u4E0D\u7ED1\u5B9A\u5DE5\u4F5C\u533A\uFF08\u9ED8\u8BA4\u76EE\u5F55\uFF09",
|
|
1028
|
-
"sched.workspaceHint": "\u6267\u884C\u65F6\u4F1A\u5728\u8FD9\u4E2A\u5DE5\u4F5C\u533A\u4E0B\u65B0\u5EFA\u4F1A\u8BDD\uFF0C\u5E76\u663E\u793A\u5728\u5DE5\u4F5C\u533A\u5206\u7EC4\u91CC\u3002",
|
|
1029
|
-
"sched.workspacePath": "\u76EE\u5F55\uFF1A{path}",
|
|
1030
|
-
"sched.workspaceCustom": "\uFF0B \u81EA\u5B9A\u4E49\u76EE\u5F55\u2026",
|
|
1031
|
-
"sched.workspaceCustomPlaceholder": "\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 /Users/\u4F60/tasks",
|
|
1032
|
-
"sched.workspaceCustomHint": "\u76EE\u5F55\u4E0D\u5B58\u5728\u65F6\u4F1A\u81EA\u52A8\u521B\u5EFA\uFF0C\u5E76\u6CE8\u518C\u6210\u4E00\u4E2A\u5DE5\u4F5C\u533A\u3002",
|
|
1033
|
-
"sched.workspaceCustomEmpty": "\u8BF7\u5148\u586B\u5199\u81EA\u5B9A\u4E49\u76EE\u5F55\u7684\u7EDD\u5BF9\u8DEF\u5F84\u3002",
|
|
1034
|
-
"sched.workspaceAutoRecoverHint": "\u5DE5\u4F5C\u533A\u4E0D\u89C1\u4E86\uFF0C{path} \u4E0B\u6B21\u6267\u884C\u65F6\u4F1A\u81EA\u52A8\u5EFA\u56DE\u6765\u3002",
|
|
1035
|
-
"sched.workspaceMissingHintNoPath": "\u5DE5\u4F5C\u533A\u4E0D\u89C1\u4E86\uFF0C\u4E14\u4EFB\u52A1\u91CC\u6CA1\u8BB0\u76EE\u5F55\u2014\u2014\u4E0B\u6B21\u6267\u884C\u81EA\u52A8\u6062\u590D\u4E0D\u4E86\uFF0C\u8BF7\u53BB\u5DE6\u4FA7\u5DE5\u4F5C\u533A\u5217\u8868\u65B0\u5EFA\u4E00\u4E2A\u540C\u540D/\u540C\u8DEF\u5F84\u7684\u5DE5\u4F5C\u533A\u3002",
|
|
1036
|
-
"sched.cronLabel": "cron \u5B9A\u65F6\u5668",
|
|
1037
|
-
"sched.cronHint": "\u4E94\u6BB5 croner \u8868\u8FBE\u5F0F\uFF08\u5206 \u65F6 \u65E5 \u6708 \u5468\uFF09\uFF0C\u4F8B\u5982 \u201C0 9 * * *\u201D \u8868\u793A\u6BCF\u5929 09:00\u3002",
|
|
1038
|
-
"sched.cronHourly": "\u6BCF\u5C0F\u65F6",
|
|
1039
|
-
"sched.cronDaily": "\u6BCF\u5929",
|
|
1040
|
-
"sched.cronWeekly": "\u6BCF\u5468",
|
|
1041
|
-
"sched.cronCustom": "\u81EA\u5B9A\u4E49",
|
|
1042
|
-
"sched.cronEvery": "\u6BCF\u9694",
|
|
1043
|
-
"sched.cronAtMinute": "\u6BCF\u5C0F\u65F6\u7684\u7B2C",
|
|
1044
|
-
"sched.cronMinuteUnit": "\u5206",
|
|
1045
|
-
"sched.cronMinutesUnit": "\u5206\u949F",
|
|
1046
|
-
"sched.hourField": "\u5C0F\u65F6",
|
|
1047
|
-
"sched.minuteField": "\u5206\u949F",
|
|
1048
|
-
"sched.presetHourly": "\u6BCF\u5C0F\u65F6\u6574\u70B9",
|
|
1049
|
-
"sched.presetMin30": "\u6BCF 30 \u5206\u949F",
|
|
1050
|
-
"sched.presetDaily9": "\u6BCF\u5929 9:00",
|
|
1051
|
-
"sched.presetWeekday830": "\u5DE5\u4F5C\u65E5 8:30",
|
|
1052
|
-
"sched.presetMon10": "\u6BCF\u5468\u4E00 10:00",
|
|
959
|
+
"pop.title": "T\u4E13\u5BB6"
|
|
960
|
+
// 列表过滤与搜索(与官方「自动化任务」页同一套:标签行 + 搜索框)
|
|
961
|
+
// 三档:全部 / 已启用 / 已停用 —— 停用 ≠ 删除(停用的任务保留数据、只是不触发)。
|
|
962
|
+
// 运行时间卡片(对齐官方详情页的「运行时间」:重复 / 时间 / 星期 三行)
|
|
1053
963
|
// 周几:键必须**逐行**写、并且在代码里以字面量引用(字典无人引用自检会盯着这一点)。
|
|
1054
|
-
"sched.wd1": "\u4E00",
|
|
1055
|
-
"sched.wd2": "\u4E8C",
|
|
1056
|
-
"sched.wd3": "\u4E09",
|
|
1057
|
-
"sched.wd4": "\u56DB",
|
|
1058
|
-
"sched.wd5": "\u4E94",
|
|
1059
|
-
"sched.wd6": "\u516D",
|
|
1060
|
-
"sched.wd0": "\u65E5",
|
|
1061
|
-
"sched.listSep": "\u3001",
|
|
1062
|
-
"sched.sumMin": "\u6BCF {n} \u5206\u949F\u6267\u884C\u4E00\u6B21",
|
|
1063
|
-
"sched.sumHour": "\u6BCF\u5C0F\u65F6\u7B2C {m} \u5206\u6267\u884C",
|
|
1064
|
-
"sched.sumDaily": "\u6BCF\u5929 {t} \u6267\u884C",
|
|
1065
|
-
"sched.sumWeekly": "\u6BCF\u5468{w} {t} \u6267\u884C",
|
|
1066
|
-
"sched.sumWeeklyWorkday": "\u5DE5\u4F5C\u65E5 {t} \u6267\u884C",
|
|
1067
|
-
"sched.sumCustom": "\u81EA\u5B9A\u4E49\u8868\u8FBE\u5F0F\uFF1A{raw}",
|
|
1068
|
-
"sched.sumEmpty": "\u9009\u62E9\u6216\u586B\u5199\u4E00\u4E2A\u6267\u884C\u65F6\u95F4",
|
|
1069
|
-
"sched.nextRuns": "\u6700\u8FD1 {n} \u6B21\u6267\u884C",
|
|
1070
|
-
"sched.titleLabel": "\u6807\u9898",
|
|
1071
|
-
"sched.titlePlaceholder": "\u4F8B\u5982\uFF1A\u6668\u4F1A\u7EAA\u8981",
|
|
1072
|
-
"sched.promptLabel": "\u63D0\u793A\u8BCD",
|
|
1073
|
-
"sched.promptPlaceholder": "\u5230\u70B9\u65F6\uFF0C\u8BA9 agent \u505A\u4EC0\u4E48\uFF1F",
|
|
1074
|
-
"sched.expertPick": "T\u4E13\u5BB6",
|
|
1075
|
-
"sched.expertPickHint": "\u70B9\u8FD9\u4E2A\u6309\u94AE\u4ECE\u5DF2\u542F\u7528\u4E13\u5BB6\u91CC\u6311\u4E00\u4F4D\uFF0C\u628A @\u4E13\u5BB6\u540D \u586B\u8FDB\u63D0\u793A\u8BCD\u3002",
|
|
1076
|
-
"sched.expertPickSearch": "\u641C\u7D22\u4E13\u5BB6\u540D\u6216 slug",
|
|
1077
|
-
"sched.expertPickEmpty": "\u6CA1\u6709\u5339\u914D\u7684\u5DF2\u542F\u7528\u4E13\u5BB6\u3002\u5148\u53BB \u8BBE\u7F6E \u2192 T\u4E13\u5BB6 \u542F\u7528\u3002",
|
|
1078
|
-
"sched.expertInvokeHint": "\u5230\u70B9\u6267\u884C\u65F6\u4F1A\u53EC\u5524\u300C{name}\u300D\u6765\u5B8C\u6210\u8FD9\u6BB5\u63D0\u793A\u8BCD\u3002",
|
|
1079
|
-
"sched.expertInvokeManyHint": "\u5230\u70B9\u6267\u884C\u65F6\u4F1A\u540C\u65F6\u53EC\u5524\u300C{names}\u300D\u6765\u5B8C\u6210\u8FD9\u6BB5\u63D0\u793A\u8BCD\u3002",
|
|
1080
|
-
"sched.expertRemove": "\u79FB\u9664 {name}",
|
|
1081
|
-
"sched.enabledLabel": "\u542F\u7528",
|
|
1082
|
-
"sched.enabledHint": "\u505C\u7528\u7684\u4E8B\u9879\u4FDD\u7559\u6570\u636E\uFF0C\u4F46\u4E0D\u4F1A\u5B9A\u65F6\u89E6\u53D1\u3002",
|
|
1083
|
-
"sched.invalidForm": "\u6807\u9898\u3001\u63D0\u793A\u8BCD\u548C cron \u5B9A\u65F6\u5668\u90FD\u662F\u5FC5\u586B\u9879\u3002",
|
|
1084
|
-
"sched.off": "\u5B9A\u65F6\u4EFB\u52A1\u5DF2\u5728 \u8BBE\u7F6E \u2192 T\u4E13\u5BB6 \u91CC\u5173\u95ED\uFF1A\u73B0\u5728\u4E0D\u4F1A\u5B9A\u65F6\u89E6\u53D1\uFF0C\u4E5F\u4E0D\u80FD\u7ACB\u5373\u6267\u884C\u3002\u91CD\u65B0\u6253\u5F00\u300C\u663E\u793A\u5B9A\u65F6\u4EFB\u52A1\u6309\u94AE\u300D\u5373\u6062\u590D\u3002",
|
|
1085
|
-
"sched.noAgents": "\u5BBF\u4E3B\u6CA1\u6709\u53EF\u7528\u7684 agents \u670D\u52A1\uFF0C\u521B\u5EFA\u4F1A\u8BDD\u4F1A\u5931\u8D25\uFF1A\u8BF7\u68C0\u67E5\u5BBF\u4E3B\u88C5\u914D\u3002",
|
|
1086
|
-
"sched.file": "\u6570\u636E\u6587\u4EF6\uFF1A{path}"
|
|
1087
964
|
};
|
|
1088
965
|
var en = {
|
|
1089
966
|
"settings.title": "T Expert",
|
|
@@ -1185,96 +1062,10 @@ var en = {
|
|
|
1185
1062
|
"custom.deleteHint": "Delete \u201C{name}\u201D? Only this custom expert file is removed; this cannot be undone.",
|
|
1186
1063
|
"custom.badge": "Custom",
|
|
1187
1064
|
"custom.loadingBody": "Loading persona body\u2026",
|
|
1188
|
-
"pop.title": "T Expert"
|
|
1189
|
-
//
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
"sched.nav": "Scheduled tasks",
|
|
1193
|
-
"sched.title": "Scheduled tasks",
|
|
1194
|
-
"sched.intro": "Send a prompt to a fresh agent session on a cron schedule \u2014 or run it right now. Each run appears under its workspace in the sidebar.",
|
|
1195
|
-
"sched.tip": "An enabled item creates a session and submits its prompt in the background (the agent acts on its own), so only write prompts you trust.",
|
|
1196
|
-
"sched.back": "Back to conversation",
|
|
1197
|
-
"sched.refresh": "Refresh",
|
|
1198
|
-
"sched.loading": "Loading scheduled tasks\u2026",
|
|
1199
|
-
"sched.error": "The scheduled tasks service is unavailable.",
|
|
1200
|
-
"sched.empty": "No scheduled tasks yet \u2014 create the first one.",
|
|
1201
|
-
"sched.retry": "Retry",
|
|
1202
|
-
"sched.new": "New scheduled task",
|
|
1203
|
-
"sched.edit": "Edit scheduled task",
|
|
1204
|
-
"sched.save": "Save",
|
|
1205
|
-
"sched.saving": "Saving\u2026",
|
|
1206
|
-
"sched.cancel": "Cancel",
|
|
1207
|
-
"sched.delete": "Delete",
|
|
1208
|
-
"sched.deleteConfirm": "Delete this scheduled task?",
|
|
1209
|
-
"sched.runNow": "Run now",
|
|
1210
|
-
"sched.running": "Running\u2026",
|
|
1211
|
-
"sched.runHistory": "Run history ({count})",
|
|
1212
|
-
"sched.runOk": "OK",
|
|
1213
|
-
"sched.runFail": "Failed",
|
|
1214
|
-
"sched.lastRun": "Last run",
|
|
1215
|
-
"sched.neverRun": "Never",
|
|
1216
|
-
"sched.failed": "failed",
|
|
1217
|
-
"sched.disabledTag": "Disabled",
|
|
1218
|
-
"sched.workspace": "Workspace",
|
|
1219
|
-
"sched.workspaceNone": "None (default directory)",
|
|
1220
|
-
"sched.workspaceHint": "Each run starts a new session in this workspace; sessions appear grouped under it in the sidebar.",
|
|
1221
|
-
"sched.workspacePath": "Directory: {path}",
|
|
1222
|
-
"sched.workspaceCustom": "+ Custom directory\u2026",
|
|
1223
|
-
"sched.workspaceCustomPlaceholder": "Absolute path, e.g. /Users/you/tasks",
|
|
1224
|
-
"sched.workspaceCustomHint": "The directory is created when missing, then registered as a workspace.",
|
|
1225
|
-
"sched.workspaceCustomEmpty": "Enter an absolute path for the custom directory first.",
|
|
1226
|
-
"sched.workspaceAutoRecoverHint": "Workspace gone \u2014 {path} will be recreated automatically on the next run.",
|
|
1227
|
-
"sched.workspaceMissingHintNoPath": "Workspace gone and no directory recorded \u2014 automatic recovery is not possible. Please create the workspace again in the sidebar workspace list.",
|
|
1228
|
-
"sched.cronLabel": "Cron schedule",
|
|
1229
|
-
"sched.cronHint": 'Five-field cron expression (minute hour day month weekday), e.g. "0 9 * * *" runs daily at 09:00.',
|
|
1230
|
-
"sched.cronHourly": "Hourly",
|
|
1231
|
-
"sched.cronDaily": "Daily",
|
|
1232
|
-
"sched.cronWeekly": "Weekly",
|
|
1233
|
-
"sched.cronCustom": "Custom",
|
|
1234
|
-
"sched.cronEvery": "Every",
|
|
1235
|
-
"sched.cronAtMinute": "hour at minute",
|
|
1236
|
-
"sched.cronMinuteUnit": "",
|
|
1237
|
-
"sched.cronMinutesUnit": "minutes",
|
|
1238
|
-
"sched.hourField": "Hour",
|
|
1239
|
-
"sched.minuteField": "Minute",
|
|
1240
|
-
"sched.presetHourly": "Every hour",
|
|
1241
|
-
"sched.presetMin30": "Every 30 min",
|
|
1242
|
-
"sched.presetDaily9": "Daily at 9:00",
|
|
1243
|
-
"sched.presetWeekday830": "Weekdays at 8:30",
|
|
1244
|
-
"sched.presetMon10": "Mondays at 10:00",
|
|
1245
|
-
"sched.wd1": "Mon",
|
|
1246
|
-
"sched.wd2": "Tue",
|
|
1247
|
-
"sched.wd3": "Wed",
|
|
1248
|
-
"sched.wd4": "Thu",
|
|
1249
|
-
"sched.wd5": "Fri",
|
|
1250
|
-
"sched.wd6": "Sat",
|
|
1251
|
-
"sched.wd0": "Sun",
|
|
1252
|
-
"sched.listSep": ", ",
|
|
1253
|
-
"sched.sumMin": "Every {n} minutes",
|
|
1254
|
-
"sched.sumHour": "Every hour at minute {m}",
|
|
1255
|
-
"sched.sumDaily": "Daily at {t}",
|
|
1256
|
-
"sched.sumWeekly": "Weekly on {w} at {t}",
|
|
1257
|
-
"sched.sumWeeklyWorkday": "Weekdays at {t}",
|
|
1258
|
-
"sched.sumCustom": "Custom: {raw}",
|
|
1259
|
-
"sched.sumEmpty": "Pick or type a schedule",
|
|
1260
|
-
"sched.nextRuns": "Next {n} runs",
|
|
1261
|
-
"sched.titleLabel": "Title",
|
|
1262
|
-
"sched.titlePlaceholder": "e.g. Morning standup notes",
|
|
1263
|
-
"sched.promptLabel": "Prompt",
|
|
1264
|
-
"sched.promptPlaceholder": "What should the agent do when this item runs?",
|
|
1265
|
-
"sched.expertPick": "T Expert",
|
|
1266
|
-
"sched.expertPickHint": "Pick one of the enabled experts here and its @name lands in the prompt.",
|
|
1267
|
-
"sched.expertPickSearch": "Search expert name or slug",
|
|
1268
|
-
"sched.expertPickEmpty": "No matching enabled expert. Enable some in Settings \u2192 T Expert.",
|
|
1269
|
-
"sched.expertInvokeHint": 'This run will summon "{name}" to carry out this prompt.',
|
|
1270
|
-
"sched.expertInvokeManyHint": 'This run will summon "{names}" together to carry out this prompt.',
|
|
1271
|
-
"sched.expertRemove": "Remove {name}",
|
|
1272
|
-
"sched.enabledLabel": "Enabled",
|
|
1273
|
-
"sched.enabledHint": "Disabled items keep their data but never run on schedule.",
|
|
1274
|
-
"sched.invalidForm": "Title, prompt, and cron schedule are required.",
|
|
1275
|
-
"sched.off": 'Scheduled tasks are turned off in Settings \u2192 T Expert: nothing triggers and nothing can be run by hand. Re-enable "Show scheduled tasks button" to restore it.',
|
|
1276
|
-
"sched.noAgents": "The host has no usable agents service, so creating a session will fail \u2014 check the host composition.",
|
|
1277
|
-
"sched.file": "Data file: {path}"
|
|
1065
|
+
"pop.title": "T Expert"
|
|
1066
|
+
// List filter and search (same shape as the built-in Automation page: tab row + search field).
|
|
1067
|
+
// Three lanes: All / Active / Disabled — disabled keeps its data and simply never fires.
|
|
1068
|
+
// Run-time card (mirrors the built-in page's "Run time": repeat / time / weekday rows)
|
|
1278
1069
|
};
|
|
1279
1070
|
|
|
1280
1071
|
// src/client/insert.js
|
|
@@ -21051,64 +20842,13 @@ var enabledStateSchema = external_exports.object({
|
|
|
21051
20842
|
revision: external_exports.number().int().min(0)
|
|
21052
20843
|
});
|
|
21053
20844
|
var uiPrefsSchema = external_exports.object({
|
|
21054
|
-
showScheduleButton: external_exports.boolean(),
|
|
21055
20845
|
// 窗口右上角「活跃指示」是否显示。宿主**总是**返回布尔(缺省按 true 算),所以这里必填。
|
|
21056
20846
|
showActivePulse: external_exports.boolean()
|
|
21057
20847
|
});
|
|
21058
20848
|
var uiPrefsPatchSchema = external_exports.object({
|
|
21059
|
-
showScheduleButton: external_exports.boolean().optional(),
|
|
21060
20849
|
showActivePulse: external_exports.boolean().optional()
|
|
21061
20850
|
});
|
|
21062
20851
|
var promptSchema = external_exports.object({ prompt: external_exports.string() });
|
|
21063
|
-
var scheduleRunSchema = external_exports.object({
|
|
21064
|
-
at: external_exports.string(),
|
|
21065
|
-
ok: external_exports.boolean(),
|
|
21066
|
-
sessionId: external_exports.string().optional(),
|
|
21067
|
-
error: external_exports.string().optional()
|
|
21068
|
-
});
|
|
21069
|
-
var scheduleItemSchema = external_exports.object({
|
|
21070
|
-
id: external_exports.string(),
|
|
21071
|
-
title: external_exports.string(),
|
|
21072
|
-
prompt: external_exports.string(),
|
|
21073
|
-
cron: external_exports.string(),
|
|
21074
|
-
enabled: external_exports.boolean(),
|
|
21075
|
-
workspaceId: external_exports.string().optional(),
|
|
21076
|
-
/** 绑定时记下的工作区目录:工作区被删后凭它「重建」回到原路径。面板也会在编辑表单里显示它。 */
|
|
21077
|
-
workspacePath: external_exports.string().optional(),
|
|
21078
|
-
createdAt: external_exports.string(),
|
|
21079
|
-
updatedAt: external_exports.string(),
|
|
21080
|
-
lastRunAt: external_exports.string().optional(),
|
|
21081
|
-
lastRunError: external_exports.string().optional(),
|
|
21082
|
-
runs: external_exports.array(scheduleRunSchema)
|
|
21083
|
-
});
|
|
21084
|
-
var scheduleSnapshotSchema = external_exports.object({
|
|
21085
|
-
items: external_exports.array(scheduleItemSchema),
|
|
21086
|
-
/** 定时事项功能是否启用(= 设置页那个开关的当前值)。 */
|
|
21087
|
-
armed: external_exports.boolean(),
|
|
21088
|
-
/** 数据文件绝对路径(面板把它显示在说明里,便于用户备份)。 */
|
|
21089
|
-
file: external_exports.string(),
|
|
21090
|
-
/** 正在执行中的事项 id(面板据此显示「执行中…」)。 */
|
|
21091
|
-
running: external_exports.array(external_exports.string()),
|
|
21092
|
-
capabilities: external_exports.object({ agents: external_exports.boolean(), presets: external_exports.boolean() }),
|
|
21093
|
-
/** 可选工作区(下拉选项);path 是目录,面板显示给用户看落地位置。 */
|
|
21094
|
-
workspaces: external_exports.array(external_exports.object({ id: external_exports.string(), title: external_exports.string(), path: external_exports.string().optional() }))
|
|
21095
|
-
});
|
|
21096
|
-
var scheduleInputSchema = external_exports.object({
|
|
21097
|
-
title: external_exports.string().min(1).max(200),
|
|
21098
|
-
prompt: external_exports.string().min(1).max(2e4),
|
|
21099
|
-
cron: external_exports.string().min(1).max(120),
|
|
21100
|
-
enabled: external_exports.boolean(),
|
|
21101
|
-
/** 空串 = 不绑定工作区(显式解绑也走这个值)。 */
|
|
21102
|
-
workspaceId: external_exports.string().max(200).optional(),
|
|
21103
|
-
/** 绑定时记下的工作区目录;老数据可缺省,按当前选中的 workspace 自动补。 */
|
|
21104
|
-
workspacePath: external_exports.string().max(1024).optional()
|
|
21105
|
-
});
|
|
21106
|
-
var schedulePatchSchema = scheduleInputSchema.partial();
|
|
21107
|
-
var schedulePreviewSchema = external_exports.object({ fires: external_exports.array(external_exports.string()) });
|
|
21108
|
-
var scheduleArmedSchema = external_exports.object({ armed: external_exports.boolean() });
|
|
21109
|
-
var scheduleWorkspaceSchema = external_exports.object({
|
|
21110
|
-
workspace: external_exports.object({ id: external_exports.string(), title: external_exports.string(), path: external_exports.string() })
|
|
21111
|
-
});
|
|
21112
20852
|
|
|
21113
20853
|
// src/client/remote.js
|
|
21114
20854
|
function direct(method, parameters, typeSymbol, schema) {
|
|
@@ -21140,27 +20880,6 @@ var TYPERT_REMOTE = {
|
|
|
21140
20880
|
direct("setUiPrefs", [
|
|
21141
20881
|
{ name: "patch", wire: "patch", source: "json", codec: { mode: "strict", typeSymbol: "TTeamUiPrefsPatch", schema: uiPrefsPatchSchema, create: () => uiPrefsPatchSchema } }
|
|
21142
20882
|
], "TTeamUiPrefs", uiPrefsSchema),
|
|
21143
|
-
// 定时任务:读一份快照;写操作全部回传刷新后的整份快照,面板拿到直接重绘。
|
|
21144
|
-
direct("getSchedule", [], "TTeamSchedule", scheduleSnapshotSchema),
|
|
21145
|
-
direct("createScheduleItem", [
|
|
21146
|
-
{ name: "input", wire: "input", source: "json", codec: { mode: "strict", typeSymbol: "TTeamScheduleInput", schema: scheduleInputSchema, create: () => scheduleInputSchema } }
|
|
21147
|
-
], "TTeamSchedule", scheduleSnapshotSchema),
|
|
21148
|
-
direct("updateScheduleItem", [
|
|
21149
|
-
{ name: "id", wire: "id", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128), create: () => external_exports.string().min(1).max(128) } },
|
|
21150
|
-
{ name: "patch", wire: "patch", source: "json", codec: { mode: "strict", typeSymbol: "TTeamSchedulePatch", schema: schedulePatchSchema, create: () => schedulePatchSchema } }
|
|
21151
|
-
], "TTeamSchedule", scheduleSnapshotSchema),
|
|
21152
|
-
direct("deleteScheduleItem", [
|
|
21153
|
-
{ name: "id", wire: "id", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128), create: () => external_exports.string().min(1).max(128) } }
|
|
21154
|
-
], "TTeamSchedule", scheduleSnapshotSchema),
|
|
21155
|
-
direct("runScheduleItem", [
|
|
21156
|
-
{ name: "id", wire: "id", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(128), create: () => external_exports.string().min(1).max(128) } }
|
|
21157
|
-
], "TTeamSchedule", scheduleSnapshotSchema),
|
|
21158
|
-
direct("ensureScheduleWorkspace", [
|
|
21159
|
-
{ name: "path", wire: "path", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().max(1024), create: () => external_exports.string().max(1024) } }
|
|
21160
|
-
], "TTeamScheduleWorkspace", scheduleWorkspaceSchema),
|
|
21161
|
-
direct("previewSchedule", [
|
|
21162
|
-
{ name: "cron", wire: "cron", source: "json", codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string().min(1).max(120), create: () => external_exports.string().min(1).max(120) } }
|
|
21163
|
-
], "TTeamSchedulePreview", schedulePreviewSchema),
|
|
21164
20883
|
direct("createExpert", [
|
|
21165
20884
|
{ name: "expert", wire: "expert", source: "json", codec: { mode: "strict", typeSymbol: "TTeamCustomExpertInput", schema: customExpertInputSchema, create: () => customExpertInputSchema } }
|
|
21166
20885
|
], "TTeamCatalog", catalogSnapshotSchema),
|
|
@@ -21187,916 +20906,18 @@ var TYPERT_REMOTE = {
|
|
|
21187
20906
|
]
|
|
21188
20907
|
};
|
|
21189
20908
|
|
|
21190
|
-
// src/client/schedule.jsx
|
|
21191
|
-
var import_react4 = __toESM(require("react"), 1);
|
|
21192
|
-
|
|
21193
|
-
// src/schedule-cron.js
|
|
21194
|
-
var WEEKDAY_KEYS = [1, 2, 3, 4, 5, 6, 0];
|
|
21195
|
-
var CRON_PRESETS = [
|
|
21196
|
-
{ id: "hourly", cron: "0 * * * *" },
|
|
21197
|
-
{ id: "min30", cron: "*/30 * * * *" },
|
|
21198
|
-
{ id: "daily9", cron: "0 9 * * *" },
|
|
21199
|
-
{ id: "weekday830", cron: "30 8 * * 1-5" },
|
|
21200
|
-
{ id: "mon10", cron: "0 10 * * 1" }
|
|
21201
|
-
];
|
|
21202
|
-
var HOURLY_STEPS = [60, 30, 15, 10, 5];
|
|
21203
|
-
function int2(value, min, max) {
|
|
21204
|
-
if (!/^\d+$/.test(value)) return null;
|
|
21205
|
-
const n = Number(value);
|
|
21206
|
-
return n >= min && n <= max ? n : null;
|
|
21207
|
-
}
|
|
21208
|
-
function parseDow(field) {
|
|
21209
|
-
if (field === "*") return null;
|
|
21210
|
-
const days = /* @__PURE__ */ new Set();
|
|
21211
|
-
for (const token of field.split(",")) {
|
|
21212
|
-
const range = token.match(/^(\d+)-(\d+)$/);
|
|
21213
|
-
let lo;
|
|
21214
|
-
let hi;
|
|
21215
|
-
if (range) {
|
|
21216
|
-
lo = Number(range[1]);
|
|
21217
|
-
hi = Number(range[2]);
|
|
21218
|
-
if (lo > hi) return null;
|
|
21219
|
-
} else {
|
|
21220
|
-
lo = hi = Number(token);
|
|
21221
|
-
}
|
|
21222
|
-
for (let atom = lo; atom <= hi; atom++) {
|
|
21223
|
-
if (!Number.isInteger(atom)) return null;
|
|
21224
|
-
if (atom < 0 || atom > 7) return null;
|
|
21225
|
-
days.add(atom === 7 ? 0 : atom);
|
|
21226
|
-
}
|
|
21227
|
-
}
|
|
21228
|
-
if (days.size === 0) return null;
|
|
21229
|
-
return WEEKDAY_KEYS.filter((key) => days.has(key));
|
|
21230
|
-
}
|
|
21231
|
-
function parseCron(str) {
|
|
21232
|
-
const raw = typeof str === "string" ? str.trim() : "";
|
|
21233
|
-
const custom2 = { mode: "custom", raw };
|
|
21234
|
-
const fields = raw.split(/\s+/);
|
|
21235
|
-
if (fields.length !== 5) return raw === "" ? { mode: "daily", minute: 0, hour: 9 } : custom2;
|
|
21236
|
-
const [mf, hf, domf, monf, dowf] = fields;
|
|
21237
|
-
if (domf !== "*" || monf !== "*") return custom2;
|
|
21238
|
-
if (hf === "*" && dowf === "*") {
|
|
21239
|
-
const step = mf.match(/^\*\/(\d+)$/);
|
|
21240
|
-
if (step) {
|
|
21241
|
-
const n = Number(step[1]);
|
|
21242
|
-
return HOURLY_STEPS.includes(n) ? { mode: "hourly", step: n } : custom2;
|
|
21243
|
-
}
|
|
21244
|
-
const minute2 = int2(mf, 0, 59);
|
|
21245
|
-
return minute2 === null ? custom2 : { mode: "hourly", step: 60, minute: minute2 };
|
|
21246
|
-
}
|
|
21247
|
-
const hour = int2(hf, 0, 23);
|
|
21248
|
-
const minute = int2(mf, 0, 59);
|
|
21249
|
-
if (hour === null || minute === null) return custom2;
|
|
21250
|
-
const days = parseDow(dowf);
|
|
21251
|
-
if (days === null) return dowf === "*" ? { mode: "daily", hour, minute } : custom2;
|
|
21252
|
-
return { mode: "weekly", hour, minute, days };
|
|
21253
|
-
}
|
|
21254
|
-
function formatDow(days) {
|
|
21255
|
-
const week = days.filter((d) => d >= 1 && d <= 6).sort((a, b) => a - b);
|
|
21256
|
-
const tokens = [];
|
|
21257
|
-
let start = null;
|
|
21258
|
-
let prev = null;
|
|
21259
|
-
const flush = () => {
|
|
21260
|
-
if (start === null) return;
|
|
21261
|
-
tokens.push(start === prev ? String(start) : `${start}-${prev}`);
|
|
21262
|
-
start = null;
|
|
21263
|
-
};
|
|
21264
|
-
for (const d of week) {
|
|
21265
|
-
if (start === null) {
|
|
21266
|
-
start = d;
|
|
21267
|
-
prev = d;
|
|
21268
|
-
} else if (d === prev + 1) {
|
|
21269
|
-
prev = d;
|
|
21270
|
-
} else {
|
|
21271
|
-
flush();
|
|
21272
|
-
start = d;
|
|
21273
|
-
prev = d;
|
|
21274
|
-
}
|
|
21275
|
-
}
|
|
21276
|
-
flush();
|
|
21277
|
-
if (days.includes(0)) tokens.push("0");
|
|
21278
|
-
return tokens.join(",");
|
|
21279
|
-
}
|
|
21280
|
-
function buildCron(model) {
|
|
21281
|
-
if (!model || model.mode === "custom") return (model?.raw || "").trim();
|
|
21282
|
-
const minute = model.minute ?? 0;
|
|
21283
|
-
if (model.mode === "hourly") {
|
|
21284
|
-
return model.step && model.step < 60 ? `*/${model.step} * * * *` : `${minute} * * * *`;
|
|
21285
|
-
}
|
|
21286
|
-
const hour = model.hour ?? 9;
|
|
21287
|
-
if (model.mode === "daily") return `${minute} ${hour} * * *`;
|
|
21288
|
-
if (model.mode === "weekly") {
|
|
21289
|
-
const days = model.days && model.days.length ? model.days : [1];
|
|
21290
|
-
return `${minute} ${hour} * * ${formatDow(days)}`;
|
|
21291
|
-
}
|
|
21292
|
-
return "";
|
|
21293
|
-
}
|
|
21294
|
-
|
|
21295
|
-
// src/client/schedule.jsx
|
|
21296
|
-
var CUSTOM_WORKSPACE = "__custom__";
|
|
21297
|
-
var SCHEDULE_PANEL_KEY = `${NS}-schedule`;
|
|
21298
|
-
var SCHEDULE_PRESET_LABELS = {
|
|
21299
|
-
hourly: "sched.presetHourly",
|
|
21300
|
-
min30: "sched.presetMin30",
|
|
21301
|
-
daily9: "sched.presetDaily9",
|
|
21302
|
-
weekday830: "sched.presetWeekday830",
|
|
21303
|
-
mon10: "sched.presetMon10"
|
|
21304
|
-
};
|
|
21305
|
-
var SCHEDULE_WEEKDAY_LABELS = {
|
|
21306
|
-
1: "sched.wd1",
|
|
21307
|
-
2: "sched.wd2",
|
|
21308
|
-
3: "sched.wd3",
|
|
21309
|
-
4: "sched.wd4",
|
|
21310
|
-
5: "sched.wd5",
|
|
21311
|
-
6: "sched.wd6",
|
|
21312
|
-
0: "sched.wd0"
|
|
21313
|
-
};
|
|
21314
|
-
function errorText(cause) {
|
|
21315
|
-
return cause instanceof Error ? cause.message : String(cause);
|
|
21316
|
-
}
|
|
21317
|
-
function CronPicker({ t, remote, value, onChange, disabled }) {
|
|
21318
|
-
const [model, setModel] = import_react4.default.useState(() => parseCron(value));
|
|
21319
|
-
const [fires, setFires] = import_react4.default.useState([]);
|
|
21320
|
-
const [hint, setHint] = import_react4.default.useState("");
|
|
21321
|
-
import_react4.default.useEffect(() => {
|
|
21322
|
-
const next = parseCron(value);
|
|
21323
|
-
if (next.mode === "custom" && typeof value === "string") {
|
|
21324
|
-
setModel({ mode: "custom", raw: value });
|
|
21325
|
-
return;
|
|
21326
|
-
}
|
|
21327
|
-
setModel(next);
|
|
21328
|
-
}, [value]);
|
|
21329
|
-
import_react4.default.useEffect(() => {
|
|
21330
|
-
const cron = String(value ?? "").trim();
|
|
21331
|
-
if (cron === "") {
|
|
21332
|
-
setFires([]);
|
|
21333
|
-
setHint("");
|
|
21334
|
-
return void 0;
|
|
21335
|
-
}
|
|
21336
|
-
let cancelled = false;
|
|
21337
|
-
const timer = setTimeout(() => {
|
|
21338
|
-
void (async () => {
|
|
21339
|
-
try {
|
|
21340
|
-
const payload = unwrap(await remote.previewSchedule(cron), "previewSchedule");
|
|
21341
|
-
if (cancelled) return;
|
|
21342
|
-
setFires(Array.isArray(payload?.fires) ? payload.fires : []);
|
|
21343
|
-
setHint("");
|
|
21344
|
-
} catch (cause) {
|
|
21345
|
-
if (cancelled) return;
|
|
21346
|
-
setFires([]);
|
|
21347
|
-
setHint(errorText(cause));
|
|
21348
|
-
}
|
|
21349
|
-
})();
|
|
21350
|
-
}, 250);
|
|
21351
|
-
return () => {
|
|
21352
|
-
cancelled = true;
|
|
21353
|
-
clearTimeout(timer);
|
|
21354
|
-
};
|
|
21355
|
-
}, [value, remote]);
|
|
21356
|
-
import_react4.default.useEffect(() => {
|
|
21357
|
-
if (!value || String(value).trim() === "") onChange(buildCron(parseCron("")));
|
|
21358
|
-
}, []);
|
|
21359
|
-
const emit = (next) => {
|
|
21360
|
-
setModel(next);
|
|
21361
|
-
const cron = buildCron(next);
|
|
21362
|
-
if (cron !== "") onChange(cron);
|
|
21363
|
-
};
|
|
21364
|
-
const setMode = (mode) => {
|
|
21365
|
-
if (mode === model.mode) return;
|
|
21366
|
-
if (mode === "hourly") emit({ mode, step: 60, minute: model.minute ?? 0 });
|
|
21367
|
-
else if (mode === "daily") emit({ mode, hour: model.hour ?? 9, minute: model.minute ?? 0 });
|
|
21368
|
-
else if (mode === "weekly") emit({ mode, hour: model.hour ?? 9, minute: model.minute ?? 0, days: model.days && model.days.length ? model.days : [1, 2, 3, 4, 5] });
|
|
21369
|
-
else {
|
|
21370
|
-
const raw = buildCron(model) || "0 9 * * *";
|
|
21371
|
-
setModel({ mode, raw });
|
|
21372
|
-
onChange(raw);
|
|
21373
|
-
}
|
|
21374
|
-
};
|
|
21375
|
-
const toggleDay = (day) => {
|
|
21376
|
-
const current = model.days || [];
|
|
21377
|
-
const next = current.includes(day) ? current.filter((item) => item !== day) : WEEKDAY_KEYS.filter((item) => current.includes(item) || item === day);
|
|
21378
|
-
if (next.length === 0) return;
|
|
21379
|
-
emit({ ...model, days: next });
|
|
21380
|
-
};
|
|
21381
|
-
const pad2 = (n) => String(n).padStart(2, "0");
|
|
21382
|
-
const hours = Array.from({ length: 24 }, (_, i) => i);
|
|
21383
|
-
const minutes = Array.from({ length: 60 }, (_, i) => i);
|
|
21384
|
-
const time3 = `${pad2(model.hour ?? 9)}:${pad2(model.minute ?? 0)}`;
|
|
21385
|
-
let summary;
|
|
21386
|
-
if (model.mode === "hourly") {
|
|
21387
|
-
summary = model.step && model.step < 60 ? t("sched.sumMin", { n: model.step }) : t("sched.sumHour", { m: pad2(model.minute ?? 0) });
|
|
21388
|
-
} else if (model.mode === "daily") {
|
|
21389
|
-
summary = t("sched.sumDaily", { t: time3 });
|
|
21390
|
-
} else if (model.mode === "weekly") {
|
|
21391
|
-
const days = model.days || [];
|
|
21392
|
-
const isWorkday = days.length === 5 && [1, 2, 3, 4, 5].every((day) => days.includes(day));
|
|
21393
|
-
const week = isWorkday ? "" : days.map((day) => t(SCHEDULE_WEEKDAY_LABELS[day])).join(t("sched.listSep"));
|
|
21394
|
-
summary = t(isWorkday ? "sched.sumWeeklyWorkday" : "sched.sumWeekly", { w: week, t: time3 });
|
|
21395
|
-
} else {
|
|
21396
|
-
summary = model.raw ? t("sched.sumCustom", { raw: model.raw }) : t("sched.sumEmpty");
|
|
21397
|
-
}
|
|
21398
|
-
const timeSelects = /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("select", { "aria-label": t("sched.hourField"), value: model.hour ?? 9, disabled, onChange: (event) => emit({ ...model, hour: Number(event.target.value) }) }, hours.map((n) => /* @__PURE__ */ import_react4.default.createElement("option", { key: n, value: n }, pad2(n)))), /* @__PURE__ */ import_react4.default.createElement("span", null, ":"), /* @__PURE__ */ import_react4.default.createElement("select", { "aria-label": t("sched.minuteField"), value: model.minute ?? 0, disabled, onChange: (event) => emit({ ...model, minute: Number(event.target.value) }) }, minutes.map((n) => /* @__PURE__ */ import_react4.default.createElement("option", { key: n, value: n }, pad2(n)))));
|
|
21399
|
-
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-cron" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-chips" }, CRON_PRESETS.map((preset) => /* @__PURE__ */ import_react4.default.createElement(
|
|
21400
|
-
"button",
|
|
21401
|
-
{
|
|
21402
|
-
key: preset.id,
|
|
21403
|
-
type: "button",
|
|
21404
|
-
className: "t-team-sched-chip",
|
|
21405
|
-
disabled,
|
|
21406
|
-
onClick: () => onChange(preset.cron)
|
|
21407
|
-
},
|
|
21408
|
-
t(SCHEDULE_PRESET_LABELS[preset.id])
|
|
21409
|
-
))), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-seg", role: "tablist" }, [["hourly", "sched.cronHourly"], ["daily", "sched.cronDaily"], ["weekly", "sched.cronWeekly"], ["custom", "sched.cronCustom"]].map(([mode, key]) => /* @__PURE__ */ import_react4.default.createElement(
|
|
21410
|
-
"button",
|
|
21411
|
-
{
|
|
21412
|
-
key: mode,
|
|
21413
|
-
type: "button",
|
|
21414
|
-
role: "tab",
|
|
21415
|
-
"aria-selected": model.mode === mode,
|
|
21416
|
-
"data-on": model.mode === mode,
|
|
21417
|
-
disabled,
|
|
21418
|
-
onClick: () => setMode(mode)
|
|
21419
|
-
},
|
|
21420
|
-
t(key)
|
|
21421
|
-
))), model.mode === "hourly" && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-cronRow" }, /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.cronEvery")), /* @__PURE__ */ import_react4.default.createElement(
|
|
21422
|
-
"select",
|
|
21423
|
-
{
|
|
21424
|
-
value: model.step ?? 60,
|
|
21425
|
-
disabled,
|
|
21426
|
-
onChange: (event) => {
|
|
21427
|
-
const step = Number(event.target.value);
|
|
21428
|
-
emit(step === 60 ? { mode: "hourly", step, minute: model.minute ?? 0 } : { mode: "hourly", step });
|
|
21429
|
-
}
|
|
21430
|
-
},
|
|
21431
|
-
HOURLY_STEPS.map((step) => /* @__PURE__ */ import_react4.default.createElement("option", { key: step, value: step }, step === 60 ? "1" : String(step)))
|
|
21432
|
-
), (model.step ?? 60) === 60 ? /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.cronAtMinute")), /* @__PURE__ */ import_react4.default.createElement(
|
|
21433
|
-
"select",
|
|
21434
|
-
{
|
|
21435
|
-
value: model.minute ?? 0,
|
|
21436
|
-
disabled,
|
|
21437
|
-
onChange: (event) => emit({ ...model, minute: Number(event.target.value) })
|
|
21438
|
-
},
|
|
21439
|
-
minutes.map((n) => /* @__PURE__ */ import_react4.default.createElement("option", { key: n, value: n }, pad2(n)))
|
|
21440
|
-
), /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.cronMinuteUnit"))) : /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.cronMinutesUnit"))), (model.mode === "daily" || model.mode === "weekly") && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-cronRow" }, model.mode === "weekly" && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-days" }, WEEKDAY_KEYS.map((day) => /* @__PURE__ */ import_react4.default.createElement(
|
|
21441
|
-
"button",
|
|
21442
|
-
{
|
|
21443
|
-
key: day,
|
|
21444
|
-
type: "button",
|
|
21445
|
-
className: "t-team-sched-day",
|
|
21446
|
-
"data-on": (model.days || []).includes(day),
|
|
21447
|
-
"aria-pressed": (model.days || []).includes(day),
|
|
21448
|
-
disabled,
|
|
21449
|
-
onClick: () => toggleDay(day)
|
|
21450
|
-
},
|
|
21451
|
-
t(SCHEDULE_WEEKDAY_LABELS[day])
|
|
21452
|
-
))), timeSelects), model.mode === "custom" && /* @__PURE__ */ import_react4.default.createElement(
|
|
21453
|
-
"input",
|
|
21454
|
-
{
|
|
21455
|
-
value: model.raw || "",
|
|
21456
|
-
disabled,
|
|
21457
|
-
placeholder: "0 9 * * *",
|
|
21458
|
-
spellCheck: false,
|
|
21459
|
-
onChange: (event) => {
|
|
21460
|
-
const raw = event.target.value;
|
|
21461
|
-
setModel({ mode: "custom", raw });
|
|
21462
|
-
onChange(raw);
|
|
21463
|
-
}
|
|
21464
|
-
}
|
|
21465
|
-
), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-sum" }, hint === "" ? summary : hint), fires.length > 0 && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-next" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-sched-nextLabel" }, t("sched.nextRuns", { n: fires.length })), /* @__PURE__ */ import_react4.default.createElement("ul", { className: "t-team-sched-nextList" }, fires.map((iso, index) => /* @__PURE__ */ import_react4.default.createElement("li", { key: index }, new Date(iso).toLocaleString(void 0, { weekday: "short", month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit" }))))));
|
|
21466
|
-
}
|
|
21467
|
-
function emptyScheduleForm() {
|
|
21468
|
-
return { editingId: null, title: "", prompt: "", cron: "", enabled: true, workspaceId: "", customDir: "", workspacePath: "" };
|
|
21469
|
-
}
|
|
21470
|
-
function scheduleLastRun(t, item) {
|
|
21471
|
-
if (!item.lastRunAt) return t("sched.neverRun");
|
|
21472
|
-
const time3 = new Date(item.lastRunAt).toLocaleString();
|
|
21473
|
-
return item.lastRunError === void 0 ? time3 : `${time3}\uFF08${t("sched.failed")}: ${item.lastRunError}\uFF09`;
|
|
21474
|
-
}
|
|
21475
|
-
function PromptEditor({ editorRef, t, active, experts, value, disabled, onChange }) {
|
|
21476
|
-
const boxRef = import_react4.default.useRef(null);
|
|
21477
|
-
const lastWritten = import_react4.default.useRef(null);
|
|
21478
|
-
const savedRange = import_react4.default.useRef(null);
|
|
21479
|
-
const buildChipIcon = () => {
|
|
21480
|
-
const NS2 = "http://www.w3.org/2000/svg";
|
|
21481
|
-
const svg = document.createElementNS(NS2, "svg");
|
|
21482
|
-
svg.setAttribute("class", "t-team-sched-chip-icon");
|
|
21483
|
-
svg.setAttribute("viewBox", "0 0 16 16");
|
|
21484
|
-
svg.setAttribute("width", "13");
|
|
21485
|
-
svg.setAttribute("height", "13");
|
|
21486
|
-
svg.setAttribute("fill", "none");
|
|
21487
|
-
svg.setAttribute("stroke", "currentColor");
|
|
21488
|
-
svg.setAttribute("stroke-width", "1.4");
|
|
21489
|
-
svg.setAttribute("stroke-linecap", "round");
|
|
21490
|
-
svg.setAttribute("aria-hidden", "true");
|
|
21491
|
-
const circle = document.createElementNS(NS2, "circle");
|
|
21492
|
-
circle.setAttribute("cx", "8");
|
|
21493
|
-
circle.setAttribute("cy", "8");
|
|
21494
|
-
circle.setAttribute("r", "6");
|
|
21495
|
-
const line1 = document.createElementNS(NS2, "line");
|
|
21496
|
-
line1.setAttribute("x1", "5.4");
|
|
21497
|
-
line1.setAttribute("y1", "6.6");
|
|
21498
|
-
line1.setAttribute("x2", "10.6");
|
|
21499
|
-
line1.setAttribute("y2", "6.6");
|
|
21500
|
-
const line2 = document.createElementNS(NS2, "line");
|
|
21501
|
-
line2.setAttribute("x1", "5.4");
|
|
21502
|
-
line2.setAttribute("y1", "9.4");
|
|
21503
|
-
line2.setAttribute("x2", "9");
|
|
21504
|
-
line2.setAttribute("y2", "9.4");
|
|
21505
|
-
svg.append(circle, line1, line2);
|
|
21506
|
-
return svg;
|
|
21507
|
-
};
|
|
21508
|
-
const buildChip = (name) => {
|
|
21509
|
-
const chip = document.createElement("span");
|
|
21510
|
-
chip.className = "t-team-sched-chip";
|
|
21511
|
-
chip.contentEditable = "false";
|
|
21512
|
-
chip.dataset.expert = name;
|
|
21513
|
-
const label = document.createElement("span");
|
|
21514
|
-
label.className = "t-team-sched-chip-name";
|
|
21515
|
-
label.textContent = name;
|
|
21516
|
-
const remove = document.createElement("button");
|
|
21517
|
-
remove.type = "button";
|
|
21518
|
-
remove.className = "t-team-sched-chip-remove";
|
|
21519
|
-
remove.dataset.remove = name;
|
|
21520
|
-
remove.textContent = "\xD7";
|
|
21521
|
-
remove.title = t("sched.expertRemove", { name });
|
|
21522
|
-
chip.append(buildChipIcon(), label, remove);
|
|
21523
|
-
return chip;
|
|
21524
|
-
};
|
|
21525
|
-
const serialize = () => {
|
|
21526
|
-
const box = boxRef.current;
|
|
21527
|
-
if (box === null) return "";
|
|
21528
|
-
let out = "";
|
|
21529
|
-
for (const node2 of box.childNodes) {
|
|
21530
|
-
if (node2.nodeType === 3) {
|
|
21531
|
-
out += node2.textContent ?? "";
|
|
21532
|
-
continue;
|
|
21533
|
-
}
|
|
21534
|
-
if (node2.nodeType !== 1) continue;
|
|
21535
|
-
const el = (
|
|
21536
|
-
/** @type {HTMLElement} */
|
|
21537
|
-
node2
|
|
21538
|
-
);
|
|
21539
|
-
if (el.dataset?.expert !== void 0) {
|
|
21540
|
-
out += `@${el.dataset.expert}`;
|
|
21541
|
-
continue;
|
|
21542
|
-
}
|
|
21543
|
-
if (el.tagName === "BR") {
|
|
21544
|
-
out += "\n";
|
|
21545
|
-
continue;
|
|
21546
|
-
}
|
|
21547
|
-
out += el.textContent ?? "";
|
|
21548
|
-
}
|
|
21549
|
-
return out;
|
|
21550
|
-
};
|
|
21551
|
-
const refreshEmpty = () => {
|
|
21552
|
-
const box = boxRef.current;
|
|
21553
|
-
if (box !== null) box.dataset.empty = box.textContent === "" ? "true" : "false";
|
|
21554
|
-
};
|
|
21555
|
-
const pushOut = () => {
|
|
21556
|
-
const text = serialize();
|
|
21557
|
-
lastWritten.current = text;
|
|
21558
|
-
refreshEmpty();
|
|
21559
|
-
onChange(text);
|
|
21560
|
-
};
|
|
21561
|
-
const rebuild = () => {
|
|
21562
|
-
const box = boxRef.current;
|
|
21563
|
-
if (box === null) return;
|
|
21564
|
-
box.textContent = "";
|
|
21565
|
-
for (const token of tokenizePrompt(value, experts, active)) {
|
|
21566
|
-
box.append(token.type === "text" ? document.createTextNode(token.text ?? "") : buildChip(token.name ?? ""));
|
|
21567
|
-
}
|
|
21568
|
-
refreshEmpty();
|
|
21569
|
-
};
|
|
21570
|
-
const removeExpert = (name) => {
|
|
21571
|
-
const box = boxRef.current;
|
|
21572
|
-
if (box === null) return;
|
|
21573
|
-
for (const el of box.querySelectorAll("[data-expert]")) {
|
|
21574
|
-
if (
|
|
21575
|
-
/** @type {HTMLElement} */
|
|
21576
|
-
el.dataset.expert === name
|
|
21577
|
-
) {
|
|
21578
|
-
el.remove();
|
|
21579
|
-
break;
|
|
21580
|
-
}
|
|
21581
|
-
}
|
|
21582
|
-
pushOut();
|
|
21583
|
-
};
|
|
21584
|
-
const insertExpert = (name) => {
|
|
21585
|
-
const box = boxRef.current;
|
|
21586
|
-
if (box === null || disabled) return;
|
|
21587
|
-
const chip = buildChip(name);
|
|
21588
|
-
const space = document.createTextNode(" ");
|
|
21589
|
-
box.focus();
|
|
21590
|
-
const selection = window.getSelection();
|
|
21591
|
-
if (selection !== null && savedRange.current !== null && box.contains(savedRange.current.commonAncestorContainer)) {
|
|
21592
|
-
selection.removeAllRanges();
|
|
21593
|
-
selection.addRange(savedRange.current);
|
|
21594
|
-
}
|
|
21595
|
-
const inside = selection !== null && selection.rangeCount > 0 && box.contains(selection.anchorNode);
|
|
21596
|
-
if (inside) {
|
|
21597
|
-
const range = selection.getRangeAt(0);
|
|
21598
|
-
range.deleteContents();
|
|
21599
|
-
range.insertNode(chip);
|
|
21600
|
-
chip.after(space);
|
|
21601
|
-
range.setStartAfter(space);
|
|
21602
|
-
range.collapse(true);
|
|
21603
|
-
selection.removeAllRanges();
|
|
21604
|
-
selection.addRange(range);
|
|
21605
|
-
savedRange.current = range.cloneRange();
|
|
21606
|
-
} else {
|
|
21607
|
-
box.append(chip, space);
|
|
21608
|
-
}
|
|
21609
|
-
pushOut();
|
|
21610
|
-
};
|
|
21611
|
-
import_react4.default.useEffect(() => {
|
|
21612
|
-
if (editorRef === void 0) return void 0;
|
|
21613
|
-
editorRef.current = { insertExpert, removeExpert, focus: () => boxRef.current?.focus() };
|
|
21614
|
-
return () => {
|
|
21615
|
-
editorRef.current = null;
|
|
21616
|
-
};
|
|
21617
|
-
});
|
|
21618
|
-
import_react4.default.useEffect(() => {
|
|
21619
|
-
if (lastWritten.current === value) return;
|
|
21620
|
-
rebuild();
|
|
21621
|
-
}, [value, experts, active]);
|
|
21622
|
-
import_react4.default.useEffect(() => {
|
|
21623
|
-
const onSelectionChange = () => {
|
|
21624
|
-
const box = boxRef.current;
|
|
21625
|
-
if (box === null) return;
|
|
21626
|
-
const selection = window.getSelection();
|
|
21627
|
-
if (selection === null || selection.rangeCount === 0) return;
|
|
21628
|
-
const range = selection.getRangeAt(0);
|
|
21629
|
-
if (box.contains(range.commonAncestorContainer)) savedRange.current = range.cloneRange();
|
|
21630
|
-
};
|
|
21631
|
-
document.addEventListener("selectionchange", onSelectionChange);
|
|
21632
|
-
return () => document.removeEventListener("selectionchange", onSelectionChange);
|
|
21633
|
-
}, []);
|
|
21634
|
-
const onPaste = (event) => {
|
|
21635
|
-
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
21636
|
-
if (text === "") return;
|
|
21637
|
-
event.preventDefault();
|
|
21638
|
-
const selection = window.getSelection();
|
|
21639
|
-
if (selection === null || selection.rangeCount === 0) return;
|
|
21640
|
-
const range = selection.getRangeAt(0);
|
|
21641
|
-
range.deleteContents();
|
|
21642
|
-
const node2 = document.createTextNode(text);
|
|
21643
|
-
range.insertNode(node2);
|
|
21644
|
-
range.setStartAfter(node2);
|
|
21645
|
-
range.collapse(true);
|
|
21646
|
-
selection.removeAllRanges();
|
|
21647
|
-
selection.addRange(range);
|
|
21648
|
-
pushOut();
|
|
21649
|
-
};
|
|
21650
|
-
return /* @__PURE__ */ import_react4.default.createElement(
|
|
21651
|
-
"div",
|
|
21652
|
-
{
|
|
21653
|
-
ref: boxRef,
|
|
21654
|
-
className: "t-team-sched-prompt-input",
|
|
21655
|
-
contentEditable: !disabled,
|
|
21656
|
-
suppressContentEditableWarning: true,
|
|
21657
|
-
role: "textbox",
|
|
21658
|
-
"aria-multiline": "true",
|
|
21659
|
-
"aria-label": t("sched.promptLabel"),
|
|
21660
|
-
"data-placeholder": t("sched.promptPlaceholder"),
|
|
21661
|
-
"data-empty": "true",
|
|
21662
|
-
onInput: () => {
|
|
21663
|
-
if (!disabled) pushOut();
|
|
21664
|
-
},
|
|
21665
|
-
onPaste,
|
|
21666
|
-
onBlur: () => {
|
|
21667
|
-
if (!disabled) pushOut();
|
|
21668
|
-
},
|
|
21669
|
-
onMouseDownCapture: (event) => {
|
|
21670
|
-
const target = (
|
|
21671
|
-
/** @type {HTMLElement} */
|
|
21672
|
-
event.target
|
|
21673
|
-
);
|
|
21674
|
-
const name = target?.dataset?.remove;
|
|
21675
|
-
if (name === void 0 || disabled) return;
|
|
21676
|
-
event.preventDefault();
|
|
21677
|
-
removeExpert(name);
|
|
21678
|
-
}
|
|
21679
|
-
}
|
|
21680
|
-
);
|
|
21681
|
-
}
|
|
21682
|
-
function ExpertPicker({ t, active, experts, disabled, selected, onPick }) {
|
|
21683
|
-
const [open2, setOpen] = import_react4.default.useState(false);
|
|
21684
|
-
const [query, setQuery] = import_react4.default.useState("");
|
|
21685
|
-
const [index, setIndex] = import_react4.default.useState(0);
|
|
21686
|
-
const wrapRef = import_react4.default.useRef(null);
|
|
21687
|
-
const picked = selected ?? [];
|
|
21688
|
-
import_react4.default.useEffect(() => {
|
|
21689
|
-
if (!open2) return void 0;
|
|
21690
|
-
const onDown = (event) => {
|
|
21691
|
-
const node2 = wrapRef.current;
|
|
21692
|
-
if (node2 !== null && !node2.contains(event.target)) setOpen(false);
|
|
21693
|
-
};
|
|
21694
|
-
document.addEventListener("pointerdown", onDown, true);
|
|
21695
|
-
return () => document.removeEventListener("pointerdown", onDown, true);
|
|
21696
|
-
}, [open2]);
|
|
21697
|
-
const needle = query.trim().toLowerCase();
|
|
21698
|
-
const candidates = (experts ?? []).filter((expert) => matchExpert(expert, active, needle)).slice(0, 50);
|
|
21699
|
-
const pick2 = (expert) => {
|
|
21700
|
-
if (expert === void 0) return;
|
|
21701
|
-
onPick(expert);
|
|
21702
|
-
setOpen(false);
|
|
21703
|
-
setQuery("");
|
|
21704
|
-
setIndex(0);
|
|
21705
|
-
};
|
|
21706
|
-
const onKeyDown = (event) => {
|
|
21707
|
-
if (event.key === "Escape") {
|
|
21708
|
-
event.preventDefault();
|
|
21709
|
-
setOpen(false);
|
|
21710
|
-
return;
|
|
21711
|
-
}
|
|
21712
|
-
if (candidates.length === 0) return;
|
|
21713
|
-
if (event.key === "ArrowDown") {
|
|
21714
|
-
event.preventDefault();
|
|
21715
|
-
setIndex((current) => (current + 1) % candidates.length);
|
|
21716
|
-
} else if (event.key === "ArrowUp") {
|
|
21717
|
-
event.preventDefault();
|
|
21718
|
-
setIndex((current) => (current - 1 + candidates.length) % candidates.length);
|
|
21719
|
-
} else if (event.key === "Enter") {
|
|
21720
|
-
event.preventDefault();
|
|
21721
|
-
pick2(candidates[Math.min(index, candidates.length - 1)]);
|
|
21722
|
-
}
|
|
21723
|
-
};
|
|
21724
|
-
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-expert-pick", ref: wrapRef }, /* @__PURE__ */ import_react4.default.createElement(
|
|
21725
|
-
"button",
|
|
21726
|
-
{
|
|
21727
|
-
type: "button",
|
|
21728
|
-
className: "t-team-chip",
|
|
21729
|
-
"data-active": open2,
|
|
21730
|
-
disabled,
|
|
21731
|
-
"aria-expanded": open2,
|
|
21732
|
-
onClick: () => {
|
|
21733
|
-
setOpen(!open2);
|
|
21734
|
-
setQuery("");
|
|
21735
|
-
setIndex(0);
|
|
21736
|
-
}
|
|
21737
|
-
},
|
|
21738
|
-
"\u{1F9E9} ",
|
|
21739
|
-
t("sched.expertPick")
|
|
21740
|
-
), /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-expert-pick-hint" }, t("sched.expertPickHint")), open2 && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-expert-pick-panel" }, /* @__PURE__ */ import_react4.default.createElement(
|
|
21741
|
-
"input",
|
|
21742
|
-
{
|
|
21743
|
-
className: "t-team-expert-pick-search",
|
|
21744
|
-
value: query,
|
|
21745
|
-
autoFocus: true,
|
|
21746
|
-
spellCheck: false,
|
|
21747
|
-
placeholder: t("sched.expertPickSearch"),
|
|
21748
|
-
"aria-label": t("sched.expertPickSearch"),
|
|
21749
|
-
onChange: (event) => {
|
|
21750
|
-
setQuery(event.target.value);
|
|
21751
|
-
setIndex(0);
|
|
21752
|
-
},
|
|
21753
|
-
onKeyDown
|
|
21754
|
-
}
|
|
21755
|
-
), candidates.length === 0 ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-expert-pick-empty" }, t("sched.expertPickEmpty")) : /* @__PURE__ */ import_react4.default.createElement("ul", { className: "t-team-expert-pick-list", role: "listbox" }, candidates.map((expert, position) => /* @__PURE__ */ import_react4.default.createElement("li", { key: expert.slug }, /* @__PURE__ */ import_react4.default.createElement(
|
|
21756
|
-
"button",
|
|
21757
|
-
{
|
|
21758
|
-
type: "button",
|
|
21759
|
-
role: "option",
|
|
21760
|
-
"aria-selected": position === index,
|
|
21761
|
-
"data-active": position === index,
|
|
21762
|
-
"data-picked": picked.includes(displayName(expert, active)),
|
|
21763
|
-
className: "t-team-expert-pick-item",
|
|
21764
|
-
onMouseEnter: () => setIndex(position),
|
|
21765
|
-
onMouseDown: (event) => event.preventDefault(),
|
|
21766
|
-
onClick: () => pick2(expert)
|
|
21767
|
-
},
|
|
21768
|
-
/* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-expert-pick-name" }, picked.includes(displayName(expert, active)) ? "\u2713 " : "", expert.emoji, " ", displayName(expert, active)),
|
|
21769
|
-
/* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-expert-pick-meta" }, divisionLabel(expert, active))
|
|
21770
|
-
))))));
|
|
21771
|
-
}
|
|
21772
|
-
function SchedulePanel({ t, ctx: hostCtx, remote, getActive }) {
|
|
21773
|
-
const showButton = useShowScheduleButton();
|
|
21774
|
-
const [snapshot, setSnapshot] = import_react4.default.useState(null);
|
|
21775
|
-
const [error62, setError] = import_react4.default.useState("");
|
|
21776
|
-
const [loading, setLoading] = import_react4.default.useState(true);
|
|
21777
|
-
const [busy, setBusy] = import_react4.default.useState(false);
|
|
21778
|
-
const [form, setForm] = import_react4.default.useState(null);
|
|
21779
|
-
const [historyId, setHistoryId] = import_react4.default.useState(null);
|
|
21780
|
-
const [confirmingId, setConfirmingId] = import_react4.default.useState("");
|
|
21781
|
-
const [runningId, setRunningId] = import_react4.default.useState(null);
|
|
21782
|
-
const [experts, setExperts] = import_react4.default.useState([]);
|
|
21783
|
-
const promptEditorRef = import_react4.default.useRef(null);
|
|
21784
|
-
const [extraWorkspaces, setExtraWorkspaces] = import_react4.default.useState([]);
|
|
21785
|
-
const layout = () => hostCtx?.get?.("layout") ?? hostCtx?.layout;
|
|
21786
|
-
const backToConversation = () => layout()?.selectPanel?.(null);
|
|
21787
|
-
const load = import_react4.default.useCallback(async () => {
|
|
21788
|
-
setLoading(true);
|
|
21789
|
-
try {
|
|
21790
|
-
setSnapshot(unwrap(await remote.getSchedule(), "getSchedule"));
|
|
21791
|
-
setError("");
|
|
21792
|
-
} catch (cause) {
|
|
21793
|
-
setError(errorText(cause));
|
|
21794
|
-
} finally {
|
|
21795
|
-
setLoading(false);
|
|
21796
|
-
}
|
|
21797
|
-
}, [remote]);
|
|
21798
|
-
import_react4.default.useEffect(() => {
|
|
21799
|
-
void load();
|
|
21800
|
-
}, [load]);
|
|
21801
|
-
import_react4.default.useEffect(() => {
|
|
21802
|
-
let alive = true;
|
|
21803
|
-
const sync = () => {
|
|
21804
|
-
const current = snapshotOf(remote);
|
|
21805
|
-
if (current === void 0 || !alive) return;
|
|
21806
|
-
setExperts(current.experts.filter((expert) => expert.conflict !== true && current.enabledSet.has(expert.slug)));
|
|
21807
|
-
};
|
|
21808
|
-
const stop = onCatalogLoaded(sync);
|
|
21809
|
-
void (async () => {
|
|
21810
|
-
try {
|
|
21811
|
-
await refresh(remote);
|
|
21812
|
-
sync();
|
|
21813
|
-
} catch (cause) {
|
|
21814
|
-
console.warn("[t-team] \u5B9A\u65F6\u4EFB\u52A1\uFF1A\u8BFB\u53D6\u4E13\u5BB6\u540D\u518C\u5931\u8D25\uFF0C\u300CT\u4E13\u5BB6\u300D\u6311\u9009\u5668\u6682\u4E0D\u53EF\u7528\uFF1A", cause);
|
|
21815
|
-
}
|
|
21816
|
-
})();
|
|
21817
|
-
return () => {
|
|
21818
|
-
alive = false;
|
|
21819
|
-
stop();
|
|
21820
|
-
};
|
|
21821
|
-
}, [remote]);
|
|
21822
|
-
const active = getActive();
|
|
21823
|
-
import_react4.default.useEffect(() => {
|
|
21824
|
-
if (showButton) return;
|
|
21825
|
-
layout()?.selectPanel?.(null);
|
|
21826
|
-
}, [showButton]);
|
|
21827
|
-
const applySnapshot = (next) => {
|
|
21828
|
-
setSnapshot(next);
|
|
21829
|
-
setError("");
|
|
21830
|
-
};
|
|
21831
|
-
function fillExpert(expert) {
|
|
21832
|
-
const editor = promptEditorRef.current;
|
|
21833
|
-
if (editor === null) return;
|
|
21834
|
-
const name = displayName(expert, active);
|
|
21835
|
-
if (mentioned.includes(name)) editor.removeExpert(name);
|
|
21836
|
-
else editor.insertExpert(name);
|
|
21837
|
-
}
|
|
21838
|
-
function rememberWorkspace(workspace) {
|
|
21839
|
-
if (workspace === void 0 || workspace === null) return "";
|
|
21840
|
-
setExtraWorkspaces((current) => current.some((item) => item.id === workspace.id) ? current : [...current, workspace]);
|
|
21841
|
-
return workspace.id;
|
|
21842
|
-
}
|
|
21843
|
-
async function openNewForm() {
|
|
21844
|
-
setBusy(true);
|
|
21845
|
-
let workspaceId = "";
|
|
21846
|
-
try {
|
|
21847
|
-
workspaceId = rememberWorkspace(unwrap(await remote.ensureScheduleWorkspace(""), "ensureScheduleWorkspace")?.workspace);
|
|
21848
|
-
} catch (cause) {
|
|
21849
|
-
setError(errorText(cause));
|
|
21850
|
-
} finally {
|
|
21851
|
-
setBusy(false);
|
|
21852
|
-
}
|
|
21853
|
-
setForm({ ...emptyScheduleForm(), workspaceId });
|
|
21854
|
-
}
|
|
21855
|
-
async function submitForm() {
|
|
21856
|
-
if (form === null || busy) return;
|
|
21857
|
-
setError("");
|
|
21858
|
-
if (form.title.trim() === "" || form.prompt.trim() === "" || form.cron.trim() === "") {
|
|
21859
|
-
setError(t("sched.invalidForm"));
|
|
21860
|
-
return;
|
|
21861
|
-
}
|
|
21862
|
-
setBusy(true);
|
|
21863
|
-
try {
|
|
21864
|
-
let workspaceId = form.workspaceId;
|
|
21865
|
-
if (workspaceId === CUSTOM_WORKSPACE) {
|
|
21866
|
-
const dir = form.customDir.trim();
|
|
21867
|
-
if (dir === "") {
|
|
21868
|
-
setError(t("sched.workspaceCustomEmpty"));
|
|
21869
|
-
return;
|
|
21870
|
-
}
|
|
21871
|
-
workspaceId = rememberWorkspace(unwrap(await remote.ensureScheduleWorkspace(dir), "ensureScheduleWorkspace")?.workspace);
|
|
21872
|
-
}
|
|
21873
|
-
const payload = {
|
|
21874
|
-
title: form.title.trim(),
|
|
21875
|
-
prompt: form.prompt,
|
|
21876
|
-
cron: form.cron.trim(),
|
|
21877
|
-
enabled: form.enabled,
|
|
21878
|
-
// 空串 = 不绑定工作区(显式解绑也走这个值,宿主认得)。
|
|
21879
|
-
workspaceId: workspaceId === void 0 || workspaceId === null ? "" : workspaceId,
|
|
21880
|
-
// 把当前绑定的目录也一起带上:将来工作区被删时,面板行内的「重建工作区」才能按这个路径
|
|
21881
|
-
// 把任务拉回来(老数据没有这个字段时由宿主用空串兜底)。
|
|
21882
|
-
workspacePath: selectedWorkspacePath
|
|
21883
|
-
};
|
|
21884
|
-
const next = form.editingId === null ? unwrap(await remote.createScheduleItem(payload), "createScheduleItem") : unwrap(await remote.updateScheduleItem(form.editingId, payload), "updateScheduleItem");
|
|
21885
|
-
applySnapshot(next);
|
|
21886
|
-
setForm(null);
|
|
21887
|
-
} catch (cause) {
|
|
21888
|
-
setError(errorText(cause));
|
|
21889
|
-
} finally {
|
|
21890
|
-
setBusy(false);
|
|
21891
|
-
}
|
|
21892
|
-
}
|
|
21893
|
-
async function removeItem(id) {
|
|
21894
|
-
if (confirmingId !== id) {
|
|
21895
|
-
setConfirmingId(id);
|
|
21896
|
-
return;
|
|
21897
|
-
}
|
|
21898
|
-
setConfirmingId("");
|
|
21899
|
-
setBusy(true);
|
|
21900
|
-
try {
|
|
21901
|
-
applySnapshot(unwrap(await remote.deleteScheduleItem(id), "deleteScheduleItem"));
|
|
21902
|
-
} catch (cause) {
|
|
21903
|
-
setError(errorText(cause));
|
|
21904
|
-
} finally {
|
|
21905
|
-
setBusy(false);
|
|
21906
|
-
}
|
|
21907
|
-
}
|
|
21908
|
-
async function runItem(id) {
|
|
21909
|
-
setRunningId(id);
|
|
21910
|
-
try {
|
|
21911
|
-
applySnapshot(unwrap(await remote.runScheduleItem(id), "runScheduleItem"));
|
|
21912
|
-
const startedAt = Date.now();
|
|
21913
|
-
while (Date.now() - startedAt < 6e3) {
|
|
21914
|
-
await new Promise((r) => setTimeout(r, 600));
|
|
21915
|
-
try {
|
|
21916
|
-
const next = unwrap(await remote.getSchedule(), "getSchedule");
|
|
21917
|
-
if (next?.items?.find?.((it) => it.id === id) === void 0) break;
|
|
21918
|
-
applySnapshot(next);
|
|
21919
|
-
const live = next?.running ?? [];
|
|
21920
|
-
if (!live.includes(id)) break;
|
|
21921
|
-
} catch {
|
|
21922
|
-
}
|
|
21923
|
-
}
|
|
21924
|
-
} catch (cause) {
|
|
21925
|
-
setError(errorText(cause));
|
|
21926
|
-
} finally {
|
|
21927
|
-
setRunningId(null);
|
|
21928
|
-
}
|
|
21929
|
-
}
|
|
21930
|
-
const items = snapshot?.items ?? [];
|
|
21931
|
-
const workspaces = snapshot?.workspaces ?? [];
|
|
21932
|
-
const allWorkspaces = [...workspaces];
|
|
21933
|
-
for (const workspace of extraWorkspaces) {
|
|
21934
|
-
if (!allWorkspaces.some((item) => item.id === workspace.id)) allWorkspaces.push(workspace);
|
|
21935
|
-
}
|
|
21936
|
-
const workspaceTitle = (id) => allWorkspaces.find((workspace) => workspace.id === id)?.title ?? id;
|
|
21937
|
-
const isWorkspaceMissing = (item) => {
|
|
21938
|
-
if (item.workspaceId === void 0 || item.workspaceId === "") return false;
|
|
21939
|
-
return !allWorkspaces.some((workspace) => workspace.id === item.workspaceId);
|
|
21940
|
-
};
|
|
21941
|
-
const rowMeta = (item) => {
|
|
21942
|
-
const parts = [];
|
|
21943
|
-
if (item.workspaceId !== void 0) parts.push(`${t("sched.workspace")}: ${workspaceTitle(item.workspaceId)}`);
|
|
21944
|
-
if (item.enabled !== true) parts.push(t("sched.disabledTag"));
|
|
21945
|
-
parts.push(`${t("sched.lastRun")}: ${scheduleLastRun(t, item)}`);
|
|
21946
|
-
return parts.join(" \xB7 ");
|
|
21947
|
-
};
|
|
21948
|
-
const disabled = busy || loading || !showButton;
|
|
21949
|
-
const mentioned = form === null ? [] : collectExpertMentions(form.prompt, experts, active);
|
|
21950
|
-
const selectedWorkspacePath = form === null ? "" : allWorkspaces.find((workspace) => workspace.id === form.workspaceId)?.path ?? "";
|
|
21951
|
-
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-head" }, /* @__PURE__ */ import_react4.default.createElement("div", null, /* @__PURE__ */ import_react4.default.createElement("h2", { className: "t-team-sched-title" }, t("sched.title")), /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-intro" }, t("sched.intro"))), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-actions" }, /* @__PURE__ */ import_react4.default.createElement("button", { type: "button", className: "t-team-sched-btn", disabled: loading, onClick: () => void load() }, t("sched.refresh")), /* @__PURE__ */ import_react4.default.createElement("button", { type: "button", className: "t-team-sched-btn", onClick: backToConversation }, t("sched.back")))), !showButton && /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-note" }, t("sched.off")), snapshot !== null && snapshot.capabilities?.agents !== true && /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-note" }, t("sched.noAgents")), error62 !== "" && /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-error", role: "alert" }, t("sched.error"), " ", error62, /* @__PURE__ */ import_react4.default.createElement("button", { type: "button", className: "t-team-sched-btn", onClick: () => void load() }, t("sched.retry"))), loading && /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-intro" }, t("sched.loading")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-body" }, !loading && items.length === 0 && error62 === "" && /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-intro" }, t("sched.empty")), /* @__PURE__ */ import_react4.default.createElement("ul", { className: "t-team-sched-list" }, items.map((item) => /* @__PURE__ */ import_react4.default.createElement("li", { key: item.id, className: "t-team-sched-row" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-rowMain" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-sched-rowTitle" }, item.title), /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-sched-rowCron" }, item.cron), /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-sched-rowMeta" }, rowMeta(item)), isWorkspaceMissing(item) && // 任务绑的工作区在 registry 查不到:执行路径会按 task.workspacePath 自动
|
|
21952
|
-
// mkdir + create 兜底,面板这里只挂一行轻量提示——不要按钮、不要输入框,
|
|
21953
|
-
// 不替用户做决定,恢复就是自动的。
|
|
21954
|
-
/* @__PURE__ */ import_react4.default.createElement("small", { className: "t-team-sched-rowNote" }, typeof item.workspacePath === "string" && item.workspacePath !== "" ? t("sched.workspaceAutoRecoverHint", { path: item.workspacePath }) : t("sched.workspaceMissingHintNoPath")), item.runs?.length > 0 && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
|
|
21955
|
-
"button",
|
|
21956
|
-
{
|
|
21957
|
-
type: "button",
|
|
21958
|
-
className: "t-team-sched-runsToggle",
|
|
21959
|
-
"aria-expanded": historyId === item.id,
|
|
21960
|
-
onClick: () => setHistoryId(historyId === item.id ? null : item.id)
|
|
21961
|
-
},
|
|
21962
|
-
t("sched.runHistory", { count: item.runs?.length ?? 0 })
|
|
21963
|
-
), historyId === item.id && /* @__PURE__ */ import_react4.default.createElement("ul", { className: "t-team-sched-runs" }, [...item.runs ?? []].reverse().map((run, index) => /* @__PURE__ */ import_react4.default.createElement("li", { key: index, className: "t-team-sched-run" }, /* @__PURE__ */ import_react4.default.createElement("span", null, new Date(run.at).toLocaleString()), run.ok === true ? /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.runOk")) : /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-sched-runFail" }, t("sched.runFail"), ": ", run.error ?? ""), run.sessionId !== void 0 && /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-sched-runSession" }, run.sessionId)))))), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-rowActions" }, /* @__PURE__ */ import_react4.default.createElement(
|
|
21964
|
-
"button",
|
|
21965
|
-
{
|
|
21966
|
-
type: "button",
|
|
21967
|
-
className: "t-team-sched-btn",
|
|
21968
|
-
disabled: disabled || runningId === item.id || (snapshot?.running ?? []).includes(item.id),
|
|
21969
|
-
onClick: () => void runItem(item.id)
|
|
21970
|
-
},
|
|
21971
|
-
runningId === item.id || (snapshot?.running ?? []).includes(item.id) ? t("sched.running") : t("sched.runNow")
|
|
21972
|
-
), /* @__PURE__ */ import_react4.default.createElement(
|
|
21973
|
-
"button",
|
|
21974
|
-
{
|
|
21975
|
-
type: "button",
|
|
21976
|
-
className: "t-team-sched-btn",
|
|
21977
|
-
disabled,
|
|
21978
|
-
onClick: () => setForm({
|
|
21979
|
-
editingId: item.id,
|
|
21980
|
-
title: item.title,
|
|
21981
|
-
prompt: item.prompt,
|
|
21982
|
-
cron: item.cron,
|
|
21983
|
-
enabled: item.enabled === true,
|
|
21984
|
-
workspaceId: item.workspaceId ?? "",
|
|
21985
|
-
customDir: "",
|
|
21986
|
-
// 编辑时把记录的目录带进来:跟 workspaceId 一对,没手动改过就不会丢。
|
|
21987
|
-
workspacePath: item.workspacePath ?? ""
|
|
21988
|
-
})
|
|
21989
|
-
},
|
|
21990
|
-
t("sched.edit")
|
|
21991
|
-
), /* @__PURE__ */ import_react4.default.createElement("button", { type: "button", className: confirmingId === item.id ? "t-team-sched-btn t-team-sched-btn-danger" : "t-team-sched-btn t-team-sched-btn-danger", disabled, onClick: () => void removeItem(item.id) }, confirmingId === item.id ? t("sched.deleteConfirm") : t("sched.delete")))))), form === null ? /* @__PURE__ */ import_react4.default.createElement("button", { type: "button", className: "t-team-sched-btn t-team-sched-btn-primary", disabled, onClick: () => void openNewForm() }, t("sched.new")) : /* @__PURE__ */ import_react4.default.createElement(
|
|
21992
|
-
"form",
|
|
21993
|
-
{
|
|
21994
|
-
className: "t-team-sched-form",
|
|
21995
|
-
onSubmit: (event) => {
|
|
21996
|
-
event.preventDefault();
|
|
21997
|
-
void submitForm();
|
|
21998
|
-
}
|
|
21999
|
-
},
|
|
22000
|
-
/* @__PURE__ */ import_react4.default.createElement("h3", { className: "t-team-sched-formTitle" }, form.editingId === null ? t("sched.new") : t("sched.edit")),
|
|
22001
|
-
/* @__PURE__ */ import_react4.default.createElement("label", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.titleLabel")), /* @__PURE__ */ import_react4.default.createElement(
|
|
22002
|
-
"input",
|
|
22003
|
-
{
|
|
22004
|
-
value: form.title,
|
|
22005
|
-
disabled: busy,
|
|
22006
|
-
placeholder: t("sched.titlePlaceholder"),
|
|
22007
|
-
onChange: (event) => setForm({ ...form, title: event.target.value })
|
|
22008
|
-
}
|
|
22009
|
-
)),
|
|
22010
|
-
/* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.promptLabel")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-promptbox" }, /* @__PURE__ */ import_react4.default.createElement(
|
|
22011
|
-
PromptEditor,
|
|
22012
|
-
{
|
|
22013
|
-
editorRef: promptEditorRef,
|
|
22014
|
-
t,
|
|
22015
|
-
active,
|
|
22016
|
-
experts,
|
|
22017
|
-
value: form.prompt,
|
|
22018
|
-
disabled: busy,
|
|
22019
|
-
onChange: (prompt) => setForm((current) => current === null ? current : { ...current, prompt })
|
|
22020
|
-
}
|
|
22021
|
-
)), /* @__PURE__ */ import_react4.default.createElement(
|
|
22022
|
-
ExpertPicker,
|
|
22023
|
-
{
|
|
22024
|
-
t,
|
|
22025
|
-
active,
|
|
22026
|
-
experts,
|
|
22027
|
-
disabled: busy,
|
|
22028
|
-
selected: mentioned,
|
|
22029
|
-
onPick: fillExpert
|
|
22030
|
-
}
|
|
22031
|
-
), mentioned.length > 0 && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-expert-pick-hint" }, mentioned.length === 1 ? t("sched.expertInvokeHint", { name: mentioned[0] }) : t("sched.expertInvokeManyHint", { names: mentioned.join(t("sched.listSep")) }))),
|
|
22032
|
-
/* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.cronLabel")), /* @__PURE__ */ import_react4.default.createElement(CronPicker, { t, remote, value: form.cron, disabled: busy, onChange: (cron) => setForm((current) => current === null ? current : { ...current, cron }) }), /* @__PURE__ */ import_react4.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.cronHint"))),
|
|
22033
|
-
/* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-field" }, /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.workspace")), /* @__PURE__ */ import_react4.default.createElement(
|
|
22034
|
-
"select",
|
|
22035
|
-
{
|
|
22036
|
-
value: form.workspaceId,
|
|
22037
|
-
disabled: busy,
|
|
22038
|
-
onChange: (event) => setForm({ ...form, workspaceId: event.target.value })
|
|
22039
|
-
},
|
|
22040
|
-
/* @__PURE__ */ import_react4.default.createElement("option", { value: "" }, t("sched.workspaceNone")),
|
|
22041
|
-
allWorkspaces.map((workspace) => /* @__PURE__ */ import_react4.default.createElement("option", { key: workspace.id, value: workspace.id }, workspace.title)),
|
|
22042
|
-
form.workspaceId !== "" && form.workspaceId !== CUSTOM_WORKSPACE && !allWorkspaces.some((workspace) => workspace.id === form.workspaceId) && /* @__PURE__ */ import_react4.default.createElement("option", { value: form.workspaceId }, form.workspaceId),
|
|
22043
|
-
/* @__PURE__ */ import_react4.default.createElement("option", { value: CUSTOM_WORKSPACE }, t("sched.workspaceCustom"))
|
|
22044
|
-
), form.workspaceId === CUSTOM_WORKSPACE ? /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
|
|
22045
|
-
"input",
|
|
22046
|
-
{
|
|
22047
|
-
value: form.customDir,
|
|
22048
|
-
disabled: busy,
|
|
22049
|
-
placeholder: t("sched.workspaceCustomPlaceholder"),
|
|
22050
|
-
onChange: (event) => setForm({ ...form, customDir: event.target.value })
|
|
22051
|
-
}
|
|
22052
|
-
), /* @__PURE__ */ import_react4.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspaceCustomHint"))) : /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspaceHint")), selectedWorkspacePath !== "" && /* @__PURE__ */ import_react4.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.workspacePath", { path: selectedWorkspacePath })))),
|
|
22053
|
-
/* @__PURE__ */ import_react4.default.createElement("label", { className: "t-team-sched-checkbox" }, /* @__PURE__ */ import_react4.default.createElement(
|
|
22054
|
-
"input",
|
|
22055
|
-
{
|
|
22056
|
-
type: "checkbox",
|
|
22057
|
-
checked: form.enabled,
|
|
22058
|
-
disabled: busy,
|
|
22059
|
-
onChange: (event) => setForm({ ...form, enabled: event.target.checked })
|
|
22060
|
-
}
|
|
22061
|
-
), /* @__PURE__ */ import_react4.default.createElement("span", null, t("sched.enabledLabel")), /* @__PURE__ */ import_react4.default.createElement("small", { className: "t-team-sched-hint" }, t("sched.enabledHint"))),
|
|
22062
|
-
/* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-sched-formActions" }, /* @__PURE__ */ import_react4.default.createElement("button", { type: "submit", className: "t-team-sched-btn t-team-sched-btn-primary", disabled: busy }, busy ? t("sched.saving") : t("sched.save")), /* @__PURE__ */ import_react4.default.createElement("button", { type: "button", className: "t-team-sched-btn", disabled: busy, onClick: () => setForm(null) }, t("sched.cancel")))
|
|
22063
|
-
), /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-tip" }, t("sched.tip")), snapshot !== null && snapshot.file !== "" && /* @__PURE__ */ import_react4.default.createElement("p", { className: "t-team-sched-file" }, t("sched.file", { path: snapshot.file }))));
|
|
22064
|
-
}
|
|
22065
|
-
function ScheduleGlyph({ size = 16 }) {
|
|
22066
|
-
return /* @__PURE__ */ import_react4.default.createElement(
|
|
22067
|
-
"svg",
|
|
22068
|
-
{
|
|
22069
|
-
className: "t-team-schedule-glyph",
|
|
22070
|
-
width: size,
|
|
22071
|
-
height: size,
|
|
22072
|
-
viewBox: "0 0 16 16",
|
|
22073
|
-
fill: "none",
|
|
22074
|
-
stroke: "currentColor",
|
|
22075
|
-
strokeWidth: "1.4",
|
|
22076
|
-
strokeLinecap: "round",
|
|
22077
|
-
strokeLinejoin: "round",
|
|
22078
|
-
"aria-hidden": "true",
|
|
22079
|
-
focusable: "false"
|
|
22080
|
-
},
|
|
22081
|
-
/* @__PURE__ */ import_react4.default.createElement("rect", { x: "2.2", y: "3.4", width: "11.6", height: "10.4", rx: "2.4" }),
|
|
22082
|
-
/* @__PURE__ */ import_react4.default.createElement("path", { d: "M2.2 6.6h11.6" }),
|
|
22083
|
-
/* @__PURE__ */ import_react4.default.createElement("path", { d: "M5.6 2.2v2.4M10.4 2.2v2.4" }),
|
|
22084
|
-
/* @__PURE__ */ import_react4.default.createElement("path", { d: "M6.1 9.7l1.3 1.3 2.5-2.7" })
|
|
22085
|
-
);
|
|
22086
|
-
}
|
|
22087
|
-
|
|
22088
20909
|
// src/client/settings.jsx
|
|
22089
|
-
var
|
|
20910
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
22090
20911
|
|
|
22091
20912
|
// src/client/tabs.jsx
|
|
22092
|
-
var
|
|
20913
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
22093
20914
|
function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
22094
|
-
const [key, setKey] =
|
|
22095
|
-
const [label, setLabel] =
|
|
22096
|
-
const [editing, setEditing] =
|
|
22097
|
-
const [pendingDelete, setPendingDelete] =
|
|
22098
|
-
const [error62, setError] =
|
|
22099
|
-
const [busy, setBusy] =
|
|
20915
|
+
const [key, setKey] = import_react4.default.useState("");
|
|
20916
|
+
const [label, setLabel] = import_react4.default.useState("");
|
|
20917
|
+
const [editing, setEditing] = import_react4.default.useState(null);
|
|
20918
|
+
const [pendingDelete, setPendingDelete] = import_react4.default.useState("");
|
|
20919
|
+
const [error62, setError] = import_react4.default.useState("");
|
|
20920
|
+
const [busy, setBusy] = import_react4.default.useState(false);
|
|
22100
20921
|
const list = categories ?? [];
|
|
22101
20922
|
const mine = list.filter((item) => !item.official);
|
|
22102
20923
|
const official = list.filter((item) => item.official);
|
|
@@ -22116,7 +20937,7 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22116
20937
|
setBusy(false);
|
|
22117
20938
|
}
|
|
22118
20939
|
}
|
|
22119
|
-
const row = (item) => /* @__PURE__ */
|
|
20940
|
+
const row = (item) => /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-cat-row", key: item.key }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-cat-name", title: item.label }, item.label), /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-badge", "data-tone": item.official ? void 0 : "custom" }, item.official ? t("cat.officialBadge") : t("cat.customBadge")), /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-cat-key", title: item.key }, item.key), /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-cat-count" }, t("cat.count", { count: item.count, custom: item.customCount })), !item.official && /* @__PURE__ */ import_react4.default.createElement("span", { className: "t-team-cat-actions" }, editing !== null && editing.key === item.key ? /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
|
|
22120
20941
|
"input",
|
|
22121
20942
|
{
|
|
22122
20943
|
className: "t-team-input",
|
|
@@ -22124,7 +20945,7 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22124
20945
|
placeholder: t("cat.label"),
|
|
22125
20946
|
onChange: (event) => setEditing({ key: item.key, label: event.target.value })
|
|
22126
20947
|
}
|
|
22127
|
-
), /* @__PURE__ */
|
|
20948
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
|
22128
20949
|
"button",
|
|
22129
20950
|
{
|
|
22130
20951
|
className: "t-team-chip",
|
|
@@ -22133,7 +20954,7 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22133
20954
|
onClick: () => void run(() => remote.updateCategory(item.key, editing.label.trim()))
|
|
22134
20955
|
},
|
|
22135
20956
|
t("cat.save")
|
|
22136
|
-
), /* @__PURE__ */
|
|
20957
|
+
), /* @__PURE__ */ import_react4.default.createElement("button", { className: "t-team-chip", type: "button", disabled: busy, onClick: () => setEditing(null) }, t("custom.cancel"))) : /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
|
|
22137
20958
|
"button",
|
|
22138
20959
|
{
|
|
22139
20960
|
className: "t-team-chip",
|
|
@@ -22142,7 +20963,7 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22142
20963
|
onClick: () => setEditing({ key: item.key, label: item.label })
|
|
22143
20964
|
},
|
|
22144
20965
|
t("cat.rename")
|
|
22145
|
-
), pendingDelete === item.key ? /* @__PURE__ */
|
|
20966
|
+
), pendingDelete === item.key ? /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(
|
|
22146
20967
|
"button",
|
|
22147
20968
|
{
|
|
22148
20969
|
className: "t-team-chip",
|
|
@@ -22152,8 +20973,8 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22152
20973
|
onClick: () => void run(() => remote.deleteCategory(item.key))
|
|
22153
20974
|
},
|
|
22154
20975
|
t("cat.confirmDelete")
|
|
22155
|
-
), /* @__PURE__ */
|
|
22156
|
-
return /* @__PURE__ */
|
|
20976
|
+
), /* @__PURE__ */ import_react4.default.createElement("button", { className: "t-team-chip", type: "button", disabled: busy, onClick: () => setPendingDelete("") }, t("custom.cancel"))) : /* @__PURE__ */ import_react4.default.createElement("button", { className: "t-team-chip", type: "button", disabled: busy, onClick: () => setPendingDelete(item.key) }, t("cat.delete")))));
|
|
20977
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-tabbody" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-note" }, t("cat.hint")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-bar" }, /* @__PURE__ */ import_react4.default.createElement(
|
|
22157
20978
|
"input",
|
|
22158
20979
|
{
|
|
22159
20980
|
className: "t-team-input",
|
|
@@ -22162,7 +20983,7 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22162
20983
|
value: key,
|
|
22163
20984
|
onChange: (event) => setKey(event.target.value)
|
|
22164
20985
|
}
|
|
22165
|
-
), /* @__PURE__ */
|
|
20986
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
|
22166
20987
|
"input",
|
|
22167
20988
|
{
|
|
22168
20989
|
className: "t-team-input",
|
|
@@ -22170,7 +20991,7 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22170
20991
|
value: label,
|
|
22171
20992
|
onChange: (event) => setLabel(event.target.value)
|
|
22172
20993
|
}
|
|
22173
|
-
), /* @__PURE__ */
|
|
20994
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
|
22174
20995
|
"button",
|
|
22175
20996
|
{
|
|
22176
20997
|
className: "t-team-chip",
|
|
@@ -22180,22 +21001,22 @@ function CategoriesTab({ t, remote, categories, onChanged }) {
|
|
|
22180
21001
|
onClick: () => void run(() => remote.createCategory(key.trim(), label.trim()))
|
|
22181
21002
|
},
|
|
22182
21003
|
t("cat.create")
|
|
22183
|
-
)), error62 !== "" && /* @__PURE__ */
|
|
21004
|
+
)), error62 !== "" && /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-error" }, error62), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-section-head" }, t("cat.mine")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-cat-list" }, mine.length === 0 ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-cat-empty" }, t("cat.empty")) : mine.map(row)), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-section-head" }, t("cat.official")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-meta" }, t("cat.officialNote")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "t-team-cat-list", "data-scroll": "true" }, official.map(row)));
|
|
22184
21005
|
}
|
|
22185
21006
|
|
|
22186
21007
|
// src/client/settings.jsx
|
|
22187
21008
|
function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
22188
|
-
const [snapshot, setSnapshot] =
|
|
22189
|
-
const [query, setQuery] =
|
|
22190
|
-
const [division, setDivision] =
|
|
22191
|
-
const [status, setStatus] =
|
|
22192
|
-
const [error62, setError] =
|
|
22193
|
-
const [busy, setBusy] =
|
|
22194
|
-
const [promptView, setPromptView] =
|
|
22195
|
-
const [editor, setEditor] =
|
|
22196
|
-
const [pendingDelete, setPendingDelete] =
|
|
22197
|
-
const [tab, setTab] =
|
|
22198
|
-
const reload =
|
|
21009
|
+
const [snapshot, setSnapshot] = import_react5.default.useState(() => snapshotOf(remote) ?? null);
|
|
21010
|
+
const [query, setQuery] = import_react5.default.useState("");
|
|
21011
|
+
const [division, setDivision] = import_react5.default.useState("");
|
|
21012
|
+
const [status, setStatus] = import_react5.default.useState("");
|
|
21013
|
+
const [error62, setError] = import_react5.default.useState("");
|
|
21014
|
+
const [busy, setBusy] = import_react5.default.useState(false);
|
|
21015
|
+
const [promptView, setPromptView] = import_react5.default.useState(null);
|
|
21016
|
+
const [editor, setEditor] = import_react5.default.useState(null);
|
|
21017
|
+
const [pendingDelete, setPendingDelete] = import_react5.default.useState("");
|
|
21018
|
+
const [tab, setTab] = import_react5.default.useState(initialTab ?? "experts");
|
|
21019
|
+
const reload = import_react5.default.useCallback(async (force) => {
|
|
22199
21020
|
try {
|
|
22200
21021
|
const next = await refresh(remote, force);
|
|
22201
21022
|
setSnapshot({ ...next });
|
|
@@ -22206,7 +21027,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22206
21027
|
return void 0;
|
|
22207
21028
|
}
|
|
22208
21029
|
}, [remote]);
|
|
22209
|
-
|
|
21030
|
+
import_react5.default.useEffect(() => {
|
|
22210
21031
|
let alive = true;
|
|
22211
21032
|
(async () => {
|
|
22212
21033
|
const next = await reload(false);
|
|
@@ -22231,7 +21052,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22231
21052
|
});
|
|
22232
21053
|
}
|
|
22233
21054
|
}
|
|
22234
|
-
|
|
21055
|
+
import_react5.default.useEffect(() => {
|
|
22235
21056
|
if (promptView === null) return void 0;
|
|
22236
21057
|
const onKey = (event) => {
|
|
22237
21058
|
if (event.key === "Escape") setPromptView(null);
|
|
@@ -22387,25 +21208,23 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22387
21208
|
setBusy(false);
|
|
22388
21209
|
}
|
|
22389
21210
|
}
|
|
22390
|
-
const [
|
|
22391
|
-
const [
|
|
22392
|
-
const [
|
|
22393
|
-
const
|
|
22394
|
-
|
|
22395
|
-
import_react6.default.useEffect(() => {
|
|
21211
|
+
const [showActivePulse, setShowActivePulseState] = import_react5.default.useState(true);
|
|
21212
|
+
const [uiPrefsError, setUiPrefsError] = import_react5.default.useState("");
|
|
21213
|
+
const [uiPrefsWriteError, setUiPrefsWriteError] = import_react5.default.useState("");
|
|
21214
|
+
const uiPrefQueue = import_react5.default.useRef(Promise.resolve());
|
|
21215
|
+
import_react5.default.useEffect(() => {
|
|
22396
21216
|
let alive = true;
|
|
22397
21217
|
void (async () => {
|
|
22398
21218
|
try {
|
|
22399
21219
|
const data = unwrap(await remote.getUiPrefs(), "getUiPrefs");
|
|
22400
21220
|
if (!alive) return;
|
|
22401
|
-
if (typeof data?.
|
|
21221
|
+
if (typeof data?.showActivePulse !== "boolean") {
|
|
22402
21222
|
setUiPrefsError(t("settings.uiPrefsUnreadable"));
|
|
22403
21223
|
return;
|
|
22404
21224
|
}
|
|
22405
21225
|
setUiPrefsError("");
|
|
22406
|
-
setShowScheduleButtonState(data.showScheduleButton);
|
|
22407
21226
|
setShowActivePulseState(data.showActivePulse);
|
|
22408
|
-
setUiPrefs({
|
|
21227
|
+
setUiPrefs({ showActivePulse: data.showActivePulse });
|
|
22409
21228
|
} catch (cause) {
|
|
22410
21229
|
console.error("[t-team] \u754C\u9762\u504F\u597D\u8BFB\u53D6\u5931\u8D25\uFF0C\u6682\u6309\u9ED8\u8BA4\u503C\u5904\u7406\uFF1A", cause);
|
|
22411
21230
|
if (alive) setUiPrefsError(cause instanceof Error ? cause.message : String(cause));
|
|
@@ -22416,7 +21235,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22416
21235
|
};
|
|
22417
21236
|
}, [remote]);
|
|
22418
21237
|
if (snapshot === null) {
|
|
22419
|
-
return /* @__PURE__ */
|
|
21238
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-settings" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-title" }, t("settings.title")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-meta" }, t("settings.loading")), error62 !== "" && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-error" }, t("settings.loadFailed", { detail: error62 })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-row" }, /* @__PURE__ */ import_react5.default.createElement("button", { className: "t-team-chip", type: "button", onClick: () => void reload(true) }, t("settings.retry")))));
|
|
22420
21239
|
}
|
|
22421
21240
|
async function writeUiPref(patch, rollback) {
|
|
22422
21241
|
setUiPrefs(patch);
|
|
@@ -22424,12 +21243,10 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22424
21243
|
try {
|
|
22425
21244
|
const next = unwrap(await remote.setUiPrefs(patch), "setUiPrefs");
|
|
22426
21245
|
setUiPrefs(next);
|
|
22427
|
-
setShowScheduleButtonState(next.showScheduleButton);
|
|
22428
21246
|
setShowActivePulseState(next.showActivePulse);
|
|
22429
21247
|
setUiPrefsWriteError("");
|
|
22430
21248
|
} catch (cause) {
|
|
22431
21249
|
setUiPrefs(rollback);
|
|
22432
|
-
setShowScheduleButtonState(rollback.showScheduleButton ?? showScheduleButton);
|
|
22433
21250
|
setShowActivePulseState(rollback.showActivePulse ?? showActivePulse);
|
|
22434
21251
|
setUiPrefsWriteError(cause instanceof Error ? cause.message : String(cause));
|
|
22435
21252
|
}
|
|
@@ -22438,27 +21255,12 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22438
21255
|
});
|
|
22439
21256
|
await run;
|
|
22440
21257
|
}
|
|
22441
|
-
async function setShowScheduleButton(next) {
|
|
22442
|
-
setShowScheduleButtonState(next);
|
|
22443
|
-
await writeUiPref({ showScheduleButton: next }, { showScheduleButton: !next });
|
|
22444
|
-
}
|
|
22445
21258
|
async function setShowActivePulse(next) {
|
|
22446
21259
|
setShowActivePulseState(next);
|
|
22447
21260
|
await writeUiPref({ showActivePulse: next }, { showActivePulse: !next });
|
|
22448
21261
|
}
|
|
22449
21262
|
const enabledCount = snapshot.enabled.length;
|
|
22450
|
-
return /* @__PURE__ */
|
|
22451
|
-
"button",
|
|
22452
|
-
{
|
|
22453
|
-
className: "t-team-switch",
|
|
22454
|
-
type: "button",
|
|
22455
|
-
role: "switch",
|
|
22456
|
-
"aria-checked": showScheduleButton,
|
|
22457
|
-
"data-on": showScheduleButton,
|
|
22458
|
-
onClick: () => void setShowScheduleButton(!showScheduleButton)
|
|
22459
|
-
},
|
|
22460
|
-
/* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-switch-knob" })
|
|
22461
|
-
)), /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showScheduleButtonHint")), uiPrefsError !== "" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-error" }, t("settings.uiPrefsUnreadable"), "\uFF1A", uiPrefsError), uiPrefsWriteError !== "" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-error" }, t("settings.uiPrefsWriteFailed"), "\uFF1A", uiPrefsWriteError)), /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-setting-row" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-setting-head" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-setting-name" }, t("settings.showActivePulse")), /* @__PURE__ */ import_react6.default.createElement(
|
|
21263
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-settings" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-head" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-title" }, t("settings.title")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-meta" }, t("settings.enabledCount", { enabled: enabledCount, total: experts.length }), " \xB7 v", CLIENT_BUILD_VERSION)), (uiPrefsError !== "" || uiPrefsWriteError !== "") && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-setting-row" }, uiPrefsError !== "" && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-error" }, t("settings.uiPrefsUnreadable"), "\uFF1A", uiPrefsError), uiPrefsWriteError !== "" && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-error" }, t("settings.uiPrefsWriteFailed"), "\uFF1A", uiPrefsWriteError)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-setting-row" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-setting-head" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "t-team-setting-name" }, t("settings.showActivePulse")), /* @__PURE__ */ import_react5.default.createElement(
|
|
22462
21264
|
"button",
|
|
22463
21265
|
{
|
|
22464
21266
|
className: "t-team-switch",
|
|
@@ -22468,8 +21270,8 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22468
21270
|
"data-on": showActivePulse,
|
|
22469
21271
|
onClick: () => void setShowActivePulse(!showActivePulse)
|
|
22470
21272
|
},
|
|
22471
|
-
/* @__PURE__ */
|
|
22472
|
-
)), /* @__PURE__ */
|
|
21273
|
+
/* @__PURE__ */ import_react5.default.createElement("span", { className: "t-team-switch-knob" })
|
|
21274
|
+
)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-setting-hint" }, t("settings.showActivePulseHint"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-tabs", role: "tablist" }, [["experts", "tab.experts"], ["categories", "tab.categories"]].map(([key, label]) => /* @__PURE__ */ import_react5.default.createElement(
|
|
22473
21275
|
"button",
|
|
22474
21276
|
{
|
|
22475
21277
|
className: "t-team-tab",
|
|
@@ -22481,7 +21283,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22481
21283
|
onClick: () => setTab(key)
|
|
22482
21284
|
},
|
|
22483
21285
|
t(label)
|
|
22484
|
-
))), /* @__PURE__ */
|
|
21286
|
+
))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-tabbody", hidden: tab !== "categories" }, /* @__PURE__ */ import_react5.default.createElement(SectionBoundary, { t, reloadKey: tab }, /* @__PURE__ */ import_react5.default.createElement(CategoriesTab, { t, remote, categories, onChanged: () => reload(true) }))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-tabbody", hidden: tab !== "experts" }, /* @__PURE__ */ import_react5.default.createElement(SectionBoundary, { t, reloadKey: tab }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-note" }, t("roster.expertsHint")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-bar" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
22485
21287
|
"input",
|
|
22486
21288
|
{
|
|
22487
21289
|
className: "t-team-input",
|
|
@@ -22489,7 +21291,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22489
21291
|
value: query,
|
|
22490
21292
|
onChange: (event) => setQuery(event.target.value)
|
|
22491
21293
|
}
|
|
22492
|
-
), /* @__PURE__ */
|
|
21294
|
+
), /* @__PURE__ */ import_react5.default.createElement(
|
|
22493
21295
|
"select",
|
|
22494
21296
|
{
|
|
22495
21297
|
className: "t-team-select",
|
|
@@ -22498,12 +21300,12 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22498
21300
|
value: division,
|
|
22499
21301
|
onChange: (event) => setDivision(event.target.value)
|
|
22500
21302
|
},
|
|
22501
|
-
/* @__PURE__ */
|
|
21303
|
+
/* @__PURE__ */ import_react5.default.createElement("option", { value: "" }, t("filter.allDivisions")),
|
|
22502
21304
|
divisions.map((item) => {
|
|
22503
21305
|
const count = experts.filter((expert) => expert.division === item).length;
|
|
22504
|
-
return /* @__PURE__ */
|
|
21306
|
+
return /* @__PURE__ */ import_react5.default.createElement("option", { key: item, value: item }, `${labelOf(item)} (${count})`);
|
|
22505
21307
|
})
|
|
22506
|
-
), filtered && /* @__PURE__ */
|
|
21308
|
+
), filtered && /* @__PURE__ */ import_react5.default.createElement(
|
|
22507
21309
|
"button",
|
|
22508
21310
|
{
|
|
22509
21311
|
className: "t-team-chip",
|
|
@@ -22515,9 +21317,9 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22515
21317
|
}
|
|
22516
21318
|
},
|
|
22517
21319
|
t("filter.clear")
|
|
22518
|
-
), /* @__PURE__ */
|
|
21320
|
+
), /* @__PURE__ */ import_react5.default.createElement("button", { className: "t-team-chip", type: "button", onClick: openEditorNew }, t("custom.new"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-meta" }, t("filter.summary", { shown: visible.length, total: experts.length, enabled: enabledSet.size })), error62 !== "" && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-error" }, error62 === "CONFLICT" ? t("settings.conflictRetry") : t("settings.saveFailed", { detail: error62 })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-groups" }, grouped.map((group) => /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-group", key: group.division }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-division" }, divisionLabel(group.items[0], active), " \xB7 ", group.items.length), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-grid" }, group.items.map((expert) => {
|
|
22519
21321
|
const on = enabledSet.has(expert.slug);
|
|
22520
|
-
return /* @__PURE__ */
|
|
21322
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-card", "data-enabled": on, key: expert.slug }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-card-body" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-avatar" }, expert.emoji || "\u{1F9E9}"), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-identity" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-card-name" }, displayName(expert, active), expert.custom === true && /* @__PURE__ */ import_react5.default.createElement("span", { className: "t-team-badge-custom" }, t("custom.badge"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-card-division" }, divisionLabel(expert, active)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-card-slug" }, expert.slug)), /* @__PURE__ */ import_react5.default.createElement("p", { className: "t-team-card-desc" }, displayDescription(expert, active)), expert.conflict === true && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-conflict", style: { gridColumn: "1/-1" } }, t("settings.conflict"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-card-tools" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
22521
21323
|
"button",
|
|
22522
21324
|
{
|
|
22523
21325
|
className: "t-team-icon-btn",
|
|
@@ -22527,7 +21329,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22527
21329
|
onClick: () => void openPrompt(expert)
|
|
22528
21330
|
},
|
|
22529
21331
|
"\u{1F4C4}"
|
|
22530
|
-
), expert.custom === true && /* @__PURE__ */
|
|
21332
|
+
), expert.custom === true && /* @__PURE__ */ import_react5.default.createElement(
|
|
22531
21333
|
"button",
|
|
22532
21334
|
{
|
|
22533
21335
|
className: "t-team-icon-btn",
|
|
@@ -22537,7 +21339,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22537
21339
|
onClick: () => void openEditorEdit(expert)
|
|
22538
21340
|
},
|
|
22539
21341
|
"\u270F\uFE0F"
|
|
22540
|
-
), expert.custom === true && (pendingDelete === expert.slug ? /* @__PURE__ */
|
|
21342
|
+
), expert.custom === true && (pendingDelete === expert.slug ? /* @__PURE__ */ import_react5.default.createElement(
|
|
22541
21343
|
"button",
|
|
22542
21344
|
{
|
|
22543
21345
|
className: "t-team-chip t-team-danger",
|
|
@@ -22546,7 +21348,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22546
21348
|
onClick: () => void removeExpert(expert)
|
|
22547
21349
|
},
|
|
22548
21350
|
t("custom.confirmDelete")
|
|
22549
|
-
) : /* @__PURE__ */
|
|
21351
|
+
) : /* @__PURE__ */ import_react5.default.createElement(
|
|
22550
21352
|
"button",
|
|
22551
21353
|
{
|
|
22552
21354
|
className: "t-team-icon-btn",
|
|
@@ -22557,7 +21359,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22557
21359
|
},
|
|
22558
21360
|
"\u{1F5D1}"
|
|
22559
21361
|
))));
|
|
22560
|
-
})))), visible.length === 0 && /* @__PURE__ */
|
|
21362
|
+
})))), visible.length === 0 && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-meta" }, t("settings.empty"))))), promptView !== null && /* @__PURE__ */ import_react5.default.createElement(
|
|
22561
21363
|
"div",
|
|
22562
21364
|
{
|
|
22563
21365
|
className: "t-team-mask",
|
|
@@ -22565,8 +21367,8 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22565
21367
|
if (event.target === event.currentTarget) setPromptView(null);
|
|
22566
21368
|
}
|
|
22567
21369
|
},
|
|
22568
|
-
/* @__PURE__ */
|
|
22569
|
-
), editor !== null && /* @__PURE__ */
|
|
21370
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-modal", role: "dialog", "aria-modal": "true", "aria-label": t("card.promptTitle", { name: promptView.name }) }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-modal-head" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("card.promptTitle", { name: promptView.name })), /* @__PURE__ */ import_react5.default.createElement("button", { className: "t-team-chip", type: "button", onClick: () => setPromptView(null) }, t("card.close"))), /* @__PURE__ */ import_react5.default.createElement("pre", { className: "t-team-modal-body" }, promptView.loading ? t("card.promptLoading") : promptView.error !== "" ? t("card.promptFailed", { detail: promptView.error }) : promptView.text === "" ? t("card.promptEmpty") : promptView.text))
|
|
21371
|
+
), editor !== null && /* @__PURE__ */ import_react5.default.createElement(
|
|
22570
21372
|
"div",
|
|
22571
21373
|
{
|
|
22572
21374
|
className: "t-team-mask",
|
|
@@ -22574,7 +21376,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22574
21376
|
if (event.target === event.currentTarget && !editor.saving) setEditor(null);
|
|
22575
21377
|
}
|
|
22576
21378
|
},
|
|
22577
|
-
/* @__PURE__ */
|
|
21379
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
22578
21380
|
"div",
|
|
22579
21381
|
{
|
|
22580
21382
|
className: "t-team-modal",
|
|
@@ -22582,8 +21384,8 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22582
21384
|
"aria-modal": "true",
|
|
22583
21385
|
"aria-label": editor.mode === "new" ? t("custom.titleNew") : t("custom.titleEdit", { name: editor.name || editor.slug })
|
|
22584
21386
|
},
|
|
22585
|
-
/* @__PURE__ */
|
|
22586
|
-
/* @__PURE__ */
|
|
21387
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-modal-head" }, /* @__PURE__ */ import_react5.default.createElement("span", null, editor.mode === "new" ? t("custom.titleNew") : t("custom.titleEdit", { name: editor.name || editor.slug })), /* @__PURE__ */ import_react5.default.createElement("button", { className: "t-team-chip", type: "button", disabled: editor.saving, onClick: () => setEditor(null) }, t("custom.cancel"))),
|
|
21388
|
+
/* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-editor", style: { padding: 14, overflow: "auto" } }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-note" }, t("custom.hint")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.division")), /* @__PURE__ */ import_react5.default.createElement(
|
|
22587
21389
|
"select",
|
|
22588
21390
|
{
|
|
22589
21391
|
className: "t-team-select",
|
|
@@ -22594,9 +21396,9 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22594
21396
|
else patchEditor({ divisionNew: false, division: value });
|
|
22595
21397
|
}
|
|
22596
21398
|
},
|
|
22597
|
-
editorDivisionOptions.map((item) => /* @__PURE__ */
|
|
22598
|
-
/* @__PURE__ */
|
|
22599
|
-
), editor.divisionNew && /* @__PURE__ */
|
|
21399
|
+
editorDivisionOptions.map((item) => /* @__PURE__ */ import_react5.default.createElement("option", { key: item.key, value: item.key }, `${item.label} \xB7 ${item.key}`)),
|
|
21400
|
+
/* @__PURE__ */ import_react5.default.createElement("option", { value: NEW_DIVISION }, t("custom.divisionNew"))
|
|
21401
|
+
), editor.divisionNew && /* @__PURE__ */ import_react5.default.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 6 } }, /* @__PURE__ */ import_react5.default.createElement(
|
|
22600
21402
|
"input",
|
|
22601
21403
|
{
|
|
22602
21404
|
className: "t-team-input",
|
|
@@ -22605,7 +21407,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22605
21407
|
value: editor.divisionKey,
|
|
22606
21408
|
onChange: (event) => patchEditor({ divisionKey: event.target.value })
|
|
22607
21409
|
}
|
|
22608
|
-
), /* @__PURE__ */
|
|
21410
|
+
), /* @__PURE__ */ import_react5.default.createElement(
|
|
22609
21411
|
"input",
|
|
22610
21412
|
{
|
|
22611
21413
|
className: "t-team-input",
|
|
@@ -22613,7 +21415,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22613
21415
|
value: editor.divisionLabel,
|
|
22614
21416
|
onChange: (event) => patchEditor({ divisionLabel: event.target.value })
|
|
22615
21417
|
}
|
|
22616
|
-
))), /* @__PURE__ */
|
|
21418
|
+
))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.slug")), /* @__PURE__ */ import_react5.default.createElement(
|
|
22617
21419
|
"input",
|
|
22618
21420
|
{
|
|
22619
21421
|
className: "t-team-input",
|
|
@@ -22622,7 +21424,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22622
21424
|
spellCheck: false,
|
|
22623
21425
|
onChange: (event) => patchEditor({ slug: event.target.value })
|
|
22624
21426
|
}
|
|
22625
|
-
)), /* @__PURE__ */
|
|
21427
|
+
)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.name")), /* @__PURE__ */ import_react5.default.createElement("input", { className: "t-team-input", value: editor.name, onChange: (event) => patchEditor({ name: event.target.value }) })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.nameEn")), /* @__PURE__ */ import_react5.default.createElement("input", { className: "t-team-input", value: editor.nameEn, onChange: (event) => patchEditor({ nameEn: event.target.value }) })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.emoji")), /* @__PURE__ */ import_react5.default.createElement("input", { className: "t-team-input", maxLength: 8, value: editor.emoji, onChange: (event) => patchEditor({ emoji: event.target.value }) })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.description")), /* @__PURE__ */ import_react5.default.createElement("input", { className: "t-team-input", value: editor.description, onChange: (event) => patchEditor({ description: event.target.value }) })), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, t("custom.body")), /* @__PURE__ */ import_react5.default.createElement(
|
|
22626
21428
|
"textarea",
|
|
22627
21429
|
{
|
|
22628
21430
|
className: "t-team-input",
|
|
@@ -22630,7 +21432,7 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22630
21432
|
disabled: editor.loading,
|
|
22631
21433
|
onChange: (event) => patchEditor({ body: event.target.value })
|
|
22632
21434
|
}
|
|
22633
|
-
)), editor.loading && /* @__PURE__ */
|
|
21435
|
+
)), editor.loading && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-meta" }, t("custom.loadingBody")), editor.error !== "" && /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-error" }, editor.error), /* @__PURE__ */ import_react5.default.createElement("div", { className: "t-team-editor-actions" }, /* @__PURE__ */ import_react5.default.createElement("button", { className: "t-team-chip", type: "button", disabled: editor.saving, onClick: () => setEditor(null) }, t("custom.cancel")), /* @__PURE__ */ import_react5.default.createElement(
|
|
22634
21436
|
"button",
|
|
22635
21437
|
{
|
|
22636
21438
|
className: "t-team-chip",
|
|
@@ -22646,14 +21448,14 @@ function SettingsPanel({ t, ctx, remote, getActive, initialTab }) {
|
|
|
22646
21448
|
}
|
|
22647
21449
|
|
|
22648
21450
|
// src/client/summon.jsx
|
|
22649
|
-
var
|
|
21451
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
22650
21452
|
function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillHint: insertSkillHint2, sessionId, preview, rootRemote }) {
|
|
22651
|
-
const [open2, setOpen] =
|
|
22652
|
-
const [popTab, setPopTab] =
|
|
22653
|
-
const [skills, setSkills] =
|
|
22654
|
-
const [skillQuery, setSkillQuery] =
|
|
22655
|
-
const [skillsDiag, setSkillsDiag] =
|
|
22656
|
-
|
|
21453
|
+
const [open2, setOpen] = import_react6.default.useState(preview?.open === true);
|
|
21454
|
+
const [popTab, setPopTab] = import_react6.default.useState(preview?.tab ?? "experts");
|
|
21455
|
+
const [skills, setSkills] = import_react6.default.useState(null);
|
|
21456
|
+
const [skillQuery, setSkillQuery] = import_react6.default.useState("");
|
|
21457
|
+
const [skillsDiag, setSkillsDiag] = import_react6.default.useState("");
|
|
21458
|
+
import_react6.default.useEffect(() => {
|
|
22657
21459
|
if (!open2) return void 0;
|
|
22658
21460
|
const cached2 = skillsCache.get(sessionId);
|
|
22659
21461
|
if (cached2 !== void 0) setSkills(cached2);
|
|
@@ -22701,12 +21503,12 @@ function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillH
|
|
|
22701
21503
|
alive = false;
|
|
22702
21504
|
};
|
|
22703
21505
|
}, [open2, sessionId, rootRemote]);
|
|
22704
|
-
const [popNote, setPopNote] =
|
|
22705
|
-
const [query, setQuery] =
|
|
22706
|
-
const [failed, setFailed] =
|
|
22707
|
-
const [position, setPosition] =
|
|
22708
|
-
const rootRef =
|
|
22709
|
-
const popRef =
|
|
21506
|
+
const [popNote, setPopNote] = import_react6.default.useState("");
|
|
21507
|
+
const [query, setQuery] = import_react6.default.useState("");
|
|
21508
|
+
const [failed, setFailed] = import_react6.default.useState("");
|
|
21509
|
+
const [position, setPosition] = import_react6.default.useState(void 0);
|
|
21510
|
+
const rootRef = import_react6.default.useRef(null);
|
|
21511
|
+
const popRef = import_react6.default.useRef(null);
|
|
22710
21512
|
const snap = snapshotOf(remote);
|
|
22711
21513
|
function anchorInput() {
|
|
22712
21514
|
let node2 = rootRef.current?.parentElement ?? null;
|
|
@@ -22733,13 +21535,30 @@ function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillH
|
|
|
22733
21535
|
const laidOut = measured > 0 ? measured : width;
|
|
22734
21536
|
const maxLeft = laidOut === 0 ? Number.POSITIVE_INFINITY : Math.max(8, window.innerWidth - laidOut - 8);
|
|
22735
21537
|
const wantedLeft = hasInput ? inputRect.left : rect.left;
|
|
22736
|
-
|
|
21538
|
+
const refTop = hasInput ? inputRect.top : rect.top;
|
|
21539
|
+
const refBottom = hasInput ? inputRect.bottom : rect.bottom;
|
|
21540
|
+
const EDGE = 8;
|
|
21541
|
+
const OFFSET = 6;
|
|
21542
|
+
const IDEAL = 600;
|
|
21543
|
+
const cap = Math.max(0, Math.min(IDEAL, window.innerHeight - EDGE * 2));
|
|
21544
|
+
const spaceAbove = refTop - EDGE;
|
|
21545
|
+
const spaceBelow = window.innerHeight - refBottom - EDGE;
|
|
21546
|
+
const up = spaceAbove >= spaceBelow;
|
|
21547
|
+
const maxHeight = Math.max(0, Math.min(cap, up ? spaceAbove : spaceBelow));
|
|
21548
|
+
const pos = {
|
|
22737
21549
|
left: Math.min(Math.max(8, wantedLeft), maxLeft),
|
|
22738
|
-
bottom: Math.max(8, window.innerHeight - (hasInput ? inputRect.top : rect.top) + 6),
|
|
22739
21550
|
"--t-team-pop-w": width > 0 ? `${width}px` : void 0
|
|
22740
|
-
}
|
|
21551
|
+
};
|
|
21552
|
+
if (up) {
|
|
21553
|
+
pos.bottom = Math.max(EDGE, window.innerHeight - refTop + OFFSET);
|
|
21554
|
+
pos.maxHeight = `${maxHeight}px`;
|
|
21555
|
+
} else {
|
|
21556
|
+
pos.top = Math.max(EDGE, refBottom + OFFSET);
|
|
21557
|
+
pos.maxHeight = `${maxHeight}px`;
|
|
21558
|
+
}
|
|
21559
|
+
setPosition(pos);
|
|
22741
21560
|
}
|
|
22742
|
-
|
|
21561
|
+
import_react6.default.useEffect(() => {
|
|
22743
21562
|
if (!open2) return void 0;
|
|
22744
21563
|
const onDown = (event) => {
|
|
22745
21564
|
if (rootRef.current !== null && !rootRef.current.contains(event.target)) setOpen(false);
|
|
@@ -22808,7 +21627,7 @@ function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillH
|
|
|
22808
21627
|
setFailed(t("button.insertFailed"));
|
|
22809
21628
|
}
|
|
22810
21629
|
}
|
|
22811
|
-
return /* @__PURE__ */
|
|
21630
|
+
return /* @__PURE__ */ import_react6.default.createElement("span", { ref: rootRef, className: "t-team-btn-wrap" }, /* @__PURE__ */ import_react6.default.createElement("button", { className: "t-team-btn", type: "button", title: t("button.title"), onClick: () => void toggle() }, "\u{1F9E9} ", t("button.label")), open2 && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop", "data-tab": popTab, ref: popRef, style: position }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop-head" }, /* @__PURE__ */ import_react6.default.createElement("span", null, t("pop.title")), /* @__PURE__ */ import_react6.default.createElement("button", { className: "t-team-chip", type: "button", onClick: () => setOpen(false) }, t("button.close"))), /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-tabs", role: "tablist" }, popTabs.map(([key, label]) => /* @__PURE__ */ import_react6.default.createElement(
|
|
22812
21631
|
"button",
|
|
22813
21632
|
{
|
|
22814
21633
|
className: "t-team-tab",
|
|
@@ -22823,8 +21642,8 @@ function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillH
|
|
|
22823
21642
|
}
|
|
22824
21643
|
},
|
|
22825
21644
|
t(label),
|
|
22826
|
-
tabCounts[key] === void 0 ? null : /* @__PURE__ */
|
|
22827
|
-
))), popNote !== "" && /* @__PURE__ */
|
|
21645
|
+
tabCounts[key] === void 0 ? null : /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-tab-count" }, t("tab.count", { count: tabCounts[key] }))
|
|
21646
|
+
))), popNote !== "" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-ok" }, popNote), failed !== "" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-error" }, failed), popTab === "experts" && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(
|
|
22828
21647
|
"input",
|
|
22829
21648
|
{
|
|
22830
21649
|
className: "t-team-input",
|
|
@@ -22833,10 +21652,10 @@ function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillH
|
|
|
22833
21652
|
value: query,
|
|
22834
21653
|
onChange: (event) => setQuery(event.target.value)
|
|
22835
21654
|
}
|
|
22836
|
-
), /* @__PURE__ */
|
|
21655
|
+
), /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop-list" }, grouped.map((group) => /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, { key: group.division }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-division" }, divisionLabel(group.items[0], active)), group.items.map((expert) => {
|
|
22837
21656
|
const alt = active === "en" ? expert.name : expert.nameEn;
|
|
22838
|
-
return /* @__PURE__ */
|
|
22839
|
-
}))), experts.length === 0 && /* @__PURE__ */
|
|
21657
|
+
return /* @__PURE__ */ import_react6.default.createElement("button", { className: "t-team-pop-item", type: "button", key: expert.slug, onClick: () => pick2(expert) }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-head" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-avatar" }, expert.emoji || "\u{1F9E9}"), /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-title" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-name" }, displayName(expert, active)), alt !== void 0 && alt !== "" && /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-sub" }, alt))), /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-desc" }, displayDescription(expert, active)));
|
|
21658
|
+
}))), experts.length === 0 && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop-empty" }, t("button.empty")), experts.length > 0 && visible.length === 0 && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop-empty" }, t("button.noMatch")))), popTab === "skills" && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(
|
|
22840
21659
|
"input",
|
|
22841
21660
|
{
|
|
22842
21661
|
className: "t-team-input",
|
|
@@ -22845,7 +21664,7 @@ function SummonButton({ t, ctx, remote, getActive, insertReference, insertSkillH
|
|
|
22845
21664
|
value: skillQuery,
|
|
22846
21665
|
onChange: (event) => setSkillQuery(event.target.value)
|
|
22847
21666
|
}
|
|
22848
|
-
), /* @__PURE__ */
|
|
21667
|
+
), /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop-list" }, visibleSkills.map((skill) => /* @__PURE__ */ import_react6.default.createElement("button", { className: "t-team-pop-item", type: "button", key: skill.name, onClick: () => pickSkill(skill) }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-head" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-avatar" }, "\u{1F9F0}"), /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-title" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-name" }, skill.name), skill.modelInvocable === false && /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-sub" }, t("pop.skillUserOnly")))), /* @__PURE__ */ import_react6.default.createElement("span", { className: "t-team-pop-desc" }, skill.description ?? ""))), visibleSkills.length === 0 && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-pop-empty" }, skills === null ? t("pop.skillEmpty") : t("pop.skillNoMatch")), skillsDiag !== "" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "t-team-error", style: { fontSize: "11px", whiteSpace: "pre-wrap" } }, "\u8BCA\u65AD\uFF1A", skillsDiag)))));
|
|
22849
21668
|
}
|
|
22850
21669
|
|
|
22851
21670
|
// src/client/index.jsx
|
|
@@ -22912,61 +21731,14 @@ async function apply(ctx) {
|
|
|
22912
21731
|
label: () => ctx.locale.bind(NS)("settings.title"),
|
|
22913
21732
|
locale: NS,
|
|
22914
21733
|
icon: "expert"
|
|
22915
|
-
}, (props) =>
|
|
22916
|
-
ctx.slots.inject("sidebar.panellist", () => {
|
|
22917
|
-
let disposeEntry;
|
|
22918
|
-
const sync = () => {
|
|
22919
|
-
const want = scheduleEntryVisible();
|
|
22920
|
-
if (want === (disposeEntry !== void 0)) return;
|
|
22921
|
-
if (!want) {
|
|
22922
|
-
disposeEntry?.();
|
|
22923
|
-
disposeEntry = void 0;
|
|
22924
|
-
return;
|
|
22925
|
-
}
|
|
22926
|
-
try {
|
|
22927
|
-
disposeEntry = ctx.slots.register({
|
|
22928
|
-
name: "sidebar.panellist",
|
|
22929
|
-
id: SCHEDULE_PANEL_KEY,
|
|
22930
|
-
// order 取最小:侧栏那一组里它排在最前,紧贴「新会话」按钮。
|
|
22931
|
-
order: 1,
|
|
22932
|
-
label: () => ctx.locale.bind(NS)("sched.nav"),
|
|
22933
|
-
locale: NS
|
|
22934
|
-
}, (props) => import_react8.default.createElement(ScheduleGlyph, { size: props?.size ?? 16 }));
|
|
22935
|
-
} catch (cause) {
|
|
22936
|
-
console.warn("[t-team] \u4FA7\u680F\u5B9A\u65F6\u4EFB\u52A1\u5165\u53E3\u6CE8\u518C\u5931\u8D25\uFF1A", cause);
|
|
22937
|
-
disposeEntry = void 0;
|
|
22938
|
-
}
|
|
22939
|
-
};
|
|
22940
|
-
const unsubscribe = subscribeUiPrefs(sync);
|
|
22941
|
-
sync();
|
|
22942
|
-
return () => {
|
|
22943
|
-
unsubscribe();
|
|
22944
|
-
disposeEntry?.();
|
|
22945
|
-
disposeEntry = void 0;
|
|
22946
|
-
};
|
|
22947
|
-
});
|
|
22948
|
-
ctx.slots.inject("main", () => ctx.slots.register({
|
|
22949
|
-
name: "main",
|
|
22950
|
-
key: SCHEDULE_PANEL_KEY,
|
|
22951
|
-
locale: NS
|
|
22952
|
-
}, (props) => import_react8.default.createElement(
|
|
22953
|
-
SectionBoundary,
|
|
22954
|
-
{ t: ctx.locale.bind(NS), reloadKey: "schedule" },
|
|
22955
|
-
import_react8.default.createElement(SchedulePanel, {
|
|
22956
|
-
...props,
|
|
22957
|
-
t: ctx.locale.bind(NS),
|
|
22958
|
-
remote,
|
|
22959
|
-
getActive,
|
|
22960
|
-
ctx: props?.ctx ?? ctx
|
|
22961
|
-
})
|
|
22962
|
-
)));
|
|
21734
|
+
}, (props) => import_react7.default.createElement(SettingsPanel, { ...props, t: ctx.locale.bind(NS), remote, getActive })));
|
|
22963
21735
|
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
22964
21736
|
name: "conversation.session.header.utilities",
|
|
22965
21737
|
id: `${NS}-pulse`,
|
|
22966
21738
|
order: 1,
|
|
22967
21739
|
label: () => ctx.locale.bind(NS)("pulse.on"),
|
|
22968
21740
|
locale: NS
|
|
22969
|
-
}, (props) =>
|
|
21741
|
+
}, (props) => import_react7.default.createElement(ActivePulse, {
|
|
22970
21742
|
...props,
|
|
22971
21743
|
t: ctx.locale.bind(NS),
|
|
22972
21744
|
ctx: props?.ctx ?? ctx,
|
|
@@ -22985,7 +21757,7 @@ async function apply(ctx) {
|
|
|
22985
21757
|
insertSkillHint: (text) => insertSkillHint(target(), text)
|
|
22986
21758
|
};
|
|
22987
21759
|
}
|
|
22988
|
-
}, (props) =>
|
|
21760
|
+
}, (props) => import_react7.default.createElement(SummonButton, { ...props, t: ctx.locale.bind(NS), remote, getActive, rootRemote: ctx.remote })));
|
|
22989
21761
|
const registerSources = (active, divisions) => {
|
|
22990
21762
|
const disposers = [];
|
|
22991
21763
|
try {
|