feat: add tooltips to headers on the LP dashboard and add some new data points (#2064)
* feat: add tooltips to headers on the details view * feat: add header tooltips to liqudity dashboard markets page * feat: add fee level and target stake to market summary list These two data points are already in our health bar, but we want to call them out more visibly so you don't have to hover to see them. * feat: add % Target stake column to market list page Adds a column which calculates what percentage of the target stake is currently being supplied. We _trim_ this number to the whole percentage value, so some precision may be lost, which we can add later if we want. * chore: remove the estimated return/APY column while we dont use it We can revert this commit later if we want it to return. * feat: wrap the status pill with a tooltip Uses the ui-toolkit tooltip to wrap the status pill, providing a bit more information for what the statuses mean. * chore: wrap getTooltipDescription in t() translate fn
This commit is contained in:
parent
9aa672968f
commit
ce62342d9a
@ -8,8 +8,17 @@ import type {
|
||||
} from 'ag-grid-community';
|
||||
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
|
||||
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||
import { Icon, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
t,
|
||||
addDecimalsFormatNumber,
|
||||
formatNumberPercentage,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
Icon,
|
||||
AsyncRenderer,
|
||||
TooltipCellComponent,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import type { Market } from '@vegaprotocol/liquidity';
|
||||
import {
|
||||
useMarketsLiquidity,
|
||||
@ -50,9 +59,11 @@ export const MarketList = () => {
|
||||
sortable: true,
|
||||
unSortIcon: true,
|
||||
cellClass: ['flex', 'flex-col', 'justify-center'],
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
}}
|
||||
getRowId={getRowId}
|
||||
isRowClickable
|
||||
tooltipShowDelay={500}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Market (futures)')}
|
||||
@ -78,6 +89,7 @@ export const MarketList = () => {
|
||||
}}
|
||||
minWidth={100}
|
||||
flex="1"
|
||||
headerTooltip={t('The market name and settlement asset')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
@ -90,10 +102,11 @@ export const MarketList = () => {
|
||||
.decimals
|
||||
)} (${displayChange(data.volumeChange)})`
|
||||
}
|
||||
headerTooltip={t('The trade volume over the last 24h')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('Committed bond/stake')}
|
||||
headerName={t('Committed bond')}
|
||||
field="liquidityCommitted"
|
||||
valueFormatter={({ value, data }: ValueFormatterParams) =>
|
||||
formatWithAsset(
|
||||
@ -101,6 +114,47 @@ export const MarketList = () => {
|
||||
data.tradableInstrument.instrument.product.settlementAsset
|
||||
)
|
||||
}
|
||||
headerTooltip={t(
|
||||
'The amount of funds allocated to provide liquidity'
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('Target stake')}
|
||||
field="target"
|
||||
valueFormatter={({ value, data }: ValueFormatterParams) =>
|
||||
formatWithAsset(
|
||||
value,
|
||||
data.tradableInstrument.instrument.product.settlementAsset
|
||||
)
|
||||
}
|
||||
headerTooltip={t(
|
||||
'The ideal committed liquidity to operate the market. If total commitment currently below this level then LPs can set the fee level with new commitment.'
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('% Target stake met')}
|
||||
valueFormatter={({ data }: ValueFormatterParams) => {
|
||||
const roundedPercentage =
|
||||
parseInt(
|
||||
(data.liquidityCommitted / parseFloat(data.target)).toFixed(0)
|
||||
) * 100;
|
||||
const display = Number.isNaN(roundedPercentage)
|
||||
? 'N/A'
|
||||
: formatNumberPercentage(toBigNum(roundedPercentage, 2));
|
||||
return display;
|
||||
}}
|
||||
headerTooltip={t('% Target stake met')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
headerName={t('Fee levels')}
|
||||
field="fees"
|
||||
valueFormatter={({ value, data }: ValueFormatterParams) =>
|
||||
`${value.factors.liquidityFee}%`
|
||||
}
|
||||
headerTooltip={t('Fee level for this market')}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
@ -117,6 +171,9 @@ export const MarketList = () => {
|
||||
<Status trigger={data.data?.trigger} tradingMode={value} />
|
||||
);
|
||||
}}
|
||||
headerTooltip={t(
|
||||
'The current market status - those below the target stake mark are most in need of liquidity'
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn
|
||||
@ -154,7 +211,6 @@ export const MarketList = () => {
|
||||
sortable={false}
|
||||
cellStyle={{ overflow: 'unset' }}
|
||||
/>
|
||||
<AgGridColumn headerName={t('Est. return / APY')} field="apy" />
|
||||
</Grid>
|
||||
|
||||
<HealthDialog
|
||||
|
@ -11,6 +11,7 @@ import type {
|
||||
import { formatWithAsset } from '@vegaprotocol/liquidity';
|
||||
|
||||
import { Grid } from '../../grid';
|
||||
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
const formatToHours = ({ value }: { value?: string | null }) => {
|
||||
if (!value) {
|
||||
@ -39,11 +40,14 @@ export const LPProvidersGrid = ({
|
||||
return (
|
||||
<Grid
|
||||
rowData={liquidityProviders}
|
||||
tooltipShowDelay={500}
|
||||
defaultColDef={{
|
||||
resizable: true,
|
||||
sortable: true,
|
||||
unSortIcon: true,
|
||||
cellClass: ['flex', 'flex-col', 'justify-center'],
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
minWidth: 100,
|
||||
}}
|
||||
getRowId={getRowId}
|
||||
rowHeight={92}
|
||||
@ -53,11 +57,13 @@ export const LPProvidersGrid = ({
|
||||
field="party.id"
|
||||
flex="1"
|
||||
minWidth={100}
|
||||
headerTooltip={t('Liquidity providers')}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Time in market')}
|
||||
headerName={t('Duration')}
|
||||
valueFormatter={formatToHours}
|
||||
field="createdAt"
|
||||
headerTooltip={t('Time in market')}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Equity-like share')}
|
||||
@ -67,23 +73,50 @@ export const LPProvidersGrid = ({
|
||||
? `${parseFloat(parseFloat(value).toFixed(2)) * 100}%`
|
||||
: '';
|
||||
}}
|
||||
headerTooltip={t(
|
||||
'The share of the markets liquidity held - the earlier you commit liquidity the greater % fees you earn'
|
||||
)}
|
||||
minWidth={140}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('committed bond/stake')}
|
||||
headerName={t('committed bond')}
|
||||
field="commitmentAmount"
|
||||
valueFormatter={({ value }: { value?: string | null }) =>
|
||||
value ? formatWithAsset(value, settlementAsset) : '0'
|
||||
}
|
||||
headerTooltip={t('The amount of funds allocated to provide liquidity')}
|
||||
minWidth={140}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Margin Req.')}
|
||||
field="margin"
|
||||
headerTooltip={t(
|
||||
'Margin required for arising positions based on liquidity commitment'
|
||||
)}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('24h Fees')}
|
||||
field="fees"
|
||||
headerTooltip={t(
|
||||
'Total fees earned by the liquidity provider in the last 24 hours'
|
||||
)}
|
||||
/>
|
||||
<AgGridColumn headerName={t('Margin Req.')} field="margin" />
|
||||
<AgGridColumn headerName={t('24h Fees')} field="fees" />
|
||||
<AgGridColumn
|
||||
headerName={t('Fee level')}
|
||||
valueFormatter={({ value }: { value?: string | null }) => `${value}%`}
|
||||
field="fee"
|
||||
headerTooltip={t(
|
||||
"The market's liquidity fee, or the percentage of a trade's value which is collected from the price taker for every trade"
|
||||
)}
|
||||
/>
|
||||
|
||||
<AgGridColumn headerName={t('APY')} field="apy" />
|
||||
<AgGridColumn
|
||||
headerName={t('APY')}
|
||||
field="apy"
|
||||
headerTooltip={t(
|
||||
'An annualised estimate based on the total liquidity provision fees and maker fees collected by liquidity providers, the maximum margin needed and maximum commitment (bond) over the course of 7 epochs'
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import { Lozenge, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import {
|
||||
@ -6,6 +6,7 @@ import {
|
||||
AuctionTriggerMapping,
|
||||
Schema,
|
||||
} from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
|
||||
import { Indicator } from '../indicator';
|
||||
|
||||
@ -33,17 +34,46 @@ export const Status = ({
|
||||
return MarketTradingModeMapping[tradingMode];
|
||||
};
|
||||
|
||||
const status = getStatus();
|
||||
const tooltipDescription = t(getTooltipDescription(status));
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('inline-flex whitespace-normal', {
|
||||
'text-base': size === 'large',
|
||||
'text-sm': size === 'small',
|
||||
})}
|
||||
>
|
||||
<Lozenge className="border border-greys-light-300 bg-greys-light-100 flex items-center">
|
||||
<Indicator status={tradingMode} />
|
||||
{getStatus()}
|
||||
</Lozenge>
|
||||
<div>
|
||||
<Tooltip description={tooltipDescription}>
|
||||
<div
|
||||
className={classNames('inline-flex whitespace-normal', {
|
||||
'text-base': size === 'large',
|
||||
'text-sm': size === 'small',
|
||||
})}
|
||||
>
|
||||
<Lozenge className="border border-greys-light-300 bg-greys-light-100 flex items-center">
|
||||
<Indicator status={tradingMode} />
|
||||
{status}
|
||||
</Lozenge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getTooltipDescription = (status: string) => {
|
||||
let tooltipDescription = '';
|
||||
switch (status) {
|
||||
case MarketTradingModeMapping.TRADING_MODE_CONTINUOUS:
|
||||
tooltipDescription =
|
||||
'This is the standard trading mode where trades are executed whenever orders are received';
|
||||
break;
|
||||
case `${MarketTradingModeMapping.TRADING_MODE_MONITORING_AUCTION} - ${AuctionTriggerMapping.AUCTION_TRIGGER_LIQUIDITY}`:
|
||||
tooltipDescription =
|
||||
'This market is in auction until it reaches sufficient liquidity';
|
||||
break;
|
||||
case MarketTradingModeMapping.TRADING_MODE_OPENING_AUCTION:
|
||||
tooltipDescription =
|
||||
'This is a new market in an opening auction to determine a fair mid-price before starting continuous trading.';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return tooltipDescription;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user