606156f604
Adds a controlled desktop left activity rail resize handle with persisted width, collapse-aware disabled state, narrow/mobile disablement, and focused Playwright coverage. No DEV rollout requested.
370 lines
18 KiB
HTML
370 lines
18 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>HWLAB 云工作台</title>
|
||
<link rel="stylesheet" href="/styles.css" />
|
||
<script type="module" src="/app.mjs"></script>
|
||
</head>
|
||
<body data-auth-state="checking">
|
||
<section class="login-shell" id="login-shell" data-auth-login aria-labelledby="login-title">
|
||
<div class="login-panel">
|
||
<div class="login-heading">
|
||
<p class="eyebrow">HWLAB</p>
|
||
<h1 id="login-title">云工作台登录</h1>
|
||
<p>请输入账号和密码。</p>
|
||
</div>
|
||
<form class="login-form" id="login-form" autocomplete="on">
|
||
<label>
|
||
<span>用户名</span>
|
||
<input id="login-username" name="username" type="text" autocomplete="username" inputmode="text" required />
|
||
</label>
|
||
<label>
|
||
<span>密码</span>
|
||
<input id="login-password" name="password" type="password" autocomplete="current-password" required />
|
||
</label>
|
||
<p class="login-error" id="login-error" role="alert" hidden></p>
|
||
<button class="login-submit" id="login-submit" type="submit">登录</button>
|
||
</form>
|
||
</div>
|
||
</section>
|
||
|
||
<main class="workbench-shell" data-app-shell data-help-route-policy="non-default-internal-help" data-internal-help-path="/help.md" hidden aria-hidden="true">
|
||
<aside class="activity-rail" id="activity-rail" aria-label="工作台活动栏">
|
||
<button class="rail-button active" type="button" data-route="workspace" title="工作台" aria-label="工作台">工作台</button>
|
||
<button class="rail-button" type="button" data-route="gate" title="内部复核" aria-label="内部复核">内部复核</button>
|
||
<button class="rail-button" type="button" data-route="help" title="使用说明" aria-label="使用说明">使用说明</button>
|
||
<span class="rail-spacer" aria-hidden="true"></span>
|
||
<button
|
||
class="rail-button sidebar-toggle"
|
||
id="left-sidebar-toggle"
|
||
type="button"
|
||
aria-controls="activity-rail"
|
||
aria-expanded="true"
|
||
aria-label="折叠左侧导航"
|
||
title="折叠左侧导航"
|
||
>收起</button>
|
||
</aside>
|
||
<div
|
||
class="resize-handle left-sidebar-resize"
|
||
id="left-sidebar-resize"
|
||
role="separator"
|
||
tabindex="0"
|
||
aria-label="拖拽调整左侧导航宽度"
|
||
aria-controls="activity-rail"
|
||
aria-orientation="vertical"
|
||
aria-valuemin="72"
|
||
aria-valuemax="180"
|
||
aria-valuenow="92"
|
||
title="拖拽调整左侧导航宽度;用左右方向键微调,Home/End 到最小或最大。"
|
||
></div>
|
||
|
||
<section class="center-workspace">
|
||
<header class="topbar">
|
||
<div class="topbar-main">
|
||
<p class="eyebrow">用户工作台</p>
|
||
<h2>Agent 对话与硬件资源面板</h2>
|
||
<p id="route-path" class="route-path">当前浏览器会话只保存任务草稿,硬件动作需通过受控后端流程。</p>
|
||
</div>
|
||
<div class="probe-card user-card" aria-live="polite">
|
||
<span class="metric-label">工作区状态</span>
|
||
<strong id="live-status" class="tone-pending">等待验证</strong>
|
||
<small id="live-detail">正在验证 hwlab-cloud-api /health/live、/v1、/v1/agent/chat 与 /v1/m3/io;未完成前不标为通过。</small>
|
||
<details class="live-build-summary" id="live-build-summary">
|
||
<summary>
|
||
<span class="live-build-summary-label" id="live-build-latest">最新镜像构建时间:等待实时元数据</span>
|
||
</summary>
|
||
<div class="live-build-list" id="live-build-list" aria-label="live HWLAB 微服务构建时间明细"></div>
|
||
</details>
|
||
</div>
|
||
<button class="logout-button" id="logout-button" type="button">退出</button>
|
||
</header>
|
||
|
||
<section class="view workbench-view" id="workspace" data-view="workspace" aria-labelledby="workspace-title">
|
||
<div class="conversation-column">
|
||
<div class="workspace-panel conversation-panel">
|
||
<div class="panel-title-row">
|
||
<div>
|
||
<p class="eyebrow">Agent 工作区</p>
|
||
<h2 id="workspace-title">Agent 对话</h2>
|
||
</div>
|
||
<span class="state-tag tone-source" id="agent-chat-status">等待输入</span>
|
||
</div>
|
||
<details class="code-agent-summary tone-border-pending" id="code-agent-summary">
|
||
<summary>
|
||
<span class="code-agent-summary-icon tone-pending" id="code-agent-summary-icon" aria-hidden="true">○</span>
|
||
<strong class="code-agent-summary-label tone-pending" id="code-agent-summary-label">探测中</strong>
|
||
<span class="code-agent-summary-capability" id="code-agent-summary-capability">未观测</span>
|
||
<span class="code-agent-summary-trace" id="code-agent-summary-trace">trace 未观测</span>
|
||
</summary>
|
||
<div class="code-agent-summary-detail" id="code-agent-summary-detail"></div>
|
||
</details>
|
||
<div class="conversation-list" id="conversation-list" aria-live="polite"></div>
|
||
</div>
|
||
|
||
<div class="workspace-panel task-panel">
|
||
<div class="panel-title-row">
|
||
<div>
|
||
<p class="eyebrow">工作清单</p>
|
||
<h2>下一步任务草稿</h2>
|
||
</div>
|
||
<span class="state-tag tone-source">浏览器本地</span>
|
||
</div>
|
||
<div id="task-list" class="task-list"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="view help-view" id="help" data-view="help" aria-labelledby="help-title" hidden>
|
||
<div class="workspace-panel help-panel">
|
||
<div class="panel-title-row">
|
||
<div>
|
||
<p class="eyebrow">内部说明</p>
|
||
<h2 id="help-title">使用说明</h2>
|
||
</div>
|
||
<span class="state-tag tone-dry-run" id="help-status">加载中</span>
|
||
</div>
|
||
<div id="help-content" class="help-content" aria-live="polite"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="view gate-view" id="gate" data-view="gate" aria-labelledby="gate-title" hidden>
|
||
<header class="gate-header">
|
||
<div>
|
||
<p class="eyebrow">内部二级入口</p>
|
||
<h2 id="gate-title">内部复核</h2>
|
||
</div>
|
||
<span class="state-tag tone-source" id="gate-source-status">等待 live 后端</span>
|
||
</header>
|
||
<div class="gate-controls" aria-label="内部复核过滤控件">
|
||
<label>
|
||
<span>状态</span>
|
||
<select id="gate-status-filter">
|
||
<option value="all">全部</option>
|
||
<option value="通过">通过</option>
|
||
<option value="阻塞">阻塞</option>
|
||
<option value="失败">失败</option>
|
||
<option value="待验证">待验证</option>
|
||
<option value="信息">信息</option>
|
||
</select>
|
||
</label>
|
||
<label>
|
||
<span>搜索</span>
|
||
<input id="gate-search" type="search" placeholder="按类别、检查项、对象或 trace 搜索" autocomplete="off" />
|
||
</label>
|
||
<button class="command-button secondary" id="gate-refresh" type="button">刷新</button>
|
||
</div>
|
||
<div class="gate-table-wrap">
|
||
<table class="gate-table" aria-describedby="gate-source-status">
|
||
<thead>
|
||
<tr>
|
||
<th>类别</th>
|
||
<th>检查项</th>
|
||
<th>状态</th>
|
||
<th>归因对象</th>
|
||
<th>关键细节</th>
|
||
<th>证据/trace</th>
|
||
<th>更新时间</th>
|
||
<th>下一步</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="gate-review-body">
|
||
<tr>
|
||
<td colspan="8">正在读取 live 后端聚合。</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<form class="command-bar" id="command-form" aria-label="Agent 输入">
|
||
<div class="agent-quick-prompts" aria-label="Code Agent 快捷用例">
|
||
<button
|
||
type="button"
|
||
data-agent-quick-prompt="pwd"
|
||
data-prompt-action="fill"
|
||
title="只填充输入框,点击发送后交给 Code Agent"
|
||
data-prompt-text="通过 Skill CLI 执行 pwd,列出当前工作目录。"
|
||
>Skill CLI:pwd</button>
|
||
<button
|
||
type="button"
|
||
data-agent-quick-prompt="skills"
|
||
data-prompt-action="fill"
|
||
title="只填充输入框,点击发送后交给 Code Agent"
|
||
data-prompt-text="通过 Skill CLI 列出你能使用的所有 skill。"
|
||
>Skill CLI:列出 skill</button>
|
||
<button
|
||
type="button"
|
||
data-agent-quick-prompt="do1-true-di1"
|
||
data-prompt-action="fill"
|
||
data-requires-explicit-send="true"
|
||
title="只填充输入框;必须再点击发送才确认写入请求"
|
||
data-prompt-text="通过 HWLAB API / Skill CLI 把 res_boxsimu_1 的 DO1 写成 true,然后读取 res_boxsimu_2 的 DI1;我点击发送后才确认执行这次写入请求。"
|
||
>HWLAB API:DO1=true 后读 DI1</button>
|
||
<button
|
||
type="button"
|
||
data-agent-quick-prompt="do1-false-di1"
|
||
data-prompt-action="fill"
|
||
data-requires-explicit-send="true"
|
||
title="只填充输入框;必须再点击发送才确认写入请求"
|
||
data-prompt-text="通过 HWLAB API / Skill CLI 把 res_boxsimu_1 的 DO1 写成 false,并复核 res_boxsimu_2 的 DI1;我点击发送后才确认执行这次写入请求。"
|
||
>HWLAB API:DO1=false 复核 DI1</button>
|
||
</div>
|
||
<div class="input-shell">
|
||
<span class="prompt-mark">hwlab</span>
|
||
<input
|
||
id="command-input"
|
||
autocomplete="off"
|
||
type="text"
|
||
placeholder="输入要发送给 Code Agent 的消息;不会直接触发硬件变更。"
|
||
/>
|
||
</div>
|
||
<button class="command-button" id="command-send" type="submit">发送</button>
|
||
<button class="command-button secondary" id="command-clear" type="button">清空</button>
|
||
</form>
|
||
</section>
|
||
|
||
<aside class="right-sidebar" id="hardware-sidebar" aria-label="运行状态与可信记录">
|
||
<div
|
||
class="resize-handle right-sidebar-resize"
|
||
id="right-sidebar-resize"
|
||
role="separator"
|
||
tabindex="0"
|
||
aria-label="拖拽调整右侧硬件状态栏宽度"
|
||
aria-controls="hardware-sidebar"
|
||
aria-orientation="vertical"
|
||
aria-valuemin="560"
|
||
aria-valuemax="760"
|
||
aria-valuenow="620"
|
||
title="拖拽调整右侧硬件状态栏宽度;用左右方向键微调,Home/End 到最小或最大。"
|
||
></div>
|
||
<section class="hardware-status">
|
||
<div class="panel-title-row">
|
||
<div>
|
||
<p class="eyebrow">M3 实况状态</p>
|
||
<h2>硬件状态工作区</h2>
|
||
</div>
|
||
<span class="state-tag tone-source" id="hardware-source-status">未验证</span>
|
||
</div>
|
||
<div class="hardware-status-tabs" role="tablist" aria-label="M3 硬件状态">
|
||
<button class="hardware-tab active" type="button" role="tab" aria-selected="true" data-hardware-tab="overview">总览</button>
|
||
<button class="hardware-tab" type="button" role="tab" aria-selected="false" data-hardware-tab="gateways">Gateway-SIMU</button>
|
||
<button class="hardware-tab" type="button" role="tab" aria-selected="false" data-hardware-tab="box1">BOX-SIMU-1</button>
|
||
<button class="hardware-tab" type="button" role="tab" aria-selected="false" data-hardware-tab="box2">BOX-SIMU-2</button>
|
||
<button class="hardware-tab" type="button" role="tab" aria-selected="false" data-hardware-tab="patch">Patch Panel</button>
|
||
</div>
|
||
<div id="hardware-list" class="hardware-list" data-static-source-fallback="SOURCE">
|
||
<article class="hardware-section">
|
||
<span class="hardware-section-title">Key / Value</span>
|
||
<dl class="kv-list">
|
||
<div><dt>数据入口</dt><dd>等待 cloud-api /v1/m3/status</dd></div>
|
||
<div><dt>链路</dt><dd>res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1</dd></div>
|
||
<div><dt>来源</dt><dd>未验证;拓扑资料只可作为 fallback</dd></div>
|
||
</dl>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="side-workspace">
|
||
<div class="side-tabs" role="tablist" aria-label="工作台右侧面板">
|
||
<button class="side-tab active" id="tab-control" type="button" role="tab" aria-selected="true" data-side-tab="control">控制</button>
|
||
<button class="side-tab" id="tab-wiring" type="button" role="tab" aria-selected="false" data-side-tab="wiring">接线</button>
|
||
<button class="side-tab" id="tab-records" type="button" role="tab" aria-selected="false" data-side-tab="records">可信记录</button>
|
||
</div>
|
||
|
||
<section class="side-panel active" id="panel-control" role="tabpanel" aria-labelledby="tab-control" data-side-panel="control">
|
||
<div class="panel-title-row">
|
||
<h2>基础 IO 控制</h2>
|
||
<span class="state-tag tone-blocked" id="m3-control-status">探测中</span>
|
||
</div>
|
||
<form class="m3-control-form" id="m3-control-form" aria-label="DO1 写入">
|
||
<div class="m3-control-grid">
|
||
<label>
|
||
<span>Gateway</span>
|
||
<select id="m3-gateway-select">
|
||
<option value="gwsimu_1">gateway-simu-1</option>
|
||
</select>
|
||
</label>
|
||
<label>
|
||
<span>BOX</span>
|
||
<select id="m3-box-select">
|
||
<option value="res_boxsimu_1">box-simu-1 / res_boxsimu_1</option>
|
||
</select>
|
||
</label>
|
||
<label>
|
||
<span>端口</span>
|
||
<select id="m3-port-select">
|
||
<option value="DO1">DO1</option>
|
||
</select>
|
||
</label>
|
||
<label>
|
||
<span>值</span>
|
||
<select id="m3-value-select">
|
||
<option value="true">true</option>
|
||
<option value="false">false</option>
|
||
</select>
|
||
</label>
|
||
</div>
|
||
<div class="m3-control-actions">
|
||
<button class="command-button" id="m3-write-do" type="submit">写入 DO1</button>
|
||
<button class="command-button secondary" id="m3-read-di" type="button">读取 DI1</button>
|
||
</div>
|
||
</form>
|
||
<div id="control-list" class="compact-list"></div>
|
||
</section>
|
||
|
||
<section class="side-panel" id="panel-wiring" role="tabpanel" aria-labelledby="tab-wiring" data-side-panel="wiring" hidden>
|
||
<div class="panel-title-row">
|
||
<h2>接线:hwlab-patch-panel</h2>
|
||
<span class="state-tag tone-source">来源拓扑接线</span>
|
||
</div>
|
||
<div class="table-wrap wiring-table-wrap" data-wiring-layout="two-column-long-table">
|
||
<table class="wiring-table wiring-long-table" aria-describedby="wiring-summary">
|
||
<thead>
|
||
<tr data-wiring-row="devices">
|
||
<th scope="col">
|
||
<span class="mono wrap" id="wiring-source-device">res_boxsimu_1</span>
|
||
<small>互连设备 A</small>
|
||
</th>
|
||
<th scope="col">
|
||
<span class="mono wrap" id="wiring-target-device">res_boxsimu_2</span>
|
||
<small>互连设备 B</small>
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="wiring-body">
|
||
<tr data-source-kind="SOURCE" data-wiring-row="io">
|
||
<td>
|
||
<span class="wiring-port mono">DO1</span>
|
||
<small class="wiring-detail">源端口;经 hwlab-patch-panel;状态:待可信记录</small>
|
||
</td>
|
||
<td>
|
||
<span class="wiring-port mono">DI1</span>
|
||
<small class="wiring-detail">目标端口;证据来源:来源拓扑;轨迹/证据:等待可信记录</small>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<p class="wiring-summary" id="wiring-summary">接线盘:hwlab-patch-panel;状态:待可信记录;证据来源:来源拓扑;轨迹/证据:等待可信记录。</p>
|
||
</section>
|
||
|
||
<section class="side-panel" id="panel-records" role="tabpanel" aria-labelledby="tab-records" data-side-panel="records" hidden>
|
||
<div class="panel-title-row">
|
||
<h2>可信记录</h2>
|
||
<span class="state-tag tone-source">来源拓扑 + 只读查询</span>
|
||
</div>
|
||
<div id="records-list" class="compact-list"></div>
|
||
</section>
|
||
|
||
<div class="readonly-rpc sidebar-note">
|
||
<h3>复核入口</h3>
|
||
<p class="panel-copy">技术复核已移至二级页面,不作为默认工作区内容。</p>
|
||
</div>
|
||
</section>
|
||
</aside>
|
||
</main>
|
||
</body>
|
||
</html>
|