feat(trading): mobile responsiveness tweaks (#5613)

This commit is contained in:
m.ray 2024-01-15 17:26:13 +02:00 committed by GitHub
parent d32f27fcb1
commit b751bcf17d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 428 additions and 372 deletions

View File

@ -137,6 +137,8 @@ const ClosedMarketsDataGrid = ({
headerName: t('Market'),
field: 'code',
cellRenderer: 'MarketCodeCell',
width: 150,
resizable: true,
},
{
headerName: t('Status'),
@ -280,6 +282,7 @@ const ClosedMarketsDataGrid = ({
return (
<AgGrid
rowData={rowData}
defaultColDef={COL_DEFS.default}
columnDefs={colDefs}
getRowId={({ data }) => data.id}
overlayNoRowsTemplate={error ? error.message : t('No markets')}

View File

@ -17,6 +17,7 @@ const defaultColDef = {
filter: true,
resizable: true,
filterParams: { buttons: ['reset'] },
minWidth: 120,
};
const components = {

View File

@ -53,6 +53,7 @@ export const MarketsPage = () => {
size="extra-small"
data-testid="propose-new-market"
href={externalLink}
target="_blank"
>
{t('Propose a new market')}
</TradingAnchorButton>

View File

@ -29,6 +29,7 @@ export const useColumnDefs = () => {
{
headerName: t('Market'),
field: 'tradableInstrument.instrument.code',
pinned: true,
cellRenderer: ({
value,
data,

View File

@ -67,6 +67,7 @@ const defaultColDef = {
sortable: true,
tooltipComponent: TooltipCellComponent,
comparator: accountValuesComparator,
minWidth: 150,
};
export interface GetRowsParams extends Omit<IGetRowsParams, 'successCallback'> {
successCallback(rowsThisBlock: AccountFields[], lastRow?: number): void;
@ -139,6 +140,8 @@ export const AccountTable = ({
{
headerName: t('Asset'),
field: 'asset.symbol',
pinned: true,
minWidth: 75,
headerTooltip: t(
'Asset is the collateral that is deposited into the Vega protocol.'
),
@ -253,8 +256,8 @@ export const AccountTable = ({
colId: 'accounts-actions',
field: 'asset.id',
...COL_DEFS.actions,
minWidth: showDepositButton ? 105 : COL_DEFS.actions.minWidth,
maxWidth: showDepositButton ? 105 : COL_DEFS.actions.maxWidth,
minWidth: showDepositButton ? 110 : COL_DEFS.actions.minWidth,
maxWidth: showDepositButton ? 110 : COL_DEFS.actions.maxWidth,
cellRenderer: ({
value: assetId,
node,

View File

@ -23,7 +23,9 @@ import { AccountType } from '@vegaprotocol/types';
const defaultColDef = {
resizable: true,
sortable: true,
minWidth: 100,
};
interface BreakdownTableProps extends AgGridReactProps {
data: AccountFields[] | null;
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
@ -32,12 +34,13 @@ interface BreakdownTableProps extends AgGridReactProps {
const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
({ data }, ref) => {
const t = useT();
const coldefs = useMemo(() => {
const colDefs = useMemo(() => {
const defs: ColDef[] = [
{
headerName: t('Market'),
field: 'market.tradableInstrument.instrument.code',
minWidth: 200,
width: 90,
pinned: true,
sort: 'desc',
cellRenderer: ({
value,
@ -141,7 +144,7 @@ const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
components={{ PriceCell, ProgressBarCell }}
tooltipShowDelay={500}
defaultColDef={defaultColDef}
columnDefs={coldefs}
columnDefs={colDefs}
domLayout="autoHeight"
/>
);

View File

@ -9,4 +9,7 @@ export const COL_DEFS = {
type: 'rightAligned',
pinned: 'right' as const,
},
default: {
minWidth: 100,
},
};

View File

@ -6,7 +6,7 @@ import {
isNumeric,
} from '@vegaprotocol/utils';
import { type ColDef } from 'ag-grid-community';
import { AgGrid } from '@vegaprotocol/datagrid';
import { AgGrid, COL_DEFS } from '@vegaprotocol/datagrid';
import {
type VegaICellRendererParams,
type VegaValueFormatterParams,
@ -21,7 +21,7 @@ export const DepositsTable = (
) => {
const columnDefs = useMemo<ColDef[]>(
() => [
{ headerName: 'Asset', field: 'asset.symbol' },
{ headerName: 'Asset', field: 'asset.symbol', pinned: true },
{
headerName: 'Amount',
field: 'amount',
@ -74,5 +74,11 @@ export const DepositsTable = (
],
[]
);
return <AgGrid columnDefs={columnDefs} {...props} />;
return (
<AgGrid
columnDefs={columnDefs}
defaultColDef={COL_DEFS.default}
{...props}
/>
);
};

View File

@ -48,6 +48,7 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
field: 'market.tradableInstrument.instrument.code',
cellRenderer: 'MarketNameCell',
cellRendererParams: { idPath: 'market.id', onMarketClick },
pinned: true,
},
{
headerName: t('Size'),
@ -143,6 +144,7 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
<AgGrid
ref={ref}
columnDefs={columnDefs}
defaultColDef={COL_DEFS.default}
overlayNoRowsTemplate={t('No fills')}
getRowId={({ data }) => data?.id}
tooltipShowDelay={0}

View File

@ -39,6 +39,7 @@ const defaultColDef = {
resizable: true,
sortable: true,
filterParams: { buttons: ['reset'] },
minWidth: 100,
};
export type OrderListTableProps = TypedDataAgGrid<Order> & {
@ -82,6 +83,9 @@ export const OrderListTable = memo<
field: 'market.tradableInstrument.instrument.code',
cellRenderer: 'MarketNameCell',
cellRendererParams: { idPath: 'market.id', onMarketClick },
pinned: true,
width: 130,
resizable: true,
},
{
headerName: t('Filled'),

View File

@ -40,6 +40,7 @@ const defaultColDef = {
resizable: true,
sortable: true,
filterParams: { buttons: ['reset'] },
minWidth: 100,
};
export type StopOrdersTableProps = TypedDataAgGrid<StopOrder> & {
@ -61,6 +62,7 @@ export const StopOrdersTable = memo(
field: 'market.tradableInstrument.instrument.code',
cellRenderer: 'MarketNameCell',
cellRendererParams: { idPath: 'market.id', onMarketClick },
pinned: true,
},
{
headerName: t('Trigger'),

View File

@ -71,6 +71,7 @@ const defaultColDef = {
filterParams: { buttons: ['reset'] },
tooltipComponent: TooltipCellComponent,
resizable: true,
minWidth: 110,
};
export const PositionsTable = ({
@ -83,6 +84,330 @@ export const PositionsTable = ({
...props
}: Props) => {
const t = useT();
const colDefs = useMemo<ColDef[]>(() => {
const columnDefs: (ColDef | null)[] = [
multipleKeys
? {
headerName: t('Vega key'),
field: 'partyId',
valueGetter: ({ data }: VegaValueGetterParams<Position>) =>
(data?.partyId &&
pubKeys &&
pubKeys.find((key) => key.publicKey === data.partyId)?.name) ||
data?.partyId,
}
: null,
{
headerName: t('Market'),
field: 'marketCode',
resizable: true,
onCellClicked: ({ data }) => {
if (!onMarketClick) return;
onMarketClick(data.marketId);
},
pinned: true,
cellRenderer: ({
value,
data,
}: VegaICellRendererParams<Position, 'marketCode'>) => {
if (!data || !value) return '-';
return (
<StackedCell
primary={value}
secondary={
<>
{data?.assetSymbol}
<MarketProductPill productType={data.productType} />
</>
}
/>
);
},
},
{
headerName: t('Size / Notional'),
field: 'openVolume',
type: 'rightAligned',
cellClass: 'font-mono text-right',
cellClassRules: signedNumberCssClassRules,
filter: 'agNumberColumnFilter',
valueGetter: ({ data }: { data: Position }) => {
return data?.openVolume === undefined
? undefined
: toBigNum(data?.openVolume, data.positionDecimalPlaces).toNumber();
},
valueFormatter: ({
data,
}: VegaValueFormatterParams<Position, 'openVolume'>): string => {
if (!data?.openVolume) return '-';
const vol = volumePrefix(
addDecimalsFormatNumber(data.openVolume, data.positionDecimalPlaces)
);
return vol;
},
cellRenderer: OpenVolumeCell,
},
{
headerName: t('Entry / Mark'),
field: 'markPrice',
type: 'rightAligned',
cellClass: 'font-mono text-right',
cellRenderer: ({
data,
}: VegaICellRendererParams<Position, 'markPrice'>) => {
if (
!data?.averageEntryPrice ||
!data?.markPrice ||
!data?.marketDecimalPlaces
) {
return <>-</>;
}
if (
data.marketTradingMode ===
MarketTradingMode.TRADING_MODE_OPENING_AUCTION
) {
return <>-</>;
}
const entry = addDecimalsFormatNumber(
data.averageEntryPrice,
data.marketDecimalPlaces
);
const mark = addDecimalsFormatNumber(
data.markPrice,
data.marketDecimalPlaces
);
return (
<StackedCell
primary={entry}
secondary={
<PriceFlashCell
value={Number(data.markPrice)}
valueFormatted={mark}
/>
}
/>
);
},
filter: 'agNumberColumnFilter',
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
return !data ||
!data.markPrice ||
data.marketTradingMode ===
MarketTradingMode.TRADING_MODE_OPENING_AUCTION
? undefined
: toBigNum(data.markPrice, data.marketDecimalPlaces).toNumber();
},
},
{
headerName: t('Margin / Leverage'),
colId: 'margin',
type: 'rightAligned',
cellClass: 'font-mono text-right',
filter: 'agNumberColumnFilter',
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
return !data
? undefined
: toBigNum(
data.marginAccountBalance,
data.assetDecimals
).toNumber();
},
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
if (
!data ||
!data.marginAccountBalance ||
!data.marketDecimalPlaces
) {
return null;
}
const margin = addDecimalsFormatNumberQuantum(
data.marginAccountBalance,
data.assetDecimals,
data.quantum
);
const lev = data?.currentLeverage ? data.currentLeverage : 1;
const leverage = formatNumber(Math.max(1, lev), 1);
return <StackedCell primary={margin} secondary={leverage + 'x'} />;
},
},
{
colId: 'liquidationPrice',
headerName: 'Liquidation',
headerTooltip: t('Worst case liquidation price'),
cellClass: 'font-mono text-right',
type: 'rightAligned',
// Cannot be sortable as data is fetched within the cell
sortable: false,
filter: false,
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
if (!data) {
return '-';
}
return (
<div className="flex h-[45px] items-center">
<LiquidationPrice
className="block text-right grow"
marketId={data.marketId}
openVolume={data.openVolume}
collateralAvailable={data.totalBalance}
decimalPlaces={data.marketDecimalPlaces}
/>
</div>
);
},
},
{
headerName: t('Realised PNL'),
field: 'realisedPNL',
type: 'rightAligned',
cellClassRules: signedNumberCssClassRules,
cellClass: 'font-mono text-right',
filter: 'agNumberColumnFilter',
valueGetter: realisedPNLValueGetter,
cellRenderer: (
args: VegaICellRendererParams<Position, 'realisedPNL'>
) => {
const LOSS_SOCIALIZATION_LINK = DocsLinks?.LOSS_SOCIALIZATION ?? '';
if (!args.data || args.value === undefined) {
return null;
}
const losses = parseInt(args.data?.lossSocializationAmount ?? '0');
if (losses <= 0) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return (
<Tooltip description={args.valueFormatted} align="end">
<div>
<PNLCell {...args} />
</div>
</Tooltip>
);
}
const lossesFormatted = addDecimalsFormatNumber(
args.data.lossSocializationAmount,
args.data.assetDecimals
);
return (
<Tooltip
align="end"
description={
<>
<p className="mb-2">
{t('Realised PNL: {{value}}', {
nsSeparator: '*',
replace: { value: args.value },
})}
</p>
<p className="mb-2">
{t('Lifetime loss socialisation deductions: {{losses}}', {
nsSeparator: '*',
replace: {
losses: lossesFormatted,
},
})}
</p>
<p className="mb-2">
{t(
`You received less {{assetSymbol}} in gains that you should have when the market moved in your favour. This occurred because one or more other trader(s) were closed out and did not have enough funds to cover their losses, and the market's insurance pool was empty.`,
{ assetSymbol: args.data.assetSymbol }
)}
</p>
{LOSS_SOCIALIZATION_LINK && (
<ExternalLink href={LOSS_SOCIALIZATION_LINK}>
{t('Read more about loss socialisation')}
</ExternalLink>
)}
</>
}
>
<div>
<PNLCell {...args} />
</div>
</Tooltip>
);
},
valueFormatter: ({
data,
}: VegaValueFormatterParams<Position, 'realisedPNL'>) => {
return !data
? ''
: addDecimalsFormatNumberQuantum(
data.realisedPNL,
data.assetDecimals,
data.quantum
);
},
headerTooltip: t(
'Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.'
),
},
{
headerName: t('Unrealised PNL'),
field: 'unrealisedPNL',
type: 'rightAligned',
cellClassRules: signedNumberCssClassRules,
cellClass: 'font-mono text-right',
filter: 'agNumberColumnFilter',
valueGetter: unrealisedPNLValueGetter,
// @ts-ignore no type overlap but function can be identical
tooltipValueGetter: unrealisedPNLValueGetter,
valueFormatter: ({
data,
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
!data
? ''
: addDecimalsFormatNumberQuantum(
data.unrealisedPNL,
data.assetDecimals,
data.quantum
),
headerTooltip: t(
'Unrealised profit is the current profit on your open position. Margin is still allocated to your position.'
),
},
onClose && !isReadOnly
? {
...COL_DEFS.actions,
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
return (
<div className="flex items-center justify-end gap-2">
{data?.openVolume &&
data?.openVolume !== '0' &&
data.partyId === pubKey ? (
<ButtonLink
data-testid="close-position"
onClick={() => data && onClose(data)}
title={t('Close position')}
>
<VegaIcon name={VegaIconNames.CROSS} size={16} />
</ButtonLink>
) : null}
{data?.assetId && (
<PositionActionsDropdown assetId={data?.assetId} />
)}
</div>
);
},
minWidth: 55,
maxWidth: 55,
}
: null,
];
return columnDefs.filter<ColDef>(
(colDef: ColDef | null): colDef is ColDef => colDef !== null
);
}, [isReadOnly, multipleKeys, onClose, onMarketClick, pubKey, pubKeys, t]);
return (
<AgGrid
overlayNoRowsTemplate={t('No positions')}
@ -95,349 +420,7 @@ export const PositionsTable = ({
MarketNameCell,
}}
rowHeight={45}
columnDefs={useMemo<ColDef[]>(() => {
const columnDefs: (ColDef | null)[] = [
multipleKeys
? {
headerName: t('Vega key'),
field: 'partyId',
valueGetter: ({ data }: VegaValueGetterParams<Position>) =>
(data?.partyId &&
pubKeys &&
pubKeys.find((key) => key.publicKey === data.partyId)
?.name) ||
data?.partyId,
}
: null,
{
headerName: t('Market'),
field: 'marketCode',
onCellClicked: ({ data }) => {
if (!onMarketClick) return;
onMarketClick(data.marketId);
},
cellRenderer: ({
value,
data,
}: VegaICellRendererParams<Position, 'marketCode'>) => {
if (!data || !value) return '-';
return (
<StackedCell
primary={value}
secondary={
<>
{data?.assetSymbol}
<MarketProductPill productType={data.productType} />
</>
}
/>
);
},
},
{
headerName: t('Size / Notional'),
field: 'openVolume',
type: 'rightAligned',
cellClass: 'font-mono text-right',
cellClassRules: signedNumberCssClassRules,
filter: 'agNumberColumnFilter',
valueGetter: ({ data }: { data: Position }) => {
return data?.openVolume === undefined
? undefined
: toBigNum(
data?.openVolume,
data.positionDecimalPlaces
).toNumber();
},
valueFormatter: ({
data,
}: VegaValueFormatterParams<Position, 'openVolume'>): string => {
if (!data?.openVolume) return '-';
const vol = volumePrefix(
addDecimalsFormatNumber(
data.openVolume,
data.positionDecimalPlaces
)
);
return vol;
},
cellRenderer: OpenVolumeCell,
},
{
headerName: t('Entry / Mark'),
field: 'markPrice',
type: 'rightAligned',
cellClass: 'font-mono text-right',
cellRenderer: ({
data,
}: VegaICellRendererParams<Position, 'markPrice'>) => {
if (
!data?.averageEntryPrice ||
!data?.markPrice ||
!data?.marketDecimalPlaces
) {
return <>-</>;
}
if (
data.marketTradingMode ===
MarketTradingMode.TRADING_MODE_OPENING_AUCTION
) {
return <>-</>;
}
const entry = addDecimalsFormatNumber(
data.averageEntryPrice,
data.marketDecimalPlaces
);
const mark = addDecimalsFormatNumber(
data.markPrice,
data.marketDecimalPlaces
);
return (
<StackedCell
primary={entry}
secondary={
<PriceFlashCell
value={Number(data.markPrice)}
valueFormatted={mark}
/>
}
/>
);
},
filter: 'agNumberColumnFilter',
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
return !data ||
!data.markPrice ||
data.marketTradingMode ===
MarketTradingMode.TRADING_MODE_OPENING_AUCTION
? undefined
: toBigNum(data.markPrice, data.marketDecimalPlaces).toNumber();
},
},
{
headerName: t('Margin / Leverage'),
colId: 'margin',
type: 'rightAligned',
cellClass: 'font-mono text-right',
filter: 'agNumberColumnFilter',
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
return !data
? undefined
: toBigNum(
data.marginAccountBalance,
data.assetDecimals
).toNumber();
},
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
if (
!data ||
!data.marginAccountBalance ||
!data.marketDecimalPlaces
) {
return null;
}
const margin = addDecimalsFormatNumberQuantum(
data.marginAccountBalance,
data.assetDecimals,
data.quantum
);
const lev = data?.currentLeverage ? data.currentLeverage : 1;
const leverage = formatNumber(Math.max(1, lev), 1);
return (
<StackedCell primary={margin} secondary={leverage + 'x'} />
);
},
},
{
colId: 'liquidationPrice',
headerName: 'Liquidation',
headerTooltip: t('Worst case liquidation price'),
cellClass: 'font-mono text-right',
type: 'rightAligned',
// Cannot be sortable as data is fetched within the cell
sortable: false,
filter: false,
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
if (!data) {
return '-';
}
return (
<div className="flex h-[45px] items-center">
<LiquidationPrice
className="block text-right grow"
marketId={data.marketId}
openVolume={data.openVolume}
collateralAvailable={data.totalBalance}
decimalPlaces={data.marketDecimalPlaces}
/>
</div>
);
},
},
{
headerName: t('Realised PNL'),
field: 'realisedPNL',
type: 'rightAligned',
cellClassRules: signedNumberCssClassRules,
cellClass: 'font-mono text-right',
filter: 'agNumberColumnFilter',
valueGetter: realisedPNLValueGetter,
cellRenderer: (
args: VegaICellRendererParams<Position, 'realisedPNL'>
) => {
const LOSS_SOCIALIZATION_LINK =
DocsLinks?.LOSS_SOCIALIZATION ?? '';
if (!args.data || args.value === undefined) {
return null;
}
const losses = parseInt(
args.data?.lossSocializationAmount ?? '0'
);
if (losses <= 0) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return (
<Tooltip description={args.valueFormatted} align="end">
<div>
<PNLCell {...args} />
</div>
</Tooltip>
);
}
const lossesFormatted = addDecimalsFormatNumber(
args.data.lossSocializationAmount,
args.data.assetDecimals
);
return (
<Tooltip
align="end"
description={
<>
<p className="mb-2">
{t('Realised PNL: {{value}}', {
nsSeparator: '*',
replace: { value: args.value },
})}
</p>
<p className="mb-2">
{t(
'Lifetime loss socialisation deductions: {{losses}}',
{
nsSeparator: '*',
replace: {
losses: lossesFormatted,
},
}
)}
</p>
<p className="mb-2">
{t(
`You received less {{assetSymbol}} in gains that you should have when the market moved in your favour. This occurred because one or more other trader(s) were closed out and did not have enough funds to cover their losses, and the market's insurance pool was empty.`,
{ assetSymbol: args.data.assetSymbol }
)}
</p>
{LOSS_SOCIALIZATION_LINK && (
<ExternalLink href={LOSS_SOCIALIZATION_LINK}>
{t('Read more about loss socialisation')}
</ExternalLink>
)}
</>
}
>
<div>
<PNLCell {...args} />
</div>
</Tooltip>
);
},
valueFormatter: ({
data,
}: VegaValueFormatterParams<Position, 'realisedPNL'>) => {
return !data
? ''
: addDecimalsFormatNumberQuantum(
data.realisedPNL,
data.assetDecimals,
data.quantum
);
},
headerTooltip: t(
'Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.'
),
},
{
headerName: t('Unrealised PNL'),
field: 'unrealisedPNL',
type: 'rightAligned',
cellClassRules: signedNumberCssClassRules,
cellClass: 'font-mono text-right',
filter: 'agNumberColumnFilter',
valueGetter: unrealisedPNLValueGetter,
// @ts-ignore no type overlap but function can be identical
tooltipValueGetter: unrealisedPNLValueGetter,
valueFormatter: ({
data,
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
!data
? ''
: addDecimalsFormatNumberQuantum(
data.unrealisedPNL,
data.assetDecimals,
data.quantum
),
headerTooltip: t(
'Unrealised profit is the current profit on your open position. Margin is still allocated to your position.'
),
},
onClose && !isReadOnly
? {
...COL_DEFS.actions,
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
return (
<div className="flex items-center justify-end gap-2">
{data?.openVolume &&
data?.openVolume !== '0' &&
data.partyId === pubKey ? (
<ButtonLink
data-testid="close-position"
onClick={() => data && onClose(data)}
title={t('Close position')}
>
<VegaIcon name={VegaIconNames.CROSS} size={16} />
</ButtonLink>
) : null}
{data?.assetId && (
<PositionActionsDropdown assetId={data?.assetId} />
)}
</div>
);
},
minWidth: 55,
maxWidth: 55,
}
: null,
];
return columnDefs.filter<ColDef>(
(colDef: ColDef | null): colDef is ColDef => colDef !== null
);
}, [
isReadOnly,
multipleKeys,
onClose,
onMarketClick,
pubKey,
pubKeys,
t,
])}
columnDefs={colDefs}
{...props}
/>
);

View File

@ -29,6 +29,7 @@ export const useColumnDefs = () => {
colId: 'market',
headerName: t('Market'),
field: 'terms.change.instrument.code',
pinned: true,
cellStyle: { lineHeight: '14px' },
cellRenderer: ({
value,

View File

@ -85,19 +85,21 @@ export function Dialog({
<VegaIcon name={VegaIconNames.CROSS} size={24} />
</DialogPrimitives.Close>
)}
<div className="flex gap-4 max-w-full">
{icon && <div className="fill-current">{icon}</div>}
<div data-testid="dialog-content" className="flex-1 max-w-full">
{title && (
<h1
className="text-xl uppercase mb-4 pr-2"
data-testid="dialog-title"
>
{title}
</h1>
)}
<div>{children}</div>
</div>
<div data-testid="dialog-content" className="flex-1 max-w-full">
{title && (
<span
className="text-xl uppercase flex gap-4"
data-testid="dialog-title"
>
{icon && (
<span className="fill-current flex items-center">
{icon}
</span>
)}
{title}
</span>
)}
<div>{children}</div>
</div>
</div>
</div>

View File

@ -5,15 +5,16 @@ import { ToastPosition, useToastsConfiguration, useToasts } from './use-toasts';
import { useCallback } from 'react';
import { Intent } from '../../utils/intent';
import { useT } from '../../use-t';
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
export const ToastPositionSetter = () => {
const t = useT();
const setPostion = useToastsConfiguration((store) => store.setPosition);
const setPosition = useToastsConfiguration((store) => store.setPosition);
const position = useToastsConfiguration((store) => store.position);
const setToast = useToasts((store) => store.setToast);
const handleChange = useCallback(
(position: ToastPosition) => {
setPostion(position);
setPosition(position);
setToast({
id: 'test-toast',
intent: Intent.Primary,
@ -21,11 +22,49 @@ export const ToastPositionSetter = () => {
onClose: () => useToasts.getState().remove('test-toast'),
});
},
[setToast, setPostion, t]
[setToast, setPosition, t]
);
const buttonCssClasses =
'flex items-center px-1 py-1 relative rounded bg-vega-clight-400 dark:bg-vega-cdark-400';
const activeIcon = 'fill-vega-clight-900 dark:fill-vega-cdark-900';
const { screenSize } = useScreenDimensions();
const isMobileScreen = screenSize === 'xs';
if (isMobileScreen) {
return (
<div className="flex justify-between">
<div className={classNames('grid grid-cols-1 grid-rows-2 gap-1')}>
<button
className={buttonCssClasses}
onClick={() => handleChange(ToastPosition.TopCenter)}
>
<Icon
className={classNames(
position === ToastPosition.TopCenter && activeIcon
)}
size={3}
name={IconNames.ARROW_UP}
/>
</button>
<button
className={buttonCssClasses}
onClick={() => handleChange(ToastPosition.BottomCenter)}
>
<Icon
className={classNames(
position === ToastPosition.BottomCenter && activeIcon
)}
size={3}
name={IconNames.ARROW_DOWN}
/>
</button>
</div>
</div>
);
}
return (
<div className="flex justify-between">
<div className={classNames('grid grid-cols-3 grid-rows-2 gap-1')}>

View File

@ -92,7 +92,7 @@ export const ToastsContainer = ({
className={classNames(
'absolute right-0 top-[-38px] z-20 w-full',
'transition-opacity',
'opacity-0 hover:!opacity-100 group-hover:opacity-50',
'sm:opacity-0 sm:hover:!opacity-100 sm:group-hover:opacity-50',
{
hidden: validToasts.length === 0,
}

View File

@ -34,7 +34,7 @@ export class ViewConnector implements VegaConnector {
});
return Promise.resolve([
{
name: 'View only pubkey',
name: 'View only',
publicKey: this.pubkey,
},
]);

View File

@ -15,6 +15,7 @@ import {
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import {
COL_DEFS,
type TypedDataAgGrid,
type VegaICellRendererParams,
type VegaValueFormatterParams,
@ -46,7 +47,7 @@ export const WithdrawalsTable = ({
const columnDefs = useMemo<ColDef[]>(
() => [
{ headerName: t('Asset'), field: 'asset.symbol' },
{ headerName: t('Asset'), field: 'asset.symbol', pinned: true },
{
headerName: t('Amount'),
field: 'amount',
@ -135,6 +136,7 @@ export const WithdrawalsTable = ({
<AgGrid
overlayNoRowsTemplate={t('No withdrawals')}
columnDefs={columnDefs}
defaultColDef={COL_DEFS.default}
components={{
RecipientCell,
StatusCell,

View File

@ -38,7 +38,7 @@
"@radix-ui/react-slider": "^1.1.0",
"@radix-ui/react-switch": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.7",
"@sentry/nextjs": "^6.19.3",
"@sentry/react": "^6.19.2",
"@sentry/tracing": "^6.19.2",

View File

@ -4864,7 +4864,7 @@
"@radix-ui/react-separator" "1.0.3"
"@radix-ui/react-toggle-group" "1.0.4"
"@radix-ui/react-tooltip@^1.0.3":
"@radix-ui/react-tooltip@^1.0.7":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz#8f55070f852e7e7450cc1d9210b793d2e5a7686e"
integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==