Skip to content

Commit 43c76fd

Browse files
authored
Polish runtime account status display
1 parent 40bca61 commit 43c76fd

3 files changed

Lines changed: 99 additions & 21 deletions

File tree

tests/strategy_switch_worker_validation.mjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,13 @@ assert.ok(indexHtml.includes('reservePolicyMax'));
6464
assert.ok(indexHtml.includes('pluginModeAuto'));
6565
assert.ok(indexHtml.includes('pluginModeNone'));
6666
assert.ok(indexHtml.includes('runtimeTargetMode: "账号运行状态"'));
67-
assert.ok(indexHtml.includes('runtimeTargetEnabled: "启用正式运行"'));
68-
assert.ok(indexHtml.includes('runtimeTargetDisabled: "停用正式运行"'));
67+
assert.ok(indexHtml.includes('runtimeTargetEnabled: "启用"'));
68+
assert.ok(indexHtml.includes('runtimeTargetDisabled: "禁用"'));
6969
assert.ok(indexHtml.includes('runtimeTargetMode: "Account status"'));
70+
assert.ok(indexHtml.includes('runtimeTargetEnabled: "Enabled"'));
71+
assert.ok(indexHtml.includes('runtimeTargetDisabled: "Disabled"'));
72+
assert.ok(indexHtml.includes("function runtimeTargetStateForAccount("));
73+
assert.ok(indexHtml.includes(".summary-status.disabled"));
7074
assert.ok(indexHtml.includes('pluginMode: "插件启用范围"'));
7175
assert.ok(indexHtml.includes('pluginModeAuto: "启用插件"'));
7276
assert.ok(indexHtml.includes('pluginModeNone: "禁用插件"'));

web/strategy-switch-console/index.html

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,38 @@
612612
font-weight: 800;
613613
}
614614

615+
.summary-status {
616+
min-height: 24px;
617+
display: inline-flex;
618+
align-items: center;
619+
justify-content: center;
620+
padding: 0 9px;
621+
border: 1px solid rgba(19, 111, 99, 0.28);
622+
border-radius: 999px;
623+
background: #eff9f6;
624+
color: var(--accent);
625+
font-size: 12px;
626+
line-height: 1.2;
627+
font-weight: 800;
628+
white-space: nowrap;
629+
}
630+
631+
.summary-status.disabled {
632+
border-color: rgba(181, 65, 55, 0.32);
633+
background: #fff1ef;
634+
color: var(--danger);
635+
}
636+
637+
.summary-status.neutral {
638+
border-color: var(--line);
639+
background: #f6f7f8;
640+
color: var(--muted);
641+
}
642+
643+
.summary-row.pending .summary-status {
644+
font-weight: 840;
645+
}
646+
615647
.summary-actions {
616648
display: flex;
617649
gap: 10px;
@@ -1012,8 +1044,8 @@ <h2 data-i18n="summary">切换摘要</h2>
10121044
paper: "模拟",
10131045
runtimeTargetMode: "账号运行状态",
10141046
runtimeTargetCurrent: "沿用当前状态",
1015-
runtimeTargetEnabled: "启用正式运行",
1016-
runtimeTargetDisabled: "停用正式运行",
1047+
runtimeTargetEnabled: "启用",
1048+
runtimeTargetDisabled: "禁用",
10171049
runtimeTargetModeMeta: "停用后正式运行会跳过,模拟运行和健康检查仍可用。",
10181050
pluginMode: "插件启用范围",
10191051
pluginModeAuto: "启用插件",
@@ -1097,9 +1129,8 @@ <h2 data-i18n="summary">切换摘要</h2>
10971129
currentStrategy: "当前策略",
10981130
nextStrategy: "切换策略",
10991131
notRead: "未读取",
1100-
runtimeTargetDefault: "未配置(默认启用)",
1101-
runtimeTargetOn: "启用正式运行",
1102-
runtimeTargetOff: "停用正式运行",
1132+
runtimeTargetOn: "启用",
1133+
runtimeTargetOff: "禁用",
11031134
incomeLayerDefault: "策略默认:开启,起始 {start},最高 {ratio}",
11041135
incomeLayerOff: "关闭",
11051136
incomeLayerOn: "开启,起始 {start},最高 {ratio}",
@@ -1125,8 +1156,8 @@ <h2 data-i18n="summary">切换摘要</h2>
11251156
paper: "Dry run",
11261157
runtimeTargetMode: "Account status",
11271158
runtimeTargetCurrent: "Keep current status",
1128-
runtimeTargetEnabled: "Enable live runs",
1129-
runtimeTargetDisabled: "Disable live runs",
1159+
runtimeTargetEnabled: "Enabled",
1160+
runtimeTargetDisabled: "Disabled",
11301161
runtimeTargetModeMeta: "Disabled accounts skip live runs; dry runs and health checks still work.",
11311162
pluginMode: "Plugin scope",
11321163
pluginModeAuto: "Enabled",
@@ -1210,9 +1241,8 @@ <h2 data-i18n="summary">切换摘要</h2>
12101241
currentStrategy: "Current strategy",
12111242
nextStrategy: "Switch strategy",
12121243
notRead: "Not read",
1213-
runtimeTargetDefault: "Not configured (enabled by default)",
1214-
runtimeTargetOn: "Live runs enabled",
1215-
runtimeTargetOff: "Live runs disabled",
1244+
runtimeTargetOn: "Enabled",
1245+
runtimeTargetOff: "Disabled",
12161246
incomeLayerDefault: "Strategy default: enabled, starts at {start}, max {ratio}",
12171247
incomeLayerOff: "Disabled",
12181248
incomeLayerOn: "Enabled, starts at {start}, max {ratio}",
@@ -1477,12 +1507,33 @@ <h2 data-i18n="summary">切换摘要</h2>
14771507
return cleanOptionalBoolean(currentEntryForAccount(platform, account)?.runtime_target_enabled);
14781508
}
14791509

