feat: fix positions and margins providers update (#2753)
This commit is contained in:
parent
613262f7a5
commit
98b5260d93
@ -112,7 +112,7 @@ export const SelectMarketPopover = ({
|
||||
} = useMarketList();
|
||||
const variables = useMemo(() => ({ partyId: pubKey }), [pubKey]);
|
||||
const {
|
||||
data: party,
|
||||
data: positions,
|
||||
loading: positionsLoading,
|
||||
reload,
|
||||
} = useDataProvider({
|
||||
@ -132,11 +132,9 @@ export const SelectMarketPopover = ({
|
||||
const markets = useMemo(
|
||||
() =>
|
||||
data?.filter((market) =>
|
||||
party?.positionsConnection?.edges?.find(
|
||||
(edge) => edge.node.market.id === market.id
|
||||
)
|
||||
positions?.find((node) => node.market.id === market.id)
|
||||
),
|
||||
[data, party]
|
||||
[data, positions]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -172,15 +170,13 @@ export const SelectMarketPopover = ({
|
||||
</div>
|
||||
) : (
|
||||
<table className="relative text-sm w-full whitespace-nowrap">
|
||||
{pubKey && (party?.positionsConnection?.edges?.length ?? 0) > 0 ? (
|
||||
{pubKey && (positions?.length ?? 0) > 0 ? (
|
||||
<>
|
||||
<TableTitle>{t('My markets')}</TableTitle>
|
||||
<SelectAllMarketsTableBody
|
||||
inViewRoot={inViewRoot}
|
||||
markets={markets}
|
||||
positions={party?.positionsConnection?.edges
|
||||
?.filter((edge) => edge.node)
|
||||
.map((edge) => edge.node)}
|
||||
positions={positions || undefined}
|
||||
onSelect={onSelectMarket}
|
||||
onCellClick={onCellClick}
|
||||
headers={columnHeadersPositionMarkets}
|
||||
|
@ -96,7 +96,7 @@ const EthTxPendingToastContent = ({ tx }: EthTxToastContentProps) => {
|
||||
return (
|
||||
<div>
|
||||
<h3 className="font-bold">{t('Awaiting confirmation')}</h3>
|
||||
<p>{t('Please wait for your transaction to be confirmed')}</p>
|
||||
<p>{t('Please wait for your transaction to be confirmed.')}</p>
|
||||
<EtherscanLink tx={tx} />
|
||||
<EthTransactionDetails tx={tx} />
|
||||
</div>
|
||||
@ -138,7 +138,7 @@ const EthTxConfirmedToastContent = ({ tx }: EthTxToastContentProps) => {
|
||||
return (
|
||||
<div>
|
||||
<h3 className="font-bold">{t('Transaction confirmed')}</h3>
|
||||
<p>{t('Your transaction has been confirmed')}</p>
|
||||
<p>{t('Your transaction has been confirmed.')}</p>
|
||||
<EtherscanLink tx={tx} />
|
||||
<EthTransactionDetails tx={tx} />
|
||||
</div>
|
||||
@ -153,7 +153,7 @@ const EthTxCompletedToastContent = ({ tx }: EthTxToastContentProps) => {
|
||||
{t('Processing')} {isDeposit && t('deposit')}
|
||||
</h3>
|
||||
<p>
|
||||
{t('Your transaction has been completed.')}
|
||||
{t('Your transaction has been completed.')}{' '}
|
||||
{isDeposit && t('Waiting for deposit confirmation.')}
|
||||
</p>
|
||||
<EtherscanLink tx={tx} />
|
||||
|
@ -1,64 +1,62 @@
|
||||
import produce from 'immer';
|
||||
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
makeDataProvider,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
MarginsSubscriptionDocument,
|
||||
MarginsDocument,
|
||||
} from './__generated__/Positions';
|
||||
import type {
|
||||
MarginsQuery,
|
||||
MarginFieldsFragment,
|
||||
MarginsSubscriptionSubscription,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
const update = (
|
||||
data: MarginsQuery['party'],
|
||||
data: MarginFieldsFragment[],
|
||||
delta: MarginsSubscriptionSubscription['margins']
|
||||
) => {
|
||||
return produce(data, (draft) => {
|
||||
const { marketId } = delta;
|
||||
if (marketId && draft?.marginsConnection?.edges) {
|
||||
const index = draft.marginsConnection.edges.findIndex(
|
||||
(edge) => edge.node.market.id === marketId
|
||||
);
|
||||
if (index !== -1) {
|
||||
const currNode = draft.marginsConnection.edges[index].node;
|
||||
draft.marginsConnection.edges[index].node = {
|
||||
...currNode,
|
||||
maintenanceLevel: delta.maintenanceLevel,
|
||||
searchLevel: delta.searchLevel,
|
||||
initialLevel: delta.initialLevel,
|
||||
collateralReleaseLevel: delta.collateralReleaseLevel,
|
||||
};
|
||||
} else {
|
||||
draft.marginsConnection.edges.unshift({
|
||||
__typename: 'MarginEdge',
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: delta.marketId,
|
||||
},
|
||||
maintenanceLevel: delta.maintenanceLevel,
|
||||
searchLevel: delta.searchLevel,
|
||||
initialLevel: delta.initialLevel,
|
||||
collateralReleaseLevel: delta.collateralReleaseLevel,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: delta.asset,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
const index = draft.findIndex((node) => node.market.id === marketId);
|
||||
if (index !== -1) {
|
||||
const currNode = draft[index];
|
||||
draft[index] = {
|
||||
...currNode,
|
||||
maintenanceLevel: delta.maintenanceLevel,
|
||||
searchLevel: delta.searchLevel,
|
||||
initialLevel: delta.initialLevel,
|
||||
collateralReleaseLevel: delta.collateralReleaseLevel,
|
||||
};
|
||||
} else {
|
||||
draft.unshift({
|
||||
__typename: 'MarginLevels',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: delta.marketId,
|
||||
},
|
||||
maintenanceLevel: delta.maintenanceLevel,
|
||||
searchLevel: delta.searchLevel,
|
||||
initialLevel: delta.initialLevel,
|
||||
collateralReleaseLevel: delta.collateralReleaseLevel,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: delta.asset,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getData = (responseData: MarginsQuery) => responseData.party;
|
||||
const getData = (responseData: MarginsQuery) =>
|
||||
removePaginationWrapper(responseData.party?.marginsConnection?.edges) || [];
|
||||
const getDelta = (subscriptionData: MarginsSubscriptionSubscription) =>
|
||||
subscriptionData.margins;
|
||||
|
||||
export const marginsDataProvider = makeDataProvider<
|
||||
MarginsQuery,
|
||||
MarginsQuery['party'],
|
||||
MarginFieldsFragment[],
|
||||
MarginsSubscriptionSubscription,
|
||||
MarginsSubscriptionSubscription['margins']
|
||||
>({
|
||||
|
@ -1,7 +1,10 @@
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Account } from '@vegaprotocol/accounts';
|
||||
import type { MarketWithData } from '@vegaprotocol/market-list';
|
||||
import type { PositionsQuery, MarginsQuery } from './__generated__/Positions';
|
||||
import type {
|
||||
PositionFieldsFragment,
|
||||
MarginFieldsFragment,
|
||||
} from './__generated__/Positions';
|
||||
import { getMetrics, rejoinPositionData } from './positions-data-providers';
|
||||
|
||||
const accounts = [
|
||||
@ -63,47 +66,32 @@ const accounts = [
|
||||
},
|
||||
] as Account[];
|
||||
|
||||
const positions: PositionsQuery = {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: '02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65',
|
||||
positionsConnection: {
|
||||
__typename: 'PositionConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'PositionEdge',
|
||||
node: {
|
||||
__typename: 'Position',
|
||||
openVolume: '100',
|
||||
averageEntryPrice: '8993727',
|
||||
updatedAt: '2022-07-28T14:53:54.725477Z',
|
||||
realisedPNL: '0',
|
||||
unrealisedPNL: '43804770',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '5e6035fe6a6df78c9ec44b333c231e63d357acef0a0620d2c243f5865d1dc0d8',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'PositionEdge',
|
||||
node: {
|
||||
__typename: 'Position',
|
||||
openVolume: '-100',
|
||||
realisedPNL: '0',
|
||||
unrealisedPNL: '-9112700',
|
||||
averageEntryPrice: '840158',
|
||||
updatedAt: '2022-07-28T15:09:34.441143Z',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10c4b1114d2f6fda239b73d018bca55888b6018f0ac70029972a17fea0a6a56e',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
const positions: PositionFieldsFragment[] = [
|
||||
{
|
||||
__typename: 'Position',
|
||||
openVolume: '100',
|
||||
averageEntryPrice: '8993727',
|
||||
updatedAt: '2022-07-28T14:53:54.725477Z',
|
||||
realisedPNL: '0',
|
||||
unrealisedPNL: '43804770',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '5e6035fe6a6df78c9ec44b333c231e63d357acef0a0620d2c243f5865d1dc0d8',
|
||||
},
|
||||
},
|
||||
};
|
||||
{
|
||||
__typename: 'Position',
|
||||
openVolume: '-100',
|
||||
realisedPNL: '0',
|
||||
unrealisedPNL: '-9112700',
|
||||
averageEntryPrice: '840158',
|
||||
updatedAt: '2022-07-28T15:09:34.441143Z',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10c4b1114d2f6fda239b73d018bca55888b6018f0ac70029972a17fea0a6a56e',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const marketsData = [
|
||||
{
|
||||
@ -162,60 +150,44 @@ const marketsData = [
|
||||
},
|
||||
] as MarketWithData[];
|
||||
|
||||
const margins: MarginsQuery = {
|
||||
party: {
|
||||
id: '02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65',
|
||||
marginsConnection: {
|
||||
edges: [
|
||||
{
|
||||
__typename: 'MarginEdge',
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '5e6035fe6a6df78c9ec44b333c231e63d357acef0a0620d2c243f5865d1dc0d8',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tDAI-id',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'MarginEdge',
|
||||
node: {
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10c4b1114d2f6fda239b73d018bca55888b6018f0ac70029972a17fea0a6a56e',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tDAI-id',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
__typename: 'MarginConnection',
|
||||
const margins: MarginFieldsFragment[] = [
|
||||
{
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '5e6035fe6a6df78c9ec44b333c231e63d357acef0a0620d2c243f5865d1dc0d8',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tDAI-id',
|
||||
},
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
|
||||
{
|
||||
__typename: 'MarginLevels',
|
||||
maintenanceLevel: '0',
|
||||
searchLevel: '0',
|
||||
initialLevel: '0',
|
||||
collateralReleaseLevel: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10c4b1114d2f6fda239b73d018bca55888b6018f0ac70029972a17fea0a6a56e',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'tDAI-id',
|
||||
},
|
||||
},
|
||||
];
|
||||
describe('getMetrics && rejoinPositionData', () => {
|
||||
it('returns positions metrics', () => {
|
||||
const positionsRejoined = rejoinPositionData(
|
||||
positions.party,
|
||||
positions,
|
||||
marketsData,
|
||||
margins.party
|
||||
margins
|
||||
);
|
||||
const metrics = getMetrics(positionsRejoined, accounts || null);
|
||||
expect(metrics.length).toEqual(2);
|
||||
@ -223,9 +195,9 @@ describe('getMetrics && rejoinPositionData', () => {
|
||||
|
||||
it('calculates metrics', () => {
|
||||
const positionsRejoined = rejoinPositionData(
|
||||
positions.party,
|
||||
positions,
|
||||
marketsData,
|
||||
margins.party
|
||||
margins
|
||||
);
|
||||
const metrics = getMetrics(positionsRejoined, accounts || null);
|
||||
|
||||
|
@ -8,14 +8,15 @@ import { toBigNum } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
makeDataProvider,
|
||||
makeDerivedDataProvider,
|
||||
removePaginationWrapper,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { MarketWithData } from '@vegaprotocol/market-list';
|
||||
import { marketsWithDataProvider } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
PositionsQuery,
|
||||
PositionFieldsFragment,
|
||||
PositionsSubscriptionSubscription,
|
||||
MarginsQuery,
|
||||
MarginFieldsFragment,
|
||||
} from './__generated__/Positions';
|
||||
import {
|
||||
@ -170,20 +171,17 @@ export const getMetrics = (
|
||||
};
|
||||
|
||||
export const update = (
|
||||
data: PositionsQuery['party'],
|
||||
data: PositionFieldsFragment[],
|
||||
deltas: PositionsSubscriptionSubscription['positions']
|
||||
) => {
|
||||
return produce(data, (draft) => {
|
||||
deltas.forEach((delta) => {
|
||||
if (!draft?.positionsConnection?.edges || !delta) {
|
||||
return;
|
||||
}
|
||||
const index = draft.positionsConnection.edges.findIndex(
|
||||
(edge) => edge.node.market.id === delta.marketId
|
||||
const index = draft.findIndex(
|
||||
(node) => node.market.id === delta.marketId
|
||||
);
|
||||
if (index !== -1) {
|
||||
const currNode = draft.positionsConnection.edges[index].node;
|
||||
draft.positionsConnection.edges[index].node = {
|
||||
const currNode = draft[index];
|
||||
draft[index] = {
|
||||
...currNode,
|
||||
realisedPNL: delta.realisedPNL,
|
||||
unrealisedPNL: delta.unrealisedPNL,
|
||||
@ -192,15 +190,12 @@ export const update = (
|
||||
updatedAt: delta.updatedAt,
|
||||
};
|
||||
} else {
|
||||
draft.positionsConnection.edges.unshift({
|
||||
__typename: 'PositionEdge',
|
||||
node: {
|
||||
...delta,
|
||||
__typename: 'Position',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: delta.marketId,
|
||||
},
|
||||
draft.unshift({
|
||||
...delta,
|
||||
__typename: 'Position',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: delta.marketId,
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -210,29 +205,29 @@ export const update = (
|
||||
|
||||
export const positionsDataProvider = makeDataProvider<
|
||||
PositionsQuery,
|
||||
PositionsQuery['party'],
|
||||
PositionFieldsFragment[],
|
||||
PositionsSubscriptionSubscription,
|
||||
PositionsSubscriptionSubscription['positions']
|
||||
>({
|
||||
query: PositionsDocument,
|
||||
subscriptionQuery: PositionsSubscriptionDocument,
|
||||
update,
|
||||
getData: (responseData: PositionsQuery) => responseData.party,
|
||||
getData: (responseData: PositionsQuery) =>
|
||||
removePaginationWrapper(responseData.party?.positionsConnection?.edges) ||
|
||||
[],
|
||||
getDelta: (subscriptionData: PositionsSubscriptionSubscription) =>
|
||||
subscriptionData.positions,
|
||||
});
|
||||
|
||||
const upgradeMarginsConnection = (
|
||||
marketId: string,
|
||||
margins: MarginsQuery['party'] | null
|
||||
margins: MarginFieldsFragment[] | null
|
||||
) => {
|
||||
if (marketId && margins?.marginsConnection?.edges) {
|
||||
if (marketId && margins) {
|
||||
const index =
|
||||
margins.marginsConnection.edges.findIndex(
|
||||
(edge) => edge.node.market.id === marketId
|
||||
) ?? -1;
|
||||
margins.findIndex((node) => node.market.id === marketId) ?? -1;
|
||||
if (index >= 0) {
|
||||
const marginLevel = margins.marginsConnection.edges[index].node;
|
||||
const marginLevel = margins[index];
|
||||
return {
|
||||
maintenanceLevel: marginLevel.maintenanceLevel,
|
||||
searchLevel: marginLevel.searchLevel,
|
||||
@ -244,12 +239,12 @@ const upgradeMarginsConnection = (
|
||||
};
|
||||
|
||||
export const rejoinPositionData = (
|
||||
positions: PositionsQuery['party'] | null,
|
||||
positions: PositionFieldsFragment[] | null,
|
||||
marketsData: MarketWithData[] | null,
|
||||
margins: MarginsQuery['party'] | null
|
||||
margins: MarginFieldsFragment[] | null
|
||||
): PositionRejoined[] | null => {
|
||||
if (positions?.positionsConnection?.edges && marketsData && margins) {
|
||||
return positions.positionsConnection.edges.map(({ node }) => {
|
||||
if (positions && marketsData && margins) {
|
||||
return positions.map((node) => {
|
||||
return {
|
||||
realisedPNL: node.realisedPNL,
|
||||
openVolume: node.openVolume,
|
||||
|
@ -2,30 +2,17 @@ import { useCallback, useState } from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { marginsDataProvider } from './margin-data-provider';
|
||||
import type {
|
||||
MarginsQuery,
|
||||
MarginsSubscriptionSubscription,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
const getMarketMarginPosition = ({
|
||||
data,
|
||||
marketId,
|
||||
}: {
|
||||
data: MarginsQuery['party'] | null;
|
||||
marketId: string;
|
||||
}) => {
|
||||
const positions =
|
||||
data?.marginsConnection?.edges?.map((item) => item.node) ?? [];
|
||||
return positions.find((item) => item.market.id === marketId);
|
||||
};
|
||||
import type { MarginFieldsFragment } from './__generated__/Positions';
|
||||
|
||||
export const useMarketMargin = (marketId: string) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [marginLevel, setMarginLevel] = useState<string>('');
|
||||
|
||||
const update = useCallback(
|
||||
({ data }: { data: MarginsQuery['party'] | null }) => {
|
||||
const marginMarketPosition = getMarketMarginPosition({ data, marketId });
|
||||
({ data }: { data: MarginFieldsFragment[] | null }) => {
|
||||
const marginMarketPosition = data?.find(
|
||||
(item) => item.market.id === marketId
|
||||
);
|
||||
if (marginMarketPosition?.maintenanceLevel) {
|
||||
setMarginLevel(marginMarketPosition?.maintenanceLevel || '');
|
||||
}
|
||||
@ -34,10 +21,7 @@ export const useMarketMargin = (marketId: string) => {
|
||||
[setMarginLevel, marketId]
|
||||
);
|
||||
|
||||
useDataProvider<
|
||||
MarginsQuery['party'],
|
||||
MarginsSubscriptionSubscription['margins']
|
||||
>({
|
||||
useDataProvider({
|
||||
dataProvider: marginsDataProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
skip: !pubKey || !marketId,
|
||||
|
@ -3,28 +3,16 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { positionsDataProvider } from './positions-data-providers';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
PositionsQuery,
|
||||
PositionFieldsFragment,
|
||||
PositionsSubscriptionSubscription,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
const getMarketPosition = ({
|
||||
data,
|
||||
marketId,
|
||||
}: {
|
||||
data: PositionsQuery['party'];
|
||||
marketId: string;
|
||||
}) => {
|
||||
const positions =
|
||||
data?.positionsConnection?.edges?.map((item) => item.node) ?? [];
|
||||
return positions.find((item) => item.market.id === marketId);
|
||||
};
|
||||
|
||||
export const useMarketPositionOpenVolume = (marketId: string) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [openVolume, setOpenVolume] = useState<string>('');
|
||||
const update = useCallback(
|
||||
({ data }: { data: PositionsQuery['party'] | undefined }) => {
|
||||
const position = getMarketPosition({ data, marketId });
|
||||
({ data }: { data: PositionFieldsFragment[] | null }) => {
|
||||
const position = data?.find((node) => node.market.id === marketId);
|
||||
if (position?.openVolume) {
|
||||
setOpenVolume(position?.openVolume || '');
|
||||
}
|
||||
@ -34,7 +22,7 @@ export const useMarketPositionOpenVolume = (marketId: string) => {
|
||||
);
|
||||
|
||||
useDataProvider<
|
||||
PositionsQuery['party'],
|
||||
PositionFieldsFragment[],
|
||||
PositionsSubscriptionSubscription['positions']
|
||||
>({
|
||||
dataProvider: positionsDataProvider,
|
||||
|
Loading…
Reference in New Issue
Block a user