Skip to content
Merged
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
72 changes: 49 additions & 23 deletions src/libs/SearchUIUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ type GetReportSectionsParams = {
bankAccountList: OnyxEntry<OnyxTypes.BankAccountList>;
reportActions?: Record<string, OnyxTypes.ReportAction[]>;
allReportMetadata: OnyxCollection<OnyxTypes.ReportMetadata>;
queryJSON?: SearchQueryJSON;
};

type GetTransactionSectionsParams = {
Expand Down Expand Up @@ -1393,6 +1394,7 @@ function buildLastExportedActionByReportIDMap(data: OnyxTypes.SearchResults['dat
function shouldShowYear(
data: TransactionListItemType[] | TransactionGroupListItemType[] | TaskListItemType[] | OnyxTypes.SearchResults['data'],
checkOnlyReports = false,
precomputedLastExportedMap?: Map<string, OnyxTypes.ReportAction>,
): ShouldShowYearResult {
const result: ShouldShowYearResult = {
shouldShowYearCreated: false,
Expand Down Expand Up @@ -1450,7 +1452,7 @@ function shouldShowYear(
return result;
}

const lastExportedActionByReportID = buildLastExportedActionByReportIDMap(data);
const lastExportedActionByReportID = precomputedLastExportedMap ?? buildLastExportedActionByReportIDMap(data);

for (const key of Object.keys(data)) {
if (!checkOnlyReports && isTransactionEntry(key)) {
Expand Down Expand Up @@ -1670,7 +1672,8 @@ function getTransactionsSections({
cardFeeds,
}: GetTransactionSectionsParams): [TransactionListItemType[], number] {
const shouldShowMerchant = getShouldShowMerchant(data);
const {shouldShowYearCreated, shouldShowYearSubmitted, shouldShowYearApproved, shouldShowYearPosted, shouldShowYearExported} = shouldShowYear(data);
const lastExportedActionByReportID = buildLastExportedActionByReportIDMap(data);
const {shouldShowYearCreated, shouldShowYearSubmitted, shouldShowYearApproved, shouldShowYearPosted, shouldShowYearExported} = shouldShowYear(data, false, lastExportedActionByReportID);
const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(data);

// Pre-filter transaction keys to avoid repeated checks
Expand All @@ -1684,8 +1687,6 @@ function getTransactionsSections({

const transactionsSections: TransactionListItemType[] = [];

const lastExportedActionByReportID = buildLastExportedActionByReportIDMap(data);

// Use the provided queryJSON if available, otherwise fall back to getCurrentSearchQueryJSON()
const currentQueryJSON = queryJSON ?? getCurrentSearchQueryJSON();

Expand Down Expand Up @@ -1850,6 +1851,7 @@ function getActions(
bankAccountList: OnyxEntry<OnyxTypes.BankAccountList>,
reportMetadata: OnyxEntry<OnyxTypes.ReportMetadata>,
reportActions: OnyxTypes.ReportAction[] = [],
precomputedTransactionsForReport?: OnyxTypes.Transaction[],
): SearchTransactionAction[] {
const isTransaction = isTransactionEntry(key);
const report = getReportFromKey(data, key);
Expand Down Expand Up @@ -1888,7 +1890,7 @@ function getActions(
const allActions: SearchTransactionAction[] = [];
let allReportTransactions: OnyxTypes.Transaction[];
if (isReportEntry(key)) {
allReportTransactions = getTransactionsForReport(data, report.reportID);
allReportTransactions = precomputedTransactionsForReport ?? getTransactionsForReport(data, report.reportID);
} else {
allReportTransactions = transaction ? [transaction] : [];
}
Expand Down Expand Up @@ -1968,6 +1970,7 @@ function getTaskSections(
formatPhoneNumber: LocaleContextProps['formatPhoneNumber'],
archivedReportsIDList?: ArchivedReportsIDSet,
): [TaskListItemType[], number] {
const {shouldShowYearCreated} = shouldShowYear(data);
const tasks = Object.keys(data)
.filter(isReportEntry)
// Ensure that the reports that were passed are tasks, and not some other
Expand All @@ -1985,7 +1988,6 @@ function getTaskSections(
const report = getReportOrDraftReport(taskItem.reportID) ?? taskItem;
const parentReport = getReportOrDraftReport(taskItem.parentReportID) ?? data[`${ONYXKEYS.COLLECTION.REPORT}${taskItem.parentReportID}`];

const {shouldShowYearCreated} = shouldShowYear(data);
const reportName = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.reportName));
const description = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.description));

Expand Down Expand Up @@ -2171,46 +2173,70 @@ function getReportSections({
bankAccountList,
reportActions = {},
allReportMetadata,
queryJSON,
}: GetReportSectionsParams): [TransactionGroupListItemType[], number] {
const shouldShowMerchant = getShouldShowMerchant(data);
const lastExportedActionByReportID = buildLastExportedActionByReportIDMap(data);

const {
shouldShowYearCreated: shouldShowYearCreatedTransaction,
shouldShowYearSubmitted: shouldShowYearSubmittedTransaction,
shouldShowYearApproved: shouldShowYearApprovedTransaction,
shouldShowYearPosted: shouldShowYearPostedTransaction,
shouldShowYearExported: shouldShowYearExportedTransaction,
} = shouldShowYear(data);
} = shouldShowYear(data, false, lastExportedActionByReportID);
const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(data);
const {moneyRequestReportActionsByTransactionID, holdReportActionsByTransactionID} = createReportActionsLookupMaps(data);

// Get violations - optimize by using a Map for faster lookups
const allViolations = getViolations(data);

const queryJSON = getCurrentSearchQueryJSON();
const currentQueryJSON = queryJSON ?? getCurrentSearchQueryJSON();
const reportIDToTransactions: Record<string, TransactionReportGroupListItemType> = {};

// Build transactionsByReportID map and compute report-level year flags in a single pass for performance reasons.
const transactionsByReportID = new Map<string, OnyxTypes.Transaction[]>();
let shouldShowYearCreatedReport = false;
let shouldShowYearSubmittedReport = false;
let shouldShowYearApprovedReport = false;
let shouldShowYearExportedReport = false;

const {reportKeys, transactionKeys} = Object.keys(data).reduce(
(acc, key) => {
if (isReportEntry(key)) {
acc.reportKeys.push(key);
const item = data[key];
if (!shouldShowYearCreatedReport && item.created && DateUtils.doesDateBelongToAPastYear(item.created)) {
shouldShowYearCreatedReport = true;
}
if (!shouldShowYearSubmittedReport && item.submitted && DateUtils.doesDateBelongToAPastYear(item.submitted)) {
shouldShowYearSubmittedReport = true;
}
if (!shouldShowYearApprovedReport && item.approved && DateUtils.doesDateBelongToAPastYear(item.approved)) {
shouldShowYearApprovedReport = true;
}
const exportedAction = lastExportedActionByReportID.get(item.reportID);
if (!shouldShowYearExportedReport && exportedAction?.created && DateUtils.doesDateBelongToAPastYear(exportedAction.created)) {
shouldShowYearExportedReport = true;
}
} else if (isTransactionEntry(key)) {
acc.transactionKeys.push(key);
const transaction = data[key];
if (transaction.reportID) {
const existing = transactionsByReportID.get(transaction.reportID);
if (existing) {
existing.push(transaction);
} else {
transactionsByReportID.set(transaction.reportID, [transaction]);
}
}
}
return acc;
},
{reportKeys: [] as string[], transactionKeys: [] as string[]},
);

const orderedKeys: string[] = [...reportKeys, ...transactionKeys];
const {
shouldShowYearCreated: shouldShowYearCreatedReport,
shouldShowYearSubmitted: shouldShowYearSubmittedReport,
shouldShowYearApproved: shouldShowYearApprovedReport,
shouldShowYearExported: shouldShowYearExportedReport,
} = shouldShowYear(data, true);

const lastExportedActionByReportID = buildLastExportedActionByReportIDMap(data);

for (const key of orderedKeys) {
if (isReportEntry(key) && (data[key].type === CONST.REPORT.TYPE.IOU || data[key].type === CONST.REPORT.TYPE.EXPENSE || data[key].type === CONST.REPORT.TYPE.INVOICE)) {
Expand All @@ -2223,9 +2249,9 @@ function getReportSections({
let shouldShow = true;

const isActionLoading = isActionLoadingSet?.has(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportItem.reportID}`);
if (queryJSON && !isActionLoading) {
if (queryJSON.type === CONST.SEARCH.DATA_TYPES.EXPENSE) {
const status = queryJSON.status;
if (currentQueryJSON && !isActionLoading) {
if (currentQueryJSON.type === CONST.SEARCH.DATA_TYPES.EXPENSE) {
const status = currentQueryJSON.status;

if (Array.isArray(status)) {
shouldShow = status.some((expenseStatus) => {
Expand All @@ -2241,7 +2267,8 @@ function getReportSections({
const reportPendingAction = reportItem?.pendingAction ?? reportItem?.pendingFields?.preview;
const shouldShowBlankTo = !reportItem || isOpenExpenseReport(reportItem);
const reportMetadata = allReportMetadata?.[`${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportItem.reportID}`] ?? {};
const allActions = getActions(data, allViolations, key, currentSearch, currentUserEmail, currentAccountID, bankAccountList, reportMetadata, actions);
const allReportTransactions = transactionsByReportID.get(reportItem.reportID) ?? [];
const allActions = getActions(data, allViolations, key, currentSearch, currentUserEmail, currentAccountID, bankAccountList, reportMetadata, actions, allReportTransactions);

const fromDetails =
data.personalDetailsList?.[reportItem.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID] ??
Expand All @@ -2253,8 +2280,6 @@ function getReportSections({
const formattedTo = !shouldShowBlankTo ? formatPhoneNumber(getDisplayNameOrDefault(toDetails)) : '';

const formattedStatus = getReportStatusTranslation({stateNum: reportItem.stateNum, statusNum: reportItem.statusNum, translate});

const allReportTransactions = getTransactionsForReport(data, reportItem.reportID);
const policyFromKey = getPolicyFromKey(data, reportItem);
const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${reportItem?.policyID ?? String(CONST.DEFAULT_NUMBER_ID)}`] ?? policyFromKey;

Expand All @@ -2281,6 +2306,7 @@ function getReportSections({
);

const {totalDisplaySpend, nonReimbursableSpend, reimbursableSpend} = getMoneyRequestSpendBreakdown(reportItem);

reportIDToTransactions[reportKey] = {
...reportItem,
action: allActions.at(0) ?? CONST.SEARCH.ACTION_TYPES.VIEW,
Expand Down Expand Up @@ -2374,7 +2400,6 @@ function getReportSections({
}

const reportIDToTransactionsValues = Object.values(reportIDToTransactions);

return [reportIDToTransactionsValues, reportIDToTransactionsValues.length];
}

Expand Down Expand Up @@ -2839,6 +2864,7 @@ function getSections({
bankAccountList,
reportActions,
allReportMetadata,
queryJSON,
});
}

Expand Down
Loading