Skip to content
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

Fix/47308 workspace feed cleanup #48408

Merged
merged 7 commits into from
Sep 2, 2024
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: 6 additions & 5 deletions src/components/ReportActionItem/IssueCardMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type {OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import RenderHTML from '@components/RenderHTML';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -12,22 +11,24 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {ReportAction} from '@src/types/onyx';
import type OriginalMessage from '@src/types/onyx/OriginalMessage';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

type IssueCardMessageProps = {
action: OnyxEntry<ReportAction>;
};

type IssueNewCardOriginalMessage = OriginalMessage<
typeof CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS | typeof CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED | typeof CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED_VIRTUAL
>;

function IssueCardMessage({action}: IssueCardMessageProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const {environmentURL} = useEnvironment();
// TODO: now mocking accountID with current user accountID instead of action.message.assigneeAccountID
const personalData = useCurrentUserPersonalDetails();
const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS);

// TODO: now mocking accountID with current user accountID instead of action.message.assigneeAccountID
const assignee = `<mention-user accountID=${personalData.accountID}></mention-user>`;
const assignee = `<mention-user accountID=${(action?.originalMessage as IssueNewCardOriginalMessage)?.assigneeAccountID}></mention-user>`;
const link = `<a href='${environmentURL}/${ROUTES.SETTINGS_WALLET}'>${translate('cardPage.expensifyCard')}</a>`;

const noMailingAddress = action?.actionName === CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS && isEmptyObject(privatePersonalDetails?.address);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
type RequestExpensifyCardLimitIncreaseParams = {
authToken: string | null | undefined;
settlementBankAccountID: string;
settlementBankAccountID: number;
mountiny marked this conversation as resolved.
Show resolved Hide resolved
};

export default RequestExpensifyCardLimitIncreaseParams;
12 changes: 11 additions & 1 deletion src/libs/actions/Card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as NetworkStore from '@libs/Network/NetworkStore';
import * as PolicyUtils from '@libs/PolicyUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Card} from '@src/types/onyx';
Expand Down Expand Up @@ -253,10 +254,11 @@ function updateSettlementFrequency(workspaceAccountID: number, settlementFrequen
API.write(WRITE_COMMANDS.UPDATE_CARD_SETTLEMENT_FREQUENCY, parameters, {optimisticData, successData, failureData});
}

function updateSettlementAccount(workspaceAccountID: number, domainName: string, settlementBankAccountID?: number, currentSettlementBankAccountID?: number) {
function updateSettlementAccount(workspaceAccountID: number, policyID: string, settlementBankAccountID?: number, currentSettlementBankAccountID?: number) {
if (!settlementBankAccountID) {
return;
}
const domainName = PolicyUtils.getDomainNameForPolicy(policyID);

const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -296,6 +298,13 @@ function updateSettlementAccount(workspaceAccountID: number, domainName: string,
API.write(WRITE_COMMANDS.UPDATE_CARD_SETTLEMENT_ACCOUNT, parameters, {optimisticData, successData, failureData});
}

function getCardDefaultName(userName?: string) {
if (!userName) {
return '';
}
return `${userName}'s Card`;
}

function setIssueNewCardStepAndData({data, isEditing, step}: IssueNewCardFlowData) {
Onyx.merge(ONYXKEYS.ISSUE_NEW_EXPENSIFY_CARD, {data, isEditing, currentStep: step});
}
Expand Down Expand Up @@ -706,5 +715,6 @@ export {
updateExpensifyCardLimitType,
updateSelectedFeed,
deactivateCard,
getCardDefaultName,
};
export type {ReplacementReason};
6 changes: 5 additions & 1 deletion src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2151,7 +2151,11 @@ function openDraftWorkspaceRequest(policyID: string) {
API.read(READ_COMMANDS.OPEN_DRAFT_WORKSPACE_REQUEST, params);
}

function requestExpensifyCardLimitIncrease(settlementBankAccountID: string) {
function requestExpensifyCardLimitIncrease(settlementBankAccountID?: number) {
if (!settlementBankAccountID) {
return;
}

const authToken = NetworkStore.getAuthToken();

const params: RequestExpensifyCardLimitIncreaseParams = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as AccountingUtils from '@libs/AccountingUtils';
import {getLastFourDigits} from '@libs/BankAccountUtils';
import * as CardUtils from '@libs/CardUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import * as Card from '@userActions/Card';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

type ReconciliationAccountSettingsPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.ACCOUNTING.RECONCILIATION_ACCOUNT_SETTINGS>;

Expand All @@ -38,18 +41,23 @@ function ReconciliationAccountSettingsPage({route}: ReconciliationAccountSetting
const settlementAccountEnding = getLastFourDigits(bankAccountNumber);

const sections = useMemo(() => {
const data = Object.values(bankAccountList ?? {}).map((bankAccount) => ({
if (!bankAccountList || isEmptyObject(bankAccountList)) {
return [];
}
const eligibleBankAccounts = CardUtils.getEligibleBankAccountsForCard(bankAccountList);

const data = eligibleBankAccounts.map((bankAccount) => ({
text: bankAccount.title,
value: bankAccount.accountData?.bankAccountID,
keyForList: bankAccount.accountData?.bankAccountID?.toString(),
isSelected: bankAccount.accountData?.bankAccountID === selectedBankAccount?.accountData?.bankAccountID,
isSelected: bankAccount.accountData?.bankAccountID === paymentBankAccountID,
}));
return [{data}];
}, [bankAccountList, selectedBankAccount]);
}, [bankAccountList, paymentBankAccountID]);

const selectBankAccount = () => {
// TODO: add API call when it's implemented https://github.com/Expensify/Expensify/issues/407836
// Navigation.goBack();
const selectBankAccount = (newBankAccountID?: number) => {
Card.updateSettlementAccount(workspaceAccountID, policyID, newBankAccountID, paymentBankAccountID);
Navigation.goBack();
};

return (
Expand All @@ -74,9 +82,9 @@ function ReconciliationAccountSettingsPage({route}: ReconciliationAccountSetting

<SelectionList
sections={sections}
onSelectRow={selectBankAccount}
onSelectRow={({value}) => selectBankAccount(value)}
ListItem={RadioListItem}
initiallyFocusedOptionKey={selectedBankAccount?.accountData?.bankAccountID?.toString()}
initiallyFocusedOptionKey={paymentBankAccountID.toString()}
/>
</ConnectionLayout>
);
Expand Down
12 changes: 8 additions & 4 deletions src/pages/workspace/expensifyCard/WorkspaceCardsListLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import getClickedTargetLocation from '@libs/getClickedTargetLocation';
import * as PolicyUtils from '@libs/PolicyUtils';
import type {FullScreenNavigatorParamList} from '@navigation/types';
import variables from '@styles/variables';
import * as Policy from '@userActions/Policy/Policy';
import * as Report from '@userActions/Report';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -50,9 +52,12 @@ function WorkspaceCardsListLabel({type, value, style}: WorkspaceCardsListLabelPr
const [anchorPosition, setAnchorPosition] = useState({top: 0, left: 0});
const anchorRef = useRef(null);

const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(route.params.policyID);
const policyCurrency = useMemo(() => policy?.outputCurrency ?? CONST.CURRENCY.USD, [policy]);
// TODO: instead of the first bankAccount on the list get settlementBankAccountID from the private_expensifyCardSettings NVP and check if that is connected via Plaid.
const isConnectedWithPlaid = useMemo(() => !!Object.values(bankAccountList ?? {})[0]?.accountData?.additionalData?.plaidAccountID, [bankAccountList]);
const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`);
const paymentBankAccountID = cardSettings?.paymentBankAccountID;

const isConnectedWithPlaid = useMemo(() => !!bankAccountList?.[paymentBankAccountID ?? 0]?.accountData?.additionalData?.plaidAccountID, [bankAccountList, paymentBankAccountID]);

useEffect(() => {
if (!anchorRef.current || !isVisible) {
Expand All @@ -69,8 +74,7 @@ function WorkspaceCardsListLabel({type, value, style}: WorkspaceCardsListLabelPr
}, [isVisible, windowWidth]);

const requestLimitIncrease = () => {
// TODO: uncomment when RequestExpensifyCardLimitIncrease API call is supported
// Policy.requestExpensifyCardLimitIncrease(settlementBankAccountID);
Policy.requestExpensifyCardLimitIncrease(cardSettings?.paymentBankAccountID);
setVisible(false);
Report.navigateToConciergeChat();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA

const handleSelectBankAccount = (value?: number) => {
Card.configureExpensifyCardsForPolicy(policyID, value);
const domainName = PolicyUtils.getDomainNameForPolicy(policyID);
Card.updateSettlementAccount(workspaceAccountID, domainName, value);
Card.updateSettlementAccount(workspaceAccountID, policyID, value);
Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID));
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ function WorkspaceSettlementAccountPage({route}: WorkspaceSettlementAccountPageP
}, [eligibleBankAccounts, paymentBankAccountID, styles, translate]);

const updateSettlementAccount = (value: number) => {
const domainName = PolicyUtils.getDomainNameForPolicy(policyID);
Card.updateSettlementAccount(workspaceAccountID, domainName, value, paymentBankAccountID);
Card.updateSettlementAccount(workspaceAccountID, policyID, value, paymentBankAccountID);
Navigation.goBack();
};

Expand Down
14 changes: 11 additions & 3 deletions src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as Card from '@userActions/Card';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';
import type {IssueNewCardData} from '@src/types/onyx/Card';

const MINIMUM_MEMBER_TO_SHOW_SEARCH = 8;

Expand All @@ -42,11 +43,18 @@ function AssigneeStep({policy}: AssigneeStepProps) {
const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState('');

const submit = (assignee: ListItem) => {
const data: Partial<IssueNewCardData> = {
assigneeEmail: assignee?.login ?? '',
};

if (isEditing && issueNewCard?.data?.cardTitle === Card.getCardDefaultName(PersonalDetailsUtils.getUserNameByEmail(issueNewCard?.data?.assigneeEmail, 'firstName'))) {
// If the card title is the default card title, update it with the new assignee's name
data.cardTitle = Card.getCardDefaultName(PersonalDetailsUtils.getUserNameByEmail(assignee?.login ?? '', 'firstName'));
}

Card.setIssueNewCardStepAndData({
step: isEditing ? CONST.EXPENSIFY_CARD.STEP.CONFIRMATION : CONST.EXPENSIFY_CARD.STEP.CARD_TYPE,
data: {
assigneeEmail: assignee?.login ?? '',
},
data,
isEditing: false,
});
};
Expand Down
14 changes: 11 additions & 3 deletions src/types/onyx/OriginalMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,14 @@ type OriginalMessageIntegrationSyncFailed = {
errorMessage: string;
};

/**
* Original message for CARD_ISSUED, CARD_MISSING_ADDRESS, and CARD_ISSUED_VIRTUAL actions
*/
type OriginalMessageExpensifyCard = {
/** The id of the user the card was assigned to */
assigneeAccountID: number;
};

/** The map type of original message */
type OriginalMessageMap = {
/** */
Expand Down Expand Up @@ -633,11 +641,11 @@ type OriginalMessageMap = {
/** */
[CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_SETUP_REQUESTED]: never;
/** */
[CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED]: never;
[CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED]: OriginalMessageExpensifyCard;
/** */
[CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS]: never;
[CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS]: OriginalMessageExpensifyCard;
/** */
[CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED_VIRTUAL]: never;
[CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED_VIRTUAL]: OriginalMessageExpensifyCard;
/** */
[CONST.REPORT.ACTIONS.TYPE.INTEGRATION_SYNC_FAILED]: OriginalMessageIntegrationSyncFailed;
} & OldDotOriginalMessageMap & {
Expand Down
Loading