From 944bfe26cd21f46fa546099cba5261dc188fee0d Mon Sep 17 00:00:00 2001 From: allgandaf Date: Thu, 9 Jul 2026 02:50:11 +0530 Subject: [PATCH 1/2] Keep the travel billing toggle lock from flashing while loading --- .../workspace/travel/WorkspaceTravelInvoicingSection.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx b/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx index 7936cd349bf3..3d8a3299bb2c 100644 --- a/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx +++ b/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx @@ -230,6 +230,11 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec * When turning OFF: show confirmation modal, then call deactivateTravelInvoicing. */ const handleToggle = (isEnabled: boolean) => { + // Block toggling while a card-settings request is in flight here rather than through `disabled`, which would flash the lock icon on the toggle. + if (isLoading) { + return; + } + // Check if user is on a public domain - Travel Invoicing requires a private domain if (account?.isFromPublicDomain) { const hasPolicyIDInActiveRoute = getSearchParamFromPath(Navigation.getActiveRoute(), CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID) !== null; @@ -418,7 +423,7 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec switchAccessibilityLabel={translate('workspace.moreFeatures.travel.travelInvoicing.travelInvoicingSection.subtitle')} onToggle={handleToggle} isActive={isTravelInvoicingEnabled} - disabled={!canWriteMoreFeatures || isLoading || isOnWaitlist} + disabled={!canWriteMoreFeatures || isOnWaitlist} disabledAction={getToggleDisabledAction()} showLockIcon={!canWriteMoreFeatures || isOnWaitlist || hasOutstandingBalance} pendingAction={togglePendingAction} From 1f10f59b5cc934666ded88f7b5301f48f650b28d Mon Sep 17 00:00:00 2001 From: allgandaf Date: Thu, 9 Jul 2026 02:50:12 +0530 Subject: [PATCH 2/2] Test the travel billing toggle lock stays hidden while loading --- .../WorkspaceTravelInvoicingSectionTest.tsx | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/ui/WorkspaceTravelInvoicingSectionTest.tsx b/tests/ui/WorkspaceTravelInvoicingSectionTest.tsx index d4d92b9f7e5c..5fec1871982f 100644 --- a/tests/ui/WorkspaceTravelInvoicingSectionTest.tsx +++ b/tests/ui/WorkspaceTravelInvoicingSectionTest.tsx @@ -556,6 +556,29 @@ describe('WorkspaceTravelInvoicingSection', () => { expect(screen.queryByTestId(CONST.SWITCH_LOCK_ICON_TEST_ID, {includeHiddenElements: true})).toBeNull(); }); + + it('does not show the toggle lock icon while card settings are loading', async () => { + // Given a configured, enabled workspace with no balance while a card-settings request is in flight + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, mockPolicy); + await Onyx.merge(cardSettingsKey, { + isLoading: true, + TRAVEL_US: { + isEnabled: true, + paymentBankAccountID: 12345, + currentBalance: 0, + pendingSettlementAmount: 0, + }, + }); + await waitForBatchedUpdatesWithAct(); + }); + + renderWorkspaceTravelInvoicingSection(); + await waitForBatchedUpdatesWithAct(); + + // Loading pulses (openPolicyTravelPage runs on every page focus) must not flash the lock icon + expect(screen.queryByTestId(CONST.SWITCH_LOCK_ICON_TEST_ID, {includeHiddenElements: true})).toBeNull(); + }); }); describe('Currency Conversion Prompt', () => {