From 3ffa907dae15d8b298a0c69260e3aaf8f434c806 Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Mon, 6 May 2024 13:46:00 +0200
Subject: [PATCH 01/11] Add dynamic columns

---
 src/CONST.ts                                  |  6 ++++++
 src/components/Search.tsx                     |  3 +--
 .../SelectionList/SearchTableHeader.tsx       | 21 ++++++++++++++++---
 .../SelectionList/TransactionListItem.tsx     | 20 +++++++++++++++++-
 src/components/SelectionList/types.ts         |  6 ++++++
 src/libs/SearchUtils.ts                       | 11 +++++++++-
 src/styles/utils/index.ts                     |  6 ++----
 src/types/onyx/SearchResults.ts               |  2 ++
 8 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/src/CONST.ts b/src/CONST.ts
index 566d5179f86a..d2bc9f266dcc 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -924,10 +924,16 @@ const CONST = {
         MERCHANT: 'merchant',
         FROM: 'from',
         TO: 'to',
+        CATEGORY: 'category',
+        TAG: 'tag',
         TOTAL: 'total',
         TYPE: 'type',
         ACTION: 'action',
     },
+    SEARCH_TABLE_OPTIONAL_COLUMNS: {
+        CATEGORY: 'category',
+        TAG: 'tag',
+    },
     PRIORITY_MODE: {
         GSD: 'gsd',
         DEFAULT: 'default',
diff --git a/src/components/Search.tsx b/src/components/Search.tsx
index d8d3160a2633..a90ddc8d96fd 100644
--- a/src/components/Search.tsx
+++ b/src/components/Search.tsx
@@ -57,11 +57,10 @@ function Search({query}: SearchProps) {
 
     const ListItem = SearchUtils.getListItem();
     const data = SearchUtils.getSections(searchResults?.data ?? {});
-    const shouldShowMerchant = SearchUtils.getShouldShowMerchant(searchResults?.data ?? {});
 
     return (
         <SelectionList
-            customListHeader={<SearchTableHeader shouldShowMerchant={shouldShowMerchant} />}
+            customListHeader={<SearchTableHeader data={searchResults?.data} />}
             ListItem={ListItem}
             sections={[{data, isDisabled: false}]}
             onSelectRow={(item) => {
diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx
index 02986f22dccc..0fcec85f3833 100644
--- a/src/components/SelectionList/SearchTableHeader.tsx
+++ b/src/components/SelectionList/SearchTableHeader.tsx
@@ -5,20 +5,25 @@ import useLocalize from '@hooks/useLocalize';
 import useStyleUtils from '@hooks/useStyleUtils';
 import useThemeStyles from '@hooks/useThemeStyles';
 import useWindowDimensions from '@hooks/useWindowDimensions';
+import * as SearchUtils from '@libs/SearchUtils';
 import CONST from '@src/CONST';
+import type * as OnyxTypes from '@src/types/onyx';
 
 type SearchTableHeaderProps = {
-    /** Whether we should show the merchant or description column */
-    shouldShowMerchant: boolean;
+    data: OnyxTypes.SearchResults['data'];
 };
 
-function SearchTableHeader({shouldShowMerchant}: SearchTableHeaderProps) {
+function SearchTableHeader({data}: SearchTableHeaderProps) {
     const styles = useThemeStyles();
     const StyleUtils = useStyleUtils();
     const {isSmallScreenWidth, isMediumScreenWidth} = useWindowDimensions();
     const {translate} = useLocalize();
     const displayNarrowVersion = isMediumScreenWidth || isSmallScreenWidth;
 
+    const shouldShowCategoryColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.CATEGORY);
+    const shouldShowTagColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.TAG);
+    const shouldShowMerchant = SearchUtils.getShouldShowMerchant(data);
+
     if (displayNarrowVersion) {
         return;
     }
@@ -38,6 +43,16 @@ function SearchTableHeader({shouldShowMerchant}: SearchTableHeaderProps) {
                 <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TO)]}>
                     <Text style={[styles.mutedNormalTextLabel]}>{translate('common.to')}</Text>
                 </View>
+                {shouldShowCategoryColumn && (
+                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>
+                        <Text style={[styles.mutedNormalTextLabel]}>{translate('common.category')}</Text>
+                    </View>
+                )}
+                {shouldShowTagColumn && (
+                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAG)]}>
+                        <Text style={[styles.mutedNormalTextLabel]}>{translate('common.tag')}</Text>
+                    </View>
+                )}
                 <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}>
                     <Text style={[styles.mutedNormalTextLabel]}>{translate('common.total')}</Text>
                 </View>
diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index 0965ce6dabce..17c16229915d 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -108,6 +108,22 @@ function TransactionListItem<TItem extends ListItem>({
         );
     };
 
+    const categoryCell = (
+        <TextWithTooltip
+            shouldShowTooltip={showTooltip}
+            text={transactionItem?.category}
+            style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter]}
+        />
+    );
+
+    const tagCell = (
+        <TextWithTooltip
+            shouldShowTooltip={showTooltip}
+            text={transactionItem?.tag}
+            style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter]}
+        />
+    );
+
     const totalCell = (
         <TextWithTooltip
             shouldShowTooltip={showTooltip}
@@ -216,7 +232,9 @@ function TransactionListItem<TItem extends ListItem>({
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.DATE)]}>{dateCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.MERCHANT)]}>{merchantCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.FROM)]}>{userCell(transactionItem.from)}</View>
-                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.FROM)]}>{userCell(transactionItem.to)}</View>
+                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TO)]}>{userCell(transactionItem.to)}</View>
+                    {transactionItem.shouldShowCategory && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>{categoryCell}</View>}
+                    {transactionItem.shouldShowTag && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>{tagCell}</View>}
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}>{totalCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TYPE)]}>{typeCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.ACTION)]}>{actionCell}</View>
diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts
index 8a2a1efdd030..404314cf8227 100644
--- a/src/components/SelectionList/types.ts
+++ b/src/components/SelectionList/types.ts
@@ -185,6 +185,12 @@ type TransactionListItemType = ListItem & {
 
     /** Whether we should show the merchant column */
     shouldShowMerchant: boolean;
+
+    /** Whether we should show the category column */
+    shouldShowCategory: boolean;
+
+    /** Whether we should show the tag column */
+    shouldShowTag: boolean;
 };
 
 type ListItemProps<TItem extends ListItem> = CommonListItemProps<TItem> & {
diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts
index 570a8e780f5a..62f664a209b0 100644
--- a/src/libs/SearchUtils.ts
+++ b/src/libs/SearchUtils.ts
@@ -1,3 +1,4 @@
+import type {ValueOf} from 'react-native-gesture-handler/lib/typescript/typeUtils';
 import TransactionListItem from '@components/SelectionList/TransactionListItem';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -12,8 +13,14 @@ function getShouldShowMerchant(data: OnyxTypes.SearchResults['data']): boolean {
     });
 }
 
