chore(trading): dropdown alignments, account history default asset, transfer dialog asset selector (#4239)

This commit is contained in:
Art 2023-07-05 13:02:02 +02:00 committed by GitHub
parent fc8f12d6fc
commit f6fc4df1c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 286 additions and 333 deletions

View File

@ -153,7 +153,7 @@ describe('markets all table', { tags: '@smoke' }, () => {
cy.get(dropdownContent)
.find(dropdownContentItem)
.eq(2)
.should('have.text', 'View asset');
.should('have.text', 'View settlement asset details');
cy.getByTestId('market-actions-content').click();
});

View File

@ -18,7 +18,7 @@ import type {
MarketMaybeWithData,
} from '@vegaprotocol/markets';
import {
MarketTableActions,
MarketActionsDropdown,
closedMarketsWithDataProvider,
} from '@vegaprotocol/markets';
import { useVegaWallet } from '@vegaprotocol/wallet';
@ -291,7 +291,7 @@ const ClosedMarketsDataGrid = ({
cellRenderer: ({ data }: VegaICellRendererParams<Row>) => {
if (!data) return null;
return (
<MarketTableActions
<MarketActionsDropdown
marketId={data.id}
assetId={data.settlementAsset.id}
/>

View File

@ -24,7 +24,10 @@ import { PriceChart } from 'pennant';
import 'pennant/dist/style.css';
import type { Account } from '@vegaprotocol/accounts';
import { accountsDataProvider } from '@vegaprotocol/accounts';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import {
useLocalStorageSnapshot,
useThemeSwitcher,
} from '@vegaprotocol/react-helpers';
import { useDataProvider } from '@vegaprotocol/data-provider';
import type { Market } from '@vegaprotocol/markets';
@ -68,7 +71,7 @@ export const AccountHistoryContainer = () => {
const { data: assets } = useAssetsDataProvider();
if (!pubKey) {
return <Splash>Connect wallet</Splash>;
return <Splash>{t('Connect wallet')}</Splash>;
}
return (
@ -114,7 +117,15 @@ const AccountHistoryManager = ({
.sort((a, b) => a.name.localeCompare(b.name)),
[assetData, assetIds]
);
const [asset, setAsset] = useState<AssetFieldsFragment>(assets[0]);
const [assetId, setAssetId] = useLocalStorageSnapshot(
'account-history-active-asset-id'
);
const asset = useMemo(
() => assets.find((a) => a.id === assetId) || assets[0],
[assetId, assets]
);
const [range, setRange] = useState<typeof DateRange[keyof typeof DateRange]>(
DateRange.RANGE_1M
);
@ -146,10 +157,10 @@ const AccountHistoryManager = ({
m.tradableInstrument.instrument.product.settlementAsset.id;
const newAsset = assets.find((item) => item.id === newAssetId);
if ((!asset || (assets && newAssetId !== asset.id)) && newAsset) {
setAsset(newAsset);
setAssetId(newAsset.id);
}
},
[asset, assets]
[asset, assets, setAssetId]
);
const variables = useMemo(
@ -211,14 +222,14 @@ const AccountHistoryManager = ({
>
<DropdownMenuContent>
{assets.map((a) => (
<DropdownMenuItem key={a.id} onClick={() => setAsset(a)}>
<DropdownMenuItem key={a.id} onClick={() => setAssetId(a.id)}>
{a.symbol}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}, [assets, asset]);
}, [asset, assets, setAssetId]);
const marketsMenu = useMemo(() => {
return accountType === Schema.AccountType.ACCOUNT_TYPE_MARGIN &&
markets?.length ? (

View File

@ -1,11 +1,9 @@
import { ETHERSCAN_ADDRESS, useEtherscanLink } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import {
DropdownMenu,
DropdownMenuContent,
ActionsDropdown,
DropdownMenuCopyItem,
DropdownMenuItem,
DropdownMenuTrigger,
Link,
VegaIcon,
VegaIconNames,
@ -29,75 +27,65 @@ export const AccountsActionsDropdown = ({
const etherscanLink = useEtherscanLink();
const openTransferDialog = useTransferDialog((store) => store.open);
const openAssetDialog = useAssetDetailsDialogStore((store) => store.open);
return (
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent>
<DropdownMenuItem
key={'deposit'}
data-testid="deposit"
onClick={onClickDeposit}
>
<VegaIcon name={VegaIconNames.DEPOSIT} size={16} />
{t('Deposit')}
<ActionsDropdown>
<DropdownMenuItem
key={'deposit'}
data-testid="deposit"
onClick={onClickDeposit}
>
<VegaIcon name={VegaIconNames.DEPOSIT} size={16} />
{t('Deposit')}
</DropdownMenuItem>
<DropdownMenuItem
key={'withdraw'}
data-testid="withdraw"
onClick={onClickWithdraw}
>
<VegaIcon name={VegaIconNames.WITHDRAW} size={16} />
{t('Withdraw')}
</DropdownMenuItem>
<DropdownMenuItem
key={'transfer'}
data-testid="transfer"
onClick={() => openTransferDialog(true, assetId)}
>
<VegaIcon name={VegaIconNames.TRANSFER} size={16} />
{t('Transfer')}
</DropdownMenuItem>
<DropdownMenuItem
key={'breakdown'}
data-testid="breakdown"
onClick={onClickBreakdown}
>
<VegaIcon name={VegaIconNames.BREAKDOWN} size={16} />
{t('View usage breakdown')}
</DropdownMenuItem>
<DropdownMenuItem
onClick={(e) => {
openAssetDialog(assetId, e.target as HTMLElement);
}}
>
<VegaIcon name={VegaIconNames.INFO} size={16} />
{t('View asset details')}
</DropdownMenuItem>
<DropdownMenuCopyItem value={assetId} text={t('Copy asset ID')} />
{assetContractAddress && (
<DropdownMenuItem>
<Link
href={etherscanLink(
ETHERSCAN_ADDRESS.replace(':hash', assetContractAddress)
)}
target="_blank"
>
<span className="flex gap-2">
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View on Etherscan')}
</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem
key={'withdraw'}
data-testid="withdraw"
onClick={onClickWithdraw}
>
<VegaIcon name={VegaIconNames.WITHDRAW} size={16} />
{t('Withdraw')}
</DropdownMenuItem>
<DropdownMenuItem
key={'transfer'}
data-testid="transfer"
onClick={() => openTransferDialog(true, assetId)}
>
<VegaIcon name={VegaIconNames.TRANSFER} size={16} />
{t('Transfer')}
</DropdownMenuItem>
<DropdownMenuItem
key={'breakdown'}
data-testid="breakdown"
onClick={onClickBreakdown}
>
<VegaIcon name={VegaIconNames.BREAKDOWN} size={16} />
{t('Breakdown')}
</DropdownMenuItem>
<DropdownMenuItem
onClick={(e) => {
openAssetDialog(assetId, e.target as HTMLElement);
}}
>
<VegaIcon name={VegaIconNames.BREAKDOWN} size={16} />
{t('View asset')}
</DropdownMenuItem>
<DropdownMenuCopyItem value={assetId} text={t('Copy asset ID')} />
{assetContractAddress && (
<DropdownMenuItem>
<Link
href={etherscanLink(
ETHERSCAN_ADDRESS.replace(':hash', assetContractAddress)
)}
target="_blank"
>
<span className="flex gap-2">
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View on Etherscan')}
</span>
</Link>
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
)}
</ActionsDropdown>
);
};

View File

@ -13,6 +13,7 @@ import { accountsDataProvider } from './accounts-data-provider';
import { TransferForm } from './transfer-form';
import { useTransferDialog } from './transfer-dialog';
import { Lozenge } from '@vegaprotocol/ui-toolkit';
import sortBy from 'lodash/sortBy';
export const TransferContainer = ({ assetId }: { assetId?: string }) => {
const { pubKey, pubKeys } = useVegaWallet();
@ -58,7 +59,7 @@ export const TransferContainer = ({ assetId }: { assetId?: string }) => {
<TransferForm
pubKey={pubKey}
pubKeys={pubKeys ? pubKeys?.map((pk) => pk.publicKey) : null}
assets={assets}
assets={sortBy(assets, 'name')}
assetId={assetId}
feeFactor={param}
submitTransfer={transfer}

View File

@ -8,7 +8,7 @@ import {
import BigNumber from 'bignumber.js';
import { AddressField, TransferFee, TransferForm } from './transfer-form';
import { AccountType } from '@vegaprotocol/types';
import { formatNumber, removeDecimal } from '@vegaprotocol/utils';
import { addDecimal, formatNumber, removeDecimal } from '@vegaprotocol/utils';
describe('TransferForm', () => {
const submit = () => fireEvent.submit(screen.getByTestId('transfer-form'));
@ -16,11 +16,11 @@ describe('TransferForm', () => {
const pubKey =
'70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680';
const asset = {
id: 'asset-0',
symbol: 'ASSET 0',
name: 'Asset 0',
id: 'eur',
symbol: '',
name: 'EUR',
decimals: 2,
balance: '1000',
balance: addDecimal(100000, 2), // 1000
};
const props = {
pubKey,
@ -92,7 +92,7 @@ describe('TransferForm', () => {
expect(await screen.findByTestId('select-asset')).toHaveTextContent(
asset.name
);
expect(screen.getByTestId('asset-balance')).toHaveTextContent(
expect(await screen.findByTestId('asset-balance')).toHaveTextContent(
formatNumber(asset.balance, asset.decimals)
);
@ -168,7 +168,7 @@ describe('TransferForm', () => {
expect(await screen.findByTestId('select-asset')).toHaveTextContent(
asset.name
);
expect(screen.getByTestId('asset-balance')).toHaveTextContent(
expect(await screen.findByTestId('asset-balance')).toHaveTextContent(
formatNumber(asset.balance, asset.decimals)
);
@ -244,7 +244,7 @@ describe('TransferForm', () => {
expect(await screen.findByTestId('select-asset')).toHaveTextContent(
asset.name
);
expect(screen.getByTestId('asset-balance')).toHaveTextContent(
expect(await screen.findByTestId('asset-balance')).toHaveTextContent(
formatNumber(asset.balance, asset.decimals)
);

View File

@ -12,7 +12,6 @@ import {
FormGroup,
Input,
InputError,
Option,
RichSelect,
Select,
Tooltip,
@ -24,6 +23,7 @@ import BigNumber from 'bignumber.js';
import type { ReactNode } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { AssetOption, Balance } from '@vegaprotocol/assets';
interface FormFields {
toAddress: string;
@ -193,21 +193,20 @@ export const TransferForm = ({
onValueChange={(value) => {
field.onChange(value);
}}
placeholder={t('Please select')}
placeholder={t('Please select an asset')}
value={field.value}
>
{assets.map((a) => (
<Option key={a.id} value={a.id}>
<div className="text-left" data-testid={`asset-${a.id}`}>
<div>{a.name}</div>
<div className="text-xs">
<span className="font-mono" data-testid="asset-balance">
{formatNumber(a.balance, a.decimals)}
</span>{' '}
<span>{a.symbol}</span>
</div>
</div>
</Option>
<AssetOption
key={a.id}
asset={a}
balance={
<Balance
balance={formatNumber(a.balance, a.decimals)}
symbol={a.symbol}
/>
}
/>
))}
</RichSelect>
)}

View File

@ -5,7 +5,7 @@ import { t } from '@vegaprotocol/i18n';
import type { ReactNode } from 'react';
type AssetOptionProps = {
asset: AssetFieldsFragment;
asset: Pick<AssetFieldsFragment, 'id' | 'name' | 'symbol'>;
balance?: ReactNode;
};
@ -17,11 +17,13 @@ export const Balance = ({
symbol: string;
}) =>
balance ? (
<div className="mt-1 font-alpha">
<div className="mt-1 font-alpha" data-testid="asset-balance">
{balance} {symbol}
</div>
) : (
<div className="text-vega-orange-500">{t('Fetching balance…')}</div>
<div className="text-vega-orange-500" data-testid="asset-balance">
{t('Fetching balance…')}
</div>
);
export const AssetOption = ({ asset, balance }: AssetOptionProps) => {

View File

@ -1,10 +1,6 @@
import {
DropdownMenu,
DropdownMenuContent,
ActionsDropdown,
DropdownMenuCopyItem,
DropdownMenuTrigger,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
@ -18,27 +14,13 @@ export const FillActionsDropdown = ({
sellOrderId: string;
}) => {
return (
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent data-testid="market-actions-content">
<DropdownMenuCopyItem value={tradeId} text={t('Copy trade ID')} />
<DropdownMenuCopyItem
value={buyOrderId}
text={t('Copy buy order ID')}
/>
<DropdownMenuCopyItem
value={sellOrderId}
text={t('Copy sell order ID')}
/>
</DropdownMenuContent>
</DropdownMenu>
<ActionsDropdown data-testid="market-actions-content">
<DropdownMenuCopyItem value={tradeId} text={t('Copy trade ID')} />
<DropdownMenuCopyItem value={buyOrderId} text={t('Copy buy order ID')} />
<DropdownMenuCopyItem
value={sellOrderId}
text={t('Copy sell order ID')}
/>
</ActionsDropdown>
);
};

View File

@ -1,18 +1,16 @@
import { t } from '@vegaprotocol/i18n';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuCopyItem,
Link,
VegaIcon,
VegaIconNames,
ActionsDropdown,
} from '@vegaprotocol/ui-toolkit';
import { DApp, EXPLORER_MARKET, useLinks } from '@vegaprotocol/environment';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
export const MarketTableActions = ({
export const MarketActionsDropdown = ({
marketId,
assetId,
}: {
@ -21,39 +19,29 @@ export const MarketTableActions = ({
}) => {
const open = useAssetDetailsDialogStore((store) => store.open);
const linkCreator = useLinks(DApp.Explorer);
return (
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
<ActionsDropdown data-testid="market-actions-content">
<DropdownMenuCopyItem value={marketId} text={t('Copy Market ID')} />
<DropdownMenuItem>
<Link
href={linkCreator(EXPLORER_MARKET.replace(':id', marketId))}
target="_blank"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent data-testid="market-actions-content">
<DropdownMenuCopyItem value={marketId} text={t('Copy Market ID')} />
<DropdownMenuItem>
<Link
href={linkCreator(EXPLORER_MARKET.replace(':id', marketId))}
target="_blank"
>
<span className="flex gap-2">
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View on Explorer')}
</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem
onClick={(e) => {
open(assetId, e.target as HTMLElement);
}}
>
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View asset')}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<span className="flex gap-2">
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View on Explorer')}
</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem
onClick={(e) => {
open(assetId, e.target as HTMLElement);
}}
>
<VegaIcon name={VegaIconNames.INFO} size={16} />
{t('View settlement asset details')}
</DropdownMenuItem>
</ActionsDropdown>
);
};

View File

@ -12,7 +12,7 @@ import { addDecimalsFormatNumber, toBigNum } from '@vegaprotocol/utils';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import type { MarketMaybeWithData } from '../../markets-provider';
import { MarketTableActions } from './market-table-actions';
import { MarketActionsDropdown } from './market-table-actions';
interface Props {
onMarketClick: (marketId: string, metaKey?: boolean) => void;
@ -172,7 +172,7 @@ export const useColumnDefs = ({ onMarketClick }: Props) => {
}: VegaICellRendererParams<MarketMaybeWithData>) => {
if (!data) return null;
return (
<MarketTableActions
<MarketActionsDropdown
marketId={data.id}
assetId={
data.tradableInstrument.instrument.product.settlementAsset.id

View File

@ -1,28 +1,13 @@
import {
DropdownMenu,
DropdownMenuContent,
ActionsDropdown,
DropdownMenuCopyItem,
DropdownMenuTrigger,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
export const OrderActionsDropdown = ({ id }: { id: string }) => {
return (
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent data-testid="market-actions-content">
<DropdownMenuCopyItem value={id} text={t('Copy order ID')} />
</DropdownMenuContent>
</DropdownMenu>
<ActionsDropdown data-testid="market-actions-content">
<DropdownMenuCopyItem value={id} text={t('Copy order ID')} />
</ActionsDropdown>
);
};

View File

@ -1,37 +1,25 @@
import { t } from '@vegaprotocol/i18n';
import {
DropdownMenu,
DropdownMenuContent,
ActionsDropdown,
DropdownMenuItem,
DropdownMenuTrigger,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
export const PositionTableActions = ({ assetId }: { assetId: string }) => {
export const PositionActionsDropdown = ({ assetId }: { assetId: string }) => {
const open = useAssetDetailsDialogStore((store) => store.open);
return (
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent data-testid="market-actions-content">
<DropdownMenuItem
onClick={(e) => {
open(assetId, e.target as HTMLElement);
}}
>
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View asset')}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<ActionsDropdown data-testid="market-actions-content">
<DropdownMenuItem
onClick={(e) => {
open(assetId, e.target as HTMLElement);
}}
>
<VegaIcon name={VegaIconNames.INFO} size={16} />
{t('View settlement asset details')}
</DropdownMenuItem>
</ActionsDropdown>
);
};

View File

@ -38,7 +38,7 @@ import type { Position } from './positions-data-providers';
import * as Schema from '@vegaprotocol/types';
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
import { DocsLinks } from '@vegaprotocol/environment';
import { PositionTableActions } from './position-actions-dropdown';
import { PositionActionsDropdown } from './position-actions-dropdown';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { LiquidationPrice } from './liquidation-price';
@ -264,6 +264,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
if (!data) return null;
return (
<ButtonLink
title={t('View settlement asset details')}
onClick={(e) => {
openAssetDetailsDialog(
data.assetId,
@ -449,7 +450,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
</ButtonLink>
) : null}
{data?.assetId && (
<PositionTableActions assetId={data?.assetId} />
<PositionActionsDropdown assetId={data?.assetId} />
)}
</div>
);

View File

@ -1,39 +1,27 @@
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
VegaIcon,
VegaIconNames,
Link,
ActionsDropdown,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
export const ProposalActionsDropdown = ({ id }: { id: string }) => {
const linkCreator = useLinks(DApp.Token);
return (
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
<ActionsDropdown data-testid="market-actions-content">
<DropdownMenuItem>
<Link
href={linkCreator(TOKEN_PROPOSAL.replace(':id', id))}
target="_blank"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent data-testid="market-actions-content">
<DropdownMenuItem>
<Link
href={linkCreator(TOKEN_PROPOSAL.replace(':id', id))}
target="_blank"
>
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View proposal')}
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View proposal')}
</Link>
</DropdownMenuItem>
</ActionsDropdown>
);
};

View File

@ -0,0 +1,26 @@
import { VegaIcon, VegaIconNames } from '../icon';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from './dropdown-menu';
export const ActionsDropdownTrigger = () => {
return (
<DropdownMenuTrigger
className='hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 [&[aria-expanded="true"]]:bg-vega-light-200 dark:[&[aria-expanded="true"]]:bg-vega-dark-200 p-0.5 rounded-full'
data-testid="dropdown-menu"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
);
};
type ActionMenuContentProps = React.ComponentProps<typeof DropdownMenuContent>;
export const ActionsDropdown = (props: ActionMenuContentProps) => {
return (
<DropdownMenu trigger={<ActionsDropdownTrigger />}>
<DropdownMenuContent {...props}></DropdownMenuContent>
</DropdownMenu>
);
};

View File

@ -1 +1,2 @@
export * from './dropdown-menu';
export * from './actions-dropdown';

View File

@ -0,0 +1,12 @@
export const IconInfo = ({ size = 14 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 14 14"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7 0C3.13 0 0 3.13 0 7C0 10.87 3.13 14 7 14C10.87 14 14 10.87 14 7C14 3.13 10.87 0 7 0ZM7.75 10.75H6.25V5.75H7.75V10.75ZM7.75 4.75H6.25V3.25H7.75V4.75Z" />
</svg>
);
};

View File

@ -1,72 +1,75 @@
import { IconBreakdown } from './svg-icons/icon-breakdown';
import { IconCopy } from './svg-icons/icon-copy';
import { IconDeposit } from './svg-icons/icon-deposit';
import { IconWithdraw } from './svg-icons/icon-withdraw';
import { IconTransfer } from './svg-icons/icon-transfer';
import { IconEdit } from './svg-icons/icon-edit';
import { IconMoon } from './svg-icons/icon-moon';
import { IconGlobe } from './svg-icons/icon-globe';
import { IconLinkedIn } from './svg-icons/icon-linkedin';
import { IconTwitter } from './svg-icons/icon-twitter';
import { IconQuestionMark } from './svg-icons/icon-question-mark';
import { IconForum } from './svg-icons/icon-forum';
import { IconOpenExternal } from './svg-icons/icon-open-external';
import { IconArrowRight } from './svg-icons/icon-arrow-right';
import { IconChevronUp } from './svg-icons/icon-chevron-up';
import { IconTrendUp } from './svg-icons/icon-trend-up';
import { IconCross } from './svg-icons/icon-cross';
import { IconKebab } from './svg-icons/icon-kebab';
import { IconArrowDown } from './svg-icons/icon-arrow-down';
import { IconArrowRight } from './svg-icons/icon-arrow-right';
import { IconBreakdown } from './svg-icons/icon-breakdown';
import { IconChevronDown } from './svg-icons/icon-chevron-down';
import { IconChevronUp } from './svg-icons/icon-chevron-up';
import { IconCopy } from './svg-icons/icon-copy';
import { IconCross } from './svg-icons/icon-cross';
import { IconDeposit } from './svg-icons/icon-deposit';
import { IconEdit } from './svg-icons/icon-edit';
import { IconForum } from './svg-icons/icon-forum';
import { IconGlobe } from './svg-icons/icon-globe';
import { IconInfo } from './svg-icons/icon-info';
import { IconKebab } from './svg-icons/icon-kebab';
import { IconLinkedIn } from './svg-icons/icon-linkedin';
import { IconMoon } from './svg-icons/icon-moon';
import { IconOpenExternal } from './svg-icons/icon-open-external';
import { IconQuestionMark } from './svg-icons/icon-question-mark';
import { IconTick } from './svg-icons/icon-tick';
import { IconTransfer } from './svg-icons/icon-transfer';
import { IconTrendUp } from './svg-icons/icon-trend-up';
import { IconTwitter } from './svg-icons/icon-twitter';
import { IconWithdraw } from './svg-icons/icon-withdraw';
export enum VegaIconNames {
ARROW_DOWN = 'arrow-down',
ARROW_RIGHT = 'arrow-right',
BREAKDOWN = 'breakdown',
CHEVRON_DOWN = 'chevron-down',
CHEVRON_UP = 'chevron-up',
COPY = 'copy',
CROSS = 'cross',
DEPOSIT = 'deposit',
WITHDRAW = 'withdraw',
EDIT = 'edit',
TRANSFER = 'transfer',
FORUM = 'forum',
GLOBE = 'globe',
INFO = 'info',
KEBAB = 'kebab',
LINKEDIN = 'linkedin',
TWITTER = 'twitter',
MOON = 'moon',
OPEN_EXTERNAL = 'open-external',
QUESTION_MARK = 'question-mark',
ARROW_RIGHT = 'arrow-right',
ARROW_DOWN = 'arrow-down',
CHEVRON_UP = 'chevron-up',
CHEVRON_DOWN = 'chevron-down',
TREND_UP = 'trend-up',
CROSS = 'cross',
KEBAB = 'kebab',
TICK = 'tick',
TRANSFER = 'transfer',
TREND_UP = 'trend-up',
TWITTER = 'twitter',
WITHDRAW = 'withdraw',
}
export const VegaIconNameMap: Record<
VegaIconNames,
({ size }: { size: number }) => JSX.Element
> = {
'arrow-down': IconArrowDown,
'arrow-right': IconArrowRight,
'chevron-down': IconChevronDown,
'chevron-up': IconChevronUp,
'open-external': IconOpenExternal,
'question-mark': IconQuestionMark,
'trend-up': IconTrendUp,
breakdown: IconBreakdown,
copy: IconCopy,
deposit: IconDeposit,
withdraw: IconWithdraw,
transfer: IconTransfer,
edit: IconEdit,
moon: IconMoon,
globe: IconGlobe,
linkedin: IconLinkedIn,
twitter: IconTwitter,
'question-mark': IconQuestionMark,
forum: IconForum,
'open-external': IconOpenExternal,
'arrow-right': IconArrowRight,
'arrow-down': IconArrowDown,
'chevron-up': IconChevronUp,
'chevron-down': IconChevronDown,
'trend-up': IconTrendUp,
cross: IconCross,
deposit: IconDeposit,
edit: IconEdit,
forum: IconForum,
globe: IconGlobe,
info: IconInfo,
kebab: IconKebab,
linkedin: IconLinkedIn,
moon: IconMoon,
tick: IconTick,
transfer: IconTransfer,
twitter: IconTwitter,
withdraw: IconWithdraw,
};

View File

@ -48,24 +48,12 @@ export const RichSelect = forwardRef<
const containerRef = useRef<HTMLDivElement>();
const contentRef = useRef<HTMLDivElement>();
const setWidth = () => {
if (contentRef.current) {
contentRef.current.style.width = containerRef.current ? `450px` : 'auto';
}
};
return (
<div
ref={containerRef as Ref<HTMLDivElement>}
className="flex items-center relative"
>
<SelectPrimitive.Root
{...props}
onOpenChange={() => {
setWidth();
}}
defaultOpen={false}
>
<SelectPrimitive.Root {...props} defaultOpen={false}>
<SelectPrimitive.Trigger
data-testid={props['data-testid'] || 'rich-select-trigger'}
className={classNames(
@ -85,9 +73,10 @@ export const RichSelect = forwardRef<
<SelectPrimitive.Content
ref={contentRef as Ref<HTMLDivElement>}
className={classNames(
'relative',
'z-20',
'bg-white dark:bg-black',
'border border-neutral-500 focus:border-black dark:focus:border-white',
'border border-neutral-500 focus:border-black dark:focus:border-white rounded',
'overflow-hidden',
'shadow-lg'
)}
@ -95,11 +84,11 @@ export const RichSelect = forwardRef<
side={'bottom'}
align={'center'}
>
<SelectPrimitive.ScrollUpButton className="flex items-center justify-center p-1 absolute w-full h-6 z-20 bg-gradient-to-t from-transparent to-neutral-50 dark:to-neutral-900">
<SelectPrimitive.ScrollUpButton className="flex items-center justify-center py-1 absolute w-full h-6 z-20 bg-gradient-to-t from-transparent to-neutral-50 dark:to-neutral-900">
<Icon name="chevron-up" />
</SelectPrimitive.ScrollUpButton>
<SelectPrimitive.Viewport>{children}</SelectPrimitive.Viewport>
<SelectPrimitive.ScrollDownButton className="flex items-center justify-center p-1 absolute bottom-0 w-full h-6 z-20 bg-gradient-to-b from-transparent to-neutral-50 dark:to-neutral-900">
<SelectPrimitive.ScrollDownButton className="flex items-center justify-center py-1 absolute bottom-0 w-full h-6 z-20 bg-gradient-to-b from-transparent to-neutral-50 dark:to-neutral-900">
<Icon name="chevron-down" />
</SelectPrimitive.ScrollDownButton>
</SelectPrimitive.Content>

View File

@ -2,7 +2,7 @@ import { useAccountBalance } from '@vegaprotocol/accounts';
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
import { useBalancesStore } from '@vegaprotocol/assets';
import { Balance } from '@vegaprotocol/assets';
import { addDecimal } from '@vegaprotocol/utils';
import { addDecimal, formatNumber } from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js';
import { useEffect } from 'react';
@ -23,7 +23,10 @@ export const AssetBalance = ({ asset }: { asset: AssetFieldsFragment }) => {
return (
<Balance
balance={getBalance(asset.id)?.balanceOnVega?.toString()}
balance={formatNumber(
getBalance(asset.id)?.balanceOnVega || 0,
accountDecimals || 0
)}
symbol={asset.symbol}
/>
);

View File

@ -10,11 +10,9 @@ import {
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import {
ActionsDropdown,
ButtonLink,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
@ -160,7 +158,7 @@ export type CompleteCellProps = {
};
export const CompleteCell = ({ data, complete }: CompleteCellProps) => {
const open = useWithdrawalApprovalDialog((state) => state.open);
const ref = useRef<HTMLDivElement>(null);
const ref = useRef<HTMLButtonElement>(null);
if (!data) {
return null;
@ -176,32 +174,20 @@ export const CompleteCell = ({ data, complete }: CompleteCellProps) => {
{t('Complete withdrawal')}
</ButtonLink>
<DropdownMenu
trigger={
<DropdownMenuTrigger
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
>
<VegaIcon name={VegaIconNames.KEBAB} />
</DropdownMenuTrigger>
}
>
<DropdownMenuContent>
<DropdownMenuItem
key={'withdrawal-approval'}
data-testid="withdrawal-approval"
ref={ref}
onClick={() => {
if (data.id) {
open(data.id, ref.current, false);
}
}}
>
<VegaIcon name={VegaIconNames.BREAKDOWN} size={16} />
{t('View withdrawal details')}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<ActionsDropdown>
<DropdownMenuItem
key={'withdrawal-approval'}
data-testid="withdrawal-approval"
onClick={() => {
if (data.id) {
open(data.id, ref.current, false);
}
}}
>
<VegaIcon name={VegaIconNames.BREAKDOWN} size={16} />
{t('View withdrawal details')}
</DropdownMenuItem>
</ActionsDropdown>
</div>
);
};