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 7 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
Original file line number Diff line number Diff line change
@@ -1,101 +1,83 @@
import PropTypes from 'prop-types';
import React, {memo} from 'react';
import avatarPropTypes from '@components/avatarPropTypes';
import {withNetwork} from '@components/OnyxProvider';
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 withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import compose from '@libs/compose';
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 type {EmptyObject} from '@src/types/utils/EmptyObject';
import AttachmentCommentFragment from './comment/AttachmentCommentFragment';
import TextCommentFragment from './comment/TextCommentFragment';
import reportActionFragmentPropTypes from './reportActionFragmentPropTypes';

const propTypes = {
type ReportActionItemFragmentProps = {
/** Users accountID */
accountID: PropTypes.number.isRequired,
accountID: number;

/** The message fragment needing to be displayed */
fragment: reportActionFragmentPropTypes.isRequired,
fragment: Message;
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved

/** If this fragment is attachment than has info? */
attachmentInfo: PropTypes.shape({
/** The file name of attachment */
name: PropTypes.string,

/** The file size of the attachment in bytes. */
size: PropTypes.number,

/** The MIME type of the attachment. */
type: PropTypes.string,

/** Attachment's URL represents the specified File object or Blob object */
source: PropTypes.string,
}),
attachmentInfo?: EmptyObject | File;

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

/** The reportAction's source */
source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']),
source: OriginalMessageSource;

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

// Additional styles to add after local styles
style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]),
/** 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: PropTypes.number,
delegateAccountID?: number;

/** icon */
actorIcon: avatarPropTypes,
actorIcon?: AvatarProps;

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

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

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

/** Used to format RTL display names in Old Dot system messages e.g. Arabic */
isFragmentContainingDisplayName: PropTypes.bool,

...windowDimensionsPropTypes,

/** localization props */
...withLocalizePropTypes,
};
isFragmentContainingDisplayName?: boolean;

const defaultProps = {
attachmentInfo: {
name: '',
size: 0,
type: '',
source: '',
},
iouMessage: '',
isSingleLine: false,
source: '',
style: [],
delegateAccountID: 0,
actorIcon: {},
isThreadParentMessage: false,
isApprovedOrSubmittedReportAction: false,
isFragmentContainingDisplayName: false,
displayAsGroup: false,
/** The pending action for the report action */
pendingAction?: OnyxCommon.PendingAction;
};

