-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Show modal when user tries to cancel confirmed transaction (#22943)
## **Description** If user tries to cancel transaction which is already confirmed, we would like to show them a modal to show a link to block explorer. ## **Related issues** Fixes: #22314 Related: #22663 ## **Manual testing steps** Please see the recording. ## **Screenshots/Recordings** https://github.com/MetaMask/metamask-extension/assets/7644512/861ef616-89a4-4292-8a2b-8a1733f2d88b ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've clearly explained what problem this PR is solving and how it is solved. - [x] I've linked related issues - [x] I've included manual testing steps - [x] I've included screenshots/recordings if applicable - [ ] 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. - [ ] I’ve properly set the pull request status: - [ ] In case it's not yet "ready for review", I've set it to "draft". - [ ] In case it's "ready for review", I've changed it from "draft" to "non-draft". ## **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: MetaMask Bot <[email protected]>
- Loading branch information
Showing
11 changed files
with
329 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
...s/transaction-already-confirmed/__snapshots__/transaction-already-confirmed.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Transaction Already Confirmed modal should match snapshot 1`] = ` | ||
<body> | ||
<div | ||
id="popover-content" | ||
/> | ||
<div /> | ||
<div | ||
class="mm-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" | ||
> | ||
<header | ||
class="mm-box mm-header-base mm-modal-header mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--padding-left-4 mm-box--display-flex mm-box--justify-content-space-between" | ||
> | ||
<div | ||
class="mm-box mm-box--width-full" | ||
> | ||
<h4 | ||
class="mm-box mm-text mm-text--heading-sm mm-text--text-align-center mm-box--color-text-default" | ||
> | ||
Transaction already confirmed | ||
</h4> | ||
</div> | ||
<div | ||
class="mm-box mm-box--display-flex mm-box--justify-content-flex-end" | ||
style="min-width: 0px;" | ||
> | ||
<button | ||
aria-label="Close" | ||
class="mm-box mm-button-icon mm-button-icon--size-sm mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg" | ||
> | ||
<span | ||
class="mm-box mm-icon mm-icon--size-sm mm-box--display-inline-block mm-box--color-inherit" | ||
style="mask-image: url('./images/icons/close.svg');" | ||
/> | ||
</button> | ||
</div> | ||
</header> | ||
<div | ||
class="mm-box mm-modal-body mm-box--padding-right-4 mm-box--padding-left-4" | ||
> | ||
<p | ||
class="mm-box mm-text mm-text--body-md mm-box--color-text-default" | ||
> | ||
We weren't able to cancel your transaction before it was confirmed on the blockchain. | ||
</p> | ||
</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-direction-column mm-box--flex-wrap-wrap mm-box--align-items-stretch" | ||
> | ||
<button | ||
class="mm-box mm-text mm-button-base mm-button-base--size-lg mm-modal-footer__button mm-button-secondary 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-default mm-box--background-color-transparent mm-box--rounded-pill mm-box--border-color-primary-default box--border-style-solid box--border-width-1" | ||
> | ||
View on block explorer | ||
</button> | ||
<button | ||
class="mm-box mm-text mm-button-base mm-button-base--size-lg 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" | ||
> | ||
Got it | ||
</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> | ||
`; |
1 change: 1 addition & 0 deletions
1
ui/components/app/modals/transaction-already-confirmed/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './transaction-already-confirmed'; |
34 changes: 34 additions & 0 deletions
34
...omponents/app/modals/transaction-already-confirmed/transaction-already-confirmed.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
import configureMockStore from 'redux-mock-store'; | ||
import mockStore from '../../../../../test/data/mock-state.json'; | ||
|
||
import { | ||
renderWithProvider, | ||
} from '../../../../../test/jest'; | ||
import TransactionAlreadyConfirmed from '.'; | ||
|
||
const getStoreWithModalData = () => { | ||
return configureMockStore()({ | ||
...mockStore, | ||
appState: { | ||
...mockStore.appState, | ||
modal: { | ||
modalState: { | ||
props: { | ||
originalTransactionId: 'test', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
}; | ||
|
||
describe('Transaction Already Confirmed modal', () => { | ||
it('should match snapshot', async () => { | ||
const { baseElement } = renderWithProvider( | ||
<TransactionAlreadyConfirmed />, | ||
getStoreWithModalData(), | ||
); | ||
expect(baseElement).toMatchSnapshot(); | ||
}); | ||
}); |
82 changes: 82 additions & 0 deletions
82
ui/components/app/modals/transaction-already-confirmed/transaction-already-confirmed.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import React, { useContext } from 'react'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { getBlockExplorerLink } from '@metamask/etherscan-link'; | ||
import { type TransactionMeta } from '@metamask/transaction-controller'; | ||
import { type NetworkClientConfiguration } from '@metamask/network-controller'; | ||
import { | ||
getRpcPrefsForCurrentProvider, | ||
getTransaction, | ||
} from '../../../../selectors'; | ||
import { useModalProps } from '../../../../hooks/useModalProps'; | ||
|
||
import { | ||
Modal, | ||
ModalOverlay, | ||
ModalContent, | ||
ModalHeader, | ||
ModalBody, | ||
Text, | ||
ModalFooter, | ||
} from '../../../component-library'; | ||
import { | ||
AlignItems, | ||
FlexDirection, | ||
} from '../../../../helpers/constants/design-system'; | ||
import { I18nContext } from '../../../../contexts/i18n'; | ||
import { MetaMaskReduxState } from '../../../../store/store'; | ||
|
||
export default function TransactionAlreadyConfirmed() { | ||
const { | ||
hideModal, | ||
props: { originalTransactionId }, | ||
} = useModalProps(); | ||
const t = useContext(I18nContext); | ||
const dispatch = useDispatch(); | ||
const transaction: TransactionMeta = useSelector( | ||
(state: MetaMaskReduxState) => | ||
(getTransaction as any)(state, originalTransactionId), | ||
); | ||
const rpcPrefs: NetworkClientConfiguration = useSelector( | ||
getRpcPrefsForCurrentProvider, | ||
); | ||
|
||
const viewTransaction = () => { | ||
// TODO: Fix getBlockExplorerLink arguments compatible with the actual controller types | ||
const blockExplorerLink = getBlockExplorerLink( | ||
transaction as any, | ||
rpcPrefs as any, | ||
); | ||
global.platform.openTab({ | ||
url: blockExplorerLink, | ||
}); | ||
dispatch(hideModal()); | ||
}; | ||
|
||
return ( | ||
<Modal isOpen onClose={hideModal}> | ||
<ModalOverlay /> | ||
<ModalContent> | ||
<ModalHeader onClose={hideModal}> | ||
{t('yourTransactionConfirmed')} | ||
</ModalHeader> | ||
<ModalBody> | ||
<Text>{t('yourTransactionJustConfirmed')}</Text> | ||
</ModalBody> | ||
<ModalFooter | ||
onSubmit={hideModal} | ||
onCancel={viewTransaction} | ||
submitButtonProps={{ | ||
children: t('gotIt'), | ||
}} | ||
cancelButtonProps={{ | ||
children: t('viewOnBlockExplorer'), | ||
}} | ||
containerProps={{ | ||
flexDirection: FlexDirection.Column, | ||
alignItems: AlignItems.stretch, | ||
}} | ||
/> | ||
</ModalContent> | ||
</Modal> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { useModalProps } from './useModalProps'; | ||
|
||
const MOCK_PROPS = { | ||
test: 'test', | ||
}; | ||
const MOCK_MM_STATE = { | ||
appState: { | ||
modal: { | ||
modalState: { | ||
props: MOCK_PROPS, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
jest.mock('react-redux', () => ({ | ||
useSelector: (selector: any) => selector(MOCK_MM_STATE), | ||
useDispatch: jest.fn(), | ||
})); | ||
|
||
jest.mock('../store/actions', () => ({ | ||
hideModal: jest.fn(), | ||
})); | ||
|
||
describe('useModalProps', () => { | ||
it('should return modal props and hideModal function', () => { | ||
const { props, hideModal } = useModalProps(); | ||
|
||
expect(props).toStrictEqual(MOCK_PROPS); | ||
expect(hideModal).toStrictEqual(expect.any(Function)); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { useSelector, useDispatch } from 'react-redux'; | ||
import { hideModal } from '../store/actions'; | ||
|
||
interface ModalProps { | ||
props: Record<string, any>; | ||
hideModal: () => void; | ||
} | ||
|
||
export function useModalProps(): ModalProps { | ||
const modalProps = useSelector((state: any) => { | ||
return state.appState.modal.modalState?.props; | ||
}); | ||
|
||
const dispatch = useDispatch(); | ||
const onHideModal = () => dispatch(hideModal()); | ||
|
||
return { props: modalProps, hideModal: onHideModal }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters