Skip to content

Commit

Permalink
Merge pull request Expensify#34734 from ruben-rebelo/ts-migration/Fla…
Browse files Browse the repository at this point in the history
…gCommentPage

[TS Migration] Migrate FlagCommentPage
  • Loading branch information
danieldoglas authored Feb 8, 2024
2 parents 92e7261 + fbef230 commit e632a82
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 90 deletions.
159 changes: 75 additions & 84 deletions src/pages/FlagCommentPage.js → src/pages/FlagCommentPage.tsx
Original file line number Diff line number Diff line change
@@ -1,155 +1,150 @@
import PropTypes from 'prop-types';
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import {ScrollView, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import type {OnyxEntry} from 'react-native-onyx';
import type {SvgProps} from 'react-native-svg';
import type {ValueOf} from 'type-fest';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import ScreenWrapper from '@components/ScreenWrapper';
import Text from '@components/Text';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import compose from '@libs/compose';
import Navigation from '@libs/Navigation/Navigation';
import type {FlagCommentNavigatorParamList} from '@libs/Navigation/types';
import * as ReportUtils from '@libs/ReportUtils';
import * as Report from '@userActions/Report';
import * as Session from '@userActions/Session';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import reportActionPropTypes from './home/report/reportActionPropTypes';
import type SCREENS from '@src/SCREENS';
import type * as OnyxTypes from '@src/types/onyx';
import withReportAndReportActionOrNotFound from './home/report/withReportAndReportActionOrNotFound';
import reportPropTypes from './reportPropTypes';
import type {WithReportAndReportActionOrNotFoundProps} from './home/report/withReportAndReportActionOrNotFound';

const propTypes = {
/** Array of report actions for this report */
reportActions: PropTypes.shape(reportActionPropTypes),

/** The active report */
report: reportPropTypes,
type FlagCommentPageWithOnyxProps = {
/** All the report actions from the parent report */
parentReportActions: OnyxEntry<OnyxTypes.ReportActions>;
};

/** Route params */
route: PropTypes.shape({
params: PropTypes.shape({
/** Report ID passed via route r/:reportID/:reportActionID */
reportID: PropTypes.string,
type FlagCommentPageNavigationProps = StackScreenProps<FlagCommentNavigatorParamList, typeof SCREENS.FLAG_COMMENT_ROOT>;

/** ReportActionID passed via route r/:reportID/:reportActionID */
reportActionID: PropTypes.string,
}),
}).isRequired,
type FlagCommentPageProps = FlagCommentPageNavigationProps & WithReportAndReportActionOrNotFoundProps & FlagCommentPageWithOnyxProps;

...withLocalizePropTypes,
type Severity = ValueOf<typeof CONST.MODERATION>;

/* Onyx Props */
/** All the report actions from the parent report */
parentReportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)),
type SeverityItem = {
severity: Severity;
name: string;
icon: React.FC<SvgProps>;
description: string;
furtherDetails: string;
furtherDetailsIcon: React.FC<SvgProps>;
};

const defaultProps = {
reportActions: {},
parentReportActions: {},
report: {},
};
type SeverityItemList = SeverityItem[];

