From 0e6759f10c7475994eff8a7959e3e3622f85d339 Mon Sep 17 00:00:00 2001 From: Alessandro Izzo Date: Wed, 29 May 2024 11:46:32 +0200 Subject: [PATCH] feat: [IOBP-647] Latest used method pre-selection (#5783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Short description This PR implements the logic to pre-select a payment method from the user wallets that have been recently used and will be shown in the appropriate “Recently Used” list item ## List of changes proposed in this pull request - Added an additional selector to filter the recently used payment method from the user wallet with the field `updateDate` as more recent; - Added a pre-selection statement into the reducer when the action `paymentsGetPaymentUserMethodsAction.success` is fired to filter the most recent payment method. ## How to test Start a new payment flow with the new payment section feature flag enabled; When you start a payment, you should be able to see the most recently used payment method pre-selected ## Preview https://github.com/pagopa/io-app/assets/34343582/38e455e8-3e10-450d-a360-8c4024d3a75b --------- Co-authored-by: Jacopo Pompilii Co-authored-by: Federico Mastrini --- locales/en/index.yml | 1 + locales/it/index.yml | 1 + .../components/CheckoutPaymentMethodsList.tsx | 48 +++++++++++++++++-- .../payments/checkout/store/reducers/index.ts | 7 ++- .../store/selectors/paymentMethods.ts | 15 ++++++ 5 files changed, 66 insertions(+), 6 deletions(-) diff --git a/locales/en/index.yml b/locales/en/index.yml index a297614d25d..8c00774454d 100644 --- a/locales/en/index.yml +++ b/locales/en/index.yml @@ -1709,6 +1709,7 @@ wallet: header: Seleziona un metodo yourMethods: Saved otherMethods: All methods + latestMethod: Recently used alert: body: "A causa dell’importo elevato, alcuni metodi non sono disponibili." cta: "Ok, ho capito!" diff --git a/locales/it/index.yml b/locales/it/index.yml index 6f45dadd78c..334ecbc5685 100644 --- a/locales/it/index.yml +++ b/locales/it/index.yml @@ -1709,6 +1709,7 @@ wallet: header: Seleziona un metodo yourMethods: Salvati otherMethods: Tutti i metodi + latestMethod: Usato di recente alert: body: "A causa dell’importo elevato, alcuni metodi non sono disponibili." cta: "Ok, ho capito!" diff --git a/ts/features/payments/checkout/components/CheckoutPaymentMethodsList.tsx b/ts/features/payments/checkout/components/CheckoutPaymentMethodsList.tsx index b7385114149..69f72688e5f 100644 --- a/ts/features/payments/checkout/components/CheckoutPaymentMethodsList.tsx +++ b/ts/features/payments/checkout/components/CheckoutPaymentMethodsList.tsx @@ -23,6 +23,7 @@ import { walletPaymentAllMethodsSelector, walletPaymentSelectedPaymentMethodIdOptionSelector, walletPaymentSelectedWalletIdOptionSelector, + walletPaymentUserWalletLastUpdatedSelector, walletPaymentUserWalletsSelector } from "../store/selectors/paymentMethods"; import { getPaymentLogoFromWalletDetails } from "../../common/utils"; @@ -37,6 +38,9 @@ const CheckoutPaymentMethodsList = () => { const paymentAmountPot = useIOSelector(walletPaymentAmountSelector); const allPaymentMethods = useIOSelector(walletPaymentAllMethodsSelector); const userWallets = useIOSelector(walletPaymentUserWalletsSelector); + const latestPaymentMethodUsed = useIOSelector( + walletPaymentUserWalletLastUpdatedSelector + ); const selectedUserWalletIdOption = useIOSelector( walletPaymentSelectedWalletIdOptionSelector @@ -51,6 +55,17 @@ const CheckoutPaymentMethodsList = () => { O.getOrElse(() => 0) ); + const latestPaymentMethodListItem = useMemo( + () => + pipe( + latestPaymentMethodUsed, + O.chainNullableK(mapUserWalletToRadioItem), + O.map(A.of), + O.getOrElse(() => [] as Array>) + ), + [latestPaymentMethodUsed] + ); + const userPaymentMethodListItems = useMemo( () => pipe( @@ -59,9 +74,15 @@ const CheckoutPaymentMethodsList = () => { O.map(methods => methods.map(mapUserWalletToRadioItem)), O.map(A.map(O.fromNullable)), O.map(A.compact), + O.map( + A.filter( + method => + !latestPaymentMethodListItem.some(item => item.id === method.id) + ) + ), O.getOrElse(() => [] as Array>) ), - [userWallets] + [userWallets, latestPaymentMethodListItem] ); const allPaymentMethodListItems = useMemo( @@ -79,11 +100,17 @@ const CheckoutPaymentMethodsList = () => { useEffect(() => { const hasDisabledMethods = - [...userPaymentMethodListItems, ...allPaymentMethodListItems].find( - item => item.disabled - ) !== undefined; + [ + ...userPaymentMethodListItems, + ...allPaymentMethodListItems, + ...latestPaymentMethodListItem + ].find(item => item.disabled) !== undefined; setShouldShowWarningBanner(hasDisabledMethods); - }, [userPaymentMethodListItems, allPaymentMethodListItems]); + }, [ + userPaymentMethodListItems, + allPaymentMethodListItems, + latestPaymentMethodListItem + ]); const handleSelectUserWallet = (walletId: string) => pipe( @@ -131,6 +158,17 @@ const CheckoutPaymentMethodsList = () => { action={I18n.t("wallet.payment.methodSelection.alert.cta")} /> )} + {!_.isEmpty(latestPaymentMethodListItem) && ( + + )} + + type="radioListItem" + selectedItem={selectedWalletId} + items={latestPaymentMethodListItem} + onPress={handleSelectUserWallet} + /> {!_.isEmpty(userPaymentMethodListItems) && ( + acc.updateDate > curr.updateDate ? acc : curr + ) + ) }; case getType(paymentsGetPaymentUserMethodsAction.failure): return { diff --git a/ts/features/payments/checkout/store/selectors/paymentMethods.ts b/ts/features/payments/checkout/store/selectors/paymentMethods.ts index 5cc97cfcea7..80f2df8afc2 100644 --- a/ts/features/payments/checkout/store/selectors/paymentMethods.ts +++ b/ts/features/payments/checkout/store/selectors/paymentMethods.ts @@ -12,6 +12,21 @@ export const walletPaymentUserWalletsSelector = createSelector( state => pot.map(state.userWallets, _ => _.wallets ?? []) ); +// Get from the userwallets the wallet with the attribute lastUpdated more recent +export const walletPaymentUserWalletLastUpdatedSelector = createSelector( + walletPaymentUserWalletsSelector, + userWalletsPot => + pipe( + userWalletsPot, + pot.toOption, + O.map(userWallets => + userWallets.reduce((acc, curr) => + acc.updateDate > curr.updateDate ? acc : curr + ) + ) + ) +); + export const walletPaymentAllMethodsSelector = createSelector( selectPaymentsCheckoutState, state => pot.map(state.allPaymentMethods, _ => _.paymentMethods ?? [])