Files

64 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>设备首页 · Multi SimAdmin Island</title><link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="island-bg" aria-hidden="true"></div>
<div id="appShell" class="app-shell">
<aside class="desktop-sidebar" aria-label="主导航">
<a class="brand" href="#" data-view="home"><span>🏝️</span><b>SIM 岛</b></a>
<nav class="side-nav">
<button type="button" data-view="home" aria-current="page"><span>设备首页</span></button>
<button type="button" data-view="detail"><span>设备详情</span></button>
<button type="button" data-view="rawpage"><span>原始页面</span></button>
<button type="button" data-view="api"><span>API 工作台</span></button>
</nav>
<div class="sidebar-foot"><span>本地配置</span><code id="configPath">config.json</code></div>
</aside>
<div class="app-content">
<header class="sim-topbar">
<div><p class="eyebrow">MULTI SIMADMIN</p><h1 id="pageHeading">设备首页</h1><p id="pageSubtitle">集中巡检你的 SimAdmin 设备</p></div>
<div class="hero-actions"><button id="refreshBtn" class="animal-btn default-btn" type="button">刷新状态</button><button id="addInstanceBtn" class="animal-btn primary-btn" type="button"> 添加设备</button></div>
</header>
<div id="persistentError" class="persistent-message error" role="alert" hidden><span id="persistentErrorText"></span><button id="dismissError" type="button">关闭</button></div>
<div id="staleBanner" class="persistent-message warn" role="status" hidden></div>
<main class="sim-main">
<section id="homeView" class="view active home-view" aria-labelledby="pageHeading">
<div id="initialLoading" class="state-card" role="status">正在读取本地配置与设备状态…</div>
<div id="fatalState" class="state-card error" role="alert" hidden><h2>应用无法初始化</h2><p id="fatalText"></p><button id="retryInit" class="animal-btn primary-btn" type="button">重试</button></div>
<section id="homeContent" hidden>
<div class="fleet-overview island-card"><div><h2>设备卡片墙</h2><p>状态、资产与连接信息一览</p></div><div id="fleetStats" class="wallet-row"></div></div>
<div class="home-toolbar island-card">
<label for="instanceSearch">搜索设备</label><input id="instanceSearch" type="search" placeholder="名称、ID、标签、地址、ICCID…" autocomplete="off">
<label for="sortSelect">排序</label><select id="sortSelect"><option value="name">名称</option><option value="status">状态</option><option value="latency">延迟</option></select>
<button id="densityBtn" class="animal-btn default-btn" type="button" aria-pressed="false">紧凑密度</button>
<nav class="status-filters" id="statusFilters" aria-label="设备状态筛选">
<button type="button" data-filter="all" aria-pressed="true">全部</button><button type="button" data-filter="online" aria-pressed="false">在线</button><button type="button" data-filter="auth" aria-pressed="false">需登录</button><button type="button" data-filter="offline" aria-pressed="false">离线</button><button type="button" data-filter="unknown" aria-pressed="false">未知</button>
</nav>
</div>
<section id="homeDeviceGrid" class="home-device-grid" aria-label="设备卡片列表"></section>
</section>
</section>
<section id="detailView" class="view detail-view" aria-label="设备详情">
<header class="workspace-hero island-card"><div><p id="activeKicker" class="eyebrow">DEVICE DETAIL</p><h2 id="activeName">设备详情</h2><p id="activeMeta"></p></div><div class="hero-actions"><button id="backToFleetBtn" class="animal-btn default-btn" type="button">返回首页</button><button id="editActiveBtn" class="animal-btn default-btn" type="button">编辑设备</button><button id="loginBtn" class="animal-btn default-btn" type="button">登录/刷新会话</button><a id="openExternal" class="animal-btn default-btn" href="#" target="_blank" rel="noopener noreferrer">原站打开</a></div></header>
<section class="detail-layout"><section class="signal-board island-card"><h3>实时状态</h3><div id="signalPanel" class="signal-grid"></div></section><section id="overview" class="nook-metrics" aria-label="关键指标"></section><section class="island-card detail-board"><h3>设备详情</h3><div id="detailDeviceGrid" class="device-detail-grid"></div></section><section class="island-card detail-actions-card"><h3>功能入口</h3><div id="detailActions" class="detail-actions"></div></section></section>
</section>
<section id="rawpageView" class="view rawpage-view" aria-label="原始管理页"><div class="frame-toolbar island-card"><button type="button" class="animal-btn default-btn" data-view="detail">返回详情</button><span id="frameHint">若目标站禁止 iframe,请使用“原站打开”。</span></div><iframe id="frame" class="frame" title="SimAdmin 原始管理页面" hidden></iframe></section>
<section id="apiView" class="view api-layout" aria-label="API 工作台">
<aside class="api-catalog island-card"><h2>接口目录</h2><label for="endpointSearch">搜索接口</label><input id="endpointSearch" type="search" placeholder="搜索 endpoint"><div id="endpointList" class="endpoint-list"></div></aside>
<section class="api-console island-card"><div class="console-toolbar"><label for="methodSelect">方法</label><select id="methodSelect"><option>GET</option><option>POST</option><option>PUT</option><option>PATCH</option><option>DELETE</option></select><label for="endpointInput">路径</label><input id="endpointInput" value="/api/device" spellcheck="false"><button id="runEndpoint" class="animal-btn primary-btn" type="button">发送请求</button></div><div id="writeWarning" class="danger-warning" role="alert" hidden>写操作可能改变设备状态。发送前将创建一次性确认令牌。</div><label for="requestBody">JSON 请求体(GET 不发送请求体)</label><textarea id="requestBody" class="request-body" placeholder='{"enabled":true}'></textarea><div class="output-tools"><button id="outputPretty" type="button" aria-pressed="true">Pretty</button><button id="outputRaw" type="button" aria-pressed="false">Raw</button><button id="copyOutput" type="button">复制结果</button></div><pre id="rawOutput" class="raw-output">选择接口不会自动发送。确认设备和参数后点击“发送请求”。</pre></section>
</section>
</main>
</div>
<nav class="mobile-nav" aria-label="移动端主导航"><button type="button" data-view="home" aria-current="page"><span>首页</span></button><button type="button" data-view="detail"><span>详情</span></button><button type="button" data-view="rawpage"><span>原页</span></button><button type="button" data-view="api"><span>API</span></button></nav>
</div>
<dialog id="loginDialog" aria-labelledby="loginTitle"><form method="dialog" id="loginForm" class="dialog-card"><h2 id="loginTitle">登录 SimAdmin</h2><p>密码仅发送至本地聚合服务。</p><label for="passwordInput">管理员密码</label><input id="passwordInput" type="password" autocomplete="current-password"><p id="loginError" class="form-error" role="alert" hidden></p><menu><button type="button" data-dialog-cancel="loginDialog" class="animal-btn default-btn">取消</button><button id="submitLogin" value="default" class="animal-btn primary-btn">登录</button></menu></form></dialog>
<dialog id="instanceDialog" aria-labelledby="instanceDialogTitle"><form method="dialog" id="instanceForm" class="dialog-card"><h2 id="instanceDialogTitle">添加设备</h2><input type="hidden" id="instanceOriginalId"><label for="instanceIdInput">设备 ID</label><input id="instanceIdInput" required pattern="[a-zA-Z0-9_.-]+"><label for="instanceNameInput">显示名称</label><input id="instanceNameInput" required><label for="instanceUrlInput">设备地址</label><input id="instanceUrlInput" required type="url"><label for="instanceDescInput">描述</label><textarea id="instanceDescInput"></textarea><label for="instanceTagsInput">标签(逗号分隔)</label><input id="instanceTagsInput"><fieldset id="passwordActions"><legend>保存密码</legend><label><input id="passwordPreserve" type="radio" name="passwordAction" value="preserve" checked> 保留现有密码</label><label><input id="passwordSet" type="radio" name="passwordAction" value="set"> 设置新密码</label><label><input id="passwordClear" type="radio" name="passwordAction" value="clear"> 清除密码</label></fieldset><label id="newPasswordLabel" for="instancePasswordInput" hidden>新密码<input id="instancePasswordInput" type="password" autocomplete="new-password"></label><label id="clearPasswordLabel" class="confirm-check" hidden><input id="clearPasswordConfirm" type="checkbox"> 我确认清除已保存密码</label><p id="instanceFormError" class="form-error" role="alert" hidden></p><menu><button type="button" data-dialog-cancel="instanceDialog" class="animal-btn default-btn">取消</button><button id="deleteInstanceBtn" type="button" class="animal-btn danger-btn" hidden>删除设备</button><button id="saveInstanceBtn" value="default" class="animal-btn primary-btn">保存</button></menu></form></dialog>
<dialog id="deleteDialog" aria-labelledby="deleteDialogTitle"><form method="dialog" class="dialog-card"><h2 id="deleteDialogTitle">确认删除设备</h2><div id="deleteDetails" class="delete-details"></div><p>此操作将立即写入本地配置,且不可撤销。</p><p id="deleteError" class="form-error" role="alert" hidden></p><menu><button type="button" data-dialog-cancel="deleteDialog" class="animal-btn default-btn">取消</button><button id="confirmDeleteBtn" value="default" class="animal-btn danger-primary">确认删除</button></menu></form></dialog>
<dialog id="apiDeleteDialog" aria-labelledby="apiDeleteTitle"><form method="dialog" class="dialog-card"><h2 id="apiDeleteTitle">确认发送写操作</h2><p id="apiDeleteDetails"></p><pre id="apiDeleteBody" class="raw-output"></pre><p>该请求将改变设备状态,请核对设备、方法、路径和请求体。</p><menu><button type="button" data-dialog-cancel="apiDeleteDialog" class="animal-btn default-btn">取消</button><button id="confirmApiDelete" value="default" class="animal-btn danger-primary">确认并发送</button></menu></form></dialog>
<div id="toast" class="toast" aria-live="polite" role="status" hidden></div>
<script src="/app.js" type="module"></script>
</body></html>