+function getShouldShowColumn(data: OnyxTypes.SearchResults['data'], columnName: ValueOf<typeof CONST.SEARCH_TABLE_OPTIONAL_COLUMNS>) {
+    return Object.values(data).some((item) => !!item[columnName]);
+}
+
 function getTransactionsSections(data: OnyxTypes.SearchResults['data']): SearchTransaction[] {
     const shouldShowMerchant = getShouldShowMerchant(data);
+    const shouldShowCategory = getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.CATEGORY);
+    const shouldShowTag = getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.TAG);
     return Object.entries(data)
         .filter(([key]) => key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION))
         .map(([, value]) => {
@@ -23,6 +30,8 @@ function getTransactionsSections(data: OnyxTypes.SearchResults['data']): SearchT
                 from: data.personalDetailsList?.[value.accountID],
                 to: isExpenseReport ? data[`${ONYXKEYS.COLLECTION.POLICY}${value.policyID}`] : data.personalDetailsList?.[value.managerID],
                 shouldShowMerchant,
+                shouldShowCategory,
+                shouldShowTag,
                 keyForList: value.transactionID,
             };
         })
@@ -56,4 +65,4 @@ function getQueryHash(query: string): number {
     return UserUtils.hashText(query, 2 ** 32);
 }
 
-export {getListItem, getQueryHash, getSections, getShouldShowMerchant};
+export {getListItem, getQueryHash, getSections, getShouldShowMerchant, getShouldShowColumn};
diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts
index ca238c3ffd88..a2f292cdeecf 100644
--- a/src/styles/utils/index.ts
+++ b/src/styles/utils/index.ts
@@ -1529,12 +1529,10 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
                 columnWidth = getWidthStyle(variables.w44);
                 break;
             case CONST.SEARCH_TABLE_COLUMNS.MERCHANT:
-                columnWidth = styles.flex1;
-                break;
             case CONST.SEARCH_TABLE_COLUMNS.FROM:
-                columnWidth = styles.flex1;
-                break;
             case CONST.SEARCH_TABLE_COLUMNS.TO:
+            case CONST.SEARCH_TABLE_COLUMNS.CATEGORY:
+            case CONST.SEARCH_TABLE_COLUMNS.TAG:
                 columnWidth = styles.flex1;
                 break;
             case CONST.SEARCH_TABLE_COLUMNS.TOTAL:
diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts
index af23821d70e8..ff89f6119cb8 100644
--- a/src/types/onyx/SearchResults.ts
+++ b/src/types/onyx/SearchResults.ts
@@ -48,6 +48,8 @@ type SearchTransaction = {
     policyID: string;
     transactionThreadReportID: string;
     shouldShowMerchant: boolean;
+    shouldShowCategory: boolean;
+    shouldShowTag: boolean;
     action: string;
 };
 

From 666f58ece4d4e9c4a1441059098fb436defe89a6 Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Mon, 6 May 2024 15:26:45 +0200
Subject: [PATCH 02/11] Handle displaying Tag and Category on small screens

---
 .../SelectionList/TransactionListItem.tsx     | 55 ++++++++++++++++++-
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index 17c16229915d..806e5a8946dc 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -7,6 +7,7 @@ import Icon from '@components/Icon';
 import * as Expensicons from '@components/Icon/Expensicons';
 import Text from '@components/Text';
 import TextWithTooltip from '@components/TextWithTooltip';
+import Tooltip from '@components/Tooltip';
 import useLocalize from '@hooks/useLocalize';
 import useStyleUtils from '@hooks/useStyleUtils';
 import useTheme from '@hooks/useTheme';
@@ -18,9 +19,37 @@ import variables from '@styles/variables';
 import CONST from '@src/CONST';
 import type {Transaction} from '@src/types/onyx';
 import type {SearchPersonalDetails, SearchPolicyDetails, SearchTransactionType} from '@src/types/onyx/SearchResults';
+import type IconAsset from '@src/types/utils/IconAsset';
 import BaseListItem from './BaseListItem';
 import type {ListItem, TransactionListItemProps, TransactionListItemType} from './types';
 
+type TextWithIconCellProps = {
+    icon: IconAsset;
+    text: string;
+    showTooltip: boolean;
+};
+
+function TextWithIconCell({icon, text, showTooltip}: TextWithIconCellProps) {
+    const styles = useThemeStyles();
+    const theme = useTheme();
+    return (
+        <Tooltip
+            shouldRender={showTooltip}
+            text={text}
+        >
+            <View style={[styles.flexRow, styles.gap1]}>
+                <Icon
+                    src={icon}
+                    fill={theme.icon}
+                    height={12}
+                    width={12}
+                />
+                <Text style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter, styles.textMicro, styles.textSupporting]}>{text}</Text>
+            </View>
+        </Tooltip>
+    );
+}
+
 const getTypeIcon = (type?: SearchTransactionType) => {
     switch (type) {
         case CONST.SEARCH_TRANSACTION_TYPE.CASH:
@@ -156,6 +185,22 @@ function TransactionListItem<TItem extends ListItem>({
     const listItemPressableStyle = [styles.selectionListPressableItemWrapper, styles.pv3, item.isSelected && styles.activeComponentBG, isFocused && styles.sidebarLinkActive];
 
     if (!isLargeScreenWidth) {
+        const smallCategoryCell = transactionItem?.category ? (
+            <TextWithIconCell
+                icon={Expensicons.Folder}
+                showTooltip={showTooltip}
+                text={transactionItem?.category}
+            />
+        ) : null;
+
+        const smallTagCell = transactionItem?.tag ? (
+            <TextWithIconCell
+                icon={Expensicons.Tag}
+                showTooltip={showTooltip}
+                text={transactionItem?.tag}
+            />
+        ) : null;
+
         return (
             <BaseListItem
                 item={item}
@@ -192,7 +237,13 @@ function TransactionListItem<TItem extends ListItem>({
                             <View style={[StyleUtils.getWidthStyle(variables.w80)]}>{actionCell}</View>
                         </View>
                         <View style={[styles.flexRow, styles.justifyContentBetween, styles.gap1]}>
-                            <View style={[styles.flex1]}>{merchantCell}</View>
+                            <View style={[styles.flex1, styles.gap1]}>
+                                {merchantCell}
+                                <View style={[styles.flexRow, styles.alignItemsEnd, styles.gap3]}>
+                                    {smallCategoryCell}
+                                    {smallTagCell}
+                                </View>
+                            </View>
                             <View style={[styles.alignItemsEnd, styles.gap1]}>
                                 {totalCell}
                                 <View style={[styles.flexRow, styles.gap1, styles.justifyContentCenter]}>
@@ -234,7 +285,7 @@ function TransactionListItem<TItem extends ListItem>({
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.FROM)]}>{userCell(transactionItem.from)}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TO)]}>{userCell(transactionItem.to)}</View>
                     {transactionItem.shouldShowCategory && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>{categoryCell}</View>}
-                    {transactionItem.shouldShowTag && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>{tagCell}</View>}
+                    {transactionItem.shouldShowTag && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAG)]}>{tagCell}</View>}
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}>{totalCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TYPE)]}>{typeCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.ACTION)]}>{actionCell}</View>

