From 15338b9c07c37a06b49247df79c1dc405e0beee8 Mon Sep 17 00:00:00 2001 From: Fitsum Abebe Date: Mon, 15 Jan 2024 18:40:01 +0300 Subject: [PATCH] Ts migration ReportActionItemImage and ReportActionItemImages --- src/components/ImageWithSizeCalculation.tsx | 2 +- ...ItemImage.js => ReportActionItemImage.tsx} | 70 +++++++++---------- ...emImages.js => ReportActionItemImages.tsx} | 40 +++++------ src/components/ThumbnailImage.tsx | 2 +- src/libs/tryResolveUrlFromApiRoot.ts | 1 + 5 files changed, 51 insertions(+), 64 deletions(-) rename src/components/ReportActionItem/{ReportActionItemImage.js => ReportActionItemImage.tsx} (58%) rename src/components/ReportActionItem/{ReportActionItemImages.js => ReportActionItemImages.tsx} (83%) diff --git a/src/components/ImageWithSizeCalculation.tsx b/src/components/ImageWithSizeCalculation.tsx index b13d863d97e1..c65faef53748 100644 --- a/src/components/ImageWithSizeCalculation.tsx +++ b/src/components/ImageWithSizeCalculation.tsx @@ -19,7 +19,7 @@ type OnLoadNativeEvent = { type ImageWithSizeCalculationProps = { /** Url for image to display */ - url: string; + url: string | number; /** Any additional styles to apply */ style?: StyleProp; diff --git a/src/components/ReportActionItem/ReportActionItemImage.js b/src/components/ReportActionItem/ReportActionItemImage.tsx similarity index 58% rename from src/components/ReportActionItem/ReportActionItemImage.js rename to src/components/ReportActionItem/ReportActionItemImage.tsx index 1495dcbd9111..e56f32327d05 100644 --- a/src/components/ReportActionItem/ReportActionItemImage.js +++ b/src/components/ReportActionItem/ReportActionItemImage.tsx @@ -1,47 +1,38 @@ import Str from 'expensify-common/lib/str'; -import PropTypes from 'prop-types'; import React from 'react'; +import type {ReactElement} from 'react'; import {View} from 'react-native'; -import _ from 'underscore'; import AttachmentModal from '@components/AttachmentModal'; import EReceiptThumbnail from '@components/EReceiptThumbnail'; import Image from '@components/Image'; import PressableWithoutFocus from '@components/Pressable/PressableWithoutFocus'; import {ShowContextMenuContext} from '@components/ShowContextMenuContext'; import ThumbnailImage from '@components/ThumbnailImage'; -import transactionPropTypes from '@components/transactionPropTypes'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as TransactionUtils from '@libs/TransactionUtils'; import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; import CONST from '@src/CONST'; +import type {Transaction} from '@src/types/onyx'; -const propTypes = { +type ReportActionItemImageProps = { /** thumbnail URI for the image */ - thumbnail: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + thumbnail: string | number | null; /** URI for the image or local numeric reference for the image */ - image: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + image: string | number; /** whether or not to enable the image preview modal */ - enablePreviewModal: PropTypes.bool, + enablePreviewModal?: boolean; /* The transaction associated with this image, if any. Passed for handling eReceipts. */ - transaction: transactionPropTypes, + transaction?: Transaction; /** whether thumbnail is refer the local file or not */ - isLocalFile: PropTypes.bool, + isLocalFile: boolean; /** whether the receipt can be replaced */ - canEditReceipt: PropTypes.bool, -}; - -const defaultProps = { - thumbnail: null, - transaction: {}, - enablePreviewModal: false, - isLocalFile: false, - canEditReceipt: false, + canEditReceipt?: boolean; }; /** @@ -50,14 +41,14 @@ const defaultProps = { * and optional preview modal as well. */ -function ReportActionItemImage({thumbnail, image, enablePreviewModal, transaction, canEditReceipt, isLocalFile}) { +function ReportActionItemImage({thumbnail = null, image, enablePreviewModal = false, transaction, canEditReceipt = false, isLocalFile = false}: ReportActionItemImageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const imageSource = tryResolveUrlFromApiRoot(image || ''); - const thumbnailSource = tryResolveUrlFromApiRoot(thumbnail || ''); - const isEReceipt = !_.isEmpty(transaction) && TransactionUtils.hasEReceipt(transaction); + const imageSource = tryResolveUrlFromApiRoot(image ?? ''); + const thumbnailSource = tryResolveUrlFromApiRoot(thumbnail ?? ''); + const isEReceipt = transaction && TransactionUtils.hasEReceipt(transaction); - let receiptImageComponent; + let receiptImageComponent: ReactElement; if (isEReceipt) { receiptImageComponent = ( @@ -65,7 +56,7 @@ function ReportActionItemImage({thumbnail, image, enablePreviewModal, transactio ); - } else if (thumbnail && !isLocalFile && !Str.isPDF(imageSource)) { + } else if (thumbnail && !isLocalFile && !Str.isPDF(imageSource as string)) { receiptImageComponent = ( ); @@ -87,6 +78,7 @@ function ReportActionItemImage({thumbnail, image, enablePreviewModal, transactio return ( {({report}) => ( + // @ts-expect-error TODO: Remove this once AttachmentModal (https://github.com/Expensify/App/issues/25130) is migrated to TypeScript. - {({show}) => ( - - {receiptImageComponent} - - )} + { + // @ts-expect-error TODO: Remove this once AttachmentModal (https://github.com/Expensify/App/issues/25130) is migrated to TypeScript. + ({show}) => ( + + {receiptImageComponent} + + ) + } )} @@ -115,8 +111,6 @@ function ReportActionItemImage({thumbnail, image, enablePreviewModal, transactio return receiptImageComponent; } -ReportActionItemImage.propTypes = propTypes; -ReportActionItemImage.defaultProps = defaultProps; ReportActionItemImage.displayName = 'ReportActionItemImage'; export default ReportActionItemImage; diff --git a/src/components/ReportActionItem/ReportActionItemImages.js b/src/components/ReportActionItem/ReportActionItemImages.tsx similarity index 83% rename from src/components/ReportActionItem/ReportActionItemImages.js rename to src/components/ReportActionItem/ReportActionItemImages.tsx index 96f919aea750..0ccce9521e27 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.js +++ b/src/components/ReportActionItem/ReportActionItemImages.tsx @@ -1,44 +1,38 @@ -import PropTypes from 'prop-types'; +/* eslint-disable react/no-array-index-key */ import React from 'react'; import {View} from 'react-native'; import {Polygon, Svg} from 'react-native-svg'; -import _ from 'underscore'; import Text from '@components/Text'; -import transactionPropTypes from '@components/transactionPropTypes'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import variables from '@styles/variables'; +import type {Transaction} from '@src/types/onyx'; import ReportActionItemImage from './ReportActionItemImage'; -const propTypes = { +type Image = { + thumbnail: string | number; + image: string | number; + transaction: Transaction; + isLocalFile: boolean; +}; + +type ReportActionItemImagesProps = { /** array of image and thumbnail URIs */ - images: PropTypes.arrayOf( - PropTypes.shape({ - thumbnail: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - image: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - transaction: transactionPropTypes, - }), - ).isRequired, + images: Image[]; // We're not providing default values for size and total and disabling the ESLint rule // because we want them to default to the length of images, but we can't set default props // to be computed from another prop /** max number of images to show in the row if different than images length */ - // eslint-disable-next-line react/require-default-props - size: PropTypes.number, + size: number; /** total number of images if different than images length */ - // eslint-disable-next-line react/require-default-props - total: PropTypes.number, + total: number; /** if the corresponding report action item is hovered */ - isHovered: PropTypes.bool, -}; - -const defaultProps = { - isHovered: false, + isHovered: boolean; }; /** @@ -50,7 +44,7 @@ const defaultProps = { * additional number when subtracted from size. */ -function ReportActionItemImages({images, size, total, isHovered}) { +function ReportActionItemImages({images, size, total, isHovered = false}: ReportActionItemImagesProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -77,7 +71,7 @@ function ReportActionItemImages({images, size, total, isHovered}) { return ( - {_.map(shownImages, ({thumbnail, image, transaction, isLocalFile}, index) => { + {shownImages.map(({thumbnail, image, transaction, isLocalFile}, index) => { const isLastImage = index === numberOfShownImages - 1; // Show a border to separate multiple images. Shown to the right for each except the last. @@ -117,8 +111,6 @@ function ReportActionItemImages({images, size, total, isHovered}) { ); } -ReportActionItemImages.propTypes = propTypes; -ReportActionItemImages.defaultProps = defaultProps; ReportActionItemImages.displayName = 'ReportActionItemImages'; export default ReportActionItemImages; diff --git a/src/components/ThumbnailImage.tsx b/src/components/ThumbnailImage.tsx index 3c903ee9e78f..a1778e2feaee 100644 --- a/src/components/ThumbnailImage.tsx +++ b/src/components/ThumbnailImage.tsx @@ -10,7 +10,7 @@ import ImageWithSizeCalculation from './ImageWithSizeCalculation'; type ThumbnailImageProps = { /** Source URL for the preview image */ - previewSourceURL: string; + previewSourceURL: string | number; /** Any additional styles to apply */ style?: StyleProp; diff --git a/src/libs/tryResolveUrlFromApiRoot.ts b/src/libs/tryResolveUrlFromApiRoot.ts index 7a80228e0a34..adf717d500be 100644 --- a/src/libs/tryResolveUrlFromApiRoot.ts +++ b/src/libs/tryResolveUrlFromApiRoot.ts @@ -19,6 +19,7 @@ const ORIGIN_PATTERN = new RegExp(`^(${ORIGINS_TO_REPLACE.join('|')})`); */ function tryResolveUrlFromApiRoot(url: string): string; function tryResolveUrlFromApiRoot(url: number): number; +function tryResolveUrlFromApiRoot(url: string | number): string | number; function tryResolveUrlFromApiRoot(url: string | number): string | number { // in native, when we import an image asset, it will have a number representation which can be used in `source` of Image // in this case we can skip the url resolving