diff --git a/src/hooks/useCardFeeds.tsx b/src/hooks/useCardFeeds.tsx new file mode 100644 index 0000000000000..53871e9a4739f --- /dev/null +++ b/src/hooks/useCardFeeds.tsx @@ -0,0 +1,68 @@ +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'; +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, {canBeMissing: true}); + + 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 ?? {}; + + return 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 (feedCompanyCardNicknames) { + acc.settings.companyCardNicknames[feedName] = feedCompanyCardNicknames; + } + }); + + return acc; + }, + {settings: {companyCards, companyCardNicknames, oAuthAccountDetails}}, + ); + }, [allFeeds, policyID, workspaceAccountID]); + + return [workspaceFeeds, allFeedsResult]; +}; + +export default useCardFeeds; diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index 3e34882f7a523..39f4ea535baba 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'; @@ -84,8 +85,11 @@ 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 [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID.toString()}`); + 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); const [isReportFieldsWarningModalOpen, setIsReportFieldsWarningModalOpen] = useState(false); @@ -95,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/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index 7246f0aebaeeb..3e3420fc78c7f 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 usePayAndDowngrade from '@hooks/usePayAndDowngrade'; @@ -78,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] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`, {canBeMissing: true}); + const [cardFeeds] = 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 65edcb67d7d87..5ca088cd5dc3d 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'; @@ -150,7 +151,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}`, {canBeMissing: true}); + const [cardFeeds] = useCardFeeds(policyIDToDelete); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, { selector: filterInactiveCards, canBeMissing: true, diff --git a/src/pages/workspace/companyCards/BankConnection/index.native.tsx b/src/pages/workspace/companyCards/BankConnection/index.native.tsx index 58e96b661933e..00b4f5205a82c 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'; @@ -43,16 +43,15 @@ 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; 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..0b2d81b47e663 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'; @@ -43,12 +43,11 @@ 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 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..bedb3c75f01a8 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,9 +43,9 @@ 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 [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); - const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [cardFeeds] = useCardFeeds(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 808b2ad673031..a3c095d7ff48a 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsListHeaderButtons.tsx @@ -7,6 +7,7 @@ import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; 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'; @@ -51,8 +52,8 @@ 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 [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); + const [cardFeeds] = useCardFeeds(policyID); + 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 b317dc48049d4..49b74323a970b 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'; @@ -45,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 [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + 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 d557b0326caa8..5cd56a8cd51d8 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'; @@ -40,8 +41,8 @@ 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 [cardFeeds, cardFeedsResult] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + 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 7e7656a488849..1cf89ba77e82b 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,12 +39,12 @@ 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 [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); + const [cardFeeds] = useCardFeeds(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 39f2c8dff4877..a9e036894eac9 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'; @@ -36,11 +36,10 @@ 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 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..1eeba58378fe7 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'; @@ -39,11 +40,11 @@ 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 [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + 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]); const isEditing = assignCard?.isEditing; diff --git a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx index bae21b64aa0bb..f3b20f326917c 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'; @@ -41,10 +42,10 @@ 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 [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); + 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; 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..112b1db918b0d 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 [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD, {canBeMissing: false}); 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..caa48569be226 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'; @@ -28,9 +28,8 @@ type WorkspaceDowngradePageProps = PlatformStackScreenProps