From 392bf3c804069676a89e0f2df0a29ecced3da07e Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Tue, 7 May 2024 10:29:31 +0200
Subject: [PATCH 03/11] Add TextWithIconCell

---
 .../SelectionList/TextWithIconCell.tsx        | 40 +++++++++++
 .../SelectionList/TransactionListItem.tsx     | 66 +++++--------------
 2 files changed, 57 insertions(+), 49 deletions(-)
 create mode 100644 src/components/SelectionList/TextWithIconCell.tsx

diff --git a/src/components/SelectionList/TextWithIconCell.tsx b/src/components/SelectionList/TextWithIconCell.tsx
new file mode 100644
index 000000000000..5e770d092053
--- /dev/null
+++ b/src/components/SelectionList/TextWithIconCell.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import {View} from 'react-native';
+import Icon from '@components/Icon';
+import Text from '@components/Text';
+import Tooltip from '@components/Tooltip';
+import useTheme from '@hooks/useTheme';
+import useThemeStyles from '@hooks/useThemeStyles';
+import type IconAsset from '@src/types/utils/IconAsset';
+
+type TextWithIconCellProps = {
+    icon: IconAsset;
+    text: string;
+    showTooltip: boolean;
+};
+
+export default function TextWithIconCell({icon, text, showTooltip}: TextWithIconCellProps) {
+    const styles = useThemeStyles();
+    const theme = useTheme();
+
+    if (!text) {
+        return null;
+    }
+
+    return (
+        <Tooltip
+            shouldRender={showTooltip}
+            text={text}
+        >
+            <View style={[styles.flexRow, styles.gap1]}>
+                <Icon
+                    src={icon}
+                    fill={theme.icon}
+                    height={12}
+                    width={12}
+                />
+                <Text style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter, styles.textMicro, styles.textSupporting]}>{text}</Text>
+            </View>
+        </Tooltip>
+    );
+}
diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index 806e5a8946dc..2e863c298b67 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -7,7 +7,6 @@ import Icon from '@components/Icon';
 import * as Expensicons from '@components/Icon/Expensicons';
 import Text from '@components/Text';
 import TextWithTooltip from '@components/TextWithTooltip';
-import Tooltip from '@components/Tooltip';
 import useLocalize from '@hooks/useLocalize';
 import useStyleUtils from '@hooks/useStyleUtils';
 import useTheme from '@hooks/useTheme';
@@ -19,37 +18,10 @@ import variables from '@styles/variables';
 import CONST from '@src/CONST';
 import type {Transaction} from '@src/types/onyx';
 import type {SearchPersonalDetails, SearchPolicyDetails, SearchTransactionType} from '@src/types/onyx/SearchResults';
-import type IconAsset from '@src/types/utils/IconAsset';
 import BaseListItem from './BaseListItem';
+import TextWithIconCell from './TextWithIconCell';
 import type {ListItem, TransactionListItemProps, TransactionListItemType} from './types';
 
