feat: liquidity provision health

This commit is contained in:
Malin Antonsson
2022-10-13 15:07:13 +02:00
parent 4f1524918d
commit f787641067
4 changed files with 217 additions and 82 deletions
@@ -1,128 +1,133 @@
.App {
font-family: sans-serif;
text-align: center;
font-family: sans-serif;
text-align: center;
width: 300px;
margin: auto;
width: 300px;
margin: auto;
}
.health {
width: 100%;
width: 100%;
}
.health-wrapper {
padding: 8px 0;
position: relative;
padding: 8px 0;
position: relative;
}
.health-inner {
overflow: hidden;
position: relative;
height: 16px;
width: 100%;
overflow: hidden;
position: relative;
height: 16px;
width: 100%;
}
.health-full {
background: #f5f5f5;
height: 100%;
background: #f5f5f5;
height: 100%;
}
.health-committed {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
.health-committed--continuous {
background-color: #00a88a;
background-color: #00a88a;
}
.health-committed--auction {
background-color: #fb8e7f;
background-color: #fb8e7f;
}
.health-committed--open {
background-color: #68e2e4;
background-color: #68e2e4;
}
.health-target-container {
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
padding: 0 5px;
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
padding: 0 5px;
}
.health-target {
width: 2px;
height: 32px;
background-color: black;
width: 2px;
height: 32px;
background-color: black;
}
.health-copy {
font-size: 8px;
line-height: 144%;
font-weight: 500;
font-size: 8px;
line-height: 144%;
font-weight: 500;
}
.health-size--large .health-inner {
height: 32px;
height: 32px;
}
.health-size--large .health-target {
height: 72px;
height: 72px;
}
.health-size--large .health-wrapper {
padding: 20px 0;
padding: 20px 0;
}
.health-size--large .health-copy {
font-size: 12px;
font-size: 12px;
}
.health-tooltip {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -120%);
border: 1px solid #bfccd6;
background-color: #fff;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -120%);
border: 1px solid #bfccd6;
background-color: #fff;
}
.health-committed-tooltip {
min-width: 90px;
}
.health-committed-tooltip,
.health-target-tooltip {
padding: 8px;
display: flex;
flex-direction: column;
padding: 8px;
display: flex;
flex-direction: column;
z-index: 1;
}
.health-tooltip::before,
.health-tooltip::after {
content: " ";
position: absolute;
left: calc(50% - 8px);
bottom: 1px;
width: 0;
height: 0;
transform: translate(50%, 100%);
content: ' ';
position: absolute;
left: calc(50% - 8px);
bottom: 1px;
width: 0;
height: 0;
transform: translate(50%, 100%);
}
.health-tooltip::before {
bottom: -1px;
border: 4px solid;
border-color: #bfccd6 transparent transparent transparent;
bottom: -1px;
border: 4px solid;
border-color: #bfccd6 transparent transparent transparent;
}
.health-tooltip::after {
border: 4px solid;
border-color: white transparent transparent transparent;
border: 4px solid;
border-color: white transparent transparent transparent;
}
.health-tooltip-copy {
font-size: 8px;
line-height: 1.2em;
font-weight: 500;
}
font-size: 8px;
line-height: 1.2em;
font-weight: 500;
}
@@ -2,36 +2,48 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
import { useState } from 'react';
import type { MarketTradingMode } from '@vegaprotocol/types';
// import { MarketTradingModeMapping } from '@vegaprotocol/types';
//import type { MarketTradingMode } from '@vegaprotocol/types';
import { MarketTradingMode } from '@vegaprotocol/types';
import './health-bar.scss';
enum marketTradingModeClassname {
TRADING_MODE_CONTINUOUS = 'continuous',
TRADING_MODE_MONITORING_AUCTION = 'auction',
TRADING_MODE_OPENING_AUCTION = 'open',
TRADING_MODE_BATCH_AUCTION = 'batch',
TRADING_MODE_NO_TRADING = 'none',
}
// enum marketTradingModeClassname {
// TRADING_MODE_CONTINUOUS = 'continuous',
// TRADING_MODE_MONITORING_AUCTION = 'auction',
// TRADING_MODE_OPENING_AUCTION = 'open',
// TRADING_MODE_BATCH_AUCTION = 'batch',
// TRADING_MODE_NO_TRADING = 'none',
// }
enum sizes {
small = 'small',
large = 'large',
const marketTradingModeClassname = {
[MarketTradingMode.TRADING_MODE_CONTINUOUS]: 'continuous',
[MarketTradingMode.TRADING_MODE_MONITORING_AUCTION]: 'auction',
[MarketTradingMode.TRADING_MODE_OPENING_AUCTION]: 'open',
[MarketTradingMode.TRADING_MODE_BATCH_AUCTION]: 'batch',
[MarketTradingMode.TRADING_MODE_NO_TRADING]: 'none',
};
console.log('marketTradingModeClassname: ', marketTradingModeClassname);
interface Node {
commitmentAmount: string;
fee: string;
}
export default function Health({
status,
target,
committed,
size = sizes.small,
committedEdges = [],
size = 'small',
isExpanded = false,
}: {
status: MarketTradingMode;
size: sizes | undefined;
committed: string;
target: string;
isExpanded: boolean | undefined;
committedEdges?: Node[];
isExpanded?: boolean;
size?: 'small' | 'large';
}) {
const [isTargetTooltipShowing, setIsTargetTooltipShowing] =
useState(isExpanded);
@@ -56,7 +68,7 @@ export default function Health({
console.log('targetPercent: ', targetPercent);
return (
<div className={`health health-size--${sizes[size]}`}>
<div className={`health health-size--${size}`}>
<div className="health-wrapper">
<div className="health-copy-wrapper">
<div
@@ -0,0 +1,89 @@
import { formatNumber, t } from '@vegaprotocol/react-helpers';
import { Dialog } from '@vegaprotocol/ui-toolkit';
import type { MarketsListData } from '@vegaprotocol/liquidity-provision';
import { MarketTradingMode } from '@vegaprotocol/types';
import { MarketTradingModeMapping } from '@vegaprotocol/types';
import HealthBar from './health-bar';
interface HealthDialogProps {
isOpen: boolean;
onChange: (isOpen: boolean) => void;
}
const ROWS = [
{
key: '1',
title: 'Continuous',
copy: 'Markets that have committed liquidity equal or greater than the target stake are trading continuously.',
data: {
status: MarketTradingMode.TRADING_MODE_CONTINUOUS,
target: '171320',
committed: '220000',
},
},
{
key: '2',
title: 'Liquidity auction',
copy: 'Markets below the target stake will see trading suspended and go into liquidity auction.',
data: {
status: MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
target: '171320',
committed: '150000',
},
},
{
key: '3',
title: 'Opening auction',
copy: 'A newly created market looking for a target liquidity amount to start trading.',
data: {
status: MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
target: '171320',
committed: '140000',
},
},
];
export default function HealthDialog({ onChange, isOpen }: HealthDialogProps) {
return (
<Dialog size="medium" open={isOpen} onChange={onChange}>
<h1 className="text-xl mb-4 pr-2 font-bold" data-testid="dialog-title">
{t('Health')}
</h1>
<p className="text-xl mb-4">
{t(
'Market health is a representation of market and liquidity status and how close that market is to moving from one fee level to another.'
)}
</p>
<table className="table-fixed">
<thead>
<th className="w-1/2 text-left">{t('Market status')}</th>
<th className="w-1/2 text-left">{t('Liquidity status')}</th>
</thead>
<tbody>
{ROWS.map((r) => {
return (
<tr key={r.key}>
<td className="pr-4 py-10">
<h2 className="font-bold text-base">{t(r.title)}</h2>
<p className="text-base">{t(r.copy)}</p>
</td>
<td className="py-10">
<HealthBar
size="large"
status={r.data.status}
target={r.data.target}
committed={r.data.committed}
isExpanded
/>
</td>
</tr>
);
})}
</tbody>
</table>
</Dialog>
);
}
@@ -1,4 +1,4 @@
import { useCallback, useRef, useEffect } from 'react';
import { useCallback, useRef, useEffect, useState } from 'react';
import { AgGridReact, AgGridColumn } from 'ag-grid-react';
import type { AgGridReact as AgGridReactType } from 'ag-grid-react';
import type {
@@ -9,6 +9,7 @@ import type {
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { formatNumber, t } from '@vegaprotocol/react-helpers';
import { Icon } from '@vegaprotocol/ui-toolkit';
import {
formatWithAsset,
@@ -20,6 +21,7 @@ import type { MarketTradingMode } from '@vegaprotocol/types';
import { MarketTradingModeMapping } from '@vegaprotocol/types';
import HealthBar from './health-bar';
import HealthDialog from './health-dialog';
// #BFCCD6
const agGridVariables = `
@@ -76,14 +78,14 @@ const healthCellRenderer = ({ value, data }: GroupCellRendererParams) => {
status={value}
target={data.data.targetStake}
committed={committed}
size={undefined}
isExpanded={false}
committedEdges={data.liquidityProvisionsConnection?.edges}
/>
</div>
);
};
const MarketList = ({ data }: { data: MarketsListData }) => {
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
const gridRef = useRef<AgGridReactType | null>(null);
const localData = formatMarketLists(data);
@@ -157,7 +159,19 @@ const MarketList = ({ data }: { data: MarketsListData }) => {
/>
<AgGridColumn
headerName={t('Health')}
headerComponent={() => {
return (
<div>
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
>
<Icon name="info-sign" />
</button>
</div>
);
}}
field="tradingMode"
headerTooltip={t('This is the health tooltip')}
cellRenderer={healthCellRenderer}
@@ -170,9 +184,24 @@ const MarketList = ({ data }: { data: MarketsListData }) => {
headerTooltip={t('This is the APY tooltip')}
/>
</AgGridReact>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
</>
);
};
{
/* <HealthBar
status="TRADING_MODE_CONTINUOUS"
target="171320"
committed="220000"
size="large"
isExpanded={TransformStreamDefaultController}
/> */
}
export default MarketList;