chore: fix data and no data message update issues in trading data grids (#2620)
This commit is contained in:
parent
c70ec7676e
commit
1a6266e2ec
@ -33,17 +33,16 @@ const AccountsManager = () => {
|
|||||||
update,
|
update,
|
||||||
variables,
|
variables,
|
||||||
});
|
});
|
||||||
const getRows = async ({
|
const getRows = useCallback(
|
||||||
successCallback,
|
async ({ successCallback, startRow, endRow }: IGetRowsParams) => {
|
||||||
startRow,
|
const rowsThisBlock = dataRef.current
|
||||||
endRow,
|
? dataRef.current.slice(startRow, endRow)
|
||||||
}: IGetRowsParams) => {
|
: [];
|
||||||
const rowsThisBlock = dataRef.current
|
const lastRow = dataRef.current ? dataRef.current.length : 0;
|
||||||
? dataRef.current.slice(startRow, endRow)
|
successCallback(rowsThisBlock, lastRow);
|
||||||
: [];
|
},
|
||||||
const lastRow = dataRef.current ? dataRef.current.length : 0;
|
[]
|
||||||
successCallback(rowsThisBlock, lastRow);
|
);
|
||||||
};
|
|
||||||
const { columnDefs, defaultColDef } = useAccountColumnDefinitions();
|
const { columnDefs, defaultColDef } = useAccountColumnDefinitions();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -13,7 +13,7 @@ import useColumnDefinitions from './use-column-definitions';
|
|||||||
const Positions = () => {
|
const Positions = () => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const { partyId } = useOutletContext<{ partyId: string }>();
|
const { partyId } = useOutletContext<{ partyId: string }>();
|
||||||
const { data, error, loading } = usePositionsData(partyId, gridRef);
|
const { data, error, loading, getRows } = usePositionsData(partyId, gridRef);
|
||||||
const { columnDefs, defaultColDef } = useColumnDefinitions();
|
const { columnDefs, defaultColDef } = useColumnDefinitions();
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer
|
<AsyncRenderer
|
||||||
@ -29,7 +29,8 @@ const Positions = () => {
|
|||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
defaultColDef={defaultColDef}
|
defaultColDef={defaultColDef}
|
||||||
getRowId={getRowId}
|
getRowId={getRowId}
|
||||||
rowData={data || undefined}
|
rowModelType="infinite"
|
||||||
|
datasource={{ getRows }}
|
||||||
components={{ PriceFlashCell }}
|
components={{ PriceFlashCell }}
|
||||||
/>
|
/>
|
||||||
</AsyncRenderer>
|
</AsyncRenderer>
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
t,
|
t,
|
||||||
useDataProvider,
|
useDataProvider,
|
||||||
useNetworkParams,
|
useNetworkParams,
|
||||||
|
updateGridData,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import {
|
import {
|
||||||
@ -22,21 +23,18 @@ import {
|
|||||||
Indicator,
|
Indicator,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
import { Header, HeaderStat } from '../../components/header';
|
import { Header, HeaderStat } from '../../components/header';
|
||||||
|
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
|
import type { IGetRowsParams } from 'ag-grid-community';
|
||||||
|
|
||||||
import type { LiquidityProvisionData } from '@vegaprotocol/liquidity';
|
import type { LiquidityProvisionData } from '@vegaprotocol/liquidity';
|
||||||
import { Link, useParams } from 'react-router-dom';
|
import { Link, useParams } from 'react-router-dom';
|
||||||
import { Links, Routes } from '../../pages/client-router';
|
import { Links, Routes } from '../../pages/client-router';
|
||||||
import type {
|
|
||||||
MarketData,
|
import { useMarket, useStaticMarketData } from '@vegaprotocol/market-list';
|
||||||
MarketDataUpdateFieldsFragment,
|
|
||||||
MarketDealTicket,
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import { marketProvider, marketDataProvider } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
export const Liquidity = () => {
|
export const Liquidity = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@ -44,86 +42,42 @@ export const Liquidity = () => {
|
|||||||
return <LiquidityViewContainer marketId={marketId} />;
|
return <LiquidityViewContainer marketId={marketId} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const useReloadLiquidityData = (marketId: string | undefined) => {
|
||||||
|
const { reload } = useDataProvider({
|
||||||
|
dataProvider: liquidityProvisionsDataProvider,
|
||||||
|
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||||
|
});
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(reload, 10000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [reload]);
|
||||||
|
};
|
||||||
|
|
||||||
export const LiquidityContainer = ({
|
export const LiquidityContainer = ({
|
||||||
marketId,
|
marketId,
|
||||||
}: {
|
}: {
|
||||||
marketId: string | undefined;
|
marketId: string | undefined;
|
||||||
}) => {
|
}) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const [market, setMarket] = useState<MarketDealTicket | null>(null);
|
const market = useMarket(marketId);
|
||||||
const variables = useMemo(
|
|
||||||
() => ({
|
|
||||||
marketId: marketId,
|
|
||||||
}),
|
|
||||||
[marketId]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: marketProvision } = useDataProvider<
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
never
|
|
||||||
>({
|
|
||||||
dataProvider: marketProvider,
|
|
||||||
variables,
|
|
||||||
skip: !marketId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateMarket = useCallback(
|
|
||||||
({ data: marketData }: { data: MarketData | null }) => {
|
|
||||||
if (marketData) {
|
|
||||||
setMarket({
|
|
||||||
...marketProvision,
|
|
||||||
data: marketData,
|
|
||||||
} as MarketDealTicket);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
[marketProvision]
|
|
||||||
);
|
|
||||||
|
|
||||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
|
||||||
dataProvider: marketDataProvider,
|
|
||||||
update: updateMarket,
|
|
||||||
variables,
|
|
||||||
skip: !marketId || !marketProvision,
|
|
||||||
});
|
|
||||||
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
||||||
|
|
||||||
const { reload } = useDataProvider({
|
// To be removed when liquidityProvision subscriptions are working
|
||||||
dataProvider: liquidityProvisionsDataProvider,
|
useReloadLiquidityData(marketId);
|
||||||
variables,
|
|
||||||
});
|
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: LiquidityProvisionData[] | null }) => {
|
({ data }: { data: LiquidityProvisionData[] | null }) => {
|
||||||
if (!gridRef.current?.api) {
|
return updateGridData(dataRef, data, gridRef);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataRef.current?.length) {
|
|
||||||
dataRef.current = data;
|
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
[gridRef]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const { data, loading, error } = useDataProvider({
|
||||||
data: liquidityProviders,
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
} = useDataProvider({
|
|
||||||
dataProvider: lpAggregatedDataProvider,
|
dataProvider: lpAggregatedDataProvider,
|
||||||
update,
|
update,
|
||||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||||
});
|
});
|
||||||
|
|
||||||
// To be removed when liquidityProvision subscriptions are working
|
|
||||||
useEffect(() => {
|
|
||||||
const interval = setInterval(reload, 10000);
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, [reload]);
|
|
||||||
|
|
||||||
const assetDecimalPlaces =
|
const assetDecimalPlaces =
|
||||||
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
|
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
|
||||||
const symbol =
|
const symbol =
|
||||||
@ -133,28 +87,38 @@ export const LiquidityContainer = ({
|
|||||||
NetworkParams.market_liquidity_stakeToCcyVolume,
|
NetworkParams.market_liquidity_stakeToCcyVolume,
|
||||||
]);
|
]);
|
||||||
const stakeToCcyVolume = params.market_liquidity_stakeToCcyVolume;
|
const stakeToCcyVolume = params.market_liquidity_stakeToCcyVolume;
|
||||||
const filteredEdges = useMemo(
|
|
||||||
() =>
|
const getRows = useCallback(
|
||||||
liquidityProviders?.filter((e) =>
|
async ({ successCallback, startRow, endRow }: IGetRowsParams) => {
|
||||||
[
|
const rowsThisBlock = dataRef.current
|
||||||
Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
|
? dataRef.current.slice(startRow, endRow)
|
||||||
Schema.LiquidityProvisionStatus.STATUS_UNDEPLOYED,
|
: [];
|
||||||
Schema.LiquidityProvisionStatus.STATUS_PENDING,
|
const lastRow = dataRef.current ? dataRef.current.length : 0;
|
||||||
].includes(e.status)
|
successCallback(rowsThisBlock, lastRow);
|
||||||
),
|
},
|
||||||
[liquidityProviders]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={filteredEdges}>
|
<div className="h-full relative">
|
||||||
<LiquidityTable
|
<LiquidityTable
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
data={filteredEdges}
|
datasource={{ getRows }}
|
||||||
|
rowModelType="infinite"
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
assetDecimalPlaces={assetDecimalPlaces}
|
assetDecimalPlaces={assetDecimalPlaces}
|
||||||
stakeToCcyVolume={stakeToCcyVolume}
|
stakeToCcyVolume={stakeToCcyVolume}
|
||||||
/>
|
/>
|
||||||
</AsyncRenderer>
|
<div className="pointer-events-none absolute inset-0">
|
||||||
|
<AsyncRenderer
|
||||||
|
loading={loading}
|
||||||
|
error={error}
|
||||||
|
data={data}
|
||||||
|
noDataMessage={t('No liquidity provisions')}
|
||||||
|
noDataCondition={(data) => !data?.length}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,48 +129,13 @@ export const LiquidityViewContainer = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const [market, setMarket] = useState<MarketDealTicket | null>(null);
|
const market = useMarket(marketId);
|
||||||
const variables = useMemo(
|
const marketData = useStaticMarketData(marketId);
|
||||||
() => ({
|
|
||||||
marketId: marketId,
|
|
||||||
}),
|
|
||||||
[marketId]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: marketProvision } = useDataProvider<
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
never
|
|
||||||
>({
|
|
||||||
dataProvider: marketProvider,
|
|
||||||
variables,
|
|
||||||
skip: !marketId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateMarket = useCallback(
|
|
||||||
({ data: marketData }: { data: MarketData | null }) => {
|
|
||||||
if (marketData) {
|
|
||||||
setMarket({
|
|
||||||
...marketProvision,
|
|
||||||
data: marketData,
|
|
||||||
} as MarketDealTicket);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
[marketProvision]
|
|
||||||
);
|
|
||||||
|
|
||||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
|
||||||
dataProvider: marketDataProvider,
|
|
||||||
update: updateMarket,
|
|
||||||
variables,
|
|
||||||
skip: !marketId || !marketProvision,
|
|
||||||
});
|
|
||||||
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
||||||
|
|
||||||
const { reload } = useDataProvider({
|
// To be removed when liquidityProvision subscriptions are working
|
||||||
dataProvider: liquidityProvisionsDataProvider,
|
useReloadLiquidityData(marketId);
|
||||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
|
||||||
});
|
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: LiquidityProvisionData[] | null }) => {
|
({ data }: { data: LiquidityProvisionData[] | null }) => {
|
||||||
@ -233,14 +162,8 @@ export const LiquidityViewContainer = ({
|
|||||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||||
});
|
});
|
||||||
|
|
||||||
// To be removed when liquidityProvision subscriptions are working
|
const targetStake = marketData?.targetStake;
|
||||||
useEffect(() => {
|
const suppliedStake = marketData?.suppliedStake;
|
||||||
const interval = setInterval(reload, 10000);
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, [reload]);
|
|
||||||
|
|
||||||
const targetStake = market?.data?.targetStake;
|
|
||||||
const suppliedStake = market?.data?.suppliedStake;
|
|
||||||
const assetDecimalPlaces =
|
const assetDecimalPlaces =
|
||||||
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
|
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
|
||||||
const symbol =
|
const symbol =
|
||||||
@ -359,7 +282,7 @@ export const LiquidityViewContainer = ({
|
|||||||
{myLpEdges && (
|
{myLpEdges && (
|
||||||
<LiquidityTable
|
<LiquidityTable
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
data={myLpEdges}
|
rowData={myLpEdges}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
stakeToCcyVolume={stakeToCcyVolume}
|
stakeToCcyVolume={stakeToCcyVolume}
|
||||||
assetDecimalPlaces={assetDecimalPlaces}
|
assetDecimalPlaces={assetDecimalPlaces}
|
||||||
@ -370,7 +293,7 @@ export const LiquidityViewContainer = ({
|
|||||||
{activeEdges && (
|
{activeEdges && (
|
||||||
<LiquidityTable
|
<LiquidityTable
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
data={activeEdges}
|
rowData={activeEdges}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
assetDecimalPlaces={assetDecimalPlaces}
|
assetDecimalPlaces={assetDecimalPlaces}
|
||||||
stakeToCcyVolume={stakeToCcyVolume}
|
stakeToCcyVolume={stakeToCcyVolume}
|
||||||
@ -382,7 +305,7 @@ export const LiquidityViewContainer = ({
|
|||||||
{inactiveEdges && (
|
{inactiveEdges && (
|
||||||
<LiquidityTable
|
<LiquidityTable
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
data={inactiveEdges}
|
rowData={inactiveEdges}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
assetDecimalPlaces={assetDecimalPlaces}
|
assetDecimalPlaces={assetDecimalPlaces}
|
||||||
stakeToCcyVolume={stakeToCcyVolume}
|
stakeToCcyVolume={stakeToCcyVolume}
|
||||||
|
@ -9,15 +9,20 @@ export const DepositsContainer = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full grid grid-rows-[1fr,min-content]">
|
<div className="h-full grid grid-rows-[1fr,min-content]">
|
||||||
<div>
|
<div className="h-full relative">
|
||||||
<AsyncRenderer
|
<DepositsTable
|
||||||
data={deposits}
|
rowData={deposits || []}
|
||||||
loading={loading}
|
noRowsOverlayComponent={() => null}
|
||||||
error={error}
|
|
||||||
render={(data) => {
|
|
||||||
return <DepositsTable deposits={data} />;
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0">
|
||||||
|
<AsyncRenderer
|
||||||
|
data={deposits}
|
||||||
|
loading={loading}
|
||||||
|
error={error}
|
||||||
|
noDataCondition={(data) => !(data && data.length)}
|
||||||
|
noDataMessage={t('No deposits')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||||
<Button
|
<Button
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
import {
|
||||||
|
t,
|
||||||
|
useDataProvider,
|
||||||
|
updateGridData,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { useRef, useMemo, useCallback, memo } from 'react';
|
import { useRef, useMemo, useCallback, memo } from 'react';
|
||||||
@ -25,10 +29,7 @@ export const AccountManager = ({
|
|||||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: AccountFields[] | null }) => {
|
({ data }: { data: AccountFields[] | null }) => {
|
||||||
const isEmpty = !dataRef.current?.length;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
dataRef.current = data;
|
|
||||||
gridRef.current?.api?.refreshInfiniteCache();
|
|
||||||
return Boolean((isEmpty && !data?.length) || (!isEmpty && data?.length));
|
|
||||||
},
|
},
|
||||||
[gridRef]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { forwardRef } from 'react';
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
import {
|
import {
|
||||||
t,
|
t,
|
||||||
@ -9,25 +10,27 @@ import {
|
|||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
VegaValueFormatterParams,
|
||||||
|
TypedDataAgGrid,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGridDynamic as AgGrid, Link } from '@vegaprotocol/ui-toolkit';
|
import { AgGridDynamic as AgGrid, Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { DepositFieldsFragment } from './__generated__/Deposit';
|
import type { DepositFieldsFragment } from './__generated__/Deposit';
|
||||||
import { useEnvironment } from '@vegaprotocol/environment';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { DepositStatusMapping } from '@vegaprotocol/types';
|
import { DepositStatusMapping } from '@vegaprotocol/types';
|
||||||
|
|
||||||
export interface DepositsTableProps {
|
export const DepositsTable = forwardRef<
|
||||||
deposits: DepositFieldsFragment[];
|
AgGridReact,
|
||||||
}
|
TypedDataAgGrid<DepositFieldsFragment>
|
||||||
|
>((props, ref) => {
|
||||||
export const DepositsTable = ({ deposits }: DepositsTableProps) => {
|
|
||||||
const { ETHERSCAN_URL } = useEnvironment();
|
const { ETHERSCAN_URL } = useEnvironment();
|
||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
rowData={deposits}
|
ref={ref}
|
||||||
overlayNoRowsTemplate={t('No deposits')}
|
overlayNoRowsTemplate={t('No deposits')}
|
||||||
defaultColDef={{ flex: 1, resizable: true }}
|
defaultColDef={{ flex: 1, resizable: true }}
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
suppressCellFocus={true}
|
suppressCellFocus={true}
|
||||||
|
{...props}
|
||||||
>
|
>
|
||||||
<AgGridColumn headerName="Asset" field="asset.symbol" />
|
<AgGridColumn headerName="Asset" field="asset.symbol" />
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
@ -84,4 +87,4 @@ export const DepositsTable = ({ deposits }: DepositsTableProps) => {
|
|||||||
/>
|
/>
|
||||||
</AgGrid>
|
</AgGrid>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
@ -4,6 +4,7 @@ import { useCallback, useMemo, useRef } from 'react';
|
|||||||
import {
|
import {
|
||||||
makeInfiniteScrollGetRows,
|
makeInfiniteScrollGetRows,
|
||||||
useDataProvider,
|
useDataProvider,
|
||||||
|
updateGridData,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import type { Trade, TradeEdge } from './fills-data-provider';
|
import type { Trade, TradeEdge } from './fills-data-provider';
|
||||||
import { fillsWithMarketProvider } from './fills-data-provider';
|
import { fillsWithMarketProvider } from './fills-data-provider';
|
||||||
@ -53,13 +54,7 @@ export const useFillsList = ({
|
|||||||
).length;
|
).length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
const avoidRerender = !!(
|
|
||||||
(dataRef.current?.length && data?.length) ||
|
|
||||||
(!dataRef.current?.length && !data?.length)
|
|
||||||
);
|
|
||||||
gridRef.current?.api?.refreshInfiniteCache();
|
|
||||||
return avoidRerender;
|
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
return false;
|
return false;
|
||||||
@ -75,11 +70,10 @@ export const useFillsList = ({
|
|||||||
data: (TradeEdge | null)[] | null;
|
data: (TradeEdge | null)[] | null;
|
||||||
totalCount?: number;
|
totalCount?: number;
|
||||||
}) => {
|
}) => {
|
||||||
dataRef.current = data;
|
|
||||||
totalCountRef.current = totalCount;
|
totalCountRef.current = totalCount;
|
||||||
return true;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
},
|
},
|
||||||
[]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
|
||||||
const variables = useMemo(() => ({ partyId, marketId }), [partyId, marketId]);
|
const variables = useMemo(() => ({ partyId, marketId }), [partyId, marketId]);
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
makeDataProvider,
|
makeDataProvider,
|
||||||
makeDerivedDataProvider,
|
makeDerivedDataProvider,
|
||||||
useDataProvider,
|
useDataProvider,
|
||||||
|
updateGridData,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import type * as Schema from '@vegaprotocol/types';
|
import type * as Schema from '@vegaprotocol/types';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
@ -158,12 +159,7 @@ export const useLedgerEntriesDataProvider = ({
|
|||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: (AggregatedLedgerEntriesEdge | null)[] | null }) => {
|
({ data }: { data: (AggregatedLedgerEntriesEdge | null)[] | null }) => {
|
||||||
dataRef.current = data;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
const rerender =
|
|
||||||
(!dataRef.current?.length && data?.length) ||
|
|
||||||
(dataRef.current?.length && !data?.length);
|
|
||||||
gridRef.current?.api?.refreshInfiniteCache();
|
|
||||||
return !rerender;
|
|
||||||
},
|
},
|
||||||
[gridRef]
|
[gridRef]
|
||||||
);
|
);
|
||||||
@ -178,9 +174,9 @@ export const useLedgerEntriesDataProvider = ({
|
|||||||
}) => {
|
}) => {
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
totalCountRef.current = totalCount;
|
totalCountRef.current = totalCount;
|
||||||
return true;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
},
|
},
|
||||||
[]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data, error, loading, load, totalCount } = useDataProvider({
|
const { data, error, loading, load, totalCount } = useDataProvider({
|
||||||
|
@ -22,7 +22,7 @@ export const ledgerEntriesQuery = (
|
|||||||
'eyJ2ZWdhX3RpbWUiOiIyMDIyLTExLTIzVDE3OjI3OjU2LjczNDM2NFoifQ==',
|
'eyJ2ZWdhX3RpbWUiOiIyMDIyLTExLTIzVDE3OjI3OjU2LjczNDM2NFoifQ==',
|
||||||
endCursor:
|
endCursor:
|
||||||
'eyJ2ZWdhX3RpbWUiOiIyMDIyLTExLTIzVDEzOjExOjE2LjU0NjM2M1oifQ==',
|
'eyJ2ZWdhX3RpbWUiOiIyMDIyLTExLTIzVDEzOjExOjE2LjU0NjM2M1oifQ==',
|
||||||
hasNextPage: true,
|
hasNextPage: false,
|
||||||
hasPreviousPage: false,
|
hasPreviousPage: false,
|
||||||
__typename: 'PageInfo',
|
__typename: 'PageInfo',
|
||||||
},
|
},
|
||||||
|
@ -152,10 +152,7 @@ export const liquidityFeeShareDataProvider = makeDataProvider<
|
|||||||
|
|
||||||
export const lpAggregatedDataProvider = makeDerivedDataProvider(
|
export const lpAggregatedDataProvider = makeDerivedDataProvider(
|
||||||
[
|
[
|
||||||
(callback, client, variables) =>
|
liquidityProvisionsDataProvider,
|
||||||
liquidityProvisionsDataProvider(callback, client, {
|
|
||||||
marketId: variables?.marketId,
|
|
||||||
}),
|
|
||||||
marketLiquidityDataProvider,
|
marketLiquidityDataProvider,
|
||||||
liquidityFeeShareDataProvider,
|
liquidityFeeShareDataProvider,
|
||||||
],
|
],
|
||||||
@ -177,32 +174,43 @@ export const getLiquidityProvision = (
|
|||||||
marketLiquidity: MarketLpQuery,
|
marketLiquidity: MarketLpQuery,
|
||||||
liquidityFeeShare: LiquidityProviderFeeShareFieldsFragment[]
|
liquidityFeeShare: LiquidityProviderFeeShareFieldsFragment[]
|
||||||
): LiquidityProvisionData[] => {
|
): LiquidityProvisionData[] => {
|
||||||
return liquidityProvisions.map((lp) => {
|
return liquidityProvisions
|
||||||
const market = marketLiquidity?.market;
|
.map((lp) => {
|
||||||
const feeShare = liquidityFeeShare.find((f) => f.party.id === lp.party.id);
|
const market = marketLiquidity?.market;
|
||||||
if (!feeShare) return lp;
|
const feeShare = liquidityFeeShare.find(
|
||||||
const accounts = compact(lp.party.accountsConnection?.edges).map(
|
(f) => f.party.id === lp.party.id
|
||||||
(e) => e.node
|
);
|
||||||
|
if (!feeShare) return lp;
|
||||||
|
const accounts = compact(lp.party.accountsConnection?.edges).map(
|
||||||
|
(e) => e.node
|
||||||
|
);
|
||||||
|
const bondAccounts = accounts?.filter(
|
||||||
|
(a) => a?.type === Schema.AccountType.ACCOUNT_TYPE_BOND
|
||||||
|
);
|
||||||
|
const balance =
|
||||||
|
bondAccounts
|
||||||
|
?.reduce(
|
||||||
|
(acc, a) => acc.plus(new BigNumber(a.balance ?? 0)),
|
||||||
|
new BigNumber(0)
|
||||||
|
)
|
||||||
|
.toString() || '0';
|
||||||
|
return {
|
||||||
|
...lp,
|
||||||
|
averageEntryValuation: feeShare?.averageEntryValuation,
|
||||||
|
equityLikeShare: feeShare?.equityLikeShare,
|
||||||
|
assetDecimalPlaces:
|
||||||
|
market?.tradableInstrument.instrument.product.settlementAsset
|
||||||
|
.decimals,
|
||||||
|
balance,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter((e) =>
|
||||||
|
[
|
||||||
|
Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
|
||||||
|
Schema.LiquidityProvisionStatus.STATUS_UNDEPLOYED,
|
||||||
|
Schema.LiquidityProvisionStatus.STATUS_PENDING,
|
||||||
|
].includes(e.status)
|
||||||
);
|
);
|
||||||
const bondAccounts = accounts?.filter(
|
|
||||||
(a) => a?.type === Schema.AccountType.ACCOUNT_TYPE_BOND
|
|
||||||
);
|
|
||||||
const balance =
|
|
||||||
bondAccounts
|
|
||||||
?.reduce(
|
|
||||||
(acc, a) => acc.plus(new BigNumber(a.balance ?? 0)),
|
|
||||||
new BigNumber(0)
|
|
||||||
)
|
|
||||||
.toString() || '0';
|
|
||||||
return {
|
|
||||||
...lp,
|
|
||||||
averageEntryValuation: feeShare?.averageEntryValuation,
|
|
||||||
equityLikeShare: feeShare?.equityLikeShare,
|
|
||||||
assetDecimalPlaces:
|
|
||||||
market?.tradableInstrument.instrument.product.settlementAsset.decimals,
|
|
||||||
balance,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface LiquidityProvisionData
|
export interface LiquidityProvisionData
|
||||||
|
@ -22,7 +22,7 @@ describe('LiquidityTable', () => {
|
|||||||
it('should render successfully', async () => {
|
it('should render successfully', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<LiquidityTable data={[]} stakeToCcyVolume={'1'} />
|
<LiquidityTable rowData={[]} stakeToCcyVolume={'1'} />
|
||||||
);
|
);
|
||||||
expect(baseElement).toBeTruthy();
|
expect(baseElement).toBeTruthy();
|
||||||
});
|
});
|
||||||
@ -30,7 +30,9 @@ describe('LiquidityTable', () => {
|
|||||||
|
|
||||||
it('should render correct columns', async () => {
|
it('should render correct columns', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(<LiquidityTable data={singleRowData} stakeToCcyVolume={'0.3'} />);
|
render(
|
||||||
|
<LiquidityTable rowData={singleRowData} stakeToCcyVolume={'0.3'} />
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const headers = await screen.getAllByRole('columnheader');
|
const headers = await screen.getAllByRole('columnheader');
|
||||||
|
@ -5,7 +5,10 @@ import {
|
|||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
t,
|
t,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
import type {
|
||||||
|
VegaValueFormatterParams,
|
||||||
|
TypedDataAgGrid,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import {
|
import {
|
||||||
AgGridDynamic as AgGrid,
|
AgGridDynamic as AgGrid,
|
||||||
TooltipCellComponent,
|
TooltipCellComponent,
|
||||||
@ -30,15 +33,15 @@ const dateValueFormatter = ({ value }: { value?: string | null }) => {
|
|||||||
return getDateTimeFormat().format(new Date(value));
|
return getDateTimeFormat().format(new Date(value));
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface LiquidityTableProps {
|
export interface LiquidityTableProps
|
||||||
data?: LiquidityProvisionData[];
|
extends TypedDataAgGrid<LiquidityProvisionData> {
|
||||||
symbol?: string;
|
symbol?: string;
|
||||||
assetDecimalPlaces?: number;
|
assetDecimalPlaces?: number;
|
||||||
stakeToCcyVolume: string | null;
|
stakeToCcyVolume: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
||||||
({ data, symbol = '', assetDecimalPlaces, stakeToCcyVolume }, ref) => {
|
({ symbol = '', assetDecimalPlaces, stakeToCcyVolume, ...props }, ref) => {
|
||||||
const assetDecimalsFormatter = ({ value }: ValueFormatterParams) => {
|
const assetDecimalsFormatter = ({ value }: ValueFormatterParams) => {
|
||||||
if (!value) return '-';
|
if (!value) return '-';
|
||||||
return `${addDecimalsFormatNumber(value, assetDecimalPlaces ?? 0, 5)}`;
|
return `${addDecimalsFormatNumber(value, assetDecimalPlaces ?? 0, 5)}`;
|
||||||
@ -51,7 +54,6 @@ export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
|||||||
return `${addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0, 5)}`;
|
return `${addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0, 5)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!data) return null;
|
|
||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
@ -66,7 +68,7 @@ export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
|||||||
tooltipComponent: TooltipCellComponent,
|
tooltipComponent: TooltipCellComponent,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
}}
|
}}
|
||||||
rowData={data}
|
{...props}
|
||||||
>
|
>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
headerName={t('Party')}
|
headerName={t('Party')}
|
||||||
|
@ -128,9 +128,10 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
|||||||
const marketDataUpdate = useCallback(
|
const marketDataUpdate = useCallback(
|
||||||
({ data }: { data: MarketData | null }) => {
|
({ data }: { data: MarketData | null }) => {
|
||||||
marketDataRef.current = data;
|
marketDataRef.current = data;
|
||||||
|
updateDepthData();
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[]
|
[updateDepthData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { MarketListTable } from './market-list-table';
|
import { MarketListTable } from './market-list-table';
|
||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
@ -15,7 +16,7 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<div className="h-full relative">
|
||||||
<MarketListTable
|
<MarketListTable
|
||||||
rowData={data}
|
rowData={data}
|
||||||
onRowClicked={(rowEvent: RowClickedEvent) => {
|
onRowClicked={(rowEvent: RowClickedEvent) => {
|
||||||
@ -29,6 +30,14 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
|||||||
onSelect((data as MarketWithData).id);
|
onSelect((data as MarketWithData).id);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</AsyncRenderer>
|
<div className="pointer-events-none absolute inset-0">
|
||||||
|
<AsyncRenderer
|
||||||
|
loading={loading}
|
||||||
|
error={error}
|
||||||
|
data={data}
|
||||||
|
noDataMessage={t('No markets')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@ import type { AgGridReact } from 'ag-grid-react';
|
|||||||
import {
|
import {
|
||||||
makeInfiniteScrollGetRows,
|
makeInfiniteScrollGetRows,
|
||||||
useDataProvider,
|
useDataProvider,
|
||||||
|
updateGridData,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { ordersWithMarketProvider } from '../order-data-provider/order-data-provider';
|
import { ordersWithMarketProvider } from '../order-data-provider/order-data-provider';
|
||||||
import type {
|
import type {
|
||||||
@ -99,13 +100,7 @@ export const useOrderListData = ({
|
|||||||
).length;
|
).length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
totalCountRef.current = totalCount;
|
|
||||||
const rerender =
|
|
||||||
(!dataRef.current?.length && data?.length) ||
|
|
||||||
(dataRef.current?.length && !data?.length);
|
|
||||||
gridRef.current?.api?.refreshInfiniteCache();
|
|
||||||
return !rerender;
|
|
||||||
},
|
},
|
||||||
[gridRef, scrolledToTop]
|
[gridRef, scrolledToTop]
|
||||||
);
|
);
|
||||||
@ -118,11 +113,10 @@ export const useOrderListData = ({
|
|||||||
data: (OrderEdge | null)[] | null;
|
data: (OrderEdge | null)[] | null;
|
||||||
totalCount?: number;
|
totalCount?: number;
|
||||||
}) => {
|
}) => {
|
||||||
dataRef.current = data;
|
|
||||||
totalCountRef.current = totalCount;
|
totalCountRef.current = totalCount;
|
||||||
return true;
|
return updateGridData(dataRef, data, gridRef);
|
||||||
},
|
},
|
||||||
[]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data, error, loading, load, totalCount } = useDataProvider({
|
const { data, error, loading, load, totalCount } = useDataProvider({
|
||||||
|
@ -13,7 +13,7 @@ interface PositionsManagerProps {
|
|||||||
|
|
||||||
export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
|
export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const { data, error, loading } = usePositionsData(partyId, gridRef);
|
const { data, error, loading, getRows } = usePositionsData(partyId, gridRef);
|
||||||
const {
|
const {
|
||||||
submit,
|
submit,
|
||||||
closingOrder,
|
closingOrder,
|
||||||
@ -26,8 +26,9 @@ export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
|
|||||||
return (
|
return (
|
||||||
<div className="h-full relative">
|
<div className="h-full relative">
|
||||||
<PositionsTable
|
<PositionsTable
|
||||||
|
rowModelType="infinite"
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
rowData={data}
|
datasource={{ getRows }}
|
||||||
onClose={(position) => submit(position)}
|
onClose={(position) => submit(position)}
|
||||||
noRowsOverlayComponent={() => null}
|
noRowsOverlayComponent={() => null}
|
||||||
/>
|
/>
|
||||||
|
@ -53,22 +53,13 @@ describe('usePositionData Hook', () => {
|
|||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
const mockApplyTransactions = jest.fn();
|
const mockRefreshInfiniteCache = jest.fn();
|
||||||
const mockApplyTransactionsAsync = jest.fn();
|
|
||||||
const mockGetRowNode = jest
|
const mockGetRowNode = jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockImplementation((id: string) =>
|
.mockImplementation((id: string) =>
|
||||||
mockData.find((position) => position.marketId === id)
|
mockData.find((position) => position.marketId === id)
|
||||||
);
|
);
|
||||||
const partyId = 'partyId';
|
const partyId = 'partyId';
|
||||||
const aNewOne = {
|
|
||||||
marketId: 'market-5',
|
|
||||||
openVolume: '1',
|
|
||||||
};
|
|
||||||
const toRemoveOne = {
|
|
||||||
marketId: 'market-0',
|
|
||||||
openVolume: '0',
|
|
||||||
};
|
|
||||||
const anUpdatedOne = {
|
const anUpdatedOne = {
|
||||||
marketId: 'market-1',
|
marketId: 'market-1',
|
||||||
openVolume: '1',
|
openVolume: '1',
|
||||||
@ -76,8 +67,7 @@ describe('usePositionData Hook', () => {
|
|||||||
const gridRef = {
|
const gridRef = {
|
||||||
current: {
|
current: {
|
||||||
api: {
|
api: {
|
||||||
applyTransaction: mockApplyTransactions,
|
refreshInfiniteCache: mockRefreshInfiniteCache,
|
||||||
applyTransactionAsync: mockApplyTransactionsAsync,
|
|
||||||
getRowNode: mockGetRowNode,
|
getRowNode: mockGetRowNode,
|
||||||
},
|
},
|
||||||
} as unknown as AgGridReact,
|
} as unknown as AgGridReact,
|
||||||
@ -87,27 +77,10 @@ describe('usePositionData Hook', () => {
|
|||||||
const { result } = renderHook(() => usePositionsData(partyId, gridRef), {
|
const { result } = renderHook(() => usePositionsData(partyId, gridRef), {
|
||||||
wrapper: MockedProvider,
|
wrapper: MockedProvider,
|
||||||
});
|
});
|
||||||
expect(result.current.data?.length ?? 0).toEqual(3);
|
expect(result.current.data?.length ?? 0).toEqual(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should append by sync', async () => {
|
it('should call mockRefreshInfiniteCache', async () => {
|
||||||
renderHook(() => usePositionsData(partyId, gridRef), {
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
});
|
|
||||||
|
|
||||||
await waitFor(() => {
|
|
||||||
updateMock({ delta: [aNewOne, toRemoveOne, anUpdatedOne] as Position[] });
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(mockApplyTransactions).toHaveBeenCalledWith({
|
|
||||||
update: [anUpdatedOne],
|
|
||||||
add: [aNewOne],
|
|
||||||
remove: [toRemoveOne],
|
|
||||||
addIndex: 0,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should append by async', async () => {
|
|
||||||
renderHook(() => usePositionsData(partyId, gridRef), {
|
renderHook(() => usePositionsData(partyId, gridRef), {
|
||||||
wrapper: MockedProvider,
|
wrapper: MockedProvider,
|
||||||
});
|
});
|
||||||
@ -115,12 +88,7 @@ describe('usePositionData Hook', () => {
|
|||||||
updateMock({ delta: [anUpdatedOne] as Position[] });
|
updateMock({ delta: [anUpdatedOne] as Position[] });
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(mockApplyTransactionsAsync).toHaveBeenCalledWith({
|
expect(mockRefreshInfiniteCache).toHaveBeenCalledWith();
|
||||||
update: [anUpdatedOne],
|
|
||||||
add: [],
|
|
||||||
remove: [],
|
|
||||||
addIndex: 0,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('no data should return null', () => {
|
it('no data should return null', () => {
|
||||||
|
@ -4,7 +4,8 @@ import type { AgGridReact } from 'ag-grid-react';
|
|||||||
import type { Position } from './positions-data-providers';
|
import type { Position } from './positions-data-providers';
|
||||||
import { positionsMetricsProvider } from './positions-data-providers';
|
import { positionsMetricsProvider } from './positions-data-providers';
|
||||||
import type { PositionsMetricsProviderVariables } from './positions-data-providers';
|
import type { PositionsMetricsProviderVariables } from './positions-data-providers';
|
||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
import { useDataProvider, updateGridData } from '@vegaprotocol/react-helpers';
|
||||||
|
import type { GetRowsParams } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
export const getRowId = ({ data }: { data: Position }) => data.marketId;
|
export const getRowId = ({ data }: { data: Position }) => data.marketId;
|
||||||
|
|
||||||
@ -18,49 +19,8 @@ export const usePositionsData = (
|
|||||||
);
|
);
|
||||||
const dataRef = useRef<Position[] | null>(null);
|
const dataRef = useRef<Position[] | null>(null);
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({
|
({ data }: { data: Position[] | null }) => {
|
||||||
data,
|
return updateGridData(dataRef, data, gridRef);
|
||||||
delta,
|
|
||||||
}: {
|
|
||||||
data: Position[] | null;
|
|
||||||
delta?: Position[] | null;
|
|
||||||
}) => {
|
|
||||||
dataRef.current = data;
|
|
||||||
|
|
||||||
const update: Position[] = [];
|
|
||||||
const add: Position[] = [];
|
|
||||||
const remove: Position[] = [];
|
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
(delta || []).forEach((position) => {
|
|
||||||
const rowNode = gridRef.current?.api.getRowNode(
|
|
||||||
getRowId({ data: position })
|
|
||||||
);
|
|
||||||
if (rowNode) {
|
|
||||||
if (position.openVolume === '0') {
|
|
||||||
remove.push(position);
|
|
||||||
} else {
|
|
||||||
update.push(position);
|
|
||||||
}
|
|
||||||
} else if (position.openVolume !== '0') {
|
|
||||||
add.push(position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (update.length || add.length || remove.length) {
|
|
||||||
const rowDataTransaction = {
|
|
||||||
update,
|
|
||||||
add,
|
|
||||||
remove,
|
|
||||||
addIndex: 0,
|
|
||||||
};
|
|
||||||
if (add.length || remove.length) {
|
|
||||||
gridRef.current.api.applyTransaction(rowDataTransaction);
|
|
||||||
} else {
|
|
||||||
gridRef.current.api.applyTransactionAsync(rowDataTransaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
[gridRef]
|
[gridRef]
|
||||||
);
|
);
|
||||||
@ -69,9 +29,20 @@ export const usePositionsData = (
|
|||||||
update,
|
update,
|
||||||
variables,
|
variables,
|
||||||
});
|
});
|
||||||
|
const getRows = useCallback(
|
||||||
|
async ({ successCallback, startRow, endRow }: GetRowsParams<Position>) => {
|
||||||
|
const rowsThisBlock = dataRef.current
|
||||||
|
? dataRef.current.slice(startRow, endRow)
|
||||||
|
: [];
|
||||||
|
const lastRow = dataRef.current ? dataRef.current.length : 0;
|
||||||
|
successCallback(rowsThisBlock, lastRow);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
data: data?.filter((position) => position.openVolume !== '0'),
|
data,
|
||||||
error,
|
error,
|
||||||
loading,
|
loading,
|
||||||
|
getRows,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@ export * from './lib/get-events';
|
|||||||
export * from './lib/grid';
|
export * from './lib/grid';
|
||||||
export * from './lib/i18n';
|
export * from './lib/i18n';
|
||||||
export * from './lib/pagination';
|
export * from './lib/pagination';
|
||||||
|
export * from './lib/ag-grid-update';
|
||||||
export * from './lib/remove-0x';
|
export * from './lib/remove-0x';
|
||||||
export * from './lib/storage';
|
export * from './lib/storage';
|
||||||
export * from './lib/time';
|
export * from './lib/time';
|
||||||
|
28
libs/react-helpers/src/lib/ag-grid-update.ts
Normal file
28
libs/react-helpers/src/lib/ag-grid-update.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import type { MutableRefObject, RefObject } from 'react';
|
||||||
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
|
import type { IGetRowsParams } from 'ag-grid-community';
|
||||||
|
type AnyArray = Array<any> | null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
export const isXOrWasEmpty = (prev?: AnyArray, curr?: AnyArray) =>
|
||||||
|
Boolean(Number(!!prev?.length) ^ Number(!!curr?.length));
|
||||||
|
|
||||||
|
export const updateGridData = (
|
||||||
|
dataRef: MutableRefObject<AnyArray>,
|
||||||
|
data: AnyArray,
|
||||||
|
gridRef: RefObject<AgGridReact>
|
||||||
|
) => {
|
||||||
|
const rerender = isXOrWasEmpty(dataRef.current, data);
|
||||||
|
dataRef.current = data;
|
||||||
|
gridRef.current?.api?.refreshInfiniteCache();
|
||||||
|
return !rerender;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const makeGetRows =
|
||||||
|
(dataRef: MutableRefObject<AnyArray>) =>
|
||||||
|
() =>
|
||||||
|
async ({ successCallback, startRow, endRow }: IGetRowsParams) => {
|
||||||
|
const rowsThisBlock = dataRef.current
|
||||||
|
? dataRef.current.slice(startRow, endRow)
|
||||||
|
: [];
|
||||||
|
const lastRow = dataRef.current ? dataRef.current.length : 0;
|
||||||
|
successCallback(rowsThisBlock, lastRow);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user