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

Tweaks to the expense flow #53760

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
49269d0
remove the Just track it button
JKobrynski Dec 9, 2024
7a2556d
add the create $amount expense label
JKobrynski Dec 9, 2024
103bf6c
add Workspace and Personal sections to recipients list
JKobrynski Dec 10, 2024
50bbaaa
Merge branch 'main' into JKobrynski/feat/tweaks-to-create-expense-flow
JKobrynski Dec 11, 2024
3464608
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 11, 2024
052b1ff
update translation, add return type
JKobrynski Dec 11, 2024
520ec32
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 12, 2024
676a76d
put default workspace on top of the list
JKobrynski Dec 13, 2024
ff2fcc4
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 13, 2024
3bdf6d2
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 16, 2024
b1e5d19
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 17, 2024
c4fb54a
replace id fallbacks with CONST.DEFAULT_NUMBER_ID
JKobrynski Dec 17, 2024
50ebfa5
rename recentWorkspaceChats to workspaceChats
JKobrynski Dec 17, 2024
9e9e428
separate all workspace chats, not just recents
JKobrynski Dec 17, 2024
9848008
filter selfDMChat option
JKobrynski Dec 17, 2024
efe51d4
replace id fallbacks with CONST.DEFAULT_NUMBER_ID
JKobrynski Dec 17, 2024
398feac
fix ids rule
JKobrynski Dec 17, 2024
927ee63
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 18, 2024
9b2c48d
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 19, 2024
0bf0562
export getReport from ReportUtils
JKobrynski Dec 19, 2024
53adb31
simplify workspace filtering, fix no results found condition
JKobrynski Dec 19, 2024
2764399
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 19, 2024
e1447e9
replace isPolicyExpenseChat with isOwnPolicyExpenseChat
JKobrynski Dec 20, 2024
8aa913d
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 20, 2024
dd65178
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 20, 2024
d56d865
remove ReportUtils.getReport references
JKobrynski Dec 20, 2024
5f6ffce
filter out archived workspaces
JKobrynski Dec 20, 2024
70ca10d
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 20, 2024
f246b59
remove limit of displayed workspaces
JKobrynski Dec 20, 2024
a652bd5
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 27, 2024
6a6207d
fix id fallbacks
JKobrynski Dec 27, 2024
9f49eed
fix id fallback in MoneyRequestParticipantsSelector
JKobrynski Dec 27, 2024
28d4fef
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/twe…
JKobrynski Dec 30, 2024
eee9a5b
revert ID fallback changes in OptionsListUtils.ts
JKobrynski Dec 30, 2024
ad595ec
remove unnecessary empty line
JKobrynski Dec 30, 2024
3c27b60
fix optional parameters
JKobrynski Dec 31, 2024
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
4 changes: 2 additions & 2 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ function MoneyRequestConfirmationList({
text = translate('common.next');
}
} else if (isTypeTrackExpense) {
text = translate('iou.trackExpense');
text = translate('iou.createExpenseWithAmount', {amount: formattedAmount});
} else if (isTypeSplit && iouAmount === 0) {
text = translate('iou.splitExpense');
} else if ((receiptPath && isTypeRequest) || isDistanceRequestWithPendingRoute) {
Expand All @@ -419,7 +419,7 @@ function MoneyRequestConfirmationList({
text = translate('iou.submitAmount', {amount: formattedAmount});
}
} else {
const translationKey = isTypeSplit ? 'iou.splitAmount' : 'iou.submitAmount';
const translationKey = isTypeSplit ? 'iou.splitAmount' : 'iou.createExpenseWithAmount';
text = translate(translationKey, {amount: formattedAmount});
}
return [
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ const translations = {
createExpense: 'Create expense',
trackExpense: 'Track expense',
chooseRecipient: 'Choose recipient',
createExpenseWithAmount: ({amount}: {amount: string}) => `Create ${amount} expense`,
confirmDetails: 'Confirm details',
pay: 'Pay',
cancelPayment: 'Cancel payment',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,7 @@ const translations = {
trackExpense: 'Seguimiento de gastos',
chooseRecipient: 'Elige destinatario',
confirmDetails: 'Confirma los detalles',
createExpenseWithAmount: ({amount}: {amount: string}) => `Crea un gasto de ${amount}`,
JKobrynski marked this conversation as resolved.
Show resolved Hide resolved
pay: 'Pagar',
cancelPayment: 'Cancelar el pago',
cancelPaymentConfirmation: '¿Estás seguro de que quieres cancelar este pago?',
Expand Down
58 changes: 56 additions & 2 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ type GetOptionsConfig = {
shouldAcceptName?: boolean;
recentAttendees?: Attendee[];
shouldBoldTitleByDefault?: boolean;
shouldSeparateWorkspaceChat?: boolean;
shouldSeparateSelfDMChat?: boolean;
};

type GetUserToInviteConfig = {
Expand Down Expand Up @@ -146,6 +148,8 @@ type Options = {
personalDetails: ReportUtils.OptionData[];
userToInvite: ReportUtils.OptionData | null;
currentUserOption: ReportUtils.OptionData | null | undefined;
recentWorkspaceChats?: ReportUtils.OptionData[];
selfDMChat?: ReportUtils.OptionData | undefined;
};

type PreviewConfig = {showChatPreviewLine?: boolean; forcePolicyNamePreview?: boolean; showPersonalDetails?: boolean};
Expand Down Expand Up @@ -1070,6 +1074,8 @@ function getOptions(
action,
recentAttendees,
shouldBoldTitleByDefault = true,
shouldSeparateSelfDMChat = false,
shouldSeparateWorkspaceChat = false,
}: GetOptionsConfig = {},
): Options {
const topmostReportId = Navigation.getTopmostReportId() ?? '-1';
Expand Down Expand Up @@ -1280,6 +1286,17 @@ function getOptions(
}

const currentUserOption = allPersonalDetailsOptions.find((personalDetailsOption) => personalDetailsOption.login === currentUserLogin);
let recentWorkspaceChats: ReportUtils.OptionData[] = [];
let selfDMChat: ReportUtils.OptionData | undefined;

if (shouldSeparateWorkspaceChat) {
recentWorkspaceChats = recentReportOptions.filter((option) => option.isPolicyExpenseChat);
JKobrynski marked this conversation as resolved.
Show resolved Hide resolved
recentReportOptions = recentReportOptions.filter((option) => !option.isPolicyExpenseChat);
}
if (shouldSeparateSelfDMChat) {
selfDMChat = recentReportOptions.find((option) => option.isSelfDM);
recentReportOptions = recentReportOptions.filter((option) => !option.isSelfDM);
}

return {
personalDetails: personalDetailsOptions,
Expand All @@ -1288,6 +1305,8 @@ function getOptions(
// User to invite is generated by the search input of a user.
// As this function isn't concerned with any search input yet, this is null (will be set when using filterOptions).
userToInvite: null,
recentWorkspaceChats,
JKobrynski marked this conversation as resolved.
Show resolved Hide resolved
selfDMChat,
};
}

Expand Down Expand Up @@ -1520,6 +1539,7 @@ function formatSectionsFromSearchTerm(
filteredPersonalDetails: ReportUtils.OptionData[],
personalDetails: OnyxEntry<PersonalDetailsList> = {},
shouldGetOptionDetails = false,
filteredRecentWorkspaceChats: ReportUtils.OptionData[] = [],
): SectionForSearchTerm {
// We show the selected participants at the top of the list when there is no search term or maximum number of participants has already been selected
// However, if there is a search term we remove the selected participants from the top of the list unless they are part of the search results
Expand All @@ -1545,8 +1565,10 @@ function formatSectionsFromSearchTerm(
const selectedParticipantsWithoutDetails = selectedOptions.filter((participant) => {
const accountID = participant.accountID ?? null;
const isPartOfSearchTerm = getPersonalDetailSearchTerms(participant).join(' ').toLowerCase().includes(cleanSearchTerm);
const isReportInRecentReports = filteredRecentReports.some((report) => report.accountID === accountID);
const isReportInRecentReports =
filteredRecentReports.some((report) => report.accountID === accountID) || filteredRecentWorkspaceChats.some((report) => report.accountID === accountID);
const isReportInPersonalDetails = filteredPersonalDetails.some((personalDetail) => personalDetail.accountID === accountID);

return isPartOfSearchTerm && !isReportInRecentReports && !isReportInPersonalDetails;
});

Expand Down Expand Up @@ -1610,10 +1632,13 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt
if (searchInputValue.trim() === '' && maxRecentReportsToShow > 0) {
const recentReports = options.recentReports.slice(0, maxRecentReportsToShow);
const personalDetails = filteredPersonalDetailsOfRecentReports(recentReports, options.personalDetails);
const recentWorkspaceChats = options.recentWorkspaceChats?.slice(0, maxRecentReportsToShow);

return {
...options,
recentReports,
personalDetails,
recentWorkspaceChats,
};
}

Expand Down Expand Up @@ -1651,6 +1676,28 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt

return uniqFast(values);
});

const recentWorkspaceChats = filterArrayByMatch(items.recentWorkspaceChats ?? [], term, (item) => {
const values: string[] = [];
if (item.text) {
values.push(item.text);
}
if (item.login) {
values.push(item.login);
values.push(item.login.replace(CONST.EMAIL_SEARCH_REGEX, ''));
}
if (item.isThread) {
if (item.alternateText) {
values.push(item.alternateText);
}
} else if (!!item.isChatRoom || !!item.isPolicyExpenseChat) {
if (item.subtitle) {
values.push(item.subtitle);
}
}
return uniqFast(values);
});

const personalDetails = filterArrayByMatch(items.personalDetails, term, (item) => uniqFast(getPersonalDetailSearchTerms(item)));

const currentUserOptionSearchText = items.currentUserOption ? uniqFast(getCurrentUserSearchTerms(items.currentUserOption)).join(' ') : '';
Expand All @@ -1661,10 +1708,11 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt
personalDetails: personalDetails ?? [],
userToInvite: null,
currentUserOption,
recentWorkspaceChats: recentWorkspaceChats ?? [],
};
}, options);

const {recentReports, personalDetails} = matchResults;
const {recentReports, personalDetails, recentWorkspaceChats = []} = matchResults;

const personalDetailsWithoutDMs = filteredPersonalDetailsOfRecentReports(recentReports, personalDetails);

Expand Down Expand Up @@ -1696,12 +1744,18 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt
recentReports.splice(maxRecentReportsToShow);
}

if (maxRecentReportsToShow > 0 && recentWorkspaceChats.length > maxRecentReportsToShow) {
recentWorkspaceChats.splice(maxRecentReportsToShow);
}

const sortedRecentReports = orderOptions(filteredRecentReports, searchValue, {preferChatroomsOverThreads, preferPolicyExpenseChat, preferRecentExpenseReports});
return {
personalDetails: filteredPersonalDetails,
recentReports: sortedRecentReports,
userToInvite,
currentUserOption: matchResults.currentUserOption,
recentWorkspaceChats,
selfDMChat: options.selfDMChat,
JKobrynski marked this conversation as resolved.
Show resolved Hide resolved
};
}