-type TextWithIconCellProps = {
-    icon: IconAsset;
-    text: string;
-    showTooltip: boolean;
-};
-
-function TextWithIconCell({icon, text, showTooltip}: TextWithIconCellProps) {
-    const styles = useThemeStyles();
-    const theme = useTheme();
-    return (
-        <Tooltip
-            shouldRender={showTooltip}
-            text={text}
-        >
-            <View style={[styles.flexRow, styles.gap1]}>
-                <Icon
-                    src={icon}
-                    fill={theme.icon}
-                    height={12}
-                    width={12}
-                />
-                <Text style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter, styles.textMicro, styles.textSupporting]}>{text}</Text>
-            </View>
-        </Tooltip>
-    );
-}
-
 const getTypeIcon = (type?: SearchTransactionType) => {
     switch (type) {
         case CONST.SEARCH_TRANSACTION_TYPE.CASH:
@@ -137,20 +109,32 @@ function TransactionListItem<TItem extends ListItem>({
         );
     };
 
-    const categoryCell = (
+    const categoryCell = isLargeScreenWidth ? (
         <TextWithTooltip
             shouldShowTooltip={showTooltip}
             text={transactionItem?.category}
             style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter]}
         />
+    ) : (
+        <TextWithIconCell
+            icon={Expensicons.Folder}
+            showTooltip={showTooltip}
+            text={transactionItem?.category}
+        />
     );
 
-    const tagCell = (
+    const tagCell = isLargeScreenWidth ? (
         <TextWithTooltip
             shouldShowTooltip={showTooltip}
             text={transactionItem?.tag}
             style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter]}
         />
+    ) : (
+        <TextWithIconCell
+            icon={Expensicons.Tag}
+            showTooltip={showTooltip}
+            text={transactionItem?.tag}
+        />
     );
 
     const totalCell = (
@@ -185,22 +169,6 @@ function TransactionListItem<TItem extends ListItem>({
     const listItemPressableStyle = [styles.selectionListPressableItemWrapper, styles.pv3, item.isSelected && styles.activeComponentBG, isFocused && styles.sidebarLinkActive];
 
     if (!isLargeScreenWidth) {
-        const smallCategoryCell = transactionItem?.category ? (
-            <TextWithIconCell
-                icon={Expensicons.Folder}
-                showTooltip={showTooltip}
-                text={transactionItem?.category}
-            />
-        ) : null;
-
-        const smallTagCell = transactionItem?.tag ? (
-            <TextWithIconCell
-                icon={Expensicons.Tag}
-                showTooltip={showTooltip}
-                text={transactionItem?.tag}
-            />
-        ) : null;
-
         return (
             <BaseListItem
                 item={item}
@@ -240,8 +208,8 @@ function TransactionListItem<TItem extends ListItem>({
                             <View style={[styles.flex1, styles.gap1]}>
                                 {merchantCell}
                                 <View style={[styles.flexRow, styles.alignItemsEnd, styles.gap3]}>
-                                    {smallCategoryCell}
-                                    {smallTagCell}
+                                    {categoryCell}
+                                    {tagCell}
                                 </View>
                             </View>
                             <View style={[styles.alignItemsEnd, styles.gap1]}>

From 22a00fa250777938ce80b43376c7ca529069ce7c Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Tue, 7 May 2024 10:37:13 +0200
Subject: [PATCH 04/11] Remove CONST.SEARCH_TABLE_OPTIONAL_COLUMNS

---
 src/CONST.ts                                       | 4 ----
 src/components/SelectionList/SearchTableHeader.tsx | 4 ++--
 src/libs/SearchUtils.ts                            | 6 +++---
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/CONST.ts b/src/CONST.ts
index d2bc9f266dcc..ec999f18a63c 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -930,10 +930,6 @@ const CONST = {
         TYPE: 'type',
         ACTION: 'action',
     },
-    SEARCH_TABLE_OPTIONAL_COLUMNS: {
-        CATEGORY: 'category',
-        TAG: 'tag',
-    },
     PRIORITY_MODE: {
         GSD: 'gsd',
         DEFAULT: 'default',
diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx
index 0fcec85f3833..76a73e6f1d28 100644
--- a/src/components/SelectionList/SearchTableHeader.tsx
+++ b/src/components/SelectionList/SearchTableHeader.tsx
@@ -20,8 +20,8 @@ function SearchTableHeader({data}: SearchTableHeaderProps) {
     const {translate} = useLocalize();
     const displayNarrowVersion = isMediumScreenWidth || isSmallScreenWidth;
 
-    const shouldShowCategoryColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.CATEGORY);
-    const shouldShowTagColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.TAG);
+    const shouldShowCategoryColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.CATEGORY);
+    const shouldShowTagColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAG);
     const shouldShowMerchant = SearchUtils.getShouldShowMerchant(data);
 
     if (displayNarrowVersion) {
diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts
index 62f664a209b0..d8198548eb50 100644
--- a/src/libs/SearchUtils.ts
+++ b/src/libs/SearchUtils.ts
@@ -13,14 +13,14 @@ function getShouldShowMerchant(data: OnyxTypes.SearchResults['data']): boolean {
     });
 }
 
-function getShouldShowColumn(data: OnyxTypes.SearchResults['data'], columnName: ValueOf<typeof CONST.SEARCH_TABLE_OPTIONAL_COLUMNS>) {
+function getShouldShowColumn(data: OnyxTypes.SearchResults['data'], columnName: ValueOf<typeof CONST.SEARCH_TABLE_COLUMNS>) {
     return Object.values(data).some((item) => !!item[columnName]);
 }
 
 function getTransactionsSections(data: OnyxTypes.SearchResults['data']): SearchTransaction[] {
     const shouldShowMerchant = getShouldShowMerchant(data);
-    const shouldShowCategory = getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.CATEGORY);
-    const shouldShowTag = getShouldShowColumn(data, CONST.SEARCH_TABLE_OPTIONAL_COLUMNS.TAG);
+    const shouldShowCategory = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.CATEGORY);
+    const shouldShowTag = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAG);
     return Object.entries(data)
         .filter(([key]) => key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION))
         .map(([, value]) => {

From 72e75b5f96e828cbaa1e3c236fbd909620e949e9 Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Tue, 7 May 2024 12:25:21 +0200
Subject: [PATCH 05/11] Refactor TransactionListItemType

---
 .../SelectionList/TextWithIconCell.tsx        |  2 +-
 .../SelectionList/TransactionListItem.tsx     |  4 +-
 src/components/SelectionList/types.ts         | 79 ++++---------------
 src/libs/SearchUtils.ts                       |  8 +-
 src/types/onyx/SearchResults.ts               | 70 +++++++++++-----
 5 files changed, 72 insertions(+), 91 deletions(-)

diff --git a/src/components/SelectionList/TextWithIconCell.tsx b/src/components/SelectionList/TextWithIconCell.tsx
index 5e770d092053..d9b9dc99f668 100644
--- a/src/components/SelectionList/TextWithIconCell.tsx
+++ b/src/components/SelectionList/TextWithIconCell.tsx
@@ -9,7 +9,7 @@ import type IconAsset from '@src/types/utils/IconAsset';
 
 type TextWithIconCellProps = {
     icon: IconAsset;
-    text: string;
+    text?: string;
     showTooltip: boolean;
 };
 
diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index 2e863c298b67..1a298fd30cb7 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -17,7 +17,7 @@ import * as TransactionUtils from '@libs/TransactionUtils';
 import variables from '@styles/variables';
 import CONST from '@src/CONST';
 import type {Transaction} from '@src/types/onyx';
-import type {SearchPersonalDetails, SearchPolicyDetails, SearchTransactionType} from '@src/types/onyx/SearchResults';
+import type {SearchAccountDetails, SearchTransactionType} from '@src/types/onyx/SearchResults';
 import BaseListItem from './BaseListItem';
 import TextWithIconCell from './TextWithIconCell';
 import type {ListItem, TransactionListItemProps, TransactionListItemType} from './types';
@@ -83,7 +83,7 @@ function TransactionListItem<TItem extends ListItem>({
         />
     );
 
-    const userCell = (participant: SearchPersonalDetails & SearchPolicyDetails) => {
+    const userCell = (participant: SearchAccountDetails) => {
         const displayName = participant?.name ?? participant?.displayName ?? participant?.login;
         const avatarURL = participant?.avatarURL ?? participant?.avatar;
         const isWorkspace = participant?.avatarURL !== undefined;
diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts
index 404314cf8227..37f7cf2e1f3b 100644
--- a/src/components/SelectionList/types.ts
+++ b/src/components/SelectionList/types.ts
@@ -1,11 +1,10 @@
 import type {MutableRefObject, ReactElement, ReactNode} from 'react';
 import type {GestureResponderEvent, InputModeOptions, LayoutChangeEvent, SectionListData, StyleProp, TextInput, TextStyle, ViewStyle} from 'react-native';
-import type {ValueOf} from 'type-fest';
 import type {MaybePhraseKey} from '@libs/Localize';
 import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
 import type CONST from '@src/CONST';
 import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon';
-import type {SearchPersonalDetails, SearchPolicyDetails} from '@src/types/onyx/SearchResults';
+import type {SearchAccountDetails, SearchTransaction} from '@src/types/onyx/SearchResults';
 import type {ReceiptErrors} from '@src/types/onyx/Transaction';
 import type ChildrenProps from '@src/types/utils/ChildrenProps';
 import type IconAsset from '@src/types/utils/IconAsset';
@@ -128,70 +127,22 @@ type ListItem = {
     brickRoadIndicator?: BrickRoad | '' | null;
 };
 
-type TransactionListItemType = ListItem & {
-    /** The ID of the transaction */
-    transactionID: string;
+type TransactionListItemType = ListItem &
+    SearchTransaction & {
+        /** The personal details of the user requesting money */
+        from: SearchAccountDetails;
 
-    /** The transaction created date */
-    created: string;
+        /** The personal details of the user paying the request */
+        to: SearchAccountDetails;
+        /** Whether we should show the merchant column */
+        shouldShowMerchant: boolean;
 
-    /** The edited transaction created date */
-    modifiedCreated: string;
+        /** Whether we should show the category column */
+        shouldShowCategory: boolean;
 
-    /** The transaction amount */
-    amount: number;
-
-    /** The edited transaction amount */
-    modifiedAmount: number;
-
-    /** The transaction currency */
-    currency: string;
-
-    /** The edited transaction currency */
-    modifiedCurrency: string;
-
-    /** The transaction merchant */
-    merchant: string;
-
-    /** The edited transaction merchant */
-    modifiedMerchant: string;
-
-    /** The receipt object */
-    receipt?: {source?: string};
-
-    /** The personal details of the user requesting money */
-    from: SearchPersonalDetails & SearchPolicyDetails;
-
-    /** The personal details of the user paying the request */
-    to: SearchPersonalDetails & SearchPolicyDetails;
-
-    /** The transaction tag */
-    tag: string;
-
-    /** The transaction description */
-    comment: {comment: string};
-
-    /** The transaction category */
-    category: string;
-
-    /** The type of request */
-    type: ValueOf<typeof CONST.SEARCH_TRANSACTION_TYPE>;
-
-    /** The type of report the transaction is associated with */
-    reportType: string;
-
-    /** The ID of the policy the transaction is associated with */
-    policyID: string;
-
-    /** Whether we should show the merchant column */
-    shouldShowMerchant: boolean;
-
-    /** Whether we should show the category column */
-    shouldShowCategory: boolean;
-
-    /** Whether we should show the tag column */
-    shouldShowTag: boolean;
-};
+        /** Whether we should show the tag column */
+        shouldShowTag: boolean;
+    };
 
 type ListItemProps<TItem extends ListItem> = CommonListItemProps<TItem> & {
     /** The section list item */
@@ -454,7 +405,7 @@ export type {
     SelectionListHandle,
     TableListItemProps,
     TransactionListItemProps,
+    TransactionListItemType,
     UserListItemProps,
     ValidListItem,
-    TransactionListItemType,
 };
diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts
index d8198548eb50..56edf69457e4 100644
--- a/src/libs/SearchUtils.ts
+++ b/src/libs/SearchUtils.ts
@@ -1,9 +1,9 @@
 import type {ValueOf} from 'react-native-gesture-handler/lib/typescript/typeUtils';
 import TransactionListItem from '@components/SelectionList/TransactionListItem';
+import type {TransactionListItemType} from '@components/SelectionList/types';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import type * as OnyxTypes from '@src/types/onyx';
-import type {SearchTransaction} from '@src/types/onyx/SearchResults';
 import * as UserUtils from './UserUtils';
 
 function getShouldShowMerchant(data: OnyxTypes.SearchResults['data']): boolean {
@@ -17,7 +17,7 @@ function getShouldShowColumn(data: OnyxTypes.SearchResults['data'], columnName:
     return Object.values(data).some((item) => !!item[columnName]);
 }
 
-function getTransactionsSections(data: OnyxTypes.SearchResults['data']): SearchTransaction[] {
+function getTransactionsSections(data: OnyxTypes.SearchResults['data']): TransactionListItemType[] {
     const shouldShowMerchant = getShouldShowMerchant(data);
     const shouldShowCategory = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.CATEGORY);
     const shouldShowTag = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAG);
@@ -57,7 +57,7 @@ function getListItem(): typeof TransactionListItem {
     return searchTypeToItemMap.transaction.listItem;
 }
 
-function getSections(data: OnyxTypes.SearchResults['data']): SearchTransaction[] {
+function getSections(data: OnyxTypes.SearchResults['data']): TransactionListItemType[] {
     return searchTypeToItemMap.transaction.getSections(data);
 }
 
@@ -65,4 +65,4 @@ function getQueryHash(query: string): number {
     return UserUtils.hashText(query, 2 ** 32);
 }
 
-export {getListItem, getQueryHash, getSections, getShouldShowMerchant, getShouldShowColumn};
+export {getListItem, getQueryHash, getSections, getShouldShowColumn, getShouldShowMerchant};
diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts
index ff89f6119cb8..08a5e759740b 100644
--- a/src/types/onyx/SearchResults.ts
+++ b/src/types/onyx/SearchResults.ts
@@ -1,6 +1,5 @@
 import type {ValueOf} from 'type-fest';
 import type CONST from '@src/CONST';
-import type {Receipt} from './Transaction';
 
 type SearchResultsInfo = {
     offset: number;
@@ -22,37 +21,68 @@ type SearchPolicyDetails = {
 };
 
 type SearchTransaction = {
+    /** The ID of the transaction */
     transactionID: string;
-    parentTransactionID?: string;
-    receipt?: Receipt;
-    hasEReceipt?: boolean;
+
+    /** The transaction created date */
     created: string;
+
+    /** The edited transaction created date */
+    modifiedCreated: string;
+
+    /** The transaction amount */
+    amount: number;
+
+    /** The edited transaction amount */
+    modifiedAmount: number;
+
+    /** The transaction currency */
+    currency: string;
+
+    /** The edited transaction currency */
+    modifiedCurrency: string;
+
+    /** The transaction merchant */
     merchant: string;
-    modifiedCreated?: string;
-    modifiedMerchant?: string;
+
+    /** The edited transaction merchant */
+    modifiedMerchant: string;
+
+    /** The receipt object */
+    receipt?: {source?: string};
+
+    /** The transaction tag */
+    tag: string;
+
+    /** The transaction description */
+    comment: {comment: string};
+
+    /** The transaction category */
+    category: string;
+
+    /** The type of request */
+    type: ValueOf<typeof CONST.SEARCH_TRANSACTION_TYPE>;
+
+    /** The type of report the transaction is associated with */
+    reportType: string;
+
+    /** The ID of the policy the transaction is associated with */
+    policyID: string;
+
+    parentTransactionID?: string;
+    hasEReceipt?: boolean;
     description: string;
     accountID: number;
     managerID: number;
-    from: SearchPersonalDetails | SearchPolicyDetails;
-    to: SearchPersonalDetails | SearchPolicyDetails;
-    amount: number;
-    modifiedAmount?: number;
-    category?: string;
-    currency: string;
-    tag?: string;
-    type: SearchTransactionType;
     hasViolation: boolean;
     taxAmount?: number;
     reportID: string;
-    reportType: string;
-    policyID: string;
     transactionThreadReportID: string;
-    shouldShowMerchant: boolean;
-    shouldShowCategory: boolean;
-    shouldShowTag: boolean;
     action: string;
 };
 
+type SearchAccountDetails = Partial<SearchPolicyDetails & SearchPersonalDetails>;
+
 type SearchTransactionType = ValueOf<typeof CONST.SEARCH_TRANSACTION_TYPE>;
 
 type SearchQuery = ValueOf<typeof CONST.TAB_SEARCH>;
@@ -64,4 +94,4 @@ type SearchResults = {
 
 export default SearchResults;
 
-export type {SearchQuery, SearchTransaction, SearchTransactionType, SearchPersonalDetails, SearchPolicyDetails};
+export type {SearchQuery, SearchTransaction, SearchTransactionType, SearchPersonalDetails, SearchPolicyDetails, SearchAccountDetails};

From ac96c83a8e850b1a626b532627892a63794c975d Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Tue, 7 May 2024 13:44:58 +0200
Subject: [PATCH 06/11] Add docs for SearchTransaction

---
 src/components/SelectionList/types.ts |  1 +
 src/types/onyx/SearchResults.ts       | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts
index 37f7cf2e1f3b..66a1f81af7e9 100644
--- a/src/components/SelectionList/types.ts
+++ b/src/components/SelectionList/types.ts
@@ -134,6 +134,7 @@ type TransactionListItemType = ListItem &
 
         /** The personal details of the user paying the request */
         to: SearchAccountDetails;
+
         /** Whether we should show the merchant column */
         shouldShowMerchant: boolean;
 
diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts
index 08a5e759740b..91c76774d209 100644
--- a/src/types/onyx/SearchResults.ts
+++ b/src/types/onyx/SearchResults.ts
@@ -69,15 +69,34 @@ type SearchTransaction = {
     /** The ID of the policy the transaction is associated with */
     policyID: string;
 
+    /** The ID of the parent of the transaction */
     parentTransactionID?: string;
+
+    /** If the transaction has an Ereceipt */
     hasEReceipt?: boolean;
+
+    /** The transaction description */
     description: string;
+
+    /** The transaction sender ID */
     accountID: number;
+
+    /** The transaction recipient ID */
     managerID: number;
+
+    /** If the transaction has a Ereceipt */
     hasViolation: boolean;
+
+    /** The transaction tax amount */
     taxAmount?: number;
+
+    /** The ID of the report the transaction is associated with */
     reportID: string;
+
+    /** The report ID of the transaction thread associated with the transaction */
     transactionThreadReportID: string;
+
+    /** The action that can be performed for the transaction */
     action: string;
 };
 

From bbbd786f70e35d9b6ad88f0cdeaf588f7e59d34e Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Wed, 8 May 2024 10:13:32 +0200
Subject: [PATCH 07/11] Add tax column

---
 src/CONST.ts                                         |  1 +
 src/components/SelectionList/SearchTableHeader.tsx   |  6 ++++++
 src/components/SelectionList/TransactionListItem.tsx | 10 ++++++++++
 src/components/SelectionList/types.ts                |  3 +++
 src/languages/en.ts                                  |  1 +
 src/languages/es.ts                                  |  1 +
 src/libs/SearchUtils.ts                              |  2 ++
 src/styles/utils/index.ts                            |  1 +
 8 files changed, 25 insertions(+)

diff --git a/src/CONST.ts b/src/CONST.ts
index ec999f18a63c..40a8f345cd13 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -929,6 +929,7 @@ const CONST = {
         TOTAL: 'total',
         TYPE: 'type',
         ACTION: 'action',
+        TAX_AMOUNT: 'taxAmount',
     },
     PRIORITY_MODE: {
         GSD: 'gsd',
diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx
index 76a73e6f1d28..34ec54cf1f7b 100644
--- a/src/components/SelectionList/SearchTableHeader.tsx
+++ b/src/components/SelectionList/SearchTableHeader.tsx
@@ -22,6 +22,7 @@ function SearchTableHeader({data}: SearchTableHeaderProps) {
 
     const shouldShowCategoryColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.CATEGORY);
     const shouldShowTagColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAG);
+    const shouldShowTaxColumn = SearchUtils.getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT);
     const shouldShowMerchant = SearchUtils.getShouldShowMerchant(data);
 
     if (displayNarrowVersion) {
@@ -53,6 +54,11 @@ function SearchTableHeader({data}: SearchTableHeaderProps) {
                         <Text style={[styles.mutedNormalTextLabel]}>{translate('common.tag')}</Text>
                     </View>
                 )}
+                {!shouldShowTaxColumn && (
+                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT)]}>
+                        <Text style={[styles.mutedNormalTextLabel]}>{translate('common.tax')}</Text>
+                    </View>
+                )}
                 <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}>
                     <Text style={[styles.mutedNormalTextLabel]}>{translate('common.total')}</Text>
                 </View>
diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index 1a298fd30cb7..f0e78d4012de 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -62,6 +62,7 @@ function TransactionListItem<TItem extends ListItem>({
     const isFromExpenseReport = transactionItem.reportType === CONST.REPORT.TYPE.EXPENSE;
     const date = TransactionUtils.getCreated(transactionItem as OnyxEntry<Transaction>, CONST.DATE.MONTH_DAY_ABBR_FORMAT);
     const amount = TransactionUtils.getAmount(transactionItem as OnyxEntry<Transaction>, isFromExpenseReport);
+    const taxAmount = TransactionUtils.getAmount(transactionItem as OnyxEntry<Transaction>);
     const currency = TransactionUtils.getCurrency(transactionItem as OnyxEntry<Transaction>);
     const description = TransactionUtils.getDescription(transactionItem as OnyxEntry<Transaction>);
     const merchant = getMerchant();
@@ -137,6 +138,14 @@ function TransactionListItem<TItem extends ListItem>({
         />
     );
 
+    const taxCell = (
+        <TextWithTooltip
+            shouldShowTooltip={showTooltip}
+            text={CurrencyUtils.convertToDisplayString(taxAmount, currency)}
+            style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter, styles.textAlignRight]}
+        />
+    );
+
     const totalCell = (
         <TextWithTooltip
             shouldShowTooltip={showTooltip}
@@ -254,6 +263,7 @@ function TransactionListItem<TItem extends ListItem>({
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TO)]}>{userCell(transactionItem.to)}</View>
                     {transactionItem.shouldShowCategory && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>{categoryCell}</View>}
                     {transactionItem.shouldShowTag && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAG)]}>{tagCell}</View>}
+                    {transactionItem.shouldShowTax && <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT)]}>{taxCell}</View>}
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}>{totalCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TYPE)]}>{typeCell}</View>
                     <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.ACTION)]}>{actionCell}</View>
diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts
index 66a1f81af7e9..79e47e4aa4d7 100644
--- a/src/components/SelectionList/types.ts
+++ b/src/components/SelectionList/types.ts
@@ -143,6 +143,9 @@ type TransactionListItemType = ListItem &
 
         /** Whether we should show the tag column */
         shouldShowTag: boolean;
+
+        /** Whether we should show the tax column */
+        shouldShowTax: boolean;
     };
 
 type ListItemProps<TItem extends ListItem> = CommonListItemProps<TItem> & {
diff --git a/src/languages/en.ts b/src/languages/en.ts
index aadd6ac03f58..48b49c7ab5c3 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -331,6 +331,7 @@ export default {
         type: 'Type',
         action: 'Action',
         expenses: 'Expenses',
+        tax: 'Tax',
     },
     location: {
         useCurrent: 'Use current location',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index d4efe11a51b0..413fbb39a613 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -321,6 +321,7 @@ export default {
         type: 'Tipo',
         action: 'Acción',
         expenses: 'Gastos',
+        tax: 'Impuesto',
     },
     connectionComplete: {
         title: 'Conexión Completa',
diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts
index 56edf69457e4..23dbabb66af7 100644
--- a/src/libs/SearchUtils.ts
+++ b/src/libs/SearchUtils.ts
@@ -21,6 +21,7 @@ function getTransactionsSections(data: OnyxTypes.SearchResults['data']): Transac
     const shouldShowMerchant = getShouldShowMerchant(data);
     const shouldShowCategory = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.CATEGORY);
     const shouldShowTag = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAG);
+    const shouldShowTax = getShouldShowColumn(data, CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT);
     return Object.entries(data)
         .filter(([key]) => key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION))
         .map(([, value]) => {
@@ -32,6 +33,7 @@ function getTransactionsSections(data: OnyxTypes.SearchResults['data']): Transac
                 shouldShowMerchant,
                 shouldShowCategory,
                 shouldShowTag,
+                shouldShowTax,
                 keyForList: value.transactionID,
             };
         })
diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts
index a2f292cdeecf..b902915f4b10 100644
--- a/src/styles/utils/index.ts
+++ b/src/styles/utils/index.ts
@@ -1535,6 +1535,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
             case CONST.SEARCH_TABLE_COLUMNS.TAG:
                 columnWidth = styles.flex1;
                 break;
+            case CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT:
             case CONST.SEARCH_TABLE_COLUMNS.TOTAL:
                 columnWidth = {...getWidthStyle(variables.w96), ...styles.alignItemsEnd};
                 break;

From ee24845a5c5fc18dafaab2671465c994dcfe88ca Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Thu, 9 May 2024 10:13:02 +0200
Subject: [PATCH 08/11] Add SearchTableHeaderColumn

---
 .../SelectionList/SearchTableHeader.tsx       | 82 ++++++++++---------
 .../SelectionList/SearchTableHeaderColumn.tsx | 31 +++++++
 2 files changed, 76 insertions(+), 37 deletions(-)
 create mode 100644 src/components/SelectionList/SearchTableHeaderColumn.tsx

diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx
index 34ec54cf1f7b..ec0267d20c04 100644
--- a/src/components/SelectionList/SearchTableHeader.tsx
+++ b/src/components/SelectionList/SearchTableHeader.tsx
@@ -1,6 +1,5 @@
 import React from 'react';
 import {View} from 'react-native';
