Skip to content

Commit

Permalink
Merge branch 'master' into IOAPPX-414-add-native-stack-to-DS
Browse files Browse the repository at this point in the history
  • Loading branch information
dmnplb authored Nov 4, 2024
2 parents 4fb8dee + 6224619 commit ac65bac
Show file tree
Hide file tree
Showing 16 changed files with 254 additions and 64 deletions.
10 changes: 5 additions & 5 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ inbox:
enableButton: Enable Inbox
disableButton: Disable Inbox
enableCallToActionDescription: Enable the inbox to view messages
settings:
informativeBanner:
settings:
informativeBanner:
content: Looking for your profile? We have moved it, it is now in the top right corner!
action: Go to Settings
profile:
Expand Down Expand Up @@ -3421,10 +3421,10 @@ features:
alerts:
mdl:
content: "Puoi usare la tua Patente su IO solo in Italia per dimostrare di essere abilitato alla guida in caso di controlli delle Forze dell'ordine."
action: Scopri di più
ehc:
content: "Puoi usare la tua Tessera Sanitaria - Tessera europea di assicurazione malattia su IO per accedere alle prestazioni fornite dal Servizio Sanitario Nazionale."
action: "Scopri di più"
edc:
content: "Puoi usare la tua Carta Europea della Disabilità su IO per accedere ai servizi sul territorio italiano, negli stessi contesti d’uso del tuo documento fisico."
expired:
content: Il documento non è più valido. Se sei già in possesso del nuovo documento valido, puoi aggiornare la versione digitale nel Portafoglio
action: Aggiorna il documento
Expand Down Expand Up @@ -3512,7 +3512,7 @@ support:
panicMode:
title: "We cannot help you at the moment"
body: "We know there is a problem and we are working to solve it. If the problem remains, or if you need support on another topic, please try again later."
errorGetZendeskToken:
errorGetZendeskToken:
title: Sorry, we're unable to open a service request at the moment.
subtitle: Try again later
askPermissions:
Expand Down
10 changes: 5 additions & 5 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ inbox:
enableButton: Abilita Inbox
disableButton: Disabilita Inbox
enableCallToActionDescription: Abilita l'inbox per visualizzare i messaggi
settings:
informativeBanner:
settings:
informativeBanner:
content: Cerchi il Profilo? Lo abbiamo spostato, ora è in alto a destra!
action: Vai alle Impostazioni
profile:
Expand Down Expand Up @@ -3421,10 +3421,10 @@ features:
alerts:
mdl:
content: "Puoi usare la tua Patente su IO solo in Italia per dimostrare di essere abilitato alla guida in caso di controlli delle Forze dell'ordine."
action: Scopri di più
ehc:
content: "Puoi usare la tua Tessera Sanitaria - Tessera europea di assicurazione malattia su IO per accedere alle prestazioni fornite dal Servizio Sanitario Nazionale."
action: "Scopri di più"
edc:
content: "Puoi usare la tua Carta Europea della Disabilità su IO per accedere ai servizi sul territorio italiano, negli stessi contesti d’uso del tuo documento fisico."
expired:
content: Il documento non è più valido. Se sei già in possesso del nuovo documento valido, puoi aggiornare la versione digitale nel Portafoglio
action: Aggiorna il documento
Expand Down Expand Up @@ -3512,7 +3512,7 @@ support:
panicMode:
title: "Purtroppo, in questo momento non riusciamo ad aiutarti"
body: "Sappiamo che c’è un problema e siamo al lavoro per risolverlo. Se il problema persiste, o se hai bisogno di assistenza su un altro argomento, riprova a scriverci più tardi."
errorGetZendeskToken:
errorGetZendeskToken:
title: Al momento non riusciamo ad aprire una richiesta di assistenza
subtitle: Riprova più tardi
askPermissions:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
import { Route, useNavigation, useRoute } from "@react-navigation/native";
import { pipe } from "fp-ts/lib/function";
import * as O from "fp-ts/lib/Option";
import * as React from "react";
import { useMemo } from "react";
import {
View,
LayoutChangeEvent,
RefreshControl,
Platform
} from "react-native";
import {
Divider,
H3,
Expand All @@ -19,22 +8,39 @@ import {
VSpacer,
hexToRgba
} from "@pagopa/io-app-design-system";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Route, useNavigation, useRoute } from "@react-navigation/native";
import { pipe } from "fp-ts/lib/function";
import * as O from "fp-ts/lib/Option";
import * as React from "react";
import { useMemo } from "react";
import {
Dimensions,
LayoutChangeEvent,
Platform,
RefreshControl,
View
} from "react-native";
import Animated, {
useAnimatedScrollHandler,
useSharedValue
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Merchant } from "../../../../../../definitions/cgn/merchants/Merchant";
import { IOStyles } from "../../../../../components/core/variables/IOStyles";
import GenericErrorComponent from "../../../../../components/screens/GenericErrorComponent";
import I18n from "../../../../../i18n";
import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList";
import { useIODispatch, useIOSelector } from "../../../../../store/hooks";
import { ProductCategoryEnum } from "../../../../../../definitions/cgn/merchants/ProductCategory";
import {
getValueOrElse,
isError,
isLoading
} from "../../../../../common/model/RemoteValue";
import { IOStyles } from "../../../../../components/core/variables/IOStyles";
import { OperationResultScreenContent } from "../../../../../components/screens/OperationResultScreenContent";
import FocusAwareStatusBar from "../../../../../components/ui/FocusAwareStatusBar";
import { useHeaderSecondLevel } from "../../../../../hooks/useHeaderSecondLevel";
import I18n from "../../../../../i18n";
import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList";
import { useIODispatch, useIOSelector } from "../../../../../store/hooks";
import { CgnMerchantListSkeleton } from "../../components/merchants/CgnMerchantListSkeleton";
import { CgnMerchantListViewRenderItem } from "../../components/merchants/CgnMerchantsListView";
import { CgnDetailsParamsList } from "../../navigation/params";
import CGN_ROUTES from "../../navigation/routes";
import {
Expand All @@ -47,17 +53,13 @@ import {
} from "../../store/reducers/merchants";
import { getCategorySpecs } from "../../utils/filters";
import { mixAndSortMerchants } from "../../utils/merchants";
import { ProductCategoryEnum } from "../../../../../../definitions/cgn/merchants/ProductCategory";
import { useHeaderSecondLevel } from "../../../../../hooks/useHeaderSecondLevel";
import FocusAwareStatusBar from "../../../../../components/ui/FocusAwareStatusBar";
import { CgnMerchantListViewRenderItem } from "../../components/merchants/CgnMerchantsListView";
import { CgnMerchantListSkeleton } from "../../components/merchants/CgnMerchantListSkeleton";

export type CgnMerchantListByCategoryScreenNavigationParams = Readonly<{
category: ProductCategoryEnum;
}>;

const CgnMerchantsListByCategory = () => {
const screenHeight = Dimensions.get("window").height;
const [titleHeight, setTitleHeight] = React.useState(0);
const translationY = useSharedValue(0);

Expand All @@ -72,6 +74,7 @@ const CgnMerchantsListByCategory = () => {
// eslint-disable-next-line functional/immutable-data
translationY.value = event.contentOffset.y;
});

const insets = useSafeAreaInsets();
const dispatch = useIODispatch();
const route =
Expand Down Expand Up @@ -230,14 +233,34 @@ const CgnMerchantsListByCategory = () => {
}}
/>
);

