fix: widen M3 hardware status workspace

This commit is contained in:
Code Queue Review
2026-05-23 22:57:29 +00:00
parent 3df89fe151
commit efbee38ae1
5 changed files with 53 additions and 31 deletions
+10 -10
View File
@@ -579,7 +579,7 @@ function runStaticSmoke() {
"aside#resource-explorer absent",
"#explorer-resize absent",
"resource tree / quick actions / capability cards absent",
"right side keeps a 560-760px M3 status workspace boundary through --right-width"
"right side keeps a 560-740px M3 status workspace boundary through --right-width"
]
});
@@ -2313,19 +2313,19 @@ function hasResourceExplorerRemovalContract({ html, app, styles }) {
/id=["']right-sidebar-resize["']/u.test(html) &&
/aria-label=["']拖拽调整右侧硬件状态栏宽度["']/u.test(html) &&
/aria-valuemin=["']560["']/u.test(html) &&
/aria-valuemax=["']760["']/u.test(html) &&
/aria-valuenow=["']620["']/u.test(html) &&
/RIGHT_SIDEBAR_DEFAULT_WIDTH\s*=\s*620/u.test(app) &&
/aria-valuemax=["']740["']/u.test(html) &&
/aria-valuenow=["']728["']/u.test(html) &&
/RIGHT_SIDEBAR_DEFAULT_WIDTH\s*=\s*728/u.test(app) &&
/RIGHT_SIDEBAR_MIN_WIDTH\s*=\s*560/u.test(app) &&
/RIGHT_SIDEBAR_MAX_WIDTH\s*=\s*760/u.test(app) &&
/RIGHT_SIDEBAR_MAX_WIDTH\s*=\s*740/u.test(app) &&
/function\s+initRightSidebarResize\s*\(/u.test(app) &&
/function\s+clampRightSidebarWidth\s*\(/u.test(app) &&
/function\s+rightSidebarResizeBounds\s*\(/u.test(app) &&
/setRightSidebarWidth\(drag\.startWidth \+ drag\.startX - event\.clientX/u.test(app) &&
/rightSidebarWidth:\s*state\.layout\.rightSidebarWidth/u.test(app) &&
/--right-sidebar-width:\s*620px/u.test(styles) &&
/--right-sidebar-width:\s*728px/u.test(styles) &&
/--right-sidebar-min-width:\s*560px/u.test(styles) &&
/--right-sidebar-max-width:\s*760px/u.test(styles) &&
/--right-sidebar-max-width:\s*740px/u.test(styles) &&
/--right-width:\s*clamp\(var\(--right-sidebar-min-width\),\s*var\(--right-sidebar-width\),\s*var\(--right-sidebar-max-width\)\)/u.test(styles) &&
/--right-width-expanded:\s*clamp\(var\(--right-sidebar-min-width\),\s*var\(--right-sidebar-width\),\s*var\(--right-sidebar-max-width\)\)/u.test(styles) &&
/\.right-sidebar-resize\s*\{[^}]*cursor:\s*col-resize;/su.test(styles) &&
@@ -4922,7 +4922,7 @@ export async function runM3StatusFixtureSmoke() {
const desktop = await inspectM3StatusFixtureViewport(browser, server.url, {
width: 1366,
height: 768,
expectedRightWidthMin: 560
expectedRightWidthMin: 720
});
const mobile = await inspectM3StatusFixtureViewport(browser, server.url, {
width: 390,
@@ -5978,7 +5978,7 @@ async function inspectM3StatusFixtureViewport(browser, url, viewport) {
getComputedStyle(document.body).overflow === "hidden" &&
document.documentElement.scrollHeight <= document.documentElement.clientHeight + 2 &&
document.body.scrollHeight <= document.body.clientHeight + 2,
keysVisible: ["状态", "Gateway 在线", "BOX 在线", "DO1", "DI1", "runtime durable", "blocker"].every((term) => hardwareText.includes(term)),
keysVisible: ["状态", "Gateway 在线", "BOX 在线", "链路状态", "blocked", "DO1", "DI1", "runtime durable", "blocker"].every((term) => hardwareText.includes(term)),
tabsVisible: ["总览", "Gateway-SIMU", "BOX-SIMU-1", "BOX-SIMU-2", "Patch Panel"].every((term) => tabLabels.includes(term)),
blockedVisible: text.includes("runtime_durable_adapter_auth_blocked") && !text.includes("实况可信"),
noHorizontalOverflow:
@@ -7121,7 +7121,7 @@ async function inspectLayoutState(page, { mode, viewport, compareTo }) {
const rightWidthTarget = isDesktop
? rightPanelStacked
? boxes.right?.width >= 560 && boxes.right?.width <= viewport.width
: boxes.right?.width >= (viewport.width >= 1500 ? 700 : 560) && boxes.right?.width <= 760
: boxes.right?.width >= 720 && boxes.right?.width <= 740
: boxes.right?.width <= viewport.width && boxes.right?.width >= Math.max(0, viewport.width - 80);
const rootAfterScrollAttempt = {
windowScrollY: window.scrollY,
+29 -12
View File
@@ -87,9 +87,9 @@ const LAYOUT_STORAGE_KEY = "hwlab.workbench.layout.v1";
const LEFT_SIDEBAR_DEFAULT_WIDTH = 92;
const LEFT_SIDEBAR_MIN_WIDTH = 72;
const LEFT_SIDEBAR_MAX_WIDTH = 180;
const RIGHT_SIDEBAR_DEFAULT_WIDTH = 620;
const RIGHT_SIDEBAR_DEFAULT_WIDTH = 728;
const RIGHT_SIDEBAR_MIN_WIDTH = 560;
const RIGHT_SIDEBAR_MAX_WIDTH = 760;
const RIGHT_SIDEBAR_MAX_WIDTH = 740;
const viewIds = new Set([...document.querySelectorAll("[data-view]")].map((view) => view.dataset.view));
let rpcSequence = 0;
@@ -1455,10 +1455,11 @@ function hardwareOverviewGroups(status) {
["观测时间", status.observedAt ?? "未验证", "source"],
["Gateway 在线", `${onlineCount(status.gateways)} / ${status.gateways?.length ?? 0}`, onlineCount(status.gateways) === 2 ? "live" : "blocked"],
["BOX 在线", `${onlineCount(status.boxes)} / ${status.boxes?.length ?? 0}`, onlineCount(status.boxes) === 2 ? "live" : "blocked"],
["链路状态", m3LinkStatus(status, patch), m3LinkTone(status, patch)],
["链路", `${M3_TRUSTED_ROUTE.fromResourceId}:${M3_TRUSTED_ROUTE.fromPort} -> ${M3_TRUSTED_ROUTE.patchPanelServiceId} -> ${M3_TRUSTED_ROUTE.toResourceId}:${M3_TRUSTED_ROUTE.toPort}`, patch.connectionActive ? "live" : "blocked"],
["DO1", valueLabel(do1), portTone(do1)],
["DI1", valueLabel(di1), portTone(di1)],
["patchPanel connectionActive", String(Boolean(patch.connectionActive)), patch.connectionActive ? "live" : "blocked"],
["接线盘连接", String(Boolean(patch.connectionActive)), patch.connectionActive ? "live" : "blocked"],
["runtime durable", trust.durableStatus ?? "blocked", trust.durableStatus === "green" ? "dev-live" : "blocked"],
["blocker", trust.blocker ?? status.blocker?.code ?? "none", trust.blocker || status.blocker ? "blocked" : "source"]
]),
@@ -1474,11 +1475,11 @@ function hardwareOverviewGroups(status) {
function hardwareGatewayGroups(status) {
return (status.gateways ?? []).map((gateway) =>
hardwareKvGroup(`${gateway.id} / ${gateway.role}`, [
["online", String(Boolean(gateway.online)), gateway.online ? "live" : "blocked"],
["在线", String(Boolean(gateway.online)), gateway.online ? "live" : "blocked"],
["sessionId", gateway.sessionId ?? "未验证", gateway.sessionId ? "source" : "blocked"],
["lastSeenAt", gateway.lastSeenAt ?? status.observedAt ?? "未验证", gateway.online ? "live" : "source"],
["source", gateway.sourceKind ?? "UNVERIFIED", sourceKindTone(gateway.sourceKind)],
["lastError", gateway.lastError ?? "none", gateway.lastError ? "blocked" : "source"]
["更新时间", gateway.lastSeenAt ?? status.observedAt ?? "未验证", gateway.online ? "live" : "source"],
["来源", gateway.sourceKind ?? "UNVERIFIED", sourceKindTone(gateway.sourceKind)],
["阻塞原因", gateway.lastError ?? "none", gateway.lastError ? "blocked" : "source"]
])
);
}
@@ -1488,8 +1489,8 @@ function hardwareBoxGroups(status, resourceId) {
const portEntries = Object.entries(box?.ports ?? {});
return [
hardwareKvGroup(box ? `${box.id} / ${box.resourceId}` : resourceId, [
["online", String(Boolean(box?.online)), box?.online ? "live" : "blocked"],
["gateway", `${box?.gatewayId ?? "未验证"} / ${box?.gatewaySessionId ?? "未验证"}`, box?.gatewayId ? "source" : "blocked"],
["在线", String(Boolean(box?.online)), box?.online ? "live" : "blocked"],
["Gateway", `${box?.gatewayId ?? "未验证"} / ${box?.gatewaySessionId ?? "未验证"}`, box?.gatewayId ? "source" : "blocked"],
["更新时间", box?.observedAt ?? status.observedAt ?? "未验证", sourceKindTone(box?.sourceKind)],
["来源", box?.sourceKind ?? "UNVERIFIED", sourceKindTone(box?.sourceKind)],
...portEntries.map(([port, portState]) => [port, valueLabel(portState), portTone(portState)]),
@@ -1505,16 +1506,32 @@ function hardwarePatchPanelGroups(status) {
return [
hardwareKvGroup("hwlab-patch-panel", [
["serviceId", patch.serviceId ?? M3_TRUSTED_ROUTE.patchPanelServiceId, "source"],
["connectionActive", String(Boolean(patch.connectionActive)), patch.connectionActive ? "live" : "blocked"],
["接线状态", m3LinkStatus(status, patch), m3LinkTone(status, patch)],
["连接已激活", String(Boolean(patch.connectionActive)), patch.connectionActive ? "live" : "blocked"],
["connectionVersion", patch.connectionVersion ?? "未验证", patch.connectionVersion !== null && patch.connectionVersion !== undefined ? "source" : "blocked"],
["wiringConfigId", patch.wiringConfigId ?? "未验证", patch.wiringConfigId ? "source" : "blocked"],
["lastSyncAt", patch.lastSyncAt ?? status.observedAt ?? "未验证", patch.connectionActive ? "live" : "source"],
["lastError", patch.lastError ?? "none", patch.lastError ? "blocked" : "source"],
["更新时间", patch.lastSyncAt ?? status.observedAt ?? "未验证", patch.connectionActive ? "live" : "source"],
["阻塞原因", patch.lastError ?? "none", patch.lastError ? "blocked" : "source"],
["来源", patch.sourceKind ?? "UNVERIFIED", sourceKindTone(patch.sourceKind)]
])
];
}
function m3LinkStatus(status, patch = status?.patchPanel ?? {}) {
if (status?.status === "error") return "error";
if (status?.status === "unverified") return "unverified";
if (status?.status === "live" && status?.trust?.durableStatus === "green" && patch.connectionActive === true) return "live";
if (patch.connectionActive === true) return "blocked";
return status?.status === "blocked" ? "blocked" : "unverified";
}
function m3LinkTone(status, patch) {
const linkStatus = m3LinkStatus(status, patch);
if (linkStatus === "live") return "live";
if (linkStatus === "error" || linkStatus === "blocked") return "blocked";
return "source";
}
function hardwareKvGroup(title, rows) {
const article = document.createElement("article");
article.className = "hardware-section hardware-kv-section";
+2 -2
View File
@@ -235,8 +235,8 @@
aria-controls="hardware-sidebar"
aria-orientation="vertical"
aria-valuemin="560"
aria-valuemax="760"
aria-valuenow="620"
aria-valuemax="740"
aria-valuenow="728"
title="拖拽调整右侧硬件状态栏宽度;用左右方向键微调,Home/End 到最小或最大。"
></div>
<section class="hardware-status">
+10 -5
View File
@@ -389,7 +389,8 @@ assert.match(functionBody(app, "fetchJson"), /timeoutMs\s*=\s*API_TIMEOUT_MS/);
for (const hardwareTerm of [
"Gateway 在线",
"BOX 在线",
"patchPanel connectionActive",
"链路状态",
"接线盘连接",
"runtime durable",
"DISABLED 后续能力",
"SOURCE",
@@ -475,8 +476,8 @@ assert.match(html, /aria-expanded="true"/);
assert.match(html, /id="right-sidebar-resize"/);
assert.match(html, /aria-label="拖拽调整右侧硬件状态栏宽度"/);
assert.match(html, /aria-valuemin="560"/);
assert.match(html, /aria-valuemax="760"/);
assert.match(html, /aria-valuenow="620"/);
assert.match(html, /aria-valuemax="740"/);
assert.match(html, /aria-valuenow="728"/);
assert.doesNotMatch(app, /setExplorerCollapsed|initExplorerResize|clampExplorerWidth|syncMobileExplorer|collapseExplorerAfterMobileAction/);
assert.match(app, /LAYOUT_STORAGE_KEY\s*=\s*"hwlab\.workbench\.layout\.v1"/);
assert.match(app, /leftSidebarCollapsed:\s*payload\.leftSidebarCollapsed === true/);
@@ -497,9 +498,9 @@ assert.match(app, /ArrowRight/);
assert.match(app, /event\.key === "Home"/);
assert.match(app, /event\.key === "End"/);
assert.doesNotMatch(styles, /--explorer-width|--explorer-min-width|--explorer-max-width|\.explorer|\.explorer-resize|\.quick-actions|\.resource-tree|\.tree-panel|\.tree-row|\.tree-label/);
assert.match(styles, /--right-sidebar-width:\s*620px/);
assert.match(styles, /--right-sidebar-width:\s*728px/);
assert.match(styles, /--right-sidebar-min-width:\s*560px/);
assert.match(styles, /--right-sidebar-max-width:\s*760px/);
assert.match(styles, /--right-sidebar-max-width:\s*740px/);
assert.match(styles, /--right-width:\s*clamp\(var\(--right-sidebar-min-width\),\s*var\(--right-sidebar-width\),\s*var\(--right-sidebar-max-width\)\)/);
assert.match(styles, /--right-width-expanded:\s*clamp\(var\(--right-sidebar-min-width\),\s*var\(--right-sidebar-width\),\s*var\(--right-sidebar-max-width\)\)/);
assert.match(styles, /--rail-collapsed-width:\s*44px/);
@@ -701,7 +702,11 @@ assert.match(html, /data-hardware-tab="box2"[\s\S]*>BOX-SIMU-2<\/button>/);
assert.match(html, /data-hardware-tab="patch"[\s\S]*>Patch Panel<\/button>/);
assert.match(app, /function initHardwareTabs/);
assert.match(app, /function hardwareKvGroup/);
assert.match(app, /function m3LinkStatus/);
assert.match(app, /sourceFallbackM3Status/);
for (const hardwareLabel of ["链路状态", "接线盘连接", "在线", "更新时间", "阻塞原因", "接线状态", "连接已激活"]) {
assert.match(app, new RegExp(escapeRegExp(hardwareLabel)), `missing Chinese hardware label ${hardwareLabel}`);
}
assert.match(styles, /\.hardware-status-tabs\s*\{/);
assert.match(styles, /\.kv-list\s*\{/);
assert.match(styles, /\.right-sidebar \.table-wrap\s*\{[^}]*overflow-x:\s*hidden;/s);
+2 -2
View File
@@ -21,9 +21,9 @@
--left-sidebar-min-width: 72px;
--left-sidebar-max-width: 180px;
--rail-width: 92px;
--right-sidebar-width: 620px;
--right-sidebar-width: 728px;
--right-sidebar-min-width: 560px;
--right-sidebar-max-width: 760px;
--right-sidebar-max-width: 740px;
--right-width: clamp(var(--right-sidebar-min-width), var(--right-sidebar-width), var(--right-sidebar-max-width));
--right-width-expanded: clamp(var(--right-sidebar-min-width), var(--right-sidebar-width), var(--right-sidebar-max-width));
--rail-collapsed-width: 44px;