-import Text from '@components/Text';
 import useLocalize from '@hooks/useLocalize';
 import useStyleUtils from '@hooks/useStyleUtils';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -8,6 +7,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
 import * as SearchUtils from '@libs/SearchUtils';
 import CONST from '@src/CONST';
 import type * as OnyxTypes from '@src/types/onyx';
+import SearchTableHeaderColumn from './SearchTableHeaderColumn';
 
 type SearchTableHeaderProps = {
     data: OnyxTypes.SearchResults['data'];
@@ -32,42 +32,50 @@ function SearchTableHeader({data}: SearchTableHeaderProps) {
     return (
         <View style={[styles.ph5, styles.pb3]}>
             <View style={[styles.flex1, styles.flexRow, styles.gap3, styles.ph4]}>
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.DATE)]}>
-                    <Text style={[styles.mutedNormalTextLabel]}>{translate('common.date')}</Text>
-                </View>
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.MERCHANT)]}>
-                    <Text style={[styles.mutedNormalTextLabel]}>{translate(shouldShowMerchant ? 'common.merchant' : 'common.description')}</Text>
-                </View>
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.FROM)]}>
-                    <Text style={[styles.mutedNormalTextLabel]}>{translate('common.from')}</Text>
-                </View>
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TO)]}>
-                    <Text style={[styles.mutedNormalTextLabel]}>{translate('common.to')}</Text>
-                </View>
-                {shouldShowCategoryColumn && (
-                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}>
-                        <Text style={[styles.mutedNormalTextLabel]}>{translate('common.category')}</Text>
-                    </View>
-                )}
-                {shouldShowTagColumn && (
-                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAG)]}>
-                        <Text style={[styles.mutedNormalTextLabel]}>{translate('common.tag')}</Text>
-                    </View>
-                )}
-                {!shouldShowTaxColumn && (
-                    <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT)]}>
-                        <Text style={[styles.mutedNormalTextLabel]}>{translate('common.tax')}</Text>
-                    </View>
-                )}
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}>
-                    <Text style={[styles.mutedNormalTextLabel]}>{translate('common.total')}</Text>
-                </View>
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TYPE)]}>
-                    <Text style={[styles.mutedNormalTextLabel]}>{translate('common.type')}</Text>
-                </View>
-                <View style={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.ACTION)]}>
-                    <Text style={[styles.mutedNormalTextLabel, styles.textAlignCenter]}>{translate('common.action')}</Text>
-                </View>
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.DATE)]}
+                    text={translate('common.date')}
+                />
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.MERCHANT)]}
+                    text={translate(shouldShowMerchant ? 'common.merchant' : 'common.description')}
+                />
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.FROM)]}
+                    text={translate('common.from')}
+                />
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TO)]}
+                    text={translate('common.to')}
+                />
+                <SearchTableHeaderColumn
+                    shouldShow={shouldShowCategoryColumn}
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.CATEGORY)]}
+                    text={translate('common.category')}
+                />
+                <SearchTableHeaderColumn
+                    shouldShow={shouldShowTagColumn}
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAG)]}
+                    text={translate('common.tag')}
+                />
+                <SearchTableHeaderColumn
+                    shouldShow={shouldShowTaxColumn}
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TAX_AMOUNT)]}
+                    text={translate('common.tax')}
+                />
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TOTAL)]}
+                    text={translate('common.total')}
+                />
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.TYPE)]}
+                    text={translate('common.type')}
+                />
+                <SearchTableHeaderColumn
+                    containerStyle={[StyleUtils.getSearchTableColumnStyles(CONST.SEARCH_TABLE_COLUMNS.ACTION)]}
+                    text={translate('common.action')}
+                    textStyle={styles.textAlignCenter}
+                />
             </View>
         </View>
     );
diff --git a/src/components/SelectionList/SearchTableHeaderColumn.tsx b/src/components/SelectionList/SearchTableHeaderColumn.tsx
new file mode 100644
index 000000000000..92b59f702cb1
--- /dev/null
+++ b/src/components/SelectionList/SearchTableHeaderColumn.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import {View} from 'react-native';
+import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
+import Text from '@components/Text';
+import useThemeStyles from '@hooks/useThemeStyles';
+
+type SearchTableHeaderColumnProps = {
+    shouldShow?: boolean;
+    containerStyle?: StyleProp<ViewStyle>;
+    text: string;
+    textStyle?: StyleProp<TextStyle>;
+};
+
+export default function SearchTableHeaderColumn({containerStyle, text, textStyle, shouldShow = true}: SearchTableHeaderColumnProps) {
+    const styles = useThemeStyles();
+
+    if (!shouldShow) {
+        return null;
+    }
+
+    return (
+        <View style={containerStyle}>
+            <Text
+                numberOfLines={1}
+                style={[styles.mutedNormalTextLabel, textStyle]}
+            >
+                {text}
+            </Text>
+        </View>
+    );
+}

