Skip to content

Commit

Permalink
feat: new components for network UI (#27085)
Browse files Browse the repository at this point in the history
## **Description**

This PR splits off the new UI components from
#26433. They support
the new UI for editing networks directly via the network picker.

- `MultiRpcEditModal` - A modal shown only to users who have multiple
networks for a given chain. Allows them to customize via the network
form if they don't like how we merged them.

<img width="321" alt="Screenshot 2024-09-11 at 4 32 42 PM"
src="https://github.com/user-attachments/assets/38623a28-a753-46c0-9e13-e6fb51b761bb">

- `DropdownEditor` - A generic dropdown for selecting, adding, and
deleting items. Currently shared by the editing experience for RPC
endpoints and block explorers.

<img width="305" alt="Screenshot 2024-09-11 at 4 34 40 PM"
src="https://github.com/user-attachments/assets/cbebcc56-9615-48ce-96ac-548b677c8320">

<img width="304" alt="Screenshot 2024-09-11 at 4 34 18 PM"
src="https://github.com/user-attachments/assets/bfa29f61-9e85-4314-96e5-5d181e1ef259">


- `AddBlockExplorerModal` - The sub page within the network form where
you add a block explorer

<img width="320" alt="Screenshot 2024-09-11 at 4 35 49 PM"
src="https://github.com/user-attachments/assets/78fb3bfe-5dcc-4303-be0e-f8d0be559985">


- `AddRpcUrlModal` - The sub page within the network form where you add
an RPC url

<img width="319" alt="Screenshot 2024-09-11 at 4 35 56 PM"
src="https://github.com/user-attachments/assets/5412cd87-2c39-4fb6-9163-1c540f7dd0ec">


- `RpcListItem` - A component representing a single RPC endpoint with a
list. Currently shared between selecting via the `SelectRpcUrlModal` and
editing via the RPC `DropdownEditor`

<img width="335" alt="Screenshot 2024-09-11 at 4 50 43 PM"
src="https://github.com/user-attachments/assets/249eeb2e-b09d-49f9-9d04-d232a18d6d59">

- `SelectRpcUrlModal` - The page used to switch RPC endpoints for a
chain.

<img width="334" alt="Screenshot 2024-09-11 at 4 52 09 PM"
src="https://github.com/user-attachments/assets/1aa66829-ed35-4549-8569-f5c0b61610c4">

Additionally some actions are modified to support new features used by
these components.


[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27085?quickstart=1)

## **Related issues**


## **Manual testing steps**

None of these are visible in the product yet, but will be after
#26433

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: sahar-fehri <[email protected]>
  • Loading branch information
bergeron and sahar-fehri authored Sep 12, 2024
1 parent b305de8 commit daacc1a
Show file tree
Hide file tree
Showing 37 changed files with 1,653 additions and 98 deletions.
3 changes: 0 additions & 3 deletions app/_locales/de/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/el/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 15 additions & 3 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/es/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/fr/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/hi/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/id/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/ja/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/ko/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/pt/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/ru/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/tl/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/tr/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/vi/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions app/_locales/zh_CN/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`MultiRpcEditModal renders correctly with required props 1`] = `
<body>
<div
id="popover-content"
/>
<div />
<div
class="mm-modal"
data-testid="multi-rpc-edit-modal"
>
<div
aria-hidden="true"
class="mm-box mm-modal-overlay mm-box--width-full mm-box--height-full mm-box--background-color-overlay-default"
/>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
<div
data-focus-lock-disabled="false"
>
<div
class="mm-box mm-modal-content mm-box--padding-top-4 mm-box--sm:padding-top-8 mm-box--md:padding-top-12 mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--sm:padding-bottom-8 mm-box--md:padding-bottom-12 mm-box--padding-left-4 mm-box--display-flex mm-box--justify-content-center mm-box--align-items-flex-start mm-box--width-screen mm-box--height-screen"
>
<section
aria-modal="true"
class="mm-box mm-modal-content__dialog mm-modal-content__dialog--size-sm mm-box--padding-top-4 mm-box--padding-bottom-4 mm-box--display-flex mm-box--flex-direction-column mm-box--width-full mm-box--background-color-background-default mm-box--rounded-lg"
role="dialog"
>
<div
class="mm-box mm-modal-body mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-flex mm-box--flex-direction-column"
>
<div
class="mm-box mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--rounded-sm"
>
<img
src="/images/networks1.png"
/>
</div>
<p
class="mm-box mm-text mm-text--body-md-bold mm-text--text-align-center mm-box--color-text-default"
>
updatedRpcForNetworks
</p>
<p
class="mm-box mm-text mm-text--body-md mm-text--text-align-center mm-box--padding-top-2 mm-box--color-text-default"
>
supportMultiRpcInformation
</p>
<div
class="mm-box mm-box--padding-bottom-6"
>
<div
class="mm-box mm-box--margin-top-4 mm-box--margin-bottom-1"
/>
</div>
</div>
<div
class="mm-box mm-modal-footer mm-box--padding-top-4 mm-box--padding-right-4 mm-box--padding-left-4"
>
<div
class="mm-box mm-container mm-container--max-width-sm mm-box--margin-right-auto mm-box--margin-left-auto mm-box--display-flex mm-box--gap-4 mm-box--flex-wrap-wrap mm-box--align-items-center"
>
<button
class="mm-box mm-text mm-button-base mm-button-base--size-lg mm-button-base--block mm-modal-footer__button mm-button-primary mm-text--body-md-medium mm-box--padding-0 mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-primary-inverse mm-box--background-color-primary-default mm-box--rounded-pill"
data-theme="light"
>
accept
</button>
</div>
</div>
</section>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
</div>
</body>
`;
113 changes: 113 additions & 0 deletions ui/components/app/multi-rpc-edit-modal/multi-rpc-edit-modal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { useI18nContext } from '../../../hooks/useI18nContext';
import MultiRpcEditModal from './multi-rpc-edit-modal';
import '@testing-library/jest-dom/extend-expect';