1480-
function currentRuntimeTargetText(platform = state.selected, account = selectedAccount(platform)) {
1481-
const enabled = runtimeTargetEnabledForAccount(platform, account);
1482-
if (enabled === null) return t("runtimeTargetDefault");
1510+
function runtimeTargetStateForAccount(platform = state.selected, account = selectedAccount(platform)) {
1511+
const entry = currentEntryForAccount(platform, account);
1512+
if (!entry) return { known: false, enabled: null };
1513+
const configured = cleanOptionalBoolean(entry.runtime_target_enabled);
1514+
return { known: true, enabled: configured ?? true };
1515+
}
1516+
1517+
function runtimeTargetText(enabled) {
14831518
return enabled ? t("runtimeTargetOn") : t("runtimeTargetOff");
14841519
}
14851520

1521+
function runtimeTargetTone(enabled) {
1522+
return enabled ? "enabled" : "disabled";
1523+
}
1524+
1525+
function currentRuntimeTargetText(platform = state.selected, account = selectedAccount(platform)) {
1526+
const target = runtimeTargetStateForAccount(platform, account);
1527+
if (!target.known) return t("notRead");
1528+
return runtimeTargetText(target.enabled);
1529+
}
1530+
1531+
function currentRuntimeTargetTone(platform = state.selected, account = selectedAccount(platform)) {
1532+
const target = runtimeTargetStateForAccount(platform, account);
1533+
if (!target.known) return "neutral";
1534+
return runtimeTargetTone(target.enabled);
1535+
}
1536+
14861537
function incomeLayerDefaultForStrategy(profile) {
14871538
return incomeLayerDefaults[cleanStrategyProfile(profile)] || null;
14881539
}
@@ -1998,7 +2049,13 @@ <h2 data-i18n="summary">切换摘要</h2>
19982049
function pendingRuntimeTargetText(inputs, platform = state.selected, account = selectedAccount(platform)) {
19992050
const pending = pendingRuntimeTarget(inputs, platform, account);
20002051
if (!pending.changed) return t("unchanged");
2001-
return pending.inputs.runtime_target_enabled ? t("runtimeTargetOn") : t("runtimeTargetOff");
2052+
return runtimeTargetText(pending.inputs.runtime_target_enabled);
2053+
}
2054+
2055+
function pendingRuntimeTargetTone(inputs, platform = state.selected, account = selectedAccount(platform)) {
2056+
const pending = pendingRuntimeTarget(inputs, platform, account);
2057+
if (!pending.changed) return "neutral";
2058+
return runtimeTargetTone(pending.inputs.runtime_target_enabled);
20022059
}
20032060

20042061
function currentDcaText(platform = state.selected, account = selectedAccount(platform), profile = state.forms[platform]?.strategy) {
@@ -2175,7 +2232,12 @@ <h2 data-i18n="summary">切换摘要</h2>
21752232
[t("selectedAccount"), account.label],
21762233
[t("currentStrategy"), currentStrategyText],
21772234
[t("selectedMarket"), supportedDomainLabel(state.selected, account)],
2178-
[t("currentRuntimeTarget"), currentRuntimeTargetText(state.selected, account)],
2235+
[
2236+
t("currentRuntimeTarget"),
2237+
currentRuntimeTargetText(state.selected, account),
2238+
"",
2239+
currentRuntimeTargetTone(state.selected, account),
2240+
],
21792241
[t("currentPluginMode"), pluginModeLabel(changes.currentPluginMode)],
21802242
[t("reservedCashPolicy"), currentReservedCashPolicyText(state.selected, account)],
21812243
];
@@ -2201,7 +2263,12 @@ <h2 data-i18n="summary">切换摘要</h2>
22012263
rows.push([t("pendingPluginMode"), pluginModeLabel(changes.nextPluginMode), "pending"]);
22022264
}
22032265
if (changes.runtimeTargetChanged) {
2204-
rows.push([t("pendingRuntimeTarget"), pendingRuntimeTargetText(inputs, state.selected, account), "pending"]);
2266+
rows.push([
2267+
t("pendingRuntimeTarget"),
2268+
pendingRuntimeTargetText(inputs, state.selected, account),
2269+
"pending",
2270+
pendingRuntimeTargetTone(inputs, state.selected, account),
2271+
]);
22052272
}
22062273
if (changes.strategyChanged && changes.nextProfile) {
22072274
rows.push([t("nextStrategy"), strategyLabel(changes.nextProfile), "pending"]);
@@ -2425,14 +2492,21 @@ <h2 data-i18n="summary">切换摘要</h2>
24252492
const list = el("summary-list");
24262493
list.replaceChildren();
24272494
document.querySelector(".summary-head h2").textContent = t("summary");
2428-
for (const [label, value, rowClass] of summaryRows(inputs)) {
2495+
for (const [label, value, rowClass, valueTone] of summaryRows(inputs)) {
24292496
const row = document.createElement("div");
24302497
row.className = "summary-row";
24312498
if (rowClass) row.classList.add(rowClass);
24322499
const labelNode = document.createElement("dt");
24332500
labelNode.textContent = label;
24342501
const valueNode = document.createElement("dd");
2435-
valueNode.textContent = value;
2502+
if (valueTone) {
2503+
const badge = document.createElement("span");
2504+
badge.className = `summary-status ${valueTone}`;
2505+
badge.textContent = value;
2506+
valueNode.appendChild(badge);
2507+
} else {
2508+
valueNode.textContent = value;
2509+
}
24362510
row.append(labelNode, valueNode);
24372511
list.appendChild(row);
24382512
}

web/strategy-switch-console/page_asset.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)