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 'ReportActionItemFragment.js' and related components to TypeScript #33958

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
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
1 change: 1 addition & 0 deletions src/components/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,4 @@ function Avatar({
Avatar.displayName = 'Avatar';

export default Avatar;
export {type AvatarProps};
4 changes: 2 additions & 2 deletions src/components/InvertedFlatList/CellRendererComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import type {StyleProp, ViewProps} from 'react-native';
import type {StyleProp, ViewProps, ViewStyle} from 'react-native';
import {View} from 'react-native';

type CellRendererComponentProps = ViewProps & {
index: number;
style?: StyleProp<ViewProps>;
style?: StyleProp<ViewStyle>;
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
};

function CellRendererComponent(props: CellRendererComponentProps) {
Expand Down
179 changes: 0 additions & 179 deletions src/pages/home/report/ReportActionItemFragment.js

This file was deleted.

156 changes: 156 additions & 0 deletions src/pages/home/report/ReportActionItemFragment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, {memo} from 'react';
import type {StyleProp, TextStyle} from 'react-native';
import type {AvatarProps} from '@components/Avatar';
import RenderHTML from '@components/RenderHTML';
import Text from '@components/Text';
import UserDetailsTooltip from '@components/UserDetailsTooltip';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import convertToLTR from '@libs/convertToLTR';
import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
import type * as OnyxCommon from '@src/types/onyx/OnyxCommon';
import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage';
import type {Message} from '@src/types/onyx/ReportAction';
import AttachmentCommentFragment from './comment/AttachmentCommentFragment';
import TextCommentFragment from './comment/TextCommentFragment';

type ReportActionItemFragmentProps = {
/** Users accountID */
accountID: number;

/** The message fragment needing to be displayed */
fragment: Message;

/** Message(text) of an IOU report action */
iouMessage?: string;

/** The reportAction's source */
source?: OriginalMessageSource;

/** Should this fragment be contained in a single line? */
isSingleLine?: boolean;

/** Additional styles to add after local styles */
style?: StyleProp<TextStyle>;

/** The accountID of the copilot who took this action on behalf of the user */
delegateAccountID?: number;

/** icon */
actorIcon?: AvatarProps;

/** Whether the comment is a thread parent message/the first message in a thread */
isThreadParentMessage?: boolean;

/** Should the comment have the appearance of being grouped with the previous comment? */
displayAsGroup?: boolean;

/** Whether the report action type is 'APPROVED' or 'SUBMITTED'. Used to style system messages from Old Dot */
isApprovedOrSubmittedReportAction?: boolean;

/** Used to format RTL display names in Old Dot system messages e.g. Arabic */
isFragmentContainingDisplayName?: boolean;

/** The pending action for the report action */
pendingAction?: OnyxCommon.PendingAction;
};

function ReportActionItemFragment({
pendingAction,
fragment,
accountID,
iouMessage = '',
isSingleLine = false,
source = '',
style = [],
delegateAccountID = 0,
actorIcon = {},
isThreadParentMessage = false,
isApprovedOrSubmittedReportAction = false,
isFragmentContainingDisplayName = false,
displayAsGroup = false,
}: ReportActionItemFragmentProps) {
const styles = useThemeStyles();
const {isOffline} = useNetwork();
const {translate} = useLocalize();

switch (fragment.type) {
case 'COMMENT': {
const isPendingDelete = pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;

// Threaded messages display "[Deleted message]" instead of being hidden altogether.
// While offline we display the previous message with a strikethrough style. Once online we want to
// immediately display "[Deleted message]" while the delete action is pending.

if ((!isOffline && isThreadParentMessage && isPendingDelete) || fragment.isDeletedParentAction) {
return <RenderHTML html={`<comment>${translate('parentReportAction.deletedMessage')}</comment>`} />;
}

if (ReportUtils.isReportMessageAttachment(fragment)) {
return (
<AttachmentCommentFragment
source={source}
html={fragment.html ?? ''}
addExtraMargin={!displayAsGroup}
/>
);
}

return (
<TextCommentFragment
source={source}
fragment={fragment}
styleAsDeleted={!!(isOffline && isPendingDelete)}
iouMessage={iouMessage}
displayAsGroup={displayAsGroup}
style={style}
/>
);
}
case 'TEXT': {
return isApprovedOrSubmittedReportAction ? (
<Text
numberOfLines={isSingleLine ? 1 : undefined}
style={[styles.chatItemMessage, styles.colorMuted]}
>
{isFragmentContainingDisplayName ? convertToLTR(fragment.text) : fragment.text}
</Text>
) : (
<UserDetailsTooltip
accountID={accountID}
delegateAccountID={delegateAccountID}
icon={actorIcon}
>
<Text
numberOfLines={isSingleLine ? 1 : undefined}
style={[styles.chatItemMessageHeaderSender, isSingleLine ? styles.pre : styles.preWrap]}
>
{fragment.text}
</Text>
</UserDetailsTooltip>
);
}
case 'LINK':
return <Text>LINK</Text>;
case 'INTEGRATION_COMMENT':
return <Text>REPORT_LINK</Text>;
case 'REPORT_LINK':
return <Text>REPORT_LINK</Text>;
case 'POLICY_LINK':
return <Text>POLICY_LINK</Text>;

// If we have a message fragment type of OLD_MESSAGE this means we have not yet converted this over to the
// new data structure. So we simply set this message as inner html and render it like we did before.
// This wil allow us to convert messages over to the new structure without needing to do it all at once.
case 'OLD_MESSAGE':
return <Text>OLD_MESSAGE</Text>;
default:
return <Text>fragment.text</Text>;
}
}

ReportActionItemFragment.displayName = 'ReportActionItemFragment';

export default memo(ReportActionItemFragment);
11 changes: 5 additions & 6 deletions src/pages/home/report/ReportActionItemMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type {ReactElement} from 'react';
import React from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import {Text, View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
import type {ReportAction} from '@src/types/onyx';
import type {OriginalMessageAddComment} from '@src/types/onyx/OriginalMessage';
import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage';
import TextCommentFragment from './comment/TextCommentFragment';
import ReportActionItemFragment from './ReportActionItemFragment';

Expand All @@ -20,7 +20,7 @@ type ReportActionItemMessageProps = {
displayAsGroup: boolean;

/** Additional styles to add after local styles. */
style?: StyleProp<ViewStyle>;
style?: StyleProp<ViewStyle & TextStyle>;

/** Whether or not the message is hidden by moderation */
isHidden?: boolean;
Expand Down Expand Up @@ -74,10 +74,9 @@ function ReportActionItemMessage({action, displayAsGroup, reportID, style, isHid
fragment={fragment}
iouMessage={iouMessage}
isThreadParentMessage={ReportActionsUtils.isThreadParentMessage(action, reportID)}
attachmentInfo={action.attachmentInfo}
pendingAction={action.pendingAction}
source={(action.originalMessage as OriginalMessageAddComment['originalMessage'])?.source}
accountID={action.actorAccountID}
source={action.originalMessage as OriginalMessageSource}
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
accountID={action.actorAccountID ?? 0}
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
style={style}
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
displayAsGroup={displayAsGroup}
isApprovedOrSubmittedReportAction={isApprovedOrSubmittedReportAction}
Expand Down
Loading
Loading