Skip to content

Commit

Permalink
Merge pull request Expensify#3925 from Expensify/joe-pin-owed-balances
Browse files Browse the repository at this point in the history
Treat IOU debts as pinned reports in the LHN
  • Loading branch information
johnmlee101 authored Jul 14, 2021
2 parents 6cda0be + c146960 commit 9903cdb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 7 deletions.
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: ['[email protected]'],
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: '[email protected]',
},
'[email protected]': {
displayName: 'Mr Sinister',
login: '[email protected]',
},

// These do not exist in reports at all
'[email protected]': {
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: ['[email protected]'],
reportName: 'Concierge',
unreadActionCount: 1,
Expand All @@ -160,6 +177,10 @@ describe('OptionsListUtils', () => {
keys: ONYXKEYS,
initialKeyStates: {
[ONYXKEYS.SESSION]: {email: '[email protected]'},
[`${ONYXKEYS.COLLECTION.REPORT_IOUS}100`]: {
ownerEmail: '[email protected]',
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: ['[email protected]'],
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('[email protected]');

// And the third report is the report with a lastMessageTimestamp
expect(results.recentReports[2].login).toBe('[email protected]');
// And the third report is the report with an IOU debt
expect(results.recentReports[2].login).toBe('[email protected]');

// And the fourth report is the report with the lastMessage timestamp
expect(results.recentReports[3].login).toBe('[email protected]');
});

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('[email protected]');

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

0 comments on commit 9903cdb

Please sign in to comment.