/**
* Get the reportID for the associated chatReport
*
* @param {Object} route
* @param {Object} route.params
* @param {String} route.params.reportID
* @returns {String}
*/
function getReportID(route) {
function getReportID(route: FlagCommentPageNavigationProps['route']) {
return route.params.reportID.toString();
}

function FlagCommentPage(props) {
function FlagCommentPage({parentReportActions, route, report, reportActions}: FlagCommentPageProps) {
const styles = useThemeStyles();
const severities = [
const {translate} = useLocalize();

const severities: SeverityItemList = [
{
severity: CONST.MODERATION.FLAG_SEVERITY_SPAM,
name: props.translate('moderation.spam'),
name: translate('moderation.spam'),
icon: Expensicons.FlagLevelOne,
description: props.translate('moderation.spamDescription'),
furtherDetails: props.translate('moderation.levelOneResult'),
description: translate('moderation.spamDescription'),
furtherDetails: translate('moderation.levelOneResult'),
furtherDetailsIcon: Expensicons.FlagLevelOne,
},
{
severity: CONST.MODERATION.FLAG_SEVERITY_INCONSIDERATE,
name: props.translate('moderation.inconsiderate'),
name: translate('moderation.inconsiderate'),
icon: Expensicons.FlagLevelOne,
description: props.translate('moderation.inconsiderateDescription'),
furtherDetails: props.translate('moderation.levelOneResult'),
description: translate('moderation.inconsiderateDescription'),
furtherDetails: translate('moderation.levelOneResult'),
furtherDetailsIcon: Expensicons.FlagLevelOne,
},
{
severity: CONST.MODERATION.FLAG_SEVERITY_INTIMIDATION,
name: props.translate('moderation.intimidation'),
name: translate('moderation.intimidation'),
icon: Expensicons.FlagLevelTwo,
description: props.translate('moderation.intimidationDescription'),
furtherDetails: props.translate('moderation.levelTwoResult'),
description: translate('moderation.intimidationDescription'),
furtherDetails: translate('moderation.levelTwoResult'),
furtherDetailsIcon: Expensicons.FlagLevelTwo,
},
{
severity: CONST.MODERATION.FLAG_SEVERITY_BULLYING,
name: props.translate('moderation.bullying'),
name: translate('moderation.bullying'),
icon: Expensicons.FlagLevelTwo,
description: props.translate('moderation.bullyingDescription'),
furtherDetails: props.translate('moderation.levelTwoResult'),
description: translate('moderation.bullyingDescription'),
furtherDetails: translate('moderation.levelTwoResult'),
furtherDetailsIcon: Expensicons.FlagLevelTwo,
},
{
severity: CONST.MODERATION.FLAG_SEVERITY_HARASSMENT,
name: props.translate('moderation.harassment'),
name: translate('moderation.harassment'),
icon: Expensicons.FlagLevelThree,
description: props.translate('moderation.harassmentDescription'),
furtherDetails: props.translate('moderation.levelThreeResult'),
description: translate('moderation.harassmentDescription'),
furtherDetails: translate('moderation.levelThreeResult'),
furtherDetailsIcon: Expensicons.FlagLevelThree,
},
{
severity: CONST.MODERATION.FLAG_SEVERITY_ASSAULT,
name: props.translate('moderation.assault'),
name: translate('moderation.assault'),
icon: Expensicons.FlagLevelThree,
description: props.translate('moderation.assaultDescription'),
furtherDetails: props.translate('moderation.levelThreeResult'),
description: translate('moderation.assaultDescription'),
furtherDetails: translate('moderation.levelThreeResult'),
furtherDetailsIcon: Expensicons.FlagLevelThree,
},
];

const getActionToFlag = useCallback(() => {
let reportAction = props.reportActions[`${props.route.params.reportActionID.toString()}`];
const getActionToFlag = useCallback((): OnyxTypes.ReportAction | null => {
let reportAction = reportActions?.[`${route.params.reportActionID.toString()}`];

// Handle threads if needed
if (reportAction === undefined || reportAction.reportActionID === undefined) {
reportAction = props.parentReportActions[props.report.parentReportActionID] || {};
if (reportAction?.reportActionID === undefined) {
reportAction = parentReportActions?.[report?.parentReportActionID ?? ''];
}

if (!reportAction) {
return null;
}

return reportAction;
}, [props.report, props.reportActions, props.route.params.reportActionID, props.parentReportActions]);
}, [report, reportActions, route.params.reportActionID, parentReportActions]);

const flagComment = (severity) => {
let reportID = getReportID(props.route);
const flagComment = (severity: Severity) => {
let reportID: string | undefined = getReportID(route);
const reportAction = getActionToFlag();
const parentReportAction = props.parentReportActions[props.report.parentReportActionID] || {};
const parentReportAction = parentReportActions?.[report?.parentReportActionID ?? ''];

// Handle threads if needed
if (ReportUtils.isChatThread(props.report) && reportAction.reportActionID === parentReportAction.reportActionID) {
reportID = ReportUtils.getParentReport(props.report).reportID;
if (ReportUtils.isChatThread(report) && reportAction?.reportActionID === parentReportAction?.reportActionID) {
reportID = ReportUtils.getParentReport(report)?.reportID;
}

if (ReportUtils.canFlagReportAction(reportAction, reportID)) {
Report.flagComment(reportID, reportAction, severity);
if (reportAction && ReportUtils.canFlagReportAction(reportAction, reportID)) {
Report.flagComment(reportID ?? '', reportAction, severity);
}

Navigation.dismissModal();
};

const severityMenuItems = _.map(severities, (item, index) => (
const severityMenuItems = severities.map((item) => (
<MenuItem
key={`${item.severity}_${index}`}
key={`${item.severity}`}
shouldShowRightIcon
title={item.name}
description={item.description}
Expand All @@ -166,13 +161,13 @@ function FlagCommentPage(props) {
testID={FlagCommentPage.displayName}
>
{({safeAreaPaddingBottomStyle}) => (
<FullPageNotFoundView shouldShow={!ReportUtils.shouldShowFlagComment(getActionToFlag(), props.report)}>
<FullPageNotFoundView shouldShow={!ReportUtils.shouldShowFlagComment(getActionToFlag(), report)}>
<HeaderWithBackButton
title={props.translate('reportActionContextMenu.flagAsOffensive')}
title={translate('reportActionContextMenu.flagAsOffensive')}
shouldNavigateToTopMostReport
onBackButtonPress={() => {
Navigation.goBack();
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(props.report.reportID));
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report?.reportID ?? ''));
}}
/>
<ScrollView
Expand All @@ -181,10 +176,10 @@ function FlagCommentPage(props) {
>
<View style={styles.pageWrapper}>
<View style={styles.settingsPageBody}>
<Text style={styles.baseFontStyle}>{props.translate('moderation.flagDescription')}</Text>
<Text style={styles.webViewStyles.baseFontStyle}>{translate('moderation.flagDescription')}</Text>
</View>
</View>
<Text style={[styles.ph5, styles.textLabelSupporting, styles.mb1]}>{props.translate('moderation.chooseAReason')}</Text>
<Text style={[styles.ph5, styles.textLabelSupporting, styles.mb1]}>{translate('moderation.chooseAReason')}</Text>
{severityMenuItems}
</ScrollView>
</FullPageNotFoundView>
Expand All @@ -193,17 +188,13 @@ function FlagCommentPage(props) {
);
}

FlagCommentPage.propTypes = propTypes;
FlagCommentPage.defaultProps = defaultProps;
FlagCommentPage.displayName = 'FlagCommentPage';

export default compose(
withLocalize,
withReportAndReportActionOrNotFound,
withOnyx({
export default withReportAndReportActionOrNotFound(
withOnyx<FlagCommentPageProps, FlagCommentPageWithOnyxProps>({
parentReportActions: {
key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID || report.reportID}`,
key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID ?? report?.reportID}`,
canEvict: false,
},
}),
)(FlagCommentPage);
})(FlagCommentPage),
);
15 changes: 9 additions & 6 deletions src/pages/home/report/withReportAndReportActionOrNotFound.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable rulesdir/no-negated-variables */
import type {RouteProp} from '@react-navigation/native';
import type {StackScreenProps} from '@react-navigation/stack';
import type {ComponentType, ForwardedRef, RefAttributes} from 'react';
import React, {useCallback, useEffect} from 'react';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
Expand All @@ -9,11 +9,13 @@ import withWindowDimensions from '@components/withWindowDimensions';
import type {WindowDimensionsProps} from '@components/withWindowDimensions/types';
import compose from '@libs/compose';
import getComponentDisplayName from '@libs/getComponentDisplayName';
import type {FlagCommentNavigatorParamList} from '@libs/Navigation/types';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import * as Report from '@userActions/Report';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import type * as OnyxTypes from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

Expand All @@ -37,12 +39,11 @@ type OnyxProps = {
isLoadingReportData: OnyxEntry<boolean>;
};

type ComponentProps = OnyxProps &
WindowDimensionsProps & {
route: RouteProp<{params: {reportID: string; reportActionID: string}}>;
};
type WithReportAndReportActionOrNotFoundProps = OnyxProps & WindowDimensionsProps & StackScreenProps<FlagCommentNavigatorParamList, typeof SCREENS.FLAG_COMMENT_ROOT>;

export default function <TProps extends ComponentProps, TRef>(WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>): ComponentType<TProps & RefAttributes<TRef>> {
export default function <TProps extends WithReportAndReportActionOrNotFoundProps, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): ComponentType<TProps & RefAttributes<TRef>> {
function WithReportOrNotFound(props: TProps, ref: ForwardedRef<TRef>) {
const getReportAction = useCallback(() => {
let reportAction: OnyxTypes.ReportAction | Record<string, never> | undefined = props.reportActions?.[`${props.route.params.reportActionID}`];
Expand Down Expand Up @@ -118,3 +119,5 @@ export default function <TProps extends ComponentProps, TRef>(WrappedComponent:
withWindowDimensions,
)(React.forwardRef(WithReportOrNotFound));
}

export type {WithReportAndReportActionOrNotFoundProps};

0 comments on commit e632a82

Please sign in to comment.