Fixes for workflows (#291)

* change to setting envars rather than passing in via CLI

* update nx to latest patch version

* add env files for token-e2e, fix lint and ts errors

* move generate functions to mocs for trading e2e to avoid violating boundary rules

* add jsx compiler option for trading-e2e

* downgrade nextjs

* add testing-library to types declaration where required
This commit is contained in:
Matthew Russell 2022-04-22 17:51:18 -07:00 committed by GitHub
parent 9591687a80
commit 899277e6d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 686 additions and 987 deletions

View File

@ -56,7 +56,10 @@ jobs:
run: ./vegawallet service run --network fairground & run: ./vegawallet service run --network fairground &
- name: Run Cypress tests - name: Run Cypress tests
run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.tradingWalletPassphrase=${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }} --env.slackWebhook=${{ secrets.CYPRESS_SLACK_WEBHOOK }} --browser chrome env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
pr: pr:
name: Run end-to-end tests - PR name: Run end-to-end tests - PR
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -103,4 +106,7 @@ jobs:
run: ./vegawallet service run --network fairground & run: ./vegawallet service run --network fairground &
- name: Run Cypress tests - name: Run Cypress tests
run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.tradingWalletPassphrase=${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }} --env.slackWebhook=${{ secrets.CYPRESS_SLACK_WEBHOOK }} --browser chrome env:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome

30
apps/token-e2e/.env Normal file
View File

@ -0,0 +1,30 @@
# React Environment Variables
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
# Netlify Environment Variables
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
REACT_APP_VERSION=$npm_package_version
REACT_APP_REPOSITORY_URL=$REPOSITORY_URL
REACT_APP_BRANCH=$BRANCH
REACT_APP_PULL_REQUEST=$PULL_REQUEST
REACT_APP_HEAD=$HEAD
REACT_APP_COMMIT_REF=$COMMIT_REF
REACT_APP_CONTEXT=$CONTEXT
REACT_APP_REVIEW_ID=$REVIEW_ID
REACT_APP_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
REACT_APP_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
REACT_APP_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
REACT_APP_URL=$URL
REACT_APP_DEPLOY_URL=$DEPLOY_URL
REACT_APP_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
# App configuration variables
NX_VEGA_ENV = "TESTNET"
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 3
NX_ETHEREUM_PROVIDER_URL = "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8"
NX_ETHERSCAN_URL = "https://ropsten.etherscan.io"
NX_FAIRGROUND = false
#Test configuration variables
CYPRESS_FAIRGROUND = false

View File

@ -0,0 +1,6 @@
# App configuration variables
NX_VEGA_ENV = "DEVNET"
NX_VEGA_URL = "https://n04.d.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 3
NX_ETHEREUM_PROVIDER_URL = "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8"
NX_ETHERSCAN_URL = "https://ropsten.etherscan.io"

View File

@ -0,0 +1,6 @@
# App configuration variables
NX_VEGA_ENV = "MAINNET"
NX_VEGA_URL = "https://api.token.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 1
NX_ETHEREUM_PROVIDER_URL = "https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8"
NX_ETHERSCAN_URL = "https://etherscan.io"

View File

@ -0,0 +1,6 @@
# App configuration variables
NX_VEGA_ENV = "STAGNET"
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 3
NX_ETHEREUM_PROVIDER_URL = "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8"
NX_ETHERSCAN_URL = "https://ropsten.etherscan.io"

View File

@ -0,0 +1,6 @@
# App configuration variables
NX_VEGA_ENV = "STAGNET2"
NX_VEGA_URL = "https://n03.stagnet2.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 3
NX_ETHEREUM_PROVIDER_URL = "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8"
NX_ETHERSCAN_URL = "https://ropsten.etherscan.io"

View File

@ -0,0 +1,6 @@
# App configuration variables
NX_VEGA_ENV = "TESTNET"
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
NX_ETHEREUM_CHAIN_ID = 3
NX_ETHEREUM_PROVIDER_URL = "https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8"
NX_ETHERSCAN_URL = "https://ropsten.etherscan.io"

View File

