@morehao/dsh-github-trending 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +3 -1
- package/client.js +253 -205
- package/lib/{chunk-WDBZAMWN.js → chunk-R3EDPRRO.js} +104 -18
- package/lib/index.js +1 -1
- package/lib/internal.d.ts +68 -10
- package/lib/internal.js +5 -3
- package/package.json +3 -3
package/client.js
CHANGED
|
@@ -294,6 +294,10 @@ var DICT = {
|
|
|
294
294
|
"overview.live.note": "核心一次完成抓取、总结、渲染与提交,结束前没有分段进度;这里只显示已用时间和粗阶段。",
|
|
295
295
|
"overview.live.started": "开始于",
|
|
296
296
|
"run.dryRunShort": "试跑",
|
|
297
|
+
"run.force": "重新生成",
|
|
298
|
+
"run.force.hint": "忽略摘要缓存,强制重新抓取与总结",
|
|
299
|
+
"run.force.noChange": "内容无变化,未新增提交",
|
|
300
|
+
"run.forced.tag": "强制重跑",
|
|
297
301
|
"run.usage.commit": "提交",
|
|
298
302
|
"runs.count": "最近 {count} 次,超出即裁剪",
|
|
299
303
|
"runs.files": "{count} 个文件",
|
|
@@ -352,6 +356,7 @@ var DICT = {
|
|
|
352
356
|
"digest.select": "选择日报日期",
|
|
353
357
|
"digest.render": "渲染",
|
|
354
358
|
"digest.raw": "原文",
|
|
359
|
+
"digest.regenerate": "重新生成这一期",
|
|
355
360
|
"digest.mode": "预览方式",
|
|
356
361
|
"digest.copyPath": "复制路径",
|
|
357
362
|
"digest.copied": "已复制",
|
|
@@ -449,7 +454,7 @@ var DICT = {
|
|
|
449
454
|
"releases.budget.auto": "自动",
|
|
450
455
|
"releases.budget.fixed": "指定",
|
|
451
456
|
"subs.title": "订阅",
|
|
452
|
-
"subs.desc": "
|
|
457
|
+
"subs.desc": "管理发版订阅仓库,查看每周变更记录。",
|
|
453
458
|
"subs.select": "选择",
|
|
454
459
|
"subs.select.done": "完成",
|
|
455
460
|
"subs.cmd.placeholder": "搜索 owner/repo,或输入完整仓库名直接添加",
|
|
@@ -476,8 +481,18 @@ var DICT = {
|
|
|
476
481
|
"subs.removed.many": "已移除 {count} 个仓库,下次运行随产物提交。",
|
|
477
482
|
"subs.remove": "移除",
|
|
478
483
|
"subs.removing": "移除中…",
|
|
479
|
-
"subs.row.changes": "
|
|
484
|
+
"subs.row.changes": "查看变更",
|
|
480
485
|
"subs.row.changesRepo": "查看 {repo} 的变更",
|
|
486
|
+
"subs.row.trigger": "触发分析",
|
|
487
|
+
"subs.row.triggerRepo": "只对 {repo} 生成变更分析",
|
|
488
|
+
"subs.search.placeholder": "搜索仓库",
|
|
489
|
+
"subs.search.label": "搜索仓库",
|
|
490
|
+
"subs.toolbar.add": "+ 添加仓库",
|
|
491
|
+
"subs.toolbar.analyze": "生成变更分析",
|
|
492
|
+
"subs.analyzing": "分析中…",
|
|
493
|
+
"subs.analyze.done": "变更分析已生成 · {count} 个仓库有更新",
|
|
494
|
+
"subs.analyze.doneOne": "{repo} 已更新",
|
|
495
|
+
"subs.analyze.failed": "分析失败:{message}",
|
|
481
496
|
"subs.row.removeRepo": "移除 {repo}",
|
|
482
497
|
"subs.col.repo": "仓库",
|
|
483
498
|
"subs.col.tag": "最近版本",
|
|
@@ -801,6 +816,10 @@ var DICT = {
|
|
|
801
816
|
"overview.live.note": "The core fetches, summarizes, renders and commits in one run; there is no per-step progress before it finishes. Only elapsed time and a coarse phase are shown here.",
|
|
802
817
|
"overview.live.started": "Started",
|
|
803
818
|
"run.dryRunShort": "Dry run",
|
|
819
|
+
"run.force": "Regenerate",
|
|
820
|
+
"run.force.hint": "Ignore the summary cache and re-fetch and re-summarize",
|
|
821
|
+
"run.force.noChange": "No content change; no new commit",
|
|
822
|
+
"run.forced.tag": "Forced",
|
|
804
823
|
"run.usage.commit": "Commit",
|
|
805
824
|
"runs.count": "Last {count} runs; older ones are trimmed",
|
|
806
825
|
"runs.files": "{count} files",
|
|
@@ -859,6 +878,7 @@ var DICT = {
|
|
|
859
878
|
"digest.select": "Choose a digest date",
|
|
860
879
|
"digest.render": "Rendered",
|
|
861
880
|
"digest.raw": "Raw",
|
|
881
|
+
"digest.regenerate": "Regenerate this period",
|
|
862
882
|
"digest.mode": "Preview mode",
|
|
863
883
|
"digest.copyPath": "Copy path",
|
|
864
884
|
"digest.copied": "Copied",
|
|
@@ -956,7 +976,7 @@ var DICT = {
|
|
|
956
976
|
"releases.budget.auto": "Auto",
|
|
957
977
|
"releases.budget.fixed": "Fixed",
|
|
958
978
|
"subs.title": "Subscriptions",
|
|
959
|
-
"subs.desc": "
|
|
979
|
+
"subs.desc": "Manage release-subscription repos and review weekly change records.",
|
|
960
980
|
"subs.select": "Select",
|
|
961
981
|
"subs.select.done": "Done",
|
|
962
982
|
"subs.cmd.placeholder": "Search owner/repo, or type a full repo name to add it",
|
|
@@ -983,8 +1003,18 @@ var DICT = {
|
|
|
983
1003
|
"subs.removed.many": "Removed {count} repos; committed with artifacts on the next run.",
|
|
984
1004
|
"subs.remove": "Remove",
|
|
985
1005
|
"subs.removing": "Removing…",
|
|
986
|
-
"subs.row.changes": "
|
|
1006
|
+
"subs.row.changes": "View changes",
|
|
987
1007
|
"subs.row.changesRepo": "Show changes for {repo}",
|
|
1008
|
+
"subs.row.trigger": "Analyze",
|
|
1009
|
+
"subs.row.triggerRepo": "Generate change analysis for {repo} only",
|
|
1010
|
+
"subs.search.placeholder": "Search repositories",
|
|
1011
|
+
"subs.search.label": "Search repositories",
|
|
1012
|
+
"subs.toolbar.add": "+ Add repository",
|
|
1013
|
+
"subs.toolbar.analyze": "Generate change analysis",
|
|
1014
|
+
"subs.analyzing": "Analyzing…",
|
|
1015
|
+
"subs.analyze.done": "Change analysis ready · {count} repos updated",
|
|
1016
|
+
"subs.analyze.doneOne": "{repo} updated",
|
|
1017
|
+
"subs.analyze.failed": "Analysis failed: {message}",
|
|
988
1018
|
"subs.row.removeRepo": "Remove {repo}",
|
|
989
1019
|
"subs.col.repo": "Repo",
|
|
990
1020
|
"subs.col.tag": "Latest version",
|
|
@@ -1424,6 +1454,24 @@ var CSS = `
|
|
|
1424
1454
|
|
|
1425
1455
|
/* ——— 订阅:命令栏 + 四列表格 + 选择条 + 发版记录抽屉 ——— */
|
|
1426
1456
|
.dshgt-subs{gap:12px;padding-bottom:10px;}
|
|
1457
|
+
/* 工具条:搜索 + 添加 + 选择 + 生成变更分析;列表在上方操作区之下 */
|
|
1458
|
+
.dshgt-subs-toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding-bottom:12px;border-bottom:1px solid color-mix(in srgb,var(--gt-border) 70%,transparent);}
|
|
1459
|
+
.dshgt-subs-search{position:relative;flex:1;min-width:180px;max-width:340px;display:flex;align-items:center;}
|
|
1460
|
+
.dshgt-subs-search svg{position:absolute;left:9px;color:var(--gt-muted);pointer-events:none;}
|
|
1461
|
+
.dshgt-subs-search input{width:100%;height:32px;box-sizing:border-box;padding:0 10px 0 30px;border:1px solid var(--gt-border);border-radius:8px;background:var(--gt-bg);color:var(--gt-fg);font:inherit;font-size:13px;}
|
|
1462
|
+
.dshgt-subs-search input:focus{outline:2px solid color-mix(in srgb,var(--gt-accent) 30%,transparent);outline-offset:1px;border-color:color-mix(in srgb,var(--gt-accent) 45%,var(--gt-border));}
|
|
1463
|
+
.dshgt-subs-search input::placeholder{color:var(--gt-muted);}
|
|
1464
|
+
.dshgt-subs-toolbar-spacer{flex:1 1 auto;min-width:0;}
|
|
1465
|
+
.dshgt-subs-addform{display:flex;align-items:center;gap:6px;}
|
|
1466
|
+
.dshgt-subs-addform input{height:32px;box-sizing:border-box;width:200px;padding:0 9px;border:1px solid var(--gt-border);border-radius:8px;background:var(--gt-bg);color:var(--gt-fg);font:inherit;font-size:12.5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}
|
|
1467
|
+
.dshgt-subs-addform input:focus{outline:2px solid color-mix(in srgb,var(--gt-accent) 30%,transparent);outline-offset:1px;}
|
|
1468
|
+
.dshgt-subs-act.gen{color:var(--gt-muted);}
|
|
1469
|
+
.dshgt-subs-act.gen:hover{color:var(--gt-accent);background:color-mix(in srgb,var(--gt-accent) 10%,transparent);}
|
|
1470
|
+
.dshgt-subs-act.gen:disabled{opacity:.5;cursor:not-allowed;}
|
|
1471
|
+
.dshgt-subs-rowbusy{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--gt-accent);padding:3px 4px;white-space:nowrap;}
|
|
1472
|
+
.dshgt-spin{width:12px;height:12px;border-radius:50%;border:2px solid color-mix(in srgb,var(--gt-accent) 30%,transparent);border-top-color:var(--gt-accent);animation:dshgt-spin .7s linear infinite;display:inline-block;flex:none;}
|
|
1473
|
+
@keyframes dshgt-spin{to{transform:rotate(360deg);}}
|
|
1474
|
+
.dshgt-subs-row.is-analyzing{background:color-mix(in srgb,var(--gt-accent) 6%,var(--gt-bg));}
|
|
1427
1475
|
.dshgt-subs-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap;}
|
|
1428
1476
|
.dshgt-subs-head-main{min-width:0;}
|
|
1429
1477
|
.dshgt-subs-head h2{margin:0;font-size:17px;font-weight:650;letter-spacing:-.01em;}
|
|
@@ -1771,11 +1819,6 @@ function releaseRunsOf(state) {
|
|
|
1771
1819
|
const nested = Array.isArray(state.status?.releaseRuns) ? state.status.releaseRuns : void 0;
|
|
1772
1820
|
return root ?? nested ?? [];
|
|
1773
1821
|
}
|
|
1774
|
-
function lastReleaseAtOf(state) {
|
|
1775
|
-
if (state === null || state === void 0) return void 0;
|
|
1776
|
-
const value = state.lastReleaseAt ?? state.status?.lastReleaseAt;
|
|
1777
|
-
return typeof value === "string" && value !== "" ? value : void 0;
|
|
1778
|
-
}
|
|
1779
1822
|
function getPreview(runId, signal) {
|
|
1780
1823
|
return apiCall("GET", `/preview?id=${encodeURIComponent(runId)}`, void 0, signal === void 0 ? {} : { signal });
|
|
1781
1824
|
}
|
|
@@ -1823,6 +1866,45 @@ async function postSubscriptions(action, repos) {
|
|
|
1823
1866
|
const payload = await apiCall("POST", "/subscriptions", { action, repos });
|
|
1824
1867
|
return normalizeSubscriptionList(payload);
|
|
1825
1868
|
}
|
|
1869
|
+
async function postReleasesRun(repo) {
|
|
1870
|
+
const payload = await apiCall("POST", "/releases/run", repo === void 0 ? {} : { repo });
|
|
1871
|
+
return normalizeReleaseRun(payload.release);
|
|
1872
|
+
}
|
|
1873
|
+
function normalizeReleaseRun(raw) {
|
|
1874
|
+
const r = typeof raw === "object" && raw !== null ? raw : {};
|
|
1875
|
+
const str = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
1876
|
+
const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
1877
|
+
const opt = (v) => typeof v === "string" && v !== "" ? v : void 0;
|
|
1878
|
+
const status = r.status === "ok" || r.status === "failed" || r.status === "skipped" || r.status === "cancelled" ? r.status : "failed";
|
|
1879
|
+
const record = {
|
|
1880
|
+
id: str(r.id),
|
|
1881
|
+
startedAt: str(r.startedAt),
|
|
1882
|
+
finishedAt: str(r.finishedAt),
|
|
1883
|
+
status,
|
|
1884
|
+
checked: num(r.checked),
|
|
1885
|
+
changed: num(r.changed),
|
|
1886
|
+
newTags: num(r.newTags),
|
|
1887
|
+
summarized: num(r.summarized),
|
|
1888
|
+
degraded: num(r.degraded),
|
|
1889
|
+
failed: num(r.failed),
|
|
1890
|
+
rateLimited: num(r.rateLimited),
|
|
1891
|
+
durationMs: num(r.durationMs)
|
|
1892
|
+
};
|
|
1893
|
+
const maybe = {
|
|
1894
|
+
tokens: typeof r.tokens === "number" ? r.tokens : void 0,
|
|
1895
|
+
commit: opt(r.commit),
|
|
1896
|
+
prUrl: opt(r.prUrl),
|
|
1897
|
+
branch: opt(r.branch),
|
|
1898
|
+
errorCode: opt(r.errorCode),
|
|
1899
|
+
errorMessage: opt(r.errorMessage),
|
|
1900
|
+
coreVersion: opt(r.coreVersion),
|
|
1901
|
+
scopeRepo: opt(r.scopeRepo)
|
|
1902
|
+
};
|
|
1903
|
+
for (const [k, v] of Object.entries(maybe)) {
|
|
1904
|
+
if (v !== void 0) record[k] = v;
|
|
1905
|
+
}
|
|
1906
|
+
return record;
|
|
1907
|
+
}
|
|
1826
1908
|
async function getSubscriptionDoc(repo, volume, signal) {
|
|
1827
1909
|
const query = `?repo=${encodeURIComponent(repo)}${volume === void 0 ? "" : `&volume=${encodeURIComponent(String(volume))}`}`;
|
|
1828
1910
|
const payload = await apiCall(
|
|
@@ -2740,14 +2822,18 @@ function useRunController(store) {
|
|
|
2740
2822
|
const [dryRun, setDryRun] = import_react.default.useState(false);
|
|
2741
2823
|
const [localStartedAt, setLocalStartedAt] = import_react.default.useState(null);
|
|
2742
2824
|
const run = import_react.default.useCallback(
|
|
2743
|
-
async (overrideDry) => {
|
|
2825
|
+
async (overrideDry, options) => {
|
|
2744
2826
|
const dry = overrideDry ?? dryRun;
|
|
2745
2827
|
setBusy(true);
|
|
2746
2828
|
setError(null);
|
|
2747
2829
|
setSummary(null);
|
|
2748
2830
|
setLocalStartedAt((/* @__PURE__ */ new Date()).toISOString());
|
|
2749
2831
|
try {
|
|
2750
|
-
const
|
|
2832
|
+
const body = { dryRun: dry };
|
|
2833
|
+
if (options?.force === true) body.force = true;
|
|
2834
|
+
if (options?.date !== void 0 && options.date !== "") body.date = options.date;
|
|
2835
|
+
if (options?.period !== void 0) body.period = options.period;
|
|
2836
|
+
const result = await apiCall("POST", "/run", body);
|
|
2751
2837
|
setSummary(result.summary);
|
|
2752
2838
|
await refresh({ quiet: true });
|
|
2753
2839
|
} catch (failure) {
|
|
@@ -2936,6 +3022,9 @@ function digestTarget(record, timeZone) {
|
|
|
2936
3022
|
const period = recordPeriod(record);
|
|
2937
3023
|
return { period, bucket: periodBucket(period, info.date) };
|
|
2938
3024
|
}
|
|
3025
|
+
function regenTarget(day) {
|
|
3026
|
+
return { period: day.period, date: day.date };
|
|
3027
|
+
}
|
|
2939
3028
|
function buildPeriodGroups(records, options) {
|
|
2940
3029
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
2941
3030
|
const today = zonedDateString(now, options.timeZone);
|
|
@@ -3325,7 +3414,10 @@ function recordSummary(t, record) {
|
|
|
3325
3414
|
if (!record.ok) {
|
|
3326
3415
|
return [record.errorCode, record.errorMessage].filter((item) => item !== void 0 && item !== "").join(" · ") || t("state.failed");
|
|
3327
3416
|
}
|
|
3328
|
-
if (record.skipped)
|
|
3417
|
+
if (record.skipped) {
|
|
3418
|
+
if (record.forced === true && record.skipReason === "unchanged") return t("run.force.noChange");
|
|
3419
|
+
return skipHint(t, record.skipReason, t("runs.noChange"));
|
|
3420
|
+
}
|
|
3329
3421
|
if (record.kind === "dry-run") return t("runs.dryHint");
|
|
3330
3422
|
if (record.branch !== void 0) return record.branch;
|
|
3331
3423
|
if (record.commit !== void 0) return record.commit;
|
|
@@ -3459,7 +3551,8 @@ function RunsView(props) {
|
|
|
3459
3551
|
{ className: "dshgt-run-what" },
|
|
3460
3552
|
record.kind === "dry-run" ? t("state.dry") : record.skipped ? t("state.skipped") : record.ok ? t("state.ok") : t("state.failed"),
|
|
3461
3553
|
h("span", { className: "dshgt-run-muted" }, recordSummary(t, record)),
|
|
3462
|
-
record.legacy === true ? h("span", { className: "dshgt-tag dshgt-inline-tag" }, t("runs.legacy")) : null
|
|
3554
|
+
record.legacy === true ? h("span", { className: "dshgt-tag dshgt-inline-tag" }, t("runs.legacy")) : null,
|
|
3555
|
+
record.forced === true ? h("span", { className: "dshgt-tag dshgt-inline-tag" }, t("run.forced.tag")) : null
|
|
3463
3556
|
),
|
|
3464
3557
|
h("span", { className: "dshgt-run-files" }, t("runs.files", { count: record.files })),
|
|
3465
3558
|
record.tokens === void 0 ? null : h("span", { className: "dshgt-run-tokens dshgt-mono", title: t("run.usage.tokens") }, `${formatTokens(record.tokens)} tok`),
|
|
@@ -4074,6 +4167,7 @@ function EmptyDigest(props) {
|
|
|
4074
4167
|
"div",
|
|
4075
4168
|
{ className: "dshgt-actions" },
|
|
4076
4169
|
h(Btn, { small: true, onClick: props.onOpenRuns }, t("digest.empty.viewRuns")),
|
|
4170
|
+
props.onRegenerate === void 0 ? null : h(Btn, { small: true, onClick: props.onRegenerate, disabled: props.regenDisabled === true }, t("digest.regenerate")),
|
|
4077
4171
|
nearest === void 0 ? null : h(
|
|
4078
4172
|
Btn,
|
|
4079
4173
|
{ small: true, onClick: () => props.onSelect({ period: nearest.period, bucket: nearest.bucket }) },
|
|
@@ -4083,7 +4177,7 @@ function EmptyDigest(props) {
|
|
|
4083
4177
|
);
|
|
4084
4178
|
}
|
|
4085
4179
|
function DigestView(props) {
|
|
4086
|
-
const { t, lang, store, selected } = props;
|
|
4180
|
+
const { t, lang, store, selected, controller } = props;
|
|
4087
4181
|
const [mode, setMode] = import_react.default.useState("render");
|
|
4088
4182
|
const [payload, setPayload] = import_react.default.useState(null);
|
|
4089
4183
|
const [loading, setLoading] = import_react.default.useState(false);
|
|
@@ -4119,20 +4213,20 @@ function DigestView(props) {
|
|
|
4119
4213
|
setLoading(false);
|
|
4120
4214
|
return () => void 0;
|
|
4121
4215
|
}
|
|
4122
|
-
const
|
|
4216
|
+
const controller2 = new AbortController();
|
|
4123
4217
|
setLoading(true);
|
|
4124
4218
|
setError(null);
|
|
4125
4219
|
setPayload(null);
|
|
4126
|
-
getPreview(previewRunId,
|
|
4127
|
-
if (
|
|
4220
|
+
getPreview(previewRunId, controller2.signal).then((result) => {
|
|
4221
|
+
if (controller2.signal.aborted) return;
|
|
4128
4222
|
setPayload(result);
|
|
4129
4223
|
setLoading(false);
|
|
4130
4224
|
}).catch((failure) => {
|
|
4131
|
-
if (
|
|
4225
|
+
if (controller2.signal.aborted) return;
|
|
4132
4226
|
setError(failure instanceof Error ? failure.message : String(failure));
|
|
4133
4227
|
setLoading(false);
|
|
4134
4228
|
});
|
|
4135
|
-
return () =>
|
|
4229
|
+
return () => controller2.abort();
|
|
4136
4230
|
}, [previewRunId]);
|
|
4137
4231
|
if (state === null) {
|
|
4138
4232
|
return h("div", { className: "dshgt-empty" }, store.error ?? t("quickfill.loading"));
|
|
@@ -4253,6 +4347,12 @@ function DigestView(props) {
|
|
|
4253
4347
|
}
|
|
4254
4348
|
const showEmpty = day.status !== "preview" || error !== null;
|
|
4255
4349
|
const record = day.record;
|
|
4350
|
+
const regenerate = () => {
|
|
4351
|
+
const target = regenTarget(day);
|
|
4352
|
+
props.onSelect({ period: target.period, bucket: day.bucket });
|
|
4353
|
+
void controller.run(false, { force: true, date: target.date, period: target.period });
|
|
4354
|
+
};
|
|
4355
|
+
const regenerateDisabled = controller.running || controller.busy;
|
|
4256
4356
|
return h(
|
|
4257
4357
|
"div",
|
|
4258
4358
|
{ className: "dshgt-view dshgt-digest" },
|
|
@@ -4268,7 +4368,9 @@ function DigestView(props) {
|
|
|
4268
4368
|
...nearest === void 0 ? {} : { nearest },
|
|
4269
4369
|
...error === null ? {} : { error },
|
|
4270
4370
|
onOpenRuns: props.onOpenRuns,
|
|
4271
|
-
onSelect: props.onSelect
|
|
4371
|
+
onSelect: props.onSelect,
|
|
4372
|
+
onRegenerate: regenerate,
|
|
4373
|
+
regenDisabled: regenerateDisabled
|
|
4272
4374
|
}) : h(
|
|
4273
4375
|
"div",
|
|
4274
4376
|
{ className: "dshgt-digest-body" },
|
|
@@ -4284,6 +4386,7 @@ function DigestView(props) {
|
|
|
4284
4386
|
h("span", { className: "dshgt-dim" }, record.preview === void 0 ? "—" : formatBytes(record.preview.bytes)),
|
|
4285
4387
|
payload?.preview.truncated === true ? h("span", { className: "dshgt-tag" }, t("digest.truncated")) : null,
|
|
4286
4388
|
h("span", { className: "dshgt-grow" }),
|
|
4389
|
+
h(Btn, { small: true, onClick: regenerate, disabled: regenerateDisabled }, t("digest.regenerate")),
|
|
4287
4390
|
h(
|
|
4288
4391
|
"div",
|
|
4289
4392
|
{ className: "dshgt-seg", role: "group", "aria-label": t("digest.mode") },
|
|
@@ -4372,12 +4475,6 @@ function monthDay(value) {
|
|
|
4372
4475
|
if (value === void 0 || value === "") return "—";
|
|
4373
4476
|
return DATE_RE2.test(value) ? value.slice(5) : value;
|
|
4374
4477
|
}
|
|
4375
|
-
function clock(value) {
|
|
4376
|
-
return /^\d{2}:\d{2}/.test(value) ? value.slice(0, 5) : value;
|
|
4377
|
-
}
|
|
4378
|
-
function weekdayLabel(t, weekday) {
|
|
4379
|
-
return weekday >= 1 && weekday <= 7 ? t(`weekday.${weekday}`) : String(weekday);
|
|
4380
|
-
}
|
|
4381
4478
|
function toneOf(status) {
|
|
4382
4479
|
if (status === "ok") return "ok";
|
|
4383
4480
|
if (status === "rate_limited") return "warn";
|
|
@@ -4435,47 +4532,6 @@ function highlight(text, needle) {
|
|
|
4435
4532
|
if (index < text.length) parts.push(text.slice(index));
|
|
4436
4533
|
return parts;
|
|
4437
4534
|
}
|
|
4438
|
-
function weekStart(date) {
|
|
4439
|
-
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
|
|
4440
|
-
if (match === null) return date;
|
|
4441
|
-
const value = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
|
|
4442
|
-
const dayIndex = (value.getUTCDay() + 6) % 7;
|
|
4443
|
-
value.setUTCDate(value.getUTCDate() - dayIndex);
|
|
4444
|
-
return value.toISOString().slice(0, 10);
|
|
4445
|
-
}
|
|
4446
|
-
function metaOf(t, store) {
|
|
4447
|
-
const state = store?.state ?? null;
|
|
4448
|
-
const schedule = state?.schedule;
|
|
4449
|
-
const releaseSchedule = state?.settings?.releases?.schedule;
|
|
4450
|
-
const weekday = typeof schedule?.releaseWeekday === "number" ? schedule.releaseWeekday : releaseSchedule?.weekday;
|
|
4451
|
-
const time = typeof schedule?.releaseTime === "string" && schedule.releaseTime !== "" ? schedule.releaseTime : releaseSchedule?.time;
|
|
4452
|
-
const timezone = (typeof schedule?.releaseTimezone === "string" && schedule.releaseTimezone !== "" ? schedule.releaseTimezone : releaseSchedule?.timezone) ?? schedule?.timezone ?? "Asia/Shanghai";
|
|
4453
|
-
const cadence = weekday === void 0 || time === void 0 || time === "" ? t("subs.meta.cadence") : t("subs.meta.cadence.full", { weekday: weekdayLabel(t, weekday), time: clock(time) });
|
|
4454
|
-
const nextAt = typeof schedule?.nextReleaseAt === "string" && schedule.nextReleaseAt !== "" ? schedule.nextReleaseAt : void 0;
|
|
4455
|
-
const next = nextAt === void 0 ? void 0 : shortTime(nextAt);
|
|
4456
|
-
const runs = releaseRunsOf(state);
|
|
4457
|
-
const newest = runs.length === 0 ? void 0 : runs.reduce((a, b) => Date.parse(b.finishedAt || b.startedAt) > Date.parse(a.finishedAt || a.startedAt) ? b : a);
|
|
4458
|
-
const lastCheckAt = newest?.finishedAt ?? lastReleaseAtOf(state);
|
|
4459
|
-
const lastCheck = typeof lastCheckAt === "string" && lastCheckAt !== "" ? shortTime(lastCheckAt) : void 0;
|
|
4460
|
-
let lastWeek;
|
|
4461
|
-
if (newest !== void 0) {
|
|
4462
|
-
const today = zonedDateString(/* @__PURE__ */ new Date(), timezone);
|
|
4463
|
-
const currentFrom = weekStart(today);
|
|
4464
|
-
const lastFrom = addDays(currentFrom, -7);
|
|
4465
|
-
const at = newest.finishedAt !== "" ? newest.finishedAt : newest.startedAt;
|
|
4466
|
-
const runDate = zonedDateString(new Date(at), timezone);
|
|
4467
|
-
if (runDate >= lastFrom && runDate <= addDays(lastFrom, 6)) {
|
|
4468
|
-
lastWeek = t("subs.meta.lastWeek", { from: monthDay(lastFrom), to: monthDay(addDays(lastFrom, 6)), changed: newest.changed });
|
|
4469
|
-
} else if (runDate >= currentFrom && runDate <= addDays(currentFrom, 6)) {
|
|
4470
|
-
lastWeek = t("subs.meta.thisWeek", { from: monthDay(currentFrom), to: monthDay(addDays(currentFrom, 6)), changed: newest.changed });
|
|
4471
|
-
}
|
|
4472
|
-
}
|
|
4473
|
-
const info = { cadence };
|
|
4474
|
-
if (next !== void 0) info.next = next;
|
|
4475
|
-
if (lastWeek !== void 0) info.lastWeek = lastWeek;
|
|
4476
|
-
if (lastCheck !== void 0) info.lastCheck = lastCheck;
|
|
4477
|
-
return info;
|
|
4478
|
-
}
|
|
4479
4535
|
function isMissingDoc(code, message) {
|
|
4480
4536
|
if (code !== void 0 && /NOT_?FOUND|MISSING|NO_?DOC/i.test(code)) return true;
|
|
4481
4537
|
return /not\s*found|no such file|enoent|404|不存在|no release document|has no release|无发版记录/i.test(message);
|
|
@@ -4630,7 +4686,10 @@ function SubscriptionsView(props) {
|
|
|
4630
4686
|
const [selected, setSelected] = import_react.default.useState([]);
|
|
4631
4687
|
const [confirming, setConfirming] = import_react.default.useState(null);
|
|
4632
4688
|
const [openRepo, setOpenRepo] = import_react.default.useState(null);
|
|
4633
|
-
const [
|
|
4689
|
+
const [addOpen, setAddOpen] = import_react.default.useState(false);
|
|
4690
|
+
const [addValue, setAddValue] = import_react.default.useState("");
|
|
4691
|
+
const [analyzing, setAnalyzing] = import_react.default.useState(null);
|
|
4692
|
+
const [result, setResult] = import_react.default.useState(null);
|
|
4634
4693
|
const load = import_react.default.useCallback((signal) => {
|
|
4635
4694
|
getSubscriptions(signal).then((next) => {
|
|
4636
4695
|
if (signal?.aborted === true) return;
|
|
@@ -4647,23 +4706,10 @@ function SubscriptionsView(props) {
|
|
|
4647
4706
|
load(controller.signal);
|
|
4648
4707
|
return () => controller.abort();
|
|
4649
4708
|
}, [load]);
|
|
4650
|
-
const inputRef = import_react.default.useRef(null);
|
|
4651
|
-
import_react.default.useEffect(() => {
|
|
4652
|
-
const onKey = (event) => {
|
|
4653
|
-
if (event.key.toLowerCase() !== "k" || !(event.metaKey || event.ctrlKey)) return;
|
|
4654
|
-
event.preventDefault();
|
|
4655
|
-
inputRef.current?.focus?.();
|
|
4656
|
-
};
|
|
4657
|
-
document.addEventListener("keydown", onKey);
|
|
4658
|
-
return () => document.removeEventListener("keydown", onKey);
|
|
4659
|
-
}, []);
|
|
4660
4709
|
const rows = mergeRows(list);
|
|
4661
4710
|
const needle = query.trim().toLowerCase();
|
|
4662
4711
|
const matched = needle === "" ? rows : rows.filter((row) => row.name.toLowerCase().includes(needle));
|
|
4663
4712
|
const sorted = sortRows(matched, sort);
|
|
4664
|
-
const candidate = needle !== "" && REPO_PATTERN.test(query.trim()) ? query.trim() : void 0;
|
|
4665
|
-
const subscribed = candidate !== void 0 && rows.some((row) => row.name.toLowerCase() === candidate.toLowerCase());
|
|
4666
|
-
const activeFocus = focus >= 0 && focus < sorted.length ? focus : -1;
|
|
4667
4713
|
const toggleSelect = (repo) => {
|
|
4668
4714
|
setSelected((current) => current.includes(repo) ? current.filter((item) => item !== repo) : [...current, repo]);
|
|
4669
4715
|
};
|
|
@@ -4673,8 +4719,8 @@ function SubscriptionsView(props) {
|
|
|
4673
4719
|
setNote(null);
|
|
4674
4720
|
postSubscriptions("add", [repo]).then((next) => {
|
|
4675
4721
|
setList(next);
|
|
4676
|
-
|
|
4677
|
-
|
|
4722
|
+
setAddValue("");
|
|
4723
|
+
setAddOpen(false);
|
|
4678
4724
|
setNote(t("subs.add.queued", { repo }));
|
|
4679
4725
|
}).catch((failure) => setError(errorText(failure))).finally(() => setBusy(null));
|
|
4680
4726
|
};
|
|
@@ -4703,6 +4749,22 @@ function SubscriptionsView(props) {
|
|
|
4703
4749
|
setConfirming(null);
|
|
4704
4750
|
}).finally(() => setBusy(null));
|
|
4705
4751
|
};
|
|
4752
|
+
const runAnalyze = (repo) => {
|
|
4753
|
+
if (analyzing !== null) return;
|
|
4754
|
+
setAnalyzing(repo === void 0 ? { scope: "all" } : { scope: "one", repo });
|
|
4755
|
+
setError(null);
|
|
4756
|
+
setResult(null);
|
|
4757
|
+
postReleasesRun(repo).then((record) => {
|
|
4758
|
+
setResult({ scope: repo === void 0 ? "all" : "one", ...repo === void 0 ? {} : { repo }, ok: record.status !== "failed", changed: record.changed });
|
|
4759
|
+
if (record.status === "failed" && record.errorMessage !== void 0) {
|
|
4760
|
+
setError(t("subs.analyze.failed", { message: record.errorMessage }));
|
|
4761
|
+
}
|
|
4762
|
+
load();
|
|
4763
|
+
}).catch((failure) => {
|
|
4764
|
+
setError(errorText(failure));
|
|
4765
|
+
setResult({ scope: repo === void 0 ? "all" : "one", ...repo === void 0 ? {} : { repo }, ok: false, changed: 0 });
|
|
4766
|
+
}).finally(() => setAnalyzing(null));
|
|
4767
|
+
};
|
|
4706
4768
|
const onSort = (key) => {
|
|
4707
4769
|
setSort((current) => current.key === key ? { key, dir: current.dir === 1 ? -1 : 1 } : { key, dir: 1 });
|
|
4708
4770
|
};
|
|
@@ -4723,48 +4785,19 @@ function SubscriptionsView(props) {
|
|
|
4723
4785
|
active ? h("span", { className: "dshgt-subs-ord" }, sort.dir === 1 ? "▲" : "▼") : null
|
|
4724
4786
|
);
|
|
4725
4787
|
};
|
|
4726
|
-
const
|
|
4727
|
-
|
|
4728
|
-
if (event.key === "Escape") {
|
|
4729
|
-
setQuery("");
|
|
4730
|
-
setFocus(-1);
|
|
4731
|
-
if (selecting) {
|
|
4732
|
-
setSelecting(false);
|
|
4733
|
-
setSelected([]);
|
|
4734
|
-
}
|
|
4735
|
-
return;
|
|
4736
|
-
}
|
|
4737
|
-
if (event.key === "Enter") {
|
|
4738
|
-
if (candidate !== void 0 && !subscribed) {
|
|
4739
|
-
event.preventDefault();
|
|
4740
|
-
addRepo(candidate);
|
|
4741
|
-
return;
|
|
4742
|
-
}
|
|
4743
|
-
if (activeFocus >= 0) {
|
|
4744
|
-
event.preventDefault();
|
|
4745
|
-
setOpenRepo(sorted[activeFocus]?.name ?? null);
|
|
4746
|
-
}
|
|
4747
|
-
return;
|
|
4748
|
-
}
|
|
4749
|
-
if (event.key === "ArrowDown") {
|
|
4750
|
-
event.preventDefault();
|
|
4751
|
-
setFocus(Math.min(sorted.length - 1, focus + 1));
|
|
4752
|
-
return;
|
|
4753
|
-
}
|
|
4754
|
-
if (event.key === "ArrowUp") {
|
|
4755
|
-
event.preventDefault();
|
|
4756
|
-
setFocus(Math.max(-1, focus - 1));
|
|
4757
|
-
}
|
|
4758
|
-
};
|
|
4759
|
-
const meta = metaOf(t, props.store);
|
|
4760
|
-
const metaRight = needle !== "" ? [t("subs.meta.match", { matched: sorted.length, total: rows.length })] : [
|
|
4761
|
-
meta.lastCheck === void 0 ? void 0 : t("subs.meta.lastCheck", { time: meta.lastCheck }),
|
|
4762
|
-
meta.lastWeek
|
|
4763
|
-
].filter((item) => item !== void 0);
|
|
4788
|
+
const canAdd = REPO_PATTERN.test(addValue.trim());
|
|
4789
|
+
const alreadySubscribed = canAdd && rows.some((row) => row.name.toLowerCase() === addValue.trim().toLowerCase());
|
|
4764
4790
|
const drawerRow = openRepo === null ? void 0 : rows.find((row) => row.name === openRepo);
|
|
4765
|
-
const
|
|
4791
|
+
const globalBusy = analyzing !== null;
|
|
4792
|
+
const banner = result === null ? null : result.ok ? h(
|
|
4793
|
+
Alert,
|
|
4794
|
+
{ kind: "ok" },
|
|
4795
|
+
result.scope === "all" ? t("subs.analyze.done", { count: result.changed }) : t("subs.analyze.doneOne", { repo: result.repo ?? "" })
|
|
4796
|
+
) : null;
|
|
4797
|
+
const rowNodes = sorted.map((row) => {
|
|
4766
4798
|
const item = row.item;
|
|
4767
4799
|
const tone = toneOf(item?.status);
|
|
4800
|
+
const rowAnalyzing = analyzing !== null && analyzing.scope === "one" && analyzing.repo === row.name;
|
|
4768
4801
|
const checkbox = selecting ? h(
|
|
4769
4802
|
"span",
|
|
4770
4803
|
{ key: "cb", role: "cell", className: "dshgt-subs-cbwrap" },
|
|
@@ -4782,7 +4815,7 @@ function SubscriptionsView(props) {
|
|
|
4782
4815
|
{
|
|
4783
4816
|
key: row.name,
|
|
4784
4817
|
role: "row",
|
|
4785
|
-
className: `dshgt-subs-row${
|
|
4818
|
+
className: `dshgt-subs-row${rowAnalyzing ? " is-analyzing" : ""}`,
|
|
4786
4819
|
onClick: () => {
|
|
4787
4820
|
if (selecting) toggleSelect(row.name);
|
|
4788
4821
|
else setOpenRepo(row.name);
|
|
@@ -4805,6 +4838,21 @@ function SubscriptionsView(props) {
|
|
|
4805
4838
|
h(
|
|
4806
4839
|
"span",
|
|
4807
4840
|
{ key: "act", role: "cell", className: "dshgt-subs-actions" },
|
|
4841
|
+
rowAnalyzing ? h("span", { className: "dshgt-subs-rowbusy" }, h("span", { className: "dshgt-spin" }), t("subs.analyzing")) : h(
|
|
4842
|
+
"button",
|
|
4843
|
+
{
|
|
4844
|
+
type: "button",
|
|
4845
|
+
className: "dshgt-subs-act gen",
|
|
4846
|
+
"aria-label": t("subs.row.triggerRepo", { repo: row.name }),
|
|
4847
|
+
title: t("subs.row.triggerRepo", { repo: row.name }),
|
|
4848
|
+
disabled: globalBusy || busy !== null,
|
|
4849
|
+
onClick: (event) => {
|
|
4850
|
+
event.stopPropagation();
|
|
4851
|
+
runAnalyze(row.name);
|
|
4852
|
+
}
|
|
4853
|
+
},
|
|
4854
|
+
t("subs.row.trigger")
|
|
4855
|
+
),
|
|
4808
4856
|
h(
|
|
4809
4857
|
"button",
|
|
4810
4858
|
{
|
|
@@ -4840,10 +4888,7 @@ function SubscriptionsView(props) {
|
|
|
4840
4888
|
{ className: "dshgt-subs-empty" },
|
|
4841
4889
|
h("b", null, t("subs.empty")),
|
|
4842
4890
|
h("span", null, t("subs.empty.hint"))
|
|
4843
|
-
) : sorted.length === 0 ?
|
|
4844
|
-
// 输入完整 owner/repo 时上方已给出「+ 添加」建议,这里不再叠一句「没有匹配」。
|
|
4845
|
-
null
|
|
4846
|
-
) : h(
|
|
4891
|
+
) : sorted.length === 0 ? h(
|
|
4847
4892
|
"div",
|
|
4848
4893
|
{ className: "dshgt-subs-empty" },
|
|
4849
4894
|
h("b", null, t("subs.empty.match")),
|
|
@@ -4867,101 +4912,94 @@ function SubscriptionsView(props) {
|
|
|
4867
4912
|
return h(
|
|
4868
4913
|
"div",
|
|
4869
4914
|
{ className: "dshgt-view dshgt-subs" },
|
|
4870
|
-
|
|
4871
|
-
"section",
|
|
4872
|
-
{ className: "dshgt-subs-head" },
|
|
4873
|
-
h(
|
|
4874
|
-
"div",
|
|
4875
|
-
{ className: "dshgt-subs-head-main" },
|
|
4876
|
-
h("h2", null, t("subs.title")),
|
|
4877
|
-
h("p", { className: "dshgt-subs-dek" }, t("subs.desc"))
|
|
4878
|
-
),
|
|
4879
|
-
h(
|
|
4880
|
-
"div",
|
|
4881
|
-
{ className: "dshgt-subs-head-actions" },
|
|
4882
|
-
h(
|
|
4883
|
-
Btn,
|
|
4884
|
-
{
|
|
4885
|
-
small: true,
|
|
4886
|
-
onClick: () => {
|
|
4887
|
-
if (selecting) setSelected([]);
|
|
4888
|
-
setSelecting(!selecting);
|
|
4889
|
-
}
|
|
4890
|
-
},
|
|
4891
|
-
selecting ? t("subs.select.done") : t("subs.select")
|
|
4892
|
-
)
|
|
4893
|
-
)
|
|
4894
|
-
),
|
|
4915
|
+
// 工具条:搜索 + 添加 + 选择 + 生成变更分析(主操作)
|
|
4895
4916
|
h(
|
|
4896
4917
|
"div",
|
|
4897
|
-
{ className: "dshgt-subs-
|
|
4918
|
+
{ className: "dshgt-subs-toolbar" },
|
|
4898
4919
|
h(
|
|
4899
4920
|
"div",
|
|
4900
|
-
{ className: "dshgt-subs-
|
|
4921
|
+
{ className: "dshgt-subs-search" },
|
|
4922
|
+
h(
|
|
4923
|
+
"svg",
|
|
4924
|
+
{ width: 15, height: 15, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": 2, "stroke-linecap": "round", "aria-hidden": "true" },
|
|
4925
|
+
h("circle", { cx: 11, cy: 11, r: 7 }),
|
|
4926
|
+
h("path", { d: "m20 20-3.5-3.5" })
|
|
4927
|
+
),
|
|
4901
4928
|
h("input", {
|
|
4902
4929
|
type: "text",
|
|
4903
|
-
ref: inputRef,
|
|
4904
4930
|
value: query,
|
|
4905
|
-
placeholder: t("subs.
|
|
4906
|
-
"aria-label": t("subs.
|
|
4907
|
-
"aria-keyshortcuts": "Meta+K Control+K",
|
|
4931
|
+
placeholder: t("subs.search.placeholder"),
|
|
4932
|
+
"aria-label": t("subs.search.label"),
|
|
4908
4933
|
autoComplete: "off",
|
|
4909
4934
|
spellCheck: false,
|
|
4910
|
-
onInput: (event) =>
|
|
4911
|
-
|
|
4912
|
-
setFocus(-1);
|
|
4913
|
-
},
|
|
4914
|
-
onKeyDown: onCommandKey
|
|
4915
|
-
}),
|
|
4916
|
-
h("kbd", { className: "dshgt-subs-kbd" }, "⌘K")
|
|
4935
|
+
onInput: (event) => setQuery(event.target.value)
|
|
4936
|
+
})
|
|
4917
4937
|
),
|
|
4918
|
-
h(
|
|
4938
|
+
h("div", { className: "dshgt-subs-toolbar-spacer" }),
|
|
4939
|
+
addOpen ? h(
|
|
4919
4940
|
"div",
|
|
4920
|
-
{ className: "dshgt-subs-
|
|
4941
|
+
{ className: "dshgt-subs-addform" },
|
|
4942
|
+
h("input", {
|
|
4943
|
+
type: "text",
|
|
4944
|
+
value: addValue,
|
|
4945
|
+
placeholder: t("subs.add.placeholder"),
|
|
4946
|
+
"aria-label": t("subs.add.placeholder"),
|
|
4947
|
+
autoComplete: "off",
|
|
4948
|
+
spellCheck: false,
|
|
4949
|
+
autoFocus: true,
|
|
4950
|
+
onInput: (event) => setAddValue(event.target.value),
|
|
4951
|
+
onKeyDown: (event) => {
|
|
4952
|
+
if (event.isComposing === true) return;
|
|
4953
|
+
if (event.key === "Enter" && canAdd && !alreadySubscribed) addRepo(addValue.trim());
|
|
4954
|
+
if (event.key === "Escape") {
|
|
4955
|
+
setAddOpen(false);
|
|
4956
|
+
setAddValue("");
|
|
4957
|
+
}
|
|
4958
|
+
}
|
|
4959
|
+
}),
|
|
4921
4960
|
h(
|
|
4922
|
-
|
|
4923
|
-
null,
|
|
4924
|
-
t("subs.
|
|
4925
|
-
" · ",
|
|
4926
|
-
h(
|
|
4927
|
-
"button",
|
|
4928
|
-
{ type: "button", className: "dshgt-subs-linkbtn", title: t("subs.param.link"), onClick: () => props.onOpenSettings() },
|
|
4929
|
-
meta.cadence
|
|
4930
|
-
),
|
|
4931
|
-
meta.next === void 0 ? null : ` · ${t("subs.meta.next", { time: meta.next })}`
|
|
4932
|
-
),
|
|
4933
|
-
metaRight.length === 0 ? null : h(
|
|
4934
|
-
"span",
|
|
4935
|
-
{ className: "dshgt-subs-meta-right" },
|
|
4936
|
-
metaRight.flatMap((part, index) => index === 0 ? [part] : [h("span", { key: `sep${index}`, className: "dshgt-subs-meta-sep" }, "·"), part])
|
|
4961
|
+
Btn,
|
|
4962
|
+
{ small: true, variant: "primary", disabled: busy !== null || !canAdd || alreadySubscribed, onClick: () => canAdd && !alreadySubscribed && addRepo(addValue.trim()) },
|
|
4963
|
+
t("subs.add.confirm")
|
|
4937
4964
|
)
|
|
4965
|
+
) : h(
|
|
4966
|
+
Btn,
|
|
4967
|
+
{
|
|
4968
|
+
small: true,
|
|
4969
|
+
disabled: busy !== null,
|
|
4970
|
+
onClick: () => {
|
|
4971
|
+
setAddOpen(true);
|
|
4972
|
+
setAddValue("");
|
|
4973
|
+
}
|
|
4974
|
+
},
|
|
4975
|
+
t("subs.toolbar.add")
|
|
4976
|
+
),
|
|
4977
|
+
h(
|
|
4978
|
+
Btn,
|
|
4979
|
+
{
|
|
4980
|
+
small: true,
|
|
4981
|
+
onClick: () => {
|
|
4982
|
+
if (selecting) setSelected([]);
|
|
4983
|
+
setSelecting(!selecting);
|
|
4984
|
+
}
|
|
4985
|
+
},
|
|
4986
|
+
selecting ? t("subs.select.done") : t("subs.select")
|
|
4987
|
+
),
|
|
4988
|
+
h(
|
|
4989
|
+
Btn,
|
|
4990
|
+
{
|
|
4991
|
+
small: true,
|
|
4992
|
+
variant: "primary",
|
|
4993
|
+
disabled: globalBusy || busy !== null,
|
|
4994
|
+
onClick: () => runAnalyze()
|
|
4995
|
+
},
|
|
4996
|
+
analyzing !== null && analyzing.scope === "all" ? t("subs.analyzing") : t("subs.toolbar.analyze")
|
|
4938
4997
|
)
|
|
4939
4998
|
),
|
|
4940
|
-
|
|
4941
|
-
"div",
|
|
4942
|
-
{ className: "dshgt-subs-suggest" },
|
|
4943
|
-
subscribed ? [
|
|
4944
|
-
h("span", { key: "pill", className: "dshgt-tag" }, t("subs.cmd.subscribed")),
|
|
4945
|
-
h("span", { key: "repo", className: "repo" }, candidate),
|
|
4946
|
-
h("span", { key: "hint", className: "hint" }, t("subs.cmd.subscribed.hint"))
|
|
4947
|
-
] : [
|
|
4948
|
-
h("span", { key: "plus", className: "plus" }, "+"),
|
|
4949
|
-
h("span", { key: "add" }, t("subs.cmd.add")),
|
|
4950
|
-
h("span", { key: "repo", className: "repo" }, candidate),
|
|
4951
|
-
h("span", { key: "hint", className: "hint" }, t("subs.cmd.add.hint"))
|
|
4952
|
-
]
|
|
4953
|
-
),
|
|
4999
|
+
banner,
|
|
4954
5000
|
error === null ? null : h(Alert, { kind: "err" }, error),
|
|
4955
5001
|
note === null ? null : h(Alert, { kind: "ok" }, note),
|
|
4956
5002
|
tableBody,
|
|
4957
|
-
h(
|
|
4958
|
-
"div",
|
|
4959
|
-
{ className: "dshgt-subs-keys" },
|
|
4960
|
-
h("span", null, t("subs.keys.move")),
|
|
4961
|
-
h("span", null, t("subs.keys.enter")),
|
|
4962
|
-
h("span", null, t("subs.keys.esc")),
|
|
4963
|
-
h("span", null, t("subs.keys.sort"))
|
|
4964
|
-
),
|
|
4965
5003
|
selecting && rows.length > 0 ? h(
|
|
4966
5004
|
"div",
|
|
4967
5005
|
{ className: "dshgt-subs-selbar" },
|
|
@@ -5550,7 +5588,7 @@ function apply(ctx) {
|
|
|
5550
5588
|
state.github.configured
|
|
5551
5589
|
].filter(Boolean).length;
|
|
5552
5590
|
const digestTail = state?.status.lastResult?.date ?? state?.status.history[0]?.date;
|
|
5553
|
-
const showActions = view === "overview" || view === "runs";
|
|
5591
|
+
const showActions = view === "overview" || view === "runs" || view === "digest";
|
|
5554
5592
|
const nextRun = schedule === void 0 || !schedule.enabled ? t("shell.scheduleOff") : schedule.nextRunAt === void 0 ? `${schedule.time} · ${schedule.timezone}` : nextRunText(schedule.nextRunAt);
|
|
5555
5593
|
const relNext = schedule !== void 0 && schedule.enabled && schedule.nextRunAt !== void 0 ? relativeFuture(schedule.nextRunAt, t) : void 0;
|
|
5556
5594
|
const viewNode = view === "overview" ? h(OverviewView, {
|
|
@@ -5565,6 +5603,7 @@ function apply(ctx) {
|
|
|
5565
5603
|
t,
|
|
5566
5604
|
lang,
|
|
5567
5605
|
store: value,
|
|
5606
|
+
controller,
|
|
5568
5607
|
...digestTarget2 === void 0 ? {} : { selected: digestTarget2 },
|
|
5569
5608
|
onSelect: setDigestTarget,
|
|
5570
5609
|
onOpenRuns: openRuns
|
|
@@ -5641,6 +5680,15 @@ function apply(ctx) {
|
|
|
5641
5680
|
},
|
|
5642
5681
|
t("run.dryRunShort")
|
|
5643
5682
|
),
|
|
5683
|
+
h(
|
|
5684
|
+
Btn,
|
|
5685
|
+
{
|
|
5686
|
+
key: "force",
|
|
5687
|
+
onClick: () => void controller.run(false, { force: true }),
|
|
5688
|
+
disabled: controller.running || controller.busy
|
|
5689
|
+
},
|
|
5690
|
+
t("run.force")
|
|
5691
|
+
),
|
|
5644
5692
|
h(
|
|
5645
5693
|
Btn,
|
|
5646
5694
|
{
|