Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(MyPortal): [#174859517] Checks token_name on CTA actions #2208

Merged
merged 24 commits into from
Sep 25, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
08033dc
[#174859517] Checks token_name on CTA actions
CrisTofani Sep 18, 2020
b58cc80
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 18, 2020
7978da2
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 21, 2020
25ca30b
[#174859517] Connects cta component to redux for reading right metadata
CrisTofani Sep 21, 2020
d2b3ec4
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 21, 2020
3da07cb
Fixes
CrisTofani Sep 21, 2020
4691ce1
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 21, 2020
7194f31
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 22, 2020
0d4a492
Removes dispatch from component props
CrisTofani Sep 22, 2020
85c553b
Refactoring getCta to handle valid CTA
CrisTofani Sep 22, 2020
1b837a1
Fixes
CrisTofani Sep 22, 2020
87f418c
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 23, 2020
6352963
Refactoring
CrisTofani Sep 23, 2020
4aa2b19
Updates comment
CrisTofani Sep 23, 2020
b0187ff
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 23, 2020
31816bd
Update tests
CrisTofani Sep 24, 2020
36911d6
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 24, 2020
50db727
Merge branch '174859517-cta-check-improvements' of github.com:pagopa/…
CrisTofani Sep 24, 2020
1cd30fe
Add tests on extended validation logic
CrisTofani Sep 24, 2020
9c26f08
[#174859517] add comments
Undermaken Sep 24, 2020
28b5766
[#174859517] fix a bug due to a typo in a codec field
Undermaken Sep 24, 2020
9236b57
[#174859517] fix a bug due to a typo in a codec field
Undermaken Sep 24, 2020
bd788af
[#174859517] update tests
Undermaken Sep 24, 2020
b7d1a46
Merge branch 'master' into 174859517-cta-check-improvements
CrisTofani Sep 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ts/__mocks__/react-native-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
MYPORTAL_ENABLED: "YES"
};
56 changes: 45 additions & 11 deletions ts/components/messages/MessageDetailCTABar.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import * as pot from "italia-ts-commons/lib/pot";
import { fromNullable, fromPredicate } from "fp-ts/lib/Option";
import { View } from "native-base";
import React from "react";
import { StyleSheet } from "react-native";
import { connect } from "react-redux";
import { CreatedMessageWithContent } from "../../../definitions/backend/CreatedMessageWithContent";
import { ServicePublic } from "../../../definitions/backend/ServicePublic";
import { ReduxProps } from "../../store/actions/types";
import { loadServiceMetadata } from "../../store/actions/content";
import { servicesMetadataByIdSelector } from "../../store/reducers/content";
import { PaidReason } from "../../store/reducers/entities/payments";
import { GlobalState } from "../../store/reducers/types";
import { getCTA, isExpired, paymentExpirationInfo } from "../../utils/messages";
import { Dispatch } from "../../store/actions/types";
import CalendarEventButton from "./CalendarEventButton";
import { MessageNestedCTABar } from "./MessageNestedCTABar";
import MessageNestedCTABar from "./MessageNestedCTABar";
import PaymentButton from "./PaymentButton";

type Props = {
type OwnProps = {
message: CreatedMessageWithContent;
service?: ServicePublic;
payment?: PaidReason;
} & ReduxProps;
};

type Props = OwnProps &
ReturnType<typeof mapStateToProps> &
ReturnType<typeof mapDispatchToProps>;

const styles = StyleSheet.create({
row: {
Expand Down Expand Up @@ -48,15 +56,20 @@ class MessageDetailCTABar extends React.PureComponent<Props> {
return fromNullable(this.props.message.content.due_date);
}

public componentDidMount() {
if (!this.props.serviceMetadata && this.props.service) {
this.props.loadServiceMetadata(this.props.service);
}
}

// Render a button to add/remove an event related to the message in the calendar
private renderCalendarEventButton = () =>
private renderCalendarEventButton = () =>
// The add/remove reminder button is hidden:
// - if the message hasn't a due date
// - if the message has a payment and it has been paid or is expired
this.dueDate
this.dueDate
.chain(fromPredicate(() => !this.paid && !this.isPaymentExpired))
.fold(null, _ => <CalendarEventButton message={this.props.message} />)
;
.fold(null, _ => <CalendarEventButton message={this.props.message} />);

// Render a button to display details of the payment related to the message
private renderPaymentButton() {
Expand Down Expand Up @@ -87,13 +100,15 @@ class MessageDetailCTABar extends React.PureComponent<Props> {
{paymentButton}
</View>
);
const maybeCtas = getCTA(this.props.message);
const maybeCtas = getCTA(this.props.message, this.props.serviceMetadata);
const footer2 = maybeCtas.isSome() && (
<View footer={true} style={styles.row}>
<MessageNestedCTABar
ctas={maybeCtas.value}
dispatch={this.props.dispatch}
xsmall={false}
dispatch={this.props.dispatch}
serviceMetadata={this.props.serviceMetadata}
service={this.props.service}
/>
</View>
);
Expand All @@ -106,4 +121,23 @@ class MessageDetailCTABar extends React.PureComponent<Props> {
}
}

export default connect()(MessageDetailCTABar);
const mapStateToProps = (state: GlobalState, ownProps: OwnProps) => {
const servicesMetadataByID = servicesMetadataByIdSelector(state);

return {
serviceMetadata: ownProps.service
? servicesMetadataByID[ownProps.service.service_id]
: pot.none
};
};

const mapDispatchToProps = (dispatch: Dispatch) => ({
loadServiceMetadata: (service: ServicePublic) =>
dispatch(loadServiceMetadata.request(service.service_id)),
dispatch
});

export default connect(
mapStateToProps,
mapDispatchToProps
)(MessageDetailCTABar);
53 changes: 42 additions & 11 deletions ts/components/messages/MessageListCTABar.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as pot from "italia-ts-commons/lib/pot";
import { fromNullable, Option } from "fp-ts/lib/Option";
import { capitalize } from "lodash";
import { View } from "native-base";
Expand All @@ -6,22 +7,29 @@ import { StyleSheet } from "react-native";
import { connect } from "react-redux";
import { CreatedMessageWithContent } from "../../../definitions/backend/CreatedMessageWithContent";
import { ServicePublic } from "../../../definitions/backend/ServicePublic";
import { ReduxProps } from "../../store/actions/types";
import { loadServiceMetadata } from "../../store/actions/content";
import { Dispatch } from "../../store/actions/types";
import { servicesMetadataByIdSelector } from "../../store/reducers/content";
import { PaidReason } from "../../store/reducers/entities/payments";
import { GlobalState } from "../../store/reducers/types";
import customVariables from "../../theme/variables";
import { formatDateAsDay, formatDateAsMonth } from "../../utils/dates";
import { getCTA, isExpired, paymentExpirationInfo } from "../../utils/messages";
import CalendarEventButton from "./CalendarEventButton";
import CalendarIconComponent from "./CalendarIconComponent";
import { MessageNestedCTABar } from "./MessageNestedCTABar";
import MessageNestedCTABar from "./MessageNestedCTABar";
import PaymentButton from "./PaymentButton";

type Props = {
type OwnProps = {
message: CreatedMessageWithContent;
service?: ServicePublic;
payment?: PaidReason;
disabled?: boolean;
} & ReduxProps;
};

type Props = OwnProps &
ReturnType<typeof mapStateToProps> &
ReturnType<typeof mapDispatchToProps>;

const styles = StyleSheet.create({
topContainer: {
Expand Down Expand Up @@ -67,6 +75,12 @@ class MessageListCTABar extends React.PureComponent<Props> {
return fromNullable(this.props.message.content.due_date);
}

public componentDidMount() {
if (!this.props.serviceMetadata && this.props.service) {
this.props.loadServiceMetadata(this.props.service);
}
}

private renderCalendarIcon = () => {
const { dueDate } = this;

Expand All @@ -88,20 +102,19 @@ class MessageListCTABar extends React.PureComponent<Props> {
};

// Render a button to add/remove an event related to the message in the calendar
private renderCalendarEventButton = () =>
private renderCalendarEventButton = () =>
// The add/remove reminder button is shown if:
// - if the message has a due date
// - if the message has a payment and it is not paid nor expired
this.dueDate
this.dueDate
.filter(() => !this.paid && !this.isPaymentExpired)
.fold(undefined, _ => (
<CalendarEventButton
small={true}
disabled={this.props.disabled}
message={this.props.message}
/>
))
;
));

// Render a button to display details of the payment related to the message
private renderPaymentButton() {
Expand All @@ -126,14 +139,16 @@ class MessageListCTABar extends React.PureComponent<Props> {
public render() {
const calendarIcon = this.renderCalendarIcon();
const calendarEventButton = this.renderCalendarEventButton();
const maybeCTA = getCTA(this.props.message);
const maybeCTA = getCTA(this.props.message, this.props.serviceMetadata);
// payment CTA has priority to nested CTA
const nestedCTA =
!this.hasPaymentData && maybeCTA.isSome() ? (
<MessageNestedCTABar
ctas={maybeCTA.value}
dispatch={this.props.dispatch}
xsmall={true}
dispatch={this.props.dispatch}
serviceMetadata={this.props.serviceMetadata}
service={this.props.service}
/>
) : null;
const content = nestedCTA || (
Expand All @@ -158,4 +173,20 @@ class MessageListCTABar extends React.PureComponent<Props> {
}
}

export default connect()(MessageListCTABar);
const mapStateToProps = (state: GlobalState, ownProps: OwnProps) => {
const servicesMetadataByID = servicesMetadataByIdSelector(state);

return {
serviceMetadata: ownProps.service
? servicesMetadataByID[ownProps.service.service_id]
: pot.none
};
};

const mapDispatchToProps = (dispatch: Dispatch) => ({
loadServiceMetadata: (service: ServicePublic) =>
dispatch(loadServiceMetadata.request(service.service_id)),
dispatch
});

export default connect(mapStateToProps, mapDispatchToProps)(MessageListCTABar);
31 changes: 20 additions & 11 deletions ts/components/messages/MessageNestedCTABar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { View } from "native-base";
import React, { ReactElement } from "react";
import { Dispatch } from "redux";
import { ServicePublic } from "../../../definitions/backend/ServicePublic";
import { ServiceMetadataState } from "../../store/reducers/content";
import { CTA, CTAS } from "../../types/MessageCTA";
import { handleCtaAction, isCtaActionValid } from "../../utils/messages";
import { MessageNestedCtaButton } from "./MessageNestedCtaButton";
Expand All @@ -9,25 +11,30 @@ type Props = {
ctas: CTAS;
xsmall: boolean;
dispatch: Dispatch;
service?: ServicePublic;
serviceMetadata?: ServiceMetadataState;
};

// render cta1 and cta2 if they are defined in the message content as nested front-matter
export const MessageNestedCTABar: React.FunctionComponent<Props> = (
const MessageNestedCTABar: React.FunctionComponent<Props> = (
props: Props
): ReactElement => {
const handleCTAPress = (cta: CTA) => {
handleCtaAction(cta, props.dispatch);
handleCtaAction(cta, props.dispatch, props.service);
};

const { ctas } = props;
const cta2 = ctas.cta_2 && isCtaActionValid(ctas.cta_2) && (
<MessageNestedCtaButton
cta={ctas.cta_2}
xsmall={props.xsmall}
primary={false}
onCTAPress={handleCTAPress}
/>
);
const cta1 = isCtaActionValid(ctas.cta_1) && (

const cta2 = ctas.cta_2 &&
isCtaActionValid(ctas.cta_2, props.serviceMetadata) && (
<MessageNestedCtaButton
cta={ctas.cta_2}
xsmall={props.xsmall}
primary={false}
onCTAPress={handleCTAPress}
/>
);
const cta1 = isCtaActionValid(ctas.cta_1, props.serviceMetadata) && (
<MessageNestedCtaButton
cta={ctas.cta_1}
primary={true}
Expand All @@ -43,3 +50,5 @@ export const MessageNestedCTABar: React.FunctionComponent<Props> = (
</>
);
};

export default MessageNestedCTABar;
13 changes: 11 additions & 2 deletions ts/components/ui/Markdown/handlers/internalLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,18 @@ export function getInternalRoute(href: string): Option<InternalRoute> {
}
}

export function handleInternalLink(dispatch: Dispatch, href: string) {
export function handleInternalLink(
dispatch: Dispatch,
href: string,
serviceId?: string
) {
getInternalRoute(href).map(internalNavigation => {
dispatch(addInternalRouteNavigation(internalNavigation));
dispatch(
addInternalRouteNavigation({
...internalNavigation,
params: { ...internalNavigation.params, serviceId }
})
);
dispatch(
NavigationActions.navigate({
routeName: internalNavigation.routeName
Expand Down
Loading