-
Notifications
You must be signed in to change notification settings - Fork 3.2k
[Internal QA] feat: show domain feed in ND #59538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
68a11a4
867b5f7
d8aa73c
2a582dd
14df615
dda41ee
8e52783
9aaefd3
4062666
8ca900c
beaddf1
9c23913
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import {useOnyx} from 'react-native-onyx'; | ||
import CONST from '@src/CONST'; | ||
import ONYXKEYS from '@src/ONYXKEYS'; | ||
|
||
function useDomainCardsID(policyID: string | undefined) { | ||
const [domainCardsID] = useOnyx(ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS, { | ||
selector: (cardSettings) => { | ||
const matchingEntry = Object.entries(cardSettings ?? {}).find( | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
([_, settings]) => settings?.preferredPolicy && settings.preferredPolicy === policyID, | ||
); | ||
|
||
if (!matchingEntry) { | ||
return CONST.DEFAULT_NUMBER_ID; | ||
} | ||
|
||
const key = matchingEntry[0]; | ||
const prefix = ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS; | ||
|
||
if (!key.startsWith(prefix)) { | ||
return CONST.DEFAULT_NUMBER_ID; | ||
} | ||
|
||
const accountIDStr = key.substring(prefix.length); | ||
|
||
const accountID = Number(accountIDStr); | ||
return Number.isNaN(accountID) ? CONST.DEFAULT_NUMBER_ID : accountID; | ||
}, | ||
}); | ||
|
||
return domainCardsID; | ||
} | ||
|
||
export default useDomainCardsID; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; | |
import OfflineWithFeedback from '@components/OfflineWithFeedback'; | ||
import ScreenWrapper from '@components/ScreenWrapper'; | ||
import ScrollView from '@components/ScrollView'; | ||
import useDomainCardsID from '@hooks/useDomainCardsID'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import useNetwork from '@hooks/useNetwork'; | ||
import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||
|
@@ -29,7 +30,7 @@ import Navigation from '@navigation/Navigation'; | |
import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; | ||
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; | ||
import variables from '@styles/variables'; | ||
import {deactivateCard as deactivateCard_1, openCardDetailsPage} from '@userActions/Card'; | ||
import {deactivateCard as deactivateCardAction, openCardDetailsPage} from '@userActions/Card'; | ||
import CONST from '@src/CONST'; | ||
import ONYXKEYS from '@src/ONYXKEYS'; | ||
import ROUTES from '@src/ROUTES'; | ||
|
@@ -44,6 +45,11 @@ type WorkspaceExpensifyCardDetailsPageProps = PlatformStackScreenProps< | |
function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetailsPageProps) { | ||
const {policyID, cardID, backTo} = route.params; | ||
const workspaceAccountID = useWorkspaceAccountID(policyID); | ||
const domainCardsID = useDomainCardsID(policyID); | ||
|
||
// TODO: add logic for choosing between the domain and workspace feed when both available | ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing | ||
const cardsID = domainCardsID || workspaceAccountID; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I notice we also have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yeah, calling it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, so I'll rename to fundID |
||
|
||
const [isDeactivateModalVisible, setIsDeactivateModalVisible] = useState(false); | ||
const [isOfflineModalVisible, setIsOfflineModalVisible] = useState(false); | ||
|
@@ -54,7 +60,7 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail | |
const styles = useThemeStyles(); | ||
|
||
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); | ||
const [cardsList, cardsListResult] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); | ||
const [cardsList, cardsListResult] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${cardsID}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); | ||
|
||
const isWorkspaceCardRhp = route.name === SCREENS.WORKSPACE.EXPENSIFY_CARD_DETAILS; | ||
const card = cardsList?.[cardID]; | ||
|
@@ -77,7 +83,7 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail | |
setIsDeactivateModalVisible(false); | ||
Navigation.goBack(); | ||
InteractionManager.runAfterInteractions(() => { | ||
deactivateCard_1(workspaceAccountID, card); | ||
deactivateCardAction(workspaceAccountID, card); | ||
}); | ||
}; | ||
|
||
|
@@ -188,7 +194,11 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail | |
onPress={() => { | ||
Navigation.navigate( | ||
ROUTES.SEARCH_ROOT.getRoute({ | ||
query: buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.EXPENSE, status: CONST.SEARCH.STATUS.EXPENSE.ALL, cardID}), | ||
query: buildCannedSearchQuery({ | ||
type: CONST.SEARCH.DATA_TYPES.EXPENSE, | ||
status: CONST.SEARCH.STATUS.EXPENSE.ALL, | ||
cardID, | ||
}), | ||
}), | ||
); | ||
}} | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -36,9 +36,12 @@ type WorkspaceExpensifyCardListPageProps = { | |||||
|
||||||
/** List of Expensify cards */ | ||||||
cardsList: OnyxEntry<WorkspaceCardsList>; | ||||||
|
||||||
/** Cards ID */ | ||||||
cardsID: number; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes more sense to me that this would be singular if it's the ID for a single card. Or is this the ID for the card feed?
Suggested change
|
||||||
}; | ||||||
|
||||||
function WorkspaceExpensifyCardListPage({route, cardsList}: WorkspaceExpensifyCardListPageProps) { | ||||||
function WorkspaceExpensifyCardListPage({route, cardsList, cardsID}: WorkspaceExpensifyCardListPageProps) { | ||||||
const {shouldUseNarrowLayout} = useResponsiveLayout(); | ||||||
const {translate} = useLocalize(); | ||||||
const styles = useThemeStyles(); | ||||||
|
@@ -48,6 +51,7 @@ function WorkspaceExpensifyCardListPage({route, cardsList}: WorkspaceExpensifyCa | |||||
const workspaceAccountID = policy?.workspaceAccountID ?? CONST.DEFAULT_NUMBER_ID; | ||||||
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); | ||||||
const [cardOnWaitlist] = useOnyx(`${ONYXKEYS.COLLECTION.NVP_EXPENSIFY_ON_CARD_WAITLIST}${policyID}`); | ||||||
const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${cardsID}`); | ||||||
|
||||||
const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => !!account?.delegatedAccess?.delegate}); | ||||||
const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); | ||||||
|
@@ -115,7 +119,15 @@ function WorkspaceExpensifyCardListPage({route, cardsList}: WorkspaceExpensifyCa | |||||
[personalDetails, policyCurrency, policyID, workspaceAccountID, styles], | ||||||
); | ||||||
|
||||||
const renderListHeader = useCallback(() => <WorkspaceCardListHeader policyID={policyID} />, [policyID]); | ||||||
const renderListHeader = useCallback( | ||||||
() => ( | ||||||
<WorkspaceCardListHeader | ||||||
policyID={policyID} | ||||||
cardSettings={cardSettings} | ||||||
/> | ||||||
), | ||||||
[policyID, cardSettings], | ||||||
); | ||||||
|
||||||
return ( | ||||||
<ScreenWrapper | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ import {useFocusEffect} from '@react-navigation/native'; | |
import React, {useCallback} from 'react'; | ||
import {ActivityIndicator} from 'react-native'; | ||
import {useOnyx} from 'react-native-onyx'; | ||
import useDomainCardsID from '@hooks/useDomainCardsID'; | ||
import useNetwork from '@hooks/useNetwork'; | ||
import useTheme from '@hooks/useTheme'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
|
@@ -25,12 +26,17 @@ function WorkspaceExpensifyCardPage({route}: WorkspaceExpensifyCardPageProps) { | |
|
||
const styles = useThemeStyles(); | ||
const theme = useTheme(); | ||
const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); | ||
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); | ||
const domainCardsID = useDomainCardsID(policyID); | ||
|
||
// TODO: add logic for choosing between the domain and workspace feed when both available | ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing | ||
const cardsID = domainCardsID || workspaceAccountID; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we can call this domainAccountID since that's what it is in the db. And technically a workspaceAccountID is a type of domainAccountID. Or maybe we call it the cardAccountID. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${cardsID}`); | ||
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${cardsID}_${CONST.EXPENSIFY_CARD.BANK}`, {selector: filterInactiveCards}); | ||
|
||
const fetchExpensifyCards = useCallback(() => { | ||
openPolicyExpensifyCardsPage(policyID, workspaceAccountID); | ||
}, [policyID, workspaceAccountID]); | ||
openPolicyExpensifyCardsPage(policyID, cardsID); | ||
}, [policyID, cardsID]); | ||
|
||
const {isOffline} = useNetwork({onReconnect: fetchExpensifyCards}); | ||
|
||
|
@@ -39,26 +45,37 @@ function WorkspaceExpensifyCardPage({route}: WorkspaceExpensifyCardPageProps) { | |
const paymentBankAccountID = cardSettings?.paymentBankAccountID ?? CONST.DEFAULT_NUMBER_ID; | ||
const isLoading = !isOffline && (!cardSettings || cardSettings.isLoading); | ||
|
||
return ( | ||
<AccessOrNotFoundWrapper | ||
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} | ||
policyID={route.params.policyID} | ||
featureName={CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED} | ||
> | ||
{!!isLoading && !paymentBankAccountID && ( | ||
const renderContent = () => { | ||
if (!!isLoading && !paymentBankAccountID && !domainCardsID) { | ||
return ( | ||
<ActivityIndicator | ||
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE} | ||
style={styles.flex1} | ||
color={theme.spinner} | ||
/> | ||
)} | ||
{!!paymentBankAccountID && ( | ||
); | ||
} | ||
if (!!paymentBankAccountID || domainCardsID) { | ||
return ( | ||
<WorkspaceExpensifyCardListPage | ||
cardsList={cardsList} | ||
cardsID={cardsID} | ||
route={route} | ||
/> | ||
)} | ||
{!paymentBankAccountID && !isLoading && <WorkspaceExpensifyCardPageEmptyState route={route} />} | ||
); | ||
} | ||
if (!paymentBankAccountID && !isLoading) { | ||
return <WorkspaceExpensifyCardPageEmptyState route={route} />; | ||
} | ||
}; | ||
|
||
return ( | ||
<AccessOrNotFoundWrapper | ||
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} | ||
policyID={route.params.policyID} | ||
featureName={CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED} | ||
> | ||
{renderContent()} | ||
</AccessOrNotFoundWrapper> | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can technically be multiple domainAccountIDs that we would return here, right? Since there could be multiple domains that have this set as the preferred policy. Maybe it would make sense to call it
useDomainCardIDs
oruseDomainAccountIDs
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so I need to refactor this then, for now it takes the first matching entry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed it to FundID like in the other locations, if it's a fundID in the cards_ object
@puneetlath May I work on refactoring it to return an array of the ids in the second PR for selector? Here, without selector it would make things a bit complicated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that makes sense to me.