diff --git a/manual_trading_hub/static/app.css b/manual_trading_hub/static/app.css index 1b931a7..5d633e4 100644 --- a/manual_trading_hub/static/app.css +++ b/manual_trading_hub/static/app.css @@ -5797,6 +5797,9 @@ body.funds-fullscreen-open { background: var(--panel); } .archive-trade-row { + cursor: default; +} +#page-archive.is-chart-open .archive-trade-row { cursor: pointer; } .archive-trade-row.is-active { diff --git a/manual_trading_hub/static/archive.js b/manual_trading_hub/static/archive.js index d6807ab..f02a50c 100644 --- a/manual_trading_hub/static/archive.js +++ b/manual_trading_hub/static/archive.js @@ -945,6 +945,50 @@ ); } + function isTradeRowInteractiveTarget(el) { + return !!( + el && + el.closest && + el.closest("button, select, input, textarea, a, label, .archive-actions-cell") + ); + } + + async function switchToTrade(tr) { + if (!tr) return; + const exKey = String(tr.exchange_key || "").toLowerCase(); + const sym = tr.symbol || ""; + if (!exKey || !sym) { + setStatus("该笔交易缺少交易所或合约,无法切换"); + return; + } + const key = tradeRowKey(tr); + const prevEx = selected && selected.exchange_key; + const prevSym = selected && selected.symbol; + if (key === selectedTradeKey && prevEx === exKey && prevSym === sym) return; + + selected = { exchange_key: exKey, symbol: sym }; + selectedTradeKey = key; + renderTrades(); + + const needSymbolReload = prevEx !== exKey || prevSym !== sym; + if (needSymbolReload) { + await loadSymbolTradesForChart(exKey, sym); + } + if (!isChartOpen()) return; + + if (needSymbolReload) { + await loadChart(); + return; + } + applyChartMarkers(); + const anchor = pickAnchorTrade(); + if (anchor && lastCandles.length) { + focusInitialTradeView(lastCandles, anchor, timeframe); + } + updateChartTitle(); + setStatus("已切换至 " + sym + " · " + exchangeLabel(exKey)); + } + async function openTradeChart(tr) { if (!tr) return; const exKey = String(tr.exchange_key || "").toLowerCase(); @@ -953,12 +997,8 @@ setStatus("该笔交易缺少交易所或合约,无法加载图表"); return; } - selected = { exchange_key: exKey, symbol: sym }; - selectedTradeKey = tradeRowKey(tr); - renderTrades(); setChartOpen(true); - await loadSymbolTradesForChart(exKey, sym); - await loadChart(); + await switchToTrade(tr); } function renderTrades() { @@ -1080,14 +1120,31 @@ } }); }); + elTrades.querySelectorAll(".archive-trade-row").forEach(function (row) { + row.addEventListener("click", function (ev) { + if (!isChartOpen()) return; + if (isTradeRowInteractiveTarget(ev.target)) return; + const tr = findTradeByKey(row.getAttribute("data-key")); + if (tr) void switchToTrade(tr); + }); + }); elTrades.querySelectorAll(".archive-tag-select").forEach(function (sel) { applyTagSelectStyle(sel); + sel.addEventListener("mousedown", function (ev) { + ev.stopPropagation(); + }); sel.addEventListener("change", function () { applyTagSelectStyle(sel); saveOverlay(sel.getAttribute("data-id"), sel.getAttribute("data-ex"), sel.value, null); }); }); elTrades.querySelectorAll(".archive-note-input").forEach(function (inp) { + inp.addEventListener("mousedown", function (ev) { + ev.stopPropagation(); + }); + inp.addEventListener("click", function (ev) { + ev.stopPropagation(); + }); inp.addEventListener("change", function () { const row = inp.closest(".archive-trade-row"); const tagSel = row && row.querySelector(".archive-tag-select"); diff --git a/manual_trading_hub/static/index.html b/manual_trading_hub/static/index.html index 7bd87d5..371b71d 100644 --- a/manual_trading_hub/static/index.html +++ b/manual_trading_hub/static/index.html @@ -15,7 +15,7 @@ - +
@@ -584,7 +584,7 @@ - +