feat(trading): additional row actions for tables (#3600)
This commit is contained in:
parent
0be934edca
commit
8dc465c1d1
@ -32,9 +32,9 @@
|
||||
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
||||
}
|
||||
|
||||
.vega-ag-grid .ag-row {
|
||||
border-width: 1px 0;
|
||||
border-bottom: 1px solid transparent;
|
||||
.vega-ag-grid .ag-row,
|
||||
.vega-ag-grid .ag-cell {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
/* Light variables */
|
||||
@ -46,7 +46,6 @@
|
||||
--ag-header-column-separator-color: theme(colors.neutral[300]);
|
||||
--ag-row-border-color: theme(colors.white);
|
||||
--ag-row-hover-color: theme(colors.neutral[100]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
|
||||
/* Dark variables */
|
||||
@ -58,7 +57,6 @@
|
||||
--ag-header-column-separator-color: theme(colors.neutral[600]);
|
||||
--ag-row-border-color: theme(colors.black);
|
||||
--ag-row-hover-color: theme(colors.neutral[800]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
|
||||
.voteicon svg {
|
||||
|
@ -40,9 +40,9 @@
|
||||
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
||||
}
|
||||
|
||||
.vega-ag-grid .ag-row {
|
||||
border-width: 1px 0;
|
||||
border-bottom: 1px solid transparent;
|
||||
.vega-ag-grid .ag-row,
|
||||
.vega-ag-grid .ag-cell {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
/* Dark variables */
|
||||
@ -54,7 +54,6 @@
|
||||
--ag-header-column-separator-color: theme(colors.neutral[600]);
|
||||
--ag-row-border-color: theme(colors.black);
|
||||
--ag-row-hover-color: theme(colors.neutral[800]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
|
||||
.validators-table .ag-theme-balham-dark .ag-body-horizontal-scroll {
|
||||
|
@ -318,10 +318,11 @@ describe('Closed markets', { tags: '@smoke' }, () => {
|
||||
.should('have.text', product.settlementAsset.symbol);
|
||||
|
||||
// 6001-MARK-020
|
||||
cy.get(rowSelector)
|
||||
cy.get('.ag-pinned-right-cols-container')
|
||||
.find('[col-id="market-actions"]')
|
||||
.first()
|
||||
.find('[col-id="id"]')
|
||||
.should('have.text', settledMarket.id);
|
||||
.find('button svg')
|
||||
.should('exist');
|
||||
});
|
||||
|
||||
// test market list for market in terminated state
|
||||
@ -373,5 +374,33 @@ describe('Closed markets', { tags: '@smoke' }, () => {
|
||||
'have.text',
|
||||
`Asset details - ${settlementAsset.symbol}`
|
||||
);
|
||||
|
||||
cy.get('[data-testid="dialog-close"]').click();
|
||||
});
|
||||
|
||||
it('can open row actions', () => {
|
||||
cy.get('.ag-pinned-right-cols-container')
|
||||
.find('[col-id="market-actions"]')
|
||||
.first()
|
||||
.find('button')
|
||||
.click();
|
||||
|
||||
const dropdownContent = '[data-testid="market-actions-content"]';
|
||||
const dropdownContentItem = '[role="menuitem"]';
|
||||
cy.get(dropdownContent)
|
||||
.find(dropdownContentItem)
|
||||
.eq(0)
|
||||
// Cannot click the copy button as it falls back to window.prompt, blocking the test.
|
||||
.should('have.text', 'Copy Market ID');
|
||||
|
||||
cy.get(dropdownContent)
|
||||
.find(dropdownContentItem)
|
||||
.eq(1)
|
||||
.find('a')
|
||||
.then(($el) => {
|
||||
const href = $el.attr('href');
|
||||
expect(/\/markets\/0/.test(href || '')).to.equal(true);
|
||||
})
|
||||
.should('have.text', 'View on Explorer');
|
||||
});
|
||||
});
|
||||
|
@ -108,10 +108,9 @@ describe('deposit actions', { tags: '@smoke' }, () => {
|
||||
|
||||
it('Deposit to trade is visble', () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit to trade').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit to trade').click();
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.getByTestId('deposit-submit').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
@ -48,7 +48,7 @@ describe('accounts', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId('tab-accounts')
|
||||
.get(tradingAccountRowId)
|
||||
.find('[col-id="accounts-actions"]')
|
||||
.should('have.text', ' ');
|
||||
.should('have.text', '');
|
||||
|
||||
cy.getByTestId('tab-accounts')
|
||||
.get(tradingAccountRowId)
|
||||
|
@ -214,7 +214,7 @@ describe('Closed', () => {
|
||||
'Settlement price',
|
||||
'Realised PNL',
|
||||
'Settlement asset',
|
||||
'Market ID',
|
||||
'', // actions row
|
||||
];
|
||||
expect(headers).toHaveLength(expectedHeaders.length);
|
||||
expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders);
|
||||
@ -236,7 +236,7 @@ describe('Closed', () => {
|
||||
addDecimalsFormatNumber(property.value, market.decimalPlaces),
|
||||
addDecimalsFormatNumber(position.realisedPNL, market.decimalPlaces),
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol,
|
||||
market.id,
|
||||
'', // actions row
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
@ -328,8 +328,13 @@ describe('Closed', () => {
|
||||
// check that only included ids are shown
|
||||
const cells = screen
|
||||
.getAllByRole('gridcell')
|
||||
.filter((cell) => cell.getAttribute('col-id') === 'id')
|
||||
.map((cell) => cell.textContent?.trim());
|
||||
.filter((cell) => cell.getAttribute('col-id') === 'code')
|
||||
.map((cell) => {
|
||||
const marketId = within(cell)
|
||||
.getByTestId('market-code')
|
||||
.getAttribute('data-market-id');
|
||||
return marketId;
|
||||
});
|
||||
expect(cells).toEqual(expectedRows.map((m) => m.node.id));
|
||||
});
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ import type {
|
||||
VegaICellRendererParams,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
||||
import { AgGridLazy as AgGrid, COL_DEFS } from '@vegaprotocol/datagrid';
|
||||
import { useMemo } from 'react';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { MarketState, MarketStateMapping } from '@vegaprotocol/types';
|
||||
@ -14,7 +14,10 @@ import {
|
||||
} from '@vegaprotocol/utils';
|
||||
import { usePositionsQuery } from '@vegaprotocol/positions';
|
||||
import type { MarketMaybeWithData } from '@vegaprotocol/market-list';
|
||||
import { closedMarketsWithDataProvider } from '@vegaprotocol/market-list';
|
||||
import {
|
||||
MarketTableActions,
|
||||
closedMarketsWithDataProvider,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import type { ColDef } from 'ag-grid-community';
|
||||
@ -121,6 +124,16 @@ const ClosedMarketsDataGrid = ({ rowData }: { rowData: Row[] }) => {
|
||||
{
|
||||
headerName: t('Market'),
|
||||
field: 'code',
|
||||
cellRenderer: ({
|
||||
value,
|
||||
data,
|
||||
}: VegaICellRendererParams<Row, 'code'>) => {
|
||||
return (
|
||||
<span data-testid="market-code" data-market-id={data?.id}>
|
||||
{value}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
headerName: t('Description'),
|
||||
@ -262,9 +275,17 @@ const ClosedMarketsDataGrid = ({ rowData }: { rowData: Row[] }) => {
|
||||
),
|
||||
},
|
||||
{
|
||||
headerName: t('Market ID'),
|
||||
field: 'id',
|
||||
flex: 1,
|
||||
colId: 'market-actions',
|
||||
...COL_DEFS.actions,
|
||||
cellRenderer: ({ data }: VegaICellRendererParams<Row>) => {
|
||||
if (!data) return null;
|
||||
return (
|
||||
<MarketTableActions
|
||||
marketId={data.id}
|
||||
assetId={data.settlementAsset.id}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
return cols;
|
||||
|
@ -21,6 +21,7 @@ import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { WalletIcon } from '../icons/wallet';
|
||||
import { useTransferDialog } from '@vegaprotocol/accounts';
|
||||
import { useCopyTimeout } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const MobileWalletButton = ({
|
||||
isConnected,
|
||||
@ -237,21 +238,7 @@ export const VegaWalletConnectButton = () => {
|
||||
};
|
||||
|
||||
const KeypairItem = ({ pk }: { pk: PubKey }) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line
|
||||
let timeout: any;
|
||||
|
||||
if (copied) {
|
||||
timeout = setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 800);
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}, [copied]);
|
||||
const [copied, setCopied] = useCopyTimeout();
|
||||
|
||||
return (
|
||||
<DropdownMenuRadioItem value={pk.publicKey}>
|
||||
|
@ -93,9 +93,9 @@ html [data-theme='light'] {
|
||||
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
||||
}
|
||||
|
||||
.vega-ag-grid .ag-row {
|
||||
border-width: 1px 0;
|
||||
border-bottom: 1px solid transparent;
|
||||
.vega-ag-grid .ag-row,
|
||||
.vega-ag-grid .ag-cell {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
/* Light variables */
|
||||
@ -107,7 +107,6 @@ html [data-theme='light'] {
|
||||
--ag-header-column-separator-color: theme(colors.neutral[300]);
|
||||
--ag-row-border-color: theme(colors.white);
|
||||
--ag-row-hover-color: theme(colors.neutral[100]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
|
||||
/* Dark variables */
|
||||
@ -119,7 +118,6 @@ html [data-theme='light'] {
|
||||
--ag-header-column-separator-color: theme(colors.neutral[600]);
|
||||
--ag-row-border-color: theme(colors.black);
|
||||
--ag-row-hover-color: theme(colors.neutral[800]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
.ag-theme-balham-dark .ag-row.no-hover,
|
||||
.ag-theme-balham-dark .ag-row.no-hover:hover,
|
||||
|
103
libs/accounts/src/lib/accounts-actions-dropdown.tsx
Normal file
103
libs/accounts/src/lib/accounts-actions-dropdown.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
import { ETHERSCAN_ADDRESS, useEtherscanLink } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuCopyItem,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
Link,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useTransferDialog } from './transfer-dialog';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
|
||||
export const AccountsActionsDropdown = ({
|
||||
assetId,
|
||||
assetContractAddress,
|
||||
onClickDeposit,
|
||||
onClickWithdraw,
|
||||
onClickBreakdown,
|
||||
}: {
|
||||
assetId: string;
|
||||
assetContractAddress?: string;
|
||||
onClickDeposit: () => void;
|
||||
onClickWithdraw: () => void;
|
||||
onClickBreakdown: () => void;
|
||||
}) => {
|
||||
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')}
|
||||
</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>
|
||||
);
|
||||
};
|
@ -9,14 +9,11 @@ import type {
|
||||
VegaICellRendererParams,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { COL_DEFS } from '@vegaprotocol/datagrid';
|
||||
import {
|
||||
Button,
|
||||
ButtonLink,
|
||||
Dialog,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
@ -38,6 +35,7 @@ import type { AccountFields } from './accounts-data-provider';
|
||||
import type { Asset } from '@vegaprotocol/types';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import classNames from 'classnames';
|
||||
import { AccountsActionsDropdown } from './accounts-actions-dropdown';
|
||||
|
||||
const colorClass = (percentageUsed: number, neutral = false) => {
|
||||
return classNames({
|
||||
@ -109,7 +107,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
const [row, setRow] = useState<AccountFields>();
|
||||
const pinnedAssetId = props.pinnedAsset?.id;
|
||||
|
||||
const pinnedAssetRow = useMemo(() => {
|
||||
const pinnedAsset = useMemo(() => {
|
||||
const currentPinnedAssetRow = props.rowData?.find(
|
||||
(row) => row.asset.id === pinnedAssetId
|
||||
);
|
||||
@ -143,6 +141,13 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
[pinnedAssetId, getRowHeight]
|
||||
);
|
||||
|
||||
const accountForPinnedAsset = props?.rowData?.find(
|
||||
(a) => a.asset.id === pinnedAssetId
|
||||
);
|
||||
const showDepositButton = accountForPinnedAsset
|
||||
? new BigNumber(accountForPinnedAsset.total).isLessThanOrEqualTo(0)
|
||||
: true;
|
||||
|
||||
return (
|
||||
<>
|
||||
<AgGrid
|
||||
@ -162,7 +167,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
comparator: accountValuesComparator,
|
||||
}}
|
||||
getRowHeight={getPinnedAssetRowHeight}
|
||||
pinnedTopRowData={pinnedAssetRow ? [pinnedAssetRow] : undefined}
|
||||
pinnedTopRowData={pinnedAsset ? [pinnedAsset] : undefined}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Asset')}
|
||||
@ -266,104 +271,57 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
formatWithAssetDecimals(data, data?.total)
|
||||
}
|
||||
/>
|
||||
{
|
||||
<AgGridColumn
|
||||
colId="accounts-actions"
|
||||
headerName=""
|
||||
sortable={false}
|
||||
maxWidth={200}
|
||||
type="rightAligned"
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<AccountFields>) => {
|
||||
if (!data) return null;
|
||||
else {
|
||||
if (
|
||||
data.asset.id === pinnedAssetId &&
|
||||
new BigNumber(data.total).isLessThanOrEqualTo(0)
|
||||
) {
|
||||
return (
|
||||
<CenteredGridCellWrapper className="h-[30px] justify-end py-1">
|
||||
<Button
|
||||
size="xs"
|
||||
variant="primary"
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit to trade')}
|
||||
</Button>
|
||||
</CenteredGridCellWrapper>
|
||||
);
|
||||
}
|
||||
<AgGridColumn
|
||||
colId="accounts-actions"
|
||||
{...COL_DEFS.actions}
|
||||
minWidth={showDepositButton ? 130 : COL_DEFS.actions.minWidth}
|
||||
maxWidth={showDepositButton ? 130 : COL_DEFS.actions.maxWidth}
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<AccountFields>) => {
|
||||
if (!data) return null;
|
||||
else {
|
||||
if (showDepositButton && data.asset.id === pinnedAssetId) {
|
||||
return (
|
||||
!props.isReadOnly && (
|
||||
<DropdownMenu
|
||||
trigger={
|
||||
<DropdownMenuTrigger
|
||||
iconName="more"
|
||||
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"
|
||||
></DropdownMenuTrigger>
|
||||
}
|
||||
<CenteredGridCellWrapper className="h-[30px] justify-end py-1">
|
||||
<Button
|
||||
size="xs"
|
||||
variant="primary"
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
key={'deposit'}
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
<span className="flex gap-2">
|
||||
<VegaIcon
|
||||
name={VegaIconNames.DEPOSIT}
|
||||
size={16}
|
||||
/>
|
||||
{t('Deposit')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
key={'withdraw'}
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
<span className="flex gap-2">
|
||||
<VegaIcon
|
||||
name={VegaIconNames.WITHDRAW}
|
||||
size={16}
|
||||
/>
|
||||
{t('Withdraw')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
key={'breakdown'}
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setRow(data);
|
||||
}}
|
||||
>
|
||||
<span className="flex gap-2">
|
||||
<VegaIcon
|
||||
name={VegaIconNames.BREAKDOWN}
|
||||
size={16}
|
||||
/>
|
||||
{t('Breakdown')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
<VegaIcon name={VegaIconNames.DEPOSIT} /> {t('Deposit')}
|
||||
</Button>
|
||||
</CenteredGridCellWrapper>
|
||||
);
|
||||
}
|
||||
}}
|
||||
flex={1}
|
||||
/>
|
||||
}
|
||||
return (
|
||||
!props.isReadOnly && (
|
||||
<AccountsActionsDropdown
|
||||
assetId={data.asset.id}
|
||||
assetContractAddress={
|
||||
data.asset.source?.__typename === 'ERC20'
|
||||
? data.asset.source.contractAddress
|
||||
: undefined
|
||||
}
|
||||
onClickDeposit={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
onClickWithdraw={() => {
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id);
|
||||
}}
|
||||
onClickBreakdown={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setRow(data);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</AgGrid>
|
||||
<Dialog size="medium" open={openBreakdown} onChange={setOpenBreakdown}>
|
||||
<div
|
||||
|
@ -14,7 +14,7 @@ import { TransferForm } from './transfer-form';
|
||||
import { useTransferDialog } from './transfer-dialog';
|
||||
import { Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export const TransferContainer = () => {
|
||||
export const TransferContainer = ({ assetId }: { assetId?: string }) => {
|
||||
const { pubKey, pubKeys } = useVegaWallet();
|
||||
const open = useTransferDialog((store) => store.open);
|
||||
const { param } = useNetworkParam(NetworkParams.transfer_fee_factor);
|
||||
@ -59,6 +59,7 @@ export const TransferContainer = () => {
|
||||
pubKey={pubKey}
|
||||
pubKeys={pubKeys ? pubKeys?.map((pk) => pk.publicKey) : null}
|
||||
assets={assets}
|
||||
assetId={assetId}
|
||||
feeFactor={param}
|
||||
submitTransfer={transfer}
|
||||
/>
|
||||
|
@ -5,24 +5,26 @@ import { TransferContainer } from './transfer-container';
|
||||
|
||||
interface State {
|
||||
isOpen: boolean;
|
||||
assetId: string | undefined;
|
||||
}
|
||||
|
||||
interface Actions {
|
||||
open: (open?: boolean) => void;
|
||||
open: (open?: boolean, assetId?: string) => void;
|
||||
}
|
||||
|
||||
export const useTransferDialog = create<State & Actions>()((set) => ({
|
||||
isOpen: false,
|
||||
open: (open = true) => {
|
||||
set(() => ({ isOpen: open }));
|
||||
assetId: undefined,
|
||||
open: (open = true, assetId) => {
|
||||
set(() => ({ isOpen: open, assetId }));
|
||||
},
|
||||
}));
|
||||
|
||||
export const TransferDialog = () => {
|
||||
const { isOpen, open } = useTransferDialog();
|
||||
const { isOpen, open, assetId } = useTransferDialog();
|
||||
return (
|
||||
<Dialog title={t('Transfer')} open={isOpen} onChange={open} size="small">
|
||||
<TransferContainer />
|
||||
<TransferContainer assetId={assetId} />
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
@ -41,6 +41,7 @@ interface TransferFormProps {
|
||||
decimals: number;
|
||||
balance: string;
|
||||
}>;
|
||||
assetId?: string;
|
||||
feeFactor: string | null;
|
||||
submitTransfer: (transfer: Transfer) => void;
|
||||
}
|
||||
@ -49,6 +50,7 @@ export const TransferForm = ({
|
||||
pubKey,
|
||||
pubKeys,
|
||||
assets,
|
||||
assetId: initialAssetId,
|
||||
feeFactor,
|
||||
submitTransfer,
|
||||
}: TransferFormProps) => {
|
||||
@ -59,7 +61,11 @@ export const TransferForm = ({
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<FormFields>();
|
||||
} = useForm<FormFields>({
|
||||
defaultValues: {
|
||||
asset: initialAssetId,
|
||||
},
|
||||
});
|
||||
|
||||
const amount = watch('amount');
|
||||
const assetId = watch('asset');
|
||||
|
@ -1,6 +1,8 @@
|
||||
export * from './lib/ag-grid/ag-grid-lazy';
|
||||
export * from './lib/ag-grid/use-column-sizes';
|
||||
|
||||
export * from './lib/column-definitions';
|
||||
|
||||
export * from './lib/cells/cumulative-vol-cell';
|
||||
export * from './lib/cells/flash-cell';
|
||||
export * from './lib/cells/numeric-cell';
|
||||
|
12
libs/datagrid/src/lib/column-definitions.ts
Normal file
12
libs/datagrid/src/lib/column-definitions.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export const COL_DEFS = {
|
||||
actions: {
|
||||
headerName: '',
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
filter: false,
|
||||
minWidth: 45,
|
||||
maxWidth: 45,
|
||||
type: 'rightAligned',
|
||||
pinned: 'right',
|
||||
},
|
||||
};
|
@ -154,19 +154,21 @@ export const NetworkSwitcher = ({
|
||||
<>
|
||||
{advancedNetworkKeys.map((key) => (
|
||||
<DropdownMenuItem key={key} data-testid="network-item-advanced">
|
||||
<div className="mr-4">
|
||||
<Link href={VEGA_NETWORKS[key]}>{envNameMapping[key]}</Link>
|
||||
<NetworkLabel
|
||||
isCurrent={current === key}
|
||||
isAvailable={!!VEGA_NETWORKS[key]}
|
||||
/>
|
||||
<div className="w-full flex justify-between gap-2">
|
||||
<div>
|
||||
<Link href={VEGA_NETWORKS[key]}>{envNameMapping[key]}</Link>
|
||||
<NetworkLabel
|
||||
isCurrent={current === key}
|
||||
isAvailable={!!VEGA_NETWORKS[key]}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="hidden md:inline"
|
||||
data-testid="network-item-description"
|
||||
>
|
||||
{envDescriptionMapping[key]}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className="hidden md:inline"
|
||||
data-testid="network-item-description"
|
||||
>
|
||||
{envDescriptionMapping[key]}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</>
|
||||
|
@ -133,6 +133,7 @@ export const useProtocolUpgradeProposalLink = () => {
|
||||
// Explorer pages
|
||||
export const EXPLORER_TX = '/txs/:hash';
|
||||
export const EXPLORER_ORACLE = '/oracles/:id';
|
||||
export const EXPLORER_MARKET = '/markets/:id';
|
||||
|
||||
// Etherscan pages
|
||||
export const ETHERSCAN_ADDRESS = '/address/:hash';
|
||||
|
44
libs/fills/src/lib/fill-actions-dropdown.tsx
Normal file
44
libs/fills/src/lib/fill-actions-dropdown.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuCopyItem,
|
||||
DropdownMenuTrigger,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const FillActionsDropdown = ({
|
||||
tradeId,
|
||||
buyOrderId,
|
||||
sellOrderId,
|
||||
}: {
|
||||
tradeId: string;
|
||||
buyOrderId: string;
|
||||
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>
|
||||
);
|
||||
};
|
@ -48,6 +48,7 @@ describe('FillsTable', () => {
|
||||
'Role',
|
||||
'Fee',
|
||||
'Date',
|
||||
'', // action column
|
||||
];
|
||||
expect(headers).toHaveLength(expectedHeaders.length);
|
||||
expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders);
|
||||
@ -77,6 +78,7 @@ describe('FillsTable', () => {
|
||||
'Maker',
|
||||
'2.00 BTC',
|
||||
getDateTimeFormat().format(new Date(buyerFill.createdAt)),
|
||||
'', // action column
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
@ -111,6 +113,7 @@ describe('FillsTable', () => {
|
||||
'Taker',
|
||||
'0.03 BTC',
|
||||
getDateTimeFormat().format(new Date(buyerFill.createdAt)),
|
||||
'', // action column
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
@ -145,6 +148,7 @@ describe('FillsTable', () => {
|
||||
'-',
|
||||
'0.03 BTC',
|
||||
getDateTimeFormat().format(new Date(buyerFill.createdAt)),
|
||||
'', // action column
|
||||
];
|
||||
cells.forEach((cell, i) => {
|
||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||
|
@ -19,12 +19,17 @@ import {
|
||||
positiveClassNames,
|
||||
negativeClassNames,
|
||||
MarketNameCell,
|
||||
COL_DEFS,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type {
|
||||
VegaValueFormatterParams,
|
||||
VegaICellRendererParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/datagrid';
|
||||
import { forwardRef } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { Trade } from './fills-data-provider';
|
||||
import type { FillFieldsFragment } from './__generated__/Fills';
|
||||
import { FillActionsDropdown } from './fill-actions-dropdown';
|
||||
|
||||
const TAKER = 'Taker';
|
||||
const MAKER = 'Maker';
|
||||
@ -108,6 +113,20 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
return value ? getDateTimeFormat().format(new Date(value)) : '';
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
colId="fill-actions"
|
||||
{...COL_DEFS.actions}
|
||||
cellRenderer={({ data }: VegaICellRendererParams<Trade, 'id'>) => {
|
||||
if (!data) return null;
|
||||
return (
|
||||
<FillActionsDropdown
|
||||
buyOrderId={data.buyOrder}
|
||||
sellOrderId={data.sellOrder}
|
||||
tradeId={data.id}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</AgGrid>
|
||||
);
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './markets-container';
|
||||
export * from './market-table-actions';
|
||||
|
@ -0,0 +1 @@
|
||||
export * from './market-table-actions';
|
@ -0,0 +1,59 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuCopyItem,
|
||||
Link,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { DApp, EXPLORER_MARKET, useLinks } from '@vegaprotocol/environment';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
|
||||
export const MarketTableActions = ({
|
||||
marketId,
|
||||
assetId,
|
||||
}: {
|
||||
marketId: string;
|
||||
assetId: string;
|
||||
}) => {
|
||||
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"
|
||||
>
|
||||
<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>
|
||||
);
|
||||
};
|
@ -7,6 +7,7 @@ import type {
|
||||
VegaICellRendererParams,
|
||||
TypedDataAgGrid,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { COL_DEFS } from '@vegaprotocol/datagrid';
|
||||
import {
|
||||
AgGridLazy as AgGrid,
|
||||
PriceFlashCell,
|
||||
@ -18,6 +19,7 @@ import { AgGridColumn } from 'ag-grid-react';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { MarketMaybeWithData } from '../../';
|
||||
import { MarketTableActions } from '../../';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
|
||||
const { MarketTradingMode, AuctionTrigger } = Schema;
|
||||
@ -176,15 +178,13 @@ export const MarketListTable = forwardRef<
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Settlement asset')}
|
||||
field="tradableInstrument.instrument.product.settlementAsset.symbol"
|
||||
field="tradableInstrument.instrument.product.settlementAsset"
|
||||
cellRenderer={({
|
||||
data,
|
||||
value,
|
||||
}: VegaICellRendererParams<
|
||||
MarketMaybeWithData,
|
||||
'tradableInstrument.instrument.product.settlementAsset.symbol'
|
||||
'tradableInstrument.instrument.product.settlementAsset'
|
||||
>) => {
|
||||
const value =
|
||||
data?.tradableInstrument.instrument.product.settlementAsset;
|
||||
return value ? (
|
||||
<ButtonLink
|
||||
onClick={(e) => {
|
||||
@ -198,7 +198,23 @@ export const MarketListTable = forwardRef<
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn headerName={t('Market ID')} field="id" flex={1} />
|
||||
<AgGridColumn
|
||||
colId="market-actions"
|
||||
{...COL_DEFS.actions}
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<MarketMaybeWithData>) => {
|
||||
if (!data) return null;
|
||||
return (
|
||||
<MarketTableActions
|
||||
marketId={data.id}
|
||||
assetId={
|
||||
data.tradableInstrument.instrument.product.settlementAsset.id
|
||||
}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</AgGrid>
|
||||
);
|
||||
});
|
||||
|
@ -36,9 +36,12 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||
suppressNoRowsOverlay
|
||||
onCellClicked={(cellEvent: CellClickedEvent) => {
|
||||
const { data, column, event } = cellEvent;
|
||||
// prevent navigating to the market page if any of the below cells are clicked
|
||||
// event.preventDefault or event.stopPropagation dont seem to apply for aggird
|
||||
const colId = column.getColId();
|
||||
if (
|
||||
[
|
||||
'id',
|
||||
'tradableInstrument.instrument.code',
|
||||
'tradableInstrument.instrument.product.settlementAsset',
|
||||
].includes(colId)
|
||||
|
@ -0,0 +1 @@
|
||||
export * from './order-actions-dropdown';
|
@ -0,0 +1,28 @@
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
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>
|
||||
);
|
||||
};
|
@ -145,7 +145,7 @@ export const OrderListManager = ({
|
||||
<OrderListTable
|
||||
rowData={data as Order[]}
|
||||
ref={gridRef}
|
||||
readonlyStatusFilter={filter !== undefined}
|
||||
filter={filter}
|
||||
onGridReady={onGridReady}
|
||||
cancel={cancel}
|
||||
setEditOrder={setEditOrder}
|
||||
|
@ -160,7 +160,6 @@ describe('OrderListTable', () => {
|
||||
);
|
||||
});
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.getAllByRole('button')).toHaveLength(2);
|
||||
await userEvent.click(amendCell.getByTestId('edit'));
|
||||
expect(mockEdit).toHaveBeenCalledWith(order);
|
||||
await userEvent.click(amendCell.getByTestId('cancel'));
|
||||
@ -187,7 +186,8 @@ describe('OrderListTable', () => {
|
||||
);
|
||||
});
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
expect(amendCell.queryByTestId('edit')).not.toBeInTheDocument();
|
||||
expect(amendCell.queryByTestId('cancel')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows if an order is a liquidity provision order and does not show order actions', async () => {
|
||||
@ -204,7 +204,8 @@ describe('OrderListTable', () => {
|
||||
const amendCell = getAmendCell();
|
||||
const typeCell = screen.getAllByRole('gridcell')[2];
|
||||
expect(typeCell).toHaveTextContent('Liquidity provision');
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
expect(amendCell.queryByTestId('edit')).not.toBeInTheDocument();
|
||||
expect(amendCell.queryByTestId('cancel')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows if an order is a pegged order and does not show order actions', async () => {
|
||||
@ -225,7 +226,8 @@ describe('OrderListTable', () => {
|
||||
const amendCell = getAmendCell();
|
||||
const typeCell = screen.getAllByRole('gridcell')[2];
|
||||
expect(typeCell).toHaveTextContent('Mid - 10.0 Peg limit');
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
expect(amendCell.queryByTestId('edit')).not.toBeInTheDocument();
|
||||
expect(amendCell.queryByTestId('cancel')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it.each([
|
||||
@ -242,7 +244,7 @@ describe('OrderListTable', () => {
|
||||
});
|
||||
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.getAllByRole('button')).toHaveLength(2);
|
||||
expect(amendCell.getAllByRole('button')).toHaveLength(3);
|
||||
});
|
||||
|
||||
it.each([
|
||||
@ -251,19 +253,23 @@ describe('OrderListTable', () => {
|
||||
Schema.OrderStatus.STATUS_FILLED,
|
||||
Schema.OrderStatus.STATUS_REJECTED,
|
||||
Schema.OrderStatus.STATUS_STOPPED,
|
||||
])('does not show buttons for %s orders', async (status) => {
|
||||
const order = generateOrder({
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status,
|
||||
});
|
||||
])(
|
||||
'does not show edit and cancel buttons for %s orders',
|
||||
async (status) => {
|
||||
const order = generateOrder({
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
status,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(generateJsx({ rowData: [order] }));
|
||||
});
|
||||
await act(async () => {
|
||||
render(generateJsx({ rowData: [order] }));
|
||||
});
|
||||
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
});
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryByTestId('edit')).not.toBeInTheDocument();
|
||||
expect(amendCell.queryByTestId('cancel')).not.toBeInTheDocument();
|
||||
}
|
||||
);
|
||||
|
||||
const getAmendCell = () => {
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
positiveClassNames,
|
||||
MarketNameCell,
|
||||
OrderTypeCell,
|
||||
COL_DEFS,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type {
|
||||
TypedDataAgGrid,
|
||||
@ -26,7 +27,8 @@ import type {
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import type { Order } from '../order-data-provider';
|
||||
import * as React from 'react';
|
||||
import { OrderActionsDropdown } from '../order-actions-dropdown';
|
||||
import { Filter } from '../order-list-manager';
|
||||
|
||||
export type OrderListTableProps = TypedDataAgGrid<Order> & {
|
||||
marketId?: string;
|
||||
@ -34,7 +36,7 @@ export type OrderListTableProps = TypedDataAgGrid<Order> & {
|
||||
setEditOrder: (order: Order) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
onOrderTypeClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
readonlyStatusFilter?: boolean;
|
||||
filter?: Filter;
|
||||
isReadOnly: boolean;
|
||||
storeKey?: string;
|
||||
};
|
||||
@ -49,11 +51,14 @@ export const OrderListTable = memo<
|
||||
setEditOrder,
|
||||
onMarketClick,
|
||||
onOrderTypeClick,
|
||||
readonlyStatusFilter,
|
||||
filter,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const showAllActions =
|
||||
filter === undefined || filter === Filter.Open ? true : false;
|
||||
|
||||
return (
|
||||
<AgGrid
|
||||
ref={ref}
|
||||
@ -130,7 +135,7 @@ export const OrderListTable = memo<
|
||||
filter={SetFilter}
|
||||
filterParams={{
|
||||
set: Schema.OrderStatusMapping,
|
||||
readonly: readonlyStatusFilter,
|
||||
readonly: filter !== undefined,
|
||||
}}
|
||||
valueFormatter={({
|
||||
value,
|
||||
@ -270,28 +275,38 @@ export const OrderListTable = memo<
|
||||
/>
|
||||
<AgGridColumn
|
||||
colId="amend"
|
||||
headerName=""
|
||||
field="status"
|
||||
minWidth={100}
|
||||
type="rightAligned"
|
||||
cellRenderer={({ data, node }: VegaICellRendererParams<Order>) => {
|
||||
return data && isOrderAmendable(data) && !props.isReadOnly ? (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="edit"
|
||||
onClick={() => setEditOrder(data)}
|
||||
>
|
||||
{t('Edit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink data-testid="cancel" onClick={() => cancel(data)}>
|
||||
{t('Cancel')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
) : null;
|
||||
field="id"
|
||||
{...COL_DEFS.actions}
|
||||
minWidth={showAllActions ? 120 : COL_DEFS.actions.minWidth}
|
||||
maxWidth={showAllActions ? 120 : COL_DEFS.actions.minWidth}
|
||||
cellRenderer={({
|
||||
data,
|
||||
value,
|
||||
}: VegaICellRendererParams<Order, 'id'>) => {
|
||||
if (!value || !data) return null;
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 items-center justify-end">
|
||||
{isOrderAmendable(data) && !props.isReadOnly && (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="edit"
|
||||
onClick={() => setEditOrder(data)}
|
||||
>
|
||||
{t('Edit')}
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
data-testid="cancel"
|
||||
onClick={() => cancel(data)}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
)}
|
||||
<OrderActionsDropdown id={value} />
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
sortable={false}
|
||||
flex={1}
|
||||
/>
|
||||
</AgGrid>
|
||||
);
|
||||
|
37
libs/positions/src/lib/position-actions-dropdown.tsx
Normal file
37
libs/positions/src/lib/position-actions-dropdown.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
|
||||
export const PositionTableActions = ({ 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>
|
||||
);
|
||||
};
|
@ -57,6 +57,7 @@ export interface Position {
|
||||
positionDecimalPlaces: number;
|
||||
totalBalance: string;
|
||||
assetSymbol: string;
|
||||
assetId: string;
|
||||
lowMarginLevel: boolean;
|
||||
marketId: string;
|
||||
marketTradingMode: Schema.MarketTradingMode;
|
||||
@ -155,6 +156,7 @@ export const getMetrics = (
|
||||
decimals,
|
||||
assetSymbol:
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol,
|
||||
assetId: market.tradableInstrument.instrument.product.settlementAsset.id,
|
||||
totalBalance: totalBalance.multipliedBy(10 ** decimals).toFixed(),
|
||||
lowMarginLevel,
|
||||
marketId: market.id,
|
||||
|
@ -17,6 +17,7 @@ const singleRow: Position = {
|
||||
decimals: 2,
|
||||
totalBalance: '123456',
|
||||
assetSymbol: 'BTC',
|
||||
assetId: 'asset-id',
|
||||
lowMarginLevel: false,
|
||||
marketId: 'string',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
|
@ -8,6 +8,7 @@ import type {
|
||||
TypedDataAgGrid,
|
||||
VegaICellRendererParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { COL_DEFS } from '@vegaprotocol/datagrid';
|
||||
import { ProgressBarCell } from '@vegaprotocol/datagrid';
|
||||
import {
|
||||
AgGridLazy as AgGrid,
|
||||
@ -39,6 +40,8 @@ import * as Schema from '@vegaprotocol/types';
|
||||
import { getRowId } from './use-positions-data';
|
||||
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
|
||||
import { DocsLinks } from '@vegaprotocol/environment';
|
||||
import { PositionTableActions } from './position-actions-dropdown';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
|
||||
interface Props extends TypedDataAgGrid<Position> {
|
||||
onClose?: (data: Position) => void;
|
||||
@ -81,6 +84,7 @@ AmountCell.displayName = 'AmountCell';
|
||||
|
||||
export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
({ onClose, onMarketClick, ...props }, ref) => {
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
return (
|
||||
<AgGrid
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
@ -212,8 +216,20 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Settlement asset')}
|
||||
field="assetSymbol"
|
||||
colId="asset"
|
||||
minWidth={100}
|
||||
cellRenderer={({ data }: VegaICellRendererParams<Position>) => {
|
||||
if (!data) return null;
|
||||
return (
|
||||
<ButtonLink
|
||||
onClick={(e) => {
|
||||
openAssetDetailsDialog(data.assetId, e.target as HTMLElement);
|
||||
}}
|
||||
>
|
||||
{data?.assetSymbol}
|
||||
</ButtonLink>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Entry price')}
|
||||
@ -370,19 +386,26 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
/>
|
||||
{onClose && !props.isReadOnly ? (
|
||||
<AgGridColumn
|
||||
type="rightAligned"
|
||||
cellRenderer={({ data }: VegaICellRendererParams<Position>) =>
|
||||
data?.openVolume && data?.openVolume !== '0' ? (
|
||||
<ButtonLink
|
||||
data-testid="close-position"
|
||||
onClick={() => data && onClose(data)}
|
||||
>
|
||||
{t('Close')}
|
||||
</ButtonLink>
|
||||
) : null
|
||||
}
|
||||
minWidth={80}
|
||||
flex={1}
|
||||
{...COL_DEFS.actions}
|
||||
cellRenderer={({ data }: VegaICellRendererParams<Position>) => {
|
||||
return (
|
||||
<div className="flex gap-2 items-center justify-end">
|
||||
{data?.openVolume && data?.openVolume !== '0' ? (
|
||||
<ButtonLink
|
||||
data-testid="close-position"
|
||||
onClick={() => data && onClose(data)}
|
||||
>
|
||||
{t('Close')}
|
||||
</ButtonLink>
|
||||
) : null}
|
||||
{data?.assetId && (
|
||||
<PositionTableActions assetId={data?.assetId} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
minWidth={90}
|
||||
maxWidth={90}
|
||||
/>
|
||||
) : null}
|
||||
</AgGrid>
|
||||
|
@ -2,3 +2,5 @@ export * from './asset-proposal-notification';
|
||||
export * from './market-proposal-notification';
|
||||
export * from './protocol-upgrade-countdown';
|
||||
export * from './protocol-upgrade-proposal-notification';
|
||||
export * from './proposals-list';
|
||||
export * from './voting-progress';
|
||||
|
39
libs/proposals/src/components/proposal-actions-dropdown.tsx
Normal file
39
libs/proposals/src/components/proposal-actions-dropdown.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
Link,
|
||||
} 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"
|
||||
>
|
||||
<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>
|
||||
);
|
||||
};
|
@ -7,7 +7,7 @@ import {
|
||||
} from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { ProposalsList } from './proposals-list';
|
||||
import type { ProposalListFieldsFragment } from '../proposals-data-provider';
|
||||
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
const votesMock = {
|
@ -4,10 +4,10 @@ import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
import { proposalsDataProvider } from '../proposals-data-provider';
|
||||
import { proposalsDataProvider } from '../../lib/proposals-data-provider';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { useColumnDefs } from './use-column-defs';
|
||||
import type { ProposalListFieldsFragment } from '../proposals-data-provider/__generated__/Proposals';
|
||||
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
||||
|
||||
export const getNewMarketProposals = (data: ProposalListFieldsFragment[]) =>
|
||||
data.filter((proposal) =>
|
@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { ColDef } from 'ag-grid-community';
|
||||
import { DateRangeFilter, SetFilter } from '@vegaprotocol/datagrid';
|
||||
import { COL_DEFS, DateRangeFilter, SetFilter } from '@vegaprotocol/datagrid';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
@ -15,8 +15,9 @@ import type {
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { ProposalStateMapping } from '@vegaprotocol/types';
|
||||
import type { ProposalListFieldsFragment } from '../proposals-data-provider/__generated__/Proposals';
|
||||
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
||||
import { VoteProgress } from '../voting-progress';
|
||||
import { ProposalActionsDropdown } from '../proposal-actions-dropdown';
|
||||
|
||||
export const useColumnDefs = () => {
|
||||
const { VEGA_TOKEN_URL } = useEnvironment();
|
||||
@ -134,8 +135,20 @@ export const useColumnDefs = () => {
|
||||
filter: DateRangeFilter,
|
||||
flex: 1,
|
||||
},
|
||||
{
|
||||
colId: 'proposal-actions',
|
||||
...COL_DEFS.actions,
|
||||
cellRenderer: ({
|
||||
data,
|
||||
}: VegaICellRendererParams<ProposalListFieldsFragment>) => {
|
||||
if (!data?.id) return null;
|
||||
return <ProposalActionsDropdown id={data.id} />;
|
||||
},
|
||||
flex: 1,
|
||||
},
|
||||
];
|
||||
}, [VEGA_TOKEN_URL, requiredMajorityPercentage]);
|
||||
|
||||
const defaultColDef: ColDef = useMemo(() => {
|
||||
return {
|
||||
sortable: true,
|
||||
@ -145,6 +158,7 @@ export const useColumnDefs = () => {
|
||||
filterParams: { buttons: ['reset'] },
|
||||
};
|
||||
}, []);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
columnDefs,
|
@ -1,6 +1,4 @@
|
||||
export * from './proposals-hooks';
|
||||
export * from './voting-hooks';
|
||||
export * from './proposals-data-provider';
|
||||
export * from './proposals-list';
|
||||
export * from './voting-progress';
|
||||
export * from './proposals-hooks';
|
||||
export * from './protocol-upgrade-proposals';
|
||||
export * from './voting-hooks';
|
||||
|
@ -13,3 +13,4 @@ export * from './use-yesterday';
|
||||
export * from './use-previous';
|
||||
export * from './use-logger';
|
||||
export * from './use-pane-layout';
|
||||
export * from './use-copy-timeout';
|
||||
|
21
libs/react-helpers/src/hooks/use-copy-timeout.ts
Normal file
21
libs/react-helpers/src/hooks/use-copy-timeout.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export const useCopyTimeout = () => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line
|
||||
let timeout: any;
|
||||
|
||||
if (copied) {
|
||||
timeout = setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 800);
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}, [copied]);
|
||||
|
||||
return [copied, setCopied] as const;
|
||||
};
|
@ -2,11 +2,14 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import type { IconName } from '../icon';
|
||||
import { VegaIcon, VegaIconNames } from '../icon';
|
||||
import { Icon } from '../icon';
|
||||
import { useCopyTimeout } from '@vegaprotocol/react-helpers';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
const itemClass = classNames(
|
||||
'relative flex items-center justify-between rounded-sm p-2 text-sm',
|
||||
'relative flex gap-2 items-center rounded-sm p-2 text-sm',
|
||||
'cursor-default hover:cursor-pointer',
|
||||
'hover:bg-white dark:hover:bg-vega-dark-200',
|
||||
'focus:bg-white dark:focus:bg-vega-dark-200',
|
||||
@ -18,10 +21,6 @@ type DropdownMenuProps = DropdownMenuPrimitive.DropdownMenuProps & {
|
||||
trigger: ReactNode;
|
||||
};
|
||||
|
||||
type DropdownTriggerProps = DropdownMenuPrimitive.DropdownMenuTriggerProps & {
|
||||
iconName?: IconName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains all the parts of a dropdown menu.
|
||||
*/
|
||||
@ -43,8 +42,8 @@ export const DropdownMenu = ({
|
||||
*/
|
||||
export const DropdownMenuTrigger = forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
|
||||
DropdownTriggerProps
|
||||
>(({ className, children, iconName, ...props }, forwardedRef) => {
|
||||
DropdownMenuPrimitive.DropdownMenuTriggerProps
|
||||
>(({ className, children, ...props }, forwardedRef) => {
|
||||
const defaultClasses = [
|
||||
'text-sm py-1 px-2 rounded bg-transparent border whitespace-nowrap',
|
||||
'border-vega-light-200 dark:border-vega-dark-200',
|
||||
@ -58,9 +57,7 @@ export const DropdownMenuTrigger = forwardRef<
|
||||
className={className || defaultClasses}
|
||||
{...props}
|
||||
>
|
||||
<button>
|
||||
{children} {iconName && <Icon name={iconName || 'chevron-down'} />}
|
||||
</button>
|
||||
<button>{children}</button>
|
||||
</DropdownMenuPrimitive.Trigger>
|
||||
);
|
||||
});
|
||||
@ -110,7 +107,7 @@ export const DropdownMenuCheckboxItem = forwardRef<
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
{...checkboxItemProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames(itemClass, className)}
|
||||
className={classNames(itemClass, 'justify-between', className)}
|
||||
/>
|
||||
));
|
||||
|
||||
@ -126,7 +123,7 @@ export const DropdownMenuRadioItem = forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
{...radioItemProps}
|
||||
ref={forwardedRef}
|
||||
className={classNames(itemClass, className)}
|
||||
className={classNames(itemClass, 'justify-between', className)}
|
||||
/>
|
||||
));
|
||||
|
||||
@ -163,3 +160,32 @@ export const DropdownMenuSeparator = forwardRef<
|
||||
)}
|
||||
/>
|
||||
));
|
||||
|
||||
/**
|
||||
* Wraps a regular DropdownMenuItem with copy to clip board functionality
|
||||
*/
|
||||
export const DropdownMenuCopyItem = ({
|
||||
value,
|
||||
text,
|
||||
}: {
|
||||
value: string;
|
||||
text: string;
|
||||
}) => {
|
||||
const [copied, setCopied] = useCopyTimeout();
|
||||
|
||||
return (
|
||||
<CopyToClipboard text={value} onCopy={() => setCopied(true)}>
|
||||
<DropdownMenuItem
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.COPY} size={16} />
|
||||
{text}
|
||||
{copied && (
|
||||
<span className="text-xs text-neutral-500">{t('Copied')}</span>
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
</CopyToClipboard>
|
||||
);
|
||||
};
|
||||
|
@ -1,29 +1,20 @@
|
||||
export const IconBreakdown = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="8" cy="8" r="6.5" stroke="stroke-current" />
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<circle
|
||||
cx="8"
|
||||
cy="8"
|
||||
r="6.5"
|
||||
className="stroke-current fill-transparent"
|
||||
/>
|
||||
<rect
|
||||
x="8.5"
|
||||
y="11"
|
||||
width="1"
|
||||
height="4"
|
||||
transform="rotate(-180 8.5 11)"
|
||||
fill="white"
|
||||
/>
|
||||
<rect
|
||||
x="8.5"
|
||||
y="6"
|
||||
width="1"
|
||||
height="1"
|
||||
transform="rotate(-180 8.5 6)"
|
||||
fill="white"
|
||||
/>
|
||||
<rect x="8.5" y="6" width="1" height="1" transform="rotate(-180 8.5 6)" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,18 +1,7 @@
|
||||
export const IconCopy = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M4.47021 1.46997H14.5302V11.53H12.5002V10.47H13.4702V2.52997H5.53021V3.49997H4.47021V1.46997ZM1.47021 4.46997H11.5302V14.53H1.47021V4.46997ZM2.53021 5.52997V13.47H10.4702V5.52997H2.53021Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M4.47021 1.46997H14.5302V11.53H12.5002V10.47H13.4702V2.52997H5.53021V3.49997H4.47021V1.46997ZM1.47021 4.46997H11.5302V14.53H1.47021V4.46997ZM2.53021 5.52997V13.47H10.4702V5.52997H2.53021Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,8 @@
|
||||
export const IconDeposit = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="4" y="13" width="8" height="1" fill="white" />
|
||||
<path
|
||||
d="M8.52977 8.72048L11.625 5.62524L12.3745 6.37478L7.99977 10.7495L3.625 6.37478L4.37453 5.62524L7.46977 8.72048V2H8.52977V8.72048Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<rect x="4" y="13" width="8" height="1" />
|
||||
<path d="M8.52977 8.72048L11.625 5.62524L12.3745 6.37478L7.99977 10.7495L3.625 6.37478L4.37453 5.62524L7.46977 8.72048V2H8.52977V8.72048Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,18 +1,7 @@
|
||||
export const IconEdit = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2.31 10.44L1.5 14.5L5.56 13.69L14.5 4.75L11.25 1.5V1.51L9.97784 2.78074L9.97356 2.77646L9.26645 3.48357L9.27033 3.48745L2.31 10.44ZM11.25 2.92L13.08 4.75L12.5135 5.31645L10.6835 3.48645L11.25 2.92ZM9.97644 4.19356L11.8064 6.02356L6.02355 11.8064L4.19355 9.97645L9.97644 4.19356ZM5.31644 12.5136L5.07 12.76L2.78 13.22L3.24 10.93L3.48644 10.6836L5.31644 12.5136Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M2.31 10.44L1.5 14.5L5.56 13.69L14.5 4.75L11.25 1.5V1.51L9.97784 2.78074L9.97356 2.77646L9.26645 3.48357L9.27033 3.48745L2.31 10.44ZM11.25 2.92L13.08 4.75L12.5135 5.31645L10.6835 3.48645L11.25 2.92ZM9.97644 4.19356L11.8064 6.02356L6.02355 11.8064L4.19355 9.97645L9.97644 4.19356ZM5.31644 12.5136L5.07 12.76L2.78 13.22L3.24 10.93L3.48644 10.6836L5.31644 12.5136Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,18 +1,7 @@
|
||||
export const IconForum = ({ size = 24 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.20755 15.7736H6V4H8.20755V15.7736ZM10.4151 17.8585V15.7736H8.20755V17.9811H10.4151V20.066H12.6226V17.9811H14.8302V15.7736H12.6226V17.8585H10.4151ZM16.7925 13.566H14.5849V4H16.7925V13.566ZM16.7925 13.566H19V15.7736H16.7925V13.566Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 24 24">
|
||||
<path d="M8.20755 15.7736H6V4H8.20755V15.7736ZM10.4151 17.8585V15.7736H8.20755V17.9811H10.4151V20.066H12.6226V17.9811H14.8302V15.7736H12.6226V17.8585H10.4151ZM16.7925 13.566H14.5849V4H16.7925V13.566ZM16.7925 13.566H19V15.7736H16.7925V13.566Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,18 +1,7 @@
|
||||
export const IconGlobe = ({ size = 24 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 24 24">
|
||||
<path d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,9 @@
|
||||
export const IconKebab = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg width={size} height={size} viewBox="0 0 24 24">
|
||||
<circle cx="6" cy="12" r="2" />
|
||||
<circle cx="12" cy="12" r="2" />
|
||||
<circle cx="18" cy="12" r="2" />
|
||||
</svg>
|
||||
);
|
||||
};
|
@ -1,16 +1,7 @@
|
||||
export const IconLinkedIn = ({ size = 24 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M21 4.32353V19.6765C21 20.0275 20.8606 20.3641 20.6123 20.6123C20.3641 20.8606 20.0275 21 19.6765 21H4.32353C3.97251 21 3.63586 20.8606 3.38765 20.6123C3.13944 20.3641 3 20.0275 3 19.6765V4.32353C3 3.97251 3.13944 3.63586 3.38765 3.38765C3.63586 3.13944 3.97251 3 4.32353 3H19.6765C20.0275 3 20.3641 3.13944 20.6123 3.38765C20.8606 3.63586 21 3.97251 21 4.32353V4.32353ZM8.29412 9.88235H5.64706V18.3529H8.29412V9.88235ZM8.53235 6.97059C8.53375 6.77036 8.49569 6.57182 8.42035 6.3863C8.34502 6.20078 8.23387 6.03191 8.09328 5.88935C7.95268 5.74678 7.78537 5.6333 7.60091 5.5554C7.41646 5.47749 7.21846 5.43668 7.01824 5.43529H6.97059C6.5634 5.43529 6.1729 5.59705 5.88497 5.88497C5.59705 6.1729 5.43529 6.5634 5.43529 6.97059C5.43529 7.37777 5.59705 7.76828 5.88497 8.05621C6.1729 8.34413 6.5634 8.50588 6.97059 8.50588V8.50588C7.17083 8.51081 7.37008 8.47623 7.55696 8.40413C7.74383 8.33202 7.91467 8.2238 8.0597 8.08565C8.20474 7.94749 8.32113 7.78212 8.40223 7.59897C8.48333 7.41582 8.52755 7.21848 8.53235 7.01824V6.97059ZM18.3529 13.2071C18.3529 10.6606 16.7329 9.67059 15.1235 9.67059C14.5966 9.6442 14.0719 9.75644 13.6019 9.9961C13.1318 10.2358 12.7328 10.5945 12.4447 11.0365H12.3706V9.88235H9.88235V18.3529H12.5294V13.8476C12.4911 13.3862 12.6365 12.9283 12.9339 12.5735C13.2313 12.2186 13.6567 11.9954 14.1176 11.9524H14.2182C15.06 11.9524 15.6847 12.4818 15.6847 13.8159V18.3529H18.3318L18.3529 13.2071Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 24 24">
|
||||
<path d="M21 4.32353V19.6765C21 20.0275 20.8606 20.3641 20.6123 20.6123C20.3641 20.8606 20.0275 21 19.6765 21H4.32353C3.97251 21 3.63586 20.8606 3.38765 20.6123C3.13944 20.3641 3 20.0275 3 19.6765V4.32353C3 3.97251 3.13944 3.63586 3.38765 3.38765C3.63586 3.13944 3.97251 3 4.32353 3H19.6765C20.0275 3 20.3641 3.13944 20.6123 3.38765C20.8606 3.63586 21 3.97251 21 4.32353V4.32353ZM8.29412 9.88235H5.64706V18.3529H8.29412V9.88235ZM8.53235 6.97059C8.53375 6.77036 8.49569 6.57182 8.42035 6.3863C8.34502 6.20078 8.23387 6.03191 8.09328 5.88935C7.95268 5.74678 7.78537 5.6333 7.60091 5.5554C7.41646 5.47749 7.21846 5.43668 7.01824 5.43529H6.97059C6.5634 5.43529 6.1729 5.59705 5.88497 5.88497C5.59705 6.1729 5.43529 6.5634 5.43529 6.97059C5.43529 7.37777 5.59705 7.76828 5.88497 8.05621C6.1729 8.34413 6.5634 8.50588 6.97059 8.50588V8.50588C7.17083 8.51081 7.37008 8.47623 7.55696 8.40413C7.74383 8.33202 7.91467 8.2238 8.0597 8.08565C8.20474 7.94749 8.32113 7.78212 8.40223 7.59897C8.48333 7.41582 8.52755 7.21848 8.53235 7.01824V6.97059ZM18.3529 13.2071C18.3529 10.6606 16.7329 9.67059 15.1235 9.67059C14.5966 9.6442 14.0719 9.75644 13.6019 9.9961C13.1318 10.2358 12.7328 10.5945 12.4447 11.0365H12.3706V9.88235H9.88235V18.3529H12.5294V13.8476C12.4911 13.3862 12.6365 12.9283 12.9339 12.5735C13.2313 12.2186 13.6567 11.9954 14.1176 11.9524H14.2182C15.06 11.9524 15.6847 12.4818 15.6847 13.8159V18.3529H18.3318L18.3529 13.2071Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,23 +1,9 @@
|
||||
export const IconMoon = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96C6.34 6.48 6.43 6.06 6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z"
|
||||
fill="white"
|
||||
/>
|
||||
<circle cx="8" cy="8" r="7" fill="white" />
|
||||
<path
|
||||
d="M6.15393 5.69232C6.15393 5.10304 6.24054 4.5075 6.46161 4C4.99179 4.63982 4 6.14089 4 7.84607C4 10.1402 5.85982 12 8.15393 12C9.85911 12 11.3602 11.0082 12 9.53839C11.4925 9.75946 10.8964 9.84607 10.3077 9.84607C8.01357 9.84607 6.15393 7.98643 6.15393 5.69232Z"
|
||||
fill="black"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96C6.34 6.48 6.43 6.06 6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z" />
|
||||
<circle cx="8" cy="8" r="7" />
|
||||
<path d="M6.15393 5.69232C6.15393 5.10304 6.24054 4.5075 6.46161 4C4.99179 4.63982 4 6.14089 4 7.84607C4 10.1402 5.85982 12 8.15393 12C9.85911 12 11.3602 11.0082 12 9.53839C11.4925 9.75946 10.8964 9.84607 10.3077 9.84607C8.01357 9.84607 6.15393 7.98643 6.15393 5.69232Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,16 +1,7 @@
|
||||
export const IconOpenExternal = ({ size = 24 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10.9605 4.28998H3.76002V3.22998H12.77V12.24H11.71V5.03952L4.13479 12.6148L3.38525 11.8652L10.9605 4.28998Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M10.9605 4.28998H3.76002V3.22998H12.77V12.24H11.71V5.03952L4.13479 12.6148L3.38525 11.8652L10.9605 4.28998Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,18 +1,7 @@
|
||||
export const IconQuestionMark = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96L6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96L6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,20 +1,8 @@
|
||||
export const IconTransfer = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3.27952 5.90477L5.37476 8L4.62522 8.74953L1.25046 5.37477L4.62522 2L5.37476 2.74953L3.27952 4.84477L9 4.84477L9 5.90477L3.27952 5.90477Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M12.7205 10.0952L10.6252 8L11.3748 7.25047L14.7495 10.6252L11.3748 14L10.6252 13.2505L12.7205 11.1552L7 11.1552L7 10.0952L12.7205 10.0952Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M3.27952 5.90477L5.37476 8L4.62522 8.74953L1.25046 5.37477L4.62522 2L5.37476 2.74953L3.27952 4.84477L9 4.84477L9 5.90477L3.27952 5.90477Z" />
|
||||
<path d="M12.7205 10.0952L10.6252 8L11.3748 7.25047L14.7495 10.6252L11.3748 14L10.6252 13.2505L12.7205 11.1552L7 11.1552L7 10.0952L12.7205 10.0952Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,16 +1,7 @@
|
||||
export const IconTwitter = ({ size = 24 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.28743 20.2575C15.8423 20.2575 19.9641 14 19.9641 8.58084C19.9641 8.4012 19.9641 8.22156 19.9541 8.0519C20.7525 7.47305 21.4511 6.74451 22 5.92615C21.2615 6.25549 20.4731 6.47505 19.6447 6.57485C20.493 6.06587 21.1417 5.26747 21.4511 4.2994C20.6627 4.76846 19.7844 5.10778 18.8463 5.29741C18.0978 4.499 17.0299 4 15.8523 4C13.5868 4 11.7505 5.83633 11.7505 8.1018C11.7505 8.42116 11.7904 8.74052 11.8603 9.03992C8.43713 8.86028 5.40319 7.22355 3.38723 4.7485C3.02794 5.34731 2.82834 6.05589 2.82834 6.80439C2.82834 8.23154 3.55689 9.48902 4.65469 10.2176C3.97605 10.2076 3.34731 10.018 2.7984 9.70858C2.7984 9.72854 2.7984 9.73852 2.7984 9.75848C2.7984 11.7445 4.21557 13.4112 6.09182 13.7804C5.74251 13.8703 5.38323 13.9202 5.01397 13.9202C4.75449 13.9202 4.49501 13.8902 4.24551 13.8503C4.76447 15.477 6.28144 16.6647 8.07784 16.7046C6.67066 17.8024 4.90419 18.4611 2.97804 18.4611C2.6487 18.4611 2.31936 18.4411 2 18.4012C3.80639 19.5788 5.96208 20.2575 8.28743 20.2575Z"
|
||||
fill="white"
|
||||
/>
|
||||
<svg width={size} height={size} viewBox="0 0 24 24">
|
||||
<path d="M8.28743 20.2575C15.8423 20.2575 19.9641 14 19.9641 8.58084C19.9641 8.4012 19.9641 8.22156 19.9541 8.0519C20.7525 7.47305 21.4511 6.74451 22 5.92615C21.2615 6.25549 20.4731 6.47505 19.6447 6.57485C20.493 6.06587 21.1417 5.26747 21.4511 4.2994C20.6627 4.76846 19.7844 5.10778 18.8463 5.29741C18.0978 4.499 17.0299 4 15.8523 4C13.5868 4 11.7505 5.83633 11.7505 8.1018C11.7505 8.42116 11.7904 8.74052 11.8603 9.03992C8.43713 8.86028 5.40319 7.22355 3.38723 4.7485C3.02794 5.34731 2.82834 6.05589 2.82834 6.80439C2.82834 8.23154 3.55689 9.48902 4.65469 10.2176C3.97605 10.2076 3.34731 10.018 2.7984 9.70858C2.7984 9.72854 2.7984 9.73852 2.7984 9.75848C2.7984 11.7445 4.21557 13.4112 6.09182 13.7804C5.74251 13.8703 5.38323 13.9202 5.01397 13.9202C4.75449 13.9202 4.49501 13.8902 4.24551 13.8503C4.76447 15.477 6.28144 16.6647 8.07784 16.7046C6.67066 17.8024 4.90419 18.4611 2.97804 18.4611C2.6487 18.4611 2.31936 18.4411 2 18.4012C3.80639 19.5788 5.96208 20.2575 8.28743 20.2575Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,8 @@
|
||||
export const IconWithdraw = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.47023 4.0291L4.375 7.12433L3.62547 6.37479L8.00023 2.00003L12.375 6.3748L11.6255 7.12433L8.53023 4.0291L8.53023 10.7496L7.47023 10.7496L7.47023 4.0291Z"
|
||||
fill="white"
|
||||
/>
|
||||
<rect x="4" y="13" width="8" height="1" fill="white" />
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M7.47002 4.02906L4.37479 7.1243L3.62525 6.37476L8.00002 2L12.3748 6.37476L11.6253 7.1243L8.53002 4.02906L8.53002 10.7495L7.47002 10.7495L7.47002 4.02906Z" />
|
||||
<rect x="4" y="13" width="8" height="1" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ 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';
|
||||
|
||||
export enum VegaIconNames {
|
||||
BREAKDOWN = 'breakdown',
|
||||
@ -34,6 +35,7 @@ export enum VegaIconNames {
|
||||
CHEVRON_UP = 'chevron-up',
|
||||
TREND_UP = 'trend-up',
|
||||
CROSS = 'cross',
|
||||
KEBAB = 'kebab',
|
||||
}
|
||||
|
||||
export const VegaIconNameMap: Record<
|
||||
@ -57,4 +59,5 @@ export const VegaIconNameMap: Record<
|
||||
'chevron-up': IconChevronUp,
|
||||
'trend-up': IconTrendUp,
|
||||
cross: IconCross,
|
||||
kebab: IconKebab,
|
||||
};
|
||||
|
@ -12,7 +12,7 @@ export const VegaIcon = ({ size = 16, name }: VegaIconProps) => {
|
||||
const effectiveClassName = classNames(
|
||||
'inline-block',
|
||||
'align-text-bottom',
|
||||
'stroke-current'
|
||||
'fill-current stroke-none'
|
||||
);
|
||||
const Element = VegaIconNameMap[name];
|
||||
return (
|
||||
|
Loading…
Reference in New Issue
Block a user