From fc7c72669e32e19004bf24bc6dbe7980769b4243 Mon Sep 17 00:00:00 2001 From: Yuwen Memon Date: Mon, 16 Mar 2026 09:16:26 -0700 Subject: [PATCH] =?UTF-8?q?Revert=20"Multi-level=20categories=20with=20col?= =?UTF-8?q?ons=20are=20shown=20with=20hierarchical=20indent=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CONST/index.ts | 2 +- src/libs/CategoryOptionListUtils.ts | 43 +++-- tests/unit/CategoryOptionListUtilsTest.ts | 181 +++++++++++++++++++--- 3 files changed, 192 insertions(+), 34 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index dcff383627eb..1446825c3c13 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -6051,7 +6051,7 @@ const CONST = { PM: 'PM', }, INDENTS: ' ', - PARENT_CHILD_SEPARATOR: ':', + PARENT_CHILD_SEPARATOR: ': ', DISTANCE_MERCHANT_SEPARATOR: '@', COLON: ':', MAPBOX: { diff --git a/src/libs/CategoryOptionListUtils.ts b/src/libs/CategoryOptionListUtils.ts index a28efd7b6a92..595d7ad8b9fa 100644 --- a/src/libs/CategoryOptionListUtils.ts +++ b/src/libs/CategoryOptionListUtils.ts @@ -29,10 +29,30 @@ type Hierarchy = Record | Category[], selectedOptions: Category[] = []): OptionTree[] { +function getCategoryOptionTree(options: Record | Category[], isOneLine = false, selectedOptions: Category[] = []): OptionTree[] { const optionCollection = new Map(); for (const option of Object.values(options)) { + if (isOneLine) { + if (optionCollection.has(option.name)) { + continue; + } + + const decodedCategoryName = getDecodedCategoryName(option.name); + optionCollection.set(option.name, { + text: decodedCategoryName, + keyForList: option.name, + searchText: option.name, + tooltipText: decodedCategoryName, + isDisabled: !option.enabled || option.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + isSelected: !!option.isSelected, + pendingAction: option.pendingAction, + }); + + continue; + } + const array = option.name.split(CONST.PARENT_CHILD_SEPARATOR); for (let index = 0; index < array.length; index++) { @@ -50,14 +70,13 @@ function getCategoryOptionTree(options: Record | Category[], s if (optionCollection.has(searchText)) { continue; } - const leafName = getDecodedCategoryName(optionName.trim()); - const decodedCategoryName = getDecodedCategoryName(option.name); - const tooltipText = isChild ? decodedCategoryName : getDecodedCategoryName(searchText); + + const decodedCategoryName = getDecodedCategoryName(optionName); optionCollection.set(searchText, { - text: `${indents}${leafName}`, + text: `${indents}${decodedCategoryName}`, keyForList: searchText, searchText, - tooltipText, + tooltipText: decodedCategoryName, isDisabled: isChild ? !option.enabled || option.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : isParentOptionDisabled, isSelected: isChild ? !!option.isSelected : !!selectedParentOption, pendingAction: option.pendingAction, @@ -105,7 +124,7 @@ function getCategoryListSections({ } if (numberOfEnabledCategories === 0 && selectedOptions.length > 0) { - const data = getCategoryOptionTree(selectedOptionsWithDisabledState); + const data = getCategoryOptionTree(selectedOptionsWithDisabledState, true); categorySections.push({ // "Selected" section title: '', @@ -124,7 +143,7 @@ function getCategoryListSections({ isSelected: selectedOptions.some((selectedOption) => selectedOption.name === category.name), })); - const data = getCategoryOptionTree(searchCategories); + const data = getCategoryOptionTree(searchCategories, true); categorySections.push({ // "Search" section title: '', @@ -136,7 +155,7 @@ function getCategoryListSections({ } if (selectedOptions.length > 0) { - const data = getCategoryOptionTree(selectedOptionsWithDisabledState); + const data = getCategoryOptionTree(selectedOptionsWithDisabledState, true); categorySections.push({ // "Selected" section title: '', @@ -149,7 +168,7 @@ function getCategoryListSections({ const filteredCategories = enabledCategories.filter((category) => !selectedOptionNames.has(category.name)); if (numberOfEnabledCategories < CONST.STANDARD_LIST_ITEM_LIMIT) { - const data = getCategoryOptionTree(filteredCategories, selectedOptionsWithDisabledState); + const data = getCategoryOptionTree(filteredCategories, false, selectedOptionsWithDisabledState); categorySections.push({ // "All" section when items amount less than the threshold title: '', @@ -173,7 +192,7 @@ function getCategoryListSections({ if (filteredRecentlyUsedCategories.length > 0) { const cutRecentlyUsedCategories = filteredRecentlyUsedCategories.slice(0, maxRecentReportsToShow); - const data = getCategoryOptionTree(cutRecentlyUsedCategories); + const data = getCategoryOptionTree(cutRecentlyUsedCategories, true); categorySections.push({ // "Recent" section title: translate('common.recent'), @@ -182,7 +201,7 @@ function getCategoryListSections({ }); } - const data = getCategoryOptionTree(filteredCategories, selectedOptionsWithDisabledState); + const data = getCategoryOptionTree(filteredCategories, false, selectedOptionsWithDisabledState); categorySections.push({ // "All" section when items amount more than the threshold title: translate('common.all'), diff --git a/tests/unit/CategoryOptionListUtilsTest.ts b/tests/unit/CategoryOptionListUtilsTest.ts index ada043b7510c..ec10284f052b 100644 --- a/tests/unit/CategoryOptionListUtilsTest.ts +++ b/tests/unit/CategoryOptionListUtilsTest.ts @@ -104,7 +104,7 @@ describe('CategoryOptionListUtils', () => { text: ' Meat', keyForList: 'Food: Meat', searchText: 'Food: Meat', - tooltipText: 'Food: Meat', + tooltipText: 'Meat', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -136,7 +136,7 @@ describe('CategoryOptionListUtils', () => { pendingAction: undefined, }, { - text: ' Meat', + text: 'Food: Meat', keyForList: 'Food: Meat', searchText: 'Food: Meat', tooltipText: 'Food: Meat', @@ -357,7 +357,7 @@ describe('CategoryOptionListUtils', () => { text: ' Audi', keyForList: 'Cars: Audi', searchText: 'Cars: Audi', - tooltipText: 'Cars: Audi', + tooltipText: 'Audi', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -366,7 +366,7 @@ describe('CategoryOptionListUtils', () => { text: ' Mercedes-Benz', keyForList: 'Cars: Mercedes-Benz', searchText: 'Cars: Mercedes-Benz', - tooltipText: 'Cars: Mercedes-Benz', + tooltipText: 'Mercedes-Benz', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -393,7 +393,7 @@ describe('CategoryOptionListUtils', () => { text: ' Meat', keyForList: 'Food: Meat', searchText: 'Food: Meat', - tooltipText: 'Food: Meat', + tooltipText: 'Meat', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -402,7 +402,7 @@ describe('CategoryOptionListUtils', () => { text: ' Milk', keyForList: 'Food: Milk', searchText: 'Food: Milk', - tooltipText: 'Food: Milk', + tooltipText: 'Milk', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -438,7 +438,7 @@ describe('CategoryOptionListUtils', () => { text: ' Meals', keyForList: 'Travel: Meals', searchText: 'Travel: Meals', - tooltipText: 'Travel: Meals', + tooltipText: 'Meals', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -447,7 +447,7 @@ describe('CategoryOptionListUtils', () => { text: ' Breakfast', keyForList: 'Travel: Meals: Breakfast', searchText: 'Travel: Meals: Breakfast', - tooltipText: 'Travel: Meals: Breakfast', + tooltipText: 'Breakfast', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -456,7 +456,7 @@ describe('CategoryOptionListUtils', () => { text: ' Lunch', keyForList: 'Travel: Meals: Lunch', searchText: 'Travel: Meals: Lunch', - tooltipText: 'Travel: Meals: Lunch', + tooltipText: 'Lunch', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -488,7 +488,7 @@ describe('CategoryOptionListUtils', () => { pendingAction: undefined, }, { - text: ' Meat', + text: 'Food: Meat', keyForList: 'Food: Meat', searchText: 'Food: Meat', tooltipText: 'Food: Meat', @@ -497,7 +497,7 @@ describe('CategoryOptionListUtils', () => { pendingAction: undefined, }, { - text: ' Milk', + text: 'Food: Milk', keyForList: 'Food: Milk', searchText: 'Food: Milk', tooltipText: 'Food: Milk', @@ -698,7 +698,7 @@ describe('CategoryOptionListUtils', () => { text: ' Meat', keyForList: 'Food: Meat', searchText: 'Food: Meat', - tooltipText: 'Food: Meat', + tooltipText: 'Meat', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -707,7 +707,7 @@ describe('CategoryOptionListUtils', () => { text: ' Milk', keyForList: 'Food: Milk', searchText: 'Food: Milk', - tooltipText: 'Food: Milk', + tooltipText: 'Milk', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -725,7 +725,7 @@ describe('CategoryOptionListUtils', () => { text: ' Audi', keyForList: 'Cars: Audi', searchText: 'Cars: Audi', - tooltipText: 'Cars: Audi', + tooltipText: 'Audi', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -734,7 +734,7 @@ describe('CategoryOptionListUtils', () => { text: ' Mercedes-Benz', keyForList: 'Cars: Mercedes-Benz', searchText: 'Cars: Mercedes-Benz', - tooltipText: 'Cars: Mercedes-Benz', + tooltipText: 'Mercedes-Benz', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -752,7 +752,7 @@ describe('CategoryOptionListUtils', () => { text: ' Meals', keyForList: 'Travel: Meals', searchText: 'Travel: Meals', - tooltipText: 'Travel: Meals', + tooltipText: 'Meals', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -761,7 +761,7 @@ describe('CategoryOptionListUtils', () => { text: ' Breakfast', keyForList: 'Travel: Meals: Breakfast', searchText: 'Travel: Meals: Breakfast', - tooltipText: 'Travel: Meals: Breakfast', + tooltipText: 'Breakfast', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -770,7 +770,7 @@ describe('CategoryOptionListUtils', () => { text: ' Lunch', keyForList: 'Travel: Meals: Lunch', searchText: 'Travel: Meals: Lunch', - tooltipText: 'Travel: Meals: Lunch', + tooltipText: 'Lunch', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -815,7 +815,7 @@ describe('CategoryOptionListUtils', () => { text: ' B', keyForList: 'A: B', searchText: 'A: B', - tooltipText: 'A: B', + tooltipText: 'B', isDisabled: true, isSelected: false, pendingAction: undefined, @@ -824,7 +824,7 @@ describe('CategoryOptionListUtils', () => { text: ' C', keyForList: 'A: B: C', searchText: 'A: B: C', - tooltipText: 'A: B: C', + tooltipText: 'C', isDisabled: false, isSelected: false, pendingAction: undefined, @@ -833,7 +833,7 @@ describe('CategoryOptionListUtils', () => { text: ' D', keyForList: 'A: B: C: D', searchText: 'A: B: C: D', - tooltipText: 'A: B: C: D', + tooltipText: 'D', isDisabled: true, isSelected: false, pendingAction: undefined, @@ -842,13 +842,152 @@ describe('CategoryOptionListUtils', () => { text: ' E', keyForList: 'A: B: C: D: E', searchText: 'A: B: C: D: E', + tooltipText: 'E', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + ]; + const resultOneLine = [ + { + text: 'Meals', + keyForList: 'Meals', + searchText: 'Meals', + tooltipText: 'Meals', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Restaurant', + keyForList: 'Restaurant', + searchText: 'Restaurant', + tooltipText: 'Restaurant', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Food', + keyForList: 'Food', + searchText: 'Food', + tooltipText: 'Food', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Food: Meat', + keyForList: 'Food: Meat', + searchText: 'Food: Meat', + tooltipText: 'Food: Meat', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Food: Milk', + keyForList: 'Food: Milk', + searchText: 'Food: Milk', + tooltipText: 'Food: Milk', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Cars: Audi', + keyForList: 'Cars: Audi', + searchText: 'Cars: Audi', + tooltipText: 'Cars: Audi', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Cars: Mercedes-Benz', + keyForList: 'Cars: Mercedes-Benz', + searchText: 'Cars: Mercedes-Benz', + tooltipText: 'Cars: Mercedes-Benz', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Travel: Meals', + keyForList: 'Travel: Meals', + searchText: 'Travel: Meals', + tooltipText: 'Travel: Meals', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Travel: Meals: Breakfast', + keyForList: 'Travel: Meals: Breakfast', + searchText: 'Travel: Meals: Breakfast', + tooltipText: 'Travel: Meals: Breakfast', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Travel: Meals: Lunch', + keyForList: 'Travel: Meals: Lunch', + searchText: 'Travel: Meals: Lunch', + tooltipText: 'Travel: Meals: Lunch', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Plain', + keyForList: 'Plain', + searchText: 'Plain', + tooltipText: 'Plain', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Audi', + keyForList: 'Audi', + searchText: 'Audi', + tooltipText: 'Audi', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'Health', + keyForList: 'Health', + searchText: 'Health', + tooltipText: 'Health', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'A: B: C', + keyForList: 'A: B: C', + searchText: 'A: B: C', + tooltipText: 'A: B: C', + isDisabled: false, + isSelected: false, + pendingAction: undefined, + }, + { + text: 'A: B: C: D: E', + keyForList: 'A: B: C: D: E', + searchText: 'A: B: C: D: E', tooltipText: 'A: B: C: D: E', isDisabled: false, isSelected: false, pendingAction: undefined, }, ]; + expect(getCategoryOptionTree(categories)).toStrictEqual(result); + expect(getCategoryOptionTree(categories, true)).toStrictEqual(resultOneLine); }); it('sortCategories', () => {