feat: add marketId to orders query (#2536)

* feat: add marketId to orders query

* feat: move filters handling from useOrderListData to ordersProvider
This commit is contained in:
Bartłomiej Głownia 2023-01-16 13:26:50 +01:00 committed by GitHub
parent 12a799a2fd
commit 06151c0592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 104 additions and 100 deletions

View File

@ -97,7 +97,13 @@ describe('orders list', { tags: '@smoke' }, () => {
it('orders are sorted by most recent order', () => {
// 7003-MORD-002
const expectedOrderList = ['BTCUSD.MF21', 'BTCUSD.MF21'];
const expectedOrderList = [
'BTCUSD.MF21',
'SOLUSD',
'AAPL.MF21',
'BTCUSD.MF21',
'BTCUSD.MF21',
];
cy.getByTestId('tab-orders')
.get(`.ag-center-cols-container [col-id='${orderSymbol}']`)

View File

@ -95,9 +95,7 @@ export const SelectMarketPopover = ({
onSelect: (id: string) => void;
onCellClick: OnCellClickHandler;
}) => {
const { activeMarketId } = useGlobalStore((store) => ({
activeMarketId: store.marketId,
}));
const activeMarketId = useGlobalStore((store) => store.marketId);
const triggerClasses =
'sm:text-lg md:text-xl lg:text-2xl flex items-center gap-2 whitespace-nowrap hover:text-neutral-500 dark:hover:text-neutral-300 mt-1';
const { pubKey } = useVegaWallet();

View File

@ -153,13 +153,12 @@ export const useLedgerEntriesDataProvider = ({
const update = useCallback(
({ data }: { data: (AggregatedLedgerEntriesEdge | null)[] | null }) => {
const avoidRerender = !!(
(dataRef.current?.length && data?.length) ||
(!dataRef.current?.length && !data?.length)
);
dataRef.current = data;
const rerender =
(!dataRef.current?.length && data?.length) ||
(dataRef.current?.length && !data?.length);
gridRef.current?.api?.refreshInfiniteCache();
return avoidRerender;
return !rerender;
},
[gridRef]
);

View File

@ -27,6 +27,7 @@ query Orders(
$pagination: Pagination
$dateRange: DateRange
$filter: OrderFilter
$marketId: ID
) {
party(id: $partyId) {
id
@ -34,6 +35,7 @@ query Orders(
pagination: $pagination
dateRange: $dateRange
filter: $filter
marketId: $marketId
) {
edges {
node {

View File

@ -10,6 +10,7 @@ export type OrdersQueryVariables = Types.Exact<{
pagination?: Types.InputMaybe<Types.Pagination>;
dateRange?: Types.InputMaybe<Types.DateRange>;
filter?: Types.InputMaybe<Types.OrderFilter>;
marketId?: Types.InputMaybe<Types.Scalars['ID']>;
}>;
@ -72,13 +73,14 @@ export const OrderUpdateFieldsFragmentDoc = gql`
}
`;
export const OrdersDocument = gql`
query Orders($partyId: ID!, $pagination: Pagination, $dateRange: DateRange, $filter: OrderFilter) {
query Orders($partyId: ID!, $pagination: Pagination, $dateRange: DateRange, $filter: OrderFilter, $marketId: ID) {
party(id: $partyId) {
id
ordersConnection(
pagination: $pagination
dateRange: $dateRange
filter: $filter
marketId: $marketId
) {
edges {
node {
@ -113,6 +115,7 @@ export const OrdersDocument = gql`
* pagination: // value for 'pagination'
* dateRange: // value for 'dateRange'
* filter: // value for 'filter'
* marketId: // value for 'marketId'
* },
* });
*/

View File

@ -13,6 +13,7 @@ import { marketsProvider } from '@vegaprotocol/market-list';
import type { PageInfo, Edge } from '@vegaprotocol/react-helpers';
import type {
OrderFieldsFragment,
OrderUpdateFieldsFragment,
OrdersQuery,
OrdersUpdateSubscription,
OrdersQueryVariables,
@ -24,6 +25,52 @@ export type Order = Omit<OrderFieldsFragment, 'market'> & {
};
export type OrderEdge = Edge<Order>;
const orderMatchFilters = (
order: OrderUpdateFieldsFragment,
variables: OrdersQueryVariables
) => {
if (!order) {
return true;
}
if (
variables?.filter?.status &&
!(order.status && variables.filter.status.includes(order.status))
) {
return false;
}
if (
variables?.filter?.types &&
!(order.type && variables.filter.types.includes(order.type))
) {
return false;
}
if (
variables?.filter?.timeInForce &&
!variables.filter.timeInForce.includes(order.timeInForce)
) {
return false;
}
if (
variables?.dateRange?.start &&
!(
(order.updatedAt || order.createdAt) &&
variables.dateRange.start < (order.updatedAt || order.createdAt)
)
) {
return false;
}
if (
variables?.dateRange?.end &&
!(
(order.updatedAt || order.createdAt) &&
variables.dateRange.end > (order.updatedAt || order.createdAt)
)
) {
return false;
}
return true;
};
const getData = (responseData: OrdersQuery) =>
responseData?.party?.ordersConnection?.edges || [];
@ -57,23 +104,7 @@ export const update = (
draft.length === 0 ||
(node.updatedAt || node.createdAt) >=
(draft[0].node.updatedAt || draft[0].node.createdAt);
let doesFilterPass = true;
if (
doesFilterPass &&
variables?.dateRange?.start &&
new Date(node.updatedAt || node.createdAt) <=
new Date(variables?.dateRange?.start)
) {
doesFilterPass = false;
}
if (
doesFilterPass &&
variables?.dateRange?.end &&
new Date(node.updatedAt || node.createdAt) >=
new Date(variables?.dateRange?.end)
) {
doesFilterPass = false;
}
const doesFilterPass = !variables || orderMatchFilters(node, variables);
if (index !== -1) {
if (doesFilterPass) {
Object.assign(draft[index].node, node);

View File

@ -42,64 +42,6 @@ interface Props {
scrolledToTop: RefObject<boolean>;
}
const filterOrders = (
orders: (OrderEdge | null)[] | null,
variables: OrdersQueryVariables & OrdersUpdateSubscriptionVariables
) => {
if (!orders) {
return orders;
}
return orders.filter((order) => {
if (variables.marketId && order?.node.market?.id !== variables.marketId) {
return false;
}
if (
variables?.filter?.status &&
!(
order?.node?.status &&
variables.filter.status.includes(order.node.status)
)
) {
return false;
}
if (
variables?.filter?.types &&
!(order?.node?.type && variables.filter.types.includes(order.node.type))
) {
return false;
}
if (
variables?.filter?.timeInForce &&
!(
order?.node?.timeInForce &&
variables.filter.timeInForce.includes(order.node.timeInForce)
)
) {
return false;
}
if (
variables?.dateRange?.start &&
!(
(order?.node?.updatedAt || order?.node?.createdAt) &&
variables.dateRange.start <
(order.node.updatedAt || order.node.createdAt)
)
) {
return false;
}
if (
variables?.dateRange?.end &&
!(
(order?.node?.updatedAt || order?.node?.createdAt) &&
variables.dateRange.end > (order.node.updatedAt || order.node.createdAt)
)
) {
return false;
}
return true;
});
};
export const useOrderListData = ({
partyId,
marketId,
@ -143,9 +85,11 @@ export const useOrderListData = ({
({
data,
delta,
totalCount,
}: {
data: (OrderEdge | null)[] | null;
delta?: Order[];
totalCount?: number;
}) => {
if (dataRef.current?.length && delta?.length && !scrolledToTop.current) {
const createdAt = dataRef.current?.[0]?.node.createdAt;
@ -155,16 +99,15 @@ export const useOrderListData = ({
).length;
}
}
const filteredData = filterOrders(data, variables);
dataRef.current = filteredData;
const avoidRerender = !!(
(dataRef.current?.length && filteredData?.length) ||
(!dataRef.current?.length && !filteredData?.length)
);
dataRef.current = data;
totalCountRef.current = totalCount;
const rerender =
(!dataRef.current?.length && data?.length) ||
(dataRef.current?.length && !data?.length);
gridRef.current?.api?.refreshInfiniteCache();
return avoidRerender;
return !rerender;
},
[gridRef, scrolledToTop, variables]
[gridRef, scrolledToTop]
);
const insert = useCallback(
@ -175,11 +118,11 @@ export const useOrderListData = ({
data: (OrderEdge | null)[] | null;
totalCount?: number;
}) => {
dataRef.current = filterOrders(data, variables);
dataRef.current = data;
totalCountRef.current = totalCount;
return true;
},
[variables]
[]
);
const { data, error, loading, load, totalCount } = useDataProvider({

View File

@ -51,7 +51,6 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
<AgGridColumn
headerName={t('Market')}
field="market.tradableInstrument.instrument.code"
filter
cellRenderer={({
value,
data,

View File

@ -14,7 +14,15 @@ export interface useDataProviderParams<
Variables extends OperationVariables = OperationVariables
> {
dataProvider: Subscribe<Data, Delta, Variables>;
update?: ({ delta, data }: { delta?: Delta; data: Data | null }) => boolean;
update?: ({
delta,
data,
totalCount,
}: {
delta?: Delta;
data: Data | null;
totalCount?: number;
}) => boolean;
insert?: ({
insertionData,
data,
@ -90,7 +98,12 @@ export const useDataProvider = <
// if update or insert function returns true it means that component handles updates
// component can use flush() which will call callback without delta and cause data state update
if (!loading) {
if (isUpdate && !skipUpdates && update && update({ delta, data })) {
if (
isUpdate &&
!skipUpdates &&
update &&
update({ delta, data, totalCount })
) {
return;
}
if (isInsert && insert && insert({ insertionData, data, totalCount })) {

View File

@ -293,6 +293,13 @@ function makeDataProviderInternal<
return insertionData;
};
const setData = (updatedData: Data | null) => {
data = updatedData;
if (totalCount !== undefined && data instanceof Array) {
totalCount = data.length;
}
};
const initialFetch = async () => {
if (!client) {
return;
@ -329,7 +336,10 @@ function makeDataProviderInternal<
while (updateQueue.length) {
const delta = updateQueue.shift();
if (delta) {
data = update(data, delta, reload, variables);
setData(update(data, delta, reload, variables));
if (totalCount !== undefined && data instanceof Array) {
totalCount = data.length;
}
}
}
}
@ -377,7 +387,7 @@ function makeDataProviderInternal<
if (updatedData === data) {
return;
}
data = updatedData;
setData(updatedData);
notifyAll({ delta, isUpdate: true });
}
};