From 5ef38a6180e3508a4174c6d90e6febe02f4090a9 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 17 Jan 2024 15:59:21 +0000 Subject: [PATCH 01/22] [TS migration] Migrate SearchPage --- src/pages/{SearchPage.js => SearchPage.tsx} | 59 +++++++++++---------- 1 file changed, 30 insertions(+), 29 deletions(-) rename src/pages/{SearchPage.js => SearchPage.tsx} (78%) diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.tsx similarity index 78% rename from src/pages/SearchPage.js rename to src/pages/SearchPage.tsx index 061f43e73de8..48a1cec8198d 100755 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.tsx @@ -1,7 +1,7 @@ -import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -12,42 +12,39 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Performance from '@libs/Performance'; import * as ReportUtils from '@libs/ReportUtils'; +import type {OptionData} from '@libs/ReportUtils'; import * as Report from '@userActions/Report'; import Timing from '@userActions/Timing'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import personalDetailsPropType from './personalDetailsPropType'; -import reportPropTypes from './reportPropTypes'; - -const propTypes = { - /* Onyx Props */ +import type * as OnyxTypes from '@src/types/onyx'; +type SearchPageProps = { /** Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string), + betas: OnyxEntry; /** All of the personal details for everyone */ - personalDetails: PropTypes.objectOf(personalDetailsPropType), + personalDetails: OnyxEntry; - /** All reports shared with the user */ - reports: PropTypes.objectOf(reportPropTypes), + /** The report currently being looked at */ + reports: OnyxEntry; /** Whether we are searching for reports in the server */ - isSearchingForReports: PropTypes.bool, + isSearchingForReports: OnyxEntry; }; -const defaultProps = { - betas: [], - personalDetails: {}, - reports: {}, - isSearchingForReports: false, +type SearchOptions = { + recentReports: OnyxTypes.Report[]; + personalDetails: OnyxTypes.PersonalDetails[]; + userToInvite: []; }; -function SearchPage({betas, personalDetails, reports, isSearchingForReports}) { +function SearchPage({betas, personalDetails, reports, isSearchingForReports}: SearchPageProps) { const [searchValue, setSearchValue] = useState(''); - const [searchOptions, setSearchOptions] = useState({ - recentReports: {}, - personalDetails: {}, - userToInvite: {}, + const [searchOptions, setSearchOptions] = useState({ + recentReports: [], + personalDetails: [], + userToInvite: [], }); const {isOffline} = useNetwork(); @@ -57,9 +54,13 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}) { const updateOptions = useCallback(() => { const { + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. recentReports: localRecentReports, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. personalDetails: localPersonalDetails, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. userToInvite: localUserToInvite, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. } = OptionsListUtils.getSearchOptions(reports, personalDetails, searchValue.trim(), betas); setSearchOptions({ @@ -91,8 +92,6 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}) { /** * Returns the sections needed for the OptionsSelector - * - * @returns {Array} */ const getSections = () => { const sections = []; @@ -139,20 +138,22 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}) { /** * Reset the search value and redirect to the selected report - * - * @param {Object} option */ - const selectReport = (option) => { + const selectReport = (option: OptionData) => { if (!option) { return; } if (option.reportID) { Navigation.dismissModal(option.reportID); } else { + if (!option.login) { + return; + } Report.navigateToAndOpenReport([option.login]); } }; + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); const headerMessage = OptionsListUtils.getHeaderMessage( searchOptions.recentReports.length + searchOptions.personalDetails.length !== 0, @@ -171,6 +172,7 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}) { ({ reports: { key: ONYXKEYS.COLLECTION.REPORT, }, From a1bf42ac4d24f1f279ec40d65f86746d7b3c1c90 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 17 Jan 2024 16:34:36 +0000 Subject: [PATCH 02/22] [TS migration] Added missing key on searchPage OnyxValues --- src/ONYXKEYS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 98e3856f4544..1d040503c7f9 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -432,6 +432,7 @@ type OnyxValues = { [ONYXKEYS.MAX_CANVAS_AREA]: number; [ONYXKEYS.MAX_CANVAS_HEIGHT]: number; [ONYXKEYS.MAX_CANVAS_WIDTH]: number; + [ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: boolean; // Collections [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download; From 0311d75820259912941e58ba019105c20ae7a1ba Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Thu, 18 Jan 2024 09:21:37 +0000 Subject: [PATCH 03/22] [TS migration] SearchPage feedback --- src/pages/SearchPage.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 48a1cec8198d..205ca330bbf6 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -1,3 +1,4 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -9,6 +10,7 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; +import type {SearchNavigatorParamList} from '@libs/Navigation/types'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Performance from '@libs/Performance'; import * as ReportUtils from '@libs/ReportUtils'; @@ -17,9 +19,10 @@ import * as Report from '@userActions/Report'; import Timing from '@userActions/Timing'; 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 SearchPageProps = { +type SearchPageOnyxProps = { /** Beta features list */ betas: OnyxEntry; @@ -33,10 +36,12 @@ type SearchPageProps = { isSearchingForReports: OnyxEntry; }; +type SearchPageProps = SearchPageOnyxProps & StackScreenProps; + type SearchOptions = { - recentReports: OnyxTypes.Report[]; - personalDetails: OnyxTypes.PersonalDetails[]; - userToInvite: []; + recentReports: ReportUtils.OptionData[]; + personalDetails: ReportUtils.OptionData[]; + userToInvite: ReportUtils.OptionData | null; }; function SearchPage({betas, personalDetails, reports, isSearchingForReports}: SearchPageProps) { @@ -44,7 +49,7 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se const [searchOptions, setSearchOptions] = useState({ recentReports: [], personalDetails: [], - userToInvite: [], + userToInvite: null, }); const {isOffline} = useNetwork(); @@ -146,10 +151,7 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se if (option.reportID) { Navigation.dismissModal(option.reportID); } else { - if (!option.login) { - return; - } - Report.navigateToAndOpenReport([option.login]); + Report.navigateToAndOpenReport(option.login ? [option.login] : []); } }; @@ -198,7 +200,7 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se SearchPage.displayName = 'SearchPage'; -export default withOnyx({ +export default withOnyx({ reports: { key: ONYXKEYS.COLLECTION.REPORT, }, From 043d7a648c889d4ce4fe3471a33edf10dd33171b Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Thu, 18 Jan 2024 14:12:53 +0000 Subject: [PATCH 04/22] [TS migration] SearchPage code improvements --- src/pages/SearchPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 205ca330bbf6..c2b51d835349 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -2,7 +2,7 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -29,8 +29,8 @@ type SearchPageOnyxProps = { /** All of the personal details for everyone */ personalDetails: OnyxEntry; - /** The report currently being looked at */ - reports: OnyxEntry; + /** All reports shared with the user */ + reports: OnyxCollection; /** Whether we are searching for reports in the server */ isSearchingForReports: OnyxEntry; From 4b868f69788fd61b0f95bb161f2aa638ad6d2575 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 22 Jan 2024 17:11:27 +0000 Subject: [PATCH 05/22] [TS migration] Partially addressed comments --- src/pages/SearchPage.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 4ac8188847e8..e1a588d6d505 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -44,6 +44,14 @@ type SearchOptions = { userToInvite: ReportUtils.OptionData | null; }; +type SearchPageSectionItem = { + data: ReportUtils.OptionData[]; + shouldShow: boolean; + indexOffset: number; +}; + +type SearchPageSectionList = SearchPageSectionItem[] + function SearchPage({betas, personalDetails, reports, isSearchingForReports}: SearchPageProps) { const [searchValue, setSearchValue] = useState(''); const [searchOptions, setSearchOptions] = useState({ @@ -98,8 +106,8 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se /** * Returns the sections needed for the OptionsSelector */ - const getSections = () => { - const sections = []; + const getSections: SearchPageSectionList = () => { + const sections: SearchPageSectionList = []; let indexOffset = 0; if (searchOptions.recentReports.length > 0) { From 0b6deabb8db7b28466cd33ce10c10014dffc8b65 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 22 Jan 2024 17:14:22 +0000 Subject: [PATCH 06/22] [TS migration] SearchPage minor ts error fix --- src/pages/SearchPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index e1a588d6d505..b574448ddc02 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -106,7 +106,7 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se /** * Returns the sections needed for the OptionsSelector */ - const getSections: SearchPageSectionList = () => { + const getSections = (): SearchPageSectionList => { const sections: SearchPageSectionList = []; let indexOffset = 0; From 4885b59ae6d989764462ed066f84a50f2fcd9a84 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 22 Jan 2024 17:18:47 +0000 Subject: [PATCH 07/22] [TS migration] SearchPage Lint --- src/pages/SearchPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index b574448ddc02..1b2c011bcc72 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -50,7 +50,7 @@ type SearchPageSectionItem = { indexOffset: number; }; -type SearchPageSectionList = SearchPageSectionItem[] +type SearchPageSectionList = SearchPageSectionItem[]; function SearchPage({betas, personalDetails, reports, isSearchingForReports}: SearchPageProps) { const [searchValue, setSearchValue] = useState(''); From 000eb11437f27594b41370d1e20f58a27a68d55a Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 24 Jan 2024 10:32:41 +0000 Subject: [PATCH 08/22] [TS Migration] SearchPage route props improvement --- src/components/ScreenWrapper.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ScreenWrapper.tsx b/src/components/ScreenWrapper.tsx index 0653e2ff8577..831bb9bf6688 100644 --- a/src/components/ScreenWrapper.tsx +++ b/src/components/ScreenWrapper.tsx @@ -13,7 +13,7 @@ import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; -import type {RootStackParamList} from '@libs/Navigation/types'; +import type {RootStackParamList, SearchNavigatorParamList} from '@libs/Navigation/types'; import toggleTestToolsModal from '@userActions/TestTool'; import CONST from '@src/CONST'; import CustomDevMenu from './CustomDevMenu'; @@ -85,7 +85,7 @@ type ScreenWrapperProps = { * * This is required because transitionEnd event doesn't trigger in the testing environment. */ - navigation?: StackNavigationProp; + navigation?: StackNavigationProp | StackNavigationProp; }; function ScreenWrapper( From be14da6f26947ac50102d263a1fc30c2ca3df47c Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 29 Jan 2024 12:05:31 +0000 Subject: [PATCH 09/22] [TS migration][SearchPage] Code improvements after merged main --- src/libs/OptionsListUtils.ts | 2 +- src/pages/SearchPage.tsx | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index ef2888eebfb2..57085899866d 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1669,7 +1669,7 @@ function getOptions( /** * Build the options for the Search view */ -function getSearchOptions(reports: Record, personalDetails: OnyxEntry, searchValue = '', betas: Beta[] = []): GetOptions { +function getSearchOptions(reports: OnyxCollection, personalDetails: OnyxEntry, searchValue = '', betas: Beta[] = []): GetOptions { Timing.start(CONST.TIMING.LOAD_SEARCH_OPTIONS); Performance.markStart(CONST.TIMING.LOAD_SEARCH_OPTIONS); const options = getOptions(reports, personalDetails, { diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 1b2c011bcc72..6b804936cf64 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -67,14 +67,10 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se const updateOptions = useCallback(() => { const { - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. recentReports: localRecentReports, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. personalDetails: localPersonalDetails, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. userToInvite: localUserToInvite, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. - } = OptionsListUtils.getSearchOptions(reports, personalDetails, searchValue.trim(), betas); + } = OptionsListUtils.getSearchOptions(reports, personalDetails, searchValue.trim(), betas ?? undefined); setSearchOptions({ recentReports: localRecentReports, @@ -163,7 +159,6 @@ function SearchPage({betas, personalDetails, reports, isSearchingForReports}: Se } }; - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails); const headerMessage = OptionsListUtils.getHeaderMessage( searchOptions.recentReports.length + searchOptions.personalDetails.length !== 0, From db8c05fb6096c4c6a3116f4f200e80eab616272a Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 30 Jan 2024 15:38:46 +0000 Subject: [PATCH 10/22] [TS migration] Searchpage navigation prop --- src/pages/SearchPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 6b804936cf64..d85bd0f684a2 100755 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -52,7 +52,7 @@ type SearchPageSectionItem = { type SearchPageSectionList = SearchPageSectionItem[]; -function SearchPage({betas, personalDetails, reports, isSearchingForReports}: SearchPageProps) { +function SearchPage({betas, personalDetails, reports, isSearchingForReports, navigation}: SearchPageProps) { const [searchValue, setSearchValue] = useState(''); const [searchOptions, setSearchOptions] = useState({ recentReports: [], From 5802e70752976d79cc5eb511fdf5788322dfd8ed Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Thu, 8 Feb 2024 14:33:22 +0000 Subject: [PATCH 11/22] [TS migration][SearchPage] Migrate SearchPage after refactor --- src/components/SelectionList/types.ts | 24 +++++--- src/pages/SearchPage/{index.js => index.tsx} | 59 ++++++++++---------- 2 files changed, 47 insertions(+), 36 deletions(-) rename src/pages/SearchPage/{index.js => index.tsx} (79%) diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 222c818dd66d..8dbc2b8aec0b 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -1,5 +1,7 @@ import type {ReactElement, ReactNode} from 'react'; import type {GestureResponderEvent, InputModeOptions, SectionListData, StyleProp, TextStyle, ViewStyle} from 'react-native'; +import type CONST from '@src/CONST'; +import type {Report} from '@src/types/onyx'; import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; @@ -34,25 +36,25 @@ type CommonListItemProps = { type User = { /** Text to display */ - text: string; + text?: string; /** Alternate text to display */ - alternateText?: string; + alternateText?: string | null; /** Key used internally by React */ - keyForList: string; + keyForList?: string | null; /** Whether this option is selected */ isSelected?: boolean; /** Whether this option is disabled for selection */ - isDisabled?: boolean; + isDisabled?: boolean | null; /** User accountID */ - accountID?: number; + accountID?: number | null; /** User login */ - login?: string; + login?: string | null; /** Element to show on the right side of the item */ rightElement?: ReactElement; @@ -73,7 +75,7 @@ type User = { /** Represents the index of the option within the section it came from */ index?: number; -}; +} & Report; type UserListItemProps = CommonListItemProps & { /** The section list item */ @@ -133,7 +135,7 @@ type Section = { type BaseSelectionListProps = Partial & { /** Sections for the section list */ - sections: Array>>; + sections: Array>> | typeof CONST.EMPTY_ARRAY; /** Whether this is a multi-select list */ canSelectMultiple?: boolean; @@ -233,6 +235,12 @@ type BaseSelectionListProps = Partial void; + + /** Whether to auto focus the Search Input */ + autoFocus: boolean; }; type ItemLayout = { diff --git a/src/pages/SearchPage/index.js b/src/pages/SearchPage/index.tsx similarity index 79% rename from src/pages/SearchPage/index.js rename to src/pages/SearchPage/index.tsx index 8a06d54a1f45..672c94faabda 100644 --- a/src/pages/SearchPage/index.js +++ b/src/pages/SearchPage/index.tsx @@ -1,6 +1,7 @@ -import PropTypes from 'prop-types'; +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {usePersonalDetails} from '@components/OnyxProvider'; @@ -11,35 +12,39 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; +import type {SearchNavigatorParamList} from '@libs/Navigation/types'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Performance from '@libs/Performance'; import * as ReportUtils from '@libs/ReportUtils'; -import reportPropTypes from '@pages/reportPropTypes'; import * as Report from '@userActions/Report'; import Timing from '@userActions/Timing'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; +import type * as OnyxTypes from '@src/types/onyx'; import SearchPageFooter from './SearchPageFooter'; -const propTypes = { - /* Onyx Props */ - +type SearchPageOnyxProps = { /** Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string), + betas: OnyxEntry; /** All reports shared with the user */ - reports: PropTypes.objectOf(reportPropTypes), + reports: OnyxCollection; /** Whether or not we are searching for reports on the server */ - isSearchingForReports: PropTypes.bool, + isSearchingForReports: OnyxEntry; }; -const defaultProps = { - betas: [], - reports: {}, - isSearchingForReports: false, +type SearchPageProps = SearchPageOnyxProps & StackScreenProps; + +type SearchPageSectionItem = { + data: ReportUtils.OptionData[]; + shouldShow: boolean; + indexOffset: number; }; +type SearchPageSectionList = SearchPageSectionItem[]; + const setPerformanceTimersEnd = () => { Timing.end(CONST.TIMING.SEARCH_RENDER); Performance.markEnd(CONST.TIMING.SEARCH_RENDER); @@ -47,7 +52,7 @@ const setPerformanceTimersEnd = () => { const SearchPageFooterInstance = ; -function SearchPage({betas, reports, isSearchingForReports}) { +function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { const [isScreenTransitionEnd, setIsScreenTransitionEnd] = useState(false); const {translate} = useLocalize(); const {isOffline} = useNetwork(); @@ -75,28 +80,28 @@ function SearchPage({betas, reports, isSearchingForReports}) { } = useMemo(() => { if (!isScreenTransitionEnd) { return { - recentReports: {}, - personalDetails: {}, - userToInvite: {}, + recentReports: [], + personalDetails: [], + userToInvite: null, headerMessage: '', }; } - const options = OptionsListUtils.getSearchOptions(reports, personalDetails, debouncedSearchValue.trim(), betas); + const options = OptionsListUtils.getSearchOptions(reports, personalDetails, debouncedSearchValue.trim(), betas ?? []); const header = OptionsListUtils.getHeaderMessage(options.recentReports.length + options.personalDetails.length !== 0, Boolean(options.userToInvite), debouncedSearchValue); return {...options, headerMessage: header}; }, [debouncedSearchValue, reports, personalDetails, betas, isScreenTransitionEnd]); - const sections = useMemo(() => { - const newSections = []; + const sections = useMemo((): SearchPageSectionList => { + const newSections: SearchPageSectionList = []; let indexOffset = 0; - if (recentReports.length > 0) { + if (recentReports?.length > 0) { newSections.push({ data: recentReports, shouldShow: true, indexOffset, }); - indexOffset += recentReports.length; + indexOffset += recentReports?.length; } if (localPersonalDetails.length > 0) { @@ -119,7 +124,7 @@ function SearchPage({betas, reports, isSearchingForReports}) { return newSections; }, [localPersonalDetails, recentReports, userToInvite]); - const selectReport = (option) => { + const selectReport = (option: ReportUtils.OptionData) => { if (!option) { return; } @@ -128,7 +133,7 @@ function SearchPage({betas, reports, isSearchingForReports}) { setSearchValue(''); Navigation.dismissModal(option.reportID); } else { - Report.navigateToAndOpenReport([option.login]); + Report.navigateToAndOpenReport(option.login ? [option.login] : []); } }; @@ -148,7 +153,7 @@ function SearchPage({betas, reports, isSearchingForReports}) { <> - sections={didScreenTransitionEnd && isOptionsDataReady ? sections : CONST.EMPTY_ARRAY} textInputValue={searchValue} textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} @@ -160,7 +165,7 @@ function SearchPage({betas, reports, isSearchingForReports}) { onSelectRow={selectReport} showLoadingPlaceholder={!didScreenTransitionEnd || !isOptionsDataReady} footerContent={SearchPageFooterInstance} - isLoadingNewOptions={isSearchingForReports} + isLoadingNewOptions={isSearchingForReports ?? undefined} /> @@ -169,11 +174,9 @@ function SearchPage({betas, reports, isSearchingForReports}) { ); } -SearchPage.propTypes = propTypes; -SearchPage.defaultProps = defaultProps; SearchPage.displayName = 'SearchPage'; -export default withOnyx({ +export default withOnyx({ reports: { key: ONYXKEYS.COLLECTION.REPORT, }, From 15ba3107baf220b4a65d8d95ac6ad4602625dc9e Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Thu, 8 Feb 2024 14:47:41 +0000 Subject: [PATCH 12/22] [TS migration][SearchPage] TS fix --- src/components/SelectionList/BaseSelectionList.tsx | 2 +- src/components/SelectionList/UserListItem.tsx | 2 +- src/components/SelectionList/types.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 83ce2145fcdb..b9a32c0310b9 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -458,7 +458,7 @@ function BaseSelectionList( getItemLayout={getItemLayout} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} - keyExtractor={(item) => item.keyForList} + keyExtractor={(item) => item.keyForList ?? ''} extraData={focusedIndex} indicatorStyle="white" keyboardShouldPersistTaps="always" diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index fede09c1b435..03b0e708dace 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -19,7 +19,7 @@ function UserListItem({item, textStyles, alternateTextStyles, showTooltip, style {!!item.alternateText && ( diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 8dbc2b8aec0b..1c62cbf637b9 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -16,7 +16,7 @@ type CommonListItemProps = { alternateTextStyles?: StyleProp; /** Whether this item is disabled */ - isDisabled?: boolean; + isDisabled?: boolean | null; /** Whether this item should show Tooltip */ showTooltip: boolean; @@ -116,7 +116,7 @@ type RadioListItemProps = CommonListItemProps & { type BaseListItemProps = CommonListItemProps & { item: TItem; shouldPreventDefaultFocusOnSelectRow?: boolean; - keyForList?: string; + keyForList?: string | null; }; type Section = { @@ -237,10 +237,10 @@ type BaseSelectionListProps = Partial void; + onLayout?: () => void; /** Whether to auto focus the Search Input */ - autoFocus: boolean; + autoFocus?: boolean; }; type ItemLayout = { From 1532321d66bf51d11eb9e8abede72062a1076497 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Thu, 8 Feb 2024 14:59:31 +0000 Subject: [PATCH 13/22] [TS migration][SearchPage] Typescript adjustements --- src/components/SelectionList/BaseListItem.tsx | 6 +++--- src/components/SelectionList/RadioListItem.tsx | 2 +- src/components/SelectionList/types.ts | 14 ++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 71845931ba52..37b967fc3e18 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -55,13 +55,13 @@ function BaseListItem({ onSelectRow(item)} disabled={isDisabled} - accessibilityLabel={item.text} + accessibilityLabel={item.text ?? ''} role={CONST.ROLE.BUTTON} hoverDimmingValue={1} hoverStyle={styles.hoveredComponentBG} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined} - nativeID={keyForList} + nativeID={keyForList ?? ''} > ({ )} {rightHandSideComponentRender()} - {isUserItem && item.invitedSecondaryLogin && ( + {isUserItem && 'invitedSecondaryLogin' in item && item.invitedSecondaryLogin && ( {translate('workspace.people.invitedBySecondaryLogin', {secondaryLogin: item.invitedSecondaryLogin})} diff --git a/src/components/SelectionList/RadioListItem.tsx b/src/components/SelectionList/RadioListItem.tsx index ca0ae859c3ad..66b30fe95869 100644 --- a/src/components/SelectionList/RadioListItem.tsx +++ b/src/components/SelectionList/RadioListItem.tsx @@ -11,7 +11,7 @@ function RadioListItem({item, showTooltip, textStyles, alternateTextStyles}: Rad diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 1c62cbf637b9..5331ddb7304e 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -1,7 +1,6 @@ import type {ReactElement, ReactNode} from 'react'; import type {GestureResponderEvent, InputModeOptions, SectionListData, StyleProp, TextStyle, ViewStyle} from 'react-native'; import type CONST from '@src/CONST'; -import type {Report} from '@src/types/onyx'; import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; @@ -75,7 +74,10 @@ type User = { /** Represents the index of the option within the section it came from */ index?: number; -} & Report; + + /** ID of the report */ + reportID?: string; +}; type UserListItemProps = CommonListItemProps & { /** The section list item */ @@ -87,19 +89,19 @@ type UserListItemProps = CommonListItemProps & { type RadioItem = { /** Text to display */ - text: string; + text?: string; /** Alternate text to display */ - alternateText?: string; + alternateText?: string | null; /** Key used internally by React */ - keyForList: string; + keyForList?: string | null; /** Whether this option is selected */ isSelected?: boolean; /** Whether this option is disabled for selection */ - isDisabled?: boolean; + isDisabled?: boolean | null; /** Represents the index of the section it came from */ sectionIndex?: number; From efa4b990793992e273ed80048f30158f3994cf19 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 20 Feb 2024 09:49:56 +0000 Subject: [PATCH 14/22] [TS migration][SearchPage] Updated types based on main --- src/components/SelectionList/BaseListItem.tsx | 4 ++-- .../SelectionList/BaseSelectionList.tsx | 2 +- src/components/SelectionList/RadioListItem.tsx | 2 +- src/components/SelectionList/UserListItem.tsx | 2 +- src/components/SelectionList/types.ts | 16 ++++++++-------- src/pages/SearchPage/index.tsx | 15 ++++++++------- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index eecf9ca920bb..9bfeacbc0ac2 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -55,13 +55,13 @@ function BaseListItem({ onSelectRow(item)} disabled={isDisabled} - accessibilityLabel={item.text ?? ''} + accessibilityLabel={item.text} role={CONST.ROLE.BUTTON} hoverDimmingValue={1} hoverStyle={styles.hoveredComponentBG} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined} - nativeID={keyForList ?? ''} + nativeID={keyForList} > {({hovered}) => ( <> diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 7d7ff16bed92..850874b7abc0 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -457,7 +457,7 @@ function BaseSelectionList( getItemLayout={getItemLayout} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} - keyExtractor={(item) => item.keyForList ?? ''} + keyExtractor={(item) => item.keyForList} extraData={focusedIndex} indicatorStyle="white" keyboardShouldPersistTaps="always" diff --git a/src/components/SelectionList/RadioListItem.tsx b/src/components/SelectionList/RadioListItem.tsx index eaa8db2a0cf2..c069eaf7d8fd 100644 --- a/src/components/SelectionList/RadioListItem.tsx +++ b/src/components/SelectionList/RadioListItem.tsx @@ -11,7 +11,7 @@ function RadioListItem({item, showTooltip, textStyles, alternateTextStyles}: Lis diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index 31041f71f73b..60e97d887b4d 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -44,7 +44,7 @@ function UserListItem({item, textStyles, alternateTextStyles, showTooltip, style {!!item.alternateText && ( diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 49e6522c8cb8..8b638e29b182 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -15,7 +15,7 @@ type CommonListItemProps = { alternateTextStyles?: StyleProp; /** Whether this item is disabled */ - isDisabled?: boolean | null; + isDisabled?: boolean; /** Whether this item should show Tooltip */ showTooltip: boolean; @@ -35,25 +35,25 @@ type CommonListItemProps = { type ListItem = { /** Text to display */ - text?: string; + text: string; /** Alternate text to display */ - alternateText?: string | null; + alternateText?: string; /** Key used internally by React */ - keyForList?: string | null; + keyForList: string; /** Whether this option is selected */ isSelected?: boolean; /** Whether this option is disabled for selection */ - isDisabled?: boolean | null; + isDisabled?: boolean; /** User accountID */ accountID?: number | null; /** User login */ - login?: string | null; + login?: string; /** Element to show on the right side of the item */ rightElement?: ReactNode; @@ -77,7 +77,7 @@ type ListItem = { /** ID of the report */ reportID?: string; - + /** Whether this option should show subscript */ shouldShowSubscript?: boolean; }; @@ -96,7 +96,7 @@ type ListItemProps = CommonListItemProps & { type BaseListItemProps = CommonListItemProps & { item: TItem; shouldPreventDefaultFocusOnSelectRow?: boolean; - keyForList?: string | null; + keyForList: string; }; type Section = { diff --git a/src/pages/SearchPage/index.tsx b/src/pages/SearchPage/index.tsx index 948c97058653..6c841f506d15 100644 --- a/src/pages/SearchPage/index.tsx +++ b/src/pages/SearchPage/index.tsx @@ -7,6 +7,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {usePersonalDetails} from '@components/OnyxProvider'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; +import type {ListItem} from '@components/SelectionList/types'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -38,7 +39,7 @@ type SearchPageOnyxProps = { type SearchPageProps = SearchPageOnyxProps & StackScreenProps; type SearchPageSectionItem = { - data: ReportUtils.OptionData[]; + data: ListItem[]; shouldShow: boolean; indexOffset: number; }; @@ -97,7 +98,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (recentReports?.length > 0) { newSections.push({ - data: recentReports, + data: recentReports as ListItem[], shouldShow: true, indexOffset, }); @@ -106,7 +107,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (localPersonalDetails.length > 0) { newSections.push({ - data: localPersonalDetails, + data: localPersonalDetails as ListItem[], shouldShow: true, indexOffset, }); @@ -115,7 +116,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (userToInvite) { newSections.push({ - data: [userToInvite], + data: [userToInvite as ListItem], shouldShow: true, indexOffset, }); @@ -124,7 +125,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { return newSections; }, [localPersonalDetails, recentReports, userToInvite]); - const selectReport = (option: ReportUtils.OptionData) => { + const selectReport = (option: ListItem) => { if (!option) { return; } @@ -156,11 +157,11 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { onBackButtonPress={Navigation.goBack} /> - + Date: Tue, 20 Feb 2024 09:53:30 +0000 Subject: [PATCH 15/22] [TS migration][SearchPage] Minor ts issue --- src/components/SelectionList/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 8b638e29b182..cbe389b3f52e 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -1,5 +1,5 @@ import type {ReactElement, ReactNode} from 'react'; -import type {GestureResponderEvent, InputModeOptions, SectionListData, StyleProp, TextStyle, ViewStyle} from 'react-native'; +import type {GestureResponderEvent, InputModeOptions, LayoutChangeEvent, SectionListData, StyleProp, TextStyle, ViewStyle} from 'react-native'; import type CONST from '@src/CONST'; import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; @@ -220,7 +220,7 @@ type BaseSelectionListProps = Partial & { isLoadingNewOptions?: boolean; /** Custom callback when Selection List layout changes */ - onLayout?: () => void; + onLayout?: (nativeEvent?: LayoutChangeEvent) => void; /** Whether to auto focus the Search Input */ autoFocus?: boolean; From 5c88c77b248b9f21c195e810e56cc3b7b851e5ad Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 27 Feb 2024 09:45:59 +0000 Subject: [PATCH 16/22] Revert "[TS migration][SearchPage] Minor ts issue" This reverts commit 44304588e349a75ac832f3caf015235a7229d5e6. --- src/components/SelectionList/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index cbe389b3f52e..8b638e29b182 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -1,5 +1,5 @@ import type {ReactElement, ReactNode} from 'react'; -import type {GestureResponderEvent, InputModeOptions, LayoutChangeEvent, SectionListData, StyleProp, TextStyle, ViewStyle} from 'react-native'; +import type {GestureResponderEvent, InputModeOptions, SectionListData, StyleProp, TextStyle, ViewStyle} from 'react-native'; import type CONST from '@src/CONST'; import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; @@ -220,7 +220,7 @@ type BaseSelectionListProps = Partial & { isLoadingNewOptions?: boolean; /** Custom callback when Selection List layout changes */ - onLayout?: (nativeEvent?: LayoutChangeEvent) => void; + onLayout?: () => void; /** Whether to auto focus the Search Input */ autoFocus?: boolean; From 333700b3552b8ba1b13a09c3a0e5f1a3ebbc8106 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 27 Feb 2024 09:46:31 +0000 Subject: [PATCH 17/22] Revert "[TS migration][SearchPage] Updated types based on main" This reverts commit efa4b990793992e273ed80048f30158f3994cf19. --- src/components/SelectionList/BaseListItem.tsx | 4 ++-- .../SelectionList/BaseSelectionList.tsx | 2 +- src/components/SelectionList/RadioListItem.tsx | 2 +- src/components/SelectionList/UserListItem.tsx | 2 +- src/components/SelectionList/types.ts | 16 ++++++++-------- src/pages/SearchPage/index.tsx | 15 +++++++-------- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 9bfeacbc0ac2..eecf9ca920bb 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -55,13 +55,13 @@ function BaseListItem({ onSelectRow(item)} disabled={isDisabled} - accessibilityLabel={item.text} + accessibilityLabel={item.text ?? ''} role={CONST.ROLE.BUTTON} hoverDimmingValue={1} hoverStyle={styles.hoveredComponentBG} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined} - nativeID={keyForList} + nativeID={keyForList ?? ''} > {({hovered}) => ( <> diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 850874b7abc0..7d7ff16bed92 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -457,7 +457,7 @@ function BaseSelectionList( getItemLayout={getItemLayout} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} - keyExtractor={(item) => item.keyForList} + keyExtractor={(item) => item.keyForList ?? ''} extraData={focusedIndex} indicatorStyle="white" keyboardShouldPersistTaps="always" diff --git a/src/components/SelectionList/RadioListItem.tsx b/src/components/SelectionList/RadioListItem.tsx index c069eaf7d8fd..eaa8db2a0cf2 100644 --- a/src/components/SelectionList/RadioListItem.tsx +++ b/src/components/SelectionList/RadioListItem.tsx @@ -11,7 +11,7 @@ function RadioListItem({item, showTooltip, textStyles, alternateTextStyles}: Lis diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index 60e97d887b4d..31041f71f73b 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -44,7 +44,7 @@ function UserListItem({item, textStyles, alternateTextStyles, showTooltip, style {!!item.alternateText && ( diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 8b638e29b182..49e6522c8cb8 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -15,7 +15,7 @@ type CommonListItemProps = { alternateTextStyles?: StyleProp; /** Whether this item is disabled */ - isDisabled?: boolean; + isDisabled?: boolean | null; /** Whether this item should show Tooltip */ showTooltip: boolean; @@ -35,25 +35,25 @@ type CommonListItemProps = { type ListItem = { /** Text to display */ - text: string; + text?: string; /** Alternate text to display */ - alternateText?: string; + alternateText?: string | null; /** Key used internally by React */ - keyForList: string; + keyForList?: string | null; /** Whether this option is selected */ isSelected?: boolean; /** Whether this option is disabled for selection */ - isDisabled?: boolean; + isDisabled?: boolean | null; /** User accountID */ accountID?: number | null; /** User login */ - login?: string; + login?: string | null; /** Element to show on the right side of the item */ rightElement?: ReactNode; @@ -77,7 +77,7 @@ type ListItem = { /** ID of the report */ reportID?: string; - + /** Whether this option should show subscript */ shouldShowSubscript?: boolean; }; @@ -96,7 +96,7 @@ type ListItemProps = CommonListItemProps & { type BaseListItemProps = CommonListItemProps & { item: TItem; shouldPreventDefaultFocusOnSelectRow?: boolean; - keyForList: string; + keyForList?: string | null; }; type Section = { diff --git a/src/pages/SearchPage/index.tsx b/src/pages/SearchPage/index.tsx index 6c841f506d15..948c97058653 100644 --- a/src/pages/SearchPage/index.tsx +++ b/src/pages/SearchPage/index.tsx @@ -7,7 +7,6 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {usePersonalDetails} from '@components/OnyxProvider'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; -import type {ListItem} from '@components/SelectionList/types'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -39,7 +38,7 @@ type SearchPageOnyxProps = { type SearchPageProps = SearchPageOnyxProps & StackScreenProps; type SearchPageSectionItem = { - data: ListItem[]; + data: ReportUtils.OptionData[]; shouldShow: boolean; indexOffset: number; }; @@ -98,7 +97,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (recentReports?.length > 0) { newSections.push({ - data: recentReports as ListItem[], + data: recentReports, shouldShow: true, indexOffset, }); @@ -107,7 +106,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (localPersonalDetails.length > 0) { newSections.push({ - data: localPersonalDetails as ListItem[], + data: localPersonalDetails, shouldShow: true, indexOffset, }); @@ -116,7 +115,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (userToInvite) { newSections.push({ - data: [userToInvite as ListItem], + data: [userToInvite], shouldShow: true, indexOffset, }); @@ -125,7 +124,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { return newSections; }, [localPersonalDetails, recentReports, userToInvite]); - const selectReport = (option: ListItem) => { + const selectReport = (option: ReportUtils.OptionData) => { if (!option) { return; } @@ -157,11 +156,11 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { onBackButtonPress={Navigation.goBack} /> - sections={didScreenTransitionEnd && isOptionsDataReady ? sections : CONST.EMPTY_ARRAY} textInputValue={searchValue} textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} - textInputHint={offlineMessage as string} + textInputHint={offlineMessage} onChangeText={setSearchValue} headerMessage={headerMessage} onLayout={setPerformanceTimersEnd} From 2b01f41c5fa4f49a65b50e9b7e148ee6c0cd8fb5 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 27 Feb 2024 12:39:45 +0000 Subject: [PATCH 18/22] [TS migration][SearchPage] TS issues fix --- src/components/DatePicker/CalendarPicker/YearPickerModal.tsx | 2 +- src/components/SelectionList/BaseSelectionList.tsx | 2 +- src/components/SelectionList/TableListItem.tsx | 2 +- src/components/SelectionList/types.ts | 2 +- src/pages/RoomMembersPage.tsx | 2 +- src/pages/SearchPage/index.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx b/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx index f8c4a12ec188..8f5487f9c68b 100644 --- a/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx +++ b/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx @@ -31,7 +31,7 @@ function YearPickerModal({isVisible, years, currentYear = new Date().getFullYear const {translate} = useLocalize(); const [searchText, setSearchText] = useState(''); const {sections, headerMessage} = useMemo(() => { - const yearsList = searchText === '' ? years : years.filter((year) => year.text.includes(searchText)); + const yearsList = searchText === '' ? years : years.filter((year) => year.text?.includes(searchText)); return { headerMessage: !yearsList.length ? translate('common.noResultsFound') : '', sections: [{data: yearsList.sort((a, b) => b.value - a.value), indexOffset: 0}], diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 5c7a5c0667b8..34425ceeaecc 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -292,7 +292,7 @@ function BaseSelectionList( onDismissError={() => onDismissError?.(item)} shouldPreventDefaultFocusOnSelectRow={shouldPreventDefaultFocusOnSelectRow} rightHandSideComponent={rightHandSideComponent} - keyForList={item.keyForList} + keyForList={item.keyForList ?? ''} /> ); }; diff --git a/src/components/SelectionList/TableListItem.tsx b/src/components/SelectionList/TableListItem.tsx index 922937c72219..f4dd03b8ca27 100644 --- a/src/components/SelectionList/TableListItem.tsx +++ b/src/components/SelectionList/TableListItem.tsx @@ -60,7 +60,7 @@ function TableListItem({ & { diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 557211dc0235..ae6f400876e9 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -202,7 +202,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { }); }); - result = result.sort((value1, value2) => localeCompare(value1.text, value2.text)); + result = result.sort((value1, value2) => localeCompare(value1?.text ?? '', value2?.text ?? '')); return result; }; diff --git a/src/pages/SearchPage/index.tsx b/src/pages/SearchPage/index.tsx index 55b8130d430a..c91a1efc9c6d 100644 --- a/src/pages/SearchPage/index.tsx +++ b/src/pages/SearchPage/index.tsx @@ -60,7 +60,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { const themeStyles = useThemeStyles(); const personalDetails = usePersonalDetails(); - const offlineMessage = isOffline ? [`${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}`, {isTranslated: true}] : ''; + const offlineMessage = isOffline ? ([`${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}`, {isTranslated: true}] as unknown as string) : ''; const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState(''); From 74061d709f0990694a78911bea90f134203846c1 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 4 Mar 2024 09:31:21 +0000 Subject: [PATCH 19/22] [TS migration][SearchPage] Feedback --- src/components/ScreenWrapper.tsx | 4 ++-- src/components/SelectionList/BaseSelectionList.tsx | 2 +- src/pages/RoomMembersPage.tsx | 2 +- src/pages/SearchPage/index.tsx | 10 ++++------ 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/ScreenWrapper.tsx b/src/components/ScreenWrapper.tsx index d7bd965d19e6..198b47cb4259 100644 --- a/src/components/ScreenWrapper.tsx +++ b/src/components/ScreenWrapper.tsx @@ -14,7 +14,7 @@ import useTackInputFocus from '@hooks/useTackInputFocus'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; -import type {RootStackParamList, SearchNavigatorParamList} from '@libs/Navigation/types'; +import type {RootStackParamList} from '@libs/Navigation/types'; import toggleTestToolsModal from '@userActions/TestTool'; import CONST from '@src/CONST'; import CustomDevMenu from './CustomDevMenu'; @@ -89,7 +89,7 @@ type ScreenWrapperProps = { * * This is required because transitionEnd event doesn't trigger in the testing environment. */ - navigation?: StackNavigationProp | StackNavigationProp; + navigation?: StackNavigationProp; /** Whether to show offline indicator on wide screens */ shouldShowOfflineIndicatorInWideScreen?: boolean; diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 34425ceeaecc..a6f0082882be 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -462,7 +462,7 @@ function BaseSelectionList( getItemLayout={getItemLayout} onScroll={onScroll} onScrollBeginDrag={onScrollBeginDrag} - keyExtractor={(item) => item.keyForList ?? ''} + keyExtractor={(item, index) => item.keyForList ?? `${index}`} extraData={focusedIndex} indicatorStyle="white" keyboardShouldPersistTaps="always" diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index ae6f400876e9..4d826580b362 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -202,7 +202,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { }); }); - result = result.sort((value1, value2) => localeCompare(value1?.text ?? '', value2?.text ?? '')); + result = result.sort((value1, value2) => localeCompare(value1.text ?? '', value2.text ?? '')); return result; }; diff --git a/src/pages/SearchPage/index.tsx b/src/pages/SearchPage/index.tsx index c91a1efc9c6d..648d40c130d0 100644 --- a/src/pages/SearchPage/index.tsx +++ b/src/pages/SearchPage/index.tsx @@ -1,4 +1,3 @@ -import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; @@ -12,8 +11,8 @@ import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; +import type {MaybePhraseKey} from '@libs/Localize'; import Navigation from '@libs/Navigation/Navigation'; -import type {SearchNavigatorParamList} from '@libs/Navigation/types'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Performance from '@libs/Performance'; import * as ReportUtils from '@libs/ReportUtils'; @@ -21,7 +20,6 @@ import * as Report from '@userActions/Report'; import Timing from '@userActions/Timing'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import SearchPageFooter from './SearchPageFooter'; @@ -36,7 +34,7 @@ type SearchPageOnyxProps = { isSearchingForReports: OnyxEntry; }; -type SearchPageProps = SearchPageOnyxProps & StackScreenProps; +type SearchPageProps = SearchPageOnyxProps; type SearchPageSectionItem = { data: ReportUtils.OptionData[]; @@ -60,7 +58,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { const themeStyles = useThemeStyles(); const personalDetails = usePersonalDetails(); - const offlineMessage = isOffline ? ([`${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}`, {isTranslated: true}] as unknown as string) : ''; + const offlineMessage: MaybePhraseKey = isOffline ? [`${translate('common.youAppearToBeOffline')} ${translate('search.resultsAreLimited')}`, {isTranslated: true}] : ''; const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState(''); @@ -102,7 +100,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { shouldShow: true, indexOffset, }); - indexOffset += recentReports?.length; + indexOffset += recentReports.length; } if (localPersonalDetails.length > 0) { From 44ddd4086d6dd047eb694279aac776819fc03881 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 4 Mar 2024 09:46:04 +0000 Subject: [PATCH 20/22] [TS migration][SearchPage] TS issues fix --- src/components/SelectionList/BaseListItem.tsx | 2 +- src/components/SelectionList/types.ts | 3 ++- src/pages/SearchPage/index.tsx | 3 +-- src/pages/workspace/WorkspaceMembersPage.tsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 8d551216a384..ab0c35b4d6a3 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -78,7 +78,7 @@ function BaseListItem({ {canSelectMultiple && ( = Partial & { textInputPlaceholder?: string; /** Hint for the text input */ - textInputHint?: string; + textInputHint?: string | MaybePhraseKey; /** Value for the text input */ textInputValue?: string; diff --git a/src/pages/SearchPage/index.tsx b/src/pages/SearchPage/index.tsx index 979e4b02d7f0..f16f3bbbf27d 100644 --- a/src/pages/SearchPage/index.tsx +++ b/src/pages/SearchPage/index.tsx @@ -2,7 +2,6 @@ import React, {useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {usePersonalDetails} from '@components/OnyxProvider'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -97,7 +96,7 @@ function SearchPage({betas, reports, isSearchingForReports}: SearchPageProps) { if (recentReports?.length > 0) { newSections.push({ - data: _.map(recentReports, (report) => ({...report, isBold: report.isUnread})), + data: recentReports.map((report) => ({...report, isBold: report.isUnread})), shouldShow: true, indexOffset, }); diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index 718f2b6d9ad2..4265c84a618f 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -348,7 +348,7 @@ function WorkspaceMembersPage({policyMembers, personalDetails, route, policy, se }); }); - result = result.sort((a, b) => a.text.toLowerCase().localeCompare(b.text.toLowerCase())); + result = result.sort((a, b) => (a.text ?? '').toLowerCase().localeCompare((b.text ?? '').toLowerCase())); return result; }; From 7ba0847cab03ea7fc34db018965ba8017e05ce8b Mon Sep 17 00:00:00 2001 From: Ruben Rebelo <39693995+ruben-rebelo@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:01:06 +0000 Subject: [PATCH 21/22] [TS migration][SearchPage] Update src/components/SelectionList/types.ts Co-authored-by: wentao --- src/components/SelectionList/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 9010ec7521d8..a9cd3dacc1a7 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -190,7 +190,7 @@ type BaseSelectionListProps = Partial & { textInputPlaceholder?: string; /** Hint for the text input */ - textInputHint?: string | MaybePhraseKey; + textInputHint?: MaybePhraseKey; /** Value for the text input */ textInputValue?: string; From bef7c71ad6b9b15f35be03a866fb51d308392f95 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Tue, 5 Mar 2024 09:23:53 +0000 Subject: [PATCH 22/22] [TS migration][SeachPage] Lint --- src/libs/Navigation/types.ts | 2 +- src/pages/SearchPage/index.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 6ffbb3a358b0..b7ff1c711a6d 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -572,7 +572,7 @@ type AuthScreensParamList = SharedScreensParamList & { [SCREENS.DESKTOP_SIGN_IN_REDIRECT]: undefined; }; -type RootStackParamList = PublicScreensParamList & AuthScreensParamList; +type RootStackParamList = PublicScreensParamList & AuthScreensParamList & SearchNavigatorParamList; type BottomTabName = keyof BottomTabNavigatorParamList; diff --git a/src/pages/SearchPage/index.tsx b/src/pages/SearchPage/index.tsx index 463fde15a541..07096ce6c2d5 100644 --- a/src/pages/SearchPage/index.tsx +++ b/src/pages/SearchPage/index.tsx @@ -1,4 +1,4 @@ -import {StackScreenProps} from '@react-navigation/stack'; +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; @@ -14,7 +14,7 @@ import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import type {MaybePhraseKey} from '@libs/Localize'; import Navigation from '@libs/Navigation/Navigation'; -import {SearchNavigatorParamList} from '@libs/Navigation/types'; +import type {RootStackParamList} from '@libs/Navigation/types'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import Performance from '@libs/Performance'; import * as ReportUtils from '@libs/ReportUtils'; @@ -37,7 +37,7 @@ type SearchPageOnyxProps = { isSearchingForReports: OnyxEntry; }; -type SearchPageProps = SearchPageOnyxProps & StackScreenProps; +type SearchPageProps = SearchPageOnyxProps & StackScreenProps; type SearchPageSectionItem = { data: ReportUtils.OptionData[];