From 26dfd26527084991cac21c92e4e9bfdcffc84765 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 20 Aug 2025 20:02:08 +0700 Subject: [PATCH 1/5] optimistically delete card feed from WS when deleted --- src/hooks/useCardFeeds.tsx | 9 ++++--- src/libs/actions/Policy/Policy.ts | 26 ++++++++++++++++--- src/pages/workspace/WorkspaceOverviewPage.tsx | 6 ++--- src/pages/workspace/WorkspacesListPage.tsx | 4 +-- tests/actions/IOUTest.ts | 2 +- tests/actions/PolicyTest.ts | 10 +++---- 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index fc725e2eaf0a..b86ceb212a62 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -16,19 +16,20 @@ import useWorkspaceAccountID from './useWorkspaceAccountID'; * @param policyID - The workspace policyID to filter and construct card feeds for. * @returns - * A tuple containing: - * 1. Card feeds specific to the given policyID (or `undefined` if unavailable). + * 1. Combined workspace and domain card feeds specific to the given policyID (or `undefined` if unavailable). * 2. The result metadata from the Onyx collection fetch. + * 3. Card feeds specific to the given policyID (or `undefined` if unavailable). */ -const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { +const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>, CardFeeds | undefined] => { const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, {canBeMissing: true}); + const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const workspaceFeeds = useMemo(() => { if (!policyID || !allFeeds) { return undefined; } - const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const {companyCards = {}, companyCardNicknames = {}, oAuthAccountDetails = {}} = defaultFeed?.settings ?? {}; const result: CardFeeds & {settings: Required} = { @@ -70,7 +71,7 @@ const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, Res }, result); }, [allFeeds, policyID, workspaceAccountID]); - return [workspaceFeeds, allFeedsResult]; + return [workspaceFeeds, allFeedsResult, defaultFeed]; }; export default useCardFeeds; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 3174782a9424..92f2636c9738 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -95,6 +95,7 @@ import CONST from '@src/CONST'; import type {OnboardingAccounting} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type { + CardFeeds, IntroSelected, InvitedEmailsToAccountIDs, LastPaymentMethod, @@ -348,12 +349,22 @@ function hasActiveChatEnabledPolicies(policies: Array> /** * Delete the workspace */ -function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorkspacePolicyID: string | undefined, lastUsedPaymentMethods?: LastPaymentMethod) { +function deleteWorkspace( + policyID: string, + policyName: string, + lastAccessedWorkspacePolicyID: string | undefined, + policyCardFeeds: CardFeeds | undefined, + lastUsedPaymentMethods?: LastPaymentMethod, +) { if (!allPolicies) { return; } + // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 + // eslint-disable-next-line deprecation/deprecation + const policy = getPolicy(policyID); const filteredPolicies = Object.values(allPolicies).filter((policy): policy is Policy => policy?.id !== policyID); + const workspaceAccountID = policy?.workspaceAccountID; const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -364,6 +375,11 @@ function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorks errors: null, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, + value: null, + }, ...(!hasActiveChatEnabledPolicies(filteredPolicies, true) ? [ { @@ -377,9 +393,6 @@ function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorks : []), ]; - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line deprecation/deprecation - const policy = getPolicy(policyID); // Restore the old report stateNum and statusNum const failureData: OnyxUpdate[] = [ { @@ -397,6 +410,11 @@ function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorks pendingAction: null, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, + value: policyCardFeeds, + }, ]; if (policyID === activePolicyID) { diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index 79d12d7957e6..6bf30ec35414 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -79,7 +79,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds] = useCardFeeds(policy?.id); + const [cardFeeds, _, defaultCardFeeds] = useCardFeeds(policy?.id); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, @@ -185,10 +185,10 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa return; } - deleteWorkspace(policy.id, policyName, lastAccessedWorkspacePolicyID, lastPaymentMethod); + deleteWorkspace(policy.id, policyName, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod); setIsDeleteModalOpen(false); goBackFromInvalidPolicy(); - }, [policy?.id, policyName, lastAccessedWorkspacePolicyID, lastPaymentMethod]); + }, [policy?.id, policyName, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod]); useEffect(() => { if (isLoadingBill) { diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index f901338592df..9e1d142b6a30 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -133,7 +133,7 @@ function WorkspacesListPage() { // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyIDToDelete}`]?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds] = useCardFeeds(policyIDToDelete); + const [cardFeeds, _, defaultCardFeeds] = useCardFeeds(policyIDToDelete); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, @@ -160,7 +160,7 @@ function WorkspacesListPage() { return; } - deleteWorkspace(policyIDToDelete, policyNameToDelete, lastAccessedWorkspacePolicyID, lastPaymentMethod); + deleteWorkspace(policyIDToDelete, policyNameToDelete, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod); setIsDeleteModalOpen(false); }; diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 0dd4d3e813e0..f8f1acf9d5bd 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -4388,7 +4388,7 @@ describe('actions/IOU', () => { ) .then(() => { if (policy) { - deleteWorkspace(policy.id, policy.name, undefined); + deleteWorkspace(policy.id, policy.name, undefined, undefined); } return waitForBatchedUpdates(); }) diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index 53e0ccb27202..34558c1edaa0 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -620,7 +620,7 @@ describe('actions/Policy', () => { // When deleting a workspace fails mockFetch?.fail?.(); - Policy.deleteWorkspace(fakePolicy.id, fakePolicy.name, undefined); + Policy.deleteWorkspace(fakePolicy.id, fakePolicy.name, undefined, undefined); await waitForBatchedUpdates(); @@ -700,7 +700,7 @@ describe('actions/Policy', () => { {name: 'hold', type: CONST.VIOLATION_TYPES.WARNING}, ]); - Policy.deleteWorkspace(policyID, 'test', undefined); + Policy.deleteWorkspace(policyID, 'test', undefined, undefined); await waitForBatchedUpdates(); @@ -725,7 +725,7 @@ describe('actions/Policy', () => { jest.spyOn(PolicyUtils, 'getPersonalPolicy').mockReturnValue(personalPolicy); - Policy.deleteWorkspace(teamPolicy.id, teamPolicy.name, undefined); + Policy.deleteWorkspace(teamPolicy.id, teamPolicy.name, undefined, undefined); await waitForBatchedUpdates(); const activePolicyID: OnyxEntry = await new Promise((resolve) => { @@ -749,7 +749,7 @@ describe('actions/Policy', () => { await Onyx.merge(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); - Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID); + Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID, undefined); await waitForBatchedUpdates(); const lastAccessedWorkspacePolicyIDAfterDelete: OnyxEntry = await new Promise((resolve) => { @@ -775,7 +775,7 @@ describe('actions/Policy', () => { await Onyx.merge(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); - Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID); + Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID, undefined); await waitForBatchedUpdates(); const lastAccessedWorkspacePolicyIDAfterDelete: OnyxEntry = await new Promise((resolve) => { From ea39a5a8651305c006fd49944527462ddde4e24b Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 20 Aug 2025 20:20:55 +0700 Subject: [PATCH 2/5] lint --- src/libs/actions/Policy/Policy.ts | 2 +- src/pages/workspace/WorkspaceOverviewPage.tsx | 2 +- src/pages/workspace/WorkspacesListPage.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 92f2636c9738..7790d21b636d 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -363,7 +363,7 @@ function deleteWorkspace( // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 // eslint-disable-next-line deprecation/deprecation const policy = getPolicy(policyID); - const filteredPolicies = Object.values(allPolicies).filter((policy): policy is Policy => policy?.id !== policyID); + const filteredPolicies = Object.values(allPolicies).filter((p): p is Policy => p?.id !== policyID); const workspaceAccountID = policy?.workspaceAccountID; const optimisticData: OnyxUpdate[] = [ { diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index 6bf30ec35414..b0f59747b00c 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -79,7 +79,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds, _, defaultCardFeeds] = useCardFeeds(policy?.id); + const [cardFeeds, , defaultCardFeeds] = useCardFeeds(policy?.id); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index 9e1d142b6a30..9cd185a94ee1 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -133,7 +133,7 @@ function WorkspacesListPage() { // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyIDToDelete}`]?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds, _, defaultCardFeeds] = useCardFeeds(policyIDToDelete); + const [cardFeeds, , defaultCardFeeds] = useCardFeeds(policyIDToDelete); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, From e6dc0b82d795d783a0b6a095be0eb10565ed2e5b Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 12 Sep 2025 10:27:07 +0800 Subject: [PATCH 3/5] get the card feeds with Onyx.connectWithView --- src/hooks/useCardFeeds.tsx | 9 ++++---- src/libs/actions/Policy/Policy.ts | 21 ++++++++++++------- src/pages/workspace/WorkspaceOverviewPage.tsx | 6 +++--- src/pages/workspace/WorkspacesListPage.tsx | 4 ++-- tests/actions/IOUTest.ts | 2 +- tests/actions/PolicyTest.ts | 10 ++++----- 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index b86ceb212a62..fc725e2eaf0a 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -16,20 +16,19 @@ import useWorkspaceAccountID from './useWorkspaceAccountID'; * @param policyID - The workspace policyID to filter and construct card feeds for. * @returns - * A tuple containing: - * 1. Combined workspace and domain card feeds specific to the given policyID (or `undefined` if unavailable). + * 1. Card feeds specific to the given policyID (or `undefined` if unavailable). * 2. The result metadata from the Onyx collection fetch. - * 3. Card feeds specific to the given policyID (or `undefined` if unavailable). */ -const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>, CardFeeds | undefined] => { +const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, {canBeMissing: true}); - const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const workspaceFeeds = useMemo(() => { if (!policyID || !allFeeds) { return undefined; } + const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const {companyCards = {}, companyCardNicknames = {}, oAuthAccountDetails = {}} = defaultFeed?.settings ?? {}; const result: CardFeeds & {settings: Required} = { @@ -71,7 +70,7 @@ const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, Res }, result); }, [allFeeds, policyID, workspaceAccountID]); - return [workspaceFeeds, allFeedsResult, defaultFeed]; + return [workspaceFeeds, allFeedsResult]; }; export default useCardFeeds; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index bd2033dde2f0..167b18513197 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -281,6 +281,16 @@ Onyx.connect({ callback: (value) => (introSelected = value), }); +let policyCardFeeds: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, + waitForCollectionCallback: true, + callback: (value) => { + policyCardFeeds = value; + console.log('policy card feeds', value); + }, +}); + /** * Stores in Onyx the policy ID of the last workspace that was accessed by the user */ @@ -365,13 +375,7 @@ function hasActiveChatEnabledPolicies(policies: Array> /** * Delete the workspace */ -function deleteWorkspace( - policyID: string, - policyName: string, - lastAccessedWorkspacePolicyID: string | undefined, - policyCardFeeds: CardFeeds | undefined, - lastUsedPaymentMethods?: LastPaymentMethod, -) { +function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorkspacePolicyID: string | undefined, lastUsedPaymentMethods?: LastPaymentMethod) { if (!allPolicies) { return; } @@ -381,6 +385,7 @@ function deleteWorkspace( const policy = getPolicy(policyID); const filteredPolicies = Object.values(allPolicies).filter((p): p is Policy => p?.id !== policyID); const workspaceAccountID = policy?.workspaceAccountID; + const policyCardFeed = policyCardFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -429,7 +434,7 @@ function deleteWorkspace( { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, - value: policyCardFeeds, + value: policyCardFeed, }, ]; diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index 6ca05d0e2778..f09334c351ed 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -89,7 +89,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds, , defaultCardFeeds] = useCardFeeds(policy?.id); + const [cardFeeds] = useCardFeeds(policy?.id); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, @@ -197,10 +197,10 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa return; } - deleteWorkspace(policy.id, policyName, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod); + deleteWorkspace(policy.id, policyName, lastAccessedWorkspacePolicyID, lastPaymentMethod); setIsDeleteModalOpen(false); goBackFromInvalidPolicy(); - }, [policy?.id, policyName, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod]); + }, [policy?.id, policyName, lastAccessedWorkspacePolicyID, lastPaymentMethod]); useEffect(() => { if (isLoadingBill) { diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index c2256f52a46f..3f41310cae3e 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -134,7 +134,7 @@ function WorkspacesListPage() { // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyIDToDelete}`]?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds, , defaultCardFeeds] = useCardFeeds(policyIDToDelete); + const [cardFeeds] = useCardFeeds(policyIDToDelete); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, @@ -162,7 +162,7 @@ function WorkspacesListPage() { return; } - deleteWorkspace(policyIDToDelete, policyNameToDelete, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod); + deleteWorkspace(policyIDToDelete, policyNameToDelete, lastAccessedWorkspacePolicyID, lastPaymentMethod); setIsDeleteModalOpen(false); }; diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 200915582b84..c24957806db3 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -4396,7 +4396,7 @@ describe('actions/IOU', () => { ) .then(() => { if (policy) { - deleteWorkspace(policy.id, policy.name, undefined, undefined); + deleteWorkspace(policy.id, policy.name, undefined); } return waitForBatchedUpdates(); }) diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index fc530e8be50d..68341f9b9811 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -817,7 +817,7 @@ describe('actions/Policy', () => { // When deleting a workspace fails mockFetch?.fail?.(); - Policy.deleteWorkspace(fakePolicy.id, fakePolicy.name, undefined, undefined); + Policy.deleteWorkspace(fakePolicy.id, fakePolicy.name, undefined); await waitForBatchedUpdates(); @@ -897,7 +897,7 @@ describe('actions/Policy', () => { {name: 'hold', type: CONST.VIOLATION_TYPES.WARNING}, ]); - Policy.deleteWorkspace(policyID, 'test', undefined, undefined); + Policy.deleteWorkspace(policyID, 'test', undefined); await waitForBatchedUpdates(); @@ -922,7 +922,7 @@ describe('actions/Policy', () => { jest.spyOn(PolicyUtils, 'getPersonalPolicy').mockReturnValue(personalPolicy); - Policy.deleteWorkspace(teamPolicy.id, teamPolicy.name, undefined, undefined); + Policy.deleteWorkspace(teamPolicy.id, teamPolicy.name, undefined); await waitForBatchedUpdates(); const activePolicyID: OnyxEntry = await new Promise((resolve) => { @@ -946,7 +946,7 @@ describe('actions/Policy', () => { await Onyx.merge(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); - Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID, undefined); + Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); const lastAccessedWorkspacePolicyIDAfterDelete: OnyxEntry = await new Promise((resolve) => { @@ -972,7 +972,7 @@ describe('actions/Policy', () => { await Onyx.merge(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); - Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID, undefined); + Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); const lastAccessedWorkspacePolicyIDAfterDelete: OnyxEntry = await new Promise((resolve) => { From 4930837d1651d5aca024997ba1efd5f0e8bc07b2 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 12 Sep 2025 10:37:53 +0800 Subject: [PATCH 4/5] lint --- src/libs/actions/Policy/Policy.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 167b18513197..57f3e2ec154b 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -285,10 +285,7 @@ let policyCardFeeds: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, waitForCollectionCallback: true, - callback: (value) => { - policyCardFeeds = value; - console.log('policy card feeds', value); - }, + callback: (value) => (policyCardFeeds = value), }); /** From 896200fca4d5c28f7c8a8fd864929767a940e3bc Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sun, 14 Sep 2025 14:00:09 +0800 Subject: [PATCH 5/5] Revert "get the card feeds with Onyx.connectWithView" This reverts commit e6dc0b82d795d783a0b6a095be0eb10565ed2e5b. --- src/hooks/useCardFeeds.tsx | 9 +++++---- src/libs/actions/Policy/Policy.ts | 18 ++++++++---------- src/pages/workspace/WorkspaceOverviewPage.tsx | 6 +++--- src/pages/workspace/WorkspacesListPage.tsx | 4 ++-- tests/actions/IOUTest.ts | 2 +- tests/actions/PolicyTest.ts | 10 +++++----- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index fc725e2eaf0a..b86ceb212a62 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -16,19 +16,20 @@ import useWorkspaceAccountID from './useWorkspaceAccountID'; * @param policyID - The workspace policyID to filter and construct card feeds for. * @returns - * A tuple containing: - * 1. Card feeds specific to the given policyID (or `undefined` if unavailable). + * 1. Combined workspace and domain card feeds specific to the given policyID (or `undefined` if unavailable). * 2. The result metadata from the Onyx collection fetch. + * 3. Card feeds specific to the given policyID (or `undefined` if unavailable). */ -const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { +const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>, CardFeeds | undefined] => { const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, {canBeMissing: true}); + const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const workspaceFeeds = useMemo(() => { if (!policyID || !allFeeds) { return undefined; } - const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const {companyCards = {}, companyCardNicknames = {}, oAuthAccountDetails = {}} = defaultFeed?.settings ?? {}; const result: CardFeeds & {settings: Required} = { @@ -70,7 +71,7 @@ const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, Res }, result); }, [allFeeds, policyID, workspaceAccountID]); - return [workspaceFeeds, allFeedsResult]; + return [workspaceFeeds, allFeedsResult, defaultFeed]; }; export default useCardFeeds; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 7449bff41f7d..3bef9e2242bc 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -281,13 +281,6 @@ Onyx.connect({ callback: (value) => (introSelected = value), }); -let policyCardFeeds: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, - waitForCollectionCallback: true, - callback: (value) => (policyCardFeeds = value), -}); - /** * Stores in Onyx the policy ID of the last workspace that was accessed by the user */ @@ -372,7 +365,13 @@ function hasActiveChatEnabledPolicies(policies: Array> /** * Delete the workspace */ -function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorkspacePolicyID: string | undefined, lastUsedPaymentMethods?: LastPaymentMethod) { +function deleteWorkspace( + policyID: string, + policyName: string, + lastAccessedWorkspacePolicyID: string | undefined, + policyCardFeeds: CardFeeds | undefined, + lastUsedPaymentMethods?: LastPaymentMethod, +) { if (!allPolicies) { return; } @@ -382,7 +381,6 @@ function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorks const policy = getPolicy(policyID); const filteredPolicies = Object.values(allPolicies).filter((p): p is Policy => p?.id !== policyID); const workspaceAccountID = policy?.workspaceAccountID; - const policyCardFeed = policyCardFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -431,7 +429,7 @@ function deleteWorkspace(policyID: string, policyName: string, lastAccessedWorks { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, - value: policyCardFeed, + value: policyCardFeeds, }, ]; diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index f09334c351ed..6ca05d0e2778 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -89,7 +89,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds] = useCardFeeds(policy?.id); + const [cardFeeds, , defaultCardFeeds] = useCardFeeds(policy?.id); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, @@ -197,10 +197,10 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa return; } - deleteWorkspace(policy.id, policyName, lastAccessedWorkspacePolicyID, lastPaymentMethod); + deleteWorkspace(policy.id, policyName, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod); setIsDeleteModalOpen(false); goBackFromInvalidPolicy(); - }, [policy?.id, policyName, lastAccessedWorkspacePolicyID, lastPaymentMethod]); + }, [policy?.id, policyName, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod]); useEffect(() => { if (isLoadingBill) { diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index 3f41310cae3e..c2256f52a46f 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -134,7 +134,7 @@ function WorkspacesListPage() { // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. const workspaceAccountID = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyIDToDelete}`]?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds] = useCardFeeds(policyIDToDelete); + const [cardFeeds, , defaultCardFeeds] = useCardFeeds(policyIDToDelete); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, @@ -162,7 +162,7 @@ function WorkspacesListPage() { return; } - deleteWorkspace(policyIDToDelete, policyNameToDelete, lastAccessedWorkspacePolicyID, lastPaymentMethod); + deleteWorkspace(policyIDToDelete, policyNameToDelete, lastAccessedWorkspacePolicyID, defaultCardFeeds, lastPaymentMethod); setIsDeleteModalOpen(false); }; diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 65e429f09e47..a5ae39d38c8a 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -4414,7 +4414,7 @@ describe('actions/IOU', () => { ) .then(() => { if (policy) { - deleteWorkspace(policy.id, policy.name, undefined); + deleteWorkspace(policy.id, policy.name, undefined, undefined); } return waitForBatchedUpdates(); }) diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index 68341f9b9811..fc530e8be50d 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -817,7 +817,7 @@ describe('actions/Policy', () => { // When deleting a workspace fails mockFetch?.fail?.(); - Policy.deleteWorkspace(fakePolicy.id, fakePolicy.name, undefined); + Policy.deleteWorkspace(fakePolicy.id, fakePolicy.name, undefined, undefined); await waitForBatchedUpdates(); @@ -897,7 +897,7 @@ describe('actions/Policy', () => { {name: 'hold', type: CONST.VIOLATION_TYPES.WARNING}, ]); - Policy.deleteWorkspace(policyID, 'test', undefined); + Policy.deleteWorkspace(policyID, 'test', undefined, undefined); await waitForBatchedUpdates(); @@ -922,7 +922,7 @@ describe('actions/Policy', () => { jest.spyOn(PolicyUtils, 'getPersonalPolicy').mockReturnValue(personalPolicy); - Policy.deleteWorkspace(teamPolicy.id, teamPolicy.name, undefined); + Policy.deleteWorkspace(teamPolicy.id, teamPolicy.name, undefined, undefined); await waitForBatchedUpdates(); const activePolicyID: OnyxEntry = await new Promise((resolve) => { @@ -946,7 +946,7 @@ describe('actions/Policy', () => { await Onyx.merge(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); - Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID); + Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID, undefined); await waitForBatchedUpdates(); const lastAccessedWorkspacePolicyIDAfterDelete: OnyxEntry = await new Promise((resolve) => { @@ -972,7 +972,7 @@ describe('actions/Policy', () => { await Onyx.merge(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, lastAccessedWorkspacePolicyID); await waitForBatchedUpdates(); - Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID); + Policy.deleteWorkspace(policyToDelete.id, policyToDelete.name, lastAccessedWorkspacePolicyID, undefined); await waitForBatchedUpdates(); const lastAccessedWorkspacePolicyIDAfterDelete: OnyxEntry = await new Promise((resolve) => {