From 2cb18f146402b73ef4152f9590c801e23e9e6ec0 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 19 Feb 2025 11:49:47 +0100 Subject: [PATCH 1/4] fix: get feed cards --- src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx index dbe4bf9f3b86..37ed79140624 100644 --- a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx @@ -10,7 +10,7 @@ import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {getCardFeedIcon, getCompanyFeeds, getCustomOrFormattedFeedName, getFilteredCardList, hasOnlyOneCardToAssign, isSelectedFeedExpired} from '@libs/CardUtils'; +import {getCardFeedIcon, getCompanyFeeds, getCustomOrFormattedFeedName, getFilteredCardList, hasOnlyOneCardToAssign, isCustomFeed, isSelectedFeedExpired} from '@libs/CardUtils'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {getPolicy, getWorkspaceAccountID} from '@libs/PolicyUtils'; @@ -20,7 +20,7 @@ import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPol import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; import variables from '@styles/variables'; import {setIssueNewCardStepAndData} from '@userActions/Card'; -import {setAssignCardStepAndData} from '@userActions/CompanyCards'; +import {openPolicyCompanyCardsFeed, setAssignCardStepAndData} from '@userActions/CompanyCards'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -99,6 +99,9 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew const handleSelectFeed = (feed: CardFeedListItem) => { setSelectedFeed(feed.value); + if (isCustomFeed(feed.value as CompanyCardFeed)) { + openPolicyCompanyCardsFeed(policyID, feed.value as CompanyCardFeed); + } setShouldShowError(false); }; From 4ca6f440b00913d9a7b80f522dbd87d3939ab4c1 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 20 Feb 2025 10:56:46 +0100 Subject: [PATCH 2/4] chore: replace openPolicyCompanyCardsFeed with openAssignFeedCardPage --- src/libs/API/types.ts | 2 ++ src/libs/actions/CompanyCards.ts | 10 ++++++++++ .../workspace/members/WorkspaceMemberNewCardPage.tsx | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index b8d150672e7c..07157aba256e 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -978,6 +978,7 @@ const READ_COMMANDS = { OPEN_POLICY_REPORT_FIELDS_PAGE: 'OpenPolicyReportFieldsPage', OPEN_POLICY_EXPENSIFY_CARDS_PAGE: 'OpenPolicyExpensifyCardsPage', OPEN_POLICY_COMPANY_CARDS_FEED: 'OpenPolicyCompanyCardsFeed', + OPEN_ASSIGN_FEED_CARD_PAGE: 'OpenAssignFeedCardPage', OPEN_POLICY_COMPANY_CARDS_PAGE: 'OpenPolicyCompanyCardsPage', OPEN_POLICY_EDIT_CARD_LIMIT_TYPE_PAGE: 'OpenPolicyEditCardLimitTypePage', OPEN_SEARCH_FILTERS_CARD_PAGE: 'OpenSearchFiltersCardPage', @@ -1054,6 +1055,7 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_POLICY_EXPENSIFY_CARDS_PAGE]: Parameters.OpenPolicyExpensifyCardsPageParams; [READ_COMMANDS.OPEN_POLICY_COMPANY_CARDS_PAGE]: Parameters.OpenPolicyExpensifyCardsPageParams; [READ_COMMANDS.OPEN_POLICY_COMPANY_CARDS_FEED]: Parameters.OpenPolicyCompanyCardsFeedParams; + [READ_COMMANDS.OPEN_ASSIGN_FEED_CARD_PAGE]: Parameters.OpenPolicyCompanyCardsFeedParams; [READ_COMMANDS.OPEN_POLICY_EDIT_CARD_LIMIT_TYPE_PAGE]: Parameters.OpenPolicyEditCardLimitTypePageParams; [READ_COMMANDS.OPEN_SEARCH_FILTERS_CARD_PAGE]: null; [READ_COMMANDS.OPEN_POLICY_PROFILE_PAGE]: Parameters.OpenPolicyProfilePageParams; diff --git a/src/libs/actions/CompanyCards.ts b/src/libs/actions/CompanyCards.ts index c548d7014322..e5b90e18a953 100644 --- a/src/libs/actions/CompanyCards.ts +++ b/src/libs/actions/CompanyCards.ts @@ -724,6 +724,15 @@ function openPolicyCompanyCardsFeed(policyID: string, feed: CompanyCardFeed) { API.read(READ_COMMANDS.OPEN_POLICY_COMPANY_CARDS_FEED, parameters); } +function openAssignFeedCardPage(policyID: string, feed: CompanyCardFeed) { + const parameters: OpenPolicyCompanyCardsFeedParams = { + policyID, + feed, + }; + + API.read(READ_COMMANDS.OPEN_ASSIGN_FEED_CARD_PAGE, parameters); +} + export { setWorkspaceCompanyCardFeedName, deleteWorkspaceCompanyCardFeed, @@ -741,4 +750,5 @@ export { clearAddNewCardFlow, setAssignCardStepAndData, clearAssignCardStepAndData, + openAssignFeedCardPage, }; diff --git a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx index 37ed79140624..6cef098e1342 100644 --- a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx @@ -20,7 +20,7 @@ import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPol import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; import variables from '@styles/variables'; import {setIssueNewCardStepAndData} from '@userActions/Card'; -import {openPolicyCompanyCardsFeed, setAssignCardStepAndData} from '@userActions/CompanyCards'; +import {openAssignFeedCardPage, setAssignCardStepAndData} from '@userActions/CompanyCards'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -100,7 +100,7 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew const handleSelectFeed = (feed: CardFeedListItem) => { setSelectedFeed(feed.value); if (isCustomFeed(feed.value as CompanyCardFeed)) { - openPolicyCompanyCardsFeed(policyID, feed.value as CompanyCardFeed); + openAssignFeedCardPage(policyID, feed.value as CompanyCardFeed); } setShouldShowError(false); }; From d6fbc079d60911ca51439ca007627fb6eab61684 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Thu, 20 Feb 2025 12:11:40 +0100 Subject: [PATCH 3/4] feat: add a loader when fetching the cards data --- src/libs/actions/CompanyCards.ts | 34 +++++++++++++++++-- .../members/WorkspaceMemberNewCardPage.tsx | 3 +- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/CompanyCards.ts b/src/libs/actions/CompanyCards.ts index e5b90e18a953..ef8a54d61071 100644 --- a/src/libs/actions/CompanyCards.ts +++ b/src/libs/actions/CompanyCards.ts @@ -724,13 +724,43 @@ function openPolicyCompanyCardsFeed(policyID: string, feed: CompanyCardFeed) { API.read(READ_COMMANDS.OPEN_POLICY_COMPANY_CARDS_FEED, parameters); } -function openAssignFeedCardPage(policyID: string, feed: CompanyCardFeed) { +function openAssignFeedCardPage(policyID: string, feed: CompanyCardFeed, workspaceAccountID: number) { const parameters: OpenPolicyCompanyCardsFeedParams = { policyID, feed, }; - API.read(READ_COMMANDS.OPEN_ASSIGN_FEED_CARD_PAGE, parameters); + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, + value: { + isLoading: true, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, + value: { + isLoading: false, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, + value: { + isLoading: false, + }, + }, + ]; + + API.read(READ_COMMANDS.OPEN_ASSIGN_FEED_CARD_PAGE, parameters, {optimisticData, successData, failureData}); } export { diff --git a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx index 6cef098e1342..3a5007c66427 100644 --- a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx @@ -100,7 +100,7 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew const handleSelectFeed = (feed: CardFeedListItem) => { setSelectedFeed(feed.value); if (isCustomFeed(feed.value as CompanyCardFeed)) { - openAssignFeedCardPage(policyID, feed.value as CompanyCardFeed); + openAssignFeedCardPage(policyID, feed.value as CompanyCardFeed, workspaceAccountID); } setShouldShowError(false); }; @@ -172,6 +172,7 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew onSubmit={handleSubmit} message={translate('common.error.pleaseSelectOne')} buttonText={translate('common.next')} + isLoading={!!cardFeeds?.isLoading} /> From 770a778dc7e2944fbd6865c5d6d0c551553d148f Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Fri, 21 Feb 2025 13:55:16 +0100 Subject: [PATCH 4/4] fix: call api only when there is no sufficient data --- src/libs/CardUtils.ts | 6 ++++++ .../members/WorkspaceMemberNewCardPage.tsx | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libs/CardUtils.ts b/src/libs/CardUtils.ts index 7a48cf6bcf90..730dca6acdf3 100644 --- a/src/libs/CardUtils.ts +++ b/src/libs/CardUtils.ts @@ -512,6 +512,11 @@ function checkIfFeedConnectionIsBroken(feedCards: Record | undefin return Object.values(feedCards).some((card) => card.bank !== feedToExclude && card.lastScrapeResult !== 200); } +function hasCardListObject(workspaceAccountID: number, feedName: CompanyCardFeed): boolean { + const workspaceCards = allWorkspaceCards?.[`cards_${workspaceAccountID}_${feedName}`] ?? {}; + return !!workspaceCards.cardList; +} + export { isExpensifyCard, isCorporateCard, @@ -549,4 +554,5 @@ export { getFeedType, flatAllCardsList, checkIfFeedConnectionIsBroken, + hasCardListObject, }; diff --git a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx index 3a5007c66427..968c22283c7b 100644 --- a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx @@ -10,7 +10,16 @@ import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {getCardFeedIcon, getCompanyFeeds, getCustomOrFormattedFeedName, getFilteredCardList, hasOnlyOneCardToAssign, isCustomFeed, isSelectedFeedExpired} from '@libs/CardUtils'; +import { + getCardFeedIcon, + getCompanyFeeds, + getCustomOrFormattedFeedName, + getFilteredCardList, + hasCardListObject, + hasOnlyOneCardToAssign, + isCustomFeed, + isSelectedFeedExpired, +} from '@libs/CardUtils'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {getPolicy, getWorkspaceAccountID} from '@libs/PolicyUtils'; @@ -99,7 +108,8 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew const handleSelectFeed = (feed: CardFeedListItem) => { setSelectedFeed(feed.value); - if (isCustomFeed(feed.value as CompanyCardFeed)) { + const hasAllCardsData = hasCardListObject(workspaceAccountID, feed.value as CompanyCardFeed); + if (isCustomFeed(feed.value as CompanyCardFeed) && !hasAllCardsData) { openAssignFeedCardPage(policyID, feed.value as CompanyCardFeed, workspaceAccountID); } setShouldShowError(false);