From 42973c80773201181bfc4d5a7c37749b8616e8c3 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 16 Dec 2024 15:09:09 +0100 Subject: [PATCH 01/46] remove canUseCombinedTrackSubmit function --- src/components/ReportWelcomeText.tsx | 4 +--- src/libs/Permissions.ts | 10 ---------- src/libs/ReportUtils.ts | 4 +--- src/libs/actions/Report.ts | 16 +++++++--------- .../AttachmentPickerWithMenuItems.tsx | 17 ++++++----------- src/pages/iou/request/IOURequestStartPage.tsx | 6 ++---- 6 files changed, 17 insertions(+), 40 deletions(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index cc7dbed1f6e9..a9018104d4f1 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -3,7 +3,6 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -47,7 +46,6 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { const welcomeMessage = SidebarUtils.getWelcomeMessage(report, policy); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const canEditReportDescription = ReportUtils.canEditReportDescription(report, policy); - const {canUseCombinedTrackSubmit} = usePermissions(); const filteredOptions = moneyRequestOptions.filter( (item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE, @@ -56,7 +54,7 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { .map( (item, index) => `${index === filteredOptions.length - 1 && index > 0 ? `${translate('common.or')} ` : ''}${translate( - canUseCombinedTrackSubmit && item === 'submit' ? `reportActionsView.create` : `reportActionsView.iouTypes.${item}`, + item === 'submit' ? `reportActionsView.create` : `reportActionsView.iouTypes.${item}`, )}`, ) .join(', '); diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 4a7bba3932a3..146de150c164 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -1,9 +1,6 @@ import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; -import * as SessionUtils from './SessionUtils'; - -const isAccountIDEven = (accountID: number) => accountID % 2 === 0; function canUseAllBetas(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.ALL); @@ -25,12 +22,6 @@ function canUseCategoryAndTagApprovers(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.CATEGORY_AND_TAG_APPROVERS) || canUseAllBetas(betas); } -function canUseCombinedTrackSubmit(): boolean { - // We don't need to show this to all betas since this will be used for developing a feature for A/B testing. - const session = SessionUtils.getSession(); - return isAccountIDEven(session?.accountID ?? -1); -} - function canUsePerDiem(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.PER_DIEM) || canUseAllBetas(betas); } @@ -47,7 +38,6 @@ export default { canUseLinkPreviews, canUseSpotnanaTravel, canUseNetSuiteUSATax, - canUseCombinedTrackSubmit, canUseCategoryAndTagApprovers, canUsePerDiem, }; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index eb728586f8f2..f655e95e32fa 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -7351,9 +7351,7 @@ function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, } const requestOptions = getMoneyRequestOptions(report, policy, participantAccountIDs); - if (Permissions.canUseCombinedTrackSubmit()) { - requestOptions.push(CONST.IOU.TYPE.CREATE); - } + requestOptions.push(CONST.IOU.TYPE.CREATE); return requestOptions.includes(iouType); } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 7baf66adc5c5..f088462dc562 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3518,16 +3518,14 @@ function prepareOnboardingOptimisticData( wasInvited?: boolean, ) { // If the user has the "combinedTrackSubmit" beta enabled we'll show different tasks for track and submit expense. - if (Permissions.canUseCombinedTrackSubmit()) { - if (engagementChoice === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND) { - // eslint-disable-next-line no-param-reassign - data = CONST.COMBINED_TRACK_SUBMIT_ONBOARDING_MESSAGES[CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]; - } + if (engagementChoice === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND) { + // eslint-disable-next-line no-param-reassign + data = CONST.COMBINED_TRACK_SUBMIT_ONBOARDING_MESSAGES[CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]; + } - if (engagementChoice === CONST.ONBOARDING_CHOICES.EMPLOYER || engagementChoice === CONST.ONBOARDING_CHOICES.SUBMIT) { - // eslint-disable-next-line no-param-reassign - data = CONST.COMBINED_TRACK_SUBMIT_ONBOARDING_MESSAGES[CONST.ONBOARDING_CHOICES.SUBMIT]; - } + if (engagementChoice === CONST.ONBOARDING_CHOICES.EMPLOYER || engagementChoice === CONST.ONBOARDING_CHOICES.SUBMIT) { + // eslint-disable-next-line no-param-reassign + data = CONST.COMBINED_TRACK_SUBMIT_ONBOARDING_MESSAGES[CONST.ONBOARDING_CHOICES.SUBMIT]; } // Guides are assigned and tasks are posted in the #admins room for the MANAGE_TEAM onboarding action, except for emails that have a '+'. diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index b182bf43a52b..be19706465e3 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -12,7 +12,6 @@ import PopoverMenu from '@components/PopoverMenu'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; @@ -121,7 +120,6 @@ function AttachmentPickerWithMenuItems({ const {isDelegateAccessRestricted} = useDelegateUserDetails(); const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); - const {canUseCombinedTrackSubmit} = usePermissions(); /** * Returns the list of IOU Options @@ -143,8 +141,8 @@ function AttachmentPickerWithMenuItems({ onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, report?.reportID ?? '-1'), true), }, [CONST.IOU.TYPE.SUBMIT]: { - icon: canUseCombinedTrackSubmit ? getIconForAction(CONST.IOU.TYPE.CREATE) : getIconForAction(CONST.IOU.TYPE.REQUEST), - text: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.submitExpense'), + icon: getIconForAction(CONST.IOU.TYPE.CREATE), + text: translate('iou.createExpense'), onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, report?.reportID ?? '-1'), true), }, [CONST.IOU.TYPE.PAY]: { @@ -159,8 +157,8 @@ function AttachmentPickerWithMenuItems({ }, }, [CONST.IOU.TYPE.TRACK]: { - icon: canUseCombinedTrackSubmit ? getIconForAction(CONST.IOU.TYPE.CREATE) : getIconForAction(CONST.IOU.TYPE.TRACK), - text: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.trackExpense'), + icon: getIconForAction(CONST.IOU.TYPE.CREATE), + text: translate('iou.createExpense'), onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? '-1'), true), }, [CONST.IOU.TYPE.INVOICE]: { @@ -174,11 +172,8 @@ function AttachmentPickerWithMenuItems({ ...options[option], })); - return canUseCombinedTrackSubmit - ? // Removes track option for the workspace with the canUseCombinedTrackSubmit enabled - moneyRequestOptionsList.filter((item, index, self) => index === self.findIndex((t) => t.text === item.text)) - : moneyRequestOptionsList; - }, [translate, canUseCombinedTrackSubmit, report, policy, reportParticipantIDs, isDelegateAccessRestricted]); + return moneyRequestOptionsList.filter((item, index, self) => index === self.findIndex((t) => t.text === item.text)); + }, [translate, report, policy, reportParticipantIDs, isDelegateAccessRestricted]); /** * Determines if we can show the task option diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 78dac9220742..0794c1142eff 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -8,7 +8,6 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TabSelector from '@components/TabSelector/TabSelector'; import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; @@ -48,15 +47,14 @@ function IOURequestStartPage({ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${route?.params.transactionID || -1}`); const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); - const {canUseCombinedTrackSubmit} = usePermissions(); const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'), - [CONST.IOU.TYPE.SUBMIT]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.submitExpense'), + [CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'), [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', {name: ReportUtils.getPayeeName(report)}), [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', {name: ReportUtils.getPayeeName(report)}), [CONST.IOU.TYPE.SPLIT]: translate('iou.createExpense'), - [CONST.IOU.TYPE.TRACK]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.trackExpense'), + [CONST.IOU.TYPE.TRACK]: translate('iou.createExpense'), [CONST.IOU.TYPE.INVOICE]: translate('workspace.invoices.sendInvoice'), [CONST.IOU.TYPE.CREATE]: translate('iou.createExpense'), }; From ff7f4e00c3e40ccfadedc6e568413d317396318b Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 18 Dec 2024 15:05:22 +0100 Subject: [PATCH 02/46] fix ID fallback warnings --- src/components/ReportWelcomeText.tsx | 8 ++++---- src/libs/actions/Report.ts | 1 - .../AttachmentPickerWithMenuItems.tsx | 10 +++++----- src/pages/iou/request/IOURequestStartPage.tsx | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index a9018104d4f1..7ebefe25144f 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -108,7 +108,7 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { if (!canEditPolicyDescription) { return; } - Navigation.navigate(ROUTES.WORKSPACE_PROFILE_DESCRIPTION.getRoute(policy?.id ?? '-1')); + Navigation.navigate(ROUTES.WORKSPACE_PROFILE_DESCRIPTION.getRoute(policy?.id ?? String(CONST.DEFAULT_NUMBER_ID))); }} style={[styles.renderHTML, canEditPolicyDescription ? styles.cursorPointer : styles.cursorText]} accessibilityLabel={translate('reportDescriptionPage.roomDescription')} @@ -133,7 +133,7 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { return; } const activeRoute = Navigation.getActiveRoute(); - Navigation.navigate(ROUTES.REPORT_DESCRIPTION.getRoute(report?.reportID ?? '-1', activeRoute)); + Navigation.navigate(ROUTES.REPORT_DESCRIPTION.getRoute(report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID), activeRoute)); }} style={[styles.renderHTML, canEditReportDescription ? styles.cursorPointer : styles.cursorText]} accessibilityLabel={translate('reportDescriptionPage.roomDescription')} @@ -162,10 +162,10 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { onPress={() => { const activeRoute = Navigation.getActiveRoute(); if (canEditReportDescription) { - Navigation.navigate(ROUTES.REPORT_DESCRIPTION.getRoute(report?.reportID ?? '-1', activeRoute)); + Navigation.navigate(ROUTES.REPORT_DESCRIPTION.getRoute(report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID), activeRoute)); return; } - Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? '-1', activeRoute)); + Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID), activeRoute)); }} style={styles.renderHTML} accessibilityLabel={translate('reportDescriptionPage.roomDescription')} diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index f088462dc562..d6caa6c70fc9 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -73,7 +73,6 @@ import enhanceParameters from '@libs/Network/enhanceParameters'; import type {NetworkStatus} from '@libs/NetworkConnection'; import LocalNotification from '@libs/Notification/LocalNotification'; import Parser from '@libs/Parser'; -import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils'; diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index be19706465e3..2354605c72c9 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -138,12 +138,12 @@ function AttachmentPickerWithMenuItems({ [CONST.IOU.TYPE.SPLIT]: { icon: Expensicons.Transfer, text: translate('iou.splitExpense'), - onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, report?.reportID ?? '-1'), true), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID)), true), }, [CONST.IOU.TYPE.SUBMIT]: { icon: getIconForAction(CONST.IOU.TYPE.CREATE), text: translate('iou.createExpense'), - onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, report?.reportID ?? '-1'), true), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID)), true), }, [CONST.IOU.TYPE.PAY]: { icon: getIconForAction(CONST.IOU.TYPE.SEND), @@ -153,18 +153,18 @@ function AttachmentPickerWithMenuItems({ setIsNoDelegateAccessMenuVisible(true); return; } - selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.PAY, report?.reportID ?? '-1'), false); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.PAY, report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID)), false); }, }, [CONST.IOU.TYPE.TRACK]: { icon: getIconForAction(CONST.IOU.TYPE.CREATE), text: translate('iou.createExpense'), - onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? '-1'), true), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID)), true), }, [CONST.IOU.TYPE.INVOICE]: { icon: Expensicons.InvoiceGeneric, text: translate('workspace.invoices.sendInvoice'), - onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.INVOICE, report?.reportID ?? '-1'), false), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.INVOICE, report?.reportID ?? String(CONST.DEFAULT_NUMBER_ID)), false), }, }; diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 0794c1142eff..d6e9c7e5e534 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -45,7 +45,7 @@ function IOURequestStartPage({ const [selectedTab = CONST.TAB_REQUEST.SCAN, selectedTabResult] = useOnyx(`${ONYXKEYS.COLLECTION.SELECTED_TAB}${CONST.TAB.IOU_REQUEST_TYPE}`); const isLoadingSelectedTab = shouldUseTab ? isLoadingOnyxValue(selectedTabResult) : false; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${route?.params.transactionID || -1}`); + const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${route?.params.transactionID ?? CONST.DEFAULT_NUMBER_ID}`); const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); const tabTitles = { From cb5bc0245ca09986ba00aaf440a06e06f50f1d14 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 18 Dec 2024 15:24:38 +0100 Subject: [PATCH 03/46] fix remaining ID fallback warnings --- src/components/ReportWelcomeText.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index 7ebefe25144f..30bffd7ff441 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -33,7 +33,7 @@ function ReportWelcomeText({report, policy}: ReportWelcomeTextProps) { const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID || -1}`); + const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID ?? CONST.DEFAULT_NUMBER_ID}`); const isArchivedRoom = ReportUtils.isArchivedRoom(report, reportNameValuePairs); const isChatRoom = ReportUtils.isChatRoom(report); const isSelfDM = ReportUtils.isSelfDM(report); From 71d5082faa6aaee7e57a15551d4dbc6cb4aba30e Mon Sep 17 00:00:00 2001 From: war-in Date: Wed, 18 Dec 2024 15:37:50 +0100 Subject: [PATCH 04/46] modify HybridAppModule method --- src/libs/actions/Delegate.ts | 14 +++++++++++--- src/types/modules/react-native.d.ts | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts index f99400d87d3e..7f65469ff714 100644 --- a/src/libs/actions/Delegate.ts +++ b/src/libs/actions/Delegate.ts @@ -1,6 +1,6 @@ import {NativeModules} from 'react-native'; import Onyx from 'react-native-onyx'; -import type {OnyxUpdate} from 'react-native-onyx'; +import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import * as API from '@libs/API'; import type {AddDelegateParams, RemoveDelegateParams, UpdateDelegateRoleParams} from '@libs/API/parameters'; import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; @@ -51,6 +51,14 @@ Onyx.connect({ callback: (value) => (stashedSession = value ?? {}), }); +let activePolicyID: OnyxEntry; +Onyx.connect({ + key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, + callback: (newActivePolicyID) => { + activePolicyID = newActivePolicyID; + }, +}); + const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [ ONYXKEYS.NVP_TRY_FOCUS_MODE, ONYXKEYS.PREFERRED_THEME, @@ -140,7 +148,7 @@ function connect(email: string) { confirmReadyToOpenApp(); openApp(); - NativeModules.HybridAppModule.switchAccount(email); + NativeModules.HybridAppModule.switchAccount(email, response?.restrictedToken ?? '', activePolicyID ?? ''); }); }) .catch((error) => { @@ -210,7 +218,7 @@ function disconnect() { confirmReadyToOpenApp(); openApp(); - NativeModules.HybridAppModule.switchAccount(getCurrentUserEmail() ?? ''); + NativeModules.HybridAppModule.switchAccount(getCurrentUserEmail() ?? '', response?.authToken ?? '', activePolicyID ?? ''); }); }) .catch((error) => { diff --git a/src/types/modules/react-native.d.ts b/src/types/modules/react-native.d.ts index c72d4bf2a653..bb70c2cff1ba 100644 --- a/src/types/modules/react-native.d.ts +++ b/src/types/modules/react-native.d.ts @@ -8,7 +8,7 @@ import type StartupTimer from '@libs/StartupTimer/types'; type HybridAppModule = { closeReactNativeApp: (shouldSignOut: boolean, shouldSetNVP: boolean) => void; completeOnboarding: (status: boolean) => void; - switchAccount: (newDotCurrentAccount: string) => void; + switchAccount: (newDotCurrentAccount: string, authToken: string, policyID: string) => void; exitApp: () => void; }; From 139bc5cba1e9f286dcfce772fb772860a9e6d862 Mon Sep 17 00:00:00 2001 From: war-in Date: Thu, 19 Dec 2024 15:40:07 +0100 Subject: [PATCH 05/46] update ND copilot data when switching from OD --- src/libs/actions/Session/index.ts | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 8685a0363e31..ec32ac3ecc20 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -34,6 +34,7 @@ import Navigation from '@libs/Navigation/Navigation'; import navigationRef from '@libs/Navigation/navigationRef'; import * as MainQueue from '@libs/Network/MainQueue'; import * as NetworkStore from '@libs/Network/NetworkStore'; +import {getCurrentUserEmail} from '@libs/Network/NetworkStore'; import NetworkConnection from '@libs/NetworkConnection'; import * as Pusher from '@libs/Pusher/pusher'; import * as ReportUtils from '@libs/ReportUtils'; @@ -513,7 +514,7 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { completedHybridAppOnboarding, isSingleNewDotEntry, primaryLogin, - shouldRemoveDelegatedAccess, + oldDotOriginalAccountEmail, } = Object.fromEntries( queryParams.split('&').map((param) => { const [key, value] = param.split('='); @@ -532,10 +533,31 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { const setSessionDataAndOpenApp = new Promise((resolve) => { clearOnyxForNewAccount() .then(() => { - if (!shouldRemoveDelegatedAccess) { + // This section controls copilot changes + const currentUserEmail = getCurrentUserEmail(); + + // If ND and OD account are the same - do noting + if (email === currentUserEmail) { + return; + } + + // If account was changed to original one on OD side - clear onyx + if (!oldDotOriginalAccountEmail) { + return Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS); + } + + // If we're already logged in - do nothing, data will be set in next step + if (currentUserEmail) { return; } - return Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS); + + // If we're not logged in - set stashed data + return Onyx.multiSet({ + [ONYXKEYS.STASHED_SESSION]: { + email: oldDotOriginalAccountEmail, + }, + [ONYXKEYS.STASHED_CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, + }); }) .then(() => Onyx.multiSet({ From c036e930ca605e324db0f7ee8b42e0a6ebca198b Mon Sep 17 00:00:00 2001 From: war-in Date: Fri, 20 Dec 2024 17:05:20 +0100 Subject: [PATCH 06/46] finish copilot integration - entire flow is working now --- src/libs/actions/Delegate.ts | 20 ++++++++++++-------- src/libs/actions/Session/index.ts | 6 +++--- src/types/modules/react-native.d.ts | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts index 7f65469ff714..cb7f0bda626e 100644 --- a/src/libs/actions/Delegate.ts +++ b/src/libs/actions/Delegate.ts @@ -16,6 +16,7 @@ import type Credentials from '@src/types/onyx/Credentials'; import type Response from '@src/types/onyx/Response'; import type Session from '@src/types/onyx/Session'; import {confirmReadyToOpenApp, openApp} from './App'; +import {getCurrentUserAccountID} from './Report'; import updateSessionAuthTokens from './Session/updateSessionAuthTokens'; import updateSessionUser from './Session/updateSessionUser'; @@ -81,6 +82,8 @@ function connect(email: string) { Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, credentials); Onyx.set(ONYXKEYS.STASHED_SESSION, session); + const previousAccountID = getCurrentUserAccountID(); + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -148,7 +151,7 @@ function connect(email: string) { confirmReadyToOpenApp(); openApp(); - NativeModules.HybridAppModule.switchAccount(email, response?.restrictedToken ?? '', activePolicyID ?? ''); + NativeModules.HybridAppModule.switchAccount(email, response?.restrictedToken ?? '', activePolicyID ?? '', String(previousAccountID)); }); }) .catch((error) => { @@ -206,19 +209,20 @@ function disconnect() { return SequentialQueue.waitForIdle() .then(() => Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS)) .then(() => { + Onyx.set(ONYXKEYS.CREDENTIALS, stashedCredentials); + Onyx.set(ONYXKEYS.SESSION, stashedSession); + Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, {}); + Onyx.set(ONYXKEYS.STASHED_SESSION, {}); + // Update authToken in Onyx and in our local variables so that API requests will use the new authToken updateSessionAuthTokens(response?.authToken, response?.encryptedAuthToken); NetworkStore.setAuthToken(response?.authToken ?? null); - Onyx.set(ONYXKEYS.CREDENTIALS, stashedCredentials); - Onyx.set(ONYXKEYS.SESSION, stashedSession); - Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, {}); - Onyx.set(ONYXKEYS.STASHED_SESSION, {}); confirmReadyToOpenApp(); - openApp(); - - NativeModules.HybridAppModule.switchAccount(getCurrentUserEmail() ?? '', response?.authToken ?? '', activePolicyID ?? ''); + openApp().then(() => { + NativeModules.HybridAppModule.switchAccount(getCurrentUserEmail() ?? '', response?.authToken ?? '', activePolicyID ?? '', ''); + }); }); }) .catch((error) => { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 6c5041d2d4c1..73a2129729e2 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -512,8 +512,8 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { clearOnyxOnStart, completedHybridAppOnboarding, isSingleNewDotEntry, - primaryLogin, oldDotOriginalAccountEmail, + oldDotOriginalAccountID, } = Object.fromEntries( queryParams.split('&').map((param) => { const [key, value] = param.split('='); @@ -554,14 +554,14 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { return Onyx.multiSet({ [ONYXKEYS.STASHED_SESSION]: { email: oldDotOriginalAccountEmail, + accountID: Number(oldDotOriginalAccountID), }, - [ONYXKEYS.STASHED_CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, + [ONYXKEYS.STASHED_CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword, accountID: Number(oldDotOriginalAccountID)}, }); }) .then(() => Onyx.multiSet({ [ONYXKEYS.SESSION]: {email, authToken, encryptedAuthToken: decodeURIComponent(encryptedAuthToken), accountID: Number(accountID)}, - [ONYXKEYS.ACCOUNT]: {primaryLogin}, [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, [ONYXKEYS.IS_SINGLE_NEW_DOT_ENTRY]: isSingleNewDotEntry === 'true', [ONYXKEYS.NVP_TRYNEWDOT]: {classicRedirect: {completedHybridAppOnboarding: completedHybridAppOnboarding === 'true'}}, diff --git a/src/types/modules/react-native.d.ts b/src/types/modules/react-native.d.ts index bb70c2cff1ba..340f396882af 100644 --- a/src/types/modules/react-native.d.ts +++ b/src/types/modules/react-native.d.ts @@ -8,7 +8,7 @@ import type StartupTimer from '@libs/StartupTimer/types'; type HybridAppModule = { closeReactNativeApp: (shouldSignOut: boolean, shouldSetNVP: boolean) => void; completeOnboarding: (status: boolean) => void; - switchAccount: (newDotCurrentAccount: string, authToken: string, policyID: string) => void; + switchAccount: (newDotCurrentAccount: string, authToken: string, policyID: string, accountID: string) => void; exitApp: () => void; }; From 07cbb1edaec9f2fa15cc2b8ed921391c344d70ce Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Tue, 7 Jan 2025 09:48:47 +0100 Subject: [PATCH 07/46] fix typecheck errors --- src/pages/iou/request/step/IOURequestStepDestination.tsx | 6 ++---- src/pages/iou/request/step/IOURequestStepSubrate.tsx | 6 ++---- src/pages/iou/request/step/IOURequestStepTime.tsx | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepDestination.tsx b/src/pages/iou/request/step/IOURequestStepDestination.tsx index bec4d3862f68..6e7ff0e4cdf0 100644 --- a/src/pages/iou/request/step/IOURequestStepDestination.tsx +++ b/src/pages/iou/request/step/IOURequestStepDestination.tsx @@ -11,7 +11,6 @@ import WorkspaceEmptyStateSection from '@components/WorkspaceEmptyStateSection'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; -import usePermissions from '@hooks/usePermissions'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; @@ -55,7 +54,6 @@ function IOURequestStepDestination({ const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); - const {canUseCombinedTrackSubmit} = usePermissions(); // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFoundPage = isEmptyObject(policy); @@ -93,11 +91,11 @@ function IOURequestStepDestination({ const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'), - [CONST.IOU.TYPE.SUBMIT]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.submitExpense'), + [CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'), [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', {name: ''}), [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', {name: ''}), [CONST.IOU.TYPE.SPLIT]: translate('iou.createExpense'), - [CONST.IOU.TYPE.TRACK]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.trackExpense'), + [CONST.IOU.TYPE.TRACK]: translate('iou.createExpense'), [CONST.IOU.TYPE.INVOICE]: translate('workspace.invoices.sendInvoice'), [CONST.IOU.TYPE.CREATE]: translate('iou.createExpense'), }; diff --git a/src/pages/iou/request/step/IOURequestStepSubrate.tsx b/src/pages/iou/request/step/IOURequestStepSubrate.tsx index 1bda72212354..75381b87e9dc 100644 --- a/src/pages/iou/request/step/IOURequestStepSubrate.tsx +++ b/src/pages/iou/request/step/IOURequestStepSubrate.tsx @@ -16,7 +16,6 @@ import TextInput from '@components/TextInput'; import ValuePicker from '@components/ValuePicker'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -68,7 +67,6 @@ function IOURequestStepWaypoint({ report, }: IOURequestStepWaypointProps) { const styles = useThemeStyles(); - const {canUseCombinedTrackSubmit} = usePermissions(); const policy = usePolicy(report?.policyID); const customUnit = PolicyUtils.getPerDiemCustomUnit(policy); const {windowWidth} = useWindowDimensions(); @@ -150,11 +148,11 @@ function IOURequestStepWaypoint({ const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'), - [CONST.IOU.TYPE.SUBMIT]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.submitExpense'), + [CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'), [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', {name: ''}), [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', {name: ''}), [CONST.IOU.TYPE.SPLIT]: translate('iou.createExpense'), - [CONST.IOU.TYPE.TRACK]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.trackExpense'), + [CONST.IOU.TYPE.TRACK]: translate('iou.createExpense'), [CONST.IOU.TYPE.INVOICE]: translate('workspace.invoices.sendInvoice'), [CONST.IOU.TYPE.CREATE]: translate('iou.createExpense'), }; diff --git a/src/pages/iou/request/step/IOURequestStepTime.tsx b/src/pages/iou/request/step/IOURequestStepTime.tsx index d5186dd0f36e..d1ab6b894a56 100644 --- a/src/pages/iou/request/step/IOURequestStepTime.tsx +++ b/src/pages/iou/request/step/IOURequestStepTime.tsx @@ -8,7 +8,6 @@ import InputWrapper from '@components/Form/InputWrapper'; import type {FormOnyxValues} from '@components/Form/types'; import TimeModalPicker from '@components/TimeModalPicker'; import useLocalize from '@hooks/useLocalize'; -import usePermissions from '@hooks/usePermissions'; import useThemeStyles from '@hooks/useThemeStyles'; import DateUtils from '@libs/DateUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; @@ -45,7 +44,6 @@ function IOURequestStepTime({ const styles = useThemeStyles(); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${IOU.getIOURequestPolicyID(transaction, report)}`); const {translate} = useLocalize(); - const {canUseCombinedTrackSubmit} = usePermissions(); const currentDateAttributes = transaction?.comment?.customUnit?.attributes?.dates; const currentStartDate = currentDateAttributes?.start ? DateUtils.extractDate(currentDateAttributes.start) : undefined; const currentEndDate = currentDateAttributes?.end ? DateUtils.extractDate(currentDateAttributes.end) : undefined; @@ -89,11 +87,11 @@ function IOURequestStepTime({ const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'), - [CONST.IOU.TYPE.SUBMIT]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.submitExpense'), + [CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'), [CONST.IOU.TYPE.SEND]: translate('iou.paySomeone', {name: ''}), [CONST.IOU.TYPE.PAY]: translate('iou.paySomeone', {name: ''}), [CONST.IOU.TYPE.SPLIT]: translate('iou.createExpense'), - [CONST.IOU.TYPE.TRACK]: canUseCombinedTrackSubmit ? translate('iou.createExpense') : translate('iou.trackExpense'), + [CONST.IOU.TYPE.TRACK]: translate('iou.createExpense'), [CONST.IOU.TYPE.INVOICE]: translate('workspace.invoices.sendInvoice'), [CONST.IOU.TYPE.CREATE]: translate('iou.createExpense'), }; From f993b3b0c514440c631cc21ff7976f6a45793c70 Mon Sep 17 00:00:00 2001 From: war-in Date: Tue, 7 Jan 2025 15:59:33 +0100 Subject: [PATCH 08/46] fix ios flow (use response data for session and credentials) --- src/libs/actions/Delegate.ts | 24 +++++++++++++++++------- src/libs/actions/Session/index.ts | 9 +++------ src/types/onyx/Response.ts | 6 ++++++ 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts index cb7f0bda626e..183d314efcd3 100644 --- a/src/libs/actions/Delegate.ts +++ b/src/libs/actions/Delegate.ts @@ -7,7 +7,6 @@ import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; import Log from '@libs/Log'; import * as NetworkStore from '@libs/Network/NetworkStore'; -import {getCurrentUserEmail} from '@libs/Network/NetworkStore'; import * as SequentialQueue from '@libs/Network/SequentialQueue'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -206,22 +205,33 @@ function disconnect() { return; } + if (!response?.requesterID || !response?.requesterEmail) { + Log.alert('[Delegate] No requester data returned while disconnecting as a delegate'); + return; + } + return SequentialQueue.waitForIdle() .then(() => Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS)) .then(() => { - Onyx.set(ONYXKEYS.CREDENTIALS, stashedCredentials); - Onyx.set(ONYXKEYS.SESSION, stashedSession); + Onyx.set(ONYXKEYS.CREDENTIALS, { + ...stashedCredentials, + accountID: response.requesterID, + }); + Onyx.set(ONYXKEYS.SESSION, { + ...stashedSession, + accountID: response.requesterID, + email: response.requesterEmail, + authToken: response.authToken, + encryptedAuthToken: response.encryptedAuthToken, + }); Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, {}); Onyx.set(ONYXKEYS.STASHED_SESSION, {}); - // Update authToken in Onyx and in our local variables so that API requests will use the new authToken - updateSessionAuthTokens(response?.authToken, response?.encryptedAuthToken); - NetworkStore.setAuthToken(response?.authToken ?? null); confirmReadyToOpenApp(); openApp().then(() => { - NativeModules.HybridAppModule.switchAccount(getCurrentUserEmail() ?? '', response?.authToken ?? '', activePolicyID ?? '', ''); + NativeModules.HybridAppModule.switchAccount(response.requesterEmail ?? '', response.authToken ?? '', '', ''); }); }); }) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 73a2129729e2..630a7cb16d2a 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -512,6 +512,7 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { clearOnyxOnStart, completedHybridAppOnboarding, isSingleNewDotEntry, + primaryLogin, oldDotOriginalAccountEmail, oldDotOriginalAccountID, } = Object.fromEntries( @@ -552,11 +553,7 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { // If we're not logged in - set stashed data return Onyx.multiSet({ - [ONYXKEYS.STASHED_SESSION]: { - email: oldDotOriginalAccountEmail, - accountID: Number(oldDotOriginalAccountID), - }, - [ONYXKEYS.STASHED_CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword, accountID: Number(oldDotOriginalAccountID)}, + [ONYXKEYS.STASHED_CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, }); }) .then(() => @@ -565,7 +562,7 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, [ONYXKEYS.IS_SINGLE_NEW_DOT_ENTRY]: isSingleNewDotEntry === 'true', [ONYXKEYS.NVP_TRYNEWDOT]: {classicRedirect: {completedHybridAppOnboarding: completedHybridAppOnboarding === 'true'}}, - }), + }).then(() => Onyx.merge(ONYXKEYS.ACCOUNT, {primaryLogin})), ) .then(() => { if (clearOnyxOnStart === 'true') { diff --git a/src/types/onyx/Response.ts b/src/types/onyx/Response.ts index ce9acbaaccc6..146cf327dd31 100644 --- a/src/types/onyx/Response.ts +++ b/src/types/onyx/Response.ts @@ -83,6 +83,12 @@ type Response = { /** If there is newer data to load for pagination commands */ hasNewerActions?: boolean; + + /** The email of the original user (returned when in delegate mode) */ + requesterEmail?: string; + + /** The ID of the original user (returned when in delegate mode) */ + requesterID?: number; }; export default Response; From cf0e4b395ea040383791ed9d11884a03a2a68f4e Mon Sep 17 00:00:00 2001 From: war-in Date: Tue, 7 Jan 2025 16:26:42 +0100 Subject: [PATCH 09/46] fix lint --- src/libs/actions/Delegate.ts | 22 ++++++++++++++-------- src/libs/actions/Session/index.ts | 1 - 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts index 183d314efcd3..320f91f8a677 100644 --- a/src/libs/actions/Delegate.ts +++ b/src/libs/actions/Delegate.ts @@ -140,6 +140,14 @@ function connect(email: string) { Onyx.update(failureData); return; } + if (!activePolicyID) { + Log.alert('[Delegate] Unable to access activePolicyID'); + Onyx.update(failureData); + return; + } + const restrictedToken = response.restrictedToken; + const policyID = activePolicyID; + return SequentialQueue.waitForIdle() .then(() => Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS)) .then(() => { @@ -148,9 +156,7 @@ function connect(email: string) { NetworkStore.setAuthToken(response?.restrictedToken ?? null); confirmReadyToOpenApp(); - openApp(); - - NativeModules.HybridAppModule.switchAccount(email, response?.restrictedToken ?? '', activePolicyID ?? '', String(previousAccountID)); + openApp().then(() => NativeModules.HybridAppModule.switchAccount(email, restrictedToken, policyID, String(previousAccountID))); }); }) .catch((error) => { @@ -210,6 +216,8 @@ function disconnect() { return; } + const requesterEmail = response.requesterEmail; + const authToken = response.authToken; return SequentialQueue.waitForIdle() .then(() => Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS)) .then(() => { @@ -220,8 +228,8 @@ function disconnect() { Onyx.set(ONYXKEYS.SESSION, { ...stashedSession, accountID: response.requesterID, - email: response.requesterEmail, - authToken: response.authToken, + email: requesterEmail, + authToken, encryptedAuthToken: response.encryptedAuthToken, }); Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, {}); @@ -230,9 +238,7 @@ function disconnect() { NetworkStore.setAuthToken(response?.authToken ?? null); confirmReadyToOpenApp(); - openApp().then(() => { - NativeModules.HybridAppModule.switchAccount(response.requesterEmail ?? '', response.authToken ?? '', '', ''); - }); + openApp().then(() => NativeModules.HybridAppModule.switchAccount(requesterEmail, authToken, '', '')); }); }) .catch((error) => { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 630a7cb16d2a..70457b5034d7 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -514,7 +514,6 @@ function signInAfterTransitionFromOldDot(transitionURL: string) { isSingleNewDotEntry, primaryLogin, oldDotOriginalAccountEmail, - oldDotOriginalAccountID, } = Object.fromEntries( queryParams.split('&').map((param) => { const [key, value] = param.split('='); From 0231a56f36e3ea16c657775ff678ae70c526827d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 7 Jan 2025 11:52:59 -0700 Subject: [PATCH 10/46] dry code into canSubmitReport --- Mobile-Expensify | 2 +- src/components/MoneyReportHeader.tsx | 15 +++------------ src/components/ReportActionItem/ReportPreview.tsx | 10 +--------- src/libs/actions/IOU.ts | 4 +--- 4 files changed, 6 insertions(+), 25 deletions(-) diff --git a/Mobile-Expensify b/Mobile-Expensify index 1141a80beaf1..d98552a5c3f1 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit 1141a80beaf1390b2634dba7b1c3e5fe5561a19f +Subproject commit d98552a5c3f17d2aa30611fa5f6dc47ed24963bb diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 36310e4eb588..a98138036539 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -8,7 +8,6 @@ import useNetwork from '@hooks/useNetwork'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import {getCurrentUserAccountID} from '@libs/actions/Report'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; @@ -108,7 +107,6 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const allTransactions = useMemo(() => TransactionUtils.getAllReportTransactions(moneyRequestReport?.reportID, transactions), [moneyRequestReport?.reportID, transactions]); const canAllowSettlement = ReportUtils.hasUpdatedTotal(moneyRequestReport, policy); const policyType = policy?.type; - const isDraft = ReportUtils.isOpenExpenseReport(moneyRequestReport); const connectedIntegration = PolicyUtils.getConnectedIntegration(policy); const navigateBackToAfterDelete = useRef(); const hasHeldExpenses = ReportUtils.hasHeldExpenses(moneyRequestReport?.reportID); @@ -140,16 +138,9 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(moneyRequestReport); - const currentUserAccountID = getCurrentUserAccountID(); const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; - const shouldShowSubmitButton = - !!moneyRequestReport && - isDraft && - reimbursableSpend !== 0 && - !hasAllPendingRTERViolations && - !shouldShowBrokenConnectionViolation && - (moneyRequestReport?.ownerAccountID === currentUserAccountID || isAdmin || moneyRequestReport?.managerID === currentUserAccountID); + const shouldShowSubmitButton = IOU.canSubmitReport(moneyRequestReport, policy); const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && isAdmin && ReportUtils.canBeExported(moneyRequestReport); @@ -391,7 +382,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea /> )} - {shouldShowSubmitButton && !shouldUseNarrowLayout && ( + {!!moneyRequestReport && shouldShowSubmitButton && !shouldUseNarrowLayout && (