Skip to content

Commit

Permalink
Merge branch 'master' into IOCOM-1761-ui-alert-o-bottom-sheet-per-il-…
Browse files Browse the repository at this point in the history
…non-mostrare-piu-e-logica-di-visualizzazione
  • Loading branch information
Vangaorth authored Dec 11, 2024
2 parents 857e93a + 44a1ce5 commit 8cc526b
Show file tree
Hide file tree
Showing 30 changed files with 328 additions and 101 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [2.79.0-rc.6](https://github.com/pagopa/io-app/compare/2.79.0-rc.5...2.79.0-rc.6) (2024-12-10)


### Features

* **IT Wallet:** [[SIW-1900](https://pagopa.atlassian.net/browse/SIW-1900)] Add feedback for deferred credentials issuance ([#6516](https://github.com/pagopa/io-app/issues/6516)) ([5b244c8](https://github.com/pagopa/io-app/commit/5b244c8e608d2bec19bfd69bd2ae473bcf29cc23))


### Chores

* [[IOBP-1060](https://pagopa.atlassian.net/browse/IOBP-1060)] Add payment authorization generic error screen ([#6528](https://github.com/pagopa/io-app/issues/6528)) ([1dcbcf7](https://github.com/pagopa/io-app/commit/1dcbcf7e226b0283988cc7c8fa94813b6ce5eb9c))
* [[IOBP-1071](https://pagopa.atlassian.net/browse/IOBP-1071)] Payment onboarding bottom sheet text ([#6527](https://github.com/pagopa/io-app/issues/6527)) ([1fd724e](https://github.com/pagopa/io-app/commit/1fd724ee3fa4bbc29739dcb0c5f1dd8837658df8))
* [[IOBP-1073](https://pagopa.atlassian.net/browse/IOBP-1073)] Remove payment legacy transactions screen ([#6529](https://github.com/pagopa/io-app/issues/6529)) ([fc268d2](https://github.com/pagopa/io-app/commit/fc268d2443e16c3d720c2f24f7dd11551e979316))
* [[PE-868](https://pagopa.atlassian.net/browse/PE-868)] CGN Update cta when card is expired ([#6531](https://github.com/pagopa/io-app/issues/6531)) ([087d116](https://github.com/pagopa/io-app/commit/087d1160103076687f8abbde756461b727526c64))
* **Cross:** [[IOAPPX-445](https://pagopa.atlassian.net/browse/IOAPPX-445)] Replace legacy `FooterWithButtons` with a mix of `FooterActions` and `FooterActionsInline` ([#6477](https://github.com/pagopa/io-app/issues/6477)) ([89bb56a](https://github.com/pagopa/io-app/commit/89bb56a6f9c2e102d73cb91d96a66b6301c8c970))

## [2.79.0-rc.5](https://github.com/pagopa/io-app/compare/2.79.0-rc.4...2.79.0-rc.5) (2024-12-09)


Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ android {
applicationId "it.pagopa.io.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 100154888
versionName "2.79.0.5"
versionCode 100154889
versionName "2.79.0.6"
multiDexEnabled true
// The resConfigs attribute will remove all not required localized resources while building the application,
// including the localized resources from libraries.
Expand Down
4 changes: 2 additions & 2 deletions ios/ItaliaApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@
CODE_SIGN_ENTITLEMENTS = ItaliaApp/ItaliaApp.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 6;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = M2X5YQ4BJ7;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -827,7 +827,7 @@
CODE_SIGN_ENTITLEMENTS = ItaliaApp/ItaliaApp.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 6;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = M2X5YQ4BJ7;
ENABLE_BITCODE = NO;
Expand Down
2 changes: 1 addition & 1 deletion ios/ItaliaApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>5</string>
<string>6</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/ItaliaAppTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>5</string>
<string>6</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion locales/de/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2379,7 +2379,7 @@ bonus:
alert:
title: "Karte deaktivieren"
message: "La Carta verrà disattivata e non potrai più accedere alle opportunità disponibili."
expired: Elimina Carta Giovani Nazionale
expired: Rimuovi dal Portafoglio
otp:
error: "Aufgrund eines technischen Problems war es uns nicht möglich, einen Rabattcode zu generieren. Bitte versuche es erneut."
code:
Expand Down
1 change: 1 addition & 0 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3171,6 +3171,7 @@ features:
badge:
active: Già presente
unavailable: Non disponibile
requested: In corso
options:
cgn: Carta Giovani Nazionale
welfare: Iniziative welfare
Expand Down
3 changes: 2 additions & 1 deletion locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2883,7 +2883,7 @@ bonus:
alert:
title: "Vuoi rimuovere Carta Giovani dal Portafoglio?"
message: "La Carta verrà disattivata e non potrai più accedere alle opportunità disponibili."
expired: Elimina Carta Giovani Nazionale
expired: Rimuovi dal Portafoglio
otp:
error: "Per un problema tecnico non siamo riusciti a generare un codice sconto. Ti chiediamo di riprovare."
code:
Expand Down Expand Up @@ -3171,6 +3171,7 @@ features:
badge:
active: Già presente
unavailable: Non disponibile
requested: In corso
options:
cgn: Carta Giovani Nazionale
welfare: Iniziative welfare
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "italia-app",
"version": "2.79.0-rc.5",
"version": "2.79.0-rc.6",
"io_backend_api": "https://raw.githubusercontent.com/pagopa/io-backend/v16.4.0-RELEASE/api_backend.yaml",
"io_session_manager_api": "https://raw.githubusercontent.com/pagopa/io-auth-n-identity-domain/[email protected]/apps/io-session-manager/api/internal.yaml",
"io_session_manager_public_api": "https://raw.githubusercontent.com/pagopa/io-auth-n-identity-domain/[email protected]/apps/io-session-manager/api/public.yaml",
Expand Down Expand Up @@ -109,7 +109,7 @@
"dependencies": {
"@babel/plugin-transform-regenerator": "^7.18.6",
"@gorhom/bottom-sheet": "^4.1.5",
"@pagopa/io-app-design-system": "4.0.1",
"@pagopa/io-app-design-system": "4.0.2",
"@pagopa/io-pagopa-commons": "^3.1.0",
"@pagopa/io-react-native-cieid": "^0.3.5",
"@pagopa/io-react-native-crypto": "^0.3.0",
Expand Down
2 changes: 1 addition & 1 deletion publiccode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ releaseDate: "2024-11-21"
url: "https://github.com/pagopa/io-app"
applicationSuite: IO
landingURL: "https://io.italia.it/"
softwareVersion: 2.79.0-rc.5
softwareVersion: 2.79.0-rc.6
developmentStatus: beta
softwareType: standalone/mobile
roadmap: "https://io.italia.it/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ exports[`featuresPersistor should match snapshot 1`] = `
},
},
"lifecycle": 0,
"preferences": {},
"preferences": {
"requestedCredentials": {},
},
"walletInstance": {
"attestation": undefined,
},
Expand Down
12 changes: 11 additions & 1 deletion ts/features/itwallet/common/store/actions/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ export const itwCloseDiscoveryBanner = createStandardAction(
"ITW_CLOSE_DISCOVERY_BANNER"
)();

export const itwFlagCredentialAsRequested = createStandardAction(
"ITW_FLAG_CREDENTIAL_AS_REQUESTED"
)<string>();

export const itwUnflagCredentialAsRequested = createStandardAction(
"ITW_UNFLAG_CREDENTIAL_AS_REQUESTED"
)<string>();

export type ItwPreferencesActions =
| ActionType<typeof itwCloseFeedbackBanner>
| ActionType<typeof itwCloseDiscoveryBanner>;
| ActionType<typeof itwCloseDiscoveryBanner>
| ActionType<typeof itwFlagCredentialAsRequested>
| ActionType<typeof itwUnflagCredentialAsRequested>;
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ exports[`itWalletReducer should match snapshot 1`] = `
},
},
"lifecycle": 0,
"preferences": {},
"preferences": {
"requestedCredentials": {},
},
"walletInstance": {
"attestation": undefined,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { addMonths } from "date-fns";
import MockDate from "mockdate";
import { applicationChangeState } from "../../../../../../store/actions/application";
import { itwCloseFeedbackBanner } from "../../actions/preferences";
import {
itwCloseDiscoveryBanner,
itwCloseFeedbackBanner,
itwFlagCredentialAsRequested,
itwUnflagCredentialAsRequested
} from "../../actions/preferences";
import reducer, { ItwPreferencesState } from "../preferences";

describe("IT Wallet preferences reducer", () => {
const INITIAL_STATE: ItwPreferencesState = {};
const INITIAL_STATE: ItwPreferencesState = {
requestedCredentials: {}
};

it("should return the initial state", () => {
expect(reducer(undefined, applicationChangeState("active"))).toEqual(
Expand All @@ -27,4 +34,57 @@ describe("IT Wallet preferences reducer", () => {
});
MockDate.reset();
});

it("should handle itwCloseDiscoveryBanner action", () => {
const mockDate = "2024-11-14T20:43:21.361Z";
MockDate.set(mockDate);

const expectedDate = addMonths(mockDate, 6);
const action = itwCloseDiscoveryBanner();
const newState = reducer(INITIAL_STATE, action);

expect(newState).toEqual({
...newState,
hideDiscoveryBannerUntilDate: expectedDate.toISOString()
});
MockDate.reset();
});

it("should handle itwFlagCredentialAsRequested action", () => {
const mockDate = "2024-11-14T20:43:21.361Z";
MockDate.set(mockDate);

const action = itwFlagCredentialAsRequested("MDL");
const newState = reducer(INITIAL_STATE, action);

expect(newState).toEqual({
...newState,
requestedCredentials: {
MDL: mockDate
}
});
MockDate.reset();
});

it("should handle itwRemoveRequestedCredential action", () => {
const mockDate = "2024-11-14T20:43:21.361Z";
MockDate.set(mockDate);

const action = itwUnflagCredentialAsRequested("MDL");
const newState = reducer(
{
...INITIAL_STATE,
requestedCredentials: {
MDL: mockDate
}
},
action
);

expect(newState).toEqual({
...newState,
requestedCredentials: {}
});
MockDate.reset();
});
});
37 changes: 35 additions & 2 deletions ts/features/itwallet/common/store/reducers/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@ import { getType } from "typesafe-actions";
import { Action } from "../../../../../store/actions/types";
import {
itwCloseDiscoveryBanner,
itwCloseFeedbackBanner
itwCloseFeedbackBanner,
itwFlagCredentialAsRequested,
itwUnflagCredentialAsRequested
} from "../actions/preferences";

export type ItwPreferencesState = {
// Date until which the feedback banner should be hidden
hideFeedbackBannerUntilDate?: string;
// Date until which the discovery banner should be hidden
hideDiscoveryBannerUntilDate?: string;
// Stores the list of requested credentials which supports delayed issuance
// Each credential type is associated with a date (ISO string) which represents
// the date of the last issuance request.
requestedCredentials: { [credentialType: string]: string };
};

const INITIAL_STATE: ItwPreferencesState = {};
const INITIAL_STATE: ItwPreferencesState = {
requestedCredentials: {}
};

const reducer = (
state: ItwPreferencesState = INITIAL_STATE,
Expand All @@ -32,6 +42,29 @@ const reducer = (
};
}

case getType(itwFlagCredentialAsRequested): {
return {
...state,
requestedCredentials: {
...state.requestedCredentials,
[action.payload]: new Date().toISOString()
}
};
}

case getType(itwUnflagCredentialAsRequested): {
if (action.payload in state.requestedCredentials) {
const { [action.payload]: _, ...requestedCredentials } =
state.requestedCredentials;

return {
...state,
requestedCredentials
};
}
return state;
}

default:
return state;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { addDays, addMonths } from "date-fns";
import _ from "lodash";
import MockDate from "mockdate";
import { applicationChangeState } from "../../../../../../store/actions/application";
import { appReducer } from "../../../../../../store/reducers";
import {
itwIsDiscoveryBannerHiddenSelector,
itwIsFeedbackBannerHiddenSelector
itwIsFeedbackBannerHiddenSelector,
itwRequestedCredentialsSelector
} from "../preferences";

describe("itwIsFeedbackBannerHiddenSelector", () => {
Expand Down Expand Up @@ -47,3 +49,24 @@ describe("itwIsDiscoveryBannerHiddenSelector", () => {
).toBe(expected);
});
});

describe("itwRequestedCredentialsSelector", () => {
it("should return the list of requested credentials in the past 7 days", () => {
MockDate.set("2024-11-14T20:43:21.361Z");

const globalState = appReducer(undefined, applicationChangeState("active"));

expect(
itwRequestedCredentialsSelector(
_.set(globalState, "features.itWallet.preferences", {
requestedCredentials: {
MDL: "2023-11-14T20:43:21.362Z",
EuropeanDisabilityCard: "2023-11-14T20:43:21.360Z",
EuropeanHealthInsuranceCard: "2023-11-10T20:43:21.361Z"
}
})
)
).toEqual(["MDL"]);
MockDate.reset();
});
});
20 changes: 19 additions & 1 deletion ts/features/itwallet/common/store/selectors/preferences.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isPast } from "date-fns";
import { addYears, isFuture, isPast } from "date-fns";
import { createSelector } from "reselect";
import { GlobalState } from "../../../../../store/reducers/types";
import { ItwPreferencesState } from "../reducers/preferences";
Expand All @@ -25,8 +25,26 @@ export const itwIsFeedbackBannerHiddenSelector = createSelector(
isPastDate(hideFeedbackBannerUntilDate)
);

/**
* Returns if the discovery banner should be displayed or not based on the user's preferences.
* The banner should be visible only if the user closed it more than six months ago.
*/
export const itwIsDiscoveryBannerHiddenSelector = createSelector(
itwPreferencesSelector,
({ hideDiscoveryBannerUntilDate }: ItwPreferencesState) =>
isPastDate(hideDiscoveryBannerUntilDate)
);

/**
* Returns the list of requested credentials in the past 7 days.
*/
export const itwRequestedCredentialsSelector = createSelector(
itwPreferencesSelector,
({ requestedCredentials }: ItwPreferencesState) =>
Object.entries(requestedCredentials)
// This acts as a soft boolean flag: it is unlikely to happen that a credential remains
// in the "requested" status for this long. This allows for flexibility to adjust the
// timeframe in the future if needed.
.filter(([_, requestedAt]) => isFuture(addYears(requestedAt, 1)))
.map(([credentialType]) => credentialType)
);
Loading

0 comments on commit 8cc526b

Please sign in to comment.