Compare commits

..
Author SHA1 Message Date
Matthew Russell aea238a506 chore: change market so no settlement asset available for colalteral deposit 2023-05-01 15:14:06 -07:00
Matthew Russell 0fc772b1d3 fix: home tests as now first market will have id market-0 2023-05-01 06:53:08 -07:00
Matthew Russell ca071dd432 chore: increase github action timeout 2023-05-01 06:53:08 -07:00
Matthew Russell 7e44a293a2 test: add additional mock for asset query that is now called on dialog open 2023-05-01 06:53:08 -07:00
Matthew Russell 1f1c4ced0b chore: update test helpers with additional fields 2023-05-01 06:53:08 -07:00
Matthew Russell e09a1d8ff8 test: update unit test to use create funcs and remove old types 2023-05-01 06:53:08 -07:00
Matthew Russell 36eaa1d30a chore: re add footer 2023-05-01 06:53:08 -07:00
Matthew Russell 1142e6816c chore: add async renderer for loading state 2023-05-01 06:53:08 -07:00
Matthew Russell e80e1cf4e4 chore: make test creation easier, switch data provider 2023-05-01 06:53:08 -07:00
Matthew Russell 4dbd984dd5 test: add ac for title attr tooltip 2023-05-01 06:53:08 -07:00
Matthew Russell 42fccbe852 feat: add title attribute to show full date 2023-05-01 06:53:08 -07:00
Matthew Russell 2c11b4966d test: fix change from unknown to hyphen, link up AC 2023-05-01 06:53:08 -07:00
Matthew Russell 927694bc5c chore: update imports in unti tests 2023-05-01 06:53:08 -07:00
Matthew Russell a78ecd2ba9 chore: ignore problematic ts errors 2023-05-01 06:53:08 -07:00
Matthew Russell 67763e9f9d test: move mocks so they are co located with queries 2023-05-01 06:53:08 -07:00
Matthew Russell f7edaeee63 feat: move closed markets query for better types when mocking 2023-05-01 06:53:08 -07:00
Matthew Russell 5fa3569912 test: flesh out closed market tests 2023-05-01 06:53:07 -07:00
Matthew Russell 3e55db8665 test: add initial e2e test 2023-05-01 06:53:07 -07:00
Matthew Russell 324fe76491 feat: flatten table row data 2023-05-01 06:53:07 -07:00
Matthew Russell c4723f5b16 test: split components and add tests for table logic 2023-05-01 06:53:07 -07:00
Matthew Russell caee00da6d test: add unit test for bespoke table cells 2023-05-01 06:53:07 -07:00
Matthew Russell 85b04a9c0d feat: move hook to oracles lib, add unit test for hook 2023-05-01 06:53:07 -07:00
Matthew Russell dc6b640e19 feat: add link components 2023-05-01 06:53:07 -07:00
Matthew Russell 469d49405b feat: add table columns, add oracle query 2023-05-01 06:53:07 -07:00
97 changed files with 619 additions and 1447 deletions
@@ -4,7 +4,7 @@ import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridColumn } from 'ag-grid-react';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type { VegaICellRendererParams } from '@vegaprotocol/datagrid';
import { useRef, useLayoutEffect } from 'react';
import { BREAKPOINT_MD } from '../../config/breakpoints';
@@ -14,6 +14,7 @@ import {
SettlementAssetInfoPanel,
} from '@vegaprotocol/market-info';
import { MarketInfoTable } from '@vegaprotocol/market-info';
import { Link } from 'react-router-dom';
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
if (!market) return null;
@@ -96,19 +97,22 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
),
},
{
title: t('Settlement Oracle'),
title: t('Oracle'),
content: (
<OracleInfoPanel
noBorder={false}
market={market}
type="settlementData"
/>
),
},
{
title: t('Termination Oracle'),
content: (
<OracleInfoPanel noBorder={false} market={market} type="termination" />
<OracleInfoPanel noBorder={false} market={market}>
<Link
className="text-xs hover:underline"
to={`/oracles#${market.tradableInstrument.instrument.product.dataSourceSpecForSettlementData.id}`}
>
{t('View settlement data oracle specification')}
</Link>
<Link
className="text-xs hover:underline"
to={`/oracles#${market.tradableInstrument.instrument.product.dataSourceSpecForTradingTermination.id}`}
>
{t('View termination oracle specification')}
</Link>
</OracleInfoPanel>
),
},
];
@@ -3,7 +3,7 @@ import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridColumn } from 'ag-grid-react';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type {
VegaICellRendererParams,
VegaValueGetterParams,
@@ -3,7 +3,7 @@ import { VoteProgress } from '@vegaprotocol/proposals';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridColumn } from 'ag-grid-react';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type {
VegaICellRendererParams,
VegaValueFormatterParams,
-44
View File
@@ -1,7 +1,3 @@
@import 'ag-grid-community/dist/styles/ag-grid.css';
@import 'ag-grid-community/dist/styles/ag-theme-balham.css';
@import 'ag-grid-community/dist/styles/ag-theme-balham-dark.css';
/* You can add global styles to this file, and also import other style files */
@tailwind base;
@tailwind components;
@@ -15,43 +11,3 @@
.react-markdown-container a:before {
content: '🔗 ';
}
/* AG GRID - Do not edit without updating other global stylesheets for each app */
.vega-ag-grid .ag-root-wrapper {
border: solid 0px;
}
.vega-ag-grid .ag-react-container {
overflow: hidden;
text-overflow: ellipsis;
}
.vega-ag-grid .ag-cell,
.vega-ag-grid .ag-full-width-row .ag-cell-wrapper.ag-row-group {
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
}
/* Light variables */
.ag-theme-balham {
--ag-background-color: theme(colors.white);
--ag-border-color: theme(colors.neutral[300]);
--ag-header-background-color: theme(colors.white);
--ag-odd-row-background-color: theme(colors.white);
--ag-header-column-separator-color: theme(colors.neutral[300]);
--ag-row-border-color: theme(colors.white);
--ag-row-hover-color: theme(colors.neutral[100]);
--ag-font-size: 12px;
}
/* Dark variables */
.ag-theme-balham-dark {
--ag-background-color: theme(colors.black);
--ag-border-color: theme(colors.neutral[700]);
--ag-header-background-color: theme(colors.black);
--ag-odd-row-background-color: theme(colors.black);
--ag-header-column-separator-color: theme(colors.neutral[600]);
--ag-row-border-color: theme(colors.black);
--ag-row-hover-color: theme(colors.neutral[800]);
--ag-font-size: 12px;
}
@@ -1,39 +0,0 @@
import { render, screen } from '@testing-library/react';
import { DisconnectedNotice } from './disconnected-notice';
describe('DisconnectedNotice', () => {
it('renders Notification when isDisconnected is true and correctNetworkChainId is valid', () => {
render(
<DisconnectedNotice isDisconnected={true} correctNetworkChainId={'1'} />
);
const disconnectedNotice = screen.getByTestId('disconnected-notice');
expect(disconnectedNotice).toBeInTheDocument();
});
it("doesn't render Notification when isDisconnected is false", () => {
render(
<DisconnectedNotice isDisconnected={false} correctNetworkChainId={'1'} />
);
const disconnectedNotice = screen.queryByTestId('disconnected-notice');
expect(disconnectedNotice).not.toBeInTheDocument();
});
it("doesn't render Notification when correctNetworkChainId is undefined", () => {
render(
<DisconnectedNotice
isDisconnected={true}
correctNetworkChainId={undefined}
/>
);
const disconnectedNotice = screen.queryByTestId('disconnected-notice');
expect(disconnectedNotice).not.toBeInTheDocument();
});
it("doesn't render Notification when correctNetworkChainId is null", () => {
render(
<DisconnectedNotice isDisconnected={true} correctNetworkChainId={null} />
);
const disconnectedNotice = screen.queryByTestId('disconnected-notice');
expect(disconnectedNotice).not.toBeInTheDocument();
});
});
@@ -1,33 +0,0 @@
import { useTranslation } from 'react-i18next';
import { Intent, Notification } from '@vegaprotocol/ui-toolkit';
interface DisconnectedNoticeProps {
isDisconnected: boolean;
correctNetworkChainId?: string | null;
}
export const DisconnectedNotice = ({
isDisconnected,
correctNetworkChainId,
}: DisconnectedNoticeProps) => {
const { t } = useTranslation();
if (
!isDisconnected ||
correctNetworkChainId === undefined ||
correctNetworkChainId === null
) {
return null;
}
return (
<div className="col-span-full" data-testid="disconnected-notice">
<Notification
message={t('disconnectedNotice', {
correctNetwork: correctNetworkChainId,
})}
intent={Intent.Danger}
/>
</div>
);
};
@@ -1 +0,0 @@
export * from './disconnected-notice';
@@ -3,7 +3,6 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { Button } from '@vegaprotocol/ui-toolkit';
import { DisconnectedNotice } from '../disconnected-notice';
import {
AppStateActionType,
@@ -27,8 +26,7 @@ import {
import { Loader } from '@vegaprotocol/ui-toolkit';
import colors from 'tailwindcss/colors';
import { useBalances } from '../../lib/balances/balances-store';
import { useEthereumConfig, useWeb3Disconnect } from '@vegaprotocol/web3';
import { getChainName } from '@vegaprotocol/web3';
import { useWeb3Disconnect } from '@vegaprotocol/web3';
const removeLeadingAddressSymbol = (key: string) => {
if (key && key.length > 2 && key.slice(0, 2) === '0x') {
@@ -184,21 +182,16 @@ const ConnectedKey = () => {
export const EthWallet = () => {
const { t } = useTranslation();
const { appDispatch, appState } = useAppState();
const { appDispatch } = useAppState();
const { account, connector } = useWeb3React();
const pendingTxs = usePendingTransactions();
const disconnect = useWeb3Disconnect(connector);
const { config } = useEthereumConfig();
return (
<WalletCard>
<section data-testid="ethereum-wallet">
<WalletCardHeader>
<h1 className="m-0 uppercase">{t('ethereumKey')}</h1>
<DisconnectedNotice
isDisconnected={appState.disconnectNotice}
correctNetworkChainId={getChainName(Number(config?.chain_id))}
/>
{account && (
<div className="place-self-end font-mono">
<div
@@ -1,12 +1,13 @@
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
import {
getChainName,
useWeb3ConnectStore,
useWeb3Disconnect,
Web3ConnectDialog,
} from '@vegaprotocol/web3';
import { useWeb3React } from '@web3-react/core';
import type { ReactElement } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useEffect } from 'react';
import {
AppStateActionType,
useAppState,
@@ -35,7 +36,9 @@ export function Web3Connector({
const appChainId = Number(chainId);
return (
<>
<Web3Content appChainId={appChainId}>{children}</Web3Content>
<Web3Content appChainId={appChainId} setDialogOpen={setDialogOpen}>
{children}
</Web3Content>
<Web3ConnectDialog
connectors={connectors}
dialogOpen={appState.ethConnectOverlay}
@@ -49,59 +52,23 @@ export function Web3Connector({
interface Web3ContentProps {
children: ReactElement;
appChainId: number;
setDialogOpen: (isOpen: boolean) => void;
}
export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
const { appState, appDispatch } = useAppState();
const { connector, chainId } = useWeb3React();
const [previousChainId, setPreviousChainId] = useState(chainId);
const error = useWeb3ConnectStore((store) => store.error);
const disconnect = useWeb3Disconnect(connector);
const showDisconnectNotice = useCallback(
(isVisible: boolean) =>
appDispatch({
type: AppStateActionType.SET_DISCONNECT_NOTICE,
isVisible,
}),
[appDispatch]
);
useEffect(() => {
if (connector?.connectEagerly) {
connector.connectEagerly();
}
// wallet connect doesn't handle connectEagerly being called when connector is also in the
// wallet connect doesnt handle connectEagerly being called when connector is also in the
// deps array.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (chainId !== undefined) {
// We use this to detect when the user switches networks.
setPreviousChainId(chainId);
if (chainId !== appChainId) {
disconnect();
// If the user was previously connected, show the disconnect explanation notice.
if (previousChainId !== undefined && !appState.disconnectNotice) {
showDisconnectNotice(true);
}
} else if (appState.disconnectNotice) {
showDisconnectNotice(false);
}
}
}, [
appChainId,
appDispatch,
appState.disconnectNotice,
chainId,
disconnect,
previousChainId,
showDisconnectNotice,
]);
if (error) {
return (
<Splash>
@@ -113,5 +80,18 @@ export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
);
}
if (chainId !== undefined && chainId !== appChainId) {
return (
<Splash>
<div className="flex flex-col items-center gap-12">
<p className="text-white">
This app only works on {getChainName(appChainId)}
</p>
<Button onClick={() => disconnect()}>Disconnect</Button>
</div>
</Splash>
);
}
return children;
};
@@ -43,11 +43,6 @@ export interface AppState {
* Message to display in a banner at the top of the screen, currently always shown as a warning/error
*/
bannerMessage: string;
/**
* Displays a notice to the user that they have been disconnected because they've changed their
* ethereum network to an incompatible one.
*/
disconnectNotice: boolean;
}
export enum AppStateActionType {
@@ -63,7 +58,6 @@ export enum AppStateActionType {
SET_ASSOCIATION_BREAKDOWN,
SET_TRANSACTION_OVERLAY,
SET_BANNER_MESSAGE,
SET_DISCONNECT_NOTICE,
}
export type AppStateAction =
@@ -96,10 +90,6 @@ export type AppStateAction =
| {
type: AppStateActionType.SET_BANNER_MESSAGE;
message: string;
}
| {
type: AppStateActionType.SET_DISCONNECT_NOTICE;
isVisible: boolean;
};
type AppStateContextShape = {
@@ -1,8 +1,8 @@
import React from 'react';
import { BigNumber } from '../../lib/bignumber';
import type { AppState, AppStateAction } from './app-state-context';
import { AppStateActionType, AppStateContext } from './app-state-context';
import type { AppState, AppStateAction } from './app-state-context';
interface AppStateProviderProps {
children: React.ReactNode;
@@ -19,7 +19,6 @@ const initialAppState: AppState = {
ethConnectOverlay: false,
transactionOverlay: false,
bannerMessage: '',
disconnectNotice: false,
};
function appStateReducer(state: AppState, action: AppStateAction): AppState {
@@ -69,12 +68,6 @@ function appStateReducer(state: AppState, action: AppStateAction): AppState {
bannerMessage: action.message,
};
}
case AppStateActionType.SET_DISCONNECT_NOTICE: {
return {
...state,
disconnectNotice: action.isVisible,
};
}
}
}
@@ -790,6 +790,5 @@
"approval (% validator voting power)": "approval (% validator voting power)",
"67% voting power required": "67% voting power required",
"Token": "Token",
"associateVegaNow": "Associate $VEGA now",
"disconnectedNotice": "You have been disconnected. Connect your ETH wallet to the {{correctNetwork}} network to use this app."
"associateVegaNow": "Associate $VEGA now"
}
@@ -56,7 +56,6 @@ const mockAppState: AppState = {
ethConnectOverlay: false,
transactionOverlay: false,
bannerMessage: '',
disconnectNotice: false,
};
jest.mock('../../../contexts/app-state/app-state-context', () => ({
@@ -19,7 +19,6 @@ const mockAppState: AppState = {
ethConnectOverlay: false,
transactionOverlay: false,
bannerMessage: '',
disconnectNotice: false,
};
jest.mock('../../../contexts/app-state/app-state-context', () => ({
@@ -9,9 +9,6 @@ query ProposalMarketsQuery {
code
}
}
proposal {
state
}
}
}
}
@@ -6,7 +6,7 @@ const defaultOptions = {} as const;
export type ProposalMarketsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ProposalMarketsQueryQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string } }, proposal?: { __typename?: 'Proposal', state: Types.ProposalState } | null } }> } | null };
export type ProposalMarketsQueryQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string } } } }> } | null };
export const ProposalMarketsQueryDocument = gql`
@@ -21,9 +21,6 @@ export const ProposalMarketsQueryDocument = gql`
code
}
}
proposal {
state
}
}
}
}
@@ -0,0 +1,94 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ProposalMarketsQueryQueryVariables = Types.Exact<{
[key: string]: never;
}>;
export type ProposalMarketsQueryQuery = {
__typename?: 'Query';
marketsConnection?: {
__typename?: 'MarketConnection';
edges: Array<{
__typename?: 'MarketEdge';
node: {
__typename?: 'Market';
id: string;
tradableInstrument: {
__typename?: 'TradableInstrument';
instrument: { __typename?: 'Instrument'; name: string; code: string };
};
};
}>;
} | null;
};
export const ProposalMarketsQueryDocument = gql`
query ProposalMarketsQuery {
marketsConnection {
edges {
node {
id
tradableInstrument {
instrument {
name
code
}
}
}
}
}
}
`;
/**
* __useProposalMarketsQueryQuery__
*
* To run a query within a React component, call `useProposalMarketsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useProposalMarketsQueryQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useProposalMarketsQueryQuery({
* variables: {
* },
* });
*/
export function useProposalMarketsQueryQuery(
baseOptions?: Apollo.QueryHookOptions<
ProposalMarketsQueryQuery,
ProposalMarketsQueryQueryVariables
>
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<
ProposalMarketsQueryQuery,
ProposalMarketsQueryQueryVariables
>(ProposalMarketsQueryDocument, options);
}
export function useProposalMarketsQueryLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
ProposalMarketsQueryQuery,
ProposalMarketsQueryQueryVariables
>
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
ProposalMarketsQueryQuery,
ProposalMarketsQueryQueryVariables
>(ProposalMarketsQueryDocument, options);
}
export type ProposalMarketsQueryQueryHookResult = ReturnType<
typeof useProposalMarketsQueryQuery
>;
export type ProposalMarketsQueryLazyQueryHookResult = ReturnType<
typeof useProposalMarketsQueryLazyQuery
>;
export type ProposalMarketsQueryQueryResult = Apollo.QueryResult<
ProposalMarketsQueryQuery,
ProposalMarketsQueryQueryVariables
>;
@@ -1,16 +1,15 @@
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { MemoryRouter as Router } from 'react-router-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { mockWalletContext } from '../../test-helpers/mocks';
import { ProposeUpdateMarket } from './propose-update-market';
import type { NetworkParamsQuery } from '@vegaprotocol/react-helpers';
import { NetworkParamsDocument } from '@vegaprotocol/react-helpers';
import type { ProposalMarketsQueryQuery } from './__generated__/UpdateMarket';
import { ProposalMarketsQueryDocument } from './__generated__/UpdateMarket';
import { ProposalState } from '@vegaprotocol/types';
import type { ProposalMarketsQueryQuery } from './__generated___/UpdateMarket';
import { ProposalMarketsQueryDocument } from './__generated___/UpdateMarket';
const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
request: {
@@ -90,10 +89,6 @@ const marketQueryMock: MockedResponse<ProposalMarketsQueryQuery> = {
code: 'ETHiUSDT',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_ENACTED,
},
},
},
{
@@ -106,16 +101,11 @@ const marketQueryMock: MockedResponse<ProposalMarketsQueryQuery> = {
instrument: {
__typename: 'Instrument',
name: 'Las Vegas nuggets',
code: 'Nuggets',
code: 'Nuggets2',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_OPEN,
},
},
},
{
__typename: 'MarketEdge',
node: {
@@ -125,14 +115,10 @@ const marketQueryMock: MockedResponse<ProposalMarketsQueryQuery> = {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'California Nuggets',
code: 'Nuggets2',
name: 'Nuggets',
code: 'Nuggets',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_WAITING_FOR_NODE_VOTE,
},
},
},
{
@@ -144,71 +130,10 @@ const marketQueryMock: MockedResponse<ProposalMarketsQueryQuery> = {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'Nevada Nuggets',
code: 'Nugetts3',
name: 'CELUSD (June 2022)',
code: 'CELUSD',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_REJECTED,
},
},
},
{
__typename: 'MarketEdge',
node: {
__typename: 'Market',
id: 'asdfe1755208914b6f258a28babd19ae8dfbaf4084d8867d8a120c50dca1e17f',
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'NZ Nuggets',
code: 'Nugetts4',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_DECLINED,
},
},
},
{
__typename: 'MarketEdge',
node: {
__typename: 'Market',
id: 'asdfe1755208914b6f258a28babd19ae8dfbaf4084d8867d8a120c50dca1e17f',
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'Aussie Nuggets',
code: 'Nugetts5',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_PASSED,
},
},
},
{
__typename: 'MarketEdge',
node: {
__typename: 'Market',
id: 'xcvbe1755208914b6f258a28babd19ae8dfbaf4084d8867d8a120c50dca1e17f',
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'Tasmanian Nuggets',
code: 'Nugetts6',
},
},
proposal: {
__typename: 'Proposal',
state: ProposalState.STATE_FAILED,
},
},
},
],
@@ -274,27 +199,6 @@ describe('Propose Update Market', () => {
expect(screen.getByTestId('proposal-market-select')).toHaveValue('');
});
it('should only render enacted markets', async () => {
renderComponent();
expect(
await screen.findByText('Update market proposal')
).toBeInTheDocument();
// (state enacted)
expect(screen.getByText('ETHUSD (September Market)')).toBeInTheDocument();
// (state open)
expect(screen.queryByText('Las Vegas nuggets')).not.toBeInTheDocument();
// (state waiting for node vote)
expect(screen.queryByText('California nuggets')).not.toBeInTheDocument();
// (state rejected)
expect(screen.queryByText('Nevada nuggets')).not.toBeInTheDocument();
// (state declined)
expect(screen.queryByText('NZ nuggets')).not.toBeInTheDocument();
// (state passed)
expect(screen.queryByText('Aussie nuggets')).not.toBeInTheDocument();
// (state failed)
expect(screen.queryByText('Tasmanian nuggets')).not.toBeInTheDocument();
});
it('should render the correct market details when the market select is used', async () => {
renderComponent();
expect(
@@ -2,28 +2,25 @@ import { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import {
doesValueEquateToParam,
getClosingTimestamp,
getEnactmentTimestamp,
useProposalSubmit,
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, validateJson } from '@vegaprotocol/utils';
import { NetworkParams, useNetworkParams } from '@vegaprotocol/react-helpers';
import {
ProposalFormDescription,
ProposalFormDownloadJson,
ProposalFormSubheader,
ProposalFormSubmit,
ProposalFormTerms,
ProposalFormTitle,
ProposalFormTransactionDialog,
ProposalFormDownloadJson,
ProposalFormVoteAndEnactmentDeadline,
} from '../../components/propose';
import {
ProposalMinRequirements,
ProposalUserAction,
} from '../../components/shared';
import { ProposalMinRequirements } from '../../components/shared';
import {
AsyncRenderer,
ExternalLink,
@@ -34,9 +31,9 @@ import {
Select,
} from '@vegaprotocol/ui-toolkit';
import { Heading } from '../../../../components/heading';
import { useProposalMarketsQueryQuery } from './__generated__/UpdateMarket';
import { ProposalUserAction } from '../../components/shared';
import { useProposalMarketsQueryQuery } from './__generated___/UpdateMarket';
import { downloadJson } from '../../../../lib/download-json';
import { ProposalState } from '@vegaprotocol/types';
export interface UpdateMarketProposalFormFields {
proposalVoteDeadline: string;
@@ -76,9 +73,6 @@ export const ProposeUpdateMarket = () => {
return marketsData.marketsConnection.edges
.map((edge) => edge.node)
.filter(
(market) => market.proposal?.state === ProposalState.STATE_ENACTED
)
.sort((a, b) => {
const aName = a.tradableInstrument.instrument.name;
const bName = b.tradableInstrument.instrument.name;
@@ -3,7 +3,7 @@ import { forwardRef, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { Button, Icon } from '@vegaprotocol/ui-toolkit';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import { useAppState } from '../../../../contexts/app-state/app-state-context';
import { BigNumber } from '../../../../lib/bignumber';
import {
@@ -17,6 +17,7 @@ import {
} from '../../shared';
import {
defaultColDef,
NODE_LIST_GRID_STYLES,
PendingStakeRenderer,
stakedTotalPercentage,
StakeShareRenderer,
@@ -381,14 +382,12 @@ export const ConsensusValidatorsTable = ({
);
return (
<div
data-testid="consensus-validators-table"
className="validators-table"
>
<div data-testid="consensus-validators-table">
{nodes.length > 0 && (
<AgGrid
domLayout="autoHeight"
style={{ width: '100%' }}
customThemeParams={NODE_LIST_GRID_STYLES}
getRowHeight={(params: RowHeightParams) => getRowHeight(params)}
defaultColDef={defaultColDef}
tooltipShowDelay={0}
@@ -79,6 +79,17 @@ export interface ValidatorsTableProps {
validatorsView: ValidatorsView;
}
// Custom styling to account for the scrollbar. This is needed because the
// AG Grid places the scrollbar over the bottom validator, which obstructs
export const NODE_LIST_GRID_STYLES = `
.ag-theme-balham-dark .ag-body-horizontal-scroll {
opacity: 0.75;
}
.ag-theme-balham-dark *:hover {
cursor: pointer;
}
`;
export const stakedTotalPercentage = (stakeScore: string) =>
formatNumberPercentage(toBigNum(stakeScore, 0).times(100), 2);
@@ -1,7 +1,7 @@
import { forwardRef, useMemo, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import { useAppState } from '../../../../contexts/app-state/app-state-context';
import { BigNumber } from '../../../../lib/bignumber';
import {
@@ -13,6 +13,7 @@ import {
} from '../../shared';
import {
defaultColDef,
NODE_LIST_GRID_STYLES,
StakeNeededForPromotionRenderer,
stakedTotalPercentage,
ValidatorFields,
@@ -247,13 +248,11 @@ export const StandbyPendingValidatorsTable = ({
);
return (
<div
data-testid="standby-pending-validators-table"
className="validators-table"
>
<div data-testid="standby-pending-validators-table">
<AgGrid
domLayout="autoHeight"
style={{ width: '100%' }}
customThemeParams={NODE_LIST_GRID_STYLES}
rowHeight={68}
defaultColDef={defaultColDef}
tooltipShowDelay={0}
-44
View File
@@ -1,7 +1,3 @@
@import 'ag-grid-community/dist/styles/ag-grid.css';
@import 'ag-grid-community/dist/styles/ag-theme-balham.css';
@import 'ag-grid-community/dist/styles/ag-theme-balham-dark.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -23,43 +19,3 @@
@apply border-vega-dark-200;
}
}
/* AG GRID - Do not edit without updating other global stylesheets for each app */
.vega-ag-grid .ag-root-wrapper {
border: solid 0px;
}
.vega-ag-grid .ag-react-container {
overflow: hidden;
text-overflow: ellipsis;
}
.vega-ag-grid .ag-cell,
.vega-ag-grid .ag-full-width-row .ag-cell-wrapper.ag-row-group {
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
}
/* Light variables */
.ag-theme-balham {
--ag-background-color: theme(colors.white);
--ag-border-color: theme(colors.neutral[300]);
--ag-header-background-color: theme(colors.white);
--ag-odd-row-background-color: theme(colors.white);
--ag-header-column-separator-color: theme(colors.neutral[300]);
--ag-row-border-color: theme(colors.white);
--ag-row-hover-color: theme(colors.neutral[100]);
--ag-font-size: 12px;
}
/* Dark variables */
.ag-theme-balham-dark {
--ag-background-color: theme(colors.black);
--ag-border-color: theme(colors.neutral[700]);
--ag-header-background-color: theme(colors.black);
--ag-odd-row-background-color: theme(colors.black);
--ag-header-column-separator-color: theme(colors.neutral[600]);
--ag-row-border-color: theme(colors.black);
--ag-row-hover-color: theme(colors.neutral[800]);
--ag-font-size: 12px;
}
+26 -60
View File
@@ -38,7 +38,7 @@
"tranche_end": "2023-05-20T00:00:00.000Z",
"total_added": "19242.125",
"total_removed": "959.3245960538025",
"locked_amount": "10740.2904998553229338",
"locked_amount": "11862.280100983795583625",
"deposits": [
{
"amount": "188",
@@ -844,8 +844,8 @@
"tranche_start": "2023-04-06T00:00:00.000Z",
"tranche_end": "2023-05-06T00:00:00.000Z",
"total_added": "14520",
"total_removed": "5079.76864115505",
"locked_amount": "1328.5631944444439712",
"total_removed": "731.78640740205",
"locked_amount": "2175.2102777777776272",
"deposits": [
{
"amount": "111",
@@ -1009,11 +1009,6 @@
"user": "0x6F32AA5A6198329c16e438512F992a0548C856f9",
"tx": "0x29905e6ae54245e824fe9ea488f491b1a3c33f6d8b9345cf2b6b00aec305c5bf"
},
{
"amount": "4347.982233753",
"user": "0x83D7eD53E7CB97b542F1F71f40561d51F8019C8B",
"tx": "0x23b713ac5ee16f744549b0c4d8b49943117d0964ca2b635d9629931ae2f4a961"
},
{
"amount": "5.46866782407",
"user": "0x92A1e98C6f09970e45645Cbe57c6DcaF4547c8FE",
@@ -1071,17 +1066,10 @@
"tx": "0xf0d2927bb8d9363ddefaad3783f9a0abf8e468316c4baea24766991f6cb8cdac"
}
],
"withdrawals": [
{
"amount": "4347.982233753",
"user": "0x83D7eD53E7CB97b542F1F71f40561d51F8019C8B",
"tranche_id": 54,
"tx": "0x23b713ac5ee16f744549b0c4d8b49943117d0964ca2b635d9629931ae2f4a961"
}
],
"withdrawals": [],
"total_tokens": "5010",
"withdrawn_tokens": "4347.982233753",
"remaining_tokens": "662.017766247"
"withdrawn_tokens": "0",
"remaining_tokens": "5010"
},
{
"address": "0x2586bA83696a92b5467Aaa0CF9EEC052F28F2c02",
@@ -4703,7 +4691,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "86666.297",
"total_removed": "0",
"locked_amount": "51226.896539776924515462",
"locked_amount": "51642.2467468320019705714",
"deposits": [
{
"amount": "86666.297",
@@ -4769,7 +4757,7 @@
"tranche_end": "2023-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "394.848424145299",
"locked_amount": "418.87686965811965",
"deposits": [
{
"amount": "2500",
@@ -4802,7 +4790,7 @@
"tranche_end": "2023-11-01T00:00:00.000Z",
"total_added": "15000.000000000000015",
"total_removed": "0",
"locked_amount": "14816.165647644927014816165647644927",
"locked_amount": "14958.769248188406014958769248188406",
"deposits": [
{
"amount": "1.5e-14",
@@ -4890,7 +4878,7 @@
"tranche_end": "2023-09-01T00:00:00.000Z",
"total_added": "17500",
"total_removed": "0",
"locked_amount": "11483.8961541364725",
"locked_amount": "11650.267021437198",
"deposits": [
{
"amount": "12500",
@@ -5157,7 +5145,7 @@
"tranche_end": "2023-08-01T00:00:00.000Z",
"total_added": "37500",
"total_removed": "17836.1796921",
"locked_amount": "18593.57015423572875",
"locked_amount": "18955.98814456722",
"deposits": [
{
"amount": "7500",
@@ -5565,7 +5553,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "51180.15844229965399674",
"locked_amount": "51595.1296945521630417525",
"deposits": [
{
"amount": "129999.45",
@@ -5598,7 +5586,7 @@
"tranche_end": "2024-04-01T00:00:00.000Z",
"total_added": "54144.7663",
"total_removed": "0",
"locked_amount": "49373.06871247784644592557",
"locked_amount": "49631.84975200308971004133",
"deposits": [
{
"amount": "54144.7663",
@@ -5631,7 +5619,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "62600",
"total_removed": "0",
"locked_amount": "21051.60226407915008",
"locked_amount": "21351.614193302888218",
"deposits": [
{
"amount": "10000",
@@ -5824,7 +5812,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "1873.218702435312",
"locked_amount": "1897.1813165905632",
"deposits": [
{
"amount": "5000",
@@ -6882,7 +6870,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "1709370.7872515768348",
"locked_amount": "158090.6912451388393129414",
"locked_amount": "167387.8422968911644940364",
"deposits": [
{
"amount": "1852091.69",
@@ -40754,7 +40742,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "715655.108029600523393",
"locked_amount": "267431.675840398797767447499",
"locked_amount": "281718.160082742394755587753",
"deposits": [
{
"amount": "1998.95815",
@@ -42147,7 +42135,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "866687.25765937723884852",
"locked_amount": "6247983.1374161640607671780970752321127332",
"locked_amount": "6298642.09325955374430918146676915717356045",
"deposits": [
{
"amount": "16249.93",
@@ -48724,8 +48712,8 @@
"tranche_start": "2021-11-05T00:00:00.000Z",
"tranche_end": "2023-05-05T00:00:00.000Z",
"total_added": "14597706.0446472999",
"total_removed": "6168897.174282186485373182",
"locked_amount": "46652.9124232901388230326056764886",
"total_removed": "6167911.210808830654624182",
"locked_amount": "93420.936997419715583180200347021",
"deposits": [
{
"amount": "129284.449",
@@ -48979,11 +48967,6 @@
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x2c531bd9c61e0a3705f161bba2c03703722f1e41533725684fcccb9176117e0e"
},
{
"amount": "985.963473355830749",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x53d67a8df4d069f956ae1eb76d5e099642dcc8d7e40fa9357be0b8ae879b90c4"
},
{
"amount": "1360.32447632896938825",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -52320,12 +52303,6 @@
"tranche_id": 3,
"tx": "0x2c531bd9c61e0a3705f161bba2c03703722f1e41533725684fcccb9176117e0e"
},
{
"amount": "985.963473355830749",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x53d67a8df4d069f956ae1eb76d5e099642dcc8d7e40fa9357be0b8ae879b90c4"
},
{
"amount": "1360.32447632896938825",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -55148,8 +55125,8 @@
}
],
"total_tokens": "359123.469575",
"withdrawn_tokens": "357792.4615146437139805",
"remaining_tokens": "1331.0080603562860195"
"withdrawn_tokens": "356806.4980412878832315",
"remaining_tokens": "2316.9715337121167685"
},
{
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
@@ -56618,7 +56595,7 @@
"tranche_start": "2021-10-05T00:00:00.000Z",
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "5778205.3912159303",
"total_removed": "3480901.398845846498418769",
"total_removed": "3480709.486904665102263769",
"locked_amount": "0",
"deposits": [
{
@@ -56768,11 +56745,6 @@
"user": "0x83b1a48376E045D26420200345414e6b93066396",
"tx": "0xeb193da202cd833a574a524eff7f1dd13a0ee8669e51a7db36984ef4d6735fd6"
},
{
"amount": "191.911941181396155",
"user": "0xBc934494675a6ceB639B9EfEe5b9C0f017D35a75",
"tx": "0xb741f4e653131d11eed34bc9c5f3f8425d23cf054b336f3dc61fbd936b39744a"
},
{
"amount": "219.945520329711288",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
@@ -57795,12 +57767,6 @@
}
],
"withdrawals": [
{
"amount": "191.911941181396155",
"user": "0xBc934494675a6ceB639B9EfEe5b9C0f017D35a75",
"tranche_id": 4,
"tx": "0xb741f4e653131d11eed34bc9c5f3f8425d23cf054b336f3dc61fbd936b39744a"
},
{
"amount": "10509.407528939748325",
"user": "0xBc934494675a6ceB639B9EfEe5b9C0f017D35a75",
@@ -57911,8 +57877,8 @@
}
],
"total_tokens": "110499.5291",
"withdrawn_tokens": "110499.5291",
"remaining_tokens": "0"
"withdrawn_tokens": "110307.617158818603845",
"remaining_tokens": "191.911941181396155"
},
{
"address": "0xdbC5d439F373EB646345e1c67D1d46231ACE7dD3",
@@ -58824,7 +58790,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "44078.8527972103416",
"locked_amount": "42376.077741542987921938344901044",
"locked_amount": "44639.852834767825412159812480992",
"deposits": [
{
"amount": "3000",
@@ -180,21 +180,25 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
it('oracle displayed', () => {
cy.getByTestId(marketTitle).contains('Oracle').click();
validateMarketDataRow(0, 'Settlement Data Property', 'prices.BTC.value');
validateMarketDataRow(
1,
'Trading Termination Property',
'termination.BTC.value'
);
// check that links to github for oracle proofs are shown
cy.getByTestId(accordionContent)
.getByTestId('provider-name')
.and('contain', 'Another oracle');
.getByTestId('oracle-proof-links')
.find(`[data-testid="${externalLink}"]`)
.should('have.attr', 'href')
.and('contain', 'https://github.com/vegaprotocol/well-known');
cy.getByTestId(accordionContent)
.getByTestId('signed-proofs')
.and('contain', '1');
cy.getByTestId(accordionContent)
.getByTestId('verified-proofs')
.and('contain', '1');
cy.getByTestId(accordionContent)
.getByTestId('signed-proofs')
.and('contain', '1');
.getByTestId('oracle-spec-links')
.find(`[data-testid="${externalLink}"]`)
.should('have.attr', 'href')
.and('contain', '/oracles');
});
it('proposal displayed', () => {
@@ -1,7 +1,5 @@
import { checkSorting } from '@vegaprotocol/cypress';
const dialogClose = 'dialog-close';
describe('accounts', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockTradingPage();
@@ -68,44 +66,16 @@ describe('accounts', { tags: '@smoke' }, () => {
it('should open asset details dialog when clicked on symbol', () => {
// 7001-COLL-008
// 6501-ASSE-001
// 6501-ASSE-002
// 6501-ASSE-003
// 6501-ASSE-004
// 6501-ASSE-005
// 6501-ASSE-006
// 6501-ASSE-007
// 6501-ASSE-008
// 6501-ASSE-009
// 6501-ASSE-010
// 6501-ASSE-011
// 6501-ASSE-012
// 6501-ASSE-013
const titles = [
'ID',
'Type',
'Name',
'Symbol',
'Decimals',
'Quantum',
'Status',
'Contract address',
'Withdrawal threshold',
'Lifetime limit',
'Infrastructure fee account balance',
'Global reward pool account balance',
'Maker paid fees account balance',
'Maker received fees account balance',
'Liquidity provision fee reward account balance',
'Market proposer reward account balance',
];
cy.getByTestId('asset').contains('tEURO').click();
cy.get('[data-testid$="_label"]').should('have.length', 16);
cy.get('[data-testid$="_label"]').each((element, index) => {
cy.wrap(element).should('have.text', titles[index]);
});
cy.getByTestId(dialogClose).click();
cy.getByTestId(dialogClose).should('not.exist');
cy.get('[data-testid="dialog-close"]').click();
});
it('should open asset details dialog when clicked on symbol', () => {
// 7001-COLL-008
cy.getByTestId('asset').contains('tEURO').click();
cy.get('[data-testid$="_label"]').should('have.length', 16);
cy.get('[data-testid="dialog-close"]').click();
});
it('should open usage breakdown dialog when clicked on used', () => {
@@ -119,7 +89,7 @@ describe('accounts', { tags: '@smoke' }, () => {
cy.wrap($header).should('have.text', headers[i]);
});
});
cy.getByTestId(dialogClose).click();
cy.get('[data-testid="dialog-close"]').click();
});
it('sorting usage breakdown columns should work well', () => {
@@ -138,7 +108,7 @@ describe('accounts', { tags: '@smoke' }, () => {
.eq(3)
.should('have.text', 'General');
cy.getByTestId(dialogClose).click();
cy.get('[data-testid="dialog-close"]').click();
});
describe('sorting by ag-grid columns should work well', () => {
+17 -28
View File
@@ -27,10 +27,7 @@ import { NO_MARKET } from './constants';
import { LiquidityContainer } from '../liquidity/liquidity';
import { useNavigate } from 'react-router-dom';
import type { PinnedAsset } from '@vegaprotocol/accounts';
import {
usePaneLayout,
useScreenDimensions,
} from '@vegaprotocol/react-helpers';
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
import {
useMarketClickHandler,
useMarketLiquidityClickHandler,
@@ -86,20 +83,15 @@ interface BottomPanelProps {
const MarketBottomPanel = memo(
({ marketId, pinnedAsset }: BottomPanelProps) => {
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'bottom' });
const { screenSize } = useScreenDimensions();
const onMarketClick = useMarketClickHandler(true);
const onOrderTypeClick = useMarketLiquidityClickHandler(true);
return 'xxxl' === screenSize ? (
<ResizableGrid
proportionalLayout
minSize={200}
onChange={handleOnLayoutChange}
>
<ResizableGrid proportionalLayout minSize={200}>
<ResizableGridPanel
priority={LayoutPriority.Low}
preferredSize={sizes[0] || '50%'}
preferredSize="50%"
minSize={50}
>
<TradeGridChild>
@@ -127,7 +119,7 @@ const MarketBottomPanel = memo(
</ResizableGridPanel>
<ResizableGridPanel
priority={LayoutPriority.Low}
preferredSize={sizes[1] || '50%'}
preferredSize="50%"
minSize={50}
>
<TradeGridChild>
@@ -194,29 +186,22 @@ MarketBottomPanel.displayName = 'MarketBottomPanel';
const MainGrid = memo(
({
marketId,
onSelect,
pinnedAsset,
}: {
marketId: string;
onSelect: (marketId: string, metaKey?: boolean) => void;
pinnedAsset?: PinnedAsset;
}) => {
const navigate = useNavigate();
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'top' });
const [sizesMiddle, handleOnMiddleLayoutChange] = usePaneLayout({
id: 'middle',
});
return (
<ResizableGrid vertical onChange={handleOnLayoutChange}>
<ResizableGrid vertical>
<ResizableGridPanel minSize={75} priority={LayoutPriority.High}>
<ResizableGrid
proportionalLayout={false}
minSize={200}
onChange={handleOnMiddleLayoutChange}
>
<ResizableGrid proportionalLayout={false} minSize={200}>
<ResizableGridPanel
priority={LayoutPriority.High}
minSize={200}
preferredSize={sizesMiddle[0] || '50%'}
preferredSize="50%"
>
<TradeGridChild>
<Tabs storageKey="console-trade-grid-main-left">
@@ -234,7 +219,7 @@ const MainGrid = memo(
</ResizableGridPanel>
<ResizableGridPanel
priority={LayoutPriority.Low}
preferredSize={sizesMiddle[1] || 330}
preferredSize={330}
minSize={300}
>
<TradeGridChild>
@@ -253,7 +238,7 @@ const MainGrid = memo(
</ResizableGridPanel>
<ResizableGridPanel
priority={LayoutPriority.Low}
preferredSize={sizesMiddle[2] || 430}
preferredSize={430}
minSize={200}
>
<TradeGridChild>
@@ -271,7 +256,7 @@ const MainGrid = memo(
</ResizableGridPanel>
<ResizableGridPanel
priority={LayoutPriority.Low}
preferredSize={sizes[1] || '25%'}
preferredSize="25%"
minSize={50}
>
<MarketBottomPanel marketId={marketId} pinnedAsset={pinnedAsset} />
@@ -293,7 +278,11 @@ export const TradeGrid = ({
<TradeMarketHeader market={market} onSelect={onSelect} />
<OracleBanner marketId={market?.id || ''} />
</div>
<MainGrid marketId={market?.id || ''} pinnedAsset={pinnedAsset} />
<MainGrid
marketId={market?.id || ''}
onSelect={onSelect}
pinnedAsset={pinnedAsset}
/>
</div>
);
};
+1 -1
View File
@@ -4,7 +4,7 @@ import type {
VegaICellRendererParams,
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import { useMemo } from 'react';
import { t } from '@vegaprotocol/i18n';
import { MarketState, MarketStateMapping } from '@vegaprotocol/types';
@@ -12,9 +12,7 @@ export const Proposed = () => {
const externalLink = tokenLink(TOKEN_NEW_MARKET_PROPOSAL);
return (
<>
<div className="min-h-[200px]">
<ProposalsList />
</div>
<ProposalsList />
<ExternalLink className="py-4 px-[11px] text-sm" href={externalLink}>
{t('Propose a new market')}
</ExternalLink>
@@ -7,7 +7,6 @@ import { WithdrawalsContainer } from './withdrawals-container';
import { FillsContainer } from '@vegaprotocol/fills';
import type { ReactNode } from 'react';
import { useEffect } from 'react';
import { usePaneLayout } from '@vegaprotocol/react-helpers';
import { VegaWalletContainer } from '../../components/vega-wallet-container';
import { DepositsContainer } from './deposits-container';
import { LayoutPriority } from 'allotment';
@@ -35,11 +34,11 @@ export const Portfolio = () => {
const onMarketClick = useMarketClickHandler(true);
const onOrderTypeClick = useMarketLiquidityClickHandler(true);
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'portfolio' });
const wrapperClasses = 'h-full max-h-full flex flex-col';
return (
<div className={wrapperClasses}>
<ResizableGrid vertical onChange={handleOnLayoutChange}>
<ResizableGrid vertical>
<ResizableGridPanel minSize={75}>
<PortfolioGridChild>
<Tabs storageKey="console-portfolio-top">
@@ -79,7 +78,7 @@ export const Portfolio = () => {
</ResizableGridPanel>
<ResizableGridPanel
priority={LayoutPriority.Low}
preferredSize={sizes[1] || 300}
preferredSize={300}
minSize={50}
>
<PortfolioGridChild>
@@ -36,11 +36,7 @@ export const Settings = () => {
/>
</div>
<Divider />
<TelemetryApproval
helpText={t(
'Help identify bugs and improve the service by sharing anonymous usage data.'
)}
/>
<TelemetryApproval isSettingsPage />
</RoundedWrapper>
</div>
</div>
+1 -1
View File
@@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/i18n';
export const THROTTLE_UPDATE_TIME = 500;
export const RISK_ACCEPTED_KEY = 'vega_risk_accepted';
export const RISK_ACCEPTED_KEY = 'vega-risk-accepted';
export const MAINNET_WELCOME_HEADER = t(
'Trade cash settled futures on the fully decentralised Vega network.'
);
@@ -1,6 +1,9 @@
import { BrowserRouter } from 'react-router-dom';
import { render, screen, fireEvent } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
import { RiskNoticeDialog } from './risk-notice-dialog';
import { WelcomeDialog } from './welcome-dialog';
jest.mock('@vegaprotocol/environment');
@@ -11,6 +14,7 @@ const mockEnvDefinitions = {
};
describe('Risk notice dialog', () => {
const introText = 'Regulation may apply to use of this app';
const mockOnClose = jest.fn();
afterEach(() => {
jest.clearAllMocks();
@@ -18,12 +22,13 @@ describe('Risk notice dialog', () => {
it.each`
assertion | network
${'displays'} | ${Networks.MAINNET}
${'displays'} | ${Networks.CUSTOM}
${'displays'} | ${Networks.DEVNET}
${'displays'} | ${Networks.STAGNET3}
${'displays'} | ${Networks.TESTNET}
`(
'$assertion a generic message on $network',
'$assertion the risk notice on $network',
async ({ assertion, network }) => {
// @ts-ignore ignore mock implementation
useEnvironment.mockImplementation(() => ({
@@ -31,37 +36,27 @@ describe('Risk notice dialog', () => {
VEGA_ENV: network,
}));
render(<RiskNoticeDialog onClose={mockOnClose} network={network} />);
render(
<MockedProvider>
<WelcomeDialog />
</MockedProvider>,
{ wrapper: BrowserRouter }
);
expect(
screen.getByText(
new RegExp(
`This application for trading on Vega is connected to ${network}`
)
)
).toBeInTheDocument();
const button = screen.getByRole('button', {
name: 'Continue',
});
fireEvent.click(button);
expect(mockOnClose).toHaveBeenCalled();
expect(screen.queryByText(introText)).toBeInTheDocument();
}
);
it('displays a risk message for mainnet', () => {
const introText = 'Regulation may apply to use of this app';
const network = Networks.MAINNET;
it("doesn't display the risk notice when previously acknowledged", () => {
// @ts-ignore ignore mock implementation
useEnvironment.mockImplementation(() => ({
...mockEnvDefinitions,
VEGA_ENV: network,
VEGA_ENV: Networks.MAINNET,
}));
render(<RiskNoticeDialog onClose={mockOnClose} network={network} />);
render(<RiskNoticeDialog onClose={mockOnClose} />);
expect(screen.getByText(introText)).toBeInTheDocument();
expect(screen.queryByText(introText)).toBeInTheDocument();
const button = screen.getByRole('button', {
name: 'I understand, Continue',
@@ -1,100 +1,25 @@
import { useCallback } from 'react';
import { t } from '@vegaprotocol/i18n';
import {
Button,
Link,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { Button } from '@vegaprotocol/ui-toolkit';
import { LocalStorage } from '@vegaprotocol/utils';
import { RISK_ACCEPTED_KEY } from '../constants';
import { TelemetryApproval } from './telemetry-approval';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
interface Props {
onClose: () => void;
network: Networks;
}
export const RiskNoticeDialog = ({ onClose, network }: Props) => {
const [, setValue] = useLocalStorage(RISK_ACCEPTED_KEY);
const handleAcceptRisk = () => {
export const RiskNoticeDialog = ({ onClose }: Props) => {
const handleAcceptRisk = useCallback(() => {
onClose();
setValue('true');
};
LocalStorage.setItem(RISK_ACCEPTED_KEY, 'true');
}, [onClose]);
return (
<>
{network === Networks.MAINNET ? (
<MainnetContent />
) : (
<TestnetContent network={network} />
)}
<div className="my-4">
<TelemetryApproval
helpText={t(
'Help identify bugs and improve the service by sharing anonymous usage data. You can change this in your settings at any time.'
)}
/>
</div>
<Button onClick={handleAcceptRisk}>
{network === Networks.MAINNET
? t('I understand, Continue')
: t('Continue')}
</Button>
</>
);
};
const TestnetContent = ({ network }: { network: Networks }) => {
const { VEGA_DOCS_URL, GITHUB_FEEDBACK_URL, VEGA_WALLET_URL } =
useEnvironment();
return (
<>
<p className="mb-4">
{t(
'This application for trading on Vega is connected to %s, meaning you are free to try out trading with virtual assets and no risk.',
[network]
)}
</p>
<p className="mb-4">
{t(
'Your Vega wallet must also be connected to %s, and your Ethereum wallet must be connected to Sepolia.',
[network]
)}
</p>
{VEGA_DOCS_URL && GITHUB_FEEDBACK_URL && VEGA_WALLET_URL && (
<ul className="list-disc pl-4">
<li className="mb-1">
<Link href={VEGA_WALLET_URL} target="_blank">
<span className="underline">{t('Learn about Vega wallet')}</span>{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
</Link>
</li>
<li className="mb-1">
<Link href={VEGA_DOCS_URL} target="_blank">
<span className="underline">{t('View documentation')}</span>{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
</Link>
</li>
<li className="mb-1">
<Link href={GITHUB_FEEDBACK_URL} target="_blank">
<span className="underline">{t('Provide feedback')}</span>{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
</Link>
</li>
</ul>
)}
</>
);
};
const MainnetContent = () => {
return (
<>
<h4 className="text-xl mb-2 mt-4">
{t('Regulation may apply to use of this app')}
</h4>
<p className="mb-6">
<p className="text-base mb-6">
{t(
'This decentralised application allows you to connect to and use publicly available blockchain services operated by third parties that may include trading, financial products, or other services that may be subject to legal and regulatory restrictions in your jurisdiction. This application is a front end only and does not hold any funds or provide any products or services. It is available to anyone with an internet connection via IPFS and other methods, and the ability to access it does not imply any right to use any services or that it is legal for you to do so. By using this application you accept that it is your responsibility to ensure that your use of the application and any blockchain services accessed through it is compliant with applicable laws and regulations in your jusrisdiction.'
)}
@@ -102,11 +27,15 @@ const MainnetContent = () => {
<h4 className="text-xl mb-2">
{t('Technical and financial risk of loss')}
</h4>
<p className="mb-8">
<p className="text-base mb-8">
{t(
'The public blockchain services accessible via this decentralised application are operated by third parties and may carry significant risks including the potential loss of all funds that you deposit or hold with these services. Technical risks include the risk of loss in the event of the failure or compromise of the public blockchain infrastructure or smart contracts that provide any services you use. Financial risks include but are not limited to losses due to volatility, excessive leverage, low liquidity, and your own lack of understanding of the services you use. By using this decentralised application you accept that it is your responsibility to ensure that you understand any services you use and the technical and financial risks inherent in your use. Do not risk what you cannot afford to lose.'
)}
</p>
<Button onClick={handleAcceptRisk}>{t('I understand, Continue')}</Button>
<div className="text-base mt-8">
<TelemetryApproval />
</div>
</>
);
};
@@ -3,8 +3,7 @@ import { TelemetryApproval } from './telemetry-approval';
describe('TelemetryApproval', () => {
it('click on checkbox should be properly handled', () => {
const helpText = 'My help text';
render(<TelemetryApproval helpText={helpText} />);
render(<TelemetryApproval />);
expect(screen.getByRole('checkbox')).toHaveAttribute(
'data-state',
'unchecked'
@@ -16,7 +15,5 @@ describe('TelemetryApproval', () => {
'data-state',
'checked'
);
expect(screen.getByText('Share usage data')).toBeInTheDocument();
expect(screen.getByText(helpText)).toBeInTheDocument();
});
});
@@ -2,7 +2,11 @@ import { Checkbox } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
export const TelemetryApproval = ({ helpText }: { helpText: string }) => {
export const TelemetryApproval = ({
isSettingsPage,
}: {
isSettingsPage?: boolean;
}) => {
const [isApproved, setIsApproved] = useTelemetryApproval();
return (
<div className="flex flex-col px-2 py-3">
@@ -15,7 +19,13 @@ export const TelemetryApproval = ({ helpText }: { helpText: string }) => {
/>
</div>
<div className="text-sm text-vega-light-300 dark:text-vega-dark-300 ml-6">
<span>{helpText}</span>
<span>
{t(
'Help identify bugs and improve the service by sharing anonymous usage data.'
)}
{!isSettingsPage &&
' ' + t('You can change this in your settings at any time.')}
</span>
</div>
</div>
);
@@ -9,11 +9,8 @@ import { RiskNoticeDialog } from './risk-notice-dialog';
import { WelcomeNoticeDialog } from './welcome-notice-dialog';
import { WelcomeLandingDialog } from './welcome-landing-dialog';
import { useGlobalStore } from '../../stores';
import { useEnvironment } from '@vegaprotocol/environment';
import { Networks } from '@vegaprotocol/environment';
export const WelcomeDialog = () => {
const { VEGA_ENV } = useEnvironment();
const { pathname } = useLocation();
let dialogContent: React.ReactNode;
let title = '';
@@ -36,10 +33,8 @@ export const WelcomeDialog = () => {
}, [update, isRiskDialogNeeded]);
if (isRiskDialogNeeded) {
dialogContent = (
<RiskNoticeDialog onClose={onCloseDialog} network={VEGA_ENV} />
);
title = VEGA_ENV === Networks.MAINNET ? t('WARNING') : t('Vega Console');
dialogContent = <RiskNoticeDialog onClose={onCloseDialog} />;
title = t('WARNING');
size = 'medium';
} else if (isWelcomeDialogNeeded && data?.length === 0) {
dialogContent = <WelcomeNoticeDialog />;
+1 -46
View File
@@ -1,7 +1,3 @@
@import 'ag-grid-community/dist/styles/ag-grid.css';
@import 'ag-grid-community/dist/styles/ag-theme-balham.css';
@import 'ag-grid-community/dist/styles/ag-theme-balham-dark.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -28,8 +24,7 @@ html.dark {
@apply border-vega-light-200 dark:border-vega-dark-200;
}
/* PENNANT */
/* Styles for charts */
html [data-theme='dark'] {
--pennant-color-danger: theme('colors.vega.pink.DEFAULT');
@@ -76,43 +71,3 @@ html [data-theme='light'] {
--pennant-color-depth-sell-fill: theme('colors.vega.pink.400');
--pennant-color-depth-sell-stroke: theme('colors.vega.pink.550');
}
/* AG GRID - Do not edit without updating other global stylesheets for each app */
.vega-ag-grid .ag-root-wrapper {
border: solid 0px;
}
.vega-ag-grid .ag-react-container {
overflow: hidden;
text-overflow: ellipsis;
}
.vega-ag-grid .ag-cell,
.vega-ag-grid .ag-full-width-row .ag-cell-wrapper.ag-row-group {
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
}
/* Light variables */
.ag-theme-balham {
--ag-background-color: theme(colors.white);
--ag-border-color: theme(colors.neutral[300]);
--ag-header-background-color: theme(colors.white);
--ag-odd-row-background-color: theme(colors.white);
--ag-header-column-separator-color: theme(colors.neutral[300]);
--ag-row-border-color: theme(colors.white);
--ag-row-hover-color: theme(colors.neutral[100]);
--ag-font-size: 12px;
}
/* Dark variables */
.ag-theme-balham-dark {
--ag-background-color: theme(colors.black);
--ag-border-color: theme(colors.neutral[700]);
--ag-header-background-color: theme(colors.black);
--ag-odd-row-background-color: theme(colors.black);
--ag-header-column-separator-color: theme(colors.neutral[600]);
--ag-row-border-color: theme(colors.black);
--ag-row-hover-color: theme(colors.neutral[800]);
--ag-font-size: 12px;
}
@@ -23,7 +23,7 @@ describe('AccountManager', () => {
data: [],
};
})
.mockImplementation((args) => {
.mockImplementationOnce((args) => {
return {
data: [
{ asset: { id: 'a1' }, party: { id: 't1' } },
@@ -49,7 +49,7 @@ describe('AccountManager', () => {
(helpers.useDataProvider as jest.Mock).mock.calls[0][0].variables
.partyId
).toEqual('partyOne');
await act(async () => {
await act(() => {
rerender(
<AccountManager
partyId="partyTwo"
@@ -66,7 +66,7 @@ describe('AccountManager', () => {
it('update method should return proper result', async () => {
let rerenderer: (ui: React.ReactElement) => void;
await act(async () => {
await act(() => {
const { rerender } = render(
<AccountManager
partyId="partyOne"
@@ -79,7 +79,7 @@ describe('AccountManager', () => {
await waitFor(() => {
expect(screen.getByText('No accounts')).toBeInTheDocument();
});
await act(async () => {
await act(() => {
rerenderer(
<AccountManager
partyId="partyOne"
+1 -1
View File
@@ -22,7 +22,7 @@ import {
} from '@vegaprotocol/ui-toolkit';
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
import {
AgGridLazy as AgGrid,
AgGridDynamic as AgGrid,
CenteredGridCellWrapper,
} from '@vegaprotocol/datagrid';
import { AgGridColumn } from 'ag-grid-react';
+1 -1
View File
@@ -11,7 +11,7 @@ import type {
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import { progressBarCellRendererSelector } from '@vegaprotocol/datagrid';
import { AgGridLazy as AgGrid, PriceCell } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid, PriceCell } from '@vegaprotocol/datagrid';
import type { ValueFormatterParams } from 'ag-grid-community';
import { accountValuesComparator } from './accounts-table';
+1
View File
@@ -1,3 +1,4 @@
export * from './lib/ag-grid/ag-grid-dynamic';
export * from './lib/ag-grid/ag-grid-lazy';
export * from './lib/cells/cumulative-vol-cell';
@@ -0,0 +1,50 @@
import type { ReactNode } from 'react';
import colors from 'tailwindcss/colors';
import 'ag-grid-community/dist/styles/ag-theme-balham-dark.css';
const agGridDarkVariables = `
.ag-theme-balham-dark {
--ag-background-color: ${colors.black};
--ag-border-color: ${colors.neutral[700]};
--ag-header-background-color: ${colors.black};
--ag-odd-row-background-color: ${colors.black};
--ag-header-column-separator-color: ${colors.neutral[600]};
--ag-row-border-color:${colors.black};
--ag-row-hover-color: ${colors.neutral[800]};
--ag-font-size: 12px;
}
.ag-theme-balham-dark .ag-root-wrapper {
border: 0;
}
.ag-theme-balham-dark .ag-row {
border-width: 1px 0;
border-bottom: 1px solid transparent;
}
.ag-theme-balham-dark .ag-row.no-hover, .ag-theme-balham-dark .ag-row.no-hover:hover {
background: black;
}
.ag-theme-balham-dark .ag-react-container {
overflow: hidden;
text-overflow: ellipsis;
}
.ag-theme-balham-dark .ag-cell, .ag-theme-balham-dark .ag-full-width-row .ag-cell-wrapper.ag-row-group {
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
}
`;
export const AgGrid = ({
children,
customThemeParams,
}: {
children: ReactNode;
customThemeParams?: string;
}) => (
<>
<style>{agGridDarkVariables}</style>
{customThemeParams && <style>{customThemeParams}</style>}
{children}
</>
);
@@ -0,0 +1,59 @@
import type { ReactNode, FunctionComponent } from 'react';
import dynamic from 'next/dynamic';
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
import { AgGridReact } from 'ag-grid-react';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import 'ag-grid-community/dist/styles/ag-grid.css';
interface GridProps {
children: ReactNode;
customThemeParams: string;
}
const AgGridLightTheme = dynamic<GridProps>(
() => import('./ag-grid-light').then((mod) => mod.AgGrid),
{ ssr: false }
) as FunctionComponent<GridProps>;
const AgGridDarkTheme = dynamic(
() => import('./ag-grid-dark').then((mod) => mod.AgGrid),
{ ssr: false }
) as FunctionComponent<GridProps>;
export const AgGridThemed = ({
style,
className,
gridRef,
customThemeParams = '',
...props
}: (AgGridReactProps | AgReactUiProps) & {
style?: React.CSSProperties;
className?: string;
gridRef?: React.ForwardedRef<AgGridReact>;
customThemeParams?: string;
}) => {
const { theme } = useThemeSwitcher();
const defaultProps = {
rowHeight: 22,
headerHeight: 22,
enableCellTextSelection: true,
};
return (
<div
className={`${className ?? ''} ${
theme === 'dark' ? 'ag-theme-balham-dark' : 'ag-theme-balham'
}`}
style={style}
>
{theme === 'dark' ? (
<AgGridDarkTheme customThemeParams={customThemeParams}>
<AgGridReact {...defaultProps} {...props} ref={gridRef} />
</AgGridDarkTheme>
) : (
<AgGridLightTheme customThemeParams={customThemeParams}>
<AgGridReact {...defaultProps} {...props} ref={gridRef} />
</AgGridLightTheme>
)}
</div>
);
};
@@ -0,0 +1,29 @@
import * as React from 'react';
import dynamic from 'next/dynamic';
import type {
AgGridReactProps,
AgReactUiProps,
AgGridReact,
} from 'ag-grid-react';
type Props = (AgGridReactProps | AgReactUiProps) & {
style?: React.CSSProperties;
className?: string;
gridRef?: React.Ref<AgGridReact>;
customThemeParams?: string;
};
// https://stackoverflow.com/questions/69433673/nextjs-reactdomserver-does-not-yet-support-suspense
const AgGridDynamicInternal = dynamic<Props>(
() => import('./ag-grid-dynamic-themed').then((mod) => mod.AgGridThemed),
{
ssr: false,
// https://nextjs.org/docs/messages/invalid-dynamic-suspense
// suspense: true
}
) as React.FunctionComponent<Props>;
export const AgGridDynamic = React.forwardRef<AgGridReact, Props>(
(props, ref) => <AgGridDynamicInternal {...props} gridRef={ref} />
);
@@ -1,30 +1,45 @@
import * as React from 'react';
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
import { AgGridReact } from 'ag-grid-react';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import classNames from 'classnames';
import 'ag-grid-community/dist/styles/ag-grid.css';
export const AgGridThemed = ({
style,
gridRef,
...props
}: (AgGridReactProps | AgReactUiProps) & {
style?: React.CSSProperties;
gridRef?: React.ForwardedRef<AgGridReact>;
}) => {
const AgGridLightTheme = React.lazy(() =>
import('./ag-grid-light').then((module) => ({
default: module.AgGrid,
}))
);
const AgGridDarkTheme = React.lazy(() =>
import('./ag-grid-dark').then((module) => ({
default: module.AgGrid,
}))
);
export const AgGridThemed = React.forwardRef<
AgGridReact,
(AgGridReactProps | AgReactUiProps) & {
style?: React.CSSProperties;
className?: string;
}
>(({ style, className, ...props }, ref) => {
const { theme } = useThemeSwitcher();
const defaultProps = {
rowHeight: 22,
headerHeight: 22,
enableCellTextSelection: true,
};
const wrapperClasses = classNames('vega-ag-grid', {
'ag-theme-balham': theme === 'light',
'ag-theme-balham-dark': theme === 'dark',
});
return (
<div className={wrapperClasses} style={style}>
<AgGridReact {...defaultProps} {...props} ref={gridRef} />
<div
className={`${className ?? ''} ${
theme === 'dark' ? 'ag-theme-balham-dark' : 'ag-theme-balham'
}`}
style={style}
>
{theme === 'dark' ? (
<AgGridDarkTheme>
<AgGridReact {...props} ref={ref} enableCellTextSelection={true} />
</AgGridDarkTheme>
) : (
<AgGridLightTheme>
<AgGridReact {...props} ref={ref} enableCellTextSelection={true} />
</AgGridLightTheme>
)}
</div>
);
};
});
+5 -10
View File
@@ -1,17 +1,12 @@
import { forwardRef, lazy } from 'react';
import type { AgGridReactProps, AgGridReact } from 'ag-grid-react';
import * as React from 'react';
import type { AgGridReact } from 'ag-grid-react';
type Props = AgGridReactProps & {
style?: React.CSSProperties;
gridRef?: React.Ref<AgGridReact>;
};
export const AgGridLazyInternal = lazy(() =>
export const AgGridLazyInternal = React.lazy(() =>
import('./ag-grid-lazy-themed').then((module) => ({
default: module.AgGridThemed,
}))
);
export const AgGridLazy = forwardRef<AgGridReact, Props>((props, ref) => (
<AgGridLazyInternal {...props} gridRef={ref} />
export const AgGridLazy = React.forwardRef<AgGridReact>((props, ref) => (
<AgGridLazyInternal {...props} ref={ref} />
));
@@ -0,0 +1,50 @@
import type { ReactNode } from 'react';
import colors from 'tailwindcss/colors';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
const agGridLightVariables = `
.ag-theme-balham {
--ag-background-color: ${colors.white};
--ag-border-color: ${colors.neutral[300]};
--ag-header-background-color: ${colors.white};
--ag-odd-row-background-color: ${colors.white};
--ag-header-column-separator-color: ${colors.neutral[300]};
--ag-row-border-color: ${colors.white};
--ag-row-hover-color: ${colors.neutral[100]};
--ag-font-size: 12px;
}
.ag-theme-balham .ag-root-wrapper {
border: 0;
}
.ag-theme-balham .ag-row {
border-width: 1px 0;
border-bottom: 1px solid transparent;
}
.ag-theme-balham .ag-row.no-hover, .ag-theme-balham .ag-row.no-hover:hover {
background: white;
}
.ag-theme-balham .ag-react-container {
overflow: hidden;
text-overflow: ellipsis;
}
.ag-theme-balham .ag-cell, .ag-theme-balham .ag-full-width-row .ag-cell-wrapper.ag-row-group {
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
}
`;
export const AgGrid = ({
children,
customThemeParams,
}: {
children: ReactNode;
customThemeParams?: string;
}) => (
<>
<style>{agGridLightVariables}</style>
{customThemeParams && <style>{customThemeParams}</style>}
{children}
</>
);
+1 -1
View File
@@ -8,7 +8,7 @@ import {
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type {
VegaICellRendererParams,
VegaValueFormatterParams,
+1 -1
View File
@@ -15,7 +15,7 @@ import { t } from '@vegaprotocol/i18n';
import * as Schema from '@vegaprotocol/types';
import { AgGridColumn } from 'ag-grid-react';
import {
AgGridLazy as AgGrid,
AgGridDynamic as AgGrid,
positiveClassNames,
negativeClassNames,
MarketNameCell,
+1 -1
View File
@@ -10,7 +10,7 @@ import type {
TypedDataAgGrid,
} from '@vegaprotocol/datagrid';
import {
AgGridLazy as AgGrid,
AgGridDynamic as AgGrid,
DateRangeFilter,
SetFilter,
} from '@vegaprotocol/datagrid';
+1 -1
View File
@@ -9,7 +9,7 @@ import type {
VegaValueFormatterParams,
TypedDataAgGrid,
} from '@vegaprotocol/datagrid';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
import type { AgGridReact } from 'ag-grid-react';
import { AgGridColumn } from 'ag-grid-react';
@@ -198,4 +198,4 @@ export function useMarketInfoLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions
}
export type MarketInfoQueryHookResult = ReturnType<typeof useMarketInfoQuery>;
export type MarketInfoLazyQueryHookResult = ReturnType<typeof useMarketInfoLazyQuery>;
export type MarketInfoQueryResult = Apollo.QueryResult<MarketInfoQuery, MarketInfoQueryVariables>;
export type MarketInfoQueryResult = Apollo.QueryResult<MarketInfoQuery, MarketInfoQueryVariables>;
@@ -103,7 +103,6 @@ const MarketInfoAccordion = ({
content: <InsurancePoolInfoPanel market={market} account={a} />,
})),
];
const product = market.tradableInstrument.instrument.product;
const marketSpecPanels = [
{
@@ -114,13 +113,9 @@ const MarketInfoAccordion = ({
title: t('Instrument'),
content: <InstrumentInfoPanel market={market} />,
},
product.dataSourceSpecForSettlementData && {
title: t('Settlement Oracle'),
content: <OracleInfoPanel market={market} type="settlementData" />,
},
product.dataSourceSpecForTradingTermination && {
title: t('Termination Oracle'),
content: <OracleInfoPanel market={market} type="termination" />,
{
title: t('Oracle'),
content: <OracleInfoPanel market={market} />,
},
{
title: t('Settlement asset'),
@@ -26,7 +26,7 @@ import { ConditionOperatorMapping } from '@vegaprotocol/types';
import { MarketTradingModeMapping } from '@vegaprotocol/types';
import { useEnvironment } from '@vegaprotocol/environment';
import type { Provider } from '@vegaprotocol/oracles';
import { OracleBasicProfile, useOracleProofs } from '@vegaprotocol/oracles';
import { useOracleProofs } from '@vegaprotocol/oracles';
import { useDataProvider } from '@vegaprotocol/react-helpers';
type PanelProps = Pick<
@@ -449,38 +449,49 @@ export const LiquidityPriceRangeInfoPanel = ({
export const OracleInfoPanel = ({
market,
type,
}: MarketInfoProps &
PanelProps & { type: 'settlementData' | 'termination' }) => {
...props
}: MarketInfoProps & PanelProps) => {
const product = market.tradableInstrument.instrument.product;
const { VEGA_EXPLORER_URL, ORACLE_PROOFS_URL } = useEnvironment();
const { data } = useOracleProofs(ORACLE_PROOFS_URL);
return (
<div className="flex flex-col gap-4">
<DataSourceProof
<MarketInfoTable
data={{
settlementDataProperty:
product.dataSourceSpecBinding.settlementDataProperty,
tradingTerminationProperty:
product.dataSourceSpecBinding.tradingTerminationProperty,
}}
{...props}
>
<div
className="flex flex-col gap-2 mt-4"
data-testid="oracle-proof-links"
data={
type === 'settlementData'
? product.dataSourceSpecForSettlementData.data
: product.dataSourceSpecForTradingTermination.data
}
providers={data}
type={type}
/>
<ExternalLink
data-testid="oracle-spec-links"
href={`${VEGA_EXPLORER_URL}/oracles/${
type === 'settlementData'
? product.dataSourceSpecForSettlementData.id
: product.dataSourceSpecForTradingTermination.id
}`}
>
{type === 'settlementData'
? t('View settlement data specification')
: t('View termination specification')}
</ExternalLink>
</div>
<DataSourceProof
data={product.dataSourceSpecForSettlementData.data}
providers={data}
type="settlementData"
/>
<DataSourceProof
data={product.dataSourceSpecForTradingTermination.data}
providers={data}
type="termination"
/>
</div>
<div className="flex flex-col gap-2" data-testid="oracle-spec-links">
<ExternalLink
href={`${VEGA_EXPLORER_URL}/oracles#${product.dataSourceSpecForSettlementData.id}`}
>
{t('View settlement data specification')}
</ExternalLink>
<ExternalLink
href={`${VEGA_EXPLORER_URL}/oracles#${product.dataSourceSpecForTradingTermination.id}`}
>
{t('View termination specification')}
</ExternalLink>
</div>
</MarketInfoTable>
);
};
@@ -540,13 +551,20 @@ const OracleLink = ({
providers,
signer,
type,
index,
}: {
providers: Provider[];
signer: SignerKind;
type: 'settlementData' | 'termination';
index: number;
}) => {
const signerProviders = providers.filter((p) => {
const text =
type === 'settlementData'
? t('View settlement oracle details')
: t('View termination oracle details');
const textWithCount = index > 0 ? `${text} (${index + 1})` : text;
const provider = providers.find((p) => {
if (signer.__typename === 'PubKey') {
if (
p.oracle.type === 'public_key' &&
@@ -568,19 +586,14 @@ const OracleLink = ({
return false;
});
if (!signerProviders.length) {
if (!provider) {
return <NoOracleProof type={type} />;
}
return (
<div>
{signerProviders.map((provider) => (
<OracleBasicProfile
key={provider.name}
provider={provider}
></OracleBasicProfile>
))}
</div>
<p>
<ExternalLink href={provider.github_link}>{textWithCount}</ExternalLink>
</p>
);
};
@@ -8,7 +8,7 @@ import type {
TypedDataAgGrid,
} from '@vegaprotocol/datagrid';
import {
AgGridLazy as AgGrid,
AgGridDynamic as AgGrid,
PriceFlashCell,
MarketNameCell,
SetFilter,
-28
View File
@@ -1,28 +0,0 @@
const rootMain = require('../../../.storybook/main');
module.exports = {
...rootMain,
core: { ...rootMain.core, builder: 'webpack5' },
stories: [
...rootMain.stories,
'../src/**/*.stories.mdx',
'../src/**/*.stories.@(js|jsx|ts|tsx)',
],
addons: [
...rootMain.addons,
'@nrwl/react/plugins/storybook',
'storybook-addon-themes',
],
webpackFinal: async (config, { configType }) => {
// apply any global webpack configs that might have been specified in .storybook/main.js
if (rootMain.webpackFinal) {
config = await rootMain.webpackFinal(config, { configType });
}
// add your own webpack tweaks if needed
return config;
},
};
@@ -1 +0,0 @@
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
-90
View File
@@ -1,90 +0,0 @@
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import classNames from 'classnames';
import { useEffect } from 'react';
import '../src/styles.css';
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
backgrounds: { disable: true },
layout: 'fullscreen',
a11y: {
config: {
rules: [
{
// Disabled only for storybook because we display both the dark and light variants of the components on the same page without differentiating the ids, so it will always error.
id: 'duplicate-id-aria',
selector: '[data-testid="form-group"] > label',
},
{
// Disabled because we can't control the radix radio group component and it claims to be accessible to begin with, so hopefully no issues.
id: 'button-name',
selector: '[role=radiogroup] > button',
},
],
},
},
};
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'dark',
toolbar: {
icon: 'circlehollow',
items: [
{ value: 'light', title: 'Light' },
{ value: 'dark', title: 'Dark' },
{ value: 'sideBySide', title: 'Side by side' },
],
showName: true,
},
},
};
const StoryWrapper = ({ children, fill }) => {
const classes = classNames(
'p-4',
'bg-white dark:bg-black',
'text-neutral-800 dark:text-neutral-200',
{
'w-screen h-screen': fill,
}
);
return <div className={classes}>{children}</div>;
};
const ThemeWrapper = (Story, context) => {
const theme = context.parameters.theme || context.globals.theme;
const { setTheme } = useThemeSwitcher();
useEffect(() => {
// in side by side mode a 'dark' class on the html tag will interfere
// making the light 'side' dark, so remove it in that case
if (theme === 'sideBySide') {
document.documentElement.classList.remove('dark');
} else {
setTheme(theme);
}
}, [setTheme, theme]);
return theme === 'sideBySide' ? (
<>
<div className="bg-white text-black">
<StoryWrapper>
<Story />
</StoryWrapper>
</div>
<div className="dark bg-black text-white">
<StoryWrapper>
<Story />
</StoryWrapper>
</div>
</>
) : (
<StoryWrapper fill={true}>
<Story />
</StoryWrapper>
);
};
export const decorators = [ThemeWrapper];
-20
View File
@@ -1,20 +0,0 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"emitDecoratorMetadata": true,
"outDir": ""
},
"files": [
"../../../node_modules/@nrwl/react/typings/styled-jsx.d.ts",
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"../**/*.spec.ts",
"../**/*.spec.js",
"../**/*.spec.tsx",
"../**/*.spec.jsx",
"jest.config.ts"
],
"include": ["../src/**/*", "*.js"]
}
-1
View File
@@ -7,5 +7,4 @@ export default {
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/oracles',
setupFilesAfterEnv: ['./src/setup-tests.ts'],
};
-10
View File
@@ -1,10 +0,0 @@
const { join } = require('path');
module.exports = {
plugins: {
tailwindcss: {
config: join(__dirname, 'tailwind.config.js'),
},
autoprefixer: {},
},
};
-38
View File
@@ -38,44 +38,6 @@
"jestConfig": "libs/oracles/jest.config.ts",
"passWithNoTests": true
}
},
"storybook": {
"executor": "@nrwl/storybook:storybook",
"options": {
"uiFramework": "@storybook/react",
"port": 4400,
"config": {
"configFolder": "libs/oracles/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-storybook": {
"executor": "@nrwl/storybook:build",
"outputs": ["{options.outputPath}"],
"options": {
"uiFramework": "@storybook/react",
"outputPath": "dist/storybook/oracles",
"config": {
"configFolder": "libs/oracles/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-spec": {
"executor": "@nrwl/workspace:run-commands",
"outputs": [],
"options": {
"command": "yarn tsc --project ./libs/oracles/tsconfig.spec.json"
}
}
}
}
+4 -1
View File
@@ -1 +1,4 @@
export * from './lib';
export * from './lib/oracle-schema';
export * from './lib/use-oracle-proofs';
export * from './lib/use-oracle-spec-binding-data';
export * from './lib/__generated__/OracleSpecDataConnection';
-1
View File
@@ -1 +0,0 @@
export * from './OracleSpecDataConnection';
-1
View File
@@ -1 +0,0 @@
export * from './oracle-basic-profile';
@@ -1,2 +0,0 @@
export * from './oracle-basic-profile.stories';
export * from './oracle-basic-profile';
@@ -1,45 +0,0 @@
import { OracleBasicProfile } from './oracle-basic-profile';
import type { Provider } from '../../oracle-schema';
import { render, screen } from '@testing-library/react';
describe('OracleBasicProfile', () => {
const testProvider = {
name: 'Test oracle',
url: 'https://zombo.com',
description_markdown:
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
oracle: {
status: 'GOOD',
status_reason: '',
first_verified: '2023-02-28T00:00:00.000Z',
last_verified: '2023-02-28T00:00:00.000Z',
type: 'eth_address',
eth_address: '0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC',
},
proofs: [
{
format: 'signed_message',
available: true,
type: 'eth_address',
eth_address: '0x949AF81E51D57831AE52591d17fBcdd1014a5f52',
message: 'SOMEHEX',
},
],
github_link:
'https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml',
} as Provider;
it('should render successfully', () => {
const component = <OracleBasicProfile provider={testProvider} />;
expect(component).toBeTruthy();
});
it('should render the name', () => {
render(<OracleBasicProfile provider={testProvider} />);
expect(screen.getByTestId('provider-name')).toHaveTextContent(
'Test oracle'
);
expect(screen.getByTestId('verified-proofs')).toHaveTextContent('1');
expect(screen.getByTestId('signed-proofs')).toHaveTextContent('1');
});
});
@@ -1,41 +0,0 @@
import type { Story, Meta } from '@storybook/react';
import { OracleBasicProfile } from './oracle-basic-profile';
export default {
component: OracleBasicProfile,
title: 'OracleBasicProfile',
} as Meta;
const Template: Story = (args) => (
<OracleBasicProfile provider={args['provider']} />
);
export const Default = Template.bind({});
Default.args = {
provider: {
name: 'Test oracle',
url: 'https://zombo.com',
description_markdown:
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
oracle: {
status: 'GOOD',
status_reason: '',
first_verified: '2023-02-28T00:00:00.000Z',
last_verified: '2023-02-28T00:00:00.000Z',
type: 'eth_address',
eth_address: '0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC',
},
proofs: [
{
format: 'signed_message',
available: true,
type: 'eth_address',
eth_address: '0x949AF81E51D57831AE52591d17fBcdd1014a5f52',
message: 'SOMEHEX',
},
],
github_link:
'https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml',
},
};
@@ -1,158 +0,0 @@
import { t } from '@vegaprotocol/i18n';
import type { Provider } from '../../oracle-schema';
import {
ExternalLink,
Icon,
Intent,
Link,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import type { IconName } from '@blueprintjs/icons';
import { IconNames } from '@blueprintjs/icons';
import classNames from 'classnames';
const getVerifiedStatusIcon = (provider: Provider) => {
const getIconIntent = () => {
switch (provider.oracle.status) {
case 'GOOD':
return { icon: IconNames.TICK_CIRCLE, intent: Intent.Success };
case 'RETIRED':
return { icon: IconNames.MOON, intent: Intent.None };
case 'UNKNOWN':
return { icon: IconNames.HELP, intent: Intent.Primary };
case 'MALICIOUS':
return { icon: IconNames.ERROR, intent: Intent.Danger };
case 'SUSPICIOUS':
return { icon: IconNames.ERROR, intent: Intent.Danger };
case 'COMPROMISED':
return { icon: IconNames.ERROR, intent: Intent.Danger };
default:
return { icon: IconNames.HELP, intent: Intent.Primary };
}
};
if (!provider.oracle.first_verified || !provider.oracle.last_verified) {
return {
message: t('Not verified'),
...getIconIntent(),
};
}
const lastVerified = provider.oracle.last_verified
? new Date(provider.oracle.last_verified)
: new Date(provider.oracle.first_verified);
return {
...getIconIntent(),
message: t(
'Verified since %s',
lastVerified.toLocaleDateString(undefined, {
year: 'numeric',
month: 'long',
})
),
};
};
export const OracleBasicProfile = ({ provider }: { provider: Provider }) => {
const { icon, message, intent } = getVerifiedStatusIcon(provider);
const verifiedProofs = provider.proofs.filter(
(proof) => proof.available === true
);
const signedProofs = provider.proofs.filter(
(proof) => proof.format === 'signed_message' && proof.available === true
);
const links = provider.proofs
.filter((proof) => proof.format === 'url' && proof.available === true)
.map((proof) => ({
...proof,
url: 'url' in proof ? proof.url : '',
icon: getLinkIcon(proof.type),
}));
return (
<>
<span className="flex gap-1">
{provider.url && (
<Link
href={provider.github_link}
className="flex align-items-bottom text-md"
target="_blank"
>
<span>
<span data-testid="provider-name" className="underline pr-1">
{provider.name}
</span>
<span
data-testid="verified-proofs"
className="dark:text-vega-light-300 text-vega-dark-300"
>
({verifiedProofs.length})
</span>
</span>
</Link>
)}
<span
className={classNames(
{
'text-gray-700 dark:text-gray-300': intent === Intent.None,
'text-vega-blue': intent === Intent.Primary,
'text-vega-green dark:text-vega-green': intent === Intent.Success,
'text-yellow-600 dark:text-yellow': intent === Intent.Warning,
'text-vega-pink': intent === Intent.Danger,
},
'flex items-start align-text-bottom p-1'
)}
>
<Icon size={3} name={icon as IconName} />
</span>
</span>
<p className="dark:text-vega-light-300 text-vega-dark-300">{message}</p>
<p
data-testid="signed-proofs"
className="dark:text-vega-light-300 text-vega-dark-300"
>
{t('Involved in %s %s', [
signedProofs.length.toString(),
signedProofs.length !== 1 ? t('markets') : t('market'),
])}
</p>
{links.length > 0 && (
<div className="flex flex-row gap-1">
{links.map((link) => (
<ExternalLink
key={link.url}
href={link.url}
data-testid={link.url}
className="flex align-items-bottom underline text-sm"
>
<span className="pt-1">
<VegaIcon name={getLinkIcon(link.type)} />
</span>
<span className="underline capitalize">
{link.type}{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={13} />
</span>
</ExternalLink>
))}
</div>
)}
</>
);
};
export const getLinkIcon = (type: string) => {
switch (type) {
case 'twitter':
return VegaIconNames.TWITTER;
case 'github':
return VegaIconNames.GLOBE;
case 'linkedin':
return VegaIconNames.LINKEDIN;
default:
return VegaIconNames.GLOBE;
}
};
-6
View File
@@ -1,6 +0,0 @@
export * from './__generated__';
export * from './components';
export * from './oracle-schema';
export * from './oracle-spec-data-connection.mock';
export * from './use-oracle-proofs';
export * from './use-oracle-spec-binding-data';
-73
View File
@@ -1,73 +0,0 @@
[
{
"name": "Test oracle",
"url": "https://zombo.com",
"description_markdown": "Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n",
"oracle": {
"status": "GOOD",
"status_reason": "",
"first_verified": "2023-02-28T00:00:00.000Z",
"last_verified": "2023-02-28T00:00:00.000Z",
"type": "eth_address",
"eth_address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
},
"proofs": [
{
"format": "signed_message",
"available": true,
"type": "eth_address",
"eth_address": "0x949AF81E51D57831AE52591d17fBcdd1014a5f52",
"message": "SOMEHEX"
}
],
"github_link": "https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml"
},
{
"name": "Vega Admin Oracle for Testnet",
"url": "https://fairground.wtf",
"description_markdown": "The Vega Fairground admin oracle, uses a json file to settle based on Binance Spot price.\nE.g. in case the market is BTC/USDC the spot price for BTC/USDC on Binance will be used.\n\nTwitter: @VegaFairground\n",
"oracle": {
"status": "GOOD",
"status_reason": "",
"first_verified": "2022-01-01T00:00:00.000Z",
"last_verified": "2022-12-31T00:00:00.000Z",
"type": "public_key",
"public_key": "69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f"
},
"proofs": [
{
"format": "url",
"available": true,
"type": "twitter",
"url": "https://twitter.com/vegaprotocol/status/956833487230730241"
},
{
"format": "url",
"available": true,
"type": "web",
"url": "https://fairground.wtf/"
},
{
"format": "url",
"available": true,
"type": "github",
"url": "https://github.com"
},
{
"format": "signed_message",
"available": true,
"type": "public_key",
"public_key": "69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f",
"message": "SOMEHEX"
},
{
"format": "signed_message",
"available": true,
"type": "eth_address",
"eth_address": "0x0b38D0e7391CF427d309991A110a84daF37114eF",
"message": "SOMEHEX"
}
],
"github_link": "https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/public_key-69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f.toml"
}
]
-4
View File
@@ -1,4 +0,0 @@
import '@testing-library/jest-dom';
import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;
-18
View File
@@ -1,18 +0,0 @@
const { join } = require('path');
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
const theme = require('../tailwindcss-config/src/theme');
const vegaCustomClasses = require('../tailwindcss-config/src/vega-custom-classes');
module.exports = {
content: [
join(__dirname, 'src/**/*.{ts,tsx,html,mdx}'),
join(__dirname, 'src/utils/shared.ts'),
join(__dirname, '.storybook/preview.js'),
...createGlobPatternsForDependencies(__dirname),
],
darkMode: 'class',
theme: {
extend: theme,
},
plugins: [vegaCustomClasses],
};
+2 -4
View File
@@ -8,10 +8,11 @@
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": false,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
@@ -19,9 +20,6 @@
},
{
"path": "./tsconfig.spec.json"
},
{
"path": "./.storybook/tsconfig.json"
}
]
}
+2 -6
View File
@@ -9,6 +9,7 @@
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"jest.config.ts",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
@@ -16,12 +17,7 @@
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"**/*.stories.ts",
"**/*.stories.js",
"**/*.stories.jsx",
"**/*.stories.tsx",
"jest.config.ts"
"**/*.test.jsx"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
+2 -3
View File
@@ -3,9 +3,10 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node", "@testing-library/jest-dom"]
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"**/*.test.ts",
"**/*.spec.ts",
"**/*.test.tsx",
@@ -15,8 +16,6 @@
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts",
"jest.config.ts",
"../../index.d.ts",
"src/lib/use-oracle-spec-binding-data.spec.tsx"
]
}
@@ -10,7 +10,7 @@ import { AgGridColumn } from 'ag-grid-react';
import BigNumber from 'bignumber.js';
import { memo, forwardRef } from 'react';
import {
AgGridLazy as AgGrid,
AgGridDynamic as AgGrid,
SetFilter,
DateRangeFilter,
negativeClassNames,
+1 -1
View File
@@ -10,7 +10,7 @@ import type {
} from '@vegaprotocol/datagrid';
import { ProgressBarCell } from '@vegaprotocol/datagrid';
import {
AgGridLazy as AgGrid,
AgGridDynamic as AgGrid,
DateRangeFilter,
PriceFlashCell,
signedNumberCssClass,
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import { useDataProvider } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/i18n';
import * as Types from '@vegaprotocol/types';
@@ -9,6 +9,13 @@ import type { AgGridReact } from 'ag-grid-react';
import { useColumnDefs } from './use-column-defs';
import type { ProposalListFieldsFragment } from '../proposals-data-provider/__generated__/Proposals';
// prevent cutting filter windows by auto-height layout
const CUSTOM_GRID_STYLES = `
.ag-layout-auto-height {
min-height: 200px !important;
}
`;
export const getNewMarketProposals = (data: ProposalListFieldsFragment[]) =>
data.filter((proposal) =>
[
@@ -51,6 +58,7 @@ export const ProposalsList = () => {
suppressLoadingOverlay
suppressNoRowsOverlay
onFilterChanged={onFilterChanged}
customThemeParams={CUSTOM_GRID_STYLES}
/>
<div className="pointer-events-none absolute inset-0">
<AsyncRenderer
-1
View File
@@ -17,4 +17,3 @@ export * from './use-yesterday';
export * from './use-previous';
export * from './use-logger';
export * from './use-bottom-placeholder';
export * from './use-pane-layout';
@@ -1,19 +0,0 @@
import { renderHook, act, waitFor } from '@testing-library/react';
import { usePaneLayout } from './use-pane-layout';
describe('usePaneLayout', () => {
it('should return proper values', () => {
const ret = renderHook(() => usePaneLayout({ id: 'testid' }));
expect(ret.result.current[0]).toStrictEqual([]);
expect(ret.result.current[1]).toStrictEqual(expect.any(Function));
});
it('setter should change value', async () => {
const ret = renderHook(() => usePaneLayout({ id: 'testid' }));
await act(() => {
ret.result.current[1]([100, 50, 50]);
});
await waitFor(() => {
expect(ret.result.current[0]).toStrictEqual(['50%', '25%', '25%']);
});
});
});
@@ -1,47 +0,0 @@
import { useCallback } from 'react';
import debounce from 'lodash/debounce';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
const STORAGE_KEY = 'vega_pane_store';
const PANELS_SET_DEBOUNCE_TIME = 300;
export const usePaneLayoutStore = create<{
sizes: Record<string, string[]>;
valueSetter: (id: string, value: string[]) => void;
}>()(
persist(
immer((set) => ({
sizes: {},
valueSetter: (id, value) =>
set((state) => {
state.sizes[id] = value;
return state;
}),
})),
{ name: STORAGE_KEY }
)
);
interface UsePaneLayoutProps {
id: string;
}
export const usePaneLayout = ({
id,
}: UsePaneLayoutProps): [string[], (sizes: number[]) => void] => {
const sizes = usePaneLayoutStore((store) => store.sizes[id]) || [];
const valueSetter = usePaneLayoutStore((store) => store.valueSetter);
// eslint-disable-next-line react-hooks/exhaustive-deps
const handleOnChange = useCallback(
debounce((args) => {
if (args.length) {
const all = args.reduce((agg: number, item: number) => agg + item, 0);
const sizesArr = args.map((arg: number) => `${(arg / all) * 100}%`);
valueSetter(id, sizesArr);
}
}, PANELS_SET_DEBOUNCE_TIME),
[valueSetter, id]
);
return [sizes, handleOnChange];
};
+1 -1
View File
@@ -5,7 +5,7 @@ import type {
VegaICellRendererParams,
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import { AgGridLazy as AgGrid, NumericCell } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid, NumericCell } from '@vegaprotocol/datagrid';
import {
addDecimal,
addDecimalsFormatNumber,
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.20755 15.7736H6V4H8.20755V15.7736ZM10.4151 17.8585V15.7736H8.20755V17.9811H10.4151V20.066H12.6226V17.9811H14.8302V15.7736H12.6226V17.8585H10.4151ZM16.7925 13.566H14.5849V4H16.7925V13.566ZM16.7925 13.566H19V15.7736H16.7925V13.566Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 401 B

@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 4.32353V19.6765C21 20.0275 20.8606 20.3641 20.6123 20.6123C20.3641 20.8606 20.0275 21 19.6765 21H4.32353C3.97251 21 3.63586 20.8606 3.38765 20.6123C3.13944 20.3641 3 20.0275 3 19.6765V4.32353C3 3.97251 3.13944 3.63586 3.38765 3.38765C3.63586 3.13944 3.97251 3 4.32353 3H19.6765C20.0275 3 20.3641 3.13944 20.6123 3.38765C20.8606 3.63586 21 3.97251 21 4.32353V4.32353ZM8.29412 9.88235H5.64706V18.3529H8.29412V9.88235ZM8.53235 6.97059C8.53375 6.77036 8.49569 6.57182 8.42035 6.3863C8.34502 6.20078 8.23387 6.03191 8.09328 5.88935C7.95268 5.74678 7.78537 5.6333 7.60091 5.5554C7.41646 5.47749 7.21846 5.43668 7.01824 5.43529H6.97059C6.5634 5.43529 6.1729 5.59705 5.88497 5.88497C5.59705 6.1729 5.43529 6.5634 5.43529 6.97059C5.43529 7.37777 5.59705 7.76828 5.88497 8.05621C6.1729 8.34413 6.5634 8.50588 6.97059 8.50588V8.50588C7.17083 8.51081 7.37008 8.47623 7.55696 8.40413C7.74383 8.33202 7.91467 8.2238 8.0597 8.08565C8.20474 7.94749 8.32113 7.78212 8.40223 7.59897C8.48333 7.41582 8.52755 7.21848 8.53235 7.01824V6.97059ZM18.3529 13.2071C18.3529 10.6606 16.7329 9.67059 15.1235 9.67059C14.5966 9.6442 14.0719 9.75644 13.6019 9.9961C13.1318 10.2358 12.7328 10.5945 12.4447 11.0365H12.3706V9.88235H9.88235V18.3529H12.5294V13.8476C12.4911 13.3862 12.6365 12.9283 12.9339 12.5735C13.2313 12.2186 13.6567 11.9954 14.1176 11.9524H14.2182C15.06 11.9524 15.6847 12.4818 15.6847 13.8159V18.3529H18.3318L18.3529 13.2071Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96C6.34 6.48 6.43 6.06 6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z" fill="white"/>
<circle cx="8" cy="8" r="7" fill="white"/>
<path d="M6.15393 5.69232C6.15393 5.10304 6.24054 4.5075 6.46161 4C4.99179 4.63982 4 6.14089 4 7.84607C4 10.1402 5.85982 12 8.15393 12C9.85911 12 11.3602 11.0082 12 9.53839C11.4925 9.75946 10.8964 9.84607 10.3077 9.84607C8.01357 9.84607 6.15393 7.98643 6.15393 5.69232Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96L6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 929 B

@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.28743 20.2575C15.8423 20.2575 19.9641 14 19.9641 8.58084C19.9641 8.4012 19.9641 8.22156 19.9541 8.0519C20.7525 7.47305 21.4511 6.74451 22 5.92615C21.2615 6.25549 20.4731 6.47505 19.6447 6.57485C20.493 6.06587 21.1417 5.26747 21.4511 4.2994C20.6627 4.76846 19.7844 5.10778 18.8463 5.29741C18.0978 4.499 17.0299 4 15.8523 4C13.5868 4 11.7505 5.83633 11.7505 8.1018C11.7505 8.42116 11.7904 8.74052 11.8603 9.03992C8.43713 8.86028 5.40319 7.22355 3.38723 4.7485C3.02794 5.34731 2.82834 6.05589 2.82834 6.80439C2.82834 8.23154 3.55689 9.48902 4.65469 10.2176C3.97605 10.2076 3.34731 10.018 2.7984 9.70858C2.7984 9.72854 2.7984 9.73852 2.7984 9.75848C2.7984 11.7445 4.21557 13.4112 6.09182 13.7804C5.74251 13.8703 5.38323 13.9202 5.01397 13.9202C4.75449 13.9202 4.49501 13.8902 4.24551 13.8503C4.76447 15.477 6.28144 16.6647 8.07784 16.7046C6.67066 17.8024 4.90419 18.4611 2.97804 18.4611C2.6487 18.4611 2.31936 18.4411 2 18.4012C3.80639 19.5788 5.96208 20.2575 8.28743 20.2575Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -8,8 +8,8 @@ export const IconGlobe = ({ size = 24 }: { size: number }) => {
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
fill-rule="evenodd"
clip-rule="evenodd"
d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z"
fill="white"
/>
@@ -5,7 +5,7 @@ import { VegaIconNameMap } from './vega-icon-record';
export interface VegaIconProps {
name: VegaIconNames;
size?: 8 | 10 | 12 | 13 | 14 | 16 | 24 | 32;
size?: 16 | 24 | 32;
}
export const VegaIcon = ({ size = 16, name }: VegaIconProps) => {
@@ -120,11 +120,7 @@ describe('VegaConnectDialog', () => {
.mockImplementation(() =>
Promise.resolve({ success: true, error: null })
);
jest
.spyOn(connectors.rest, 'connect')
.mockImplementation(() =>
Promise.resolve([{ publicKey: 'pubkey', name: 'test key 1' }])
);
render(generateJSX());
// Switches to rest form
fireEvent.click(await screen.findByText('Hosted Fairground wallet'));
@@ -142,11 +138,10 @@ describe('VegaConnectDialog', () => {
await act(async () => {
fireEvent.submit(screen.getByTestId('rest-connector-form'));
});
await waitFor(() => {
expect(spy).toHaveBeenCalledWith(fields);
expect(mockCloseVegaDialog).toHaveBeenCalled();
});
expect(spy).toHaveBeenCalledWith(fields);
expect(mockCloseVegaDialog).toHaveBeenCalled();
});
it('handles failed connection', async () => {
-3
View File
@@ -1,4 +1 @@
import '@testing-library/jest-dom';
import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;
+1 -1
View File
@@ -10,7 +10,7 @@ import {
import { useBottomPlaceholder } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/i18n';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type {
TypedDataAgGrid,
VegaICellRendererParams,
+1 -2
View File
@@ -24,8 +24,7 @@
"echo $NX_TENDERMINT_WEBSOCKET_URL",
"echo $NX_USE_ENV_OVERRIDES",
"echo $NX_ETHEREUM_PROVIDER_URL"
],
"url": "https://cloud.nx.app"
]
}
}
},