From 70e9a61545aec84c106eefee56f3c3ccfc3d14e6 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 17 Jan 2024 09:53:31 +0000 Subject: [PATCH 01/10] [TS migration] NewChatPage migration --- src/ONYXKEYS.ts | 1 + src/pages/{NewChatPage.js => NewChatPage.tsx} | 137 ++++++++++-------- 2 files changed, 75 insertions(+), 63 deletions(-) rename src/pages/{NewChatPage.js => NewChatPage.tsx} (68%) 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; diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.tsx similarity index 68% rename from src/pages/NewChatPage.js rename to src/pages/NewChatPage.tsx index b90ce6bbc247..3574917ecce9 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.tsx @@ -1,64 +1,61 @@ -import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import KeyboardAvoidingView from '@components/KeyboardAvoidingView'; import OfflineIndicator from '@components/OfflineIndicator'; import OptionsSelector from '@components/OptionsSelector'; import ScreenWrapper from '@components/ScreenWrapper'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; -import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import compose from '@libs/compose'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import doInteractionTask from '@libs/DoInteractionTask'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import type {OptionData} from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import personalDetailsPropType from './personalDetailsPropType'; -import reportPropTypes from './reportPropTypes'; - -const propTypes = { - /** Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string), - - /** All of the personal details for everyone */ - personalDetails: PropTypes.objectOf(personalDetailsPropType), +import type {Beta, Report as OnyxReport, PersonalDetails} from '@src/types/onyx'; +type NewChatPageWithOnyxProps = { /** All reports shared with the user */ - reports: PropTypes.objectOf(reportPropTypes), + reports: OnyxEntry; - ...windowDimensionsPropTypes, + /** All of the personal details for everyone */ + personalDetails: OnyxCollection; - ...withLocalizePropTypes, + betas: OnyxEntry; /** Whether we are searching for reports in the server */ - isSearchingForReports: PropTypes.bool, + isSearchingForReports: OnyxEntry; +}; + +type NewChatPageProps = NewChatPageWithOnyxProps & { + isGroupChat: boolean; }; -const defaultProps = { - betas: [], - personalDetails: {}, - reports: {}, - isSearchingForReports: false, +type NewChatSectionListData = { + title?: string; + data: OnyxReport[] | PersonalDetails[]; + shouldShow: boolean; + indexOffset: number; }; -const excludedGroupEmails = _.without(CONST.EXPENSIFY_EMAILS, CONST.EMAIL.CONCIERGE); +const excludedGroupEmails = CONST.EXPENSIFY_EMAILS.filter((value) => value !== CONST.EMAIL.CONCIERGE); -function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, isSearchingForReports}) { +function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingForReports}: NewChatPageProps) { + const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, setSearchTerm] = useState(''); - const [filteredRecentReports, setFilteredRecentReports] = useState([]); - const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); + const [searchTerm, setSearchTerm] = useState(''); + const [filteredRecentReports, setFilteredRecentReports] = useState([]); + const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); const [filteredUserToInvite, setFilteredUserToInvite] = useState(); - const [selectedOptions, setSelectedOptions] = useState([]); + const [selectedOptions, setSelectedOptions] = useState([]); const {isOffline} = useNetwork(); const {isSmallScreenWidth} = useWindowDimensions(); const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); @@ -69,16 +66,20 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i Boolean(filteredUserToInvite), searchTerm.trim(), maxParticipantsReached, - _.some(selectedOptions, (participant) => participant.searchText.toLowerCase().includes(searchTerm.trim().toLowerCase())), + selectedOptions.some((participant) => participant?.searchText?.toLowerCase().includes(searchTerm.trim().toLowerCase())), ); + + // @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 sections = useMemo(() => { - const sectionsList = []; + const sectionsList: NewChatSectionListData[] = []; let indexOffset = 0; const formatResults = OptionsListUtils.formatSectionsFromSearchTerm(searchTerm, selectedOptions, filteredRecentReports, filteredPersonalDetails, {}, false, indexOffset); + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. sectionsList.push(formatResults.section); + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. indexOffset = formatResults.newIndexOffset; if (maxParticipantsReached) { @@ -88,7 +89,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i sectionsList.push({ title: translate('common.recents'), data: filteredRecentReports, - shouldShow: !_.isEmpty(filteredRecentReports), + shouldShow: filteredRecentReports.length > 0, indexOffset, }); indexOffset += filteredRecentReports.length; @@ -96,7 +97,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i sectionsList.push({ title: translate('common.contacts'), data: filteredPersonalDetails, - shouldShow: !_.isEmpty(filteredPersonalDetails), + shouldShow: filteredPersonalDetails.length > 0, indexOffset, }); indexOffset += filteredPersonalDetails.length; @@ -115,24 +116,28 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i /** * Removes a selected option from list if already selected. If not already selected add this option to the list. - * @param {Object} option + * @param option - Option selected from the list */ - const toggleOption = (option) => { - const isOptionInList = _.some(selectedOptions, (selectedOption) => selectedOption.login === option.login); + const toggleOption = (option: OptionData) => { + const isOptionInList = selectedOptions.some((selectedOption) => selectedOption.login === option.login); let newSelectedOptions; if (isOptionInList) { - newSelectedOptions = _.reject(selectedOptions, (selectedOption) => selectedOption.login === option.login); + newSelectedOptions = selectedOptions.filter((selectedOption) => selectedOption.login !== option.login); } else { newSelectedOptions = [...selectedOptions, option]; } const { + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. recentReports, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. personalDetails: newChatPersonalDetails, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. userToInvite, } = OptionsListUtils.getFilteredOptions( + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. reports, personalDetails, betas, @@ -161,9 +166,12 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i * Creates a new 1:1 chat with the option and the current user, * or navigates to the existing chat if one with those participants already exists. * - * @param {Object} option + * @param option - Option choosen to create the chat */ - const createChat = (option) => { + const createChat = (option: OptionData) => { + if (option.login === undefined || option.login === null) { + return; + } Report.navigateToAndOpenReport([option.login]); }; @@ -172,19 +180,25 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i * or navigates to the existing chat if one with those participants already exists. */ const createGroup = () => { - const logins = _.pluck(selectedOptions, 'login'); + const logins = selectedOptions.map((option) => option.login).filter((login): login is string => typeof login === 'string'); + if (logins.length < 1) { return; } + Report.navigateToAndOpenReport(logins); }; const updateOptions = useCallback(() => { const { + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. recentReports, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. personalDetails: newChatPersonalDetails, + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. userToInvite, } = OptionsListUtils.getFilteredOptions( + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. reports, personalDetails, betas, @@ -209,6 +223,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i // eslint-disable-next-line react-hooks/exhaustive-deps }, [reports, personalDetails, searchTerm]); + useEffect(() => { const interactionTask = doInteractionTask(() => { setDidScreenTransitionEnd(true); @@ -218,7 +233,8 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i if (!interactionTask) { return; } - interactionTask.cancel(); + + (interactionTask as { cancel: () => void }).cancel(); }; }, []); @@ -252,11 +268,12 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, translate, i behavior="padding" // Offset is needed as KeyboardAvoidingView in nested inside of TabNavigator instead of wrapping whole screen. // This is because when wrapping whole screen the screen was freezing when changing Tabs. - keyboardVerticalOffset={variables.contentHeaderHeight + insets.top + variables.tabSelectorButtonHeight + variables.tabSelectorButtonPadding} + keyboardVerticalOffset={variables.contentHeaderHeight + (insets?.top ?? 0) + variables.tabSelectorButtonHeight + variables.tabSelectorButtonPadding} > 0 ? safeAreaPaddingBottomStyle : {}]}> ({ + reports: { + key: ONYXKEYS.COLLECTION.REPORT, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + betas: { + key: ONYXKEYS.BETAS, + }, + isSearchingForReports: { + key: ONYXKEYS.IS_SEARCHING_FOR_REPORTS, + initWithStoredValues: false, + }, +})(NewChatPage); From fd389a90ba41cc0152852cc83700b127bb413f7c Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 17 Jan 2024 09:55:58 +0000 Subject: [PATCH 02/10] [TS migration] Prettified NewChatPage --- src/pages/NewChatPage.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 3574917ecce9..8d613d91d906 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -223,7 +223,6 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF // eslint-disable-next-line react-hooks/exhaustive-deps }, [reports, personalDetails, searchTerm]); - useEffect(() => { const interactionTask = doInteractionTask(() => { setDidScreenTransitionEnd(true); @@ -233,8 +232,8 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF if (!interactionTask) { return; } - - (interactionTask as { cancel: () => void }).cancel(); + + (interactionTask as {cancel: () => void}).cancel(); }; }, []); From e41b426a4fc03c9224554311b47a4512fe5188df Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Wed, 17 Jan 2024 15:10:18 +0000 Subject: [PATCH 03/10] [TS migration] Partially addressed feedback --- src/pages/NewChatPage.tsx | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 8d613d91d906..2002d21cdaa1 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -1,7 +1,7 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import KeyboardAvoidingView from '@components/KeyboardAvoidingView'; import OfflineIndicator from '@components/OfflineIndicator'; import OptionsSelector from '@components/OptionsSelector'; @@ -20,16 +20,16 @@ import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Beta, Report as OnyxReport, PersonalDetails} from '@src/types/onyx'; +import type * as OnyxTypes from '@src/types/onyx'; type NewChatPageWithOnyxProps = { /** All reports shared with the user */ - reports: OnyxEntry; + reports: OnyxEntry; /** All of the personal details for everyone */ - personalDetails: OnyxCollection; + personalDetails: OnyxEntry; - betas: OnyxEntry; + betas: OnyxEntry; /** Whether we are searching for reports in the server */ isSearchingForReports: OnyxEntry; @@ -41,7 +41,7 @@ type NewChatPageProps = NewChatPageWithOnyxProps & { type NewChatSectionListData = { title?: string; - data: OnyxReport[] | PersonalDetails[]; + data: OnyxTypes.Report[] | OnyxTypes.PersonalDetails[]; shouldShow: boolean; indexOffset: number; }; @@ -51,9 +51,9 @@ const excludedGroupEmails = CONST.EXPENSIFY_EMAILS.filter((value) => value !== C function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingForReports}: NewChatPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const [searchTerm, setSearchTerm] = useState(''); - const [filteredRecentReports, setFilteredRecentReports] = useState([]); - const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); + const [searchTerm, setSearchTerm] = useState(''); + const [filteredRecentReports, setFilteredRecentReports] = useState([]); + const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); const [filteredUserToInvite, setFilteredUserToInvite] = useState(); const [selectedOptions, setSelectedOptions] = useState([]); const {isOffline} = useNetwork(); @@ -116,7 +116,6 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF /** * Removes a selected option from list if already selected. If not already selected add this option to the list. - * @param option - Option selected from the list */ const toggleOption = (option: OptionData) => { const isOptionInList = selectedOptions.some((selectedOption) => selectedOption.login === option.login); @@ -165,11 +164,9 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF /** * Creates a new 1:1 chat with the option and the current user, * or navigates to the existing chat if one with those participants already exists. - * - * @param option - Option choosen to create the chat */ const createChat = (option: OptionData) => { - if (option.login === undefined || option.login === null) { + if (!option.login) { return; } Report.navigateToAndOpenReport([option.login]); From 1b481c953b81274948a8178d599495648f1ff126 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Fri, 19 Jan 2024 08:48:54 +0000 Subject: [PATCH 04/10] [TS migration] NewChatPage code improvements --- src/libs/DoInteractionTask/index.desktop.ts | 8 ++++---- src/libs/DoInteractionTask/index.ts | 8 +++++--- src/libs/DoInteractionTask/types.ts | 5 +++++ src/pages/NewChatPage.tsx | 10 ++++++---- 4 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 src/libs/DoInteractionTask/types.ts diff --git a/src/libs/DoInteractionTask/index.desktop.ts b/src/libs/DoInteractionTask/index.desktop.ts index 73b3cb19ec32..835dfd46bd98 100644 --- a/src/libs/DoInteractionTask/index.desktop.ts +++ b/src/libs/DoInteractionTask/index.desktop.ts @@ -1,10 +1,10 @@ import {InteractionManager} from 'react-native'; +import type DoInteractionTask from './types'; // For desktop, we should call the callback after all interactions to prevent freezing. See more detail in https://github.com/Expensify/App/issues/28916 -function doInteractionTask(callback: () => void) { - return InteractionManager.runAfterInteractions(() => { +const doInteractionTask: DoInteractionTask = (callback) => + InteractionManager.runAfterInteractions(() => { callback(); }); -} -export default doInteractionTask; +export default doInteractionTask; \ No newline at end of file diff --git a/src/libs/DoInteractionTask/index.ts b/src/libs/DoInteractionTask/index.ts index dffbb0562b98..5be25a621c36 100644 --- a/src/libs/DoInteractionTask/index.ts +++ b/src/libs/DoInteractionTask/index.ts @@ -1,6 +1,8 @@ -function doInteractionTask(callback: () => void) { +import type DoInteractionTask from './types'; + +const doInteractionTask: DoInteractionTask = (callback) => { callback(); return null; -} +}; -export default doInteractionTask; +export default doInteractionTask; \ No newline at end of file diff --git a/src/libs/DoInteractionTask/types.ts b/src/libs/DoInteractionTask/types.ts new file mode 100644 index 000000000000..d4a76d904482 --- /dev/null +++ b/src/libs/DoInteractionTask/types.ts @@ -0,0 +1,5 @@ +import type {InteractionManager} from 'react-native'; + +type DoInteractionTask = (callback: () => void) => ReturnType | null; + +export default DoInteractionTask; \ No newline at end of file diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 2002d21cdaa1..c10d809cbf4a 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -39,9 +39,11 @@ type NewChatPageProps = NewChatPageWithOnyxProps & { isGroupChat: boolean; }; +type Option = Partial; + type NewChatSectionListData = { title?: string; - data: OnyxTypes.Report[] | OnyxTypes.PersonalDetails[]; + data: Option[]; shouldShow: boolean; indexOffset: number; }; @@ -52,8 +54,8 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF const {translate} = useLocalize(); const styles = useThemeStyles(); const [searchTerm, setSearchTerm] = useState(''); - const [filteredRecentReports, setFilteredRecentReports] = useState([]); - const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); + const [filteredRecentReports, setFilteredRecentReports] = useState([]); + const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); const [filteredUserToInvite, setFilteredUserToInvite] = useState(); const [selectedOptions, setSelectedOptions] = useState([]); const {isOffline} = useNetwork(); @@ -230,7 +232,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF return; } - (interactionTask as {cancel: () => void}).cancel(); + interactionTask.cancel(); }; }, []); From 6447729f6735ddbe365f64fb8f2867dfcc57216a Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Fri, 19 Jan 2024 08:53:55 +0000 Subject: [PATCH 05/10] [TS migration] Lint fixes --- src/libs/DoInteractionTask/index.desktop.ts | 2 +- src/libs/DoInteractionTask/index.ts | 2 +- src/libs/DoInteractionTask/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/DoInteractionTask/index.desktop.ts b/src/libs/DoInteractionTask/index.desktop.ts index 835dfd46bd98..3b0340d68425 100644 --- a/src/libs/DoInteractionTask/index.desktop.ts +++ b/src/libs/DoInteractionTask/index.desktop.ts @@ -7,4 +7,4 @@ const doInteractionTask: DoInteractionTask = (callback) => callback(); }); -export default doInteractionTask; \ No newline at end of file +export default doInteractionTask; diff --git a/src/libs/DoInteractionTask/index.ts b/src/libs/DoInteractionTask/index.ts index 5be25a621c36..0eadb8f7dbee 100644 --- a/src/libs/DoInteractionTask/index.ts +++ b/src/libs/DoInteractionTask/index.ts @@ -5,4 +5,4 @@ const doInteractionTask: DoInteractionTask = (callback) => { return null; }; -export default doInteractionTask; \ No newline at end of file +export default doInteractionTask; diff --git a/src/libs/DoInteractionTask/types.ts b/src/libs/DoInteractionTask/types.ts index d4a76d904482..3c1da4b5364d 100644 --- a/src/libs/DoInteractionTask/types.ts +++ b/src/libs/DoInteractionTask/types.ts @@ -2,4 +2,4 @@ import type {InteractionManager} from 'react-native'; type DoInteractionTask = (callback: () => void) => ReturnType | null; -export default DoInteractionTask; \ No newline at end of file +export default DoInteractionTask; From e75c2f1746c19c53e28fa0a006fa74fa95bd9bd9 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Fri, 19 Jan 2024 10:29:52 +0000 Subject: [PATCH 06/10] [TS Migration] Added todo on sectionList type on NewChatPage --- src/pages/NewChatPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index c10d809cbf4a..1539eeb3d686 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -41,6 +41,7 @@ type NewChatPageProps = NewChatPageWithOnyxProps & { type Option = Partial; +// TODO: Update this type when OptionListUtils (https://github.com/Expensify/App/pull/32470) is migrated type NewChatSectionListData = { title?: string; data: Option[]; From c80e510d3fdb5e300df4de1553e5efa950cb4f82 Mon Sep 17 00:00:00 2001 From: Ruben Rebelo <39693995+ruben-rebelo@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:50:37 +0000 Subject: [PATCH 07/10] [TS migration] Updated TODO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/pages/NewChatPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 1539eeb3d686..a717f540cd7c 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -41,7 +41,7 @@ type NewChatPageProps = NewChatPageWithOnyxProps & { type Option = Partial; -// TODO: Update this type when OptionListUtils (https://github.com/Expensify/App/pull/32470) is migrated +// TODO: Update this type once OptionListUtils.js (https://github.com/Expensify/App/issues/24921) is migrated to TypeScript. type NewChatSectionListData = { title?: string; data: Option[]; From 8163c3debcd73a760e3a3eec85531762b3e34497 Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Mon, 29 Jan 2024 15:50:22 +0000 Subject: [PATCH 08/10] [TS migration][NewChatPage] Type changed after merge with main --- src/libs/OptionsListUtils.ts | 6 +++-- src/pages/NewChatPage.tsx | 43 ++++++++++-------------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index b075ae1e6a30..0d98d999625c 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1730,7 +1730,7 @@ function getIOUConfirmationOptionsFromParticipants(participants: Participant[], * Build the options for the New Group view */ function getFilteredOptions( - reports: Record, + reports: OnyxCollection, personalDetails: OnyxEntry, betas: Beta[] = [], searchValue = '', @@ -1914,7 +1914,7 @@ function formatSectionsFromSearchTerm( searchTerm: string, selectedOptions: ReportUtils.OptionData[], filteredRecentReports: ReportUtils.OptionData[], - filteredPersonalDetails: PersonalDetails[], + filteredPersonalDetails: ReportUtils.OptionData[], personalDetails: OnyxEntry = {}, shouldGetOptionDetails = false, indexOffset = 0, @@ -1994,3 +1994,5 @@ export { formatSectionsFromSearchTerm, transformedTaxRates, }; + +export type {CategorySection}; diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index a717f540cd7c..66e9475b4af4 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -1,7 +1,7 @@ import React, {useCallback, useEffect, useMemo, 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 KeyboardAvoidingView from '@components/KeyboardAvoidingView'; import OfflineIndicator from '@components/OfflineIndicator'; import OptionsSelector from '@components/OptionsSelector'; @@ -24,7 +24,7 @@ import type * as OnyxTypes from '@src/types/onyx'; type NewChatPageWithOnyxProps = { /** All reports shared with the user */ - reports: OnyxEntry; + reports: OnyxCollection; /** All of the personal details for everyone */ personalDetails: OnyxEntry; @@ -39,25 +39,15 @@ type NewChatPageProps = NewChatPageWithOnyxProps & { isGroupChat: boolean; }; -type Option = Partial; - -// TODO: Update this type once OptionListUtils.js (https://github.com/Expensify/App/issues/24921) is migrated to TypeScript. -type NewChatSectionListData = { - title?: string; - data: Option[]; - shouldShow: boolean; - indexOffset: number; -}; - const excludedGroupEmails = CONST.EXPENSIFY_EMAILS.filter((value) => value !== CONST.EMAIL.CONCIERGE); function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingForReports}: NewChatPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const [searchTerm, setSearchTerm] = useState(''); - const [filteredRecentReports, setFilteredRecentReports] = useState([]); - const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); - const [filteredUserToInvite, setFilteredUserToInvite] = useState(); + const [filteredRecentReports, setFilteredRecentReports] = useState([]); + const [filteredPersonalDetails, setFilteredPersonalDetails] = useState([]); + const [filteredUserToInvite, setFilteredUserToInvite] = useState(); const [selectedOptions, setSelectedOptions] = useState([]); const {isOffline} = useNetwork(); const {isSmallScreenWidth} = useWindowDimensions(); @@ -72,17 +62,16 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF selectedOptions.some((participant) => participant?.searchText?.toLowerCase().includes(searchTerm.trim().toLowerCase())), ); - // @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 sections = useMemo(() => { - const sectionsList: NewChatSectionListData[] = []; + const sections = useMemo((): OptionsListUtils.CategorySection[] => { + const sectionsList: OptionsListUtils.CategorySection[] = []; let indexOffset = 0; const formatResults = OptionsListUtils.formatSectionsFromSearchTerm(searchTerm, selectedOptions, filteredRecentReports, filteredPersonalDetails, {}, false, indexOffset); - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. + sectionsList.push(formatResults.section); - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. + indexOffset = formatResults.newIndexOffset; if (maxParticipantsReached) { @@ -132,17 +121,13 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF } const { - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. recentReports, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. personalDetails: newChatPersonalDetails, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. userToInvite, } = OptionsListUtils.getFilteredOptions( - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. reports, personalDetails, - betas, + betas ?? [], searchTerm, newSelectedOptions, isGroupChat ? excludedGroupEmails : [], @@ -191,17 +176,13 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF const updateOptions = useCallback(() => { const { - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. recentReports, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. personalDetails: newChatPersonalDetails, - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. userToInvite, } = OptionsListUtils.getFilteredOptions( - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/pull/32470) is migrated to TypeScript. reports, personalDetails, - betas, + betas ?? [], searchTerm, selectedOptions, isGroupChat ? excludedGroupEmails : [], @@ -272,7 +253,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF 0 ? safeAreaPaddingBottomStyle : {}]}> Date: Mon, 5 Feb 2024 09:46:35 +0000 Subject: [PATCH 09/10] [TS migration][NewchatPage] TS fix --- src/libs/OptionsListUtils.ts | 2 +- src/pages/NewChatPage.tsx | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 3f1cc5f07ffc..e3be3b2e71ea 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1940,7 +1940,7 @@ function formatSectionsFromSearchTerm( searchTerm: string, selectedOptions: ReportUtils.OptionData[], filteredRecentReports: ReportUtils.OptionData[], - filteredPersonalDetails: PersonalDetails[], + filteredPersonalDetails: ReportUtils.OptionData[], maxOptionsSelected: boolean, indexOffset = 0, personalDetails: OnyxEntry = {}, diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 55364405ba9a..a2ba595342e4 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -2,6 +2,7 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; import KeyboardAvoidingView from '@components/KeyboardAvoidingView'; import OfflineIndicator from '@components/OfflineIndicator'; import OptionsSelector from '@components/OptionsSelector'; @@ -23,7 +24,7 @@ import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; -import {DismissedReferralBanners} from '@src/types/onyx/Account'; +import type {DismissedReferralBanners} from '@src/types/onyx/Account'; type NewChatPageWithOnyxProps = { /** All reports shared with the user */ @@ -230,7 +231,7 @@ function NewChatPage({betas, isGroupChat, personalDetails, reports, isSearchingF updateOptions(); }, [didScreenTransitionEnd, updateOptions]); - const dismissCallToAction = (referralContentType) => { + const dismissCallToAction = (referralContentType: ValueOf) => { User.dismissReferralBanner(referralContentType); }; @@ -294,7 +295,7 @@ NewChatPage.displayName = 'NewChatPage'; export default withOnyx({ dismissedReferralBanners: { key: ONYXKEYS.ACCOUNT, - selector: (data) => data?.dismissedReferralBanners || {}, + selector: (data) => data?.dismissedReferralBanners ?? {}, }, reports: { key: ONYXKEYS.COLLECTION.REPORT, From 6c84b6ea04b22222d7e7d75c8a2cda10f62131dd Mon Sep 17 00:00:00 2001 From: ruben-rebelo Date: Thu, 8 Feb 2024 15:05:16 +0000 Subject: [PATCH 10/10] [TS migration][NewChatPage] Lint fixed --- src/pages/NewChatPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index d2143f827553..7f050f09db50 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -2,7 +2,6 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import type {ValueOf} from 'type-fest'; import KeyboardAvoidingView from '@components/KeyboardAvoidingView'; import OfflineIndicator from '@components/OfflineIndicator'; import OptionsSelector from '@components/OptionsSelector';