Files
wehub-resource-sync 91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:19 +08:00

104 lines
6.3 KiB
HTML

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; font-family: "Segoe UI", Tahoma, sans-serif; font-size: 13px; background: #f0f0f0; overflow: hidden; }
#app { display: grid; grid-template-rows: auto auto 1fr auto; height: 100vh; }
/* menu + toolbar */
#menu { background: #f7f7f7; border-bottom: 1px solid #c8c8c8; padding: 2px 0; }
#menu span { padding: 3px 10px; }
#menu span:hover { background: #cde2ff; }
#toolbar { background: #eee; border-bottom: 1px solid #c8c8c8; display: flex; }
#toolbar button { border: 1px solid transparent; background: transparent; padding: 3px 9px; }
#toolbar button:hover { border: 1px solid #b0c4de; background: #e6eefb; }
#toolbar .sep { width: 1px; background: #c8c8c8; margin: 2px 3px; }
/* main split */
#main { display: grid; grid-template-columns: 380px 1px 1fr; overflow: hidden; }
#split { background: #c8c8c8; }
/* dense form: label | control rows, only cell borders */
#form { display: grid; grid-template-columns: 120px 1fr; grid-auto-rows: 30px; background: #fff; align-content: start; }
#form .lbl { background: #f0f0f0; border-right: 1px solid #e0e0e0; border-bottom: 1px solid #e0e0e0; display: flex; align-items: center; padding-left: 8px; }
#form .cell { border-bottom: 1px solid #e0e0e0; display: flex; align-items: center; }
#form .cell > * { width: 100%; height: 100%; border: 0; background: transparent; padding: 0 6px; font: inherit; }
#form input[type=range] { padding: 0; }
#saveRow { grid-column: 1 / span 2; }
#save { width: 100%; height: 38px; font-weight: bold; }
/* right side */
#right { display: grid; grid-template-rows: 150px 1px 1fr; overflow: hidden; }
#sigHdr { background: #e1e1e1; font-weight: bold; padding: 3px 6px; border-bottom: 1px solid #c8c8c8; }
#sigWrap { display: grid; grid-template-rows: auto 1fr; }
#doodle { width: 100%; height: 100%; background: #fff; display: block; }
table { border-collapse: collapse; width: 100%; background: #fff; }
th, td { border: 1px solid #d2d2d2; padding: 2px 6px; text-align: left; font-weight: normal; }
th { background: #eef1f5; font-weight: 600; }
#gridWrap { overflow: auto; }
#status { background: #e8e8e8; border-top: 1px solid #c8c8c8; display: flex; justify-content: space-between; padding: 3px 8px; }
</style>
</head>
<body>
<div id="app">
<div id="menu"><span>File</span><span>Edit</span><span>View</span><span>Record</span><span>Tools</span><span>Help</span></div>
<div id="toolbar">
<button>New</button><button>Open</button><button>Save</button><button>Delete</button>
<div class="sep"></div><button>◀ Prev</button><button>Next ▶</button>
<div class="sep"></div><button>Find</button>
</div>
<div id="main">
<div id="form">
<div class="lbl">Account Name</div><div class="cell"><input id="acct" type="text" /></div>
<div class="lbl">Account Type</div><div class="cell"><select id="type"><option>Enterprise</option><option>SMB</option><option>Government</option><option>Reseller</option></select></div>
<div class="lbl">Region</div><div class="cell"><select id="region"><option>North</option><option>South</option><option>EMEA</option><option>APAC</option><option>LATAM</option></select></div>
<div class="lbl">Priority (1-5)</div><div class="cell"><input id="pri" type="range" min="1" max="5" value="3" /></div>
<div class="lbl">Credit Limit</div><div class="cell"><input id="credit" type="range" min="0" max="100" value="40" /></div>
<div id="saveRow" class="cell"><button id="save">Add Record</button></div>
</div>
<div id="split"></div>
<div id="right">
<div id="sigWrap"><div id="sigHdr">Signature / Notes</div><canvas id="doodle"></canvas></div>
<div id="split"></div>
<div id="gridWrap">
<table id="grid"><thead><tr><th>Account</th><th>Type</th><th>Region</th><th>Pri</th><th>Credit</th></tr></thead><tbody></tbody></table>
</div>
</div>
</div>
<div id="status"><span id="statusMsg">Ready</span><span>USER: SYSTEM ▌ CONNECTED</span><span id="recCount">Records: 0</span></div>
</div>
<script>
// line tool: one straight segment per press-drag-release (down→up)
const cv = document.getElementById('doodle');
const ctx = cv.getContext('2d');
let segs = [], dn = null, cur = null;
function redraw() {
ctx.clearRect(0, 0, cv.width, cv.height);
ctx.strokeStyle = '#191970'; ctx.lineWidth = 2;
for (const s of segs) { ctx.beginPath(); ctx.moveTo(s.x0, s.y0); ctx.lineTo(s.x1, s.y1); ctx.stroke(); }
if (dn && cur) { ctx.save(); ctx.globalAlpha = 0.45; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(dn.x, dn.y); ctx.lineTo(cur.x, cur.y); ctx.stroke(); ctx.restore(); }
}
function fit() { cv.width = cv.clientWidth; cv.height = cv.clientHeight; redraw(); }
window.addEventListener('resize', fit); requestAnimationFrame(fit);
// Pointer events (not mouse): coordinate-routed background injection arrives
// as PEN/touch pointers; pointer* covers mouse + pen + touch uniformly.
cv.style.touchAction = 'none';
cv.addEventListener('pointerdown', e => { dn = { x: e.offsetX, y: e.offsetY }; cur = dn; });
cv.addEventListener('pointermove', e => { if (dn) { cur = { x: e.offsetX, y: e.offsetY }; redraw(); } });
cv.addEventListener('pointerup', e => { if (dn) { segs.push({ x0: dn.x, y0: dn.y, x1: e.offsetX, y1: e.offsetY }); dn = null; cur = null; redraw(); } });
// save
let records = 0;
const acct = document.getElementById('acct'), tbody = document.querySelector('#grid tbody');
document.getElementById('save').addEventListener('click', () => {
let nm = (acct.value || '').trim(); if (!nm) nm = '(unnamed)';
const tr = document.createElement('tr');
const credit = '$' + (document.getElementById('credit').value * 1000);
[nm, document.getElementById('type').value, document.getElementById('region').value, document.getElementById('pri').value, credit]
.forEach(v => { const td = document.createElement('td'); td.textContent = v; tr.appendChild(td); });
tbody.appendChild(tr);
records++; document.getElementById('recCount').textContent = `Records: ${records}`;
document.getElementById('statusMsg').textContent = `Saved account '${nm}'.`;
acct.value = '';
});
</script>
</body>
</html>