diff --git a/locales/en/index.yml b/locales/en/index.yml index 26f4ccddb42..b15e65c75e3 100644 --- a/locales/en/index.yml +++ b/locales/en/index.yml @@ -3533,6 +3533,7 @@ features: requestAssistance: "Something wrong?" showClaimValues: "Show claim values" hideClaimValues: "Hide claim values" + openIPatente: "Vai al saldo punti patente" dialogs: remove: title: Vuoi rimuovere il documento dal Portafoglio? diff --git a/locales/it/index.yml b/locales/it/index.yml index 1305f0d0adb..e8dddcd9c44 100644 --- a/locales/it/index.yml +++ b/locales/it/index.yml @@ -3533,6 +3533,7 @@ features: requestAssistance: "Qualcosa non torna?" showClaimValues: "Mostra gli attributi del documento" hideClaimValues: "Nascondi gli attributi del documento" + openIPatente: "Vai al saldo punti patente" dialogs: remove: title: Vuoi rimuovere il documento dal Portafoglio? diff --git a/ts/features/itwallet/common/store/selectors/__tests__/index.test.ts b/ts/features/itwallet/common/store/selectors/__tests__/index.test.ts index fbfabaffa31..3e2865a9858 100644 --- a/ts/features/itwallet/common/store/selectors/__tests__/index.test.ts +++ b/ts/features/itwallet/common/store/selectors/__tests__/index.test.ts @@ -4,12 +4,12 @@ import { } from ".."; import { GlobalState } from "../../../../../../store/reducers/types"; import { itwIsWalletEmptySelector } from "../../../../credentials/store/selectors"; +import { itwLifecycleIsValidSelector } from "../../../../lifecycle/store/selectors"; import { itwIsFeedbackBannerHiddenSelector } from "../preferences"; import { isItwEnabledSelector, isItwFeedbackBannerEnabledSelector -} from "../../../../../../store/reducers/backendStatus/remoteConfig"; -import { itwLifecycleIsValidSelector } from "../../../../lifecycle/store/selectors"; +} from "../remoteConfig"; type JestMock = ReturnType; @@ -24,13 +24,10 @@ jest.mock("../preferences", () => ({ itwIsFeedbackBannerHiddenSelector: jest.fn() })); -jest.mock( - "../../../../../../store/reducers/backendStatus/remoteConfig", - () => ({ - isItwEnabledSelector: jest.fn(), - isItwFeedbackBannerEnabledSelector: jest.fn() - }) -); +jest.mock("../remoteConfig", () => ({ + isItwEnabledSelector: jest.fn(), + isItwFeedbackBannerEnabledSelector: jest.fn() +})); describe("itwDiscoveryBannerSelector", () => { beforeEach(() => { diff --git a/ts/features/itwallet/common/store/selectors/index.ts b/ts/features/itwallet/common/store/selectors/index.ts index f45a0cdab17..8bb3441dab8 100644 --- a/ts/features/itwallet/common/store/selectors/index.ts +++ b/ts/features/itwallet/common/store/selectors/index.ts @@ -1,7 +1,3 @@ -import { - isItwEnabledSelector, - isItwFeedbackBannerEnabledSelector -} from "../../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../../store/reducers/types"; import { itwCredentialsEidStatusSelector, @@ -10,9 +6,13 @@ import { import { itwLifecycleIsValidSelector } from "../../../lifecycle/store/selectors"; import { itwIsWalletInstanceStatusFailureSelector } from "../../../walletInstance/store/selectors"; import { - itwIsFeedbackBannerHiddenSelector, - itwIsDiscoveryBannerHiddenSelector + itwIsDiscoveryBannerHiddenSelector, + itwIsFeedbackBannerHiddenSelector } from "./preferences"; +import { + isItwEnabledSelector, + isItwFeedbackBannerEnabledSelector +} from "./remoteConfig"; /** * Returns if the discovery banner should be rendered. The banner is rendered if: diff --git a/ts/features/itwallet/common/store/selectors/remoteConfig.ts b/ts/features/itwallet/common/store/selectors/remoteConfig.ts new file mode 100644 index 00000000000..cc52d8e788f --- /dev/null +++ b/ts/features/itwallet/common/store/selectors/remoteConfig.ts @@ -0,0 +1,121 @@ +import * as O from "fp-ts/lib/Option"; +import { pipe } from "fp-ts/lib/function"; +import { Platform } from "react-native"; +import { createSelector } from "reselect"; +import { GlobalState } from "../../../../../store/reducers/types"; +import { + getAppVersion, + isVersionSupported +} from "../../../../../utils/appVersion"; + +const emptyArray: ReadonlyArray = []; // to avoid unnecessary rerenders + +const itwRemoteConfigSelector = (state: GlobalState) => + pipe( + state.remoteConfig, + O.map(config => config.itw) + ); + +/** + * Return the remote config about IT-WALLET enabled/disabled + * if there is no data or the local Feature Flag is disabled, + * false is the default value -> (IT-WALLET disabled) + */ +export const isItwEnabledSelector = createSelector( + itwRemoteConfigSelector, + (itwConfig): boolean => + pipe( + itwConfig, + O.map( + itw => + isVersionSupported( + Platform.OS === "ios" + ? itw.min_app_version.ios + : itw.min_app_version.android, + getAppVersion() + ) && itw.enabled + ), + O.getOrElse(() => false) + ) +); + +/** + * Returns the authentication methods that are disabled. + * If there is no data, an empty array is returned as the default value. + */ +export const itwDisabledIdentificationMethodsSelector = createSelector( + itwRemoteConfigSelector, + (itwConfig): ReadonlyArray => + pipe( + itwConfig, + O.chainNullableK(itw => itw.disabled_identification_methods), + O.getOrElse(() => emptyArray) + ) +); + +/** + * Return whether the IT Wallet feedback banner is remotely enabled. + */ +export const isItwFeedbackBannerEnabledSelector = createSelector( + itwRemoteConfigSelector, + itwConfig => + pipe( + itwConfig, + O.map(itw => itw.feedback_banner_visible), + O.getOrElse(() => false) + ) +); + +/** + * Return whether the Wallet activation is disabled. + * This is purely a "cosmetic" configuration to disable UI elements, + * it does not disable the entire IT Wallet feature. + */ +export const itwIsActivationDisabledSelector = createSelector( + itwRemoteConfigSelector, + itwConfig => + pipe( + itwConfig, + O.chainNullableK(itw => itw.wallet_activation_disabled), + O.getOrElse(() => false) + ) +); + +/** + * Return IT Wallet credentials that have been disabled remotely. + */ +export const itwDisabledCredentialsSelector = createSelector( + itwRemoteConfigSelector, + itwConfig => + pipe( + itwConfig, + O.chainNullableK(itw => itw.disabled_credentials), + O.getOrElse(() => emptyArray) + ) +); + +/** + * Return the remote config content for the deferred issuance screen content. + */ +export const itwDeferredIssuanceScreenContentSelector = createSelector( + itwRemoteConfigSelector, + itwConfig => + pipe( + itwConfig, + O.map(itw => itw.deferred_issuance_screen_content), + O.toUndefined + ) +); + +/** + * Return the remote config content for the deferred issuance screen content. + */ +export const itwIsIPatenteCtaEnabledSelector = createSelector( + itwRemoteConfigSelector, + itwConfig => + pipe( + itwConfig, + O.map(itw => itw.ipatente_cta_visible), + O.getOrElse(() => false) + ) +); diff --git a/ts/features/itwallet/discovery/screens/ItwDiscoveryInfoScreen.tsx b/ts/features/itwallet/discovery/screens/ItwDiscoveryInfoScreen.tsx index 7ecc9f369cc..6f2412cf05f 100644 --- a/ts/features/itwallet/discovery/screens/ItwDiscoveryInfoScreen.tsx +++ b/ts/features/itwallet/discovery/screens/ItwDiscoveryInfoScreen.tsx @@ -5,25 +5,25 @@ import { H1, VSpacer } from "@pagopa/io-app-design-system"; +import { useFocusEffect } from "@react-navigation/native"; import * as React from "react"; import { StyleSheet } from "react-native"; -import { useFocusEffect } from "@react-navigation/native"; import { AnimatedImage } from "../../../../components/AnimatedImage"; import { useHeaderSecondLevel } from "../../../../hooks/useHeaderSecondLevel"; import I18n from "../../../../i18n"; +import { useIOSelector } from "../../../../store/hooks"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { useOnFirstRender } from "../../../../utils/hooks/useOnFirstRender"; -import ItwMarkdown from "../../common/components/ItwMarkdown"; -import { selectIsLoading } from "../../machine/eid/selectors"; -import { ItwEidIssuanceMachineContext } from "../../machine/provider"; +import { tosConfigSelector } from "../../../tos/store/selectors"; import { trackItWalletActivationStart, trackItWalletIntroScreen, trackOpenItwTos } from "../../analytics"; -import { useIOSelector } from "../../../../store/hooks"; -import { isItwActivationDisabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; -import { tosConfigSelector } from "../../../tos/store/selectors"; +import ItwMarkdown from "../../common/components/ItwMarkdown"; +import { itwIsActivationDisabledSelector } from "../../common/store/selectors/remoteConfig"; +import { selectIsLoading } from "../../machine/eid/selectors"; +import { ItwEidIssuanceMachineContext } from "../../machine/provider"; /** * This is the screen that shows the information about the discovery process @@ -36,7 +36,7 @@ const ItwDiscoveryInfoScreen = () => { const machineRef = ItwEidIssuanceMachineContext.useActorRef(); const isLoading = ItwEidIssuanceMachineContext.useSelector(selectIsLoading); - const itwActivationDisabled = useIOSelector(isItwActivationDisabledSelector); + const itwActivationDisabled = useIOSelector(itwIsActivationDisabledSelector); const tosConfig = useIOSelector(tosConfigSelector); const privacyAndTosUrl = tosConfig.tos_url; diff --git a/ts/features/itwallet/identification/screens/ItwIdentificationModeSelectionScreen.tsx b/ts/features/itwallet/identification/screens/ItwIdentificationModeSelectionScreen.tsx index 419030f9b3e..153775d6aa9 100644 --- a/ts/features/itwallet/identification/screens/ItwIdentificationModeSelectionScreen.tsx +++ b/ts/features/itwallet/identification/screens/ItwIdentificationModeSelectionScreen.tsx @@ -14,9 +14,9 @@ import { trackItWalletIDMethod, trackItWalletIDMethodSelected } from "../../analytics"; -import { itwDisabledIdentificationMethodsSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { IOScrollViewWithLargeHeader } from "../../../../components/ui/IOScrollViewWithLargeHeader"; import { isCIEAuthenticationSupportedSelector } from "../../machine/eid/selectors"; +import { itwDisabledIdentificationMethodsSelector } from "../../common/store/selectors/remoteConfig"; export const ItwIdentificationModeSelectionScreen = () => { const machineRef = ItwEidIssuanceMachineContext.useActorRef(); diff --git a/ts/features/itwallet/issuance/screens/ItwIssuanceCredentialFailureScreen.tsx b/ts/features/itwallet/issuance/screens/ItwIssuanceCredentialFailureScreen.tsx index 1fdeb2f9620..b08cd38b4ff 100644 --- a/ts/features/itwallet/issuance/screens/ItwIssuanceCredentialFailureScreen.tsx +++ b/ts/features/itwallet/issuance/screens/ItwIssuanceCredentialFailureScreen.tsx @@ -1,7 +1,7 @@ import { Errors } from "@pagopa/io-react-native-wallet"; import { sequenceS } from "fp-ts/lib/Apply"; -import { constNull, pipe } from "fp-ts/lib/function"; import * as O from "fp-ts/lib/Option"; +import { constNull, pipe } from "fp-ts/lib/function"; import React from "react"; import { OperationResultScreenContent, @@ -9,11 +9,18 @@ import { } from "../../../../components/screens/OperationResultScreenContent"; import { useDebugInfo } from "../../../../hooks/useDebugInfo"; import I18n from "../../../../i18n"; +import { useIOSelector } from "../../../../store/hooks"; +import { + fallbackForLocalizedMessageKeys, + getFullLocale +} from "../../../../utils/locale"; import { useAvoidHardwareBackButton } from "../../../../utils/useAvoidHardwareBackButton"; import { trackWalletCreationFailed } from "../../analytics"; import { useItwDisableGestureNavigation } from "../../common/hooks/useItwDisableGestureNavigation"; +import { itwDeferredIssuanceScreenContentSelector } from "../../common/store/selectors/remoteConfig"; import { getClaimsFullLocale } from "../../common/utils/itwClaimsUtils"; import { StatusAttestationError } from "../../common/utils/itwCredentialStatusAttestationUtils"; +import { serializeFailureReason } from "../../common/utils/itwStoreUtils"; import { IssuerConfiguration } from "../../common/utils/itwTypesUtils"; import { CredentialIssuanceFailure, @@ -26,13 +33,6 @@ import { } from "../../machine/credential/selectors"; import { ItwCredentialIssuanceMachineContext } from "../../machine/provider"; import { useCredentialEventsTracking } from "../hooks/useCredentialEventsTracking"; -import { useIOSelector } from "../../../../store/hooks"; -import { itwDeferredIssuanceScreenContentSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; -import { - fallbackForLocalizedMessageKeys, - getFullLocale -} from "../../../../utils/locale"; -import { serializeFailureReason } from "../../common/utils/itwStoreUtils"; export const ItwIssuanceCredentialFailureScreen = () => { const failureOption = diff --git a/ts/features/itwallet/navigation/useItwLinkingOptions.tsx b/ts/features/itwallet/navigation/useItwLinkingOptions.tsx index 7be580454c1..4da52c2ec9a 100644 --- a/ts/features/itwallet/navigation/useItwLinkingOptions.tsx +++ b/ts/features/itwallet/navigation/useItwLinkingOptions.tsx @@ -1,8 +1,8 @@ import { PathConfigMap } from "@react-navigation/native"; +import { AppParamsList } from "../../../navigation/params/AppParamsList"; import { useIOSelector } from "../../../store/hooks"; +import { isItwEnabledSelector } from "../common/store/selectors/remoteConfig"; import { itwLifecycleIsValidSelector } from "../lifecycle/store/selectors"; -import { isItwEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; -import { AppParamsList } from "../../../navigation/params/AppParamsList"; import { ITW_ROUTES } from "./routes"; /** diff --git a/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx b/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx index cdaf466893f..8fa4c2231df 100644 --- a/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx +++ b/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx @@ -6,18 +6,14 @@ import { VStack } from "@pagopa/io-app-design-system"; import { useFocusEffect } from "@react-navigation/native"; -import { constFalse, pipe } from "fp-ts/lib/function"; import * as O from "fp-ts/lib/Option"; +import { constFalse, pipe } from "fp-ts/lib/function"; import React, { useCallback } from "react"; import { StyleSheet, View } from "react-native"; import { IOScrollViewWithLargeHeader } from "../../../../components/ui/IOScrollViewWithLargeHeader"; import I18n from "../../../../i18n"; import { useIONavigation } from "../../../../navigation/params/AppParamsList"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { - isItwEnabledSelector, - itwDisabledCredentialsSelector -} from "../../../../store/reducers/backendStatus/remoteConfig"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { cgnActivationStart } from "../../../bonus/cgn/store/actions/activation"; import { @@ -32,6 +28,10 @@ import { } from "../../analytics"; import { ItwDiscoveryBannerOnboarding } from "../../common/components/discoveryBanner/ItwDiscoveryBannerOnboarding"; import { itwRequestedCredentialsSelector } from "../../common/store/selectors/preferences"; +import { + isItwEnabledSelector, + itwDisabledCredentialsSelector +} from "../../common/store/selectors/remoteConfig"; import { CredentialType } from "../../common/utils/itwMocksUtils"; import { itwCredentialsTypesSelector } from "../../credentials/store/selectors"; import { itwLifecycleIsValidSelector } from "../../lifecycle/store/selectors"; diff --git a/ts/features/itwallet/presentation/components/ItwPresentationDetailsFooter.tsx b/ts/features/itwallet/presentation/components/ItwPresentationDetailsFooter.tsx index eb7190e8d5a..174a4e270d6 100644 --- a/ts/features/itwallet/presentation/components/ItwPresentationDetailsFooter.tsx +++ b/ts/features/itwallet/presentation/components/ItwPresentationDetailsFooter.tsx @@ -1,24 +1,25 @@ -import { - ContentWrapper, - ListItemAction, - useIOToast, - VSpacer -} from "@pagopa/io-app-design-system"; -import React from "react"; -import { Alert } from "react-native"; +import { ListItemAction, useIOToast } from "@pagopa/io-app-design-system"; +import React, { useMemo } from "react"; +import { Alert, View } from "react-native"; import { useStartSupportRequest } from "../../../../hooks/useStartSupportRequest"; import I18n from "../../../../i18n"; +import NavigationService from "../../../../navigation/NavigationService"; import { useIONavigation } from "../../../../navigation/params/AppParamsList"; -import { useIODispatch, useIOStore } from "../../../../store/hooks"; -import { CredentialType } from "../../common/utils/itwMocksUtils"; -import { StoredCredential } from "../../common/utils/itwTypesUtils"; -import { itwCredentialsRemove } from "../../credentials/store/actions"; +import { + useIODispatch, + useIOSelector, + useIOStore +} from "../../../../store/hooks"; +import { FIMS_ROUTES } from "../../../fims/common/navigation"; import { CREDENTIALS_MAP, trackCredentialDeleteProperties, trackItwCredentialDelete, trackWalletCredentialSupport } from "../../analytics"; +import { itwIsIPatenteCtaEnabledSelector } from "../../common/store/selectors/remoteConfig"; +import { StoredCredential } from "../../common/utils/itwTypesUtils"; +import { itwCredentialsRemove } from "../../credentials/store/actions"; type ItwPresentationDetailFooterProps = { credential: StoredCredential; @@ -80,10 +81,16 @@ const ItwPresentationDetailsFooter = ({ startSupportRequest(); }; + const credentialActions = useMemo( + () => getCredentialActions(credential.credentialType), + [credential.credentialType] + ); + return ( - - + + {credentialActions} - {credential.credentialType !== CredentialType.PID ? ( - - ) : null} - + + + ); +}; + +/** + * Returns custom CTAs for a credential + */ +const getCredentialActions = (credentialType: string): React.ReactNode => + ({ + MDL: [], + EuropeanHealthInsuranceCard: [], + EuropeanDisabilityCard: [] + }[credentialType]); + +/** + * Renders the IPatente service action item + */ +const IPatenteListItemAction = () => { + const isIPatenteEnabled = useIOSelector(itwIsIPatenteCtaEnabledSelector); + + if (!isIPatenteEnabled) { + return null; + } + + const label = I18n.t( + "features.itWallet.presentation.credentialDetails.actions.openIPatente" + ); + + return ( + { + NavigationService.navigate(FIMS_ROUTES.MAIN, { + screen: FIMS_ROUTES.CONSENTS, + params: { + ctaText: label, + ctaUrl: "https://licences.ipatente.io.pagopa.it/licences" + } + }); + }} + /> ); }; diff --git a/ts/features/itwallet/presentation/components/__tests__/ItwPresentationDetailFooter.test.tsx b/ts/features/itwallet/presentation/components/__tests__/ItwPresentationDetailFooter.test.tsx index b70e85026b6..f035f744976 100644 --- a/ts/features/itwallet/presentation/components/__tests__/ItwPresentationDetailFooter.test.tsx +++ b/ts/features/itwallet/presentation/components/__tests__/ItwPresentationDetailFooter.test.tsx @@ -12,25 +12,29 @@ import { itwCredentialIssuanceMachine } from "../../../machine/credential/machin import { ItwCredentialIssuanceMachineContext } from "../../../machine/provider"; import { ITW_ROUTES } from "../../../navigation/routes"; import { ItwPresentationDetailsFooter } from "../ItwPresentationDetailsFooter"; +import * as remoteConfigSelectors from "../../../common/store/selectors/remoteConfig"; -describe("ItwPresentationAlertsSection", () => { - test.each([ - CredentialType.DRIVING_LICENSE, - CredentialType.EUROPEAN_DISABILITY_CARD, - CredentialType.EUROPEAN_HEALTH_INSURANCE_CARD - ])( - "should render the remove credential action if credential type is %p", - credentialType => { - const { queryByTestId } = renderComponent(credentialType); - - expect(queryByTestId("removeCredentialActionTestID")).not.toBeNull(); - } - ); +describe("ItwPresentationDetailsFooter", () => { + it("should render actions", () => { + const { queryByTestId } = renderComponent( + CredentialType.EUROPEAN_HEALTH_INSURANCE_CARD + ); + + expect(queryByTestId("requestAssistanceActionTestID")).not.toBeNull(); + expect(queryByTestId("removeCredentialActionTestID")).not.toBeNull(); + expect(queryByTestId("openIPatenteActionTestID")).toBeNull(); + }); + + it("should render iPatente action", () => { + jest + .spyOn(remoteConfigSelectors, "itwIsIPatenteCtaEnabledSelector") + .mockImplementation(() => true); - it("should not render the remove credential action if credential is EID", () => { - const { queryByTestId } = renderComponent(CredentialType.PID); + const { queryByTestId } = renderComponent(CredentialType.DRIVING_LICENSE); - expect(queryByTestId("removeCredentialActionTestID")).toBeNull(); + expect(queryByTestId("requestAssistanceActionTestID")).not.toBeNull(); + expect(queryByTestId("removeCredentialActionTestID")).not.toBeNull(); + expect(queryByTestId("openIPatenteActionTestID")).not.toBeNull(); }); }); diff --git a/ts/features/itwallet/presentation/screens/ItwPresentationCredentialDetailScreen.tsx b/ts/features/itwallet/presentation/screens/ItwPresentationCredentialDetailScreen.tsx index 962b8804dff..9aaee573f1f 100644 --- a/ts/features/itwallet/presentation/screens/ItwPresentationCredentialDetailScreen.tsx +++ b/ts/features/itwallet/presentation/screens/ItwPresentationCredentialDetailScreen.tsx @@ -1,4 +1,4 @@ -import { ContentWrapper, VStack } from "@pagopa/io-app-design-system"; +import { ContentWrapper, VSpacer, VStack } from "@pagopa/io-app-design-system"; import { useFocusEffect } from "@react-navigation/native"; import * as O from "fp-ts/Option"; import React from "react"; @@ -109,19 +109,18 @@ const ItwPresentationCredentialDetail = ({ credential={credential} ctaProps={ctaProps} > - - - - - - - - - - - - - + + + + + + + + + + + + ); }; diff --git a/ts/features/itwallet/trustmark/components/ItwCredentialTrustmark.tsx b/ts/features/itwallet/trustmark/components/ItwCredentialTrustmark.tsx index 7f2a4497b32..550124fd832 100644 --- a/ts/features/itwallet/trustmark/components/ItwCredentialTrustmark.tsx +++ b/ts/features/itwallet/trustmark/components/ItwCredentialTrustmark.tsx @@ -346,8 +346,7 @@ const styles = StyleSheet.create({ height: TRUSTMARK_HEIGHT, borderCurve: "continuous", borderRadius: buttonBorderRadius, - overflow: "hidden", - marginVertical: 8 + overflow: "hidden" }, gradientView: { ...StyleSheet.absoluteFillObject diff --git a/ts/features/wallet/store/selectors/index.ts b/ts/features/wallet/store/selectors/index.ts index bd94f3c61fa..de6d1ca48e4 100644 --- a/ts/features/wallet/store/selectors/index.ts +++ b/ts/features/wallet/store/selectors/index.ts @@ -7,7 +7,6 @@ import { idPayWalletInitiativeListSelector } from "../../../idpay/wallet/store/r import { itwLifecycleIsValidSelector } from "../../../itwallet/lifecycle/store/selectors"; import { paymentsWalletUserMethodsSelector } from "../../../payments/wallet/store/selectors"; import { itwIsWalletInstanceStatusFailureSelector } from "../../../itwallet/walletInstance/store/selectors"; -import { isItwEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { WalletCard, WalletCardCategory, @@ -15,6 +14,7 @@ import { walletCardCategories } from "../../types"; import { WalletCardCategoryFilter } from "../../types/index"; +import { isItwEnabledSelector } from "../../../itwallet/common/store/selectors/remoteConfig"; /** * Returns the list of cards excluding hidden cards diff --git a/ts/store/reducers/__mock__/backendStatus.ts b/ts/store/reducers/__mock__/backendStatus.ts index efebdaace6c..f344e0ae7b1 100644 --- a/ts/store/reducers/__mock__/backendStatus.ts +++ b/ts/store/reducers/__mock__/backendStatus.ts @@ -301,10 +301,10 @@ export const baseRawBackendStatus: BackendStatus = { android: "0.0.0.0", ios: "0.0.0.0" }, - ipatente_cta_visible: true, feedback_banner_visible: true, disabled_identification_methods: [], - disabled_credentials: [] + disabled_credentials: [], + ipatente_cta_visible: true } } }; @@ -394,9 +394,9 @@ export const baseBackendConfig: Config = { android: "0.0.0.0", ios: "0.0.0.0" }, - ipatente_cta_visible: true, feedback_banner_visible: true, disabled_credentials: [], - disabled_identification_methods: [] + disabled_identification_methods: [], + ipatente_cta_visible: true } }; diff --git a/ts/store/reducers/backendStatus/remoteConfig.ts b/ts/store/reducers/backendStatus/remoteConfig.ts index e852a36657a..3382467587e 100644 --- a/ts/store/reducers/backendStatus/remoteConfig.ts +++ b/ts/store/reducers/backendStatus/remoteConfig.ts @@ -1,13 +1,13 @@ import * as O from "fp-ts/lib/Option"; -import { getType } from "typesafe-actions"; -import { createSelector } from "reselect"; import { pipe } from "fp-ts/lib/function"; import { Platform } from "react-native"; +import { createSelector } from "reselect"; +import { getType } from "typesafe-actions"; +import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; import { BackendStatus } from "../../../../definitions/content/BackendStatus"; -import { Action } from "../../actions/types"; -import { backendStatusLoadSuccess } from "../../actions/backendStatus"; -import { GlobalState } from "../types"; -import { getAppVersion, isVersionSupported } from "../../../utils/appVersion"; +import { BancomatPayConfig } from "../../../../definitions/content/BancomatPayConfig"; +import { Banner } from "../../../../definitions/content/Banner"; +import { BarcodesScannerConfig } from "../../../../definitions/content/BarcodesScannerConfig"; import { cdcEnabled, cgnMerchantsV2Enabled, @@ -15,12 +15,12 @@ import { premiumMessagesOptInEnabled, scanAdditionalBarcodesEnabled } from "../../../config"; -import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; -import { BancomatPayConfig } from "../../../../definitions/content/BancomatPayConfig"; +import { getAppVersion, isVersionSupported } from "../../../utils/appVersion"; +import { backendStatusLoadSuccess } from "../../actions/backendStatus"; +import { Action } from "../../actions/types"; import { isPropertyWithMinAppVersionEnabled } from "../featureFlagWithMinAppVersionStatus"; -import { BarcodesScannerConfig } from "../../../../definitions/content/BarcodesScannerConfig"; import { isIdPayTestEnabledSelector } from "../persistedPreferences"; -import { Banner } from "../../../../definitions/content/Banner"; +import { GlobalState } from "../types"; export type RemoteConfigState = O.Option; @@ -295,44 +295,6 @@ export const isIdPayEnabledSelector = createSelector( O.getOrElse(() => false) ) ); - -/** - * Return the remote config about IT-WALLET enabled/disabled - * if there is no data or the local Feature Flag is disabled, - * false is the default value -> (IT-WALLET disabled) - */ -export const isItwEnabledSelector = createSelector( - remoteConfigSelector, - (remoteConfig): boolean => - pipe( - remoteConfig, - O.map( - config => - isVersionSupported( - Platform.OS === "ios" - ? config.itw.min_app_version.ios - : config.itw.min_app_version.android, - getAppVersion() - ) && config.itw.enabled - ), - O.getOrElse(() => false) - ) -); - -/** - * Returns the authentication methods that are disabled. - * If there is no data, an empty array is returned as the default value. - */ -export const itwDisabledIdentificationMethodsSelector = createSelector( - remoteConfigSelector, - (remoteConfig): ReadonlyArray => - pipe( - remoteConfig, - O.chainNullableK(config => config.itw.disabled_identification_methods), - O.getOrElse(() => emptyArray) - ) -); - /** * Return the remote feature flag about the payment feedback banner enabled/disabled * that is shown after a successful payment. @@ -375,57 +337,3 @@ export const landingScreenBannerOrderSelector = (state: GlobalState) => O.chainNullableK(banners => banners.priority_order), O.getOrElse(() => emptyArray) ); - -/** - * Return whether the IT Wallet feedback banner is remotely enabled. - */ -export const isItwFeedbackBannerEnabledSelector = createSelector( - remoteConfigSelector, - remoteConfig => - pipe( - remoteConfig, - O.map(config => config.itw.feedback_banner_visible), - O.getOrElse(() => false) - ) -); - -/** - * Return whether the Wallet activation is disabled. - * This is purely a "cosmetic" configuration to disable UI elements, - * it does not disable the entire IT Wallet feature. - */ -export const isItwActivationDisabledSelector = createSelector( - remoteConfigSelector, - remoteConfig => - pipe( - remoteConfig, - O.chainNullableK(config => config.itw.wallet_activation_disabled), - O.getOrElse(() => false) - ) -); - -/** - * Return IT Wallet credentials that have been disabled remotely. - */ -export const itwDisabledCredentialsSelector = createSelector( - remoteConfigSelector, - remoteConfig => - pipe( - remoteConfig, - O.chainNullableK(config => config.itw.disabled_credentials), - O.getOrElse(() => emptyArray) - ) -); - -/** - * Return the remote config content for the deferred issuance screen content. - */ -export const itwDeferredIssuanceScreenContentSelector = createSelector( - remoteConfigSelector, - remoteConfig => - pipe( - remoteConfig, - O.map(config => config.itw.deferred_issuance_screen_content), - O.toUndefined - ) -);