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

[TS Migration] Migrate WorkspaceCard to Typescript #34963

Merged
merged 11 commits into from
Feb 12, 2024
6 changes: 1 addition & 5 deletions src/pages/workspace/WorkspacePageWithSections.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type {RouteProp} from '@react-navigation/native';
import React, {useEffect, useMemo, useRef} from 'react';
import type {ReactNode} from 'react';
import {View} from 'react-native';
Expand Down Expand Up @@ -40,9 +39,6 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps &
/** The text to display in the header */
headerText: string;

/** The route object passed to this page from the navigator */
route: RouteProp<{params: {policyID: string}}>;

/** Main content of the page */
children: (hasVBA?: boolean, policyID?: string, isUsingECard?: boolean) => ReactNode;

Expand Down Expand Up @@ -93,7 +89,7 @@ function WorkspacePageWithSections({
const isLoading = reimbursementAccount?.isLoading ?? true;
const achState = reimbursementAccount?.achData?.state ?? '';
const isUsingECard = user?.isUsingExpensifyCard ?? false;
const policyID = route.params.policyID;
const policyID = route.params?.policyID ?? '';
const policyName = policy?.name;
const hasVBA = achState === BankAccount.STATE.OPEN;
const content = children(hasVBA, policyID, isUsingECard);
Expand Down
49 changes: 0 additions & 49 deletions src/pages/workspace/card/WorkspaceCardNoVBAView.js

This file was deleted.

41 changes: 41 additions & 0 deletions src/pages/workspace/card/WorkspaceCardNoVBAView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import {View} from 'react-native';
import ConnectBankAccountButton from '@components/ConnectBankAccountButton';
import * as Illustrations from '@components/Icon/Illustrations';
import Section from '@components/Section';
import Text from '@components/Text';
import UnorderedList from '@components/UnorderedList';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';

type WorkspaceCardNoVBAViewProps = {
/** The policy ID currently being configured */
policyID: string;
};

function WorkspaceCardNoVBAView({policyID}: WorkspaceCardNoVBAViewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const unorderedListItems = [translate('workspace.card.benefit1'), translate('workspace.card.benefit2'), translate('workspace.card.benefit3'), translate('workspace.card.benefit4')];

return (
<Section
title={translate('workspace.card.header')}
icon={Illustrations.CreditCardsNew}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isCentralPane prop is removed. Was this intentional change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not intentional, I've added the prop again. Thanks for pointing that out!

>
<View style={[styles.mv4]}>
<Text>{translate('workspace.card.noVBACopy')}</Text>
</View>

<UnorderedList items={unorderedListItems} />
<ConnectBankAccountButton
policyID={policyID}
style={[styles.mt6]}
/>
</Section>
);
}

WorkspaceCardNoVBAView.displayName = 'WorkspaceCardNoVBAView';

export default WorkspaceCardNoVBAView;
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
import PropTypes from 'prop-types';
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
import CONST from '@src/CONST';
import type SCREENS from '@src/SCREENS';
import WorkspaceCardNoVBAView from './WorkspaceCardNoVBAView';
import WorkspaceCardVBANoECardView from './WorkspaceCardVBANoECardView';
import WorkspaceCardVBAWithECardView from './WorkspaceCardVBAWithECardView';

const propTypes = {
/** The route object passed to this page from the navigator */
route: PropTypes.shape({
/** Each parameter passed via the URL */
params: PropTypes.shape({
/** The policyID that is being configured */
policyID: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
type WorkspaceCardPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.CARD>;

...withLocalizePropTypes,
};

function WorkspaceCardPage(props) {
function WorkspaceCardPage({route}: WorkspaceCardPageProps) {
const {translate} = useLocalize();
return (
<WorkspacePageWithSections
shouldUseScrollView
headerText={props.translate('workspace.common.card')}
route={props.route}
headerText={translate('workspace.common.card')}
route={route}
guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_CARD}
>
{(hasVBA, policyID, isUsingECard) => (
{(hasVBA?: boolean, policyID?: string, isUsingECard?: boolean) => (
<>
{!hasVBA && <WorkspaceCardNoVBAView policyID={policyID} />}
{!hasVBA && <WorkspaceCardNoVBAView policyID={policyID ?? ''} />}

{hasVBA && !isUsingECard && <WorkspaceCardVBANoECardView />}

Expand All @@ -41,7 +33,6 @@ function WorkspaceCardPage(props) {
);
}

WorkspaceCardPage.propTypes = propTypes;
WorkspaceCardPage.displayName = 'WorkspaceCardPage';

export default withLocalize(WorkspaceCardPage);
export default WorkspaceCardPage;
Original file line number Diff line number Diff line change
@@ -1,51 +1,43 @@
import React from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import Section from '@components/Section';
import Text from '@components/Text';
import UnorderedList from '@components/UnorderedList';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import compose from '@libs/compose';
import userPropTypes from '@pages/settings/userPropTypes';
import * as Link from '@userActions/Link';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {User} from '@src/types/onyx';

const propTypes = {
type WorkspaceCardVBANoECardViewOnyxProps = {
/** Information about the logged in user's account */
user: userPropTypes,

...withLocalizePropTypes,
user: OnyxEntry<User>;
};

const defaultProps = {
user: {},
};
type WorkspaceCardVBANoECardViewProps = WorkspaceCardVBANoECardViewOnyxProps;

function WorkspaceCardVBANoECardView(props) {
function WorkspaceCardVBANoECardView({user}: WorkspaceCardVBANoECardViewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const unorderedListItems = [translate('workspace.card.benefit1'), translate('workspace.card.benefit2'), translate('workspace.card.benefit3'), translate('workspace.card.benefit4')];

return (
<>
<Section
title={props.translate('workspace.card.header')}
title={translate('workspace.card.header')}
icon={Illustrations.CreditCardsNew}
>
<View style={[styles.mv3]}>
<UnorderedList
items={[
props.translate('workspace.card.benefit1'),
props.translate('workspace.card.benefit2'),
props.translate('workspace.card.benefit3'),
props.translate('workspace.card.benefit4'),
]}
/>
<UnorderedList items={unorderedListItems} />
</View>
<Button
text={props.translate('workspace.card.addWorkEmail')}
text={translate('workspace.card.addWorkEmail')}
onPress={() => {
Link.openOldDotLink(CONST.ADD_SECONDARY_LOGIN_URL);
}}
Expand All @@ -57,20 +49,15 @@ function WorkspaceCardVBANoECardView(props) {
success
/>
</Section>
{Boolean(props.user.isCheckingDomain) && <Text style={[styles.m5, styles.formError]}>{props.translate('workspace.card.checkingDomain')}</Text>}
{!!user?.isCheckingDomain && <Text style={[styles.m5, styles.formError]}>{translate('workspace.card.checkingDomain')}</Text>}
</>
);
}

WorkspaceCardVBANoECardView.propTypes = propTypes;
WorkspaceCardVBANoECardView.defaultProps = defaultProps;
WorkspaceCardVBANoECardView.displayName = 'WorkspaceCardVBANoECardView';

export default compose(
withLocalize,
withOnyx({
user: {
key: ONYXKEYS.USER,
},
}),
)(WorkspaceCardVBANoECardView);
export default withOnyx<WorkspaceCardVBANoECardViewProps, WorkspaceCardVBANoECardViewOnyxProps>({
user: {
key: ONYXKEYS.USER,
},
})(WorkspaceCardVBANoECardView);
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,27 @@ import React from 'react';
import {View} from 'react-native';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import type {MenuItemWithLink} from '@components/MenuItemList';
import Section from '@components/Section';
import Text from '@components/Text';
import UnorderedList from '@components/UnorderedList';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Link from '@userActions/Link';

const propTypes = {
...withLocalizePropTypes,
};

const MENU_LINKS = {
ISSUE_AND_MANAGE_CARDS: 'domain_companycards',
RECONCILE_CARDS: encodeURI('domain_companycards?param={"section":"cardReconciliation"}'),
SETTLEMENT_FREQUENCY: encodeURI('domain_companycards?param={"section":"configureSettings"}'),
};
} as const;

function WorkspaceCardVBAWithECardView(props) {
function WorkspaceCardVBAWithECardView() {
const styles = useThemeStyles();
const menuItems = [
const {translate} = useLocalize();

const menuItems: MenuItemWithLink[] = [
{
title: props.translate('workspace.common.issueAndManageCards'),
title: translate('workspace.common.issueAndManageCards'),
onPress: () => Link.openOldDotLink(MENU_LINKS.ISSUE_AND_MANAGE_CARDS),
icon: Expensicons.ExpensifyCard,
shouldShowRightIcon: true,
Expand All @@ -32,7 +31,7 @@ function WorkspaceCardVBAWithECardView(props) {
link: () => Link.buildOldDotURL(MENU_LINKS.ISSUE_AND_MANAGE_CARDS),
},
{
title: props.translate('workspace.common.reconcileCards'),
title: translate('workspace.common.reconcileCards'),
onPress: () => Link.openOldDotLink(MENU_LINKS.RECONCILE_CARDS),
icon: Expensicons.ReceiptSearch,
shouldShowRightIcon: true,
Expand All @@ -41,7 +40,7 @@ function WorkspaceCardVBAWithECardView(props) {
link: () => Link.buildOldDotURL(MENU_LINKS.RECONCILE_CARDS),
},
{
title: props.translate('workspace.common.settlementFrequency'),
title: translate('workspace.common.settlementFrequency'),
onPress: () => Link.openOldDotLink(MENU_LINKS.SETTLEMENT_FREQUENCY),
icon: Expensicons.Gear,
shouldShowRightIcon: true,
Expand All @@ -53,29 +52,23 @@ function WorkspaceCardVBAWithECardView(props) {

return (
<Section
title={props.translate('workspace.card.headerWithEcard')}
title={translate('workspace.card.headerWithEcard')}
icon={Illustrations.CreditCardsNew}
menuItems={menuItems}
>
<View style={[styles.mv3]}>
<Text>{props.translate('workspace.card.VBAWithECardCopy')}</Text>
<Text>{translate('workspace.card.VBAWithECardCopy')}</Text>
</View>

<View style={[styles.mv3]}>
<UnorderedList
items={[
props.translate('workspace.card.benefit1'),
props.translate('workspace.card.benefit2'),
props.translate('workspace.card.benefit3'),
props.translate('workspace.card.benefit4'),
]}
items={[translate('workspace.card.benefit1'), translate('workspace.card.benefit2'), translate('workspace.card.benefit3'), translate('workspace.card.benefit4')]}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we have done in other files, can we move this to a separate const.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, missed that one, thank you!

/>
</View>
</Section>
);
}

WorkspaceCardVBAWithECardView.propTypes = propTypes;
WorkspaceCardVBAWithECardView.displayName = 'WorkspaceCardVBAWithECardView';

export default withLocalize(WorkspaceCardVBAWithECardView);
export default WorkspaceCardVBAWithECardView;
9 changes: 4 additions & 5 deletions src/pages/workspace/invoices/WorkspaceInvoicesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import type {RouteProp} from '@react-navigation/native';
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import useLocalize from '@hooks/useLocalize';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
import CONST from '@src/CONST';
import type SCREENS from '@src/SCREENS';
import WorkspaceInvoicesNoVBAView from './WorkspaceInvoicesNoVBAView';
import WorkspaceInvoicesVBAView from './WorkspaceInvoicesVBAView';

/** Defined route object that contains the policyID param, WorkspacePageWithSections is a common component for Workspaces and expect the route prop that includes the policyID */
type WorkspaceInvoicesPageProps = {
route: RouteProp<{params: {policyID: string}}>;
};
type WorkspaceInvoicesPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.INVOICES>;

function WorkspaceInvoicesPage({route}: WorkspaceInvoicesPageProps) {
const {translate} = useLocalize();
Expand Down
9 changes: 6 additions & 3 deletions src/pages/workspace/withPolicy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import type {ComponentType, ForwardedRef, RefAttributes} from 'react';
import React, {forwardRef} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import policyMemberPropType from '@pages/policyMemberPropType';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import type * as OnyxTypes from '@src/types/onyx';

type PolicyRoute = RouteProp<{params: {policyID: string}}>;
type PolicyRoute = RouteProp<SettingsNavigatorParamList, ValueOf<typeof SCREENS.WORKSPACE>>;

function getPolicyIDFromRoute(route: PolicyRoute): string {
return route?.params?.policyID ?? '';
Expand Down Expand Up @@ -130,5 +133,5 @@ export default function <TProps extends WithPolicyProps, TRef>(WrappedComponent:
})(forwardRef(WithPolicy));
}

export {policyPropTypes, policyDefaultProps};
export type {WithPolicyOnyxProps, WithPolicyProps};
export {policyDefaultProps, policyPropTypes};
export type {WithPolicyOnyxProps, WithPolicyProps, PolicyRoute};
Loading