From 74d3a88a2a12b979f4c52aa5f89d420cc4781ce7 Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Thu, 9 May 2024 10:26:53 +0200
Subject: [PATCH 09/11] Fix displaying users in TransactionListItem

---
 src/components/SelectionList/TransactionListItem.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index f0e78d4012de..abb2c20e72eb 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -62,7 +62,7 @@ function TransactionListItem<TItem extends ListItem>({
     const isFromExpenseReport = transactionItem.reportType === CONST.REPORT.TYPE.EXPENSE;
     const date = TransactionUtils.getCreated(transactionItem as OnyxEntry<Transaction>, CONST.DATE.MONTH_DAY_ABBR_FORMAT);
     const amount = TransactionUtils.getAmount(transactionItem as OnyxEntry<Transaction>, isFromExpenseReport);
-    const taxAmount = TransactionUtils.getAmount(transactionItem as OnyxEntry<Transaction>);
+    const taxAmount = TransactionUtils.getTaxAmount(transactionItem as OnyxEntry<Transaction>, isFromExpenseReport);
     const currency = TransactionUtils.getCurrency(transactionItem as OnyxEntry<Transaction>);
     const description = TransactionUtils.getDescription(transactionItem as OnyxEntry<Transaction>);
     const merchant = getMerchant();
@@ -209,7 +209,7 @@ function TransactionListItem<TItem extends ListItem>({
                                     height={variables.iconSizeXXSmall}
                                     fill={theme.icon}
                                 />
-                                <View style={[styles.mw50]}>{userCell(transactionItem.to)}</View>
+                                <View style={[styles.flex1, styles.mw50]}>{userCell(transactionItem.to)}</View>
                             </View>
                             <View style={[StyleUtils.getWidthStyle(variables.w80)]}>{actionCell}</View>
                         </View>

From ed74c1add93e19867990e38de3eebadcaf405098 Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Thu, 9 May 2024 10:53:28 +0200
Subject: [PATCH 10/11] Fix displaying category and tag cells in
 TransactionListItem

---
 src/components/SelectionList/TextWithIconCell.tsx    | 9 +++++++--
 src/components/SelectionList/TransactionListItem.tsx | 2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/components/SelectionList/TextWithIconCell.tsx b/src/components/SelectionList/TextWithIconCell.tsx
index d9b9dc99f668..5423bb1537ad 100644
--- a/src/components/SelectionList/TextWithIconCell.tsx
+++ b/src/components/SelectionList/TextWithIconCell.tsx
@@ -26,14 +26,19 @@ export default function TextWithIconCell({icon, text, showTooltip}: TextWithIcon
             shouldRender={showTooltip}
             text={text}
         >
-            <View style={[styles.flexRow, styles.gap1]}>
+            <View style={[styles.flexRow, styles.flex1, styles.gap1]}>
                 <Icon
                     src={icon}
                     fill={theme.icon}
                     height={12}
                     width={12}
                 />
-                <Text style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter, styles.textMicro, styles.textSupporting]}>{text}</Text>
+                <Text
+                    numberOfLines={1}
+                    style={[styles.optionDisplayName, styles.label, styles.pre, styles.justifyContentCenter, styles.textMicro, styles.textSupporting, styles.flexShrink1]}
+                >
+                    {text}
+                </Text>
             </View>
         </Tooltip>
     );
diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index abb2c20e72eb..26cd9f38e813 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -216,7 +216,7 @@ function TransactionListItem<TItem extends ListItem>({
                         <View style={[styles.flexRow, styles.justifyContentBetween, styles.gap1]}>
                             <View style={[styles.flex1, styles.gap1]}>
                                 {merchantCell}
-                                <View style={[styles.flexRow, styles.alignItemsEnd, styles.gap3]}>
+                                <View style={[styles.flexRow, styles.flex1, styles.alignItemsEnd, styles.gap3]}>
                                     {categoryCell}
                                     {tagCell}
                                 </View>

From 2fe5f209dcd321e09609833689c9bb1cf305373e Mon Sep 17 00:00:00 2001
From: Wojciech Boman <wojciechboman@gmail.com>
Date: Fri, 10 May 2024 14:13:56 +0200
Subject: [PATCH 11/11] Add style fixes to TransactionListItem

---
 src/components/SelectionList/TextWithIconCell.tsx    | 2 +-
 src/components/SelectionList/TransactionListItem.tsx | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/components/SelectionList/TextWithIconCell.tsx b/src/components/SelectionList/TextWithIconCell.tsx
index 5423bb1537ad..bd51133a362f 100644
--- a/src/components/SelectionList/TextWithIconCell.tsx
+++ b/src/components/SelectionList/TextWithIconCell.tsx
@@ -26,7 +26,7 @@ export default function TextWithIconCell({icon, text, showTooltip}: TextWithIcon
             shouldRender={showTooltip}
             text={text}
         >
-            <View style={[styles.flexRow, styles.flex1, styles.gap1]}>
+            <View style={[styles.flexRow, styles.flexShrink1, styles.gap1]}>
                 <Icon
                     src={icon}
                     fill={theme.icon}
diff --git a/src/components/SelectionList/TransactionListItem.tsx b/src/components/SelectionList/TransactionListItem.tsx
index 26cd9f38e813..04929bf883d1 100644
--- a/src/components/SelectionList/TransactionListItem.tsx
+++ b/src/components/SelectionList/TransactionListItem.tsx
@@ -200,7 +200,7 @@ function TransactionListItem<TItem extends ListItem>({
             >
                 {() => (
                     <>
-                        <View style={[styles.flexRow, styles.alignItemsCenter, styles.justifyContentBetween, styles.mb2, styles.gap2]}>
+                        <View style={[styles.flex1, styles.flexRow, styles.alignItemsCenter, styles.justifyContentBetween, styles.mb2, styles.gap2]}>
                             <View style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, styles.flex1]}>
                                 <View style={[styles.mw50]}>{userCell(transactionItem.from)}</View>
                                 <Icon
@@ -214,14 +214,14 @@ function TransactionListItem<TItem extends ListItem>({
                             <View style={[StyleUtils.getWidthStyle(variables.w80)]}>{actionCell}</View>
                         </View>
                         <View style={[styles.flexRow, styles.justifyContentBetween, styles.gap1]}>
-                            <View style={[styles.flex1, styles.gap1]}>
+                            <View style={[styles.flex2, styles.gap1]}>
                                 {merchantCell}
                                 <View style={[styles.flexRow, styles.flex1, styles.alignItemsEnd, styles.gap3]}>
                                     {categoryCell}
                                     {tagCell}
                                 </View>
                             </View>
-                            <View style={[styles.alignItemsEnd, styles.gap1]}>
+                            <View style={[styles.alignItemsEnd, styles.flex1, styles.gap1]}>
                                 {totalCell}
                                 <View style={[styles.flexRow, styles.gap1, styles.justifyContentCenter]}>
                                     {typeCell}
