Compare commits

..
20 changed files with 148 additions and 165 deletions
+2 -2
View File
@@ -184,7 +184,7 @@ const Web3Container = ({
<TemplateSidebar sidebar={sideBar}>
<AppRouter />
</TemplateSidebar>
<footer className="p-4 border-t border-neutral-700">
<footer className="p-4 border-t border-neutral-700 break-all">
<NetworkInfo />
</footer>
</AppLayout>
@@ -308,7 +308,7 @@ const AppContainer = () => {
<Router>
<ScrollToTop />
<AppStateProvider>
<div className="min-h-full text-white grid">
<div className="min-h-full text-white">
<NodeGuard
skeleton={<div>{t('Loading')}</div>}
failure={
+3 -3
View File
@@ -279,8 +279,8 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
trimmedActiveNodes={trimmedActiveNodes}
/>
<section className="grid grid-cols-2 gap-12 mb-16">
<div data-testid="home-rewards">
<section className="flex justify-between flex-wrap gap-12 mb-16">
<div className="min-w-[360px] flex-1" data-testid="home-rewards">
<Heading title={t('Rewards')} marginTop={false} />
<h3 className="mb-6">{t('homeRewardsIntro')}</h3>
<div className="flex items-center mb-8 gap-4">
@@ -290,7 +290,7 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
</div>
</div>
<div data-testid="home-vega-token">
<div className="min-w-[360px] flex-1" data-testid="home-vega-token">
<Heading title={t('vegaToken')} marginTop={false} />
<h3 className="mb-6">{t('homeVegaTokenIntro')}</h3>
<div className="flex items-center mb-8 gap-4">
@@ -159,7 +159,7 @@ export const ProposalHeader = ({
</div>
</div>
<div data-testid="proposal-title">
<div data-testid="proposal-title" className="break-all">
{isListItem ? (
<header>
<SubHeading
@@ -55,7 +55,10 @@ export const orderByUpgradeBlockHeight = (
) =>
orderBy(
arr,
[(p) => p?.upgradeBlockHeight, (p) => p.vegaReleaseTag],
[
(p) => (p?.upgradeBlockHeight ? parseInt(p.upgradeBlockHeight, 10) : 0),
(p) => p.vegaReleaseTag,
],
['desc', 'desc']
);
@@ -224,10 +227,10 @@ export const ProposalsList = ({
sortedProtocolUpgradeProposals.closed.length > 0 &&
filterString.length < 1 && (
<div
className="grid w-full justify-end xl:-mt-12 pb-6"
className="flex justify-end xl:-mt-12 pb-6"
data-testid="toggle-closed-proposals"
>
<div className="w-[440px]">
<div className="w-full max-w-[420px]">
<Toggle
name="closed-proposals-toggle"
toggles={[
@@ -130,7 +130,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
? t('byTokenVote')
: t('byLiquidityVote');
const sectionWrapperClasses = classNames('grid sm:grid-cols-2 gap-6');
const sectionWrapperClasses = classNames(
'flex justify-between flex-wrap gap-6'
);
const sectionClasses = classNames('min-w-[300px] flex-1 flex-grow');
const headingClasses = classNames('mb-2 text-vega-dark-400');
const progressDetailsClasses = classNames(
'flex justify-between flex-wrap mt-2 text-sm'
@@ -166,7 +169,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
<div className="mb-4">
<h3 className={headingClasses}>{t('liquidityProviderVote')}</h3>
<div className={sectionWrapperClasses}>
<section data-testid="lp-majority-breakdown">
<section
className={sectionClasses}
data-testid="lp-majority-breakdown"
>
<VoteProgress
percentageFor={yesLPPercentage}
colourfulBg={true}
@@ -241,7 +247,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
</div>
</section>
<section data-testid="lp-participation-breakdown">
<section
className={sectionClasses}
data-testid="lp-participation-breakdown"
>
<VoteProgress
percentageFor={
lpParticipationThresholdProgress || new BigNumber(0)
@@ -288,7 +297,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
{isUpdateMarket && <h3 className={headingClasses}>{t('tokenVote')}</h3>}
<div className={sectionWrapperClasses}>
<section data-testid="token-majority-breakdown">
<section
className={sectionClasses}
data-testid="token-majority-breakdown"
>
<VoteProgress
percentageFor={yesPercentage}
colourfulBg={true}
@@ -347,7 +359,10 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
</div>
</section>
<section data-testid="token-participation-breakdown">
<section
className={sectionClasses}
data-testid="token-participation-breakdown"
>
<VoteProgress
percentageFor={participationThresholdProgress}
testId="token-participation-progress"
@@ -133,24 +133,26 @@ export const RewardsPage = () => {
</p>
</div>
<div className="w-[360px]">
<Toggle
name="epoch-reward-view-toggle"
toggles={[
{
label: t('totalDistributed'),
value: 'total',
},
{
label: t('earnedByMe'),
value: 'individual',
},
]}
checkedValue={toggleRewardsView}
onChange={(e) =>
setToggleRewardsView(e.target.value as RewardsView)
}
/>
<div className="flex justify-end">
<div className="w-full max-w-[360px]">
<Toggle
name="epoch-reward-view-toggle"
toggles={[
{
label: t('totalDistributed'),
value: 'total',
},
{
label: t('earnedByMe'),
value: 'individual',
},
]}
checkedValue={toggleRewardsView}
onChange={(e) =>
setToggleRewardsView(e.target.value as RewardsView)
}
/>
</div>
</div>
</section>
+3 -3
View File
@@ -100,8 +100,8 @@ const Home = ({ name }: RouteChildProps) => {
</Link>
</p>
</HomeSection>
<div className="flex gap-12">
<div className="flex-1">
<div className="flex justify-between flex-wrap gap-x-12 gap-y-4">
<div className="flex-1 min-w-[360px]">
<HomeSection>
<SubHeading title={t('Staking')} />
<p>
@@ -118,7 +118,7 @@ const Home = ({ name }: RouteChildProps) => {
</p>
</HomeSection>
</div>
<div className="flex-1">
<div className="flex-1 min-w-[360px]">
<HomeSection>
<SubHeading title={t('Governance')} />
<p>
+6
View File
@@ -6,6 +6,12 @@
@tailwind utilities;
@layer base {
*,
*::before,
*::after {
box-sizing: border-box;
}
h1 {
@apply text-2xl text-white uppercase mb-4;
}
@@ -1,6 +1,12 @@
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { Notification, Intent } from '@vegaprotocol/ui-toolkit';
import {
Intent,
VegaIcon,
VegaIconNames,
Tooltip,
TradingButton,
} from '@vegaprotocol/ui-toolkit';
interface Props {
margin: string;
@@ -14,24 +20,43 @@ interface Props {
}
export const MarginWarning = ({ margin, balance, asset, onDeposit }: Props) => {
const description = (
<div className="flex flex-col items-start gap-2 p-2">
<p className="text-sm">
{t('%s %s is currently required.', [
addDecimalsFormatNumber(margin, asset.decimals),
asset.symbol,
])}
</p>
<p className="text-sm">
{t('You have only %s.', [
addDecimalsFormatNumber(balance, asset.decimals),
])}
</p>
<TradingButton
intent={Intent.Warning}
size="small"
onClick={() => onDeposit(asset.id)}
data-testid="deal-ticket-deposit-dialog-button"
type="button"
>
{t('Deposit %s', [asset.symbol])}
</TradingButton>
</div>
);
return (
<Notification
intent={Intent.Warning}
testId="deal-ticket-warning-margin"
message={`You may not have enough margin available to open this position. ${addDecimalsFormatNumber(
margin,
asset.decimals
)} ${asset.symbol} ${t(
'is currently required. You have only'
)} ${addDecimalsFormatNumber(balance, asset.decimals)} ${
asset.symbol
} ${t('available.')}`}
buttonProps={{
text: t(`Deposit ${asset.symbol}`),
action: () => onDeposit(asset.id),
dataTestId: 'deal-ticket-deposit-dialog-button',
size: 'small',
}}
/>
<Tooltip description={description}>
<div
className="flex text-xs items-center"
data-testid="deal-ticket-warning-margin"
>
<span className="text-yellow-500 mr-2">
<VegaIcon name={VegaIconNames.WARNING} />
</span>
{t('You may not have enough margin available to open this position.')}
</div>
</Tooltip>
);
};
@@ -0,0 +1,7 @@
export const IconWarning = ({ size = 16 }: { size: number }) => {
return (
<svg width={size} height={size} viewBox="0 0 16 16">
<path d="M15.84 13.5l.01-.01-7-12-.01.01c-.17-.3-.48-.5-.85-.5s-.67.2-.85.5l-.01-.01-7 12 .01.01c-.09.15-.15.31-.15.5 0 .55.45 1 1 1h14c.55 0 1-.45 1-1 0-.19-.06-.35-.15-.5zm-6.85-.51h-2v-2h2v2zm0-3h-2v-5h2v5z" />
</svg>
);
};
@@ -36,6 +36,7 @@ import { IconTrendDown } from './svg-icons/icon-trend-down';
import { IconTrendUp } from './svg-icons/icon-trend-up';
import { IconTwitter } from './svg-icons/icon-twitter';
import { IconVote } from './svg-icons/icon-vote';
import { IconWarning } from './svg-icons/icon-warning';
import { IconWithdraw } from './svg-icons/icon-withdraw';
export enum VegaIconNames {
@@ -78,6 +79,7 @@ export enum VegaIconNames {
TWITTER = 'twitter',
VOTE = 'vote',
WITHDRAW = 'withdraw',
WARNING = 'warning',
}
export const VegaIconNameMap: Record<
@@ -123,4 +125,5 @@ export const VegaIconNameMap: Record<
twitter: IconTwitter,
vote: IconVote,
withdraw: IconWithdraw,
warning: IconWarning,
};
@@ -4,7 +4,7 @@ import { TradingCheckbox } from './checkbox';
export default {
component: TradingCheckbox,
title: 'Checkbox',
title: 'Checkbox - trading',
} as Meta<typeof TradingCheckbox>;
const Template: StoryFn<TradingCheckboxProps> = (args) => (
@@ -4,7 +4,7 @@ import type { TradingFormGroupProps } from './form-group';
import { TradingFormGroup } from './form-group';
export default {
component: TradingFormGroup,
title: 'FormGroup',
title: 'FormGroup trading',
argTypes: {
label: {
type: 'string',
@@ -3,7 +3,7 @@ import { TradingInputError } from './input-error';
export default {
component: TradingInputError,
title: 'InputError',
title: 'InputError trading',
} as Meta;
const Template: StoryFn = (args) => <TradingInputError {...args} />;
@@ -3,7 +3,7 @@ import { TradingInput } from './input';
import { FormGroup } from '../form-group';
export default {
component: TradingInput,
title: 'Input',
title: 'Input trading',
} as Meta;
const Template: StoryFn = (args) => (
@@ -4,7 +4,7 @@ import { TradingRadioGroup, TradingRadio } from './radio-group';
export default {
component: TradingRadioGroup,
title: 'RadioGroup',
title: 'RadioGroup trading',
} as Meta;
const Template: StoryFn<TradingRadioGroupProps> = (args) => (
@@ -4,7 +4,7 @@ import { FormGroup } from '../form-group';
export default {
component: TradingSelect,
title: 'Select',
title: 'Select trading',
} as Meta;
const Template: StoryFn = (args) => (
@@ -12,7 +12,10 @@ import { useVegaWallet } from '../use-vega-wallet';
export const ConnectDialogTitle = ({ children }: { children: ReactNode }) => {
return (
<h1 data-testid="wallet-dialog-title" className="mb-6 text-2xl font-alpha">
<h1
data-testid="wallet-dialog-title"
className="mb-6 text-2xl uppercase font-alpha calt"
>
{children}
</h1>
);
@@ -111,7 +111,7 @@ describe('VegaConnectDialog', () => {
rerender(generateJSX());
const list = await screen.findByTestId('connectors-list');
expect(list).toBeInTheDocument();
expect(list.children).toHaveLength(2);
expect(list.children).toHaveLength(3);
expect(screen.getByTestId('connector-jsonRpc')).toHaveTextContent(
'Use the Desktop App/CLI'
);
@@ -122,7 +122,7 @@ describe('VegaConnectDialog', () => {
mockBrowserWallet();
render(generateJSX());
const list = await screen.findByTestId('connectors-list');
expect(list.children).toHaveLength(2);
expect(list.children).toHaveLength(3);
expect(screen.getByTestId('connector-injected')).toHaveTextContent(
'Connect'
);
+21 -102
View File
@@ -224,66 +224,28 @@ const ConnectorList = ({
/>
</>
);
const isItChrome = window.navigator.userAgent.includes('Chrome');
const isItMozilla =
window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
const browserName = isItChrome
? 'Chrome'
: isItMozilla
? 'Firefox'
: 'your browser';
return (
<>
<ConnectDialogTitle>{title}</ConnectDialogTitle>
<p className="text-md">
<p>
{t(
'Connect securely, deposit funds and approve or reject transactions with the Vega wallet'
)}
</p>
<div data-testid="connectors-list" className="flex flex-col mt-4 gap-4">
<div>
<div data-testid="connectors-list" className="flex flex-col mt-6 gap-2">
<div className="last:mb-0">
{isBrowserWalletInstalled() ? (
<ConnectionOptionWithDescription
<ConnectionOption
type="injected"
text={extendedText}
onClick={() => onSelect('injected')}
title={
<>
<span>{t('Vega Wallet')}</span>
{' '}
<span className="text-xs">{t('full featured')}</span>
</>
}
description={t(
`Connect Vega Wallet extension
for %s to access all features including key
management and detailed transaction views from your
browser.`,
[browserName]
)}
/>
) : (
<div className="py-2">
<h1 className="px-2 text-lg">
<span>{t('Vega Wallet')}</span>
{' '}
<span className="text-xs"> {t('full featured')}</span>
</h1>
<p className="p-2 text-sm">
{t(
`Install Vega Wallet extension
for %s to access all features including key
management and detailed transaction views from your
browser.`,
[browserName]
)}
</p>
<GetWalletButton
chromeExtensionUrl={links.chromeExtensionUrl}
mozillaExtensionUrl={links.mozillaExtensionUrl}
/>
</div>
<GetWalletButton
chromeExtensionUrl={links.chromeExtensionUrl}
mozillaExtensionUrl={links.mozillaExtensionUrl}
/>
)}
</div>
{connectors['snap'] !== undefined ? (
@@ -307,19 +269,9 @@ const ConnectorList = ({
/>
) : (
<>
<ConnectionOptionWithDescription
<ConnectionOption
type="snap"
disabled={snapStatus === SnapStatus.NOT_SUPPORTED}
title={
<>
<span>{t('Metamask Snap')}</span>
{' '}
<span className="text-xs"> {t('quick start')}</span>
</>
}
description={t(
`Connect directly via Metamask with the Vega Snap for single key support without advanced features.`
)}
text={
<>
<div className="flex items-center justify-center w-full h-full text-base gap-1">
@@ -335,7 +287,7 @@ const ConnectorList = ({
}}
/>
{snapStatus === SnapStatus.NOT_SUPPORTED ? (
<p className="pt-1 text-xs leading-tight text-default">
<p className="pt-2 text-sm text-default">
{t('No MetaMask version that supports snaps detected.')}{' '}
{t('Learn more about')}{' '}
<ExternalLink href="https://metamask.io/snaps/">
@@ -348,21 +300,20 @@ const ConnectorList = ({
</div>
) : null}
<div>
<h1 className="my-1 text-md">{t('Advanced / Other options...')}</h1>
<ConnectionOption
type="view"
text={t('View as party')}
onClick={() => onSelect('view')}
disabled={Boolean(pubKey)}
/>
<div className="mt-2">
<CustomUrlInput
walletUrl={walletUrl}
setWalletUrl={setWalletUrl}
isDesktopWalletRunning={isDesktopWalletRunning}
onSelect={() => onSelect('jsonRpc')}
/>
</div>
</div>
<div className="last:mb-0">
<CustomUrlInput
walletUrl={walletUrl}
setWalletUrl={setWalletUrl}
isDesktopWalletRunning={isDesktopWalletRunning}
onSelect={() => onSelect('jsonRpc')}
/>
</div>
</div>
</>
@@ -500,38 +451,6 @@ export const GetWalletButton = ({
);
};
const ConnectionOptionWithDescription = ({
disabled,
type,
text,
onClick,
icon,
description,
title,
}: {
type: WalletType;
text: string | ReactNode;
onClick: () => void;
disabled?: boolean;
icon?: ReactNode;
description?: string | ReactNode;
title?: string | ReactNode;
}) => {
return (
<div>
<h1 className="text-md">{title}</h1>
<p className="pb-2 text-sm text-gray-60 text-muted">{description}</p>
<ConnectionOption
disabled={disabled}
type={type}
text={text}
onClick={onClick}
icon={icon}
/>
</div>
);
};
const ConnectionOption = ({
disabled,
type,
@@ -612,7 +531,7 @@ const CustomUrlInput = ({
onClick={() => onSelect('jsonRpc')}
/>
{isDesktopWalletRunning !== null && (
<p className="pt-1 mb-2 text-sm leading-tight">
<p className="pt-2 mb-6 text-sm">
{isDesktopWalletRunning ? (
<button
className="underline text-default"
@@ -624,13 +543,13 @@ const CustomUrlInput = ({
</button>
) : (
<>
<span className="text-xs">
<span className="text-default">
{t(
'No running Desktop App/CLI detected. Open your app now to connect or enter a'
)}
</span>{' '}
<button
className="text-xs underline"
className="underline"
onClick={() => setUrlInputExpanded(true)}
disabled={Boolean(pubKey)}
>