Highlight selected Call/Put legs on the OO hedge T-quote board.

Selected buttons show 腿A/腿B and accent styling so the active strikes are obvious.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-06 09:13:00 +08:00
parent f19500bcd9
commit baf928d064
5 changed files with 82 additions and 7 deletions
+65 -4
View File
@@ -882,6 +882,50 @@
});
}
function selectedOoLegMap() {
const map = {};
if (state.legA && state.legA.inst_id) map[String(state.legA.inst_id)] = "A";
if (state.legB && state.legB.inst_id) map[String(state.legB.inst_id)] = "B";
return map;
}
function syncOoPickHighlight() {
const tbody = $("hp-oo-tbody");
if (!tbody) return;
const map = selectedOoLegMap();
tbody.querySelectorAll(".hp-oo-pick").forEach(function (btn) {
const inst = String(btn.getAttribute("data-inst") || "");
const leg = map[inst];
const on = !!leg;
btn.classList.toggle("is-selected", on);
btn.classList.toggle("active", on);
btn.setAttribute("aria-pressed", on ? "true" : "false");
const side = String(btn.getAttribute("data-side") || "").toUpperCase();
const base = side === "P" ? "Put" : "Call";
btn.textContent = on ? "腿" + leg + " · " + base : base;
btn.title = on ? "已选用为腿" + leg + "(再点其他合约可改选)" : "选用此 " + base;
});
tbody.querySelectorAll("tr").forEach(function (tr) {
const callBtn = tr.querySelector('.hp-oo-pick[data-side="C"]');
const putBtn = tr.querySelector('.hp-oo-pick[data-side="P"]');
const callOn = !!(callBtn && map[String(callBtn.getAttribute("data-inst") || "")]);
const putOn = !!(putBtn && map[String(putBtn.getAttribute("data-inst") || "")]);
tr.classList.toggle("hp-oo-row-selected", callOn || putOn);
tr.querySelectorAll("td.opt-t-call").forEach(function (td) {
td.classList.toggle("hp-oo-side-selected", callOn);
});
if (callBtn && callBtn.parentElement) {
callBtn.parentElement.classList.toggle("hp-oo-side-selected", callOn);
}
tr.querySelectorAll("td.opt-t-put").forEach(function (td) {
td.classList.toggle("hp-oo-side-selected", putOn);
});
if (putBtn && putBtn.parentElement) {
putBtn.parentElement.classList.toggle("hp-oo-side-selected", putOn);
}
});
}
function renderTStrikes() {
const tbody = $("hp-oo-tbody");
if (!tbody) return;
@@ -892,6 +936,7 @@
return;
}
const rows = buildStraddleRows(exp.contracts);
const selected = selectedOoLegMap();
rows.forEach(function (row) {
const tr = document.createElement("tr");
const call = row.call;
@@ -901,6 +946,8 @@
if (!callOk && !putOk) return;
const callAsk = callOk ? fmtPxSz(call.ask, call.ask_sz, call.ask_estimated, call.tick_sz) : "—";
const putAsk = putOk ? fmtPxSz(put.ask, put.ask_sz, put.ask_estimated, put.tick_sz) : "—";
const callLeg = callOk ? selected[String(call.inst_id)] : "";
const putLeg = putOk ? selected[String(put.inst_id)] : "";
tr.innerHTML =
'<td class="opt-t-call opt-px-sz">' +
callAsk +
@@ -908,9 +955,15 @@
(callOk ? moneynessBadge(call) : "—") +
"</td><td>" +
(callOk
? '<button type="button" class="btn-secondary hp-oo-pick" data-side="C" data-inst="' +
? '<button type="button" class="btn-secondary hp-oo-pick' +
(callLeg ? " is-selected active" : "") +
'" data-side="C" data-inst="' +
call.inst_id +
'">Call</button>'
'" aria-pressed="' +
(callLeg ? "true" : "false") +
'">' +
(callLeg ? "腿" + callLeg + " · Call" : "Call") +
"</button>"
: "—") +
'</td><td class="opt-t-strike"><strong>' +
row.strike +
@@ -920,9 +973,15 @@
putAsk +
"</td><td>" +
(putOk
? '<button type="button" class="btn-secondary hp-oo-pick" data-side="P" data-inst="' +
? '<button type="button" class="btn-secondary hp-oo-pick' +
(putLeg ? " is-selected active" : "") +
'" data-side="P" data-inst="' +
put.inst_id +
'">Put</button>'
'" aria-pressed="' +
(putLeg ? "true" : "false") +
'">' +
(putLeg ? "腿" + putLeg + " · Put" : "Put") +
"</button>"
: "—") +
"</td>";
tbody.appendChild(tr);
@@ -947,6 +1006,7 @@
renderOoLegs();
});
});
syncOoPickHighlight();
}
function renderOoLegs() {
@@ -980,6 +1040,7 @@
fill("腿A", state.legA, "hp-oo-leg-a-info", "hp-oo-sheets-a");
fill("腿B", state.legB, "hp-oo-leg-b-info", "hp-oo-sheets-b");
autoFillOoSheets();
syncOoPickHighlight();
}
function ooSheets(id) {
+14
View File
@@ -3729,6 +3729,20 @@ html[data-theme="light"] .opt-be-dist-down {
.hedge-plan-page-wrap .opt-row-selected td {
background: rgba(90, 140, 255, 0.18);
}
.hedge-plan-page-wrap .hp-oo-pick.is-selected,
.hedge-plan-page-wrap .hp-oo-pick.active {
border-color: var(--accent, #00d4ff);
color: var(--text, #fff);
background: rgba(0, 212, 255, 0.22);
box-shadow: inset 0 0 0 1px rgba(0, 212, 255, 0.45), 0 0 0 2px rgba(0, 212, 255, 0.2);
font-weight: 700;
}
.hedge-plan-page-wrap .hp-oo-side-selected {
background: rgba(0, 212, 255, 0.12);
}
.hedge-plan-page-wrap tr.hp-oo-row-selected td.opt-t-strike {
color: var(--accent, #00d4ff);
}
.hedge-plan-page-wrap .hp-tab-panel.hidden,
.hedge-plan-page-wrap .hp-tab-panel[hidden] {
display: none !important;
@@ -327,4 +327,4 @@
</div>
</div>
</div>
<script src="/static/hedge_plan.js?v=33"></script>
<script src="/static/hedge_plan.js?v=34"></script>
+1 -1
View File
@@ -8,7 +8,7 @@
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
<link rel="stylesheet" href="/static/instance_page.css?v=13">
<link rel="stylesheet" href="/static/instance_theme.css?v=111">
<link rel="stylesheet" href="/static/instance_theme.css?v=112">
<script src="/static/account_risk_badge.js?v=4"></script>
<script src="/static/open_submit_gate.js?v=1"></script>
<meta name="theme-color" content="#0b0d14">
+1 -1
View File
@@ -19,7 +19,7 @@
<link rel="manifest" href="/static/icons/manifest.webmanifest">
<title>{{ pwa_app_name }}</title>
<link rel="stylesheet" href="/static/instance_page.css?v=13">
<link rel="stylesheet" href="/static/instance_theme.css?v=111">
<link rel="stylesheet" href="/static/instance_theme.css?v=112">
</head>
<body