From d17e13ad6401353b6778ebb46629cace7758f813 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Mon, 7 Oct 2024 17:33:14 +0100 Subject: [PATCH 1/2] fix: Limit amount of decimals on spending cap modal --- app/_locales/en/messages.json | 3 ++ .../edit-spending-cap-modal.tsx | 38 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 60ec9579059d..f87eddb4d0ed 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1838,6 +1838,9 @@ "editSpendingCapDesc": { "message": "Enter the amount that you feel comfortable being spent on your behalf." }, + "editSpendingCapError": { + "message": "The spending cap shouldn't exceed $1 decimals." + }, "enable": { "message": "Enable" }, diff --git a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx index e7431457f5c2..10a4dc269235 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx @@ -1,5 +1,5 @@ import { TransactionMeta } from '@metamask/transaction-controller'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { calcTokenAmount } from '../../../../../../../../shared/lib/transactions-controller-utils'; import { hexToDecimal } from '../../../../../../../../shared/modules/conversion.utils'; @@ -32,6 +32,18 @@ import { useConfirmContext } from '../../../../../context/confirm'; import { useAssetDetails } from '../../../../../hooks/useAssetDetails'; import { useApproveTokenSimulation } from '../hooks/use-approve-token-simulation'; +function countDecimalDigits(numberString: string) { + const decimalPointIndex = numberString.indexOf('.'); + + if (decimalPointIndex === -1) { + return 0; + } + + const decimalDigits = numberString.length - decimalPointIndex - 1; + + return decimalDigits; +} + export const EditSpendingCapModal = ({ isOpenEditSpendingCapModal, setIsOpenEditSpendingCapModal, @@ -116,10 +128,17 @@ export const EditSpendingCapModal = ({ setCustomSpendingCapInputValue(formattedSpendingCap.toString()); }, [customSpendingCapInputValue, formattedSpendingCap]); + const showDecimalError = useMemo(() => { + return ( + decimals && + parseInt(decimals, 10) < countDecimalDigits(customSpendingCapInputValue) + ); + }, [decimals, customSpendingCapInputValue]); + return ( setIsOpenEditSpendingCapModal(false)} + onClose={() => handleCancel()} isClosedOnEscapeKey isClosedOnOutsideClick className="edit-spending-cap-modal" @@ -164,11 +183,24 @@ export const EditSpendingCapModal = ({ tokenSymbol || '', ])} + {showDecimalError && ( + + {t('editSpendingCapError', [decimals])} + + )} From 0764d25fdc4e01a3da9533d2542e847f4f95635d Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Tue, 8 Oct 2024 13:23:36 +0100 Subject: [PATCH 2/2] Edit copy --- app/_locales/en/messages.json | 2 +- .../edit-spending-cap-modal.test.tsx | 28 +++++++++++- .../edit-spending-cap-modal.tsx | 43 +++++++------------ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index f87eddb4d0ed..b7345f8d4f6c 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1839,7 +1839,7 @@ "message": "Enter the amount that you feel comfortable being spent on your behalf." }, "editSpendingCapError": { - "message": "The spending cap shouldn't exceed $1 decimals." + "message": "The spending cap can’t exceed $1 decimal digits. Remove decimal digits to continue." }, "enable": { "message": "Enable" diff --git a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx index e4604fb715ab..448506f17126 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx @@ -3,7 +3,10 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { getMockApproveConfirmState } from '../../../../../../../../test/data/confirmations/helper'; import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers'; -import { EditSpendingCapModal } from './edit-spending-cap-modal'; +import { + countDecimalDigits, + EditSpendingCapModal, +} from './edit-spending-cap-modal'; jest.mock('react-dom', () => ({ ...jest.requireActual('react-dom'), @@ -78,3 +81,26 @@ describe('', () => { expect(container).toMatchSnapshot(); }); }); + +describe('countDecimalDigits()', () => { + // @ts-expect-error This is missing from the Mocha type definitions + it.each([ + { numberString: '0', expectedDecimals: 0 }, + { numberString: '100', expectedDecimals: 0 }, + { numberString: '100.123', expectedDecimals: 3 }, + { numberString: '3.141592654', expectedDecimals: 9 }, + ])( + 'should return $expectedDecimals decimals for `$numberString`', + ({ + numberString, + expectedDecimals, + }: { + numberString: string; + expectedDecimals: number; + }) => { + const actual = countDecimalDigits(numberString); + + expect(actual).toEqual(expectedDecimals); + }, + ); +}); diff --git a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx index 10a4dc269235..2762e99652a5 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx @@ -1,5 +1,5 @@ import { TransactionMeta } from '@metamask/transaction-controller'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; import { calcTokenAmount } from '../../../../../../../../shared/lib/transactions-controller-utils'; import { hexToDecimal } from '../../../../../../../../shared/modules/conversion.utils'; @@ -32,16 +32,8 @@ import { useConfirmContext } from '../../../../../context/confirm'; import { useAssetDetails } from '../../../../../hooks/useAssetDetails'; import { useApproveTokenSimulation } from '../hooks/use-approve-token-simulation'; -function countDecimalDigits(numberString: string) { - const decimalPointIndex = numberString.indexOf('.'); - - if (decimalPointIndex === -1) { - return 0; - } - - const decimalDigits = numberString.length - decimalPointIndex - 1; - - return decimalDigits; +export function countDecimalDigits(numberString: string) { + return numberString.split('.')[1]?.length || 0; } export const EditSpendingCapModal = ({ @@ -128,17 +120,14 @@ export const EditSpendingCapModal = ({ setCustomSpendingCapInputValue(formattedSpendingCap.toString()); }, [customSpendingCapInputValue, formattedSpendingCap]); - const showDecimalError = useMemo(() => { - return ( - decimals && - parseInt(decimals, 10) < countDecimalDigits(customSpendingCapInputValue) - ); - }, [decimals, customSpendingCapInputValue]); + const showDecimalError = + decimals && + parseInt(decimals, 10) < countDecimalDigits(customSpendingCapInputValue); return ( handleCancel()} + onClose={handleCancel} isClosedOnEscapeKey isClosedOnOutsideClick className="edit-spending-cap-modal" @@ -173,6 +162,15 @@ export const EditSpendingCapModal = ({ style={{ width: '100%' }} inputProps={{ 'data-testid': 'custom-spending-cap-input' }} /> + {showDecimalError && ( + + {t('editSpendingCapError', [decimals])} + + )} - {showDecimalError && ( - - {t('editSpendingCapError', [decimals])} - - )}