Skip to content

Commit

Permalink
Merge pull request Expensify#47064 from VickyStash/feature/44310-Open…
Browse files Browse the repository at this point in the history
…PolicyExpensifyCardsPage-integration

[NoQA] Integrate OpenPolicyExpensifyCardsPage API call
  • Loading branch information
mountiny committed Aug 13, 2024
2 parents 9aa4eed + 2554ac1 commit 55ded55
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 298 deletions.
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5387,7 +5387,7 @@ const CONST = {
WORKSPACE_CARDS_LIST_LABEL_TYPE: {
CURRENT_BALANCE: 'currentBalance',
REMAINING_LIMIT: 'remainingLimit',
CASH_BACK: 'cashBack',
CASH_BACK: 'earnedCashback',
},

EXCLUDE_FROM_LAST_VISITED_PATH: [SCREENS.NOT_FOUND, SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN] as string[],
Expand Down
2 changes: 1 addition & 1 deletion src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ const ONYXKEYS = {
* Stores the card list for a given fundID and feed in the format: card_<fundID>_<bankName>
* So for example: card_12345_Expensify Card
*/
WORKSPACE_CARDS_LIST: 'card_',
WORKSPACE_CARDS_LIST: 'cards_',

/** Expensify cards settings */
PRIVATE_EXPENSIFY_CARD_SETTINGS: 'private_expensifyCardSettings_',
Expand Down
2 changes: 1 addition & 1 deletion src/components/FeatureList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function FeatureList({
</View>
))}
</View>
{secondaryButtonText && (
{!!secondaryButtonText && (
<Button
text={secondaryButtonText}
onPress={onSecondaryButtonPress}
Expand Down
4 changes: 2 additions & 2 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2722,8 +2722,8 @@ export default {
requestLimitIncrease: 'Request limit increase',
remainingLimitDescription:
'We consider a number of factors when calculating your remaining limit: your tenure as a customer, the business-related information you provided during signup, and the available cash in your business bank account. Your remaining limit can fluctuate on a daily basis.',
cashBack: 'Cash back',
cashBackDescription: 'Cash back balance is based on settled monthly Expensify Card spend across your workspace.',
earnedCashback: 'Cash back',
earnedCashbackDescription: 'Cash back balance is based on settled monthly Expensify Card spend across your workspace.',
issueNewCard: 'Issue new card',
finishSetup: 'Finish setup',
chooseBankAccount: 'Choose bank account',
Expand Down
4 changes: 2 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2772,8 +2772,8 @@ export default {
requestLimitIncrease: 'Solicitar aumento de límite',
remainingLimitDescription:
'A la hora de calcular tu límite restante, tenemos en cuenta una serie de factores: su antigüedad como cliente, la información relacionada con tu negocio que nos facilitaste al darte de alta y el efectivo disponible en tu cuenta bancaria comercial. Tu límite restante puede fluctuar a diario.',
cashBack: 'Reembolso',
cashBackDescription: 'El saldo de devolución se basa en el gasto mensual realizado con la tarjeta Expensify en tu espacio de trabajo.',
earnedCashback: 'Reembolso',
earnedCashbackDescription: 'El saldo de devolución se basa en el gasto mensual realizado con la tarjeta Expensify en tu espacio de trabajo.',
issueNewCard: 'Emitir nueva tarjeta',
finishSetup: 'Terminar configuración',
chooseBankAccount: 'Elegir cuenta bancaria',
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/Card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ function updateExpensifyCardLimit(workspaceAccountID: number, cardID: number, ne
value: {
[cardID]: {
nameValuePairs: {
limit: newLimit,
unapprovedExpenseLimit: newLimit,
},
isLoading: true,
errors: null,
Expand Down Expand Up @@ -355,7 +355,7 @@ function updateExpensifyCardLimit(workspaceAccountID: number, cardID: number, ne
value: {
[cardID]: {
nameValuePairs: {
limit: oldLimit,
unapprovedExpenseLimit: oldLimit,
},
isLoading: false,
errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
Expand Down
34 changes: 32 additions & 2 deletions src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2036,15 +2036,45 @@ function openPolicyTaxesPage(policyID: string) {
API.read(READ_COMMANDS.OPEN_POLICY_TAXES_PAGE, params);
}

function openPolicyExpensifyCardsPage(policyID: string) {
function openPolicyExpensifyCardsPage(policyID: string, workspaceAccountID: number) {
const authToken = NetworkStore.getAuthToken();

const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`,
value: {
isLoading: true,
},
},
];

const successData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`,
value: {
isLoading: false,
},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`,
value: {
isLoading: false,
},
},
];

const params: OpenPolicyExpensifyCardsPageParams = {
policyID,
authToken,
};

API.read(READ_COMMANDS.OPEN_POLICY_EXPENSIFY_CARDS_PAGE, params);
API.read(READ_COMMANDS.OPEN_POLICY_EXPENSIFY_CARDS_PAGE, params, {optimisticData, successData, failureData});
}

function openWorkspaceInvitePage(policyID: string, clientMemberEmails: string[]) {
Expand Down
24 changes: 12 additions & 12 deletions src/pages/workspace/expensifyCard/WorkspaceCardListHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
import React from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import * as PolicyUtils from '@libs/PolicyUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import WorkspaceCardsListLabel from './WorkspaceCardsListLabel';

// TODO: remove when Onyx data is available
const mockedSettings = {
currentBalance: 5000,
remainingLimit: 3000,
cashBack: 2000,
type WorkspaceCardListHeaderProps = {
/** ID of the current policy */
policyID: string;
};

function WorkspaceCardListHeader() {
function WorkspaceCardListHeader({policyID}: WorkspaceCardListHeaderProps) {
const {shouldUseNarrowLayout, isMediumScreenWidth, isSmallScreenWidth} = useResponsiveLayout();
const styles = useThemeStyles();
const {translate} = useLocalize();

const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID);
const isLessThanMediumScreen = isMediumScreenWidth || isSmallScreenWidth;

// TODO: uncomment the code line below to use cardSettings data from Onyx when it's supported
// const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`);
const cardSettings = mockedSettings;
const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`);

return (
<View style={styles.appBG}>
<View style={[isLessThanMediumScreen ? styles.flexColumn : styles.flexRow, isLessThanMediumScreen ? [styles.mt5, styles.mb3] : styles.mv5, styles.mh5, styles.ph4]}>
<View style={[styles.flexRow, styles.flex1, isLessThanMediumScreen && styles.mb5]}>
<WorkspaceCardsListLabel
type={CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.CURRENT_BALANCE}
value={cardSettings?.[CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.CURRENT_BALANCE]}
value={cardSettings?.[CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.CURRENT_BALANCE] ?? 0}
/>
<WorkspaceCardsListLabel
type={CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.REMAINING_LIMIT}
value={cardSettings?.[CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.REMAINING_LIMIT]}
value={cardSettings?.[CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.REMAINING_LIMIT] ?? 0}
/>
</View>
<WorkspaceCardsListLabel
type={CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.CASH_BACK}
value={cardSettings?.[CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.CASH_BACK]}
value={cardSettings?.[CONST.WORKSPACE_CARDS_LIST_LABEL_TYPE.CASH_BACK] ?? 0}
/>
</View>

Expand Down
6 changes: 3 additions & 3 deletions src/pages/workspace/expensifyCard/WorkspaceCardListRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type WorkspacesListRowProps = {
name: string;

/** Cardholder personal details */
cardholder: PersonalDetails;
cardholder?: PersonalDetails | null;

/** Card limit */
limit: number;
Expand All @@ -38,8 +38,8 @@ function WorkspaceCardListRow({limit, cardholder, lastFourPAN, name, currency}:
<View style={[styles.flexRow, styles.gap5, styles.br3, styles.p4]}>
<View style={[styles.flexRow, styles.flex5, styles.gap3, styles.alignItemsCenter]}>
<Avatar
source={getDefaultAvatarURL(cardholder.accountID)}
avatarID={cardholder.accountID}
source={getDefaultAvatarURL(cardholder?.accountID)}
avatarID={cardholder?.accountID}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.DEFAULT}
/>
Expand Down
29 changes: 8 additions & 21 deletions src/pages/workspace/expensifyCard/WorkspaceEditCardLimitPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@ import INPUT_IDS from '@src/types/form/EditExpensifyCardLimitForm';

type ConfirmationWarningTranslationPaths = 'workspace.expensifyCard.smartLimitWarning' | 'workspace.expensifyCard.monthlyLimitWarning' | 'workspace.expensifyCard.fixedLimitWarning';

// TODO: remove when Onyx data is available
const mockedCard = {
accountID: 885646,
availableSpend: 1000,
nameValuePairs: {
cardTitle: 'Test 1',
isVirtual: true,
limit: 2000,
limitType: CONST.EXPENSIFY_CARD.LIMIT_TYPES.SMART,
},
lastFourPAN: '1234',
};

type WorkspaceEditCardLimitPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.EXPENSIFY_CARD_LIMIT>;

function WorkspaceEditCardLimitPage({route}: WorkspaceEditCardLimitPageProps) {
Expand All @@ -49,11 +36,11 @@ function WorkspaceEditCardLimitPage({route}: WorkspaceEditCardLimitPageProps) {
const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID);

const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${policyID}_${CONST.EXPENSIFY_CARD.BANK}`);
const card = cardsList?.[cardID] ?? mockedCard;
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`);
const card = cardsList?.[cardID];

const getPromptTextKey = useMemo((): ConfirmationWarningTranslationPaths => {
switch (card.nameValuePairs?.limitType) {
switch (card?.nameValuePairs?.limitType) {
case CONST.EXPENSIFY_CARD.LIMIT_TYPES.SMART:
return 'workspace.expensifyCard.smartLimitWarning';
case CONST.EXPENSIFY_CARD.LIMIT_TYPES.FIXED:
Expand All @@ -63,19 +50,19 @@ function WorkspaceEditCardLimitPage({route}: WorkspaceEditCardLimitPageProps) {
default:
return 'workspace.expensifyCard.fixedLimitWarning';
}
}, [card.nameValuePairs?.limitType]);
}, [card?.nameValuePairs?.limitType]);

const updateCardLimit = (newLimit: string) => {
setIsConfirmModalVisible(false);

Card.updateExpensifyCardLimit(workspaceAccountID, Number(cardID), Number(newLimit) * 100, card.nameValuePairs?.limit);
Card.updateExpensifyCardLimit(workspaceAccountID, Number(cardID), Number(newLimit) * 100, card?.nameValuePairs?.unapprovedExpenseLimit);

Navigation.goBack();
};

const submit = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_LIMIT_FORM>) => {
const currentLimit = card.nameValuePairs?.limit ?? 0;
const currentSpend = currentLimit - (card.availableSpend ?? 0);
const currentLimit = card?.nameValuePairs?.unapprovedExpenseLimit ?? 0;
const currentSpend = currentLimit - (card?.availableSpend ?? 0);
const newLimit = Number(values[INPUT_IDS.LIMIT]) * 100;
const newAvailableSpend = newLimit - currentSpend;

Expand Down Expand Up @@ -131,7 +118,7 @@ function WorkspaceEditCardLimitPage({route}: WorkspaceEditCardLimitPageProps) {
<>
<InputWrapper
InputComponent={AmountForm}
defaultValue={CurrencyUtils.convertToFrontendAmountAsString(card.nameValuePairs?.limit, CONST.CURRENCY.USD, false)}
defaultValue={CurrencyUtils.convertToFrontendAmountAsString(card?.nameValuePairs?.unapprovedExpenseLimit, CONST.CURRENCY.USD, false)}
isCurrencyPressable={false}
inputID={INPUT_IDS.LIMIT}
ref={inputCallbackRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import useLocalize from '@hooks/useLocalize';
import usePolicy from '@hooks/usePolicy';
import useThemeStyles from '@hooks/useThemeStyles';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
Expand All @@ -20,34 +21,22 @@ import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

// TODO: remove when Onyx data is available
const mockedCard = {
accountID: 885646,
availableSpend: 1000,
nameValuePairs: {
cardTitle: 'Test 1',
isVirtual: true,
limit: 2000,
limitType: CONST.EXPENSIFY_CARD.LIMIT_TYPES.MONTHLY,
},
lastFourPAN: '1234',
};

type WorkspaceEditCardLimitTypePageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.EXPENSIFY_CARD_LIMIT_TYPE>;

function WorkspaceEditCardLimitTypePage({route}: WorkspaceEditCardLimitTypePageProps) {
const {policyID, cardID} = route.params;
const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID);

const {translate} = useLocalize();
const styles = useThemeStyles();

const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${policyID}_${CONST.EXPENSIFY_CARD.BANK}`);
const policy = usePolicy(policyID);
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`);

const card = cardsList?.[cardID] ?? mockedCard;
const card = cardsList?.[cardID];
const areApprovalsConfigured = !isEmptyObject(policy?.approver) && policy?.approvalMode !== CONST.POLICY.APPROVAL_MODE.OPTIONAL;
const defaultLimitType = areApprovalsConfigured ? CONST.EXPENSIFY_CARD.LIMIT_TYPES.SMART : CONST.EXPENSIFY_CARD.LIMIT_TYPES.MONTHLY;
const initialLimitType = card.nameValuePairs?.limitType ?? defaultLimitType;
const initialLimitType = card?.nameValuePairs?.limitType ?? defaultLimitType;
const promptTranslationKey =
initialLimitType === CONST.EXPENSIFY_CARD.LIMIT_TYPES.MONTHLY
? 'workspace.expensifyCard.changeCardMonthlyLimitTypeWarning'
Expand Down Expand Up @@ -137,7 +126,7 @@ function WorkspaceEditCardLimitTypePage({route}: WorkspaceEditCardLimitTypePageP
isVisible={isConfirmModalVisible}
onConfirm={updateCardLimitType}
onCancel={() => setIsConfirmModalVisible(false)}
prompt={translate(promptTranslationKey, CurrencyUtils.convertToDisplayString(card.nameValuePairs?.limit, CONST.CURRENCY.USD))}
prompt={translate(promptTranslationKey, CurrencyUtils.convertToDisplayString(card?.nameValuePairs?.unapprovedExpenseLimit, CONST.CURRENCY.USD))}
confirmText={translate('workspace.expensifyCard.changeLimitType')}
cancelText={translate('common.cancel')}
danger
Expand Down
19 changes: 4 additions & 15 deletions src/pages/workspace/expensifyCard/WorkspaceEditCardNamePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import TextInput from '@components/TextInput';
import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ValidationUtils from '@libs/ValidationUtils';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
Expand All @@ -20,30 +21,18 @@ import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import INPUT_IDS from '@src/types/form/EditExpensifyCardNameForm';

// TODO: remove when Onyx data is available
const mockedCard = {
accountID: 885646,
availableSpend: 1000,
nameValuePairs: {
cardTitle: 'Test 1',
isVirtual: true,
limit: 2000,
limitType: CONST.EXPENSIFY_CARD.LIMIT_TYPES.SMART,
},
lastFourPAN: '1234',
};

type WorkspaceEditCardNamePageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.EXPENSIFY_CARD_NAME>;

function WorkspaceEditCardNamePage({route}: WorkspaceEditCardNamePageProps) {
const {policyID, cardID} = route.params;
const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID);

const {translate} = useLocalize();
const {inputCallbackRef} = useAutoFocusInput();
const styles = useThemeStyles();

const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${policyID}_${CONST.EXPENSIFY_CARD.BANK}`);
const card = cardsList?.[cardID] ?? mockedCard;
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`);
const card = cardsList?.[cardID];

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const submit = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_NAME_FORM>) => {
Expand Down
Loading

0 comments on commit 55ded55

Please sign in to comment.