feat(governance): batch proposal indicators, vote breakdown ui changes (#5857)
This commit is contained in:
parent
ca64516a52
commit
72e0cb76aa
@ -1,7 +1,8 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { type ReactNode } from 'react';
|
||||||
|
|
||||||
interface HeadingProps {
|
interface HeadingProps {
|
||||||
title?: string;
|
title?: ReactNode;
|
||||||
centerContent?: boolean;
|
centerContent?: boolean;
|
||||||
marginTop?: boolean;
|
marginTop?: boolean;
|
||||||
marginBottom?: boolean;
|
marginBottom?: boolean;
|
||||||
|
@ -54,11 +54,8 @@ const ProposalTypeTags = ({
|
|||||||
|
|
||||||
if (proposal.__typename === 'BatchProposal') {
|
if (proposal.__typename === 'BatchProposal') {
|
||||||
return (
|
return (
|
||||||
<div data-testid="proposal-type" className="flex gap-1">
|
<div data-testid="proposal-type">
|
||||||
{proposal.subProposals?.map((subProposal, i) => {
|
<ProposalInfoLabel variant="secondary">BatchProposal</ProposalInfoLabel>
|
||||||
if (!subProposal?.terms) return null;
|
|
||||||
return <ProposalTypeTag key={i} terms={subProposal.terms} />;
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -315,7 +312,7 @@ const ProposalDetails = ({
|
|||||||
{proposal.subProposals.map((p, i) => {
|
{proposal.subProposals.map((p, i) => {
|
||||||
if (!p?.terms) return null;
|
if (!p?.terms) return null;
|
||||||
return (
|
return (
|
||||||
<li key={i} className="flex gap-3">
|
<li key={i} className="flex gap-3 items-center">
|
||||||
<span className={getIndicatorStyle(i + 1)}>{i + 1}</span>
|
<span className={getIndicatorStyle(i + 1)}>{i + 1}</span>
|
||||||
<span>
|
<span>
|
||||||
<div>{renderDetails(p.terms)}</div>
|
<div>{renderDetails(p.terms)}</div>
|
||||||
|
@ -5,6 +5,11 @@ import {
|
|||||||
} from './proposal-market-changes';
|
} from './proposal-market-changes';
|
||||||
import type { JsonValue } from '../../../../components/json-diff';
|
import type { JsonValue } from '../../../../components/json-diff';
|
||||||
|
|
||||||
|
jest.mock('../proposal/market-name.tsx', () => ({
|
||||||
|
...jest.requireActual('../proposal/market-name.tsx'),
|
||||||
|
MarketName: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('applyImmutableKeysFromEarlierVersion', () => {
|
describe('applyImmutableKeysFromEarlierVersion', () => {
|
||||||
it('returns an empty object if any argument is not an object or null', () => {
|
it('returns an empty object if any argument is not an object or null', () => {
|
||||||
const earlierVersion: JsonValue = null;
|
const earlierVersion: JsonValue = null;
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
type SingleProposalData,
|
type SingleProposalData,
|
||||||
type SubProposalData,
|
type SubProposalData,
|
||||||
} from '../proposal/proposal-utils';
|
} from '../proposal/proposal-utils';
|
||||||
|
import { MarketName } from '../proposal/market-name';
|
||||||
|
|
||||||
const immutableKeys = [
|
const immutableKeys = [
|
||||||
'decimalPlaces',
|
'decimalPlaces',
|
||||||
@ -139,7 +140,13 @@ export const ProposalMarketChanges = ({
|
|||||||
setToggleState={setShowChanges}
|
setToggleState={setShowChanges}
|
||||||
dataTestId={'proposal-market-changes-toggle'}
|
dataTestId={'proposal-market-changes-toggle'}
|
||||||
>
|
>
|
||||||
<SubHeading title={t('updatesToMarket')} />
|
<SubHeading
|
||||||
|
title={
|
||||||
|
<>
|
||||||
|
{t('UpdateToMarket')}: <MarketName marketId={marketId} />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</CollapsibleToggle>
|
</CollapsibleToggle>
|
||||||
|
|
||||||
{showChanges && (
|
{showChanges && (
|
||||||
|
@ -2,6 +2,11 @@ import { fireEvent, render, screen } from '@testing-library/react';
|
|||||||
import { ProposalUpdateMarketState } from './proposal-update-market-state';
|
import { ProposalUpdateMarketState } from './proposal-update-market-state';
|
||||||
import { MarketUpdateType } from '@vegaprotocol/types';
|
import { MarketUpdateType } from '@vegaprotocol/types';
|
||||||
|
|
||||||
|
jest.mock('../proposal/market-name.tsx', () => ({
|
||||||
|
...jest.requireActual('../proposal/market-name.tsx'),
|
||||||
|
MarketName: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('<ProposalUpdateMarketState />', () => {
|
describe('<ProposalUpdateMarketState />', () => {
|
||||||
const suspendProposal = {
|
const suspendProposal = {
|
||||||
__typename: 'UpdateMarketState' as const,
|
__typename: 'UpdateMarketState' as const,
|
||||||
|
@ -10,6 +10,7 @@ import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
|
|||||||
import { SubHeading } from '../../../../components/heading';
|
import { SubHeading } from '../../../../components/heading';
|
||||||
import { type UpdateMarketStatesFragment } from '../../__generated__/Proposals';
|
import { type UpdateMarketStatesFragment } from '../../__generated__/Proposals';
|
||||||
import { MarketUpdateTypeMapping } from '@vegaprotocol/types';
|
import { MarketUpdateTypeMapping } from '@vegaprotocol/types';
|
||||||
|
import { MarketName } from '../proposal/market-name';
|
||||||
|
|
||||||
interface ProposalUpdateMarketStateProps {
|
interface ProposalUpdateMarketStateProps {
|
||||||
change: UpdateMarketStatesFragment | null;
|
change: UpdateMarketStatesFragment | null;
|
||||||
@ -20,16 +21,18 @@ export const ProposalUpdateMarketState = ({
|
|||||||
}: ProposalUpdateMarketStateProps) => {
|
}: ProposalUpdateMarketStateProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [showDetails, setShowDetails] = useState(false);
|
const [showDetails, setShowDetails] = useState(false);
|
||||||
let market;
|
|
||||||
let isTerminate = false;
|
|
||||||
|
|
||||||
if (!change) {
|
if (!change || change.__typename !== 'UpdateMarketState') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change.__typename === 'UpdateMarketState') {
|
const market = change?.market;
|
||||||
market = change?.market;
|
const isTerminate =
|
||||||
isTerminate = change?.updateType === 'MARKET_STATE_UPDATE_TYPE_TERMINATE';
|
change?.updateType === 'MARKET_STATE_UPDATE_TYPE_TERMINATE';
|
||||||
|
|
||||||
|
let toggleTitle = t(change.updateType);
|
||||||
|
if (toggleTitle.length === 0) {
|
||||||
|
toggleTitle = t('MarketDetails');
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -39,7 +42,13 @@ export const ProposalUpdateMarketState = ({
|
|||||||
setToggleState={setShowDetails}
|
setToggleState={setShowDetails}
|
||||||
dataTestId="proposal-market-data-toggle"
|
dataTestId="proposal-market-data-toggle"
|
||||||
>
|
>
|
||||||
<SubHeading title={t('MarketDetails')} />
|
<SubHeading
|
||||||
|
title={
|
||||||
|
<>
|
||||||
|
{toggleTitle}: <MarketName marketId={market?.id} />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</CollapsibleToggle>
|
</CollapsibleToggle>
|
||||||
|
|
||||||
{showDetails && (
|
{showDetails && (
|
||||||
|
@ -16,18 +16,31 @@ const getColour = (indicator: number, max = COLOURS.length) => {
|
|||||||
|
|
||||||
export const getStyle = (indicator: number, max = COLOURS.length) =>
|
export const getStyle = (indicator: number, max = COLOURS.length) =>
|
||||||
classNames({
|
classNames({
|
||||||
'bg-vega-yellow-400': 'yellow' === getColour(indicator, max),
|
'bg-vega-yellow-400 after:bg-vega-yellow-400':
|
||||||
'bg-vega-green-400': 'green' === getColour(indicator, max),
|
'yellow' === getColour(indicator, max),
|
||||||
'bg-vega-blue-400': 'blue' === getColour(indicator, max),
|
'bg-vega-green-400 after:bg-vega-green-400':
|
||||||
'bg-vega-purple-400': 'purple' === getColour(indicator, max),
|
'green' === getColour(indicator, max),
|
||||||
'bg-vega-pink-400': 'pink' === getColour(indicator, max),
|
'bg-vega-blue-400 after:bg-vega-blue-400':
|
||||||
'bg-vega-orange-400': 'orange' === getColour(indicator, max),
|
'blue' === getColour(indicator, max),
|
||||||
'bg-vega-red-400': 'red' === getColour(indicator, max),
|
'bg-vega-purple-400 after:bg-vega-purple-400':
|
||||||
'bg-vega-clight-600': 'none' === getColour(indicator, max),
|
'purple' === getColour(indicator, max),
|
||||||
|
'bg-vega-pink-400 after:bg-vega-pink-400':
|
||||||
|
'pink' === getColour(indicator, max),
|
||||||
|
'bg-vega-orange-400 after:bg-vega-orange-400':
|
||||||
|
'orange' === getColour(indicator, max),
|
||||||
|
'bg-vega-red-400 after:bg-vega-red-400':
|
||||||
|
'red' === getColour(indicator, max),
|
||||||
|
'bg-vega-clight-600 after:bg-vega-clight-600':
|
||||||
|
'none' === getColour(indicator, max),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getIndicatorStyle = (indicator: number) =>
|
export const getIndicatorStyle = (indicator: number) =>
|
||||||
classNames(
|
classNames(
|
||||||
'rounded-sm text-black inline-block px-1 py-1 font-alpha calt h-8',
|
'rounded-sm text-black inline-block px-1 py-1 font-alpha calt h-8 w-7 text-center',
|
||||||
getStyle(indicator)
|
'text-border-1',
|
||||||
|
getStyle(indicator),
|
||||||
|
// Comment below if you want to remove the "chevron"
|
||||||
|
'relative mr-[11px]',
|
||||||
|
'after:absolute after:z-[-1] after:top-1 after:right-[-11px] after:rounded-sm',
|
||||||
|
"after:w-[22.62px] after:h-[22.62px] after:rotate-45 after:content-['']"
|
||||||
);
|
);
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
} from '../../__generated__/Proposals';
|
} from '../../__generated__/Proposals';
|
||||||
import { useBatchVoteInformation } from '../../hooks/use-vote-information';
|
import { useBatchVoteInformation } from '../../hooks/use-vote-information';
|
||||||
import { getIndicatorStyle } from '../proposal/colours';
|
import { getIndicatorStyle } from '../proposal/colours';
|
||||||
|
import { MarketName } from '../proposal/market-name';
|
||||||
|
|
||||||
export const CompactVotes = ({ number }: { number: BigNumber }) => (
|
export const CompactVotes = ({ number }: { number: BigNumber }) => (
|
||||||
<CompactNumber
|
<CompactNumber
|
||||||
@ -40,8 +41,9 @@ const VoteProgress = ({
|
|||||||
children,
|
children,
|
||||||
}: VoteProgressProps) => {
|
}: VoteProgressProps) => {
|
||||||
const containerClasses = classNames(
|
const containerClasses = classNames(
|
||||||
'relative h-10 rounded-md border border-vega-dark-300 overflow-hidden',
|
'relative h-2 rounded-md overflow-hidden',
|
||||||
colourfulBg ? 'bg-vega-pink' : 'bg-vega-dark-400'
|
// 'border border-vega-dark-300',
|
||||||
|
colourfulBg ? 'bg-vega-red' : 'bg-vega-dark-200'
|
||||||
);
|
);
|
||||||
|
|
||||||
const progressClasses = classNames(
|
const progressClasses = classNames(
|
||||||
@ -50,17 +52,19 @@ const VoteProgress = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const textClasses = classNames(
|
const textClasses = classNames(
|
||||||
'absolute top-0 left-0 w-full h-full flex items-center justify-start px-3 text-black'
|
'w-full flex items-center justify-start text-white text-sm pb-1'
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={textClasses}>{children}</div>
|
||||||
<div className={containerClasses}>
|
<div className={containerClasses}>
|
||||||
<div
|
<div
|
||||||
className={progressClasses}
|
className={progressClasses}
|
||||||
style={{ width: `${percentageFor}%` }}
|
style={{ width: `${percentageFor}%` }}
|
||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
/>
|
/>
|
||||||
<div className={textClasses}>{children}</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -79,14 +83,22 @@ const Status = ({ reached, threshold, text, testId }: StatusProps) => {
|
|||||||
<div data-testid={testId}>
|
<div data-testid={testId}>
|
||||||
{reached ? (
|
{reached ? (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<VegaIcon name={VegaIconNames.TICK} size={20} />
|
<VegaIcon
|
||||||
|
name={VegaIconNames.TICK}
|
||||||
|
className="text-vega-green"
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
<span>
|
<span>
|
||||||
{threshold.toString()}% {text} {t('met')}
|
{threshold.toString()}% {text} {t('met')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<VegaIcon name={VegaIconNames.CROSS} size={20} />
|
<VegaIcon
|
||||||
|
name={VegaIconNames.CROSS}
|
||||||
|
className="text-vega-red"
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
<span>
|
<span>
|
||||||
{threshold.toString()}% {text} {t('not met')}
|
{threshold.toString()}% {text} {t('not met')}
|
||||||
</span>
|
</span>
|
||||||
@ -152,7 +164,7 @@ const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
|||||||
<p className="flex gap-2 m-0 items-center">
|
<p className="flex gap-2 m-0 items-center">
|
||||||
<VegaIcon
|
<VegaIcon
|
||||||
name={VegaIconNames.CROSS}
|
name={VegaIconNames.CROSS}
|
||||||
className="text-vega-pink"
|
className="text-vega-red"
|
||||||
size={20}
|
size={20}
|
||||||
/>
|
/>
|
||||||
{t(
|
{t(
|
||||||
@ -215,7 +227,7 @@ const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
|||||||
<p className="flex gap-2 m-0 items-center">
|
<p className="flex gap-2 m-0 items-center">
|
||||||
<VegaIcon
|
<VegaIcon
|
||||||
name={VegaIconNames.CROSS}
|
name={VegaIconNames.CROSS}
|
||||||
className="text-vega-pink"
|
className="text-vega-red"
|
||||||
size={20}
|
size={20}
|
||||||
/>
|
/>
|
||||||
{t('Proposal failed: {{count}} of {{total}} proposals passed', {
|
{t('Proposal failed: {{count}} of {{total}} proposals passed', {
|
||||||
@ -237,6 +249,7 @@ const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
|||||||
if (!p?.terms) return null;
|
if (!p?.terms) return null;
|
||||||
return (
|
return (
|
||||||
<VoteBreakdownBatchSubProposal
|
<VoteBreakdownBatchSubProposal
|
||||||
|
indicator={i + 1}
|
||||||
key={i}
|
key={i}
|
||||||
proposal={proposal}
|
proposal={proposal}
|
||||||
votes={proposal.votes}
|
votes={proposal.votes}
|
||||||
@ -273,22 +286,40 @@ const VoteBreakdownBatchSubProposal = ({
|
|||||||
const isProposalOpen = proposal?.state === ProposalState.STATE_OPEN;
|
const isProposalOpen = proposal?.state === ProposalState.STATE_OPEN;
|
||||||
const isUpdateMarket = terms?.change?.__typename === 'UpdateMarket';
|
const isUpdateMarket = terms?.change?.__typename === 'UpdateMarket';
|
||||||
|
|
||||||
|
let marketId = undefined;
|
||||||
|
if (terms?.change?.__typename === 'UpdateMarket') {
|
||||||
|
marketId = terms.change.marketId;
|
||||||
|
}
|
||||||
|
if (terms?.change?.__typename === 'UpdateMarketState') {
|
||||||
|
marketId = terms.change.market.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const marketName = marketId ? (
|
||||||
|
<>
|
||||||
|
: <MarketName marketId={marketId} />
|
||||||
|
</>
|
||||||
|
) : null;
|
||||||
|
|
||||||
const indicatorElement = indicator && (
|
const indicatorElement = indicator && (
|
||||||
<span className={getIndicatorStyle(indicator)}>{indicator}</span>
|
<span className={getIndicatorStyle(indicator)}>{indicator}</span>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="mb-6">
|
||||||
<div className="flex items-baseline gap-3">
|
<div className="flex items-baseline gap-3 mb-3">
|
||||||
{indicatorElement}
|
{indicatorElement}
|
||||||
<h4>{t(terms.change.__typename)}</h4>
|
<h4>
|
||||||
|
{t(terms.change.__typename)} {marketName}
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="rounded-sm bg-vega-dark-100 p-3">
|
||||||
<VoteBreakDownUI
|
<VoteBreakDownUI
|
||||||
voteInfo={voteInfo}
|
voteInfo={voteInfo}
|
||||||
isProposalOpen={isProposalOpen}
|
isProposalOpen={isProposalOpen}
|
||||||
isUpdateMarket={isUpdateMarket}
|
isUpdateMarket={isUpdateMarket}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,11 +333,13 @@ const VoteBreakdownNormal = ({ proposal }: { proposal: Proposal }) => {
|
|||||||
const isUpdateMarket = proposal?.terms?.change?.__typename === 'UpdateMarket';
|
const isUpdateMarket = proposal?.terms?.change?.__typename === 'UpdateMarket';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div className="mb-6">
|
||||||
<VoteBreakDownUI
|
<VoteBreakDownUI
|
||||||
voteInfo={voteInfo}
|
voteInfo={voteInfo}
|
||||||
isProposalOpen={isProposalOpen}
|
isProposalOpen={isProposalOpen}
|
||||||
isUpdateMarket={isUpdateMarket}
|
isUpdateMarket={isUpdateMarket}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -370,13 +403,13 @@ const VoteBreakDownUI = ({
|
|||||||
'flex justify-between flex-wrap gap-6'
|
'flex justify-between flex-wrap gap-6'
|
||||||
);
|
);
|
||||||
const sectionClasses = classNames('min-w-[300px] flex-1 flex-grow');
|
const sectionClasses = classNames('min-w-[300px] flex-1 flex-grow');
|
||||||
const headingClasses = classNames('mb-2 text-vega-dark-400');
|
const headingClasses = classNames('mb-2 text-sm text-white font-bold');
|
||||||
const progressDetailsClasses = classNames(
|
const progressDetailsClasses = classNames(
|
||||||
'flex justify-between flex-wrap mt-2 text-sm'
|
'flex justify-between flex-wrap mt-2 text-sm'
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mb-6">
|
<div>
|
||||||
{isProposalOpen && (
|
{isProposalOpen && (
|
||||||
<div
|
<div
|
||||||
data-testid="vote-status"
|
data-testid="vote-status"
|
||||||
@ -393,7 +426,7 @@ const VoteBreakDownUI = ({
|
|||||||
<VegaIcon
|
<VegaIcon
|
||||||
name={VegaIconNames.CROSS}
|
name={VegaIconNames.CROSS}
|
||||||
size={20}
|
size={20}
|
||||||
className="text-vega-pink"
|
className="text-vega-red"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@ -409,103 +442,13 @@ const VoteBreakDownUI = ({
|
|||||||
<p className="m-0">
|
<p className="m-0">
|
||||||
<Trans
|
<Trans
|
||||||
i18nKey={'Currently expected to <0>fail</0>'}
|
i18nKey={'Currently expected to <0>fail</0>'}
|
||||||
components={[<span className="text-vega-pink" />]}
|
components={[<span className="text-vega-red" />]}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isUpdateMarket && (
|
|
||||||
<div className="mb-4">
|
|
||||||
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
|
|
||||||
<div className={sectionWrapperClasses}>
|
|
||||||
<section
|
|
||||||
className={sectionClasses}
|
|
||||||
data-testid="lp-majority-breakdown"
|
|
||||||
>
|
|
||||||
<VoteProgress
|
|
||||||
percentageFor={lpVoteWeight}
|
|
||||||
colourfulBg={true}
|
|
||||||
testId="lp-majority-progress"
|
|
||||||
>
|
|
||||||
<Status
|
|
||||||
reached={majorityLPMet}
|
|
||||||
threshold={requiredMajorityLPPercentage}
|
|
||||||
text={t('majorityThreshold')}
|
|
||||||
testId={
|
|
||||||
majorityLPMet ? 'lp-majority-met' : 'lp-majority-not-met'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</VoteProgress>
|
|
||||||
|
|
||||||
<div className={progressDetailsClasses}>
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
<span>{t('liquidityProviderVotesFor')}:</span>
|
|
||||||
<Tooltip
|
|
||||||
description={
|
|
||||||
<span>{lpVoteWeight.toFixed(defaultDP)}%</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button>{lpVoteWeight.toFixed(1)}%</button>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
<span>{t('liquidityProviderVotesAgainst')}:</span>
|
|
||||||
<span>
|
|
||||||
<Tooltip
|
|
||||||
description={
|
|
||||||
<span>{noLPPercentage.toFixed(defaultDP)}%</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button>{noLPPercentage.toFixed(1)}%</button>
|
|
||||||
</Tooltip>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section
|
|
||||||
className={sectionClasses}
|
|
||||||
data-testid="lp-participation-breakdown"
|
|
||||||
>
|
|
||||||
<VoteProgress
|
|
||||||
percentageFor={
|
|
||||||
lpParticipationThresholdProgress || new BigNumber(0)
|
|
||||||
}
|
|
||||||
testId="lp-participation-progress"
|
|
||||||
>
|
|
||||||
<Status
|
|
||||||
reached={participationLPMet}
|
|
||||||
threshold={requiredParticipationLP || new BigNumber(1)}
|
|
||||||
text={t('participationThreshold')}
|
|
||||||
testId={
|
|
||||||
participationLPMet
|
|
||||||
? 'lp-participation-met'
|
|
||||||
: 'lp-participation-not-met'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</VoteProgress>
|
|
||||||
|
|
||||||
<div className="flex mt-2 text-sm">
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
<span>{t('totalLiquidityProviderTokensVoted')}:</span>
|
|
||||||
<Tooltip
|
|
||||||
description={formatNumber(
|
|
||||||
totalEquityLikeShareWeight,
|
|
||||||
defaultDP
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isUpdateMarket && <h3 className={headingClasses}>{t('tokenVote')}</h3>}
|
{isUpdateMarket && <h3 className={headingClasses}>{t('tokenVote')}</h3>}
|
||||||
<div className={sectionWrapperClasses}>
|
<div className={sectionWrapperClasses}>
|
||||||
<section
|
<section
|
||||||
@ -605,6 +548,97 @@ const VoteBreakDownUI = ({
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/** Liquidity provider vote */}
|
||||||
|
{isUpdateMarket && (
|
||||||
|
<div className="mt-3">
|
||||||
|
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
|
||||||
|
<div className={sectionWrapperClasses}>
|
||||||
|
<section
|
||||||
|
className={sectionClasses}
|
||||||
|
data-testid="lp-majority-breakdown"
|
||||||
|
>
|
||||||
|
<VoteProgress
|
||||||
|
percentageFor={lpVoteWeight}
|
||||||
|
colourfulBg={true}
|
||||||
|
testId="lp-majority-progress"
|
||||||
|
>
|
||||||
|
<Status
|
||||||
|
reached={majorityLPMet}
|
||||||
|
threshold={requiredMajorityLPPercentage}
|
||||||
|
text={t('majorityThreshold')}
|
||||||
|
testId={
|
||||||
|
majorityLPMet ? 'lp-majority-met' : 'lp-majority-not-met'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</VoteProgress>
|
||||||
|
|
||||||
|
<div className={progressDetailsClasses}>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<span>{t('liquidityProviderVotesFor')}:</span>
|
||||||
|
<Tooltip
|
||||||
|
description={
|
||||||
|
<span>{lpVoteWeight.toFixed(defaultDP)}%</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<button>{lpVoteWeight.toFixed(1)}%</button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<span>{t('liquidityProviderVotesAgainst')}:</span>
|
||||||
|
<span>
|
||||||
|
<Tooltip
|
||||||
|
description={
|
||||||
|
<span>{noLPPercentage.toFixed(defaultDP)}%</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<button>{noLPPercentage.toFixed(1)}%</button>
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
className={sectionClasses}
|
||||||
|
data-testid="lp-participation-breakdown"
|
||||||
|
>
|
||||||
|
<VoteProgress
|
||||||
|
percentageFor={
|
||||||
|
lpParticipationThresholdProgress || new BigNumber(0)
|
||||||
|
}
|
||||||
|
testId="lp-participation-progress"
|
||||||
|
>
|
||||||
|
<Status
|
||||||
|
reached={participationLPMet}
|
||||||
|
threshold={requiredParticipationLP || new BigNumber(1)}
|
||||||
|
text={t('participationThreshold')}
|
||||||
|
testId={
|
||||||
|
participationLPMet
|
||||||
|
? 'lp-participation-met'
|
||||||
|
: 'lp-participation-not-met'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</VoteProgress>
|
||||||
|
|
||||||
|
<div className="flex mt-2 text-sm">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<span>{t('totalLiquidityProviderTokensVoted')}:</span>
|
||||||
|
<Tooltip
|
||||||
|
description={formatNumber(
|
||||||
|
totalEquityLikeShareWeight,
|
||||||
|
defaultDP
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user