From 025c7b98719e178cbdee3e0ab2963272dca89f2a Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 9 Jul 2025 18:47:16 +0700 Subject: [PATCH 1/8] fix: app crashes when group-by:reports is manually --- src/components/Search/SearchList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/SearchList.tsx b/src/components/Search/SearchList.tsx index a6f6bf436092e..5532cd11fa5c2 100644 --- a/src/components/Search/SearchList.tsx +++ b/src/components/Search/SearchList.tsx @@ -108,7 +108,7 @@ function SearchList( const styles = useThemeStyles(); const {hash, groupBy} = queryJSON; const flattenedTransactions = groupBy ? (data as TransactionGroupListItemType[]).flatMap((item) => item.transactions) : data; - const flattenedTransactionWithoutPendingDelete = flattenedTransactions.filter((t) => t.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); + const flattenedTransactionWithoutPendingDelete = flattenedTransactions.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); const selectedItemsLength = flattenedTransactions.reduce((acc, item) => { return item?.isSelected ? acc + 1 : acc; }, 0); From 44b9974bc989c7a6a8e8492ec842ed708ed972c5 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 9 Jul 2025 23:46:33 +0700 Subject: [PATCH 2/8] show the empty view if we use group by in chat or in task --- src/libs/SearchUIUtils.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 581fab0182232..160b5f85edca4 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1019,10 +1019,17 @@ function getListItem(type: SearchDataTypes, status: SearchStatus, groupBy?: Sear * Organizes data into appropriate list sections for display based on the type of search results. */ function getSections(type: SearchDataTypes, status: SearchStatus, data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search'], groupBy?: SearchGroupBy) { - if (type === CONST.SEARCH.DATA_TYPES.CHAT) { + const isChat = type === CONST.SEARCH.DATA_TYPES.CHAT; + const isTask = type === CONST.SEARCH.DATA_TYPES.TASK; + if (groupBy && (isChat || isTask)) { + // when we have groupBy on chat or task, we'll show the empty view + return []; + } + + if (isChat) { return getReportActionsSections(data); } - if (type === CONST.SEARCH.DATA_TYPES.TASK) { + if (isTask) { return getTaskSections(data); } From 152dcd2320114db91444fea2a62274998e0094c3 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 11 Jul 2025 15:28:23 +0700 Subject: [PATCH 3/8] move logic filter to search --- src/components/Search/index.tsx | 7 +++++++ src/libs/SearchUIUtils.ts | 4 ---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index ad5adb26afcf9..fdc33fcff9514 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -248,6 +248,13 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS if (searchResults === undefined || !isDataLoaded) { return []; } + + const isChat = type === CONST.SEARCH.DATA_TYPES.CHAT; + const isTask = type === CONST.SEARCH.DATA_TYPES.TASK; + if (groupBy && (isChat || isTask)) { + return []; + } + return getSections(type, status, searchResults.data, searchResults.search, groupBy); }, [searchResults, isDataLoaded, type, status, groupBy]); diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index 83bbf92b9fbc9..06ad3dd0fa420 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -1021,10 +1021,6 @@ function getListItem(type: SearchDataTypes, status: SearchStatus, groupBy?: Sear function getSections(type: SearchDataTypes, status: SearchStatus, data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search'], groupBy?: SearchGroupBy) { const isChat = type === CONST.SEARCH.DATA_TYPES.CHAT; const isTask = type === CONST.SEARCH.DATA_TYPES.TASK; - if (groupBy && (isChat || isTask)) { - // when we have groupBy on chat or task, we'll show the empty view - return []; - } if (isChat) { return getReportActionsSections(data); From d6ea890d3e9940714b46c1a51cde805820d0b3ed Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 17 Jul 2025 14:30:28 +0700 Subject: [PATCH 4/8] add typeguard --- src/components/Search/SearchList.tsx | 36 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/components/Search/SearchList.tsx b/src/components/Search/SearchList.tsx index 3817de4f0819f..15d8c768e6de6 100644 --- a/src/components/Search/SearchList.tsx +++ b/src/components/Search/SearchList.tsx @@ -96,6 +96,14 @@ type SearchListProps = Pick, 'onScroll' | 'conten const keyExtractor = (item: SearchListItem, index: number) => item.keyForList ?? `${index}`; +function isTransactionGroupListItemArray(data: SearchListItem[]): data is TransactionGroupListItemType[] { + if (data.length <= 0) { + return false; + } + const firstElement = data.at(0); + return typeof firstElement === 'object' && 'transactions' in firstElement; +} + function SearchList( { data, @@ -125,19 +133,23 @@ function SearchList( const {initialHeight, initialWidth} = useInitialWindowDimensions(); const {hash, groupBy, type} = queryJSON; - const flattenedTransactions = groupBy ? (data as TransactionGroupListItemType[]).flatMap((item) => item.transactions) : data; - - const flattenedTransactionWithoutPendingDelete = useMemo( - () => flattenedTransactions.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE), - [flattenedTransactions], - ); + const flattenedItems = useMemo(() => { + if (groupBy) { + if (!isTransactionGroupListItemArray(data)) { + return data; + } + return data.flatMap((item) => item.transactions); + } + return []; + }, [data, groupBy]); + const flattenedItemsWithoutPendingDelete = flattenedItems.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); const selectedItemsLength = useMemo( () => - flattenedTransactions.reduce((acc, item) => { + flattenedItems.reduce((acc, item) => { return item?.isSelected ? acc + 1 : acc; }, 0), - [flattenedTransactions], + [flattenedItems], ); const {translate} = useLocalize(); @@ -222,7 +234,7 @@ function SearchList( const [focusedIndex, setFocusedIndex] = useArrowKeyFocusManager({ initialFocusedIndex: -1, - maxIndex: flattenedTransactions.length - 1, + maxIndex: flattenedItems.length - 1, isActive: isFocused, onFocusedIndexChange: (index: number) => { scrollToIndex(index); @@ -352,7 +364,7 @@ function SearchList( const tableHeaderVisible = canSelectMultiple || !!SearchTableHeader; const selectAllButtonVisible = canSelectMultiple && !SearchTableHeader; - const isSelectAllChecked = selectedItemsLength > 0 && selectedItemsLength === flattenedTransactionWithoutPendingDelete.length; + const isSelectAllChecked = selectedItemsLength > 0 && selectedItemsLength === flattenedItemsWithoutPendingDelete.length; const getItemHeight = useMemo( () => @@ -407,11 +419,11 @@ function SearchList( 0 && selectedItemsLength !== flattenedTransactionWithoutPendingDelete.length} + isIndeterminate={selectedItemsLength > 0 && selectedItemsLength !== flattenedItemsWithoutPendingDelete.length} onPress={() => { onAllCheckboxPress(); }} - disabled={flattenedTransactions.length === 0} + disabled={flattenedItems.length === 0} /> )} From 3436c97621e156768aacbe6ce4d11cc7dfe67fe2 Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Fri, 18 Jul 2025 01:09:26 +0700 Subject: [PATCH 5/8] Update src/components/Search/SearchList.tsx Co-authored-by: c3024 <102477862+c3024@users.noreply.github.com> --- src/components/Search/SearchList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/SearchList.tsx b/src/components/Search/SearchList.tsx index 15d8c768e6de6..676d62abc4c1a 100644 --- a/src/components/Search/SearchList.tsx +++ b/src/components/Search/SearchList.tsx @@ -140,7 +140,7 @@ function SearchList( } return data.flatMap((item) => item.transactions); } - return []; + return data; }, [data, groupBy]); const flattenedItemsWithoutPendingDelete = flattenedItems.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); From 7a62fd3f0e042288952fea7e9106ff718b950db7 Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Fri, 18 Jul 2025 01:09:40 +0700 Subject: [PATCH 6/8] Update src/components/Search/SearchList.tsx Co-authored-by: c3024 <102477862+c3024@users.noreply.github.com> --- src/components/Search/SearchList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/SearchList.tsx b/src/components/Search/SearchList.tsx index 676d62abc4c1a..ecbab7fd105bf 100644 --- a/src/components/Search/SearchList.tsx +++ b/src/components/Search/SearchList.tsx @@ -142,7 +142,7 @@ function SearchList( } return data; }, [data, groupBy]); - const flattenedItemsWithoutPendingDelete = flattenedItems.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); + const flattenedItemsWithoutPendingDelete = useMemo(() => flattenedItems.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, [flattenedItems]); const selectedItemsLength = useMemo( () => From 0593e3f3b41f8181c6516dc085116d4cddf93a03 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 18 Jul 2025 01:55:02 +0700 Subject: [PATCH 7/8] fix lint --- src/components/Search/SearchList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/SearchList.tsx b/src/components/Search/SearchList.tsx index ecbab7fd105bf..2db0c985732a3 100644 --- a/src/components/Search/SearchList.tsx +++ b/src/components/Search/SearchList.tsx @@ -142,7 +142,7 @@ function SearchList( } return data; }, [data, groupBy]); - const flattenedItemsWithoutPendingDelete = useMemo(() => flattenedItems.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, [flattenedItems]); + const flattenedItemsWithoutPendingDelete = useMemo(() => flattenedItems.filter((t) => t?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE), [flattenedItems]); const selectedItemsLength = useMemo( () => From 62ec9e930fbdb9a5ce65f9286b6542413fa24cfd Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:09:19 +0700 Subject: [PATCH 8/8] Update src/components/Search/index.tsx Co-authored-by: Vit Horacek <36083550+mountiny@users.noreply.github.com> --- src/components/Search/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 1bc5608bf1c95..9c157fc670a08 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -272,6 +272,7 @@ function Search({queryJSON, searchResults, onSearchListScroll, contentContainerS return []; } + // Group-by option cannot be used for chats or tasks const isChat = type === CONST.SEARCH.DATA_TYPES.CHAT; const isTask = type === CONST.SEARCH.DATA_TYPES.TASK; if (groupBy && (isChat || isTask)) {