1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Fix #19439 - Allow Account Picker during Send flow (#19522)

* Fix #19439 - Allow Account Picker during Send flow

* Disable any network change with confirmations pending

* Disable the settings menu during an unconfirmed transaction
This commit is contained in:
David Walsh 2023-06-14 13:49:14 -05:00 committed by GitHub
parent f4f80c223e
commit 875bad125f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 353 additions and 324 deletions

View File

@ -3,15 +3,213 @@
exports[`App Header should match snapshot 1`] = ` exports[`App Header should match snapshot 1`] = `
<div> <div>
<div <div
class="box multichain-app-header multichain-app-header-shadow box--display-flex box--flex-direction-row box--align-items-center box--width-full box--background-color-background-default" class="box multichain-app-header-logo box--margin-2 box--display-none box--sm:display-flex box--flex-direction-row box--justify-content-center box--align-items-center"
data-testid="app-header-logo"
>
<button
class="box app-header__logo-container app-header__logo-container--clickable box--flex-direction-row box--background-color-transparent"
data-testid="app-header-logo"
>
<svg
class="app-header__metafox-logo--horizontal"
height="30"
viewBox="0 0 1311 242"
width="162"
xmlns="http://www.w3.org/2000/svg"
>
<g
fill="none"
>
<g
fill="var(--color-text-default)"
transform="translate(361 61)"
>
<path
d="m796.7 60.9c-6.8-4.5-14.3-7.7-21.4-11.7-4.6-2.6-9.5-4.9-13.5-8.2-6.8-5.6-5.4-16.6 1.7-21.4 10.2-6.8 27.1-3 28.9 10.9 0 .3.3.5.6.5h15.4c.4 0 .7-.3.6-.7-.8-9.6-4.5-17.6-11.3-22.7-6.5-4.9-13.9-7.5-21.8-7.5-40.7 0-44.4 43.1-22.5 56.7 2.5 1.6 24 12.4 31.6 17.1s10 13.3 6.7 20.1c-3 6.2-10.8 10.5-18.6 10-8.5-.5-15.1-5.1-17.4-12.3-.4-1.3-.6-3.8-.6-4.9 0-.3-.3-.6-.6-.6h-16.7c-.3 0-.6.3-.6.6 0 12.1 3 18.8 11.2 24.9 7.7 5.8 16.1 8.2 24.8 8.2 22.8 0 34.6-12.9 37-26.3 2.1-13.1-1.8-24.9-13.5-32.7z"
/>
<path
d="m71.6 2.3h-7.4-8.1c-.3 0-.5.2-.6.4l-13.7 45.2c-.2.6-1 .6-1.2 0l-13.7-45.2c-.1-.3-.3-.4-.6-.4h-8.1-7.4-10c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-87.7c0-.7 1-.8 1.2-.2l13.8 45.5 1 3.2c.1.3.3.4.6.4h12.8c.3 0 .5-.2.6-.4l1-3.2 13.8-45.5c.2-.7 1.2-.5 1.2.2v87.7c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-115.4c0-.3-.3-.6-.6-.6z"
/>
<path
d="m541 2.3c-.3 0-.5.2-.6.4l-13.7 45.2c-.2.6-1 .6-1.2 0l-13.7-45.2c-.1-.3-.3-.4-.6-.4h-25.4c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-87.7c0-.7 1-.8 1.2-.2l13.8 45.5 1 3.2c.1.3.3.4.6.4h12.8c.3 0 .5-.2.6-.4l1-3.2 13.8-45.5c.2-.7 1.2-.5 1.2.2v87.7c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-115.4c0-.3-.3-.6-.6-.6z"
/>
<path
d="m325.6 2.3h-31.1-16.7-31.1c-.3 0-.6.3-.6.6v14.4c0 .3.3.6.6.6h30.5v100.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-100.4h30.5c.3 0 .6-.3.6-.6v-14.4c0-.3-.2-.6-.6-.6z"
/>
<path
d="m424.1 118.9h15.2c.4 0 .7-.4.6-.8l-31.4-115.8c-.1-.3-.3-.4-.6-.4h-5.8-10.2-5.8c-.3 0-.5.2-.6.4l-31.4 115.8c-.1.4.2.8.6.8h15.2c.3 0 .5-.2.6-.4l9.1-33.7c.1-.3.3-.4.6-.4h33.6c.3 0 .5.2.6.4l9.1 33.7c.1.2.4.4.6.4zm-39.9-51 12.2-45.1c.2-.6 1-.6 1.2 0l12.2 45.1c.1.4-.2.8-.6.8h-24.4c-.4 0-.7-.4-.6-.8z"
/>
<path
d="m683.3 118.9h15.2c.4 0 .7-.4.6-.8l-31.4-115.8c-.1-.3-.3-.4-.6-.4h-5.8-10.2-5.8c-.3 0-.5.2-.6.4l-31.4 115.8c-.1.4.2.8.6.8h15.2c.3 0 .5-.2.6-.4l9.1-33.7c.1-.3.3-.4.6-.4h33.6c.3 0 .5.2.6.4l9.1 33.7c.1.2.3.4.6.4zm-39.9-51 12.2-45.1c.2-.6 1-.6 1.2 0l12.2 45.1c.1.4-.2.8-.6.8h-24.4c-.4 0-.7-.4-.6-.8z"
/>
<path
d="m149.8 101.8v-35.8c0-.3.3-.6.6-.6h44.5c.3 0 .6-.3.6-.6v-14.4c0-.3-.3-.6-.6-.6h-44.5c-.3 0-.6-.3-.6-.6v-30.6c0-.3.3-.6.6-.6h50.6c.3 0 .6-.3.6-.6v-14.4c0-.3-.3-.6-.6-.6h-51.2-17.3c-.3 0-.6.3-.6.6v15 31.9 15.6 37 15.8c0 .3.3.6.6.6h17.3 53.3c.3 0 .6-.3.6-.6v-15.2c0-.3-.3-.6-.6-.6h-52.8c-.3-.1-.5-.3-.5-.7z"
/>
<path
d="m949.3 117.9-57.8-59.7c-.2-.2-.2-.6 0-.8l52-54c.4-.4.1-1-.4-1h-21.3c-.2 0-.3.1-.4.2l-44.1 45.8c-.4.4-1 .1-1-.4v-45c0-.3-.3-.6-.6-.6h-16.7c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-50.8c0-.5.7-.8 1-.4l50 51.6c.1.1.3.2.4.2h21.3c.4-.1.7-.8.3-1.1z"
/>
</g>
<g
stroke-linecap="round"
stroke-linejoin="round"
transform="translate(1 1)"
>
<path
d="m246.1.2-101.1 75 18.8-44.2z"
fill="#e17726"
stroke="#e17726"
/>
<g
fill="#e27625"
stroke="#e27625"
transform="translate(2)"
>
<path
d="m10.9.2 100.2 75.7-17.9-44.9z"
/>
<path
d="m207.7 174.1-26.9 41.2 57.6 15.9 16.5-56.2z"
/>
<path
d="m.2 175 16.4 56.2 57.5-15.9-26.8-41.2z"
/>
<path
d="m71 104.5-16 24.2 57 2.6-1.9-61.5z"
/>
<path
d="m184 104.5-39.7-35.4-1.3 62.2 57-2.6z"
/>
<path
d="m74.1 215.3 34.5-16.7-29.7-23.2z"
/>
<path
d="m146.4 198.6 34.4 16.7-4.7-39.9z"
/>
</g>
<g
fill="#d5bfb2"
stroke="#d5bfb2"
transform="translate(76 198)"
>
<path
d="m106.8 17.3-34.4-16.7 2.8 22.4-.3 9.5z"
/>
<path
d="m.1 17.3 32 15.2-.2-9.5 2.7-22.4z"
/>
</g>
<path
d="m108.7 160.6-28.6-8.4 20.2-9.3z"
fill="#233447"
stroke="#233447"
/>
<path
d="m150.3 160.6 8.4-17.7 20.3 9.3z"
fill="#233447"
stroke="#233447"
/>
<g
fill="#cc6228"
stroke="#cc6228"
transform="translate(49 128)"
>
<path
d="m27.1 87.3 5-41.2-31.8.9z"
/>
<path
d="m128.9 46.1 4.9 41.2 26.9-40.3z"
/>
<path
d="m153 .7-57 2.6 5.3 29.3 8.4-17.7 20.3 9.3z"
/>
<path
d="m31.1 24.2 20.2-9.3 8.4 17.7 5.3-29.3-57-2.6z"
/>
</g>
<g
fill="#e27525"
stroke="#e27525"
transform="translate(57 128)"
>
<path
d="m0 .7 23.9 46.7-.8-23.2z"
/>
<path
d="m122 24.2-.9 23.2 23.9-46.7z"
/>
<path
d="m57 3.3-5.3 29.3 6.7 34.6 1.5-45.6z"
/>
<path
d="m88 3.3-2.8 18.2 1.4 45.7 6.7-34.6z"
/>
</g>
<path
d="m150.3 160.6-6.7 34.6 4.8 3.4 29.7-23.2.9-23.2z"
fill="#f5841f"
stroke="#f5841f"
/>
<path
d="m80.1 152.2.8 23.2 29.7 23.2 4.8-3.4-6.7-34.6z"
fill="#f5841f"
stroke="#f5841f"
/>
<path
d="m150.9 230.5.3-9.5-2.6-2.2h-38.2l-2.5 2.2.2 9.5-32-15.2 11.2 9.2 22.7 15.7h38.9l22.8-15.7 11.1-9.2z"
fill="#c0ac9d"
stroke="#c0ac9d"
/>
<path
d="m148.4 198.6-4.8-3.4h-28.2l-4.8 3.4-2.7 22.4 2.5-2.2h38.2l2.6 2.2z"
fill="#161616"
stroke="#161616"
/>
<g
fill="#763e1a"
stroke="#763e1a"
>
<path
d="m250.4 80.1 8.5-41.4-12.8-38.5-97.7 72.5 37.6 31.8 53.1 15.5 11.7-13.7-5.1-3.7 8.1-7.4-6.2-4.8 8.1-6.2z"
/>
<path
d="m.1 38.7 8.6 41.4-5.5 4.1 8.2 6.2-6.2 4.8 8.1 7.4-5.1 3.7 11.7 13.7 53.1-15.5 37.6-31.8-97.7-72.5z"
/>
</g>
<g
fill="#f5841f"
stroke="#f5841f"
>
<path
d="m239.1 120-53.1-15.5 16 24.2-23.9 46.7 31.6-.4h47.2z"
/>
<path
d="m73 104.5-53.1 15.5-17.7 55h47.1l31.6.4-23.9-46.7z"
/>
<path
d="m145 131.3 3.4-58.6 15.4-41.7h-68.6l15.4 41.7 3.4 58.6 1.3 18.4.1 45.5h28.2l.1-45.5z"
/>
</g>
</g>
</g>
</svg>
<img
alt=""
class="app-header__metafox-logo--icon"
src="./images/logo/metamask-fox.svg"
/>
</button>
</div>
<div
class="box multichain-app-header box--display-flex box--flex-direction-row box--align-items-center box--width-full box--background-color-background-alternative"
> >
<div <div
class="box multichain-app-header__lock-contents box--padding-2 box--display-flex box--gap-2 box--flex-direction-row box--justify-content-space-between box--align-items-center box--width-full box--background-color-background-default" class="box multichain-app-header__contents multichain-app-header-shadow box--padding-2 box--padding-right-4 box--padding-left-4 box--gap-2 box--flex-direction-row box--align-items-center box--width-full box--background-color-background-default box--display-flex"
> >
<div> <div>
<button <button
class="box mm-picker-network multichain-app-header__contents__network-picker box--padding-right-4 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--align-items-center box--background-color-background-alternative box--rounded-pill" class="box mm-picker-network multichain-app-header__contents__network-picker box--margin-2 box--padding-right-4 box--padding-left-2 box--display-none box--sm:display-flex box--gap-2 box--flex-direction-row box--align-items-center box--background-color-background-alternative box--rounded-pill"
data-testid="network-display" data-testid="network-display"
disabled=""
> >
<div <div
class="box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network mm-picker-network__avatar-network mm-text--body-xs mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-transparent box--border-style-solid box--border-width-1" class="box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network mm-picker-network__avatar-network mm-text--body-xs mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-transparent box--border-style-solid box--border-width-1"
@ -30,197 +228,89 @@ exports[`App Header should match snapshot 1`] = `
</button> </button>
</div> </div>
<button <button
class="box app-header__logo-container app-header__logo-container--clickable box--flex-direction-row box--background-color-transparent" class="box mm-text mm-button-base mm-button-base--size-md mm-button-base--ellipsis multichain-account-picker mm-button-primary mm-text--body-md mm-text--ellipsis box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-inverse box--background-color-transparent box--rounded-lg"
data-testid="app-header-logo" data-testid="account-menu-icon"
> >
<svg <span
class="app-header__metafox-logo--horizontal" class="box mm-text mm-text--inherit mm-text--ellipsis box--display-flex box--gap-2 box--flex-direction-row box--align-items-center box--color-primary-inverse"
height="30"
viewBox="0 0 1311 242"
width="162"
xmlns="http://www.w3.org/2000/svg"
> >
<g <div
fill="none" class="box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-account mm-text--body-xs mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-background-default box--border-style-solid box--border-width-1"
> >
<g <div
fill="var(--color-text-default)" class="mm-avatar-account__jazzicon"
transform="translate(361 61)"
> >
<path <div
d="m796.7 60.9c-6.8-4.5-14.3-7.7-21.4-11.7-4.6-2.6-9.5-4.9-13.5-8.2-6.8-5.6-5.4-16.6 1.7-21.4 10.2-6.8 27.1-3 28.9 10.9 0 .3.3.5.6.5h15.4c.4 0 .7-.3.6-.7-.8-9.6-4.5-17.6-11.3-22.7-6.5-4.9-13.9-7.5-21.8-7.5-40.7 0-44.4 43.1-22.5 56.7 2.5 1.6 24 12.4 31.6 17.1s10 13.3 6.7 20.1c-3 6.2-10.8 10.5-18.6 10-8.5-.5-15.1-5.1-17.4-12.3-.4-1.3-.6-3.8-.6-4.9 0-.3-.3-.6-.6-.6h-16.7c-.3 0-.6.3-.6.6 0 12.1 3 18.8 11.2 24.9 7.7 5.8 16.1 8.2 24.8 8.2 22.8 0 34.6-12.9 37-26.3 2.1-13.1-1.8-24.9-13.5-32.7z" style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 16px; height: 16px; display: inline-block; background: rgb(250, 58, 0);"
/>
<path
d="m71.6 2.3h-7.4-8.1c-.3 0-.5.2-.6.4l-13.7 45.2c-.2.6-1 .6-1.2 0l-13.7-45.2c-.1-.3-.3-.4-.6-.4h-8.1-7.4-10c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-87.7c0-.7 1-.8 1.2-.2l13.8 45.5 1 3.2c.1.3.3.4.6.4h12.8c.3 0 .5-.2.6-.4l1-3.2 13.8-45.5c.2-.7 1.2-.5 1.2.2v87.7c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-115.4c0-.3-.3-.6-.6-.6z"
/>
<path
d="m541 2.3c-.3 0-.5.2-.6.4l-13.7 45.2c-.2.6-1 .6-1.2 0l-13.7-45.2c-.1-.3-.3-.4-.6-.4h-25.4c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-87.7c0-.7 1-.8 1.2-.2l13.8 45.5 1 3.2c.1.3.3.4.6.4h12.8c.3 0 .5-.2.6-.4l1-3.2 13.8-45.5c.2-.7 1.2-.5 1.2.2v87.7c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-115.4c0-.3-.3-.6-.6-.6z"
/>
<path
d="m325.6 2.3h-31.1-16.7-31.1c-.3 0-.6.3-.6.6v14.4c0 .3.3.6.6.6h30.5v100.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-100.4h30.5c.3 0 .6-.3.6-.6v-14.4c0-.3-.2-.6-.6-.6z"
/>
<path
d="m424.1 118.9h15.2c.4 0 .7-.4.6-.8l-31.4-115.8c-.1-.3-.3-.4-.6-.4h-5.8-10.2-5.8c-.3 0-.5.2-.6.4l-31.4 115.8c-.1.4.2.8.6.8h15.2c.3 0 .5-.2.6-.4l9.1-33.7c.1-.3.3-.4.6-.4h33.6c.3 0 .5.2.6.4l9.1 33.7c.1.2.4.4.6.4zm-39.9-51 12.2-45.1c.2-.6 1-.6 1.2 0l12.2 45.1c.1.4-.2.8-.6.8h-24.4c-.4 0-.7-.4-.6-.8z"
/>
<path
d="m683.3 118.9h15.2c.4 0 .7-.4.6-.8l-31.4-115.8c-.1-.3-.3-.4-.6-.4h-5.8-10.2-5.8c-.3 0-.5.2-.6.4l-31.4 115.8c-.1.4.2.8.6.8h15.2c.3 0 .5-.2.6-.4l9.1-33.7c.1-.3.3-.4.6-.4h33.6c.3 0 .5.2.6.4l9.1 33.7c.1.2.3.4.6.4zm-39.9-51 12.2-45.1c.2-.6 1-.6 1.2 0l12.2 45.1c.1.4-.2.8-.6.8h-24.4c-.4 0-.7-.4-.6-.8z"
/>
<path
d="m149.8 101.8v-35.8c0-.3.3-.6.6-.6h44.5c.3 0 .6-.3.6-.6v-14.4c0-.3-.3-.6-.6-.6h-44.5c-.3 0-.6-.3-.6-.6v-30.6c0-.3.3-.6.6-.6h50.6c.3 0 .6-.3.6-.6v-14.4c0-.3-.3-.6-.6-.6h-51.2-17.3c-.3 0-.6.3-.6.6v15 31.9 15.6 37 15.8c0 .3.3.6.6.6h17.3 53.3c.3 0 .6-.3.6-.6v-15.2c0-.3-.3-.6-.6-.6h-52.8c-.3-.1-.5-.3-.5-.7z"
/>
<path
d="m949.3 117.9-57.8-59.7c-.2-.2-.2-.6 0-.8l52-54c.4-.4.1-1-.4-1h-21.3c-.2 0-.3.1-.4.2l-44.1 45.8c-.4.4-1 .1-1-.4v-45c0-.3-.3-.6-.6-.6h-16.7c-.3 0-.6.3-.6.6v115.4c0 .3.3.6.6.6h16.7c.3 0 .6-.3.6-.6v-50.8c0-.5.7-.8 1-.4l50 51.6c.1.1.3.2.4.2h21.3c.4-.1.7-.8.3-1.1z"
/>
</g>
<g
stroke-linecap="round"
stroke-linejoin="round"
transform="translate(1 1)"
>
<path
d="m246.1.2-101.1 75 18.8-44.2z"
fill="#e17726"
stroke="#e17726"
/>
<g
fill="#e27625"
stroke="#e27625"
transform="translate(2)"
> >
<path <svg
d="m10.9.2 100.2 75.7-17.9-44.9z" height="16"
/> width="16"
<path x="0"
d="m207.7 174.1-26.9 41.2 57.6 15.9 16.5-56.2z" y="0"
/> >
<path <rect
d="m.2 175 16.4 56.2 57.5-15.9-26.8-41.2z" fill="#18CDF2"
/> height="16"
<path transform="translate(-0.52419675189697 -1.6521420347302493) rotate(328.9 8 8)"
d="m71 104.5-16 24.2 57 2.6-1.9-61.5z" width="16"
/> x="0"
<path y="0"
d="m184 104.5-39.7-35.4-1.3 62.2 57-2.6z" />
/> <rect
<path fill="#035E56"
d="m74.1 215.3 34.5-16.7-29.7-23.2z" height="16"
/> transform="translate(-9.149230854416022 5.2962309358743) rotate(176.2 8 8)"
<path width="16"
d="m146.4 198.6 34.4 16.7-4.7-39.9z" x="0"
/> y="0"
</g> />
<g <rect
fill="#d5bfb2" fill="#F26602"
stroke="#d5bfb2" height="16"
transform="translate(76 198)" transform="translate(8.333921009111961 -7.102569861498541) rotate(468.9 8 8)"
> width="16"
<path x="0"
d="m106.8 17.3-34.4-16.7 2.8 22.4-.3 9.5z" y="0"
/> />
<path </svg>
d="m.1 17.3 32 15.2-.2-9.5 2.7-22.4z" </div>
/> </div>
</g> </div>
<path <span
d="m108.7 160.6-28.6-8.4 20.2-9.3z" class="box mm-text mm-text--body-md mm-text--font-weight-bold mm-text--ellipsis box--flex-direction-row box--color-text-default"
fill="#233447" >
stroke="#233447" Test Account
/> </span>
<path <span
d="m150.3 160.6 8.4-17.7 20.3 9.3z" class="box mm-icon mm-icon--size-sm box--display-inline-block box--flex-direction-row box--color-icon-default"
fill="#233447" style="mask-image: url('./images/icons/arrow-down.svg');"
stroke="#233447" />
/> </span>
<g
fill="#cc6228"
stroke="#cc6228"
transform="translate(49 128)"
>
<path
d="m27.1 87.3 5-41.2-31.8.9z"
/>
<path
d="m128.9 46.1 4.9 41.2 26.9-40.3z"
/>
<path
d="m153 .7-57 2.6 5.3 29.3 8.4-17.7 20.3 9.3z"
/>
<path
d="m31.1 24.2 20.2-9.3 8.4 17.7 5.3-29.3-57-2.6z"
/>
</g>
<g
fill="#e27525"
stroke="#e27525"
transform="translate(57 128)"
>
<path
d="m0 .7 23.9 46.7-.8-23.2z"
/>
<path
d="m122 24.2-.9 23.2 23.9-46.7z"
/>
<path
d="m57 3.3-5.3 29.3 6.7 34.6 1.5-45.6z"
/>
<path
d="m88 3.3-2.8 18.2 1.4 45.7 6.7-34.6z"
/>
</g>
<path
d="m150.3 160.6-6.7 34.6 4.8 3.4 29.7-23.2.9-23.2z"
fill="#f5841f"
stroke="#f5841f"
/>
<path
d="m80.1 152.2.8 23.2 29.7 23.2 4.8-3.4-6.7-34.6z"
fill="#f5841f"
stroke="#f5841f"
/>
<path
d="m150.9 230.5.3-9.5-2.6-2.2h-38.2l-2.5 2.2.2 9.5-32-15.2 11.2 9.2 22.7 15.7h38.9l22.8-15.7 11.1-9.2z"
fill="#c0ac9d"
stroke="#c0ac9d"
/>
<path
d="m148.4 198.6-4.8-3.4h-28.2l-4.8 3.4-2.7 22.4 2.5-2.2h38.2l2.6 2.2z"
fill="#161616"
stroke="#161616"
/>
<g
fill="#763e1a"
stroke="#763e1a"
>
<path
d="m250.4 80.1 8.5-41.4-12.8-38.5-97.7 72.5 37.6 31.8 53.1 15.5 11.7-13.7-5.1-3.7 8.1-7.4-6.2-4.8 8.1-6.2z"
/>
<path
d="m.1 38.7 8.6 41.4-5.5 4.1 8.2 6.2-6.2 4.8 8.1 7.4-5.1 3.7 11.7 13.7 53.1-15.5 37.6-31.8-97.7-72.5z"
/>
</g>
<g
fill="#f5841f"
stroke="#f5841f"
>
<path
d="m239.1 120-53.1-15.5 16 24.2-23.9 46.7 31.6-.4h47.2z"
/>
<path
d="m73 104.5-53.1 15.5-17.7 55h47.1l31.6.4-23.9-46.7z"
/>
<path
d="m145 131.3 3.4-58.6 15.4-41.7h-68.6l15.4 41.7 3.4 58.6 1.3 18.4.1 45.5h28.2l.1-45.5z"
/>
</g>
</g>
</g>
</svg>
<img
alt=""
class="app-header__metafox-logo--icon"
src="./images/logo/metamask-fox.svg"
/>
</button> </button>
<div
class="box box--display-flex box--flex-direction-row box--justify-content-flex-end box--align-items-center"
>
<div
class="box box--display-flex box--gap-4 box--flex-direction-row"
>
<div
class="box box--display-flex box--flex-direction-row box--justify-content-flex-end box--width-full"
>
<button
aria-label="Account options"
class="box mm-button-icon mm-button-icon--size-sm box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-default box--background-color-transparent box--rounded-lg"
data-testid="account-options-menu-button"
>
<span
class="box mm-icon mm-icon--size-sm box--display-inline-block box--flex-direction-row box--color-inherit"
style="mask-image: url('./images/icons/more-vertical.svg');"
/>
</button>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -105,17 +105,17 @@ export const AppHeader = ({ location }) => {
// Disable the network and account pickers if the user is in // Disable the network and account pickers if the user is in
// a critical flow // a critical flow
const sendStage = useSelector(getSendStage); const sendStage = useSelector(getSendStage);
const isTransactionEditPage = [
SEND_STAGES.EDIT,
SEND_STAGES.DRAFT,
SEND_STAGES.ADD_RECIPIENT,
].includes(sendStage);
const isConfirmationPage = Boolean( const isConfirmationPage = Boolean(
matchPath(location.pathname, { matchPath(location.pathname, {
path: CONFIRM_TRANSACTION_ROUTE, path: CONFIRM_TRANSACTION_ROUTE,
exact: false, exact: false,
}), }),
); );
const isTransactionEditPage = [
SEND_STAGES.EDIT,
SEND_STAGES.DRAFT,
SEND_STAGES.ADD_RECIPIENT,
].includes(sendStage);
const isSwapsPage = Boolean( const isSwapsPage = Boolean(
matchPath(location.pathname, { path: SWAPS_ROUTE, exact: false }), matchPath(location.pathname, { path: SWAPS_ROUTE, exact: false }),
); );
@ -123,11 +123,18 @@ export const AppHeader = ({ location }) => {
matchPath(location.pathname, { path: BUILD_QUOTE_ROUTE, exact: false }), matchPath(location.pathname, { path: BUILD_QUOTE_ROUTE, exact: false }),
); );
const disablePickers = const hasUnapprovedTransactions = useSelector(
isConfirmationPage || (state) => Object.keys(state.metamask.unapprovedTxs).length > 0,
);
const disableAccountPicker =
isConfirmationPage || (isSwapsPage && !isSwapsBuildQuotePage);
const disableNetworkPicker =
isSwapsPage ||
isTransactionEditPage || isTransactionEditPage ||
(isSwapsPage && !isSwapsBuildQuotePage); isConfirmationPage ||
const disableNetworkPicker = isSwapsPage || disablePickers; hasUnapprovedTransactions;
// Callback for network dropdown // Callback for network dropdown
const networkOpenCallback = useCallback(() => { const networkOpenCallback = useCallback(() => {
@ -261,7 +268,7 @@ export const AppHeader = ({ location }) => {
}, },
}); });
}} }}
disabled={disablePickers} disabled={disableAccountPicker}
/> />
) : null} ) : null}
<Box <Box

View File

@ -1,118 +1,34 @@
import React from 'react'; import React from 'react';
import configureStore from 'redux-mock-store'; import configureStore from '../../../store/store';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import { renderWithProvider } from '../../../../test/lib/render-helpers'; import { renderWithProvider } from '../../../../test/lib/render-helpers';
import mockState from '../../../../test/data/mock-state.json';
import { SEND_STAGES } from '../../../ducks/send'; import { SEND_STAGES } from '../../../ducks/send';
import { AppHeader } from '.'; import { AppHeader } from '.';
const render = (stateChanges = {}, location = jest.fn()) => {
const store = configureStore({
...mockState,
activeTab: {
origin: 'https://remix.ethereum.org',
},
...stateChanges,
});
return renderWithProvider(<AppHeader location={location} />, store);
};
describe('App Header', () => { describe('App Header', () => {
it('should match snapshot', () => { it('should match snapshot', () => {
const mockState = { const { container } = render();
activeTab: {
title: 'Eth Sign Tests',
origin: 'https://remix.ethereum.org',
protocol: 'https:',
url: 'https://remix.ethereum.org/',
},
metamask: {
providerConfig: {
chainId: CHAIN_IDS.GOERLI,
},
accounts: {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
},
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
},
},
preferences: {
showTestNetworks: true,
},
selectedAddress: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
cachedBalances: {},
subjects: {
'https://remix.ethereum.org': {
permissions: {
eth_accounts: {
caveats: [
{
type: 'restrictReturnedAccounts',
value: [
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
'0x7250739de134d33ec7ab1ee592711e15098c9d2d',
],
},
],
date: 1586359844177,
id: '3aa65a8b-3bcb-4944-941b-1baa5fe0ed8b',
invoker: 'https://remix.ethereum.org',
parentCapability: 'eth_accounts',
},
},
},
'peepeth.com': {
permissions: {
eth_accounts: {
caveats: [
{
type: 'restrictReturnedAccounts',
value: ['0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5'],
},
],
date: 1585676177970,
id: '840d72a0-925f-449f-830a-1aa1dd5ce151',
invoker: 'peepeth.com',
parentCapability: 'eth_accounts',
},
},
},
},
identities: {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
name: 'Really Long Name That Should Be Truncated',
},
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
lastSelected: 1586359844192,
name: 'Account 1',
},
},
keyrings: [
{
accounts: [
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5',
'0x7250739de134d33ec7ab1ee592711e15098c9d2d',
],
},
],
permissionHistory: {
'https://remix.ethereum.org': {
eth_accounts: {
accounts: {
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': 1586359844192,
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': 1586359844192,
},
lastApproved: 1586359844192,
},
},
},
},
appState: {
onboardedInThisUISession: false,
},
send: {
stage: SEND_STAGES.INACTIVE,
},
};
const mockStore = configureStore();
const store = mockStore(mockState);
const { container } = renderWithProvider(
<AppHeader location={{ pathname: '' }} />,
store,
);
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
}); });
it('should disable the network picker during a send', () => {
const { getByTestId } = render({ send: { stage: SEND_STAGES.DRAFT } });
expect(getByTestId('network-display')).toBeDisabled();
});
it('should allow switching accounts during a send', () => {
const { getByTestId } = render({ send: { stage: SEND_STAGES.DRAFT } });
expect(getByTestId('account-menu-icon')).toBeEnabled();
});
}); });

View File

@ -58,6 +58,10 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
const history = useHistory(); const history = useHistory();
const metaMetricsId = useSelector(getMetaMetricsId); const metaMetricsId = useSelector(getMetaMetricsId);
const hasUnapprovedTransactions = useSelector(
(state) => Object.keys(state.metamask.unapprovedTxs).length > 0,
);
///: BEGIN:ONLY_INCLUDE_IN(snaps) ///: BEGIN:ONLY_INCLUDE_IN(snaps)
const unreadNotificationsCount = useSelector(getUnreadNotificationsCount); const unreadNotificationsCount = useSelector(getUnreadNotificationsCount);
///: END:ONLY_INCLUDE_IN ///: END:ONLY_INCLUDE_IN
@ -199,6 +203,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
</MenuItem> </MenuItem>
<MenuItem <MenuItem
iconName={IconName.Setting} iconName={IconName.Setting}
disabled={hasUnapprovedTransactions}
onClick={() => { onClick={() => {
history.push(SETTINGS_ROUTE); history.push(SETTINGS_ROUTE);
trackEvent({ trackEvent({
@ -210,6 +215,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
}); });
closeMenu(); closeMenu();
}} }}
data-testid="global-menu-settings"
> >
{t('settings')} {t('settings')}
</MenuItem> </MenuItem>

View File

@ -4,10 +4,11 @@ import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json'; import mockState from '../../../../test/data/mock-state.json';
import { GlobalMenu } from '.'; import { GlobalMenu } from '.';
const render = () => { const render = (metamaskStateChanges = {}) => {
const store = configureStore({ const store = configureStore({
metamask: { metamask: {
...mockState.metamask, ...mockState.metamask,
...metamaskStateChanges,
}, },
}); });
return renderWithProvider( return renderWithProvider(
@ -52,6 +53,20 @@ describe('AccountListItem', () => {
}); });
}); });
it('disables the settings item when there is an active transaction', async () => {
const { getByTestId } = render();
await waitFor(() => {
expect(getByTestId('global-menu-settings')).toBeDisabled();
});
});
it('enables the settings item when there is no active transaction', async () => {
const { getByTestId } = render({ unapprovedTxs: {} });
await waitFor(() => {
expect(getByTestId('global-menu-settings')).toBeEnabled();
});
});
it('expands metamask to tab when item is clicked', async () => { it('expands metamask to tab when item is clicked', async () => {
global.platform = { openExtensionInBrowser: jest.fn() }; global.platform = { openExtensionInBrowser: jest.fn() };

View File

@ -12,11 +12,13 @@ const MenuItem = ({
iconName, iconName,
onClick, onClick,
subtitle, subtitle,
disabled = false,
}) => ( }) => (
<button <button
className={classnames('menu-item', className)} className={classnames('menu-item', className)}
data-testid={dataTestId} data-testid={dataTestId}
onClick={onClick} onClick={onClick}
disabled={disabled}
> >
{iconName ? ( {iconName ? (
<Icon name={iconName} size={IconSize.Sm} marginRight={2} /> <Icon name={iconName} size={IconSize.Sm} marginRight={2} />
@ -35,14 +37,7 @@ MenuItem.propTypes = {
iconName: PropTypes.string, iconName: PropTypes.string,
onClick: PropTypes.func, onClick: PropTypes.func,
subtitle: PropTypes.node, subtitle: PropTypes.node,
}; disabled: PropTypes.bool,
MenuItem.defaultProps = {
className: undefined,
'data-testid': undefined,
iconName: undefined,
onClick: undefined,
subtitle: undefined,
}; };
export default MenuItem; export default MenuItem;

View File

@ -36,6 +36,12 @@ export const Anchored = () => {
<MenuItem iconName={IconName.EyeSlash} onClick={action('Menu Item 3')}> <MenuItem iconName={IconName.EyeSlash} onClick={action('Menu Item 3')}>
Menu Item 3 Menu Item 3
</MenuItem> </MenuItem>
<MenuItem
iconName={IconName.AddSquare}
onClick={action('Disabled Item')}
>
Disabled Item
</MenuItem>
</Menu> </Menu>
</> </>
); );

View File

@ -58,7 +58,7 @@ describe('Routes Component', () => {
mockHideNetworkDropdown.mockClear(); mockHideNetworkDropdown.mockClear();
}); });
describe('render during send flow', () => { describe('render during send flow', () => {
it('should render with network and account change disabled while adding recipient for send flow', () => { it('should render with network change disabled while adding recipient for send flow', () => {
const store = configureMockStore()({ const store = configureMockStore()({
...mockSendState, ...mockSendState,
send: { send: {
@ -68,25 +68,21 @@ describe('Routes Component', () => {
}); });
const { getByTestId } = renderWithProvider(<Routes />, store, ['/send']); const { getByTestId } = renderWithProvider(<Routes />, store, ['/send']);
expect(getByTestId('account-menu-icon')).toBeDisabled();
const networkDisplay = getByTestId('network-display'); const networkDisplay = getByTestId('network-display');
fireEvent.click(networkDisplay); fireEvent.click(networkDisplay);
expect(mockShowNetworkDropdown).not.toHaveBeenCalled(); expect(mockShowNetworkDropdown).not.toHaveBeenCalled();
}); });
it('should render with network and account change disabled while user is in send page', () => { it('should render with network change disabled while user is in send page', () => {
const store = configureMockStore()({ const store = configureMockStore()({
...mockSendState, ...mockSendState,
}); });
const { getByTestId } = renderWithProvider(<Routes />, store, ['/send']); const { getByTestId } = renderWithProvider(<Routes />, store, ['/send']);
expect(getByTestId('account-menu-icon')).toBeDisabled();
const networkDisplay = getByTestId('network-display'); const networkDisplay = getByTestId('network-display');
fireEvent.click(networkDisplay); fireEvent.click(networkDisplay);
expect(mockShowNetworkDropdown).not.toHaveBeenCalled(); expect(mockShowNetworkDropdown).not.toHaveBeenCalled();
}); });
it('should render with network and account change disabled while editing a send transaction', () => { it('should render with network change disabled while editing a send transaction', () => {
const store = configureMockStore()({ const store = configureMockStore()({
...mockSendState, ...mockSendState,
send: { send: {
@ -96,8 +92,6 @@ describe('Routes Component', () => {
}); });
const { getByTestId } = renderWithProvider(<Routes />, store, ['/send']); const { getByTestId } = renderWithProvider(<Routes />, store, ['/send']);
expect(getByTestId('account-menu-icon')).toBeDisabled();
const networkDisplay = getByTestId('network-display'); const networkDisplay = getByTestId('network-display');
fireEvent.click(networkDisplay); fireEvent.click(networkDisplay);
expect(mockShowNetworkDropdown).not.toHaveBeenCalled(); expect(mockShowNetworkDropdown).not.toHaveBeenCalled();