Skip to content

Commit 3fefddc

Browse files
committed
Implementing features in simulation section for batched transactions
1 parent 7b91d9d commit 3fefddc

File tree

16 files changed

+668
-51
lines changed

16 files changed

+668
-51
lines changed

app/components/UI/SimulationDetails/AmountPill/AmountPill.styles.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@ import sharedStyles from '../shared.styles';
44

55
const styleSheet = (params: {
66
theme: Theme;
7-
vars: { isNegative: boolean };
7+
vars: { isApproval: boolean; isNegative: boolean };
88
}) => {
99
const { theme, vars } = params;
1010
const { colors } = theme;
11-
const { isNegative } = vars;
11+
const { isNegative, isApproval } = vars;
1212

13-
const backgroundColor = isNegative
14-
? colors.error.muted
15-
: colors.success.muted;
13+
let backgroundColor: string | undefined = undefined;
14+
let textColor: string | undefined = undefined;
1615

17-
const textColor = isNegative
18-
? colors.error.alternative
19-
: colors.success.default;
16+
if (isApproval) {
17+
backgroundColor = colors.background.muted;
18+
textColor = colors.text.default;
19+
} else {
20+
backgroundColor = isNegative ? colors.error.muted : colors.success.muted;
21+
textColor = isNegative ? colors.error.alternative : colors.success.default;
22+
}
2023

2124
return StyleSheet.create({
2225
base: {

app/components/UI/SimulationDetails/AmountPill/AmountPill.test.tsx

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,16 @@ const NATIVE_ASSET_MOCK: NativeAssetIdentifier = {
3535
};
3636

3737
const renderAndExpect = (
38-
asset: AssetIdentifier,
39-
amount: BigNumber,
38+
props: {
39+
asset: AssetIdentifier;
40+
amount: BigNumber;
41+
isApproval?: boolean;
42+
isAllApproval?: boolean;
43+
isUnlimitedApproval?: boolean;
44+
},
4045
expected: { text: string },
4146
): void => {
42-
const { getByText } = render(<AmountPill asset={asset} amount={amount} />);
47+
const { getByText } = render(<AmountPill {...props} />);
4348
expect(getByText(expected.text)).toBeTruthy();
4449
};
4550

@@ -50,71 +55,97 @@ describe('AmountPill', () => {
5055

5156
const nativeAndErc20Cases = [
5257
{
53-
amount: new BigNumber(-123.1234567),
58+
props: { amount: new BigNumber(-123.1234567) },
5459
expected: {
5560
text: '- 123.1',
5661
},
5762
},
5863
{
59-
amount: new BigNumber(789.412),
64+
props: { amount: new BigNumber(789.412) },
6065
expected: {
6166
text: '+ 789.4',
6267
},
6368
},
6469
{
65-
amount: new BigNumber(-0.000000001),
70+
props: { amount: new BigNumber(-0.000000001) },
6671
expected: {
6772
text: '- < 0.000001',
6873
},
6974
},
7075
{
71-
amount: new BigNumber(0.000000001),
76+
props: { amount: new BigNumber(0.000000001) },
7277
expected: {
7378
text: '+ < 0.000001',
7479
},
7580
},
7681
{
77-
amount: new BigNumber(-0),
82+
props: { amount: new BigNumber(-0) },
7883
expected: {
7984
text: '- 0',
8085
},
8186
},
8287
{
83-
amount: new BigNumber(0),
88+
props: { amount: new BigNumber(0) },
8489
expected: {
8590
text: '+ 0',
8691
},
8792
},
93+
{
94+
props: { amount: new BigNumber(100), isApproval: true },
95+
expected: {
96+
text: '100',
97+
},
98+
},
99+
{
100+
props: {
101+
amount: new BigNumber(100),
102+
isApproval: true,
103+
isUnlimitedApproval: true,
104+
},
105+
expected: {
106+
text: 'Unlimited',
107+
},
108+
},
109+
{
110+
props: {
111+
amount: new BigNumber(100),
112+
isApproval: true,
113+
isAllApproval: true,
114+
},
115+
expected: {
116+
text: 'All',
117+
},
118+
},
88119
];
89120

90121
describe('Native', () => {
91122
it.each(nativeAndErc20Cases)(
92123
'renders the correct sign and amount for $amount',
93-
({ amount, expected }) => {
94-
renderAndExpect(NATIVE_ASSET_MOCK, amount, expected);
124+
({ props, expected }) => {
125+
renderAndExpect({ ...props, asset: NATIVE_ASSET_MOCK }, expected);
95126
},
96127
);
97128
});
98129

99130
describe('ERC20', () => {
100131
it.each(nativeAndErc20Cases)(
101132
'renders the correct sign and amount for $amount',
102-
({ amount, expected }) => {
103-
renderAndExpect(ERC20_ASSET_MOCK, amount, expected);
133+
({ props, expected }) => {
134+
renderAndExpect({ ...props, asset: ERC20_ASSET_MOCK }, expected);
104135
},
105136
);
106137
});
107138

108139
describe('ERC721', () => {
109140
const cases = [
110141
{
111-
amount: new BigNumber(-1),
142+
props: { amount: new BigNumber(-1) },
112143
expected: {
113144
text: '- #2748',
114145
},
115146
},
116147
{
117-
amount: new BigNumber(1),
148+
props: { amount: new BigNumber(1) },
118149
expected: {
119150
text: '+ #2748',
120151
},
@@ -123,28 +154,28 @@ describe('AmountPill', () => {
123154

124155
it.each(cases)(
125156
'renders the token ID with just a plus or minus for $expected.text',
126-
({ amount, expected }) => {
127-
renderAndExpect(ERC721_ASSET_MOCK, amount, expected);
157+
({ props, expected }) => {
158+
renderAndExpect({ ...props, asset: ERC721_ASSET_MOCK }, expected);
128159
},
129160
);
130161
});
131162

132163
describe('ERC1155', () => {
133164
const cases = [
134165
{
135-
amount: new BigNumber(-3),
166+
props: { amount: new BigNumber(-3) },
136167
expected: {
137168
text: '- 3 #2748',
138169
},
139170
},
140171
{
141-
amount: new BigNumber(8),
172+
props: { amount: new BigNumber(8) },
142173
expected: {
143174
text: '+ 8 #2748',
144175
},
145176
},
146177
{
147-
amount: new BigNumber(-12),
178+
props: { amount: new BigNumber(-12) },
148179
expected: {
149180
text: '- 12 #2748',
150181
},
@@ -153,8 +184,8 @@ describe('AmountPill', () => {
153184

154185
it.each(cases)(
155186
'renders the correct sign, amount, and token ID for $expected.text',
156-
({ amount, expected }) => {
157-
renderAndExpect(ERC1155_ASSET_MOCK, amount, expected);
187+
({ props, expected }) => {
188+
renderAndExpect({ ...props, asset: ERC1155_ASSET_MOCK }, expected);
158189
},
159190
);
160191
});

app/components/UI/SimulationDetails/AmountPill/AmountPill.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react';
33
import { BigNumber } from 'bignumber.js';
44
import { AssetIdentifier, AssetType } from '../types';
55
import { formatAmount, formatAmountMaxPrecision } from '../formatAmount';
6-
import I18n from '../../../../../locales/i18n';
6+
import I18n, { strings } from '../../../../../locales/i18n';
77
import styleSheet from './AmountPill.styles';
88
import { View, ViewProps } from 'react-native';
99
import Text, {
@@ -15,6 +15,9 @@ import { hexToDecimal } from '../../../../util/conversions';
1515
interface AmountPillProperties extends ViewProps {
1616
asset: AssetIdentifier;
1717
amount: BigNumber;
18+
isApproval?: boolean;
19+
isAllApproval?: boolean;
20+
isUnlimitedApproval?: boolean;
1821
}
1922
/**
2023
* Displays a pill with an amount and a background color indicating whether the amount
@@ -28,18 +31,28 @@ const AmountPill: React.FC<AmountPillProperties> = ({
2831
asset,
2932
amount,
3033
style,
34+
isApproval,
35+
isAllApproval,
36+
isUnlimitedApproval,
3137
...props
3238
}) => {
3339
const { styles } = useStyles(styleSheet, {
3440
style,
41+
isApproval: isApproval ?? false,
3542
isNegative: amount.isNegative(),
3643
});
37-
const amountParts: string[] = [amount.isNegative() ? '-' : '+'];
44+
const amountParts: string[] = [];
3845
const tooltipParts: string[] = [];
3946

47+
if (!isApproval) {
48+
amountParts.push(amount.isNegative() ? '-' : '+');
49+
}
50+
4051
// ERC721 amounts are always 1 and are not displayed.
41-
if (asset.type !== AssetType.ERC721) {
42-
const formattedAmount = formatAmount(I18n.locale, amount.abs());
52+
if (asset.type !== AssetType.ERC721 && !isAllApproval) {
53+
const formattedAmount = isUnlimitedApproval
54+
? strings('confirm.unlimited')
55+
: formatAmount(I18n.locale, amount.abs());
4356
const fullPrecisionAmount = formatAmountMaxPrecision(
4457
I18n.locale,
4558
amount.abs(),
@@ -56,6 +69,11 @@ const AmountPill: React.FC<AmountPillProperties> = ({
5669
tooltipParts.push(tokenIdPart);
5770
}
5871

72+
if (isAllApproval) {
73+
amountParts.push(strings('confirm.all'));
74+
tooltipParts.push(strings('confirm.all'));
75+
}
76+
5977
return (
6078
<View
6179
testID="simulation-details-amount-pill"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import BigNumber from 'bignumber.js';
3+
import { Hex } from '@metamask/utils';
4+
5+
import renderWithProvider from '../../../../util/test/renderWithProvider';
6+
import {
7+
getAppStateForConfirmation,
8+
upgradeAccountConfirmation,
9+
} from '../../../../util/test/confirm-data-helpers';
10+
// eslint-disable-next-line import/no-namespace
11+
import * as BatchApprovalUtils from '../../../Views/confirmations/hooks/7702/useBatchApproveBalanceChanges';
12+
import { AssetType } from '../types';
13+
import BatchApprovalRow from './BatchApprovalRow';
14+
15+
const approvalData = [
16+
{
17+
asset: {
18+
type: 'ERC20' as AssetType.ERC20 | AssetType.ERC721 | AssetType.ERC1155,
19+
address: '0x6b175474e89094c44da98b954eedeac495271d0f' as Hex,
20+
chainId: '0x1' as Hex,
21+
},
22+
amount: new BigNumber('-0.00001'),
23+
fiatAmount: null,
24+
isApproval: true,
25+
isAllApproval: false,
26+
isUnlimitedApproval: false,
27+
nestedTransactionIndex: 0,
28+
},
29+
];
30+
31+
describe('BatchApprovalRow', () => {
32+
it('renders a balance change row', () => {
33+
jest
34+
.spyOn(BatchApprovalUtils, 'useBatchApproveBalanceChanges')
35+
.mockReturnValue({ value: approvalData, pending: false });
36+
const { getByText } = renderWithProvider(<BatchApprovalRow />, {
37+
state: getAppStateForConfirmation(upgradeAccountConfirmation),
38+
});
39+
40+
expect(getByText('You approve')).toBeTruthy();
41+
expect(getByText('- 0.00001')).toBeTruthy();
42+
});
43+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
import { strings } from '../../../../../locales/i18n';
4+
import { useBatchApproveBalanceChanges } from '../../../Views/confirmations/hooks/7702/useBatchApproveBalanceChanges';
5+
import BalanceChangeRow from '../BalanceChangeRow/BalanceChangeRow';
6+
import { BalanceChange } from '../types';
7+
8+
const BatchApprovalRow = () => {
9+
const { value: approveBalanceChanges } =
10+
useBatchApproveBalanceChanges() ?? {};
11+
12+
if (!approveBalanceChanges?.length) {
13+
return null;
14+
}
15+
16+
return (
17+
<>
18+
{approveBalanceChanges.map((balanceChange) => (
19+
<BalanceChangeRow
20+
label={strings('confirm.simulation.label_change_type_approve')}
21+
balanceChange={balanceChange as BalanceChange}
22+
/>
23+
))}
24+
</>
25+
);
26+
};
27+
28+
export default BatchApprovalRow;

0 commit comments

Comments
 (0)