const mockStore = configureStore([thunk]);

const initialState = {
metamask: {
networkConfigurationsByChainId: {
'0x1': {
blockExplorerUrls: [],
chainId: '0x1',
defaultRpcEndpointIndex: 0,
name: 'Ethereum Mainnet',
nativeCurrency: 'ETH',
rpcEndpoints: [
{
name: 'Eth test 1',
networkClientId: '96d93309-dab5-45dd-9fff-0d9d7f0843cc',
type: 'custom',
url: 'https://eth-mainnet.public.blastapi.io',
},
{
networkClientId: 'mainnet',
type: 'infura',
url: 'https://mainnet.infura.io/v3/{infuraProjectId}',
},
{
name: 'Alchemyyyy',
networkClientId: '40cd2a17-1085-4077-8ffb-1ea1bdc65289',
type: 'custom',
url: 'https://eth-mainnet.g.alchemy.com/v2/fCe_AL0z95whoz8H6hvdKvwNAE3goTa0',
},
{
name: 'onfinality',
networkClientId: '42d0d494-b92f-43f0-9270-51eb660d35a0',
type: 'custom',
url: 'https://eth.api.onfinality.io/public',
},
{
name: 'mevBlocker',
networkClientId: '53107ebb-6184-44b5-ae53-057772795de7',
type: 'custom',
url: 'https://rpc.mevblocker.io',
},
],
},
},
},
TransactionController: {
transactions: [
{
chainId: '0x1',
history: [{ networkClientId: 'mainnet' }],
},
],
},
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const setup = (props: any) => {
const store = mockStore(initialState);
return render(
<Provider store={store}>
<MultiRpcEditModal {...props} />
</Provider>,
);
};

jest.mock('../../../hooks/useI18nContext', () => ({
useI18nContext: jest.fn(),
}));

describe('MultiRpcEditModal', () => {
const useI18nContextMock = useI18nContext as jest.Mock;

beforeEach(() => {
useI18nContextMock.mockReturnValue((key: string) => key);
});

afterEach(() => {
jest.clearAllMocks();
});

it('renders correctly with required props', () => {
const onCloseMock = jest.fn();

const { baseElement } = setup({
isOpen: true,
onClose: onCloseMock,
});
expect(baseElement).toMatchSnapshot();
});

it('renders the modal and displays the network information', () => {
const onCloseMock = jest.fn();

setup({
isOpen: true,
onClose: onCloseMock,
});

expect(screen.getByTestId('multi-rpc-edit-modal')).toBeInTheDocument();
// TODO: enable with network controller v21 upgrade after `getNetworkConfigurationsByChainId` is implemented
// expect(screen.getByText('Ethereum Mainnet')).toBeInTheDocument();
expect(screen.getByText('supportMultiRpcInformation')).toBeInTheDocument();
});
});
Loading

0 comments on commit daacc1a

Please sign in to comment.