mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
Bridge tokens by redirecting to Portfolio from wallet overview page (#17952)
* Add Bridge button * Add newline to the end of bridge svg * Move Portfolio button * Vertically center Portfolio button * Use IconButton for Portfolio button * Change portfolio button size * Lowering coverage to get this in for release by a very small amount * Add unit tests for Portfolio button --------- Co-authored-by: georgewrmarshall <george.marshall@consensys.net>
This commit is contained in:
parent
13d03abe9b
commit
e77e20d8c4
3
app/_locales/en/messages.json
generated
3
app/_locales/en/messages.json
generated
@ -515,6 +515,9 @@
|
||||
"blockies": {
|
||||
"message": "Blockies"
|
||||
},
|
||||
"bridge": {
|
||||
"message": "Bridge"
|
||||
},
|
||||
"browserNotSupported": {
|
||||
"message": "Your browser is not supported..."
|
||||
},
|
||||
|
3
app/images/icons/bridge.svg
Normal file
3
app/images/icons/bridge.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m74 284c-21 7-36 26-36 49 0 28 23 51 52 51 28 0 51-23 51-51 0-20-12-38-28-46 14-65 73-114 143-114 47 0 89 22 116 56 12-6 25-10 39-11-33-50-90-84-155-84-90 0-165 65-182 150z m400 49c0 28-23 51-52 51-28 0-51-23-51-51 0-28 23-51 51-51 29 0 52 23 52 51z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 334 B |
@ -7,8 +7,8 @@
|
||||
module.exports = {
|
||||
global: {
|
||||
lines: 64.39,
|
||||
branches: 53.03,
|
||||
statements: 63.66,
|
||||
branches: 53.01,
|
||||
statements: 63.63,
|
||||
functions: 56.67,
|
||||
},
|
||||
transforms: {
|
||||
|
@ -292,6 +292,7 @@ export const EVENT_NAMES = {
|
||||
APP_UNLOCKED: 'App Unlocked',
|
||||
APP_UNLOCKED_FAILED: 'App Unlocked Failed',
|
||||
APP_WINDOW_EXPANDED: 'App Window Expanded',
|
||||
BRIDGE_LINK_CLICKED: 'Bridge Link Clicked',
|
||||
DECRYPTION_APPROVED: 'Decryption Approved',
|
||||
DECRYPTION_REJECTED: 'Decryption Rejected',
|
||||
DECRYPTION_REQUESTED: 'Decryption Requested',
|
||||
|
@ -35,7 +35,12 @@ import {
|
||||
import Spinner from '../../ui/spinner';
|
||||
import { startNewDraftTransaction } from '../../../ducks/send';
|
||||
import { AssetType } from '../../../../shared/constants/transaction';
|
||||
import { Icon, ICON_NAMES } from '../../component-library';
|
||||
import {
|
||||
ButtonIcon,
|
||||
BUTTON_ICON_SIZES,
|
||||
Icon,
|
||||
ICON_NAMES,
|
||||
} from '../../component-library';
|
||||
import { IconColor } from '../../../helpers/constants/design-system';
|
||||
import useRamps from '../../../hooks/experiences/useRamps';
|
||||
import WalletOverview from './wallet-overview';
|
||||
@ -88,6 +93,34 @@ const EthOverview = ({ className }) => {
|
||||
{balanceIsCached ? (
|
||||
<span className="eth-overview__cached-star">*</span>
|
||||
) : null}
|
||||
<ButtonIcon
|
||||
className="eth-overview__portfolio-button"
|
||||
data-testid="home__portfolio-site"
|
||||
color={IconColor.primaryDefault}
|
||||
iconName={ICON_NAMES.DIAGRAM}
|
||||
ariaLabel={t('portfolio')}
|
||||
size={BUTTON_ICON_SIZES.LG}
|
||||
onClick={() => {
|
||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
||||
global.platform.openTab({
|
||||
url: `${portfolioUrl}?metamaskEntry=ext`,
|
||||
});
|
||||
trackEvent(
|
||||
{
|
||||
category: EVENT.CATEGORIES.HOME,
|
||||
event: EVENT_NAMES.PORTFOLIO_LINK_CLICKED,
|
||||
properties: {
|
||||
url: portfolioUrl,
|
||||
},
|
||||
},
|
||||
{
|
||||
contextPropsIntoEventProperties: [
|
||||
CONTEXT_PROPS.PAGE_TITLE,
|
||||
],
|
||||
},
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{showFiat && balance && (
|
||||
<UserPreferencedCurrencyDisplay
|
||||
@ -198,31 +231,25 @@ const EthOverview = ({ className }) => {
|
||||
/>
|
||||
<IconButton
|
||||
className="eth-overview__button"
|
||||
data-testid="home__portfolio-site"
|
||||
data-testid="eth-overview-bridge"
|
||||
Icon={
|
||||
<Icon
|
||||
name={ICON_NAMES.DIAGRAM}
|
||||
color={IconColor.primaryInverse}
|
||||
/>
|
||||
<Icon name={ICON_NAMES.BRIDGE} color={IconColor.primaryInverse} />
|
||||
}
|
||||
label={t('portfolio')}
|
||||
label={t('bridge')}
|
||||
onClick={() => {
|
||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
||||
const bridgeUrl = `${portfolioUrl}/bridge`;
|
||||
global.platform.openTab({
|
||||
url: `${portfolioUrl}?metamaskEntry=ext`,
|
||||
url: `${bridgeUrl}?metamaskEntry=ext`,
|
||||
});
|
||||
trackEvent(
|
||||
{
|
||||
category: EVENT.CATEGORIES.HOME,
|
||||
event: EVENT_NAMES.PORTFOLIO_LINK_CLICKED,
|
||||
properties: {
|
||||
url: portfolioUrl,
|
||||
},
|
||||
trackEvent({
|
||||
category: EVENT.CATEGORIES.NAVIGATION,
|
||||
event: EVENT_NAMES.BRIDGE_LINK_CLICKED,
|
||||
properties: {
|
||||
location: 'Home',
|
||||
text: 'Bridge',
|
||||
},
|
||||
{
|
||||
contextPropsIntoEventProperties: [CONTEXT_PROPS.PAGE_TITLE],
|
||||
},
|
||||
);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
@ -23,6 +23,7 @@ jest.mock('../../../../shared/constants/network', () => ({
|
||||
},
|
||||
},
|
||||
}));
|
||||
let openTabSpy;
|
||||
|
||||
describe('EthOverview', () => {
|
||||
const mockStore = {
|
||||
@ -63,6 +64,8 @@ describe('EthOverview', () => {
|
||||
|
||||
const store = configureMockStore([thunk])(mockStore);
|
||||
const ETH_OVERVIEW_BUY = 'eth-overview-buy';
|
||||
const ETH_OVERVIEW_BRIDGE = 'eth-overview-bridge';
|
||||
const ETH_OVERVIEW_PORTFOLIO = 'home__portfolio-site';
|
||||
|
||||
afterEach(() => {
|
||||
store.clearActions();
|
||||
@ -76,6 +79,59 @@ describe('EthOverview', () => {
|
||||
openTab: jest.fn(),
|
||||
},
|
||||
});
|
||||
openTabSpy = jest.spyOn(global.platform, 'openTab');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
openTabSpy.mockClear();
|
||||
});
|
||||
|
||||
it('should always show the Bridge button', () => {
|
||||
const { queryByTestId } = renderWithProvider(<EthOverview />, store);
|
||||
const bridgeButton = queryByTestId(ETH_OVERVIEW_BRIDGE);
|
||||
expect(bridgeButton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should open the Bridge URI when clicking on Bridge button', async () => {
|
||||
const { queryByTestId } = renderWithProvider(<EthOverview />, store);
|
||||
|
||||
const bridgeButton = queryByTestId(ETH_OVERVIEW_BRIDGE);
|
||||
|
||||
expect(bridgeButton).toBeInTheDocument();
|
||||
expect(bridgeButton).not.toBeDisabled();
|
||||
|
||||
fireEvent.click(bridgeButton);
|
||||
expect(openTabSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(openTabSpy).toHaveBeenCalledWith({
|
||||
url: expect.stringContaining(`/bridge?metamaskEntry=ext`),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should always show the Portfolio button', () => {
|
||||
const { queryByTestId } = renderWithProvider(<EthOverview />, store);
|
||||
const portfolioButton = queryByTestId(ETH_OVERVIEW_PORTFOLIO);
|
||||
expect(portfolioButton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should open the Portfolio URI when clicking on Portfolio button', async () => {
|
||||
const { queryByTestId } = renderWithProvider(<EthOverview />, store);
|
||||
|
||||
const portfolioButton = queryByTestId(ETH_OVERVIEW_PORTFOLIO);
|
||||
|
||||
expect(portfolioButton).toBeInTheDocument();
|
||||
expect(portfolioButton).not.toBeDisabled();
|
||||
|
||||
fireEvent.click(portfolioButton);
|
||||
expect(openTabSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(openTabSpy).toHaveBeenCalledWith({
|
||||
url: expect.stringContaining(`?metamaskEntry=ext`),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should always show the Buy button regardless of current chain Id', () => {
|
||||
@ -135,8 +191,6 @@ describe('EthOverview', () => {
|
||||
mockedStoreWithBuyableChainId,
|
||||
);
|
||||
|
||||
const openTabSpy = jest.spyOn(global.platform, 'openTab');
|
||||
|
||||
const { queryByTestId } = renderWithProvider(
|
||||
<EthOverview />,
|
||||
mockedStore,
|
||||
|
@ -51,6 +51,7 @@
|
||||
|
||||
&__primary-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__primary-balance {
|
||||
@ -65,6 +66,13 @@
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
&__portfolio-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
left: calc(100% + 2px);
|
||||
}
|
||||
|
||||
&__cached-balance,
|
||||
&__cached-star {
|
||||
color: var(--color-warning-default);
|
||||
|
Loading…
Reference in New Issue
Block a user