feat(trading): make Sentry only after opt in (#3448)

This commit is contained in:
Maciek 2023-04-26 17:17:23 +02:00 committed by GitHub
parent d6ecdf80fa
commit b7a440132d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 511 additions and 68 deletions

View File

@ -32,7 +32,7 @@ describe('Navbar', { tags: '@smoke' }, () => {
});
it('Resources dropdown should be correctly rendered', () => {
const resourceSelector = 'ul li:last-child';
const resourceSelector = 'ul li:contains(Resources)';
['Docs', 'Give Feedback'].forEach((text, index) => {
cy.get('nav').find(resourceSelector).contains('Resources').click();
cy.get('nav')
@ -91,7 +91,7 @@ describe('Navbar', { tags: '@smoke' }, () => {
cy.getByTestId('button-menu-drawer').click();
cy.getByTestId('menu-drawer').should('be.visible');
cy.getByTestId('menu-drawer')
.find('[data-testid="theme-switcher"]')
.find('[data-testid="Settings"]')
.should('be.visible');
cy.getByTestId('button-menu-drawer').click();
cy.getByTestId('menu-drawer').should('not.be.visible');

View File

@ -0,0 +1,45 @@
describe('Settings page', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.clearLocalStorage().then(() => {
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/');
cy.get('[role=dialog]').within(() => {
cy.getByTestId('dialog-close').click();
});
cy.get('[aria-label="cog icon"]').click();
});
});
it('telemetry checkbox should work well', () => {
cy.location('hash').should('equal', '#/settings');
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'unchecked'
);
cy.get('[for="telemetry-approval"]').click();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'checked'
);
cy.reload();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'checked'
);
cy.get('[for="telemetry-approval"]').click();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'unchecked'
);
cy.reload();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'unchecked'
);
});
});

View File

@ -11,4 +11,4 @@ NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports

View File

@ -0,0 +1,2 @@
export { Settings as default } from './settings';
export { SettingsButton } from './settings-button';

View File

@ -0,0 +1,16 @@
import { Icon, NavigationLink } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { Links, Routes } from '../../pages/client-router';
import { COG } from '@blueprintjs/icons/src/generated/iconNames';
export const SettingsButton = ({ withMobile }: { withMobile?: boolean }) => {
return (
<NavigationLink data-testid="Settings" to={Links[Routes.SETTINGS]()}>
{withMobile ? (
t('Settings')
) : (
<Icon name={COG} className="!align-middle" />
)}
</NavigationLink>
);
};

View File

@ -0,0 +1,45 @@
import { t } from '@vegaprotocol/i18n';
import { TelemetryApproval } from '../../components/welcome-dialog/telemetry-approval';
import {
Divider,
RoundedWrapper,
Switch,
ThemeSwitcher,
} from '@vegaprotocol/ui-toolkit';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
export const Settings = () => {
const { theme, setTheme } = useThemeSwitcher();
const text = t(theme === 'dark' ? 'Light mode' : 'Dark mode');
return (
<div className="py-16 px-8 flex w-full justify-center">
<div className="lg:min-w-[700px] min-w-[300px]">
<h1 className="text-4xl xl:text-5xl uppercase font-alpha calt">
{t('Settings')}
</h1>
<div className="mt-8 text-base text-neutral-500 dark:text-neutral-400">
{t('Changes are applied automatically.')}
</div>
<div className="mt-10 w-full">
<RoundedWrapper paddingBottom>
<div className="flex justify-between py-3">
<div className="flex shrink">
<ThemeSwitcher />
<label htmlFor="theme-switcher" className="self-center text-lg">
{text}
</label>
</div>
<Switch
name="settings-theme-switch"
onCheckedChange={() => setTheme()}
checked={theme === 'dark'}
/>
</div>
<Divider />
<TelemetryApproval isSettingsPage />
</RoundedWrapper>
</div>
</div>
</div>
);
};

View File

