From a75fd26359f985376e8741e240da0e3e3d5a5939 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 13 Aug 2025 12:41:47 +0200 Subject: [PATCH] Add toggle to manually control the transaction thread report creation --- src/components/TestToolMenu.tsx | 18 +++++++++++++++++- src/languages/de.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/languages/fr.ts | 1 + src/languages/it.ts | 1 + src/languages/ja.ts | 1 + src/languages/nl.ts | 1 + src/languages/pl.ts | 1 + src/languages/pt-BR.ts | 1 + src/languages/zh-hans.ts | 1 + src/libs/actions/User.ts | 5 +++++ src/pages/Share/SubmitDetailsPage.tsx | 3 ++- .../iou/request/step/IOURequestStepAmount.tsx | 3 ++- .../step/IOURequestStepConfirmation.tsx | 3 ++- .../step/IOURequestStepScan/index.native.tsx | 3 ++- .../request/step/IOURequestStepScan/index.tsx | 3 ++- src/types/onyx/Account.ts | 3 +++ 18 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/components/TestToolMenu.tsx b/src/components/TestToolMenu.tsx index 777e8fd7b611..6b405ed21f32 100644 --- a/src/components/TestToolMenu.tsx +++ b/src/components/TestToolMenu.tsx @@ -2,12 +2,14 @@ import React from 'react'; import useIsAuthenticated from '@hooks/useIsAuthenticated'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; +import usePermissions from '@hooks/usePermissions'; import useThemeStyles from '@hooks/useThemeStyles'; import {isUsingStagingApi} from '@libs/ApiUtils'; import {setShouldFailAllRequests, setShouldForceOffline, setShouldSimulatePoorConnection} from '@userActions/Network'; import {expireSessionWithDelay, invalidateAuthToken, invalidateCredentials} from '@userActions/Session'; -import {setIsDebugModeEnabled, setShouldUseStagingServer} from '@userActions/User'; +import {setIsDebugModeEnabled, setShouldBlockTransactionThreadReportCreation, setShouldUseStagingServer} from '@userActions/User'; import CONFIG from '@src/CONFIG'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Account as AccountOnyx} from '@src/types/onyx'; import Button from './Button'; @@ -27,11 +29,14 @@ const ACCOUNT_DEFAULT: AccountOnyx = { }; function TestToolMenu() { + const {isBetaEnabled} = usePermissions(); const [network] = useOnyx(ONYXKEYS.NETWORK, {canBeMissing: true}); const [account = ACCOUNT_DEFAULT] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); const [isUsingImportedState] = useOnyx(ONYXKEYS.IS_USING_IMPORTED_STATE, {canBeMissing: true}); const shouldUseStagingServer = account?.shouldUseStagingServer ?? isUsingStagingApi(); const isDebugModeEnabled = !!account?.isDebugModeEnabled; + const shouldBlockTransactionThreadReportCreation = !!account?.shouldBlockTransactionThreadReportCreation; + const shouldShowTransactionThreadReportToggle = isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS); const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -48,6 +53,17 @@ function TestToolMenu() { {isAuthenticated && ( <> + {/* When toggled, the app won't create the transaction thread report. It should be removed together with CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS beta */} + {shouldShowTransactionThreadReportToggle && ( + + setShouldBlockTransactionThreadReportCreation(!shouldBlockTransactionThreadReportCreation)} + /> + + )} + {/* When toggled the app will be put into debug mode. */} val?.reports}); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false); @@ -60,7 +61,7 @@ function SubmitDetailsPage({ const [errorMessage, setErrorMessage] = useState(undefined); const {isBetaEnabled} = usePermissions(); - const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS); + const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS) || !account?.shouldBlockTransactionThreadReportCreation; const [validFilesToUpload, setValidFilesToUpload] = useState([]); const {validateFiles} = useFilesValidation(setValidFilesToUpload); diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index f01eec1570e6..277df05cb444 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -85,6 +85,7 @@ function IOURequestStepAmount({ const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`, {canBeMissing: true}); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true}); const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, {canBeMissing: true}); + const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); const {duplicateTransactions, duplicateTransactionViolations} = useDuplicateTransactionsAndViolations(transactionID ? [transactionID] : []); const [reportAttributesDerived] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {canBeMissing: true, selector: (val) => val?.reports}); const isEditing = action === CONST.IOU.ACTION.EDIT; @@ -94,7 +95,7 @@ function IOURequestStepAmount({ const {amount: transactionAmount} = getTransactionDetails(currentTransaction) ?? {amount: 0}; const {currency: originalCurrency} = getTransactionDetails(isEditing && !isEmptyObject(draftTransaction) ? draftTransaction : transaction) ?? {currency: CONST.CURRENCY.USD}; const currency = isValidCurrencyCode(selectedCurrency) ? selectedCurrency : originalCurrency; - const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS); + const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS) || !account?.shouldBlockTransactionThreadReportCreation; // For quick button actions, we'll skip the confirmation page unless the report is archived or this is a workspace request, as // the user will have to add a merchant. diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index aa98d70fff61..5bad77f47041 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -131,6 +131,7 @@ function IOURequestStepConfirmation({ const [userLocation] = useOnyx(ONYXKEYS.USER_LOCATION, {canBeMissing: true}); const [reportAttributesDerived] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {canBeMissing: true, selector: (val) => val?.reports}); const [recentlyUsedDestinations] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_DESTINATIONS}${realPolicyID}`, {canBeMissing: true}); + const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); /* * We want to use a report from the transaction if it exists @@ -214,7 +215,7 @@ function IOURequestStepConfirmation({ [transaction?.participants, iouType, personalDetails, reportAttributesDerived], ); const isPolicyExpenseChat = useMemo(() => participants?.some((participant) => participant.isPolicyExpenseChat), [participants]); - const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS); + const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS) || !account?.shouldBlockTransactionThreadReportCreation; const formHasBeenSubmitted = useRef(false); useFetchRoute(transaction, transaction?.comment?.waypoints, action, shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 3b8245063ef0..a959b5f3cc2b 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -113,6 +113,7 @@ function IOURequestStepScan({ const [activePolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${activePolicyID}`, {canBeMissing: true}); const [dismissedProductTraining] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {canBeMissing: true}); const [reportAttributesDerived] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {canBeMissing: true, selector: (val) => val?.reports}); + const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); const platform = getPlatform(true); const [mutedPlatforms = getEmptyObject>>()] = useOnyx(ONYXKEYS.NVP_MUTED_PLATFORMS, {canBeMissing: true}); const isPlatformMuted = mutedPlatforms[platform]; @@ -121,7 +122,7 @@ function IOURequestStepScan({ const [shouldShowMultiScanEducationalPopup, setShouldShowMultiScanEducationalPopup] = useState(false); const [cameraKey, setCameraKey] = useState(0); const {shouldStartLocationPermissionFlow} = useIOUUtils(); - const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS); + const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS) || !account?.shouldBlockTransactionThreadReportCreation; const defaultTaxCode = getDefaultTaxCode(policy, initialTransaction); const transactionTaxCode = (initialTransaction?.taxCode ? initialTransaction?.taxCode : defaultTaxCode) ?? ''; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 29d22f87d7fe..2ce6549b2f38 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -113,6 +113,7 @@ function IOURequestStepScan({ const getScreenshotTimeoutRef = useRef(null); const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`, {canBeMissing: true}); const policy = usePolicy(report?.policyID); + const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true}); const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: false}); const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${initialTransactionID}`, {canBeMissing: true}); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: false}); @@ -123,7 +124,7 @@ function IOURequestStepScan({ const canUseMultiScan = !isEditing && iouType !== CONST.IOU.TYPE.SPLIT && !backTo && !backToReport; const isReplacingReceipt = (isEditing && hasReceipt(initialTransaction)) || (!!initialTransaction?.receipt && !!backTo); const {shouldStartLocationPermissionFlow} = useIOUUtils(); - const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS); + const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS) || !account?.shouldBlockTransactionThreadReportCreation; const [optimisticTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, { selector: (items) => Object.values(items ?? {}), diff --git a/src/types/onyx/Account.ts b/src/types/onyx/Account.ts index 15add2c01ee3..32348f710621 100644 --- a/src/types/onyx/Account.ts +++ b/src/types/onyx/Account.ts @@ -205,6 +205,9 @@ type Account = { /** Whether we should use the staging version of the secure API server */ shouldUseStagingServer?: boolean; + /** Whether we should block the transaction thread report creation */ + shouldBlockTransactionThreadReportCreation?: boolean; + /** Whether or not the user is on a public domain email account or not */ isFromPublicDomain?: boolean;