Compare commits

...
26 changed files with 466 additions and 435 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
# App configuration variables
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/validator-testnet-network.json
NX_VEGA_URL=https://api.validators-testnet.vega.xyz/graphql
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_REST=https://api.validators-testnet.vega.xyz/
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+1 -1
View File
@@ -1,7 +1,7 @@
# App configuration variables
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/validator-testnet-network.json
NX_VEGA_URL=https://api.validators-testnet.vega.xyz/graphql
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_REST=https://api.validators-testnet.vega.xyz/
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
+1 -1
View File
@@ -1,5 +1,5 @@
# App configuration variables
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/validator-testnet-network.json
NX_VEGA_URL=https://api.validators-testnet.vega.xyz/graphql
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
NX_VEGA_ENV=VALIDATOR_TESTNET
+34 -23
View File
@@ -115,7 +115,7 @@
"tranche_end": "2023-04-06T00:00:00.000Z",
"total_added": "14099",
"total_removed": "14.85013776876",
"locked_amount": "10685.5091338112313906",
"locked_amount": "10572.0443992682198041",
"deposits": [
{
"amount": "30",
@@ -2785,7 +2785,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "86666.297",
"total_removed": "0",
"locked_amount": "63276.9937544835025669221",
"locked_amount": "63217.7569447474992091818",
"deposits": [
{
"amount": "86666.297",
@@ -2851,7 +2851,7 @@
"tranche_end": "2023-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "1091.95919820919835",
"locked_amount": "1088.532286579161625",
"deposits": [
{
"amount": "2500",
@@ -2972,7 +2972,7 @@
"tranche_end": "2023-09-01T00:00:00.000Z",
"total_added": "17500",
"total_removed": "0",
"locked_amount": "16310.630535426731",
"locked_amount": "16286.90289729267275",
"deposits": [
{
"amount": "12500",
@@ -3239,7 +3239,7 @@
"tranche_end": "2023-08-01T00:00:00.000Z",
"total_added": "37500",
"total_removed": "3917.838301575",
"locked_amount": "29108.00337630448125",
"locked_amount": "29056.3157036525475",
"deposits": [
{
"amount": "7500",
@@ -3471,7 +3471,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "63219.261459499182035985",
"locked_amount": "63160.078695898600610145",
"deposits": [
{
"amount": "129999.45",
@@ -3537,7 +3537,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "62600",
"total_removed": "0",
"locked_amount": "29755.51730086250692",
"locked_amount": "29712.729915017758416",
"deposits": [
{
"amount": "10000",
@@ -3730,7 +3730,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "2568.4195839675295",
"locked_amount": "2565.002061136479",
"deposits": [
{
"amount": "5000",
@@ -3941,7 +3941,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "97499.58",
"total_removed": "0",
"locked_amount": "5234.40797409175783885812",
"locked_amount": "5176.3551961233756127824",
"deposits": [
{
"amount": "97499.58",
@@ -3974,7 +3974,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "135173.4239508",
"total_removed": "98230.390980249184455396",
"locked_amount": "7154.532017746247582517782244",
"locked_amount": "7075.183892657481220515043488",
"deposits": [
{
"amount": "135173.4239508",
@@ -4020,7 +4020,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "32499.86",
"total_removed": "0",
"locked_amount": "2202.0250413096837576838",
"locked_amount": "2177.6032401362389906198",
"deposits": [
{
"amount": "32499.86",
@@ -4053,7 +4053,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "10833.29",
"total_removed": "0",
"locked_amount": "716.7377830010889285782",
"locked_amount": "708.7887237026820743298",
"deposits": [
{
"amount": "10833.29",
@@ -4086,7 +4086,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "22749.93",
"total_removed": "4720.860935375",
"locked_amount": "2679.3259133507851557384",
"locked_amount": "2649.6105543030109460985",
"deposits": [
{
"amount": "6500",
@@ -4238,7 +4238,7 @@
"tranche_end": "2023-05-01T00:00:00.000Z",
"total_added": "22500",
"total_removed": "5454.874059975",
"locked_amount": "6028.33793738489775",
"locked_amount": "5997.32533379373885",
"deposits": [
{
"amount": "7500",
@@ -4590,7 +4590,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "928642.9598472029154",
"locked_amount": "427818.6752222121424301876",
"locked_amount": "426492.725316361541598982",
"deposits": [
{
"amount": "1852091.69",
@@ -37451,7 +37451,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "700133.348465855088393",
"locked_amount": "681909.677903332474316682416",
"locked_amount": "679872.154544765551049991856",
"deposits": [
{
"amount": "1998.95815",
@@ -38833,7 +38833,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "802077.86972775802842952",
"locked_amount": "7717695.5207000420736488540244418786672073",
"locked_amount": "7710470.5936920688435643959749179847134361",
"deposits": [
{
"amount": "16249.93",
@@ -44938,7 +44938,7 @@
"tranche_end": "2023-05-05T00:00:00.000Z",
"total_added": "14597706.0446472999",
"total_removed": "5735243.926636882158318256",
"locked_amount": "1403482.000468801822914427744559301",
"locked_amount": "1396811.993986633827992401112365458",
"deposits": [
{
"amount": "129284.449",
@@ -52270,8 +52270,8 @@
"tranche_start": "2021-10-05T00:00:00.000Z",
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "5778205.3912159303",
"total_removed": "3353757.81738108986999524",
"locked_amount": "237620.823033512756318438877054666",
"total_removed": "3362269.76579626473241024",
"locked_amount": "234985.4631325448680055538651694685",
"deposits": [
{
"amount": "552496.6455",
@@ -52415,6 +52415,11 @@
}
],
"withdrawals": [
{
"amount": "8511.948415174862415",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
"tx": "0x057f4b016d6e8290e501d33060430ce96dd10cfda20e7fd672e058478e069c75"
},
{
"amount": "7754.747191950749679",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
@@ -54008,6 +54013,12 @@
}
],
"withdrawals": [
{
"amount": "8511.948415174862415",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
"tranche_id": 4,
"tx": "0x057f4b016d6e8290e501d33060430ce96dd10cfda20e7fd672e058478e069c75"
},
{
"amount": "7754.747191950749679",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
@@ -54262,8 +54273,8 @@
}
],
"total_tokens": "331498.5873",
"withdrawn_tokens": "309454.479755372490072",
"remaining_tokens": "22044.107544627509928"
"withdrawn_tokens": "317966.428170547352487",
"remaining_tokens": "13532.159129452647513"
},
{
"address": "0x16da609341ed67750A8BCC5AAa2005471006Cd77",
@@ -54366,7 +54377,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "36243.9702435650685",
"locked_amount": "108052.486425682305060663422323692",
"locked_amount": "107729.6292025373402867528488077",
"deposits": [
{
"amount": "3000",
@@ -1,3 +1,6 @@
{
"hosts": ["https://api.validators-testnet.vega.xyz/graphql"]
"hosts": [
"https://api-validators-testnet.vega.rocks/graphql",
"https://vega-testnet.anyvalid.com/query"
]
}
@@ -131,7 +131,6 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
cy.get('p.col-span-1').contains('Within 43,200 seconds');
validateMarketDataRow(0, 'Highest Price', '7.97323 ');
validateMarketDataRow(1, 'Lowest Price', '6.54701 ');
validateMarketDataRow(2, 'Reference Price', '7.22625 ');
});
it('liquidity monitoring parameters displayed', () => {
@@ -22,24 +22,25 @@ describe('accounts', { tags: '@smoke' }, () => {
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="breakdown"] [data-testid="breakdown"]')
.should('have.text', 'Breakdown');
.find('[col-id="accounts-actions"]')
.should('have.text', 'DepositWithdraw');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="breakdown"] [data-testid="deposit"]')
.find('[data-testid="deposit"]')
.should('have.text', 'Deposit');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="breakdown"] [data-testid="withdraw"]')
.find('[col-id="accounts-actions"] [data-testid="withdraw"]')
.should('have.text', 'Withdraw');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="deposited"]')
.find('[col-id="total"]')
.should('have.text', '100,001.01');
});
describe('sorting by ag-grid columns should work well', () => {
it('sorting by asset', () => {
cy.getByTestId('Collateral').click();
@@ -78,7 +79,7 @@ describe('accounts', { tags: '@smoke' }, () => {
'1,000.00',
];
checkSorting(
'deposited',
'total',
marketsSortedDefault,
marketsSortedAsc,
marketsSortedDesc
@@ -87,9 +88,27 @@ describe('accounts', { tags: '@smoke' }, () => {
it('sorting by used', () => {
cy.getByTestId('Collateral').click();
const marketsSortedDefault = ['0.00', '1.01', '0.01', '0.00', '0.00'];
const marketsSortedAsc = ['0.00', '0.00', '0.00', '0.01', '1.01'];
const marketsSortedDesc = ['1.01', '0.01', '0.00', '0.00', '0.00'];
const marketsSortedDefault = [
'0.000.00%',
'1.010.00%',
'0.010.00%',
'0.000.00%',
'0.000.00%',
];
const marketsSortedAsc = [
'0.000.00%',
'0.000.00%',
'0.000.00%',
'0.010.00%',
'1.010.00%',
];
const marketsSortedDesc = [
'1.010.00%',
'0.010.00%',
'0.000.00%',
'0.000.00%',
'0.000.00%',
];
checkSorting(
'used',
marketsSortedDefault,
@@ -98,32 +117,32 @@ describe('accounts', { tags: '@smoke' }, () => {
);
});
it('sorting by available', () => {
it('sorting by total', () => {
cy.getByTestId('Collateral').click();
const marketsSortedDefault = [
'1,000.00002',
'100,000.00',
'1,000.00',
'100,001.01',
'1,000.01',
'1,000.00',
'1,000.00001',
];
const marketsSortedAsc = [
'1,000.00',
'1,000.00',
'1,000.00001',
'1,000.00002',
'100,000.00',
'1,000.01',
'100,001.01',
];
const marketsSortedDesc = [
'100,000.00',
'100,001.01',
'1,000.01',
'1,000.00002',
'1,000.00001',
'1,000.00',
'1,000.00',
];
checkSorting(
'available',
'total',
marketsSortedDefault,
marketsSortedAsc,
marketsSortedDesc
@@ -50,7 +50,6 @@ describe('positions', { tags: '@smoke' }, () => {
const emptyCells = [
'notional',
'markPrice',
'liquidationPrice',
'currentLeverage',
'averageEntryPrice',
];
@@ -162,8 +161,6 @@ describe('positions', { tags: '@smoke' }, () => {
cy.wrap($prices).invoke('text').should('not.be.empty');
});
cy.get('[col-id="liquidationPrice"]').should('contain.text', '0'); // liquidation price
cy.get('[col-id="currentLeverage"]').should('contain.text', '2.846.1');
cy.get('[col-id="marginAccountBalance"]') // margin allocated
@@ -523,6 +523,16 @@ const VegaTxCompleteToastsContent = ({ tx }: VegaTxToastContentProps) => {
<div>
<h3 className="font-bold">{t('Transfer complete')}</h3>
<p>{t('Your transaction has been confirmed ')}</p>
{tx.txHash && (
<p className="break-all">
<ExternalLink
href={explorerLink(EXPLORER_TX.replace(':hash', tx.txHash))}
rel="noreferrer"
>
{t('View in block explorer')}
</ExternalLink>
</p>
)}
<VegaTransactionDetails tx={tx} />
</div>
);
+1 -1
View File
@@ -83,8 +83,8 @@ function AppBody({ Component }: AppProps) {
</Head>
<Title />
<div className={gridClasses}>
<Navbar theme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'system'} />
<Banner />
<Navbar theme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'system'} />
<ViewingBanner />
<main data-testid={location.pathname}>
<Component />
@@ -159,38 +159,50 @@ const accountResult = [
{
asset: {
__typename: 'Asset',
decimals: 5,
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
decimals: 5,
},
available: '4000000000000001006031',
balance: '4000000000000001006031',
breakdown: [],
deposited: '4000000000000001006031',
type: AccountType.ACCOUNT_TYPE_GENERAL,
type: 'ACCOUNT_TYPE_GENERAL',
available: '4000000000000001006031',
used: '0',
total: '4000000000000001006031',
breakdown: [
{
__typename: 'AccountBalance',
type: 'ACCOUNT_TYPE_GENERAL',
balance: '4000000000000001006031',
market: null,
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
decimals: 5,
},
total: '4000000000000001006031',
available: '4000000000000001006031',
used: '4000000000000001006031',
},
],
},
{
asset: {
__typename: 'Asset',
decimals: 5,
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
decimals: 5,
},
available: '5000593078',
balance: '5000593078',
type: 'ACCOUNT_TYPE_GENERAL',
available: '5000593078',
used: '406922',
total: '5001000000',
breakdown: [
{
__typename: 'AccountBalance',
asset: {
__typename: 'Asset',
decimals: 5,
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
},
available: '5000593078',
type: 'ACCOUNT_TYPE_MARGIN',
balance: '406922',
deposited: '5001000000',
market: {
__typename: 'Market',
id: '9c1ee71959e566c484fcea796513137f8a02219cca2e973b7ae72dc29d099581',
@@ -202,35 +214,50 @@ const accountResult = [
},
},
},
type: AccountType.ACCOUNT_TYPE_MARGIN,
asset: {
__typename: 'Asset',
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
decimals: 5,
},
total: '5001000000',
available: '5000593078',
used: '406922',
},
{
__typename: 'AccountBalance',
type: 'ACCOUNT_TYPE_GENERAL',
balance: '5000593078',
market: null,
asset: {
__typename: 'Asset',
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
decimals: 5,
},
total: '5001000000',
available: '5000593078',
used: '5000593078',
},
],
deposited: '5001000000',
type: AccountType.ACCOUNT_TYPE_GENERAL,
used: '406922',
},
{
asset: {
__typename: 'Asset',
decimals: 5,
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
decimals: 5,
},
available: '2996218603',
balance: '2996218603',
type: 'ACCOUNT_TYPE_GENERAL',
available: '2996218603',
used: '2781397',
total: '2999000000',
breakdown: [
{
__typename: 'AccountBalance',
asset: {
__typename: 'Asset',
decimals: 5,
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
},
available: '2996218603',
type: 'ACCOUNT_TYPE_MARGIN',
balance: '2781397',
deposited: '2999000000',
market: {
__typename: 'Market',
id: 'd90fd7c746286625504d7a3f5f420a280875acd3cd611676d9e70acc675f4540',
@@ -242,40 +269,91 @@ const accountResult = [
},
},
},
type: AccountType.ACCOUNT_TYPE_MARGIN,
asset: {
__typename: 'Asset',
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
decimals: 5,
},
total: '2999000000',
available: '2996218603',
used: '2781397',
},
{
__typename: 'AccountBalance',
type: 'ACCOUNT_TYPE_GENERAL',
balance: '2996218603',
market: null,
asset: {
__typename: 'Asset',
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
decimals: 5,
},
total: '2999000000',
available: '2996218603',
used: '2996218603',
},
],
deposited: '2999000000',
type: AccountType.ACCOUNT_TYPE_GENERAL,
used: '2781397',
},
{
asset: {
__typename: 'Asset',
decimals: 5,
id: '993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede',
symbol: 'tUSDC',
decimals: 5,
},
available: '1990351587',
balance: '1990351587',
breakdown: [],
deposited: '1990351587',
type: AccountType.ACCOUNT_TYPE_GENERAL,
type: 'ACCOUNT_TYPE_GENERAL',
available: '1990351587',
used: '0',
total: '1990351587',
breakdown: [
{
__typename: 'AccountBalance',
type: 'ACCOUNT_TYPE_GENERAL',
balance: '1990351587',
market: null,
asset: {
__typename: 'Asset',
id: '993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede',
symbol: 'tUSDC',
decimals: 5,
},
total: '1990351587',
available: '1990351587',
used: '1990351587',
},
],
},
{
asset: {
__typename: 'Asset',
decimals: 5,
id: 'XYZalpha',
symbol: 'XYZalpha',
decimals: 5,
},
available: '10001000000',
balance: '10001000000',
breakdown: [],
deposited: '10001000000',
type: AccountType.ACCOUNT_TYPE_GENERAL,
type: 'ACCOUNT_TYPE_GENERAL',
available: '10001000000',
used: '0',
total: '10001000000',
breakdown: [
{
__typename: 'AccountBalance',
type: 'ACCOUNT_TYPE_GENERAL',
balance: '10001000000',
market: null,
asset: {
__typename: 'Asset',
id: 'XYZalpha',
symbol: 'XYZalpha',
decimals: 5,
},
total: '10001000000',
available: '10001000000',
used: '10001000000',
},
],
},
] as AccountFields[];
@@ -99,7 +99,7 @@ export const accountsOnlyDataProvider = makeDataProvider<
export interface AccountFields extends Account {
available: string;
used: string;
deposited: string;
total: string;
balance: string;
breakdown?: AccountFields[];
}
@@ -145,15 +145,17 @@ const getAssetAccountAggregation = (
type: AccountType.ACCOUNT_TYPE_GENERAL,
available: available.toString(),
used: used.toString(),
deposited: (available + used).toString(),
total: (available + used).toString(),
};
const breakdown = accounts
.filter((a) => USE_ACCOUNT_TYPES.includes(a.type))
.filter((a) =>
[...USE_ACCOUNT_TYPES, AccountType.ACCOUNT_TYPE_GENERAL].includes(a.type)
)
.map((a) => ({
...a,
asset: accounts[0].asset,
deposited: balanceAccount.deposited,
total: balanceAccount.total,
available: balanceAccount.available,
used: a.balance,
}))
+7 -13
View File
@@ -27,7 +27,7 @@ const singleRow = {
},
available: '125600000',
used: '125600000',
deposited: '125600000',
total: '251200000',
} as AccountFields;
const singleRowData = [singleRow];
@@ -42,7 +42,7 @@ describe('AccountsTable', () => {
/>
);
});
const expectedHeaders = ['Asset', 'Total', 'Used', 'Available', ''];
const expectedHeaders = ['Asset', 'Used', 'Available', 'Total', ''];
const headers = await screen.findAllByRole('columnheader');
expect(headers).toHaveLength(expectedHeaders.length);
expect(
@@ -65,8 +65,7 @@ describe('AccountsTable', () => {
'tBTC',
'1,256.00',
'1,256.00',
'1,256.00',
'Breakdown',
'2,512.00',
'Deposit',
'Withdraw',
];
@@ -88,13 +87,8 @@ describe('AccountsTable', () => {
);
});
const cells = await screen.findAllByRole('gridcell');
const expectedValues = [
'tBTC',
'1,256.00',
'1,256.00',
'1,256.00',
'Breakdown',
];
const expectedValues = ['tBTC', '1,256.00', '1,256.00', '2,512.00', ''];
expect(cells.length).toBe(expectedValues.length);
cells.forEach((cell, i) => {
expect(cell).toHaveTextContent(expectedValues[i]);
});
@@ -145,7 +139,7 @@ describe('AccountsTable', () => {
},
available: '0',
balance: '125600000',
deposited: '125600000',
total: '125600000',
market: {
__typename: 'Market',
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
@@ -161,7 +155,7 @@ describe('AccountsTable', () => {
used: '125600000',
},
],
deposited: '125600000',
total: '125600000',
type: 'ACCOUNT_TYPE_GENERAL',
used: '125600000',
},
+182 -166
View File
@@ -8,7 +8,6 @@ import { t } from '@vegaprotocol/i18n';
import type {
VegaICellRendererParams,
VegaValueFormatterParams,
VegaValueGetterParams,
} from '@vegaprotocol/datagrid';
import { Button, ButtonLink, Dialog } from '@vegaprotocol/ui-toolkit';
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
@@ -17,12 +16,56 @@ import {
CenteredGridCellWrapper,
} from '@vegaprotocol/datagrid';
import { AgGridColumn } from 'ag-grid-react';
import type { IDatasource, IGetRowsParams } from 'ag-grid-community';
import type { IDatasource, IGetRowsParams, RowNode } from 'ag-grid-community';
import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
import BreakdownTable from './breakdown-table';
import type { AccountFields } from './accounts-data-provider';
import type { Asset } from '@vegaprotocol/types';
import BigNumber from 'bignumber.js';
import classNames from 'classnames';
const colorClass = (percentageUsed: number, neutral = false) => {
return classNames({
'text-neutral-500 dark:text-neutral-400': percentageUsed < 75 && !neutral,
'text-vega-orange': percentageUsed >= 75 && percentageUsed < 90,
'text-vega-pink': percentageUsed >= 90,
});
};
export const percentageValue = (part?: string, total?: string) =>
new BigNumber(part || 0)
.dividedBy(total || 1)
.multipliedBy(100)
.toNumber();
const formatWithAssetDecimals = (
data: AccountFields | undefined,
value: string | undefined
) => {
return (
data &&
data.asset &&
isNumeric(value) &&
addDecimalsFormatNumber(value, data.asset.decimals)
);
};
export const accountValuesComparator = (
valueA: string,
valueB: string,
nodeA: RowNode,
nodeB: RowNode
) => {
if (isNumeric(valueA) && isNumeric(valueB)) {
const a = toBigNum(valueA, nodeA.data.asset?.decimals);
const b = toBigNum(valueB, nodeB.data.asset?.decimals);
if (a.isEqualTo(b)) return 0;
return a.isGreaterThan(b) ? 1 : -1;
}
if (valueA === valueB) return 0;
return valueA > valueB ? 1 : -1;
};
export interface GetRowsParams extends Omit<IGetRowsParams, 'successCallback'> {
successCallback(rowsThisBlock: AccountFields[], lastRow?: number): void;
@@ -47,7 +90,7 @@ export interface AccountTableProps extends AgGridReactProps {
export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
({ onClickAsset, onClickWithdraw, onClickDeposit, ...props }, ref) => {
const [openBreakdown, setOpenBreakdown] = useState(false);
const [breakdown, setBreakdown] = useState<AccountFields[] | null>(null);
const [row, setRow] = useState<AccountFields>();
const pinnedAssetId = props.pinnedAsset?.id;
const pinnedAssetRow = useMemo(() => {
@@ -60,7 +103,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
asset: props.pinnedAsset,
available: '0',
used: '0',
deposited: '0',
total: '0',
balance: '0',
};
}
@@ -81,6 +124,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
resizable: true,
tooltipComponent: TooltipCellComponent,
sortable: true,
comparator: accountValuesComparator,
}}
{...props}
pinnedTopRowData={pinnedAssetRow ? [pinnedAssetRow] : undefined}
@@ -94,90 +138,64 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
cellRenderer={({
value,
data,
node,
}: VegaICellRendererParams<AccountFields, 'asset.symbol'>) => {
return value ? (
<CenteredGridCellWrapper
className={node.rowPinned ? 'h-[30px]' : undefined}
return (
<ButtonLink
data-testid="asset"
onClick={() => {
if (data) {
onClickAsset(data.asset.id);
}
}}
>
<ButtonLink
data-testid="asset"
onClick={() => {
if (data) {
onClickAsset(data.asset.id);
}
}}
>
{value}
</ButtonLink>
</CenteredGridCellWrapper>
) : null;
}}
maxWidth={300}
/>
<AgGridColumn
headerName={t('Total')}
type="rightAligned"
field="deposited"
headerTooltip={t(
'This is the total amount of collateral used plus the amount available in your general account.'
)}
valueGetter={({
data,
}: VegaValueGetterParams<AccountFields, 'deposited'>) => {
return !data?.deposited
? undefined
: toBigNum(data.deposited, data.asset.decimals).toNumber();
}}
maxWidth={300}
cellRenderer={({
data,
node,
}: VegaICellRendererParams<AccountFields, 'deposited'>) => {
const valueFormatted =
data &&
data.asset &&
isNumeric(data.deposited) &&
addDecimalsFormatNumber(data.deposited, data.asset.decimals);
return node.rowPinned ? (
<CenteredGridCellWrapper className="h-[30px] justify-end">
{valueFormatted}
</CenteredGridCellWrapper>
) : (
valueFormatted
{value}
</ButtonLink>
);
}}
maxWidth={300}
/>
<AgGridColumn
headerName={t('Used')}
type="rightAligned"
field="used"
headerTooltip={t(
'This is the amount of collateral used from your general account.'
'Currently allocated to a market as margin or bond. Check the breakdown for details.'
)}
valueGetter={({
data,
}: VegaValueGetterParams<AccountFields, 'used'>) => {
return !data?.used
? undefined
: toBigNum(data.used, data.asset.decimals).toNumber();
}}
maxWidth={300}
cellRenderer={({
data,
node,
value,
}: VegaICellRendererParams<AccountFields, 'used'>) => {
const valueFormatted =
data &&
data.asset &&
isNumeric(data.used) &&
addDecimalsFormatNumber(data.used, data.asset.decimals);
return node.rowPinned ? (
<CenteredGridCellWrapper className="h-[30px] justify-end">
{valueFormatted}
</CenteredGridCellWrapper>
if (!data) return null;
const percentageUsed = percentageValue(value, data.total);
const valueFormatted = formatWithAssetDecimals(data, value);
return data.breakdown ? (
<>
<ButtonLink
data-testid="breakdown"
onClick={() => {
setOpenBreakdown(!openBreakdown);
setRow(data);
}}
>
<span>{valueFormatted}</span>
</ButtonLink>
<span
className={classNames(
colorClass(percentageUsed),
'ml-2 inline-block w-14'
)}
>
{percentageUsed.toFixed(2)}%
</span>
</>
) : (
valueFormatted
<>
<span>{valueFormatted}</span>
<span className="ml-2 inline-block w-14 text-neutral-500 dark:text-neutral-400">
0.00%
</span>
</>
);
}}
/>
@@ -186,115 +204,113 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
field="available"
type="rightAligned"
headerTooltip={t(
'This is the amount of collateral available in your general account.'
'Deposited on the network, but not allocated to a market. Free to use for placing orders or providing liquidity.'
)}
valueGetter={({
data,
}: VegaValueGetterParams<AccountFields, 'available'>) => {
return !data?.available
? undefined
: toBigNum(data.available, data.asset.decimals).toNumber();
}}
valueFormatter={({
data,
}: VegaValueFormatterParams<AccountFields, 'available'>) =>
data &&
data.asset &&
isNumeric(data.available) &&
addDecimalsFormatNumber(data.available, data.asset.decimals)
}
maxWidth={300}
cellRenderer={({
value,
data,
node,
}: VegaICellRendererParams<AccountFields, 'available'>) => {
const valueFormatted =
data &&
data.asset &&
isNumeric(data.available) &&
addDecimalsFormatNumber(data.available, data.asset.decimals);
return node.rowPinned ? (
<CenteredGridCellWrapper className="h-[30px] justify-end">
{valueFormatted}
</CenteredGridCellWrapper>
) : (
valueFormatted
const percentageUsed = percentageValue(data?.used, data?.total);
return (
<span className={colorClass(percentageUsed, true)}>
{formatWithAssetDecimals(data, value)}
</span>
);
}}
/>
<AgGridColumn
colId="breakdown"
headerName=""
sortable={false}
minWidth={200}
headerName={t('Total')}
type="rightAligned"
cellRenderer={({
field="total"
headerTooltip={t(
'The total amount of each asset on this key. Includes used and available collateral.'
)}
valueFormatter={({
data,
}: VegaICellRendererParams<AccountFields>) => {
if (!data) return null;
else {
if (
data.asset.id === pinnedAssetId &&
new BigNumber(data.deposited).isLessThanOrEqualTo(0)
) {
}: VegaValueFormatterParams<AccountFields, 'total'>) =>
formatWithAssetDecimals(data, data?.total)
}
/>
{
<AgGridColumn
colId="accounts-actions"
headerName=""
sortable={false}
minWidth={200}
type="rightAligned"
cellRenderer={({
data,
}: VegaICellRendererParams<AccountFields>) => {
if (!data) return null;
else {
if (
data.asset.id === pinnedAssetId &&
new BigNumber(data.total).isLessThanOrEqualTo(0)
) {
return (
<CenteredGridCellWrapper className="h-[30px] justify-end py-1">
<Button
size="xs"
variant="primary"
data-testid="deposit"
onClick={() => {
onClickDeposit && onClickDeposit(data.asset.id);
}}
>
{t('Deposit to trade')}
</Button>
</CenteredGridCellWrapper>
);
}
return (
<CenteredGridCellWrapper className="h-[30px] justify-end py-1">
<Button
size="xs"
variant="primary"
data-testid="deposit"
onClick={() => {
onClickDeposit && onClickDeposit(data.asset.id);
}}
>
{t('Deposit to trade')}
</Button>
</CenteredGridCellWrapper>
<>
<span className="mx-1" />
{!props.isReadOnly && (
<ButtonLink
data-testid="deposit"
onClick={() => {
onClickDeposit && onClickDeposit(data.asset.id);
}}
>
{t('Deposit')}
</ButtonLink>
)}
<span className="mx-1" />
{!props.isReadOnly && (
<ButtonLink
data-testid="withdraw"
onClick={() =>
onClickWithdraw && onClickWithdraw(data.asset.id)
}
>
{t('Withdraw')}
</ButtonLink>
)}
</>
);
}
return (
<>
<ButtonLink
data-testid="breakdown"
onClick={() => {
setOpenBreakdown(!openBreakdown);
setBreakdown(data.breakdown || null);
}}
>
{t('Breakdown')}
</ButtonLink>
<span className="mx-1" />
{!props.isReadOnly && (
<ButtonLink
data-testid="deposit"
onClick={() => {
onClickDeposit && onClickDeposit(data.asset.id);
}}
>
{t('Deposit')}
</ButtonLink>
)}
<span className="mx-1" />
{!props.isReadOnly && (
<ButtonLink
data-testid="withdraw"
onClick={() =>
onClickWithdraw && onClickWithdraw(data.asset.id)
}
>
{t('Withdraw')}
</ButtonLink>
)}
</>
);
}
}}
/>
}}
/>
}
</AgGrid>
<Dialog size="medium" open={openBreakdown} onChange={setOpenBreakdown}>
<div className="h-[35vh] w-full m-auto flex flex-col">
<h1 className="text-xl mb-4">{t('Collateral breakdown')}</h1>
<BreakdownTable data={breakdown} domLayout="autoHeight" />
<h1 className="text-xl mb-4">
{row?.asset?.symbol} {t('usage breakdown')}
</h1>
{row && (
<p className="mb-2 text-sm">
{t('You have %s %s in total.', [
addDecimalsFormatNumber(row.total, row.asset.decimals),
row.asset.symbol,
])}
</p>
)}
<BreakdownTable
data={row?.breakdown || null}
domLayout="autoHeight"
/>
</div>
</Dialog>
</>
@@ -27,7 +27,7 @@ const singleRow = {
},
available: '125600000',
used: '125600000',
deposited: '125600000',
total: '251200000',
} as AccountFields;
const singleRowData = [singleRow];
@@ -37,10 +37,10 @@ describe('BreakdownTable', () => {
render(<BreakdownTable data={singleRowData} />);
});
const headers = await screen.findAllByRole('columnheader');
expect(headers).toHaveLength(4);
expect(headers).toHaveLength(3);
expect(
headers.map((h) => h.querySelector('[ref="eText"]')?.textContent?.trim())
).toEqual(['Account type', 'Market', 'Used', 'Balance']);
).toEqual(['Market', 'Account type', 'Balance']);
});
it('should apply correct formatting', async () => {
@@ -49,9 +49,9 @@ describe('BreakdownTable', () => {
});
const cells = await screen.findAllByRole('gridcell');
const expectedValues = [
'Margin',
'BTCUSD Monthly (30 Jun 2022)',
'1,256.001,256.00',
'Margin',
'1,256.00 (50%)',
'1,256.00',
'1,256.00',
];
@@ -83,7 +83,7 @@ describe('BreakdownTable', () => {
},
available: '0',
balance: '125600000',
deposited: '125600000',
total: '125600000',
market: {
__typename: 'Market',
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
@@ -99,7 +99,7 @@ describe('BreakdownTable', () => {
used: '125600000',
},
],
deposited: '125600000',
total: '125600000',
type: 'ACCOUNT_TYPE_GENERAL',
used: '125600000',
},
+23 -42
View File
@@ -1,5 +1,5 @@
import { forwardRef } from 'react';
import { addDecimalsFormatNumber, isNumeric } from '@vegaprotocol/utils';
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import {
Intent,
@@ -13,6 +13,7 @@ import type { ValueProps } from '@vegaprotocol/ui-toolkit';
import type { VegaValueFormatterParams } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid, PriceCell } from '@vegaprotocol/datagrid';
import type { ValueFormatterParams } from 'ag-grid-community';
import { accountValuesComparator } from './accounts-table';
export const progressBarValueFormatter = ({
data,
@@ -23,24 +24,16 @@ export const progressBarValueFormatter = ({
}
const min = BigInt(data.used);
const mid = BigInt(data.available);
const max = BigInt(data.deposited);
const max = BigInt(data.total);
const range = max > min ? max : min;
return {
low: addDecimalsFormatNumber(min.toString(), data.asset.decimals, 4),
high: addDecimalsFormatNumber(mid.toString(), data.asset.decimals, 4),
low: addDecimalsFormatNumber(min.toString(), data.asset.decimals),
high: addDecimalsFormatNumber(mid.toString(), data.asset.decimals),
value: range ? Number((min * BigInt(100)) / range) : 0,
intent: Intent.Warning,
};
};
export const progressBarHeaderComponentParams = {
template:
'<div class="ag-cell-label-container" role="presentation">' +
` <span>${t('Available')}</span>` +
' <span ref="eText" class="ag-header-cell-text"></span>' +
'</div>',
};
interface BreakdownTableProps extends AgGridReactProps {
data: AccountFields[] | null;
}
@@ -62,8 +55,23 @@ const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
defaultColDef={{
flex: 1,
resizable: true,
sortable: true,
}}
>
<AgGridColumn
headerName={t('Market')}
field="market.tradableInstrument.instrument.name"
valueFormatter={({
value,
}: VegaValueFormatterParams<
AccountFields,
'market.tradableInstrument.instrument.name'
>) => {
if (!value) return 'None';
return value;
}}
minWidth={200}
/>
<AgGridColumn
headerName={t('Account type')}
field="type"
@@ -76,42 +84,15 @@ const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
: ''
}
/>
<AgGridColumn
headerName={t('Market')}
field="market.tradableInstrument.instrument.name"
valueFormatter={({
value,
}: VegaValueFormatterParams<
AccountFields,
'market.tradableInstrument.instrument.name'
>) => {
if (!value) return '-';
return value;
}}
minWidth={200}
/>
<AgGridColumn
headerName={t('Used')}
headerName={t('Balance')}
field="used"
flex={2}
maxWidth={500}
headerComponentParams={progressBarHeaderComponentParams}
cellRendererSelector={progressBarCellRendererSelector}
valueFormatter={progressBarValueFormatter}
/>
<AgGridColumn
headerName={t('Balance')}
field="balance"
valueFormatter={({
value,
data,
}: VegaValueFormatterParams<AccountFields, 'balance'>) => {
if (data && data.asset && isNumeric(value)) {
return addDecimalsFormatNumber(value, data.asset.decimals);
}
return '-';
}}
maxWidth={300}
comparator={accountValuesComparator}
/>
</AgGrid>
);
+1
View File
@@ -53,6 +53,7 @@ export const checkSorting = (
});
checkSortChange(orderTabDesc, column);
};
const checkSortChange = (tabsArr: string[], column: string) => {
cy.get('.ag-center-cols-container').within(() => {
tabsArr.forEach((entry, i) => {
@@ -116,7 +116,7 @@ export const DealTicket = ({
return;
}
const hasNoBalance = generalAccountBalance === '0';
const hasNoBalance = !BigInt(generalAccountBalance);
if (hasNoBalance) {
setError('summary', {
message: SummaryValidationType.NoCollateral,
@@ -141,7 +141,6 @@ export const DealTicket = ({
pubKey,
setError,
clearErrors,
errors.summary,
]);
const onSubmit = useCallback(
@@ -386,8 +385,12 @@ const SummaryMessage = memo(
// If there is no blocking error but user doesn't have enough
// balance render the margin warning, but still allow submission
if (BigInt(balance) < BigInt(margin)) {
return <MarginWarning balance={balance} margin={margin} asset={asset} />;
if (BigInt(balance) < BigInt(margin) && BigInt(balance) > BigInt(0)) {
return (
<div className="mb-2">
<MarginWarning balance={balance} margin={margin} asset={asset} />
</div>
);
}
// Show auction mode warning
if (
+7 -18
View File
@@ -134,6 +134,10 @@ export const LedgerTable = forwardRef<AgGridReact, LedgerEntryProps>(
headerName={t('Transfer type')}
field="transferType"
tooltipField="transferType"
filter={SetFilter}
filterParams={{
set: TransferTypeMapping,
}}
valueFormatter={({
value,
}: VegaValueFormatterParams<LedgerEntry, 'transferType'>) =>
@@ -147,14 +151,9 @@ export const LedgerTable = forwardRef<AgGridReact, LedgerEntryProps>(
value,
data,
}: VegaValueFormatterParams<LedgerEntry, 'quantity'>) => {
const marketDecimalPlaces = data?.marketSender?.decimalPlaces;
const assetDecimalPlaces = data?.asset?.decimals || 0;
return value
? addDecimalsFormatNumber(
value,
assetDecimalPlaces,
marketDecimalPlaces
)
? addDecimalsFormatNumber(value, assetDecimalPlaces)
: value;
}}
/>
@@ -175,14 +174,9 @@ export const LedgerTable = forwardRef<AgGridReact, LedgerEntryProps>(
value,
data,
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountBalance'>) => {
const marketDecimalPlaces = data?.marketSender?.decimalPlaces;
const assetDecimalPlaces = data?.asset?.decimals || 0;
return value
? addDecimalsFormatNumber(
value,
assetDecimalPlaces,
marketDecimalPlaces
)
? addDecimalsFormatNumber(value, assetDecimalPlaces)
: value;
}}
/>
@@ -193,14 +187,9 @@ export const LedgerTable = forwardRef<AgGridReact, LedgerEntryProps>(
value,
data,
}: VegaValueFormatterParams<LedgerEntry, 'toAccountBalance'>) => {
const marketDecimalPlaces = data?.marketReceiver?.decimalPlaces;
const assetDecimalPlaces = data?.asset?.decimals || 0;
return value
? addDecimalsFormatNumber(
value,
assetDecimalPlaces,
marketDecimalPlaces
)
? addDecimalsFormatNumber(value, assetDecimalPlaces)
: value;
}}
/>
@@ -322,9 +322,8 @@ export const Info = ({ market, onSelect }: InfoProps) => {
data={{
highestPrice: bounds.maxValidPrice,
lowestPrice: bounds.minValidPrice,
referencePrice: bounds.referencePrice,
}}
decimalPlaces={assetDecimals}
decimalPlaces={market.decimalPlaces}
assetSymbol={quoteUnit}
/>
)}
@@ -213,7 +213,6 @@ describe('getMetrics && rejoinPositionData', () => {
expect(metrics[0].marketDecimalPlaces).toEqual(5);
expect(metrics[0].positionDecimalPlaces).toEqual(0);
expect(metrics[0].decimals).toEqual(5);
expect(metrics[0].liquidationPrice).toEqual('169990');
expect(metrics[0].lowMarginLevel).toEqual(false);
expect(metrics[0].markPrice).toEqual('9431775');
expect(metrics[0].marketId).toEqual(
@@ -242,7 +241,6 @@ describe('getMetrics && rejoinPositionData', () => {
expect(metrics[1].marketDecimalPlaces).toEqual(5);
expect(metrics[1].positionDecimalPlaces).toEqual(0);
expect(metrics[1].decimals).toEqual(5);
expect(metrics[1].liquidationPrice).toEqual('9830750');
expect(metrics[1].lowMarginLevel).toEqual(false);
expect(metrics[1].markPrice).toEqual('869762');
expect(metrics[1].marketId).toEqual(
@@ -67,7 +67,6 @@ export interface Position {
positionDecimalPlaces: number;
totalBalance: string;
assetSymbol: string;
liquidationPrice: string | undefined;
lowMarginLevel: boolean;
marketId: string;
marketTradingMode: Schema.MarketTradingMode;
@@ -140,7 +139,6 @@ export const getMetrics = (
? new BigNumber(0)
: marginAccountBalance.dividedBy(totalBalance).multipliedBy(100);
const marginMaintenance = toBigNum(marginLevel.maintenanceLevel, decimals);
const marginSearch = toBigNum(marginLevel.searchLevel, decimals);
const marginInitial = toBigNum(marginLevel.initialLevel, decimals);
@@ -151,17 +149,6 @@ export const getMetrics = (
.plus(markPrice)
: undefined;
const liquidationPrice = markPrice
? BigNumber.maximum(
0,
marginMaintenance
.minus(marginAccountBalance)
.minus(generalAccountBalance)
.dividedBy(openVolume)
.plus(markPrice)
)
: undefined;
const lowMarginLevel =
marginAccountBalance.isLessThan(
marginSearch.plus(marginInitial.minus(marginSearch).dividedBy(2))
@@ -180,9 +167,6 @@ export const getMetrics = (
market.tradableInstrument.instrument.product.settlementAsset.symbol,
totalBalance: totalBalance.multipliedBy(10 ** decimals).toFixed(),
lowMarginLevel,
liquidationPrice: liquidationPrice
? liquidationPrice.multipliedBy(10 ** marketDecimalPlaces).toFixed(0)
: undefined,
marketId: market.id,
marketTradingMode: market.tradingMode,
markPrice: marketData ? marketData.markPrice : undefined,
@@ -17,7 +17,6 @@ const singleRow: Position = {
decimals: 2,
totalBalance: '123456',
assetSymbol: 'BTC',
liquidationPrice: '83',
lowMarginLevel: false,
marketId: 'string',
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
@@ -50,7 +49,7 @@ it('render correct columns', async () => {
});
const headers = screen.getAllByRole('columnheader');
expect(headers).toHaveLength(12);
expect(headers).toHaveLength(11);
expect(
headers.map((h) => h.querySelector('[ref="eText"]')?.textContent?.trim())
).toEqual([
@@ -60,7 +59,6 @@ it('render correct columns', async () => {
'Mark price',
'Settlement asset',
'Entry price',
'Liquidation price (est)',
'Leverage',
'Margin allocated',
'Realised PNL',
@@ -146,33 +144,12 @@ it('displays mark price', async () => {
expect(cells[3].textContent).toEqual('-');
});
it("displays properly entry, liquidation price and liquidation bar and it's intent", async () => {
let result: RenderResult;
await act(async () => {
result = render(
<PositionsTable rowData={singleRowData} isReadOnly={false} />
);
});
let cells = screen.getAllByRole('gridcell');
const entryPrice = cells[5].firstElementChild?.firstElementChild?.textContent;
expect(entryPrice).toEqual('13.3');
await act(async () => {
result.rerender(
<PositionsTable
rowData={[{ ...singleRow, lowMarginLevel: true }]}
isReadOnly={false}
/>
);
});
cells = screen.getAllByRole('gridcell');
});
it('displays leverage', async () => {
await act(async () => {
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
const cells = screen.getAllByRole('gridcell');
expect(cells[7].textContent).toEqual('1.1');
expect(cells[6].textContent).toEqual('1.1');
});
it('displays allocated margin', async () => {
@@ -180,7 +157,7 @@ it('displays allocated margin', async () => {
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
const cells = screen.getAllByRole('gridcell');
const cell = cells[8];
const cell = cells[7];
expect(cell.textContent).toEqual('123,456.00');
});
@@ -189,8 +166,7 @@ it('displays realised and unrealised PNL', async () => {
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
const cells = screen.getAllByRole('gridcell');
expect(cells[9].textContent).toEqual('1.23');
expect(cells[10].textContent).toEqual('4.56');
expect(cells[9].textContent).toEqual('4.56');
});
it('displays close button', async () => {
@@ -206,7 +182,7 @@ it('displays close button', async () => {
);
});
const cells = screen.getAllByRole('gridcell');
expect(cells[12].textContent).toEqual('Close');
expect(cells[11].textContent).toEqual('Close');
});
it('do not display close button if openVolume is zero', async () => {
@@ -222,7 +198,7 @@ it('do not display close button if openVolume is zero', async () => {
);
});
const cells = screen.getAllByRole('gridcell');
expect(cells[12].textContent).toEqual('');
expect(cells[11].textContent).toEqual('');
});
describe('PNLCell', () => {
@@ -9,7 +9,9 @@ export default {
title: 'PositionsTable',
} as Meta;
const Template: Story = (args) => <PositionsTable {...args} />;
const Template: Story = (args) => (
<PositionsTable {...args} isReadOnly={false} />
);
export const Primary = Template.bind({});
const longPosition: Position = {
@@ -27,7 +29,6 @@ const longPosition: Position = {
// leverageMaintenance: '0',
// leverageRelease: '0',
// leverageSearch: '0',
liquidationPrice: '1129935',
lowMarginLevel: false,
marginAccountBalance: new BigNumber('0').toString(),
// marginMaintenance: '0',
@@ -42,6 +43,8 @@ const longPosition: Position = {
unrealisedPNL: '45',
searchPrice: '1132123',
updatedAt: '2022-07-27T15:02:58.400Z',
lossSocializationAmount: '0',
status: Schema.PositionStatus.POSITION_STATUS_UNSPECIFIED,
};
const shortPosition: Position = {
@@ -59,7 +62,6 @@ const shortPosition: Position = {
// leverageMaintenance: '0',
// leverageRelease: '0',
// leverageSearch: '0',
liquidationPrice: '23734',
lowMarginLevel: false,
marginAccountBalance: new BigNumber('0').toString(),
// marginMaintenance: '0',
@@ -74,6 +76,8 @@ const shortPosition: Position = {
unrealisedPNL: '0',
searchPrice: '0',
updatedAt: '2022-07-26T14:01:34.800Z',
lossSocializationAmount: '0',
status: Schema.PositionStatus.POSITION_STATUS_UNSPECIFIED,
};
Primary.args = {
@@ -249,40 +249,6 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
);
}}
/>
<AgGridColumn
headerName={t('Liquidation price (est)')}
field="liquidationPrice"
type="rightAligned"
cellRendererSelector={(): CellRendererSelectorResult => {
return {
component: PriceFlashCell,
};
}}
filter="agNumberColumnFilter"
valueGetter={({
data,
}: VegaValueGetterParams<Position, 'liquidationPrice'>) => {
return data?.liquidationPrice === undefined || !data
? undefined
: toBigNum(
data.liquidationPrice,
data.marketDecimalPlaces
).toNumber();
}}
valueFormatter={({
data,
}: VegaValueFormatterParams<Position, 'liquidationPrice'>):
| string
| undefined => {
if (!data || data?.liquidationPrice === undefined) {
return undefined;
}
return addDecimalsFormatNumber(
data.liquidationPrice,
data.marketDecimalPlaces
);
}}
/>
<AgGridColumn
headerName={t('Leverage')}
field="currentLeverage"
@@ -20,8 +20,9 @@ export const ProgressBarCell = ({ valueFormatted }: ValueProps) => {
return valueFormatted ? (
<>
<div className="flex justify-between leading-tight font-mono">
<div>{valueFormatted.low}</div>
<div>{valueFormatted.high}</div>
<div>
{valueFormatted.low} ({valueFormatted.value}%)
</div>
</div>
<ProgressBar
value={valueFormatted.value}