Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,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(
Expand Down Expand Up @@ -1402,6 +1416,7 @@ function Search({
!shouldShowTableHeader ? undefined : (
<View style={[!isTask && styles.pr8, styles.flex1]}>
<SearchTableHeader
measurements={measurements}
canSelectMultiple={canSelectMultiple}
columns={columnsToShow}
type={type}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ function TransactionListItem<TItem extends ListItem>({
columns,
isLoading,
violations,
customCardNames,
onDEWModalOpen,
isDEWBetaEnabled,
lastPaymentMethod,
Expand Down Expand Up @@ -110,14 +109,6 @@ function TransactionListItem<TItem extends ListItem>({
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
Expand Down Expand Up @@ -217,20 +208,12 @@ function TransactionListItem<TItem extends ListItem>({
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}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -422,6 +422,7 @@ function getSearchColumns(type: ValueOf<typeof CONST.SEARCH.DATA_TYPES>, icons:
}

type SearchTableHeaderProps = {
measurements?: TransactionColumnMeasurements;
columns: SortableColumnName[];
type: SearchDataTypes;
sortBy?: SearchColumnType;
Expand All @@ -445,6 +446,7 @@ type SearchTableHeaderProps = {
function SearchTableHeader({
columns,
type,
measurements,
sortBy,
sortOrder,
onSortPress,
Expand Down Expand Up @@ -517,6 +519,7 @@ function SearchTableHeader({

return (
<SortableTableHeader
measurements={measurements}
columns={orderedColumnConfig}
shouldShowColumn={shouldShowColumn}
dateColumnSize={shouldShowYear ? CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE : CONST.SEARCH.TABLE_COLUMN_SIZES.NORMAL}
Expand Down
34 changes: 20 additions & 14 deletions src/components/SelectionListWithSections/SortableTableHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type IconAsset from '@src/types/utils/IconAsset';
import SortableHeaderText from './SortableHeaderText';
import type {SortableColumnName} from './types';
import type {SortableColumnName, TransactionColumnMeasurements, TransactionTextColumns} from './types';

type ColumnConfig = {
columnName: SearchColumnType;
Expand All @@ -20,6 +20,7 @@ type ColumnConfig = {
};

type SearchTableHeaderProps = {
measurements?: TransactionColumnMeasurements;
columns: ColumnConfig[];
sortBy?: SortableColumnName;
sortOrder?: SortOrder;
Expand All @@ -38,6 +39,7 @@ type SearchTableHeaderProps = {
};

function SortableTableHeader({
measurements,
columns,
sortBy,
sortOrder,
Expand Down Expand Up @@ -70,6 +72,22 @@ function SortableTableHeader({
const isActive = sortBy === columnName;
const textStyle = columnName === CONST.SEARCH.TABLE_COLUMNS.RECEIPT ? StyleUtils.getTextOverflowStyle('clip') : null;

const shouldUseMeasurement = measurements && columnName in measurements;

const containerStyle = shouldUseMeasurement
? {width: measurements[columnName as TransactionTextColumns]}
: StyleUtils.getReportTableColumnStyles(
columnName,
dateColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
amountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
taxAmountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
submittedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
approvedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
postedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
exportedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
shouldRemoveTotalColumnFlex,
);

return (
<SortableHeaderText
key={columnName}
Expand All @@ -79,19 +97,7 @@ function SortableTableHeader({
sortOrder={sortOrder ?? CONST.SEARCH.SORT_ORDER.ASC}
isActive={isActive}
sentryLabel={CONST.SENTRY_LABEL.SEARCH.SORTABLE_HEADER}
containerStyle={[
StyleUtils.getReportTableColumnStyles(
columnName,
dateColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
amountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
taxAmountColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
submittedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
approvedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
postedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
exportedColumnSize === CONST.SEARCH.TABLE_COLUMN_SIZES.WIDE,
shouldRemoveTotalColumnFlex,
),
]}
containerStyle={containerStyle}
isSortable={isSortable}
onPress={(order: SortOrder) => onSortPress(columnName, order)}
/>
Expand Down
34 changes: 33 additions & 1 deletion src/components/SelectionListWithSections/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,39 @@ type ListItem<K extends string | number = string> = {
isIndeterminate?: boolean;
};

// Columns that are shown in plain text
type TransactionTextColumns =
| 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;

type TransactionColumnMeasurements = Record<TransactionTextColumns, number>;

type TransactionListItemType = ListItem &
Transaction & {
/** The measurements for each column */
measurements: TransactionColumnMeasurements;

/** Formatted values for each column */
formattedValues: Record<TransactionTextColumns, string>;

/** Report to which the transaction belongs */
report: Report | undefined;

Expand Down Expand Up @@ -673,7 +704,6 @@ type TransactionListItemProps<TItem extends ListItem> = ListItemProps<TItem> & {
isLoading?: boolean;
columns?: SearchColumnType[];
violations?: Record<string, TransactionViolations | undefined> | undefined;
customCardNames?: Record<number, string>;
/** Callback to fire when DEW modal should be opened */
onDEWModalOpen?: () => void;
/** Whether the DEW beta flag is enabled */
Expand Down Expand Up @@ -1247,4 +1277,6 @@ export type {
SortableColumnName,
SearchListItem,
UnreportedExpenseListItemType,
TransactionColumnMeasurements,
TransactionTextColumns,
};
Loading
Loading