Skip to content

Commit

Permalink
Added navigation between multiple sign prompts and reject all sign pr…
Browse files Browse the repository at this point in the history
…ompts (#17093)

* Fixed navigation through multiple unapproved transactions for ERC20 tokens

* Fixed tx details activity-log currency

* Fixed e2e test failure

* Added navigation between multiple sign prompts and reject all sign prompts

* Resolving conflicts

* Creating SignatureRequestNavigation component and extracting the UI rendering part into a single component

* Fixing e2e tests and updating snapshot

* Using single component for navigation which shows both messages and transactions requests

* Fixing test-unit-jest-main

* Added more unit tests

* Fixing test-storybook

* Fixing test-storybook

---------

Co-authored-by: Filip Sekulic <filip.sekulic@consensys.net>
  • Loading branch information
VSaric and filipsekulic authored Jan 31, 2023
1 parent 6439d03 commit 8aa3263
Show file tree
Hide file tree
Showing 14 changed files with 456 additions and 24 deletions.
2 changes: 1 addition & 1 deletion ui/components/app/app-components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@
@import 'detected-token/detected-token-selection-popover/index';
@import 'network-account-balance-header/index';
@import 'approve-content-card/index';
@import 'transaction-alerts/transaction-alerts'
@import 'transaction-alerts/transaction-alerts';
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,43 @@ import React, { useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useParams } from 'react-router-dom';
import {
getCurrentChainId,
getUnapprovedTransactions,
unconfirmedTransactionsHashSelector,
unapprovedDecryptMsgsSelector,
unapprovedEncryptionPublicKeyMsgsSelector,
} from '../../../../selectors';
import { transactionMatchesNetwork } from '../../../../../shared/modules/transaction.utils';
import { I18nContext } from '../../../../contexts/i18n';
import { CONFIRM_TRANSACTION_ROUTE } from '../../../../helpers/constants/routes';
import {
CONFIRM_TRANSACTION_ROUTE,
SIGNATURE_REQUEST_PATH,
} from '../../../../helpers/constants/routes';
import { clearConfirmTransaction } from '../../../../ducks/confirm-transaction/confirm-transaction.duck';
import { hexToDecimal } from '../../../../../shared/modules/conversion.utils';

const ConfirmPageContainerNavigation = () => {
const t = useContext(I18nContext);
const dispatch = useDispatch();
const history = useHistory();
const { id } = useParams();

const unapprovedTxs = useSelector(getUnapprovedTransactions);
const currentChainId = useSelector(getCurrentChainId);
const network = hexToDecimal(currentChainId);
const unapprovedDecryptMsgs = useSelector(unapprovedDecryptMsgsSelector);
const unapprovedEncryptionPublicKeyMsgs = useSelector(
unapprovedEncryptionPublicKeyMsgsSelector,
);
const uncofirmedTransactions = useSelector(
unconfirmedTransactionsHashSelector,
);

const currentNetworkUnapprovedTxs = Object.keys(unapprovedTxs)
.filter((key) =>
transactionMatchesNetwork(unapprovedTxs[key], currentChainId, network),
)
.reduce((acc, key) => ({ ...acc, [key]: unapprovedTxs[key] }), {});
const enumUnapprovedDecryptMsgsKey = Object.keys(unapprovedDecryptMsgs);
const enumUnapprovedEncryptMsgsKey = Object.keys(
unapprovedEncryptionPublicKeyMsgs,
);
const enumDecryptAndEncryptMsgs = [
...enumUnapprovedDecryptMsgsKey,
...enumUnapprovedEncryptMsgsKey,
];

const enumUnapprovedTxs = Object.keys(currentNetworkUnapprovedTxs);
const enumUnapprovedTxs = Object.keys(uncofirmedTransactions).filter(
(key) => enumDecryptAndEncryptMsgs.includes(key) === false,
);

const currentPosition = enumUnapprovedTxs.indexOf(id);

Expand All @@ -42,7 +53,11 @@ const ConfirmPageContainerNavigation = () => {
const onNextTx = (txId) => {
if (txId) {
dispatch(clearConfirmTransaction());
history.push(`${CONFIRM_TRANSACTION_ROUTE}/${txId}`);
history.push(
uncofirmedTransactions[txId]?.msgParams
? `${CONFIRM_TRANSACTION_ROUTE}/${txId}${SIGNATURE_REQUEST_PATH}`
: `${CONFIRM_TRANSACTION_ROUTE}/${txId}`,
);
}
};

Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,76 @@ exports[`SignatureRequestOriginal should match snapshot 1`] = `
<div
class="request-signature__container"
>
<div
class="request-signature__navigation"
>
<div
class="confirm-page-container-navigation"
style="display: none;"
>
<div
class="confirm-page-container-navigation__container"
data-testid="navigation-container"
style="visibility: hidden;"
>
<button
class="confirm-page-container-navigation__arrow"
data-testid="first-page"
>
<i
class="fa fa-angle-double-left fa-2x"
/>
</button>
<button
class="confirm-page-container-navigation__arrow"
data-testid="previous-page"
>
<i
class="fa fa-angle-left fa-2x"
/>
</button>
</div>
<div
class="confirm-page-container-navigation__textcontainer"
>
<div
class="confirm-page-container-navigation__navtext"
>
0
of
0
</div>
<div
class="confirm-page-container-navigation__longtext"
>
requests waiting to be acknowledged
</div>
</div>
<div
class="confirm-page-container-navigation__container"
style="visibility: hidden;"
>
<button
class="confirm-page-container-navigation__arrow"
data-testid="next-page"
>
<i
class="fa fa-angle-right fa-2x"
/>
</button>
<button
class="confirm-page-container-navigation__arrow"
data-testid="last-page"
>
<i
class="fa fa-angle-double-right fa-2x"
/>
</button>
</div>
</div>
</div>
<div
class="request-signature__account"
>
Expand Down
5 changes: 3 additions & 2 deletions ui/components/app/signature-request-original/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}

@include screen-sm-min {
height: 620px;
height: 650px;
}

&__reject {
Expand Down Expand Up @@ -56,7 +56,8 @@
z-index: 3;
}

&__account {
&__account,
&__navigation {
width: 100%;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { NETWORK_TYPES } from '../../../../shared/constants/network';
import { Numeric } from '../../../../shared/modules/Numeric';
import { EtherDenomination } from '../../../../shared/constants/common';
import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation';
import SignatureRequestOriginalWarning from './signature-request-original-warning';

export default class SignatureRequestOriginal extends Component {
Expand Down Expand Up @@ -280,6 +281,9 @@ export default class SignatureRequestOriginal extends Component {

return (
<div className="request-signature__container">
<div className="request-signature__navigation">
<ConfirmPageContainerNavigation />
</div>
<div className="request-signature__account">
<NetworkAccountBalanceHeader
networkName={currentNetwork}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ describe('SignatureRequestOriginal', () => {
expect(container).toMatchSnapshot();
});

it('should render navigation', () => {
render();
const navigationContainer = screen.queryByTestId('navigation-container');
expect(navigationContainer).toBeInTheDocument();
});

it('should render eth sign screen', () => {
render();
expect(screen.getByText('Signature request')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,72 @@ exports[`Signature Request Component render should match snapshot 1`] = `
<div
class="signature-request"
>
<div
class="confirm-page-container-navigation"
style="display: none;"
>
<div
class="confirm-page-container-navigation__container"
data-testid="navigation-container"
style="visibility: hidden;"
>
<button
class="confirm-page-container-navigation__arrow"
data-testid="first-page"
>
<i
class="fa fa-angle-double-left fa-2x"
/>
</button>
<button
class="confirm-page-container-navigation__arrow"
data-testid="previous-page"
>
<i
class="fa fa-angle-left fa-2x"
/>
</button>
</div>
<div
class="confirm-page-container-navigation__textcontainer"
>
<div
class="confirm-page-container-navigation__navtext"
>
0
of
0
</div>
<div
class="confirm-page-container-navigation__longtext"
>
requests waiting to be acknowledged
</div>
</div>
<div
class="confirm-page-container-navigation__container"
style="visibility: hidden;"
>
<button
class="confirm-page-container-navigation__arrow"
data-testid="next-page"
>
<i
class="fa fa-angle-right fa-2x"
/>
</button>
<button
class="confirm-page-container-navigation__arrow"
data-testid="last-page"
>
<i
class="fa fa-angle-double-right fa-2x"
/>
</button>
</div>
</div>
<div
class="request-signature__account"
>
Expand Down
7 changes: 6 additions & 1 deletion ui/components/app/signature-request/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,22 @@
flex-direction: column;
min-width: 0;
width: 408px;
height: max-content;
background-color: var(--color-background-default);
box-shadow: var(--shadow-size-xs) var(--color-shadow-default);
border-radius: 8px;

@include screen-sm-min {
max-height: 55vh;
max-height: 80vh;
min-height: 570px;
flex: 0 0 auto;
margin-left: auto;
margin-right: auto;
}

&__reject-all-button {
margin-top: -15px;
}
}

.signature-request-header {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import NetworkAccountBalanceHeader from '../network-account-balance-header';
import { NETWORK_TYPES } from '../../../../shared/constants/network';
import { Numeric } from '../../../../shared/modules/Numeric';
import { EtherDenomination } from '../../../../shared/constants/common';
import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation';
import Footer from './signature-request-footer';
import Message from './signature-request-message';

Expand Down Expand Up @@ -67,6 +68,12 @@ export default class SignatureRequest extends PureComponent {
nativeCurrency: PropTypes.string,
provider: PropTypes.object,
subjectMetadata: PropTypes.object,
unapprovedMessagesCount: PropTypes.number,
clearConfirmTransaction: PropTypes.func.isRequired,
history: PropTypes.object,
mostRecentOverviewPage: PropTypes.string,
showRejectTransactionsConfirmationModal: PropTypes.func.isRequired,
cancelAll: PropTypes.func.isRequired,
};

static contextTypes = {
Expand Down Expand Up @@ -115,6 +122,26 @@ export default class SignatureRequest extends PureComponent {
return { sanitizedMessage, domain, primaryType };
});

handleCancelAll = () => {
const {
cancelAll,
clearConfirmTransaction,
history,
mostRecentOverviewPage,
showRejectTransactionsConfirmationModal,
unapprovedMessagesCount,
} = this.props;

showRejectTransactionsConfirmationModal({
unapprovedTxCount: unapprovedMessagesCount,
onSubmit: async () => {
await cancelAll();
clearConfirmTransaction();
history.push(mostRecentOverviewPage);
},
});
};

render() {
const {
txData: {
Expand All @@ -133,13 +160,15 @@ export default class SignatureRequest extends PureComponent {
subjectMetadata,
conversionRate,
nativeCurrency,
unapprovedMessagesCount,
} = this.props;
const { trackEvent } = this.context;
const { t, trackEvent } = this.context;
const {
sanitizedMessage,
domain: { verifyingContract },
primaryType,
} = this.memoizedParseMessage(data);
const rejectNText = t('rejectRequestsN', [unapprovedMessagesCount]);
const currentNetwork = this.getNetworkName();

const balanceInBaseAsset = new Numeric(balance, 16, EtherDenomination.WEI)
Expand Down Expand Up @@ -185,6 +214,7 @@ export default class SignatureRequest extends PureComponent {

return (
<div className="signature-request">
<ConfirmPageContainerNavigation />
<div className="request-signature__account">
<NetworkAccountBalanceHeader
networkName={currentNetwork}
Expand Down Expand Up @@ -274,6 +304,19 @@ export default class SignatureRequest extends PureComponent {
isContractRequestingSignature
/>
)}
{unapprovedMessagesCount > 1 ? (
<Button
type="link"
className="signature-request__reject-all-button"
data-testid="signature-request-reject-all"
onClick={(e) => {
e.preventDefault();
this.handleCancelAll();
}}
>
{rejectNText}
</Button>
) : null}
</div>
);
}
Expand Down
Loading

0 comments on commit 8aa3263

Please sign in to comment.