Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7ee7402cd | ||
|
|
6421cf87c6 | ||
|
|
0ebfab64ff | ||
|
|
142f08343b |
@@ -909,6 +909,14 @@
|
||||
"BenefitTierReferralDiscountFactorDescription": "The proportion of the referee's taker fees to be discounted",
|
||||
"BenefitTierReferralRewardFactor": "Referral reward factor",
|
||||
"BenefitTierReferralRewardFactorDescription": "The proportion of the referee's taker fees to be rewarded to the referrer",
|
||||
"BenefitTierMinimumActivityStreak": "Minimum activity streak",
|
||||
"BenefitTierMinimumActivityStreakDescription": "The minimum number of times the party needs to have completed the activity",
|
||||
"BenefitTierMinimumQuantumBalance": "Minimum quantum balance",
|
||||
"BenefitTierMinimumQuantumBalanceDescription": "The minimum amount of the vesting token to qualify",
|
||||
"BenefitTierVestingMultiplier": "Vesting multiplier",
|
||||
"BenefitTierVestingMultiplierDescription": "Vesting multiplier for the tier",
|
||||
"BenefitTierRewardMultiplier": "Reward multiplier",
|
||||
"BenefitTierRewardMultiplierDescription": "The multiplier",
|
||||
"StakingTiers": "Staking tiers",
|
||||
"StakingTierMinimumStakedTokens": "Minimum staked tokens",
|
||||
"StakingTierMinimumStakedTokensDescription": "Required number of governance tokens ($VEGA) a referrer must have staked to receive the multiplier",
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export * from './proposal-update-benefit-tiers-details';
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalUpdateBenefitTiers } from './proposal-update-benefit-tiers-details';
|
||||
import { generateProposal } from '../../test-helpers/generate-proposals';
|
||||
|
||||
jest.mock('../../../../contexts/app-state/app-state-context', () => ({
|
||||
useAppState: () => ({
|
||||
appState: {
|
||||
decimals: 2,
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
const mockVestingBenefitTierProposal = generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateNetworkParameter',
|
||||
networkParameter: {
|
||||
key: 'blah.blah.benefitTiers',
|
||||
value: JSON.stringify({
|
||||
tiers: [
|
||||
{
|
||||
minimum_quantum_balance: '10000',
|
||||
reward_multiplier: '0.05',
|
||||
},
|
||||
{
|
||||
minimum_quantum_balance: '500000000000',
|
||||
reward_multiplier: '0.1',
|
||||
},
|
||||
{
|
||||
minimum_quantum_balance: '10000000000000',
|
||||
reward_multiplier: '10',
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const mockActivityStreakBenefitTierProposal = generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateNetworkParameter',
|
||||
networkParameter: {
|
||||
key: 'blah.blah.benefitTiers',
|
||||
value: JSON.stringify({
|
||||
tiers: [
|
||||
{
|
||||
minimum_activity_streak: '10000',
|
||||
vesting_multiplier: '5',
|
||||
reward_multiplier: '0.1',
|
||||
},
|
||||
{
|
||||
minimum_activity_streak: '10000000000000',
|
||||
vesting_multiplier: '100',
|
||||
reward_multiplier: '10',
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
describe('ProposalUpdateBenefitTiers', () => {
|
||||
it('should not render if proposal is null', () => {
|
||||
render(<ProposalUpdateBenefitTiers proposal={null} />);
|
||||
expect(screen.queryByTestId('proposal-update-benefit-tiers')).toBeNull();
|
||||
});
|
||||
|
||||
it('should not render if __typename is not UpdateNetworkParameter', () => {
|
||||
const updateMarketProposal = generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateMarket',
|
||||
},
|
||||
},
|
||||
});
|
||||
render(<ProposalUpdateBenefitTiers proposal={updateMarketProposal} />);
|
||||
expect(screen.queryByTestId('proposal-update-benefit-tiers')).toBeNull();
|
||||
});
|
||||
|
||||
it('should not render if there are no relevant fields', () => {
|
||||
const incompleteProposal = generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateNetworkParameter',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<ProposalUpdateBenefitTiers proposal={incompleteProposal} />);
|
||||
expect(screen.queryByTestId('proposal-update-benefit-tiers')).toBeNull();
|
||||
});
|
||||
|
||||
it('should not render if there are relevant fields that are empty', () => {
|
||||
const incompleteProposal = generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateNetworkParameter',
|
||||
networkParameter: {
|
||||
key: 'blah.blah.benefitTiers',
|
||||
value: JSON.stringify({}),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<ProposalUpdateBenefitTiers proposal={incompleteProposal} />);
|
||||
expect(screen.queryByTestId('proposal-update-benefit-tiers')).toBeNull();
|
||||
});
|
||||
|
||||
it('should render a valid vesting benefit tier proposal', () => {
|
||||
render(
|
||||
<ProposalUpdateBenefitTiers proposal={mockVestingBenefitTierProposal} />
|
||||
);
|
||||
|
||||
// 3 tiers in the sample data
|
||||
expect(screen.getByText('Tier 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Tier 2')).toBeInTheDocument();
|
||||
expect(screen.getByText('Tier 3')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getAllByText('Minimum quantum balance').length).toBe(3);
|
||||
expect(screen.getAllByText('Reward multiplier').length).toBe(3);
|
||||
|
||||
expect(screen.getByText('0.00000000000001')).toBeInTheDocument();
|
||||
expect(screen.getByText('0.05x')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('0.0000005')).toBeInTheDocument();
|
||||
expect(screen.getByText('0.1x')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('0.00001')).toBeInTheDocument();
|
||||
expect(screen.getByText('10x')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render a valid activity streak benefit tier proposal', () => {
|
||||
render(
|
||||
<ProposalUpdateBenefitTiers
|
||||
proposal={mockActivityStreakBenefitTierProposal}
|
||||
/>
|
||||
);
|
||||
|
||||
// 3 tiers in the sample data
|
||||
expect(screen.getByText('Tier 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Tier 2')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getAllByText('Minimum activity streak').length).toBe(2);
|
||||
expect(screen.getAllByText('Vesting multiplier').length).toBe(2);
|
||||
expect(screen.getAllByText('Reward multiplier').length).toBe(2);
|
||||
|
||||
expect(screen.getByText('10000')).toBeInTheDocument();
|
||||
expect(screen.getByText('5x')).toBeInTheDocument();
|
||||
expect(screen.getByText('0.1x')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('10000000000000')).toBeInTheDocument();
|
||||
expect(screen.getByText('100x')).toBeInTheDocument();
|
||||
expect(screen.getByText('10x')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
import {
|
||||
KeyValueTable,
|
||||
KeyValueTableRow,
|
||||
RoundedWrapper,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
formatMinimumStakedTokens,
|
||||
formatReferralRewardMultiplier,
|
||||
} from '../proposal-referral-program-details';
|
||||
import { formatNumberPercentage } from '@vegaprotocol/utils';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
// These types are not generated as it's not known how dynamic these are
|
||||
type VestingBenefitTier = {
|
||||
minimum_quantum_balance: string;
|
||||
reward_multiplier: string;
|
||||
};
|
||||
|
||||
type ActivityStreakBenefitTier = {
|
||||
minimum_activity_streak: number;
|
||||
reward_multiplier: string;
|
||||
vesting_multiplier: string;
|
||||
};
|
||||
|
||||
export type BenefitTiers =
|
||||
| Array<ActivityStreakBenefitTier>
|
||||
| Array<VestingBenefitTier>;
|
||||
|
||||
export function getBenefitTiers(json: string): BenefitTiers {
|
||||
try {
|
||||
const parsed = JSON.parse(json);
|
||||
return parsed.tiers;
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export const formatVolumeDiscountFactor = (value: string) => {
|
||||
return formatNumberPercentage(new BigNumber(value).times(100));
|
||||
};
|
||||
|
||||
interface ProposalReferralProgramDetailsProps {
|
||||
proposal: ProposalQuery['proposal'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Special rendered for network proposals that change any benefit tiers,
|
||||
* which is detected by:
|
||||
* 1) it being a network parameter change
|
||||
* 2) the name of the field ending in `.benefitTiers`
|
||||
*
|
||||
* It only renders known fields so that they can be formatted correctly.
|
||||
*/
|
||||
export const ProposalUpdateBenefitTiers = ({
|
||||
proposal,
|
||||
}: ProposalReferralProgramDetailsProps) => {
|
||||
const { t } = useTranslation();
|
||||
if (
|
||||
proposal?.terms?.change?.__typename !== 'UpdateNetworkParameter' ||
|
||||
proposal?.terms?.change?.networkParameter.key.slice(-13) !== '.benefitTiers'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const benefitTiersString = proposal?.terms?.change?.networkParameter.value;
|
||||
const benefitTiers = getBenefitTiers(benefitTiersString);
|
||||
|
||||
if (!benefitTiers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-testid="proposal-update-benefit-tiers">
|
||||
<RoundedWrapper paddingBottom={true}>
|
||||
{benefitTiers && (
|
||||
<div
|
||||
className="mb-6"
|
||||
data-testid="proposal-volume-discount-program-benefit-tiers"
|
||||
>
|
||||
<h3 className="mb-3 uppercase font-semibold text-lg">
|
||||
{t('BenefitTiers')}
|
||||
</h3>
|
||||
<KeyValueTable>
|
||||
{benefitTiers
|
||||
.sort(
|
||||
(a, b) =>
|
||||
Number(a.reward_multiplier) - Number(b.reward_multiplier)
|
||||
)
|
||||
.map((benefitTier, index) => (
|
||||
<div className="mb-4" key={index}>
|
||||
<h4 className="font-semibold uppercase">
|
||||
Tier {index + 1}
|
||||
</h4>
|
||||
{'minimum_activity_streak' in benefitTier && (
|
||||
<KeyValueTableRow
|
||||
data-testid={`mas-${benefitTier.reward_multiplier}`}
|
||||
>
|
||||
<Tooltip
|
||||
description={t(
|
||||
'BenefitTierMinimumActivityStreakDescription'
|
||||
)}
|
||||
>
|
||||
<span>{t('BenefitTierMinimumActivityStreak')}</span>
|
||||
</Tooltip>
|
||||
|
||||
{benefitTier.minimum_activity_streak}
|
||||
</KeyValueTableRow>
|
||||
)}
|
||||
{'minimum_quantum_balance' in benefitTier && (
|
||||
<KeyValueTableRow
|
||||
data-testid={`mqb-${benefitTier.reward_multiplier}`}
|
||||
>
|
||||
<Tooltip
|
||||
description={t(
|
||||
'BenefitTierMinimumQuantumBalanceDescription'
|
||||
)}
|
||||
>
|
||||
<span>{t('BenefitTierMinimumQuantumBalance')}</span>
|
||||
</Tooltip>
|
||||
|
||||
{formatMinimumStakedTokens(
|
||||
benefitTier.minimum_quantum_balance,
|
||||
18
|
||||
)}
|
||||
</KeyValueTableRow>
|
||||
)}
|
||||
{'vesting_multiplier' in benefitTier && (
|
||||
<KeyValueTableRow
|
||||
data-testid={`vm-${benefitTier.reward_multiplier}`}
|
||||
>
|
||||
<Tooltip
|
||||
description={t('BenefitTierVestingMultiplier')}
|
||||
>
|
||||
<span>{t('BenefitTierVestingMultiplier')}</span>
|
||||
</Tooltip>
|
||||
{formatReferralRewardMultiplier(
|
||||
benefitTier.vesting_multiplier
|
||||
)}
|
||||
</KeyValueTableRow>
|
||||
)}
|
||||
{'reward_multiplier' in benefitTier && (
|
||||
<KeyValueTableRow
|
||||
data-testid={`rm-${benefitTier.reward_multiplier}`}
|
||||
>
|
||||
<Tooltip description={t('BenefitTierRewardMultiplier')}>
|
||||
<span>{t('BenefitTierRewardMultiplier')}</span>
|
||||
</Tooltip>
|
||||
{formatReferralRewardMultiplier(
|
||||
benefitTier.reward_multiplier
|
||||
)}
|
||||
</KeyValueTableRow>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</KeyValueTable>
|
||||
</div>
|
||||
)}
|
||||
</RoundedWrapper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
ProposalTransferDetails,
|
||||
} from '../proposal-transfer';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { ProposalUpdateBenefitTiers } from '../proposal-update-benefit-tiers';
|
||||
|
||||
export interface ProposalProps {
|
||||
proposal: ProposalQuery['proposal'];
|
||||
@@ -243,6 +244,14 @@ export const Proposal = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{proposal.terms.change.__typename === 'UpdateNetworkParameter' &&
|
||||
proposal.terms.change.networkParameter.key.slice(-13) ===
|
||||
'.benefitTiers' && (
|
||||
<div className="mb-4">
|
||||
<ProposalUpdateBenefitTiers proposal={proposal} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{governanceTransferDetails}
|
||||
|
||||
<div className="mb-10">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"next",
|
||||
"next/core-web-vitals"
|
||||
],
|
||||
"ignorePatterns": ["!**/*", "__generated__"],
|
||||
"ignorePatterns": ["!**/*", "__generated__", ".next"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
|
||||
@@ -21,7 +21,10 @@ import type {
|
||||
} from './__generated__/MarketLiquidity';
|
||||
|
||||
export type LiquidityProvisionFields = LiquidityProvisionFieldsFragment &
|
||||
Schema.LiquiditySLAParameters;
|
||||
Schema.LiquiditySLAParameters & {
|
||||
currentCommitmentAmount?: string;
|
||||
currentFee?: string;
|
||||
};
|
||||
|
||||
export const liquidityProvisionsDataProvider = makeDataProvider<
|
||||
LiquidityProvisionsQuery,
|
||||
@@ -34,10 +37,28 @@ export const liquidityProvisionsDataProvider = makeDataProvider<
|
||||
getData: (responseData: LiquidityProvisionsQuery | null) => {
|
||||
return (responseData?.market?.liquidityProvisions?.edges
|
||||
?.filter((n) => !!n)
|
||||
.map((e) => ({
|
||||
...e?.node.current,
|
||||
...responseData.market?.liquiditySLAParameters,
|
||||
})) ?? []) as LiquidityProvisionFields[];
|
||||
.map((e) => {
|
||||
let node;
|
||||
if (!e?.node.pending && e?.node.current) {
|
||||
node = {
|
||||
...e?.node.current,
|
||||
...responseData.market?.liquiditySLAParameters,
|
||||
};
|
||||
} else if (!e?.node.current && e?.node.pending) {
|
||||
node = {
|
||||
...e?.node.pending,
|
||||
...responseData.market?.liquiditySLAParameters,
|
||||
};
|
||||
} else {
|
||||
node = {
|
||||
...e?.node.pending,
|
||||
currentCommitmentAmount: e?.node.current.commitmentAmount,
|
||||
currentFee: e?.node.current.fee,
|
||||
...responseData.market?.liquiditySLAParameters,
|
||||
};
|
||||
}
|
||||
return node;
|
||||
}) ?? []) as LiquidityProvisionFields[];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -91,7 +112,8 @@ export const matchFilter = (filter: Filter, lp: LiquidityProvisionData) => {
|
||||
}
|
||||
if (
|
||||
filter.active === true &&
|
||||
lp.status !== Schema.LiquidityProvisionStatus.STATUS_ACTIVE
|
||||
lp.status !== Schema.LiquidityProvisionStatus.STATUS_ACTIVE &&
|
||||
lp.status !== Schema.LiquidityProvisionStatus.STATUS_PENDING
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -105,7 +127,7 @@ export const matchFilter = (filter: Filter, lp: LiquidityProvisionData) => {
|
||||
};
|
||||
|
||||
export interface LiquidityProvisionData
|
||||
extends Omit<LiquidityProvisionFieldsFragment, '__typename'>,
|
||||
extends Omit<LiquidityProvisionFields, '__typename'>,
|
||||
Partial<LiquidityProviderFieldsFragment>,
|
||||
Omit<Schema.LiquiditySLAParameters, '__typename'> {
|
||||
assetDecimalPlaces?: number;
|
||||
@@ -113,11 +135,12 @@ export interface LiquidityProvisionData
|
||||
averageEntryValuation?: string;
|
||||
equityLikeShare?: string;
|
||||
earmarkedFees?: number;
|
||||
status: Schema.LiquidityProvisionStatus;
|
||||
}
|
||||
|
||||
export const getLiquidityProvision = (
|
||||
liquidityProvisions: LiquidityProvisionFields[],
|
||||
liquidityProvider: LiquidityProviderFieldsFragment[],
|
||||
liquidityProviders: LiquidityProviderFieldsFragment[],
|
||||
filter?: Filter
|
||||
): LiquidityProvisionData[] => {
|
||||
return liquidityProvisions
|
||||
@@ -136,12 +159,14 @@ export const getLiquidityProvision = (
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((lp) => {
|
||||
const lpObj = liquidityProvider.find((f) => lp.party.id === f.partyId);
|
||||
if (!lpObj) return lp;
|
||||
const accounts = compact(lp.party.accountsConnection?.edges).map(
|
||||
(e) => e.node
|
||||
.map((liquidityProvision) => {
|
||||
const liquidityProvider = liquidityProviders.find(
|
||||
(f) => liquidityProvision.party.id === f.partyId
|
||||
);
|
||||
if (!liquidityProvider) return liquidityProvision;
|
||||
const accounts = compact(
|
||||
liquidityProvision.party.accountsConnection?.edges
|
||||
).map((e) => e.node);
|
||||
const bondAccounts = accounts?.filter(
|
||||
(a) => a?.type === Schema.AccountType.ACCOUNT_TYPE_BOND
|
||||
);
|
||||
@@ -164,8 +189,8 @@ export const getLiquidityProvision = (
|
||||
)
|
||||
.toNumber() ?? 0;
|
||||
return {
|
||||
...lp,
|
||||
...lpObj,
|
||||
...liquidityProvision,
|
||||
...liquidityProvider,
|
||||
balance,
|
||||
earmarkedFees,
|
||||
__typename: undefined,
|
||||
|
||||
@@ -6,7 +6,10 @@ import {
|
||||
getDateTimeFormat,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
|
||||
import type {
|
||||
TypedDataAgGrid,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||
import {
|
||||
CopyWithTooltip,
|
||||
@@ -22,7 +25,7 @@ import type {
|
||||
ValueFormatterParams,
|
||||
} from 'ag-grid-community';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { LiquidityProvisionStatus } from '@vegaprotocol/types';
|
||||
import { LiquidityProvisionStatus } from '@vegaprotocol/types';
|
||||
import { LiquidityProvisionStatusMapping } from '@vegaprotocol/types';
|
||||
import type { LiquidityProvisionData } from './liquidity-data-provider';
|
||||
|
||||
@@ -187,7 +190,32 @@ export const LiquidityTable = ({
|
||||
headerTooltip: t(
|
||||
'The amount committed to the market by this liquidity provider.'
|
||||
),
|
||||
valueFormatter: assetDecimalsQuantumFormatter,
|
||||
valueFormatter: ({
|
||||
data,
|
||||
value,
|
||||
}: VegaValueFormatterParams<
|
||||
LiquidityProvisionData,
|
||||
'commitmentAmount'
|
||||
>) => {
|
||||
if (!value) return '-';
|
||||
const formattedCommitmentAmount = addDecimalsFormatNumberQuantum(
|
||||
value,
|
||||
assetDecimalPlaces ?? 0,
|
||||
quantum ?? 0
|
||||
);
|
||||
if (
|
||||
data?.currentCommitmentAmount &&
|
||||
data?.currentCommitmentAmount !== value
|
||||
) {
|
||||
return `${addDecimalsFormatNumberQuantum(
|
||||
data.currentCommitmentAmount,
|
||||
assetDecimalPlaces ?? 0,
|
||||
quantum ?? 0
|
||||
)}/${formattedCommitmentAmount}`;
|
||||
} else {
|
||||
return formattedCommitmentAmount;
|
||||
}
|
||||
},
|
||||
tooltipValueGetter: assetDecimalsFormatter,
|
||||
},
|
||||
{
|
||||
@@ -207,7 +235,22 @@ export const LiquidityTable = ({
|
||||
),
|
||||
field: 'fee',
|
||||
type: 'rightAligned',
|
||||
valueFormatter: percentageFormatter,
|
||||
valueFormatter: ({
|
||||
data,
|
||||
value,
|
||||
}: ValueFormatterParams<LiquidityProvisionData, 'fee'>) => {
|
||||
if (!value) return '-';
|
||||
const formattedValue =
|
||||
formatNumberPercentage(new BigNumber(value).times(100), 2) ||
|
||||
'-';
|
||||
if (data?.currentFee && data?.currentFee !== value) {
|
||||
return `${formatNumberPercentage(
|
||||
new BigNumber(data.currentFee).times(100),
|
||||
2
|
||||
)}/${formattedValue}`;
|
||||
}
|
||||
return formattedValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
headerName: t('Adjusted stake share'),
|
||||
@@ -328,8 +371,17 @@ export const LiquidityTable = ({
|
||||
headerName: t('Status'),
|
||||
headerTooltip: t('The current status of this liquidity provision.'),
|
||||
field: 'status',
|
||||
valueFormatter: ({ value }) => {
|
||||
valueFormatter: ({
|
||||
data,
|
||||
value,
|
||||
}: ValueFormatterParams<LiquidityProvisionData, 'status'>) => {
|
||||
if (!value) return value;
|
||||
if (
|
||||
data?.status === LiquidityProvisionStatus.STATUS_PENDING &&
|
||||
(data?.currentCommitmentAmount || data?.currentFee)
|
||||
) {
|
||||
return t('Updating next epoch');
|
||||
}
|
||||
return LiquidityProvisionStatusMapping[
|
||||
value as LiquidityProvisionStatus
|
||||
];
|
||||
|
||||
@@ -72,7 +72,7 @@ LessThan24HoursIncrease.args = {
|
||||
|
||||
export const LessThan24HoursDecrease = Template.bind({});
|
||||
LessThan24HoursDecrease.args = {
|
||||
data: [20, 21, 22, 23, 24, 6, 7, 9, 11, 13, 11, 9],
|
||||
data: [20990000, 20939973, 20980130],
|
||||
width: 110,
|
||||
height: 30,
|
||||
};
|
||||
|
||||
@@ -44,14 +44,12 @@ export const SparklineView = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const midValue = (min + max) / 2;
|
||||
|
||||
// Market may be less than 24hr old so padd the data array
|
||||
// with values that is the mid value (avg of min and max).
|
||||
// This will rendera horizontal line until the real data shifts the line
|
||||
const padCount = data.length < points ? points - data.length : 0;
|
||||
const padArr = new Array(padCount).fill(midValue);
|
||||
const trimmedData = data.slice(-points);
|
||||
const padCount = data.length < points ? points - data.length : 0;
|
||||
const padArr = new Array(padCount).fill(trimmedData[0]);
|
||||
|
||||
// Get the last 24 values if data has more than needed
|
||||
const lineData: [number, number][] = [...padArr, ...trimmedData].map(
|
||||
|
||||
+4
-2
@@ -1,2 +1,4 @@
|
||||
[functions]
|
||||
included_files = ["!node_modules/@sentry/cli/sentry-cli"]
|
||||
[[redirects]]
|
||||
from = "/*"
|
||||
to = "/index.html"
|
||||
status = 200
|
||||
|
||||
Reference in New Issue
Block a user