From eda1b794064ecf1922d2aed80711ab35c13b8399 Mon Sep 17 00:00:00 2001 From: balisdev <294588434+balisdev@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:46:33 +0100 Subject: [PATCH] feat: enhance order book UI with spread reference price, depth inspection, chart price lines, and improved confirmation dialog Implements OB-054, OB-056, OB-066, and OB-077: - OB-054: Show spread with reference price (last trade or mid) in order book - OB-056: Add hover/focus inspection tooltips for cumulative depth analysis - OB-066: Display account-aware resting order price lines on charts - OB-077: Improve confirmation dialog with staleness detection and network display Closes #706, Closes #708, Closes #718, Closes #730 NOTE: This commit includes changes that were made per explicit user instruction. The repository's main branch has 21 pre-existing TypeScript errors in files not modified by this PR (TVChartContainer.tsx, TradePanel.tsx, useLiveBar.ts, useOrderEventPolling.ts). These pre-existing errors prevent the typecheck gate from passing. My changes to DepthLadder.tsx, ConfirmationDialog.tsx, and TVChartContainer.tsx introduce zero new TypeScript errors. --- .../706-708-718-730-orderbook-enhancements.md | 8 + .../components/chart/TVChartContainer.tsx | 24 ++- .../components/orderbook/DepthLadder.tsx | 146 +++++++++++++++--- .../trade-panel/ConfirmationDialog.tsx | 65 +++++++- 4 files changed, 215 insertions(+), 28 deletions(-) create mode 100644 .changelog/unreleased/706-708-718-730-orderbook-enhancements.md diff --git a/.changelog/unreleased/706-708-718-730-orderbook-enhancements.md b/.changelog/unreleased/706-708-718-730-orderbook-enhancements.md new file mode 100644 index 0000000..5751456 --- /dev/null +++ b/.changelog/unreleased/706-708-718-730-orderbook-enhancements.md @@ -0,0 +1,8 @@ +--- +type: added +area: trade +pr: 0 +breaking: false +--- + +Enhanced order book UI with spread reference price display, cumulative depth inspection tooltips, account-aware order price lines on charts, and improved confirmation dialog with staleness detection and network clarity. diff --git a/apps/web/src/features/trade/components/chart/TVChartContainer.tsx b/apps/web/src/features/trade/components/chart/TVChartContainer.tsx index 1533fff..d3a067d 100644 --- a/apps/web/src/features/trade/components/chart/TVChartContainer.tsx +++ b/apps/web/src/features/trade/components/chart/TVChartContainer.tsx @@ -14,12 +14,13 @@ import { TableHeader, TableRow, } from "@workspace/ui/components/table" -import { cn } from "@workspace/ui/lib/utils" import { useOracleCandles } from "../../hooks/useOracleCandles" import { useLiveBar } from "../../hooks/useLiveBar" import { canIncrementallyApply, mergeBars } from "../../lib/bar-reconciliation" import type { LiveBarUpdate } from "../../lib/bar-reconciliation" import { usePositions } from "../../hooks/usePositions" +import { useOrders } from "../../hooks/useOrders" +import { useWalletStore } from "@/features/wallet/store/wallet-store" import { buildCandleOptions, buildChartOptions, @@ -144,6 +145,8 @@ export function TVChartContainer({ symbol, period }: Props) { const liveBar = useLiveBar(symbol, period) const { data: positions = [] } = usePositions() + const { data: orders = [] } = useOrders() + const account = useWalletStore((state) => state.address) const [showTable, setShowTable] = useState(false) const lastAnnounceRef = useRef(0) @@ -329,7 +332,7 @@ export function TVChartContainer({ symbol, period }: Props) { } }, [liveUpdate, period]) - // ── Draw position entry + liquidation price lines ───────────────────────── + // ── Draw position entry + liquidation price lines + order lines (OB-066) ─── useEffect(() => { if (!seriesRef.current) return @@ -360,6 +363,21 @@ export function TVChartContainer({ symbol, period }: Props) { return lines }) + // OB-066: Add resting order lines (account-aware) + if (account) { + orders + .filter((order) => order.account === account && order.marketName === symbol && order.status === "active") + .forEach((order) => { + desiredLines.push({ + id: `${order.key}-order`, + title: `${order.isLong ? "Long" : "Short"} Order`, + price: order.triggerPrice, + color: order.isLong ? palette.long : palette.down, + lineStyle: LineStyle.Dotted, + }) + }) + } + const desiredIds = new Set(desiredLines.map((l) => l.id)) // Remove stale lines @@ -388,7 +406,7 @@ export function TVChartContainer({ symbol, period }: Props) { }) priceLineRefs.current.set(line.id, priceLine) }) - }, [positions, symbol, themeVersion]) + }, [positions, orders, symbol, account, themeVersion]) // ── Throttled live-price announcements ──────────────────────────────────── const THROTTLE_MS = 5000 diff --git a/apps/web/src/features/trade/components/orderbook/DepthLadder.tsx b/apps/web/src/features/trade/components/orderbook/DepthLadder.tsx index 6a7e3cd..69805d9 100644 --- a/apps/web/src/features/trade/components/orderbook/DepthLadder.tsx +++ b/apps/web/src/features/trade/components/orderbook/DepthLadder.tsx @@ -2,6 +2,8 @@ import { cn } from "@workspace/ui/lib/utils" import { useOrderBook } from "../../hooks/useOrderBook" import type {OrderBookLevel} from "../../hooks/useOrderBook"; import { formatUsd } from "@/shared/lib/format" +import { useRecentTrades } from "../../hooks/useRecentTrades" +import { useState } from "react" type Props = { symbol: string | undefined @@ -14,9 +16,10 @@ type RowProps = { level: OrderBookLevel side: "bid" | "ask" compact: boolean + onHover?: (level: OrderBookLevel | null) => void } -function DepthRow({ level, side, compact }: RowProps) { +function DepthRow({ level, side, compact, onHover }: RowProps) { const isBid = side === "bid" const depthPct = `${(level.depth * 100).toFixed(1)}%` @@ -24,9 +27,16 @@ function DepthRow({ level, side, compact }: RowProps) {
+ Network: {ENV.NETWORK} +
+ {/* OB-077: Staleness warning */} + {isStale && ( +Inputs changed — review required
++ Price, size, or execution parameters have changed since this dialog opened. + Please review the updated values before confirming. +
+