From 6d8f969f3b10baa67cea6ec6f19d30dea3f86875 Mon Sep 17 00:00:00 2001 From: Matteo Boschi Date: Thu, 4 Jun 2020 15:50:14 +0200 Subject: [PATCH] feat: [#173146890] Align bonus available type with the remote data (#1869) * [#173146890] align bonus available type with the remote data refactoring * [#173146890] fix refactoring errors * [#173146890] fix refactoring errors * [#173146890] fix refactoring errors * [#173146890] change filed from active -> is_active * [#173146890] update comment --- .../bonusVacanze/api/backendBonusVacanze.ts | 9 +++-- .../components/AvailableBonusItem.tsx | 4 +-- .../bonusVacanze/components/RequestBonus.tsx | 4 +-- .../screens/AvailableBonusScreen.tsx | 6 ++-- .../screens/BonusInformationScreen.tsx | 4 +-- .../store/actions/bonusVacanze.ts | 4 +-- .../store/reducers/availableBonuses.ts | 6 ++-- ts/features/bonusVacanze/types/bonusList.ts | 29 ---------------- .../bonusVacanze/types/bonusesAvailable.ts | 34 +++++++++++++++++++ ts/screens/wallet/WalletHomeScreen.tsx | 24 ++++++++----- 10 files changed, 70 insertions(+), 54 deletions(-) delete mode 100644 ts/features/bonusVacanze/types/bonusList.ts create mode 100644 ts/features/bonusVacanze/types/bonusesAvailable.ts diff --git a/ts/features/bonusVacanze/api/backendBonusVacanze.ts b/ts/features/bonusVacanze/api/backendBonusVacanze.ts index 17273536b2e..b863742f918 100644 --- a/ts/features/bonusVacanze/api/backendBonusVacanze.ts +++ b/ts/features/bonusVacanze/api/backendBonusVacanze.ts @@ -12,7 +12,10 @@ import { } from "italia-ts-commons/lib/requests"; import { ProblemJson } from "../../../../definitions/backend/ProblemJson"; import { defaultRetryingFetch } from "../../../utils/fetch"; -import { BonusList, BonusListT } from "../types/bonusList"; +import { + BonusesAvailable, + BonusesAvailableCodec +} from "../types/bonusesAvailable"; import { BonusVacanze, BonusVacanzeT } from "../types/bonusVacanzeActivation"; import { EligibilityCheck, @@ -25,7 +28,7 @@ type GetBonusListT = IGetApiRequestType< {}, never, never, - BasicResponseType + BasicResponseType >; type EligibilityCheckT = IGetApiRequestType< @@ -140,7 +143,7 @@ const getAvailableBonusesT: GetBonusListT = { url: () => `/bonus/vacanze`, query: _ => ({}), headers: () => ({}), - response_decoder: basicResponseDecoder(BonusListT) + response_decoder: basicResponseDecoder(BonusesAvailableCodec) }; // diff --git a/ts/features/bonusVacanze/components/AvailableBonusItem.tsx b/ts/features/bonusVacanze/components/AvailableBonusItem.tsx index 1a97949ce9b..2e5dcbc8798 100644 --- a/ts/features/bonusVacanze/components/AvailableBonusItem.tsx +++ b/ts/features/bonusVacanze/components/AvailableBonusItem.tsx @@ -7,10 +7,10 @@ import IconFont from "../../../components/ui/IconFont"; import { makeFontStyleObject } from "../../../theme/fonts"; import customVariables from "../../../theme/variables"; import { formatDateAsLocal } from "../../../utils/dates"; -import { BonusItem } from "../types/bonusList"; +import { BonusAvailable } from "../types/bonusesAvailable"; type Props = { - bonusItem: BonusItem; + bonusItem: BonusAvailable; onPress: () => void; }; diff --git a/ts/features/bonusVacanze/components/RequestBonus.tsx b/ts/features/bonusVacanze/components/RequestBonus.tsx index cadfa303f6b..4b46a486035 100644 --- a/ts/features/bonusVacanze/components/RequestBonus.tsx +++ b/ts/features/bonusVacanze/components/RequestBonus.tsx @@ -7,7 +7,7 @@ import H5 from "../../../components/ui/H5"; import I18n from "../../../i18n"; import customVariables from "../../../theme/variables"; import { maybeInnerProperty } from "../../../utils/options"; -import { BonusList } from "../types/bonusList"; +import { BonusesAvailable } from "../types/bonusesAvailable"; import { BonusVacanze } from "../types/bonusVacanzeActivation"; import { ID_BONUS_VACANZE_TYPE } from "../utils/bonus"; import ActiveBonus from "./ActiveBonus"; @@ -16,7 +16,7 @@ type OwnProps = { onButtonPress: () => void; onBonusPress: (bonus: BonusVacanze, validFrom?: Date, validTo?: Date) => void; bonus: pot.Pot; - availableBonusesList: BonusList; + availableBonusesList: BonusesAvailable; }; const styles = StyleSheet.create({ diff --git a/ts/features/bonusVacanze/screens/AvailableBonusScreen.tsx b/ts/features/bonusVacanze/screens/AvailableBonusScreen.tsx index 705a9bbc2c6..13baf6b384c 100644 --- a/ts/features/bonusVacanze/screens/AvailableBonusScreen.tsx +++ b/ts/features/bonusVacanze/screens/AvailableBonusScreen.tsx @@ -23,7 +23,7 @@ import AvailableBonusItem from "../components/AvailableBonusItem"; import { availableBonusesLoad } from "../store/actions/bonusVacanze"; import { availableBonusesSelector } from "../store/reducers/availableBonuses"; import { bonusVacanzeActivationSelector } from "../store/reducers/bonusVacanzeActivation"; -import { BonusItem } from "../types/bonusList"; +import { BonusAvailable } from "../types/bonusesAvailable"; import { BonusVacanze } from "../types/bonusVacanzeActivation"; import { ID_BONUS_VACANZE_TYPE, isBonusActive } from "../utils/bonus"; @@ -47,7 +47,7 @@ const styles = StyleSheet.create({ * instead if bonus is not active the user can navigate to the begin of request flow. */ class AvailableBonusScreen extends React.PureComponent { - private renderListItem = (info: ListRenderItemInfo) => { + private renderListItem = (info: ListRenderItemInfo) => { const { activeBonus } = this.props; const item = info.item; const bonusVacanzeCategory = this.props.availableBonusesList.items.find( @@ -135,7 +135,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ navigateBack: () => dispatch(navigateBack()), loadAvailableBonuses: () => dispatch(availableBonusesLoad.request()), // TODO Add the param to navigate to proper bonus by name (?) - navigateToBonusRequest: (bonusItem: BonusItem) => + navigateToBonusRequest: (bonusItem: BonusAvailable) => dispatch(navigateToBonusRequestInformation({ bonusItem })), // TODO Add the param to bonus detail if a bonus is already active navigateToBonusDetail: ( diff --git a/ts/features/bonusVacanze/screens/BonusInformationScreen.tsx b/ts/features/bonusVacanze/screens/BonusInformationScreen.tsx index b4b07251ca4..211e73bd88b 100644 --- a/ts/features/bonusVacanze/screens/BonusInformationScreen.tsx +++ b/ts/features/bonusVacanze/screens/BonusInformationScreen.tsx @@ -14,10 +14,10 @@ import { navigateBack } from "../../../store/actions/navigation"; import { ReduxProps } from "../../../store/actions/types"; import themeVariables from "../../../theme/variables"; import { FooterTwoButtons } from "../components/markdown/FooterTwoButtons"; -import { BonusItem } from "../types/bonusList"; +import { BonusAvailable } from "../types/bonusesAvailable"; type NavigationParams = Readonly<{ - bonusItem: BonusItem; + bonusItem: BonusAvailable; }>; type Props = ReduxProps & diff --git a/ts/features/bonusVacanze/store/actions/bonusVacanze.ts b/ts/features/bonusVacanze/store/actions/bonusVacanze.ts index 09cd0fc7e02..47c7e4dfbd1 100644 --- a/ts/features/bonusVacanze/store/actions/bonusVacanze.ts +++ b/ts/features/bonusVacanze/store/actions/bonusVacanze.ts @@ -3,7 +3,7 @@ import { createAsyncAction, createStandardAction } from "typesafe-actions"; -import { BonusList } from "../../types/bonusList"; +import { BonusesAvailable } from "../../types/bonusesAvailable"; import { BonusVacanze } from "../../types/bonusVacanzeActivation"; import { EligibilityCheck, EligibilityId } from "../../types/eligibility"; import { EligibilityRequestProgressEnum } from "../reducers/eligibility"; @@ -16,7 +16,7 @@ export const availableBonusesLoad = createAsyncAction( "BONUS_AVAILABLE_REQUEST", "BONUS_AVAILABLE_SUCCESS", "BONUS_AVAILABLE_FAILURE" -)(); +)(); export const checkBonusEligibility = createAsyncAction( "BONUS_CHECK_ELIGIBILITY_REQUEST", diff --git a/ts/features/bonusVacanze/store/reducers/availableBonuses.ts b/ts/features/bonusVacanze/store/reducers/availableBonuses.ts index 24c8a6e6197..0e58c9b5112 100644 --- a/ts/features/bonusVacanze/store/reducers/availableBonuses.ts +++ b/ts/features/bonusVacanze/store/reducers/availableBonuses.ts @@ -2,10 +2,10 @@ import * as pot from "italia-ts-commons/lib/pot"; import { getType } from "typesafe-actions"; import { Action } from "../../../../store/actions/types"; import { GlobalState } from "../../../../store/reducers/types"; -import { BonusList } from "../../types/bonusList"; +import { BonusesAvailable } from "../../types/bonusesAvailable"; import { availableBonusesLoad } from "../actions/bonusVacanze"; -export type AvailableBonusesState = pot.Pot; +export type AvailableBonusesState = pot.Pot; const INITIAL_STATE: AvailableBonusesState = pot.none; @@ -28,6 +28,6 @@ const reducer = ( // Selectors export const availableBonusesSelector = ( state: GlobalState -): pot.Pot => state.bonus.availableBonuses; +): pot.Pot => state.bonus.availableBonuses; export default reducer; diff --git a/ts/features/bonusVacanze/types/bonusList.ts b/ts/features/bonusVacanze/types/bonusList.ts deleted file mode 100644 index 7903cf9df38..00000000000 --- a/ts/features/bonusVacanze/types/bonusList.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * TEMPORARY TYPE DEFINITION - * this type must be replaced with the one auto-generated from spec - */ -import * as t from "io-ts"; -import { NonNegativeInteger } from "italia-ts-commons/lib/numbers"; -import { Timestamp } from "../../../../definitions/backend/Timestamp"; - -const BonusItemR = t.interface({ - id_type: NonNegativeInteger, - name: t.string, - description: t.string, - valid_from: Timestamp, - valid_to: Timestamp -}); -const BonusItemO = t.partial({ - cover: t.string -}); -export const BonusItemT = t.intersection([BonusItemR, BonusItemO], "BonusItem"); -const BonusListR = t.interface({ - items: t.readonlyArray(BonusItemT, "array of Bonus") -}); -const BonusListRO = t.partial({}); -export const BonusListT = t.intersection( - [BonusListR, BonusListRO], - "BonusList" -); -export type BonusList = t.TypeOf; -export type BonusItem = t.TypeOf; diff --git a/ts/features/bonusVacanze/types/bonusesAvailable.ts b/ts/features/bonusVacanze/types/bonusesAvailable.ts new file mode 100644 index 00000000000..7f1a66e497f --- /dev/null +++ b/ts/features/bonusVacanze/types/bonusesAvailable.ts @@ -0,0 +1,34 @@ +/** + * TEMPORARY TYPE DEFINITION + * this type must be replaced with the one auto-generated from spec + */ +import * as t from "io-ts"; +import { NonNegativeInteger } from "italia-ts-commons/lib/numbers"; +import { Timestamp } from "../../../../definitions/backend/Timestamp"; + +const BonusAvailableR = t.interface({ + id_type: NonNegativeInteger, + name: t.string, + is_active: t.boolean, + description: t.string, + valid_from: Timestamp, + valid_to: Timestamp +}); +const BonusAvailableO = t.partial({ + cover: t.string, + service_id: t.string +}); +export const BonusAvailableCodec = t.intersection( + [BonusAvailableR, BonusAvailableO], + "BonusAvailable" +); +const BonusListR = t.interface({ + items: t.readonlyArray(BonusAvailableCodec, "array of available bonuses") +}); +const BonusListRO = t.partial({}); +export const BonusesAvailableCodec = t.intersection( + [BonusListR, BonusListRO], + "BonusesAvailable" +); +export type BonusesAvailable = t.TypeOf; +export type BonusAvailable = t.TypeOf; diff --git a/ts/screens/wallet/WalletHomeScreen.tsx b/ts/screens/wallet/WalletHomeScreen.tsx index 14b5e8019b5..47f537dbb46 100644 --- a/ts/screens/wallet/WalletHomeScreen.tsx +++ b/ts/screens/wallet/WalletHomeScreen.tsx @@ -183,6 +183,13 @@ class WalletHomeScreen extends React.PureComponent { return true; }; + private loadBonusVacanze = () => { + if (bonusVacanzeEnabled) { + this.props.loadAvailableBonuses(); + this.props.loadBonusVacanzeFromId("FAKE_ID"); + } + }; + public componentDidMount() { // WIP loadTransactions should not be called from here // (transactions should be persisted & fetched periodically) @@ -196,10 +203,7 @@ class WalletHomeScreen extends React.PureComponent { customVariables.brandDarkGray ); }); // tslint:disable-line no-object-mutation - if (bonusVacanzeEnabled) { - this.props.loadAvailableBonuses(); - this.props.loadBonusVacanzeFromId("FAKE_ID"); - } + this.loadBonusVacanze(); BackHandler.addEventListener("hardwareBackPress", this.handleBackPress); } @@ -456,6 +460,13 @@ class WalletHomeScreen extends React.PureComponent { ); } + // triggered on pull to refresh + private handleOnRefresh = () => { + this.loadBonusVacanze(); + this.props.loadTransactions(this.props.transactionsLoadedLength); + this.props.loadWallets(); + }; + public render(): React.ReactNode { const { potWallets, potTransactions, historyPayments } = this.props; @@ -485,10 +496,7 @@ class WalletHomeScreen extends React.PureComponent { const walletRefreshControl = ( { - this.props.loadTransactions(this.props.transactionsLoadedLength); - this.props.loadWallets(); - }} + onRefresh={this.handleOnRefresh} refreshing={false} tintColor={"transparent"} // iOS />