import { forwardRef, useMemo, useState } from 'react'; import { addDecimalsFormatNumber, isNumeric, toBigNum, } from '@vegaprotocol/utils'; import { t } from '@vegaprotocol/i18n'; import type { VegaICellRendererParams, VegaValueFormatterParams, } from '@vegaprotocol/datagrid'; import { Button, ButtonLink, Dialog } from '@vegaprotocol/ui-toolkit'; import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit'; import { AgGridDynamic as AgGrid, CenteredGridCellWrapper, } from '@vegaprotocol/datagrid'; import { AgGridColumn } from 'ag-grid-react'; 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 { successCallback(rowsThisBlock: AccountFields[], lastRow?: number): void; } export interface Datasource extends IDatasource { getRows(params: GetRowsParams): void; } export type PinnedAsset = Pick; export interface AccountTableProps extends AgGridReactProps { rowData?: AccountFields[] | null; datasource?: Datasource; onClickAsset: (assetId: string) => void; onClickWithdraw?: (assetId: string) => void; onClickDeposit?: (assetId: string) => void; isReadOnly: boolean; pinnedAsset?: PinnedAsset; } export const AccountTable = forwardRef( ({ onClickAsset, onClickWithdraw, onClickDeposit, ...props }, ref) => { const [openBreakdown, setOpenBreakdown] = useState(false); const [row, setRow] = useState(); const pinnedAssetId = props.pinnedAsset?.id; const pinnedAssetRow = useMemo(() => { const currentPinnedAssetRow = props.rowData?.find( (row) => row.asset.id === pinnedAssetId ); if (!currentPinnedAssetRow) { if (props.pinnedAsset) { return { asset: props.pinnedAsset, available: '0', used: '0', total: '0', balance: '0', }; } } return undefined; }, [pinnedAssetId, props.pinnedAsset, props.rowData]); return ( <> data.asset.id} ref={ref} tooltipShowDelay={500} defaultColDef={{ flex: 1, resizable: true, tooltipComponent: TooltipCellComponent, sortable: true, comparator: accountValuesComparator, }} {...props} pinnedTopRowData={pinnedAssetRow ? [pinnedAssetRow] : undefined} > ) => { return ( { if (data) { onClickAsset(data.asset.id); } }} > {value} ); }} maxWidth={300} /> ) => { if (!data) return null; const percentageUsed = percentageValue(value, data.total); const valueFormatted = formatWithAssetDecimals(data, value); return data.breakdown ? ( <> { setOpenBreakdown(!openBreakdown); setRow(data); }} > {valueFormatted} {percentageUsed.toFixed(2)}% ) : ( <> {valueFormatted} 0.00% ); }} /> ) => { const percentageUsed = percentageValue(data?.used, data?.total); return ( {formatWithAssetDecimals(data, value)} ); }} /> ) => formatWithAssetDecimals(data, data?.total) } /> { ) => { if (!data) return null; else { if ( data.asset.id === pinnedAssetId && new BigNumber(data.total).isLessThanOrEqualTo(0) ) { return ( ); } return ( <> {!props.isReadOnly && ( { onClickDeposit && onClickDeposit(data.asset.id); }} > {t('Deposit')} )} {!props.isReadOnly && ( onClickWithdraw && onClickWithdraw(data.asset.id) } > {t('Withdraw')} )} ); } }} /> }

{row?.asset?.symbol} {t('usage breakdown')}

{row && (

{t('You have %s %s in total.', [ addDecimalsFormatNumber(row.total, row.asset.decimals), row.asset.symbol, ])}

)}
); } );