From 8cffd511c0c2a163af223ef8cf546c4bd4e8537a Mon Sep 17 00:00:00 2001 From: VickyStash Date: Tue, 15 Apr 2025 11:54:57 +0200 Subject: [PATCH 1/6] Implement useCardFeeds hook --- src/hooks/useCardFeeds.tsx | 37 +++++++++++++++++++ .../workspace/WorkspaceMoreFeaturesPage.tsx | 3 +- src/pages/workspace/WorkspaceOverviewPage.tsx | 3 +- src/pages/workspace/WorkspacesListPage.tsx | 3 +- .../BankConnection/index.native.tsx | 5 +-- .../companyCards/BankConnection/index.tsx | 5 +-- .../WorkspaceCompanyCardFeedSelectorPage.tsx | 3 +- ...WorkspaceCompanyCardsListHeaderButtons.tsx | 3 +- .../WorkspaceCompanyCardsPage.tsx | 3 +- ...kspaceCompanyCardsSettingsFeedNamePage.tsx | 3 +- .../WorkspaceCompanyCardsSettingsPage.tsx | 3 +- .../companyCards/addNew/DetailsStep.tsx | 5 +-- .../companyCards/assignCard/AssigneeStep.tsx | 3 +- .../assignCard/CardSelectionStep.tsx | 3 +- .../assignCard/ConfirmationStep.tsx | 5 +-- .../downgrade/WorkspaceDowngradePage.tsx | 5 +-- .../members/WorkspaceMemberDetailsPage.tsx | 3 +- .../members/WorkspaceMemberNewCardPage.tsx | 3 +- 18 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 src/hooks/useCardFeeds.tsx diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx new file mode 100644 index 0000000000000..d3027e03dc194 --- /dev/null +++ b/src/hooks/useCardFeeds.tsx @@ -0,0 +1,37 @@ +import type {ResultMetadata} from 'react-native-onyx'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {CardFeeds, CompanyCardFeed} from '@src/types/onyx'; +import useOnyx from './useOnyx'; + +const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata] => { + const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER); + + if (!policyID || !allFeeds) { + return [undefined, allFeedsResult]; + } + + const workspaceFeeds: {settings: Required} = {settings: {companyCards: {}, companyCardNicknames: {}, oAuthAccountDetails: {}}}; + + Object.values(allFeeds).forEach((feed) => { + if (!feed) { + return; + } + const companyCards = feed.settings.companyCards; + Object.entries(companyCards ?? {}).forEach(([key, feedSettings]) => { + const feedName = key as CompanyCardFeed; + if (feedSettings.preferredPolicy === policyID && !workspaceFeeds.settings.companyCards[feedName]) { + workspaceFeeds.settings.companyCards[feedName] = feedSettings; + if (feed.settings.oAuthAccountDetails?.[feedName]) { + workspaceFeeds.settings.oAuthAccountDetails[feedName] = feed.settings.oAuthAccountDetails[feedName]; + } + if (feed.settings.companyCardNicknames?.[feedName]) { + workspaceFeeds.settings.companyCardNicknames[feedName] = feed.settings.companyCardNicknames[feedName]; + } + } + }); + }); + + return [workspaceFeeds, allFeedsResult]; +}; + +export default useCardFeeds; diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index 3e34882f7a523..e0d02fe1d57d0 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -8,6 +8,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import Text from '@components/Text'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -85,7 +86,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const policyID = policy?.id; const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID.toString()}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID.toString()}`); + const [cardFeeds] = useCardFeeds(policyID); const [isOrganizeWarningModalOpen, setIsOrganizeWarningModalOpen] = useState(false); const [isIntegrateWarningModalOpen, setIsIntegrateWarningModalOpen] = useState(false); const [isReportFieldsWarningModalOpen, setIsReportFieldsWarningModalOpen] = useState(false); diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index ee207ac0ecdd6..131a0ffb05992 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -13,6 +13,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import Section from '@components/Section'; import useActiveWorkspace from '@hooks/useActiveWorkspace'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; @@ -72,7 +73,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] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policy?.id); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); const hasCardFeedOrExpensifyCard = // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index e5590b1f37506..877ed8472e30b 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -24,6 +24,7 @@ import ScrollView from '@components/ScrollView'; import SupportalActionRestrictedModal from '@components/SupportalActionRestrictedModal'; import Text from '@components/Text'; import useActiveWorkspace from '@hooks/useActiveWorkspace'; +import useCardFeeds from '@hooks/useCardFeeds'; import useHandleBackButton from '@hooks/useHandleBackButton'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -143,7 +144,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] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyIDToDelete); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); const policyToDelete = getPolicy(policyIDToDelete); const hasCardFeedOrExpensifyCard = diff --git a/src/pages/workspace/companyCards/BankConnection/index.native.tsx b/src/pages/workspace/companyCards/BankConnection/index.native.tsx index 58e96b661933e..97de0164bc1f5 100644 --- a/src/pages/workspace/companyCards/BankConnection/index.native.tsx +++ b/src/pages/workspace/companyCards/BankConnection/index.native.tsx @@ -7,11 +7,11 @@ import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOffli import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID'; import {updateSelectedFeed} from '@libs/actions/Card'; import {setAssignCardStepAndData} from '@libs/actions/CompanyCards'; import {checkIfNewFeedConnected, getBankName, isSelectedFeedExpired} from '@libs/CardUtils'; @@ -51,8 +51,7 @@ function BankConnection({policyID: policyIDFromProps, feed, route}: BankConnecti const policyID = policyIDFromProps ?? policyIDFromRoute; const bankName = feed ? getBankName(feed) : bankNameFromRoute ?? addNewCard?.data?.selectedBank; const url = getCompanyCardBankConnection(policyID, bankName); - const workspaceAccountID = useWorkspaceAccountID(policyID); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const [isConnectionCompleted, setConnectionCompleted] = useState(false); const prevFeedsData = usePrevious(cardFeeds?.settings?.oAuthAccountDetails); const isFeedExpired = feed ? isSelectedFeedExpired(cardFeeds?.settings?.oAuthAccountDetails?.[feed]) : false; diff --git a/src/pages/workspace/companyCards/BankConnection/index.tsx b/src/pages/workspace/companyCards/BankConnection/index.tsx index c5daa650e05f8..7dc370e64e9ba 100644 --- a/src/pages/workspace/companyCards/BankConnection/index.tsx +++ b/src/pages/workspace/companyCards/BankConnection/index.tsx @@ -7,11 +7,11 @@ import {PendingBank} from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID'; import {setAssignCardStepAndData} from '@libs/actions/CompanyCards'; import {checkIfNewFeedConnected, getBankName, isSelectedFeedExpired} from '@libs/CardUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -47,8 +47,7 @@ function BankConnection({policyID: policyIDFromProps, feed, route}: BankConnecti const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); const {bankName: bankNameFromRoute, backTo, policyID: policyIDFromRoute} = route?.params ?? {}; const policyID = policyIDFromProps ?? policyIDFromRoute; - const workspaceAccountID = useWorkspaceAccountID(policyID); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const prevFeedsData = usePrevious(cardFeeds?.settings?.oAuthAccountDetails); const [shouldBlockWindowOpen, setShouldBlockWindowOpen] = useState(false); const bankName = feed ? getBankName(feed) : bankNameFromRoute ?? addNewCard?.data?.selectedBank; diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx index d14db3b205b11..277e4bf23a906 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx @@ -8,6 +8,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeIllustrations from '@hooks/useThemeIllustrations'; @@ -42,7 +43,7 @@ function WorkspaceCompanyCardFeedSelectorPage({route}: WorkspaceCompanyCardFeedS const {translate} = useLocalize(); const styles = useThemeStyles(); const illustrations = useThemeIllustrations(); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); const selectedFeed = getSelectedFeed(lastSelectedFeed, cardFeeds); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx index 37786c6f578c0..7ffb7e1187f3f 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx @@ -8,6 +8,7 @@ import * as Expensicons from '@components/Icon/Expensicons'; import {PressableWithFeedback} from '@components/Pressable'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -53,7 +54,7 @@ function WorkspaceCompanyCardsListHeaderButtons({policyID, selectedFeed, shouldS const illustrations = useThemeIllustrations(); const {shouldUseNarrowLayout, isMediumScreenWidth} = useResponsiveLayout(); const workspaceAccountID = useWorkspaceAccountID(policyID); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); const shouldChangeLayout = isMediumScreenWidth || shouldUseNarrowLayout; const formattedFeedName = getCustomOrFormattedFeedName(selectedFeed, cardFeeds?.settings?.companyCardNicknames); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx index b317dc48049d4..97fc648c88562 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx @@ -4,6 +4,7 @@ import {useOnyx} from 'react-native-onyx'; import DecisionModal from '@components/DecisionModal'; import DelegateNoAccessModal from '@components/DelegateNoAccessModal'; import * as Illustrations from '@components/Icon/Illustrations'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -48,7 +49,7 @@ function WorkspaceCompanyCardsPage({route}: WorkspaceCompanyCardsPageProps) { const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const selectedFeed = getSelectedFeed(lastSelectedFeed, cardFeeds); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${selectedFeed}`, {selector: filterInactiveCards}); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx index d557b0326caa8..6f48e0d6740e8 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx @@ -10,6 +10,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -41,7 +42,7 @@ function WorkspaceCompanyCardsSettingsFeedNamePage({ const policy = usePolicy(policyID); const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; const [lastSelectedFeed, lastSelectedFeedResult] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); - const [cardFeeds, cardFeedsResult] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds, cardFeedsResult] = useCardFeeds(policyID); const selectedFeed = getSelectedFeed(lastSelectedFeed, cardFeeds); const feedName = getCustomOrFormattedFeedName(selectedFeed, cardFeeds?.settings?.companyCardNicknames); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx index 7e7656a488849..baae341cd1fb6 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx @@ -9,6 +9,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -38,7 +39,7 @@ function WorkspaceCompanyCardsSettingsPage({ const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; const [deleteCompanyCardConfirmModalVisible, setDeleteCompanyCardConfirmModalVisible] = useState(false); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); const selectedFeed = useMemo(() => getSelectedFeed(lastSelectedFeed, cardFeeds), [cardFeeds, lastSelectedFeed]); diff --git a/src/pages/workspace/companyCards/addNew/DetailsStep.tsx b/src/pages/workspace/companyCards/addNew/DetailsStep.tsx index 39f2c8dff4877..28474be4cf5a6 100644 --- a/src/pages/workspace/companyCards/addNew/DetailsStep.tsx +++ b/src/pages/workspace/companyCards/addNew/DetailsStep.tsx @@ -12,10 +12,10 @@ import Text from '@components/Text'; import TextInput from '@components/TextInput'; import TextLink from '@components/TextLink'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID'; import {getFieldRequiredErrors} from '@libs/ValidationUtils'; import Navigation from '@navigation/Navigation'; import variables from '@styles/variables'; @@ -39,8 +39,7 @@ function DetailsStep({policyID}: DetailsStepProps) { const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD); const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); - const workspaceAccountID = useWorkspaceAccountID(policyID); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const feedProvider = addNewCard?.data?.feedType; const isStripeFeedProvider = feedProvider === CONST.COMPANY_CARD.FEED_BANK_NAME.STRIPE; diff --git a/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx b/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx index 74148acbbc4d1..9d595187b9647 100644 --- a/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx @@ -9,6 +9,7 @@ import SelectionList from '@components/SelectionList'; import type {ListItem} from '@components/SelectionList/types'; import UserListItem from '@components/SelectionList/UserListItem'; import Text from '@components/Text'; +import useCardFeeds from '@hooks/useCardFeeds'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; @@ -43,7 +44,7 @@ function AssigneeStep({policy, feed}: AssigneeStepProps) { const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`, {selector: filterInactiveCards}); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policy?.id); const filteredCardList = getFilteredCardList(list, cardFeeds?.settings?.oAuthAccountDetails?.[feed]); const isEditing = assignCard?.isEditing; diff --git a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx index bae21b64aa0bb..7fcdd58d40d89 100644 --- a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx @@ -11,6 +11,7 @@ import RadioListItem from '@components/SelectionList/RadioListItem'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useBottomSafeSafeAreaPaddingStyle from '@hooks/useBottomSafeSafeAreaPaddingStyle'; +import useCardFeeds from '@hooks/useCardFeeds'; import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; import useThemeIllustrations from '@hooks/useThemeIllustrations'; @@ -44,7 +45,7 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) { const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`, {selector: filterInactiveCards}); const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const isEditing = assignCard?.isEditing; const assigneeDisplayName = getPersonalDetailByEmail(assignCard?.data?.email ?? '')?.displayName ?? ''; diff --git a/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx b/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx index 71a7241118d48..95bc959d8bbc7 100644 --- a/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx @@ -7,10 +7,10 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID'; import {isSelectedFeedExpired, lastFourNumbersFromCardName, maskCardNumber} from '@libs/CardUtils'; import {getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils'; import Navigation from '@navigation/Navigation'; @@ -34,11 +34,10 @@ function ConfirmationStep({policyID, backTo}: ConfirmationStepProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); - const workspaceAccountID = useWorkspaceAccountID(policyID); const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); const feed = assignCard?.data?.bankName as CompanyCardFeed | undefined; - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const data = assignCard?.data; const cardholderName = getPersonalDetailByEmail(data?.email ?? '')?.displayName ?? ''; diff --git a/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx b/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx index 74bf7754c5a80..ea2d056644680 100644 --- a/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx +++ b/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx @@ -6,6 +6,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -15,7 +16,6 @@ import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavig import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {canModifyPlan, isCollectPolicy} from '@libs/PolicyUtils'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; -import CONST from '@src/CONST'; import {downgradeToTeam} from '@src/libs/actions/Policy/Policy'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -29,8 +29,7 @@ function WorkspaceDowngradePage({route}: WorkspaceDowngradePageProps) { const styles = useThemeStyles(); const policyID = route.params?.policyID; const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); - const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const companyFeeds = getCompanyFeeds(cardFeeds); const {translate} = useLocalize(); const {isOffline} = useNetwork(); diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx index c8241dc2310f9..9e44b513baad7 100644 --- a/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx @@ -18,6 +18,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import UserDetailsTooltip from '@components/UserDetailsTooltip'; +import useCardFeeds from '@hooks/useCardFeeds'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; @@ -74,7 +75,7 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM const StyleUtils = useStyleUtils(); const illustrations = useThemeIllustrations(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const [cardList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); diff --git a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx index 4bf96adc4297c..6af093a12ff4b 100644 --- a/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberNewCardPage.tsx @@ -8,6 +8,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {ListItem} from '@components/SelectionList/types'; +import useCardFeeds from '@hooks/useCardFeeds'; import useLocalize from '@hooks/useLocalize'; import useThemeIllustrations from '@hooks/useThemeIllustrations'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -55,7 +56,7 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew const {translate} = useLocalize(); const styles = useThemeStyles(); const illustrations = useThemeIllustrations(); - const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + const [cardFeeds] = useCardFeeds(policyID); const [selectedFeed, setSelectedFeed] = useState(''); const [shouldShowError, setShouldShowError] = useState(false); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); From 92df591066a469bb2098b9bca876130d92ff0f00 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 16 Apr 2025 10:56:46 +0200 Subject: [PATCH 2/6] Update useCardFeed hook --- src/hooks/useCardFeeds.tsx | 49 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index d3027e03dc194..fc56393c0552b 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -2,34 +2,47 @@ import type {ResultMetadata} from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; import type {CardFeeds, CompanyCardFeed} from '@src/types/onyx'; import useOnyx from './useOnyx'; +import useWorkspaceAccountID from './useWorkspaceAccountID'; const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata] => { + const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER); + const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; + const {companyCards = {}, companyCardNicknames = {}, oAuthAccountDetails = {}} = defaultFeed?.settings ?? {}; if (!policyID || !allFeeds) { return [undefined, allFeedsResult]; } - const workspaceFeeds: {settings: Required} = {settings: {companyCards: {}, companyCardNicknames: {}, oAuthAccountDetails: {}}}; - - Object.values(allFeeds).forEach((feed) => { - if (!feed) { - return; - } - const companyCards = feed.settings.companyCards; - Object.entries(companyCards ?? {}).forEach(([key, feedSettings]) => { - const feedName = key as CompanyCardFeed; - if (feedSettings.preferredPolicy === policyID && !workspaceFeeds.settings.companyCards[feedName]) { - workspaceFeeds.settings.companyCards[feedName] = feedSettings; - if (feed.settings.oAuthAccountDetails?.[feedName]) { - workspaceFeeds.settings.oAuthAccountDetails[feedName] = feed.settings.oAuthAccountDetails[feedName]; + const workspaceFeeds = Object.values(allFeeds).reduce}>( + (acc, feed) => { + if (!feed?.settings?.companyCards) { + return acc; + } + + Object.entries(feed.settings.companyCards).forEach(([key, feedSettings]) => { + const feedName = key as CompanyCardFeed; + const feedOAuthAccountDetails = feed.settings.oAuthAccountDetails?.[feedName]; + const feedCompanyCardNicknames = feed.settings.companyCardNicknames?.[feedName]; + + if (feedSettings.preferredPolicy !== policyID || acc.settings.companyCards[feedName]) { + return; + } + + acc.settings.companyCards[feedName] = feedSettings; + + if (feedOAuthAccountDetails) { + acc.settings.oAuthAccountDetails[feedName] = feedOAuthAccountDetails; } - if (feed.settings.companyCardNicknames?.[feedName]) { - workspaceFeeds.settings.companyCardNicknames[feedName] = feed.settings.companyCardNicknames[feedName]; + if (feedCompanyCardNicknames) { + acc.settings.companyCardNicknames[feedName] = feedCompanyCardNicknames; } - } - }); - }); + }); + + return acc; + }, + {settings: {companyCards, companyCardNicknames, oAuthAccountDetails}}, + ); return [workspaceFeeds, allFeedsResult]; }; From 31236b948d5138157a4e7ff10080c01fae3ac72c Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 16 Apr 2025 11:27:06 +0200 Subject: [PATCH 3/6] Fix ts error --- src/hooks/useCardFeeds.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index fc56393c0552b..3f70090ae09be 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -1,10 +1,10 @@ -import type {ResultMetadata} from 'react-native-onyx'; +import type {OnyxCollection, ResultMetadata} from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; import type {CardFeeds, CompanyCardFeed} from '@src/types/onyx'; import useOnyx from './useOnyx'; import useWorkspaceAccountID from './useWorkspaceAccountID'; -const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata] => { +const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER); const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; From 2b0c298b17eec5f5bf1d808469c92bf7981ecb1e Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 17 Apr 2025 10:45:38 +0200 Subject: [PATCH 4/6] Apply reviewer feedback --- src/hooks/useCardFeeds.tsx | 62 ++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index 3f70090ae09be..d270ad731de6c 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -1,3 +1,4 @@ +import {useMemo} from 'react'; import type {OnyxCollection, ResultMetadata} from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; import type {CardFeeds, CompanyCardFeed} from '@src/types/onyx'; @@ -7,42 +8,45 @@ import useWorkspaceAccountID from './useWorkspaceAccountID'; const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER); - const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; - const {companyCards = {}, companyCardNicknames = {}, oAuthAccountDetails = {}} = defaultFeed?.settings ?? {}; - if (!policyID || !allFeeds) { - return [undefined, allFeedsResult]; - } + const workspaceFeeds = useMemo(() => { + if (!policyID || !allFeeds) { + return undefined; + } - const workspaceFeeds = Object.values(allFeeds).reduce}>( - (acc, feed) => { - if (!feed?.settings?.companyCards) { - return acc; - } - - Object.entries(feed.settings.companyCards).forEach(([key, feedSettings]) => { - const feedName = key as CompanyCardFeed; - const feedOAuthAccountDetails = feed.settings.oAuthAccountDetails?.[feedName]; - const feedCompanyCardNicknames = feed.settings.companyCardNicknames?.[feedName]; + const defaultFeed = allFeeds?.[`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`]; + const {companyCards = {}, companyCardNicknames = {}, oAuthAccountDetails = {}} = defaultFeed?.settings ?? {}; - if (feedSettings.preferredPolicy !== policyID || acc.settings.companyCards[feedName]) { - return; + return Object.values(allFeeds).reduce}>( + (acc, feed) => { + if (!feed?.settings?.companyCards) { + return acc; } - acc.settings.companyCards[feedName] = feedSettings; + Object.entries(feed.settings.companyCards).forEach(([key, feedSettings]) => { + const feedName = key as CompanyCardFeed; + const feedOAuthAccountDetails = feed.settings.oAuthAccountDetails?.[feedName]; + const feedCompanyCardNicknames = feed.settings.companyCardNicknames?.[feedName]; - if (feedOAuthAccountDetails) { - acc.settings.oAuthAccountDetails[feedName] = feedOAuthAccountDetails; - } - if (feedCompanyCardNicknames) { - acc.settings.companyCardNicknames[feedName] = feedCompanyCardNicknames; - } - }); + if (feedSettings.preferredPolicy !== policyID || acc.settings.companyCards[feedName]) { + return; + } - return acc; - }, - {settings: {companyCards, companyCardNicknames, oAuthAccountDetails}}, - ); + acc.settings.companyCards[feedName] = feedSettings; + + if (feedOAuthAccountDetails) { + acc.settings.oAuthAccountDetails[feedName] = feedOAuthAccountDetails; + } + if (feedCompanyCardNicknames) { + acc.settings.companyCardNicknames[feedName] = feedCompanyCardNicknames; + } + }); + + return acc; + }, + {settings: {companyCards, companyCardNicknames, oAuthAccountDetails}}, + ); + }, [allFeeds, policyID, workspaceAccountID]); return [workspaceFeeds, allFeedsResult]; }; From 5f04b71bebe1514aebad6e49f03c2970c8b660a3 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 17 Apr 2025 22:29:30 +0200 Subject: [PATCH 5/6] Describe useCardFeeds hook --- src/hooks/useCardFeeds.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index d270ad731de6c..634eb37af8c6a 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -5,6 +5,20 @@ import type {CardFeeds, CompanyCardFeed} from '@src/types/onyx'; import useOnyx from './useOnyx'; import useWorkspaceAccountID from './useWorkspaceAccountID'; +/** + * This is a custom hook that combines workspace and domain card feeds for a given policy. + * + * This hook: + * - Gets all available feeds (ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER) from Onyx. + * - Extracts and compiles card feeds data including only feeds where the `preferredPolicy` matches the `policyID`. + * - Merges a workspace feed with relevant domain feeds. + * + * @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). + * 2. The result metadata from the Onyx collection fetch. + */ const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { const workspaceAccountID = useWorkspaceAccountID(policyID); const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER); From 2528c8c9e4068cf2a0d581ae2bbff1b57937cf0b Mon Sep 17 00:00:00 2001 From: VickyStash Date: Fri, 18 Apr 2025 09:28:56 +0200 Subject: [PATCH 6/6] Add canBeMissing flags to fix lint errors --- src/hooks/useCardFeeds.tsx | 2 +- src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 7 +++++-- .../companyCards/BankConnection/index.native.tsx | 6 +++--- src/pages/workspace/companyCards/BankConnection/index.tsx | 4 ++-- .../companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx | 4 ++-- .../WorkspaceCompanyCardsListHeaderButtons.tsx | 2 +- .../workspace/companyCards/WorkspaceCompanyCardsPage.tsx | 8 ++++---- .../WorkspaceCompanyCardsSettingsFeedNamePage.tsx | 2 +- .../companyCards/WorkspaceCompanyCardsSettingsPage.tsx | 4 ++-- src/pages/workspace/companyCards/addNew/DetailsStep.tsx | 4 ++-- .../workspace/companyCards/assignCard/AssigneeStep.tsx | 4 ++-- .../companyCards/assignCard/CardSelectionStep.tsx | 6 +++--- .../companyCards/assignCard/ConfirmationStep.tsx | 2 +- src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx | 2 +- .../workspace/members/WorkspaceMemberDetailsPage.tsx | 4 ++-- .../workspace/members/WorkspaceMemberNewCardPage.tsx | 4 ++-- 16 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx index 634eb37af8c6a..53871e9a4739f 100644 --- a/src/hooks/useCardFeeds.tsx +++ b/src/hooks/useCardFeeds.tsx @@ -21,7 +21,7 @@ import useWorkspaceAccountID from './useWorkspaceAccountID'; */ const useCardFeeds = (policyID: string | undefined): [CardFeeds | undefined, ResultMetadata>] => { const workspaceAccountID = useWorkspaceAccountID(policyID); - const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER); + const [allFeeds, allFeedsResult] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, {canBeMissing: true}); const workspaceFeeds = useMemo(() => { if (!policyID || !allFeeds) { diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index e0d02fe1d57d0..39f4ea535baba 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -85,7 +85,10 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro !!policy?.connections?.netsuite?.options?.config?.syncOptions?.syncTax; const policyID = policy?.id; const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID.toString()}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); + const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID.toString()}_${CONST.EXPENSIFY_CARD.BANK}`, { + selector: filterInactiveCards, + canBeMissing: true, + }); const [cardFeeds] = useCardFeeds(policyID); const [isOrganizeWarningModalOpen, setIsOrganizeWarningModalOpen] = useState(false); const [isIntegrateWarningModalOpen, setIsIntegrateWarningModalOpen] = useState(false); @@ -96,7 +99,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const perDiemCustomUnit = getPerDiemCustomUnit(policy); - const [cardList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); + const [cardList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`, {canBeMissing: true}); const workspaceCards = getAllCardsForWorkspace(workspaceAccountID, cardList); const isSmartLimitEnabled = isSmartLimitEnabledUtil(workspaceCards); diff --git a/src/pages/workspace/companyCards/BankConnection/index.native.tsx b/src/pages/workspace/companyCards/BankConnection/index.native.tsx index 97de0164bc1f5..00b4f5205a82c 100644 --- a/src/pages/workspace/companyCards/BankConnection/index.native.tsx +++ b/src/pages/workspace/companyCards/BankConnection/index.native.tsx @@ -43,10 +43,10 @@ function BankConnection({policyID: policyIDFromProps, feed, route}: BankConnecti const {translate} = useLocalize(); const theme = useTheme(); const webViewRef = useRef(null); - const [session] = useOnyx(ONYXKEYS.SESSION); - const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); + const [session] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: false}); + const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: true}); const authToken = session?.authToken ?? null; - const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD); + const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD, {canBeMissing: true}); const {bankName: bankNameFromRoute, backTo, policyID: policyIDFromRoute} = route?.params ?? {}; const policyID = policyIDFromProps ?? policyIDFromRoute; const bankName = feed ? getBankName(feed) : bankNameFromRoute ?? addNewCard?.data?.selectedBank; diff --git a/src/pages/workspace/companyCards/BankConnection/index.tsx b/src/pages/workspace/companyCards/BankConnection/index.tsx index 7dc370e64e9ba..0b2d81b47e663 100644 --- a/src/pages/workspace/companyCards/BankConnection/index.tsx +++ b/src/pages/workspace/companyCards/BankConnection/index.tsx @@ -43,8 +43,8 @@ type BankConnectionProps = { function BankConnection({policyID: policyIDFromProps, feed, route}: BankConnectionProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD); - const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); + const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD, {canBeMissing: true}); + const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: true}); const {bankName: bankNameFromRoute, backTo, policyID: policyIDFromRoute} = route?.params ?? {}; const policyID = policyIDFromProps ?? policyIDFromRoute; const [cardFeeds] = useCardFeeds(policyID); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx index 277e4bf23a906..bedb3c75f01a8 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx @@ -44,8 +44,8 @@ function WorkspaceCompanyCardFeedSelectorPage({route}: WorkspaceCompanyCardFeedS const styles = useThemeStyles(); const illustrations = useThemeIllustrations(); const [cardFeeds] = useCardFeeds(policyID); - const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); - const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`, {canBeMissing: false}); + const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`, {canBeMissing: true}); const selectedFeed = getSelectedFeed(lastSelectedFeed, cardFeeds); const companyFeeds = getCompanyFeeds(cardFeeds); const isCollect = isCollectPolicy(policy); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx index 2e37ca896caf3..a3c095d7ff48a 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx @@ -53,7 +53,7 @@ function WorkspaceCompanyCardsListHeaderButtons({policyID, selectedFeed, shouldS const {shouldUseNarrowLayout, isMediumScreenWidth} = useResponsiveLayout(); const workspaceAccountID = useWorkspaceAccountID(policyID); const [cardFeeds] = useCardFeeds(policyID); - const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); + const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`, {canBeMissing: false}); const shouldChangeLayout = isMediumScreenWidth || shouldUseNarrowLayout; const formattedFeedName = getCustomOrFormattedFeedName(selectedFeed, cardFeeds?.settings?.companyCardNicknames); const isCommercialFeed = isCustomFeed(selectedFeed); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx index 97fc648c88562..49b74323a970b 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx @@ -46,16 +46,16 @@ function WorkspaceCompanyCardsPage({route}: WorkspaceCompanyCardsPageProps) { const styles = useThemeStyles(); const theme = useTheme(); const policyID = route.params.policyID; - const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {canBeMissing: false}); const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`, {canBeMissing: true}); const [cardFeeds] = useCardFeeds(policyID); const selectedFeed = getSelectedFeed(lastSelectedFeed, cardFeeds); - const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${selectedFeed}`, {selector: filterInactiveCards}); + const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${selectedFeed}`, {selector: filterInactiveCards, canBeMissing: true}); const {cardList, ...cards} = cardsList ?? {}; - const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => !!account?.delegatedAccess?.delegate}); + const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => !!account?.delegatedAccess?.delegate, canBeMissing: false}); const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); const filteredCardList = getFilteredCardList(cardsList, selectedFeed ? cardFeeds?.settings?.oAuthAccountDetails?.[selectedFeed] : undefined); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx index 6f48e0d6740e8..5cd56a8cd51d8 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsFeedNamePage.tsx @@ -41,7 +41,7 @@ function WorkspaceCompanyCardsSettingsFeedNamePage({ const {inputCallbackRef} = useAutoFocusInput(); const policy = usePolicy(policyID); const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [lastSelectedFeed, lastSelectedFeedResult] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [lastSelectedFeed, lastSelectedFeedResult] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`, {canBeMissing: true}); const [cardFeeds, cardFeedsResult] = useCardFeeds(policyID); const selectedFeed = getSelectedFeed(lastSelectedFeed, cardFeeds); const feedName = getCustomOrFormattedFeedName(selectedFeed, cardFeeds?.settings?.companyCardNicknames); diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx index baae341cd1fb6..1cf89ba77e82b 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsSettingsPage.tsx @@ -40,11 +40,11 @@ function WorkspaceCompanyCardsSettingsPage({ const [deleteCompanyCardConfirmModalVisible, setDeleteCompanyCardConfirmModalVisible] = useState(false); const [cardFeeds] = useCardFeeds(policyID); - const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`, {canBeMissing: true}); const selectedFeed = useMemo(() => getSelectedFeed(lastSelectedFeed, cardFeeds), [cardFeeds, lastSelectedFeed]); - const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${selectedFeed}`, {selector: filterInactiveCards}); + const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${selectedFeed}`, {selector: filterInactiveCards, canBeMissing: false}); const feedName = getCustomOrFormattedFeedName(selectedFeed, cardFeeds?.settings?.companyCardNicknames); const companyFeeds = getCompanyFeeds(cardFeeds); const liabilityType = selectedFeed && companyFeeds[selectedFeed]?.liabilityType; diff --git a/src/pages/workspace/companyCards/addNew/DetailsStep.tsx b/src/pages/workspace/companyCards/addNew/DetailsStep.tsx index 28474be4cf5a6..a9e036894eac9 100644 --- a/src/pages/workspace/companyCards/addNew/DetailsStep.tsx +++ b/src/pages/workspace/companyCards/addNew/DetailsStep.tsx @@ -36,8 +36,8 @@ function DetailsStep({policyID}: DetailsStepProps) { const styles = useThemeStyles(); const {inputCallbackRef} = useAutoFocusInput(); - const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD); - const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [addNewCard] = useOnyx(ONYXKEYS.ADD_NEW_COMPANY_CARD, {canBeMissing: false}); + const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`, {canBeMissing: true}); const [cardFeeds] = useCardFeeds(policyID); diff --git a/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx b/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx index 9d595187b9647..1eeba58378fe7 100644 --- a/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx @@ -40,10 +40,10 @@ function AssigneeStep({policy, feed}: AssigneeStepProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isOffline} = useNetwork(); - const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); + const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: true}); const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; - const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`, {selector: filterInactiveCards}); + const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`, {selector: filterInactiveCards, canBeMissing: false}); const [cardFeeds] = useCardFeeds(policy?.id); const filteredCardList = getFilteredCardList(list, cardFeeds?.settings?.oAuthAccountDetails?.[feed]); diff --git a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx index 7fcdd58d40d89..f3b20f326917c 100644 --- a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx @@ -42,9 +42,9 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) { const illustrations = useThemeIllustrations(); const {environmentURL} = useEnvironment(); const [searchText, setSearchText] = useState(''); - const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); - const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`, {selector: filterInactiveCards}); - const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST); + const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: false}); + const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`, {selector: filterInactiveCards, canBeMissing: false}); + const [workspaceCardFeeds] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST, {canBeMissing: false}); const [cardFeeds] = useCardFeeds(policyID); const isEditing = assignCard?.isEditing; diff --git a/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx b/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx index 95bc959d8bbc7..112b1db918b0d 100644 --- a/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx +++ b/src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx @@ -35,7 +35,7 @@ function ConfirmationStep({policyID, backTo}: ConfirmationStepProps) { const styles = useThemeStyles(); const {isOffline} = useNetwork(); - const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD); + const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: false}); const feed = assignCard?.data?.bankName as CompanyCardFeed | undefined; const [cardFeeds] = useCardFeeds(policyID); diff --git a/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx b/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx index ea2d056644680..caa48569be226 100644 --- a/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx +++ b/src/pages/workspace/downgrade/WorkspaceDowngradePage.tsx @@ -28,7 +28,7 @@ type WorkspaceDowngradePageProps = PlatformStackScreenProps