Skip to content

Commit

Permalink
split gORIDs into smaller functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kacper-mikolajczak committed Mar 4, 2024
1 parent 8876c08 commit cdef526
Showing 1 changed file with 98 additions and 45 deletions.
143 changes: 98 additions & 45 deletions src/libs/SidebarUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,16 @@ function compareStringDates(a: string, b: string): 0 | 1 | -1 {
return 0;
}

/**
* @returns An array of reportIDs sorted in the proper order
*/
function getOrderedReportIDs(
function filterReportsToDisplay(
reports: Report[],
currentReportId: string | null,
allReports: Record<string, Report>,
betas: Beta[],
policies: Record<string, Policy>,
priorityMode: ValueOf<typeof CONST.PRIORITY_MODE>,
allReportActions: OnyxCollection<ReportAction[]>,
transactionViolations: OnyxCollection<TransactionViolation[]>,
currentPolicyID = '',
policyMemberAccountIDs: number[] = [],
): string[] {
const isInGSDMode = priorityMode === CONST.PRIORITY_MODE.GSD;
const isInDefaultMode = !isInGSDMode;
const allReportsDictValues = Object.values(allReports);

// Filter out all the reports that shouldn't be displayed
let reportsToDisplay = allReportsDictValues.filter((report) => {
betas: Beta[],
policies: Record<string, Policy>,
isInGSDMode: boolean,
): Report[] {
return reports.filter((report) => {
const parentReportActionsKey = `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`;
const parentReportActions = allReportActions?.[parentReportActionsKey];
const parentReportAction = parentReportActions?.find((action) => action && report && action?.reportActionID === report?.parentReportActionID);
Expand All @@ -95,18 +85,18 @@ function getOrderedReportIDs(
doesReportHaveViolations,
});
});
}

if (reportsToDisplay.length === 0) {
// Display Concierge chat report when there is no report to be displayed
const conciergeChatReport = allReportsDictValues.find(ReportUtils.isConciergeChatReport);
if (conciergeChatReport) {
reportsToDisplay.push(conciergeChatReport);
}
function filterReportsBelongingToWorkspace(reports: Report[], currentPolicyID: string, policyMemberAccountIDs: number[]): Report[] {
if (currentPolicyID || policyMemberAccountIDs.length > 0) {
return reports.filter((report) => ReportUtils.doesReportBelongToWorkspace(report, policyMemberAccountIDs, currentPolicyID));
}
return reports;
}

function groupReports(reports: Report[]) {
// The LHN is split into four distinct groups, and each group is sorted a little differently. The groups will ALWAYS be in this order:
// 1. Pinned/GBR - Always sorted by reportDisplayName
// 2. Drafts - Always sorted by reportDisplayName
// 3. Non-archived reports and settled IOUs
// - Sorted by lastVisibleActionCreated in default (most recent) view mode
// - Sorted by reportDisplayName in GSD (focus) view mode
Expand All @@ -118,22 +108,13 @@ function getOrderedReportIDs(
const nonArchivedReports: Report[] = [];
const archivedReports: Report[] = [];

if (currentPolicyID || policyMemberAccountIDs.length > 0) {
reportsToDisplay = reportsToDisplay.filter((report) => ReportUtils.doesReportBelongToWorkspace(report, policyMemberAccountIDs, currentPolicyID));
}
// There are a few properties that need to be calculated for the report which are used when sorting reports.
reportsToDisplay.forEach((report) => {
// Normally, the spread operator would be used here to clone the report and prevent the need to reassign the params.
// However, this code needs to be very performant to handle thousands of reports, so in the interest of speed, we're just going to disable this lint rule and add
// the reportDisplayName property to the report object directly.
// eslint-disable-next-line no-param-reassign
report.displayName = ReportUtils.getReportName(report);

reports.forEach((report) => {
const isPinned = report.isPinned ?? false;
const reportAction = ReportActionsUtils.getReportAction(report.parentReportID ?? '', report.parentReportActionID ?? '');
if (isPinned || ReportUtils.requiresAttentionFromCurrentUser(report, reportAction)) {
pinnedAndGBRReports.push(report);
} else if (report.hasDraft) {
} else if (hasValidDraftComment(report.reportID)) {
draftReports.push(report);
} else if (ReportUtils.isArchivedRoom(report)) {
archivedReports.push(report);
Expand All @@ -142,22 +123,93 @@ function getOrderedReportIDs(
}
});

// Sort each group of reports accordingly
pinnedAndGBRReports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
draftReports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
return {
pinnedAndGBRReports,
draftReports,
nonArchivedReports,
archivedReports,
};
}

function updateReportsNames(reports: Report[]) {
reports.forEach((report) => {
// Normally, the spread operator would be used here to clone the report and prevent the need to reassign the params.
// However, this code needs to be very performant to handle thousands of reports, so in the interest of speed, we're just going to disable this lint rule and add
// the reportDisplayName property to the report object directly.
// eslint-disable-next-line no-param-reassign
report.displayName = ReportUtils.getReportName(report);
});
}

function sortPinnedAndGBRReports(reports: Report[]) {
return reports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
}

function sortDraftReports(reports: Report[]) {
return reports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
}

function sortNonArchivedReports(reports: Report[], isInDefaultMode: boolean) {
if (isInDefaultMode) {
nonArchivedReports.sort((a, b) => {
return reports.sort((a, b) => {
const compareDates = a?.lastVisibleActionCreated && b?.lastVisibleActionCreated ? compareStringDates(b.lastVisibleActionCreated, a.lastVisibleActionCreated) : 0;
if (compareDates) {
return compareDates;
}
const compareDisplayNames = a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0;
return compareDates || compareDisplayNames;
return compareDisplayNames;
});
// For archived reports ensure that most recent reports are at the top by reversing the order
archivedReports.sort((a, b) => (a?.lastVisibleActionCreated && b?.lastVisibleActionCreated ? compareStringDates(b.lastVisibleActionCreated, a.lastVisibleActionCreated) : 0));
} else {
nonArchivedReports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
archivedReports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
}
return reports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
}

function sortArchivedReports(reports: Report[], isInDefaultMode: boolean) {
if (isInDefaultMode) {
return reports.sort((a, b) => (a?.lastVisibleActionCreated && b?.lastVisibleActionCreated ? compareStringDates(b.lastVisibleActionCreated, a.lastVisibleActionCreated) : 0));
}
return reports.sort((a, b) => (a?.displayName && b?.displayName ? localeCompare(a.displayName, b.displayName) : 0));
}

/**
* @returns An array of reportIDs sorted in the proper order
*/
function getOrderedReportIDs(
currentReportId: string | null,
allReports: Record<string, Report>,
betas: Beta[],
policies: Record<string, Policy>,
priorityMode: ValueOf<typeof CONST.PRIORITY_MODE>,
allReportActions: OnyxCollection<ReportAction[]>,
transactionViolations: OnyxCollection<TransactionViolation[]>,
currentPolicyID = '',
policyMemberAccountIDs: number[] = [],
): string[] {
const isInGSDMode = priorityMode === CONST.PRIORITY_MODE.GSD;
const isInDefaultMode = !isInGSDMode;
const allReportsDictValues = Object.values(allReports);

// Filter out all the reports that shouldn't be displayed
let reportsToDisplay = filterReportsToDisplay(allReportsDictValues, currentReportId, allReportActions, transactionViolations, betas, policies, isInGSDMode);

if (reportsToDisplay.length === 0) {
// Display Concierge chat report when there is no report to be displayed
const conciergeChatReport = allReportsDictValues.find(ReportUtils.isConciergeChatReport);
if (conciergeChatReport) {
reportsToDisplay.push(conciergeChatReport);
}
}

reportsToDisplay = filterReportsBelongingToWorkspace(reportsToDisplay, currentPolicyID, policyMemberAccountIDs);

updateReportsNames(reportsToDisplay);

const {pinnedAndGBRReports, draftReports, nonArchivedReports, archivedReports} = groupReports(reportsToDisplay);

// Sort each group of reports accordingly
sortPinnedAndGBRReports(pinnedAndGBRReports);
sortDraftReports(draftReports);
sortNonArchivedReports(nonArchivedReports, isInDefaultMode);
sortArchivedReports(archivedReports, isInDefaultMode);

// Now that we have all the reports grouped and sorted, they must be flattened into an array and only return the reportID.
// The order the arrays are concatenated in matters and will determine the order that the groups are displayed in the sidebar.
Expand Down Expand Up @@ -389,4 +441,5 @@ function getOptionData({
export default {
getOptionData,
getOrderedReportIDs,
sortDraftReports,
};

0 comments on commit cdef526

Please sign in to comment.