chore(trading): dropdown alignments, account history default asset, transfer dialog asset selector (#4239)
This commit is contained in:
parent
fc8f12d6fc
commit
f6fc4df1c5
@ -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();
|
||||
});
|
||||
|
||||
|
@ -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}
|
||||
/>
|
||||
|
@ -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 ? (
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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}
|
||||
|
@ -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)
|
||||
);
|
||||
|
||||
|
@ -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>
|
||||
)}
|
||||
|
@ -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) => {
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
@ -1 +1,2 @@
|
||||
export * from './dropdown-menu';
|
||||
export * from './actions-dropdown';
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
@ -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,
|
||||
};
|
||||
|
@ -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>
|
||||
|
@ -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}
|
||||
/>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user