From 06a6fe6d6754799c9b232c7165b7790c8307a465 Mon Sep 17 00:00:00 2001 From: "m.ray" <16125548+MadalinaRaicu@users.noreply.github.com> Date: Mon, 20 Nov 2023 23:07:17 +0200 Subject: [PATCH 1/4] fix(accounts): remove account balance formatting in transfer form (#5315) Co-authored-by: Matthew Russell --- libs/accounts/src/lib/accounts-table.spec.tsx | 68 +++++------- libs/accounts/src/lib/transfer-form.spec.tsx | 104 ++++++++++++++++-- libs/accounts/src/lib/transfer-form.tsx | 14 +-- 3 files changed, 126 insertions(+), 60 deletions(-) diff --git a/libs/accounts/src/lib/accounts-table.spec.tsx b/libs/accounts/src/lib/accounts-table.spec.tsx index 3b4155c74..e3da431f1 100644 --- a/libs/accounts/src/lib/accounts-table.spec.tsx +++ b/libs/accounts/src/lib/accounts-table.spec.tsx @@ -1,10 +1,23 @@ -import { act, render, screen } from '@testing-library/react'; +import { act, render, screen, within } from '@testing-library/react'; import * as Types from '@vegaprotocol/types'; import type { AccountFields } from './accounts-data-provider'; import { getAccountData } from './accounts-data-provider'; import { AccountTable } from './accounts-table'; import userEvent from '@testing-library/user-event'; - +const asset1 = { + __typename: 'Asset', + id: 'asset-1', + symbol: 'tBTC', + decimals: 5, + name: 'T BTC', +}; +const asset2 = { + __typename: 'Asset', + id: 'asset-2', + symbol: 'aBTC', + decimals: 5, + name: 'A BTC', +}; const singleRow = { __typename: 'AccountBalance', type: Types.AccountType.ACCOUNT_TYPE_MARGIN, @@ -13,12 +26,7 @@ const singleRow = { __typename: 'Market', id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35', }, - asset: { - __typename: 'Asset', - id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c', - symbol: 'tBTC', - decimals: 5, - }, + asset: asset1, available: '125600000', used: '125600000', total: '251200000', @@ -33,12 +41,7 @@ const secondRow = { __typename: 'Market', id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35', }, - asset: { - __typename: 'Asset', - id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c', - symbol: 'aBTC', - decimals: 5, - }, + asset: asset2, available: '125600001', used: '125600001', total: '251200002', @@ -134,7 +137,7 @@ describe('AccountsTable', () => { it('should sort assets', async () => { // 7001-COLL-010 - const { container } = render( + render( null} @@ -142,13 +145,13 @@ describe('AccountsTable', () => { /> ); - const headerCell = screen.getByText('Asset'); - await userEvent.click(headerCell); - const rows = container.querySelectorAll( - '.ag-center-cols-container .ag-row' - ); - expect(rows[0].textContent).toContain('aBTC'); - expect(rows[1].textContent).toContain('tBTC'); + const headerCell = screen + .getAllByRole('columnheader') + .find((h) => h?.getAttribute('col-id') === 'asset.symbol') as HTMLElement; + + await userEvent.click(within(headerCell).getByText(/asset/i)); + + expect(headerCell).toHaveAttribute('aria-sort', 'ascending'); }); it('should apply correct formatting in view as user mode', async () => { @@ -176,12 +179,7 @@ describe('AccountsTable', () => { rowData={singleRowData} onClickAsset={() => null} isReadOnly={false} - pinnedAsset={{ - decimals: 5, - id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c', - symbol: 'tBTC', - name: 'tBTC', - }} + pinnedAsset={asset1} /> ); await screen.findAllByRole('rowgroup'); @@ -213,23 +211,13 @@ describe('AccountsTable', () => { const result = getAccountData([singleRow]); const expected = [ { - asset: { - __typename: 'Asset', - decimals: 5, - id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c', - symbol: 'tBTC', - }, + asset: asset1, available: '0', balance: '0', breakdown: [ { __typename: 'AccountBalance', - asset: { - __typename: 'Asset', - decimals: 5, - id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c', - symbol: 'tBTC', - }, + asset: asset1, available: '0', balance: '125600000', total: '125600000', diff --git a/libs/accounts/src/lib/transfer-form.spec.tsx b/libs/accounts/src/lib/transfer-form.spec.tsx index 0fdad0897..93b5e522f 100644 --- a/libs/accounts/src/lib/transfer-form.spec.tsx +++ b/libs/accounts/src/lib/transfer-form.spec.tsx @@ -1,4 +1,10 @@ -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { + fireEvent, + render, + screen, + waitFor, + within, +} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import BigNumber from 'bignumber.js'; import { @@ -7,7 +13,7 @@ import { TransferForm, type TransferFormProps, } from './transfer-form'; -import { AccountType } from '@vegaprotocol/types'; +import { AccountType, AccountTypeMapping } from '@vegaprotocol/types'; import { removeDecimal } from '@vegaprotocol/utils'; describe('TransferForm', () => { @@ -39,8 +45,7 @@ describe('TransferForm', () => { }; const amount = '100'; - const pubKey = - '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680'; + const pubKey = '1'.repeat(64); const asset = { id: 'eur', symbol: '€', @@ -50,10 +55,7 @@ describe('TransferForm', () => { }; const props = { pubKey, - pubKeys: [ - pubKey, - 'a4b6e3de5d7ef4e31ae1b090be49d1a2ef7bcefff60cccf7658a0d4922651cce', - ], + pubKeys: [pubKey, '2'.repeat(64)], feeFactor: '0.001', submitTransfer: jest.fn(), accounts: [ @@ -182,7 +184,7 @@ describe('TransferForm', () => { // Test use max button await userEvent.click(screen.getByRole('button', { name: 'Use max' })); - expect(amountInput).toHaveValue('1000'); + expect(amountInput).toHaveValue('1000.00'); // Test amount validation await userEvent.clear(amountInput); @@ -267,7 +269,7 @@ describe('TransferForm', () => { // Test use max button await userEvent.click(screen.getByRole('button', { name: 'Use max' })); - expect(amountInput).toHaveValue('100'); + expect(amountInput).toHaveValue('100.00'); // If transfering from a vested account 'include fees' checkbox should // be disabled and fees should be 0 @@ -296,6 +298,88 @@ describe('TransferForm', () => { }); }); + it('handles lots of decimal places', async () => { + const balance = '904195168829277777'; + const expectedBalance = '0.904195168829277777'; + + const longDecimalAsset = { + id: 'assetId', + symbol: 'VEGA', + name: 'VEGA', + decimals: 18, + quantum: '1', + }; + + const account = { + type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS, + asset: longDecimalAsset, + balance, + }; + + const mockSubmit = jest.fn(); + + renderComponent({ + ...props, + accounts: [account], + submitTransfer: mockSubmit, + minQuantumMultiple: '100000', + }); + + // Select a pubkey + await userEvent.selectOptions( + screen.getByLabelText('To Vega key'), + props.pubKeys[1] // Use not current pubkey so we can check it switches to current pubkey later + ); + + // Select asset + await selectAsset(longDecimalAsset); + + const accountSelect = screen.getByLabelText('From account'); + const option = within(accountSelect) + .getAllByRole('option') + .find( + (o) => o.getAttribute('value') === `${account.type}-${account.asset.id}` + ); + // plus one for disabled 'please select' option + + expect(option).toHaveTextContent( + `${AccountTypeMapping[account.type]} (${expectedBalance} ${ + account.asset.symbol + })` + ); + + await userEvent.selectOptions( + accountSelect, + `${AccountType.ACCOUNT_TYPE_VESTED_REWARDS}-${longDecimalAsset.id}` + ); + + expect(accountSelect).toHaveValue( + `${AccountType.ACCOUNT_TYPE_VESTED_REWARDS}-${longDecimalAsset.id}` + ); + + // Check switch back to connected key + const amountInput = screen.getByLabelText('Amount'); + + // Test use max button + await userEvent.click(screen.getByRole('button', { name: 'Use max' })); + expect(amountInput).toHaveValue(expectedBalance); + + await submit(); + + await waitFor(() => { + // 1003-TRAN-023 + expect(mockSubmit).toHaveBeenCalledTimes(1); + expect(mockSubmit).toHaveBeenCalledWith({ + fromAccountType: AccountType.ACCOUNT_TYPE_VESTED_REWARDS, + toAccountType: AccountType.ACCOUNT_TYPE_GENERAL, + to: props.pubKey, + asset: longDecimalAsset.id, + amount: balance, + oneOff: {}, + }); + }); + }); + describe('IncludeFeesCheckbox', () => { it('validates fields and submits when checkbox is checked', async () => { const mockSubmit = jest.fn(); diff --git a/libs/accounts/src/lib/transfer-form.tsx b/libs/accounts/src/lib/transfer-form.tsx index 07958ddfc..b38c12946 100644 --- a/libs/accounts/src/lib/transfer-form.tsx +++ b/libs/accounts/src/lib/transfer-form.tsx @@ -5,7 +5,6 @@ import { vegaPublicKey, addDecimal, formatNumber, - addDecimalsFormatNumber, toBigNum, } from '@vegaprotocol/utils'; import { t } from '@vegaprotocol/i18n'; @@ -214,12 +213,7 @@ export const TransferForm = ({ - } + balance={} /> ))} @@ -286,8 +280,8 @@ export const TransferForm = ({ return ( ); })} @@ -413,7 +407,7 @@ export const TransferForm = ({ type="button" className="absolute top-0 right-0 ml-auto text-xs underline" onClick={() => - setValue('amount', parseFloat(accountBalance).toString(), { + setValue('amount', accountBalance, { shouldValidate: true, }) } From d9dc43b359b5ef33208cc8acde1c275426102eb7 Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Mon, 20 Nov 2023 13:57:18 -0800 Subject: [PATCH 2/4] chore(deal-ticket): re-enable margin estimates for perps (#5317) --- .../deal-ticket/deal-ticket-fee-details.tsx | 191 ++++++++---------- 1 file changed, 88 insertions(+), 103 deletions(-) diff --git a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx index e7b2cfb10..f94a5c67d 100644 --- a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react'; import { t } from '@vegaprotocol/i18n'; -import { getAsset, getProductType, getQuoteName } from '@vegaprotocol/markets'; +import { getAsset, getQuoteName } from '@vegaprotocol/markets'; import type { OrderSubmissionBody } from '@vegaprotocol/wallet'; import { useVegaWallet } from '@vegaprotocol/wallet'; @@ -151,6 +151,7 @@ export const DealTicketMarginDetails = ({ const { decimals: assetDecimals, quantum } = asset; let marginRequiredBestCase: string | undefined = undefined; let marginRequiredWorstCase: string | undefined = undefined; + if (marginEstimate) { if (currentMargins) { marginRequiredBestCase = ( @@ -286,115 +287,99 @@ export const DealTicketMarginDetails = ({ ); const quoteName = getQuoteName(market); - const productType = getProductType(market); return (
- {/* - TODO: remove this conditional check once the following PRs are deployed - and the estimatePosition query is working for perps - - - https://github.com/vegaprotocol/vega/pull/10119 - - https://github.com/vegaprotocol/vega/pull/10122 - */} - {productType === 'Future' && ( - <> - - -
-
- - - {t('Margin required')} - - - - -
- -
- {formatValue( - marginRequiredWorstCase, - assetDecimals, - quantum - )}{' '} - {assetSymbol || ''} -
-
-
- - } + + -
- +
+ + {t('Margin required')} + + + +
+ +
+ {formatValue( + marginRequiredWorstCase, assetDecimals, quantum - ), - assetSymbol - )} - /> - {deductionFromCollateral} - setBreakdownDialog(true) - : undefined - } - value={formatValue(marginAccountBalance, assetDecimals)} - symbol={assetSymbol} - labelDescription={MARGIN_ACCOUNT_TOOLTIP_TEXT} - formattedValue={formatValue( - marginAccountBalance, - assetDecimals, - quantum - )} - /> + )}{' '} + {assetSymbol || ''} +
+
-
-
- {projectedMargin} - - )} + + } + > +
+ + {deductionFromCollateral} + setBreakdownDialog(true) + : undefined + } + value={formatValue(marginAccountBalance, assetDecimals)} + symbol={assetSymbol} + labelDescription={MARGIN_ACCOUNT_TOOLTIP_TEXT} + formattedValue={formatValue( + marginAccountBalance, + assetDecimals, + quantum + )} + /> +
+
+
+ {projectedMargin} Date: Mon, 27 Nov 2023 12:42:47 +0200 Subject: [PATCH 3/4] feat(trading): reset console to default (#5344) --- .gitignore | 1 + .../components/settings/settings.spec.tsx | 12 ++++ apps/trading/components/settings/settings.tsx | 57 ++++++++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 apps/trading/components/settings/settings.spec.tsx diff --git a/.gitignore b/.gitignore index 0a587cc44..6fd2a0956 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ cypress.env.json /apps/**/cypress/reports/ /apps/**/cypress/downloads/ /apps/**/fixtures/wallet/node** +.nx/ diff --git a/apps/trading/components/settings/settings.spec.tsx b/apps/trading/components/settings/settings.spec.tsx new file mode 100644 index 000000000..363c32ce9 --- /dev/null +++ b/apps/trading/components/settings/settings.spec.tsx @@ -0,0 +1,12 @@ +import { Settings } from './settings'; +import { render, screen } from '@testing-library/react'; + +describe('Settings', () => { + it('should the settings component with all the options', () => { + render(); + expect(screen.getByText('Dark mode')).toBeInTheDocument(); + expect(screen.getByText('Share usage data')).toBeInTheDocument(); + expect(screen.getByText('Toast location')).toBeInTheDocument(); + expect(screen.getByText('Reset to default')).toBeInTheDocument(); + }); +}); diff --git a/apps/trading/components/settings/settings.tsx b/apps/trading/components/settings/settings.tsx index 0d5f5eb43..84759a781 100644 --- a/apps/trading/components/settings/settings.tsx +++ b/apps/trading/components/settings/settings.tsx @@ -1,12 +1,19 @@ import { t } from '@vegaprotocol/i18n'; -import { Switch, ToastPositionSetter } from '@vegaprotocol/ui-toolkit'; +import { + Dialog, + Intent, + Switch, + ToastPositionSetter, + TradingButton, +} from '@vegaprotocol/ui-toolkit'; import { useThemeSwitcher } from '@vegaprotocol/react-helpers'; import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval'; -import type { ReactNode } from 'react'; +import { useState, type ReactNode } from 'react'; export const Settings = () => { const { theme, setTheme } = useThemeSwitcher(); const [isApproved, setIsApproved] = useTelemetryApproval(); + const [open, setOpen] = useState(false); return (
@@ -31,6 +38,52 @@ export const Settings = () => { + + { + setOpen(true); + }} + > + {t('Reset')} + + +
+

+ {t( + 'You will lose all persisted settings and you will be logged out.' + )} +

+

+ {t('Are you sure you want to reset all settings to default?')} +

+
+ +
+ { + localStorage.clear(); + window.location.reload(); + }} + > + {t('Yes, clear cache and refresh')} + + { + setOpen(false); + }} + > + {t('No, keep settings')} + +
+
+
); }; From e5d4d2b0b80c0a5b6041700c33e2b68ce1d76573 Mon Sep 17 00:00:00 2001 From: "m.ray" <16125548+MadalinaRaicu@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:48:29 +0200 Subject: [PATCH 4/4] chore(trading): temporarily disable close position (#5350) --- libs/positions/src/lib/positions-manager.spec.tsx | 3 ++- libs/positions/src/lib/positions-manager.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/positions/src/lib/positions-manager.spec.tsx b/libs/positions/src/lib/positions-manager.spec.tsx index 6bd2d3825..e78448725 100644 --- a/libs/positions/src/lib/positions-manager.spec.tsx +++ b/libs/positions/src/lib/positions-manager.spec.tsx @@ -27,7 +27,8 @@ jest.mock('@vegaprotocol/data-provider', () => ({ })); describe('PositionsManager', () => { - it('should close position with max uint64', async () => { + // TODO: temporarily disable close position + it.skip('should close position with max uint64', async () => { render(, { wrapper: MockedProvider, }); diff --git a/libs/positions/src/lib/positions-manager.tsx b/libs/positions/src/lib/positions-manager.tsx index d431ef019..2056c68ed 100644 --- a/libs/positions/src/lib/positions-manager.tsx +++ b/libs/positions/src/lib/positions-manager.tsx @@ -73,7 +73,8 @@ export const PositionsManager = ({ pubKeys={pubKeys} rowData={data} onMarketClick={onMarketClick} - onClose={onClose} + // TODO: temporarily disable close position + // onClose={onClose} isReadOnly={isReadOnly} multipleKeys={partyIds.length > 1} overlayNoRowsTemplate={error ? error.message : t('No positions')}