function ReportActionItemFragment(props) {
function ReportActionItemFragment({
iouMessage = '',
isSingleLine = false,
source = '',
style = [],
delegateAccountID = 0,
actorIcon = {},
isThreadParentMessage = false,
isApprovedOrSubmittedReportAction = false,
isFragmentContainingDisplayName = false,
displayAsGroup = false,
...props
}: ReportActionItemFragmentProps) {
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
const styles = useThemeStyles();
const fragment = props.fragment;
const {fragment} = props;
const {isOffline} = useNetwork();
const {translate} = useLocalize();

switch (fragment.type) {
case 'COMMENT': {
Expand All @@ -105,48 +87,48 @@ function ReportActionItemFragment(props) {
// 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 ((!props.network.isOffline && props.isThreadParentMessage && isPendingDelete) || props.fragment.isDeletedParentAction) {
return <RenderHTML html={`<comment>${props.translate('parentReportAction.deletedMessage')}</comment>`} />;
if ((!isOffline && isThreadParentMessage && isPendingDelete) || props.fragment.isDeletedParentAction) {
return <RenderHTML html={`<comment>${translate('parentReportAction.deletedMessage')}</comment>`} />;
}

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

return (
<TextCommentFragment
source={props.source}
source={source}
fragment={fragment}
styleAsDeleted={isPendingDelete && props.network.isOffline}
iouMessage={props.iouMessage}
displayAsGroup={props.displayAsGroup}
style={props.style}
styleAsDeleted={Boolean(isOffline && isPendingDelete)}
iouMessage={iouMessage}
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
displayAsGroup={displayAsGroup}
style={style}
/>
);
}
case 'TEXT': {
return props.isApprovedOrSubmittedReportAction ? (
return isApprovedOrSubmittedReportAction ? (
<Text
numberOfLines={props.isSingleLine ? 1 : undefined}
numberOfLines={isSingleLine ? 1 : undefined}
style={[styles.chatItemMessage, styles.colorMuted]}
>
{props.isFragmentContainingDisplayName ? convertToLTR(props.fragment.text) : props.fragment.text}
{isFragmentContainingDisplayName ? convertToLTR(props.fragment.text) : props.fragment.text}
</Text>
) : (
<UserDetailsTooltip
accountID={props.accountID}
delegateAccountID={props.delegateAccountID}
icon={props.actorIcon}
delegateAccountID={delegateAccountID}
icon={actorIcon}
>
<Text
numberOfLines={props.isSingleLine ? 1 : undefined}
style={[styles.chatItemMessageHeaderSender, props.isSingleLine ? styles.pre : styles.preWrap]}
numberOfLines={isSingleLine ? 1 : undefined}
style={[styles.chatItemMessageHeaderSender, isSingleLine ? styles.pre : styles.preWrap]}
>
{fragment.text}
</Text>
Expand All @@ -172,8 +154,6 @@ function ReportActionItemFragment(props) {
}
}

ReportActionItemFragment.propTypes = propTypes;
ReportActionItemFragment.defaultProps = defaultProps;
ReportActionItemFragment.displayName = 'ReportActionItemFragment';

export default compose(withWindowDimensions, withLocalize, withNetwork())(memo(ReportActionItemFragment));
export default memo(ReportActionItemFragment);
6 changes: 3 additions & 3 deletions src/pages/home/report/ReportActionItemMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
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 Down Expand Up @@ -43,7 +43,7 @@
<TextCommentFragment
fragment={fragment}
displayAsGroup={displayAsGroup}
style={style}

Check failure on line 46 in src/pages/home/report/ReportActionItemMessage.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type 'StyleProp<ViewStyle>' is not assignable to type 'StyleProp<TextStyle>'.
source=""
styleAsDeleted={false}
/>
Expand Down Expand Up @@ -76,9 +76,9 @@
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}

Check failure on line 81 in src/pages/home/report/ReportActionItemMessage.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type 'StyleProp<ViewStyle>' is not assignable to type 'StyleProp<TextStyle>'.
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
displayAsGroup={displayAsGroup}
isApprovedOrSubmittedReportAction={isApprovedOrSubmittedReportAction}
// Since system messages from Old Dot begin with the person who performed the action,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/report/ReportActionItemSingle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@
<ReportActionItemFragment
// eslint-disable-next-line react/no-array-index-key
key={`person-${action.reportActionID}-${index}`}
accountID={actorAccountID}
accountID={actorAccountID ?? 0}
fragment={fragment}

Check failure on line 242 in src/pages/home/report/ReportActionItemSingle.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type 'Person' is not assignable to type 'Message'.
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 is inferred as Person type

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's safe to change Person type to:

type Person = {
    type: string;
    style?: string;
    text: string;
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got a bunch of type error when type is chnaged, used this as workaround:

fragment={{...fragment, type: fragment.type ?? '', text: fragment.text ?? ''}}

delegateAccountID={action.delegateAccountID}

Check failure on line 243 in src/pages/home/report/ReportActionItemSingle.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type 'string | undefined' is not assignable to type 'number | undefined'.
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
isSingleLine
actorIcon={icon}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import reportActionSourcePropType from '@pages/home/report/reportActionSourcePropType';
import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage';
import RenderCommentHTML from './RenderCommentHTML';

const propTypes = {
/** The reportAction's source */
source: reportActionSourcePropType.isRequired,

/** The message fragment's HTML */
html: PropTypes.string.isRequired,

/** Should extra margin be added on top of the component? */
addExtraMargin: PropTypes.bool.isRequired,
type AttachmentCommentFragmentProps = {
source: OriginalMessageSource;
html: string;
addExtraMargin: boolean;
};

function AttachmentCommentFragment({addExtraMargin, html, source}) {
function AttachmentCommentFragment({addExtraMargin, html, source}: AttachmentCommentFragmentProps) {
const styles = useThemeStyles();
return (
<View style={addExtraMargin ? styles.mt2 : {}}>
Expand All @@ -28,7 +22,6 @@ function AttachmentCommentFragment({addExtraMargin, html, source}) {
);
}

AttachmentCommentFragment.propTypes = propTypes;
AttachmentCommentFragment.displayName = 'AttachmentCommentFragment';

export default AttachmentCommentFragment;
23 changes: 0 additions & 23 deletions src/pages/home/report/comment/RenderCommentHTML.js

This file was deleted.

18 changes: 18 additions & 0 deletions src/pages/home/report/comment/RenderCommentHTML.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import RenderHTML from '@components/RenderHTML';
import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage';

type RenderCommentHTMLProps = {
source: OriginalMessageSource;
html: string;
};

function RenderCommentHTML({html, source}: RenderCommentHTMLProps) {
const commentHtml = source === 'email' ? `<email-comment>${html}</email-comment>` : `<comment>${html}</comment>`;

return <RenderHTML html={commentHtml} />;
}

RenderCommentHTML.displayName = 'RenderCommentHTML';

export default RenderCommentHTML;
Loading
Loading