const getPaddingBottom = () => {
const ELEMENT_HEIGHT = 49;
const totalListElementsHeight = ELEMENT_HEIGHT * merchantsAll.length;
const usedVerticalSpace =
titleHeight + totalListElementsHeight + insets.bottom;
const availableVerticalSpace = screenHeight - usedVerticalSpace;

return availableVerticalSpace < titleHeight ? availableVerticalSpace : 0;
};

return (
<>
<FocusAwareStatusBar
backgroundColor={categorySpecs?.colors}
barStyle={"dark-content"}
/>
{isError(onlineMerchants) && isError(offlineMerchants) ? (
<GenericErrorComponent onRetry={initLoadingLists} />
<OperationResultScreenContent
pictogram="umbrellaNew"
title={I18n.t("wallet.errors.GENERIC_ERROR")}
subtitle={I18n.t("wallet.errorTransaction.submitBugText")}
action={{
label: I18n.t("global.buttons.retry"),
accessibilityLabel: I18n.t("global.buttons.retry"),
onPress: initLoadingLists
}}
/>
) : (
<Animated.FlatList
style={{ flexGrow: 1, backgroundColor: IOColors.white }}
Expand All @@ -247,11 +270,11 @@ const CgnMerchantsListByCategory = () => {
snapToEnd={false}
contentContainerStyle={{
flexGrow: 1,
paddingBottom: 48,
paddingBottom: getPaddingBottom(),
backgroundColor: IOColors.white
}}
refreshControl={refreshControl}
data={isListLoading && !isPullRefresh ? [] : merchantsAll}
data={merchantsAll}
keyExtractor={item => item.id}
ListEmptyComponent={CgnMerchantListSkeleton}
renderItem={renderItem}
Expand Down
23 changes: 15 additions & 8 deletions ts/features/itwallet/common/saga/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,40 @@ import {
trialSystemActivationStatusUpsert
} from "../../../../trialSystem/store/actions";
import { SubscriptionStateEnum } from "../../../../../../definitions/trial_system/SubscriptionState";
import { trialStatusSelector } from "../../../../trialSystem/store/reducers";
import {
trialStatusPotSelector,
trialStatusSelector
} from "../../../../trialSystem/store/reducers";
import { TrialId } from "../../../../../../definitions/trial_system/TrialId";
import { TrialSystemError } from "../../../../trialSystem/utils/error";

describe("handleTrialSystemSubscription", () => {
it("should handle trial system subscription correctly", async () => {
it("should handle trial system subscription correctly when the endpoint returns 404", async () => {
const trialId = "baz" as TrialId;
const state = SubscriptionStateEnum.UNSUBSCRIBED;
const error = new TrialSystemError(
"User not found",
"TRIAL_SYSTEM_USER_NOT_FOUND"
);
const state = pot.noneError(error);
const store: DeepPartial<GlobalState> = {
trialSystem: {
[trialId]: pot.some(state)
[trialId]: state
}
};
return expectSaga(handleTrialSystemSubscription)
.withState(store)
.put(trialSystemActivationStatus.request(trialId))
.dispatch(
trialSystemActivationStatus.success({
trialSystemActivationStatus.failure({
trialId,
state,
createdAt: new Date()
error
})
)
.take([
trialSystemActivationStatus.success,
trialSystemActivationStatus.failure
])
.provide([[matchers.select(trialStatusSelector), state]])
.provide([[matchers.select(trialStatusPotSelector), state]])
.put(trialSystemActivationStatusUpsert.request(trialId))
.run();
});
Expand Down
16 changes: 11 additions & 5 deletions ts/features/itwallet/common/saga/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SagaIterator } from "redux-saga";
import { fork, put, call, take, select } from "typed-redux-saga/macro";
import * as pot from "@pagopa/ts-commons/lib/pot";
import { isActionOf } from "typesafe-actions";
import {
trialSystemActivationStatus,
Expand All @@ -13,8 +14,7 @@ import { itwCieIsSupported } from "../../identification/store/actions";
import { watchItwCredentialsSaga } from "../../credentials/saga";
import { watchItwLifecycleSaga } from "../../lifecycle/saga";
import { checkCredentialsStatusAttestation } from "../../credentials/saga/checkCredentialsStatusAttestation";
import { trialStatusSelector } from "../../../trialSystem/store/reducers";
import { SubscriptionStateEnum } from "../../../../../definitions/trial_system/SubscriptionState";
import { trialStatusPotSelector } from "../../../trialSystem/store/reducers";

function* checkWalletInstanceAndCredentialsValiditySaga() {
// Status attestations of credentials are checked only in case of a valid wallet instance.
Expand All @@ -34,9 +34,15 @@ export function* handleTrialSystemSubscription() {
trialSystemActivationStatus.success,
trialSystemActivationStatus.failure
]);
if (isActionOf(trialSystemActivationStatus.success, outputAction)) {
const status = yield* select(trialStatusSelector(itwTrialId));
if (status && status === SubscriptionStateEnum.UNSUBSCRIBED) {
if (isActionOf(trialSystemActivationStatus.failure, outputAction)) {
/* We check if the error is due to the user not being found in the trial system and we try to subscribe the user
the trial system returns 404 if the usuer is not found or if the trial id is not found. However, the trial id is
hardcoded in the config file and we assume it is correct so the only reason for the 404 is the user not being found. */
const potStatus = yield* select(trialStatusPotSelector(itwTrialId));
if (
pot.isError(potStatus) &&
potStatus.error.type === "TRIAL_SYSTEM_USER_NOT_FOUND"
) {
yield* put(trialSystemActivationStatusUpsert.request(itwTrialId));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,8 @@ const styles = StyleSheet.create({
height: TRUSTMARK_HEIGHT,
borderCurve: "continuous",
borderRadius: buttonBorderRadius,
overflow: "hidden"
overflow: "hidden",
marginVertical: 8
},
gradientView: {
...StyleSheet.absoluteFillObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export const ItwPresentationAlertsSection = ({ credential }: Props) => {
const isMdl = credential.credentialType === CredentialType.DRIVING_LICENSE;
const isEhc =
credential.credentialType === CredentialType.EUROPEAN_HEALTH_INSURANCE_CARD;
const isEdc =
credential.credentialType === CredentialType.EUROPEAN_DISABILITY_CARD;

const expireStatus = getCredentialStatus(credential);
const expireDays = getCredentialExpireDays(credential.parsedCredential);
Expand Down Expand Up @@ -75,6 +77,13 @@ export const ItwPresentationAlertsSection = ({ credential }: Props) => {
variant="info"
/>
)}
{isEdc && (
<Alert
testID="itwEdcBannerTestID"
content={I18n.t("features.itWallet.presentation.alerts.edc.content")}
variant="info"
/>
)}
</VStack>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ describe("ItwPresentationAlertsSection", () => {
expect(queryByTestId("itwExpiredBannerTestID")).toBeNull();
expect(queryByTestId("itwExpiringBannerTestID")).toBeNull();
expect(queryByTestId("itwMdlBannerTestID")).not.toBeNull();
expect(queryByTestId("itwEhcBannerTestID")).toBeNull();
expect(queryByTestId("itwEdcBannerTestID")).toBeNull();
});

it("should render EHC alert", () => {
const { queryByTestId } = renderComponent(
CredentialType.EUROPEAN_HEALTH_INSURANCE_CARD,
new Date(2000, 2, 20)
);

expect(queryByTestId("itwExpiredBannerTestID")).toBeNull();
expect(queryByTestId("itwExpiringBannerTestID")).toBeNull();
expect(queryByTestId("itwMdlBannerTestID")).toBeNull();
expect(queryByTestId("itwEhcBannerTestID")).not.toBeNull();
expect(queryByTestId("itwEdcBannerTestID")).toBeNull();
});

it("should render EDC alert", () => {
const { queryByTestId } = renderComponent(
CredentialType.EUROPEAN_DISABILITY_CARD,
new Date(2000, 2, 20)
);

expect(queryByTestId("itwExpiredBannerTestID")).toBeNull();
expect(queryByTestId("itwExpiringBannerTestID")).toBeNull();
expect(queryByTestId("itwMdlBannerTestID")).toBeNull();
expect(queryByTestId("itwEhcBannerTestID")).toBeNull();
expect(queryByTestId("itwEdcBannerTestID")).not.toBeNull();
});
});

Expand Down
6 changes: 4 additions & 2 deletions ts/features/payments/checkout/analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ export const getPaymentAnalyticsEventFromFailureOutcome = (
};

export const getPaymentAnalyticsEventFromRequestFailure = (
falure: WalletPaymentFailure
failure: WalletPaymentFailure
) => {
switch (falure.faultCodeCategory) {
switch (failure.faultCodeCategory) {
case "PAYMENT_UNAVAILABLE":
return "PAYMENT_TECHNICAL_ERROR";
case "PAYMENT_DATA_ERROR":
Expand All @@ -93,6 +93,8 @@ export const getPaymentAnalyticsEventFromRequestFailure = (
return "PAYMENT_ALREADY_PAID_ERROR";
case "PAYMENT_UNKNOWN":
return "PAYMENT_NOT_FOUND_ERROR";
case "PAYMENT_GENERIC_ERROR_AFTER_USER_CANCELLATION":
return "PAYMENT_GENERIC_ERROR_AFTER_USER_CANCELLATION";
default:
return "PAYMENT_GENERIC_ERROR";
}
Expand Down
Loading

0 comments on commit ac65bac

Please sign in to comment.