From 0d172f3dc699ee7dd7e50bf92aa6a3ad291b5d90 Mon Sep 17 00:00:00 2001 From: Federico Mastrini Date: Fri, 5 Jul 2024 09:39:27 +0200 Subject: [PATCH 1/2] chore(IT Wallet): [SIW-1312] IT Wallet playgrounds refactoring (#5929) ## Short description This PR refactors the IT Wallet playgrounds ## List of changes proposed in this pull request - Moved IT Wallet playgrounds under `ts/features/itwallet/playgrounds` - Refactored `ItwPlayground` screen with a better arrangement of the elements ## How to test Navigate to **Profile > Playgrounds > IT Wallet** ## Preview https://github.com/pagopa/io-app/assets/6160324/6dca3805-f4cf-4b2a-8b99-904566ba08a1 --------- Co-authored-by: Mario Perrotta --- .../itwallet/navigation/ItwParamsList.ts | 2 + .../itwallet/navigation/ItwStackNavigator.tsx | 3 + ts/features/itwallet/navigation/routes.ts | 3 +- .../playgrounds/screens}/ItwPlayground.tsx | 71 ++++++++++--------- ts/navigation/ProfileNavigator.tsx | 2 - ts/navigation/params/ProfileParamsList.ts | 1 - ts/navigation/routes.ts | 1 - ts/screens/profile/DeveloperModeSection.tsx | 5 +- 8 files changed, 47 insertions(+), 41 deletions(-) rename ts/{screens/profile/playgrounds => features/itwallet/playgrounds/screens}/ItwPlayground.tsx (66%) diff --git a/ts/features/itwallet/navigation/ItwParamsList.ts b/ts/features/itwallet/navigation/ItwParamsList.ts index f9b2e015e2a..543412b23cf 100644 --- a/ts/features/itwallet/navigation/ItwParamsList.ts +++ b/ts/features/itwallet/navigation/ItwParamsList.ts @@ -14,4 +14,6 @@ export type ItwParamsList = { [ITW_ROUTES.ISSUANCE.CREDENTIAL_PREVIEW]: undefined; // PRESENTATION [ITW_ROUTES.PRESENTATION.EID_DETAIL]: undefined; + // PLAYGROUNDS + [ITW_ROUTES.PLAYGROUNDS]: undefined; }; diff --git a/ts/features/itwallet/navigation/ItwStackNavigator.tsx b/ts/features/itwallet/navigation/ItwStackNavigator.tsx index 84e2d324bd0..f3fd4a4ec56 100644 --- a/ts/features/itwallet/navigation/ItwStackNavigator.tsx +++ b/ts/features/itwallet/navigation/ItwStackNavigator.tsx @@ -10,6 +10,7 @@ import { ItwIssuanceCredentialPreviewScreen } from "../issuance/screens/ItwIssua import { ItwIssuanceEidPreviewScreen } from "../issuance/screens/ItwIssuanceEidPreviewScreen"; import { ItwIssuanceEidResultScreen } from "../issuance/screens/ItwIssuanceEidResultScreen"; import { ItwPresentationEidDetailScreen } from "../presentation/screens/ItwPresentationEidDetailScreen"; +import ItwPlayground from "../playgrounds/screens/ItwPlayground"; import { ItwParamsList } from "./ItwParamsList"; import { ITW_ROUTES } from "./routes"; @@ -64,5 +65,7 @@ export const ItwStackNavigator = () => ( component={ItwPresentationEidDetailScreen} options={{ headerShown: false }} /> + {/* PLAYGROUNDS */} + ); diff --git a/ts/features/itwallet/navigation/routes.ts b/ts/features/itwallet/navigation/routes.ts index 3bfc9a34756..226e44c0510 100644 --- a/ts/features/itwallet/navigation/routes.ts +++ b/ts/features/itwallet/navigation/routes.ts @@ -16,5 +16,6 @@ export const ITW_ROUTES = { } as const, PRESENTATION: { EID_DETAIL: "ITW_PRESENTATION_EID_DETAIL" - } as const + } as const, + PLAYGROUNDS: "ITW_PLAYGROUNDS" as const }; diff --git a/ts/screens/profile/playgrounds/ItwPlayground.tsx b/ts/features/itwallet/playgrounds/screens/ItwPlayground.tsx similarity index 66% rename from ts/screens/profile/playgrounds/ItwPlayground.tsx rename to ts/features/itwallet/playgrounds/screens/ItwPlayground.tsx index 49a5a22fd8a..cd705552e3c 100644 --- a/ts/screens/profile/playgrounds/ItwPlayground.tsx +++ b/ts/features/itwallet/playgrounds/screens/ItwPlayground.tsx @@ -2,15 +2,16 @@ import { ContentWrapper, Divider, H3, + ListItemHeader, ListItemNav, VSpacer } from "@pagopa/io-app-design-system"; import * as React from "react"; import { ScrollView } from "react-native-gesture-handler"; -import { useHeaderSecondLevel } from "../../../hooks/useHeaderSecondLevel"; -import ItwMarkdown from "../../../features/itwallet/common/components/ItwMarkdown"; -import { useIONavigation } from "../../../navigation/params/AppParamsList"; -import { ITW_ROUTES } from "../../../features/itwallet/navigation/routes"; +import { useHeaderSecondLevel } from "../../../../hooks/useHeaderSecondLevel"; +import ItwMarkdown from "../../common/components/ItwMarkdown"; +import { useIONavigation } from "../../../../navigation/params/AppParamsList"; +import { ITW_ROUTES } from "../../navigation/routes"; // Sample markdown text const sampleMarkdown = ` @@ -50,12 +51,6 @@ const ItwPlayground = () => { }); }; - const navigateToIdentification = () => { - navigation.navigate(ITW_ROUTES.MAIN, { - screen: ITW_ROUTES.IDENTIFICATION.MODE_SELECTION - }); - }; - const navigateToCredentialDetail = () => { navigation.navigate(ITW_ROUTES.MAIN, { screen: ITW_ROUTES.PRESENTATION.EID_DETAIL @@ -77,39 +72,47 @@ const ItwPlayground = () => { return ( - {/* Discovery Playground */} + {/* Activation Playground */} + navigateToDiscovery()} + description="Start the eID issuing flow" + onPress={() => undefined} /> - - {/* Issuing eID Playground */} + + {/* Issuing Playground */} + undefined} /> - {/* Issuing mDL Playground */} undefined} /> - {/* Issuing TS Playground */} undefined} /> + + {/* Screens Playground */} + + - {/* Credential Preview */} { onPress={navigateToCredentialPreview} /> - {/* Credential detail playground */} { onPress={navigateToCredentialDetail} /> - {/* Credential auth playground */} - - + + {/* Other Playgrounds */} +

{"IT Wallet markdown preview"}

- {/* Markdown ITW Playground */} + {sampleMarkdown} {/* TODO: Add more items here */} +
); diff --git a/ts/navigation/ProfileNavigator.tsx b/ts/navigation/ProfileNavigator.tsx index b9eff19ea9e..a99c1d7780c 100644 --- a/ts/navigation/ProfileNavigator.tsx +++ b/ts/navigation/ProfileNavigator.tsx @@ -26,7 +26,6 @@ import ShareDataScreen from "../screens/profile/ShareDataScreen"; import TosScreen from "../screens/profile/TosScreen"; import { IdPayCodePlayGround } from "../screens/profile/playgrounds/IdPayCodePlayground"; import IdPayOnboardingPlayground from "../screens/profile/playgrounds/IdPayOnboardingPlayground"; -import ItwPlayground from "../screens/profile/playgrounds/ItwPlayground"; import MarkdownPlayground from "../screens/profile/playgrounds/MarkdownPlayground"; import { isGestureEnabled } from "../utils/navigation"; import TrialSystemPlayground from "../screens/profile/TrialSystemPlayground"; @@ -161,7 +160,6 @@ const ProfileStackNavigator = () => ( name={ROUTES.PROFILE_PREFERENCES_NOTIFICATIONS} component={NotificationsPreferencesScreen} /> - ); diff --git a/ts/navigation/params/ProfileParamsList.ts b/ts/navigation/params/ProfileParamsList.ts index 467fc20574b..d51369d3d04 100644 --- a/ts/navigation/params/ProfileParamsList.ts +++ b/ts/navigation/params/ProfileParamsList.ts @@ -31,5 +31,4 @@ export type ProfileParamsList = { [ROUTES.PROFILE_PREFERENCES_NOTIFICATIONS]: undefined; [ROUTES.IDPAY_ONBOARDING_PLAYGROUND]: undefined; [ROUTES.IDPAY_CODE_PLAYGROUND]: undefined; - [ROUTES.ITW_PLAYGROUND]: undefined; }; diff --git a/ts/navigation/routes.ts b/ts/navigation/routes.ts index c35fc4e2921..a6d2c61706e 100644 --- a/ts/navigation/routes.ts +++ b/ts/navigation/routes.ts @@ -129,7 +129,6 @@ const ROUTES = { IDPAY_ONBOARDING_PLAYGROUND: "IDPAY_ONBOARDING_PLAYGROUND", LOLLIPOP_PLAYGROUND: "LOLLIPOP_PLAYGROUND", IDPAY_CODE_PLAYGROUND: "IDPAY_CODE_PLAYGROUND", - ITW_PLAYGROUND: "ITW_PLAYGROUND", // Preferences INSERT_EMAIL_SCREEN: "INSERT_EMAIL_SCREEN", diff --git a/ts/screens/profile/DeveloperModeSection.tsx b/ts/screens/profile/DeveloperModeSection.tsx index d530f8e4430..63eca11eaf0 100644 --- a/ts/screens/profile/DeveloperModeSection.tsx +++ b/ts/screens/profile/DeveloperModeSection.tsx @@ -57,6 +57,7 @@ import { clipboardSetStringWithFeedback } from "../../utils/clipboard"; import { getDeviceId } from "../../utils/device"; import { isDevEnv } from "../../utils/environment"; +import { ITW_ROUTES } from "../../features/itwallet/navigation/routes"; import DSEnableSwitch from "./components/DSEnableSwitch"; type PlaygroundsNavListItem = { @@ -413,8 +414,8 @@ const PlaygroundsSection = () => { condition: isItWalletTestEnabled, value: "IT Wallet", onPress: () => - navigation.navigate(ROUTES.PROFILE_NAVIGATOR, { - screen: ROUTES.ITW_PLAYGROUND + navigation.navigate(ITW_ROUTES.MAIN, { + screen: ITW_ROUTES.PLAYGROUNDS }) }, { From bb96fd21d2e136542b6b8b5b316c221cc90190d4 Mon Sep 17 00:00:00 2001 From: Cristiano Tofani Date: Fri, 5 Jul 2024 16:30:44 +0200 Subject: [PATCH 2/2] chore: [IOPLT-599] Replace legacy StatusContent with Alert component for SectionStatus advices (#5924) ## Short description This PR replaces the SectionStatus component rendering with the new DS Alert component ## List of changes proposed in this pull request - Refactoring on component definition - Removal of the component from DS Section ## How to test On dev-server activate a status message on any of the dedicated sections in order to view the Alert properly rendered.
Static case
With Link https://github.com/pagopa/io-app/assets/3959405/a0a0548b-c1d4-48e3-b172-6c3c643b2d33
--------- Co-authored-by: Mario Perrotta Co-authored-by: Fabio Bombardi <16268789+shadowsheep1@users.noreply.github.com> --- ts/components/SectionStatus/StatusContent.tsx | 19 ++++ .../__tests__/SectionStatusComponent.test.tsx | 30 ++----- ts/components/SectionStatus/index.tsx | 89 ++++++------------- .../design-system/core/DSLegacyAlert.tsx | 11 +-- .../pn/components/LegacyMessageDetails.tsx | 7 +- 5 files changed, 59 insertions(+), 97 deletions(-) diff --git a/ts/components/SectionStatus/StatusContent.tsx b/ts/components/SectionStatus/StatusContent.tsx index 9c215701cd5..cdf2963cffe 100644 --- a/ts/components/SectionStatus/StatusContent.tsx +++ b/ts/components/SectionStatus/StatusContent.tsx @@ -8,6 +8,7 @@ import { } from "@pagopa/io-app-design-system"; import { WithTestID } from "../../types/WithTestID"; import { Label } from "../core/typography/Label"; +import { LevelEnum } from "../../../definitions/content/SectionStatus"; const iconSize = 24; @@ -38,6 +39,24 @@ type Props = WithTestID<{ labelPaddingVertical?: number; }>; +export const statusColorMap: Record = { + [LevelEnum.normal]: "aqua", + [LevelEnum.critical]: "red", + [LevelEnum.warning]: "orange" +}; + +export const statusIconMap: Record = { + [LevelEnum.normal]: "ok", + [LevelEnum.critical]: "notice", + [LevelEnum.warning]: "info" +}; + +// map the text background color with the relative text color +export const getStatusTextColor = ( + level: LevelEnum +): "bluegreyDark" | "white" => + level === LevelEnum.normal ? "bluegreyDark" : "white"; + const StatusContent = forwardRef>( ( { diff --git a/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx b/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx index bbd2ba6ae1d..24f1a353b33 100644 --- a/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx +++ b/ts/components/SectionStatus/__tests__/SectionStatusComponent.test.tsx @@ -68,21 +68,22 @@ describe("SectionStatusComponent", () => { }); [ - [LevelEnum.normal, IOColors.aqua], - [LevelEnum.warning, IOColors.orange], - [LevelEnum.critical, IOColors.red] + [LevelEnum.normal, IOColors["info-100"]], + [LevelEnum.warning, IOColors["warning-100"]], + [LevelEnum.critical, IOColors["error-100"]] ].forEach(([level, color]) => { describe(`given the level ${level}`, () => { const store = mockStore( mockSectionStatusState("messages", { ...sectionStatus, + web_url: undefined, level: level as LevelEnum }) ); it(`should apply background color ${color} to the status content`, () => { const component = getComponent("messages", store); - const view = component.getByTestId("SectionStatusContent"); + const view = component.getByTestId("SectionStatusComponentContent"); expect(view).toHaveStyle({ backgroundColor: color }); }); }); @@ -101,15 +102,7 @@ describe("SectionStatusComponent", () => { const component = getComponent("messages"); const view = component.getByTestId("SectionStatusComponentPressable"); expect(view.props.accessible).toBe(true); - expect(view.props.accessibilityLabel).toMatch( - `${sectionStatus.message["it-IT"]}, ${I18n.t( - "global.sectionStatus.moreInfo" - )}` - ); - expect(view.props.accessibilityHint).toMatch( - I18n.t("global.accessibility.linkHint") - ); - expect(view.props.accessibilityRole).toBe("link"); + expect(view.props.accessibilityRole).toBe("button"); }); it("should render the touchable wrapper which opens the correct url", () => { @@ -135,14 +128,9 @@ describe("SectionStatusComponent", () => { it("should set the correct a11y properties to the status content", () => { setLocale("it"); const component = getComponent("messages", store); - const view = component.getByTestId("SectionStatusContent"); - expect(view.props.accessible).toBe(true); - expect(view.props.accessibilityRole).toBeUndefined(); - expect(view.props.accessibilityLabel).toMatch( - `${sectionStatus.message["it-IT"]}, ${I18n.t( - "global.accessibility.alert" - )}` - ); + const view = component.getByTestId("SectionStatusComponentContent"); + expect(view.props.accessible).toBe(false); + expect(view.props.accessibilityRole).toBe("alert"); }); it("should display the accessibility alert text", () => { diff --git a/ts/components/SectionStatus/index.tsx b/ts/components/SectionStatus/index.tsx index 7a274ed3efa..33252078a54 100644 --- a/ts/components/SectionStatus/index.tsx +++ b/ts/components/SectionStatus/index.tsx @@ -2,10 +2,10 @@ import { useNavigation } from "@react-navigation/native"; import { pipe } from "fp-ts/lib/function"; import * as O from "fp-ts/lib/Option"; import _ from "lodash"; -import React, { useCallback } from "react"; -import { Pressable, View } from "react-native"; +import React, { ComponentProps, useCallback } from "react"; +import { View } from "react-native"; import { connect } from "react-redux"; -import type { IOColors, IOIcons } from "@pagopa/io-app-design-system"; +import { Alert } from "@pagopa/io-app-design-system"; import { LevelEnum } from "../../../definitions/content/SectionStatus"; import I18n from "../../i18n"; import { @@ -16,8 +16,6 @@ import { GlobalState } from "../../store/reducers/types"; import { getFullLocale } from "../../utils/locale"; import { maybeNotNullyString } from "../../utils/strings"; import { openWebUrl } from "../../utils/url"; -import { Link } from "../core/typography/Link"; -import StatusContent from "./StatusContent"; type OwnProps = { sectionKey: SectionStatusKey; @@ -26,24 +24,15 @@ type OwnProps = { type Props = OwnProps & ReturnType; -export const statusColorMap: Record = { - [LevelEnum.normal]: "aqua", - [LevelEnum.critical]: "red", - [LevelEnum.warning]: "orange" +export const statusVariantMap: Record< + LevelEnum, + ComponentProps["variant"] +> = { + [LevelEnum.normal]: "info", + [LevelEnum.critical]: "error", + [LevelEnum.warning]: "warning" }; -export const statusIconMap: Record = { - [LevelEnum.normal]: "ok", - [LevelEnum.critical]: "notice", - [LevelEnum.warning]: "info" -}; - -// map the text background color with the relative text color -export const getStatusTextColor = ( - level: LevelEnum -): "bluegreyDark" | "white" => - level === LevelEnum.normal ? "bluegreyDark" : "white"; - export const InnerSectionStatus = ( props: Omit & { sectionStatus: NonNullable; @@ -51,16 +40,12 @@ export const InnerSectionStatus = ( ) => { const viewRef = React.createRef(); const { sectionStatus, onSectionRef } = props; - const iconName = statusIconMap[sectionStatus.level]; - const backgroundColor = statusColorMap[sectionStatus.level]; const locale = getFullLocale(); const maybeWebUrl = maybeNotNullyString( sectionStatus.web_url && sectionStatus.web_url[locale] ); const navigation = useNavigation(); - const color = getStatusTextColor(sectionStatus.level); - const handleOnSectionRef = useCallback(() => { if (viewRef.current) { onSectionRef?.(viewRef); @@ -78,49 +63,25 @@ export const InnerSectionStatus = ( O.fold( () => ( // render text only - - {`${sectionStatus.message[locale]} `} - + fullWidth + content={`${sectionStatus.message[locale]}`} + variant={statusVariantMap[sectionStatus.level]} + viewRef={viewRef} + /> ), - - // render a pressable element with the link webUrl => ( - openWebUrl(webUrl)} + // render a pressable element with the link + - - {`${sectionStatus.message[locale]} `} - - {I18n.t("global.sectionStatus.moreInfo")} - - - + fullWidth + content={`${sectionStatus.message[locale]} `} + variant={statusVariantMap[sectionStatus.level]} + action={I18n.t("global.sectionStatus.moreInfo")} + onPress={() => openWebUrl(webUrl)} + viewRef={viewRef} + /> ) ) ); diff --git a/ts/features/design-system/core/DSLegacyAlert.tsx b/ts/features/design-system/core/DSLegacyAlert.tsx index 509a367d6ba..03a49f1daa8 100644 --- a/ts/features/design-system/core/DSLegacyAlert.tsx +++ b/ts/features/design-system/core/DSLegacyAlert.tsx @@ -1,11 +1,10 @@ import { VSpacer } from "@pagopa/io-app-design-system"; import * as React from "react"; -import SectionStatusComponent, { - getStatusTextColor, +import StatusContent, { statusColorMap, + getStatusTextColor, statusIconMap -} from "../../../components/SectionStatus"; -import StatusContent from "../../../components/SectionStatus/StatusContent"; +} from "../../../components/SectionStatus/StatusContent"; import { DSFullWidthComponent } from "../components/DSFullWidthComponent"; /* Types */ @@ -28,10 +27,6 @@ export const DSLegacyAlert = () => ( - - - -