Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into tina/ct-1055-buy-sell…
Browse files Browse the repository at this point in the history
…-marks
  • Loading branch information
tinaszheng committed Aug 16, 2024
2 parents 508a417 + f128fc0 commit 898e65c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 66 deletions.
119 changes: 55 additions & 64 deletions src/components/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Key, useCallback, useEffect, useState } from 'react';
import React, { Key, useCallback, useMemo, useState } from 'react';

import {
Cell, // CollectionBuilderContext,
Expand All @@ -25,7 +25,6 @@ import {
useTableRow,
useTableRowGroup,
} from 'react-aria';
import { useAsyncList } from 'react-stately';
import styled, { css } from 'styled-components';

import { MediaQueryKeys, useBreakpoints } from '@/hooks/useBreakpoints';
Expand Down Expand Up @@ -163,42 +162,45 @@ export const Table = <TableRowData extends BaseTableRowData | CustomRowConfig>({

const collator = useCollator();

const sortFn = (
a: TableRowData | CustomRowConfig,
b: TableRowData | CustomRowConfig,
sortColumn?: Key,
sortDirection?: SortDirection
) => {
if (!sortColumn) return 0;

const column = columns.find((c) => c.columnKey === sortColumn);
if (column == null || column.allowsSorting === false) {
return 0;
}
const first = (isCustomRow(a) ? 0 : column.getCellValue(a)) ?? undefined;
const second = (isCustomRow(b) ? 0 : column.getCellValue(b)) ?? undefined;

if (first == null || second == null) {
if (first === second) {
const sortFn = useCallback(
(
a: TableRowData | CustomRowConfig,
b: TableRowData | CustomRowConfig,
sortColumn?: Key,
sortDirection?: SortDirection
) => {
if (!sortColumn) return 0;

const column = columns.find((c) => c.columnKey === sortColumn);
if (column == null || column.allowsSorting === false) {
return 0;
}
if (first != null) {
return 1;
const first = (isCustomRow(a) ? 0 : column.getCellValue(a)) ?? undefined;
const second = (isCustomRow(b) ? 0 : column.getCellValue(b)) ?? undefined;

if (first == null || second == null) {
if (first === second) {
return 0;
}
if (first != null) {
return 1;
}
return -1;
}
return -1;
}

return (
// Compare the items by the sorted column
(Number.isNaN(Number(first))
? // String
collator.compare(String(first), String(second))
: // Number
MustBigNumber(first).comparedTo(MustBigNumber(second))) *
// Flip the direction if descending order is specified.
(sortDirection === 'descending' ? -1 : 1)
);
};

return (
// Compare the items by the sorted column
(Number.isNaN(Number(first))
? // String
collator.compare(String(first), String(second))
: // Number
MustBigNumber(first).comparedTo(MustBigNumber(second))) *
// Flip the direction if descending order is specified.
(sortDirection === 'descending' ? -1 : 1)
);
},
[collator, columns]
);

const internalGetRowKey = useCallback(
(row: TableRowData | CustomRowConfig) => {
Expand All @@ -207,30 +209,25 @@ export const Table = <TableRowData extends BaseTableRowData | CustomRowConfig>({
[getRowKey]
);

const list = useAsyncList<TableRowData | CustomRowConfig>({
getKey: internalGetRowKey,
load: async ({ sortDescriptor }) => ({
items: sortDescriptor?.column
? [...data].sort((a, b) => sortFn(a, b, sortDescriptor?.column, sortDescriptor?.direction))
: data,
}),

initialSortDescriptor: defaultSortDescriptor,

sort: async ({ items, sortDescriptor }) => ({
items: [...items].sort((a, b) =>
sortFn(a, b, sortDescriptor?.column, sortDescriptor?.direction)
),
}),
});

// FIX: refactor table so we don't have to manually reload
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => list.reload(), [data]);
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor | undefined>(
defaultSortDescriptor
);
const items = useMemo(() => {
return sortDescriptor?.column
? [...data].sort((a, b) => sortFn(a, b, sortDescriptor?.column, sortDescriptor?.direction))
: data;
}, [data, sortDescriptor?.column, sortDescriptor?.direction, sortFn]);

const isEmpty = data.length === 0;
const shouldPaginate = paginationBehavior === 'paginate' && data.length > Math.min(...PAGE_SIZES);

const bodyListItems = useMemo(
() =>
shouldPaginate && items.length > pageSize
? items.slice(currentPage * pageSize, (currentPage + 1) * pageSize)
: items,
[currentPage, items, pageSize, shouldPaginate]
);
return (
<$TableWrapper
className={className}
Expand All @@ -242,8 +239,8 @@ export const Table = <TableRowData extends BaseTableRowData | CustomRowConfig>({
{!isEmpty ? (
<TableRoot
aria-label={label}
sortDescriptor={list.sortDescriptor}
onSortChange={list.sort}
sortDescriptor={sortDescriptor}
onSortChange={setSortDescriptor}
selectedKeys={selectedKeys}
setSelectedKeys={setSelectedKeys}
selectionMode={selectionMode}
Expand Down Expand Up @@ -294,13 +291,7 @@ export const Table = <TableRowData extends BaseTableRowData | CustomRowConfig>({
)}
</TableHeader>

<TableBody
items={
shouldPaginate && list.items.length > pageSize
? list.items.slice(currentPage * pageSize, (currentPage + 1) * pageSize)
: list.items
}
>
<TableBody items={bodyListItems}>
{(item) => (
<Row key={internalGetRowKey(item)}>
{(columnKey) => (
Expand Down
20 changes: 20 additions & 0 deletions src/state/accountSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { NUM_PARENT_SUBACCOUNTS, OnboardingState } from '@/constants/account';
import { LEVERAGE_DECIMALS } from '@/constants/numbers';

import { MustBigNumber } from '@/lib/numbers';
import {
getHydratedTradingData,
isOrderStatusClearable,
Expand Down Expand Up @@ -466,6 +467,25 @@ export const getCurrentMarketFills = createAppSelector(
!currentMarketId ? [] : marketFills[currentMarketId]
);

const getFillsForOrderId = createAppSelector(
[(s, orderId) => orderId, getSubaccountFills],
(orderId, fills) => (orderId ? groupBy(fills, 'orderId')[orderId] ?? [] : [])
);

/**
* @returns the average price the order is filled at
*/
export const getAverageFillPriceForOrder = () =>
createAppSelector([(s, orderId) => getFillsForOrderId(s, orderId)], (fillsForOrderId) => {
let total = MustBigNumber(0);
let totalSize = MustBigNumber(0);
fillsForOrderId.forEach((fill) => {
total = total.plus(MustBigNumber(fill.price).times(fill.size));
totalSize = totalSize.plus(fill.size);
});
return totalSize.gt(0) ? total.div(totalSize) : null;
});

/**
* @param state
* @returns list of transfers for the currently connected subaccount
Expand Down
4 changes: 4 additions & 0 deletions src/views/forms/TriggersForm/TriggersForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ export const TriggersForm = ({
stepSizeDecimals={stepSizeDecimals}
tickSizeDecimals={tickSizeDecimals}
/>
<div tw="text-color-text-0 font-small-book">
{stringGetter({ key: STRING_KEYS.TRIGGERS_INFO_AUTOMATICALLY_CANCELED })}{' '}
{stringGetter({ key: STRING_KEYS.TRIGGERS_INFO_CUSTOM_AMOUNT })}
</div>
<WithTooltip tooltipString={hasInputErrors ? inputAlert?.alertString : undefined}>
<Button
action={ButtonAction.Primary}
Expand Down
12 changes: 10 additions & 2 deletions src/views/notifications/OrderStatusNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import { LoadingSpinner } from '@/components/Loading/LoadingSpinner';
// eslint-disable-next-line import/no-cycle
import { Notification, NotificationProps } from '@/components/Notification';

import { getFillByClientId, getOrderByClientId } from '@/state/accountSelectors';
import {
getAverageFillPriceForOrder,
getFillByClientId,
getOrderByClientId,
} from '@/state/accountSelectors';
import { useAppSelector } from '@/state/appTypes';
import { getMarketData } from '@/state/perpetualsSelectors';

Expand All @@ -48,6 +52,10 @@ export const OrderStatusNotification = ({
const order = useParameterizedSelector(getOrderByClientId, localOrder.clientId);
const fill = useParameterizedSelector(getFillByClientId, localOrder.clientId);
const marketData = useAppSelector((s) => getMarketData(s, localOrder.marketId), shallowEqual);
const averageFillPrice = useParameterizedSelector(
getAverageFillPriceForOrder,
localOrder.orderId
);

const { assetId } = marketData ?? {};
const { equityTiersLearnMore } = useURLConfigs();
Expand Down Expand Up @@ -81,7 +89,7 @@ export const OrderStatusNotification = ({
tradeType={getTradeType(order.type.rawValue) ?? undefined}
filledAmount={order.totalFilled}
assetId={assetId}
averagePrice={order.price}
averagePrice={averageFillPrice ?? order.price}
tickSizeDecimals={marketData?.configs?.displayTickSizeDecimals ?? USD_DECIMALS}
/>
);
Expand Down

0 comments on commit 898e65c

Please sign in to comment.