mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Network Form Design and switch to full screen enhancements (#12302)
This commit is contained in:
parent
e951fe6a64
commit
532927368d
@ -1258,7 +1258,6 @@ const state = {
|
||||
ledger: "m/44'/60'/0'/0/0",
|
||||
},
|
||||
networksTabSelectedRpcUrl: '',
|
||||
networksTabIsInAddMode: false,
|
||||
loadingMethodData: false,
|
||||
show3BoxModalAfterImport: false,
|
||||
threeBoxLastUpdated: null,
|
||||
|
@ -620,9 +620,6 @@
|
||||
"newContract": {
|
||||
"message": "አዲስ ኮንትራት"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "አዲስ አውታረ መረብ"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "አዲስ የይለፍ ቃል (ቢያንስ 8 ቁምፊዎች)"
|
||||
},
|
||||
|
@ -616,9 +616,6 @@
|
||||
"newContract": {
|
||||
"message": "عقد جديد"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "شبكة جديدة"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "كلمة مرور جديدة (8 أحرف كحد أدنى)"
|
||||
},
|
||||
|
@ -619,9 +619,6 @@
|
||||
"newContract": {
|
||||
"message": "Нов договор"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Нова мрежа"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Нова парола (мин. 8 символа)"
|
||||
},
|
||||
|
@ -623,9 +623,6 @@
|
||||
"newContract": {
|
||||
"message": "নতুন কন্ট্র্যাক্ট"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "নতুন নেটওয়ার্ক"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "নতুন পাসওয়ার্ড (অন্তত 8 অক্ষরের)"
|
||||
},
|
||||
|
@ -607,9 +607,6 @@
|
||||
"newContract": {
|
||||
"message": "Nou Contracte"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nova Xarxa"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nova contrasenya (mínim 8 caràcters)"
|
||||
},
|
||||
|
@ -607,9 +607,6 @@
|
||||
"newContract": {
|
||||
"message": "Ny Kontrakt"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nyt Netværk"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Ny adgangskode (min. 8 tegn)"
|
||||
},
|
||||
|
@ -602,9 +602,6 @@
|
||||
"newContract": {
|
||||
"message": "Neuer Smart Contract"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Neues Netzwerk"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Neues Passwort (min. 8 Zeichen)"
|
||||
},
|
||||
|
@ -620,9 +620,6 @@
|
||||
"newContract": {
|
||||
"message": "Νέα Σύμβαση"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Νέο Δίκτυο"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Νέος Κωδικός Πρόσβασης (ελάχιστο 8 χαρακτήρες)"
|
||||
},
|
||||
|
@ -43,6 +43,9 @@
|
||||
"activityLog": {
|
||||
"message": "activity log"
|
||||
},
|
||||
"addANetwork": {
|
||||
"message": "Add a network"
|
||||
},
|
||||
"addAcquiredTokens": {
|
||||
"message": "Add the tokens you've acquired using MetaMask"
|
||||
},
|
||||
@ -1517,8 +1520,8 @@
|
||||
"newContract": {
|
||||
"message": "New Contract"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "New Network"
|
||||
"newNetworkAdded": {
|
||||
"message": "“$1” was successfully added!"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "New password (min 8 chars)"
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Contrato nuevo"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Red nueva"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Contraseña nueva (mín. de 8 caracteres)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Contrato nuevo"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Red nueva"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Contraseña nueva (mín. de 8 caracteres)"
|
||||
},
|
||||
|
@ -613,9 +613,6 @@
|
||||
"newContract": {
|
||||
"message": "Uus kontakt"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Uus võrk"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Uus parool (vähemalt 8 tähemärki)"
|
||||
},
|
||||
|
@ -623,9 +623,6 @@
|
||||
"newContract": {
|
||||
"message": "قرارداد جدید"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "شبکه جدید"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "رمز عبور جدید (حداقل 8 حرف)"
|
||||
},
|
||||
|
@ -623,9 +623,6 @@
|
||||
"newContract": {
|
||||
"message": "Uusi sopimus"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Uusi verkko"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Uusi salasana (väh. 8 merkkiä)"
|
||||
},
|
||||
|
@ -557,9 +557,6 @@
|
||||
"newContract": {
|
||||
"message": "Bagong Contract"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Bagong Network"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Bagong Password (min 8 char)"
|
||||
},
|
||||
|
@ -608,9 +608,6 @@
|
||||
"newContract": {
|
||||
"message": "Nouveau contrat"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nouveau réseau"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nouveau mot de passe (min 8 caractères)"
|
||||
},
|
||||
|
@ -620,9 +620,6 @@
|
||||
"newContract": {
|
||||
"message": "חוזה חדש"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "רשת חדשה"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "ססמה חדשה (לפחות 8 תווים)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "नया अनुबंध"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "नया नेटवर्क"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "नया पासवर्ड (न्यूनतम 8 वर्ण)"
|
||||
},
|
||||
|
@ -616,9 +616,6 @@
|
||||
"newContract": {
|
||||
"message": "Novi ugovor"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nova mreža"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nova lozinka (najmanje osam znakova)"
|
||||
},
|
||||
|
@ -616,9 +616,6 @@
|
||||
"newContract": {
|
||||
"message": "Új szerződés"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Új hálózat"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Új jelszó (minimum 8 karakter)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Kontrak Baru"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Jaringan Baru"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Kata sandi baru (min. 8 karakter)"
|
||||
},
|
||||
|
@ -1007,9 +1007,6 @@
|
||||
"newContract": {
|
||||
"message": "Nuovo Contratto"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nuova Rete"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nuova Password (minimo 8 caratteri)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "新しいコントラクト"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "新しいネットワーク"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "新しいパスワード (最低 8 文字)"
|
||||
},
|
||||
|
@ -623,9 +623,6 @@
|
||||
"newContract": {
|
||||
"message": "ಹೊಸ ಒಪ್ಪಂದ"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "ಹೊಸ ನೆಟ್ವರ್ಕ್"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "ಹೊಸ ಪಾಸ್ವರ್ಡ್ (ಕನಿಷ್ಟ 8 ಅಕ್ಷರಗಳು)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "새 계약"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "새 네트워크"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "새 암호(8자 이상)"
|
||||
},
|
||||
|
@ -623,9 +623,6 @@
|
||||
"newContract": {
|
||||
"message": "Nauja sutartis"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Naujas tinklas"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Naujas slaptažodis (bent 8 ženklai)"
|
||||
},
|
||||
|
@ -619,9 +619,6 @@
|
||||
"newContract": {
|
||||
"message": "Jauns līgums"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Jauns tīkls"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Jauna parole (vism. 8 rakstzīmes)"
|
||||
},
|
||||
|
@ -603,9 +603,6 @@
|
||||
"newContract": {
|
||||
"message": "Kontrak Baru"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Rangkaian Baru"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Kata Laluan Baru (min 8 aks)"
|
||||
},
|
||||
|
@ -610,9 +610,6 @@
|
||||
"newContract": {
|
||||
"message": "Ny kontaktperson"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nytt nettverk "
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nytt passord (minimum 8 tegn)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Bagong Kontrata"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Bagong Network"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Bagong password (min na 8 char)"
|
||||
},
|
||||
|
@ -620,9 +620,6 @@
|
||||
"newContract": {
|
||||
"message": "Nowy kontrakt"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nowa sieć"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nowe hasło (min. 8 znaków)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Novo contrato"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nova rede"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nova senha (mín. 8 caract.)"
|
||||
},
|
||||
|
@ -610,9 +610,6 @@
|
||||
"newContract": {
|
||||
"message": "Contract nou"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Rețea nouă"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Parola Nouă (minimum 8 caractere)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Новый контракт"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Новая сеть"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Новый пароль (мин.8 знаков)"
|
||||
},
|
||||
|
@ -595,9 +595,6 @@
|
||||
"newContract": {
|
||||
"message": "Nový kontrakt"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nová sieť"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nové heslo (min 8 znaků)"
|
||||
},
|
||||
|
@ -611,9 +611,6 @@
|
||||
"newContract": {
|
||||
"message": "Nova pogodba"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Novo omrežje"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Novo geslo (min 8 znakov)"
|
||||
},
|
||||
|
@ -614,9 +614,6 @@
|
||||
"newContract": {
|
||||
"message": "Novi ugovor"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nova mreža"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nova lozinka (minimalno 8 karaktera)"
|
||||
},
|
||||
|
@ -607,9 +607,6 @@
|
||||
"newContract": {
|
||||
"message": "Nytt kontrakt"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Nytt nätverk"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nytt lösenord (minst 8 tecken)"
|
||||
},
|
||||
|
@ -601,9 +601,6 @@
|
||||
"newContract": {
|
||||
"message": "Mkataba Mpya"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Mtandao Mpya"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Nenosiri Jipya (kiwango cha chini herufi 8)"
|
||||
},
|
||||
|
@ -1001,9 +1001,6 @@
|
||||
"newContract": {
|
||||
"message": "Bagong Kontrata"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Bagong Network"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Bagong password (min na 8 char)"
|
||||
},
|
||||
|
@ -623,9 +623,6 @@
|
||||
"newContract": {
|
||||
"message": "Новий контракт"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Нова мережа"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Новий пароль (мінімум 8 символів)"
|
||||
},
|
||||
|
@ -1193,9 +1193,6 @@
|
||||
"newContract": {
|
||||
"message": "Hợp đồng mới"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "Mạng mới"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "Mật khẩu mới (tối thiểu 8 ký tự)"
|
||||
},
|
||||
|
@ -1004,9 +1004,6 @@
|
||||
"newContract": {
|
||||
"message": "新合约"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "新增网络"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "新密码(至少 8 个字符)"
|
||||
},
|
||||
|
@ -629,9 +629,6 @@
|
||||
"newContract": {
|
||||
"message": "建立新合約"
|
||||
},
|
||||
"newNetwork": {
|
||||
"message": "新增網路"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "新密碼(至少8個字元)"
|
||||
},
|
||||
|
3
app/images/check_circle.svg
Normal file
3
app/images/check_circle.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.75 8C15.75 3.75 12.25 0.25 8 0.25C3.71875 0.25 0.25 3.75 0.25 8C0.25 12.2812 3.71875 15.75 8 15.75C12.25 15.75 15.75 12.2812 15.75 8ZM7.09375 12.125C6.90625 12.3125 6.5625 12.3125 6.375 12.125L3.125 8.875C2.9375 8.6875 2.9375 8.34375 3.125 8.15625L3.84375 7.46875C4.03125 7.25 4.34375 7.25 4.53125 7.46875L6.75 9.65625L11.4375 4.96875C11.625 4.75 11.9375 4.75 12.125 4.96875L12.8438 5.65625C13.0312 5.84375 13.0312 6.1875 12.8438 6.375L7.09375 12.125Z" fill="#4CD964"/>
|
||||
</svg>
|
After Width: | Height: | Size: 586 B |
@ -32,7 +32,7 @@ describe('Stores custom RPC history', function () {
|
||||
|
||||
await driver.clickElement({ text: 'Custom RPC', tag: 'span' });
|
||||
|
||||
await driver.findElement('.settings-page__sub-header-text');
|
||||
await driver.findElement('.add-network-form__sub-header-text');
|
||||
|
||||
const customRpcInputs = await driver.findElements('input[type="text"]');
|
||||
const networkNameInput = customRpcInputs[0];
|
||||
@ -48,7 +48,7 @@ describe('Stores custom RPC history', function () {
|
||||
await chainIdInput.clear();
|
||||
await chainIdInput.sendKeys(chainId.toString());
|
||||
|
||||
await driver.clickElement('.network-form__footer .btn-primary');
|
||||
await driver.clickElement('.add-network-form__footer .btn-primary');
|
||||
await driver.findElement({ text: networkName, tag: 'span' });
|
||||
},
|
||||
);
|
||||
@ -73,7 +73,7 @@ describe('Stores custom RPC history', function () {
|
||||
|
||||
await driver.clickElement({ text: 'Custom RPC', tag: 'span' });
|
||||
|
||||
await driver.findElement('.settings-page__sub-header-text');
|
||||
await driver.findElement('.add-network-form__sub-header-text');
|
||||
|
||||
const customRpcInputs = await driver.findElements('input[type="text"]');
|
||||
const rpcUrlInput = customRpcInputs[1];
|
||||
@ -108,7 +108,7 @@ describe('Stores custom RPC history', function () {
|
||||
|
||||
await driver.clickElement({ text: 'Custom RPC', tag: 'span' });
|
||||
|
||||
await driver.findElement('.settings-page__sub-header-text');
|
||||
await driver.findElement('.add-network-form__sub-header-text');
|
||||
|
||||
const customRpcInputs = await driver.findElements('input[type="text"]');
|
||||
const rpcUrlInput = customRpcInputs[1];
|
||||
@ -192,7 +192,9 @@ describe('Stores custom RPC history', function () {
|
||||
await driver.clickElement({ text: 'Custom RPC', tag: 'span' });
|
||||
|
||||
// cancel new custom rpc
|
||||
await driver.clickElement('.network-form__footer button.btn-secondary');
|
||||
await driver.clickElement(
|
||||
'.add-network-form__footer button.btn-secondary',
|
||||
);
|
||||
|
||||
const networkListItems = await driver.findClickableElements(
|
||||
'.networks-tab__networks-list-name',
|
||||
|
@ -5,10 +5,7 @@ import { withRouter } from 'react-router-dom';
|
||||
import { compose } from 'redux';
|
||||
import * as actions from '../../../store/actions';
|
||||
import { openAlert as displayInvalidCustomNetworkAlert } from '../../../ducks/alerts/invalid-custom-network';
|
||||
import {
|
||||
NETWORKS_ROUTE,
|
||||
NETWORKS_FORM_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
import { ADD_NETWORK_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app';
|
||||
import { NETWORK_TYPE_RPC } from '../../../../shared/constants/network';
|
||||
import { isPrefixedFormattedHexString } from '../../../../shared/modules/network.utils';
|
||||
@ -51,9 +48,6 @@ function mapDispatchToProps(dispatch) {
|
||||
dispatch(actions.setRpcTarget(target, chainId, ticker, nickname));
|
||||
},
|
||||
hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
|
||||
setNetworksTabAddMode: (isInAddMode) => {
|
||||
dispatch(actions.setNetworksTabAddMode(isInAddMode));
|
||||
},
|
||||
setSelectedSettingsRpcUrl: (url) => {
|
||||
dispatch(actions.setSelectedSettingsRpcUrl(url));
|
||||
},
|
||||
@ -88,7 +82,6 @@ class NetworkDropdown extends Component {
|
||||
setProviderType: PropTypes.func.isRequired,
|
||||
setRpcTarget: PropTypes.func.isRequired,
|
||||
hideNetworkDropdown: PropTypes.func.isRequired,
|
||||
setNetworksTabAddMode: PropTypes.func.isRequired,
|
||||
setSelectedSettingsRpcUrl: PropTypes.func.isRequired,
|
||||
frequentRpcListDetail: PropTypes.array.isRequired,
|
||||
networkDropdownOpen: PropTypes.bool.isRequired,
|
||||
@ -239,8 +232,8 @@ class NetworkDropdown extends Component {
|
||||
render() {
|
||||
const {
|
||||
provider: { rpcUrl: activeNetwork },
|
||||
setNetworksTabAddMode,
|
||||
setSelectedSettingsRpcUrl,
|
||||
history,
|
||||
} = this.props;
|
||||
const rpcListDetail = this.props.frequentRpcListDetail;
|
||||
const isOpen = this.props.networkDropdownOpen;
|
||||
@ -291,13 +284,12 @@ class NetworkDropdown extends Component {
|
||||
<DropdownMenuItem
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
onClick={() => {
|
||||
this.props.history.push(
|
||||
getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN
|
||||
? NETWORKS_ROUTE
|
||||
: NETWORKS_FORM_ROUTE,
|
||||
);
|
||||
if (getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN) {
|
||||
history.push(ADD_NETWORK_ROUTE);
|
||||
} else {
|
||||
global.platform.openExtensionInBrowser(ADD_NETWORK_ROUTE);
|
||||
}
|
||||
setSelectedSettingsRpcUrl('');
|
||||
setNetworksTabAddMode(true);
|
||||
}}
|
||||
style={DROP_DOWN_MENU_ITEM_STYLE}
|
||||
>
|
||||
|
@ -6,11 +6,13 @@ import InfoTooltipIcon from '../info-tooltip/info-tooltip-icon';
|
||||
|
||||
const CLASSNAME_WARNING = 'actionable-message--warning';
|
||||
const CLASSNAME_DANGER = 'actionable-message--danger';
|
||||
const CLASSNAME_INFO = 'actionable-message--info';
|
||||
const CLASSNAME_WITH_RIGHT_BUTTON = 'actionable-message--with-right-button';
|
||||
|
||||
const typeHash = {
|
||||
warning: CLASSNAME_WARNING,
|
||||
danger: CLASSNAME_DANGER,
|
||||
info: CLASSNAME_INFO,
|
||||
default: '',
|
||||
};
|
||||
|
||||
|
@ -85,6 +85,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
&--info {
|
||||
background: $Green-000;
|
||||
border: 1px solid $Green-200;
|
||||
|
||||
.actionable-message__message {
|
||||
color: $Black-100;
|
||||
}
|
||||
}
|
||||
|
||||
&--left-aligned {
|
||||
.actionable-message__message,
|
||||
.actionable-message__actions {
|
||||
|
@ -37,7 +37,6 @@ export default function reduceApp(state = {}, action) {
|
||||
ledger: `m/44'/60'/0'/0/0`,
|
||||
},
|
||||
networksTabSelectedRpcUrl: '',
|
||||
networksTabIsInAddMode: false,
|
||||
loadingMethodData: false,
|
||||
show3BoxModalAfterImport: false,
|
||||
threeBoxLastUpdated: null,
|
||||
@ -50,6 +49,7 @@ export default function reduceApp(state = {}, action) {
|
||||
},
|
||||
gasLoadingAnimationIsShowing: false,
|
||||
ledgerWebHidConnectedStatus: WEBHID_CONNECTED_STATUSES.UNKNOWN,
|
||||
newNetworkAdded: '',
|
||||
...state,
|
||||
};
|
||||
|
||||
@ -279,10 +279,10 @@ export default function reduceApp(state = {}, action) {
|
||||
networksTabSelectedRpcUrl: action.value,
|
||||
};
|
||||
|
||||
case actionConstants.SET_NETWORKS_TAB_ADD_MODE:
|
||||
case actionConstants.SET_NEW_NETWORK_ADDED:
|
||||
return {
|
||||
...appState,
|
||||
networksTabIsInAddMode: action.value,
|
||||
newNetworkAdded: action.value,
|
||||
};
|
||||
|
||||
case actionConstants.LOADING_METHOD_DATA_STARTED:
|
||||
|
@ -11,6 +11,7 @@ const ABOUT_US_ROUTE = '/settings/about-us';
|
||||
const ALERTS_ROUTE = '/settings/alerts';
|
||||
const NETWORKS_ROUTE = '/settings/networks';
|
||||
const NETWORKS_FORM_ROUTE = '/settings/networks/form';
|
||||
const ADD_NETWORK_ROUTE = '/settings/networks/add-network';
|
||||
const CONTACT_LIST_ROUTE = '/settings/contact-list';
|
||||
const CONTACT_EDIT_ROUTE = '/settings/contact-list/edit-contact';
|
||||
const CONTACT_ADD_ROUTE = '/settings/contact-list/add-contact';
|
||||
@ -96,6 +97,7 @@ const PATH_NAME_MAP = {
|
||||
[ALERTS_ROUTE]: 'Alerts Settings Page',
|
||||
[NETWORKS_ROUTE]: 'Network Settings Page',
|
||||
[NETWORKS_FORM_ROUTE]: 'Network Settings Page Form',
|
||||
[ADD_NETWORK_ROUTE]: 'Add Network From Settings Page Form',
|
||||
[CONTACT_LIST_ROUTE]: 'Contact List Settings Page',
|
||||
[`${CONTACT_EDIT_ROUTE}/:address`]: 'Edit Contact Settings Page',
|
||||
[CONTACT_ADD_ROUTE]: 'Add Contact Settings Page',
|
||||
@ -200,6 +202,7 @@ export {
|
||||
CONTACT_VIEW_ROUTE,
|
||||
NETWORKS_ROUTE,
|
||||
NETWORKS_FORM_ROUTE,
|
||||
ADD_NETWORK_ROUTE,
|
||||
INITIALIZE_BACKUP_SEED_PHRASE_ROUTE,
|
||||
INITIALIZE_SEED_PHRASE_INTRO_ROUTE,
|
||||
CONNECT_ROUTE,
|
||||
|
@ -15,6 +15,9 @@ import { Tabs, Tab } from '../../components/ui/tabs';
|
||||
import { EthOverview } from '../../components/app/wallet-overview';
|
||||
import WhatsNewPopup from '../../components/app/whats-new-popup';
|
||||
import RecoveryPhraseReminder from '../../components/app/recovery-phrase-reminder';
|
||||
import ActionableMessage from '../../components/ui/actionable-message/actionable-message';
|
||||
import Typography from '../../components/ui/typography/typography';
|
||||
import { TYPOGRAPHY, FONT_WEIGHT } from '../../helpers/constants/design-system';
|
||||
|
||||
import { isBeta } from '../../helpers/utils/build-types';
|
||||
|
||||
@ -84,6 +87,8 @@ export default class Home extends PureComponent {
|
||||
setRecoveryPhraseReminderHasBeenShown: PropTypes.func.isRequired,
|
||||
setRecoveryPhraseReminderLastShown: PropTypes.func.isRequired,
|
||||
seedPhraseBackedUp: PropTypes.bool.isRequired,
|
||||
newNetworkAdded: PropTypes.string,
|
||||
setNewNetworkAdded: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
state = {
|
||||
@ -199,10 +204,36 @@ export default class Home extends PureComponent {
|
||||
originOfCurrentTab,
|
||||
disableWeb3ShimUsageAlert,
|
||||
infuraBlocked,
|
||||
newNetworkAdded,
|
||||
setNewNetworkAdded,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<MultipleNotifications>
|
||||
{newNetworkAdded ? (
|
||||
<ActionableMessage
|
||||
type="info"
|
||||
className="home__new-network-notification"
|
||||
message={
|
||||
<div className="home__new-network-notification-message">
|
||||
<img
|
||||
src="./images/check_circle.svg"
|
||||
className="home__new-network-notification-message--image"
|
||||
/>
|
||||
<Typography
|
||||
variant={TYPOGRAPHY.H7}
|
||||
fontWeight={FONT_WEIGHT.NORMAL}
|
||||
>
|
||||
{this.context.t('newNetworkAdded', [newNetworkAdded])}
|
||||
</Typography>
|
||||
<button
|
||||
className="fas fa-times home__close"
|
||||
title={t('close')}
|
||||
onClick={() => setNewNetworkAdded('')}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
{shouldShowWeb3ShimUsageNotification ? (
|
||||
<HomeNotification
|
||||
descriptionText={t('web3ShimUsageNotification', [
|
||||
|
@ -15,6 +15,7 @@ import {
|
||||
getShowWhatsNewPopup,
|
||||
getSortedNotificationsToShow,
|
||||
getShowRecoveryPhraseReminder,
|
||||
getNewNetworkAdded,
|
||||
} from '../../selectors';
|
||||
|
||||
import {
|
||||
@ -28,6 +29,7 @@ import {
|
||||
setAlertEnabledness,
|
||||
setRecoveryPhraseReminderHasBeenShown,
|
||||
setRecoveryPhraseReminderLastShown,
|
||||
setNewNetworkAdded,
|
||||
} from '../../store/actions';
|
||||
import { setThreeBoxLastUpdated, hideWhatsNewPopup } from '../../ducks/app/app';
|
||||
import { getWeb3ShimUsageAlertEnabledness } from '../../ducks/metamask/metamask';
|
||||
@ -112,6 +114,7 @@ const mapStateToProps = (state) => {
|
||||
showWhatsNewPopup: getShowWhatsNewPopup(state),
|
||||
showRecoveryPhraseReminder: getShowRecoveryPhraseReminder(state),
|
||||
seedPhraseBackedUp,
|
||||
newNetworkAdded: getNewNetworkAdded(state),
|
||||
};
|
||||
};
|
||||
|
||||
@ -141,6 +144,9 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
dispatch(setRecoveryPhraseReminderHasBeenShown()),
|
||||
setRecoveryPhraseReminderLastShown: (lastShown) =>
|
||||
dispatch(setRecoveryPhraseReminderLastShown(lastShown)),
|
||||
setNewNetworkAdded: (newNetwork) => {
|
||||
dispatch(setNewNetworkAdded(newNetwork));
|
||||
},
|
||||
});
|
||||
|
||||
export default compose(
|
||||
|
@ -133,4 +133,23 @@
|
||||
color: $primary-1;
|
||||
}
|
||||
}
|
||||
|
||||
&__new-network-notification {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
&__new-network-notification-message {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
&--image {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&__close {
|
||||
color: $ui-black;
|
||||
background: none;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@import 'network-form/index.scss';
|
||||
|
||||
.networks-tab {
|
||||
&__content {
|
||||
margin-top: 24px;
|
||||
@ -86,6 +88,7 @@
|
||||
@include H6;
|
||||
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__network-form-label-tooltip {
|
||||
|
76
ui/pages/settings/networks-tab/network-form/index.scss
Normal file
76
ui/pages/settings/networks-tab/network-form/index.scss
Normal file
@ -0,0 +1,76 @@
|
||||
.add-network-form {
|
||||
&__body {
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
&__subheader {
|
||||
@include H4;
|
||||
|
||||
padding: 16px 4px;
|
||||
border-bottom: 1px solid $alto;
|
||||
height: 72px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
&__subheader--break {
|
||||
margin-inline-start: 10px;
|
||||
}
|
||||
|
||||
&__sub-header-text {
|
||||
@include H4;
|
||||
|
||||
color: $ui-4;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&--warning {
|
||||
@include H7;
|
||||
|
||||
background-color: $Yellow-000;
|
||||
border: 1px solid $alert-1;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
padding: 12px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__form-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
&__form-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__network-form-row {
|
||||
padding-bottom: 30px;
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
padding: 0 0 0.75rem 0;
|
||||
width: 60%;
|
||||
|
||||
&-cancel-button {
|
||||
margin-right: 1.25rem;
|
||||
}
|
||||
|
||||
&-submit-button {
|
||||
margin-left: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,12 +23,12 @@ const FORM_STATE_KEYS = [
|
||||
export default class NetworkForm extends PureComponent {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func.isRequired,
|
||||
metricsEvent: PropTypes.func.isRequired,
|
||||
metricsEvent: PropTypes.func,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
editRpc: PropTypes.func.isRequired,
|
||||
showConfirmDeleteNetworkModal: PropTypes.func.isRequired,
|
||||
editRpc: PropTypes.func,
|
||||
showConfirmDeleteNetworkModal: PropTypes.func,
|
||||
rpcUrl: PropTypes.string,
|
||||
chainId: PropTypes.string,
|
||||
ticker: PropTypes.string,
|
||||
@ -36,12 +36,13 @@ export default class NetworkForm extends PureComponent {
|
||||
networkName: PropTypes.string,
|
||||
onClear: PropTypes.func.isRequired,
|
||||
setRpcTarget: PropTypes.func.isRequired,
|
||||
networksTabIsInAddMode: PropTypes.bool,
|
||||
isCurrentRpcTarget: PropTypes.bool,
|
||||
blockExplorerUrl: PropTypes.string,
|
||||
rpcPrefs: PropTypes.object,
|
||||
networksToRender: PropTypes.array,
|
||||
onAddNetwork: PropTypes.func.isRequired,
|
||||
networksToRender: PropTypes.array.isRequired,
|
||||
onAddNetwork: PropTypes.func,
|
||||
setNewNetworkAdded: PropTypes.func,
|
||||
addNewNetwork: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@ -63,10 +64,10 @@ export default class NetworkForm extends PureComponent {
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { networksTabIsInAddMode: prevAddMode } = prevProps;
|
||||
const { networksTabIsInAddMode } = this.props;
|
||||
const { addNewNetwork: prevAddMode } = prevProps;
|
||||
const { addNewNetwork } = this.props;
|
||||
|
||||
if (!prevAddMode && networksTabIsInAddMode) {
|
||||
if (!prevAddMode && addNewNetwork) {
|
||||
this.setState({
|
||||
rpcUrl: '',
|
||||
chainId: '',
|
||||
@ -95,7 +96,6 @@ export default class NetworkForm extends PureComponent {
|
||||
blockExplorerUrl: '',
|
||||
errors: {},
|
||||
});
|
||||
|
||||
// onClear will push the network settings route unless was pass false.
|
||||
// Since we call onClear to cause this component to be unmounted, the
|
||||
// route will already have been updated, and we avoid setting it twice.
|
||||
@ -166,7 +166,8 @@ export default class NetworkForm extends PureComponent {
|
||||
editRpc,
|
||||
rpcPrefs = {},
|
||||
onAddNetwork,
|
||||
networksTabIsInAddMode,
|
||||
setNewNetworkAdded,
|
||||
addNewNetwork,
|
||||
} = this.props;
|
||||
const {
|
||||
networkName,
|
||||
@ -199,7 +200,8 @@ export default class NetworkForm extends PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
if (networksTabIsInAddMode) {
|
||||
if (addNewNetwork) {
|
||||
setNewNetworkAdded(networkName);
|
||||
onAddNetwork();
|
||||
}
|
||||
} catch (error) {
|
||||
@ -211,9 +213,9 @@ export default class NetworkForm extends PureComponent {
|
||||
};
|
||||
|
||||
onCancel = () => {
|
||||
const { networksTabIsInAddMode, onClear } = this.props;
|
||||
const { addNewNetwork, onClear } = this.props;
|
||||
|
||||
if (networksTabIsInAddMode) {
|
||||
if (addNewNetwork) {
|
||||
onClear();
|
||||
} else {
|
||||
this.resetForm();
|
||||
@ -270,6 +272,7 @@ export default class NetworkForm extends PureComponent {
|
||||
}
|
||||
|
||||
renderFormTextField({
|
||||
className,
|
||||
fieldKey,
|
||||
textFieldId,
|
||||
onChange,
|
||||
@ -283,7 +286,7 @@ export default class NetworkForm extends PureComponent {
|
||||
const errorMessage = errors[fieldKey]?.msg || '';
|
||||
|
||||
return (
|
||||
<div className="networks-tab__network-form-row">
|
||||
<div className={className}>
|
||||
<div className="networks-tab__network-form-label">
|
||||
<div className="networks-tab__network-form-label-text">
|
||||
{this.context.t(optionalTextFieldKey || fieldKey)}
|
||||
@ -548,18 +551,8 @@ export default class NetworkForm extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
renderWarning() {
|
||||
renderAddNetworkForm() {
|
||||
const { t } = this.context;
|
||||
return (
|
||||
<div className="networks-tab__network-form-row--warning">
|
||||
{t('onlyAddTrustedNetworks')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { t } = this.context;
|
||||
const { viewOnly, isCurrentRpcTarget, networksTabIsInAddMode } = this.props;
|
||||
const {
|
||||
networkName,
|
||||
rpcUrl,
|
||||
@ -568,8 +561,115 @@ export default class NetworkForm extends PureComponent {
|
||||
blockExplorerUrl,
|
||||
} = this.state;
|
||||
|
||||
const deletable =
|
||||
!networksTabIsInAddMode && !isCurrentRpcTarget && !viewOnly;
|
||||
const isSubmitDisabled =
|
||||
this.hasErrors() || this.isSubmitting() || !rpcUrl || !chainId;
|
||||
|
||||
return (
|
||||
<div className="add-network-form__body">
|
||||
<div className="add-network-form__subheader">
|
||||
<span className="add-network-form__sub-header-text">
|
||||
{t('networks')}
|
||||
</span>
|
||||
<span>{' > '}</span>
|
||||
<div className="add-network-form__subheader--break">
|
||||
{t('addANetwork')}
|
||||
</div>
|
||||
</div>
|
||||
<div className="add-network-form__content">
|
||||
<div className="add-network-form__content--warning">
|
||||
{t('onlyAddTrustedNetworks')}
|
||||
</div>
|
||||
<div className="add-network-form__form-column">
|
||||
<div className="add-network-form__form-row">
|
||||
{this.renderFormTextField({
|
||||
className: 'add-network-form__network-form-row',
|
||||
fieldKey: 'networkName',
|
||||
textFieldId: 'network-name',
|
||||
onChange: this.setStateWithValue('networkName'),
|
||||
value: networkName,
|
||||
autoFocus: true,
|
||||
})}
|
||||
{this.renderFormTextField({
|
||||
className: 'add-network-form__network-form-row',
|
||||
fieldKey: 'rpcUrl',
|
||||
textFieldId: 'rpc-url',
|
||||
onChange: this.setStateWithValue(
|
||||
'rpcUrl',
|
||||
this.validateUrlRpcUrl,
|
||||
),
|
||||
value: rpcUrl,
|
||||
})}
|
||||
</div>
|
||||
<div className="add-network-form__form-row">
|
||||
{this.renderFormTextField({
|
||||
className: 'add-network-form__network-form-row',
|
||||
fieldKey: 'chainId',
|
||||
textFieldId: 'chainId',
|
||||
onChange: this.setStateWithValue(
|
||||
'chainId',
|
||||
this.validateChainIdOnChange.bind(this, rpcUrl),
|
||||
),
|
||||
value: chainId,
|
||||
tooltipText: t('networkSettingsChainIdDescription'),
|
||||
})}
|
||||
{this.renderFormTextField({
|
||||
className: 'add-network-form__network-form-row',
|
||||
fieldKey: 'symbol',
|
||||
textFieldId: 'network-ticker',
|
||||
onChange: this.setStateWithValue('ticker'),
|
||||
value: ticker,
|
||||
optionalTextFieldKey: 'optionalCurrencySymbol',
|
||||
})}
|
||||
</div>
|
||||
<div className="add-network-form__form-row">
|
||||
{this.renderFormTextField({
|
||||
className: 'add-network-form__network-form-row',
|
||||
fieldKey: 'blockExplorerUrl',
|
||||
textFieldId: 'block-explorer-url',
|
||||
onChange: this.setStateWithValue(
|
||||
'blockExplorerUrl',
|
||||
this.validateBlockExplorerURL,
|
||||
),
|
||||
value: blockExplorerUrl,
|
||||
optionalTextFieldKey: 'optionalBlockExplorerUrl',
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="add-network-form__footer">
|
||||
<Button
|
||||
type="secondary"
|
||||
onClick={this.onCancel}
|
||||
className="add-network-form__footer-cancel-button"
|
||||
>
|
||||
{t('cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={isSubmitDisabled}
|
||||
onClick={this.onSubmit}
|
||||
className="add-network-form__footer-submit-button"
|
||||
>
|
||||
{t('save')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderNetworkForm() {
|
||||
const { t } = this.context;
|
||||
const { viewOnly, isCurrentRpcTarget } = this.props;
|
||||
const {
|
||||
networkName,
|
||||
rpcUrl,
|
||||
chainId = '',
|
||||
ticker,
|
||||
blockExplorerUrl,
|
||||
} = this.state;
|
||||
|
||||
const deletable = !isCurrentRpcTarget && !viewOnly;
|
||||
|
||||
const isSubmitDisabled =
|
||||
this.hasErrors() ||
|
||||
this.isSubmitting() ||
|
||||
@ -579,21 +679,22 @@ export default class NetworkForm extends PureComponent {
|
||||
|
||||
return (
|
||||
<div className="networks-tab__network-form">
|
||||
{viewOnly ? null : this.renderWarning()}
|
||||
{this.renderFormTextField({
|
||||
className: 'networks-tab__network-form-row',
|
||||
fieldKey: 'networkName',
|
||||
textFieldId: 'network-name',
|
||||
onChange: this.setStateWithValue('networkName'),
|
||||
value: networkName,
|
||||
autoFocus: networksTabIsInAddMode,
|
||||
})}
|
||||
{this.renderFormTextField({
|
||||
className: 'networks-tab__network-form-row',
|
||||
fieldKey: 'rpcUrl',
|
||||
textFieldId: 'rpc-url',
|
||||
onChange: this.setStateWithValue('rpcUrl', this.validateUrlRpcUrl),
|
||||
value: rpcUrl,
|
||||
})}
|
||||
{this.renderFormTextField({
|
||||
className: 'networks-tab__network-form-row',
|
||||
fieldKey: 'chainId',
|
||||
textFieldId: 'chainId',
|
||||
onChange: this.setStateWithValue(
|
||||
@ -604,6 +705,7 @@ export default class NetworkForm extends PureComponent {
|
||||
tooltipText: viewOnly ? null : t('networkSettingsChainIdDescription'),
|
||||
})}
|
||||
{this.renderFormTextField({
|
||||
className: 'networks-tab__network-form-row',
|
||||
fieldKey: 'symbol',
|
||||
textFieldId: 'network-ticker',
|
||||
onChange: this.setStateWithValue('ticker'),
|
||||
@ -611,6 +713,7 @@ export default class NetworkForm extends PureComponent {
|
||||
optionalTextFieldKey: 'optionalCurrencySymbol',
|
||||
})}
|
||||
{this.renderFormTextField({
|
||||
className: 'networks-tab__network-form-row',
|
||||
fieldKey: 'blockExplorerUrl',
|
||||
textFieldId: 'block-explorer-url',
|
||||
onChange: this.setStateWithValue(
|
||||
@ -648,4 +751,11 @@ export default class NetworkForm extends PureComponent {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { addNewNetwork } = this.props;
|
||||
return addNewNetwork
|
||||
? this.renderAddNetworkForm()
|
||||
: this.renderNetworkForm();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { renderWithProvider } from '../../../../../test/jest/rendering';
|
||||
import { defaultNetworksData } from '../networks-tab.constants';
|
||||
import NetworkForm from '.';
|
||||
|
||||
const renderComponent = (props) => {
|
||||
const store = configureMockStore([])({ metamask: {} });
|
||||
return renderWithProvider(<NetworkForm {...props} />, store);
|
||||
};
|
||||
|
||||
const defaultNetworks = defaultNetworksData.map((network) => ({
|
||||
...network,
|
||||
viewOnly: true,
|
||||
}));
|
||||
|
||||
const propNewNetwork = {
|
||||
onClear: () => undefined,
|
||||
setRpcTarget: () => undefined,
|
||||
networksToRender: defaultNetworks,
|
||||
onAddNetwork: () => undefined,
|
||||
setNewNetworkAdded: () => undefined,
|
||||
addNewNetwork: true,
|
||||
};
|
||||
|
||||
const propNetworkDisplay = {
|
||||
editRpc: () => undefined,
|
||||
showConfirmDeleteNetworkModal: () => undefined,
|
||||
rpcUrl: 'http://localhost:8545',
|
||||
chainId: '1337',
|
||||
ticker: 'ETH',
|
||||
viewOnly: false,
|
||||
networkName: 'LocalHost',
|
||||
onClear: () => undefined,
|
||||
setRpcTarget: () => undefined,
|
||||
isCurrentRpcTarget: false,
|
||||
blockExplorerUrl: '',
|
||||
rpcPrefs: {},
|
||||
networksToRender: defaultNetworks,
|
||||
onAddNetwork: () => undefined,
|
||||
setNewNetworkAdded: () => undefined,
|
||||
addNewNetwork: false,
|
||||
};
|
||||
|
||||
describe('NetworkForm Component', () => {
|
||||
it('should render Add new network form correctly', () => {
|
||||
const { queryByText } = renderComponent(propNewNetwork);
|
||||
expect(queryByText('Network Name')).toBeInTheDocument();
|
||||
expect(queryByText('New RPC URL')).toBeInTheDocument();
|
||||
expect(queryByText('Chain ID')).toBeInTheDocument();
|
||||
expect(queryByText('Currency Symbol (optional)')).toBeInTheDocument();
|
||||
expect(queryByText('Block Explorer URL (optional)')).toBeInTheDocument();
|
||||
expect(queryByText('Cancel')).toBeInTheDocument();
|
||||
expect(queryByText('Save')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render network form correctly', () => {
|
||||
const { queryByText, getByDisplayValue } = renderComponent(
|
||||
propNetworkDisplay,
|
||||
);
|
||||
expect(queryByText('Network Name')).toBeInTheDocument();
|
||||
expect(queryByText('New RPC URL')).toBeInTheDocument();
|
||||
expect(queryByText('Chain ID')).toBeInTheDocument();
|
||||
expect(queryByText('Currency Symbol (optional)')).toBeInTheDocument();
|
||||
expect(queryByText('Block Explorer URL (optional)')).toBeInTheDocument();
|
||||
expect(queryByText('Delete')).toBeInTheDocument();
|
||||
expect(queryByText('Cancel')).toBeInTheDocument();
|
||||
expect(queryByText('Save')).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
getByDisplayValue(propNetworkDisplay.networkName),
|
||||
).toBeInTheDocument();
|
||||
expect(getByDisplayValue(propNetworkDisplay.rpcUrl)).toBeInTheDocument();
|
||||
expect(getByDisplayValue(propNetworkDisplay.chainId)).toBeInTheDocument();
|
||||
expect(getByDisplayValue(propNetworkDisplay.ticker)).toBeInTheDocument();
|
||||
expect(
|
||||
getByDisplayValue(propNetworkDisplay.blockExplorerUrl),
|
||||
).toBeInTheDocument();
|
||||
fireEvent.change(getByDisplayValue(propNetworkDisplay.networkName), {
|
||||
target: { value: 'LocalHost 8545' },
|
||||
});
|
||||
expect(getByDisplayValue('LocalHost 8545')).toBeInTheDocument();
|
||||
fireEvent.change(getByDisplayValue(propNetworkDisplay.chainId), {
|
||||
target: { value: '1' },
|
||||
});
|
||||
expect(
|
||||
queryByText('This Chain ID is currently used by the mainnet network.'),
|
||||
).toBeInTheDocument();
|
||||
|
||||
fireEvent.change(getByDisplayValue(propNetworkDisplay.rpcUrl), {
|
||||
target: { value: 'test' },
|
||||
});
|
||||
expect(
|
||||
queryByText('URLs require the appropriate HTTP/HTTPS prefix.'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -8,9 +8,10 @@ import {
|
||||
NETWORKS_ROUTE,
|
||||
NETWORKS_FORM_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
ADD_NETWORK_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
import ColorIndicator from '../../../components/ui/color-indicator';
|
||||
import { COLORS, SIZES } from '../../../helpers/constants/design-system';
|
||||
import { SIZES } from '../../../helpers/constants/design-system';
|
||||
import NetworkForm from './network-form';
|
||||
|
||||
export default class NetworksTab extends PureComponent {
|
||||
@ -23,10 +24,8 @@ export default class NetworksTab extends PureComponent {
|
||||
editRpc: PropTypes.func.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
networkIsSelected: PropTypes.bool,
|
||||
networksTabIsInAddMode: PropTypes.bool,
|
||||
networksToRender: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
selectedNetwork: PropTypes.object,
|
||||
setNetworksTabAddMode: PropTypes.func.isRequired,
|
||||
setRpcTarget: PropTypes.func.isRequired,
|
||||
setSelectedSettingsRpcUrl: PropTypes.func.isRequired,
|
||||
showConfirmDeleteNetworkModal: PropTypes.func.isRequired,
|
||||
@ -36,6 +35,8 @@ export default class NetworksTab extends PureComponent {
|
||||
history: PropTypes.object.isRequired,
|
||||
shouldRenderNetworkForm: PropTypes.bool.isRequired,
|
||||
isFullScreen: PropTypes.bool.isRequired,
|
||||
setNewNetworkAdded: PropTypes.func.isRequired,
|
||||
addNewNetwork: PropTypes.bool,
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -47,7 +48,7 @@ export default class NetworksTab extends PureComponent {
|
||||
}
|
||||
|
||||
renderSubHeader() {
|
||||
const { setSelectedSettingsRpcUrl, setNetworksTabAddMode } = this.props;
|
||||
const { history } = this.props;
|
||||
|
||||
return (
|
||||
<div className="settings-page__sub-header">
|
||||
@ -59,11 +60,10 @@ export default class NetworksTab extends PureComponent {
|
||||
type="primary"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
setSelectedSettingsRpcUrl('');
|
||||
setNetworksTabAddMode(true);
|
||||
history.push(ADD_NETWORK_ROUTE);
|
||||
}}
|
||||
>
|
||||
{this.context.t('addNetwork')}
|
||||
{this.context.t('addANetwork')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -73,11 +73,9 @@ export default class NetworksTab extends PureComponent {
|
||||
renderNetworkListItem(network, selectRpcUrl) {
|
||||
const {
|
||||
setSelectedSettingsRpcUrl,
|
||||
setNetworksTabAddMode,
|
||||
networkIsSelected,
|
||||
providerUrl,
|
||||
providerType,
|
||||
networksTabIsInAddMode,
|
||||
history,
|
||||
isFullScreen,
|
||||
} = this.props;
|
||||
@ -94,7 +92,6 @@ export default class NetworksTab extends PureComponent {
|
||||
providerType !== NETWORK_TYPE_RPC && currentProviderType === providerType;
|
||||
const listItemNetworkIsCurrentProvider =
|
||||
!networkIsSelected &&
|
||||
!networksTabIsInAddMode &&
|
||||
(listItemUrlIsProviderUrl || listItemTypeIsProviderNonRpcType);
|
||||
const displayNetworkListItemAsSelected =
|
||||
listItemNetworkIsSelected || listItemNetworkIsCurrentProvider;
|
||||
@ -104,7 +101,6 @@ export default class NetworksTab extends PureComponent {
|
||||
key={`settings-network-list-item:${rpcUrl}`}
|
||||
className="networks-tab__networks-list-item"
|
||||
onClick={() => {
|
||||
setNetworksTabAddMode(false);
|
||||
setSelectedSettingsRpcUrl(rpcUrl);
|
||||
if (!isFullScreen) {
|
||||
history.push(NETWORKS_FORM_ROUTE);
|
||||
@ -139,7 +135,6 @@ export default class NetworksTab extends PureComponent {
|
||||
networksToRender,
|
||||
selectedNetwork,
|
||||
networkIsSelected,
|
||||
networksTabIsInAddMode,
|
||||
networkDefaultedToProvider,
|
||||
} = this.props;
|
||||
|
||||
@ -147,27 +142,12 @@ export default class NetworksTab extends PureComponent {
|
||||
<div
|
||||
className={classnames('networks-tab__networks-list', {
|
||||
'networks-tab__networks-list--selection':
|
||||
(networkIsSelected && !networkDefaultedToProvider) ||
|
||||
networksTabIsInAddMode,
|
||||
networkIsSelected && !networkDefaultedToProvider,
|
||||
})}
|
||||
>
|
||||
{networksToRender.map((network) =>
|
||||
this.renderNetworkListItem(network, selectedNetwork.rpcUrl),
|
||||
)}
|
||||
{networksTabIsInAddMode && (
|
||||
<div className="networks-tab__networks-list-item">
|
||||
<ColorIndicator
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
color={COLORS.WHITE}
|
||||
borderColor={COLORS.UI4}
|
||||
size={SIZES.LG}
|
||||
/>
|
||||
<div className="networks-tab__networks-list-name networks-tab__networks-list-name--selected">
|
||||
{this.context.t('newNetwork')}
|
||||
</div>
|
||||
<div className="networks-tab__networks-list-arrow" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -178,7 +158,6 @@ export default class NetworksTab extends PureComponent {
|
||||
setRpcTarget,
|
||||
showConfirmDeleteNetworkModal,
|
||||
setSelectedSettingsRpcUrl,
|
||||
setNetworksTabAddMode,
|
||||
selectedNetwork: {
|
||||
labelKey,
|
||||
label,
|
||||
@ -189,7 +168,6 @@ export default class NetworksTab extends PureComponent {
|
||||
rpcPrefs,
|
||||
blockExplorerUrl,
|
||||
},
|
||||
networksTabIsInAddMode,
|
||||
editRpc,
|
||||
providerUrl,
|
||||
networksToRender,
|
||||
@ -211,19 +189,14 @@ export default class NetworksTab extends PureComponent {
|
||||
networksToRender={networksToRender}
|
||||
ticker={ticker}
|
||||
onClear={(shouldUpdateHistory = true) => {
|
||||
setNetworksTabAddMode(false);
|
||||
setSelectedSettingsRpcUrl('');
|
||||
if (shouldUpdateHistory) {
|
||||
history.push(NETWORKS_ROUTE);
|
||||
}
|
||||
}}
|
||||
onAddNetwork={() => {
|
||||
history.push(DEFAULT_ROUTE);
|
||||
}}
|
||||
showConfirmDeleteNetworkModal={showConfirmDeleteNetworkModal}
|
||||
viewOnly={viewOnly}
|
||||
isCurrentRpcTarget={providerUrl === rpcUrl}
|
||||
networksTabIsInAddMode={networksTabIsInAddMode}
|
||||
rpcPrefs={rpcPrefs}
|
||||
blockExplorerUrl={blockExplorerUrl}
|
||||
isFullScreen={isFullScreen}
|
||||
@ -235,14 +208,32 @@ export default class NetworksTab extends PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
setNetworksTabAddMode,
|
||||
setSelectedSettingsRpcUrl,
|
||||
history,
|
||||
isFullScreen,
|
||||
shouldRenderNetworkForm,
|
||||
setRpcTarget,
|
||||
networksToRender,
|
||||
setNewNetworkAdded,
|
||||
selectedNetwork: { rpcPrefs },
|
||||
addNewNetwork,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
return addNewNetwork ? (
|
||||
<NetworkForm
|
||||
setRpcTarget={setRpcTarget}
|
||||
onClear={(shouldUpdateHistory = true) => {
|
||||
if (shouldUpdateHistory) {
|
||||
history.push(NETWORKS_ROUTE);
|
||||
}
|
||||
}}
|
||||
onAddNetwork={() => {
|
||||
history.push(DEFAULT_ROUTE);
|
||||
}}
|
||||
rpcPrefs={rpcPrefs}
|
||||
networksToRender={networksToRender}
|
||||
setNewNetworkAdded={setNewNetworkAdded}
|
||||
addNewNetwork={addNewNetwork}
|
||||
/>
|
||||
) : (
|
||||
<div className="networks-tab__body">
|
||||
{isFullScreen ? this.renderSubHeader() : null}
|
||||
<div className="networks-tab__content">
|
||||
@ -253,9 +244,7 @@ export default class NetworksTab extends PureComponent {
|
||||
type="primary"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
setSelectedSettingsRpcUrl('');
|
||||
setNetworksTabAddMode(true);
|
||||
history.push(NETWORKS_FORM_ROUTE);
|
||||
global.platform.openExtensionInBrowser(ADD_NETWORK_ROUTE);
|
||||
}}
|
||||
>
|
||||
{this.context.t('addNetwork')}
|
||||
|
@ -5,11 +5,14 @@ import {
|
||||
setSelectedSettingsRpcUrl,
|
||||
updateAndSetCustomRpc,
|
||||
displayWarning,
|
||||
setNetworksTabAddMode,
|
||||
editRpc,
|
||||
showModal,
|
||||
setNewNetworkAdded,
|
||||
} from '../../../store/actions';
|
||||
import { NETWORKS_FORM_ROUTE } from '../../../helpers/constants/routes';
|
||||
import {
|
||||
ADD_NETWORK_ROUTE,
|
||||
NETWORKS_FORM_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app';
|
||||
import { NETWORK_TYPE_RPC } from '../../../../shared/constants/network';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
@ -30,10 +33,10 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
||||
const shouldRenderNetworkForm =
|
||||
isFullScreen || Boolean(pathname.match(NETWORKS_FORM_ROUTE));
|
||||
const addNewNetwork = Boolean(pathname.match(ADD_NETWORK_ROUTE));
|
||||
|
||||
const { frequentRpcListDetail, provider } = state.metamask;
|
||||
const { networksTabSelectedRpcUrl, networksTabIsInAddMode } = state.appState;
|
||||
|
||||
const { networksTabSelectedRpcUrl } = state.appState;
|
||||
const frequentRpcNetworkListDetails = frequentRpcListDetail.map((rpc) => {
|
||||
return {
|
||||
label: rpc.nickname,
|
||||
@ -57,7 +60,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const networkIsSelected = Boolean(selectedNetwork.rpcUrl);
|
||||
|
||||
let networkDefaultedToProvider = false;
|
||||
if (!networkIsSelected && !networksTabIsInAddMode) {
|
||||
if (!networkIsSelected) {
|
||||
selectedNetwork =
|
||||
networksToRender.find((network) => {
|
||||
return (
|
||||
@ -73,12 +76,12 @@ const mapStateToProps = (state, ownProps) => {
|
||||
selectedNetwork,
|
||||
networksToRender,
|
||||
networkIsSelected,
|
||||
networksTabIsInAddMode,
|
||||
providerType: provider.type,
|
||||
providerUrl: provider.rpcUrl,
|
||||
networkDefaultedToProvider,
|
||||
isFullScreen,
|
||||
shouldRenderNetworkForm,
|
||||
addNewNetwork,
|
||||
};
|
||||
};
|
||||
|
||||
@ -97,13 +100,14 @@ const mapDispatchToProps = (dispatch) => {
|
||||
);
|
||||
},
|
||||
displayWarning: (warning) => dispatch(displayWarning(warning)),
|
||||
setNetworksTabAddMode: (isInAddMode) =>
|
||||
dispatch(setNetworksTabAddMode(isInAddMode)),
|
||||
editRpc: (oldRpc, newRpc, chainId, ticker, nickname, rpcPrefs) => {
|
||||
return dispatch(
|
||||
editRpc(oldRpc, newRpc, chainId, ticker, nickname, rpcPrefs),
|
||||
);
|
||||
},
|
||||
setNewNetworkAdded: (newNetwork) => {
|
||||
dispatch(setNewNetworkAdded(newNetwork));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
CONTACT_EDIT_ROUTE,
|
||||
CONTACT_VIEW_ROUTE,
|
||||
EXPERIMENTAL_ROUTE,
|
||||
ADD_NETWORK_ROUTE,
|
||||
} from '../../helpers/constants/routes';
|
||||
import SettingsTab from './settings-tab';
|
||||
import AlertsTab from './alerts-tab';
|
||||
@ -39,6 +40,7 @@ class SettingsPage extends PureComponent {
|
||||
breadCrumbTextKey: PropTypes.string,
|
||||
initialBreadCrumbKey: PropTypes.string,
|
||||
mostRecentOverviewPage: PropTypes.string.isRequired,
|
||||
addNewNetwork: PropTypes.bool,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
@ -51,6 +53,7 @@ class SettingsPage extends PureComponent {
|
||||
backRoute,
|
||||
currentPath,
|
||||
mostRecentOverviewPage,
|
||||
addNewNetwork,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -69,7 +72,13 @@ class SettingsPage extends PureComponent {
|
||||
{this.renderTitle()}
|
||||
<div
|
||||
className="settings-page__close-button"
|
||||
onClick={() => history.push(mostRecentOverviewPage)}
|
||||
onClick={() => {
|
||||
if (addNewNetwork) {
|
||||
history.push(NETWORKS_ROUTE);
|
||||
} else {
|
||||
history.push(mostRecentOverviewPage);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="settings-page__content">
|
||||
@ -222,6 +231,7 @@ class SettingsPage extends PureComponent {
|
||||
<Route exact path={ABOUT_US_ROUTE} component={InfoTab} />
|
||||
<Route exact path={ADVANCED_ROUTE} component={AdvancedTab} />
|
||||
<Route exact path={ALERTS_ROUTE} component={AlertsTab} />
|
||||
<Route exact path={ADD_NETWORK_ROUTE} component={NetworksTab} />
|
||||
<Route path={NETWORKS_ROUTE} component={NetworksTab} />
|
||||
<Route exact path={SECURITY_ROUTE} component={SecurityTab} />
|
||||
<Route exact path={EXPERIMENTAL_ROUTE} component={ExperimentalTab} />
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
SECURITY_ROUTE,
|
||||
SETTINGS_ROUTE,
|
||||
EXPERIMENTAL_ROUTE,
|
||||
ADD_NETWORK_ROUTE,
|
||||
} from '../../helpers/constants/routes';
|
||||
import Settings from './settings.component';
|
||||
|
||||
@ -38,6 +39,7 @@ const ROUTES_TO_I18N_KEYS = {
|
||||
[CONTACT_VIEW_ROUTE]: 'viewContact',
|
||||
[NETWORKS_ROUTE]: 'networks',
|
||||
[NETWORKS_FORM_ROUTE]: 'networks',
|
||||
[ADD_NETWORK_ROUTE]: 'networks',
|
||||
[SECURITY_ROUTE]: 'securityAndPrivacy',
|
||||
[EXPERIMENTAL_ROUTE]: 'experimental',
|
||||
};
|
||||
@ -50,7 +52,10 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const isAddressEntryPage = pathNameTail.includes('0x');
|
||||
const isAddContactPage = Boolean(pathname.match(CONTACT_ADD_ROUTE));
|
||||
const isEditContactPage = Boolean(pathname.match(CONTACT_EDIT_ROUTE));
|
||||
const isNetworksFormPage = Boolean(pathname.match(NETWORKS_FORM_ROUTE));
|
||||
const isNetworksFormPage =
|
||||
Boolean(pathname.match(NETWORKS_FORM_ROUTE)) ||
|
||||
Boolean(pathname.match(ADD_NETWORK_ROUTE));
|
||||
const addNewNetwork = Boolean(pathname.match(ADD_NETWORK_ROUTE));
|
||||
|
||||
const isPopup = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP;
|
||||
const pathnameI18nKey = ROUTES_TO_I18N_KEYS[pathname];
|
||||
@ -85,6 +90,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
initialBreadCrumbRoute,
|
||||
initialBreadCrumbKey,
|
||||
mostRecentOverviewPage: getMostRecentOverviewPage(state),
|
||||
addNewNetwork,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -659,3 +659,12 @@ export function doesAddressRequireLedgerHidConnection(state, address) {
|
||||
addressIsLedger && transportTypePreferenceIsWebHID && webHidIsNotConnected
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* To retrieve the name of the new Network added using add network form
|
||||
* @param {*} state
|
||||
* @returns string
|
||||
*/
|
||||
export function getNewNetworkAdded(state) {
|
||||
return state.appState.newNetworkAdded;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ export const CLEAR_PENDING_TOKENS = 'CLEAR_PENDING_TOKENS';
|
||||
export const SET_FIRST_TIME_FLOW_TYPE = 'SET_FIRST_TIME_FLOW_TYPE';
|
||||
|
||||
export const SET_SELECTED_SETTINGS_RPC_URL = 'SET_SELECTED_SETTINGS_RPC_URL';
|
||||
export const SET_NETWORKS_TAB_ADD_MODE = 'SET_NETWORKS_TAB_ADD_MODE';
|
||||
export const SET_NEW_NETWORK_ADDED = 'SET_NEW_NETWORK_ADDED';
|
||||
|
||||
export const LOADING_METHOD_DATA_STARTED = 'LOADING_METHOD_DATA_STARTED';
|
||||
export const LOADING_METHOD_DATA_FINISHED = 'LOADING_METHOD_DATA_FINISHED';
|
||||
|
@ -2446,10 +2446,10 @@ export function setSelectedSettingsRpcUrl(newRpcUrl) {
|
||||
};
|
||||
}
|
||||
|
||||
export function setNetworksTabAddMode(isInAddMode) {
|
||||
export function setNewNetworkAdded(newNetworkAdded) {
|
||||
return {
|
||||
type: actionConstants.SET_NETWORKS_TAB_ADD_MODE,
|
||||
value: isInAddMode,
|
||||
type: actionConstants.SET_NEW_NETWORK_ADDED,
|
||||
value: newNetworkAdded,
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user