From 3e0f77d24a00ef27578cfdfbedb7ad34f72e3506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Tue, 10 Sep 2024 16:35:57 +0100 Subject: [PATCH 01/15] Add "Create Expense" item to Global Create menu --- src/CONST.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../FloatingActionButtonAndPopover.tsx | 103 +++++++++++------- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index cf3facb0d1d8..029f21fa3348 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2035,6 +2035,7 @@ const CONST = { INVOICE: 'invoice', SUBMIT: 'submit', TRACK: 'track', + GLOBAL_CREATE: 'create', }, REQUEST_TYPE: { DISTANCE: 'distance', diff --git a/src/languages/en.ts b/src/languages/en.ts index 38784f14a77d..d6de8a4ed644 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -748,6 +748,7 @@ export default { share: 'Share', participants: 'Participants', submitExpense: 'Submit expense', + createExpense: 'Create expense', trackExpense: 'Track expense', pay: 'Pay', cancelPayment: 'Cancel payment', diff --git a/src/languages/es.ts b/src/languages/es.ts index a56204de6fe9..012e5ffe9bc1 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -740,6 +740,7 @@ export default { share: 'Compartir', participants: 'Participantes', submitExpense: 'Presentar gasto', + createExpense: 'Crear gasto', paySomeone: ({name}: PaySomeoneParams) => `Pagar a ${name ?? 'alguien'}`, trackExpense: 'Seguimiento de gastos', pay: 'Pagar', diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index 4444f519dbcd..d89871afaf5e 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -8,6 +8,7 @@ import {useOnyx, withOnyx} from 'react-native-onyx'; import type {SvgProps} from 'react-native-svg'; import FloatingActionButton from '@components/FloatingActionButton'; import * as Expensicons from '@components/Icon/Expensicons'; +import type {PopoverMenuItem} from '@components/PopoverMenu'; import PopoverMenu from '@components/PopoverMenu'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; @@ -186,7 +187,7 @@ function FloatingActionButtonAndPopover( const prevIsFocused = usePrevious(isFocused); const {isOffline} = useNetwork(); - const {canUseSpotnanaTravel} = usePermissions(); + const {canUseSpotnanaTravel, canUseCombinedTrackSubmit} = usePermissions(); const canSendInvoice = useMemo(() => PolicyUtils.canSendInvoice(allPolicies as OnyxCollection, session?.email), [allPolicies, session?.email]); const quickActionAvatars = useMemo(() => { @@ -348,9 +349,71 @@ function FloatingActionButtonAndPopover( showCreateMenu(); } }; + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps const selfDMReportID = useMemo(() => ReportUtils.findSelfDMReportID(), [isLoading]); + const expenseMenuItems = useMemo((): PopoverMenuItem[] => { + if (canUseCombinedTrackSubmit) { + return [ + { + icon: getIconForAction(CONST.IOU.TYPE.REQUEST), + text: translate('iou.createExpense'), + onSelected: () => + interceptAnonymousUser(() => + IOU.startMoneyRequest( + CONST.IOU.TYPE.GLOBAL_CREATE, + // When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used + // for all of the routes in the creation flow. + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), + ), + ), + }, + ]; + } + + return [ + ...(selfDMReportID + ? [ + { + icon: getIconForAction(CONST.IOU.TYPE.TRACK), + text: translate('iou.trackExpense'), + onSelected: () => { + interceptAnonymousUser(() => + IOU.startMoneyRequest( + CONST.IOU.TYPE.TRACK, + // When starting to create a track expense from the global FAB, we need to retrieve selfDM reportID. + // If it doesn't exist, we generate a random optimistic reportID and use it for all of the routes in the creation flow. + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), + ), + ); + if (!hasSeenTrackTraining && !isOffline) { + setTimeout(() => { + Navigation.navigate(ROUTES.TRACK_TRAINING_MODAL); + }, CONST.ANIMATED_TRANSITION); + } + }, + }, + ] + : []), + { + icon: getIconForAction(CONST.IOU.TYPE.REQUEST), + text: translate('iou.submitExpense'), + onSelected: () => + interceptAnonymousUser(() => + IOU.startMoneyRequest( + CONST.IOU.TYPE.SUBMIT, + // When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used + // for all of the routes in the creation flow. + ReportUtils.generateReportID(), + ), + ), + }, + ]; + }, [canUseCombinedTrackSubmit, translate, selfDMReportID, hasSeenTrackTraining, isOffline]); + return ( interceptAnonymousUser(Report.startNewChat), }, - ...(selfDMReportID - ? [ - { - icon: getIconForAction(CONST.IOU.TYPE.TRACK), - text: translate('iou.trackExpense'), - onSelected: () => { - interceptAnonymousUser(() => - IOU.startMoneyRequest( - CONST.IOU.TYPE.TRACK, - // When starting to create a track expense from the global FAB, we need to retrieve selfDM reportID. - // If it doesn't exist, we generate a random optimistic reportID and use it for all of the routes in the creation flow. - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), - ), - ); - if (!hasSeenTrackTraining && !isOffline) { - setTimeout(() => { - Navigation.navigate(ROUTES.TRACK_TRAINING_MODAL); - }, CONST.ANIMATED_TRANSITION); - } - }, - }, - ] - : []), - { - icon: getIconForAction(CONST.IOU.TYPE.REQUEST), - text: translate('iou.submitExpense'), - onSelected: () => - interceptAnonymousUser(() => - IOU.startMoneyRequest( - CONST.IOU.TYPE.SUBMIT, - // When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used - // for all of the routes in the creation flow. - ReportUtils.generateReportID(), - ), - ), - }, + ...expenseMenuItems, ...(canSendInvoice ? [ { From ecbf217346fe88a49877d94cf615aa8593a60adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 11 Sep 2024 15:56:07 +0100 Subject: [PATCH 02/15] Update getIconForAction() to account for create IOU type --- src/libs/getIconForAction/index.ts | 2 ++ .../sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/getIconForAction/index.ts b/src/libs/getIconForAction/index.ts index ffe3dd8b76f2..d7b4e4ae2be4 100644 --- a/src/libs/getIconForAction/index.ts +++ b/src/libs/getIconForAction/index.ts @@ -12,6 +12,8 @@ const getIconForAction = (actionType: ValueOf) => { return Expensicons.Cash; case CONST.IOU.TYPE.SPLIT: return Expensicons.Transfer; + case CONST.IOU.TYPE.GLOBAL_CREATE: + return Expensicons.Receipt; default: return Expensicons.MoneyCircle; } diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index d89871afaf5e..ab7f51f6854d 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -357,7 +357,7 @@ function FloatingActionButtonAndPopover( if (canUseCombinedTrackSubmit) { return [ { - icon: getIconForAction(CONST.IOU.TYPE.REQUEST), + icon: getIconForAction(CONST.IOU.TYPE.GLOBAL_CREATE), text: translate('iou.createExpense'), onSelected: () => interceptAnonymousUser(() => From a04f4e473775b5ba0dc24c1ceff5e8aa99a67ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 11 Sep 2024 16:05:42 +0100 Subject: [PATCH 03/15] Add create iou type to isValidMoneyRequestType() and delete temporary_isValidMoneyRequestType() --- src/libs/IOUUtils.ts | 10 +--------- tests/unit/IOUUtilsTest.ts | 10 +++++----- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/libs/IOUUtils.ts b/src/libs/IOUUtils.ts index 55ac4ba2ac36..a7f2ca2f301c 100644 --- a/src/libs/IOUUtils.ts +++ b/src/libs/IOUUtils.ts @@ -116,16 +116,9 @@ function isValidMoneyRequestType(iouType: string): boolean { CONST.IOU.TYPE.PAY, CONST.IOU.TYPE.TRACK, CONST.IOU.TYPE.INVOICE, + CONST.IOU.TYPE.GLOBAL_CREATE, ]; - return moneyRequestType.includes(iouType); -} -/** - * Checks if the iou type is one of submit, pay, track, or split. - */ -// eslint-disable-next-line @typescript-eslint/naming-convention -function temporary_isValidMoneyRequestType(iouType: string): boolean { - const moneyRequestType: string[] = [CONST.IOU.TYPE.SUBMIT, CONST.IOU.TYPE.SPLIT, CONST.IOU.TYPE.PAY, CONST.IOU.TYPE.TRACK, CONST.IOU.TYPE.INVOICE]; return moneyRequestType.includes(iouType); } @@ -169,5 +162,4 @@ export { isValidMoneyRequestType, navigateToStartMoneyRequestStep, updateIOUOwnerAndTotal, - temporary_isValidMoneyRequestType, }; diff --git a/tests/unit/IOUUtilsTest.ts b/tests/unit/IOUUtilsTest.ts index 04a5b3babd5e..2ab1247ec5b0 100644 --- a/tests/unit/IOUUtilsTest.ts +++ b/tests/unit/IOUUtilsTest.ts @@ -1,4 +1,5 @@ import Onyx from 'react-native-onyx'; +import CONST from '@src/CONST'; import * as IOUUtils from '@src/libs/IOUUtils'; import * as ReportUtils from '@src/libs/ReportUtils'; import * as TransactionUtils from '@src/libs/TransactionUtils'; @@ -136,13 +137,12 @@ describe('IOUUtils', () => { describe('isValidMoneyRequestType', () => { test('Return true for valid iou type', () => { - expect(IOUUtils.temporary_isValidMoneyRequestType('submit')).toBe(true); - expect(IOUUtils.temporary_isValidMoneyRequestType('split')).toBe(true); - expect(IOUUtils.temporary_isValidMoneyRequestType('pay')).toBe(true); - expect(IOUUtils.temporary_isValidMoneyRequestType('track')).toBe(true); + Object.values(CONST.IOU.TYPE).forEach((iouType) => { + expect(IOUUtils.isValidMoneyRequestType(iouType)).toBe(true); + }); }); test('Return false for invalid iou type', () => { - expect(IOUUtils.temporary_isValidMoneyRequestType('money')).toBe(false); + expect(IOUUtils.isValidMoneyRequestType('money')).toBe(false); }); }); From 80acc3b5d35bce24fbc5ced8f7f3beae9499f43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Wed, 11 Sep 2024 16:17:33 +0100 Subject: [PATCH 04/15] Change canCreateRequest() to include create iou type if combined expense beta is enabled --- src/libs/ReportUtils.ts | 11 ++++++++-- .../workspace/AccessOrNotFoundWrapper.tsx | 21 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 076c6c1af3d5..70a9781f10ea 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6737,12 +6737,19 @@ function getReportOfflinePendingActionAndErrors(report: OnyxEntry): Repo /** * Check if the report can create the expense with type is iouType */ -function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, iouType: ValueOf): boolean { +function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, betas: OnyxEntry, iouType: ValueOf): boolean { const participantAccountIDs = Object.keys(report?.participants ?? {}).map(Number); + if (!canUserPerformWriteAction(report)) { return false; } - return getMoneyRequestOptions(report, policy, participantAccountIDs).includes(iouType); + + const requestOptions = getMoneyRequestOptions(report, policy, participantAccountIDs); + if (Permissions.canUseCombinedTrackSubmit(betas ?? [])) { + requestOptions.push(CONST.IOU.TYPE.GLOBAL_CREATE); + } + + return requestOptions.includes(iouType); } function getWorkspaceChats(policyID: string, accountIDs: number[]): Array> { diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 1a6f59830506..b7b6f9a8030a 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -30,16 +30,24 @@ const ACCESS_VARIANTS = { login: string, report: OnyxEntry, allPolicies: NonNullable> | null, + betas: OnyxEntry, iouType?: IOUType, ) => !!iouType && IOUUtils.isValidMoneyRequestType(iouType) && // Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the expense - (isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, iouType)) && + (isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, betas, iouType)) && (iouType !== CONST.IOU.TYPE.INVOICE || PolicyUtils.canSendInvoice(allPolicies, login)), } as const satisfies Record< string, - (policy: OnyxTypes.Policy, login: string, report: OnyxTypes.Report, allPolicies: NonNullable> | null, iouType?: IOUType) => boolean + ( + policy: OnyxTypes.Policy, + login: string, + report: OnyxTypes.Report, + allPolicies: NonNullable> | null, + betas: OnyxEntry, + iouType?: IOUType, + ) => boolean >; type AccessVariant = keyof typeof ACCESS_VARIANTS; @@ -52,6 +60,8 @@ type AccessOrNotFoundWrapperOnyxProps = { /** Indicated whether the report data is loading */ isLoadingReportData: OnyxEntry; + + betas: OnyxEntry; }; type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & { @@ -103,7 +113,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN } function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps, shouldBeBlocked, ...props}: AccessOrNotFoundWrapperProps) { - const {policy, policyID, report, iouType, allPolicies, featureName, isLoadingReportData} = props; + const {policy, policyID, report, iouType, allPolicies, featureName, isLoadingReportData, betas} = props; const {login = ''} = useCurrentUserPersonalDetails(); const isPolicyIDInRoute = !!policyID?.length; const isMoneyRequest = !!iouType && IOUUtils.isValidMoneyRequestType(iouType); @@ -129,7 +139,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps const isPageAccessible = accessVariants.reduce((acc, variant) => { const accessFunction = ACCESS_VARIANTS[variant]; - return acc && accessFunction(policy, login, report, allPolicies ?? null, iouType); + return acc && accessFunction(policy, login, report, allPolicies ?? null, betas, iouType); }, true); const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id; @@ -175,4 +185,7 @@ export default withOnyx Date: Wed, 11 Sep 2024 16:22:01 +0100 Subject: [PATCH 05/15] Add tab title for create iou type in IOURequestStartPage --- src/pages/iou/request/IOURequestStartPage.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index eac30b8839d2..1eb45dfc85b6 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -54,9 +54,10 @@ function IOURequestStartPage({ [CONST.IOU.TYPE.SPLIT]: translate('iou.splitExpense'), [CONST.IOU.TYPE.TRACK]: translate('iou.trackExpense'), [CONST.IOU.TYPE.INVOICE]: translate('workspace.invoices.sendInvoice'), + [CONST.IOU.TYPE.GLOBAL_CREATE]: translate('iou.createExpense'), }; const transactionRequestType = useRef(TransactionUtils.getRequestType(transaction)); - const {canUseP2PDistanceRequests} = usePermissions(iouType); + const {canUseP2PDistanceRequests, canUseCombinedTrackSubmit} = usePermissions(iouType); const isFromGlobalCreate = isEmptyObject(report?.reportID); // Clear out the temporary expense if the reportID in the URL has changed from the transaction's reportID @@ -69,7 +70,8 @@ function IOURequestStartPage({ const isExpenseChat = ReportUtils.isPolicyExpenseChat(report); const isExpenseReport = ReportUtils.isExpenseReport(report); - const shouldDisplayDistanceRequest = !!canUseP2PDistanceRequests || isExpenseChat || isExpenseReport || (isFromGlobalCreate && iouType !== CONST.IOU.TYPE.SPLIT); + const shouldDisplayDistanceRequest = + !!canUseCombinedTrackSubmit || !!canUseP2PDistanceRequests || isExpenseChat || isExpenseReport || (isFromGlobalCreate && iouType !== CONST.IOU.TYPE.SPLIT); const navigateBack = () => { Navigation.closeRHPFlow(); From 67cb211cedadba72aa31eb2667ea115e16e7995e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 12 Sep 2024 15:11:13 +0100 Subject: [PATCH 06/15] Navigate the user to participants page if they are using the combined flow --- src/pages/iou/request/step/IOURequestStepAmount.tsx | 9 ++++++--- src/pages/iou/request/step/IOURequestStepDistance.tsx | 9 ++++++--- .../iou/request/step/IOURequestStepScan/index.native.tsx | 4 +++- src/pages/iou/request/step/IOURequestStepScan/index.tsx | 4 +++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 069f86ce0899..8d02ee4de8ff 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -180,10 +180,13 @@ function IOURequestStepAmount({ return; } - // If a reportID exists in the report object, it's because the user started this flow from using the + button in the composer - // inside a report. In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight + // If a reportID exists in the report object, it's because either: + // - The user started this flow from using the + button in the composer inside a report. + // - The user started this flow from using the global create menu by selecting the Track expense option. + // In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight // to the confirm step. - if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs)) { + // If the user is started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. + if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs) && iouType !== CONST.IOU.TYPE.GLOBAL_CREATE) { const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? -1; diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 38a98017e61a..21233bca4fd0 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -242,10 +242,13 @@ function IOURequestStepDistance({ return; } - // If a reportID exists in the report object, it's because the user started this flow from using the + button in the composer - // inside a report. In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight + // If a reportID exists in the report object, it's because either: + // - The user started this flow from using the + button in the composer inside a report. + // - The user started this flow from using the global create menu by selecting the Track expense option. + // In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight // to the confirm step. - if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs)) { + // If the user started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. + if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs) && iouType !== CONST.IOU.TYPE.GLOBAL_CREATE) { const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? -1; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 073b1101e33f..bb312effbc0a 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -233,7 +233,9 @@ function IOURequestStepScan({ } // If the transaction was created from the global create, the person needs to select participants, so take them there. - if (transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) { + // If the user started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + if ((transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) || iouType === CONST.IOU.TYPE.GLOBAL_CREATE) { navigateToParticipantPage(); return; } diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index ff583bd1db50..79d4b53c9e75 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -265,7 +265,9 @@ function IOURequestStepScan({ } // If the transaction was created from the global create, the person needs to select participants, so take them there. - if (transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) { + // If the user started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + if ((transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) || iouType === CONST.IOU.TYPE.GLOBAL_CREATE) { navigateToParticipantPage(); return; } From 63aa38ba1fdd039cf41cec739d889a571c8394f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 12 Sep 2024 15:59:15 +0100 Subject: [PATCH 07/15] Add Track expense button to IOU participants page --- src/components/ReportWelcomeText.tsx | 5 ++- src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../MoneyRequestParticipantsSelector.tsx | 32 ++++++++++++++++++- .../step/IOURequestStepParticipants.tsx | 19 ++++++++++- 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index 96f705ea2d52..404a4359e8c8 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -46,7 +46,10 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP const welcomeMessage = SidebarUtils.getWelcomeMessage(report, policy); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const additionalText = moneyRequestOptions - .filter((item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE) + .filter( + (item): item is Exclude => + item !== CONST.IOU.TYPE.INVOICE && item !== CONST.IOU.TYPE.GLOBAL_CREATE, + ) .map((item) => translate(`reportActionsView.iouTypes.${item}`)) .join(', '); const canEditPolicyDescription = ReportUtils.canEditPolicyDescription(policy); diff --git a/src/languages/en.ts b/src/languages/en.ts index 903d8f7d6634..413676b91398 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -927,6 +927,7 @@ export default { bookingPendingDescription: "This booking is pending because it hasn't been paid yet.", bookingArchived: 'This booking is archived', bookingArchivedDescription: 'This booking is archived because the trip date has passed. Add an expense for the final amount if needed.', + justTrackIt: 'Just track it (don’t submit it)', }, notificationPreferencesPage: { header: 'Notification preferences', diff --git a/src/languages/es.ts b/src/languages/es.ts index 3fb007e14ea5..3007b50bc0e1 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -930,6 +930,7 @@ export default { bookingPendingDescription: 'Esta reserva está pendiente porque aún no se ha pagado.', bookingArchived: 'Esta reserva está archivada', bookingArchivedDescription: 'Esta reserva está archivada porque la fecha del viaje ha pasado. Agregue un gasto por el monto final si es necesario.', + justTrackIt: 'Solo guardarlo (no enviarlo)', }, notificationPreferencesPage: { header: 'Preferencias de avisos', diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index f10575f8c1d0..fe1b9ff7c701 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -7,6 +7,8 @@ import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; import EmptySelectionListContent from '@components/EmptySelectionListContent'; import FormHelpMessage from '@components/FormHelpMessage'; +import * as Expensicons from '@components/Icon/Expensicons'; +import MenuItem from '@components/MenuItem'; import {usePersonalDetails} from '@components/OnyxProvider'; import {useOptionsList} from '@components/OptionListContextProvider'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; @@ -41,6 +43,9 @@ type MoneyRequestParticipantsSelectorProps = { /** Callback to add participants in MoneyRequestModal */ onParticipantsAdded: (value: Participant[]) => void; + /** Callback to navigate to Track Expense confirmation flow */ + onTrackExpensePress?: () => void; + /** Selected participants from MoneyRequestModal with login */ participants?: Participant[] | typeof CONST.EMPTY_ARRAY; @@ -54,7 +59,15 @@ type MoneyRequestParticipantsSelectorProps = { action: IOUAction; }; -function MoneyRequestParticipantsSelector({participants = CONST.EMPTY_ARRAY, onFinish, onParticipantsAdded, iouType, iouRequestType, action}: MoneyRequestParticipantsSelectorProps) { +function MoneyRequestParticipantsSelector({ + participants = CONST.EMPTY_ARRAY, + onTrackExpensePress, + onFinish, + onParticipantsAdded, + iouType, + iouRequestType, + action, +}: MoneyRequestParticipantsSelectorProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); @@ -364,6 +377,22 @@ function MoneyRequestParticipantsSelector({participants = CONST.EMPTY_ARRAY, onF const shouldShowReferralBanner = !isDismissed && iouType !== CONST.IOU.TYPE.INVOICE && !shouldShowListEmptyContent; + const headerContent = useMemo(() => { + if (iouType !== CONST.IOU.TYPE.GLOBAL_CREATE) { + return; + } + + // We only render the track expense button if the user is coming from the combined submit/track flow. + return ( + + ); + }, [iouType, translate, onTrackExpensePress]); + const footerContent = useMemo(() => { if (isDismissed && !shouldShowSplitBillErrorMessage && !participants.length) { return; @@ -449,6 +478,7 @@ function MoneyRequestParticipantsSelector({participants = CONST.EMPTY_ARRAY, onF shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()} onSelectRow={onSelectRow} shouldSingleExecuteRowSelect + headerContent={headerContent} footerContent={footerContent} listEmptyContent={} headerMessage={header} diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index 552ad4d54e39..b09ced5af7b7 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -36,6 +36,7 @@ type IOURequestStepParticipantsProps = IOURequestStepParticipantsOnyxProps & WithFullTransactionOrNotFoundProps; function IOURequestStepParticipants({ + report, route: { params: {iouType, reportID, transactionID, action}, }, @@ -132,7 +133,14 @@ function IOURequestStepParticipants({ return; } - const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, iouType, transactionID, selectedReportID.current || reportID); + // If coming from the combined submit/track flow and the user proceeds to submit the expense + // we will use the submit IOU type in the confirmation flow. + const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute( + action, + iouType === CONST.IOU.TYPE.GLOBAL_CREATE ? CONST.IOU.TYPE.SUBMIT : iouType, + transactionID, + selectedReportID.current || reportID, + ); if (isCategorizing) { Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(action, iouType, transactionID, selectedReportID.current || reportID, iouConfirmationPageRoute)); } else { @@ -144,6 +152,14 @@ function IOURequestStepParticipants({ IOUUtils.navigateToStartMoneyRequestStep(iouRequestType, iouType, transactionID, reportID, action); }, [iouRequestType, iouType, transactionID, reportID, action]); + const trackExpense = () => { + // If coming from the combined submit/track flow and the user proceeds to just track the expense, + // we will use the track IOU type in the confirmation flow. + IOU.setMoneyRequestParticipantsFromReport(transactionID, report); + const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, CONST.IOU.TYPE.TRACK, transactionID, ReportUtils.findSelfDMReportID() ?? '-1'); + Navigation.navigate(iouConfirmationPageRoute); + }; + useEffect(() => { const isCategorizing = action === CONST.IOU.ACTION.CATEGORIZE; const isShareAction = action === CONST.IOU.ACTION.SHARE; @@ -176,6 +192,7 @@ function IOURequestStepParticipants({ iouType={iouType} iouRequestType={iouRequestType} action={action} + onTrackExpensePress={trackExpense} /> ); From 6b17906c1bf248e3c16231aae9ef64446dea4e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 12 Sep 2024 16:08:16 +0100 Subject: [PATCH 08/15] Fix TS error --- src/libs/ReportUtils.ts | 6 ++++-- .../ReportActionCompose/AttachmentPickerWithMenuItems.tsx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4844cd678818..473a34e3395e 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6494,8 +6494,10 @@ function temporary_getMoneyRequestOptions( report: OnyxEntry, policy: OnyxEntry, reportParticipants: number[], -): Array> { - return getMoneyRequestOptions(report, policy, reportParticipants, true) as Array>; +): Array> { + return getMoneyRequestOptions(report, policy, reportParticipants, true) as Array< + Exclude + >; } /** diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index 6e3c3a48de74..291931505ed0 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -31,7 +31,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -type MoneyRequestOptions = Record, PopoverMenuItem>; +type MoneyRequestOptions = Record, PopoverMenuItem>; type AttachmentPickerWithMenuItemsOnyxProps = { /** The policy tied to the report */ From d7f40327e39a120b3e818dd9acfa3e3a42c8722e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Fri, 13 Sep 2024 09:53:05 +0100 Subject: [PATCH 09/15] Fix TS --- src/components/ReportWelcomeText.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index 404a4359e8c8..3cd7f000e9b3 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -46,10 +46,7 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP const welcomeMessage = SidebarUtils.getWelcomeMessage(report, policy); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const additionalText = moneyRequestOptions - .filter( - (item): item is Exclude => - item !== CONST.IOU.TYPE.INVOICE && item !== CONST.IOU.TYPE.GLOBAL_CREATE, - ) + .filter((item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE) .map((item) => translate(`reportActionsView.iouTypes.${item}`)) .join(', '); const canEditPolicyDescription = ReportUtils.canEditPolicyDescription(policy); From c0c9d5e0739eb7fa2e4e666d30029f3432e446d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 26 Sep 2024 12:10:28 +0100 Subject: [PATCH 10/15] Fix issue when submitting expense --- src/libs/ReportUtils.ts | 6 +++--- src/libs/actions/Task.ts | 2 +- src/pages/ProfilePage.tsx | 2 +- src/pages/TrackExpensePage.tsx | 2 +- .../SidebarScreen/FloatingActionButtonAndPopover.tsx | 7 +++---- src/pages/iou/request/MoneyRequestParticipantsSelector.tsx | 4 ++-- src/pages/iou/request/step/IOURequestStepParticipants.tsx | 6 +++--- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index de888ea87ba4..e9624c08ce41 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1185,14 +1185,14 @@ function isConciergeChatReport(report: OnyxInputOrEntry): boolean { return participantAccountIDs.has(CONCIERGE_ACCOUNT_ID_STRING); } -function findSelfDMReportID(): string | undefined { +function findSelfDMReport(): OnyxEntry { const allReports = ReportConnection.getAllReports(); if (!allReports) { return; } const selfDMReport = Object.values(allReports).find((report) => isSelfDM(report) && !isThread(report)); - return selfDMReport?.reportID; + return selfDMReport; } /** @@ -7898,7 +7898,7 @@ export { doesReportBelongToWorkspace, doesTransactionThreadHaveViolations, findLastAccessedReport, - findSelfDMReportID, + findSelfDMReport, formatReportLastMessageText, generateReportID, getAddWorkspaceRoomOrChatReportErrors, diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 08568b6d5a02..a6ed897ea54e 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -786,7 +786,7 @@ function setAssigneeValue( ): OnyxEntry | undefined { let report: OnyxEntry | undefined = chatReport; if (isCurrentUser) { - const selfDMReportID = ReportUtils.findSelfDMReportID(); + const selfDMReportID = ReportUtils.findSelfDMReport()?.reportID; // If there is no share destination set, automatically set it to the assignee chat report // This allows for a much quicker process when creating a new task and is likely the desired share destination most times if (!shareToReportID && !skipShareDestination) { diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 0d47e3fd8f35..02f8e4aece22 100755 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -89,7 +89,7 @@ function ProfilePage({route}: ProfilePageProps) { const isCurrentUser = session?.accountID === accountID; const reportKey = useMemo(() => { const reportID = isCurrentUser - ? ReportUtils.findSelfDMReportID() + ? ReportUtils.findSelfDMReport()?.reportID : ReportUtils.getChatByParticipants(session?.accountID ? [accountID, session.accountID] : [], reports)?.reportID ?? '-1'; if (SessionActions.isAnonymousUser() || !reportID) { diff --git a/src/pages/TrackExpensePage.tsx b/src/pages/TrackExpensePage.tsx index 2e08c49721be..9aa6e40408cf 100644 --- a/src/pages/TrackExpensePage.tsx +++ b/src/pages/TrackExpensePage.tsx @@ -40,7 +40,7 @@ function TrackExpensePage() { IOU.startMoneyRequest( CONST.IOU.TYPE.TRACK, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), + ReportUtils.findSelfDMReport()?.reportID || ReportUtils.generateReportID(), ); if (!hasSeenTrackTraining && !isOffline) { diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index ab7f51f6854d..15275d6fafef 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -351,7 +351,7 @@ function FloatingActionButtonAndPopover( }; // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - const selfDMReportID = useMemo(() => ReportUtils.findSelfDMReportID(), [isLoading]); + const selfDMReportID = useMemo(() => ReportUtils.findSelfDMReport()?.reportID, [isLoading]); const expenseMenuItems = useMemo((): PopoverMenuItem[] => { if (canUseCombinedTrackSubmit) { @@ -365,8 +365,7 @@ function FloatingActionButtonAndPopover( CONST.IOU.TYPE.GLOBAL_CREATE, // When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used // for all of the routes in the creation flow. - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), + ReportUtils.generateReportID(), ), ), }, @@ -386,7 +385,7 @@ function FloatingActionButtonAndPopover( // When starting to create a track expense from the global FAB, we need to retrieve selfDM reportID. // If it doesn't exist, we generate a random optimistic reportID and use it for all of the routes in the creation flow. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), + ReportUtils.findSelfDMReport()?.reportID || ReportUtils.generateReportID(), ), ); if (!hasSeenTrackTraining && !isOffline) { diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index a97c4633fbdd..ae70602e8935 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -118,9 +118,9 @@ function MoneyRequestParticipantsSelector({ participants as Participant[], CONST.EXPENSIFY_EMAILS, - // If we are using this component in the "Submit expense" flow then we pass the includeOwnedWorkspaceChats argument so that the current user + // If we are using this component in the "Submit expense" or the combined submit/track flow then we pass the includeOwnedWorkspaceChats argument so that the current user // sees the option to submit an expense from their admin on their own Workspace Chat. - (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.SPLIT) && action !== CONST.IOU.ACTION.SUBMIT, + (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.GLOBAL_CREATE || iouType === CONST.IOU.TYPE.SPLIT) && action !== CONST.IOU.ACTION.SUBMIT, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing (canUseP2PDistanceRequests || iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE) && !isCategorizeOrShareAction, diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index b09ced5af7b7..cc9f4f6bad7e 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -36,7 +36,6 @@ type IOURequestStepParticipantsProps = IOURequestStepParticipantsOnyxProps & WithFullTransactionOrNotFoundProps; function IOURequestStepParticipants({ - report, route: { params: {iouType, reportID, transactionID, action}, }, @@ -155,8 +154,9 @@ function IOURequestStepParticipants({ const trackExpense = () => { // If coming from the combined submit/track flow and the user proceeds to just track the expense, // we will use the track IOU type in the confirmation flow. - IOU.setMoneyRequestParticipantsFromReport(transactionID, report); - const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, CONST.IOU.TYPE.TRACK, transactionID, ReportUtils.findSelfDMReportID() ?? '-1'); + const selfDMReport = ReportUtils.findSelfDMReport(); + IOU.setMoneyRequestParticipantsFromReport(transactionID, selfDMReport); + const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, CONST.IOU.TYPE.TRACK, transactionID, selfDMReport?.reportID ?? '-1'); Navigation.navigate(iouConfirmationPageRoute); }; From 426599e7141a3540b2e631514b7d58545f1661b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 26 Sep 2024 12:17:36 +0100 Subject: [PATCH 11/15] Fix ReportWelcomeText --- src/components/ReportWelcomeText.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index f22b94be09ba..801d0d7da9ce 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -46,7 +46,10 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP const welcomeMessage = SidebarUtils.getWelcomeMessage(report, policy); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const additionalText = moneyRequestOptions - .filter((item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE) + .filter( + (item): item is Exclude => + item !== CONST.IOU.TYPE.INVOICE, + ) .map((item) => translate(`reportActionsView.iouTypes.${item}`)) .join(', '); const canEditPolicyDescription = ReportUtils.canEditPolicyDescription(policy); From 539cf1df56a730f4d13f4546e6b06c5d223cf2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Fri, 27 Sep 2024 16:25:46 +0100 Subject: [PATCH 12/15] Revert findSelfDMReportID change --- src/libs/ReportUtils.ts | 6 +++--- src/libs/actions/Task.ts | 2 +- src/pages/ProfilePage.tsx | 2 +- src/pages/TrackExpensePage.tsx | 2 +- .../SidebarScreen/FloatingActionButtonAndPopover.tsx | 4 ++-- src/pages/iou/request/step/IOURequestStepParticipants.tsx | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 5b233e5a95d0..3a3a8916f5d3 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1234,14 +1234,14 @@ function isConciergeChatReport(report: OnyxInputOrEntry): boolean { return participantAccountIDs.has(CONCIERGE_ACCOUNT_ID_STRING); } -function findSelfDMReport(): OnyxEntry { +function findSelfDMReportID(): string | undefined { const allReports = ReportConnection.getAllReports(); if (!allReports) { return; } const selfDMReport = Object.values(allReports).find((report) => isSelfDM(report) && !isThread(report)); - return selfDMReport; + return selfDMReport?.reportID; } /** @@ -7988,7 +7988,7 @@ export { doesReportBelongToWorkspace, doesTransactionThreadHaveViolations, findLastAccessedReport, - findSelfDMReport, + findSelfDMReportID, formatReportLastMessageText, generateReportID, getAddWorkspaceRoomOrChatReportErrors, diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index a6ed897ea54e..08568b6d5a02 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -786,7 +786,7 @@ function setAssigneeValue( ): OnyxEntry | undefined { let report: OnyxEntry | undefined = chatReport; if (isCurrentUser) { - const selfDMReportID = ReportUtils.findSelfDMReport()?.reportID; + const selfDMReportID = ReportUtils.findSelfDMReportID(); // If there is no share destination set, automatically set it to the assignee chat report // This allows for a much quicker process when creating a new task and is likely the desired share destination most times if (!shareToReportID && !skipShareDestination) { diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 02f8e4aece22..0d47e3fd8f35 100755 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -89,7 +89,7 @@ function ProfilePage({route}: ProfilePageProps) { const isCurrentUser = session?.accountID === accountID; const reportKey = useMemo(() => { const reportID = isCurrentUser - ? ReportUtils.findSelfDMReport()?.reportID + ? ReportUtils.findSelfDMReportID() : ReportUtils.getChatByParticipants(session?.accountID ? [accountID, session.accountID] : [], reports)?.reportID ?? '-1'; if (SessionActions.isAnonymousUser() || !reportID) { diff --git a/src/pages/TrackExpensePage.tsx b/src/pages/TrackExpensePage.tsx index 9aa6e40408cf..2e08c49721be 100644 --- a/src/pages/TrackExpensePage.tsx +++ b/src/pages/TrackExpensePage.tsx @@ -40,7 +40,7 @@ function TrackExpensePage() { IOU.startMoneyRequest( CONST.IOU.TYPE.TRACK, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - ReportUtils.findSelfDMReport()?.reportID || ReportUtils.generateReportID(), + ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), ); if (!hasSeenTrackTraining && !isOffline) { diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index 5a5c1a896d51..af06842b22e0 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -351,7 +351,7 @@ function FloatingActionButtonAndPopover( }; // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - const selfDMReportID = useMemo(() => ReportUtils.findSelfDMReport()?.reportID, [isLoading]); + const selfDMReportID = useMemo(() => ReportUtils.findSelfDMReportID(), [isLoading]); const expenseMenuItems = useMemo((): PopoverMenuItem[] => { if (canUseCombinedTrackSubmit) { @@ -385,7 +385,7 @@ function FloatingActionButtonAndPopover( // When starting to create a track expense from the global FAB, we need to retrieve selfDM reportID. // If it doesn't exist, we generate a random optimistic reportID and use it for all of the routes in the creation flow. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - ReportUtils.findSelfDMReport()?.reportID || ReportUtils.generateReportID(), + ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(), ), ); if (!hasSeenTrackTraining && !isOffline) { diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index cc9f4f6bad7e..afb7de1b1dd6 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -154,9 +154,9 @@ function IOURequestStepParticipants({ const trackExpense = () => { // If coming from the combined submit/track flow and the user proceeds to just track the expense, // we will use the track IOU type in the confirmation flow. - const selfDMReport = ReportUtils.findSelfDMReport(); - IOU.setMoneyRequestParticipantsFromReport(transactionID, selfDMReport); - const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, CONST.IOU.TYPE.TRACK, transactionID, selfDMReport?.reportID ?? '-1'); + const selfDMReportID = ReportUtils.findSelfDMReportID() ?? '-1'; + IOU.setMoneyRequestParticipantsFromReport(transactionID, ReportUtils.getReport(selfDMReportID)); + const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, CONST.IOU.TYPE.TRACK, transactionID, selfDMReportID); Navigation.navigate(iouConfirmationPageRoute); }; From 5e52ce1614eb9f35dcde4f5f5559087e2582d356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Mon, 30 Sep 2024 17:48:45 +0100 Subject: [PATCH 13/15] Add logic to only display track button if user has a self DM --- .../iou/request/MoneyRequestParticipantsSelector.tsx | 10 +++++++--- .../iou/request/step/IOURequestStepParticipants.tsx | 11 +++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index 2c026c6b4ce4..bbdfcfa2c6d3 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -57,6 +57,9 @@ type MoneyRequestParticipantsSelectorProps = { /** The action of the IOU, i.e. create, split, move */ action: IOUAction; + + /** Whether we should display the Track Expense button at the top of the participants list */ + shouldDisplayTrackExpenseButton?: boolean; }; function MoneyRequestParticipantsSelector({ @@ -67,6 +70,7 @@ function MoneyRequestParticipantsSelector({ iouType, iouRequestType, action, + shouldDisplayTrackExpenseButton, }: MoneyRequestParticipantsSelectorProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -378,11 +382,11 @@ function MoneyRequestParticipantsSelector({ const shouldShowReferralBanner = !isDismissed && iouType !== CONST.IOU.TYPE.INVOICE && !shouldShowListEmptyContent; const headerContent = useMemo(() => { - if (iouType !== CONST.IOU.TYPE.GLOBAL_CREATE) { + if (!shouldDisplayTrackExpenseButton) { return; } - // We only render the track expense button if the user is coming from the combined submit/track flow. + // We only display the track expense button if the user is coming from the combined submit/track flow. return ( ); - }, [iouType, translate, onTrackExpensePress]); + }, [shouldDisplayTrackExpenseButton, translate, onTrackExpensePress]); const footerContent = useMemo(() => { if (isDismissed && !shouldShowSplitBillErrorMessage && !participants.length) { diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index afb7de1b1dd6..fc62eeec077b 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -75,6 +75,9 @@ function IOURequestStepParticipants({ return translate('iou.submitExpense'); }, [iouType, translate, isSplitRequest, action]); + const selfDMReportID = useMemo(() => ReportUtils.findSelfDMReportID(), []); + const shouldDisplayTrackExpenseButton = !!selfDMReportID; + const receiptFilename = transaction?.filename; const receiptPath = transaction?.receipt?.source; const receiptType = transaction?.receipt?.type; @@ -154,7 +157,10 @@ function IOURequestStepParticipants({ const trackExpense = () => { // If coming from the combined submit/track flow and the user proceeds to just track the expense, // we will use the track IOU type in the confirmation flow. - const selfDMReportID = ReportUtils.findSelfDMReportID() ?? '-1'; + if (!selfDMReportID) { + return; + } + IOU.setMoneyRequestParticipantsFromReport(transactionID, ReportUtils.getReport(selfDMReportID)); const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, CONST.IOU.TYPE.TRACK, transactionID, selfDMReportID); Navigation.navigate(iouConfirmationPageRoute); @@ -189,10 +195,11 @@ function IOURequestStepParticipants({ participants={isSplitRequest ? participants : []} onParticipantsAdded={addParticipant} onFinish={goToNextStep} + onTrackExpensePress={trackExpense} iouType={iouType} iouRequestType={iouRequestType} action={action} - onTrackExpensePress={trackExpense} + shouldDisplayTrackExpenseButton={shouldDisplayTrackExpenseButton} /> ); From fcd7690a400711ea281b536021289bd8bd689405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Tue, 1 Oct 2024 11:21:46 +0100 Subject: [PATCH 14/15] Rename GLOBAL_CREATE to CREATE --- src/CONST.ts | 2 +- src/components/ReportWelcomeText.tsx | 2 +- src/libs/IOUUtils.ts | 2 +- src/libs/ReportUtils.ts | 6 +++--- src/libs/getIconForAction/index.ts | 2 +- .../ReportActionCompose/AttachmentPickerWithMenuItems.tsx | 2 +- .../SidebarScreen/FloatingActionButtonAndPopover.tsx | 4 ++-- src/pages/iou/request/IOURequestStartPage.tsx | 2 +- src/pages/iou/request/MoneyRequestParticipantsSelector.tsx | 2 +- src/pages/iou/request/step/IOURequestStepAmount.tsx | 2 +- src/pages/iou/request/step/IOURequestStepDistance.tsx | 2 +- src/pages/iou/request/step/IOURequestStepParticipants.tsx | 2 +- .../iou/request/step/IOURequestStepScan/index.native.tsx | 2 +- src/pages/iou/request/step/IOURequestStepScan/index.tsx | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index e8db33e0213f..c4b0a9b01806 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2058,7 +2058,7 @@ const CONST = { INVOICE: 'invoice', SUBMIT: 'submit', TRACK: 'track', - GLOBAL_CREATE: 'create', + CREATE: 'create', }, REQUEST_TYPE: { DISTANCE: 'distance', diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index 801d0d7da9ce..97e611f0bafe 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -47,7 +47,7 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const additionalText = moneyRequestOptions .filter( - (item): item is Exclude => + (item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE, ) .map((item) => translate(`reportActionsView.iouTypes.${item}`)) diff --git a/src/libs/IOUUtils.ts b/src/libs/IOUUtils.ts index a7f2ca2f301c..4b56a3f460c1 100644 --- a/src/libs/IOUUtils.ts +++ b/src/libs/IOUUtils.ts @@ -116,7 +116,7 @@ function isValidMoneyRequestType(iouType: string): boolean { CONST.IOU.TYPE.PAY, CONST.IOU.TYPE.TRACK, CONST.IOU.TYPE.INVOICE, - CONST.IOU.TYPE.GLOBAL_CREATE, + CONST.IOU.TYPE.CREATE, ]; return moneyRequestType.includes(iouType); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index cfe6a44268df..7c0ee0ecaa0d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6690,9 +6690,9 @@ function temporary_getMoneyRequestOptions( report: OnyxEntry, policy: OnyxEntry, reportParticipants: number[], -): Array> { +): Array> { return getMoneyRequestOptions(report, policy, reportParticipants, true) as Array< - Exclude + Exclude >; } @@ -6941,7 +6941,7 @@ function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, const requestOptions = getMoneyRequestOptions(report, policy, participantAccountIDs); if (Permissions.canUseCombinedTrackSubmit(betas ?? [])) { - requestOptions.push(CONST.IOU.TYPE.GLOBAL_CREATE); + requestOptions.push(CONST.IOU.TYPE.CREATE); } return requestOptions.includes(iouType); diff --git a/src/libs/getIconForAction/index.ts b/src/libs/getIconForAction/index.ts index d7b4e4ae2be4..18c8d7d8741e 100644 --- a/src/libs/getIconForAction/index.ts +++ b/src/libs/getIconForAction/index.ts @@ -12,7 +12,7 @@ const getIconForAction = (actionType: ValueOf) => { return Expensicons.Cash; case CONST.IOU.TYPE.SPLIT: return Expensicons.Transfer; - case CONST.IOU.TYPE.GLOBAL_CREATE: + case CONST.IOU.TYPE.CREATE: return Expensicons.Receipt; default: return Expensicons.MoneyCircle; diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index 80088ac29b2a..005ca4df153a 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -33,7 +33,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -type MoneyRequestOptions = Record, PopoverMenuItem>; +type MoneyRequestOptions = Record, PopoverMenuItem>; type AttachmentPickerWithMenuItemsProps = { /** The report currently being looked at */ diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index af06842b22e0..8800cf35cdfd 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -357,12 +357,12 @@ function FloatingActionButtonAndPopover( if (canUseCombinedTrackSubmit) { return [ { - icon: getIconForAction(CONST.IOU.TYPE.GLOBAL_CREATE), + icon: getIconForAction(CONST.IOU.TYPE.CREATE), text: translate('iou.createExpense'), onSelected: () => interceptAnonymousUser(() => IOU.startMoneyRequest( - CONST.IOU.TYPE.GLOBAL_CREATE, + CONST.IOU.TYPE.CREATE, // When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used // for all of the routes in the creation flow. ReportUtils.generateReportID(), diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 1eb45dfc85b6..c4abf714502a 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -54,7 +54,7 @@ function IOURequestStartPage({ [CONST.IOU.TYPE.SPLIT]: translate('iou.splitExpense'), [CONST.IOU.TYPE.TRACK]: translate('iou.trackExpense'), [CONST.IOU.TYPE.INVOICE]: translate('workspace.invoices.sendInvoice'), - [CONST.IOU.TYPE.GLOBAL_CREATE]: translate('iou.createExpense'), + [CONST.IOU.TYPE.CREATE]: translate('iou.createExpense'), }; const transactionRequestType = useRef(TransactionUtils.getRequestType(transaction)); const {canUseP2PDistanceRequests, canUseCombinedTrackSubmit} = usePermissions(iouType); diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index bbdfcfa2c6d3..a2652b8693ee 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -124,7 +124,7 @@ function MoneyRequestParticipantsSelector({ // If we are using this component in the "Submit expense" or the combined submit/track flow then we pass the includeOwnedWorkspaceChats argument so that the current user // sees the option to submit an expense from their admin on their own Workspace Chat. - (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.GLOBAL_CREATE || iouType === CONST.IOU.TYPE.SPLIT) && action !== CONST.IOU.ACTION.SUBMIT, + (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.CREATE || iouType === CONST.IOU.TYPE.SPLIT) && action !== CONST.IOU.ACTION.SUBMIT, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing (canUseP2PDistanceRequests || iouRequestType !== CONST.IOU.REQUEST_TYPE.DISTANCE) && !isCategorizeOrShareAction, diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index cac2beff2bb8..2e4fb87a34f3 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -184,7 +184,7 @@ function IOURequestStepAmount({ // In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight // to the confirm step. // If the user is started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. - if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs) && iouType !== CONST.IOU.TYPE.GLOBAL_CREATE) { + if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs) && iouType !== CONST.IOU.TYPE.CREATE) { const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? -1; diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 60cdd3834058..e0eb9389a1d3 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -251,7 +251,7 @@ function IOURequestStepDistance({ // In this case, the participants can be automatically assigned from the report and the user can skip the participants step and go straight // to the confirm step. // If the user started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. - if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs) && iouType !== CONST.IOU.TYPE.GLOBAL_CREATE) { + if (report?.reportID && !ReportUtils.isArchivedRoom(report, reportNameValuePairs) && iouType !== CONST.IOU.TYPE.CREATE) { const selectedParticipants = IOU.setMoneyRequestParticipantsFromReport(transactionID, report); const participants = selectedParticipants.map((participant) => { const participantAccountID = participant?.accountID ?? -1; diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index fc62eeec077b..481f0423e072 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -139,7 +139,7 @@ function IOURequestStepParticipants({ // we will use the submit IOU type in the confirmation flow. const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute( action, - iouType === CONST.IOU.TYPE.GLOBAL_CREATE ? CONST.IOU.TYPE.SUBMIT : iouType, + iouType === CONST.IOU.TYPE.CREATE ? CONST.IOU.TYPE.SUBMIT : iouType, transactionID, selectedReportID.current || reportID, ); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 152f3f90f4d0..a2ba86009a5e 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -236,7 +236,7 @@ function IOURequestStepScan({ // If the transaction was created from the global create, the person needs to select participants, so take them there. // If the user started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - if ((transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) || iouType === CONST.IOU.TYPE.GLOBAL_CREATE) { + if ((transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) || iouType === CONST.IOU.TYPE.CREATE) { navigateToParticipantPage(); return; } diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 57277e4ad233..bd92dfd69f93 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -268,7 +268,7 @@ function IOURequestStepScan({ // If the transaction was created from the global create, the person needs to select participants, so take them there. // If the user started this flow using the Create expense option (combined submit/track flow), they should be redirected to the participants page. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - if ((transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) || iouType === CONST.IOU.TYPE.GLOBAL_CREATE) { + if ((transaction?.isFromGlobalCreate && iouType !== CONST.IOU.TYPE.TRACK && !report?.reportID) || iouType === CONST.IOU.TYPE.CREATE) { navigateToParticipantPage(); return; } From fdf3949098d322fd82536656c4cebad0ead6b36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Tue, 1 Oct 2024 11:25:15 +0100 Subject: [PATCH 15/15] Use allBetas from ReportUtils --- src/libs/ReportUtils.ts | 4 ++-- .../workspace/AccessOrNotFoundWrapper.tsx | 21 ++++--------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 7c0ee0ecaa0d..f7160e1cdf97 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6932,7 +6932,7 @@ function getReportOfflinePendingActionAndErrors(report: OnyxEntry): Repo /** * Check if the report can create the expense with type is iouType */ -function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, betas: OnyxEntry, iouType: ValueOf): boolean { +function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, iouType: ValueOf): boolean { const participantAccountIDs = Object.keys(report?.participants ?? {}).map(Number); if (!canUserPerformWriteAction(report)) { @@ -6940,7 +6940,7 @@ function canCreateRequest(report: OnyxEntry, policy: OnyxEntry, } const requestOptions = getMoneyRequestOptions(report, policy, participantAccountIDs); - if (Permissions.canUseCombinedTrackSubmit(betas ?? [])) { + if (Permissions.canUseCombinedTrackSubmit(allBetas ?? [])) { requestOptions.push(CONST.IOU.TYPE.CREATE); } diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index b7b6f9a8030a..1a6f59830506 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -30,24 +30,16 @@ const ACCESS_VARIANTS = { login: string, report: OnyxEntry, allPolicies: NonNullable> | null, - betas: OnyxEntry, iouType?: IOUType, ) => !!iouType && IOUUtils.isValidMoneyRequestType(iouType) && // Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the expense - (isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, betas, iouType)) && + (isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, iouType)) && (iouType !== CONST.IOU.TYPE.INVOICE || PolicyUtils.canSendInvoice(allPolicies, login)), } as const satisfies Record< string, - ( - policy: OnyxTypes.Policy, - login: string, - report: OnyxTypes.Report, - allPolicies: NonNullable> | null, - betas: OnyxEntry, - iouType?: IOUType, - ) => boolean + (policy: OnyxTypes.Policy, login: string, report: OnyxTypes.Report, allPolicies: NonNullable> | null, iouType?: IOUType) => boolean >; type AccessVariant = keyof typeof ACCESS_VARIANTS; @@ -60,8 +52,6 @@ type AccessOrNotFoundWrapperOnyxProps = { /** Indicated whether the report data is loading */ isLoadingReportData: OnyxEntry; - - betas: OnyxEntry; }; type AccessOrNotFoundWrapperProps = AccessOrNotFoundWrapperOnyxProps & { @@ -113,7 +103,7 @@ function PageNotFoundFallback({policyID, shouldShowFullScreenFallback, fullPageN } function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps, shouldBeBlocked, ...props}: AccessOrNotFoundWrapperProps) { - const {policy, policyID, report, iouType, allPolicies, featureName, isLoadingReportData, betas} = props; + const {policy, policyID, report, iouType, allPolicies, featureName, isLoadingReportData} = props; const {login = ''} = useCurrentUserPersonalDetails(); const isPolicyIDInRoute = !!policyID?.length; const isMoneyRequest = !!iouType && IOUUtils.isValidMoneyRequestType(iouType); @@ -139,7 +129,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps const isPageAccessible = accessVariants.reduce((acc, variant) => { const accessFunction = ACCESS_VARIANTS[variant]; - return acc && accessFunction(policy, login, report, allPolicies ?? null, betas, iouType); + return acc && accessFunction(policy, login, report, allPolicies ?? null, iouType); }, true); const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id; @@ -185,7 +175,4 @@ export default withOnyx