From 4c6c2153f67e74f25b0f8d8cfd525c2224fb0f8a Mon Sep 17 00:00:00 2001
From: Jan Nowakowski <janeknowakowski9@gmail.com>
Date: Thu, 16 Apr 2026 12:04:00 +0200
Subject: [PATCH] Fix undeleted action width

---
 .../ListItem/TransactionListItem.tsx          |  1 +
 .../Search/SearchList/ListItem/types.ts       |  5 +++
 src/components/Search/SearchList/index.tsx    |  6 ++-
 src/components/Search/SearchTableHeader.tsx   |  6 ++-
 src/components/Search/index.tsx               |  5 +++
 src/components/TransactionItemRow/index.tsx   |  4 +-
 src/libs/SearchUIUtils.ts                     | 37 ++++++++++++++++++-
 7 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/src/components/Search/SearchList/ListItem/TransactionListItem.tsx b/src/components/Search/SearchList/ListItem/TransactionListItem.tsx
index 34f06bcd0231..f30b58b25ac8 100644
--- a/src/components/Search/SearchList/ListItem/TransactionListItem.tsx
+++ b/src/components/Search/SearchList/ListItem/TransactionListItem.tsx
@@ -252,6 +252,7 @@ function TransactionListItem<TItem extends ListItem>({
                             exportedColumnSize={exportedColumnSize}
                             amountColumnSize={amountColumnSize}
                             taxAmountColumnSize={taxAmountColumnSize}
+                            isActionColumnWide={transactionItem.isActionColumnWide}
                             shouldShowCheckbox={!!canSelectMultiple}
                             checkboxSentryLabel={CONST.SENTRY_LABEL.SEARCH.TRANSACTION_LIST_ITEM_CHECKBOX}
                             style={[styles.p3, styles.pv2, shouldUseNarrowLayout ? styles.pt2 : isLargeScreenWidth && styles.noBorderRadius]}
diff --git a/src/components/Search/SearchList/ListItem/types.ts b/src/components/Search/SearchList/ListItem/types.ts
index 4de4bc9adbbc..3792f70b022f 100644
--- a/src/components/Search/SearchList/ListItem/types.ts
+++ b/src/components/Search/SearchList/ListItem/types.ts
@@ -160,6 +160,11 @@ type TransactionListItemType = ListItem &
 
         isTaxAmountColumnWide: boolean;
 
+        /** Whether the action column should use its wider variant.
+         * This is true if at least one transaction in the dataset is deleted.
+         */
+        isActionColumnWide: boolean;
+
         /** Key used internally by React */
         keyForList: string;
 
diff --git a/src/components/Search/SearchList/index.tsx b/src/components/Search/SearchList/index.tsx
index 6968b8647ddb..050b1968af88 100644
--- a/src/components/Search/SearchList/index.tsx
+++ b/src/components/Search/SearchList/index.tsx
@@ -134,6 +134,9 @@ type SearchListProps = Pick<FlashListProps<SearchListItem>, 'onScroll' | 'conten
     /** Whether all transactions have been loaded from snapshots in group-by views */
     hasLoadedAllTransactions?: boolean;
 
+    /** Whether the action column should use its wider variant (e.g. when there is at least one deleted transaction) */
+    isActionColumnWide?: boolean;
+
     /** Reference to the outer element */
     ref?: ForwardedRef<SearchListHandle>;
 };
@@ -218,6 +221,7 @@ function SearchList({
     nonPersonalAndWorkspaceCards,
     selectedTransactions,
     hasLoadedAllTransactions,
+    isActionColumnWide,
     ref,
 }: SearchListProps) {
     const styles = useThemeStyles();
@@ -332,7 +336,7 @@ function SearchList({
     }, [data, groupBy, newTransactions]);
 
     const {windowWidth} = useWindowDimensions();
-    const minTableWidth = getTableMinWidth(columns, queryJSON.type);
+    const minTableWidth = getTableMinWidth(columns, queryJSON.type, isActionColumnWide);
     const shouldScrollHorizontally = !!SearchTableHeader && minTableWidth > windowWidth;
 
     const horizontalScrollViewRef = useRef<RNScrollView>(null);
diff --git a/src/components/Search/SearchTableHeader.tsx b/src/components/Search/SearchTableHeader.tsx
index 0cdffe589a17..10a0f9fe9239 100644
--- a/src/components/Search/SearchTableHeader.tsx
+++ b/src/components/Search/SearchTableHeader.tsx
@@ -448,6 +448,9 @@ type SearchTableHeaderProps = {
 
     /** True when we are inside an expense report view, false if we're in the Reports page. */
     isExpenseReportView?: boolean;
+
+    /** True when the action column should render in its wider variant (e.g. tasks, deleted expenses). */
+    isActionColumnWide?: boolean;
 };
 
 function SearchTableHeader({
@@ -468,6 +471,7 @@ function SearchTableHeader({
     isTaxAmountColumnWide,
     groupBy,
     isExpenseReportView,
+    isActionColumnWide,
 }: SearchTableHeaderProps) {
     const styles = useThemeStyles();
     // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
@@ -540,7 +544,7 @@ function SearchTableHeader({
             sortBy={sortBy}
             sortOrder={sortOrder}
             shouldRemoveTotalColumnFlex={!!groupBy !== !!isExpenseReportView}
-            isActionColumnWide={type === CONST.SEARCH.DATA_TYPES.TASK}
+            isActionColumnWide={isActionColumnWide ?? type === CONST.SEARCH.DATA_TYPES.TASK}
             // Don't butt up against the 'select all' checkbox if present
             containerStyles={canSelectMultiple && [styles.pl3]}
             onSortPress={(columnName, order) => {
diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx
index 748fbde53cc5..9499bb62b50e 100644
--- a/src/components/Search/index.tsx
+++ b/src/components/Search/index.tsx
@@ -43,6 +43,7 @@ import {
     getSortedSections,
     getValidGroupBy,
     getWideAmountIndicators,
+    hasDeletedTransactionInData,
     isGroupedItemArray,
     isReportActionListItemType,
     isSearchDataLoaded,
@@ -1488,6 +1489,8 @@ function Search({
         [searchResults?.data],
     );
 
+    const hasDeletedTransaction = useMemo(() => (searchResults?.data ? hasDeletedTransactionInData(searchResults.data) : false), [searchResults?.data]);
+
     const onSortPress = useCallback(
         (column: SearchColumnType, order: SortOrder) => {
             clearSelectedTransactions();
@@ -1652,6 +1655,7 @@ function Search({
                                     shouldShowSorting
                                     groupBy={validGroupBy}
                                     isExpenseReportView={isExpenseReportType}
+                                    isActionColumnWide={isTask || hasDeletedTransaction}
                                 />
                             </View>
                         )
@@ -1683,6 +1687,7 @@ function Search({
                     newTransactions={newTransactions}
                     hasLoadedAllTransactions={hasLoadedAllTransactions}
                     nonPersonalAndWorkspaceCards={nonPersonalAndWorkspaceCards}
+                    isActionColumnWide={isTask || hasDeletedTransaction}
                 />
             </Animated.View>
         </SearchScopeProvider>
diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx
index 27dbb04f162c..36e8f1d5957a 100644
--- a/src/components/TransactionItemRow/index.tsx
+++ b/src/components/TransactionItemRow/index.tsx
@@ -145,6 +145,7 @@ type TransactionItemRowProps = {
     checkboxSentryLabel?: string;
     isLargeScreenWidth?: boolean;
     nonPersonalAndWorkspaceCards?: CardList;
+    isActionColumnWide?: boolean;
 };
 
 const EMPTY_ACTIVE_STYLE: StyleProp<ViewStyle> = [];
@@ -198,6 +199,7 @@ function TransactionItemRow({
     checkboxSentryLabel,
     nonPersonalAndWorkspaceCards = {},
     isLargeScreenWidth: isLargeScreenWidthProp,
+    isActionColumnWide: isActionColumnWideProp,
 }: TransactionItemRowProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
@@ -412,7 +414,7 @@ function TransactionItemRow({
                 return (
                     <View
                         key={column}
-                        style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.ACTION)]}
+                        style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.ACTION, {isActionColumnWide: isActionColumnWideProp ?? isDeletedTransaction})]}
                     >
                         {!!transactionItem.action && (
                             <ActionCell
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
index 1e58e60c33b2..c376eb9cb51c 100644
--- a/src/libs/SearchUIUtils.ts
+++ b/src/libs/SearchUIUtils.ts
@@ -1395,6 +1395,28 @@ function getWideAmountIndicators(data: TransactionListItemType[] | TransactionGr
     };
 }
 
+function hasDeletedTransactionInData(data: TransactionListItemType[] | TransactionGroupListItemType[] | TaskListItemType[] | OnyxTypes.SearchResults['data']): boolean {
+    if (Array.isArray(data)) {
+        return data.some((item) => {
+            if (isTransactionGroupListItemType(item)) {
+                return item.transactions.some((transaction) => transaction.reportID === CONST.REPORT.TRASH_REPORT_ID);
+            }
+            if (isTransactionListItemType(item)) {
+                return item.reportID === CONST.REPORT.TRASH_REPORT_ID;
+            }
+            return false;
+        });
+    }
+
+    return Object.keys(data).some((key) => {
+        if (isTransactionEntry(key)) {
+            const item = data[key];
+            return item?.reportID === CONST.REPORT.TRASH_REPORT_ID;
+        }
+        return false;
+    });
+}
+
 type ShouldShowYearResult = {
     shouldShowYearCreated: boolean;
     shouldShowYearSubmitted: boolean;
@@ -1729,6 +1751,7 @@ type PreprocessingContext = {
     shouldShowYearExportedReport: boolean;
     shouldShowAmountInWideColumn: boolean;
     shouldShowTaxAmountInWideColumn: boolean;
+    hasDeletedTransaction: boolean;
     currentYear: number;
 };
 
@@ -1754,6 +1777,7 @@ function createPreprocessingContext(): PreprocessingContext {
         shouldShowYearExportedReport: false,
         shouldShowAmountInWideColumn: false,
         shouldShowTaxAmountInWideColumn: false,
+        hasDeletedTransaction: false,
         currentYear: new Date().getFullYear(),
     };
 }
@@ -1837,6 +1861,9 @@ function processTransactionEntry(ctx: PreprocessingContext, transaction: OnyxTyp
     if (!ctx.shouldShowTaxAmountInWideColumn) {
         ctx.shouldShowTaxAmountInWideColumn = isTransactionTaxAmountTooLong(transaction);
     }
+    if (!ctx.hasDeletedTransaction) {
+        ctx.hasDeletedTransaction = transaction.reportID === CONST.REPORT.TRASH_REPORT_ID;
+    }
 
     if (!ctx.shouldShowYearCreated) {
         const transactionCreated = getTransactionCreatedDate(transaction);
@@ -2038,6 +2065,7 @@ function getTransactionsSections({
         shouldShowYearExported,
         shouldShowAmountInWideColumn,
         shouldShowTaxAmountInWideColumn,
+        hasDeletedTransaction,
     } = classifyAndPreprocess(data);
 
     const personalDetailsMap = new Map(Object.entries(data.personalDetailsList ?? {}));
@@ -2122,6 +2150,7 @@ function getTransactionsSections({
                 shouldShowYearExported,
                 isAmountColumnWide: shouldShowAmountInWideColumn,
                 isTaxAmountColumnWide: shouldShowTaxAmountInWideColumn,
+                isActionColumnWide: hasDeletedTransaction,
                 violations: transactionViolations,
                 category: isIOUReport ? '' : transactionItem?.category,
                 errors: undefined,
@@ -2623,6 +2652,7 @@ function getReportSections({
         shouldShowYearExportedReport,
         shouldShowAmountInWideColumn,
         shouldShowTaxAmountInWideColumn,
+        hasDeletedTransaction,
     } = classifyAndPreprocess(data);
 
     const currentQueryJSON = queryJSON ?? getCurrentSearchQueryJSON();
@@ -2721,6 +2751,7 @@ function getReportSections({
                     nonReimbursableSpend,
                     reimbursableSpend,
                     isAmountColumnWide: shouldShowAmountInWideColumn,
+                    isActionColumnWide: hasDeletedTransaction,
                     isAllScanning: false,
                     ...avatarProps,
                 };
@@ -2781,6 +2812,7 @@ function getReportSections({
                 violations: transactionViolations,
                 isAmountColumnWide: shouldShowAmountInWideColumn,
                 isTaxAmountColumnWide: shouldShowTaxAmountInWideColumn,
+                isActionColumnWide: hasDeletedTransaction,
                 category: isIOUReport ? '' : transactionItem?.category,
                 errors: undefined,
             };
@@ -5579,7 +5611,7 @@ function getTransactionFromTransactionListItem(item: TransactionListItemType): O
     return transaction as OnyxTypes.Transaction;
 }
 
-function getTableMinWidth(columns: SearchColumnType[], type?: SearchDataTypes) {
+function getTableMinWidth(columns: SearchColumnType[], type?: SearchDataTypes, isActionColumnWide?: boolean) {
     // Starts at 24px to account for the checkbox width
     let minWidth = 24;
 
@@ -5593,7 +5625,7 @@ function getTableMinWidth(columns: SearchColumnType[], type?: SearchDataTypes) {
         } else if (column === CONST.SEARCH.TABLE_COLUMNS.STATUS) {
             minWidth += 80;
         } else if (column === CONST.SEARCH.TABLE_COLUMNS.ACTION) {
-            minWidth += type === CONST.SEARCH.DATA_TYPES.TASK ? 80 : 68;
+            minWidth += (isActionColumnWide ?? type === CONST.SEARCH.DATA_TYPES.TASK) ? 80 : 68;
         } else if (column === CONST.SEARCH.TABLE_COLUMNS.DATE) {
             minWidth += 48;
         } else if (
@@ -5826,6 +5858,7 @@ export {
     getCurrencyOptions,
     getFeedOptions,
     getWideAmountIndicators,
+    hasDeletedTransactionInData,
     isTransactionAmountTooLong,
     isTransactionTaxAmountTooLong,
     getDatePresets,
