chore: set default fetchPolicy, handle subscription errors like query errors, timeout unsubscribe (#1482)
* chore: set default fetchPolicy, handle subscription errors like query errors,add unsubscribe timeout * chore: improve no data handling in fills, ordes and trades * chore: make reset delay optional, fix pagination and useOrderListData spec
This commit is contained in:
parent
adf6059701
commit
e310f04034
@ -15,19 +15,30 @@ import type {
|
|||||||
TabToNextCellParams,
|
TabToNextCellParams,
|
||||||
CellKeyDownEvent,
|
CellKeyDownEvent,
|
||||||
FullWidthCellKeyDownEvent,
|
FullWidthCellKeyDownEvent,
|
||||||
|
IGetRowsParams,
|
||||||
|
IDatasource,
|
||||||
} from 'ag-grid-community';
|
} from 'ag-grid-community';
|
||||||
import { NO_DATA_MESSAGE } from '../../constants';
|
import { NO_DATA_MESSAGE } from '../../constants';
|
||||||
import * as constants from '../simple-market-list/constants';
|
import * as constants from '../simple-market-list/constants';
|
||||||
|
|
||||||
|
export interface GetRowsParams<T>
|
||||||
|
extends Omit<IGetRowsParams, 'successCallback'> {
|
||||||
|
successCallback(rowsThisBlock: T[], lastRow?: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Datasource<T> extends IDatasource {
|
||||||
|
getRows(params: GetRowsParams<T>): void;
|
||||||
|
}
|
||||||
interface Props<T> extends GridOptions {
|
interface Props<T> extends GridOptions {
|
||||||
data?: T[];
|
rowData?: T[];
|
||||||
|
datasource?: Datasource<T>;
|
||||||
handleRowClicked?: (event: { data: T }) => void;
|
handleRowClicked?: (event: { data: T }) => void;
|
||||||
components?: Record<string, unknown>;
|
components?: Record<string, unknown>;
|
||||||
classNamesParam?: string | string[];
|
classNamesParam?: string | string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConsoleLiteGrid = <T extends { id?: string }>(
|
const ConsoleLiteGrid = <T extends { id?: string }>(
|
||||||
{ data, handleRowClicked, getRowId, classNamesParam, ...props }: Props<T>,
|
{ handleRowClicked, getRowId, classNamesParam, ...props }: Props<T>,
|
||||||
ref?: React.Ref<AgGridReact>
|
ref?: React.Ref<AgGridReact>
|
||||||
) => {
|
) => {
|
||||||
const { isMobile, screenSize } = useScreenDimensions();
|
const { isMobile, screenSize } = useScreenDimensions();
|
||||||
@ -70,7 +81,6 @@ const ConsoleLiteGrid = <T extends { id?: string }>(
|
|||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
className={classNames(classNamesParam)}
|
className={classNames(classNamesParam)}
|
||||||
rowData={data}
|
|
||||||
rowHeight={60}
|
rowHeight={60}
|
||||||
customThemeParams={
|
customThemeParams={
|
||||||
theme === 'dark'
|
theme === 'dark'
|
||||||
|
@ -44,7 +44,7 @@ const AccountsManager = () => {
|
|||||||
noDataMessage={NO_DATA_MESSAGE}
|
noDataMessage={NO_DATA_MESSAGE}
|
||||||
>
|
>
|
||||||
<ConsoleLiteGrid<AccountObj>
|
<ConsoleLiteGrid<AccountObj>
|
||||||
data={data as AccountObj[]}
|
rowData={data as AccountObj[]}
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
defaultColDef={defaultColDef}
|
defaultColDef={defaultColDef}
|
||||||
components={{ PriceCell }}
|
components={{ PriceCell }}
|
||||||
|
@ -56,7 +56,8 @@ const OrdersManager = () => {
|
|||||||
>
|
>
|
||||||
<ConsoleLiteGrid<OrderWithMarket>
|
<ConsoleLiteGrid<OrderWithMarket>
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
rowModelType="infinite"
|
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||||
|
rowData={data?.length ? undefined : []}
|
||||||
datasource={{ getRows }}
|
datasource={{ getRows }}
|
||||||
onBodyScrollEnd={onBodyScrollEnd}
|
onBodyScrollEnd={onBodyScrollEnd}
|
||||||
onBodyScroll={onBodyScroll}
|
onBodyScroll={onBodyScroll}
|
||||||
|
@ -47,7 +47,7 @@ const PositionsAsset = ({ partyId, assetSymbol }: Props) => {
|
|||||||
defaultColDef={defaultColDef}
|
defaultColDef={defaultColDef}
|
||||||
getRowId={getRowId}
|
getRowId={getRowId}
|
||||||
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||||
data={data?.length ? undefined : []}
|
rowData={data?.length ? undefined : []}
|
||||||
datasource={{ getRows }}
|
datasource={{ getRows }}
|
||||||
components={{ PriceFlashCell }}
|
components={{ PriceFlashCell }}
|
||||||
/>
|
/>
|
||||||
|
@ -67,7 +67,7 @@ const SimpleMarketList = () => {
|
|||||||
<ConsoleLiteGrid<MarketWithPercentChange>
|
<ConsoleLiteGrid<MarketWithPercentChange>
|
||||||
classNamesParam="mb-32 min-h-[300px]"
|
classNamesParam="mb-32 min-h-[300px]"
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
data={localData}
|
rowData={localData}
|
||||||
defaultColDef={defaultColDef}
|
defaultColDef={defaultColDef}
|
||||||
handleRowClicked={handleRowClicked}
|
handleRowClicked={handleRowClicked}
|
||||||
/>
|
/>
|
||||||
|
@ -33,8 +33,9 @@ export const FillsManager = ({ partyId }: FillsManagerProps) => {
|
|||||||
<FillsTable
|
<FillsTable
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
partyId={partyId}
|
partyId={partyId}
|
||||||
|
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||||
|
rowData={data?.length ? undefined : []}
|
||||||
datasource={{ getRows }}
|
datasource={{ getRows }}
|
||||||
rowModelType="infinite"
|
|
||||||
onBodyScrollEnd={onBodyScrollEnd}
|
onBodyScrollEnd={onBodyScrollEnd}
|
||||||
onBodyScroll={onBodyScroll}
|
onBodyScroll={onBodyScroll}
|
||||||
/>
|
/>
|
||||||
|
@ -47,6 +47,7 @@ export const useFillsList = ({ partyId, gridRef, scrolledToTop }: Props) => {
|
|||||||
if (!gridRef.current?.api) {
|
if (!gridRef.current?.api) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (dataRef.current?.length) {
|
||||||
if (!scrolledToTop.current) {
|
if (!scrolledToTop.current) {
|
||||||
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
||||||
if (createdAt) {
|
if (createdAt) {
|
||||||
@ -58,6 +59,9 @@ export const useFillsList = ({ partyId, gridRef, scrolledToTop }: Props) => {
|
|||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
dataRef.current = data;
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
[gridRef, scrolledToTop]
|
[gridRef, scrolledToTop]
|
||||||
);
|
);
|
||||||
|
@ -83,6 +83,7 @@ export const marketsProvider = makeDataProvider<
|
|||||||
>({
|
>({
|
||||||
query: MARKET_LIST_QUERY,
|
query: MARKET_LIST_QUERY,
|
||||||
getData,
|
getData,
|
||||||
|
fetchPolicy: 'cache-first',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const activeMarketsProvider = makeDerivedDataProvider<Market[], never>(
|
export const activeMarketsProvider = makeDerivedDataProvider<Market[], never>(
|
||||||
|
@ -34,7 +34,8 @@ export const OrderListManager = ({ partyId }: OrderListManagerProps) => {
|
|||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||||
<OrderList
|
<OrderList
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
rowModelType="infinite"
|
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||||
|
rowData={data?.length ? undefined : []}
|
||||||
datasource={{ getRows }}
|
datasource={{ getRows }}
|
||||||
onBodyScrollEnd={onBodyScrollEnd}
|
onBodyScrollEnd={onBodyScrollEnd}
|
||||||
onBodyScroll={onBodyScroll}
|
onBodyScroll={onBodyScroll}
|
||||||
|
@ -13,7 +13,7 @@ let mockDataProviderData = {
|
|||||||
error: undefined,
|
error: undefined,
|
||||||
loading: true,
|
loading: true,
|
||||||
load: loadMock,
|
load: loadMock,
|
||||||
totalCount: 0,
|
totalCount: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
let updateMock: jest.Mock;
|
let updateMock: jest.Mock;
|
||||||
@ -98,7 +98,7 @@ describe('useOrderListData Hook', () => {
|
|||||||
expect(mockRefreshAgGridApi).toHaveBeenCalled();
|
expect(mockRefreshAgGridApi).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('methods for pagination should works', async () => {
|
it('methods for pagination should work', async () => {
|
||||||
const successCallback = jest.fn();
|
const successCallback = jest.fn();
|
||||||
mockData = [
|
mockData = [
|
||||||
{
|
{
|
||||||
@ -114,12 +114,10 @@ describe('useOrderListData Hook', () => {
|
|||||||
},
|
},
|
||||||
} as unknown as Orders_party_ordersConnection_edges,
|
} as unknown as Orders_party_ordersConnection_edges,
|
||||||
];
|
];
|
||||||
mockDataProviderData = {
|
Object.assign(mockDataProviderData, {
|
||||||
...mockDataProviderData,
|
|
||||||
data: mockData,
|
data: mockData,
|
||||||
loading: false,
|
loading: false,
|
||||||
totalCount: 4,
|
});
|
||||||
};
|
|
||||||
const mockDelta = [
|
const mockDelta = [
|
||||||
{
|
{
|
||||||
node: {
|
node: {
|
||||||
@ -142,8 +140,6 @@ describe('useOrderListData Hook', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
updateMock({ data: mockNextData, delta: mockDelta });
|
|
||||||
|
|
||||||
const getRowsParams = {
|
const getRowsParams = {
|
||||||
successCallback,
|
successCallback,
|
||||||
failCallback: jest.fn(),
|
failCallback: jest.fn(),
|
||||||
@ -152,12 +148,14 @@ describe('useOrderListData Hook', () => {
|
|||||||
} as unknown as IGetRowsParams;
|
} as unknown as IGetRowsParams;
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
await result.current.getRows(getRowsParams);
|
const promise = result.current.getRows(getRowsParams);
|
||||||
|
updateMock({ data: mockNextData, delta: mockDelta });
|
||||||
|
await promise;
|
||||||
});
|
});
|
||||||
expect(loadMock).toHaveBeenCalled();
|
expect(loadMock).toHaveBeenCalled();
|
||||||
expect(successCallback).toHaveBeenLastCalledWith(
|
expect(successCallback).toHaveBeenLastCalledWith(
|
||||||
mockDelta.map((item) => item.node),
|
mockDelta.map((item) => item.node),
|
||||||
4
|
-1
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -50,6 +50,7 @@ export const useOrderListData = ({
|
|||||||
if (!gridRef.current?.api) {
|
if (!gridRef.current?.api) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (dataRef.current?.length) {
|
||||||
if (!scrolledToTop.current) {
|
if (!scrolledToTop.current) {
|
||||||
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
||||||
if (createdAt) {
|
if (createdAt) {
|
||||||
@ -61,6 +62,9 @@ export const useOrderListData = ({
|
|||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
dataRef.current = data;
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
[gridRef, scrolledToTop]
|
[gridRef, scrolledToTop]
|
||||||
);
|
);
|
||||||
|
@ -24,11 +24,7 @@ import type {
|
|||||||
ICellRendererParams,
|
ICellRendererParams,
|
||||||
ValueFormatterParams,
|
ValueFormatterParams,
|
||||||
} from 'ag-grid-community';
|
} from 'ag-grid-community';
|
||||||
import type {
|
import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
|
||||||
AgGridReact,
|
|
||||||
AgGridReactProps,
|
|
||||||
AgReactUiProps,
|
|
||||||
} from 'ag-grid-react';
|
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
import { forwardRef, useState } from 'react';
|
import { forwardRef, useState } from 'react';
|
||||||
import type { Orders_party_ordersConnection_edges_node } from '../';
|
import type { Orders_party_ordersConnection_edges_node } from '../';
|
||||||
@ -40,7 +36,7 @@ import { OrderEditDialog } from './order-edit-dialog';
|
|||||||
import type { OrderWithMarket } from '../';
|
import type { OrderWithMarket } from '../';
|
||||||
import { OrderFeedback } from '../order-feedback';
|
import { OrderFeedback } from '../order-feedback';
|
||||||
|
|
||||||
type OrderListProps = AgGridReactProps | AgReactUiProps;
|
type OrderListProps = AgGridReactProps;
|
||||||
|
|
||||||
export const OrderList = forwardRef<AgGridReact, OrderListProps>(
|
export const OrderList = forwardRef<AgGridReact, OrderListProps>(
|
||||||
(props, ref) => {
|
(props, ref) => {
|
||||||
@ -104,7 +100,7 @@ type OrderListTableValueFormatterParams = Omit<
|
|||||||
data: OrderWithMarket | null;
|
data: OrderWithMarket | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OrderListTableProps = (AgGridReactProps | AgReactUiProps) & {
|
type OrderListTableProps = AgGridReactProps & {
|
||||||
cancel: (order: OrderWithMarket) => void;
|
cancel: (order: OrderWithMarket) => void;
|
||||||
setEditOrder: (order: OrderWithMarket) => void;
|
setEditOrder: (order: OrderWithMarket) => void;
|
||||||
};
|
};
|
||||||
|
@ -559,15 +559,15 @@ describe('derived data provider', () => {
|
|||||||
expect(callback.mock.calls[0][0].error).toBe(error);
|
expect(callback.mock.calls[0][0].error).toBe(error);
|
||||||
expect(callback.mock.calls[0][0].loading).toBe(false);
|
expect(callback.mock.calls[0][0].loading).toBe(false);
|
||||||
subscription.reload();
|
subscription.reload();
|
||||||
expect(callback.mock.calls.length).toBe(3);
|
expect(callback.mock.calls.length).toBe(2);
|
||||||
expect(callback.mock.calls[2][0].loading).toBe(true);
|
expect(callback.mock.calls[1][0].loading).toBe(true);
|
||||||
await resolveQuery({ data: part1 });
|
await resolveQuery({ data: part1 });
|
||||||
expect(callback.mock.calls.length).toBe(3);
|
expect(callback.mock.calls.length).toBe(2);
|
||||||
await resolveQuery({ data: part2 });
|
await resolveQuery({ data: part2 });
|
||||||
expect(callback.mock.calls.length).toBe(4);
|
expect(callback.mock.calls.length).toBe(3);
|
||||||
expect(callback.mock.calls[3][0].data).toStrictEqual(data);
|
expect(callback.mock.calls[2][0].data).toStrictEqual(data);
|
||||||
expect(callback.mock.calls[3][0].loading).toBe(false);
|
expect(callback.mock.calls[2][0].loading).toBe(false);
|
||||||
expect(callback.mock.calls[3][0].error).toBeUndefined();
|
expect(callback.mock.calls[2][0].error).toBeUndefined();
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -76,7 +76,7 @@ export interface Append<Data> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface GetData<QueryData, Data> {
|
interface GetData<QueryData, Data> {
|
||||||
(queryData: QueryData): Data | null;
|
(queryData: QueryData, variables?: OperationVariables): Data | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetPageInfo<QueryData> {
|
interface GetPageInfo<QueryData> {
|
||||||
@ -88,7 +88,7 @@ interface GetTotalCount<QueryData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface GetDelta<SubscriptionData, Delta> {
|
interface GetDelta<SubscriptionData, Delta> {
|
||||||
(subscriptionData: SubscriptionData): Delta;
|
(subscriptionData: SubscriptionData, variables?: OperationVariables): Delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defaultAppend<Data>(
|
export function defaultAppend<Data>(
|
||||||
@ -144,6 +144,7 @@ interface DataProviderParams<QueryData, Data, SubscriptionData, Delta> {
|
|||||||
first: number;
|
first: number;
|
||||||
};
|
};
|
||||||
fetchPolicy?: FetchPolicy;
|
fetchPolicy?: FetchPolicy;
|
||||||
|
resetDelay?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,6 +163,7 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
getDelta,
|
getDelta,
|
||||||
pagination,
|
pagination,
|
||||||
fetchPolicy,
|
fetchPolicy,
|
||||||
|
resetDelay,
|
||||||
}: DataProviderParams<QueryData, Data, SubscriptionData, Delta>): Subscribe<
|
}: DataProviderParams<QueryData, Data, SubscriptionData, Delta>): Subscribe<
|
||||||
Data,
|
Data,
|
||||||
Delta
|
Delta
|
||||||
@ -171,6 +173,7 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
// subscription is started before initial query, all deltas that will arrive before initial query response are put on queue
|
// subscription is started before initial query, all deltas that will arrive before initial query response are put on queue
|
||||||
const updateQueue: Delta[] = [];
|
const updateQueue: Delta[] = [];
|
||||||
|
|
||||||
|
let resetTimer: ReturnType<typeof setTimeout>;
|
||||||
let variables: OperationVariables | undefined;
|
let variables: OperationVariables | undefined;
|
||||||
let data: Data | null = null;
|
let data: Data | null = null;
|
||||||
let error: Error | undefined;
|
let error: Error | undefined;
|
||||||
@ -242,7 +245,7 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
},
|
},
|
||||||
fetchPolicy: fetchPolicy || 'no-cache',
|
fetchPolicy: fetchPolicy || 'no-cache',
|
||||||
});
|
});
|
||||||
const insertionData = getData(res.data);
|
const insertionData = getData(res.data, variables);
|
||||||
const insertionPageInfo = pagination.getPageInfo(res.data);
|
const insertionPageInfo = pagination.getPageInfo(res.data);
|
||||||
({ data, totalCount } = pagination.append(
|
({ data, totalCount } = pagination.append(
|
||||||
data,
|
data,
|
||||||
@ -269,10 +272,10 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
variables: pagination
|
variables: pagination
|
||||||
? { ...variables, pagination: { first: pagination.first } }
|
? { ...variables, pagination: { first: pagination.first } }
|
||||||
: variables,
|
: variables,
|
||||||
fetchPolicy,
|
fetchPolicy: fetchPolicy || 'no-cache',
|
||||||
errorPolicy: 'ignore',
|
errorPolicy: 'ignore',
|
||||||
});
|
});
|
||||||
data = getData(res.data);
|
data = getData(res.data, variables);
|
||||||
if (data && pagination) {
|
if (data && pagination) {
|
||||||
if (!(data instanceof Array)) {
|
if (!(data instanceof Array)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -332,6 +335,9 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
|
|
||||||
const initialize = async () => {
|
const initialize = async () => {
|
||||||
if (subscription) {
|
if (subscription) {
|
||||||
|
if (resetTimer) {
|
||||||
|
clearTimeout(resetTimer);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading = true;
|
loading = true;
|
||||||
@ -352,7 +358,7 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
if (!subscriptionData) {
|
if (!subscriptionData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const delta = getDelta(subscriptionData);
|
const delta = getDelta(subscriptionData, variables);
|
||||||
if (loading || !data) {
|
if (loading || !data) {
|
||||||
updateQueue.push(delta);
|
updateQueue.push(delta);
|
||||||
} else {
|
} else {
|
||||||
@ -364,17 +370,25 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
notifyAll({ delta, isUpdate: true });
|
notifyAll({ delta, isUpdate: true });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => reload()
|
(e) => {
|
||||||
|
error = e as Error;
|
||||||
|
if (subscription) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
subscription = undefined;
|
||||||
|
}
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await initialFetch();
|
await initialFetch();
|
||||||
};
|
};
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
if (subscription) {
|
if (!subscription) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
subscription = undefined;
|
subscription = undefined;
|
||||||
}
|
|
||||||
data = null;
|
data = null;
|
||||||
error = undefined;
|
error = undefined;
|
||||||
loading = false;
|
loading = false;
|
||||||
@ -386,8 +400,12 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
const unsubscribe = (callback: UpdateCallback<Data, Delta>) => {
|
const unsubscribe = (callback: UpdateCallback<Data, Delta>) => {
|
||||||
callbacks.splice(callbacks.indexOf(callback), 1);
|
callbacks.splice(callbacks.indexOf(callback), 1);
|
||||||
if (callbacks.length === 0) {
|
if (callbacks.length === 0) {
|
||||||
|
if (resetDelay) {
|
||||||
|
resetTimer = setTimeout(reset, resetDelay);
|
||||||
|
} else {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (callback, c, v) => {
|
return (callback, c, v) => {
|
||||||
|
@ -37,15 +37,22 @@ export const makeInfiniteScrollGetRows =
|
|||||||
startRow += newRows.current;
|
startRow += newRows.current;
|
||||||
endRow += newRows.current;
|
endRow += newRows.current;
|
||||||
try {
|
try {
|
||||||
if (data.current && data.current.indexOf(null) < endRow) {
|
if (data.current) {
|
||||||
|
const firstMissingRowIndex = data.current.indexOf(null);
|
||||||
|
if (
|
||||||
|
endRow > data.current.length ||
|
||||||
|
(firstMissingRowIndex !== -1 && firstMissingRowIndex < endRow)
|
||||||
|
) {
|
||||||
await load();
|
await load();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const rowsThisBlock = data.current
|
const rowsThisBlock = data.current
|
||||||
? data.current.slice(startRow, endRow).map((edge) => edge?.node)
|
? data.current.slice(startRow, endRow).map((edge) => edge?.node)
|
||||||
: [];
|
: [];
|
||||||
successCallback(
|
successCallback(
|
||||||
rowsThisBlock,
|
rowsThisBlock,
|
||||||
getLastRow(startRow, endRow, rowsThisBlock.length, totalCount.current)
|
getLastRow(startRow, endRow, rowsThisBlock.length, totalCount.current) -
|
||||||
|
newRows.current
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
failCallback();
|
failCallback();
|
||||||
|
@ -55,6 +55,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
if (!gridRef.current?.api) {
|
if (!gridRef.current?.api) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (dataRef.current?.length) {
|
||||||
if (!scrolledToTop.current) {
|
if (!scrolledToTop.current) {
|
||||||
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
||||||
if (createdAt) {
|
if (createdAt) {
|
||||||
@ -66,6 +67,9 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
dataRef.current = data;
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
@ -115,7 +119,8 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||||
<TradesTable
|
<TradesTable
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
rowModelType="infinite"
|
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||||
|
rowData={data?.length ? undefined : []}
|
||||||
datasource={{ getRows }}
|
datasource={{ getRows }}
|
||||||
onBodyScrollEnd={onBodyScrollEnd}
|
onBodyScrollEnd={onBodyScrollEnd}
|
||||||
onBodyScroll={onBodyScroll}
|
onBodyScroll={onBodyScroll}
|
||||||
|
Loading…
Reference in New Issue
Block a user