fix: #847 add styling fixes

This commit is contained in:
Madalina Raicu 2022-09-19 17:12:40 +01:00
parent b589f627d9
commit 6bd2b15423
No known key found for this signature in database
GPG Key ID: 688B7B31149C1DCD
4 changed files with 194 additions and 66 deletions

View File

@ -25,6 +25,7 @@ interface AccountsTableProps extends AgGridReactProps {
onClickDeposit: () => void;
expanded: boolean;
showRows: boolean;
hideHeader?: boolean;
}
interface AccountsTableValueFormatterParams extends ValueFormatterParams {
@ -39,7 +40,15 @@ export const assetDecimalsFormatter = ({
export const AccountDeposit = forwardRef<AgGridReact, AccountsTableProps>(
(
{ data, onClickAsset, expanded, showRows, onClickWithdraw, onClickDeposit },
{
data,
onClickAsset,
expanded,
showRows,
hideHeader,
onClickWithdraw,
onClickDeposit,
},
ref
) => {
const openAssetAccountCellRenderer = ({ value }: GroupCellRendererParams) =>
@ -65,7 +74,7 @@ export const AccountDeposit = forwardRef<AgGridReact, AccountsTableProps>(
ref={ref}
rowHeight={34}
tooltipShowDelay={500}
headerHeight={0}
headerHeight={hideHeader ? 0 : undefined}
defaultColDef={{
flex: 1,
resizable: true,
@ -79,18 +88,27 @@ export const AccountDeposit = forwardRef<AgGridReact, AccountsTableProps>(
'Asset is the collateral that is deposited into the Vega protocol.'
)}
cellRenderer={openAssetAccountCellRenderer}
maxWidth={300}
/>
<AgGridColumn
headerName={t('Used')}
field="used"
flex={2}
maxWidth={500}
headerComponentParams={progressBarHeaderComponentParams}
cellRendererSelector={progressBarCellRendererSelector}
valueFormatter={progressBarValueFormatter}
/>
<AgGridColumn
headerName={t('Deposited')}
field="deposited"
valueFormatter={assetDecimalsFormatter}
maxWidth={300}
/>
<AgGridColumn
headerName=""
field="deposit"
maxWidth={300}
cellRenderer={() => {
return (
<Button size="xs" data-testid="deposit" onClick={onClickDeposit}>
@ -102,6 +120,7 @@ export const AccountDeposit = forwardRef<AgGridReact, AccountsTableProps>(
<AgGridColumn
headerName=""
field="withdraw"
maxWidth={300}
cellRenderer={() => {
return (
<Button

View File

@ -8,13 +8,52 @@ import type {
AccountsQuery,
AccountEventsSubscription,
} from './__generated__/Accounts';
import type { SummaryRow } from '@vegaprotocol/react-helpers';
import { makeDataProvider } from '@vegaprotocol/react-helpers';
import { AccountType } from '@vegaprotocol/types';
import BigNumber from 'bignumber.js';
import type { ColumnApi } from 'ag-grid-community';
import type { AccountFields } from './accounts-manager';
export const getId = (data: AccountFieldsFragment) =>
`${data.type}-${data.asset.symbol}-${data.market?.id ?? 'null'}`;
export const getGroupId = (
data: AccountFields & SummaryRow,
columnApi: ColumnApi
) => {
if (data.__summaryRow) {
return null;
}
const sortColumnId = columnApi.getColumnState().find((c) => c.sort)?.colId;
switch (sortColumnId) {
case 'asset.symbol':
return data.asset.id;
}
return undefined;
};
export const getGroupSummaryRow = (
data: AccountFields[],
columnApi: ColumnApi
): Partial<AccountFields & SummaryRow> | null => {
if (!data.length) {
return null;
}
const sortColumnId = columnApi.getColumnState().find((c) => c.sort)?.colId;
switch (sortColumnId) {
case 'asset.symbol':
return {
__summaryRow: true,
balance: data
.reduce((a, i) => a + (parseFloat(i.balance) || 0), 0)
.toString(),
asset: data[0].asset,
};
}
return null;
};
const update = (
data: AccountFieldsFragment[],
delta: AccountFieldsFragment
@ -30,6 +69,24 @@ const update = (
});
};
const INCOMING_ACCOUNT_TYPES = [
AccountType.ACCOUNT_TYPE_GENERAL,
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_REWARD_TAKER_PAID_FEES,
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
];
const OUTCOMING_ACCOUNT_TYPES = [
AccountType.ACCOUNT_TYPE_MARGIN,
AccountType.ACCOUNT_TYPE_BOND,
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
AccountType.ACCOUNT_TYPE_FEES_MAKER,
AccountType.ACCOUNT_TYPE_PENDING_TRANSFERS,
];
const getData = (
responseData: AccountsQuery
): AccountFieldsFragment[] | null => {
@ -63,31 +120,31 @@ export const getAccountData = (
.filter((a) => [AccountType.ACCOUNT_TYPE_GENERAL].includes(a.type))
.reduce((acc, a) => acc.plus(a.balance), new BigNumber(0));
const incoming = assetData
.filter((a) => INCOMING_ACCOUNT_TYPES.includes(a.type))
.reduce((acc, a) => acc.plus(a.balance), new BigNumber(0));
const used = assetData
.filter((a) =>
[AccountType.ACCOUNT_TYPE_MARGIN, AccountType.ACCOUNT_TYPE_BOND].includes(
a.type
)
)
.filter((a) => OUTCOMING_ACCOUNT_TYPES.includes(a.type))
.reduce((acc, a) => acc.plus(a.balance), new BigNumber(0));
const depositRow = {
...assetData[0],
available: deposited.minus(used).toString(),
available: incoming.minus(used).toString(),
deposited: deposited.toString(),
used: used.toString(),
};
const positionRows = assetData
.filter((a) => [AccountType.ACCOUNT_TYPE_MARGIN].includes(a.type))
const accountRows = assetData
.filter((a) => !INCOMING_ACCOUNT_TYPES.includes(a.type))
.map((a) => ({
...a,
available: deposited.minus(a.balance).toString(),
available: incoming.minus(a.balance).toString(),
deposited: deposited.toString(),
used: a.balance.toString(),
}));
return {
positionRows,
accountRows,
depositRow,
};
};

View File

@ -1,14 +1,27 @@
import { useCallback, useMemo, useRef, useState } from 'react';
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
import { AsyncRenderer, Dialog } from '@vegaprotocol/ui-toolkit';
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
import {
addSummaryRows,
t,
useDataProvider,
} from '@vegaprotocol/react-helpers';
import type { AccountFieldsFragment } from './__generated__/Accounts';
import { accountsDataProvider, getAccountData } from './accounts-data-provider';
import {
accountsDataProvider,
getAccountData,
getGroupId,
getGroupSummaryRow,
getId,
} from './accounts-data-provider';
import AccountsTable from './accounts-table';
import type { AgGridReact } from 'ag-grid-react';
import { AccountDeposit } from './account-deposit';
import { WithdrawalDialogs } from '@vegaprotocol/withdraws';
import { Web3Container } from '@vegaprotocol/web3';
import { DepositContainer } from '@vegaprotocol/deposits';
import produce from 'immer';
import merge from 'lodash/merge';
import classNames from 'classnames';
export interface AccountFields extends AccountFieldsFragment {
available: string;
@ -27,23 +40,46 @@ interface AccountsManagerProps {
export const AccountsManager = ({ partyId }: AccountsManagerProps) => {
const variables = useMemo(() => ({ partyId }), [partyId]);
const assetSymbols = useRef<string[] | undefined>();
const gridRef = useRef<AgGridReact | null>(null);
const update = useCallback(
({ data }: { data: AccountFieldsFragment[] | null }) => {
if (data?.length) {
const newAssetSymbols = getSymbols(data);
if (
!newAssetSymbols.every(
(symbol) =>
assetSymbols.current && assetSymbols.current.includes(symbol)
)
) {
return false;
({ delta }: { delta: AccountFieldsFragment }) => {
const update: AccountFieldsFragment[] = [];
const add: AccountFieldsFragment[] = [];
if (!gridRef.current?.api) {
return false;
}
const rowNode = gridRef.current.api.getRowNode(getId(delta));
if (rowNode) {
const updatedData = produce<AccountFieldsFragment>(
rowNode.data,
(draft: AccountFieldsFragment) => {
merge(draft, delta);
}
);
if (updatedData !== rowNode.data) {
update.push(updatedData);
}
} else {
add.push(delta);
}
if (update.length || add.length) {
gridRef.current.api.applyTransactionAsync({
update,
add,
addIndex: 0,
});
}
if (add.length) {
addSummaryRows(
gridRef.current.api,
gridRef.current.columnApi,
getGroupId,
getGroupSummaryRow
);
}
return true;
},
[]
[gridRef]
);
const { data, error, loading } = useDataProvider<
@ -56,11 +92,13 @@ export const AccountsManager = ({ partyId }: AccountsManagerProps) => {
<Web3Container>
<AsyncRenderer loading={loading} error={error} data={assetSymbols}>
{symbols &&
symbols.map((assetSymbol) => (
symbols.map((assetSymbol, i) => (
<AssetAccountTable
ref={gridRef}
key={assetSymbol}
assetSymbol={assetSymbol}
data={data}
hideHeader={i !== 0}
/>
))}
</AsyncRenderer>
@ -68,38 +106,42 @@ export const AccountsManager = ({ partyId }: AccountsManagerProps) => {
);
};
export const AssetAccountTable = ({
data,
assetSymbol,
}: {
export interface AssetAccountTableProps {
assetSymbol: string;
data: AccountFieldsFragment[];
}) => {
const { positionRows, depositRow } = getAccountData(data, assetSymbol);
hideHeader?: boolean;
}
export const AssetAccountTable = forwardRef<
AgGridReact,
AssetAccountTableProps
>(({ data, assetSymbol, hideHeader }, ref) => {
const { accountRows, depositRow } = getAccountData(data, assetSymbol);
const [open, setOpen] = useState(false);
const gridRef = useRef<AgGridReact | null>(null);
const [withdrawDialog, setWithdrawDialog] = useState(false);
const [depositDialog, setDepositDialog] = useState(false);
return (
<>
<div className="h-[50px]">
<div
className={classNames({
'h-[50px]': hideHeader,
'h-[85px]': !hideHeader,
})}
>
<AccountDeposit
ref={gridRef}
ref={ref}
data={[depositRow]}
expanded={open}
showRows={positionRows?.length > 0}
showRows={accountRows?.length > 0}
hideHeader={hideHeader}
onClickAsset={() => setOpen(!open)}
onClickWithdraw={() => setWithdrawDialog(true)}
onClickDeposit={() => setDepositDialog(true)}
/>
</div>
{open && positionRows.length > 0 && (
{open && accountRows.length > 0 && (
<div className="h-[15vh]">
<AccountsTable
ref={gridRef}
data={positionRows}
domLayout="autoHeight"
/>
<AccountsTable ref={ref} data={accountRows} domLayout="autoHeight" />
</div>
)}
<WithdrawalDialogs
@ -114,7 +156,7 @@ export const AssetAccountTable = ({
/>
</>
);
};
});
export interface DepositDialogProps {
assetId: string;

View File

@ -12,7 +12,7 @@ import {
t,
formatNumberPercentage,
} from '@vegaprotocol/react-helpers';
import { Intent } from '@vegaprotocol/ui-toolkit';
import { Button, Intent } from '@vegaprotocol/ui-toolkit';
import { AgGridDynamic as AgGrid, ProgressBar } from '@vegaprotocol/ui-toolkit';
import { AgGridColumn } from 'ag-grid-react';
import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
@ -21,6 +21,8 @@ import { getId } from './accounts-data-provider';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import type { AccountFields } from './accounts-manager';
import BigNumber from 'bignumber.js';
import { AccountTypeMapping } from '@vegaprotocol/types';
import type { AccountType } from '@vegaprotocol/types';
export interface ValueProps {
valueFormatted?: {
@ -108,21 +110,22 @@ export const AccountsTable = forwardRef<AgGridReact, AccountsTableProps>(
({ data }, ref) => {
const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } =
useAssetDetailsDialogStore();
const assetDialogCellRenderer = ({ value }: GroupCellRendererParams) =>
value && value.length > 0 ? (
<button
const assetDialogCellRenderer = ({ value }: GroupCellRendererParams) => {
if (!value || value.length <= 0) return '-';
return (
<Button
size="xs"
className="hover:underline"
onClick={() => {
setAssetDetailsDialogOpen(true);
setAssetDetailsDialogSymbol(value);
}}
>
{value}
</button>
) : (
''
{t('Asset details')}
</Button>
);
console.log('data', data);
};
return (
<AgGrid
style={{ width: '100%', height: '100%' }}
@ -131,6 +134,7 @@ export const AccountsTable = forwardRef<AgGridReact, AccountsTableProps>(
getRowId={({ data }) => getId(data)}
ref={ref}
rowHeight={34}
headerHeight={0}
components={{ PriceCell }}
tooltipShowDelay={500}
defaultColDef={{
@ -139,30 +143,36 @@ export const AccountsTable = forwardRef<AgGridReact, AccountsTableProps>(
}}
>
<AgGridColumn
headerName={t('Asset')}
field="asset.symbol"
headerTooltip={t(
'Asset is the collateral that is deposited into the Vega protocol.'
)}
cellRenderer={assetDialogCellRenderer}
headerName={t('Market')}
field="market.tradableInstrument.instrument.name"
valueFormatter="value || '—'"
maxWidth={300}
/>
<AgGridColumn
headerName={t('Used')}
field="used"
flex={2}
maxWidth={500}
headerComponentParams={progressBarHeaderComponentParams}
cellRendererSelector={progressBarCellRendererSelector}
valueFormatter={progressBarValueFormatter}
/>
<AgGridColumn
headerName={t('Deposited')}
field="deposited"
valueFormatter={assetDecimalsFormatter}
headerName={t('Type')}
field="type"
maxWidth={300}
valueFormatter={({ value }: ValueFormatterParams) =>
AccountTypeMapping[value as AccountType]
}
/>
<AgGridColumn
headerName={t('Market')}
field="market.tradableInstrument.instrument.name"
valueFormatter="value || '—'"
headerName={t('Asset')}
field="asset.symbol"
maxWidth={300}
headerTooltip={t(
'Asset is the collateral that is deposited into the Vega protocol.'
)}
cellRenderer={assetDialogCellRenderer}
/>
</AgGrid>
);