diff --git a/apps/trading/client-pages/portfolio/deposits-container.tsx b/apps/trading/client-pages/portfolio/deposits-container.tsx index 4bd1c4ba8..43e4c387c 100644 --- a/apps/trading/client-pages/portfolio/deposits-container.tsx +++ b/apps/trading/client-pages/portfolio/deposits-container.tsx @@ -4,12 +4,9 @@ import { depositsProvider } from '@vegaprotocol/deposits'; import { t } from '@vegaprotocol/i18n'; import { useDataProvider } from '@vegaprotocol/data-provider'; import { useVegaWallet } from '@vegaprotocol/wallet'; -import { useRef } from 'react'; -import type { AgGridReact } from 'ag-grid-react'; import { useSidebar, ViewType } from '../../components/sidebar'; export const DepositsContainer = () => { - const gridRef = useRef(null); const { pubKey, isReadOnly } = useVegaWallet(); const { data, error } = useDataProvider({ dataProvider: depositsProvider, @@ -24,7 +21,6 @@ export const DepositsContainer = () => {
{!isReadOnly && ( diff --git a/libs/accounts/src/lib/accounts-manager.tsx b/libs/accounts/src/lib/accounts-manager.tsx index 00eace633..a05a74094 100644 --- a/libs/accounts/src/lib/accounts-manager.tsx +++ b/libs/accounts/src/lib/accounts-manager.tsx @@ -118,7 +118,6 @@ export const AccountManager = ({ onMarketClick, gridProps, }: AccountManagerProps) => { - const gridRef = useRef(null); const [breakdownAssetId, setBreakdownAssetId] = useState(); const { data, error } = useDataProvider({ dataProvider: aggregatedAccountsDataProvider, @@ -138,7 +137,6 @@ export const AccountManager = ({ return (
( - ( - { - onClickAsset, - onClickWithdraw, - onClickDeposit, - onClickBreakdown, - onClickTransfer, - rowData, - isReadOnly, - pinnedAsset, - ...props +export const AccountTable = ({ + onClickAsset, + onClickWithdraw, + onClickDeposit, + onClickBreakdown, + onClickTransfer, + rowData, + isReadOnly, + pinnedAsset, + ...props +}: AccountTableProps) => { + const pinnedRow = useMemo(() => { + if (!pinnedAsset) { + return; + } + const currentPinnedAssetRow = rowData?.find( + (row) => row.asset.id === pinnedAsset?.id + ); + if (!currentPinnedAssetRow) { + return { + asset: pinnedAsset, + available: '0', + used: '0', + total: '0', + balance: '0', + }; + } + return currentPinnedAssetRow; + }, [pinnedAsset, rowData]); + + const { getRowHeight } = props; + + const getPinnedAssetRowHeight = useCallback( + (params: RowHeightParams) => { + if ( + params.node.rowPinned && + params.data.asset.id === pinnedAsset?.id && + new BigNumber(params.data.total).isLessThanOrEqualTo(0) + ) { + return 32; + } + return getRowHeight ? getRowHeight(params) : undefined; }, - ref - ) => { - const pinnedRow = useMemo(() => { - if (!pinnedAsset) { - return; - } - const currentPinnedAssetRow = rowData?.find( - (row) => row.asset.id === pinnedAsset?.id - ); - if (!currentPinnedAssetRow) { - return { - asset: pinnedAsset, - available: '0', - used: '0', - total: '0', - balance: '0', - }; - } - return currentPinnedAssetRow; - }, [pinnedAsset, rowData]); + [pinnedAsset?.id, getRowHeight] + ); - const { getRowHeight } = props; + const showDepositButton = pinnedRow?.balance === '0'; - const getPinnedAssetRowHeight = useCallback( - (params: RowHeightParams) => { - if ( - params.node.rowPinned && - params.data.asset.id === pinnedAsset?.id && - new BigNumber(params.data.total).isLessThanOrEqualTo(0) - ) { - return 32; - } - return getRowHeight ? getRowHeight(params) : undefined; + const colDefs = useMemo(() => { + const defs: ColDef[] = [ + { + headerName: t('Asset'), + field: 'asset.symbol', + headerTooltip: t( + 'Asset is the collateral that is deposited into the Vega protocol.' + ), + cellClass: 'underline', + onCellClicked: ({ data }) => { + if (data) { + onClickAsset(data.asset.id); + } + }, }, - [pinnedAsset?.id, getRowHeight] - ); - - const showDepositButton = pinnedRow?.balance === '0'; - - const colDefs = useMemo(() => { - const defs: ColDef[] = [ - { - headerName: t('Asset'), - field: 'asset.symbol', - headerTooltip: t( - 'Asset is the collateral that is deposited into the Vega protocol.' - ), - cellClass: 'underline', - onCellClicked: ({ data }) => { - if (data) { - onClickAsset(data.asset.id); - } - }, + { + headerName: t('Used'), + type: 'rightAligned', + field: 'used', + headerTooltip: t( + 'Currently allocated to a market as margin or bond. Check the breakdown for details.' + ), + tooltipValueGetter: ({ value, data }) => { + if (!value || !data) return null; + return addDecimalsFormatNumber(value, data.asset.decimals); }, - { - headerName: t('Used'), - type: 'rightAligned', - field: 'used', - headerTooltip: t( - 'Currently allocated to a market as margin or bond. Check the breakdown for details.' - ), - tooltipValueGetter: ({ value, data }) => { - if (!value || !data) return null; - return addDecimalsFormatNumber(value, data.asset.decimals); - }, - onCellClicked: ({ data }) => { - if (!data || !onClickBreakdown) return; - onClickBreakdown(data.asset.id); - }, - cellRenderer: ({ - data, + onCellClicked: ({ data }) => { + if (!data || !onClickBreakdown) return; + onClickBreakdown(data.asset.id); + }, + cellRenderer: ({ + data, + value, + }: VegaICellRendererParams) => { + if (!value || !data) return '-'; + const percentageUsed = percentageValue(value, data.total); + const valueFormatted = addDecimalsFormatNumberQuantum( value, - }: VegaICellRendererParams) => { - if (!value || !data) return '-'; - const percentageUsed = percentageValue(value, data.total); - const valueFormatted = addDecimalsFormatNumberQuantum( - value, - data.asset.decimals, - data.asset.quantum - ); + data.asset.decimals, + data.asset.quantum + ); - return data.breakdown ? ( - <> - {valueFormatted} - + {valueFormatted} + + {percentageUsed.toFixed(2)}% + + + ) : ( + <> + {valueFormatted} + + {t('0.00%')} + + + ); + }, + }, + { + headerName: t('Available'), + field: 'available', + type: 'rightAligned', + headerTooltip: t( + 'Deposited on the network, but not allocated to a market. Free to use for placing orders or providing liquidity.' + ), + tooltipValueGetter: ({ value, data }) => { + if (!value || !data) return null; + return addDecimalsFormatNumber(value, data.asset.decimals); + }, + cellClass: ({ data }) => { + const percentageUsed = percentageValue(data?.used, data?.total); + return colorClass(percentageUsed, true); + }, + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + if (!value || !data) return '-'; + return addDecimalsFormatNumberQuantum( + value, + data.asset.decimals, + data.asset.quantum + ); + }, + }, + + { + headerName: t('Total'), + type: 'rightAligned', + field: 'total', + headerTooltip: t( + 'The total amount of each asset on this key. Includes used and available collateral.' + ), + tooltipValueGetter: ({ value, data }) => { + if (!value || !data) return null; + return addDecimalsFormatNumber(value, data.asset.decimals); + }, + valueFormatter: ({ + data, + value, + }: VegaValueFormatterParams) => { + if (!data || !value) return '-'; + return addDecimalsFormatNumberQuantum( + value, + data.asset.decimals, + data.asset.quantum + ); + }, + }, + { + colId: 'accounts-actions', + field: 'asset.id', + ...COL_DEFS.actions, + minWidth: showDepositButton ? 130 : COL_DEFS.actions.minWidth, + maxWidth: showDepositButton ? 130 : COL_DEFS.actions.maxWidth, + cellRenderer: ({ + value: assetId, + node, + }: VegaICellRendererParams) => { + if (!assetId) return null; + if (node.rowPinned && node.data?.total === '0') { + return ( + + + ); - }, - }, - { - headerName: t('Available'), - field: 'available', - type: 'rightAligned', - headerTooltip: t( - 'Deposited on the network, but not allocated to a market. Free to use for placing orders or providing liquidity.' - ), - tooltipValueGetter: ({ value, data }) => { - if (!value || !data) return null; - return addDecimalsFormatNumber(value, data.asset.decimals); - }, - cellClass: ({ data }) => { - const percentageUsed = percentageValue(data?.used, data?.total); - return colorClass(percentageUsed, true); - }, - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - if (!value || !data) return '-'; - return addDecimalsFormatNumberQuantum( - value, - data.asset.decimals, - data.asset.quantum - ); - }, + } + return isReadOnly ? null : ( + { + onClickDeposit && onClickDeposit(assetId); + }} + onClickWithdraw={() => { + onClickWithdraw && onClickWithdraw(assetId); + }} + onClickBreakdown={() => { + onClickBreakdown && onClickBreakdown(assetId); + }} + onClickTransfer={() => { + onClickTransfer && onClickTransfer(assetId); + }} + /> + ); }, + }, + ]; + return defs; + }, [ + onClickAsset, + onClickBreakdown, + onClickDeposit, + onClickWithdraw, + onClickTransfer, + isReadOnly, + showDepositButton, + ]); - { - headerName: t('Total'), - type: 'rightAligned', - field: 'total', - headerTooltip: t( - 'The total amount of each asset on this key. Includes used and available collateral.' - ), - tooltipValueGetter: ({ value, data }) => { - if (!value || !data) return null; - return addDecimalsFormatNumber(value, data.asset.decimals); - }, - valueFormatter: ({ - data, - value, - }: VegaValueFormatterParams) => { - if (!data || !value) return '-'; - return addDecimalsFormatNumberQuantum( - value, - data.asset.decimals, - data.asset.quantum - ); - }, - }, - { - colId: 'accounts-actions', - field: 'asset.id', - ...COL_DEFS.actions, - minWidth: showDepositButton ? 130 : COL_DEFS.actions.minWidth, - maxWidth: showDepositButton ? 130 : COL_DEFS.actions.maxWidth, - cellRenderer: ({ - value: assetId, - node, - }: VegaICellRendererParams) => { - if (!assetId) return null; - if (node.rowPinned && node.data?.total === '0') { - return ( - - - - ); - } - return isReadOnly ? null : ( - { - onClickDeposit && onClickDeposit(assetId); - }} - onClickWithdraw={() => { - onClickWithdraw && onClickWithdraw(assetId); - }} - onClickBreakdown={() => { - onClickBreakdown && onClickBreakdown(assetId); - }} - onClickTransfer={() => { - onClickTransfer && onClickTransfer(assetId); - }} - /> - ); - }, - }, - ]; - return defs; - }, [ - onClickAsset, - onClickBreakdown, - onClickDeposit, - onClickWithdraw, - onClickTransfer, - isReadOnly, - showDepositButton, - ]); + const data = rowData?.filter((data) => data.asset.id !== pinnedAsset?.id); - const data = rowData?.filter((data) => data.asset.id !== pinnedAsset?.id); - - return ( - data.asset.id} - ref={ref} - tooltipShowDelay={500} - rowData={data} - defaultColDef={{ - resizable: true, - tooltipComponent: TooltipCellComponent, - sortable: true, - comparator: accountValuesComparator, - }} - columnDefs={colDefs} - getRowHeight={getPinnedAssetRowHeight} - pinnedTopRowData={pinnedRow ? [pinnedRow] : undefined} - /> - ); - } -); + return ( + data.asset.id} + tooltipShowDelay={500} + rowData={data} + defaultColDef={{ + resizable: true, + tooltipComponent: TooltipCellComponent, + sortable: true, + comparator: accountValuesComparator, + }} + columnDefs={colDefs} + getRowHeight={getPinnedAssetRowHeight} + pinnedTopRowData={pinnedRow ? [pinnedRow] : undefined} + /> + ); +}; diff --git a/libs/datagrid/src/index.ts b/libs/datagrid/src/index.ts index 758100e6d..76938986b 100644 --- a/libs/datagrid/src/index.ts +++ b/libs/datagrid/src/index.ts @@ -21,5 +21,4 @@ export * from './lib/type-helpers'; export * from './lib/cells/grid-progress-bar'; -export * from './lib/ag-grid-update'; export * from './lib/use-datagrid-events'; diff --git a/libs/datagrid/src/lib/ag-grid-update.ts b/libs/datagrid/src/lib/ag-grid-update.ts deleted file mode 100644 index f1d1bc98a..000000000 --- a/libs/datagrid/src/lib/ag-grid-update.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { MutableRefObject, RefObject } from 'react'; -import type { AgGridReact } from 'ag-grid-react'; - -type AnyArray = Array | 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, - data: AnyArray, - gridRef: RefObject -) => { - const rerender = isXOrWasEmpty(dataRef.current, data); - dataRef.current = data; - if (gridRef.current?.api?.getModel().getType() === 'infinite') { - gridRef.current?.api?.refreshInfiniteCache(); - } - return !rerender; -}; diff --git a/libs/deposits/src/lib/deposits-table.tsx b/libs/deposits/src/lib/deposits-table.tsx index 2e2771661..43820a479 100644 --- a/libs/deposits/src/lib/deposits-table.tsx +++ b/libs/deposits/src/lib/deposits-table.tsx @@ -1,4 +1,4 @@ -import { forwardRef, useMemo } from 'react'; +import { useMemo } from 'react'; import { addDecimalsFormatNumber, getDateTimeFormat, @@ -6,7 +6,6 @@ import { isNumeric, } from '@vegaprotocol/utils'; import type { ColDef } from 'ag-grid-community'; -import type { AgGridReact } from 'ag-grid-react'; import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid'; import type { VegaICellRendererParams, @@ -17,10 +16,9 @@ import type { DepositFieldsFragment } from './__generated__/Deposit'; import { EtherscanLink } from '@vegaprotocol/environment'; import { DepositStatusMapping } from '@vegaprotocol/types'; -export const DepositsTable = forwardRef< - AgGridReact, - TypedDataAgGrid ->((props, ref) => { +export const DepositsTable = ( + props: TypedDataAgGrid +) => { const columnDefs = useMemo( () => [ { headerName: 'Asset', field: 'asset.symbol' }, @@ -79,11 +77,10 @@ export const DepositsTable = forwardRef< ); return ( ); -}); +}; diff --git a/libs/ledger/src/lib/ledger-manager.tsx b/libs/ledger/src/lib/ledger-manager.tsx index 7aaa7f0cf..1dd4eb490 100644 --- a/libs/ledger/src/lib/ledger-manager.tsx +++ b/libs/ledger/src/lib/ledger-manager.tsx @@ -1,8 +1,7 @@ import { t } from '@vegaprotocol/i18n'; import type * as Schema from '@vegaprotocol/types'; import type { FilterChangedEvent } from 'ag-grid-community'; -import type { AgGridReact } from 'ag-grid-react'; -import { useCallback, useRef, useState, useMemo } from 'react'; +import { useCallback, useState, useMemo } from 'react'; import { subDays, formatRFC3339 } from 'date-fns'; import { ledgerEntriesProvider } from './ledger-entries-data-provider'; import type { LedgerEntriesQueryVariables } from './__generated__/LedgerEntries'; @@ -32,7 +31,6 @@ export const LedgerManager = ({ partyId: string; gridProps: ReturnType; }) => { - const gridRef = useRef(null); const [filter, setFilter] = useState(defaultFilter); const variables = useMemo( @@ -64,7 +62,6 @@ export const LedgerManager = ({ return (
; -export const LedgerTable = forwardRef( - (props, ref) => { - const columnDefs = useMemo( - () => [ - { - headerName: t('Sender'), - field: 'fromAccountPartyId', - cellRenderer: ({ - value, - }: VegaValueFormatterParams) => - truncateByChars(value || ''), +export const LedgerTable = (props: LedgerEntryProps) => { + const columnDefs = useMemo( + () => [ + { + headerName: t('Sender'), + field: 'fromAccountPartyId', + cellRenderer: ({ + value, + }: VegaValueFormatterParams) => + truncateByChars(value || ''), + }, + { + headerName: t('Account type'), + filter: SetFilter, + filterParams: { + set: AccountTypeMapping, }, - { - headerName: t('Account type'), - filter: SetFilter, - filterParams: { - set: AccountTypeMapping, - }, - field: 'fromAccountType', - cellRenderer: ({ - value, - }: VegaValueFormatterParams) => - value ? AccountTypeMapping[value] : '-', + field: 'fromAccountType', + cellRenderer: ({ + value, + }: VegaValueFormatterParams) => + value ? AccountTypeMapping[value] : '-', + }, + { + headerName: t('Market'), + field: 'marketSender.tradableInstrument.instrument.code', + cellRenderer: ({ + value, + }: VegaValueFormatterParams< + LedgerEntry, + 'marketSender.tradableInstrument.instrument.code' + >) => value || '-', + }, + { + headerName: t('Receiver'), + field: 'toAccountPartyId', + cellRenderer: ({ + value, + }: VegaValueFormatterParams) => + truncateByChars(value || ''), + }, + { + headerName: t('Account type'), + filter: SetFilter, + filterParams: { + set: AccountTypeMapping, }, - { - headerName: t('Market'), - field: 'marketSender.tradableInstrument.instrument.code', - cellRenderer: ({ - value, - }: VegaValueFormatterParams< - LedgerEntry, - 'marketSender.tradableInstrument.instrument.code' - >) => value || '-', + field: 'toAccountType', + cellRenderer: ({ + value, + }: VegaValueFormatterParams) => + value ? AccountTypeMapping[value] : '-', + }, + { + headerName: t('Market'), + field: 'marketReceiver.tradableInstrument.instrument.code', + cellRenderer: ({ + value, + }: VegaValueFormatterParams< + LedgerEntry, + 'marketReceiver.tradableInstrument.instrument.code' + >) => value || '-', + }, + { + headerName: t('Transfer type'), + field: 'transferType', + tooltipField: 'transferType', + filter: SetFilter, + filterParams: { + set: TransferTypeMapping, }, - { - headerName: t('Receiver'), - field: 'toAccountPartyId', - cellRenderer: ({ - value, - }: VegaValueFormatterParams) => - truncateByChars(value || ''), + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => + value ? TransferTypeMapping[value] : '', + }, + { + headerName: t('Quantity'), + field: 'quantity', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + const assetDecimalPlaces = data?.asset?.decimals || 0; + return value + ? addDecimalsFormatNumber(value, assetDecimalPlaces) + : ''; }, - { - headerName: t('Account type'), - filter: SetFilter, - filterParams: { - set: AccountTypeMapping, - }, - field: 'toAccountType', - cellRenderer: ({ - value, - }: VegaValueFormatterParams) => - value ? AccountTypeMapping[value] : '-', + }, + { + headerName: t('Asset'), + field: 'assetId', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => + data?.asset?.symbol || '', + }, + { + headerName: t('Sender account balance'), + field: 'fromAccountBalance', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + const assetDecimalPlaces = data?.asset?.decimals || 0; + return value + ? addDecimalsFormatNumber(value, assetDecimalPlaces) + : ''; }, - { - headerName: t('Market'), - field: 'marketReceiver.tradableInstrument.instrument.code', - cellRenderer: ({ - value, - }: VegaValueFormatterParams< - LedgerEntry, - 'marketReceiver.tradableInstrument.instrument.code' - >) => value || '-', + }, + { + headerName: t('Receiver account balance'), + field: 'toAccountBalance', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + const assetDecimalPlaces = data?.asset?.decimals || 0; + return value + ? addDecimalsFormatNumber(value, assetDecimalPlaces) + : ''; }, - { - headerName: t('Transfer type'), - field: 'transferType', - tooltipField: 'transferType', - filter: SetFilter, - filterParams: { - set: TransferTypeMapping, - }, - valueFormatter: ({ - value, - }: VegaValueFormatterParams) => - value ? TransferTypeMapping[value] : '', + }, + { + headerName: t('Vega time'), + field: 'vegaTime', + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => + value ? getDateTimeFormat().format(fromNanoSeconds(value)) : '-', + filterParams: dateRangeFilterParams, + filter: DateRangeFilter, + flex: 1, + }, + ], + [] + ); + return ( + ) => { - const assetDecimalPlaces = data?.asset?.decimals || 0; - return value - ? addDecimalsFormatNumber(value, assetDecimalPlaces) - : ''; - }, - }, - { - headerName: t('Asset'), - field: 'assetId', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => - data?.asset?.symbol || '', - }, - { - headerName: t('Sender account balance'), - field: 'fromAccountBalance', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - const assetDecimalPlaces = data?.asset?.decimals || 0; - return value - ? addDecimalsFormatNumber(value, assetDecimalPlaces) - : ''; - }, - }, - { - headerName: t('Receiver account balance'), - field: 'toAccountBalance', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - const assetDecimalPlaces = data?.asset?.decimals || 0; - return value - ? addDecimalsFormatNumber(value, assetDecimalPlaces) - : ''; - }, - }, - { - headerName: t('Vega time'), - field: 'vegaTime', - valueFormatter: ({ - value, - }: VegaValueFormatterParams) => - value ? getDateTimeFormat().format(fromNanoSeconds(value)) : '-', - filterParams: dateRangeFilterParams, - filter: DateRangeFilter, - flex: 1, - }, - ], - [] - ); - return ( - - ); - } -); + }} + columnDefs={columnDefs} + {...props} + /> + ); +}; diff --git a/libs/markets/src/lib/components/markets-container/market-list-table.tsx b/libs/markets/src/lib/components/markets-container/market-list-table.tsx index f56b03801..51d24e2bd 100644 --- a/libs/markets/src/lib/components/markets-container/market-list-table.tsx +++ b/libs/markets/src/lib/components/markets-container/market-list-table.tsx @@ -1,11 +1,9 @@ -import React, { forwardRef } from 'react'; import type { TypedDataAgGrid } from '@vegaprotocol/datagrid'; import { AgGridLazy as AgGrid, PriceFlashCell, MarketNameCell, } from '@vegaprotocol/datagrid'; -import type { AgGridReact } from 'ag-grid-react'; import type { MarketMaybeWithData } from '../../markets-provider'; import { OracleStatus } from './oracle-status'; import { useColumnDefs } from './use-column-defs'; @@ -43,14 +41,15 @@ const defaultColDef = { filterParams: { buttons: ['reset'] }, minWidth: 100, }; - -export const MarketListTable = forwardRef< - AgGridReact, - TypedDataAgGrid & { - onMarketClick: (marketId: string, metaKey?: boolean) => void; - SuccessorMarketRenderer?: React.FC<{ value: string }>; - } ->(({ onMarketClick, SuccessorMarketRenderer, ...props }, ref) => { +type Props = TypedDataAgGrid & { + onMarketClick: (marketId: string, metaKey?: boolean) => void; + SuccessorMarketRenderer?: React.FC<{ value: string }>; +}; +export const MarketListTable = ({ + onMarketClick, + SuccessorMarketRenderer, + ...props +}: Props) => { const columnDefs = useColumnDefs({ onMarketClick }); const components = { PriceFlashCell, @@ -61,7 +60,6 @@ export const MarketListTable = forwardRef< ); -}); +}; export default MarketListTable; diff --git a/libs/markets/src/lib/components/markets-container/markets-container.tsx b/libs/markets/src/lib/components/markets-container/markets-container.tsx index 3f68d90d5..8a8d39fb9 100644 --- a/libs/markets/src/lib/components/markets-container/markets-container.tsx +++ b/libs/markets/src/lib/components/markets-container/markets-container.tsx @@ -1,6 +1,5 @@ import type { MouseEvent } from 'react'; -import React, { useEffect, useRef } from 'react'; -import type { AgGridReact } from 'ag-grid-react'; +import React, { useEffect } from 'react'; import type { CellClickedEvent } from 'ag-grid-community'; import { t } from '@vegaprotocol/i18n'; import { MarketListTable } from './market-list-table'; @@ -18,8 +17,6 @@ export const MarketsContainer = ({ onSelect, SuccessorMarketRenderer, }: MarketsContainerProps) => { - const gridRef = useRef(null); - const { data, error, reload } = useDataProvider({ dataProvider, variables: undefined, @@ -37,7 +34,6 @@ export const MarketsContainer = ({ return (
{ const { data, column, event } = cellEvent; diff --git a/libs/orders/src/lib/components/stop-orders-manager/stop-orders-manager.spec.tsx b/libs/orders/src/lib/components/stop-orders-manager/stop-orders-manager.spec.tsx index d2b443271..47ada0edd 100644 --- a/libs/orders/src/lib/components/stop-orders-manager/stop-orders-manager.spec.tsx +++ b/libs/orders/src/lib/components/stop-orders-manager/stop-orders-manager.spec.tsx @@ -2,17 +2,13 @@ import { render, screen, act } from '@testing-library/react'; import { StopOrdersManager } from './stop-orders-manager'; import * as useDataProviderHook from '@vegaprotocol/data-provider'; import type { StopOrder } from '../order-data-provider/stop-orders-data-provider'; -import * as stopOrdersTableMock from '../stop-orders-table/stop-orders-table'; -import { forwardRef } from 'react'; import type { VegaWalletContextShape } from '@vegaprotocol/wallet'; import { VegaWalletContext } from '@vegaprotocol/wallet'; import { MockedProvider } from '@apollo/client/testing'; -// @ts-ignore StopOrdersTable is read only but we need to override with the forwardRef to -// avoid warnings about padding refs -stopOrdersTableMock.StopOrdersTable = forwardRef(() => ( -
StopOrdersTable
-)); +jest.mock('../stop-orders-table/stop-orders-table', () => ({ + StopOrdersTable: () =>
StopOrdersTable
, +})); const generateJsx = () => { const pubKey = '0x123'; diff --git a/libs/orders/src/lib/components/stop-orders-table/stop-orders-table.tsx b/libs/orders/src/lib/components/stop-orders-table/stop-orders-table.tsx index ca7f47a09..9ae5d7c89 100644 --- a/libs/orders/src/lib/components/stop-orders-table/stop-orders-table.tsx +++ b/libs/orders/src/lib/components/stop-orders-table/stop-orders-table.tsx @@ -8,7 +8,7 @@ import { t } from '@vegaprotocol/i18n'; import * as Schema from '@vegaprotocol/types'; import { ButtonLink } from '@vegaprotocol/ui-toolkit'; import type { ForwardedRef } from 'react'; -import { memo, forwardRef, useMemo } from 'react'; +import { memo, useMemo } from 'react'; import { AgGridLazy as AgGrid, SetFilter, @@ -36,265 +36,252 @@ export type StopOrdersTableProps = TypedDataAgGrid & { export const StopOrdersTable = memo< StopOrdersTableProps & { ref?: ForwardedRef } ->( - forwardRef( - ({ onCancel, onMarketClick, ...props }, ref) => { - const showAllActions = !props.isReadOnly; - const columnDefs: ColDef[] = useMemo( - () => [ - { - headerName: t('Market'), - field: 'market.tradableInstrument.instrument.code', - cellRenderer: 'MarketNameCell', - cellRendererParams: { idPath: 'market.id', onMarketClick }, - minWidth: 150, - }, - { - headerName: t('Trigger'), - field: 'trigger', - cellClass: 'font-mono text-right', - type: 'rightAligned', - sortable: false, - valueFormatter: ({ - data, - value, - }: VegaValueFormatterParams): string => { - if (data && value?.__typename === 'StopOrderPrice') { - return `${t('Mark')} ${ - data?.triggerDirection === - Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW - ? '<' - : '>' - } ${addDecimalsFormatNumber( - value.price, - data.market.decimalPlaces - )}`; - } - if ( - data && - value?.__typename === 'StopOrderTrailingPercentOffset' - ) { - return `${t('Mark')} ${ - data?.triggerDirection === - Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW - ? '+' - : '-' - }${(Number(value.trailingPercentOffset) * 100).toFixed(1)}%`; - } - return '-'; - }, - minWidth: 100, - }, - { - field: 'expiresAt', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - if ( - data && - value && - data?.expiryStrategy !== - Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_UNSPECIFIED - ) { - const expiresAt = getDateTimeFormat().format(new Date(value)); - const expiryStrategy = - data.expiryStrategy === - Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_SUBMIT - ? t('Submit') - : t('Cancels'); - return `${expiryStrategy} ${expiresAt}`; - } - return ''; - }, - minWidth: 150, - }, - { - headerName: t('Size'), - field: 'submission.size', - cellClass: 'font-mono text-right', - type: 'rightAligned', - cellClassRules: { - [positiveClassNames]: ({ data }: { data: StopOrder }) => - data?.submission.size === Schema.Side.SIDE_BUY, - [negativeClassNames]: ({ data }: { data: StopOrder }) => - data?.submission.size === Schema.Side.SIDE_SELL, - }, - valueGetter: ({ data }: VegaValueGetterParams) => { - return data?.submission.size && data.market - ? toBigNum( - data.submission.size, - data.market.positionDecimalPlaces ?? 0 - ) - .multipliedBy( - data.submission.side === Schema.Side.SIDE_SELL ? -1 : 1 - ) - .toNumber() - : undefined; - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => { - if (!data) { - return ''; - } - if (!data?.market || !isNumeric(data.submission.size)) { - return '-'; - } - const prefix = data - ? data.submission.side === Schema.Side.SIDE_BUY - ? '+' - : '-' - : ''; - return ( - prefix + - addDecimalsFormatNumber( - data.submission.size, - data.market.positionDecimalPlaces +>(({ onCancel, onMarketClick, ...props }: StopOrdersTableProps) => { + const showAllActions = !props.isReadOnly; + const columnDefs: ColDef[] = useMemo( + () => [ + { + headerName: t('Market'), + field: 'market.tradableInstrument.instrument.code', + cellRenderer: 'MarketNameCell', + cellRendererParams: { idPath: 'market.id', onMarketClick }, + minWidth: 150, + }, + { + headerName: t('Trigger'), + field: 'trigger', + cellClass: 'font-mono text-right', + type: 'rightAligned', + sortable: false, + valueFormatter: ({ + data, + value, + }: VegaValueFormatterParams): string => { + if (data && value?.__typename === 'StopOrderPrice') { + return `${t('Mark')} ${ + data?.triggerDirection === + Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW + ? '<' + : '>' + } ${addDecimalsFormatNumber( + value.price, + data.market.decimalPlaces + )}`; + } + if (data && value?.__typename === 'StopOrderTrailingPercentOffset') { + return `${t('Mark')} ${ + data?.triggerDirection === + Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW + ? '+' + : '-' + }${(Number(value.trailingPercentOffset) * 100).toFixed(1)}%`; + } + return '-'; + }, + minWidth: 100, + }, + { + field: 'expiresAt', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + if ( + data && + value && + data?.expiryStrategy !== + Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_UNSPECIFIED + ) { + const expiresAt = getDateTimeFormat().format(new Date(value)); + const expiryStrategy = + data.expiryStrategy === + Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_SUBMIT + ? t('Submit') + : t('Cancels'); + return `${expiryStrategy} ${expiresAt}`; + } + return ''; + }, + minWidth: 150, + }, + { + headerName: t('Size'), + field: 'submission.size', + cellClass: 'font-mono text-right', + type: 'rightAligned', + cellClassRules: { + [positiveClassNames]: ({ data }: { data: StopOrder }) => + data?.submission.size === Schema.Side.SIDE_BUY, + [negativeClassNames]: ({ data }: { data: StopOrder }) => + data?.submission.size === Schema.Side.SIDE_SELL, + }, + valueGetter: ({ data }: VegaValueGetterParams) => { + return data?.submission.size && data.market + ? toBigNum( + data.submission.size, + data.market.positionDecimalPlaces ?? 0 + ) + .multipliedBy( + data.submission.side === Schema.Side.SIDE_SELL ? -1 : 1 ) - ); - }, - minWidth: 80, - }, - { - field: 'submission.type', - filter: SetFilter, - filterParams: { - set: Schema.OrderTypeMapping, - }, - cellRenderer: ({ - value, - }: VegaICellRendererParams) => - value ? Schema.OrderTypeMapping[value] : '', - minWidth: 80, - }, - { - field: 'status', - filter: SetFilter, - filterParams: { - set: Schema.StopOrderStatusMapping, - }, - valueFormatter: ({ - value, - }: VegaValueFormatterParams) => { - return value ? Schema.StopOrderStatusMapping[value] : ''; - }, - cellRenderer: ({ - valueFormatted, - data, - }: { - valueFormatted: string; - data: StopOrder; - }) => ( - - {valueFormatted} - - ), - minWidth: 100, - }, - { - field: 'submission.price', - type: 'rightAligned', - cellClass: 'font-mono text-right', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - if (!data) { - return ''; - } - if ( - !data?.market || - data.submission.type === Schema.OrderType.TYPE_MARKET || - !isNumeric(value) - ) { - return '-'; - } - return addDecimalsFormatNumber(value, data.market.decimalPlaces); - }, - minWidth: 100, - }, - { - field: 'submission.timeInForce', - filter: SetFilter, - filterParams: { - set: Schema.OrderTimeInForceMapping, - }, - valueFormatter: ({ - value, - }: VegaValueFormatterParams< - StopOrder, - 'submission.timeInForce' - >) => { - return value ? Schema.OrderTimeInForceCode[value] : ''; - }, - minWidth: 150, - }, - { - field: 'updatedAt', - filter: DateRangeFilter, - valueGetter: ({ data }: VegaValueGetterParams) => - data?.updatedAt || data?.createdAt, - cellRenderer: ({ - data, - }: VegaICellRendererParams) => { - if (!data) { - return undefined; - } - const value = data.updatedAt || data.createdAt; - return ( - - {value ? getDateTimeFormat().format(new Date(value)) : '-'} - - ); - }, - minWidth: 150, - }, - { - colId: 'actions', - ...COL_DEFS.actions, - minWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth, - maxWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth, - cellRenderer: ({ data }: { data?: StopOrder }) => { - if (!data) return null; + .toNumber() + : undefined; + }, + valueFormatter: ({ + data, + }: VegaValueFormatterParams) => { + if (!data) { + return ''; + } + if (!data?.market || !isNumeric(data.submission.size)) { + return '-'; + } + const prefix = data + ? data.submission.side === Schema.Side.SIDE_BUY + ? '+' + : '-' + : ''; + return ( + prefix + + addDecimalsFormatNumber( + data.submission.size, + data.market.positionDecimalPlaces + ) + ); + }, + minWidth: 80, + }, + { + field: 'submission.type', + filter: SetFilter, + filterParams: { + set: Schema.OrderTypeMapping, + }, + cellRenderer: ({ + value, + }: VegaICellRendererParams) => + value ? Schema.OrderTypeMapping[value] : '', + minWidth: 80, + }, + { + field: 'status', + filter: SetFilter, + filterParams: { + set: Schema.StopOrderStatusMapping, + }, + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => { + return value ? Schema.StopOrderStatusMapping[value] : ''; + }, + cellRenderer: ({ + valueFormatted, + data, + }: { + valueFormatted: string; + data: StopOrder; + }) => ( + {valueFormatted} + ), + minWidth: 100, + }, + { + field: 'submission.price', + type: 'rightAligned', + cellClass: 'font-mono text-right', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + if (!data) { + return ''; + } + if ( + !data?.market || + data.submission.type === Schema.OrderType.TYPE_MARKET || + !isNumeric(value) + ) { + return '-'; + } + return addDecimalsFormatNumber(value, data.market.decimalPlaces); + }, + minWidth: 100, + }, + { + field: 'submission.timeInForce', + filter: SetFilter, + filterParams: { + set: Schema.OrderTimeInForceMapping, + }, + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => { + return value ? Schema.OrderTimeInForceCode[value] : ''; + }, + minWidth: 150, + }, + { + field: 'updatedAt', + filter: DateRangeFilter, + valueGetter: ({ data }: VegaValueGetterParams) => + data?.updatedAt || data?.createdAt, + cellRenderer: ({ + data, + }: VegaICellRendererParams) => { + if (!data) { + return undefined; + } + const value = data.updatedAt || data.createdAt; + return ( + + {value ? getDateTimeFormat().format(new Date(value)) : '-'} + + ); + }, + minWidth: 150, + }, + { + colId: 'actions', + ...COL_DEFS.actions, + minWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth, + maxWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth, + cellRenderer: ({ data }: { data?: StopOrder }) => { + if (!data) return null; - return ( -
- {data.status === Schema.StopOrderStatus.STATUS_PENDING && - !props.isReadOnly && ( - onCancel(data)} - > - {t('Cancel')} - - )} -
- ); - }, - }, - ], - [onCancel, onMarketClick, props.isReadOnly, showAllActions] - ); + return ( +
+ {data.status === Schema.StopOrderStatus.STATUS_PENDING && + !props.isReadOnly && ( + onCancel(data)} + > + {t('Cancel')} + + )} +
+ ); + }, + }, + ], + [onCancel, onMarketClick, props.isReadOnly, showAllActions] + ); - return ( - data.id} - components={{ MarketNameCell }} - {...props} - /> - ); - } - ) -); + return ( + data.id} + components={{ MarketNameCell }} + {...props} + /> + ); +}); diff --git a/libs/positions/src/lib/positions-table.tsx b/libs/positions/src/lib/positions-table.tsx index 3825c8ed1..57da4f504 100644 --- a/libs/positions/src/lib/positions-table.tsx +++ b/libs/positions/src/lib/positions-table.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import { forwardRef, useMemo } from 'react'; +import { useMemo } from 'react'; import type { CSSProperties, ReactNode } from 'react'; import type { ColDef } from 'ag-grid-community'; import type { @@ -33,7 +33,6 @@ import { addDecimalsFormatNumber, } from '@vegaprotocol/utils'; import { t } from '@vegaprotocol/i18n'; -import type { AgGridReact } from 'ag-grid-react'; import type { Position } from './positions-data-providers'; import * as Schema from '@vegaprotocol/types'; import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types'; @@ -87,383 +86,367 @@ AmountCell.displayName = 'AmountCell'; export const getRowId = ({ data }: { data: Position }) => `${data.partyId}-${data.marketId}`; -export const PositionsTable = forwardRef( - ( - { - onClose, - onMarketClick, - multipleKeys, - isReadOnly, - pubKeys, - pubKey, - ...props - }, - ref - ) => { - const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); - return ( - (() => { - const columnDefs: (ColDef | null)[] = [ - multipleKeys - ? { - headerName: t('Vega key'), - field: 'partyId', - valueGetter: ({ data }: VegaValueGetterParams) => - (data?.partyId && - pubKeys && - pubKeys.find((key) => key.publicKey === data.partyId) - ?.name) || - data?.partyId, - minWidth: 190, - } - : null, - { - headerName: t('Market'), - field: 'marketName', - cellRenderer: 'MarketNameCell', - cellRendererParams: { idPath: 'marketId', onMarketClick }, - minWidth: 190, +export const PositionsTable = ({ + onClose, + onMarketClick, + multipleKeys, + isReadOnly, + pubKeys, + pubKey, + ...props +}: Props) => { + const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); + return ( + (() => { + const columnDefs: (ColDef | null)[] = [ + multipleKeys + ? { + headerName: t('Vega key'), + field: 'partyId', + valueGetter: ({ data }: VegaValueGetterParams) => + (data?.partyId && + pubKeys && + pubKeys.find((key) => key.publicKey === data.partyId) + ?.name) || + data?.partyId, + minWidth: 190, + } + : null, + { + headerName: t('Market'), + field: 'marketName', + cellRenderer: 'MarketNameCell', + cellRendererParams: { idPath: 'marketId', onMarketClick }, + minWidth: 190, + }, + { + headerName: t('Notional'), + headerTooltip: t('Mark price x open volume.'), + field: 'notional', + type: 'rightAligned', + cellClass: 'font-mono text-right', + filter: 'agNumberColumnFilter', + valueGetter: ({ data }: VegaValueGetterParams) => { + return !data?.notional + ? undefined + : toBigNum(data.notional, data.marketDecimalPlaces).toNumber(); }, - { - headerName: t('Notional'), - headerTooltip: t('Mark price x open volume.'), - field: 'notional', - type: 'rightAligned', - cellClass: 'font-mono text-right', - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - return !data?.notional - ? undefined - : toBigNum( - data.notional, - data.marketDecimalPlaces - ).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => { - return !data || !data.notional - ? '-' - : addDecimalsFormatNumber( - data.notional, - data.marketDecimalPlaces - ); - }, - minWidth: 80, + valueFormatter: ({ + data, + }: VegaValueFormatterParams) => { + return !data || !data.notional + ? '-' + : addDecimalsFormatNumber( + data.notional, + data.marketDecimalPlaces + ); }, - { - headerName: t('Open volume'), - field: 'openVolume', - type: 'rightAligned', - cellClass: 'font-mono text-right', - cellClassRules: signedNumberCssClassRules, - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - return data?.openVolume === undefined - ? undefined - : toBigNum( - data?.openVolume, + minWidth: 80, + }, + { + headerName: t('Open volume'), + field: 'openVolume', + type: 'rightAligned', + cellClass: 'font-mono text-right', + cellClassRules: signedNumberCssClassRules, + filter: 'agNumberColumnFilter', + valueGetter: ({ data }: VegaValueGetterParams) => { + return data?.openVolume === undefined + ? undefined + : toBigNum( + data?.openVolume, + data.positionDecimalPlaces + ).toNumber(); + }, + valueFormatter: ({ + data, + }: VegaValueFormatterParams): string => { + return data?.openVolume === undefined + ? '' + : volumePrefix( + addDecimalsFormatNumber( + data.openVolume, data.positionDecimalPlaces - ).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams): string => { - return data?.openVolume === undefined - ? '' - : volumePrefix( - addDecimalsFormatNumber( - data.openVolume, - data.positionDecimalPlaces - ) + ) + ); + }, + cellRenderer: OpenVolumeCell, + minWidth: 100, + }, + { + headerName: t('Mark price'), + field: 'markPrice', + type: 'rightAligned', + cellRenderer: PriceFlashCell, + filter: 'agNumberColumnFilter', + valueGetter: ({ data }: VegaValueGetterParams) => { + return !data || + !data.markPrice || + data.marketTradingMode === + Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION + ? undefined + : toBigNum(data.markPrice, data.marketDecimalPlaces).toNumber(); + }, + valueFormatter: ({ + data, + }: VegaValueFormatterParams) => { + if (!data) { + return ''; + } + if ( + !data.markPrice || + data.marketTradingMode === + Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION + ) { + return '-'; + } + return addDecimalsFormatNumber( + data.markPrice, + data.marketDecimalPlaces + ); + }, + minWidth: 100, + }, + { + headerName: t('Liquidation price'), + colId: 'liquidationPrice', + type: 'rightAligned', + cellRenderer: ({ data }: VegaICellRendererParams) => { + if (!data) return null; + return ( + + ); + }, + }, + { + headerName: t('Settlement asset'), + field: 'assetSymbol', + colId: 'asset', + minWidth: 100, + cellRenderer: ({ data }: VegaICellRendererParams) => { + if (!data) return null; + return ( + { + openAssetDetailsDialog( + data.assetId, + e.target as HTMLElement ); - }, - cellRenderer: OpenVolumeCell, - minWidth: 100, + }} + > + {data?.assetSymbol} + + ); }, - { - headerName: t('Mark price'), - field: 'markPrice', - type: 'rightAligned', - cellRenderer: PriceFlashCell, - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - return !data || - !data.markPrice || - data.marketTradingMode === - Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION - ? undefined - : toBigNum( - data.markPrice, - data.marketDecimalPlaces - ).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => { - if (!data) { - return ''; - } - if ( - !data.markPrice || - data.marketTradingMode === - Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION - ) { - return '-'; - } - return addDecimalsFormatNumber( - data.markPrice, - data.marketDecimalPlaces - ); - }, - minWidth: 100, + }, + { + headerName: t('Entry price'), + field: 'averageEntryPrice', + type: 'rightAligned', + cellRenderer: PriceFlashCell, + filter: 'agNumberColumnFilter', + valueGetter: ({ data }: VegaValueGetterParams) => { + return data?.markPrice === undefined || !data + ? undefined + : toBigNum( + data.averageEntryPrice, + data.marketDecimalPlaces + ).toNumber(); }, - { - headerName: t('Liquidation price'), - colId: 'liquidationPrice', - type: 'rightAligned', - cellRenderer: ({ data }: VegaICellRendererParams) => { - if (!data) return null; - return ( - - ); - }, + valueFormatter: ({ + data, + }: VegaValueFormatterParams< + Position, + 'averageEntryPrice' + >): string => { + if (!data) { + return ''; + } + return addDecimalsFormatNumber( + data.averageEntryPrice, + data.marketDecimalPlaces + ); }, - { - headerName: t('Settlement asset'), - field: 'assetSymbol', - colId: 'asset', - minWidth: 100, - cellRenderer: ({ data }: VegaICellRendererParams) => { - if (!data) return null; - return ( - { - openAssetDetailsDialog( - data.assetId, - e.target as HTMLElement - ); - }} - > - {data?.assetSymbol} - - ); + minWidth: 100, + }, + multipleKeys + ? null + : { + headerName: t('Leverage'), + field: 'currentLeverage', + type: 'rightAligned', + filter: 'agNumberColumnFilter', + cellRenderer: PriceFlashCell, + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => + value === undefined ? '' : formatNumber(value.toString(), 1), + minWidth: 100, }, - }, - { - headerName: t('Entry price'), - field: 'averageEntryPrice', - type: 'rightAligned', - cellRenderer: PriceFlashCell, - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - return data?.markPrice === undefined || !data - ? undefined - : toBigNum( - data.averageEntryPrice, - data.marketDecimalPlaces - ).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams< - Position, - 'averageEntryPrice' - >): string => { - if (!data) { - return ''; - } - return addDecimalsFormatNumber( - data.averageEntryPrice, - data.marketDecimalPlaces - ); - }, - minWidth: 100, - }, - multipleKeys - ? null - : { - headerName: t('Leverage'), - field: 'currentLeverage', - type: 'rightAligned', - filter: 'agNumberColumnFilter', - cellRenderer: PriceFlashCell, - valueFormatter: ({ - value, - }: VegaValueFormatterParams) => - value === undefined - ? '' - : formatNumber(value.toString(), 1), - minWidth: 100, + multipleKeys + ? null + : { + headerName: t('Margin allocated'), + field: 'marginAccountBalance', + type: 'rightAligned', + filter: 'agNumberColumnFilter', + cellRenderer: PriceFlashCell, + valueGetter: ({ data }: VegaValueGetterParams) => { + return !data + ? undefined + : toBigNum( + data.marginAccountBalance, + data.decimals + ).toNumber(); }, - multipleKeys - ? null - : { - headerName: t('Margin allocated'), - field: 'marginAccountBalance', - type: 'rightAligned', - filter: 'agNumberColumnFilter', - cellRenderer: PriceFlashCell, - valueGetter: ({ data }: VegaValueGetterParams) => { - return !data - ? undefined - : toBigNum( - data.marginAccountBalance, - data.decimals - ).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams< - Position, - 'marginAccountBalance' - >): string => { - if (!data) { - return ''; - } - return addDecimalsFormatNumber( - data.marginAccountBalance, - data.decimals - ); - }, - minWidth: 100, + valueFormatter: ({ + data, + }: VegaValueFormatterParams< + Position, + 'marginAccountBalance' + >): string => { + if (!data) { + return ''; + } + return addDecimalsFormatNumber( + data.marginAccountBalance, + data.decimals + ); }, - { - headerName: t('Realised PNL'), - field: 'realisedPNL', - type: 'rightAligned', - cellClassRules: signedNumberCssClassRules, - cellClass: 'font-mono text-right', - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - return !data - ? undefined - : toBigNum(data.realisedPNL, data.decimals).toNumber(); + minWidth: 100, }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => { - return !data - ? '' - : addDecimalsFormatNumber(data.realisedPNL, data.decimals); - }, - headerTooltip: t( - 'Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.' - ), - cellRenderer: PNLCell, - minWidth: 100, + { + headerName: t('Realised PNL'), + field: 'realisedPNL', + type: 'rightAligned', + cellClassRules: signedNumberCssClassRules, + cellClass: 'font-mono text-right', + filter: 'agNumberColumnFilter', + valueGetter: ({ data }: VegaValueGetterParams) => { + return !data + ? undefined + : toBigNum(data.realisedPNL, data.decimals).toNumber(); }, - { - headerName: t('Unrealised PNL'), - field: 'unrealisedPNL', - type: 'rightAligned', - cellClassRules: signedNumberCssClassRules, - cellClass: 'font-mono text-right', - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - return !data - ? undefined - : toBigNum(data.unrealisedPNL, data.decimals).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => - !data - ? '' - : addDecimalsFormatNumber(data.unrealisedPNL, data.decimals), - headerTooltip: t( - 'Unrealised profit is the current profit on your open position. Margin is still allocated to your position.' - ), - cellRenderer: PNLCell, - minWidth: 100, + valueFormatter: ({ + data, + }: VegaValueFormatterParams) => { + return !data + ? '' + : addDecimalsFormatNumber(data.realisedPNL, data.decimals); }, - { - headerName: t('Updated'), - field: 'updatedAt', - type: 'rightAligned', - filter: DateRangeFilter, - valueFormatter: ({ - value, - }: VegaValueFormatterParams) => { - if (!value) { - return ''; - } - return getDateTimeFormat().format(new Date(value)); - }, - minWidth: 150, + headerTooltip: t( + 'Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.' + ), + cellRenderer: PNLCell, + minWidth: 100, + }, + { + headerName: t('Unrealised PNL'), + field: 'unrealisedPNL', + type: 'rightAligned', + cellClassRules: signedNumberCssClassRules, + cellClass: 'font-mono text-right', + filter: 'agNumberColumnFilter', + valueGetter: ({ data }: VegaValueGetterParams) => { + return !data + ? undefined + : toBigNum(data.unrealisedPNL, data.decimals).toNumber(); }, - onClose && !isReadOnly - ? { - ...COL_DEFS.actions, - cellRenderer: ({ - data, - }: VegaICellRendererParams) => { - return ( -
- {data?.openVolume && - data?.openVolume !== '0' && - data.partyId === pubKey ? ( - data && onClose(data)} - > - {t('Close')} - - ) : null} - {data?.assetId && ( - - )} -
- ); - }, - minWidth: 90, - maxWidth: 90, - } - : null, - ]; - return columnDefs.filter( - (colDef: ColDef | null): colDef is ColDef => colDef !== null - ); - }, [ - isReadOnly, - multipleKeys, - onClose, - onMarketClick, - openAssetDetailsDialog, - pubKey, - pubKeys, - ])} - /> - ); - } -); + valueFormatter: ({ + data, + }: VegaValueFormatterParams) => + !data + ? '' + : addDecimalsFormatNumber(data.unrealisedPNL, data.decimals), + headerTooltip: t( + 'Unrealised profit is the current profit on your open position. Margin is still allocated to your position.' + ), + cellRenderer: PNLCell, + minWidth: 100, + }, + { + headerName: t('Updated'), + field: 'updatedAt', + type: 'rightAligned', + filter: DateRangeFilter, + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => { + if (!value) { + return ''; + } + return getDateTimeFormat().format(new Date(value)); + }, + minWidth: 150, + }, + onClose && !isReadOnly + ? { + ...COL_DEFS.actions, + cellRenderer: ({ data }: VegaICellRendererParams) => { + return ( +
+ {data?.openVolume && + data?.openVolume !== '0' && + data.partyId === pubKey ? ( + data && onClose(data)} + > + {t('Close')} + + ) : null} + {data?.assetId && ( + + )} +
+ ); + }, + minWidth: 90, + maxWidth: 90, + } + : null, + ]; + return columnDefs.filter( + (colDef: ColDef | null): colDef is ColDef => colDef !== null + ); + }, [ + isReadOnly, + multipleKeys, + onClose, + onMarketClick, + openAssetDetailsDialog, + pubKey, + pubKeys, + ])} + /> + ); +}; export default PositionsTable; diff --git a/libs/proposals/src/components/proposals-list/proposals-list.tsx b/libs/proposals/src/components/proposals-list/proposals-list.tsx index 90fca13d3..fec75c5b4 100644 --- a/libs/proposals/src/components/proposals-list/proposals-list.tsx +++ b/libs/proposals/src/components/proposals-list/proposals-list.tsx @@ -1,9 +1,7 @@ import React from 'react'; -import { useRef } from 'react'; import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid'; import { t } from '@vegaprotocol/i18n'; import * as Types from '@vegaprotocol/types'; -import type { AgGridReact } from 'ag-grid-react'; import { useColumnDefs } from './use-column-defs'; import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals'; import { useProposalsListQuery } from '../../lib/proposals-data-provider/__generated__/Proposals'; @@ -25,7 +23,6 @@ interface ProposalListProps { export const ProposalsList = ({ SuccessorMarketRenderer, }: ProposalListProps) => { - const gridRef = useRef(null); const { data } = useProposalsListQuery({ variables: { proposalType: Types.ProposalType.TYPE_NEW_MARKET, @@ -40,7 +37,6 @@ export const ProposalsList = ({ return (
{ - const gridRef = useRef(null); const useOrderStoreRef = useCreateOrderStore(); const updateOrder = useOrderStoreRef((store) => store.update); @@ -22,7 +19,6 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => { return ( { if (price) { diff --git a/libs/trades/src/lib/trades-table.tsx b/libs/trades/src/lib/trades-table.tsx index e3d5fca09..67e965a4a 100644 --- a/libs/trades/src/lib/trades-table.tsx +++ b/libs/trades/src/lib/trades-table.tsx @@ -1,7 +1,5 @@ -import type { AgGridReact } from 'ag-grid-react'; import { useMemo } from 'react'; import type { ColDef } from 'ag-grid-community'; -import { forwardRef } from 'react'; import type { VegaICellRendererParams, VegaValueFormatterParams, @@ -48,90 +46,87 @@ interface Props extends AgGridReactProps { onClick?: (price?: string) => void; } -export const TradesTable = forwardRef( - ({ onClick, ...props }, ref) => { - const columnDefs = useMemo( - () => [ - { - headerName: t('Price'), - field: 'price', - type: 'rightAligned', - width: 130, - cellClass: changeCellClass, - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - if (!value || !data?.market) { - return ''; - } - return addDecimalsFormatNumber(value, data.market.decimalPlaces); - }, - cellRenderer: ({ - value, - data, - }: VegaICellRendererParams) => { - if (!data?.market || !value) { - return ''; - } - return ( - - ); - }, +export const TradesTable = ({ onClick, ...props }: Props) => { + const columnDefs = useMemo( + () => [ + { + headerName: t('Price'), + field: 'price', + type: 'rightAligned', + width: 130, + cellClass: changeCellClass, + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + if (!value || !data?.market) { + return ''; + } + return addDecimalsFormatNumber(value, data.market.decimalPlaces); }, - { - headerName: t('Size'), - field: 'size', - width: 125, - type: 'rightAligned', - valueFormatter: ({ - value, - data, - }: VegaValueFormatterParams) => { - if (!value || !data?.market) { - return ''; - } - return addDecimalsFormatNumber( - value, - data.market.positionDecimalPlaces - ); - }, - cellRenderer: NumericCell, + cellRenderer: ({ + value, + data, + }: VegaICellRendererParams) => { + if (!data?.market || !value) { + return ''; + } + return ( + + ); }, - { - headerName: t('Created at'), - field: 'createdAt', - type: 'rightAligned', - width: 170, - cellClass: 'text-right', - valueFormatter: ({ + }, + { + headerName: t('Size'), + field: 'size', + width: 125, + type: 'rightAligned', + valueFormatter: ({ + value, + data, + }: VegaValueFormatterParams) => { + if (!value || !data?.market) { + return ''; + } + return addDecimalsFormatNumber( value, - }: VegaValueFormatterParams) => { - return value && getDateTimeFormat().format(new Date(value)); - }, + data.market.positionDecimalPlaces + ); }, - ], - [onClick] - ); - return ( - data.id} - ref={ref} - defaultColDef={{ - flex: 1, - }} - columnDefs={columnDefs} - {...props} - /> - ); - } -); + cellRenderer: NumericCell, + }, + { + headerName: t('Created at'), + field: 'createdAt', + type: 'rightAligned', + width: 170, + cellClass: 'text-right', + valueFormatter: ({ + value, + }: VegaValueFormatterParams) => { + return value && getDateTimeFormat().format(new Date(value)); + }, + }, + ], + [onClick] + ); + return ( + data.id} + defaultColDef={{ + flex: 1, + }} + columnDefs={columnDefs} + {...props} + /> + ); +}; diff --git a/libs/withdraws/src/lib/withdrawals-table.tsx b/libs/withdraws/src/lib/withdrawals-table.tsx index f5bbc2de2..8b22e6164 100644 --- a/libs/withdraws/src/lib/withdrawals-table.tsx +++ b/libs/withdraws/src/lib/withdrawals-table.tsx @@ -1,5 +1,4 @@ import { useEffect, useRef, useState, useMemo } from 'react'; -import type { AgGridReact } from 'ag-grid-react'; import type { ColDef } from 'ag-grid-community'; import { addDecimalsFormatNumber, @@ -40,7 +39,6 @@ export const WithdrawalsTable = ({ ready?: TimestampedWithdrawals; delayed?: TimestampedWithdrawals; }) => { - const gridRef = useRef(null); const createWithdrawApproval = useEthWithdrawApprovalsStore( (store) => store.create ); @@ -146,7 +144,6 @@ export const WithdrawalsTable = ({ CompleteCell, }} suppressCellFocus - ref={gridRef} {...props} /> );