Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TWAP and Limit Order Status Display #5305

Open
wants to merge 12 commits into
base: feat/limit-ui-upgrade-2
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,29 @@ export function SpotPricesUpdater(): null {
return
}

const inputFraction = FractionUtils.fractionLikeToFraction(inputPrice.price)
const outputFraction = FractionUtils.fractionLikeToFraction(outputPrice.price)
const fraction = inputFraction.divide(outputFraction)
try {
const inputFraction = FractionUtils.fractionLikeToFraction(inputPrice.price)
const outputFraction = FractionUtils.fractionLikeToFraction(outputPrice.price)
const fraction = inputFraction.divide(outputFraction)

if (!fraction) {
return
if (!fraction) {
return
}
const price = FractionUtils.toPrice(fraction, inputCurrency, outputCurrency)

updateSpotPrices({
chainId,
sellTokenAddress: inputCurrency.address,
buyTokenAddress: outputCurrency.address,
price,
})
} catch (e) {
console.error(
`Failed to update spot prices for ${inputCurrency.address} and ${outputCurrency.address}`,
{ inputPrice, outputPrice },
e,
)
}
const price = FractionUtils.toPrice(fraction, inputCurrency, outputCurrency)

updateSpotPrices({
chainId,
sellTokenAddress: inputCurrency.address,
buyTokenAddress: outputCurrency.address,
price,
})
})
}, [usdPrices, markets, chainId, updateSpotPrices])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,43 +204,83 @@ export function OrderRow({
return orders.every((order) => order.status === OrderStatus.CANCELLED)
}

const renderFillsAt = () => (
<>
{getIsFinalizedOrder(order) ? (
order.executionData.partiallyFilled || order.status === OrderStatus.FULFILLED ? (
const renderFillsAt = () => {
// For TWAP parent orders, check child states first
if (isTwapTable && !isChild && childOrders) {
// Check if all child orders are filled (100%)
const allChildrenFilled = childOrders.every((childOrder) => {
const isFullyFilled =
childOrder.status === OrderStatus.FULFILLED &&
(percentIsAlmostHundred(childOrder.executionData.filledPercentDisplay) ||
Number(childOrder.executionData.filledPercentDisplay) >= 99.99)
console.debug('Child order fill status:', {
orderId: childOrder.id,
status: childOrder.status,
fillPercent: childOrder.executionData.filledPercentDisplay,
isFullyFilled,
})
return isFullyFilled
})

if (allChildrenFilled) {
return (
<styledEl.CellElement doubleRow>
<b>
<styledEl.FilledDisplay>
<Check size={14} strokeWidth={3.5} />
Order filled
</styledEl.FilledDisplay>
</b>
<i></i>
</styledEl.CellElement>
)
}

// Check if all child orders are at least partially filled
const allChildrenPartiallyFilled = childOrders.every(
(childOrder) =>
childOrder.status === OrderStatus.FULFILLED && Number(childOrder.executionData.filledPercentDisplay) > 0,
)

if (allChildrenPartiallyFilled) {
return (
<styledEl.FilledDisplay>
<Check size={14} strokeWidth={3.5} />
Order {order.partiallyFillable && Number(filledPercentDisplay) < 100 ? 'partially ' : ''}filled
Order partially filled
</styledEl.FilledDisplay>
) : order.status === OrderStatus.CANCELLED ? (
// For TWAP parent orders, show cancelled only when ALL child orders are cancelled
children ? (
childOrders && areAllChildOrdersCancelled(childOrders) ? (
<styledEl.CancelledDisplay>
<X size={14} strokeWidth={2.5} />
Order cancelled
</styledEl.CancelledDisplay>
) : (
'-'
)
) : (
// For non-TWAP orders and TWAP child orders, show cancelled normally
<styledEl.CancelledDisplay>
<X size={14} strokeWidth={2.5} />
Order cancelled
</styledEl.CancelledDisplay>
)
) : order.status === OrderStatus.EXPIRED ? (
<styledEl.ExpiredDisplay>
<Clock size={14} strokeWidth={2.5} />
Order expired
</styledEl.ExpiredDisplay>
) : isUnfillable ? (
''
) : (
'-'
)
) : order.status === OrderStatus.PRESIGNATURE_PENDING ? (
}

// Check for cancelled and expired
if (childOrders.every((childOrder) => childOrder.status === OrderStatus.CANCELLED)) {
return (
<styledEl.CancelledDisplay>
<X size={14} strokeWidth={2.5} />
Order cancelled
</styledEl.CancelledDisplay>
)
}

if (childOrders.every((childOrder) => childOrder.status === OrderStatus.EXPIRED)) {
return (
<styledEl.CellElement doubleRow>
<b>
<styledEl.ExpiredDisplay>
<Clock size={14} strokeWidth={2.5} />
Order expired
</styledEl.ExpiredDisplay>
</b>
<i></i>
</styledEl.CellElement>
)
}

return '-'
}

// Regular order status handling
if (order.status === OrderStatus.PRESIGNATURE_PENDING) {
return (
<styledEl.ExecuteCellWrapper>
<HoverTooltip
wrapInContainer={true}
Expand All @@ -256,7 +296,48 @@ export function OrderRow({
</styledEl.SigningDisplay>
</HoverTooltip>
</styledEl.ExecuteCellWrapper>
) : prices && estimatedExecutionPrice ? (
)
}

if (getIsFinalizedOrder(order)) {
// Check filled status first
if (Number(filledPercentDisplay) > 0) {
return (
<styledEl.FilledDisplay>
<Check size={14} strokeWidth={3.5} />
Order {Number(filledPercentDisplay) < 100 ? 'partially ' : ''}filled
</styledEl.FilledDisplay>
)
}

// Then check cancelled status
if (order.status === OrderStatus.CANCELLED) {
return (
<styledEl.CancelledDisplay>
<X size={14} strokeWidth={2.5} />
Order cancelled
</styledEl.CancelledDisplay>
)
}

if (order.status === OrderStatus.EXPIRED) {
return (
<styledEl.ExpiredDisplay>
<Clock size={14} strokeWidth={2.5} />
Order expired
</styledEl.ExpiredDisplay>
)
}

if (isUnfillable) {
return ''
}

return '-'
}

if (prices && estimatedExecutionPrice) {
return (
<styledEl.ExecuteCellWrapper>
{!isUnfillable &&
priceDiffs?.percentage &&
Expand Down Expand Up @@ -298,11 +379,11 @@ export function OrderRow({
/>
)}
</styledEl.ExecuteCellWrapper>
) : (
'-'
)}
</>
)
)
}

return '-'
}

const renderFillsAtWithDistance = () => {
// Special case for PRESIGNATURE_PENDING - return just the signing content
Expand All @@ -329,8 +410,8 @@ export function OrderRow({
}

// For TWAP parent orders
if (children && childOrders) {
// Check if all child orders are cancelled first
if (isTwapTable && !isChild && childOrders) {
// Check all child order states
if (areAllChildOrdersCancelled(childOrders)) {
return (
<styledEl.CellElement doubleRow>
Expand All @@ -345,6 +426,64 @@ export function OrderRow({
)
}

// Check if all child orders are expired
const allChildrenExpired = childOrders.every((childOrder) => childOrder.status === OrderStatus.EXPIRED)

if (allChildrenExpired) {
return (
<styledEl.CellElement doubleRow>
<b>
<styledEl.ExpiredDisplay>
<Clock size={14} strokeWidth={2.5} />
Order expired
</styledEl.ExpiredDisplay>
</b>
<i></i>
</styledEl.CellElement>
)
}

// Check if all child orders are filled (100%)
const allChildrenFilled = childOrders.every(
(childOrder) =>
childOrder.status === OrderStatus.FULFILLED && Number(childOrder.executionData.filledPercentDisplay) >= 99.99,
)

if (allChildrenFilled) {
return (
<styledEl.CellElement doubleRow>
<b>
<styledEl.FilledDisplay>
<Check size={14} strokeWidth={3.5} />
Order filled
</styledEl.FilledDisplay>
</b>
<i></i>
</styledEl.CellElement>
)
}

// Check if all child orders are at least partially filled
const allChildrenPartiallyFilled = childOrders.every(
(childOrder) =>
childOrder.status === OrderStatus.FULFILLED && Number(childOrder.executionData.filledPercentDisplay) > 0,
)

if (allChildrenPartiallyFilled) {
return (
<styledEl.CellElement doubleRow>
<b>
<styledEl.FilledDisplay>
<Check size={14} strokeWidth={3.5} />
Order partially filled
</styledEl.FilledDisplay>
</b>
<i></i>
</styledEl.CellElement>
)
}

// If no aggregate state, check for next scheduled order
const nextScheduledOrder = childOrders.find(
(childOrder) => childOrder.status === OrderStatus.SCHEDULED && !getIsFinalizedOrder(childOrder),
)
Expand Down Expand Up @@ -399,8 +538,9 @@ export function OrderRow({

// If no scheduled orders found, show dash
return (
<styledEl.CellElement>
<styledEl.CellElement doubleRow>
<b>-</b>
<i></i>
</styledEl.CellElement>
)
}
Expand Down Expand Up @@ -444,7 +584,7 @@ export function OrderRow({
}

// Check children finalization status
if (children && childOrders) {
if (isTwapTable && !isChild && childOrders) {
if (childOrders.every((childOrder) => getIsFinalizedOrder(childOrder))) {
return '-'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const TableHeader = styled.div<{ isHistoryTab: boolean; isRowSelectable:
}

// Default/Limit orders layout
return `${checkboxColumn} minmax(160px,2fr) minmax(120px,1fr) minmax(140px,1fr) minmax(120px,1fr) minmax(120px,1fr) minmax(100px,110px) minmax(80px,0.8fr) 24px`
return `${checkboxColumn} minmax(160px,2fr) minmax(120px,1fr) minmax(140px,1fr) minmax(120px,1fr) minmax(120px,1fr) minmax(100px,110px) minmax(106px,0.8fr) 24px`
}};
grid-template-rows: minmax(var(--header-height), 1fr);
align-items: center;
Expand Down
Loading