fix(frontend): limit ladder UX — rung input, crossing guard, button, cache (#295 #296 #297 #298) #757

Merged
Brouie merged 1 commit from qa/295-298-limit-ladder-ux into main 2026-06-05 03:24:32 +00:00
Brouie commented 2026-06-05 03:21:46 +00:00 (Migrated from gitlab.com)

Four fixes in the limit-ladder panel (one component, bundled to avoid same-file conflicts):

  • #295 — rung-count input snapped to the minimum on backspace. Decoupled the input from numeric state (raw string draft + clamp-on-blur), so you can clear it and type a fresh value; added an inline out-of-range message instead of the old silent cap.
  • #296 — "Place ladder" submit was the neutral btn-neo; switched to the primary CTA class (btn-primary btn-cta) the other order-submit buttons use.
  • #297 — no crossing-order validation. Ported the single-order form's non-crossing guard (describeLimitCrossingBlocker per rung) — disables submit, warns inline, and hard-guards in the mutation when ladder rungs cross the market.
  • #298 — placed orders only showed in My Limits, not the Order Book, until refresh. The place onSuccess now also invalidates the order-book / best-book query keys.

tsc -b clean. Frontend-only; browser/visual verification is totdking's. No closing keyword.

Four fixes in the limit-ladder panel (one component, bundled to avoid same-file conflicts): - **#295** — rung-count input snapped to the minimum on backspace. Decoupled the input from numeric state (raw string draft + clamp-on-blur), so you can clear it and type a fresh value; added an inline out-of-range message instead of the old silent cap. - **#296** — "Place ladder" submit was the neutral `btn-neo`; switched to the primary CTA class (`btn-primary btn-cta`) the other order-submit buttons use. - **#297** — no crossing-order validation. Ported the single-order form's non-crossing guard (`describeLimitCrossingBlocker` per rung) — disables submit, warns inline, and hard-guards in the mutation when ladder rungs cross the market. - **#298** — placed orders only showed in My Limits, not the Order Book, until refresh. The place onSuccess now also invalidates the order-book / best-book query keys. tsc -b clean. Frontend-only; browser/visual verification is totdking's. No closing keyword.
Brouie commented 2026-06-05 03:23:12 +00:00 (Migrated from gitlab.com)

mentioned in issue #295

mentioned in issue #295
Brouie commented 2026-06-05 03:23:13 +00:00 (Migrated from gitlab.com)

mentioned in issue #296

mentioned in issue #296
Brouie commented 2026-06-05 03:23:14 +00:00 (Migrated from gitlab.com)

mentioned in issue #297

mentioned in issue #297
Brouie commented 2026-06-05 03:23:15 +00:00 (Migrated from gitlab.com)

mentioned in issue #298

mentioned in issue #298
PlasticDigits commented 2026-06-05 03:24:02 +00:00 (Migrated from gitlab.com)

Security review (automated)

Commit reviewed: 84dae10f326e4d714affe4637355d4143669121f

Scope: frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx only (MR diff: rung-count draft input + clamp-on-blur, primary CTA styling, non-crossing guard ported from single-order flow, React Query cache invalidation for limit book / best book).

Method: Traced user-controlled inputs (rungCountInput, ladder prices, indexer bestBid/bestAsk) to UI sinks and placeMutation; compared crossing-guard pattern to TradeOrderTicket.tsx; confirmed on-chain enforcement remains authoritative for batch size and order insertion.

Outcome: FINDINGS: 0 (no medium, high, or critical issues on this diff)

Inline threads: None — no findings to anchor.


Summary

This MR is client-side UX and safety hardening. No new auth surfaces, secrets, server endpoints, or dependency changes.

Area Assessment
Injection / XSS User and indexer strings render as React text (LimitOrderEscrowPlaceGuardMessage, error <p>); no dangerouslySetInnerHTML. Crossing messages reuse existing describeLimitCrossingBlocker (already used in TradeOrderTicket).
Authn / authz Unchanged — placement still requires wallet-signed txs via existing placeLimitOrder*WithAllowance helpers.
Crossing guard bypass Client-only guard (same as single-order form); direct contract calls were already possible. MR adds UI + mutation checks for ladders, reducing accidental marketable placement. Stale/empty book data may allow crossing when bestBid/bestAsk are absent — pre-existing indexer semantics, user-economic impact only.
Rung-count draft state rungCount used for preview/submit stays bounded by max_batch_rungs on valid input and clamp-on-blur; contract enforces limits on-chain. Transient input/display desync is UX-only, not a privilege boundary.
Cache invalidation invalidateQueries for book keys — consistency fix only, no new data exposure.

Security review: no medium+ findings on this diff.

## Security review (automated) **Commit reviewed:** `84dae10f326e4d714affe4637355d4143669121f` **Scope:** `frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx` only (MR diff: rung-count draft input + clamp-on-blur, primary CTA styling, non-crossing guard ported from single-order flow, React Query cache invalidation for limit book / best book). **Method:** Traced user-controlled inputs (`rungCountInput`, ladder prices, indexer `bestBid`/`bestAsk`) to UI sinks and `placeMutation`; compared crossing-guard pattern to `TradeOrderTicket.tsx`; confirmed on-chain enforcement remains authoritative for batch size and order insertion. **Outcome:** **FINDINGS: 0** (no medium, high, or critical issues on this diff) **Inline threads:** None — no findings to anchor. --- ### Summary This MR is client-side UX and safety hardening. No new auth surfaces, secrets, server endpoints, or dependency changes. | Area | Assessment | |------|------------| | Injection / XSS | User and indexer strings render as React text (`LimitOrderEscrowPlaceGuardMessage`, error `<p>`); no `dangerouslySetInnerHTML`. Crossing messages reuse existing `describeLimitCrossingBlocker` (already used in `TradeOrderTicket`). | | Authn / authz | Unchanged — placement still requires wallet-signed txs via existing `placeLimitOrder*WithAllowance` helpers. | | Crossing guard bypass | Client-only guard (same as single-order form); direct contract calls were already possible. MR **adds** UI + mutation checks for ladders, reducing accidental marketable placement. Stale/empty book data may allow crossing when `bestBid`/`bestAsk` are absent — pre-existing indexer semantics, user-economic impact only. | | Rung-count draft state | `rungCount` used for preview/submit stays bounded by `max_batch_rungs` on valid input and clamp-on-blur; contract enforces limits on-chain. Transient input/display desync is UX-only, not a privilege boundary. | | Cache invalidation | `invalidateQueries` for book keys — consistency fix only, no new data exposure. | **Security review: no medium+ findings on this diff.**
PlasticDigits (Migrated from gitlab.com) merged commit 6e42a5b6f6 into main 2026-06-05 03:24:32 +00:00
PlasticDigits commented 2026-06-05 03:24:33 +00:00 (Migrated from gitlab.com)

mentioned in commit 6e42a5b6f6

mentioned in commit 6e42a5b6f6a8a5b91735b5ad60d68168450254b0
PlasticDigits commented 2026-06-05 04:40:59 +00:00 (Migrated from gitlab.com)

mentioned in merge request !767

mentioned in merge request !767
totdking commented 2026-06-16 15:15:26 +00:00 (Migrated from gitlab.com)

mentioned in issue #385

mentioned in issue #385
PlasticDigits commented 2026-06-16 15:34:17 +00:00 (Migrated from gitlab.com)

mentioned in merge request !914

mentioned in merge request !914
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic!757
No description provided.