Expand Down
60 changes: 24 additions & 36 deletions src/pages/iou/request/MoneyRequestParticipantsSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import EmptySelectionListContent from '@components/EmptySelectionListContent';
import FormHelpMessage from '@components/FormHelpMessage';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import {usePersonalDetails} from '@components/OnyxProvider';
import {useOptionsList} from '@components/OptionListContextProvider';
import ReferralProgramCTA from '@components/ReferralProgramCTA';
Expand Down Expand Up @@ -42,9 +40,6 @@ type MoneyRequestParticipantsSelectorProps = {
/** Callback to add participants in MoneyRequestModal */
onParticipantsAdded: (value: Participant[]) => void;

/** Callback to navigate to Track Expense confirmation flow */
onTrackExpensePress?: () => void;

/** Selected participants from MoneyRequestModal with login */
participants?: Participant[] | typeof CONST.EMPTY_ARRAY;

Expand All @@ -53,20 +48,9 @@ type MoneyRequestParticipantsSelectorProps = {

/** The action of the IOU, i.e. create, split, move */
action: IOUAction;

/** Whether we should display the Track Expense button at the top of the participants list */
shouldDisplayTrackExpenseButton?: boolean;
};

function MoneyRequestParticipantsSelector({
participants = CONST.EMPTY_ARRAY,
onTrackExpensePress,
onFinish,
onParticipantsAdded,
iouType,
action,
shouldDisplayTrackExpenseButton,
}: MoneyRequestParticipantsSelectorProps) {
function MoneyRequestParticipantsSelector({participants = CONST.EMPTY_ARRAY, onFinish, onParticipantsAdded, iouType, action}: MoneyRequestParticipantsSelectorProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState('');
Expand Down Expand Up @@ -124,6 +108,9 @@ function MoneyRequestParticipantsSelector({
includeInvoiceRooms: iouType === CONST.IOU.TYPE.INVOICE,
action,
maxRecentReportsToShow: 0,
shouldSeparateSelfDMChat: true,
shouldSeparateWorkspaceChat: true,
includeSelfDM: true,
},
);

Expand All @@ -146,6 +133,8 @@ function MoneyRequestParticipantsSelector({
personalDetails: [],
currentUserOption: null,
headerMessage: '',
recentWorkspaceChats: [],
selfDMChat: null,
};
}

Expand Down Expand Up @@ -181,6 +170,17 @@ function MoneyRequestParticipantsSelector({

newSections.push(formatResults.section);

newSections.push({
title: translate('workspace.common.workspace'),
data: chatOptions.recentWorkspaceChats ?? [],
shouldShow: (chatOptions.recentWorkspaceChats ?? []).length > 0,
});
newSections.push({
title: translate('workspace.invoices.paymentMethods.personal'),
data: chatOptions.selfDMChat ? [chatOptions.selfDMChat] : [],
shouldShow: !!chatOptions.selfDMChat,
});

newSections.push({
title: translate('common.recents'),
data: chatOptions.recentReports,
Expand Down Expand Up @@ -222,6 +222,8 @@ function MoneyRequestParticipantsSelector({
participants,
chatOptions.recentReports,
chatOptions.personalDetails,
chatOptions.selfDMChat,
chatOptions.recentWorkspaceChats,
chatOptions.userToInvite,
personalDetails,
translate,
Expand All @@ -237,7 +239,7 @@ function MoneyRequestParticipantsSelector({
(option: Participant) => {
const newParticipants: Participant[] = [
{
...lodashPick(option, 'accountID', 'login', 'isPolicyExpenseChat', 'reportID', 'searchText', 'policyID'),
...lodashPick(option, 'accountID', 'login', 'isPolicyExpenseChat', 'reportID', 'searchText', 'policyID', 'isSelfDM'),
selected: true,
iouType,
},
Expand All @@ -254,7 +256,10 @@ function MoneyRequestParticipantsSelector({
}

onParticipantsAdded(newParticipants);
onFinish();

if (!option.isSelfDM) {
onFinish();
}
},
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps -- we don't want to trigger this callback when iouType changes
[onFinish, onParticipantsAdded, currentUserLogin],
Expand Down Expand Up @@ -347,22 +352,6 @@ function MoneyRequestParticipantsSelector({

const shouldShowReferralBanner = !isDismissed && iouType !== CONST.IOU.TYPE.INVOICE && !shouldShowListEmptyContent;

const headerContent = useMemo(() => {
if (!shouldDisplayTrackExpenseButton) {
return;
}

// We only display the track expense button if the user is coming from the combined submit/track flow.
return (
<MenuItem
title={translate('iou.justTrackIt')}
shouldShowRightIcon
icon={Expensicons.Coins}
onPress={onTrackExpensePress}
/>
);
}, [shouldDisplayTrackExpenseButton, translate, onTrackExpensePress]);

const footerContent = useMemo(() => {
if (isDismissed && !shouldShowSplitBillErrorMessage && !participants.length) {
return;
Expand Down Expand Up @@ -448,7 +437,6 @@ function MoneyRequestParticipantsSelector({
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
onSelectRow={onSelectRow}
shouldSingleExecuteRowSelect
headerContent={headerContent}
footerContent={footerContent}
listEmptyContent={<EmptySelectionListContent contentType={iouType} />}
headerMessage={header}
Expand Down
Loading
Loading