@lmzhen/dsh-evolution-ui 0.34.0 → 0.36.0
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/lib/client.js +679 -215
- package/lib/types/panels/history/client/Workbench.d.ts +3 -1
- package/lib/types/panels/history/client/WorkbenchStore.d.ts +17 -0
- package/lib/types/panels/history/client/chrome.d.ts +1 -1
- package/lib/types/panels/history/client/history-presentation.d.ts +17 -0
- package/lib/types/panels/settings/DiagnosticsCard.d.ts +13 -0
- package/lib/types/panels/settings/PendingCard.d.ts +2 -0
- package/lib/types/panels/settings/generated-about.d.ts +1 -1
- package/lib/types/panels/settings/messages.d.ts +16 -5
- package/lib/types/panels/settings/settings-groups.d.ts +17 -0
- package/package.json +4 -4
package/lib/client.js
CHANGED
|
@@ -831,9 +831,12 @@ window.__ModuleLoader__.load({
|
|
|
831
831
|
/** Chinese copy (the family's primary language). */
|
|
832
832
|
const zh$1 = {
|
|
833
833
|
title: "自进化",
|
|
834
|
+
"group.write": "写入与审批",
|
|
835
|
+
"group.organize": "自动整理",
|
|
836
|
+
"group.memory": "记忆与回顾",
|
|
834
837
|
subtitle: "待你决定的写入在最上面;下面按功能列出你能改的参数,没有列出的由安装时的配置决定。",
|
|
835
838
|
aboutPurpose: "自进化设置与技能历史",
|
|
836
|
-
overridden: "
|
|
839
|
+
overridden: "已修改",
|
|
837
840
|
deployment: "默认",
|
|
838
841
|
loading: "正在读取设置…",
|
|
839
842
|
unavailable: "这个功能没有启动(对应的插件没有安装)",
|
|
@@ -841,12 +844,12 @@ window.__ModuleLoader__.load({
|
|
|
841
844
|
projectionFailed: "这一块读设置时出错,已记入日志;其它参数不受影响",
|
|
842
845
|
readonly: "本次会话不允许写入设置(临时运行模式)",
|
|
843
846
|
apply: "保存",
|
|
844
|
-
reset: "
|
|
847
|
+
reset: "复位",
|
|
845
848
|
empty: "这里没有可改项",
|
|
846
|
-
changed: "{n}
|
|
849
|
+
changed: "{n} 项已修改",
|
|
847
850
|
discard: "放弃修改",
|
|
848
851
|
saving: "保存中…",
|
|
849
|
-
resetting: "
|
|
852
|
+
resetting: "复位中…",
|
|
850
853
|
writeTargetHost: "保存去向:宿主配置(对所有会话生效)",
|
|
851
854
|
invalidNumber: "需要一个数字",
|
|
852
855
|
invalidSelect: "不在允许的取值里",
|
|
@@ -875,7 +878,12 @@ window.__ModuleLoader__.load({
|
|
|
875
878
|
mergeCardHint: "写入审批=使用中生成/修改;合并审批=两轮工作流。",
|
|
876
879
|
approvalTitle: "待批写入",
|
|
877
880
|
approvalLoading: "正在读取待批项…",
|
|
878
|
-
approvalEmpty: "
|
|
881
|
+
approvalEmpty: "没有待处理的写入",
|
|
882
|
+
approvalEmptyDescription: "当前没有需要你确认的技能变更。新的写入会在这里显示来源、内容和影响范围。",
|
|
883
|
+
approvalHistory: "查看技能历史",
|
|
884
|
+
approvalFactKind: "类型",
|
|
885
|
+
approvalFactAge: "时间",
|
|
886
|
+
approvalFactTarget: "对象",
|
|
879
887
|
approvalFailed: "待批项读取失败",
|
|
880
888
|
approvalRetry: "重试",
|
|
881
889
|
approvalApprove: "批准",
|
|
@@ -915,6 +923,9 @@ window.__ModuleLoader__.load({
|
|
|
915
923
|
diagTitle: "诊断",
|
|
916
924
|
diagSubtitle: "运行状态的只读自查;不会改动任何东西。",
|
|
917
925
|
diagRuntimeTitle: "运行状态",
|
|
926
|
+
diagComplete: "没有需要处理的异常",
|
|
927
|
+
diagOtherIssues: "其他 {n} 项异常",
|
|
928
|
+
diagNormal: "其他 {n} 项正常",
|
|
918
929
|
diagSummaryOk: "运行正常",
|
|
919
930
|
diagSummaryWarn: "{n} 项需要注意",
|
|
920
931
|
diagSummaryFail: "{n} 项异常",
|
|
@@ -939,9 +950,12 @@ window.__ModuleLoader__.load({
|
|
|
939
950
|
/** English copy, key for key with {@link zh}. */
|
|
940
951
|
const en$1 = {
|
|
941
952
|
title: "Self-evolution",
|
|
953
|
+
"group.write": "Writes and approval",
|
|
954
|
+
"group.organize": "Automatic tidy-up",
|
|
955
|
+
"group.memory": "Memory and review",
|
|
942
956
|
subtitle: "Writes waiting for your decision come first; the changeable parameters are listed by feature below, and anything not listed comes from the deployment configuration.",
|
|
943
957
|
aboutPurpose: "Self-evolution settings and skill history",
|
|
944
|
-
overridden: "
|
|
958
|
+
overridden: "Modified",
|
|
945
959
|
deployment: "default",
|
|
946
960
|
loading: "reading settings…",
|
|
947
961
|
unavailable: "this feature is not running (its plugin is not installed)",
|
|
@@ -949,9 +963,9 @@ window.__ModuleLoader__.load({
|
|
|
949
963
|
projectionFailed: "reading this row failed and the error is in the log; the other parameters are unaffected",
|
|
950
964
|
readonly: "settings cannot be written in this session (temporary mode)",
|
|
951
965
|
apply: "Save",
|
|
952
|
-
reset: "Reset
|
|
966
|
+
reset: "Reset",
|
|
953
967
|
empty: "nothing to change here",
|
|
954
|
-
changed: "{n}
|
|
968
|
+
changed: "{n} modified",
|
|
955
969
|
discard: "Discard",
|
|
956
970
|
saving: "Saving…",
|
|
957
971
|
resetting: "Resetting…",
|
|
@@ -983,7 +997,12 @@ window.__ModuleLoader__.load({
|
|
|
983
997
|
mergeCardHint: "Write approval = generate/modify while in use; merge approval = the two-round workflow.",
|
|
984
998
|
approvalTitle: "Writes awaiting approval",
|
|
985
999
|
approvalLoading: "reading the pending window…",
|
|
986
|
-
approvalEmpty: "
|
|
1000
|
+
approvalEmpty: "Nothing is waiting",
|
|
1001
|
+
approvalEmptyDescription: "There are no skill changes to confirm. New writes will show their source, content and impact here.",
|
|
1002
|
+
approvalHistory: "View skill history",
|
|
1003
|
+
approvalFactKind: "Kind",
|
|
1004
|
+
approvalFactAge: "Time",
|
|
1005
|
+
approvalFactTarget: "Target",
|
|
987
1006
|
approvalFailed: "the pending window could not be read",
|
|
988
1007
|
approvalRetry: "Retry",
|
|
989
1008
|
approvalApprove: "Approve",
|
|
@@ -1023,6 +1042,9 @@ window.__ModuleLoader__.load({
|
|
|
1023
1042
|
diagTitle: "Diagnostics",
|
|
1024
1043
|
diagSubtitle: "A read-only check of the runtime state; nothing here changes anything.",
|
|
1025
1044
|
diagRuntimeTitle: "Runtime status",
|
|
1045
|
+
diagComplete: "Nothing needs attention",
|
|
1046
|
+
diagOtherIssues: "Other {n} issues",
|
|
1047
|
+
diagNormal: "Other {n} normal checks",
|
|
1026
1048
|
diagSummaryOk: "All healthy",
|
|
1027
1049
|
diagSummaryWarn: "{n} need attention",
|
|
1028
1050
|
diagSummaryFail: "{n} failing",
|
|
@@ -1262,18 +1284,20 @@ window.__ModuleLoader__.load({
|
|
|
1262
1284
|
return (0, react.createElement)("div", { className: "evolution-param-field" }, (0, react.createElement)("div", { className: "evolution-param-label" }, (0, react.createElement)("label", { htmlFor: controlId(field) }, labelOf(field, lang) === "" ? field.id : labelOf(field, lang)), unit, props.overridden ? (0, react.createElement)("span", {
|
|
1263
1285
|
className: "evolution-param-source",
|
|
1264
1286
|
"data-user": "true"
|
|
1265
|
-
}, t("overridden")) : null
|
|
1266
|
-
id: controlId(field) + "-invalid",
|
|
1267
|
-
className: "evolution-param-error",
|
|
1268
|
-
role: "status"
|
|
1269
|
-
}, props.invalid), props.overridden ? (0, react.createElement)("div", { className: "evolution-param-actions" }, (0, react.createElement)("button", {
|
|
1287
|
+
}, t("overridden")) : null, props.overridden ? (0, react.createElement)("button", {
|
|
1270
1288
|
type: "button",
|
|
1271
|
-
className: "evolution-param-
|
|
1289
|
+
className: "evolution-param-reset",
|
|
1272
1290
|
disabled: props.disabled || props.clearing,
|
|
1291
|
+
"data-role": "reset",
|
|
1292
|
+
title: props.resetTo === null ? void 0 : t("resetTo", { value: props.resetTo }),
|
|
1273
1293
|
onClick: () => {
|
|
1274
1294
|
props.onClear(field.id);
|
|
1275
1295
|
}
|
|
1276
|
-
}, props.clearing ? t("resetting") : t("reset"))
|
|
1296
|
+
}, props.clearing ? t("resetting") : t("reset")) : null), FieldControl(props), (0, react.createElement)("p", { className: "evolution-param-hint" }, hintOf(field, lang) === "" ? field.doc : hintOf(field, lang)), props.invalid === null ? null : (0, react.createElement)("p", {
|
|
1297
|
+
id: controlId(field) + "-invalid",
|
|
1298
|
+
className: "evolution-param-error",
|
|
1299
|
+
role: "status"
|
|
1300
|
+
}, props.invalid));
|
|
1277
1301
|
}
|
|
1278
1302
|
/**
|
|
1279
1303
|
* Render one row's card body from a supplied snapshot.
|
|
@@ -1522,6 +1546,36 @@ window.__ModuleLoader__.load({
|
|
|
1522
1546
|
});
|
|
1523
1547
|
}
|
|
1524
1548
|
//#endregion
|
|
1549
|
+
//#region src/panels/settings/settings-groups.ts
|
|
1550
|
+
const GROUP_OF = Object.freeze({
|
|
1551
|
+
"evolution-approval": "write",
|
|
1552
|
+
"evolution-merge": "write",
|
|
1553
|
+
"tool-skill-manage": "write",
|
|
1554
|
+
"evolution-curator": "organize",
|
|
1555
|
+
"evolution-commands": "organize",
|
|
1556
|
+
"memory-files": "memory",
|
|
1557
|
+
"tool-memory": "memory",
|
|
1558
|
+
"evolution-review": "memory"
|
|
1559
|
+
});
|
|
1560
|
+
/** Stable display order for the three task groups. */
|
|
1561
|
+
const SETTINGS_GROUP_ORDER = [
|
|
1562
|
+
"write",
|
|
1563
|
+
"organize",
|
|
1564
|
+
"memory"
|
|
1565
|
+
];
|
|
1566
|
+
/**
|
|
1567
|
+
* Partition existing parameter cards by task. Unknown namespaces fall into organize so a future row
|
|
1568
|
+
* is visible rather than silently dropped.
|
|
1569
|
+
* @param cards - cards carrying only their namespace and payload.
|
|
1570
|
+
* @returns groups in display order, omitting empty groups.
|
|
1571
|
+
*/
|
|
1572
|
+
function groupParamCards(cards) {
|
|
1573
|
+
return SETTINGS_GROUP_ORDER.map((group) => ({
|
|
1574
|
+
group,
|
|
1575
|
+
items: cards.filter((card) => (GROUP_OF[card.namespace] ?? "organize") === group)
|
|
1576
|
+
})).filter((entry) => entry.items.length > 0);
|
|
1577
|
+
}
|
|
1578
|
+
//#endregion
|
|
1525
1579
|
//#region ../evolution-client-kit/src/panel.ts
|
|
1526
1580
|
function interpolate(text, values) {
|
|
1527
1581
|
if (values === void 0) return text;
|
|
@@ -1780,6 +1834,127 @@ window.__ModuleLoader__.load({
|
|
|
1780
1834
|
};
|
|
1781
1835
|
}
|
|
1782
1836
|
//#endregion
|
|
1837
|
+
//#region ../evolution-client-kit/src/format.ts
|
|
1838
|
+
/**
|
|
1839
|
+
* Format an ISO string, epoch milliseconds, or null as local wall time.
|
|
1840
|
+
* Invalid values return null; callers decide how to say "unknown".
|
|
1841
|
+
* @param value - ISO string, epoch ms, or null.
|
|
1842
|
+
* @param options - seconds on/off; defaults to on.
|
|
1843
|
+
* @returns the formatted local time, or null when the value is absent/invalid.
|
|
1844
|
+
*/
|
|
1845
|
+
function formatLocalDateTime(value, options = {}) {
|
|
1846
|
+
if (value === null || value === void 0) return null;
|
|
1847
|
+
const ms = typeof value === "number" ? value : Date.parse(value);
|
|
1848
|
+
if (!Number.isFinite(ms)) return null;
|
|
1849
|
+
const date = new Date(ms);
|
|
1850
|
+
if (Number.isNaN(date.getTime())) return null;
|
|
1851
|
+
const pad = (part) => String(part).padStart(2, "0");
|
|
1852
|
+
const head = String(date.getFullYear()) + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes());
|
|
1853
|
+
return options.seconds === false ? head : head + ":" + pad(date.getSeconds());
|
|
1854
|
+
}
|
|
1855
|
+
//#endregion
|
|
1856
|
+
//#region ../evolution-client-kit/src/notice.ts
|
|
1857
|
+
/** One inline state notice: semantic tone plus text, no surface-specific styling. */
|
|
1858
|
+
//#endregion
|
|
1859
|
+
//#region ../evolution-client-kit/src/presentation/decision-frame.ts
|
|
1860
|
+
/** One decision card: title, facts, at most one primary, secondary actions and details. */
|
|
1861
|
+
function actionButton$1(action, role) {
|
|
1862
|
+
return (0, react.createElement)("button", {
|
|
1863
|
+
key: action.id,
|
|
1864
|
+
type: "button",
|
|
1865
|
+
"data-role": role === "primary" ? "decision-primary" : "decision-secondary",
|
|
1866
|
+
"data-action": action.id,
|
|
1867
|
+
"aria-busy": action.busy === true ? "true" : void 0,
|
|
1868
|
+
...action.attributes ?? {},
|
|
1869
|
+
disabled: action.disabled === true || action.busy === true,
|
|
1870
|
+
title: action.title ?? action.label,
|
|
1871
|
+
onClick: () => {
|
|
1872
|
+
if (action.disabled !== true && action.busy !== true) action.onSelect();
|
|
1873
|
+
}
|
|
1874
|
+
}, action.label);
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Render the one-card decision surface. The model has a singular primary on purpose.
|
|
1878
|
+
* @param props - decision model and optional surface class.
|
|
1879
|
+
* @returns the decision frame.
|
|
1880
|
+
*/
|
|
1881
|
+
function DecisionFrame({ decision, className }) {
|
|
1882
|
+
const secondary = decision.secondary ?? [];
|
|
1883
|
+
return (0, react.createElement)("section", {
|
|
1884
|
+
"data-role": "decision-frame",
|
|
1885
|
+
...className === void 0 ? {} : { className }
|
|
1886
|
+
}, (0, react.createElement)("h2", { "data-role": "decision-title" }, decision.title), decision.summary === void 0 || decision.summary === "" ? null : (0, react.createElement)("p", { "data-role": "decision-summary" }, decision.summary), decision.facts.length === 0 ? null : (0, react.createElement)("dl", { "data-role": "decision-facts" }, decision.facts.map((fact) => (0, react.createElement)("div", {
|
|
1887
|
+
key: fact.label,
|
|
1888
|
+
"data-role": "decision-fact"
|
|
1889
|
+
}, (0, react.createElement)("dt", null, fact.label), (0, react.createElement)("dd", null, fact.value)))), decision.details === void 0 ? null : (0, react.createElement)("div", { "data-role": "decision-details" }, decision.details), decision.primary === void 0 && secondary.length === 0 ? null : (0, react.createElement)("div", { "data-role": "decision-actions" }, decision.primary === void 0 ? null : actionButton$1(decision.primary, "primary"), secondary.map((action) => actionButton$1(action, "secondary"))));
|
|
1890
|
+
}
|
|
1891
|
+
//#endregion
|
|
1892
|
+
//#region ../evolution-client-kit/src/presentation/task-banner.ts
|
|
1893
|
+
/** A read-only task hint; it deliberately has no primary action. */
|
|
1894
|
+
//#endregion
|
|
1895
|
+
//#region ../evolution-client-kit/src/presentation/chips.ts
|
|
1896
|
+
/** Read-only status chips and toggleable filter chips. */
|
|
1897
|
+
//#endregion
|
|
1898
|
+
//#region ../evolution-client-kit/src/presentation/empty-state.ts
|
|
1899
|
+
/** A compact completed/empty state with at most one primary next step. */
|
|
1900
|
+
function actionButton(action, role) {
|
|
1901
|
+
return (0, react.createElement)("button", {
|
|
1902
|
+
key: action.id,
|
|
1903
|
+
type: "button",
|
|
1904
|
+
"data-role": role === "primary" ? "empty-primary" : "empty-secondary",
|
|
1905
|
+
"data-action": action.id,
|
|
1906
|
+
...action.attributes ?? {},
|
|
1907
|
+
disabled: action.disabled === true || action.busy === true,
|
|
1908
|
+
title: action.title ?? action.label,
|
|
1909
|
+
onClick: () => {
|
|
1910
|
+
if (action.disabled !== true && action.busy !== true) action.onSelect();
|
|
1911
|
+
}
|
|
1912
|
+
}, action.label);
|
|
1913
|
+
}
|
|
1914
|
+
/** Render a quiet empty state; loading/failure remain the caller's separate states. */
|
|
1915
|
+
function EmptyState({ title, description, tone = "neutral", primary, secondary, className }) {
|
|
1916
|
+
const actions = primary === void 0 && secondary === void 0 ? null : (0, react.createElement)("div", { "data-role": "empty-actions" }, primary === void 0 ? null : actionButton(primary, "primary"), secondary === void 0 ? null : actionButton(secondary, "secondary"));
|
|
1917
|
+
return (0, react.createElement)("section", {
|
|
1918
|
+
"data-role": "empty-state",
|
|
1919
|
+
"data-tone": tone,
|
|
1920
|
+
...className === void 0 ? {} : { className }
|
|
1921
|
+
}, (0, react.createElement)("h2", { "data-role": "empty-title" }, title), description === void 0 || description === "" ? null : (0, react.createElement)("p", { "data-role": "empty-description" }, description), actions);
|
|
1922
|
+
}
|
|
1923
|
+
//#endregion
|
|
1924
|
+
//#region ../evolution-client-kit/src/presentation/disclosure-group.ts
|
|
1925
|
+
/** A native details group for normal/secondary facts. */
|
|
1926
|
+
//#endregion
|
|
1927
|
+
//#region ../evolution-client-kit/src/presentation/time-text.ts
|
|
1928
|
+
/** The one local-time presentation used by reading surfaces. */
|
|
1929
|
+
//#endregion
|
|
1930
|
+
//#region ../evolution-client-kit/src/presentation/action-menu.ts
|
|
1931
|
+
/**
|
|
1932
|
+
* The one seam onto the platform's menu material, plus a small fallback for deployments
|
|
1933
|
+
* without the primitive row. No page owns a second menu implementation.
|
|
1934
|
+
*/
|
|
1935
|
+
const PLATFORM_UI_MODULE$1 = "@deepseek-ai/dsh-client-ui-primitives";
|
|
1936
|
+
/**
|
|
1937
|
+
* Accept only the two component functions; a namespace row without them is not a menu.
|
|
1938
|
+
* @param row - the module row's exports.
|
|
1939
|
+
* @returns the two components, or undefined.
|
|
1940
|
+
*/
|
|
1941
|
+
function menuPrimitivesFrom(row) {
|
|
1942
|
+
const surface = row.MenuSurface;
|
|
1943
|
+
const item = row.MenuItemButton;
|
|
1944
|
+
if (typeof surface !== "function" || typeof item !== "function") return void 0;
|
|
1945
|
+
return {
|
|
1946
|
+
MenuSurface: surface,
|
|
1947
|
+
MenuItemButton: item
|
|
1948
|
+
};
|
|
1949
|
+
}
|
|
1950
|
+
(() => {
|
|
1951
|
+
try {
|
|
1952
|
+
return menuPrimitivesFrom(require(PLATFORM_UI_MODULE$1));
|
|
1953
|
+
} catch {
|
|
1954
|
+
return;
|
|
1955
|
+
}
|
|
1956
|
+
})();
|
|
1957
|
+
//#endregion
|
|
1783
1958
|
//#region ../evolution-client-kit/src/action.ts
|
|
1784
1959
|
/**
|
|
1785
1960
|
* Command-only actions. Approval decisions are a separate host API and must never
|
|
@@ -2089,6 +2264,8 @@ window.__ModuleLoader__.load({
|
|
|
2089
2264
|
const CSS$1 = [
|
|
2090
2265
|
tokenVars(".evolution-params,.evolution-param-card"),
|
|
2091
2266
|
".evolution-params{display:flex;flex-direction:column}",
|
|
2267
|
+
".evolution-settings-tab{display:flex;flex-direction:column;gap:var(--evo-space-8)}",
|
|
2268
|
+
".evolution-settings-group{margin:var(--evo-space-12) 0 0;font-size:var(--evo-type-sm);font-weight:600;color:var(--dsw-alias-label-secondary)}",
|
|
2092
2269
|
".evolution-params-title{margin:0 0 var(--evo-space-4);color:var(--dsw-alias-label-primary);font-size:var(--evo-type-lg);font-weight:600;line-height:var(--evo-leading-base)}",
|
|
2093
2270
|
".evolution-params-subtitle{margin:0 0 var(--evo-space-16);color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}",
|
|
2094
2271
|
".evolution-params-about{margin:0 0 var(--evo-space-16);color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs)}",
|
|
@@ -2096,7 +2273,7 @@ window.__ModuleLoader__.load({
|
|
|
2096
2273
|
".evolution-param-head{display:flex;align-items:center;gap:var(--evo-space-8);width:100%;padding:var(--evo-space-12) var(--evo-space-14);background:none;border:0;text-align:left;cursor:pointer;color:inherit;font:inherit}",
|
|
2097
2274
|
".evolution-param-head:hover{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
2098
2275
|
".evolution-param-card-title{flex:1;min-width:0;color:var(--dsw-alias-label-primary);font-size:var(--evo-type-sm);font-weight:500;line-height:var(--evo-leading-base)}",
|
|
2099
|
-
".evolution-param-count{color:var(--dsw-alias-
|
|
2276
|
+
".evolution-param-count{color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}",
|
|
2100
2277
|
".evolution-param-chevron{color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);line-height:var(--evo-leading-base)}",
|
|
2101
2278
|
".evolution-param-body{padding:0 var(--evo-space-14) var(--evo-space-12);border-top:var(--evo-hairline-width) solid var(--dsw-alias-border-l2)}",
|
|
2102
2279
|
".evolution-param-dest{color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs)}",
|
|
@@ -2111,7 +2288,10 @@ window.__ModuleLoader__.load({
|
|
|
2111
2288
|
".evolution-param-input:focus-visible{outline:var(--evo-focus-ring);outline-offset:var(--evo-focus-offset)}",
|
|
2112
2289
|
".evolution-param-input:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}",
|
|
2113
2290
|
".evolution-param-source{display:inline-flex;align-items:center;height:var(--evo-space-20);padding:0 var(--evo-space-6);border-radius:var(--evo-radius-chip);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);font-size:var(--evo-type-xs);line-height:var(--evo-space-20)}",
|
|
2114
|
-
".evolution-param-source[data-user=\"true\"]{background:var(--dsw-alias-
|
|
2291
|
+
".evolution-param-source[data-user=\"true\"]{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-size:var(--evo-type-xs)}",
|
|
2292
|
+
".evolution-param-reset{margin-left:auto;padding:0;border:0;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:var(--evo-type-xs);cursor:pointer}",
|
|
2293
|
+
".evolution-param-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}",
|
|
2294
|
+
".evolution-param-reset:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}",
|
|
2115
2295
|
".evolution-param-actions{display:flex;justify-content:flex-end;gap:var(--evo-space-8);padding-top:var(--evo-space-12)}",
|
|
2116
2296
|
".evolution-param-button{padding:var(--evo-space-6) var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font-size:var(--evo-type-sm);line-height:var(--evo-leading-base);cursor:pointer}",
|
|
2117
2297
|
".evolution-param-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}",
|
|
@@ -2120,6 +2300,32 @@ window.__ModuleLoader__.load({
|
|
|
2120
2300
|
".evolution-param-button[data-primary=\"true\"]{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-color:transparent}",
|
|
2121
2301
|
".evolution-param-button[data-primary=\"true\"]:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}",
|
|
2122
2302
|
".evolution-param-button:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}",
|
|
2303
|
+
".evolution-approval-item{padding:var(--evo-space-10) 0;border-top:var(--evo-hairline-width) solid var(--dsw-alias-border-l2)}",
|
|
2304
|
+
".evolution-approval-item:first-of-type{border-top:0}",
|
|
2305
|
+
".evolution-approval-decision{display:flex;flex-direction:column;gap:var(--evo-space-8);padding:var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-1)}",
|
|
2306
|
+
".evolution-approval-decision [data-role=\"decision-title\"]{margin:0;font-size:var(--evo-type-sm);font-weight:600;line-height:var(--evo-leading-base)}",
|
|
2307
|
+
".evolution-approval-decision [data-role=\"decision-summary\"]{margin:0;color:var(--dsw-alias-label-secondary);font-size:var(--evo-type-xs)}",
|
|
2308
|
+
".evolution-approval-decision [data-role=\"decision-facts\"]{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:var(--evo-space-4) var(--evo-space-12);margin:0;font-size:var(--evo-type-xs)}",
|
|
2309
|
+
".evolution-approval-decision [data-role=\"decision-fact\"]{display:contents}",
|
|
2310
|
+
".evolution-approval-decision dt{color:var(--dsw-alias-label-tertiary)}",
|
|
2311
|
+
".evolution-approval-decision dd{margin:0;color:var(--dsw-alias-label-primary);min-width:0;overflow-wrap:anywhere}",
|
|
2312
|
+
".evolution-approval-decision [data-role=\"decision-actions\"]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--evo-space-8);padding-top:var(--evo-space-8)}",
|
|
2313
|
+
".evolution-approval-decision [data-role=\"decision-primary\"],.evolution-approval-decision [data-role=\"decision-secondary\"]{padding:var(--evo-space-6) var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font-size:var(--evo-type-sm);cursor:pointer}",
|
|
2314
|
+
".evolution-approval-decision [data-role=\"decision-primary\"]{background:var(--dsw-alias-button-primary-fill);border-color:transparent;color:var(--dsw-alias-label-primary-foreground)}",
|
|
2315
|
+
".evolution-approval-decision [data-role=\"decision-primary\"]:disabled,.evolution-approval-decision [data-role=\"decision-secondary\"]:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}",
|
|
2316
|
+
".evolution-approval-decision [data-role=\"decision-details\"] details{margin:0}",
|
|
2317
|
+
".evolution-approval-decision [data-role=\"decision-details\"] summary{cursor:pointer;color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs)}",
|
|
2318
|
+
".evolution-approval-item [data-role=\"empty-state\"]{padding:var(--evo-space-20) var(--evo-space-16);text-align:center}",
|
|
2319
|
+
".evolution-approval-item [data-role=\"empty-title\"]{margin:0 0 var(--evo-space-6);font-size:var(--evo-type-lg)}",
|
|
2320
|
+
".evolution-approval-item [data-role=\"empty-description\"]{margin:0 auto var(--evo-space-12);max-width:34em;color:var(--dsw-alias-label-secondary);font-size:var(--evo-type-sm)}",
|
|
2321
|
+
".evolution-approval-item [data-role=\"empty-actions\"]{display:flex;justify-content:center;gap:var(--evo-space-8)}",
|
|
2322
|
+
".evolution-approval-item [data-role=\"empty-primary\"]{padding:var(--evo-space-6) var(--evo-space-12);border:0;border-radius:var(--evo-radius-control);background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);font-size:var(--evo-type-sm);cursor:pointer}",
|
|
2323
|
+
".evolution-approval-item [data-role=\"empty-secondary\"]{padding:var(--evo-space-6) var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:var(--evo-type-sm);cursor:pointer}",
|
|
2324
|
+
".evo-diag-issue{padding:var(--evo-space-10) var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-state-warn-primary);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-1)}",
|
|
2325
|
+
".evo-diag-issue[data-status=\"fail\"]{border-color:var(--dsw-alias-state-error-primary)}",
|
|
2326
|
+
".evo-diag-complete{padding:var(--evo-space-10) var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-state-success-primary);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-state-success-primary)}",
|
|
2327
|
+
".evo-diag-group{display:flex;flex-direction:column;gap:var(--evo-space-4);margin-top:var(--evo-space-8)}",
|
|
2328
|
+
".evo-diag-group>summary{cursor:pointer;color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs)}",
|
|
2123
2329
|
".evolution-param-select{width:100%;box-sizing:border-box;padding:var(--evo-space-8) var(--evo-space-10);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:var(--evo-type-sm);line-height:var(--evo-leading-base)}",
|
|
2124
2330
|
".evolution-param-select:focus-visible{outline:var(--evo-focus-ring);outline-offset:var(--evo-focus-offset)}",
|
|
2125
2331
|
".evolution-param-select:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}",
|
|
@@ -2255,10 +2461,14 @@ window.__ModuleLoader__.load({
|
|
|
2255
2461
|
}
|
|
2256
2462
|
/** One family tab: every parameter card lives inside the platform's Plugins page. */
|
|
2257
2463
|
function EvolutionSettingsTab(props) {
|
|
2258
|
-
return (0, react.createElement)("div", { className: "evolution-settings-tab" }, ...props.cards.
|
|
2464
|
+
return (0, react.createElement)("div", { className: "evolution-settings-tab" }, ...groupParamCards(props.cards).flatMap(({ group, items }) => [(0, react.createElement)("h3", {
|
|
2465
|
+
key: "group-" + group,
|
|
2466
|
+
className: "evolution-settings-group",
|
|
2467
|
+
"data-role": "settings-group"
|
|
2468
|
+
}, message("group." + group)), ...items.map((face, index) => (0, react.createElement)(PluginParamCard, {
|
|
2259
2469
|
key: face.namespace + ":" + String(index),
|
|
2260
2470
|
...face
|
|
2261
|
-
})));
|
|
2471
|
+
}))]));
|
|
2262
2472
|
}
|
|
2263
2473
|
//#endregion
|
|
2264
2474
|
//#region ../evolution-client-kit/src/generated/route-client.generated.ts
|
|
@@ -2602,7 +2812,7 @@ window.__ModuleLoader__.load({
|
|
|
2602
2812
|
const viewKind = state.view.kind;
|
|
2603
2813
|
const rowCount = state.view.kind === "ready" ? state.view.rows.length : 0;
|
|
2604
2814
|
(0, react.useEffect)(() => {
|
|
2605
|
-
if (viewKind === "empty") setOpen(
|
|
2815
|
+
if (viewKind === "empty") setOpen(true);
|
|
2606
2816
|
else if (viewKind === "ready" && rowCount > 0) setOpen(true);
|
|
2607
2817
|
}, [viewKind, rowCount]);
|
|
2608
2818
|
const latest = (0, react.useRef)(state);
|
|
@@ -2754,81 +2964,115 @@ window.__ModuleLoader__.load({
|
|
|
2754
2964
|
};
|
|
2755
2965
|
const summaryLine = (entry) => entry.verb === void 0 || entry.target === void 0 ? entry.summary : t(VERB_KEYS[entry.verb] ?? "approvalVerbUpdate") + " " + entry.target + (entry.operationCount !== void 0 && entry.operationCount > 1 ? " ×" + String(entry.operationCount) : "");
|
|
2756
2966
|
const row = (entry) => {
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2967
|
+
const busy = state.busy.includes(entry.id);
|
|
2968
|
+
const executing = entry.status === "executing";
|
|
2969
|
+
const confirming = armed === entry.id;
|
|
2970
|
+
const title = summaryLine(entry);
|
|
2971
|
+
const facts = [
|
|
2972
|
+
{
|
|
2973
|
+
label: t("approvalFactKind"),
|
|
2974
|
+
value: t(KIND_KEYS[entry.kind])
|
|
2975
|
+
},
|
|
2976
|
+
{
|
|
2977
|
+
label: t("approvalFactAge"),
|
|
2978
|
+
value: age(entry)
|
|
2979
|
+
},
|
|
2980
|
+
...entry.target === void 0 ? [] : [{
|
|
2981
|
+
label: t("approvalFactTarget"),
|
|
2982
|
+
value: entry.target
|
|
2983
|
+
}]
|
|
2984
|
+
];
|
|
2985
|
+
const raw = title === entry.summary ? void 0 : (0, react.createElement)("details", { className: "evolution-param-details" }, (0, react.createElement)("summary", null, t("approvalRawSummary")), (0, react.createElement)("p", { className: "evolution-param-hint" }, entry.summary));
|
|
2986
|
+
const previewAction = {
|
|
2987
|
+
id: "preview-" + entry.id,
|
|
2988
|
+
label: state.open === entry.id ? t("approvalPreviewClose") : t("approvalPreview"),
|
|
2989
|
+
onSelect: () => {
|
|
2990
|
+
togglePreview(entry.id);
|
|
2991
|
+
}
|
|
2992
|
+
};
|
|
2993
|
+
const primary = executing ? {
|
|
2994
|
+
id: "release-" + entry.id,
|
|
2995
|
+
label: busy ? t("approvalReleasing") : t("approvalRelease"),
|
|
2996
|
+
disabled: busy,
|
|
2997
|
+
onSelect: () => {
|
|
2771
2998
|
decide(entry.id, "release");
|
|
2772
2999
|
}
|
|
2773
|
-
}
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
3000
|
+
} : confirming ? {
|
|
3001
|
+
id: "confirm-" + entry.id,
|
|
3002
|
+
label: t("approvalConfirmYes"),
|
|
3003
|
+
attributes: { "data-confirm": "yes" },
|
|
3004
|
+
onSelect: () => {
|
|
3005
|
+
setArmed(null);
|
|
3006
|
+
decide(entry.id, "approve");
|
|
3007
|
+
}
|
|
3008
|
+
} : {
|
|
3009
|
+
id: "approve-" + entry.id,
|
|
3010
|
+
label: busy ? t("approvalApproving") : t("approvalApprove"),
|
|
2778
3011
|
disabled: busy,
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
if (action === "approve" && confirmMode === "ask" && armed !== entry.id) {
|
|
3012
|
+
onSelect: () => {
|
|
3013
|
+
if (confirmMode === "ask") {
|
|
2782
3014
|
setArmed(entry.id);
|
|
2783
3015
|
return;
|
|
2784
3016
|
}
|
|
2785
|
-
setArmed(null);
|
|
2786
|
-
decide(entry.id, action);
|
|
2787
|
-
}
|
|
2788
|
-
}, busy ? t(action === "approve" ? "approvalApproving" : "approvalRejecting") : t(label));
|
|
2789
|
-
return (0, react.createElement)("div", {
|
|
2790
|
-
className: "evolution-param-field",
|
|
2791
|
-
key: entry.id
|
|
2792
|
-
}, (0, react.createElement)("div", { className: "evolution-param-label" }, (0, react.createElement)("span", { className: "evolution-param-source" }, t(KIND_KEYS[entry.kind])), (0, react.createElement)("span", {
|
|
2793
|
-
className: "evolution-param-value",
|
|
2794
|
-
title: entry.summary
|
|
2795
|
-
}, summaryLine(entry))), (0, react.createElement)("p", { className: "evolution-param-hint" }, age(entry)), summaryLine(entry) === entry.summary ? null : (0, react.createElement)("details", { className: "evolution-param-details" }, (0, react.createElement)("summary", null, t("approvalRawSummary")), (0, react.createElement)("p", { className: "evolution-param-hint" }, entry.summary)), armed === entry.id ? (0, react.createElement)("p", {
|
|
2796
|
-
className: "evolution-param-note",
|
|
2797
|
-
role: "status"
|
|
2798
|
-
}, (0, react.createElement)("span", { className: "evolution-param-value" }, t("approvalConfirmNamed", { n: summaryLine(entry) })), (0, react.createElement)("button", {
|
|
2799
|
-
className: "evolution-param-button",
|
|
2800
|
-
type: "button",
|
|
2801
|
-
"data-confirm": "yes",
|
|
2802
|
-
"data-primary": "true",
|
|
2803
|
-
onClick: () => {
|
|
2804
|
-
setArmed(null);
|
|
2805
3017
|
decide(entry.id, "approve");
|
|
2806
3018
|
}
|
|
2807
|
-
}
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
3019
|
+
};
|
|
3020
|
+
const secondary = executing ? [] : confirming ? [{
|
|
3021
|
+
id: "cancel-" + entry.id,
|
|
3022
|
+
label: t("approvalConfirmNo"),
|
|
3023
|
+
onSelect: () => {
|
|
2812
3024
|
setArmed(null);
|
|
2813
3025
|
}
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
3026
|
+
}] : [{
|
|
3027
|
+
id: "reject-" + entry.id,
|
|
3028
|
+
label: busy ? t("approvalRejecting") : t("approvalReject"),
|
|
3029
|
+
disabled: busy,
|
|
3030
|
+
onSelect: () => {
|
|
3031
|
+
decide(entry.id, "reject");
|
|
2820
3032
|
}
|
|
2821
|
-
},
|
|
3033
|
+
}, previewAction];
|
|
3034
|
+
const summary = executing ? t("approvalExecuting") : confirming ? t("approvalConfirmNamed", { n: title }) : void 0;
|
|
3035
|
+
return (0, react.createElement)("div", {
|
|
3036
|
+
className: "evolution-approval-item",
|
|
3037
|
+
key: entry.id
|
|
3038
|
+
}, (0, react.createElement)(DecisionFrame, {
|
|
3039
|
+
className: "evolution-approval-decision",
|
|
3040
|
+
decision: {
|
|
3041
|
+
title,
|
|
3042
|
+
...summary === void 0 ? {} : { summary },
|
|
3043
|
+
facts,
|
|
3044
|
+
primary,
|
|
3045
|
+
...secondary.length === 0 ? {} : { secondary },
|
|
3046
|
+
...raw === void 0 ? {} : { details: raw }
|
|
3047
|
+
}
|
|
3048
|
+
}), state.open === entry.id && state.preview !== null ? preview(state.preview) : null);
|
|
2822
3049
|
};
|
|
2823
3050
|
const body = () => {
|
|
2824
3051
|
if (state.view.kind === "loading") return (0, react.createElement)("p", {
|
|
2825
3052
|
className: "evolution-param-note",
|
|
2826
3053
|
role: "status"
|
|
2827
3054
|
}, t("approvalLoading"));
|
|
2828
|
-
if (state.view.kind === "empty")
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
3055
|
+
if (state.view.kind === "empty") {
|
|
3056
|
+
const primary = props.onHistory === void 0 ? void 0 : {
|
|
3057
|
+
id: "approval-history",
|
|
3058
|
+
label: t("approvalHistory"),
|
|
3059
|
+
onSelect: props.onHistory
|
|
3060
|
+
};
|
|
3061
|
+
return (0, react.createElement)("div", { role: "status" }, (0, react.createElement)(EmptyState, {
|
|
3062
|
+
title: t("approvalEmpty"),
|
|
3063
|
+
description: t("approvalEmptyDescription"),
|
|
3064
|
+
tone: "ok",
|
|
3065
|
+
...primary === void 0 ? {} : { primary },
|
|
3066
|
+
secondary: {
|
|
3067
|
+
id: "approval-refresh",
|
|
3068
|
+
label: state.refreshing ? t("diagRefreshing") : t("approvalRefresh"),
|
|
3069
|
+
busy: state.refreshing,
|
|
3070
|
+
onSelect: () => {
|
|
3071
|
+
load();
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
}));
|
|
3075
|
+
}
|
|
2832
3076
|
if (state.view.kind === "failed") return (0, react.createElement)("div", { className: "evolution-param-actions" }, FailureBlock({
|
|
2833
3077
|
failure: state.view.failure,
|
|
2834
3078
|
t: translate,
|
|
@@ -2858,10 +3102,7 @@ window.__ModuleLoader__.load({
|
|
|
2858
3102
|
setOpen(!open);
|
|
2859
3103
|
},
|
|
2860
3104
|
"aria-expanded": open
|
|
2861
|
-
}, (0, react.createElement)("span", { className: "evolution-param-card-title" }, t("approvalTitle")), state.view.kind === "empty" ? (0, react.createElement)("
|
|
2862
|
-
className: "evolution-param-count",
|
|
2863
|
-
role: "status"
|
|
2864
|
-
}, t("approvalEmpty")) : null, waiting === 0 ? null : (0, react.createElement)("span", { className: "evolution-param-count" }, t("approvalCount", { n: waiting })), running === 0 ? null : (0, react.createElement)("span", { className: "evolution-param-count" }, t("approvalRunningCount", { n: running })), (0, react.createElement)("span", { className: "evolution-param-chevron" }, open ? "▲" : "▼")), (0, react.createElement)("div", { className: "evolution-param-actions" }, (0, react.createElement)("button", {
|
|
3105
|
+
}, (0, react.createElement)("span", { className: "evolution-param-card-title" }, t("approvalTitle")), waiting === 0 ? null : (0, react.createElement)("span", { className: "evolution-param-count" }, t("approvalCount", { n: waiting })), running === 0 ? null : (0, react.createElement)("span", { className: "evolution-param-count" }, t("approvalRunningCount", { n: running })), (0, react.createElement)("span", { className: "evolution-param-chevron" }, open ? "▲" : "▼")), state.view.kind === "empty" ? null : (0, react.createElement)("div", { className: "evolution-param-actions" }, (0, react.createElement)("button", {
|
|
2865
3106
|
className: "evolution-param-button",
|
|
2866
3107
|
type: "button",
|
|
2867
3108
|
disabled: state.refreshing,
|
|
@@ -2903,6 +3144,8 @@ window.__ModuleLoader__.load({
|
|
|
2903
3144
|
const zh = {
|
|
2904
3145
|
"entry.label": "技能历史",
|
|
2905
3146
|
title: "技能历史",
|
|
3147
|
+
bodyTitle: "正文版本",
|
|
3148
|
+
"workbench.title": "自进化",
|
|
2906
3149
|
"workbench.history": "技能历史",
|
|
2907
3150
|
"workbench.pending": "待批",
|
|
2908
3151
|
"workbench.merge": "合并",
|
|
@@ -2912,6 +3155,8 @@ window.__ModuleLoader__.load({
|
|
|
2912
3155
|
search: "按名字或描述筛选",
|
|
2913
3156
|
"search.none": "没有匹配的技能。",
|
|
2914
3157
|
"group.content": "正文版本",
|
|
3158
|
+
"group.current": "当前版本",
|
|
3159
|
+
"group.history": "历史版本",
|
|
2915
3160
|
"group.support": "文件版本(不可回退)",
|
|
2916
3161
|
"group.support.note": "附带文件的字节与正文共用一份索引;回退不恢复它们。",
|
|
2917
3162
|
"empty.skills": "还没有技能留下过内容版本。",
|
|
@@ -2932,7 +3177,9 @@ window.__ModuleLoader__.load({
|
|
|
2932
3177
|
"failure.server": "读取失败,可以重试。",
|
|
2933
3178
|
"fallback.hint": "可以改用命令:{command}",
|
|
2934
3179
|
"undo.confirm": "确认回退(会写入一版,可再回退)",
|
|
3180
|
+
"undo.confirmUnit": "确认回退整个跨技能写入单元(会写入一版,可再回退)",
|
|
2935
3181
|
"undo.no": "取消",
|
|
3182
|
+
more: "更多",
|
|
2936
3183
|
current: "当前",
|
|
2937
3184
|
"versions.count": "{n} 个版本",
|
|
2938
3185
|
"row.version": "v{n}",
|
|
@@ -2942,8 +3189,8 @@ window.__ModuleLoader__.load({
|
|
|
2942
3189
|
"row.delta.down": "(-{n} 字符)",
|
|
2943
3190
|
"diff.show": "差异",
|
|
2944
3191
|
"diff.source": "源码",
|
|
2945
|
-
"preview.show": "
|
|
2946
|
-
"preview.hide": "
|
|
3192
|
+
"preview.show": "查看正文",
|
|
3193
|
+
"preview.hide": "收起正文",
|
|
2947
3194
|
"preview.truncated": "正文过长:只显示前 {shown} 个字符(共 {total} 个)",
|
|
2948
3195
|
"path.unrecorded": "(路径未记录)",
|
|
2949
3196
|
"diff.rendered": "渲染",
|
|
@@ -2972,6 +3219,7 @@ window.__ModuleLoader__.load({
|
|
|
2972
3219
|
"action.archive": "归档",
|
|
2973
3220
|
"action.archive.note": "这一版存的是被归档的正文",
|
|
2974
3221
|
"action.consolidate": "合并",
|
|
3222
|
+
"action.merge": "合并",
|
|
2975
3223
|
"action.restructure": "结构调整",
|
|
2976
3224
|
"action.extract": "跨技能提取",
|
|
2977
3225
|
"action.support-write": "写入附带文件",
|
|
@@ -2995,6 +3243,8 @@ window.__ModuleLoader__.load({
|
|
|
2995
3243
|
const en = {
|
|
2996
3244
|
"entry.label": "Skill history",
|
|
2997
3245
|
title: "Skill history",
|
|
3246
|
+
bodyTitle: "Body versions",
|
|
3247
|
+
"workbench.title": "Self-evolution",
|
|
2998
3248
|
"workbench.history": "Skill history",
|
|
2999
3249
|
"workbench.pending": "Pending",
|
|
3000
3250
|
"workbench.merge": "Merge",
|
|
@@ -3004,6 +3254,8 @@ window.__ModuleLoader__.load({
|
|
|
3004
3254
|
search: "Filter by name or description",
|
|
3005
3255
|
"search.none": "No skill matches.",
|
|
3006
3256
|
"group.content": "Body versions",
|
|
3257
|
+
"group.current": "Current version",
|
|
3258
|
+
"group.history": "History",
|
|
3007
3259
|
"group.support": "File versions (not restorable)",
|
|
3008
3260
|
"group.support.note": "Support-file bytes share this index with the body; restoring the body does not bring them back.",
|
|
3009
3261
|
"empty.skills": "No skill has recorded a content version yet.",
|
|
@@ -3024,7 +3276,9 @@ window.__ModuleLoader__.load({
|
|
|
3024
3276
|
"failure.server": "The read failed; you can retry.",
|
|
3025
3277
|
"fallback.hint": "Command fallback: {command}",
|
|
3026
3278
|
"undo.confirm": "Confirm restore (writes a new version; can be undone)",
|
|
3279
|
+
"undo.confirmUnit": "Confirm restoring the whole cross-skill unit (writes a new version; can be undone)",
|
|
3027
3280
|
"undo.no": "Cancel",
|
|
3281
|
+
more: "More",
|
|
3028
3282
|
current: "Current",
|
|
3029
3283
|
"versions.count": "{n} versions",
|
|
3030
3284
|
"row.version": "v{n}",
|
|
@@ -3034,8 +3288,8 @@ window.__ModuleLoader__.load({
|
|
|
3034
3288
|
"row.delta.down": "(-{n} chars)",
|
|
3035
3289
|
"diff.show": "Diff",
|
|
3036
3290
|
"diff.source": "Source",
|
|
3037
|
-
"preview.show": "
|
|
3038
|
-
"preview.hide": "Hide
|
|
3291
|
+
"preview.show": "View body",
|
|
3292
|
+
"preview.hide": "Hide body",
|
|
3039
3293
|
"preview.truncated": "the body is long: showing the first {shown} of {total} characters",
|
|
3040
3294
|
"path.unrecorded": "(path not recorded)",
|
|
3041
3295
|
"diff.rendered": "Rendered",
|
|
@@ -3064,6 +3318,7 @@ window.__ModuleLoader__.load({
|
|
|
3064
3318
|
"action.archive": "archived",
|
|
3065
3319
|
"action.archive.note": "this version holds the archived body",
|
|
3066
3320
|
"action.consolidate": "merged",
|
|
3321
|
+
"action.merge": "merged",
|
|
3067
3322
|
"action.restructure": "restructured",
|
|
3068
3323
|
"action.extract": "extracted across skills",
|
|
3069
3324
|
"action.support-write": "support file written",
|
|
@@ -3130,6 +3385,7 @@ window.__ModuleLoader__.load({
|
|
|
3130
3385
|
".evo-hist-skill[aria-current=\"true\"]{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);font-weight:500}",
|
|
3131
3386
|
".evo-hist-cell-line{display:flex;align-items:baseline;gap:var(--evo-space-6);min-width:0}",
|
|
3132
3387
|
".evo-hist-cell-meta{margin-top:var(--evo-space-2)}",
|
|
3388
|
+
".evo-hist-skill-description{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-top:var(--evo-space-2);color:var(--dsw-alias-label-tertiary)}",
|
|
3133
3389
|
".evo-hist-cell{min-width:0;font-variant-numeric:tabular-nums}",
|
|
3134
3390
|
".evo-hist-slot-lead{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
|
|
3135
3391
|
".evo-hist-slot-meta{flex:none;white-space:nowrap}",
|
|
@@ -3146,12 +3402,23 @@ window.__ModuleLoader__.load({
|
|
|
3146
3402
|
".evo-hist-note[data-error=\"true\"]{color:var(--evo-tone-danger);background:var(--dsw-alias-bg-layer-2);border:var(--evo-hairline-width) solid var(--evo-tone-danger);border-radius:var(--evo-radius-control);padding:var(--evo-space-8) var(--evo-space-10)}",
|
|
3147
3403
|
".evo-hist-icon{flex:none;margin-top:.15em}",
|
|
3148
3404
|
".evo-hist-group{margin:var(--evo-space-16) 0 var(--evo-space-4);font-size:var(--evo-type-sm);font-weight:600;color:var(--dsw-alias-label-secondary)}",
|
|
3149
|
-
".evo-hist-
|
|
3405
|
+
".evo-hist-reader{max-width:calc(var(--evo-measure-read) * 1.5);margin-top:var(--evo-space-8);padding:var(--evo-space-12);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:var(--dsw-alias-bg-layer-1)}",
|
|
3406
|
+
".evo-hist-current{padding-bottom:var(--evo-space-6)}",
|
|
3407
|
+
".evo-hist-current .evo-hist-group{margin-top:0}",
|
|
3408
|
+
".evo-hist-current .evo-hist-row{max-width:none}",
|
|
3409
|
+
".evo-hist-reader .evo-hist-group{margin-top:var(--evo-space-12)}",
|
|
3410
|
+
".evo-hist-row{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:\"body actions\" \"expanded expanded\";align-items:start;gap:var(--evo-space-4) var(--evo-space-8);padding:var(--evo-space-8) 0;border-top:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);max-width:calc(var(--evo-measure-read) * 1.5);color:var(--dsw-alias-label-primary)}",
|
|
3150
3411
|
".evo-hist-row:first-of-type{border-top:0}",
|
|
3151
|
-
".evo-hist-row-body{
|
|
3412
|
+
".evo-hist-row-body{grid-area:body;min-width:0}",
|
|
3152
3413
|
".evo-hist-row-title{display:flex;align-items:baseline;gap:var(--evo-space-8);min-width:0}",
|
|
3153
3414
|
".evo-hist-row-summary{margin-top:var(--evo-space-2);line-height:var(--evo-leading-base)}",
|
|
3154
|
-
".evo-hist-actions{display:flex;
|
|
3415
|
+
".evo-hist-actions{grid-area:actions;display:flex;align-items:center;gap:var(--evo-space-6)}",
|
|
3416
|
+
".evo-hist-row-expanded{grid-area:expanded;min-width:0}",
|
|
3417
|
+
".evo-hist-more{position:relative;display:inline-flex;align-items:center}",
|
|
3418
|
+
".evo-hist-more>summary{list-style:none;cursor:pointer;color:var(--dsw-alias-label-tertiary);font-size:var(--evo-type-xs);padding:var(--evo-space-2) var(--evo-space-4)}",
|
|
3419
|
+
".evo-hist-more>summary::-webkit-details-marker{display:none}",
|
|
3420
|
+
".evo-hist-more[open]>summary{color:var(--dsw-alias-label-secondary)}",
|
|
3421
|
+
".evo-hist-more>button{margin-left:var(--evo-space-2)}",
|
|
3155
3422
|
".evo-hist-chip{flex:none;padding:var(--evo-space-2) var(--evo-space-8);border-radius:var(--evo-radius-pill);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}",
|
|
3156
3423
|
".evo-hist-button{display:inline-flex;flex:none;align-items:center;gap:var(--evo-space-2);font:inherit;padding:var(--evo-space-4) var(--evo-space-10);border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2);border-radius:var(--evo-radius-control);background:transparent;color:var(--evo-tone-quiet);cursor:pointer}",
|
|
3157
3424
|
".evo-hist-button[data-kind=\"toggle\"],.evo-hist-button[data-kind=\"switch\"]{padding:var(--evo-space-2) var(--evo-space-4);border-color:transparent;color:var(--evo-tone-quiet)}",
|
|
@@ -3173,7 +3440,8 @@ window.__ModuleLoader__.load({
|
|
|
3173
3440
|
".evo-doc-tag{position:absolute;left:var(--evo-space-8);top:var(--evo-space-8);color:var(--dsw-alias-label-tertiary)}",
|
|
3174
3441
|
".evo-doc-line-add{color:var(--evo-tone-success)}",
|
|
3175
3442
|
".evo-doc-line-del{color:var(--evo-tone-danger)}",
|
|
3176
|
-
"@media (max-width:
|
|
3443
|
+
"@media (max-width:1100px){.evo-hist-row{grid-template-columns:minmax(0,1fr);grid-template-areas:\"body\" \"actions\" \"expanded\"}.evo-hist-actions{flex-wrap:wrap;justify-content:flex-start}}",
|
|
3444
|
+
"@media (max-width:900px){.evo-hist-root{flex-direction:column}.evo-hist-aside{flex:0 0 auto;width:100%;max-height:42%;border-right:0;border-bottom:var(--evo-hairline-width) solid var(--dsw-alias-border-l2)}.evo-hist-row{max-width:none}}"
|
|
3177
3445
|
].join("\n");
|
|
3178
3446
|
//#endregion
|
|
3179
3447
|
//#region src/panels/history/client/atoms.ts
|
|
@@ -3281,11 +3549,7 @@ window.__ModuleLoader__.load({
|
|
|
3281
3549
|
*/
|
|
3282
3550
|
/** The local time an ISO timestamp names, as the operator's own clock shows it. */
|
|
3283
3551
|
function localTime(at) {
|
|
3284
|
-
|
|
3285
|
-
if (Number.isNaN(parsed)) return at;
|
|
3286
|
-
const date = new Date(parsed);
|
|
3287
|
-
const pad = (value) => String(value).padStart(2, "0");
|
|
3288
|
-
return String(date.getFullYear()) + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes());
|
|
3552
|
+
return formatLocalDateTime(at, { seconds: false }) ?? at;
|
|
3289
3553
|
}
|
|
3290
3554
|
/** The text one cell shows, resolved through the seat. */
|
|
3291
3555
|
function cellText(copy, cell) {
|
|
@@ -3334,7 +3598,11 @@ window.__ModuleLoader__.load({
|
|
|
3334
3598
|
className: "evo-hist-skill",
|
|
3335
3599
|
"aria-current": selected ? "true" : void 0,
|
|
3336
3600
|
onClick: onOpen
|
|
3337
|
-
}, cellLine(row.cells.title, copy, "evo-hist-cell-line"),
|
|
3601
|
+
}, cellLine(row.cells.title, copy, "evo-hist-cell-line"), (() => {
|
|
3602
|
+
const description = row.cells.meta.filter((cell) => cell.key === "description");
|
|
3603
|
+
const facts = row.cells.meta.filter((cell) => cell.key !== "description");
|
|
3604
|
+
return [description.length === 0 ? null : cellLine(description, copy, "evo-hist-cell-line evo-hist-skill-description"), facts.length === 0 ? null : cellLine(facts, copy, "evo-hist-cell-line evo-hist-cell-meta")];
|
|
3605
|
+
})());
|
|
3338
3606
|
}
|
|
3339
3607
|
/**
|
|
3340
3608
|
* One version row: what happened, when, how big — then the controls, then whatever is expanded.
|
|
@@ -3347,46 +3615,73 @@ window.__ModuleLoader__.load({
|
|
|
3347
3615
|
*/
|
|
3348
3616
|
function versionRow(props) {
|
|
3349
3617
|
const { copy, row, confirming, open, expanded, onRestore, onCancel, onToggle } = props;
|
|
3618
|
+
const current = row.undoable === false;
|
|
3350
3619
|
const actions = [];
|
|
3351
|
-
if (
|
|
3620
|
+
if (current) actions.push(chip({
|
|
3352
3621
|
key: "current",
|
|
3353
3622
|
children: copy.t("current")
|
|
3354
3623
|
}));
|
|
3355
|
-
if (
|
|
3356
|
-
if (confirming) actions.push(button({
|
|
3357
|
-
key: "cancel",
|
|
3358
|
-
onClick: onCancel,
|
|
3359
|
-
children: copy.t("undo.no")
|
|
3360
|
-
}));
|
|
3361
|
-
actions.push(button({
|
|
3362
|
-
key: "undo",
|
|
3363
|
-
tone: confirming ? "primary" : "quiet",
|
|
3364
|
-
onClick: onRestore,
|
|
3365
|
-
children: confirming ? copy.t("undo.confirm") : copy.t("undo")
|
|
3366
|
-
}));
|
|
3367
|
-
}
|
|
3368
|
-
if (row.undoable === true || row.charsDelta !== void 0) actions.push(button({
|
|
3369
|
-
key: "diff",
|
|
3370
|
-
kind: "toggle",
|
|
3371
|
-
expanded: open === "diff",
|
|
3372
|
-
onClick: () => {
|
|
3373
|
-
onToggle("diff");
|
|
3374
|
-
},
|
|
3375
|
-
children: open === "diff" ? copy.t("diff.hide") : copy.t("diff.show")
|
|
3376
|
-
}));
|
|
3377
|
-
actions.push(button({
|
|
3624
|
+
if (current) actions.push(button({
|
|
3378
3625
|
key: "preview",
|
|
3379
3626
|
kind: "toggle",
|
|
3627
|
+
tone: "primary",
|
|
3380
3628
|
expanded: open === "preview",
|
|
3381
3629
|
onClick: () => {
|
|
3382
3630
|
onToggle("preview");
|
|
3383
3631
|
},
|
|
3384
3632
|
children: open === "preview" ? copy.t("preview.hide") : copy.t("preview.show")
|
|
3385
3633
|
}));
|
|
3634
|
+
if (current && row.charsDelta !== void 0) actions.push(button({
|
|
3635
|
+
key: "diff",
|
|
3636
|
+
kind: "toggle",
|
|
3637
|
+
expanded: open === "diff",
|
|
3638
|
+
onClick: () => {
|
|
3639
|
+
onToggle("diff");
|
|
3640
|
+
},
|
|
3641
|
+
children: open === "diff" ? copy.t("diff.hide") : copy.t("diff.show")
|
|
3642
|
+
}));
|
|
3643
|
+
if (!current) {
|
|
3644
|
+
actions.push(button({
|
|
3645
|
+
key: "preview",
|
|
3646
|
+
kind: "toggle",
|
|
3647
|
+
expanded: open === "preview",
|
|
3648
|
+
onClick: () => {
|
|
3649
|
+
onToggle("preview");
|
|
3650
|
+
},
|
|
3651
|
+
children: open === "preview" ? copy.t("preview.hide") : copy.t("preview.show")
|
|
3652
|
+
}));
|
|
3653
|
+
const more = [];
|
|
3654
|
+
if (row.undoable === true) {
|
|
3655
|
+
if (confirming) more.push(button({
|
|
3656
|
+
key: "cancel",
|
|
3657
|
+
onClick: onCancel,
|
|
3658
|
+
children: copy.t("undo.no")
|
|
3659
|
+
}));
|
|
3660
|
+
more.push(button({
|
|
3661
|
+
key: "undo",
|
|
3662
|
+
tone: confirming ? "primary" : "quiet",
|
|
3663
|
+
onClick: onRestore,
|
|
3664
|
+
children: confirming ? copy.t(row.unitId === void 0 ? "undo.confirm" : "undo.confirmUnit") : copy.t("undo")
|
|
3665
|
+
}));
|
|
3666
|
+
}
|
|
3667
|
+
if (row.undoable === true || row.charsDelta !== void 0) more.push(button({
|
|
3668
|
+
key: "diff",
|
|
3669
|
+
kind: "toggle",
|
|
3670
|
+
expanded: open === "diff",
|
|
3671
|
+
onClick: () => {
|
|
3672
|
+
onToggle("diff");
|
|
3673
|
+
},
|
|
3674
|
+
children: open === "diff" ? copy.t("diff.hide") : copy.t("diff.show")
|
|
3675
|
+
}));
|
|
3676
|
+
if (more.length > 0) actions.push((0, react.createElement)("details", {
|
|
3677
|
+
key: "more",
|
|
3678
|
+
className: "evo-hist-more"
|
|
3679
|
+
}, (0, react.createElement)("summary", null, copy.t("more")), ...more));
|
|
3680
|
+
}
|
|
3386
3681
|
return (0, react.createElement)("div", {
|
|
3387
3682
|
key: String(row.v),
|
|
3388
3683
|
className: "evo-hist-row"
|
|
3389
|
-
}, (0, react.createElement)("div", { className: "evo-hist-row-body" }, cellLine(row.cells.title, copy, "evo-hist-row-title", { time: localTime(row.at) }), row.cells.meta.length === 0 ? null : cellLine(row.cells.meta, copy, "evo-hist-row-summary")
|
|
3684
|
+
}, (0, react.createElement)("div", { className: "evo-hist-row-body" }, cellLine(row.cells.title, copy, "evo-hist-row-title", { time: localTime(row.at) }), row.cells.meta.length === 0 ? null : cellLine(row.cells.meta, copy, "evo-hist-row-summary")), (0, react.createElement)("div", { className: "evo-hist-actions" }, actions), expanded === null || expanded === void 0 ? null : (0, react.createElement)("div", { className: "evo-hist-row-expanded" }, expanded));
|
|
3390
3685
|
}
|
|
3391
3686
|
/**
|
|
3392
3687
|
* One group's heading, and the note that explains the group.
|
|
@@ -3422,8 +3717,8 @@ window.__ModuleLoader__.load({
|
|
|
3422
3717
|
});
|
|
3423
3718
|
}
|
|
3424
3719
|
/** The pane's heading and its one control. */
|
|
3425
|
-
function panelHead(copy, onRefresh) {
|
|
3426
|
-
return (0, react.createElement)("div", { className: "evo-hist-head" }, (0, react.createElement)("h2", { className: "evo-hist-title" }, copy.t("title")), button({
|
|
3720
|
+
function panelHead(copy, onRefresh, title) {
|
|
3721
|
+
return (0, react.createElement)("div", { className: "evo-hist-head" }, (0, react.createElement)("h2", { className: "evo-hist-title" }, title ?? copy.t("title")), button({
|
|
3427
3722
|
key: "refresh",
|
|
3428
3723
|
title: copy.t("refresh"),
|
|
3429
3724
|
onClick: onRefresh,
|
|
@@ -3684,6 +3979,25 @@ window.__ModuleLoader__.load({
|
|
|
3684
3979
|
] }), toggle), diffView(face, diff.diff, mode));
|
|
3685
3980
|
}
|
|
3686
3981
|
//#endregion
|
|
3982
|
+
//#region src/panels/history/client/history-presentation.ts
|
|
3983
|
+
/**
|
|
3984
|
+
* Split a version payload without inventing a version. The host marks current rows with
|
|
3985
|
+
* `undoable: false`; if an older payload lacks that marker, the first content row is the current one.
|
|
3986
|
+
* @param payload - content and support chains from the host.
|
|
3987
|
+
* @returns the display model.
|
|
3988
|
+
*/
|
|
3989
|
+
function historyViewModel(payload) {
|
|
3990
|
+
const marked = payload.content.filter((row) => row.undoable === false);
|
|
3991
|
+
const current = marked.length > 0 ? marked : payload.content.slice(0, 1);
|
|
3992
|
+
const currentVersions = new Set(current.map((row) => row.v));
|
|
3993
|
+
return {
|
|
3994
|
+
current,
|
|
3995
|
+
older: payload.content.filter((row) => !currentVersions.has(row.v)),
|
|
3996
|
+
support: payload.support,
|
|
3997
|
+
hasAny: payload.content.length > 0 || payload.support.length > 0
|
|
3998
|
+
};
|
|
3999
|
+
}
|
|
4000
|
+
//#endregion
|
|
3687
4001
|
//#region src/panels/history/client/Panel.ts
|
|
3688
4002
|
/**
|
|
3689
4003
|
* The panel: one read, one open skill, one open row — and the faces that draw them.
|
|
@@ -3759,6 +4073,36 @@ window.__ModuleLoader__.load({
|
|
|
3759
4073
|
};
|
|
3760
4074
|
/** The sentence one failed read carries, in ONE place: every reader below reports the same way. */
|
|
3761
4075
|
const failedMessage = (error) => face.t("error") + ": " + (error instanceof Error ? error.message : String(error));
|
|
4076
|
+
/** Load one version body under the shared read ticket; used by the current default and the toggle. */
|
|
4077
|
+
const loadPreview = (name, v) => {
|
|
4078
|
+
const ticket = readTicket.current + 1;
|
|
4079
|
+
readTicket.current = ticket;
|
|
4080
|
+
setBodies((current) => new Map(current).set(v, {
|
|
4081
|
+
kind: "loading",
|
|
4082
|
+
ticket
|
|
4083
|
+
}));
|
|
4084
|
+
face.loadBody(name, v).then((body) => {
|
|
4085
|
+
if (readTicket.current !== ticket) {
|
|
4086
|
+
setBodies((current) => dropIfTicket(current, v, ticket));
|
|
4087
|
+
return;
|
|
4088
|
+
}
|
|
4089
|
+
setBodies((current) => new Map(current).set(v, {
|
|
4090
|
+
kind: "ready",
|
|
4091
|
+
body,
|
|
4092
|
+
ticket
|
|
4093
|
+
}));
|
|
4094
|
+
}).catch((error) => {
|
|
4095
|
+
if (readTicket.current !== ticket) {
|
|
4096
|
+
setBodies((current) => dropIfTicket(current, v, ticket));
|
|
4097
|
+
return;
|
|
4098
|
+
}
|
|
4099
|
+
setBodies((current) => new Map(current).set(v, {
|
|
4100
|
+
kind: "failed",
|
|
4101
|
+
message: failedMessage(error),
|
|
4102
|
+
ticket
|
|
4103
|
+
}));
|
|
4104
|
+
});
|
|
4105
|
+
};
|
|
3762
4106
|
/** Read the skills again, keeping the sentence: a re-read is not an answer to anything. */
|
|
3763
4107
|
const reloadSkills = () => {
|
|
3764
4108
|
face.loadSkills().then((next) => {
|
|
@@ -3787,9 +4131,17 @@ window.__ModuleLoader__.load({
|
|
|
3787
4131
|
setBodies(/* @__PURE__ */ new Map());
|
|
3788
4132
|
}
|
|
3789
4133
|
face.loadVersions(name).then((next) => {
|
|
3790
|
-
if (readTicket.current
|
|
3791
|
-
|
|
3792
|
-
|
|
4134
|
+
if (readTicket.current !== ticket) return;
|
|
4135
|
+
setPayload(next);
|
|
4136
|
+
clearReadFailure();
|
|
4137
|
+
if (keepContent) return;
|
|
4138
|
+
const current = historyViewModel(next).current[0];
|
|
4139
|
+
if (current !== void 0) {
|
|
4140
|
+
setExpanded({
|
|
4141
|
+
v: current.v,
|
|
4142
|
+
kind: "preview"
|
|
4143
|
+
});
|
|
4144
|
+
loadPreview(name, current.v);
|
|
3793
4145
|
}
|
|
3794
4146
|
}).catch((error) => {
|
|
3795
4147
|
if (readTicket.current !== ticket) return;
|
|
@@ -3879,36 +4231,13 @@ window.__ModuleLoader__.load({
|
|
|
3879
4231
|
});
|
|
3880
4232
|
return;
|
|
3881
4233
|
}
|
|
3882
|
-
|
|
3883
|
-
kind: "loading",
|
|
3884
|
-
ticket
|
|
3885
|
-
}));
|
|
3886
|
-
face.loadBody(name, v).then((body) => {
|
|
3887
|
-
if (readTicket.current !== ticket) {
|
|
3888
|
-
setBodies((current) => dropIfTicket(current, v, ticket));
|
|
3889
|
-
return;
|
|
3890
|
-
}
|
|
3891
|
-
setBodies((current) => new Map(current).set(v, {
|
|
3892
|
-
kind: "ready",
|
|
3893
|
-
body,
|
|
3894
|
-
ticket
|
|
3895
|
-
}));
|
|
3896
|
-
}).catch((error) => {
|
|
3897
|
-
if (readTicket.current !== ticket) {
|
|
3898
|
-
setBodies((current) => dropIfTicket(current, v, ticket));
|
|
3899
|
-
return;
|
|
3900
|
-
}
|
|
3901
|
-
setBodies((current) => new Map(current).set(v, {
|
|
3902
|
-
kind: "failed",
|
|
3903
|
-
message: failedMessage(error),
|
|
3904
|
-
ticket
|
|
3905
|
-
}));
|
|
3906
|
-
});
|
|
4234
|
+
loadPreview(name, v);
|
|
3907
4235
|
};
|
|
3908
4236
|
(0, react.useEffect)(reloadSkills, []);
|
|
3909
4237
|
const needle = query.trim().toLowerCase();
|
|
3910
4238
|
const visible = (0, react.useMemo)(() => needle === "" ? skills : skills.filter((skill) => skill.name.toLowerCase().includes(needle) || skill.description.toLowerCase().includes(needle)), [skills, needle]);
|
|
3911
4239
|
const loaded = payload !== void 0;
|
|
4240
|
+
const model = payload === void 0 ? void 0 : historyViewModel(payload);
|
|
3912
4241
|
/** Drop the pending confirmation: the control that opened it must not be the only way out. */
|
|
3913
4242
|
const cancelRestore = () => {
|
|
3914
4243
|
setPending(void 0);
|
|
@@ -3949,10 +4278,26 @@ window.__ModuleLoader__.load({
|
|
|
3949
4278
|
};
|
|
3950
4279
|
return (0, react.createElement)("div", { className: "evo-hist-root" }, (0, react.createElement)("aside", { className: "evo-hist-aside" }, searchField(face, query, setQuery), (0, react.createElement)("div", { className: "evo-hist-list" }, skills.length === 0 ? emptyState(face.t(skillsLoaded ? "empty.skills" : "loading")) : visible.length === 0 ? emptyState(face.t("search.none")) : visible.map((skill) => skillLine(face, skill, skill.name === selected, () => {
|
|
3951
4280
|
open(skill.name);
|
|
3952
|
-
})))), (0, react.createElement)("div", { className: "evo-hist-main" }, panelHead(face, refresh), notice(noteText, noteError), failure === void 0 ? null : (0, react.createElement)("div", { className: "evo-hist-failure" }, failureBlock(face.t, failure)), selected === void 0 ? [emptyState(face.t(skills.length === 0 ? skillsLoaded ? "empty.skills" : "loading" : "empty.pick"), "empty"), (0, react.createElement)("p", {
|
|
4281
|
+
})))), (0, react.createElement)("div", { className: "evo-hist-main" }, panelHead(face, refresh, selected ?? face.t("bodyTitle")), notice(noteText, noteError), failure === void 0 ? null : (0, react.createElement)("div", { className: "evo-hist-failure" }, failureBlock(face.t, failure)), selected === void 0 ? [emptyState(face.t(skills.length === 0 ? skillsLoaded ? "empty.skills" : "loading" : "empty.pick"), "empty"), (0, react.createElement)("p", {
|
|
3953
4282
|
key: "hint",
|
|
3954
4283
|
className: "evo-hist-hint"
|
|
3955
|
-
}, face.t("hint"))] : loaded ? null : emptyState(versionsFailed === void 0 ? face.t("loading") : `${face.t("empty.versions.failed")} — ${versionsFailed}`), loaded ? (0, react.createElement)("div",
|
|
4284
|
+
}, face.t("hint"))] : loaded ? null : emptyState(versionsFailed === void 0 ? face.t("loading") : `${face.t("empty.versions.failed")} — ${versionsFailed}`), loaded && model !== void 0 ? (0, react.createElement)("div", { className: "evo-hist-reader" }, model.current.length === 0 ? null : (0, react.createElement)("section", {
|
|
4285
|
+
key: "current",
|
|
4286
|
+
className: "evo-hist-current"
|
|
4287
|
+
}, ...groupHeading(face.t("group.current"), void 0), ...model.current.map((row) => versionRow({
|
|
4288
|
+
copy: face,
|
|
4289
|
+
row,
|
|
4290
|
+
confirming: pending === row.v,
|
|
4291
|
+
open: expanded !== void 0 && expanded.v === row.v ? expanded.kind : void 0,
|
|
4292
|
+
expanded: expandedOf(row),
|
|
4293
|
+
onRestore: () => {
|
|
4294
|
+
restore(row.v, row.unitId);
|
|
4295
|
+
},
|
|
4296
|
+
onCancel: cancelRestore,
|
|
4297
|
+
onToggle: (kind) => {
|
|
4298
|
+
toggle(row.v, kind);
|
|
4299
|
+
}
|
|
4300
|
+
}))), group(face.t("group.history"), model.older, void 0), model.support.length === 0 ? null : group(face.t("group.support"), model.support, face.t("group.support.note")), model.hasAny ? null : (0, react.createElement)("p", { className: "evo-hist-hint" }, face.t("empty.versions"))) : null));
|
|
3956
4301
|
}
|
|
3957
4302
|
/**
|
|
3958
4303
|
* Drop a superseded lazy read ONLY if the entry still belongs to that read.
|
|
@@ -4000,6 +4345,24 @@ window.__ModuleLoader__.load({
|
|
|
4000
4345
|
fail: "diagSummaryFail",
|
|
4001
4346
|
unknown: "diagSummaryUnknown"
|
|
4002
4347
|
});
|
|
4348
|
+
/**
|
|
4349
|
+
* Split the frozen runtime rows without dropping one. The top issue follows the same fail > warn > unknown order.
|
|
4350
|
+
* @param rows - runtime rows from the host view.
|
|
4351
|
+
* @returns the reading shape used by the card.
|
|
4352
|
+
*/
|
|
4353
|
+
function diagnosticsReading(rows) {
|
|
4354
|
+
const order = [
|
|
4355
|
+
"fail",
|
|
4356
|
+
"warn",
|
|
4357
|
+
"unknown"
|
|
4358
|
+
];
|
|
4359
|
+
const issues = [...rows].filter((row) => row.status !== "ok").sort((a, b) => order.indexOf(a.status) - order.indexOf(b.status));
|
|
4360
|
+
return {
|
|
4361
|
+
topIssue: issues[0],
|
|
4362
|
+
otherIssues: issues.slice(1),
|
|
4363
|
+
normal: rows.filter((row) => row.status === "ok")
|
|
4364
|
+
};
|
|
4365
|
+
}
|
|
4003
4366
|
/** The one status the card leads with: fail > warn > unknown > ok. */
|
|
4004
4367
|
function summaryOf(rows) {
|
|
4005
4368
|
const count = (status) => rows.filter((row) => row.status === status).length;
|
|
@@ -4029,19 +4392,26 @@ window.__ModuleLoader__.load({
|
|
|
4029
4392
|
const translate = (key, values) => t(key, values);
|
|
4030
4393
|
const [state, setState] = (0, react.useState)({ phase: "loading" });
|
|
4031
4394
|
const [refreshing, setRefreshing] = (0, react.useState)(false);
|
|
4395
|
+
const [refreshFailure, setRefreshFailure] = (0, react.useState)(void 0);
|
|
4032
4396
|
const [open, setOpen] = (0, react.useState)(false);
|
|
4033
4397
|
const ticket = (0, react.useRef)(0);
|
|
4034
4398
|
const read = (keepView) => {
|
|
4035
4399
|
const current = ticket.current + 1;
|
|
4036
4400
|
ticket.current = current;
|
|
4037
|
-
if (keepView)
|
|
4038
|
-
|
|
4401
|
+
if (keepView) {
|
|
4402
|
+
setRefreshing(true);
|
|
4403
|
+
setRefreshFailure(void 0);
|
|
4404
|
+
} else setState({ phase: "loading" });
|
|
4039
4405
|
api.view().then((answer) => {
|
|
4040
4406
|
if (ticket.current !== current) return;
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4407
|
+
if (answer.ok) {
|
|
4408
|
+
setState({
|
|
4409
|
+
phase: "ready",
|
|
4410
|
+
view: answer.data
|
|
4411
|
+
});
|
|
4412
|
+
setRefreshFailure(void 0);
|
|
4413
|
+
} else if (keepView) setRefreshFailure(answer.failure);
|
|
4414
|
+
else setState({
|
|
4045
4415
|
phase: "failed",
|
|
4046
4416
|
failure: answer.failure
|
|
4047
4417
|
});
|
|
@@ -4056,6 +4426,7 @@ window.__ModuleLoader__.load({
|
|
|
4056
4426
|
read(true);
|
|
4057
4427
|
};
|
|
4058
4428
|
const summary = state.phase === "ready" ? summaryOf(state.view.runtime) : void 0;
|
|
4429
|
+
const focusRow = summary === void 0 || summary.status === "ok" || state.phase !== "ready" ? void 0 : state.view.runtime.find((row) => row.status === summary.status);
|
|
4059
4430
|
const header = (0, react.createElement)("button", {
|
|
4060
4431
|
type: "button",
|
|
4061
4432
|
className: "evolution-param-head",
|
|
@@ -4066,13 +4437,31 @@ window.__ModuleLoader__.load({
|
|
|
4066
4437
|
}, (0, react.createElement)("span", { className: "evolution-param-card-title" }, t("diagTitle")), summary === void 0 ? null : (0, react.createElement)("span", {
|
|
4067
4438
|
className: "evo-diag-badge",
|
|
4068
4439
|
"data-status": summary.status
|
|
4069
|
-
}, t(SUMMARY_KEYS[summary.status], summary.count === 0 ? void 0 : { n: summary.count })), (0, react.createElement)("span", { className: "evolution-param-chevron" }, open ? "▲" : "▼"));
|
|
4070
|
-
const runtime = (view) =>
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4440
|
+
}, t(SUMMARY_KEYS[summary.status], summary.count === 0 ? void 0 : { n: summary.count })), focusRow === void 0 ? null : (0, react.createElement)("span", { "data-role": "diag-focus" }, focusRow.label), (0, react.createElement)("span", { className: "evolution-param-chevron" }, open ? "▲" : "▼"));
|
|
4441
|
+
const runtime = (view) => {
|
|
4442
|
+
if (view.runtime.length === 0) return null;
|
|
4443
|
+
const reading = diagnosticsReading(view.runtime);
|
|
4444
|
+
const rowNode = (row) => (0, react.createElement)("div", {
|
|
4445
|
+
key: "runtime-" + row.key,
|
|
4446
|
+
className: "evo-diag-item",
|
|
4447
|
+
"data-kind": "runtime",
|
|
4448
|
+
"data-status": row.status
|
|
4449
|
+
}, (0, react.createElement)("div", { className: "evo-diag-row-head" }, (0, react.createElement)("span", { className: "evo-diag-dot" }), (0, react.createElement)("span", { className: "evo-diag-label" }, row.label), (0, react.createElement)("span", { className: "evo-diag-status" }, t(STATUS_KEYS[row.status]))), row.detail === void 0 ? null : (0, react.createElement)("span", { className: "evo-diag-detail" }, row.detail), row.remedy === void 0 ? null : (0, react.createElement)("span", { className: "evo-diag-remedy" }, t("diagRemedy") + row.remedy));
|
|
4450
|
+
return (0, react.createElement)("div", {}, (0, react.createElement)("h3", { className: "evolution-param-group" }, t("diagRuntimeTitle")), reading.topIssue === void 0 ? (0, react.createElement)("div", {
|
|
4451
|
+
className: "evo-diag-complete",
|
|
4452
|
+
"data-role": "diag-complete"
|
|
4453
|
+
}, t("diagComplete")) : (0, react.createElement)("div", {
|
|
4454
|
+
className: "evo-diag-issue",
|
|
4455
|
+
"data-role": "diag-issue",
|
|
4456
|
+
"data-status": reading.topIssue.status
|
|
4457
|
+
}, rowNode(reading.topIssue)), reading.otherIssues.length === 0 ? null : (0, react.createElement)("details", {
|
|
4458
|
+
className: "evo-diag-group",
|
|
4459
|
+
"data-role": "diag-other-issues"
|
|
4460
|
+
}, (0, react.createElement)("summary", null, t("diagOtherIssues", { n: reading.otherIssues.length })), ...reading.otherIssues.map(rowNode)), reading.normal.length === 0 ? null : (0, react.createElement)("details", {
|
|
4461
|
+
className: "evo-diag-group",
|
|
4462
|
+
"data-role": "diag-normal"
|
|
4463
|
+
}, (0, react.createElement)("summary", null, t("diagNormal", { n: reading.normal.length })), ...reading.normal.map(rowNode)));
|
|
4464
|
+
};
|
|
4076
4465
|
const body = () => {
|
|
4077
4466
|
if (state.phase === "loading") return (0, react.createElement)("p", { className: "evolution-param-loading" }, t("stateLoading"));
|
|
4078
4467
|
if (state.phase === "failed") return FailureBlock({
|
|
@@ -4081,7 +4470,11 @@ window.__ModuleLoader__.load({
|
|
|
4081
4470
|
fallback: props.fallback
|
|
4082
4471
|
});
|
|
4083
4472
|
const view = state.view;
|
|
4084
|
-
return (0, react.createElement)("div", {}, (0, react.createElement)("p", { className: "evolution-param-note" }, t("diagSubtitle")),
|
|
4473
|
+
return (0, react.createElement)("div", {}, (0, react.createElement)("p", { className: "evolution-param-note" }, t("diagSubtitle")), refreshFailure === void 0 ? null : FailureBlock({
|
|
4474
|
+
failure: refreshFailure,
|
|
4475
|
+
t: translate,
|
|
4476
|
+
fallback: props.fallback
|
|
4477
|
+
}), (0, react.createElement)("div", { className: "evolution-param-actions" }, (0, react.createElement)("button", {
|
|
4085
4478
|
type: "button",
|
|
4086
4479
|
className: "evolution-param-button",
|
|
4087
4480
|
onClick: refresh,
|
|
@@ -4104,6 +4497,69 @@ window.__ModuleLoader__.load({
|
|
|
4104
4497
|
}, header, open ? (0, react.createElement)("div", { className: "evolution-param-body" }, body()) : null);
|
|
4105
4498
|
}
|
|
4106
4499
|
//#endregion
|
|
4500
|
+
//#region src/panels/history/client/WorkbenchStore.ts
|
|
4501
|
+
/**
|
|
4502
|
+
* Resolve the first landing from task counts. Pending outranks merge; no task lands on history.
|
|
4503
|
+
* @param counts - read-only task counts.
|
|
4504
|
+
* @param hasMerge - whether the merge view is mounted.
|
|
4505
|
+
* @returns the view to open when the user has not chosen one.
|
|
4506
|
+
*/
|
|
4507
|
+
function resolveDefaultView(counts, hasMerge) {
|
|
4508
|
+
if (counts.pending > 0) return "pending";
|
|
4509
|
+
if (hasMerge && counts.merge > 0) return "merge";
|
|
4510
|
+
return "history";
|
|
4511
|
+
}
|
|
4512
|
+
function createWorkbenchStore(initial = {
|
|
4513
|
+
view: "history",
|
|
4514
|
+
focusRevision: 0,
|
|
4515
|
+
explicitView: false
|
|
4516
|
+
}) {
|
|
4517
|
+
let state = initial;
|
|
4518
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
4519
|
+
const emit = (next) => {
|
|
4520
|
+
state = next;
|
|
4521
|
+
for (const listener of listeners) listener();
|
|
4522
|
+
};
|
|
4523
|
+
return {
|
|
4524
|
+
getState: () => state,
|
|
4525
|
+
subscribe(listener) {
|
|
4526
|
+
listeners.add(listener);
|
|
4527
|
+
return () => {
|
|
4528
|
+
listeners.delete(listener);
|
|
4529
|
+
};
|
|
4530
|
+
},
|
|
4531
|
+
setView(view) {
|
|
4532
|
+
if (state.view !== view || state.explicitView !== true) emit({
|
|
4533
|
+
...state,
|
|
4534
|
+
view,
|
|
4535
|
+
explicitView: true
|
|
4536
|
+
});
|
|
4537
|
+
},
|
|
4538
|
+
setDefaultView(view) {
|
|
4539
|
+
if (state.explicitView !== true && state.view !== view) emit({
|
|
4540
|
+
...state,
|
|
4541
|
+
view,
|
|
4542
|
+
explicitView: false
|
|
4543
|
+
});
|
|
4544
|
+
},
|
|
4545
|
+
openHistory(skill) {
|
|
4546
|
+
emit({
|
|
4547
|
+
view: "history",
|
|
4548
|
+
...skill === void 0 ? {} : { selectedSkill: skill },
|
|
4549
|
+
focusRevision: state.focusRevision + 1,
|
|
4550
|
+
explicitView: true
|
|
4551
|
+
});
|
|
4552
|
+
},
|
|
4553
|
+
clearSelection() {
|
|
4554
|
+
const { selectedSkill: _selected, ...rest } = state;
|
|
4555
|
+
emit({
|
|
4556
|
+
...rest,
|
|
4557
|
+
focusRevision: state.focusRevision + 1
|
|
4558
|
+
});
|
|
4559
|
+
}
|
|
4560
|
+
};
|
|
4561
|
+
}
|
|
4562
|
+
//#endregion
|
|
4107
4563
|
//#region src/panels/history/client/Workbench.ts
|
|
4108
4564
|
/**
|
|
4109
4565
|
* The family's one task page. G3 owns the history view; later groups add health
|
|
@@ -4129,13 +4585,29 @@ window.__ModuleLoader__.load({
|
|
|
4129
4585
|
const hasMerge = props.hasView?.("merge") ?? true;
|
|
4130
4586
|
const hasHealth = props.hasView?.("health") ?? true;
|
|
4131
4587
|
(0, react.useEffect)(() => {
|
|
4132
|
-
if (view === "merge" && !hasMerge || view === "health" && !hasHealth) props.store.
|
|
4588
|
+
if (view === "merge" && !hasMerge || view === "health" && !hasHealth) props.store.setDefaultView("history");
|
|
4133
4589
|
}, [
|
|
4134
4590
|
view,
|
|
4135
4591
|
hasMerge,
|
|
4136
4592
|
hasHealth,
|
|
4137
4593
|
props.store
|
|
4138
4594
|
]);
|
|
4595
|
+
(0, react.useEffect)(() => {
|
|
4596
|
+
const load = props.loadTaskCounts;
|
|
4597
|
+
if (load === void 0 || state.explicitView === true) return;
|
|
4598
|
+
let live = true;
|
|
4599
|
+
load().then((counts) => {
|
|
4600
|
+
if (live) props.store.setDefaultView(resolveDefaultView(counts, hasMerge));
|
|
4601
|
+
}).catch(() => {});
|
|
4602
|
+
return () => {
|
|
4603
|
+
live = false;
|
|
4604
|
+
};
|
|
4605
|
+
}, [
|
|
4606
|
+
props.loadTaskCounts,
|
|
4607
|
+
state.explicitView,
|
|
4608
|
+
hasMerge,
|
|
4609
|
+
props.store
|
|
4610
|
+
]);
|
|
4139
4611
|
const viewOrder = [
|
|
4140
4612
|
"history",
|
|
4141
4613
|
"pending",
|
|
@@ -4157,7 +4629,10 @@ window.__ModuleLoader__.load({
|
|
|
4157
4629
|
return (0, react.createElement)("section", {
|
|
4158
4630
|
className: "evolution-page-surface evo-workbench",
|
|
4159
4631
|
"data-page": view
|
|
4160
|
-
}, (0, react.createElement)("div", { className: "evo-workbench-head" }, (0, react.createElement)("h1", {
|
|
4632
|
+
}, (0, react.createElement)("div", { className: "evo-workbench-head" }, (0, react.createElement)("h1", {
|
|
4633
|
+
className: "evo-workbench-title",
|
|
4634
|
+
"data-view": view
|
|
4635
|
+
}, props.t("workbench.title")), (0, react.createElement)("div", {
|
|
4161
4636
|
className: "evo-workbench-tabs",
|
|
4162
4637
|
role: "tablist",
|
|
4163
4638
|
"aria-label": props.t("entry.label")
|
|
@@ -4239,7 +4714,12 @@ window.__ModuleLoader__.load({
|
|
|
4239
4714
|
...props.history,
|
|
4240
4715
|
focusSkill: selectedSkill,
|
|
4241
4716
|
focusRevision
|
|
4242
|
-
}) : view === "pending" ? (0, react.createElement)(PendingCard,
|
|
4717
|
+
}) : view === "pending" ? (0, react.createElement)(PendingCard, {
|
|
4718
|
+
...props.pending,
|
|
4719
|
+
onHistory: () => {
|
|
4720
|
+
openHistory(void 0);
|
|
4721
|
+
}
|
|
4722
|
+
}) : view === "diagnostics" ? (0, react.createElement)(DiagnosticsCard, props.diagnostics) : null, (0, react.createElement)("div", {
|
|
4243
4723
|
hidden: view !== "merge" && view !== "health",
|
|
4244
4724
|
className: "evo-workbench-feature"
|
|
4245
4725
|
}, props.renderSlot?.("evolution.workbench.view", {
|
|
@@ -4275,52 +4755,14 @@ window.__ModuleLoader__.load({
|
|
|
4275
4755
|
".evo-workbench-tabs button:focus-visible{outline:var(--evo-focus-ring);outline-offset:var(--evo-focus-offset)}",
|
|
4276
4756
|
".evo-workbench-title{margin:0;font-size:var(--evo-type-lg);font-weight:600;line-height:var(--evo-leading-base)}",
|
|
4277
4757
|
".evo-workbench-body{display:flex;flex:1;min-height:0;min-width:0;overflow:hidden}",
|
|
4758
|
+
".evo-workbench-feature{display:flex;flex:1;min-width:0;min-height:0}",
|
|
4759
|
+
".evo-workbench-feature[hidden]{display:none}",
|
|
4760
|
+
".evo-workbench-feature>*{flex:1;min-width:0}",
|
|
4761
|
+
".evo-workbench-feature .evolution-merge-panel,.evo-workbench-feature .evolution-skill-health-panel{flex:1 1 auto;min-width:0}",
|
|
4278
4762
|
".evo-workbench-body>.evolution-param-card{flex:1;min-width:0;overflow:auto}",
|
|
4279
4763
|
"@media (max-width:720px){.evo-workbench-head{flex-wrap:wrap}.evo-workbench-tabs{flex-wrap:wrap}}"
|
|
4280
4764
|
].join("");
|
|
4281
4765
|
//#endregion
|
|
4282
|
-
//#region src/panels/history/client/WorkbenchStore.ts
|
|
4283
|
-
function createWorkbenchStore(initial = {
|
|
4284
|
-
view: "history",
|
|
4285
|
-
focusRevision: 0
|
|
4286
|
-
}) {
|
|
4287
|
-
let state = initial;
|
|
4288
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
4289
|
-
const emit = (next) => {
|
|
4290
|
-
state = next;
|
|
4291
|
-
for (const listener of listeners) listener();
|
|
4292
|
-
};
|
|
4293
|
-
return {
|
|
4294
|
-
getState: () => state,
|
|
4295
|
-
subscribe(listener) {
|
|
4296
|
-
listeners.add(listener);
|
|
4297
|
-
return () => {
|
|
4298
|
-
listeners.delete(listener);
|
|
4299
|
-
};
|
|
4300
|
-
},
|
|
4301
|
-
setView(view) {
|
|
4302
|
-
if (state.view !== view) emit({
|
|
4303
|
-
...state,
|
|
4304
|
-
view
|
|
4305
|
-
});
|
|
4306
|
-
},
|
|
4307
|
-
openHistory(skill) {
|
|
4308
|
-
emit({
|
|
4309
|
-
view: "history",
|
|
4310
|
-
...skill === void 0 ? {} : { selectedSkill: skill },
|
|
4311
|
-
focusRevision: state.focusRevision + 1
|
|
4312
|
-
});
|
|
4313
|
-
},
|
|
4314
|
-
clearSelection() {
|
|
4315
|
-
const { selectedSkill: _selected, ...rest } = state;
|
|
4316
|
-
emit({
|
|
4317
|
-
...rest,
|
|
4318
|
-
focusRevision: state.focusRevision + 1
|
|
4319
|
-
});
|
|
4320
|
-
}
|
|
4321
|
-
};
|
|
4322
|
-
}
|
|
4323
|
-
//#endregion
|
|
4324
4766
|
//#region src/panels/history/client/index.ts
|
|
4325
4767
|
/**
|
|
4326
4768
|
* Register the locale namespace, the workbench main occupant and its sidebar row.
|
|
@@ -4369,9 +4811,10 @@ window.__ModuleLoader__.load({
|
|
|
4369
4811
|
footnotes: t("markdown.footnotes")
|
|
4370
4812
|
}
|
|
4371
4813
|
});
|
|
4814
|
+
const approvalApi = createApprovalApi((input, init) => fetch(input, init));
|
|
4372
4815
|
const pendingFace = () => ({
|
|
4373
4816
|
t: pendingT,
|
|
4374
|
-
api:
|
|
4817
|
+
api: approvalApi,
|
|
4375
4818
|
confirmMode,
|
|
4376
4819
|
fallback: FALLBACKS.approval
|
|
4377
4820
|
});
|
|
@@ -4380,6 +4823,26 @@ window.__ModuleLoader__.load({
|
|
|
4380
4823
|
api: createDiagnosticsApi((input, init) => fetch(input, init)),
|
|
4381
4824
|
fallback: FALLBACKS.diagnostics
|
|
4382
4825
|
});
|
|
4826
|
+
const loadTaskCounts = async () => {
|
|
4827
|
+
const pending = approvalApi.pending().then((answer) => answer.ok ? answer.data.length : 0).catch(() => 0);
|
|
4828
|
+
const merge = (async () => {
|
|
4829
|
+
try {
|
|
4830
|
+
const response = await fetch(ROUTES.merge.view, { headers: { accept: "application/json" } });
|
|
4831
|
+
if (!response.ok) return 0;
|
|
4832
|
+
const body = await response.json();
|
|
4833
|
+
const raw = body.ok === true ? body.data : body;
|
|
4834
|
+
const count = Number(raw?.counts?.active?.pending ?? raw?.counts?.pending ?? 0);
|
|
4835
|
+
return Number.isFinite(count) && count > 0 ? count : 0;
|
|
4836
|
+
} catch {
|
|
4837
|
+
return 0;
|
|
4838
|
+
}
|
|
4839
|
+
})();
|
|
4840
|
+
const [pendingCount, mergeCount] = await Promise.all([pending, merge]);
|
|
4841
|
+
return {
|
|
4842
|
+
pending: pendingCount,
|
|
4843
|
+
merge: mergeCount
|
|
4844
|
+
};
|
|
4845
|
+
};
|
|
4383
4846
|
const workbenchStore = createWorkbenchStore();
|
|
4384
4847
|
registerSidebarPanel(ctx, {
|
|
4385
4848
|
id: WORKBENCH_ID,
|
|
@@ -4401,7 +4864,8 @@ window.__ModuleLoader__.load({
|
|
|
4401
4864
|
history: historyFace(t),
|
|
4402
4865
|
pending: pendingFace(),
|
|
4403
4866
|
diagnostics: diagnosticsFace(),
|
|
4404
|
-
hasView
|
|
4867
|
+
hasView,
|
|
4868
|
+
loadTaskCounts
|
|
4405
4869
|
}),
|
|
4406
4870
|
children: { "evolution.workbench.view": {
|
|
4407
4871
|
kind: "list",
|