From e5ea703c128f18583ae484f825c757d17247eaaf Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 09:25:52 -0700 Subject: [PATCH 01/21] add to headers array --- src/CONST/index.ts | 1 + .../SelectionListWithSections/SearchTableHeader.tsx | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index b3f875c62c42..1f14138be9f2 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -6744,6 +6744,7 @@ const CONST = { TABLE_COLUMNS: { RECEIPT: 'receipt', DATE: 'date', + SUBMITTED: 'submitted', MERCHANT: 'merchant', DESCRIPTION: 'description', FROM: 'from', diff --git a/src/components/SelectionListWithSections/SearchTableHeader.tsx b/src/components/SelectionListWithSections/SearchTableHeader.tsx index 8965f6b59c4c..a9db8580b28d 100644 --- a/src/components/SelectionListWithSections/SearchTableHeader.tsx +++ b/src/components/SelectionListWithSections/SearchTableHeader.tsx @@ -34,6 +34,10 @@ const getExpenseHeaders = (groupBy?: SearchGroupBy): SearchColumnConfig[] => [ columnName: CONST.SEARCH.TABLE_COLUMNS.DATE, translationKey: 'common.date', }, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.SUBMITTED, + translationKey: 'common.submitted', + }, { columnName: CONST.SEARCH.TABLE_COLUMNS.MERCHANT, translationKey: 'common.merchant', @@ -140,6 +144,10 @@ const getExpenseReportHeaders = (profileIcon?: IconAsset): SearchColumnConfig[] columnName: CONST.SEARCH.TABLE_COLUMNS.DATE, translationKey: 'common.date', }, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.SUBMITTED, + translationKey: 'common.submitted', + }, { columnName: CONST.SEARCH.TABLE_COLUMNS.STATUS, translationKey: 'common.status', From bd6eeedd2408e4b9e453ca70dffba30dd6b23818 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 09:27:07 -0700 Subject: [PATCH 02/21] add to getColumnsToShow function --- src/libs/SearchUIUtils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 0781a0f037ff..af5e42b07211 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -2424,6 +2424,7 @@ function getColumnsToShow( return { [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true, [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true, [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true, [CONST.SEARCH.TABLE_COLUMNS.FROM]: true, @@ -2472,6 +2473,7 @@ function getColumnsToShow( [CONST.SEARCH.TABLE_COLUMNS.RECEIPT]: true, [CONST.SEARCH.TABLE_COLUMNS.TYPE]: true, [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, [CONST.SEARCH.TABLE_COLUMNS.MERCHANT]: false, [CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION]: false, [CONST.SEARCH.TABLE_COLUMNS.FROM]: false, From 93f9baa3cd588e3ac37884f6be85baf8bf68254d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 09:38:17 -0700 Subject: [PATCH 03/21] add to transaction list --- src/CONST/index.ts | 1 + src/components/TransactionItemRow/index.tsx | 13 +++++++++++++ src/types/onyx/Report.ts | 3 +++ 3 files changed, 17 insertions(+) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 1f14138be9f2..f2d902873b99 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -1380,6 +1380,7 @@ const CONST = { COMMENTS: 'comments', RECEIPT: 'receipt', DATE: 'date', + SUBMITTED: 'submitted', MERCHANT: 'merchant', DESCRIPTION: 'description', FROM: 'from', diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx index b41ad32b44d4..a4bbabacf21c 100644 --- a/src/components/TransactionItemRow/index.tsx +++ b/src/components/TransactionItemRow/index.tsx @@ -256,6 +256,18 @@ function TransactionItemRow({ /> ), + [CONST.REPORT.TRANSACTION_LIST.COLUMNS.SUBMITTED]: ( + + + + ), [CONST.REPORT.TRANSACTION_LIST.COLUMNS.CATEGORY]: ( ; From cafaf1f5ef742dc59fea2aedb4a08e8a87b38cb3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 09:55:44 -0700 Subject: [PATCH 04/21] add submitted column to transaction --- src/components/SelectionListWithSections/types.ts | 3 +++ src/libs/SearchUIUtils.ts | 7 +++++-- src/styles/utils/index.ts | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/SelectionListWithSections/types.ts b/src/components/SelectionListWithSections/types.ts index d7d04dc9c4f5..8ed740903c13 100644 --- a/src/components/SelectionListWithSections/types.ts +++ b/src/components/SelectionListWithSections/types.ts @@ -243,6 +243,9 @@ type TransactionListItemType = ListItem & /** Report to which the transaction belongs */ report: Report | undefined; + /** The date the report was submitted */ + submitted?: string; + /** Policy to which the transaction belongs */ policy: Policy | undefined; diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index af5e42b07211..97ce1dfb6e4b 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -137,6 +137,7 @@ const transactionColumnNamesToSortingProperty: TransactionSorting = { [CONST.SEARCH.TABLE_COLUMNS.TO]: 'formattedTo' as const, [CONST.SEARCH.TABLE_COLUMNS.FROM]: 'formattedFrom' as const, [CONST.SEARCH.TABLE_COLUMNS.DATE]: 'date' as const, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: 'submitted' as const, [CONST.SEARCH.TABLE_COLUMNS.TAG]: 'tag' as const, [CONST.SEARCH.TABLE_COLUMNS.MERCHANT]: 'formattedMerchant' as const, [CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT]: 'formattedTotal' as const, @@ -644,7 +645,7 @@ function getTransactionItemCommonFormattedProperties( policy: OnyxTypes.Policy, formatPhoneNumber: LocaleContextProps['formatPhoneNumber'], report: OnyxTypes.Report | undefined, -): Pick { +): Pick { const isExpenseReport = report?.type === CONST.REPORT.TYPE.EXPENSE; const fromName = getDisplayNameOrDefault(from); @@ -662,11 +663,13 @@ function getTransactionItemCommonFormattedProperties( const date = transactionItem?.modifiedCreated ? transactionItem.modifiedCreated : transactionItem?.created; const merchant = getTransactionMerchant(transactionItem, policy); const formattedMerchant = merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT ? '' : merchant; + const submitted = report?.submitted; return { formattedFrom, formattedTo, date, + submitted, formattedTotal, formattedMerchant, }; @@ -2473,7 +2476,7 @@ function getColumnsToShow( [CONST.SEARCH.TABLE_COLUMNS.RECEIPT]: true, [CONST.SEARCH.TABLE_COLUMNS.TYPE]: true, [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, - [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: true, [CONST.SEARCH.TABLE_COLUMNS.MERCHANT]: false, [CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION]: false, [CONST.SEARCH.TABLE_COLUMNS.FROM]: false, diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 0ae12fa272e7..d25c6499348d 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1731,6 +1731,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ case CONST.SEARCH.TABLE_COLUMNS.STATUS: columnWidth = {...getWidthStyle(variables.w80), ...styles.alignItemsCenter}; break; + case CONST.SEARCH.TABLE_COLUMNS.SUBMITTED: case CONST.SEARCH.TABLE_COLUMNS.DATE: if (isDateColumnFullWidth) { columnWidth = styles.flex1; From aac468702f30c94071b56694e7d4395f904a949e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 10:01:33 -0700 Subject: [PATCH 05/21] add submitted to transaction item --- src/libs/SearchUIUtils.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 97ce1dfb6e4b..882031f076e3 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1101,7 +1101,7 @@ function getTransactionsSections( const from = reportAction?.actorAccountID ? (personalDetailsMap.get(reportAction.actorAccountID.toString()) ?? emptyPersonalDetails) : emptyPersonalDetails; const to = getToFieldValueForTransaction(transactionItem, report, data.personalDetailsList, reportAction); - const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date} = getTransactionItemCommonFormattedProperties( + const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date, submitted} = getTransactionItemCommonFormattedProperties( transactionItem, from, to, @@ -1126,6 +1126,7 @@ function getTransactionsSections( formattedTotal, formattedMerchant, date, + submitted, shouldShowMerchant, shouldShowYear: doesDataContainAPastYearTransaction, isAmountColumnWide: shouldShowAmountInWideColumn, @@ -1914,7 +1915,7 @@ function getSortedTransactionData(data: TransactionListItemType[], localeCompare return data.sort((a, b) => { const aValue = sortingProperty === 'comment' ? a.comment?.comment : a[sortingProperty as keyof TransactionListItemType]; const bValue = sortingProperty === 'comment' ? b.comment?.comment : b[sortingProperty as keyof TransactionListItemType]; - + console.log('sortingProperty', {sortingProperty, aValue, bValue, a, b}); return compareValues(aValue, bValue, sortOrder, sortingProperty, localeCompare); }); } From cf70171026c80ee5023bfc59a2a6add9a1dfbea8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 10:18:11 -0700 Subject: [PATCH 06/21] update sorting function --- src/libs/SearchUIUtils.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 882031f076e3..742e62af99bc 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1879,11 +1879,21 @@ function getSortedSections( */ function compareValues(a: unknown, b: unknown, sortOrder: SortOrder, sortBy: string, localeCompare: LocaleContextProps['localeCompare'], shouldCompareOriginalValue = false): number { const isAsc = sortOrder === CONST.SEARCH.SORT_ORDER.ASC; + const aIsEmpty = a === undefined || a === null || a === ''; + const bIsEmpty = b === undefined || b === null || b === ''; - if (a === undefined || b === undefined) { + if (aIsEmpty && bIsEmpty) { return 0; } + if (aIsEmpty) { + return isAsc ? -1 : 1; + } + + if (bIsEmpty) { + return isAsc ? 1 : -1; + } + if (typeof a === 'string' && typeof b === 'string') { return isAsc ? localeCompare(a, b) : localeCompare(b, a); } @@ -1915,7 +1925,7 @@ function getSortedTransactionData(data: TransactionListItemType[], localeCompare return data.sort((a, b) => { const aValue = sortingProperty === 'comment' ? a.comment?.comment : a[sortingProperty as keyof TransactionListItemType]; const bValue = sortingProperty === 'comment' ? b.comment?.comment : b[sortingProperty as keyof TransactionListItemType]; - console.log('sortingProperty', {sortingProperty, aValue, bValue, a, b}); + return compareValues(aValue, bValue, sortOrder, sortingProperty, localeCompare); }); } From fb241ea2504345cf1eb2db81828a4556fc08c630 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 10:46:04 -0700 Subject: [PATCH 07/21] refactor show year logic --- .../SelectionListWithSections/types.ts | 11 +++ src/libs/SearchUIUtils.ts | 92 +++++++++++++------ 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/src/components/SelectionListWithSections/types.ts b/src/components/SelectionListWithSections/types.ts index 8ed740903c13..cc5f8bd7c864 100644 --- a/src/components/SelectionListWithSections/types.ts +++ b/src/components/SelectionListWithSections/types.ts @@ -284,6 +284,11 @@ type TransactionListItemType = ListItem & */ shouldShowYear: boolean; + /** Whether we should show the year for the submitted date. + * This is true if at least one transaction in the dataset was submitted in past years + */ + shouldShowYearSubmitted: boolean; + isAmountColumnWide: boolean; isTaxAmountColumnWide: boolean; @@ -402,6 +407,12 @@ type TransactionReportGroupListItemType = TransactionGroupListItemType & {groupe */ shouldShowYear: boolean; + /** + * Whether we should show the year for the submitted date. + * This is true if at least one report in the dataset was submitted in past years + */ + shouldShowYearSubmitted: boolean; + /** The main action that can be performed for the report */ action: SearchTransactionAction | undefined; diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 742e62af99bc..e117d75d9204 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -848,59 +848,98 @@ function getWideAmountIndicators(data: TransactionListItemType[] | TransactionGr }; } +type ShouldShowYearResult = { + shouldShowYearCreated: boolean; + shouldShowYearSubmitted: boolean; +}; + /** * Checks if the date of transactions or reports indicate the need to display the year because they are from a past year. * @param data - The search results data (array or object) * @param checkOnlyReports - When true and data is an object, only check report dates (skip transactions and report actions) + * @returns An object indicating which date fields should display the full year */ -function shouldShowYear(data: TransactionListItemType[] | TransactionGroupListItemType[] | TaskListItemType[] | OnyxTypes.SearchResults['data'], checkOnlyReports = false) { +function shouldShowYear( + data: TransactionListItemType[] | TransactionGroupListItemType[] | TaskListItemType[] | OnyxTypes.SearchResults['data'], + checkOnlyReports = false, +): ShouldShowYearResult { + const result: ShouldShowYearResult = { + shouldShowYearCreated: false, + shouldShowYearSubmitted: false, + }; + const currentYear = new Date().getFullYear(); if (Array.isArray(data)) { - return data.some((item: TransactionListItemType | TransactionGroupListItemType | TaskListItemType) => { + for (const item of data) { if (isTaskListItemType(item)) { const taskYear = new Date(item.created).getFullYear(); - return taskYear !== currentYear; + if (taskYear !== currentYear) { + result.shouldShowYearCreated = true; + } } - - if (isTransactionGroupListItemType(item)) { - // If the item is a TransactionGroupListItemType, iterate over its transactions and check them - return item.transactions.some((transaction) => { - const transactionYear = new Date(getTransactionCreatedDate(transaction)).getFullYear(); - return transactionYear !== currentYear; - }); + if (isTransactionReportGroupListItemType(item)) { + if (item.created && DateUtils.doesDateBelongToAPastYear(item.created)) { + result.shouldShowYearCreated = true; + } + if (item.submitted && DateUtils.doesDateBelongToAPastYear(item.submitted)) { + result.shouldShowYearSubmitted = true; + } + } + if (isTransactionListItemType(item)) { + const transactionCreated = getTransactionCreatedDate(item); + if (transactionCreated && DateUtils.doesDateBelongToAPastYear(transactionCreated)) { + result.shouldShowYearCreated = true; + } + if (item.submitted && DateUtils.doesDateBelongToAPastYear(item.submitted)) { + result.shouldShowYearSubmitted = true; + } } - const createdYear = new Date(item?.modifiedCreated ? item.modifiedCreated : item?.created || '').getFullYear(); - return createdYear !== currentYear; - }); + // Early exit if all flags are true + if (result.shouldShowYearCreated && result.shouldShowYearSubmitted) { + return result; + } + } + return result; } - for (const key in data) { + for (const key of Object.keys(data)) { if (!checkOnlyReports && isTransactionEntry(key)) { const item = data[key]; - if (shouldShowTransactionYear(item)) { - return true; + if (item.created && DateUtils.doesDateBelongToAPastYear(item.created)) { + result.shouldShowYearCreated = true; + } + const report = data[`${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`]; + if (report?.submitted && DateUtils.doesDateBelongToAPastYear(report.submitted)) { + result.shouldShowYearSubmitted = true; } } else if (!checkOnlyReports && isReportActionEntry(key)) { const item = data[key]; for (const action of Object.values(item)) { const date = action.created; - if (DateUtils.doesDateBelongToAPastYear(date)) { - return true; + result.shouldShowYearCreated = true; } } } else if (isReportEntry(key)) { const item = data[key]; - const date = item.created; - if (date && DateUtils.doesDateBelongToAPastYear(date)) { - return true; + if (item.created && DateUtils.doesDateBelongToAPastYear(item.created)) { + result.shouldShowYearCreated = true; + } + if (item.submitted && DateUtils.doesDateBelongToAPastYear(item.submitted)) { + result.shouldShowYearSubmitted = true; } } + + // Early exit if all flags are true + if (result.shouldShowYearCreated && result.shouldShowYearSubmitted) { + return result; + } } - return false; + + return result; } /** @@ -1052,7 +1091,7 @@ function getTransactionsSections( isActionLoadingSet: ReadonlySet | undefined, ): [TransactionListItemType[], number] { const shouldShowMerchant = getShouldShowMerchant(data); - const doesDataContainAPastYearTransaction = shouldShowYear(data); + const {shouldShowYearCreated, shouldShowYearSubmitted} = shouldShowYear(data); const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(data); // Pre-filter transaction keys to avoid repeated checks @@ -1128,7 +1167,8 @@ function getTransactionsSections( date, submitted, shouldShowMerchant, - shouldShowYear: doesDataContainAPastYearTransaction, + shouldShowYear: shouldShowYearCreated, + shouldShowYearSubmitted, isAmountColumnWide: shouldShowAmountInWideColumn, isTaxAmountColumnWide: shouldShowTaxAmountInWideColumn, violations: transactionViolations, @@ -1340,7 +1380,7 @@ function getTaskSections( const report = getReportOrDraftReport(taskItem.reportID) ?? taskItem; const parentReport = getReportOrDraftReport(taskItem.parentReportID); - const doesDataContainAPastYearTransaction = shouldShowYear(data); + const {shouldShowYearCreated} = shouldShowYear(data); const reportName = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.reportName)); const description = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.description)); @@ -1353,7 +1393,7 @@ function getTaskSections( createdBy, formattedCreatedBy, keyForList: taskItem.reportID, - shouldShowYear: doesDataContainAPastYearTransaction, + shouldShowYear: shouldShowYearCreated, }; if (parentReport && personalDetails) { From 4f8410dbd18d6cd84c4a7f6b4224c3bbb508306b Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 10:47:33 -0700 Subject: [PATCH 08/21] refactor call sites --- src/libs/SearchUIUtils.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index e117d75d9204..d70647091d51 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -123,7 +123,6 @@ import { isScanning, isViolationDismissed, } from './TransactionUtils'; -import shouldShowTransactionYear from './TransactionUtils/shouldShowTransactionYear'; import ViolationsUtils from './Violations/ViolationsUtils'; type ColumnSortMapping = Partial>; @@ -1540,7 +1539,7 @@ function getReportSections( ): [TransactionGroupListItemType[], number] { const shouldShowMerchant = getShouldShowMerchant(data); - const doesDataContainAPastYearTransaction = shouldShowYear(data); + const {shouldShowYearCreated: shouldShowYearCreatedTransaction, shouldShowYearSubmitted: shouldShowYearSubmittedTransaction} = shouldShowYear(data); const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(data); const {moneyRequestReportActionsByTransactionID, holdReportActionsByTransactionID} = createReportActionsLookupMaps(data); @@ -1563,7 +1562,7 @@ function getReportSections( ); const orderedKeys: string[] = [...reportKeys, ...transactionKeys]; - const doesDataContainAPastYearReport = shouldShowYear(data, true); + const {shouldShowYearCreated: shouldShowYearCreatedReport, shouldShowYearSubmitted: shouldShowYearSubmittedReport} = shouldShowYear(data, true); 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)) { @@ -1636,7 +1635,8 @@ function getReportSections( formattedStatus, transactions, ...(reportPendingAction ? {pendingAction: reportPendingAction} : {}), - shouldShowYear: doesDataContainAPastYearReport, + shouldShowYear: shouldShowYearCreatedReport, + shouldShowYearSubmitted: shouldShowYearSubmittedReport, hasVisibleViolations: hasVisibleViolationsForReport, }; @@ -1682,7 +1682,8 @@ function getReportSections( formattedMerchant, date, shouldShowMerchant, - shouldShowYear: doesDataContainAPastYearTransaction, + shouldShowYear: shouldShowYearCreatedTransaction, + shouldShowYearSubmitted: shouldShowYearSubmittedTransaction, keyForList: transactionItem.transactionID, violations: transactionViolations, isAmountColumnWide: shouldShowAmountInWideColumn, From b517149501b77fc8f3f79170e70b7bd1e4d7eb3e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 10:52:37 -0700 Subject: [PATCH 09/21] fix table width --- src/components/Search/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 5c8482a536fb..b466a2a8e4bd 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1034,7 +1034,7 @@ function Search({ navigation.setParams({q: newQuery, rawQuery: undefined}); }; - const shouldShowYear = shouldShowYearUtil(searchResults?.data, isExpenseReportType ?? false); + const {shouldShowYearCreated} = shouldShowYearUtil(searchResults?.data, isExpenseReportType ?? false); const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(searchResults?.data); const shouldShowSorting = !validGroupBy; const shouldShowTableHeader = isLargeScreenWidth && !isChat && !validGroupBy; @@ -1064,7 +1064,7 @@ function Search({ onSortPress={onSortPress} sortOrder={sortOrder} sortBy={sortBy} - shouldShowYear={shouldShowYear} + shouldShowYear={shouldShowYearCreated} isAmountColumnWide={shouldShowAmountInWideColumn} isTaxAmountColumnWide={shouldShowTaxAmountInWideColumn} shouldShowSorting={shouldShowSorting} From 29220f860af322db110e0da3828f2e128dcdfa8f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 12:52:01 -0700 Subject: [PATCH 10/21] resolve conflicts --- src/components/TransactionItemRow/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx index b4fc3239f3f4..198f7f2a8445 100644 --- a/src/components/TransactionItemRow/index.tsx +++ b/src/components/TransactionItemRow/index.tsx @@ -262,7 +262,7 @@ function TransactionItemRow({ style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.DATE, isDateColumnWide, false, false, areAllOptionalColumnsHidden)]} > From b7ba0d6374af7a4bf19b52fa4d18e4db0ce08bb1 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 13:09:15 -0700 Subject: [PATCH 11/21] make column wide if needed --- src/components/Search/index.tsx | 3 ++- .../Search/TransactionListItem.tsx | 6 ++++-- .../SelectionListWithSections/SearchTableHeader.tsx | 3 +++ .../SelectionListWithSections/SortableTableHeader.tsx | 3 +++ src/components/TransactionItemRow/index.tsx | 6 +++++- src/styles/utils/index.ts | 4 +++- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index b466a2a8e4bd..e1e248ba7bdf 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1034,7 +1034,7 @@ function Search({ navigation.setParams({q: newQuery, rawQuery: undefined}); }; - const {shouldShowYearCreated} = shouldShowYearUtil(searchResults?.data, isExpenseReportType ?? false); + const {shouldShowYearCreated, shouldShowYearSubmitted} = shouldShowYearUtil(searchResults?.data, isExpenseReportType ?? false); const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(searchResults?.data); const shouldShowSorting = !validGroupBy; const shouldShowTableHeader = isLargeScreenWidth && !isChat && !validGroupBy; @@ -1065,6 +1065,7 @@ function Search({ sortOrder={sortOrder} sortBy={sortBy} shouldShowYear={shouldShowYearCreated} + shouldShowYearSubmitted={shouldShowYearSubmitted} isAmountColumnWide={shouldShowAmountInWideColumn} isTaxAmountColumnWide={shouldShowTaxAmountInWideColumn} shouldShowSorting={shouldShowSorting} diff --git a/src/components/SelectionListWithSections/Search/TransactionListItem.tsx b/src/components/SelectionListWithSections/Search/TransactionListItem.tsx index da8b1707a2fc..b56f3f13c1e7 100644 --- a/src/components/SelectionListWithSections/Search/TransactionListItem.tsx +++ b/src/components/SelectionListWithSections/Search/TransactionListItem.tsx @@ -98,13 +98,14 @@ function TransactionListItem({ backgroundColor: theme.highlightBG, }); - const {amountColumnSize, dateColumnSize, taxAmountColumnSize} = useMemo(() => { + const {amountColumnSize, dateColumnSize, taxAmountColumnSize, submittedColumnSize} = useMemo(() => { return { amountColumnSize: transactionItem.isAmountColumnWide ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL, taxAmountColumnSize: transactionItem.isTaxAmountColumnWide ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL, dateColumnSize: transactionItem.shouldShowYear ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL, + submittedColumnSize: transactionItem.shouldShowYearSubmitted ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL, }; - }, [transactionItem.isAmountColumnWide, transactionItem.isTaxAmountColumnWide, transactionItem.shouldShowYear]); + }, [transactionItem.isAmountColumnWide, transactionItem.isTaxAmountColumnWide, transactionItem.shouldShowYear, transactionItem.shouldShowYearSubmitted]); const transactionViolations = useMemo(() => { return (violations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionItem.transactionID}`] ?? []).filter( @@ -201,6 +202,7 @@ function TransactionListItem({ isActionLoading={isLoading ?? isActionLoading} isSelected={!!transactionItem.isSelected} dateColumnSize={dateColumnSize} + submittedColumnSize={submittedColumnSize} amountColumnSize={amountColumnSize} taxAmountColumnSize={taxAmountColumnSize} shouldShowCheckbox={!!canSelectMultiple} diff --git a/src/components/SelectionListWithSections/SearchTableHeader.tsx b/src/components/SelectionListWithSections/SearchTableHeader.tsx index a9db8580b28d..c7d112b8c29e 100644 --- a/src/components/SelectionListWithSections/SearchTableHeader.tsx +++ b/src/components/SelectionListWithSections/SearchTableHeader.tsx @@ -200,6 +200,7 @@ type SearchTableHeaderProps = { sortOrder?: SortOrder; onSortPress: (column: SearchColumnType, order: SortOrder) => void; shouldShowYear: boolean; + shouldShowYearSubmitted?: boolean; isAmountColumnWide: boolean; isTaxAmountColumnWide: boolean; shouldShowSorting: boolean; @@ -215,6 +216,7 @@ function SearchTableHeader({ sortOrder, onSortPress, shouldShowYear, + shouldShowYearSubmitted, shouldShowSorting, canSelectMultiple, isAmountColumnWide, @@ -253,6 +255,7 @@ function SearchTableHeader({ areAllOptionalColumnsHidden={areAllOptionalColumnsHidden} shouldShowColumn={shouldShowColumn} dateColumnSize={shouldShowYear ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL} + submittedColumnSize={shouldShowYearSubmitted ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL} amountColumnSize={isAmountColumnWide ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL} taxAmountColumnSize={isTaxAmountColumnWide ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL} shouldShowSorting={shouldShowSorting} diff --git a/src/components/SelectionListWithSections/SortableTableHeader.tsx b/src/components/SelectionListWithSections/SortableTableHeader.tsx index 1d1ff42243b7..6157f929ec04 100644 --- a/src/components/SelectionListWithSections/SortableTableHeader.tsx +++ b/src/components/SelectionListWithSections/SortableTableHeader.tsx @@ -25,6 +25,7 @@ type SearchTableHeaderProps = { sortOrder?: SortOrder; shouldShowSorting: boolean; dateColumnSize: TableColumnSize; + submittedColumnSize?: TableColumnSize; amountColumnSize: TableColumnSize; taxAmountColumnSize: TableColumnSize; containerStyles?: StyleProp; @@ -39,6 +40,7 @@ function SortableTableHeader({ sortOrder, shouldShowColumn, dateColumnSize, + submittedColumnSize, containerStyles, shouldShowSorting, onSortPress, @@ -77,6 +79,7 @@ function SortableTableHeader({ amountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE, taxAmountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE, !!areAllOptionalColumnsHidden, + submittedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE, ), ]} isSortable={isSortable} diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx index 198f7f2a8445..c4eca3b0eac2 100644 --- a/src/components/TransactionItemRow/index.tsx +++ b/src/components/TransactionItemRow/index.tsx @@ -92,6 +92,7 @@ type TransactionItemRowProps = { isSelected: boolean; shouldShowTooltip: boolean; dateColumnSize: TableColumnSize; + submittedColumnSize?: TableColumnSize; amountColumnSize: TableColumnSize; taxAmountColumnSize: TableColumnSize; onCheckboxPress?: (transactionID: string) => void; @@ -134,6 +135,7 @@ function TransactionItemRow({ isSelected, shouldShowTooltip, dateColumnSize, + submittedColumnSize, amountColumnSize, taxAmountColumnSize, onCheckboxPress = () => {}, @@ -165,6 +167,7 @@ function TransactionItemRow({ const expensicons = useMemoizedLazyExpensifyIcons(['ArrowRight']); const isDateColumnWide = dateColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE; + const isSubmittedColumnWide = submittedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE; const isAmountColumnWide = amountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE; const isTaxAmountColumnWide = taxAmountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE; @@ -259,7 +262,7 @@ function TransactionItemRow({ [CONST.REPORT.TRANSACTION_LIST.COLUMNS.SUBMITTED]: ( ({ return isDragging ? styles.cursorGrabbing : styles.cursorZoomOut; }, - getReportTableColumnStyles: (columnName: string, isDateColumnWide = false, isAmountColumnWide = false, isTaxAmountColumnWide = false, isDateColumnFullWidth = false): ViewStyle => { + getReportTableColumnStyles: (columnName: string, isDateColumnWide = false, isAmountColumnWide = false, isTaxAmountColumnWide = false, isDateColumnFullWidth = false, isSubmittedColumnWide = false): ViewStyle => { let columnWidth; switch (columnName) { case CONST.REPORT.TRANSACTION_LIST.COLUMNS.COMMENTS: @@ -1732,6 +1732,8 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ columnWidth = {...getWidthStyle(variables.w80), ...styles.alignItemsCenter}; break; case CONST.SEARCH.TABLE_COLUMNS.SUBMITTED: + columnWidth = {...getWidthStyle(isSubmittedColumnWide ? variables.w92 : variables.w52)}; + break; case CONST.SEARCH.TABLE_COLUMNS.DATE: if (isDateColumnFullWidth) { columnWidth = styles.flex1; From 907c5116f41804c4e7ae0d1814872da24c9bc2fc Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 13:10:27 -0700 Subject: [PATCH 12/21] add min table width --- src/libs/SearchUIUtils.ts | 2 ++ src/styles/utils/index.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 58937a52d344..554930e8a3c0 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -2725,6 +2725,8 @@ function getTableMinWidth(columns: SearchColumnType[]) { minWidth += 80; } else if (column === CONST.SEARCH.TABLE_COLUMNS.DATE) { minWidth += 48; + } else if (column === CONST.SEARCH.TABLE_COLUMNS.SUBMITTED) { + minWidth += 72; } else if (column === CONST.SEARCH.TABLE_COLUMNS.TYPE) { minWidth += 20; } else { diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index f56c3de2d9b1..5292e9f1ea14 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1732,7 +1732,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ columnWidth = {...getWidthStyle(variables.w80), ...styles.alignItemsCenter}; break; case CONST.SEARCH.TABLE_COLUMNS.SUBMITTED: - columnWidth = {...getWidthStyle(isSubmittedColumnWide ? variables.w92 : variables.w52)}; + columnWidth = {...getWidthStyle(isSubmittedColumnWide ? variables.w92 : variables.w72)}; break; case CONST.SEARCH.TABLE_COLUMNS.DATE: if (isDateColumnFullWidth) { From f7ddd1e7645dd5c9cd8e222c90583af26ee617ed Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 13:13:57 -0700 Subject: [PATCH 13/21] add to report items --- .../Search/ExpenseReportListItemRow.tsx | 7 +++++++ src/libs/SearchUIUtils.ts | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx b/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx index 8d3dd41b846c..b8d618276532 100644 --- a/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx +++ b/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx @@ -158,6 +158,13 @@ function ExpenseReportListItemRow({ isLargeScreenWidth /> + + + Date: Mon, 15 Dec 2025 13:17:59 -0700 Subject: [PATCH 14/21] fix report sorting --- src/libs/SearchUIUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 27bbc6ff0196..289f52bf7441 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -160,6 +160,7 @@ const taskColumnNamesToSortingProperty: TaskSorting = { const expenseReportColumnNamesToSortingProperty: ExpenseReportSorting = { [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: null, [CONST.SEARCH.TABLE_COLUMNS.DATE]: 'created' as const, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: 'submitted' as const, [CONST.SEARCH.TABLE_COLUMNS.STATUS]: 'formattedStatus' as const, [CONST.SEARCH.TABLE_COLUMNS.TITLE]: 'reportName' as const, [CONST.SEARCH.TABLE_COLUMNS.FROM]: 'formattedFrom' as const, From 716c751894cf6665c80d74f4131fec06ece0a170 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 13:19:56 -0700 Subject: [PATCH 15/21] fix prettier --- src/libs/SearchUIUtils.ts | 2 +- src/styles/utils/index.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 289f52bf7441..20a3c3fa4744 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -885,7 +885,7 @@ function shouldShowYear( if (item.submitted && DateUtils.doesDateBelongToAPastYear(item.submitted)) { result.shouldShowYearSubmitted = true; } - } + } if (isTransactionListItemType(item)) { const transactionCreated = getTransactionCreatedDate(item); if (transactionCreated && DateUtils.doesDateBelongToAPastYear(transactionCreated)) { diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 5292e9f1ea14..1d62b86ace97 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1718,7 +1718,14 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ return isDragging ? styles.cursorGrabbing : styles.cursorZoomOut; }, - getReportTableColumnStyles: (columnName: string, isDateColumnWide = false, isAmountColumnWide = false, isTaxAmountColumnWide = false, isDateColumnFullWidth = false, isSubmittedColumnWide = false): ViewStyle => { + getReportTableColumnStyles: ( + columnName: string, + isDateColumnWide = false, + isAmountColumnWide = false, + isTaxAmountColumnWide = false, + isDateColumnFullWidth = false, + isSubmittedColumnWide = false, + ): ViewStyle => { let columnWidth; switch (columnName) { case CONST.REPORT.TRANSACTION_LIST.COLUMNS.COMMENTS: From 6be89602b21e588e5cee6490bbd58d35494f9805 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 13:49:41 -0700 Subject: [PATCH 16/21] fix ts, tests --- src/libs/DebugUtils.ts | 1 + src/types/utils/whitelistedReportKeys.ts | 1 + tests/unit/Search/SearchUIUtilsTest.ts | 139 +++++++++++++++++- .../Search/handleActionButtonPressTest.ts | 6 + tests/unit/TransactionGroupListItemTest.tsx | 4 + 5 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/libs/DebugUtils.ts b/src/libs/DebugUtils.ts index fd81224bb2ac..813b8f6e7d23 100644 --- a/src/libs/DebugUtils.ts +++ b/src/libs/DebugUtils.ts @@ -617,6 +617,7 @@ function validateReportDraftProperty(key: keyof Report | keyof ReportNameValuePa isCancelledIOU: CONST.RED_BRICK_ROAD_PENDING_ACTION, hasReportBeenRetracted: CONST.RED_BRICK_ROAD_PENDING_ACTION, hasReportBeenReopened: CONST.RED_BRICK_ROAD_PENDING_ACTION, + submitted: CONST.RED_BRICK_ROAD_PENDING_ACTION, isExportedToIntegration: CONST.RED_BRICK_ROAD_PENDING_ACTION, hasExportError: CONST.RED_BRICK_ROAD_PENDING_ACTION, iouReportID: CONST.RED_BRICK_ROAD_PENDING_ACTION, diff --git a/src/types/utils/whitelistedReportKeys.ts b/src/types/utils/whitelistedReportKeys.ts index 0a6b4100ebbc..c3f10b4da0e2 100644 --- a/src/types/utils/whitelistedReportKeys.ts +++ b/src/types/utils/whitelistedReportKeys.ts @@ -32,6 +32,7 @@ type WhitelistedReport = OnyxCommon.OnyxValueWithOfflineFeedback< writeCapability: unknown; type: unknown; created: unknown; + submitted: unknown; visibility: unknown; invoiceReceiver: unknown; parentReportID: unknown; diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index fc6bb19fe607..c706c1f49d0f 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -110,6 +110,7 @@ const report2 = { action: 'view', chatReportID: '1706144653204915', created: '2024-12-21 13:05:20', + submitted: '2024-12-21 13:05:20', currency: 'USD', isOneTransactionReport: true, isWaitingOnBankAccount: false, @@ -132,6 +133,7 @@ const report3 = { chatReportID: '6155022250251839', chatType: undefined, created: '2025-03-05 16:34:27', + submitted: '2025-03-05', currency: 'VND', isOneTransactionReport: false, isOwnPolicyExpenseChat: false, @@ -764,6 +766,7 @@ const transactionsListItems = [ category: '', comment: {comment: ''}, created: '2024-12-21', + submitted: undefined, currency: 'USD', date: '2024-12-21', formattedFrom: 'Admin', @@ -788,6 +791,7 @@ const transactionsListItems = [ reportID: '123456789', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, isAmountColumnWide: false, isTaxAmountColumnWide: false, tag: '', @@ -815,6 +819,7 @@ const transactionsListItems = [ category: '', comment: {comment: ''}, created: '2024-12-21', + submitted: '2024-12-21 13:05:20', currency: 'USD', date: '2024-12-21', formattedFrom: 'Admin', @@ -838,6 +843,7 @@ const transactionsListItems = [ reportID: '11111', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, isAmountColumnWide: false, isTaxAmountColumnWide: false, tag: '', @@ -876,6 +882,7 @@ const transactionsListItems = [ category: '', comment: {comment: ''}, created: '2025-03-05', + submitted: '2025-03-05', currency: 'VND', hasEReceipt: false, merchant: '(none)', @@ -906,6 +913,7 @@ const transactionsListItems = [ date: '2025-03-05', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, keyForList: '3', isAmountColumnWide: false, isTaxAmountColumnWide: false, @@ -932,6 +940,7 @@ const transactionsListItems = [ category: '', comment: {comment: ''}, created: '2025-03-05', + submitted: '2025-03-05', currency: 'VND', hasEReceipt: false, merchant: '(none)', @@ -962,6 +971,7 @@ const transactionsListItems = [ date: '2025-03-05', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, keyForList: '4', isAmountColumnWide: false, isTaxAmountColumnWide: false, @@ -1006,6 +1016,7 @@ const transactionReportGroupListItems = [ reportID: '123456789', reportName: 'Expense Report #123', shouldShowYear: true, + shouldShowYearSubmitted: true, stateNum: 0, statusNum: 0, to: emptyPersonalDetails, @@ -1049,6 +1060,7 @@ const transactionReportGroupListItems = [ reportID: '123456789', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, isAmountColumnWide: false, isTaxAmountColumnWide: false, tag: '', @@ -1074,6 +1086,7 @@ const transactionReportGroupListItems = [ allActions: ['approve'], chatReportID: '1706144653204915', created: '2024-12-21 13:05:20', + submitted: '2024-12-21 13:05:20', currency: 'USD', formattedFrom: 'Admin', formattedStatus: 'Outstanding', @@ -1095,6 +1108,7 @@ const transactionReportGroupListItems = [ reportID: '11111', reportName: 'Expense Report #123', shouldShowYear: true, + shouldShowYearSubmitted: true, stateNum: 1, statusNum: 1, to: { @@ -1148,6 +1162,7 @@ const transactionReportGroupListItems = [ reportID: '11111', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, isAmountColumnWide: false, isTaxAmountColumnWide: false, tag: '', @@ -1177,6 +1192,7 @@ const transactionReportGroupListItems = [ chatReportID: '6155022250251839', chatType: undefined, created: '2025-03-05 16:34:27', + submitted: '2025-03-05', currency: 'VND', formattedFrom: 'Admin', formattedStatus: 'Outstanding', @@ -1194,6 +1210,7 @@ const transactionReportGroupListItems = [ reportID: '99999', reportName: 'Approver owes ₫44.00', shouldShowYear: true, + shouldShowYearSubmitted: true, stateNum: 1, statusNum: 1, total: 4400, @@ -1215,7 +1232,122 @@ const transactionReportGroupListItems = [ displayName: 'Approver', login: 'approver@policy.com', }, - transactions: [transactionsListItems.at(2), transactionsListItems.at(3)], + transactions: [ + { + amount: 1200, + action: 'view', + allActions: ['view'], + report: report3, + policy, + reportAction: reportAction3, + holdReportAction: undefined, + cardID: undefined, + cardName: undefined, + category: '', + comment: {comment: ''}, + created: '2025-03-05', + currency: 'VND', + hasEReceipt: false, + merchant: '(none)', + modifiedAmount: 0, + modifiedCreated: '', + modifiedCurrency: '', + modifiedMerchant: '', + parentTransactionID: '', + reportID: '99999', + tag: '', + transactionID: '3', + from: { + accountID: 18439984, + avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png', + displayName: 'Admin', + login: 'admin@policy.com', + }, + to: { + accountID: 1111111, + avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png', + displayName: 'Approver', + login: 'approver@policy.com', + }, + formattedFrom: 'Admin', + formattedTo: 'Approver', + formattedTotal: 1200, + formattedMerchant: '', + date: '2025-03-05', + shouldShowMerchant: true, + shouldShowYear: true, + shouldShowYearSubmitted: true, + keyForList: '3', + isAmountColumnWide: false, + isTaxAmountColumnWide: false, + receipt: undefined, + taxAmount: undefined, + mccGroup: undefined, + modifiedMCCGroup: undefined, + pendingAction: undefined, + errors: undefined, + violations: [], + groupAmount: -5000, + groupCurrency: 'USD', + }, + { + amount: 3200, + action: 'view', + allActions: ['view'], + report: report3, + policy, + reportAction: reportAction4, + holdReportAction: undefined, + cardID: undefined, + cardName: undefined, + category: '', + comment: {comment: ''}, + created: '2025-03-05', + currency: 'VND', + hasEReceipt: false, + merchant: '(none)', + modifiedAmount: 0, + modifiedCreated: '', + modifiedCurrency: '', + modifiedMerchant: '', + parentTransactionID: '', + reportID: '99999', + tag: '', + transactionID: '4', + from: { + accountID: 18439984, + avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png', + displayName: 'Admin', + login: 'admin@policy.com', + }, + to: { + accountID: 1111111, + avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png', + displayName: 'Approver', + login: 'approver@policy.com', + }, + formattedFrom: 'Admin', + formattedTo: 'Approver', + formattedTotal: 3200, + formattedMerchant: '', + date: '2025-03-05', + shouldShowMerchant: true, + shouldShowYear: true, + shouldShowYearSubmitted: true, + keyForList: '4', + isAmountColumnWide: false, + isTaxAmountColumnWide: false, + receipt: undefined, + taxAmount: undefined, + mccGroup: undefined, + modifiedMCCGroup: undefined, + pendingAction: undefined, + errors: undefined, + violations: [], + groupAmount: -5000, + groupCurrency: 'USD', + }, + ], }, { groupedBy: 'expense-report', @@ -1245,6 +1377,7 @@ const transactionReportGroupListItems = [ reportID: reportID5, reportName: 'Expense Report #123', shouldShowYear: true, + shouldShowYearSubmitted: true, stateNum: 0, statusNum: 0, to: emptyPersonalDetails, @@ -1696,7 +1829,7 @@ describe('SearchUIUtils', () => { expect(distanceTransaction).toBeDefined(); expect(distanceTransaction?.iouRequestType).toBe(CONST.IOU.REQUEST_TYPE.DISTANCE); - const expectedPropertyCount = 45; + const expectedPropertyCount = 47; expect(Object.keys(distanceTransaction ?? {}).length).toBe(expectedPropertyCount); }); @@ -1729,7 +1862,7 @@ describe('SearchUIUtils', () => { expect(distanceTransaction).toBeDefined(); expect(distanceTransaction?.iouRequestType).toBe(CONST.IOU.REQUEST_TYPE.DISTANCE); - const expectedPropertyCount = 45; + const expectedPropertyCount = 46; expect(Object.keys(distanceTransaction ?? {}).length).toBe(expectedPropertyCount); }); diff --git a/tests/unit/Search/handleActionButtonPressTest.ts b/tests/unit/Search/handleActionButtonPressTest.ts index 5bb137e4228e..6adf6279af0b 100644 --- a/tests/unit/Search/handleActionButtonPressTest.ts +++ b/tests/unit/Search/handleActionButtonPressTest.ts @@ -16,6 +16,7 @@ const mockReportItemWithHold = { allActions: ['approve'], chatReportID: '2108006919825366', created: '2024-12-04 23:18:33', + submitted: '2024-12-04', currency: 'USD', isOneTransactionReport: false, isPolicyExpenseChat: false, @@ -64,6 +65,7 @@ const mockReportItemWithHold = { validated: false, }, shouldShowYear: false, + shouldShowYearSubmitted: false, transactions: [ { report: { @@ -107,6 +109,7 @@ const mockReportItemWithHold = { modifiedCurrency: '', modifiedMerchant: '', parentTransactionID: '', + submitted: '2024-12-04', policyID: '48D7178DE42EE9F9', reportID: '1350959062018695', reportType: 'expense', @@ -150,6 +153,7 @@ const mockReportItemWithHold = { date: '2024-12-04', shouldShowMerchant: true, shouldShowYear: false, + shouldShowYearSubmitted: false, keyForList: '1049531721038862176', isAmountColumnWide: false, isTaxAmountColumnWide: false, @@ -185,6 +189,7 @@ const mockReportItemWithHold = { comment: '', }, created: '2024-12-04', + submitted: '2024-12-04', currency: 'USD', hasEReceipt: false, merchant: 'Forbes', @@ -215,6 +220,7 @@ const mockReportItemWithHold = { date: '2024-12-04', shouldShowMerchant: true, shouldShowYear: false, + shouldShowYearSubmitted: false, keyForList: '5345995386715609966', isAmountColumnWide: false, isTaxAmountColumnWide: false, diff --git a/tests/unit/TransactionGroupListItemTest.tsx b/tests/unit/TransactionGroupListItemTest.tsx index 05cc0ab57376..6e951836b48b 100644 --- a/tests/unit/TransactionGroupListItemTest.tsx +++ b/tests/unit/TransactionGroupListItemTest.tsx @@ -30,6 +30,7 @@ const mockTransaction: TransactionListItemType = { groupAmount: 1284, groupCurrency: 'USD', created: '2025-09-19', + submitted: '2025-09-19', currency: 'USD', policy: { id: '06F34677820A4D07', @@ -64,6 +65,7 @@ const mockTransaction: TransactionListItemType = { date: '2025-09-07', shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: false, keyForList: '1', isAmountColumnWide: false, isTaxAmountColumnWide: false, @@ -88,6 +90,7 @@ const mockReport: TransactionReportGroupListItemType = { chatReportID: '4735435600700077', chatType: undefined, created: '2025-09-19 20:00:47', + submitted: '2025-09-19', currency: 'USD', isOneTransactionReport: true, isOwnPolicyExpenseChat: false, @@ -117,6 +120,7 @@ const mockReport: TransactionReportGroupListItemType = { displayName: 'Main Applause QA', }, shouldShowYear: false, + shouldShowYearSubmitted: false, action: 'view', transactions: [], groupedBy: 'expense-report', From b55165e939443e20ca14e67cf889b946d2221616 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 13:50:43 -0700 Subject: [PATCH 17/21] fix ts --- src/libs/DebugUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/DebugUtils.ts b/src/libs/DebugUtils.ts index 813b8f6e7d23..ada3d8ab01fc 100644 --- a/src/libs/DebugUtils.ts +++ b/src/libs/DebugUtils.ts @@ -418,6 +418,7 @@ function validateReportDraftProperty(key: keyof Report | keyof ReportNameValuePa switch (key) { case 'avatarUrl': case 'created': + case 'submitted': case 'lastMessageText': case 'lastVisibleActionCreated': case 'lastReadTime': From 042d02b26415970fff21f9cc596a87a9d3aa6b8d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 14:03:34 -0700 Subject: [PATCH 18/21] fix ts --- tests/unit/MoneyRequestReportUtilsTest.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/MoneyRequestReportUtilsTest.ts b/tests/unit/MoneyRequestReportUtilsTest.ts index 9cae1e021d32..616603708fea 100644 --- a/tests/unit/MoneyRequestReportUtilsTest.ts +++ b/tests/unit/MoneyRequestReportUtilsTest.ts @@ -16,6 +16,7 @@ const policyBaseMock: Policy = { const reportBaseMock: Report = { chatReportID: '1706144653204915', created: '2024-12-21 13:05:20', + submitted: '2024-12-21 13:05:20', currency: 'USD', isWaitingOnBankAccount: false, managerID: 100, @@ -60,6 +61,7 @@ const transactionItemBaseMock: TransactionListItemType = { category: '', comment: {comment: ''}, created: '2024-12-21', + submitted: '2024-12-21', currency: 'USD', date: '2024-12-21', formattedFrom: 'Admin', @@ -84,6 +86,7 @@ const transactionItemBaseMock: TransactionListItemType = { reportID: reportBaseMock.reportID, shouldShowMerchant: true, shouldShowYear: true, + shouldShowYearSubmitted: true, isAmountColumnWide: false, isTaxAmountColumnWide: false, tag: '', From 544faba673fd835618241185929ca0c9f6881211 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 18:22:38 -0700 Subject: [PATCH 19/21] fix logic --- .../Search/ExpenseReportListItemRow.tsx | 15 ++++++++------- src/libs/SearchUIUtils.ts | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx b/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx index ba235eb7a5e3..f9cd1d84c604 100644 --- a/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx +++ b/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx @@ -88,13 +88,14 @@ function ExpenseReportListItemRow({ /> ), - [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: ( - - + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: ( + + + ), [CONST.SEARCH.TABLE_COLUMNS.STATUS]: ( diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index ca9a8d4a5021..4ec23eba0f49 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -2615,7 +2615,7 @@ function getColumnsToShow( [CONST.SEARCH.TABLE_COLUMNS.RECEIPT]: true, [CONST.SEARCH.TABLE_COLUMNS.TYPE]: true, [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, - [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: true, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, [CONST.SEARCH.TABLE_COLUMNS.MERCHANT]: false, [CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION]: false, [CONST.SEARCH.TABLE_COLUMNS.FROM]: false, From 8135521aa5725b68781dd4514d6be074a7530a92 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 18:33:47 -0700 Subject: [PATCH 20/21] fix column ordeer --- src/libs/SearchUIUtils.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 4ec23eba0f49..2154f596efd0 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -2544,20 +2544,21 @@ function getColumnsToShow( type?: SearchDataTypes, ): ColumnVisibility { if (type === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT) { - const reportColumns = [ - CONST.SEARCH.TABLE_COLUMNS.AVATAR, - CONST.SEARCH.TABLE_COLUMNS.DATE, - CONST.SEARCH.TABLE_COLUMNS.STATUS, - CONST.SEARCH.TABLE_COLUMNS.TITLE, - CONST.SEARCH.TABLE_COLUMNS.FROM, - CONST.SEARCH.TABLE_COLUMNS.TO, - CONST.SEARCH.TABLE_COLUMNS.TOTAL, - CONST.SEARCH.TABLE_COLUMNS.ACTION, - ]; + const reportColumns: ColumnVisibility = { + [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true, + [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, + [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true, + [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true, + [CONST.SEARCH.TABLE_COLUMNS.FROM]: true, + [CONST.SEARCH.TABLE_COLUMNS.TO]: true, + [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: true, + [CONST.SEARCH.TABLE_COLUMNS.ACTION]: true, + }; // If there are no visible columns, everything should be visible if (!visibleColumns.length) { - return Object.fromEntries(reportColumns.map((column) => [column, true])); + return reportColumns; } // If the user has set custom columns, toggle the visible columns on, with all other @@ -2565,7 +2566,7 @@ function getColumnsToShow( const columns: ColumnVisibility = {}; const requiredColumns = new Set([CONST.SEARCH.TABLE_COLUMNS.AVATAR, CONST.SEARCH.TABLE_COLUMNS.TOTAL]); - for (const columnId of reportColumns) { + for (const columnId of Object.keys(reportColumns) as SearchColumnType[]) { columns[columnId] = requiredColumns.has(columnId); } From 5a66b1931efb0a3c29cd25dfc223b7e4564613bd Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 15 Dec 2025 18:42:34 -0700 Subject: [PATCH 21/21] fix test --- tests/unit/Search/SearchUIUtilsTest.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 488a3f849f37..63ba9786d6ec 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -2703,6 +2703,7 @@ describe('SearchUIUtils', () => { expect(SearchUIUtils.getColumnsToShow(1, [], [], false, CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT)).toEqual({ [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true, [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true, [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true, [CONST.SEARCH.TABLE_COLUMNS.FROM]: true, @@ -2719,6 +2720,7 @@ describe('SearchUIUtils', () => { // Avatar should always be visible [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true, [CONST.SEARCH.TABLE_COLUMNS.DATE]: true, + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: false, [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true, [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true, [CONST.SEARCH.TABLE_COLUMNS.FROM]: false,