@ -10,7 +10,6 @@ import { t } from '@vegaprotocol/i18n';
import { useGlobalStore } from '../../stores';
import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
import {
ThemeSwitcher,
Navigation,
NavigationList,
NavigationItem,
@ -24,6 +23,7 @@ import {
import { Links, Routes } from '../../pages/client-router';
import { createDocsLinks } from '@vegaprotocol/utils';
import { SettingsButton } from '../../client-pages/settings';
export const Navbar = ({
theme = 'system',
@ -45,7 +45,7 @@ export const Navbar = ({
theme={theme}
actions={
<>
<ThemeSwitcher />
<SettingsButton />
<VegaWalletConnectButton />
</>
}
@ -108,15 +108,15 @@ export const Navbar = ({
)}
</NavigationList>
<NavigationList
className="[.drawer-content_&]:border-t [.drawer-content_&]:border-t-vega-light-200 dark:[.drawer-content_&]:border-t-vega-dark-200 [.drawer-content_&]:pt-8 [.drawer-content_&]:mt-4"
className="[.drawer-content_&]:border-t [.drawer-content_&]:border-t-vega-light-200 dark:[.drawer-content_&]:border-t-vega-dark-200 [.drawer-content_&]:pt-4 [.drawer-content_&]:mt-4"
hide={[
NavigationBreakpoint.Small,
NavigationBreakpoint.Narrow,
NavigationBreakpoint.Full,
]}
>
<NavigationItem className="[.drawer-content_&]:w-full text-black dark:text-white">
<ThemeSwitcher withMobile />
<NavigationItem className="[.drawer-content_&]:w-full">
<SettingsButton withMobile />
</NavigationItem>
</NavigationList>
</Navigation>

View File

@ -21,12 +21,12 @@ describe('Risk notice dialog', () => {
});
it.each`
assertion | network
${'displays'} | ${Networks.MAINNET}
${'does not display'} | ${Networks.CUSTOM}
${'does not display'} | ${Networks.DEVNET}
${'does not display'} | ${Networks.STAGNET3}
${'does not display'} | ${Networks.TESTNET}
assertion | network
${'displays'} | ${Networks.MAINNET}
${'displays'} | ${Networks.CUSTOM}
${'displays'} | ${Networks.DEVNET}
${'displays'} | ${Networks.STAGNET3}
${'displays'} | ${Networks.TESTNET}
`(
'$assertion the risk notice on $network',
async ({ assertion, network }) => {
@ -43,13 +43,7 @@ describe('Risk notice dialog', () => {
{ wrapper: BrowserRouter }
);
if (assertion === 'displays') {
// eslint-disable-next-line jest/no-conditional-expect
expect(screen.queryByText(introText)).toBeInTheDocument();
} else {
// eslint-disable-next-line jest/no-conditional-expect
expect(screen.queryByText(introText)).not.toBeInTheDocument();
}
expect(screen.queryByText(introText)).toBeInTheDocument();
}
);

View File

@ -3,6 +3,7 @@ import { t } from '@vegaprotocol/i18n';
import { Button } from '@vegaprotocol/ui-toolkit';
import { LocalStorage } from '@vegaprotocol/utils';
import { RISK_ACCEPTED_KEY } from '../constants';
import { TelemetryApproval } from './telemetry-approval';
interface Props {
onClose: () => void;
@ -32,6 +33,9 @@ export const RiskNoticeDialog = ({ onClose }: Props) => {
)}
</p>
<Button onClick={handleAcceptRisk}>{t('I understand, Continue')}</Button>
<div className="text-base mt-8">
<TelemetryApproval />
</div>
</>
);
};

View File

@ -0,0 +1,19 @@
import { render, screen, act } from '@testing-library/react';
import { TelemetryApproval } from './telemetry-approval';
describe('TelemetryApproval', () => {
it('click on checkbox should be properly handled', () => {
render(<TelemetryApproval />);
expect(screen.getByRole('checkbox')).toHaveAttribute(
'data-state',
'unchecked'
);
act(() => {
screen.getByRole('checkbox').click();
});
expect(screen.getByRole('checkbox')).toHaveAttribute(
'data-state',
'checked'
);
});
});

View File

@ -0,0 +1,32 @@
import { Checkbox } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
export const TelemetryApproval = ({
isSettingsPage,
}: {
isSettingsPage?: boolean;
}) => {
const [isApproved, setIsApproved] = useTelemetryApproval();
return (
<div className="flex flex-col px-2 py-3">
<div className="mr-4" role="form">
<Checkbox
label={<span className="text-lg pl-1">{t('Share usage data')}</span>}
checked={isApproved}
name="telemetry-approval"
onCheckedChange={() => setIsApproved(!isApproved)}
/>
</div>
<div className="text-sm text-neutral-600 dark:text-neutral-300 ml-6">
<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>
);
};

View File

@ -4,7 +4,6 @@ import { Dialog } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useDataProvider, useLocalStorage } from '@vegaprotocol/react-helpers';
import { activeMarketsProvider } from '@vegaprotocol/market-list';
import { useEnvironment, Networks } from '@vegaprotocol/environment';
import * as constants from '../constants';
import { RiskNoticeDialog } from './risk-notice-dialog';
import { WelcomeNoticeDialog } from './welcome-notice-dialog';
@ -13,37 +12,38 @@ import { useGlobalStore } from '../../stores';
export const WelcomeDialog = () => {
const { pathname } = useLocation();
const { VEGA_ENV } = useEnvironment();
let dialogContent: React.ReactNode = null;
let dialogContent: React.ReactNode;
let title = '';
let size: 'small' | 'medium' = 'small';
let onClose: ((open: boolean) => void) | undefined = undefined;
const [riskAccepted] = useLocalStorage(constants.RISK_ACCEPTED_KEY);
const { data } = useDataProvider({
dataProvider: activeMarketsProvider,
variables: undefined,
});
const { update, shouldDisplayWelcomeDialog } = useGlobalStore((store) => ({
update: store.update,
shouldDisplayWelcomeDialog: store.shouldDisplayWelcomeDialog,
}));
const isRiskDialogNeeded =
riskAccepted !== 'true' && VEGA_ENV === Networks.MAINNET;
const update = useGlobalStore((store) => store.update);
const shouldDisplayWelcomeDialog = useGlobalStore(
(store) => store.shouldDisplayWelcomeDialog
);
const isRiskDialogNeeded = riskAccepted !== 'true' && !('Cypress' in window);
const isWelcomeDialogNeeded = pathname === '/' || shouldDisplayWelcomeDialog;
const onClose = useCallback(() => {
const onCloseDialog = useCallback(() => {
update({ shouldDisplayWelcomeDialog: isRiskDialogNeeded });
// eslint-disable-next-line react-hooks/exhaustive-deps
dialogContent = null;
}, [update, isRiskDialogNeeded]);
if (isRiskDialogNeeded) {
dialogContent = <RiskNoticeDialog onClose={onClose} />;
dialogContent = <RiskNoticeDialog onClose={onCloseDialog} />;
title = t('WARNING');
size = 'medium';
} else if (isWelcomeDialogNeeded && data?.length === 0) {
dialogContent = <WelcomeNoticeDialog />;
onClose = onCloseDialog;
} else if (isWelcomeDialogNeeded && (data?.length || 0) > 0) {
dialogContent = <WelcomeLandingDialog onClose={onClose} />;
dialogContent = <WelcomeLandingDialog onClose={onCloseDialog} />;
onClose = onCloseDialog;
} else {
dialogContent = null as React.ReactNode;
}
return (

View File

@ -0,0 +1,48 @@
import { renderHook, act, waitFor } from '@testing-library/react';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { SentryInit, SentryClose } from '@vegaprotocol/utils';
import { STORAGE_KEY, useTelemetryApproval } from './use-telemetry-approval';
const mockSetValue = jest.fn();
const mockRemoveValue = jest.fn();
jest.mock('@vegaprotocol/utils');
jest.mock('@vegaprotocol/react-helpers', () => ({
...jest.requireActual('@vegaprotocol/react-helpers'),
useLocalStorage: jest
.fn()
.mockImplementation(() => [false, mockSetValue, mockRemoveValue]),
}));
describe('useTelemetryApproval', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('hook should return proper array', () => {
const res = renderHook(() => useTelemetryApproval());
expect(res.result.current[0]).toEqual(false);
expect(res.result.current[1]).toEqual(expect.any(Function));
expect(useLocalStorage).toHaveBeenCalledWith(STORAGE_KEY);
});
it('hook should init stuff properly', async () => {
const res = renderHook(() => useTelemetryApproval());
await act(() => {
res.result.current[1](true);
});
await waitFor(() => {
expect(SentryInit).toHaveBeenCalled();
expect(mockSetValue).toHaveBeenCalledWith('1');
});
});
it('hook should close stuff properly', async () => {
const res = renderHook(() => useTelemetryApproval());
await act(() => {
res.result.current[1](false);
});
await waitFor(() => {
expect(SentryClose).toHaveBeenCalled();
expect(mockRemoveValue).toHaveBeenCalledWith();
});
});
});

View File

@ -0,0 +1,24 @@
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { useCallback } from 'react';
import { SentryInit, SentryClose } from '@vegaprotocol/utils';
import { ENV } from '../config';
export const STORAGE_KEY = 'vega_telemetry_approval';
export const useTelemetryApproval = (): [
value: boolean,
setValue: (value: boolean) => void
] => {
const [value, setValue, removeValue] = useLocalStorage(STORAGE_KEY);
const setApprove = useCallback(
(value: boolean) => {
if (value) {
SentryInit(ENV.dsn, ENV.envName);
return setValue('1');
}
SentryClose();
removeValue();
},
[setValue, removeValue]
);
return [Boolean(value), setApprove];
};

View File

@ -36,6 +36,7 @@ import { Navbar } from '../components/navbar';
import { ENV } from '../lib/config';
import { useDataProvider } from '@vegaprotocol/react-helpers';
import { activeOrdersProvider } from '@vegaprotocol/orders';
import { useTelemetryApproval } from '../lib/hooks/use-telemetry-approval';
const DEFAULT_TITLE = t('Welcome to Vega trading!');
@ -145,7 +146,10 @@ const PartyData = () => {
const MaybeConnectEagerly = () => {
useVegaEagerConnect(Connectors);
useEthereumEagerConnect(ENV.dsn);
const [isTelemetryApproved] = useTelemetryApproval();
useEthereumEagerConnect(
isTelemetryApproved ? { dsn: ENV.dsn, env: ENV.envName } : {}
);
const { pubKey, connect } = useVegaWallet();
const [searchParams] = useSearchParams();

View File

@ -26,12 +26,17 @@ const LazyPortfolio = dynamic(() => import('../client-pages/portfolio'), {
ssr: false,
});
const LazySettings = dynamic(() => import('../client-pages/settings'), {
ssr: false,
});
export enum Routes {
HOME = '/',
MARKET = '/markets',
MARKETS = '/markets/all',
PORTFOLIO = '/portfolio',
LIQUIDITY = '/liquidity',
LIQUIDITY = 'liquidity/:marketId',
SETTINGS = 'settings',
}
type ConsoleLinks = { [r in Routes]: (...args: string[]) => string };
@ -45,6 +50,7 @@ export const Links: ConsoleLinks = {
marketId
? trimEnd(`${Routes.LIQUIDITY}/${marketId}`, '/')
: Routes.LIQUIDITY,
[Routes.SETTINGS]: () => Routes.SETTINGS,
};
const routerConfig: RouteObject[] = [
@ -87,6 +93,10 @@ const routerConfig: RouteObject[] = [
path: Routes.PORTFOLIO,
element: <LazyPortfolio />,
},
{
path: Routes.SETTINGS,
element: <LazySettings />,
},
{
path: '*',
element: (

View File

@ -1,14 +1,9 @@
import * as Sentry from '@sentry/nextjs';
import { BrowserTracing } from '@sentry/tracing';
import { ENV } from './lib/config/env';
import { LocalStorage, SentryInit } from '@vegaprotocol/utils';
import { STORAGE_KEY } from './lib/hooks/use-telemetry-approval';
const { dsn } = ENV;
if (dsn) {
Sentry.init({
dsn,
integrations: [new BrowserTracing()],
tracesSampleRate: 1,
environment: ENV.envName,
});
const { dsn, envName } = ENV;
const isTelemetryApproved = !!LocalStorage.getItem(STORAGE_KEY);
if (dsn && isTelemetryApproved) {
SentryInit(dsn, envName);
}

View File

@ -1,24 +1,18 @@
import { useRef } from 'react';
import { BrowserTracing } from '@sentry/tracing';
import * as Sentry from '@sentry/browser';
import type { LocalLogger, LoggerConf } from '@vegaprotocol/utils';
import { localLoggerFactory } from '@vegaprotocol/utils';
import { localLoggerFactory, SentryInit } from '@vegaprotocol/utils';
interface Props extends LoggerConf {
export interface LoggerProps extends LoggerConf {
dsn?: string;
env?: string;
}
export const useLogger = ({ dsn, ...props }: Props) => {
export const useLogger = ({ dsn, env, ...props }: LoggerProps) => {
const logger = useRef<LocalLogger | null>(null);
if (!logger.current) {
logger.current = localLoggerFactory(props);
if (dsn) {
Sentry.init({
dsn,
integrations: [new BrowserTracing()],
tracesSampleRate: 1,
defaultIntegrations: false,
});
SentryInit(dsn, env);
}
}
return logger.current;

View File

@ -0,0 +1,41 @@
import type { ComponentStory, ComponentMeta } from '@storybook/react';
import className from 'classnames';
import { Divider } from './divider';
export default {
title: 'Divider',
component: Divider,
} as ComponentMeta<typeof Divider>;
const Template: ComponentStory<typeof Divider> = (args) => {
return (
<div
className={className('flex', {
'flex-col': args?.orientation !== 'vertical',
'h-[50px]': args?.orientation === 'vertical',
})}
>
<div
className={className(
'h-[50px]',
args?.orientation !== 'vertical' ? 'w-full' : 'w-1/2'
)}
/>
<Divider orientation={args?.orientation} />
<div
className={className(
'h-[50px]',
args?.orientation !== 'vertical' ? 'w-full' : 'w-2/2'
)}
/>
</div>
);
};
export const Default = Template.bind({});
Default.args = {};
export const Vertical = Template.bind({});
Vertical.args = {
orientation: 'vertical',
};

View File

@ -0,0 +1,19 @@
import { forwardRef } from 'react';
import * as Separator from '@radix-ui/react-separator';
interface DividerProps {
orientation?: 'horizontal' | 'vertical';
decorative?: boolean;
}
export const Divider = forwardRef<HTMLDivElement, DividerProps>(
({ orientation = 'horizontal', decorative }, ref) => {
return (
<Separator.Root
ref={ref}
className="bg-neutral-700 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px data-[orientation=vertical]:mx-3 data-[orientation=horizontal]:my-3"
{...{ orientation, decorative }}
/>
);
}
);

View File

@ -0,0 +1 @@
export { Divider } from './divider';

View File

@ -9,6 +9,7 @@ export * from './callout';
export * from './checkbox';
export * from './copy-with-tooltip';
export * from './dialog';
export * from './divider';
export * from './drawer';
export * from './dropdown-menu';
export * from './form-group';
@ -37,6 +38,7 @@ export * from './simple-grid';
export * from './slider';
export * from './sparkline';
export * from './splash';
export * from './switch';
export * from './syntax-highlighter';
export * from './tabs';
export * from './text-area';

View File

@ -0,0 +1 @@
export { Switch } from './switch';

View File

@ -0,0 +1,31 @@
import type { Story, ComponentMeta } from '@storybook/react';
import type { SwitchProps } from './switch';
import { Switch } from './switch';
import { useState } from 'react';
export default {
component: Switch,
title: 'Switch',
} as ComponentMeta<typeof Switch>;
const Template: Story<SwitchProps> = (args) => {
const [checked, setChecked] = useState(args.checked || false);
return (
<Switch
{...args}
checked={checked}
onCheckedChange={(checked) => setChecked(checked)}
/>
);
};
export const Default = Template.bind({});
Default.args = {
name: 'switch',
};
export const WithTextLabel = Template.bind({});
WithTextLabel.args = {
name: 'switch',
labelText: 'Light mode',
};

View File

@ -0,0 +1,38 @@
import type { ReactNode } from 'react';
import { forwardRef } from 'react';
import * as RootSwitch from '@radix-ui/react-switch';
export interface SwitchProps {
name?: string;
onCheckedChange?: (checked: boolean) => void;
checked?: boolean;
disabled?: boolean;
labelText?: ReactNode | string;
}
export const Switch = forwardRef<HTMLButtonElement, SwitchProps>(
(
{ name = 'switch', labelText, onCheckedChange, checked = false, disabled },
ref
) => {
return (
<div className="flex items-center justify-start">
<RootSwitch.Root
className="w-[41px] h-[18px] rounded bg-vega-light-200 dark:bg-neutral-700 rounded-full relative data-[state=checked]:bg-vega-light-200 dark:data-[state=checked]:bg-neutral-700 outline-none cursor-default"
id={`switch-${name}`}
onCheckedChange={onCheckedChange}
checked={checked}
disabled={disabled}
ref={ref}
>
<RootSwitch.Thumb className="block w-[18px] h-[18px] bg-black dark:bg-white rounded-full transition-transform duration-100 translate-x-0.3 will-change-transform data-[state=checked]:translate-x-[23px]" />
</RootSwitch.Root>
{labelText && (
<label htmlFor={`switch-${name}`} className="ml-2">
{labelText}
</label>
)}
</div>
);
}
);

View File

@ -17,6 +17,7 @@ export const ThemeSwitcher = ({
onClick={() => setTheme()}
className={className}
data-testid="theme-switcher"
id="theme-switcher"
>
{theme === 'dark' && <SunIcon />}
{theme === 'light' && <MoonIcon />}

View File

@ -17,3 +17,4 @@ export * from './lib/remove-0x';
export * from './lib/remove-pagination-wrapper';
export * from './lib/time';
export * from './lib/validate';
export * from './lib/sentry-utils';

View File

@ -0,0 +1,26 @@
import * as Sentry from '@sentry/nextjs';
import { SentryInit, SentryClose } from './sentry-utils';
jest.mock('@sentry/nextjs');
describe('Sentry utlis', () => {
describe('SentryInit', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should initialize', () => {
SentryInit('sentry.dsn');
expect(Sentry.init).toHaveBeenCalled();
});
it('should do nothing', () => {
SentryInit('');
expect(Sentry.init).not.toHaveBeenCalled();
});
it('should close', () => {
SentryClose();
expect(Sentry.close).toHaveBeenCalled();
});
});
});

View File

@ -0,0 +1,15 @@
import * as Sentry from '@sentry/nextjs';
import { BrowserTracing } from '@sentry/tracing';
export const SentryInit = (dsn: string, env?: string) => {
if (dsn) {
Sentry.init({
dsn,
integrations: [new BrowserTracing()],
tracesSampleRate: 1,
environment: env || '',
});
}
};
export const SentryClose = () => Sentry.close();

View File

@ -1,3 +1,4 @@
import type { LoggerProps } from '@vegaprotocol/react-helpers';
import { useLocalStorage, useLogger } from '@vegaprotocol/react-helpers';
import type { Web3ReactHooks } from '@web3-react/core';
import { MetaMask } from '@web3-react/metamask';
@ -8,12 +9,12 @@ import { useWeb3ConnectStore } from './web3-connect-store';
export const ETHEREUM_EAGER_CONNECT = 'ethereum-eager-connect';
export const useEagerConnect = (sentryDsn?: string) => {
export const useEagerConnect = (loggerConf: LoggerProps) => {
const connectors = useWeb3ConnectStore((store) => store.connectors);
const [eagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
const attemptedRef = useRef(false);
const logger = useLogger({ dsn: sentryDsn });
const logger = useLogger(loggerConf);
useEffect(() => {
if (attemptedRef.current || 'Cypress' in window) return;

View File

@ -31,7 +31,9 @@
"@radix-ui/react-popover": "^1.0.3",
"@radix-ui/react-radio-group": "^1.1.1",
"@radix-ui/react-select": "^1.2.0",
"@radix-ui/react-separator": "^1.0.2",
"@radix-ui/react-slider": "^1.1.0",
"@radix-ui/react-switch": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.3",
"@sentry/nextjs": "^6.19.3",
@ -202,6 +204,8 @@
"*.{ts,tsx,js,jsx}": "yarn eslint --fix"
},
"resolutions": {
"graphql": "15.8.0"
"graphql": "15.8.0",
"//": "workaround storybook issue: https://github.com/storybookjs/storybook/issues/21642",
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.cd77847.0"
}
}

View File

@ -4609,6 +4609,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-slot" "1.0.1"
"@radix-ui/react-primitive@1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz#54e22f49ca59ba88d8143090276d50b93f8a7053"
integrity sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-slot" "1.0.1"
"@radix-ui/react-radio-group@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-1.1.1.tgz#564549b3e0a5905367dfe9adfe7b0e245cbdb640"
@ -4670,6 +4678,14 @@
aria-hidden "^1.1.1"
react-remove-scroll "2.5.5"
"@radix-ui/react-separator@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.0.2.tgz#52417c8bfae1e4ef87356b2f7bffbc3dbbeddf23"
integrity sha512-lZoAG/rS2jzb/OSvyBrpN3dmikw20ewmWx1GkM1VldbDyD0DACCbH9LIXSrqyS/2mE1VYKOHmyq5W90Dx4ryqA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.2"
"@radix-ui/react-slider@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-1.1.0.tgz#b3fdaca27619150e9e6067ad9f979a4535f68d5e"
@ -4696,6 +4712,20 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.0"
"@radix-ui/react-switch@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.0.2.tgz#e3d1b9fe18b6b1173aadc8b8e6efdc96a28a70f8"
integrity sha512-BcG/LKehxt36NXG0wPnoCitIfSMtU9Xo7BmythYA1PAMLtsMvW7kALfBzmduQoHTWcKr0AVcFyh0gChBUp9TiQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.0"
"@radix-ui/react-compose-refs" "1.0.0"
"@radix-ui/react-context" "1.0.0"
"@radix-ui/react-primitive" "1.0.2"
"@radix-ui/react-use-controllable-state" "1.0.0"
"@radix-ui/react-use-previous" "1.0.0"
"@radix-ui/react-use-size" "1.0.0"
"@radix-ui/react-tabs@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.2.tgz#8f5ec73ca41b151a413bdd6e00553408ff34ce07"
@ -6266,17 +6296,17 @@
unfetch "^4.2.0"
util-deprecate "^1.0.2"
"@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0":
version "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0"
resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0.tgz#3103532ff494fb7dc3cf835f10740ecf6a26c0f9"
integrity sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w==
"@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0", "@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.cd77847.0":
version "1.0.6--canary.9.cd77847.0"
resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.cd77847.0.tgz#35beed1bd0813569fc8852b372c92069fe74a448"
integrity sha512-I4oBYmnUCX5IsrZhg+ST72dubSIV4wdwY+SfqJiJ3NHvDpdb240ZjdHAmjIy/yJh5rh42Fl4jbG8Tr4SzwV53Q==
dependencies:
debug "^4.1.1"
endent "^2.0.1"
find-cache-dir "^3.3.1"
flat-cache "^3.0.4"
micromatch "^4.0.2"
react-docgen-typescript "^2.1.1"
react-docgen-typescript "^2.2.2"
tslib "^2.0.0"
"@storybook/react@6.5.10":
@ -20701,7 +20731,7 @@ react-copy-to-clipboard@^5.0.4:
copy-to-clipboard "^3.3.1"
prop-types "^15.8.1"
react-docgen-typescript@^2.1.1:
react-docgen-typescript@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c"
integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==