Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/libs/CardUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {TranslationPaths} from '@src/languages/types';
import type {OnyxValues} from '@src/ONYXKEYS';
import ONYXKEYS from '@src/ONYXKEYS';
import type {BankAccountList, Card, CardFeeds, CardList, CompanyCardFeed, PersonalDetailsList, WorkspaceCardsList} from '@src/types/onyx';
import type {CardFeedData} from '@src/types/onyx/CardFeeds';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type IconAsset from '@src/types/utils/IconAsset';
import localeCompare from './LocaleCompare';
Expand Down Expand Up @@ -226,6 +227,13 @@ function getCardFeedIcon(cardFeed: CompanyCardFeed | typeof CONST.EXPENSIFY_CARD
return Illustrations.AmexCompanyCards;
}

function removeExpensifyCardFromCompanyCards(companyCards?: Record<string, CardFeedData>) {
if (!companyCards) {
return {};
}
return Object.fromEntries(Object.entries(companyCards).filter(([key]) => key !== CONST.EXPENSIFY_CARD.BANK));
}

function getCardFeedName(feedType: CompanyCardFeed): string {
const feedNamesMapping = {
[CONST.COMPANY_CARD.FEED_BANK_NAME.VISA]: 'Visa',
Expand Down Expand Up @@ -293,7 +301,7 @@ const getCorrectStepForSelectedBank = (selectedBank: ValueOf<typeof CONST.COMPAN
};

function getSelectedFeed(lastSelectedFeed: OnyxEntry<CompanyCardFeed>, cardFeeds: OnyxEntry<CardFeeds>): CompanyCardFeed {
const defaultFeed = Object.keys(cardFeeds?.settings?.companyCards ?? {}).at(0) as CompanyCardFeed;
const defaultFeed = Object.keys(removeExpensifyCardFromCompanyCards(cardFeeds?.settings?.companyCards)).at(0) as CompanyCardFeed;
return lastSelectedFeed ?? defaultFeed;
}

Expand All @@ -318,4 +326,5 @@ export {
getBankCardDetailsImage,
getSelectedFeed,
getCorrectStepForSelectedBank,
removeExpensifyCardFromCompanyCards,
};
3 changes: 2 additions & 1 deletion src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useNetwork from '@hooks/useNetwork';
import usePermissions from '@hooks/usePermissions';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import * as CardUtils from '@libs/CardUtils';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {FullScreenNavigatorParamList} from '@libs/Navigation/types';
Expand Down Expand Up @@ -126,7 +127,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitleTranslationKey: 'workspace.moreFeatures.companyCards.subtitle',
isActive: policy?.areCompanyCardsEnabled ?? false,
pendingAction: policy?.pendingFields?.areCompanyCardsEnabled,
disabled: !isEmptyObject(cardFeeds?.settings?.companyCards),
disabled: !isEmptyObject(CardUtils.removeExpensifyCardFromCompanyCards(cardFeeds?.settings?.companyCards)),
action: (isEnabled: boolean) => {
if (!policyID) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ function WorkspaceCompanyCardFeedSelectorPage({route}: WorkspaceCompanyCardFeedS
const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`);
const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`);
const selectedFeed = CardUtils.getSelectedFeed(lastSelectedFeed, cardFeeds);
const availableCards = CardUtils.removeExpensifyCardFromCompanyCards(cardFeeds?.settings?.companyCards);

const feeds: CardFeedListItem[] = (Object.keys(cardFeeds?.settings?.companyCards ?? {}) as CompanyCardFeed[]).map((feed) => ({
const feeds: CardFeedListItem[] = (Object.keys(availableCards) as CompanyCardFeed[]).map((feed) => ({
value: feed,
text: cardFeeds?.settings?.companyCardNicknames?.[feed] ?? CardUtils.getCardFeedName(feed),
keyForList: feed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function WorkspaceCompanyCardPage({route}: WorkspaceCompanyCardPageProps) {
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${selectedFeed}`);

const isLoading = !cardFeeds || !!(cardFeeds.isLoading && !cardFeeds.settings);
const companyCards = cardFeeds?.settings?.companyCards ?? {};
const companyCards = CardUtils.removeExpensifyCardFromCompanyCards(cardFeeds?.settings?.companyCards);
const selectedCompanyCard = companyCards[selectedFeed ?? ''] ?? null;
const isNoFeed = !selectedCompanyCard;
const isPending = !!selectedCompanyCard?.pending;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {
const {environmentURL} = useEnvironment();
const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD);
const [list] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${feed}`);
const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`);
const accountCardList = cardFeeds?.settings?.oAuthAccountDetails?.[feed]?.accountList ?? [];

const isEditing = assignCard?.isEditing;
const assignee = assignCard?.data?.email ?? '';
Expand All @@ -46,7 +48,6 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {
const filteredCardList = Object.fromEntries(
Object.entries(cardList ?? {}).filter(([cardNumber]) => !Object.values(cards).find((card) => card.lastFourPAN && cardNumber.endsWith(card.lastFourPAN))),
);

const [cardSelected, setCardSelected] = useState(assignCard?.data?.encryptedCardNumber ?? '');
const [shouldShowError, setShouldShowError] = useState(false);

Expand All @@ -66,6 +67,21 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {
setShouldShowError(false);
};

const accountCardListOptions = accountCardList.map((encryptedCardNumber) => ({
keyForList: encryptedCardNumber,
value: encryptedCardNumber,
text: encryptedCardNumber,
isSelected: cardSelected === encryptedCardNumber,
leftElement: (
<Icon
src={CardUtils.getCardFeedIcon(feed)}
height={variables.iconSizeExtraLarge}
width={variables.iconSizeExtraLarge}
additionalStyles={styles.mr3}
/>
),
}));

const submit = () => {
if (!cardSelected) {
setShouldShowError(true);
Expand All @@ -79,7 +95,7 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {

CompanyCards.setAssignCardStepAndData({
currentStep: isEditing ? CONST.COMPANY_CARD.STEP.CONFIRMATION : CONST.COMPANY_CARD.STEP.TRANSACTION_START_DATE,
data: {encryptedCardNumber: cardSelected, cardName},
data: {encryptedCardNumber: cardSelected, cardName: accountCardList?.length > 0 ? cardSelected : cardName},
isEditing: false,
});
};
Expand All @@ -99,15 +115,17 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {
),
}));

const listOptions = accountCardList?.length > 0 ? accountCardListOptions : cardListOptions;

return (
<InteractiveStepWrapper
wrapperID={CardSelectionStep.displayName}
handleBackButtonPress={handleBackButtonPress}
startStepIndex={cardListOptions.length ? 1 : undefined}
stepNames={cardListOptions.length ? CONST.COMPANY_CARD.STEP_NAMES : undefined}
startStepIndex={listOptions.length ? 1 : undefined}
stepNames={listOptions.length ? CONST.COMPANY_CARD.STEP_NAMES : undefined}
headerTitle={translate('workspace.companyCards.assignCard')}
>
{!cardListOptions.length ? (
{!listOptions.length ? (
<View style={[styles.flex1, styles.justifyContentCenter, styles.alignItemsCenter, styles.ph5, styles.mb9]}>
<Icon
src={Illustrations.BrokenMagnifyingGlass}
Expand Down Expand Up @@ -136,7 +154,7 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {
})}
</Text>
<SelectionList
sections={[{data: cardListOptions}]}
sections={[{data: listOptions}]}
ListItem={RadioListItem}
onSelectRow={({value}) => handleSelectCard(value)}
initiallyFocusedOptionKey={cardSelected}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew

const accountID = Number(route.params.accountID);
const memberLogin = personalDetails?.[accountID]?.login ?? '';
const availableCompanyCards = CardUtils.removeExpensifyCardFromCompanyCards(cardFeeds?.settings?.companyCards);

const handleSubmit = () => {
if (!selectedFeed) {
Expand Down Expand Up @@ -78,7 +79,7 @@ function WorkspaceMemberNewCardPage({route, personalDetails}: WorkspaceMemberNew
setShouldShowError(false);
};

const companyCardFeeds: CardFeedListItem[] = (Object.keys(cardFeeds?.settings?.companyCards ?? {}) as CompanyCardFeed[]).map((key) => ({
const companyCardFeeds: CardFeedListItem[] = (Object.keys(availableCompanyCards) as CompanyCardFeed[]).map((key) => ({
value: key,
text: cardFeeds?.settings?.companyCardNicknames?.[key] ?? CardUtils.getCardFeedName(key),
keyForList: key,
Expand Down
15 changes: 15 additions & 0 deletions src/types/onyx/CardFeeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ type CardFeeds = {

/** Company cards feeds */
companyCards: Record<string, CardFeedData>;

/** Account details */
oAuthAccountDetails: Record<
ValueOf<typeof CONST.COMPANY_CARD.FEED_BANK_NAME>,
{
/** List of accounts */
accountList: string[];

/** Credentials info */
credentials: string;

/** Expiration number */
expiration: number;
}
>;
};

/** Whether we are loading the data via the API */
Expand Down