From 5a175d9b04f89d53558b6045ba5936440b5ae6bf Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 11:25:28 +0200 Subject: [PATCH 01/10] fix undefined role route --- src/ROUTES.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 9650d323d676..340dd0efcda5 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -355,7 +355,10 @@ const ROUTES = { }, ROOM_INVITE: { route: 'r/:reportID/invite/:role?', - getRoute: (reportID: string, role?: string) => `r/${reportID}/invite/${role}` as const, + getRoute: (reportID: string, role?: string) => { + const route = role ? (`r/${reportID}/invite/${role}` as const) : (`r/${reportID}/invite` as const); + return route; + }, }, MONEY_REQUEST_HOLD_REASON: { route: ':type/edit/reason/:transactionID?', From 0d3cc6e311af6b3f7929cb1236d63b1169560dec Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 14:34:57 +0200 Subject: [PATCH 02/10] move search state to onyx wip --- src/ONYXKEYS.ts | 4 ++++ src/libs/actions/UserSearchPhrase.ts | 15 +++++++++++++++ src/pages/RoomInvitePage.tsx | 15 ++++++--------- src/pages/RoomMembersPage.tsx | 17 ++++++++++++----- 4 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/libs/actions/UserSearchPhrase.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 7102d6396381..06b2603deadb 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -400,6 +400,9 @@ const ONYXKEYS = { /** Stores the information about currently edited advanced approval workflow */ APPROVAL_WORKFLOW: 'approvalWorkflow', + /** Stores the user search value for persistance across the screens */ + USER_SEARCH_PHRASE: 'userSearchPhrase', + /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', @@ -879,6 +882,7 @@ type OnyxValuesMapping = { [ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip; [ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[]; [ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflow; + [ONYXKEYS.USER_SEARCH_PHRASE]: string; }; type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; diff --git a/src/libs/actions/UserSearchPhrase.ts b/src/libs/actions/UserSearchPhrase.ts new file mode 100644 index 000000000000..d1104776dc46 --- /dev/null +++ b/src/libs/actions/UserSearchPhrase.ts @@ -0,0 +1,15 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '@src/ONYXKEYS'; + +function clearUserSearchPhrase() { + Onyx.set(ONYXKEYS.USER_SEARCH_PHRASE, ''); +} + +/** + * Persists user search phrase from the serch input across the screens. + */ +function updateUserSearchPhrase(value: string) { + Onyx.merge(ONYXKEYS.USER_SEARCH_PHRASE, value); +} + +export {clearUserSearchPhrase as clearUserSearchValue, updateUserSearchPhrase}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index 17239e6d4fb5..3399985cb7eb 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -18,6 +18,7 @@ import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportActions from '@libs/actions/Report'; +import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; import {READ_COMMANDS} from '@libs/API/types'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import HttpUtils from '@libs/HttpUtils'; @@ -38,7 +39,6 @@ import type {Policy} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; import withReportOrNotFound from './home/report/withReportOrNotFound'; -import SearchInputManager from './workspace/SearchInputManager'; type RoomInvitePageProps = WithReportOrNotFoundProps & WithNavigationTransitionEndProps & StackScreenProps; @@ -53,15 +53,12 @@ function RoomInvitePage({ }: RoomInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); + const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(userSearchPhrase ?? ''); const [selectedOptions, setSelectedOptions] = useState([]); const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); - const {options, areOptionsInitialized} = useOptionsList(); - useEffect(() => { - setSearchTerm(SearchInputManager.searchInput); - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, []); + const {options, areOptionsInitialized} = useOptionsList(); // Any existing participants and Expensify emails should not be eligible for invitation const excludedUsers = useMemo(() => { @@ -207,7 +204,7 @@ function RoomInvitePage({ if (reportID) { Report.inviteToRoom(reportID, invitedEmailsToAccountIDs); } - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchValue(); Navigation.navigate(backRoute); }, [selectedOptions, backRoute, reportID, validate]); @@ -239,6 +236,7 @@ function RoomInvitePage({ }, [debouncedSearchTerm, inviteOptions.userToInvite, inviteOptions.personalDetails, excludedUsers, translate, reportName]); useEffect(() => { + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); ReportActions.searchInServer(debouncedSearchTerm); }, [debouncedSearchTerm]); @@ -265,7 +263,6 @@ function RoomInvitePage({ textInputLabel={translate('selectionList.nameEmailOrPhoneNumber')} textInputValue={searchTerm} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchTerm(value); }} headerMessage={headerMessage} diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 896b3d10162a..18e039d7581e 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -2,7 +2,7 @@ import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx, withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import Button from '@components/Button'; @@ -16,8 +16,10 @@ import type {ListItem} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import localeCompare from '@libs/LocaleCompare'; import Log from '@libs/Log'; @@ -53,7 +55,8 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const {formatPhoneNumber, translate} = useLocalize(); const [selectedMembers, setSelectedMembers] = useState([]); const [removeMembersConfirmModalVisible, setRemoveMembersConfirmModalVisible] = useState(false); - const [searchValue, setSearchValue] = useState(''); + const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(userSearchPhrase ?? ''); const [didLoadRoomMembers, setDidLoadRoomMembers] = useState(false); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? ''}`], [policies, report?.policyID]); @@ -61,13 +64,17 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const isFocusedScreen = useIsFocused(); + // useEffect(() => { + // setSearchValue(userSearchPhrase); + // }, [isFocusedScreen]); + useEffect(() => { - setSearchValue(SearchInputManager.searchInput); - }, [isFocusedScreen]); + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); + }, [debouncedSearchTerm]); useEffect( () => () => { - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchValue(); }, [], ); From 75654cf952b9b07ff6fa57998ed7ec0015f7dfff Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:03:25 +0200 Subject: [PATCH 03/10] apply onyx search persist to the members flow --- src/pages/RoomMembersPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 18e039d7581e..1d2a7aa60666 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -64,9 +64,9 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const isFocusedScreen = useIsFocused(); - // useEffect(() => { - // setSearchValue(userSearchPhrase); - // }, [isFocusedScreen]); + useEffect(() => { + setSearchValue(userSearchPhrase ?? ''); + }, [isFocusedScreen, setSearchValue, userSearchPhrase]); useEffect(() => { UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); From f06810d56b3e8750f155f1260aed0f1a35c40eed Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:15:52 +0200 Subject: [PATCH 04/10] cleanup --- src/pages/RoomMembersPage.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 1d2a7aa60666..b72df5a36bd0 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -39,7 +39,6 @@ import type {Session} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; import withReportOrNotFound from './home/report/withReportOrNotFound'; -import SearchInputManager from './workspace/SearchInputManager'; type RoomMembersPageOnyxProps = { session: OnyxEntry; @@ -56,7 +55,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const [selectedMembers, setSelectedMembers] = useState([]); const [removeMembersConfirmModalVisible, setRemoveMembersConfirmModalVisible] = useState(false); const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); - const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(userSearchPhrase ?? ''); + const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(''); const [didLoadRoomMembers, setDidLoadRoomMembers] = useState(false); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? ''}`], [policies, report?.policyID]); @@ -68,10 +67,6 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { setSearchValue(userSearchPhrase ?? ''); }, [isFocusedScreen, setSearchValue, userSearchPhrase]); - useEffect(() => { - UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); - }, [debouncedSearchTerm]); - useEffect( () => () => { UserSearchPhraseActions.clearUserSearchValue(); @@ -79,6 +74,10 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { [], ); + useEffect(() => { + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); + }, [debouncedSearchTerm]); + /** * Get members for the current room */ @@ -302,7 +301,6 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { disableKeyboardShortcuts={removeMembersConfirmModalVisible} textInputValue={searchValue} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchValue(value); }} headerMessage={headerMessage} From d6df1ba1b0f215ffb8ecf2972f96b885f7cafb28 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:36:30 +0200 Subject: [PATCH 05/10] remove persist from workspace invite page --- src/pages/workspace/WorkspaceInvitePage.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInvitePage.tsx b/src/pages/workspace/WorkspaceInvitePage.tsx index c29819b3c6f9..ad48d15aa9df 100644 --- a/src/pages/workspace/WorkspaceInvitePage.tsx +++ b/src/pages/workspace/WorkspaceInvitePage.tsx @@ -38,7 +38,6 @@ import type {Beta, InvitedEmailsToAccountIDs} from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; -import SearchInputManager from './SearchInputManager'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; @@ -77,7 +76,6 @@ function WorkspaceInvitePage({route, betas, invitedEmailsToAccountIDsDraft, poli }); useEffect(() => { - setSearchTerm(SearchInputManager.searchInput); return () => { Member.setWorkspaceInviteMembersDraft(route.params.policyID, {}); }; @@ -338,7 +336,6 @@ function WorkspaceInvitePage({route, betas, invitedEmailsToAccountIDsDraft, poli textInputLabel={translate('selectionList.nameEmailOrPhoneNumber')} textInputValue={searchTerm} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchTerm(value); }} headerMessage={headerMessage} From 30ff249c389db433f9640283d679ad4cd588d656 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:38:29 +0200 Subject: [PATCH 06/10] cleanup --- src/libs/Navigation/AppNavigator/AuthScreens.tsx | 3 --- src/pages/workspace/SearchInputManager.ts | 5 ----- src/pages/workspace/WorkspaceInviteMessagePage.tsx | 2 -- 3 files changed, 10 deletions(-) delete mode 100644 src/pages/workspace/SearchInputManager.ts diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 64816562a507..cac4337e2f7f 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -27,7 +27,6 @@ import * as SessionUtils from '@libs/SessionUtils'; import ConnectionCompletePage from '@pages/ConnectionCompletePage'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import DesktopSignInRedirectPage from '@pages/signin/DesktopSignInRedirectPage'; -import SearchInputManager from '@pages/workspace/SearchInputManager'; import * as App from '@userActions/App'; import * as Download from '@userActions/Download'; import * as Modal from '@userActions/Modal'; @@ -174,8 +173,6 @@ const modalScreenListeners = { Modal.setModalVisibility(false); }, beforeRemove: () => { - // Clear search input (WorkspaceInvitePage) when modal is closed - SearchInputManager.searchInput = ''; Modal.setModalVisibility(false); Modal.willAlertModalBecomeVisible(false); }, diff --git a/src/pages/workspace/SearchInputManager.ts b/src/pages/workspace/SearchInputManager.ts deleted file mode 100644 index 599f7cca6cf9..000000000000 --- a/src/pages/workspace/SearchInputManager.ts +++ /dev/null @@ -1,5 +0,0 @@ -// eslint-disable-next-line prefer-const -let searchInput = ''; -export default { - searchInput, -}; diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/WorkspaceInviteMessagePage.tsx index df34875f5fa6..ff5b7326af84 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/WorkspaceInviteMessagePage.tsx @@ -38,7 +38,6 @@ import INPUT_IDS from '@src/types/form/WorkspaceInviteMessageForm'; import type {InvitedEmailsToAccountIDs, PersonalDetailsList} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; -import SearchInputManager from './SearchInputManager'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; @@ -110,7 +109,6 @@ function WorkspaceInviteMessagePage({ // Please see https://github.com/Expensify/App/blob/main/README.md#Security for more details Member.addMembersToWorkspace(invitedEmailsToAccountIDsDraft ?? {}, `${welcomeNoteSubject}\n\n${welcomeNote}`, route.params.policyID); debouncedSaveDraft(null); - SearchInputManager.searchInput = ''; Navigation.dismissModal(); }; From a3118679ab75105e3319be4e71b623393c7f8a32 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 15:49:22 +0200 Subject: [PATCH 07/10] cleanup --- src/ONYXKEYS.ts | 4 ++-- .../{UserSearchPhrase.ts => RoomMembersUserSearchPhrase.ts} | 4 ++-- src/pages/RoomInvitePage.tsx | 4 ++-- src/pages/RoomMembersPage.tsx | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/libs/actions/{UserSearchPhrase.ts => RoomMembersUserSearchPhrase.ts} (72%) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 06b2603deadb..4c358e73a5a5 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -401,7 +401,7 @@ const ONYXKEYS = { APPROVAL_WORKFLOW: 'approvalWorkflow', /** Stores the user search value for persistance across the screens */ - USER_SEARCH_PHRASE: 'userSearchPhrase', + ROOM_MEMBERS_USER_SEARCH_PHRASE: 'roomMembersUserSearchPhrase', /** Collection Keys */ COLLECTION: { @@ -882,7 +882,7 @@ type OnyxValuesMapping = { [ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip; [ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[]; [ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflow; - [ONYXKEYS.USER_SEARCH_PHRASE]: string; + [ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE]: string; }; type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; diff --git a/src/libs/actions/UserSearchPhrase.ts b/src/libs/actions/RoomMembersUserSearchPhrase.ts similarity index 72% rename from src/libs/actions/UserSearchPhrase.ts rename to src/libs/actions/RoomMembersUserSearchPhrase.ts index d1104776dc46..4267e0a73f43 100644 --- a/src/libs/actions/UserSearchPhrase.ts +++ b/src/libs/actions/RoomMembersUserSearchPhrase.ts @@ -2,14 +2,14 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; function clearUserSearchPhrase() { - Onyx.set(ONYXKEYS.USER_SEARCH_PHRASE, ''); + Onyx.set(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, ''); } /** * Persists user search phrase from the serch input across the screens. */ function updateUserSearchPhrase(value: string) { - Onyx.merge(ONYXKEYS.USER_SEARCH_PHRASE, value); + Onyx.merge(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, value); } export {clearUserSearchPhrase as clearUserSearchValue, updateUserSearchPhrase}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index 3399985cb7eb..95fe77a6ec72 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -18,7 +18,7 @@ import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportActions from '@libs/actions/Report'; -import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; +import * as UserSearchPhraseActions from '@libs/actions/RoomMembersUserSearchPhrase'; import {READ_COMMANDS} from '@libs/API/types'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import HttpUtils from '@libs/HttpUtils'; @@ -53,7 +53,7 @@ function RoomInvitePage({ }: RoomInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [userSearchPhrase] = useOnyx(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE); const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(userSearchPhrase ?? ''); const [selectedOptions, setSelectedOptions] = useState([]); const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index b72df5a36bd0..4b60b509bbed 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -19,7 +19,7 @@ import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalD import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as UserSearchPhraseActions from '@libs/actions/UserSearchPhrase'; +import * as UserSearchPhraseActions from '@libs/actions/RoomMembersUserSearchPhrase'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import localeCompare from '@libs/LocaleCompare'; import Log from '@libs/Log'; @@ -54,7 +54,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { const {formatPhoneNumber, translate} = useLocalize(); const [selectedMembers, setSelectedMembers] = useState([]); const [removeMembersConfirmModalVisible, setRemoveMembersConfirmModalVisible] = useState(false); - const [userSearchPhrase] = useOnyx(ONYXKEYS.USER_SEARCH_PHRASE); + const [userSearchPhrase] = useOnyx(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE); const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(''); const [didLoadRoomMembers, setDidLoadRoomMembers] = useState(false); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; From ba8b96048ef5e1bf066c764be7052094776e348f Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 8 Aug 2024 17:02:45 +0200 Subject: [PATCH 08/10] review fixes --- src/libs/actions/RoomMembersUserSearchPhrase.ts | 4 ++-- src/pages/RoomInvitePage.tsx | 2 +- src/pages/RoomMembersPage.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/RoomMembersUserSearchPhrase.ts b/src/libs/actions/RoomMembersUserSearchPhrase.ts index 4267e0a73f43..1395b1ecec7f 100644 --- a/src/libs/actions/RoomMembersUserSearchPhrase.ts +++ b/src/libs/actions/RoomMembersUserSearchPhrase.ts @@ -2,7 +2,7 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; function clearUserSearchPhrase() { - Onyx.set(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, ''); + Onyx.merge(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, ''); } /** @@ -12,4 +12,4 @@ function updateUserSearchPhrase(value: string) { Onyx.merge(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE, value); } -export {clearUserSearchPhrase as clearUserSearchValue, updateUserSearchPhrase}; +export {clearUserSearchPhrase, updateUserSearchPhrase}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index 95fe77a6ec72..d08c7b18b3be 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -204,7 +204,7 @@ function RoomInvitePage({ if (reportID) { Report.inviteToRoom(reportID, invitedEmailsToAccountIDs); } - UserSearchPhraseActions.clearUserSearchValue(); + UserSearchPhraseActions.clearUserSearchPhrase(); Navigation.navigate(backRoute); }, [selectedOptions, backRoute, reportID, validate]); diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index 4b60b509bbed..0bc8602aa45d 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -69,7 +69,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { useEffect( () => () => { - UserSearchPhraseActions.clearUserSearchValue(); + UserSearchPhraseActions.clearUserSearchPhrase(); }, [], ); From 86db79caaf07e7d58ca870a9bfe55ac3b9cd7f90 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 28 Aug 2024 10:44:49 +0200 Subject: [PATCH 09/10] cleanup --- src/ONYXKEYS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index ad3255dc1ca0..562ddb844e6e 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -402,6 +402,7 @@ const ONYXKEYS = { /** Stores the user search value for persistance across the screens */ ROOM_MEMBERS_USER_SEARCH_PHRASE: 'roomMembersUserSearchPhrase', + /** Stores the route to open after changing app permission from settings */ LAST_ROUTE: 'lastRoute', From dd1158276253fffd3a45f671e5f31cf124c3a0b9 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Tue, 10 Sep 2024 13:06:15 +0200 Subject: [PATCH 10/10] replace search input manager for the updated screens --- src/pages/InviteReportParticipantsPage.tsx | 37 +++++++++++----------- src/pages/ReportParticipantsPage.tsx | 22 +++++++------ src/pages/RoomMembersPage.tsx | 4 +-- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/pages/InviteReportParticipantsPage.tsx b/src/pages/InviteReportParticipantsPage.tsx index 5a3b69aa628f..0308982f382c 100644 --- a/src/pages/InviteReportParticipantsPage.tsx +++ b/src/pages/InviteReportParticipantsPage.tsx @@ -1,7 +1,7 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; import type {SectionListData} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx, withOnyx} from 'react-native-onyx'; import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {useOptionsList} from '@components/OptionListContextProvider'; @@ -14,6 +14,7 @@ import type {WithNavigationTransitionEndProps} from '@components/withNavigationT import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as UserSearchPhraseActions from '@libs/actions/RoomMembersUserSearchPhrase'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as LoginUtils from '@libs/LoginUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -28,7 +29,6 @@ import ROUTES from '@src/ROUTES'; import type {InvitedEmailsToAccountIDs, PersonalDetailsList} from '@src/types/onyx'; import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; import withReportOrNotFound from './home/report/withReportOrNotFound'; -import SearchInputManager from './workspace/SearchInputManager'; type InviteReportParticipantsPageOnyxProps = { /** All of the personal details for everyone */ @@ -46,13 +46,13 @@ function InviteReportParticipantsPage({betas, personalDetails, report, didScreen const styles = useThemeStyles(); const {translate} = useLocalize(); - const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); + const [userSearchPhrase] = useOnyx(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE); + const [searchValue, debouncedSearchTerm, setSearchValue] = useDebouncedState(userSearchPhrase ?? ''); const [selectedOptions, setSelectedOptions] = useState([]); useEffect(() => { - setSearchTerm(SearchInputManager.searchInput); - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, []); + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchTerm); + }, [debouncedSearchTerm]); // Any existing participants and Expensify emails should not be eligible for invitation const excludedUsers = useMemo( @@ -104,8 +104,8 @@ function InviteReportParticipantsPage({betas, personalDetails, report, didScreen filterSelectedOptions = selectedOptions.filter((option) => { const accountID = option?.accountID; const isOptionInPersonalDetails = inviteOptions.personalDetails.some((personalDetail) => accountID && personalDetail?.accountID === accountID); - const searchValue = OptionsListUtils.getSearchValueForPhoneOrEmail(debouncedSearchTerm); - const isPartOfSearchTerm = !!option.text?.toLowerCase().includes(searchValue) || !!option.login?.toLowerCase().includes(searchValue); + const processedSearchValue = OptionsListUtils.getSearchValueForPhoneOrEmail(debouncedSearchTerm); + const isPartOfSearchTerm = !!option.text?.toLowerCase().includes(processedSearchValue) || !!option.login?.toLowerCase().includes(processedSearchValue); return isPartOfSearchTerm || isOptionInPersonalDetails; }); } @@ -183,22 +183,22 @@ function InviteReportParticipantsPage({betas, personalDetails, report, didScreen }, [selectedOptions, backRoute, reportID, validate]); const headerMessage = useMemo(() => { - const searchValue = debouncedSearchTerm.trim().toLowerCase(); + const processedLogin = debouncedSearchTerm.trim().toLowerCase(); const expensifyEmails = CONST.EXPENSIFY_EMAILS as string[]; - if (!inviteOptions.userToInvite && expensifyEmails.includes(searchValue)) { + if (!inviteOptions.userToInvite && expensifyEmails.includes(processedLogin)) { return translate('messages.errorMessageInvalidEmail'); } if ( !inviteOptions.userToInvite && excludedUsers.includes( - PhoneNumber.parsePhoneNumber(LoginUtils.appendCountryCode(searchValue)).possible - ? PhoneNumber.addSMSDomainIfPhoneNumber(LoginUtils.appendCountryCode(searchValue)) - : searchValue, + PhoneNumber.parsePhoneNumber(LoginUtils.appendCountryCode(processedLogin)).possible + ? PhoneNumber.addSMSDomainIfPhoneNumber(LoginUtils.appendCountryCode(processedLogin)) + : processedLogin, ) ) { - return translate('messages.userIsAlreadyMember', {login: searchValue, name: reportName ?? ''}); + return translate('messages.userIsAlreadyMember', {login: processedLogin, name: reportName ?? ''}); } - return OptionsListUtils.getHeaderMessage(inviteOptions.recentReports.length + inviteOptions.personalDetails.length !== 0, !!inviteOptions.userToInvite, searchValue); + return OptionsListUtils.getHeaderMessage(inviteOptions.recentReports.length + inviteOptions.personalDetails.length !== 0, !!inviteOptions.userToInvite, processedLogin); }, [debouncedSearchTerm, inviteOptions.userToInvite, inviteOptions.recentReports.length, inviteOptions.personalDetails.length, excludedUsers, translate, reportName]); const footerContent = useMemo( @@ -207,7 +207,7 @@ function InviteReportParticipantsPage({betas, personalDetails, report, didScreen isDisabled={!selectedOptions.length} buttonText={translate('common.invite')} onSubmit={() => { - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchPhrase(); inviteUsers(); }} containerStyles={[styles.flexReset, styles.flexGrow0, styles.flexShrink0, styles.flexBasisAuto]} @@ -236,10 +236,9 @@ function InviteReportParticipantsPage({betas, personalDetails, report, didScreen sections={sections} ListItem={InviteMemberListItem} textInputLabel={translate('selectionList.nameEmailOrPhoneNumber')} - textInputValue={searchTerm} + textInputValue={searchValue} onChangeText={(value) => { - SearchInputManager.searchInput = value; - setSearchTerm(value); + setSearchValue(value); }} headerMessage={headerMessage} onSelectRow={toggleOption} diff --git a/src/pages/ReportParticipantsPage.tsx b/src/pages/ReportParticipantsPage.tsx index c99ef44688cb..ad7c73b50307 100755 --- a/src/pages/ReportParticipantsPage.tsx +++ b/src/pages/ReportParticipantsPage.tsx @@ -17,6 +17,7 @@ import TableListItem from '@components/SelectionList/TableListItem'; import type {ListItem, SelectionListHandle} from '@components/SelectionList/types'; import SelectionListWithModal from '@components/SelectionListWithModal'; import Text from '@components/Text'; +import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useNetwork from '@hooks/useNetwork'; @@ -25,6 +26,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import {turnOffMobileSelectionMode} from '@libs/actions/MobileSelectionMode'; import * as Report from '@libs/actions/Report'; +import * as UserSearchPhraseActions from '@libs/actions/RoomMembersUserSearchPhrase'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; @@ -34,7 +36,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {WithReportOrNotFoundProps} from './home/report/withReportOrNotFound'; import withReportOrNotFound from './home/report/withReportOrNotFound'; -import SearchInputManager from './workspace/SearchInputManager'; type MemberOption = Omit & {accountID: number}; @@ -47,6 +48,7 @@ function ReportParticipantsPage({report}: WithReportOrNotFoundProps) { const {shouldUseNarrowLayout, isSmallScreenWidth} = useResponsiveLayout(); const selectionListRef = useRef(null); const textInputRef = useRef(null); + const [userSearchPhrase] = useOnyx(ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE); const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID ?? -1}`); const {selectionMode} = useMobileSelectionMode(); const [session] = useOnyx(ONYXKEYS.SESSION); @@ -57,15 +59,19 @@ function ReportParticipantsPage({report}: WithReportOrNotFoundProps) { const isFocused = useIsFocused(); const {isOffline} = useNetwork(); const canSelectMultiple = isGroupChat && isCurrentUserAdmin && (isSmallScreenWidth ? selectionMode?.isEnabled : true); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState(''); useEffect( () => () => { - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchPhrase(); }, [], ); + useEffect(() => { + UserSearchPhraseActions.updateUserSearchPhrase(debouncedSearchValue); + }, [debouncedSearchValue]); + useEffect(() => { if (isFocused) { return; @@ -96,12 +102,12 @@ function ReportParticipantsPage({report}: WithReportOrNotFoundProps) { return; } if (shouldShowTextInput) { - setSearchValue(SearchInputManager.searchInput); + setSearchValue(userSearchPhrase ?? ''); } else { - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchPhrase(); setSearchValue(''); } - }, [isFocused, shouldShowTextInput]); + }, [isFocused, setSearchValue, shouldShowTextInput, userSearchPhrase]); const getParticipants = () => { let result: MemberOption[] = []; @@ -186,7 +192,6 @@ function ReportParticipantsPage({report}: WithReportOrNotFoundProps) { * Open the modal to invite a user */ const inviteUser = useCallback(() => { - setSearchValue(''); Navigation.navigate(ROUTES.REPORT_PARTICIPANTS_INVITE.getRoute(report.reportID)); }, [report]); @@ -199,7 +204,7 @@ function ReportParticipantsPage({report}: WithReportOrNotFoundProps) { const accountIDsToRemove = selectedMembers.filter((id) => id !== currentUserAccountID); Report.removeFromGroupChat(report.reportID, accountIDsToRemove); setSearchValue(''); - SearchInputManager.searchInput = ''; + UserSearchPhraseActions.clearUserSearchPhrase(); setSelectedMembers([]); setRemoveMembersConfirmModalVisible(false); }; @@ -404,7 +409,6 @@ function ReportParticipantsPage({report}: WithReportOrNotFoundProps) { textInputLabel={translate('selectionList.findMember')} textInputValue={searchValue} onChangeText={(value) => { - SearchInputManager.searchInput = value; setSearchValue(value); }} headerMessage={headerMessage} diff --git a/src/pages/RoomMembersPage.tsx b/src/pages/RoomMembersPage.tsx index b8c893eb0f87..41003d9bfb8b 100644 --- a/src/pages/RoomMembersPage.tsx +++ b/src/pages/RoomMembersPage.tsx @@ -114,7 +114,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { } setSearchValue(''); Navigation.navigate(ROUTES.ROOM_INVITE.getRoute(report.reportID)); - }, [report]); + }, [report, setSearchValue]); /** * Remove selected users from the room @@ -205,7 +205,7 @@ function RoomMembersPage({report, session, policies}: RoomMembersPageProps) { UserSearchPhraseActions.clearUserSearchPhrase(); setSearchValue(''); } - }, [isFocusedScreen, shouldShowTextInput]); + }, [isFocusedScreen, setSearchValue, shouldShowTextInput, userSearchPhrase]); const data = useMemo((): ListItem[] => { let result: ListItem[] = [];