Files
dbtool-cli-v1/gui/prototype/index.html
Paperclip CTO a28dab4cd9
Some checks failed
release-smoke / macos-13 / x86_64-apple-darwin (push) Has been cancelled
release-smoke / ubuntu-latest / x86_64-unknown-linux-gnu (push) Has been cancelled
release-smoke / windows-latest / x86_64-pc-windows-msvc (push) Has been cancelled
feat(usable): package gui-host validation snapshot
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 10:21:36 +00:00

446 lines
18 KiB
HTML
Raw 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" data-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>dbtool-cli-v1 GUI Foundation Prototype</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div class="app-shell">
<header class="topbar">
<div class="topbar__brand">
<div class="brand-mark">DB</div>
<div>
<p class="eyebrow">dbtool future desktop</p>
<h1>Operator Workspace Foundation</h1>
<p class="topbar__copy">
面向数据库操作者的安静型工作台原型,聚焦 connect → inspect → query → export。
</p>
</div>
</div>
<div class="topbar__context">
<button class="ghost-button" id="command-button">⌘K Quick Actions</button>
<button class="ghost-button" id="theme-toggle">切换到 Light</button>
<div class="connection-pill">
<span class="status-dot status-dot--ok"></span>
<div>
<span class="pill-label">Active Target</span>
<strong id="active-connection">pg-prod-readonly</strong>
</div>
</div>
</div>
</header>
<section class="workspace-summary">
<article class="summary-card">
<span class="summary-card__label">Workspace</span>
<strong id="summary-workspace">Production Read Audit</strong>
<p id="summary-workspace-copy">只读 PostgreSQL 连接,聚焦近 7 天订单审计。</p>
</article>
<article class="summary-card">
<span class="summary-card__label">Selection</span>
<strong id="summary-selection">public.orders</strong>
<p id="summary-selection-copy">Schema browser 与 inspector 指向同一对象。</p>
</article>
<article class="summary-card">
<span class="summary-card__label">Last Run</span>
<strong id="summary-run">Success · 50 rows</strong>
<p id="summary-run-copy">182 ms结果可导出。</p>
</article>
<article class="summary-card">
<span class="summary-card__label">Export</span>
<strong id="summary-export">/tmp/orders-last-7-days.csv</strong>
<p id="summary-export-copy">当前展示默认导出目标,不执行真实写盘。</p>
</article>
</section>
<main class="workspace">
<aside class="panel panel--nav">
<section class="panel-section">
<div class="section-head">
<div>
<p class="eyebrow">Connection Manager</p>
<h2>Saved Targets</h2>
</div>
<button class="ghost-button ghost-button--small">+ New</button>
</div>
<div class="connection-list">
<button
class="connection-card is-active"
data-connection="pg-prod-readonly"
data-driver="PostgreSQL"
data-environment="Production"
data-mode="Read-only"
data-selection="public.orders"
data-workspace="Production Read Audit"
data-workspace-copy="只读 PostgreSQL 连接,聚焦近 7 天订单审计。"
data-last-validated="2 minutes ago"
>
<div class="connection-card__head">
<strong>pg-prod-readonly</strong>
<span class="pill pill--success">Healthy</span>
</div>
<p>PostgreSQL · Production · Read-only</p>
<div class="connection-card__meta">
<span>Latency 28 ms</span>
<span>Last checked 2m ago</span>
</div>
</button>
<button
class="connection-card"
data-connection="mysql-staging"
data-driver="MySQL"
data-environment="Staging"
data-mode="Write enabled"
data-selection="qa_demo.orders"
data-workspace="Staging Validation"
data-workspace-copy="用于确认变更前后数据差异的暂存环境。"
data-last-validated="9 minutes ago"
>
<div class="connection-card__head">
<strong>mysql-staging</strong>
<span class="pill pill--muted">Idle</span>
</div>
<p>MySQL · Staging · Write enabled</p>
<div class="connection-card__meta">
<span>Latency 41 ms</span>
<span>Last checked 9m ago</span>
</div>
</button>
<button
class="connection-card"
data-connection="sqlite-local"
data-driver="SQLite"
data-environment="Local file"
data-mode="Local verify"
data-selection="main.audit_events"
data-workspace="Local Evidence Review"
data-workspace-copy="本地 SQLite 文件验证与导出证据收集。"
data-last-validated="Ready on open"
>
<div class="connection-card__head">
<strong>sqlite-local</strong>
<span class="pill pill--muted">Ready</span>
</div>
<p>SQLite · Local file · Single file</p>
<div class="connection-card__meta">
<span>Offline</span>
<span>Open on demand</span>
</div>
</button>
</div>
</section>
<section class="panel-section">
<div class="section-head">
<div>
<p class="eyebrow">Schema Browser</p>
<h2>Catalog</h2>
</div>
<button class="ghost-button ghost-button--small" id="clear-search">Clear</button>
</div>
<label class="search-field">
<span>Search</span>
<input id="schema-search" type="search" placeholder="tables, views, columns" />
</label>
<div class="tree" id="schema-tree"></div>
</section>
<section class="panel-section">
<p class="eyebrow">Workflow Checkpoints</p>
<ul class="focus-list">
<li>连接状态应在进入工作台前即被看见</li>
<li>schema browser 与 inspector 应共享同一选中对象</li>
<li>执行反馈应独立于结果表格持续可见</li>
<li>导出动作必须贴近当前结果集而不是离散分散</li>
</ul>
</section>
</aside>
<section class="panel panel--main">
<div class="editor-toolbar">
<div class="toolbar-tabs" id="toolbar-tabs"></div>
<div class="toolbar-actions">
<span class="pill pill--muted" id="driver-pill">PostgreSQL</span>
<button class="action-button" id="cycle-state">Next State</button>
<button class="action-button action-button--primary" id="run-query">Run Query</button>
<button class="action-button" id="export-current">Export</button>
</div>
</div>
<div class="context-strip">
<div>
<span class="context-label">Target</span>
<strong id="context-target">pg-prod-readonly</strong>
</div>
<div>
<span class="context-label">Mode</span>
<strong id="context-mode">Read-only</strong>
</div>
<div>
<span class="context-label">Selection</span>
<strong id="context-selection">public.orders</strong>
</div>
<div>
<span class="context-label">Last validated</span>
<strong id="context-validated">2 minutes ago</strong>
</div>
</div>
<section class="editor">
<div class="editor-gutter" id="editor-gutter">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
</div>
<pre class="editor-code"><code id="editor-code"></code></pre>
</section>
<section class="execution-banner is-success" id="execution-banner">
<div>
<p class="eyebrow">Execution</p>
<strong id="execution-title">Last run succeeded</strong>
<p id="execution-copy">50 rows returned in 182 ms. Export is available.</p>
</div>
<div class="banner-metrics">
<div>
<span>Duration</span>
<strong id="duration-value">182 ms</strong>
</div>
<div>
<span>Rows</span>
<strong id="row-count">50</strong>
</div>
<div>
<span>State</span>
<strong id="state-label">Success</strong>
</div>
</div>
</section>
<section class="bottom-panel">
<div class="bottom-tabs">
<button class="bottom-tab is-active" data-tab="results">Results</button>
<button class="bottom-tab" data-tab="history">History</button>
<button class="bottom-tab" data-tab="export">Export</button>
<button class="bottom-tab" data-tab="problems">Problems</button>
<button class="bottom-tab" data-tab="contract">Contract</button>
</div>
<div class="tab-content is-active" data-content="results">
<div class="result-summary">
<strong id="result-summary">50 rows · sorted by created_at desc</strong>
<span id="result-copy">结果区保留紧邻执行反馈的上下文,不让表格单独承担状态信息。</span>
</div>
<div class="table-wrap">
<table>
<thead>
<tr id="results-head"></tr>
</thead>
<tbody id="results-body"></tbody>
</table>
</div>
</div>
<div class="tab-content" data-content="history">
<div class="log-list" id="history-list"></div>
</div>
<div class="tab-content" data-content="export">
<div class="export-box">
<div>
<p class="eyebrow">Export Status</p>
<strong id="export-title">Ready to export the current result set</strong>
<p id="export-copy">`/tmp/orders-last-7-days.csv` is available as the default target.</p>
</div>
<div class="export-actions">
<button class="action-button" id="export-csv">CSV</button>
<button class="action-button" id="export-json">JSON</button>
</div>
</div>
</div>
<div class="tab-content" data-content="problems">
<div class="problem-box">
<strong id="problem-title">No blocking problem</strong>
<p id="problem-copy">When a query fails, this area should show the error summary, SQL fragment, and next action.</p>
</div>
</div>
<div class="tab-content" data-content="contract">
<div class="contract-card">
<div>
<p class="eyebrow">Contract Snapshot</p>
<strong id="contract-title">Query success envelope preview</strong>
<p id="contract-copy">展示当前界面状态如何映射到共享结构化契约;`running` 仍属于前端暂态。</p>
</div>
<pre class="contract-preview"><code id="contract-json"></code></pre>
</div>
</div>
</section>
<footer class="status-bar">
<span id="status-message" aria-live="polite">Ready for review. Use 15 to preview states, `R` to simulate run, `T` to switch theme, `/` to focus search.</span>
<div class="status-shortcuts">
<span>1 Running</span>
<span>2 Success</span>
<span>3 Empty</span>
<span>4 Error</span>
<span>5 Exported</span>
<span>R Run</span>
<span>T Theme</span>
<span>/ Search</span>
<span>⌘/Ctrl+K Actions</span>
</div>
</footer>
</section>
<aside class="panel panel--side">
<section class="panel-section">
<p class="eyebrow">Inspector</p>
<h2>Current Selection</h2>
<div class="info-card">
<span>Object</span>
<strong id="inspector-object">public.orders</strong>
</div>
<div class="info-card">
<span>Kind</span>
<strong id="selection-kind">Table</strong>
</div>
<div class="info-card">
<span>Primary Key</span>
<strong id="selection-primary-key">id</strong>
</div>
<div class="info-card">
<span>Columns</span>
<strong id="selection-columns">12</strong>
</div>
</section>
<section class="panel-section">
<p class="eyebrow">Execution Detail</p>
<div class="detail-list">
<div>
<span>Target</span>
<strong id="detail-target">pg-prod-readonly</strong>
</div>
<div>
<span>Mode</span>
<strong id="detail-mode">Read-only</strong>
</div>
<div>
<span>Last export</span>
<strong id="detail-export">Not started</strong>
</div>
<div>
<span>Theme</span>
<strong id="detail-theme">Dark</strong>
</div>
</div>
</section>
<section class="panel-section">
<p class="eyebrow">Acceptance Focus</p>
<ul class="focus-list">
<li>连接概览、工作区上下文、执行状态三者始终同时可见</li>
<li>空结果与失败都不能伪装成同一种“空白”界面</li>
<li>切换连接后主区域、导出区、Inspector 同步更新</li>
<li>Light / Dark 两种主题都保持低噪音和高对比</li>
</ul>
</section>
</aside>
</main>
</div>
<div class="command-palette" id="command-palette" hidden>
<button class="command-palette__backdrop" id="command-backdrop" aria-label="关闭快捷操作"></button>
<section class="command-dialog" role="dialog" aria-modal="true" aria-labelledby="command-title">
<div class="command-dialog__head">
<div>
<p class="eyebrow">Keyboard-first review</p>
<h2 id="command-title">Quick Actions</h2>
</div>
<button class="ghost-button ghost-button--small" id="command-close">Esc Close</button>
</div>
<div class="command-grid">
<section class="command-section">
<p class="eyebrow">Execution States</p>
<div class="command-list">
<button class="command-item" data-command-state="running">
<strong>Preview Running</strong>
<span>1 · 模拟执行中态,锁定导出并保留工作区上下文</span>
</button>
<button class="command-item" data-command-state="success">
<strong>Preview Success</strong>
<span>2 · 返回 50 行结果并保持导出入口可见</span>
</button>
<button class="command-item" data-command-state="empty">
<strong>Preview Empty</strong>
<span>3 · 成功但无结果,避免误判为错误</span>
</button>
<button class="command-item" data-command-state="error">
<strong>Preview Error</strong>
<span>4 · 错误摘要持续停留在工作区内</span>
</button>
<button class="command-item" data-command-state="exported">
<strong>Preview Exported</strong>
<span>5 · 导出完成反馈与结果表格并存</span>
</button>
</div>
</section>
<section class="command-section">
<p class="eyebrow">Connections</p>
<div class="command-list">
<button class="command-item" data-command-connection="pg-prod-readonly">
<strong>Open pg-prod-readonly</strong>
<span>PostgreSQL · Production · Read-only</span>
</button>
<button class="command-item" data-command-connection="mysql-staging">
<strong>Open mysql-staging</strong>
<span>MySQL · Staging · Write enabled</span>
</button>
<button class="command-item" data-command-connection="sqlite-local">
<strong>Open sqlite-local</strong>
<span>SQLite · Local file · Evidence review</span>
</button>
</div>
</section>
<section class="command-section">
<p class="eyebrow">Workflow</p>
<div class="command-list">
<button class="command-item" data-command-action="run">
<strong>Run current query</strong>
<span>R · 先进入 Running再回到当前 SQL 对应终态</span>
</button>
<button class="command-item" data-command-action="search">
<strong>Focus schema search</strong>
<span>/ · 快速定位 schema、table 和 column</span>
</button>
<button class="command-item" data-command-action="theme">
<strong>Toggle theme</strong>
<span>T · 切换 Light / Dark检查对比度稳定性</span>
</button>
</div>
</section>
</div>
</section>
</div>
<script src="./app.js"></script>
</body>
</html>