diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx
index 87f1fe8f9ff3b..f9245ba79a349 100644
--- a/src/components/Search/index.tsx
+++ b/src/components/Search/index.tsx
@@ -1283,6 +1283,20 @@ function Search({
endSpanWithAttributes(CONST.TELEMETRY.SPAN_NAVIGATE_TO_REPORTS, {[CONST.TELEMETRY.ATTRIBUTE_IS_WARM]: true});
}, []);
+ const measurements = useMemo(() => {
+ if (!filteredDataLength) {
+ return undefined;
+ }
+
+ const firstItem = filteredData.at(0);
+
+ if (firstItem && isTransactionListItemType(firstItem)) {
+ return firstItem.measurements;
+ }
+
+ return undefined;
+ }, [filteredDataLength, filteredData]);
+
// On re-visits, react-freeze serves the cached layout — onLayout/onLayoutSkeleton never fire.
// useFocusEffect fires on unfreeze, which is when the screen becomes visible.
useFocusEffect(
@@ -1429,6 +1443,7 @@ function Search({
!shouldShowTableHeader ? undefined : (
({
columns,
isLoading,
violations,
- customCardNames,
onDEWModalOpen,
isDEWBetaEnabled,
lastPaymentMethod,
@@ -110,14 +109,6 @@ function TransactionListItem({
backgroundColor: theme.highlightBG,
});
- const amountColumnSize = transactionItem.isAmountColumnWide ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
- const taxAmountColumnSize = transactionItem.isTaxAmountColumnWide ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
- const dateColumnSize = transactionItem.shouldShowYear ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
- const submittedColumnSize = transactionItem.shouldShowYearSubmitted ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
- const approvedColumnSize = transactionItem.shouldShowYearApproved ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
- const postedColumnSize = transactionItem.shouldShowYearPosted ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
- const exportedColumnSize = transactionItem.shouldShowYearExported ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL;
-
// Prefer live Onyx policy data over snapshot to ensure fresh policy settings
// like isAttendeeTrackingEnabled is not missing
// Use snapshotReport/snapshotPolicy as fallbacks to fix offline issues where
@@ -217,20 +208,12 @@ function TransactionListItem({
isActionLoading={isLoading ?? isActionLoading}
isSelected={!!transactionItem.isSelected}
isDisabled={!!isDisabled}
- dateColumnSize={dateColumnSize}
- submittedColumnSize={submittedColumnSize}
- approvedColumnSize={approvedColumnSize}
- postedColumnSize={postedColumnSize}
- exportedColumnSize={exportedColumnSize}
- amountColumnSize={amountColumnSize}
- taxAmountColumnSize={taxAmountColumnSize}
shouldShowCheckbox={!!canSelectMultiple}
checkboxSentryLabel={CONST.SENTRY_LABEL.SEARCH.TRANSACTION_LIST_ITEM_CHECKBOX}
style={[styles.p3, styles.pv2, shouldUseNarrowLayout ? styles.pt2 : {}]}
violations={transactionViolations}
onArrowRightPress={() => onSelectRow(item, transactionPreviewData)}
isHover={hovered}
- customCardNames={customCardNames}
reportActions={exportedReportActions}
/>
>
diff --git a/src/components/SelectionListWithSections/SearchTableHeader.tsx b/src/components/SelectionListWithSections/SearchTableHeader.tsx
index 7d05263b54a09..c4fe51b2d98a3 100644
--- a/src/components/SelectionListWithSections/SearchTableHeader.tsx
+++ b/src/components/SelectionListWithSections/SearchTableHeader.tsx
@@ -9,7 +9,7 @@ import type {TranslationPaths} from '@src/languages/types';
import type {SearchDataTypes} from '@src/types/onyx/SearchResults';
import type IconAsset from '@src/types/utils/IconAsset';
import SortableTableHeader from './SortableTableHeader';
-import type {SortableColumnName} from './types';
+import type {SortableColumnName, TransactionColumnMeasurements} from './types';
type SearchColumnConfig = {
columnName: SearchColumnType;
@@ -422,6 +422,7 @@ function getSearchColumns(type: ValueOf, icons:
}
type SearchTableHeaderProps = {
+ measurements?: TransactionColumnMeasurements;
columns: SortableColumnName[];
type: SearchDataTypes;
sortBy?: SearchColumnType;
@@ -445,6 +446,7 @@ type SearchTableHeaderProps = {
function SearchTableHeader({
columns,
type,
+ measurements,
sortBy,
sortOrder,
onSortPress,
@@ -517,6 +519,7 @@ function SearchTableHeader({
return (
onSortPress(columnName, order)}
/>
diff --git a/src/components/SelectionListWithSections/types.ts b/src/components/SelectionListWithSections/types.ts
index c240285c3ae6f..4022a4ae3aa8a 100644
--- a/src/components/SelectionListWithSections/types.ts
+++ b/src/components/SelectionListWithSections/types.ts
@@ -255,8 +255,84 @@ type ListItem = {
isIndeterminate?: boolean;
};
+// Columns that are shown in plain text
+type SearchTextColumns =
+ | typeof CONST.SEARCH.TABLE_COLUMNS.MERCHANT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.CATEGORY
+ | typeof CONST.SEARCH.TABLE_COLUMNS.TAG
+ | typeof CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.EXCHANGE_RATE
+ | typeof CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION
+ | typeof CONST.SEARCH.TABLE_COLUMNS.CARD
+ | typeof CONST.SEARCH.TABLE_COLUMNS.BILLABLE
+ | typeof CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE
+ | typeof CONST.SEARCH.TABLE_COLUMNS.TITLE
+ | typeof CONST.SEARCH.TABLE_COLUMNS.TAX_RATE
+ | typeof CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.REPORT_ID
+ | typeof CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID
+ | typeof CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.DATE
+ | typeof CONST.SEARCH.TABLE_COLUMNS.EXPORTED
+ | typeof CONST.SEARCH.TABLE_COLUMNS.SUBMITTED
+ | typeof CONST.SEARCH.TABLE_COLUMNS.APPROVED
+ | typeof CONST.SEARCH.TABLE_COLUMNS.POSTED
+ | typeof CONST.SEARCH.TABLE_COLUMNS.TOTAL
+ | typeof CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID
+ | typeof CONST.SEARCH.TABLE_COLUMNS.EXPENSES
+ | typeof CONST.SEARCH.TABLE_COLUMNS.FEED
+ | typeof CONST.SEARCH.TABLE_COLUMNS.WITHDRAWN
+ | typeof CONST.SEARCH.TABLE_COLUMNS.BANK_ACCOUNT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE_TOTAL
+ | typeof CONST.SEARCH.TABLE_COLUMNS.NON_REIMBURSABLE_TOTAL
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_EXPENSES
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_TOTAL
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_CARD
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_FEED
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_BANK_ACCOUNT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_WITHDRAWN
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_WITHDRAWAL_ID
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_CATEGORY
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_MERCHANT
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_TAG
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_MONTH
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_WEEK
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_YEAR
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_QUARTER
+ | typeof CONST.SEARCH.TABLE_COLUMNS.GROUP_WITHDRAWAL_ID;
+
+type SearchTransactionTextColumns = Extract>;
+
+type SearchExpenseReportTextColumns = Extract>;
+
+type SearchCardGroupingColumns = Extract;
+
+type SearchFromGroupingColumns = Extract;
+
+type SearchWithdrawalIDGroupingColumns = Extract;
+
+type SearchCategoryGroupingColumns = Extract;
+
+type SearchMerchantGroupingColumns = Extract;
+
+type SearchTagGroupingColumns = Extract;
+
+type SearchMonthGroupingColumns = Extract;
+
+type SearchWeekGroupingColumns = Extract;
+
+type SearchYearGroupingColumns = Extract;
+
+type SearchQuarterGroupingColumns = Extract;
+
type TransactionListItemType = ListItem &
Transaction & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Report to which the transaction belongs */
report: Report | undefined;
@@ -439,6 +515,12 @@ type TransactionGroupListItemType = ListItem & {
};
type TransactionReportGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT} & Report & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** The personal details of the user requesting money */
from: PersonalDetails;
@@ -514,11 +596,23 @@ type TransactionReportGroupListItemType = TransactionGroupListItemType & {groupe
type TransactionMemberGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.FROM} & PersonalDetails &
SearchMemberGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "from" value used for displaying and sorting */
formattedFrom?: string;
};
type TransactionMonthGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.MONTH} & SearchMonthGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "month" value used for displaying */
formattedMonth: string;
@@ -528,6 +622,12 @@ type TransactionMonthGroupListItemType = TransactionGroupListItemType & {grouped
type TransactionCardGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.CARD} & PersonalDetails &
SearchCardGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "cardName" value used for displaying and sorting */
formattedCardName?: string;
@@ -536,31 +636,67 @@ type TransactionCardGroupListItemType = TransactionGroupListItemType & {groupedB
};
type TransactionWithdrawalIDGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID} & SearchWithdrawalIDGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "withdrawalID" value used for displaying and sorting */
formattedWithdrawalID?: string;
};
type TransactionCategoryGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.CATEGORY} & SearchCategoryGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "category" value used for displaying and sorting */
formattedCategory?: string;
};
type TransactionMerchantGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.MERCHANT} & SearchMerchantGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "merchant" value used for displaying and sorting */
formattedMerchant?: string;
};
type TransactionTagGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.TAG} & SearchTagGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "tag" value used for displaying and sorting */
formattedTag?: string;
};
type TransactionWeekGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.WEEK} & SearchWeekGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "week" value used for displaying */
formattedWeek: string;
};
type TransactionYearGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.YEAR} & SearchYearGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "year" value used for displaying */
formattedYear: string;
@@ -569,6 +705,12 @@ type TransactionYearGroupListItemType = TransactionGroupListItemType & {groupedB
};
type TransactionQuarterGroupListItemType = TransactionGroupListItemType & {groupedBy: typeof CONST.SEARCH.GROUP_BY.QUARTER} & SearchQuarterGroup & {
+ /** The measurements for each column */
+ measurements: Record;
+
+ /** Formatted values for each column */
+ formattedValues: Record;
+
/** Final and formatted "quarter" value used for displaying */
formattedQuarter: string;
@@ -686,7 +828,6 @@ type TransactionListItemProps = ListItemProps & {
isLoading?: boolean;
columns?: SearchColumnType[];
violations?: Record | undefined;
- customCardNames?: Record;
/** Callback to fire when DEW modal should be opened */
onDEWModalOpen?: () => void;
/** Whether the DEW beta flag is enabled */
@@ -1260,4 +1401,17 @@ export type {
SortableColumnName,
SearchListItem,
UnreportedExpenseListItemType,
+ SearchTextColumns as TransactionTextColumns,
+ SearchTransactionTextColumns,
+ SearchExpenseReportTextColumns,
+ SearchCardGroupingColumns,
+ SearchFromGroupingColumns,
+ SearchWithdrawalIDGroupingColumns,
+ SearchCategoryGroupingColumns,
+ SearchMerchantGroupingColumns,
+ SearchTagGroupingColumns,
+ SearchMonthGroupingColumns,
+ SearchWeekGroupingColumns,
+ SearchYearGroupingColumns,
+ SearchQuarterGroupingColumns,
};
diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx
index 13a5de8f1debd..4826fe4cd2a0c 100644
--- a/src/components/TransactionItemRow/index.tsx
+++ b/src/components/TransactionItemRow/index.tsx
@@ -6,15 +6,15 @@ import Icon from '@components/Icon';
import type {TransactionWithOptionalHighlight} from '@components/MoneyRequestReportView/MoneyRequestReportTransactionList';
import {PressableWithFeedback} from '@components/Pressable';
import RadioButton from '@components/RadioButton';
-import type {SearchColumnType, TableColumnSize} from '@components/Search/types';
+import type {SearchColumnType} from '@components/Search/types';
import ActionCell from '@components/SelectionListWithSections/Search/ActionCell';
import DateCell from '@components/SelectionListWithSections/Search/DateCell';
import ExportedIconCell from '@components/SelectionListWithSections/Search/ExportedIconCell';
import StatusCell from '@components/SelectionListWithSections/Search/StatusCell';
import TextCell from '@components/SelectionListWithSections/Search/TextCell';
-import AmountCell from '@components/SelectionListWithSections/Search/TotalCell';
import UserInfoCell from '@components/SelectionListWithSections/Search/UserInfoCell';
import WorkspaceCell from '@components/SelectionListWithSections/Search/WorkspaceCell';
+import type {TransactionListItemType} from '@components/SelectionListWithSections/types';
import Text from '@components/Text';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
@@ -23,25 +23,17 @@ import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {isCategoryMissing} from '@libs/CategoryUtils';
-import getBase62ReportID from '@libs/getBase62ReportID';
import {getIOUActionForTransactionID} from '@libs/ReportActionsUtils';
-import {getReportName} from '@libs/ReportNameUtils';
-import {isExpenseReport, isIOUReport, isSettled} from '@libs/ReportUtils';
+import {isIOUReport, isSettled} from '@libs/ReportUtils';
import StringUtils from '@libs/StringUtils';
import {
getDescription,
- getExchangeRate,
getMerchant,
- getOriginalAmountForDisplay,
- getOriginalCurrencyForDisplay,
- getReimbursable,
- getTaxName,
getCreated as getTransactionCreated,
hasMissingSmartscanFields,
isAmountMissing,
isMerchantMissing,
isScanning,
- isTimeRequest,
isUnreportedAndHasInvalidDistanceRateTransaction,
} from '@libs/TransactionUtils';
import CONST from '@src/CONST';
@@ -53,7 +45,6 @@ import ChatBubbleCell from './DataCells/ChatBubbleCell';
import MerchantOrDescriptionCell from './DataCells/MerchantCell';
import ReceiptCell from './DataCells/ReceiptCell';
import TagCell from './DataCells/TagCell';
-import TaxCell from './DataCells/TaxCell';
import TotalCell from './DataCells/TotalCell';
import TypeCell from './DataCells/TypeCell';
import TransactionItemRowRBR from './TransactionItemRowRBR';
@@ -106,19 +97,12 @@ type TransactionWithOptionalSearchFields = TransactionWithOptionalHighlight & {
};
type TransactionItemRowProps = {
- transactionItem: TransactionWithOptionalSearchFields;
+ transactionItem: TransactionListItemType;
report?: Report;
policy?: Policy;
shouldUseNarrowLayout: boolean;
isSelected: boolean;
shouldShowTooltip: boolean;
- dateColumnSize: TableColumnSize;
- submittedColumnSize?: TableColumnSize;
- approvedColumnSize?: TableColumnSize;
- postedColumnSize?: TableColumnSize;
- exportedColumnSize?: TableColumnSize;
- amountColumnSize: TableColumnSize;
- taxAmountColumnSize: TableColumnSize;
onCheckboxPress?: (transactionID: string) => void;
shouldShowCheckbox?: boolean;
columns?: SearchColumnType[];
@@ -137,7 +121,6 @@ type TransactionItemRowProps = {
onArrowRightPress?: () => void;
isHover?: boolean;
shouldShowArrowRightOnNarrowLayout?: boolean;
- customCardNames?: Record;
reportActions?: ReportAction[];
checkboxSentryLabel?: string;
};
@@ -164,13 +147,6 @@ function TransactionItemRow({
shouldUseNarrowLayout,
isSelected,
shouldShowTooltip,
- dateColumnSize,
- submittedColumnSize,
- approvedColumnSize,
- postedColumnSize,
- exportedColumnSize,
- amountColumnSize,
- taxAmountColumnSize,
onCheckboxPress = () => {},
shouldShowCheckbox = false,
columns,
@@ -189,7 +165,6 @@ function TransactionItemRow({
onArrowRightPress,
isHover = false,
shouldShowArrowRightOnNarrowLayout,
- customCardNames,
reportActions,
checkboxSentryLabel,
}: TransactionItemRowProps) {
@@ -201,15 +176,10 @@ function TransactionItemRow({
const hasCategoryOrTag = !isCategoryMissing(transactionItem?.category) || !!transactionItem.tag;
const createdAt = getTransactionCreated(transactionItem);
const expensicons = useMemoizedLazyExpensifyIcons(['ArrowRight']);
- const transactionThreadReportID = reportActions ? getIOUActionForTransactionID(reportActions, transactionItem.transactionID)?.childReportID : undefined;
- const isDateColumnWide = dateColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
- const isSubmittedColumnWide = submittedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
- const isApprovedColumnWide = approvedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
- const isPostedColumnWide = postedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
- const isExportedColumnWide = exportedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
- const isAmountColumnWide = amountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
- const isTaxAmountColumnWide = taxAmountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE;
+ const measurements = transactionItem.measurements;
+ const formattedValues = transactionItem.formattedValues;
+ const transactionThreadReportID = reportActions ? getIOUActionForTransactionID(reportActions, transactionItem.transactionID)?.childReportID : undefined;
const bgActiveStyles = useMemo(() => {
if (!isSelected || !shouldHighlightItemWhenSelected) {
@@ -250,22 +220,6 @@ function TransactionItemRow({
}
}, [transactionItem, translate, report, policy]);
- const exchangeRateMessage = getExchangeRate(transactionItem);
-
- const cardName = useMemo(() => {
- if (transactionItem.isCardFeedDeleted) {
- return translate('workspace.companyCards.deletedFeed');
- }
- if (transactionItem.cardName === CONST.EXPENSE.TYPE.CASH_CARD_NAME) {
- return '';
- }
- const cardID = transactionItem.cardID;
- if (cardID && customCardNames?.[cardID]) {
- return customCardNames[cardID];
- }
- return transactionItem.cardName;
- }, [transactionItem.cardID, transactionItem.cardName, transactionItem.isCardFeedDeleted, customCardNames, translate]);
-
const renderColumn = (column: SearchColumnType): React.ReactNode => {
switch (column) {
case CONST.SEARCH.TABLE_COLUMNS.TYPE:
@@ -297,109 +251,81 @@ function TransactionItemRow({
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.DATE:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.SUBMITTED:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.APPROVED:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.POSTED:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.EXPORTED:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.CATEGORY:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE:
return (
- {getReimbursable(transactionItem) ? translate('common.yes') : translate('common.no')}
+
);
case CONST.SEARCH.TABLE_COLUMNS.BILLABLE:
return (
- {transactionItem.billable ? translate('common.yes') : translate('common.no')}
+
);
case CONST.SEARCH.TABLE_COLUMNS.ACTION:
@@ -429,31 +355,18 @@ function TransactionItemRow({
return (
- {!!merchant && (
-
- )}
+
);
case CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION:
return (
- {!!description && (
-
- )}
+
);
case CONST.SEARCH.TABLE_COLUMNS.TO:
@@ -464,8 +377,8 @@ function TransactionItemRow({
>
{!!transactionItem.to && (
)}
@@ -479,8 +392,8 @@ function TransactionItemRow({
>
{!!transactionItem.from && (
)}
@@ -490,9 +403,9 @@ function TransactionItemRow({
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.COMMENTS:
@@ -511,75 +424,63 @@ function TransactionItemRow({
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.REPORT_ID:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.TAX_RATE:
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT:
return (
- {isTimeRequest(transactionItem) ? null : (
-
- )}
+
);
case CONST.SEARCH.TABLE_COLUMNS.POLICY_NAME:
@@ -589,8 +490,8 @@ function TransactionItemRow({
style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.POLICY_NAME)]}
>
);
@@ -598,12 +499,9 @@ function TransactionItemRow({
return (
-
+
);
case CONST.SEARCH.TABLE_COLUMNS.STATUS:
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
index c5192dfdefb85..569ae8370c0e2 100644
--- a/src/libs/SearchUIUtils.ts
+++ b/src/libs/SearchUIUtils.ts
@@ -40,9 +40,11 @@ import type {
ListItem,
ReportActionListItemType,
SearchListItem,
+ SearchTransactionTextColumns,
TaskListItemType,
TransactionCardGroupListItemType,
TransactionCategoryGroupListItemType,
+ TransactionColumnMeasurements,
TransactionGroupListItemType,
TransactionListItemType,
TransactionMemberGroupListItemType,
@@ -91,9 +93,10 @@ import {setOptimisticDataForTransactionThreadPreview} from './actions/Search';
import type {CardFeedForDisplay} from './CardFeedUtils';
import {getCardFeedsForDisplay} from './CardFeedUtils';
import {doesCardFeedExist, getCardDescription, getFeedNameForDisplay} from './CardUtils';
-import {getDecodedCategoryName} from './CategoryUtils';
+import {getDecodedCategoryName, isCategoryMissing} from './CategoryUtils';
import {convertToDisplayString} from './CurrencyUtils';
import DateUtils from './DateUtils';
+import getBase62ReportID from './getBase62ReportID';
import interceptAnonymousUser from './interceptAnonymousUser';
import isSearchTopmostFullScreenRoute from './Navigation/helpers/isSearchTopmostFullScreenRoute';
import Navigation from './Navigation/Navigation';
@@ -111,6 +114,7 @@ import {
isResolvedActionableWhisper,
isWhisperActionTargetedToOthers,
} from './ReportActionsUtils';
+import {getReportName as getReportNameUtil} from './ReportNameUtils';
import {isExportAction} from './ReportPrimaryActionUtils';
import {
canDeleteMoneyRequestReport,
@@ -131,6 +135,7 @@ import {
isAllowedToApproveExpenseReport as isAllowedToApproveExpenseReportUtils,
isArchivedReport,
isClosedReport,
+ isExpenseReport,
isInvoiceReport,
isIOUReport as isIOUReportReportUtil,
isMoneyRequestReport,
@@ -144,11 +149,16 @@ import {buildCannedSearchQuery, buildQueryStringFromFilterFormValues, buildSearc
import StringUtils from './StringUtils';
import {getIOUPayerAndReceiver} from './TransactionPreviewUtils';
import {
+ getBillable,
getCategory,
+ getCurrency,
getDescription,
getExchangeRate,
getOriginalAmountForDisplay,
+ getOriginalCurrencyForDisplay,
+ getReimbursable,
getTag,
+ getTagForDisplay,
getTaxAmount,
getTaxName,
getAmount as getTransactionAmount,
@@ -156,6 +166,7 @@ import {
getMerchant as getTransactionMerchant,
isPending,
isScanning,
+ isTimeRequest,
isViolationDismissed,
} from './TransactionUtils';
import {isInvalidMerchantValue} from './ValidationUtils';
@@ -204,6 +215,7 @@ type GetTransactionSectionsParams = {
currentSearch: SearchKey;
currentAccountID: number;
currentUserEmail: string;
+ translate: LocalizedTranslate;
formatPhoneNumber: LocaleContextProps['formatPhoneNumber'];
isActionLoadingSet: ReadonlySet | undefined;
bankAccountList: OnyxEntry;
@@ -1111,7 +1123,7 @@ function getTransactionItemCommonFormattedProperties(
const formattedTo = formatPhoneNumber(toName);
const formattedTotal = getTransactionAmount(transactionItem, isExpenseReport);
- const date = transactionItem?.modifiedCreated ? transactionItem.modifiedCreated : transactionItem?.created;
+ const date = getTransactionCreatedDate(transactionItem);
const merchant = getTransactionMerchant(transactionItem);
const formattedMerchant = isInvalidMerchantValue(merchant) ? '' : merchant;
const submitted = report?.submitted;
@@ -1661,6 +1673,18 @@ function getToFieldValueForTransaction(
return emptyPersonalDetails;
}
+function getColumnWidthStyle(currentMaxWidth: number | undefined, columnValue: string | null | undefined): number {
+ const maxColumnWidthPx = 400;
+ // The actual average length, but lets add padding so we're more accurate, we'd
+ // rather go over the actual length, than under and have the text be cut off
+ const averageCharacterPxWithPadding = 8.45;
+ const columnValueCharLength = columnValue?.length ?? 0;
+
+ // The maximum amount of space the column would need for its longest value
+ const columnMaxWidth = Math.round(Math.min(maxColumnWidthPx, Math.max(currentMaxWidth ?? 0, columnValueCharLength * averageCharacterPxWithPadding)));
+ return columnMaxWidth;
+}
+
/**
* @private
* Organizes data into List Sections for display, for the TransactionListItemType of Search Results.
@@ -1672,6 +1696,7 @@ function getTransactionsSections({
currentSearch,
currentAccountID,
currentUserEmail,
+ translate,
formatPhoneNumber,
isActionLoadingSet,
bankAccountList,
@@ -1682,8 +1707,8 @@ function getTransactionsSections({
}: GetTransactionSectionsParams): [TransactionListItemType[], number] {
const shouldShowMerchant = getShouldShowMerchant(data);
const lastExportedActionByReportID = buildLastExportedActionByReportIDMap(data);
- const {shouldShowYearCreated, shouldShowYearSubmitted, shouldShowYearApproved, shouldShowYearPosted, shouldShowYearExported} = shouldShowYear(data, false, lastExportedActionByReportID);
const {shouldShowAmountInWideColumn, shouldShowTaxAmountInWideColumn} = getWideAmountIndicators(data);
+ const {shouldShowYearCreated, shouldShowYearSubmitted, shouldShowYearApproved, shouldShowYearPosted, shouldShowYearExported} = shouldShowYear(data, false, lastExportedActionByReportID);
// Pre-filter transaction keys to avoid repeated checks
const transactionKeys = Object.keys(data).filter(isTransactionEntry);
@@ -1698,91 +1723,215 @@ function getTransactionsSections({
// Use the provided queryJSON if available, otherwise fall back to getCurrentSearchQueryJSON()
const currentQueryJSON = queryJSON ?? getCurrentSearchQueryJSON();
+ const measurements = {} as Record;
for (const key of transactionKeys) {
- const transactionItem = data[key];
- const report = data[`${ONYXKEYS.COLLECTION.REPORT}${transactionItem.reportID}`];
+ const transaction = data[key];
+ const report = data[`${ONYXKEYS.COLLECTION.REPORT}${transaction.reportID}`];
+ const policy = data[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`];
+ const actions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transaction.reportID}`] ?? [];
+ const reportMetadata = allReportMetadata?.[`${ONYXKEYS.COLLECTION.REPORT_METADATA}${transaction.reportID}`] ?? {};
+
+ const reportAction = moneyRequestReportActionsByTransactionID.get(transaction.transactionID);
+ const isActionLoading = isActionLoadingSet?.has(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${transaction.reportID}`);
+ const allActions = getActions(data, allViolations, key, currentSearch, currentUserEmail, currentAccountID, bankAccountList, reportMetadata, actions);
- let shouldShow = true;
+ let shouldShowTransaction = !!transaction.transactionID;
- const isActionLoading = isActionLoadingSet?.has(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${transactionItem.reportID}`);
- if (currentQueryJSON && !isActionLoading) {
+ if (currentQueryJSON && !isActionLoading && shouldShowTransaction) {
if (currentQueryJSON.type === CONST.SEARCH.DATA_TYPES.EXPENSE) {
const status = currentQueryJSON.status;
if (Array.isArray(status)) {
- shouldShow = status.some((expenseStatus) => {
+ shouldShowTransaction = status.some((expenseStatus) => {
return isValidExpenseStatus(expenseStatus) ? expenseStatusActionMapping[expenseStatus](report) : false;
});
} else {
- shouldShow = isValidExpenseStatus(status) ? expenseStatusActionMapping[status](report) : false;
+ shouldShowTransaction = isValidExpenseStatus(status) ? expenseStatusActionMapping[status](report) : false;
}
}
}
- if (!transactionItem.transactionID) {
- shouldShow = false;
+ if (!shouldShowTransaction || !transaction) {
+ continue;
}
- if (shouldShow) {
- const reportAction = moneyRequestReportActionsByTransactionID.get(transactionItem.transactionID);
- const policy = data[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`];
- const shouldShowBlankTo = !report || isOpenExpenseReport(report);
- const transactionViolations = getTransactionViolations(allViolations, transactionItem, currentUserEmail, currentAccountID ?? CONST.DEFAULT_NUMBER_ID, report, policy);
- // Use Map.get() for faster lookups with default values
- const fromAccountID = reportAction?.actorAccountID ?? report?.ownerAccountID;
- const from = fromAccountID ? (personalDetailsMap.get(fromAccountID.toString()) ?? emptyPersonalDetails) : emptyPersonalDetails;
- const to = getToFieldValueForTransaction(transactionItem, report, data.personalDetailsList, reportAction);
- const isIOUReport = report?.type === CONST.REPORT.TYPE.IOU;
- // Check if the card feed has been deleted. If cardFeeds is still loading (undefined), return undefined to avoid showing incorrect state.
- const isCardFeedDeleted = cardFeeds === undefined ? undefined : !doesCardFeedExist(transactionItem.bank as OnyxTypes.CompanyCardFeed, cardFeeds);
+ const shouldShowBlankTo = !report || isOpenExpenseReport(report);
+ const transactionViolations = getTransactionViolations(allViolations, transaction, currentUserEmail, currentAccountID ?? CONST.DEFAULT_NUMBER_ID, report, policy);
- const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date, submitted, approved, posted} = getTransactionItemCommonFormattedProperties(
- transactionItem,
- from,
- to,
- policy,
- formatPhoneNumber,
- report,
- );
- const actions = reportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionItem.reportID}`] ?? [];
- const reportMetadata = allReportMetadata?.[`${ONYXKEYS.COLLECTION.REPORT_METADATA}${transactionItem.reportID}`] ?? {};
- const allActions = getActions(data, allViolations, key, currentSearch, currentUserEmail, currentAccountID, bankAccountList, reportMetadata, actions);
- const transactionSection: TransactionListItemType = {
- ...transactionItem,
- keyForList: transactionItem.transactionID,
- action: allActions.at(0) ?? CONST.SEARCH.ACTION_TYPES.VIEW,
- allActions,
- report,
- policy,
- reportAction,
- holdReportAction: holdReportActionsByTransactionID.get(transactionItem.transactionID),
- from,
- to,
- formattedFrom,
- formattedTo: shouldShowBlankTo ? '' : formattedTo,
- formattedTotal,
- formattedMerchant,
- isCardFeedDeleted,
- date,
- submitted,
- approved,
- posted,
- exported: transactionItem.reportID ? (lastExportedActionByReportID.get(transactionItem.reportID)?.created ?? '') : '',
- shouldShowMerchant,
- shouldShowYear: shouldShowYearCreated,
- shouldShowYearSubmitted,
- shouldShowYearApproved,
- shouldShowYearPosted,
- shouldShowYearExported,
- isAmountColumnWide: shouldShowAmountInWideColumn,
- isTaxAmountColumnWide: shouldShowTaxAmountInWideColumn,
- violations: transactionViolations,
- category: isIOUReport ? '' : transactionItem?.category,
- };
+ const fromAccountID = reportAction?.actorAccountID ?? report?.ownerAccountID;
+ const from = fromAccountID ? (personalDetailsMap.get(fromAccountID.toString()) ?? emptyPersonalDetails) : emptyPersonalDetails;
+ const to = getToFieldValueForTransaction(transaction, report, data.personalDetailsList, reportAction);
- transactionsSections.push(transactionSection);
- }
+ const isIOUReport = report?.type === CONST.REPORT.TYPE.IOU;
+ const isCardFeedDeleted = cardFeeds === undefined ? undefined : !doesCardFeedExist(transaction.bank as OnyxTypes.CompanyCardFeed, cardFeeds);
+
+ const {formattedFrom, formattedTo, formattedTotal, formattedMerchant, date, submitted, approved, posted} = getTransactionItemCommonFormattedProperties(
+ transaction,
+ from,
+ to,
+ policy,
+ formatPhoneNumber,
+ report,
+ );
+
+ // Compute the maximum size of all of the text fields to determine how much space we need to delegate
+ // Handle the merchant
+ measurements[CONST.SEARCH.TABLE_COLUMNS.MERCHANT] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.MERCHANT], formattedMerchant);
+
+ // Handle the category
+ const formattedCategory = isCategoryMissing(transaction?.category) ? '' : getDecodedCategoryName(transaction?.category ?? '');
+ measurements[CONST.SEARCH.TABLE_COLUMNS.CATEGORY] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.CATEGORY], formattedCategory);
+
+ // Handle the tag
+ const formattedTag = getTagForDisplay(transaction);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.TAG] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.TAG], formattedTag);
+
+ // Handle the amount
+ const transactionCurrency = getOriginalCurrencyForDisplay(transaction);
+ const transactionDisplayAmount = getOriginalAmountForDisplay(transaction, isExpenseReport(report));
+ const formattedAmount = convertToDisplayString(transactionDisplayAmount, transactionCurrency);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT], formattedAmount);
+
+ // Handle the exchange rate
+ const formattedExchangeRate = getExchangeRate(transaction);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.EXCHANGE_RATE] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.EXCHANGE_RATE], formattedExchangeRate);
+
+ // Handle the description
+ const formattedDescription = getDescription(transaction);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION], formattedDescription);
+
+ // Handle the card
+ // JACK_TODO: This is missing customCardNames but it doesnt matter for now
+ const deletedFeedCardName = isCardFeedDeleted ? translate('workspace.companyCards.deletedFeed') : null;
+ const cashCardName = transaction.cardName === CONST.EXPENSE.TYPE.CASH_CARD_NAME ? '' : null;
+ const formattedCardName = deletedFeedCardName ?? cashCardName ?? transaction.cardName ?? '';
+ measurements[CONST.SEARCH.TABLE_COLUMNS.CARD] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.CARD], formattedCardName);
+
+ // Handle the billable
+ const formattedBillable = getBillable(transaction) ? translate('common.yes') : translate('common.no');
+ measurements[CONST.SEARCH.TABLE_COLUMNS.BILLABLE] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.BILLABLE], formattedBillable);
+
+ // Handle the reimbursable
+ const formattedReimbursable = getReimbursable(transaction) ? translate('common.yes') : translate('common.no');
+ measurements[CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE], formattedReimbursable);
+
+ // Handle the title
+ const formattedTitle = getReportNameUtil(report);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.TITLE] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.TITLE], formattedTitle);
+
+ // Handle the tax rate
+ const formattedTaxRate = !isTimeRequest(transaction) ? (getTaxName(policy, transaction) ?? transaction.taxValue ?? '') : '';
+ measurements[CONST.SEARCH.TABLE_COLUMNS.TAX_RATE] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.TAX_RATE], formattedTaxRate);
+
+ // Handle the tax
+ const transactionTaxAmount = getTaxAmount(transaction, true);
+ const transactionTaxAmountCurrency = getCurrency(transaction);
+ const formattedTaxAmount = !isTimeRequest(transaction) ? convertToDisplayString(transactionTaxAmount, transactionTaxAmountCurrency) : '';
+ measurements[CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT], formattedTaxAmount);
+
+ // Handle the report ID
+ const formattedReportID = transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID ? '' : (transaction.reportID?.toString() ?? '');
+ measurements[CONST.SEARCH.TABLE_COLUMNS.REPORT_ID] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.REPORT_ID], formattedReportID);
+
+ // Handle the base62 report ID
+ const formattedBase62ReportID = transaction.reportID === CONST.REPORT.UNREPORTED_REPORT_ID ? '' : getBase62ReportID(Number(transaction.reportID));
+ measurements[CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID], formattedBase62ReportID);
+
+ // Handle the original amount
+ const originalAmountTotal = getOriginalAmountForDisplay(transaction, isExpenseReport(report));
+ const originalAmountCurrency = getOriginalCurrencyForDisplay(transaction);
+ const formattedOriginalAmount = convertToDisplayString(originalAmountTotal, originalAmountCurrency);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT], formattedOriginalAmount);
+
+ // Handle the date
+ const createdDate = date ?? '';
+ const isCreatedLastYear = DateUtils.doesDateBelongToAPastYear(createdDate);
+ const formattedDate = DateUtils.formatWithUTCTimeZone(createdDate, isCreatedLastYear ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.DATE] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.DATE], formattedDate);
+
+ // Handle exported date
+ const exportDate = transaction.reportID ? (lastExportedActionByReportID.get(transaction.reportID)?.created ?? '') : '';
+ const isExportedLastYear = DateUtils.doesDateBelongToAPastYear(exportDate);
+ const formattedExportDate = DateUtils.formatWithUTCTimeZone(exportDate, isExportedLastYear ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.EXPORTED] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.EXPORTED], formattedExportDate);
+
+ // Handle submitted date
+ const submittedDate = report.submitted ?? '';
+ const isSubmittedLastYear = DateUtils.doesDateBelongToAPastYear(submittedDate);
+ const formattedSubmittedDate = DateUtils.formatWithUTCTimeZone(submittedDate, isSubmittedLastYear ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.SUBMITTED] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.SUBMITTED], formattedSubmittedDate);
+
+ // Handle approved date
+ const approvedDate = report.approved ?? '';
+ const isApprovedLastYear = DateUtils.doesDateBelongToAPastYear(approvedDate);
+ const formattedApprovedDate = DateUtils.formatWithUTCTimeZone(approvedDate, isApprovedLastYear ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.APPROVED] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.APPROVED], formattedApprovedDate);
+
+ // Handle posted date
+ const postedDate = posted ?? '';
+ const isPostedLastYear = DateUtils.doesDateBelongToAPastYear(postedDate);
+ const formattedPostedDate = DateUtils.formatWithUTCTimeZone(postedDate, isPostedLastYear ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT);
+ measurements[CONST.SEARCH.TABLE_COLUMNS.POSTED] = getColumnWidthStyle(measurements[CONST.SEARCH.TABLE_COLUMNS.POSTED], formattedPostedDate);
+
+ const transactionSection: TransactionListItemType = {
+ ...transaction,
+ measurements,
+ formattedValues: {
+ [CONST.SEARCH.TABLE_COLUMNS.DATE]: formattedDate,
+ [CONST.SEARCH.TABLE_COLUMNS.MERCHANT]: formattedMerchant,
+ [CONST.SEARCH.TABLE_COLUMNS.CATEGORY]: formattedCategory,
+ [CONST.SEARCH.TABLE_COLUMNS.TAG]: formattedTag,
+ [CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT]: formattedAmount,
+ [CONST.SEARCH.TABLE_COLUMNS.EXCHANGE_RATE]: formattedExchangeRate,
+ [CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION]: formattedDescription,
+ [CONST.SEARCH.TABLE_COLUMNS.CARD]: formattedCardName,
+ [CONST.SEARCH.TABLE_COLUMNS.BILLABLE]: formattedBillable,
+ [CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE]: formattedReimbursable,
+ [CONST.SEARCH.TABLE_COLUMNS.TITLE]: formattedTitle,
+ [CONST.SEARCH.TABLE_COLUMNS.TAX_RATE]: formattedTaxRate,
+ [CONST.SEARCH.TABLE_COLUMNS.TAX_AMOUNT]: formattedTaxAmount,
+ [CONST.SEARCH.TABLE_COLUMNS.REPORT_ID]: formattedReportID,
+ [CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID]: formattedBase62ReportID,
+ [CONST.SEARCH.TABLE_COLUMNS.ORIGINAL_AMOUNT]: formattedOriginalAmount,
+ [CONST.SEARCH.TABLE_COLUMNS.EXPORTED]: formattedExportDate,
+ [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: formattedSubmittedDate,
+ [CONST.SEARCH.TABLE_COLUMNS.APPROVED]: formattedApprovedDate,
+ [CONST.SEARCH.TABLE_COLUMNS.POSTED]: formattedPostedDate,
+ },
+ keyForList: transaction.transactionID,
+ action: allActions.at(0) ?? CONST.SEARCH.ACTION_TYPES.VIEW,
+ allActions,
+ report,
+ policy,
+ reportAction,
+ holdReportAction: holdReportActionsByTransactionID.get(transaction.transactionID),
+ from,
+ to,
+ formattedFrom,
+ formattedTo: shouldShowBlankTo ? '' : formattedTo,
+ formattedTotal,
+ formattedMerchant,
+ isCardFeedDeleted,
+ date,
+ submitted,
+ approved,
+ posted,
+ exported: transaction.reportID ? (lastExportedActionByReportID.get(transaction.reportID)?.created ?? '') : '',
+ shouldShowMerchant,
+ shouldShowYear: shouldShowYearCreated,
+ shouldShowYearSubmitted,
+ shouldShowYearApproved,
+ shouldShowYearPosted,
+ shouldShowYearExported,
+ isAmountColumnWide: shouldShowAmountInWideColumn,
+ isTaxAmountColumnWide: shouldShowTaxAmountInWideColumn,
+ violations: transactionViolations,
+ category: isIOUReport ? '' : transaction?.category,
+ };
+
+ transactionsSections.push(transactionSection);
}
+
return [transactionsSections, transactionsSections.length];
}
@@ -2966,6 +3115,7 @@ function getSections({
return getTransactionsSections({
data,
+ translate,
currentSearch,
currentAccountID,
currentUserEmail,