fix(hub): use single position table header on desktop monitor cards
Render all exchange positions in one table row group instead of repeating column headers per symbol. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1272,6 +1272,14 @@ body.market-chart-fs-open {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.pos-table-wrap {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.data-table-positions tbody tr:not(:last-child) td {
|
||||
border-bottom: 1px dashed var(--border-soft);
|
||||
}
|
||||
|
||||
.pos-action-group {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
|
||||
@@ -1537,16 +1537,25 @@
|
||||
.join("");
|
||||
}
|
||||
|
||||
function renderPositionBlock(exchangeId, exchangeKey, x, monitorOrder, trendPlan, tickMap, opts) {
|
||||
function renderPositionTableRow(
|
||||
exchangeId,
|
||||
exchangeKey,
|
||||
x,
|
||||
monitorOrder,
|
||||
trendPlan,
|
||||
tickMap,
|
||||
opts
|
||||
) {
|
||||
const options = opts || {};
|
||||
const compact = !!options.compact;
|
||||
const symAttr = esc(x.symbol || "").replace(/"/g, """);
|
||||
const exKeyAttr = esc(exchangeKey || exchangeId || "").replace(/"/g, """);
|
||||
const sideAttr = esc((x.side || "").toLowerCase()).replace(/"/g, """);
|
||||
const side = sideAttr || "long";
|
||||
const contractsAttr = esc(String(x.contracts != null ? x.contracts : "")).replace(/"/g, """);
|
||||
const contractsAttr = esc(String(x.contracts != null ? x.contracts : "")).replace(
|
||||
/"/g,
|
||||
"""
|
||||
);
|
||||
const cond = condOrdersFromPosition(x);
|
||||
const reg = Array.isArray(x.regular_orders) ? x.regular_orders : [];
|
||||
const tpsl = resolvePositionTpsl(x, monitorOrder, trendPlan);
|
||||
const beSecured = isBreakevenSecured(side, tpsl.entry, monitorOrder, cond, x);
|
||||
const slAttr = esc(String(tpsl.sl)).replace(/"/g, """);
|
||||
@@ -1559,13 +1568,7 @@
|
||||
<button type="button" class="btn-place-tpsl btn-sm ghost" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}" data-contracts="${contractsAttr}" data-sl="${slAttr}" data-tp="${tpAttr}">委托</button>
|
||||
<button type="button" class="btn-close-pos btn-sm danger" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}">平仓</button>
|
||||
</div>`;
|
||||
const ordersBlock = compact
|
||||
? ""
|
||||
: renderOrdersCollapse(exchangeId, x.symbol, cond, reg, tickMap);
|
||||
return `<div class="pos-block">
|
||||
<div class="table-scroll">
|
||||
<table class="data-table"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th><th>浮盈</th><th>操作</th></tr></thead><tbody>
|
||||
<tr>
|
||||
return `<tr>
|
||||
<td class="td-symbol"><button type="button" class="btn-open-market sym-link" ${mktAttrs} title="打开行情区(含入场/止盈止损)">${esc(x.symbol)}</button>${symBeBadge}</td>
|
||||
<td class="${sideDirCls(x.side)}">${renderDirectionHtml(x.side)}</td>
|
||||
<td class="td-entry">${fmtEntryPrice(x, tickMap)}</td>
|
||||
@@ -1573,13 +1576,57 @@
|
||||
<td>${fmt(x.contracts, 4)}</td>
|
||||
<td class="${pnlCls(x.unrealized_pnl)}">${fmt(x.unrealized_pnl, 2)}</td>
|
||||
<td class="td-actions">${actionCell}</td>
|
||||
</tr>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
function renderPositionBlock(exchangeId, exchangeKey, x, monitorOrder, trendPlan, tickMap, opts) {
|
||||
const options = opts || {};
|
||||
const compact = !!options.compact;
|
||||
const reg = Array.isArray(x.regular_orders) ? x.regular_orders : [];
|
||||
const cond = condOrdersFromPosition(x);
|
||||
const ordersBlock = compact
|
||||
? ""
|
||||
: renderOrdersCollapse(exchangeId, x.symbol, cond, reg, tickMap);
|
||||
const rowHtml = renderPositionTableRow(
|
||||
exchangeId,
|
||||
exchangeKey,
|
||||
x,
|
||||
monitorOrder,
|
||||
trendPlan,
|
||||
tickMap,
|
||||
opts
|
||||
);
|
||||
return `<div class="pos-block">
|
||||
<div class="table-scroll">
|
||||
<table class="data-table"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th><th>浮盈</th><th>操作</th></tr></thead><tbody>
|
||||
${rowHtml}
|
||||
</tbody></table>
|
||||
</div>
|
||||
${ordersBlock}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function renderGridPositionsTable(exchangeId, exchangeKey, positions, orders, trends, tickMap) {
|
||||
const rows = positions
|
||||
.map((p) =>
|
||||
renderPositionTableRow(
|
||||
exchangeId,
|
||||
exchangeKey,
|
||||
p,
|
||||
findMonitorOrder(orders, p.symbol, p.side),
|
||||
findTrendPlan(trends, p.symbol, p.side),
|
||||
tickMap,
|
||||
{ compact: true }
|
||||
)
|
||||
)
|
||||
.join("");
|
||||
return `<div class="pos-table-wrap table-scroll">
|
||||
<table class="data-table data-table-positions"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th><th>浮盈</th><th>操作</th></tr></thead><tbody>
|
||||
${rows}
|
||||
</tbody></table>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function renderGridBody(row, ag, pos, hm, flaskOk, keys, orders, trends, rolls, kmap) {
|
||||
const tickMap = buildPriceTickMap(row);
|
||||
let inner = `<div class="stat-row">
|
||||
@@ -1588,19 +1635,14 @@
|
||||
</div>`;
|
||||
inner += `<div class="section-title">交易所持仓 · ${pos.length} 仓</div>`;
|
||||
if (pos.length) {
|
||||
inner += pos
|
||||
.map((p) =>
|
||||
renderPositionBlock(
|
||||
row.id,
|
||||
row.key || row.id,
|
||||
p,
|
||||
findMonitorOrder(orders, p.symbol, p.side),
|
||||
findTrendPlan(trends, p.symbol, p.side),
|
||||
tickMap,
|
||||
{ compact: true }
|
||||
)
|
||||
)
|
||||
.join("");
|
||||
inner += renderGridPositionsTable(
|
||||
row.id,
|
||||
row.key || row.id,
|
||||
pos,
|
||||
orders,
|
||||
trends,
|
||||
tickMap
|
||||
);
|
||||
} else {
|
||||
inner += '<div class="empty-hint">无持仓</div>';
|
||||
}
|
||||
|
||||
@@ -246,6 +246,6 @@
|
||||
<div id="toast"></div>
|
||||
<script src="https://unpkg.com/lightweight-charts@4.2.0/dist/lightweight-charts.standalone.production.js"></script>
|
||||
<script src="/assets/chart.js?v=20260603-hub-binance-tick"></script>
|
||||
<script src="/assets/app.js?v=20260604-hub-grid-compact2"></script>
|
||||
<script src="/assets/app.js?v=20260604-hub-pos-table"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user