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

Treat IOU debts as pinned reports in the LHN #3925

Merged
merged 5 commits into from
Jul 14, 2021
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
35 changes: 34 additions & 1 deletion src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ Onyx.connect({
},
});

const iouReports = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT_IOUS,
callback: (iouReport, key) => {
if (iouReport && key && iouReport.ownerEmail) {
iouReports[key] = iouReport;
}
},
});

/**
* Helper method to return a default avatar
*
Expand Down Expand Up @@ -180,6 +190,10 @@ function createOption(personalDetailList, report, draftComments, {
&& lodashGet(draftComments, `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report.reportID}`, '');

const hasOutstandingIOU = lodashGet(report, 'hasOutstandingIOU', false);
const iouReport = hasOutstandingIOU
? lodashGet(iouReports, `${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, {})
: {};

const lastActorDetails = report ? _.find(personalDetailList, {login: report.lastActorEmail}) : null;
const lastMessageText = report
? (hasMultipleParticipants && lastActorDetails
Expand Down Expand Up @@ -226,6 +240,8 @@ function createOption(personalDetailList, report, draftComments, {
isPinned: lodashGet(report, 'isPinned', false),
hasOutstandingIOU,
iouReportID: lodashGet(report, 'iouReportID'),
isIOUReportOwner: lodashGet(iouReport, 'ownerEmail', '') === currentUserLogin,
iouReportAmount: lodashGet(iouReport, 'total', 0),
isDefaultChatRoom,
};
}
Expand Down Expand Up @@ -280,10 +296,12 @@ function getOptions(reports, personalDetails, draftComments, activeReportID, {
hideReadReports = false,
sortByAlphaAsc = false,
forcePolicyNamePreview = false,
prioritizeIOUDebts = false,
}) {
let recentReportOptions = [];
const pinnedReportOptions = [];
const personalDetailsOptions = [];
const iouDebtReportOptions = [];

const reportMapForLogins = {};
let sortProperty = sortByLastMessageTimestamp
Expand All @@ -307,15 +325,20 @@ function getOptions(reports, personalDetails, draftComments, activeReportID, {
const reportDraftComment = report
&& draftComments
&& lodashGet(draftComments, `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${report.reportID}`, '');
const iouReportOwner = lodashGet(report, 'hasOutstandingIOU', false)
? lodashGet(iouReports, [`${ONYXKEYS.COLLECTION.REPORT_IOUS}${report.iouReportID}`, 'ownerEmail'], '')
: '';

const reportContainsIOUDebt = iouReportOwner && iouReportOwner !== currentUserLogin;
const shouldFilterReportIfEmpty = !showReportsWithNoComments && report.lastMessageTimestamp === 0;
const shouldFilterReportIfRead = hideReadReports && report.unreadActionCount === 0;
const shouldShowReportIfHasDraft = showReportsWithDrafts && reportDraftComment && reportDraftComment.length > 0;
const shouldFilterReport = shouldFilterReportIfEmpty || shouldFilterReportIfRead;
if (report.reportID !== activeReportID
&& !report.isPinned
&& !shouldShowReportIfHasDraft
&& shouldFilterReport) {
&& shouldFilterReport
&& !reportContainsIOUDebt) {
return;
}

Expand Down Expand Up @@ -380,6 +403,8 @@ function getOptions(reports, personalDetails, draftComments, activeReportID, {
// collect the pinned reports so we can sort them alphabetically once they are collected
if (prioritizePinnedReports && reportOption.isPinned) {
pinnedReportOptions.push(reportOption);
} else if (prioritizeIOUDebts && reportOption.hasOutstandingIOU && !reportOption.isIOUReportOwner) {
iouDebtReportOptions.push(reportOption);
} else {
recentReportOptions.push(reportOption);
}
Expand All @@ -391,6 +416,12 @@ function getOptions(reports, personalDetails, draftComments, activeReportID, {
}
}

// If we are prioritizing IOUs the user owes, add them before the normal recent report options
if (prioritizeIOUDebts) {
const sortedIOUReports = lodashOrderBy(iouDebtReportOptions, ['iouReportAmount'], ['desc']);
recentReportOptions = sortedIOUReports.concat(recentReportOptions);
}

// If we are prioritizing our pinned reports then shift them to the front and sort them by report name
if (prioritizePinnedReports) {
const sortedPinnedReports = lodashOrderBy(pinnedReportOptions, ['text'], ['asc']);
Expand Down Expand Up @@ -475,6 +506,7 @@ function getSearchOptions(
includePersonalDetails: true,
sortByLastMessageTimestamp: false,
forcePolicyNamePreview: true,
prioritizeIOUDebts: false,
});
}

Expand Down Expand Up @@ -589,6 +621,7 @@ function getSidebarOptions(
) {
let sideBarOptions = {
prioritizePinnedReports: true,
prioritizeIOUDebts: true,
};
if (priorityMode === CONST.PRIORITY_MODE.GSD) {
sideBarOptions = {
Expand Down
39 changes: 33 additions & 6 deletions tests/unit/OptionsListUtilsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ describe('OptionsListUtils', () => {
reportName: 'Silver Surfer',
unreadActionCount: 0,
},

// Note: This report has an IOU
9: {
lastVisitedTimestamp: 1610666739302,
lastMessageTimestamp: 1611282168,
isPinned: false,
reportID: 9,
participants: ['mistersinister@marauders.com'],
reportName: 'Mister Sinister',
unreadActionCount: 0,
iouReportID: 100,
hasOutstandingIOU: true,
},
};

// And a set of personalDetails some with existing reports and some without
Expand Down Expand Up @@ -119,6 +132,10 @@ describe('OptionsListUtils', () => {
displayName: 'Captain America',
login: 'steverogers@expensify.com',
},
'mistersinister@marauders.com': {
displayName: 'Mr Sinister',
login: 'mistersinister@marauders.com',
},

// These do not exist in reports at all
'natasharomanoff@expensify.com': {
Expand All @@ -134,11 +151,11 @@ describe('OptionsListUtils', () => {
const REPORTS_WITH_CONCIERGE = {
...REPORTS,

9: {
10: {
lastVisitedTimestamp: 1610666739302,
lastMessageTimestamp: 1,
isPinned: false,
reportID: 9,
reportID: 10,
participants: ['concierge@expensify.com'],
reportName: 'Concierge',
unreadActionCount: 1,
Expand All @@ -160,6 +177,10 @@ describe('OptionsListUtils', () => {
keys: ONYXKEYS,
initialKeyStates: {
[ONYXKEYS.SESSION]: {email: 'tonystark@expensify.com'},
[`${ONYXKEYS.COLLECTION.REPORT_IOUS}100`]: {
ownerEmail: 'mistersinister@marauders.com',
total: '1000',
},
},
registerStorageEventListener: () => {},
});
Expand Down Expand Up @@ -404,11 +425,11 @@ describe('OptionsListUtils', () => {
...REPORTS,

// Note: This report has no lastMessageTimestamp but is also pinned
9: {
10: {
lastVisitedTimestamp: 1610666739300,
lastMessageTimestamp: 0,
isPinned: true,
reportID: 9,
reportID: 10,
participants: ['captain_britain@expensify.com'],
reportName: 'Captain Britain',
},
Expand Down Expand Up @@ -436,8 +457,11 @@ describe('OptionsListUtils', () => {
// And the most recent pinned report is first in the list of reports
expect(results.recentReports[0].login).toBe('captain_britain@expensify.com');

// And the third report is the report with a lastMessageTimestamp
expect(results.recentReports[2].login).toBe('steverogers@expensify.com');
// And the third report is the report with an IOU debt
expect(results.recentReports[2].login).toBe('mistersinister@marauders.com');

// And the fourth report is the report with the lastMessage timestamp
expect(results.recentReports[3].login).toBe('steverogers@expensify.com');
});

it('getSidebarOptions() with GSD priority mode', () => {
Expand All @@ -457,5 +481,8 @@ describe('OptionsListUtils', () => {

// And Black Panther is alphabetically the first report and has an unread message
expect(results.recentReports[0].login).toBe('tchalla@expensify.com');

// And Mister Sinister is alphabetically the fifth report and has an IOU debt despite not being pinned
expect(results.recentReports[5].login).toBe('mistersinister@marauders.com');
});
});