@ -3,7 +3,7 @@ const fairgroundSet = Cypress.env('FAIRGROUND');
describe('token', () => { describe('token', () => {
beforeEach(() => cy.visit('/')); beforeEach(() => cy.visit('/'));
it('should always have an header title based on environment', () => { it('should always have a header title based on environment', () => {
cy.get('.nav h1').should( cy.get('.nav h1').should(
'have.text', 'have.text',
`${fairgroundSet ? 'Fairground token' : '$VEGA TOKEN'}` `${fairgroundSet ? 'Fairground token' : '$VEGA TOKEN'}`

View File

@ -1,6 +1,6 @@
{ {
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"], "ignorePatterns": ["!**/*", "__generated__"],
"overrides": [ "overrides": [
{ {
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],

View File

@ -34,15 +34,17 @@ function App() {
<ContractsProvider> <ContractsProvider>
<AppLoader> <AppLoader>
<BalanceManager> <BalanceManager>
<div className="app dark"> <>
<AppBanner /> <div className="app dark">
<TemplateSidebar sidebar={sideBar}> <AppBanner />
<AppRouter /> <TemplateSidebar sidebar={sideBar}>
</TemplateSidebar> <AppRouter />
<AppFooter /> </TemplateSidebar>
</div> <AppFooter />
<VegaWalletDialogs /> </div>
<TransactionModal /> <VegaWalletDialogs />
<TransactionModal />
</>
</BalanceManager> </BalanceManager>
</AppLoader> </AppLoader>
</ContractsProvider> </ContractsProvider>

View File

@ -1,28 +1,32 @@
import * as Sentry from "@sentry/react"; import * as Sentry from '@sentry/react';
import { useWeb3React } from "@web3-react/core"; import { useWeb3React } from '@web3-react/core';
import React from "react"; import React from 'react';
import { ADDRESSES } from "../../config"; import { ADDRESSES } from '../../config';
import { import {
AppStateActionType, AppStateActionType,
useAppState, useAppState,
} from "../../contexts/app-state/app-state-context"; } from '../../contexts/app-state/app-state-context';
import { useContracts } from "../../contexts/contracts/contracts-context"; import { useContracts } from '../../contexts/contracts/contracts-context';
import { useGetAssociationBreakdown } from "../../hooks/use-get-association-breakdown"; import { useGetAssociationBreakdown } from '../../hooks/use-get-association-breakdown';
import { useGetUserTrancheBalances } from "../../hooks/use-get-user-tranche-balances"; import { useGetUserTrancheBalances } from '../../hooks/use-get-user-tranche-balances';
import { BigNumber } from "../../lib/bignumber"; import { BigNumber } from '../../lib/bignumber';
export const BalanceManager = ({ children }: any) => { interface BalanceManagerProps {
children: React.ReactElement;
}
export const BalanceManager = ({ children }: BalanceManagerProps) => {
const contracts = useContracts(); const contracts = useContracts();
const { account } = useWeb3React(); const { account } = useWeb3React();
const { appDispatch } = useAppState(); const { appDispatch } = useAppState();
const getUserTrancheBalances = useGetUserTrancheBalances( const getUserTrancheBalances = useGetUserTrancheBalances(
account || "", account || '',
contracts?.vesting contracts?.vesting
); );
const getAssociationBreakdown = useGetAssociationBreakdown( const getAssociationBreakdown = useGetAssociationBreakdown(
account || "", account || '',
contracts?.staking, contracts?.staking,
contracts?.vesting contracts?.vesting
); );

View File

@ -27,7 +27,7 @@ export const filterCountry: ItemPredicate<ICountry> = (
export interface CountrySelectorProps { export interface CountrySelectorProps {
onSelectCountry: (countryCode: string) => void; onSelectCountry: (countryCode: string) => void;
code: string | null; code: string | null | undefined;
} }
export const CountrySelector = ({ export const CountrySelector = ({

View File

@ -11,8 +11,10 @@ export const StakingMethodRadio = ({
setSelectedStakingMethod, setSelectedStakingMethod,
selectedStakingMethod, selectedStakingMethod,
}: { }: {
selectedStakingMethod: string; selectedStakingMethod: StakingMethod | null;
setSelectedStakingMethod: React.Dispatch<any>; setSelectedStakingMethod: React.Dispatch<
React.SetStateAction<StakingMethod | null>
>;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@ -22,7 +24,7 @@ export const StakingMethodRadio = ({
// @ts-ignore can't recognise .value // @ts-ignore can't recognise .value
setSelectedStakingMethod(e.target.value); setSelectedStakingMethod(e.target.value);
}} }}
selectedValue={selectedStakingMethod} selectedValue={selectedStakingMethod || undefined}
> >
<Radio <Radio
data-testid="associate-radio-contract" data-testid="associate-radio-contract"

View File

@ -107,8 +107,10 @@ export const TokenInput = ({
'If requires approval is true allowance, approve, approveTxState and approveDispatch props are required!' 'If requires approval is true allowance, approve, approveTxState and approveDispatch props are required!'
); );
} }
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const isApproved = !new BigNumber(allowance!).isEqualTo(0); const isApproved = !new BigNumber(allowance!).isEqualTo(0);
const showApproveButton = const showApproveButton =
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
!isApproved || new BigNumber(amount).isGreaterThan(allowance!); !isApproved || new BigNumber(amount).isGreaterThan(allowance!);
const isDisabled = React.useMemo<boolean>(() => { const isDisabled = React.useMemo<boolean>(() => {

View File

@ -38,7 +38,7 @@ export const TransactionCallout = ({
<TransactionPending <TransactionPending
confirmations={state.txData.confirmations} confirmations={state.txData.confirmations}
requiredConfirmations={state.requiredConfirmations} requiredConfirmations={state.requiredConfirmations}
hash={state.txData.hash!} hash={state.txData.hash || ''}
heading={pendingHeading} heading={pendingHeading}
body={pendingBody} body={pendingBody}
footer={pendingFooter} footer={pendingFooter}
@ -49,7 +49,7 @@ export const TransactionCallout = ({
} else if (state.txState === TxState.Complete) { } else if (state.txState === TxState.Complete) {
return ( return (
<TransactionComplete <TransactionComplete
hash={state.txData.hash!} hash={state.txData.hash || ''}
heading={completeHeading} heading={completeHeading}
body={completeBody} body={completeBody}
footer={completeFooter} footer={completeFooter}

View File

@ -48,7 +48,7 @@ export const Web3Content = ({
appChainId, appChainId,
setDialogOpen, setDialogOpen,
}: Web3ContentProps) => { }: Web3ContentProps) => {
const { isActive, error, connector, chainId } = useWeb3React(); const { error, connector, chainId } = useWeb3React();
useEffect(() => { useEffect(() => {
if (connector?.connectEagerly) { if (connector?.connectEagerly) {

View File

@ -1,11 +1,11 @@
const TRUTHY = ['1', 'true']; const TRUTHY = ['1', 'true'];
export const Flags = { export const Flags = {
NETWORK_DOWN: TRUTHY.includes(process.env['NX_NETWORK_DOWN']!), NETWORK_DOWN: TRUTHY.includes(process.env['NX_NETWORK_DOWN'] as string),
HOSTED_WALLET_ENABLED: TRUTHY.includes( HOSTED_WALLET_ENABLED: TRUTHY.includes(
process.env['NX_HOSTED_WALLET_ENABLED']! process.env['NX_HOSTED_WALLET_ENABLED'] as string
), ),
MOCK: TRUTHY.includes(process.env['NX_MOCKED']!), MOCK: TRUTHY.includes(process.env['NX_MOCKED'] as string),
FAIRGROUND: TRUTHY.includes(process.env['NX_FAIRGROUND']!), FAIRGROUND: TRUTHY.includes(process.env['NX_FAIRGROUND'] as string),
NETWORK_LIMITS: TRUTHY.includes(process.env['NX_NETWORK_LIMITS']!), NETWORK_LIMITS: TRUTHY.includes(process.env['NX_NETWORK_LIMITS'] as string),
}; };

View File

@ -1,38 +1,38 @@
import * as React from 'react' import * as React from 'react';
export function useCopyToClipboard() { export function useCopyToClipboard() {
const [copied, setCopied] = React.useState(false) const [copied, setCopied] = React.useState(false);
// Once copied flip a boolean so we can display // Once copied flip a boolean so we can display
// a message to the user such as 'Copied!' which will // a message to the user such as 'Copied!' which will
// revert after 800 milliseconds // revert after 800 milliseconds
React.useEffect(() => { React.useEffect(() => {
let timeout: any let timeout: ReturnType<typeof setTimeout>;
if (copied) { if (copied) {
timeout = setTimeout(() => { timeout = setTimeout(() => {
setCopied(false) setCopied(false);
}, 800) }, 800);
} }
return () => clearTimeout(timeout) return () => clearTimeout(timeout);
}, [copied]) }, [copied]);
// Create an input we can copy text from and render it // Create an input we can copy text from and render it
// off screen // off screen
function handler(text: string) { function handler(text: string) {
const input = document.createElement('input') const input = document.createElement('input');
input.style.position = 'fixed' input.style.position = 'fixed';
input.style.left = '100vw' input.style.left = '100vw';
input.style.opacity = '0' input.style.opacity = '0';
input.value = text input.value = text;
document.body.appendChild(input) document.body.appendChild(input);
input.select() input.select();
document.execCommand('copy') document.execCommand('copy');
document.body.removeChild(input) document.body.removeChild(input);
setCopied(true) setCopied(true);
} }
return { return {
copy: handler, copy: handler,
copied copied,
} };
} }

View File

@ -100,7 +100,7 @@ export function useCreateWithdrawal(pubKey: string): [Status, Submit] {
); );
React.useEffect(() => { React.useEffect(() => {
let interval: any = null; let interval: ReturnType<typeof setInterval>;
if (status === Status.Pending) { if (status === Status.Pending) {
interval = setInterval(async () => { interval = setInterval(async () => {
try { try {

View File

@ -5,6 +5,7 @@ export function useSearchParams() {
const location = useLocation(); const location = useLocation();
return React.useMemo(() => { return React.useMemo(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new URLSearchParams(location.search) as any; return new URLSearchParams(location.search) as any;
}, [location]); }, [location]);
} }

View File

@ -2,7 +2,6 @@ import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector'; import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next'; import { initReactI18next } from 'react-i18next';
import { Flags } from '../config';
import dev from './translations/dev.json'; import dev from './translations/dev.json';
i18n i18n

View File

@ -77,7 +77,7 @@ export function createClient() {
Delegation: { Delegation: {
keyFields: false, keyFields: false,
// Only get full updates // Only get full updates
merge(_, incoming: any[]) { merge(_, incoming) {
return incoming; return incoming;
}, },
fields: { fields: {

View File

@ -1,5 +1,5 @@
// creates a random number generator function. // creates a random number generator function.
function createRandomGenerator(seed: any) { function createRandomGenerator(seed: number) {
const a = 5486230734; // some big numbers const a = 5486230734; // some big numbers
const b = 6908969830; const b = 6908969830;
const m = 9853205067; const m = 9853205067;

View File

@ -88,7 +88,6 @@ export interface CommandSyncResponse {
export interface IVegaWalletService { export interface IVegaWalletService {
url: string; url: string;
token: string; token: string;
statusPoll: any;
getToken(params: { getToken(params: {
wallet: string; wallet: string;
passphrase: string; passphrase: string;
@ -101,7 +100,6 @@ export class VegaWalletService implements IVegaWalletService {
version: number; version: number;
url: string; url: string;
token: string; token: string;
statusPoll: any;
key: string; key: string;
constructor() { constructor() {
@ -260,7 +258,8 @@ export class VegaWalletService implements IVegaWalletService {
return `${this.url}/api/v${this.version}`; return `${this.url}/api/v${this.version}`;
} }
private handleServiceUnavailable(returnVal?: any): [string, any] { // eslint-disable-next-line @typescript-eslint/no-explicit-any
private handleServiceUnavailable(returnVal?: boolean): [string, any] {
this.clearWalletUrl(); this.clearWalletUrl();
return [Errors.SERVICE_UNAVAILABLE, returnVal]; return [Errors.SERVICE_UNAVAILABLE, returnVal];
} }

View File

@ -46,6 +46,7 @@ export const ClaimFlow = ({
(tranche) => tranche.tranche_id === state.claimData?.claim.tranche (tranche) => tranche.tranche_id === state.claimData?.claim.tranche
); );
const { claim } = useContracts(); const { claim } = useContracts();
// eslint-disable-next-line
const code = state.claimData?.signature.s!; const code = state.claimData?.signature.s!;
const shortCode = truncateMiddle(code); const shortCode = truncateMiddle(code);
@ -54,10 +55,13 @@ export const ClaimFlow = ({
const run = async () => { const run = async () => {
dispatch({ type: ClaimActionType.SET_LOADING, loading: true }); dispatch({ type: ClaimActionType.SET_LOADING, loading: true });
try { try {
if (!state.claimData) {
throw new Error('No claim data');
}
const [committed, expired, used] = await Promise.all([ const [committed, expired, used] = await Promise.all([
claim.isCommitted({ s: code }), claim.isCommitted({ s: code }),
claim.isExpired(state.claimData?.claim.expiry!), claim.isExpired(state.claimData.claim.expiry),
claim.isUsed(code!), claim.isUsed(code),
]); ]);
dispatch({ dispatch({
@ -77,7 +81,7 @@ export const ClaimFlow = ({
} }
}; };
run(); run();
}, [address, claim, code, dispatch, state.claimData?.claim.expiry]); }, [address, claim, code, dispatch, state.claimData]);
if (!currentTranche) { if (!currentTranche) {
return <TrancheNotFound />; return <TrancheNotFound />;
@ -95,11 +99,11 @@ export const ClaimFlow = ({
return <Expired code={shortCode} />; return <Expired code={shortCode} />;
} }
if (state.claimStatus === ClaimStatus.Finished) { if (state.claimStatus === ClaimStatus.Finished && state.claimData) {
return ( return (
<Complete <Complete
address={address} address={address}
balanceFormatted={state.claimData?.claim.amount!} balanceFormatted={state.claimData.claim.amount}
commitTxHash={state.commitTxHash} commitTxHash={state.commitTxHash}
claimTxHash={state.claimTxHash} claimTxHash={state.claimTxHash}
/> />
@ -160,7 +164,11 @@ export const ClaimFlow = ({
</KeyValueTableRow> </KeyValueTableRow>
<KeyValueTableRow> <KeyValueTableRow>
<th>{t('Amount of VEGA')}</th> <th>{t('Amount of VEGA')}</th>
<td>{formatNumber(state.claimData?.claim.amount!)}</td> <td>
{state.claimData
? formatNumber(state.claimData.claim.amount)
: 'None'}
</td>
</KeyValueTableRow> </KeyValueTableRow>
<KeyValueTableRow> <KeyValueTableRow>
<th>{t('Claim expires')}</th> <th>{t('Claim expires')}</th>

View File

@ -35,7 +35,7 @@ export const ClaimForm = ({
onSubmit, onSubmit,
}: { }: {
txState: TransactionState; txState: TransactionState;
countryCode: string; countryCode: string | undefined;
txDispatch: React.Dispatch<TransactionAction>; txDispatch: React.Dispatch<TransactionAction>;
onSubmit: () => void; onSubmit: () => void;
}) => { }) => {
@ -46,6 +46,9 @@ export const ClaimForm = ({
const handleOnClick = React.useCallback(async () => { const handleOnClick = React.useCallback(async () => {
setCountryCheck(CountryCheck.Pending); setCountryCheck(CountryCheck.Pending);
try { try {
if (!countryCode) {
throw new Error('No country code provided');
}
const blocked = await claim.isCountryBlocked(countryCode); const blocked = await claim.isCountryBlocked(countryCode);
if (!blocked) { if (!blocked) {
setCountryCheck(CountryCheck.Allowed); setCountryCheck(CountryCheck.Allowed);

View File

@ -91,7 +91,7 @@ export function claimReducer(
action: ClaimAction action: ClaimAction
): ClaimState { ): ClaimState {
switch (action.type) { switch (action.type) {
case ClaimActionType.SET_DATA_FROM_URL: case ClaimActionType.SET_DATA_FROM_URL: {
// We need all of these otherwise the code is invalid // We need all of these otherwise the code is invalid
if ( if (
// Do not need target as keys can be for the holder only // Do not need target as keys can be for the holder only
@ -126,7 +126,8 @@ export function claimReducer(
}, },
}; };
} }
case ClaimActionType.SET_INITIAL_CLAIM_STATUS: }
case ClaimActionType.SET_INITIAL_CLAIM_STATUS: {
let status = ClaimStatus.Ready; let status = ClaimStatus.Ready;
if (action.used) { if (action.used) {
status = ClaimStatus.Used; status = ClaimStatus.Used;
@ -140,12 +141,14 @@ export function claimReducer(
...state, ...state,
claimStatus: status, claimStatus: status,
}; };
case ClaimActionType.SET_CLAIM_STATUS: }
case ClaimActionType.SET_CLAIM_STATUS: {
return { return {
...state, ...state,
claimStatus: action.status, claimStatus: action.status,
}; };
case ClaimActionType.SET_COUNTRY: }
case ClaimActionType.SET_COUNTRY: {
return state.claimData return state.claimData
? { ? {
...state, ...state,
@ -155,25 +158,30 @@ export function claimReducer(
}, },
} }
: state; : state;
case ClaimActionType.SET_LOADING: }
case ClaimActionType.SET_LOADING: {
return { return {
...state, ...state,
loading: action.loading, loading: action.loading,
}; };
case ClaimActionType.SET_COMMIT_TX_HASH: }
case ClaimActionType.SET_COMMIT_TX_HASH: {
return { return {
...state, ...state,
commitTxHash: action.commitTxHash, commitTxHash: action.commitTxHash,
}; };
case ClaimActionType.SET_CLAIM_TX_HASH: }
case ClaimActionType.SET_CLAIM_TX_HASH: {
return { return {
...state, ...state,
claimTxHash: action.claimTxHash, claimTxHash: action.claimTxHash,
}; };
case ClaimActionType.ERROR: }
case ClaimActionType.ERROR: {
return { return {
...state, ...state,
error: action.error, error: action.error,
}; };
}
} }
} }

View File

@ -7,6 +7,7 @@ export const useClaim = (claimData: IClaimTokenParams, address: string) => {
...claimData, ...claimData,
...claimData.signature, ...claimData.signature,
...claimData.claim, ...claimData.claim,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
country: claimData.country!, country: claimData.country!,
account: address, account: address,
}; };

View File

@ -60,7 +60,7 @@ export const TargetedClaim = ({
labelFor="country-selector" labelFor="country-selector"
> >
<CountrySelector <CountrySelector
code={state.claimData?.country!} code={state.claimData?.country}
onSelectCountry={(countryCode) => onSelectCountry={(countryCode) =>
dispatch({ type: ClaimActionType.SET_COUNTRY, countryCode }) dispatch({ type: ClaimActionType.SET_COUNTRY, countryCode })
} }
@ -69,9 +69,9 @@ export const TargetedClaim = ({
<BulletHeader tag="h2"> <BulletHeader tag="h2">
{t('Step')} 2. {t('Claim tokens')} {t('Step')} 2. {t('Claim tokens')}
</BulletHeader> </BulletHeader>
{state.claimData?.country! ? ( {state.claimData?.country ? (
<ClaimForm <ClaimForm
countryCode={state.claimData?.country!} countryCode={state.claimData?.country}
txState={txState} txState={txState}
txDispatch={txDispatch} txDispatch={txDispatch}
onSubmit={claimTargeted} onSubmit={claimTargeted}

View File

@ -1,5 +1,6 @@
import type { IClaimTokenParams } from '@vegaprotocol/smart-contracts-sdk'; import type { IClaimTokenParams } from '@vegaprotocol/smart-contracts-sdk';
import { FormGroup } from '@vegaprotocol/ui-toolkit'; import { FormGroup } from '@vegaprotocol/ui-toolkit';
import { BigNumber } from '../../../lib/bignumber';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -80,7 +81,7 @@ export const UntargetedClaim = ({
labelFor="country-selector" labelFor="country-selector"
> >
<CountrySelector <CountrySelector
code={state.claimData?.country!} code={state.claimData?.country}
onSelectCountry={(countryCode) => onSelectCountry={(countryCode) =>
dispatch({ type: ClaimActionType.SET_COUNTRY, countryCode }) dispatch({ type: ClaimActionType.SET_COUNTRY, countryCode })
} }
@ -107,7 +108,7 @@ export const UntargetedClaim = ({
<ClaimStep2 <ClaimStep2
txState={revealState} txState={revealState}
txDispatch={revealDispatch} txDispatch={revealDispatch}
amount={state.claimData?.claim.amount!} amount={state.claimData?.claim.amount || new BigNumber(0)}
onSubmit={commitReveal} onSubmit={commitReveal}
/> />
) : ( ) : (

View File

@ -19,7 +19,7 @@ it('Renders all data for table', () => {
const proposal = generateProposal(); const proposal = generateProposal();
render(<ProposalChangeTable proposal={proposal} />); render(<ProposalChangeTable proposal={proposal} />);
expect(screen.getByText('ID')).toBeInTheDocument(); expect(screen.getByText('ID')).toBeInTheDocument();
expect(screen.getByText(proposal.id!)).toBeInTheDocument(); expect(screen.getByText(proposal.id as string)).toBeInTheDocument();
expect(screen.getByText('State')).toBeInTheDocument(); expect(screen.getByText('State')).toBeInTheDocument();
expect(screen.getByText('Open')).toBeInTheDocument(); expect(screen.getByText('Open')).toBeInTheDocument();
@ -39,7 +39,7 @@ it('Renders all data for table', () => {
).toBeInTheDocument(); ).toBeInTheDocument();
expect(screen.getByText('Proposed by')).toBeInTheDocument(); expect(screen.getByText('Proposed by')).toBeInTheDocument();
expect(screen.getByText(proposal.party.id!)).toBeInTheDocument(); expect(screen.getByText(proposal.party.id)).toBeInTheDocument();
expect(screen.getByText('Proposed on')).toBeInTheDocument(); expect(screen.getByText('Proposed on')).toBeInTheDocument();
expect( expect(

View File

@ -20,6 +20,7 @@ import type {
export interface RestProposalResponse { export interface RestProposalResponse {
data: { data: {
proposal: { proposal: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
terms: any; terms: any;
}; };
}; };

View File

@ -30,6 +30,6 @@ test('It sums some longer tranches correctly', () => {
test('Handles null tranche array', () => { test('Handles null tranche array', () => {
const tranches = null; const tranches = null;
const result = sumCirculatingTokens(tranches as any as Tranche[]); const result = sumCirculatingTokens(tranches as unknown as Tranche[]);
expect(result.toString()).toEqual('0'); expect(result.toString()).toEqual('0');
}); });

View File

@ -92,6 +92,7 @@ export const RedemptionInformation = () => {
<Tranche0Table <Tranche0Table
trancheId={0} trancheId={0}
total={ total={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
trancheBalances.find( trancheBalances.find(
({ id }) => id.toString() === zeroTranche.id.toString() ({ id }) => id.toString() === zeroTranche.id.toString()
)!.locked )!.locked
@ -104,11 +105,13 @@ export const RedemptionInformation = () => {
tranche={tr} tranche={tr}
lien={lien} lien={lien}
locked={ locked={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
trancheBalances.find( trancheBalances.find(
({ id }) => id.toString() === tr.tranche_id.toString() ({ id }) => id.toString() === tr.tranche_id.toString()
)!.locked )!.locked
} }
vested={ vested={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
trancheBalances.find( trancheBalances.find(
({ id }) => id.toString() === tr.tranche_id.toString() ({ id }) => id.toString() === tr.tranche_id.toString()
)!.vested )!.vested

View File

@ -28,9 +28,8 @@ export const AssociatePage = ({
const params = useSearchParams(); const params = useSearchParams();
const [amount, setAmount] = React.useState<string>(''); const [amount, setAmount] = React.useState<string>('');
const [selectedStakingMethod, setSelectedStakingMethod] = React.useState< const [selectedStakingMethod, setSelectedStakingMethod] =
StakingMethod | '' React.useState<StakingMethod | null>(params.method || null);
>('');
// Clear the amount when the staking method changes // Clear the amount when the staking method changes
React.useEffect(() => { React.useEffect(() => {
@ -69,7 +68,7 @@ export const AssociatePage = ({
} else if (!zeroVega && zeroVesting) { } else if (!zeroVega && zeroVesting) {
setSelectedStakingMethod(StakingMethod.Wallet); setSelectedStakingMethod(StakingMethod.Wallet);
} else { } else {
setSelectedStakingMethod(params.method as StakingMethod | ''); setSelectedStakingMethod(params.method);
} }
}, [params.method, zeroVega, zeroVesting]); }, [params.method, zeroVega, zeroVesting]);
if (txState.txState !== TxState.Default) { if (txState.txState !== TxState.Default) {

View File

@ -71,7 +71,7 @@ export const AssociateTransaction = ({
})} })}
</p> </p>
<p> <p>
<EtherscanLink tx={state.txData.hash!} /> <EtherscanLink tx={state.txData.hash || ''} />
</p> </p>
<p data-testid="transaction-pending-footer"> <p data-testid="transaction-pending-footer">
{t('pendingAssociationText', { {t('pendingAssociationText', {

View File

@ -20,7 +20,7 @@ export const useAddStake = (
address: string, address: string,
amount: string, amount: string,
vegaKey: string, vegaKey: string,
stakingMethod: StakingMethod | '', stakingMethod: StakingMethod | null,
confirmations: number confirmations: number
) => { ) => {
const { staking, vesting } = useContracts(); const { staking, vesting } = useContracts();
@ -88,7 +88,7 @@ export const usePollForStakeLinking = (
// Query for linkings under current connected party (vega key) // Query for linkings under current connected party (vega key)
React.useEffect(() => { React.useEffect(() => {
const interval: any = setInterval(() => { const interval = setInterval(() => {
if (!txHash || !partyId) return; if (!txHash || !partyId) return;
client client

View File

@ -1,40 +1,39 @@
import "./disassociate-page.scss"; import './disassociate-page.scss';
import React from "react"; import React from 'react';
import { useTranslation } from "react-i18next"; import { useTranslation } from 'react-i18next';
import { import {
StakingMethod, StakingMethod,
StakingMethodRadio, StakingMethodRadio,
} from "../../../components/staking-method-radio"; } from '../../../components/staking-method-radio';
import { useSearchParams } from "../../../hooks/use-search-params"; import { useSearchParams } from '../../../hooks/use-search-params';
import { ConnectToVega } from "../connect-to-vega"; import { ConnectToVega } from '../connect-to-vega';
import { ContractDisassociate } from "./contract-disassociate"; import { ContractDisassociate } from './contract-disassociate';
export const DisassociatePageNoVega = () => { export const DisassociatePageNoVega = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const params = useSearchParams(); const params = useSearchParams();
const [amount, setAmount] = React.useState<string>(""); const [amount, setAmount] = React.useState<string>('');
const [selectedStakingMethod, setSelectedStakingMethod] = React.useState< const [selectedStakingMethod, setSelectedStakingMethod] =
StakingMethod | "" React.useState<StakingMethod | null>(params.method || null);
>(params.method as StakingMethod | "");
return ( return (
<section className="disassociate-page" data-testid="disassociate-page"> <section className="disassociate-page" data-testid="disassociate-page">
<p> <p>
{t( {t(
"Use this form to disassociate VEGA tokens with a Vega key. This returns them to either the Ethereum wallet that used the Staking bridge or the vesting contract." 'Use this form to disassociate VEGA tokens with a Vega key. This returns them to either the Ethereum wallet that used the Staking bridge or the vesting contract.'
)} )}
</p> </p>
<p> <p>
<span className="disassociate-page__error">{t("Warning")}:</span>{" "} <span className="disassociate-page__error">{t('Warning')}:</span>{' '}
{t( {t(
"Any Tokens that have been nominated to a node will sacrifice any Rewards they are due for the current epoch. If you do not wish to sacrifices fees you should remove stake from a node at the end of an epoch before disassocation." 'Any Tokens that have been nominated to a node will sacrifice any Rewards they are due for the current epoch. If you do not wish to sacrifices fees you should remove stake from a node at the end of an epoch before disassocation.'
)} )}
</p> </p>
<h2>{t("What Vega wallet are you removing Tokens from?")}</h2> <h2>{t('What Vega wallet are you removing Tokens from?')}</h2>
<ConnectToVega /> <ConnectToVega />
<h2>{t("What tokens would you like to return?")}</h2> <h2>{t('What tokens would you like to return?')}</h2>
<StakingMethodRadio <StakingMethodRadio
setSelectedStakingMethod={setSelectedStakingMethod} setSelectedStakingMethod={setSelectedStakingMethod}
selectedStakingMethod={selectedStakingMethod} selectedStakingMethod={selectedStakingMethod}
@ -46,7 +45,7 @@ export const DisassociatePageNoVega = () => {
<ContractDisassociate <ContractDisassociate
setAmount={setAmount} setAmount={setAmount}
amount={amount} amount={amount}
perform={() => {}} perform={() => undefined}
/> />
))} ))}
</section> </section>

View File

@ -26,9 +26,8 @@ export const DisassociatePage = ({
const { t } = useTranslation(); const { t } = useTranslation();
const params = useSearchParams(); const params = useSearchParams();
const [amount, setAmount] = React.useState<string>(''); const [amount, setAmount] = React.useState<string>('');
const [selectedStakingMethod, setSelectedStakingMethod] = React.useState< const [selectedStakingMethod, setSelectedStakingMethod] =
StakingMethod | '' React.useState<StakingMethod | null>(params.method || null);
>(params.method as StakingMethod | '');
// Clear the amount when the staking method changes // Clear the amount when the staking method changes
React.useEffect(() => { React.useEffect(() => {

View File

@ -1,18 +1,18 @@
import BigNumber from "bignumber.js"; import BigNumber from 'bignumber.js';
import React from "react"; import React from 'react';
import { StakingMethod } from "../../../components/staking-method-radio"; import { StakingMethod } from '../../../components/staking-method-radio';
import { useContracts } from "../../../contexts/contracts/contracts-context"; import { useContracts } from '../../../contexts/contracts/contracts-context';
import { TxState } from "../../../hooks/transaction-reducer"; import { TxState } from '../../../hooks/transaction-reducer';
import { useGetAssociationBreakdown } from "../../../hooks/use-get-association-breakdown"; import { useGetAssociationBreakdown } from '../../../hooks/use-get-association-breakdown';
import { useRefreshBalances } from "../../../hooks/use-refresh-balances"; import { useRefreshBalances } from '../../../hooks/use-refresh-balances';
import { useTransaction } from "../../../hooks/use-transaction"; import { useTransaction } from '../../../hooks/use-transaction';
export const useRemoveStake = ( export const useRemoveStake = (
address: string, address: string,
amount: string, amount: string,
vegaKey: string, vegaKey: string,
stakingMethod: StakingMethod | "" stakingMethod: StakingMethod | null
) => { ) => {
const { staking, vesting } = useContracts(); const { staking, vesting } = useContracts();
// Cannot use call on these as they check wallet balance // Cannot use call on these as they check wallet balance

View File

@ -1,9 +1,10 @@
import { render } from "@testing-library/react"; import { render } from '@testing-library/react';
import { ADDRESSES, EthereumChainIds } from "../../config"; import { ADDRESSES, EthereumChainIds } from '../../config';
import { TrancheLabel } from "./tranche-label"; import type { TrancheLabelProps } from './tranche-label';
import { TrancheLabel } from './tranche-label';
let props: any; let props: TrancheLabelProps;
beforeEach(() => { beforeEach(() => {
props = { props = {
@ -13,7 +14,7 @@ beforeEach(() => {
}; };
}); });
it("Renders null for right contract address, wrong network", () => { it('Renders null for right contract address, wrong network', () => {
const WRONG_CHAIN = EthereumChainIds.Goerli; const WRONG_CHAIN = EthereumChainIds.Goerli;
const { container } = render( const { container } = render(
<TrancheLabel {...props} chainId={WRONG_CHAIN} /> <TrancheLabel {...props} chainId={WRONG_CHAIN} />
@ -22,8 +23,8 @@ it("Renders null for right contract address, wrong network", () => {
expect(container).toBeEmptyDOMElement(); expect(container).toBeEmptyDOMElement();
}); });
it("Renders null for right network, wrong contract address", () => { it('Renders null for right network, wrong contract address', () => {
const WRONG_ADDRESS = "0x0"; const WRONG_ADDRESS = '0x0';
const { container } = render( const { container } = render(
<TrancheLabel {...props} contract={WRONG_ADDRESS} /> <TrancheLabel {...props} contract={WRONG_ADDRESS} />
@ -32,7 +33,7 @@ it("Renders null for right network, wrong contract address", () => {
expect(container).toBeEmptyDOMElement(); expect(container).toBeEmptyDOMElement();
}); });
it("Renders null for right network, right contract address, tranche without a name", () => { it('Renders null for right network, right contract address, tranche without a name', () => {
const UNNAMED_TRANCHE = 0; const UNNAMED_TRANCHE = 0;
const { container } = render( const { container } = render(
@ -42,7 +43,7 @@ it("Renders null for right network, right contract address, tranche without a na
expect(container).toBeEmptyDOMElement(); expect(container).toBeEmptyDOMElement();
}); });
it("Renders named for right network, right contract address, tranche with a name", () => { it('Renders named for right network, right contract address, tranche with a name', () => {
const { container } = render(<TrancheLabel {...props} />); const { container } = render(<TrancheLabel {...props} />);
expect(container).toHaveTextContent("Coinlist Option 1Community Whitelist"); expect(container).toHaveTextContent('Coinlist Option 1Community Whitelist');
}); });

View File

@ -11,6 +11,12 @@ const TRANCHE_LABELS: Record<number, string[]> = {
'16': ['Coinlist Option 2', 'Coinlist wallets'], '16': ['Coinlist Option 2', 'Coinlist wallets'],
}; };
export interface TrancheLabelProps {
chainId: EthereumChainId | null;
contract: string;
id: number;
}
/** /**
* Some tranches have names that will be useful to * Some tranches have names that will be useful to
* users trying to identify where their tokens are. * users trying to identify where their tokens are.
@ -21,15 +27,7 @@ const TRANCHE_LABELS: Record<number, string[]> = {
* @param chainId The ID of the chain this contract is on * @param chainId The ID of the chain this contract is on
* @param id The tranche ID on this contract * @param id The tranche ID on this contract
*/ */
export const TrancheLabel = ({ export const TrancheLabel = ({ contract, chainId, id }: TrancheLabelProps) => {
contract,
chainId,
id,
}: {
chainId: EthereumChainId | null;
contract: string;
id: number;
}) => {
// Only mainnet tranches on the known vesting contract have useful name // Only mainnet tranches on the known vesting contract have useful name
if ( if (
chainId && chainId &&

View File

@ -23,7 +23,7 @@ export const Tranche = () => {
const { trancheId } = useParams<{ trancheId: string }>(); const { trancheId } = useParams<{ trancheId: string }>();
const { chainId } = useWeb3React(); const { chainId } = useWeb3React();
const tranche = tranches.find( const tranche = tranches.find(
(tranche) => tranche.tranche_id === parseInt(trancheId!) (tranche) => trancheId && parseInt(trancheId) === tranche.tranche_id
); );
const lockedData = React.useMemo(() => { const lockedData = React.useMemo(() => {

View File

@ -1,6 +1,6 @@
import { format, startOfMonth } from "date-fns"; import { format, startOfMonth } from 'date-fns';
import React from "react"; import React from 'react';
import { useTranslation } from "react-i18next"; import { useTranslation } from 'react-i18next';
import { import {
Area, Area,
AreaChart, AreaChart,
@ -11,13 +11,13 @@ import {
Tooltip, Tooltip,
XAxis, XAxis,
YAxis, YAxis,
} from "recharts"; } from 'recharts';
import { Colors } from "../../config"; import { Colors } from '../../config';
import { DATE_FORMAT_LONG } from "../../lib/date-formats"; import { DATE_FORMAT_LONG } from '../../lib/date-formats';
import data from "./data.json"; import data from './data.json';
const ORDER = ["community", "publicSale", "earlyInvestors", "team"]; const ORDER = ['community', 'publicSale', 'earlyInvestors', 'team'];
export const VestingChart = () => { export const VestingChart = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -31,10 +31,10 @@ export const VestingChart = () => {
<AreaChart data={data}> <AreaChart data={data}>
<defs> <defs>
{[ {[
["pink", Colors.PINK], ['pink', Colors.PINK],
["green", Colors.VEGA_GREEN], ['green', Colors.VEGA_GREEN],
["orange", Colors.VEGA_ORANGE], ['orange', Colors.VEGA_ORANGE],
["yellow", Colors.VEGA_YELLOW], ['yellow', Colors.VEGA_YELLOW],
].map(([key, color]) => ( ].map(([key, color]) => (
<linearGradient id={key} x1="0" y1="0" x2="0" y2="1"> <linearGradient id={key} x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor={color} stopOpacity={0.85} /> <stop offset="0%" stopColor={color} stopOpacity={0.85} />
@ -45,18 +45,19 @@ export const VestingChart = () => {
<Tooltip <Tooltip
contentStyle={{ backgroundColor: Colors.BLACK }} contentStyle={{ backgroundColor: Colors.BLACK }}
separator=":" separator=":"
formatter={(value: any) => { formatter={(value: number) => {
return ( return (
<div <div
style={{ style={{
display: "flex", display: 'flex',
textAlign: "right", textAlign: 'right',
}} }}
> >
{Intl.NumberFormat().format(value)} {Intl.NumberFormat().format(value)}
</div> </div>
); );
}} }}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
itemSorter={(label: any) => { itemSorter={(label: any) => {
return ORDER.indexOf(label.dataKey) + 1; return ORDER.indexOf(label.dataKey) + 1;
}} }}
@ -64,7 +65,7 @@ export const VestingChart = () => {
<YAxis type="number" width={100}> <YAxis type="number" width={100}>
<Label <Label
angle={270} angle={270}
value={t("VEGA").toString()} value={t('VEGA').toString()}
position="left" position="left"
offset={-5} offset={-5}
fill={Colors.WHITE} fill={Colors.WHITE}
@ -72,7 +73,7 @@ export const VestingChart = () => {
</YAxis> </YAxis>
<XAxis dataKey="date"> <XAxis dataKey="date">
<Label <Label
value={t("date").toString()} value={t('date').toString()}
position="bottom" position="bottom"
offset={5} offset={5}
fill={Colors.WHITE} fill={Colors.WHITE}
@ -83,7 +84,7 @@ export const VestingChart = () => {
stroke={Colors.WHITE} stroke={Colors.WHITE}
strokeWidth={2} strokeWidth={2}
label={{ label={{
position: "right", position: 'right',
value: currentDate, value: currentDate,
fill: Colors.WHITE, fill: Colors.WHITE,
}} }}
@ -98,7 +99,7 @@ export const VestingChart = () => {
strokeWidth={2} strokeWidth={2}
fillOpacity={0.85} fillOpacity={0.85}
stackId="1" stackId="1"
name={t("Team")} name={t('Team')}
/> />
<Area <Area
dot={false} dot={false}
@ -110,7 +111,7 @@ export const VestingChart = () => {
strokeWidth={2} strokeWidth={2}
fillOpacity={0.85} fillOpacity={0.85}
stackId="1" stackId="1"
name={t("Early Investors")} name={t('Early Investors')}
/> />
<Area <Area
dot={false} dot={false}
@ -122,7 +123,7 @@ export const VestingChart = () => {
strokeWidth={2} strokeWidth={2}
stackId="1" stackId="1"
fillOpacity={0.85} fillOpacity={0.85}
name={t("Public Sale")} name={t('Public Sale')}
/> />
<Area <Area
dot={false} dot={false}
@ -134,9 +135,9 @@ export const VestingChart = () => {
strokeWidth={2} strokeWidth={2}
fillOpacity={0.85} fillOpacity={0.85}
stackId="1" stackId="1"
name={t("Community")} name={t('Community')}
/> />
<Legend wrapperStyle={{ position: "relative" }} /> <Legend wrapperStyle={{ position: 'relative' }} />
</AreaChart> </AreaChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>

View File

@ -1,9 +1,6 @@
import merge from 'lodash/merge'; import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest'; import type { PartialDeep } from 'type-fest';
import type { import type { Candles, Candles_market_candles } from '@vegaprotocol/chart';
Candles,
Candles_market_candles,
} from '../lib/__generated__/Candles';
export const generateCandles = (override?: PartialDeep<Candles>): Candles => { export const generateCandles = (override?: PartialDeep<Candles>): Candles => {
const candles: Candles_market_candles[] = [ const candles: Candles_market_candles[] = [

View File

@ -3,7 +3,7 @@ import type { PartialDeep } from 'type-fest';
import type { import type {
Chart, Chart,
Chart_market_data_priceMonitoringBounds, Chart_market_data_priceMonitoringBounds,
} from '../lib/__generated__/Chart'; } from '@vegaprotocol/chart';
export const generateChart = (override?: PartialDeep<Chart>): Chart => { export const generateChart = (override?: PartialDeep<Chart>): Chart => {
const priceMonitoringBound: Chart_market_data_priceMonitoringBounds = { const priceMonitoringBound: Chart_market_data_priceMonitoringBounds = {

View File

@ -1,7 +1,7 @@
import { MarketState, MarketTradingMode } from '@vegaprotocol/types'; import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
import merge from 'lodash/merge'; import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest'; import type { PartialDeep } from 'type-fest';
import type { DealTicketQuery } from '../__generated__/DealTicketQuery'; import type { DealTicketQuery } from '@vegaprotocol/deal-ticket';
export const generateDealTicketQuery = ( export const generateDealTicketQuery = (
override?: PartialDeep<DealTicketQuery> override?: PartialDeep<DealTicketQuery>

View File

@ -1,6 +1,15 @@
import merge from 'lodash/merge'; import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest'; import type { PartialDeep } from 'type-fest';
import type { Market } from '../__generated__/Market';
export interface Market_market {
__typename: 'Market';
id: string;
name: string;
}
export interface Market {
market: Market_market | null;
}
export const generateMarket = (override?: PartialDeep<Market>): Market => { export const generateMarket = (override?: PartialDeep<Market>): Market => {
const defaultResult = { const defaultResult = {

View File

@ -1,7 +1,7 @@
import merge from 'lodash/merge'; import merge from 'lodash/merge';
import { MarketState, MarketTradingMode } from '@vegaprotocol/types'; import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest'; import type { PartialDeep } from 'type-fest';
import type { Markets, Markets_markets } from '../lib/__generated__/Markets'; import type { Markets, Markets_markets } from '@vegaprotocol/market-list';
export const generateMarkets = (override?: PartialDeep<Markets>): Markets => { export const generateMarkets = (override?: PartialDeep<Markets>): Markets => {
const markets: Markets_markets[] = [ const markets: Markets_markets[] = [

View File

@ -1,6 +1,6 @@
import merge from 'lodash/merge'; import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest'; import type { PartialDeep } from 'type-fest';
import type { Trades, Trades_market_trades } from '../lib/__generated__/Trades'; import type { Trades, Trades_market_trades } from '@vegaprotocol/trades';
export const generateTrades = (override?: PartialDeep<Trades>): Trades => { export const generateTrades = (override?: PartialDeep<Trades>): Trades => {
const trades: Trades_market_trades[] = [ const trades: Trades_market_trades[] = [

View File

@ -2,7 +2,7 @@ import { And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
import { hasOperationName } from '..'; import { hasOperationName } from '..';
import MarketsPage from '../pages/markets-page'; import MarketsPage from '../pages/markets-page';
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import { generateMarkets } from '../../../../../libs/market-list/src/__tests__/generate-markets'; import { generateMarkets } from '../mocks/generate-markets';
const marketsPage = new MarketsPage(); const marketsPage = new MarketsPage();

View File

@ -1,16 +1,13 @@
import { Given, Then } from 'cypress-cucumber-preprocessor/steps'; import { Given, Then } from 'cypress-cucumber-preprocessor/steps';
import { hasOperationName } from '..'; import { hasOperationName } from '..';
import { MarketState } from '@vegaprotocol/types'; import { MarketState } from '@vegaprotocol/types';
/* eslint-disable @nrwl/nx/enforce-module-boundaries */
import { generateTrades } from '../../../../../libs/trades/src/__tests__';
import {
generateChart,
generateCandles,
} from '../../../../../libs/chart/src/__tests__';
import { generateDealTicketQuery } from '../../../../../libs/deal-ticket/src/__tests__';
import { generateMarket } from '../../../../trading/pages/markets/__tests__';
import TradesList from '../trading-windows/trades-list'; import TradesList from '../trading-windows/trades-list';
import TradingPage from '../pages/trading-page'; import TradingPage from '../pages/trading-page';
import { generateChart } from '../mocks/generate-chart';
import { generateCandles } from '../mocks/generate-candles';
import { generateTrades } from '../mocks/generate-trades';
import { generateDealTicketQuery } from '../mocks/generate-deal-ticket-query';
import { generateMarket } from '../mocks/generate-market';
const tradesList = new TradesList(); const tradesList = new TradesList();
const tradingPage = new TradingPage(); const tradingPage = new TradingPage();

View File

@ -24,7 +24,7 @@ When('I connect to Vega Wallet', () => {
vegaWallet.openVegaWalletConnectDialog(); vegaWallet.openVegaWalletConnectDialog();
vegaWallet.fillInWalletForm( vegaWallet.fillInWalletForm(
'UI_Trading_Test', 'UI_Trading_Test',
Cypress.env('tradingWalletPassphrase') Cypress.env('TRADING_TEST_VEGA_WALLET_PASSPHRASE')
); );
vegaWallet.clickConnectVegaWallet(); vegaWallet.clickConnectVegaWallet();
}); });

View File

@ -1,6 +1,7 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"jsx": "preserve",
"sourceMap": false, "sourceMap": false,
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"allowJs": true, "allowJs": true,

View File

@ -2,15 +2,16 @@ import { fireEvent, render, screen } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing'; import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing';
import { NETWORK_PARAMS_QUERY, Web3Container } from './web3-container'; import { NETWORK_PARAMS_QUERY, Web3Container } from './web3-container';
import type { NetworkParametersQuery } from '@vegaprotocol/graphql'; import type { NetworkParamsQuery } from './__generated__/NetworkParamsQuery';
import type { useWeb3React } from '@web3-react/core';
const defaultHookValue = { const defaultHookValue = {
isActive: false, isActive: false,
error: undefined, error: undefined,
connector: null, connector: null,
chainId: 3, chainId: 3,
}; } as unknown as ReturnType<typeof useWeb3React>;
let mockHookValue; let mockHookValue: ReturnType<typeof useWeb3React>;
const mockEthereumConfig = { const mockEthereumConfig = {
network_id: '3', network_id: '3',
@ -21,7 +22,7 @@ const mockEthereumConfig = {
}, },
}; };
const networkParamsQueryMock: MockedResponse<NetworkParametersQuery> = { const networkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
request: { request: {
query: NETWORK_PARAMS_QUERY, query: NETWORK_PARAMS_QUERY,
}, },
@ -117,7 +118,7 @@ test('Passes ethereum config to children', async () => {
}); });
test('Shows no config found message if the network parameter doesnt exist', async () => { test('Shows no config found message if the network parameter doesnt exist', async () => {
const mock: MockedResponse<NetworkParametersQuery> = { const mock: MockedResponse<NetworkParamsQuery> = {
request: { request: {
query: NETWORK_PARAMS_QUERY, query: NETWORK_PARAMS_QUERY,
}, },
@ -141,7 +142,7 @@ test('Shows no config found message if the network parameter doesnt exist', asyn
}); });
test('Shows message if ethereum config could not be parsed', async () => { test('Shows message if ethereum config could not be parsed', async () => {
const mock: MockedResponse<NetworkParametersQuery> = { const mock: MockedResponse<NetworkParamsQuery> = {
request: { request: {
query: NETWORK_PARAMS_QUERY, query: NETWORK_PARAMS_QUERY,
}, },

View File

@ -1 +0,0 @@
export * from './generate-market';

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"], "types": ["jest", "node", "@testing-library/jest-dom"],
"jsx": "react" "jsx": "react"
}, },
"include": [ "include": [

View File

@ -1,2 +0,0 @@
export * from './generate-candles';
export * from './generate-chart';

View File

@ -1 +1,5 @@
export * from './lib/trading-chart'; export * from './lib/trading-chart';
export * from './lib/__generated__/Candles';
export * from './lib/__generated__/CandleFields';
export * from './lib/__generated__/CandlesSub';
export * from './lib/__generated__/Chart';

View File

@ -15,7 +15,7 @@ export function addSlackCommand() {
cy.log('NOTIFYING SLACK'); cy.log('NOTIFYING SLACK');
const webhook = Cypress.env('slackWebhook'); const webhook = Cypress.env('SLACK_WEBHOOK');
if (!webhook) { if (!webhook) {
return; return;

View File

@ -6,4 +6,5 @@ module.exports = {
}, },
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/deal-ticket', coverageDirectory: '../../coverage/libs/deal-ticket',
setupFilesAfterEnv: ['./src/setup-tests.ts'],
}; };

View File

@ -1 +0,0 @@
export * from './generate-deal-ticket-query';

View File

@ -1,4 +1,3 @@
import '@testing-library/jest-dom';
import { import {
VegaWalletContext, VegaWalletContext,
OrderTimeInForce, OrderTimeInForce,

View File

@ -1,3 +1,5 @@
export * from './deal-ticket'; export * from './deal-ticket';
export * from './use-order-state'; export * from './use-order-state';
export * from './deal-ticket-container'; export * from './deal-ticket-container';
export * from './__generated__/DealTicketQuery';
export * from './__generated__/OrderEvent';

View File

@ -0,0 +1 @@
import '@testing-library/jest-dom';

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-library/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-library/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

View File

@ -1,2 +1,5 @@
export * from './lib/market-list-table'; export * from './lib/market-list-table';
export * from './lib/markets-container'; export * from './lib/markets-container';
export * from './lib/__generated__/Markets';
export * from './lib/__generated__/MarketDataFields';
export * from './lib/__generated__/MarketDataSub';

View File

@ -1,53 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: DepositPage
// ====================================================
export interface DepositPage_assets_source_BuiltinAsset {
__typename: "BuiltinAsset";
}
export interface DepositPage_assets_source_ERC20 {
__typename: "ERC20";
/**
* The address of the erc20 contract
*/
contractAddress: string;
}
export type DepositPage_assets_source = DepositPage_assets_source_BuiltinAsset | DepositPage_assets_source_ERC20;
export interface DepositPage_assets {
__typename: "Asset";
/**
* The id of the asset
*/
id: string;
/**
* The symbol of the asset (e.g: GBP)
*/
symbol: string;
/**
* The full name of the asset (e.g: Great British Pound)
*/
name: string;
/**
* The precision of the asset
*/
decimals: number;
/**
* The origin source of the asset (e.g: an erc20 asset)
*/
source: DepositPage_assets_source;
}
export interface DepositPage {
/**
* The list of all assets in use in the vega network
*/
assets: DepositPage_assets[] | null;
}

View File

@ -1,63 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
import { BusEventType, DepositStatus } from "./globalTypes";
// ====================================================
// GraphQL subscription operation: DepositEvent
// ====================================================
export interface DepositEvent_busEvents_event_TimeUpdate {
__typename: "TimeUpdate" | "MarketEvent" | "TransferResponses" | "PositionResolution" | "Order" | "Trade" | "Account" | "Party" | "MarginLevels" | "Proposal" | "Vote" | "MarketData" | "NodeSignature" | "LossSocialization" | "SettlePosition" | "Market" | "Asset" | "MarketTick" | "SettleDistressed" | "AuctionEvent" | "RiskFactor" | "Withdrawal" | "OracleSpec" | "LiquidityProvision";
}
export interface DepositEvent_busEvents_event_Deposit {
__typename: "Deposit";
/**
* The Vega internal id of the deposit
*/
id: string;
/**
* Hash of the transaction on the foreign chain
*/
txHash: string | null;
/**
* The current status of the deposit
*/
status: DepositStatus;
}
export type DepositEvent_busEvents_event = DepositEvent_busEvents_event_TimeUpdate | DepositEvent_busEvents_event_Deposit;
export interface DepositEvent_busEvents {
__typename: "BusEvent";
/**
* the id for this event
*/
eventId: string;
/**
* the block hash
*/
block: string;
/**
* the type of event we're dealing with
*/
type: BusEventType;
/**
* the payload - the wrapped event
*/
event: DepositEvent_busEvents_event;
}
export interface DepositEvent {
/**
* Subscribe to event data from the event bus
*/
busEvents: DepositEvent_busEvents[] | null;
}
export interface DepositEventVariables {
partyId: string;
}

View File

@ -1,53 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: DepositPage
// ====================================================
export interface DepositPage_assets_source_BuiltinAsset {
__typename: "BuiltinAsset";
}
export interface DepositPage_assets_source_ERC20 {
__typename: "ERC20";
/**
* The address of the erc20 contract
*/
contractAddress: string;
}
export type DepositPage_assets_source = DepositPage_assets_source_BuiltinAsset | DepositPage_assets_source_ERC20;
export interface DepositPage_assets {
__typename: "Asset";
/**
* The id of the asset
*/
id: string;
/**
* The symbol of the asset (e.g: GBP)
*/
symbol: string;
/**
* The full name of the asset (e.g: Great British Pound)
*/
name: string;
/**
* The precision of the asset
*/
decimals: number;
/**
* The origin source of the asset (e.g: an erc20 asset)
*/
source: DepositPage_assets_source;
}
export interface DepositPage {
/**
* The list of all assets in use in the vega network
*/
assets: DepositPage_assets[] | null;
}

View File

@ -1,27 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: NetworkParamsQuery
// ====================================================
export interface NetworkParamsQuery_networkParameters {
__typename: "NetworkParameter";
/**
* The name of the network parameter
*/
key: string;
/**
* The value of the network parameter
*/
value: string;
}
export interface NetworkParamsQuery {
/**
* return the full list of network parameters
*/
networkParameters: NetworkParamsQuery_networkParameters[] | null;
}

View File

@ -26,6 +26,7 @@ export const MarketListTable = forwardRef<AgGridReact, MarketListTableProps>(
flex: 1, flex: 1,
resizable: true, resizable: true,
}} }}
suppressCellFocus={true}
onRowClicked={({ data }: { data: Markets_markets }) => onRowClicked={({ data }: { data: Markets_markets }) =>
onRowClicked(data.id) onRowClicked(data.id)
} }

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-library/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

View File

@ -1 +0,0 @@
export * from './generate-trades';

View File

@ -1 +1,4 @@
export * from './lib/trades-container'; export * from './lib/trades-container';
export * from './lib/__generated__/TradeFields';
export * from './lib/__generated__/Trades';
export * from './lib/__generated__/TradesSub';

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-library/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-libary/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

View File

@ -1,4 +1,3 @@
import '@testing-library/jest-dom';
import { import {
act, act,
fireEvent, fireEvent,

View File

@ -1,4 +1,3 @@
import '@testing-library/jest-dom';
import { act, fireEvent, render, screen } from '@testing-library/react'; import { act, fireEvent, render, screen } from '@testing-library/react';
import type { VegaKey } from '@vegaprotocol/vegawallet-service-api-client'; import type { VegaKey } from '@vegaprotocol/vegawallet-service-api-client';
import { RestConnector } from './connectors'; import { RestConnector } from './connectors';

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-library/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

View File

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../../dist/out-tsc", "outDir": "../../dist/out-tsc",
"module": "commonjs", "module": "commonjs",
"types": ["jest", "node"] "types": ["jest", "node", "@testing-library/jest-dom"]
}, },
"include": [ "include": [
"**/*.test.ts", "**/*.test.ts",

28
migrations.json Normal file
View File

@ -0,0 +1,28 @@
{
"migrations": [
{
"version": "13.9.0-beta.0",
"description": "Replace @nrwl/tao with nx",
"cli": "nx",
"implementation": "./src/migrations/update-13-9-0/replace-tao-with-nx",
"package": "@nrwl/workspace",
"name": "13-9-0-replace-tao-with-nx"
},
{
"version": "13.10.0-beta.0",
"description": "Update the decorate-angular-cli script to require nx instead of @nrwl/cli",
"cli": "nx",
"implementation": "./src/migrations/update-13-10-0/update-decorate-cli",
"package": "@nrwl/workspace",
"name": "13-10-0-update-decorate-cli"
},
{
"version": "13.10.0-beta.0",
"description": "Update the tasks runner property to import it from the nx package instead of @nrwl/worksapce",
"cli": "nx",
"implementation": "./src/migrations/update-13-10-0/update-tasks-runner",
"package": "@nrwl/workspace",
"name": "13-10-0-update-tasks-runner"
}
]
}

View File

@ -17,7 +17,7 @@
"@blueprintjs/core": "^3.47.0", "@blueprintjs/core": "^3.47.0",
"@blueprintjs/icons": "^3.32.0", "@blueprintjs/icons": "^3.32.0",
"@blueprintjs/select": "^3.16.6", "@blueprintjs/select": "^3.16.6",
"@nrwl/next": "13.8.1", "@nrwl/next": "13.10.3",
"@radix-ui/react-dialog": "^0.1.5", "@radix-ui/react-dialog": "^0.1.5",
"@radix-ui/react-tabs": "^0.1.5", "@radix-ui/react-tabs": "^0.1.5",
"@radix-ui/react-tooltip": "^0.1.7", "@radix-ui/react-tooltip": "^0.1.7",
@ -49,7 +49,7 @@
"i18next-browser-languagedetector": "^6.1.2", "i18next-browser-languagedetector": "^6.1.2",
"immer": "^9.0.12", "immer": "^9.0.12",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"next": "12.0.7", "next": "^12.0.7",
"nx": "^13.8.3", "nx": "^13.8.3",
"pennant": "0.4.5", "pennant": "0.4.5",
"postcss": "^8.4.6", "postcss": "^8.4.6",
@ -74,17 +74,17 @@
"@apollo/react-testing": "^4.0.0", "@apollo/react-testing": "^4.0.0",
"@babel/core": "7.12.13", "@babel/core": "7.12.13",
"@babel/preset-typescript": "7.12.13", "@babel/preset-typescript": "7.12.13",
"@nrwl/cli": "13.8.1", "@nrwl/cli": "13.10.3",
"@nrwl/cypress": "13.8.1", "@nrwl/cypress": "13.10.3",
"@nrwl/eslint-plugin-nx": "13.8.1", "@nrwl/eslint-plugin-nx": "13.10.3",
"@nrwl/jest": "13.8.1", "@nrwl/jest": "13.10.3",
"@nrwl/linter": "13.8.1", "@nrwl/linter": "13.10.3",
"@nrwl/nx-cloud": "latest", "@nrwl/nx-cloud": "13.3.1",
"@nrwl/react": "^13.8.1", "@nrwl/react": "13.10.3",
"@nrwl/storybook": "^13.8.1", "@nrwl/storybook": "13.10.3",
"@nrwl/tao": "13.8.1", "@nrwl/tao": "13.8.1",
"@nrwl/web": "13.8.1", "@nrwl/web": "13.10.3",
"@nrwl/workspace": "13.8.1", "@nrwl/workspace": "13.10.3",
"@sentry/webpack-plugin": "^1.18.8", "@sentry/webpack-plugin": "^1.18.8",
"@storybook/addon-a11y": "^6.4.19", "@storybook/addon-a11y": "^6.4.19",
"@storybook/addon-essentials": "~6.4.12", "@storybook/addon-essentials": "~6.4.12",
@ -107,14 +107,14 @@
"@types/react-router-dom": "5.3.1", "@types/react-router-dom": "5.3.1",
"@types/react-virtualized-auto-sizer": "^1.0.1", "@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "~5.10.0", "@typescript-eslint/eslint-plugin": "5.18.0",
"@typescript-eslint/parser": "~5.10.0", "@typescript-eslint/parser": "5.18.0",
"babel-jest": "27.2.3", "babel-jest": "27.2.3",
"babel-loader": "8.1.0", "babel-loader": "8.1.0",
"cypress": "^9.5.4", "cypress": "^9.5.4",
"cypress-cucumber-preprocessor": "^4.3.1", "cypress-cucumber-preprocessor": "^4.3.1",
"eslint": "~8.7.0", "eslint": "8.12.0",
"eslint-config-next": "12.0.7", "eslint-config-next": "12.1.2",
"eslint-config-prettier": "8.1.0", "eslint-config-prettier": "8.1.0",
"eslint-plugin-cypress": "^2.10.3", "eslint-plugin-cypress": "^2.10.3",
"eslint-plugin-import": "2.25.2", "eslint-plugin-import": "2.25.2",
@ -130,7 +130,7 @@
"prettier": "^2.5.1", "prettier": "^2.5.1",
"react-test-renderer": "17.0.2", "react-test-renderer": "17.0.2",
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"sass": "^1.49.11", "sass": "1.49.9",
"storybook-addon-themes": "^6.1.0", "storybook-addon-themes": "^6.1.0",
"ts-jest": "27.0.5", "ts-jest": "27.0.5",
"type-fest": "^2.12.2", "type-fest": "^2.12.2",

892
yarn.lock

File diff suppressed because it is too large Load Diff