From cf7a891741ab32821d1aa9489ac8db9d92e3d0dc Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 23 Mar 2024 12:59:59 +0700 Subject: [PATCH 01/10] Implement underscore's sort for tag, ensure consistent with oldDot --- src/libs/OptionsListUtils.ts | 6 +- .../workspace/tags/WorkspaceTagsPage.tsx | 56 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 0f83b260c8f2..8715cf2c8ca2 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -53,6 +53,7 @@ import * as ReportUtils from './ReportUtils'; import * as TaskUtils from './TaskUtils'; import * as TransactionUtils from './TransactionUtils'; import * as UserUtils from './UserUtils'; +import _ from 'underscore'; type Tag = { enabled: boolean; @@ -920,14 +921,13 @@ function sortTags(tags: Record | Tag[]) { let sortedTags; if (Array.isArray(tags)) { - sortedTags = tags.sort((a, b) => localeCompare(a.name, b.name)); + sortedTags = _.sortBy(tags, 'name'); } else { - sortedTags = Object.values(tags).sort((a, b) => localeCompare(a.name, b.name)); + sortedTags = _.sortBy(Object.values(tags), 'name'); } return sortedTags; } - /** * Builds the options for the category tree hierarchy via indents * diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index f764f8d8e987..77d7842e6b1f 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -36,6 +36,8 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; +import _ from 'underscore'; + type PolicyForList = { value: string; @@ -80,35 +82,33 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]); const tagList = useMemo( - () => - policyTagLists - .map((policyTagList) => - Object.values(policyTagList.tags || []) - .sort((a, b) => localeCompare(a.name, b.name)) - .map((value) => ({ - value: value.name, - text: value.name, - keyForList: value.name, - isSelected: !!selectedTags[value.name], - pendingAction: value.pendingAction, - errors: value.errors ?? undefined, - enabled: value.enabled, - rightElement: ( - - - {value.enabled ? translate('workspace.common.enabled') : translate('workspace.common.disabled')} - - - - + () => policyTagLists + .map((policyTagList) => + _.sortBy(Object.values(policyTagList.tags || []), 'name') + .map((value) => ({ + value: value.name, + text: value.name, + keyForList: value.name, + isSelected: !!selectedTags[value.name], + pendingAction: value.pendingAction, + errors: value.errors ?? undefined, + enabled: value.enabled, + rightElement: ( + + + {value.enabled ? translate('workspace.common.enabled') : translate('workspace.common.disabled')} + + + - ), - })), - ) - .flat(), + + ), + })), + ) + .flat(), [policyTagLists, selectedTags, styles.alignSelfCenter, styles.flexRow, styles.label, styles.p1, styles.pl2, styles.textSupporting, theme.icon, translate], ); From 326538094c1d520035359907ed534b3f31ae9c46 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 23 Mar 2024 13:34:49 +0700 Subject: [PATCH 02/10] Include localeCompare --- src/libs/OptionsListUtils.ts | 10 ++-------- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 8715cf2c8ca2..716d2b70dbd0 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -918,14 +918,8 @@ function sortCategories(categories: Record): Category[] { * Sorts tags alphabetically by name. */ function sortTags(tags: Record | Tag[]) { - let sortedTags; - - if (Array.isArray(tags)) { - sortedTags = _.sortBy(tags, 'name'); - } else { - sortedTags = _.sortBy(Object.values(tags), 'name'); - } - + const tagsArray = Array.isArray(tags) ? tags : Object.values(tags); + const sortedTags = _.sortBy(tagsArray, 'name', localeCompare); return sortedTags; } /** diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 77d7842e6b1f..560e81042408 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -84,7 +84,7 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { const tagList = useMemo( () => policyTagLists .map((policyTagList) => - _.sortBy(Object.values(policyTagList.tags || []), 'name') + _.sortBy(Object.values(policyTagList.tags || []), 'name', localeCompare) .map((value) => ({ value: value.name, text: value.name, From 8a3ea16f21058474b484df7af73640bbdb807044 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 25 Mar 2024 14:43:55 +0700 Subject: [PATCH 03/10] fix sort tags, remove localCompate --- src/libs/OptionsListUtils.ts | 7 ++++--- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 716d2b70dbd0..9611e97e3de2 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -53,7 +53,6 @@ import * as ReportUtils from './ReportUtils'; import * as TaskUtils from './TaskUtils'; import * as TransactionUtils from './TransactionUtils'; import * as UserUtils from './UserUtils'; -import _ from 'underscore'; type Tag = { enabled: boolean; @@ -919,9 +918,11 @@ function sortCategories(categories: Record): Category[] { */ function sortTags(tags: Record | Tag[]) { const tagsArray = Array.isArray(tags) ? tags : Object.values(tags); - const sortedTags = _.sortBy(tagsArray, 'name', localeCompare); - return sortedTags; + + // Use lodash's sortBy to ensure consistency with oldDot + return lodashSortBy(tagsArray, 'name'); } + /** * Builds the options for the category tree hierarchy via indents * diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 560e81042408..40a1f741084e 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -36,7 +36,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import _ from 'underscore'; +import lodashSortBy from 'lodash/sortBy'; type PolicyForList = { @@ -84,7 +84,7 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { const tagList = useMemo( () => policyTagLists .map((policyTagList) => - _.sortBy(Object.values(policyTagList.tags || []), 'name', localeCompare) + lodashSortBy(Object.values(policyTagList.tags || []), 'name') .map((value) => ({ value: value.name, text: value.name, From 4f910e860eaf5fb2e956907317f76b9153b4c340 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 25 Mar 2024 16:51:46 +0700 Subject: [PATCH 04/10] Add unit test of sortTags --- src/libs/OptionsListUtils.ts | 3 ++- .../workspace/tags/WorkspaceTagsPage.tsx | 2 +- tests/unit/OptionsListUtilsTest.js | 23 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 9611e97e3de2..a954860f16eb 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -920,7 +920,7 @@ function sortTags(tags: Record | Tag[]) { const tagsArray = Array.isArray(tags) ? tags : Object.values(tags); // Use lodash's sortBy to ensure consistency with oldDot - return lodashSortBy(tagsArray, 'name'); + return lodashSortBy(tagsArray, 'name', localeCompare); } /** @@ -2094,6 +2094,7 @@ export { getEnabledCategoriesCount, hasEnabledOptions, sortCategories, + sortTags, getCategoryOptionTree, hasEnabledTags, formatMemberForList, diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 40a1f741084e..c68b281b5e31 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -84,7 +84,7 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { const tagList = useMemo( () => policyTagLists .map((policyTagList) => - lodashSortBy(Object.values(policyTagList.tags || []), 'name') + lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare) .map((value) => ({ value: value.name, text: value.name, diff --git a/tests/unit/OptionsListUtilsTest.js b/tests/unit/OptionsListUtilsTest.js index 7244b7830a29..246a99ef4af6 100644 --- a/tests/unit/OptionsListUtilsTest.js +++ b/tests/unit/OptionsListUtilsTest.js @@ -2058,6 +2058,29 @@ describe('OptionsListUtils', () => { expect(OptionsListUtils.sortCategories(categoriesIncorrectOrdering3)).toStrictEqual(result3); }); + it('sortTags', () => { + const createTagObjects = (names) => names.map(name => ({ name, enabled: true })); + + const unorderedTagNames = ['10bc', 'b', '0a', '1', '中国', 'b10', '!', '2', '0', '@', 'a1', 'a', '3', 'b1', '日本', '$', '20', '20a', '#', 'a20', 'c', '10' ]; + const expectedOrderNames = ["!", "#", "$", "0", "0a", "1", "10", "10bc", "2", "20", "20a", "3", "@", "a", "a1", "a20", "b", "b1", "b10", "c", "中国", "日本"]; + const unorderedTags = createTagObjects(unorderedTagNames); + const expectedOrder = createTagObjects(expectedOrderNames); + expect(OptionsListUtils.sortTags(unorderedTags)).toStrictEqual(expectedOrder); + + const unorderedTagNames2 = ['0', 'a1', '1', 'b1', '3', '10', 'b10', 'a', '2', 'c', '20', 'a20', 'b']; + const expectedOrderNames2 = ["0", "1", "10", "2", "20", "3", "a", "a1", "a20", "b", "b1", "b10", "c"]; + const unorderedTags2 = createTagObjects(unorderedTagNames2); + const expectedOrder2 = createTagObjects(expectedOrderNames2); + expect(OptionsListUtils.sortTags(unorderedTags2)).toStrictEqual(expectedOrder2); + + const unorderedTagNames3 = ['61', '39', '97', '93', '77', '71', '22', '27', '30', '64', '91', '24', '33', '60', '21', '85', '59', '76', '42', '67', '13', '96', '84', '44', '68', '31', '62', '87', '50', '4', '100', '12', '28', '49', '53', '5', '45', '14', '55', '78', '11', '35', '75', '18', '9', '80', '54', '2', '34', '48', '81', '6', '73', '15', '98', '25', '8', '99', '17', '90', '47', '1', '10', '38', '66', '57', '23', '86', '29', '3', '65', '74', '19', '56', '63', '20', '7', '32', '46', '70', '26', '16', '83', '37', '58', '43', '36', '69', '79', '72', '41', '94', '95', '82', '51', '52', '89', '88', '40', '92']; + const expectedOrderNames3 = ['1', '10', '100', '11', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '3', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '4', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '5', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '6', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '7', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '8', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '9', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99']; + const unorderedTags3 = createTagObjects(unorderedTagNames3); + const expectedOrder3 = createTagObjects(expectedOrderNames3); + expect(OptionsListUtils.sortTags(unorderedTags3)).toStrictEqual(expectedOrder3); + }); + + it('getFilteredOptions() for taxRate', () => { const search = 'rate'; const emptySearch = ''; From 4578af6c85c032b1e2c205a6e9667020c944b7f3 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 25 Mar 2024 16:58:37 +0700 Subject: [PATCH 05/10] adjust test case --- tests/unit/OptionsListUtilsTest.js | 215 ++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 7 deletions(-) diff --git a/tests/unit/OptionsListUtilsTest.js b/tests/unit/OptionsListUtilsTest.js index 246a99ef4af6..2f3e65c0c384 100644 --- a/tests/unit/OptionsListUtilsTest.js +++ b/tests/unit/OptionsListUtilsTest.js @@ -2059,28 +2059,229 @@ describe('OptionsListUtils', () => { }); it('sortTags', () => { - const createTagObjects = (names) => names.map(name => ({ name, enabled: true })); + const createTagObjects = (names) => _.map(names, (name) => ({name, enabled: true})); - const unorderedTagNames = ['10bc', 'b', '0a', '1', '中国', 'b10', '!', '2', '0', '@', 'a1', 'a', '3', 'b1', '日本', '$', '20', '20a', '#', 'a20', 'c', '10' ]; - const expectedOrderNames = ["!", "#", "$", "0", "0a", "1", "10", "10bc", "2", "20", "20a", "3", "@", "a", "a1", "a20", "b", "b1", "b10", "c", "中国", "日本"]; + const unorderedTagNames = ['10bc', 'b', '0a', '1', '中国', 'b10', '!', '2', '0', '@', 'a1', 'a', '3', 'b1', '日本', '$', '20', '20a', '#', 'a20', 'c', '10']; + const expectedOrderNames = ['!', '#', '$', '0', '0a', '1', '10', '10bc', '2', '20', '20a', '3', '@', 'a', 'a1', 'a20', 'b', 'b1', 'b10', 'c', '中国', '日本']; const unorderedTags = createTagObjects(unorderedTagNames); const expectedOrder = createTagObjects(expectedOrderNames); expect(OptionsListUtils.sortTags(unorderedTags)).toStrictEqual(expectedOrder); const unorderedTagNames2 = ['0', 'a1', '1', 'b1', '3', '10', 'b10', 'a', '2', 'c', '20', 'a20', 'b']; - const expectedOrderNames2 = ["0", "1", "10", "2", "20", "3", "a", "a1", "a20", "b", "b1", "b10", "c"]; + const expectedOrderNames2 = ['0', '1', '10', '2', '20', '3', 'a', 'a1', 'a20', 'b', 'b1', 'b10', 'c']; const unorderedTags2 = createTagObjects(unorderedTagNames2); const expectedOrder2 = createTagObjects(expectedOrderNames2); expect(OptionsListUtils.sortTags(unorderedTags2)).toStrictEqual(expectedOrder2); - const unorderedTagNames3 = ['61', '39', '97', '93', '77', '71', '22', '27', '30', '64', '91', '24', '33', '60', '21', '85', '59', '76', '42', '67', '13', '96', '84', '44', '68', '31', '62', '87', '50', '4', '100', '12', '28', '49', '53', '5', '45', '14', '55', '78', '11', '35', '75', '18', '9', '80', '54', '2', '34', '48', '81', '6', '73', '15', '98', '25', '8', '99', '17', '90', '47', '1', '10', '38', '66', '57', '23', '86', '29', '3', '65', '74', '19', '56', '63', '20', '7', '32', '46', '70', '26', '16', '83', '37', '58', '43', '36', '69', '79', '72', '41', '94', '95', '82', '51', '52', '89', '88', '40', '92']; - const expectedOrderNames3 = ['1', '10', '100', '11', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '3', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '4', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '5', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '6', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '7', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '8', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '9', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99']; + const unorderedTagNames3 = [ + '61', + '39', + '97', + '93', + '77', + '71', + '22', + '27', + '30', + '64', + '91', + '24', + '33', + '60', + '21', + '85', + '59', + '76', + '42', + '67', + '13', + '96', + '84', + '44', + '68', + '31', + '62', + '87', + '50', + '4', + '100', + '12', + '28', + '49', + '53', + '5', + '45', + '14', + '55', + '78', + '11', + '35', + '75', + '18', + '9', + '80', + '54', + '2', + '34', + '48', + '81', + '6', + '73', + '15', + '98', + '25', + '8', + '99', + '17', + '90', + '47', + '1', + '10', + '38', + '66', + '57', + '23', + '86', + '29', + '3', + '65', + '74', + '19', + '56', + '63', + '20', + '7', + '32', + '46', + '70', + '26', + '16', + '83', + '37', + '58', + '43', + '36', + '69', + '79', + '72', + '41', + '94', + '95', + '82', + '51', + '52', + '89', + '88', + '40', + '92', + ]; + const expectedOrderNames3 = [ + '1', + '10', + '100', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '2', + '20', + '21', + '22', + '23', + '24', + '25', + '26', + '27', + '28', + '29', + '3', + '30', + '31', + '32', + '33', + '34', + '35', + '36', + '37', + '38', + '39', + '4', + '40', + '41', + '42', + '43', + '44', + '45', + '46', + '47', + '48', + '49', + '5', + '50', + '51', + '52', + '53', + '54', + '55', + '56', + '57', + '58', + '59', + '6', + '60', + '61', + '62', + '63', + '64', + '65', + '66', + '67', + '68', + '69', + '7', + '70', + '71', + '72', + '73', + '74', + '75', + '76', + '77', + '78', + '79', + '8', + '80', + '81', + '82', + '83', + '84', + '85', + '86', + '87', + '88', + '89', + '9', + '90', + '91', + '92', + '93', + '94', + '95', + '96', + '97', + '98', + '99', + ]; const unorderedTags3 = createTagObjects(unorderedTagNames3); const expectedOrder3 = createTagObjects(expectedOrderNames3); expect(OptionsListUtils.sortTags(unorderedTags3)).toStrictEqual(expectedOrder3); }); - it('getFilteredOptions() for taxRate', () => { const search = 'rate'; const emptySearch = ''; From 448f6b43107461031cc1b5610ae86b56deffeb0c Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 26 Mar 2024 00:10:15 +0700 Subject: [PATCH 06/10] run prettier --- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index c68b281b5e31..208d92df0a51 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -1,4 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; +import lodashSortBy from 'lodash/sortBy'; import React, {useEffect, useMemo, useRef, useState} from 'react'; import {ActivityIndicator, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -36,8 +37,6 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import lodashSortBy from 'lodash/sortBy'; - type PolicyForList = { value: string; @@ -82,10 +81,10 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]); const tagList = useMemo( - () => policyTagLists - .map((policyTagList) => - lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare) - .map((value) => ({ + () => + policyTagLists + .map((policyTagList) => + lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare).map((value) => ({ value: value.name, text: value.name, keyForList: value.name, @@ -107,8 +106,8 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { ), })), - ) - .flat(), + ) + .flat(), [policyTagLists, selectedTags, styles.alignSelfCenter, styles.flexRow, styles.label, styles.p1, styles.pl2, styles.textSupporting, theme.icon, translate], ); From 8e017bab031077f0cfed3a7cd2e11cbc919548ce Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 26 Mar 2024 00:54:53 +0700 Subject: [PATCH 07/10] fix policytag type guard --- .../workspace/tags/WorkspaceTagsPage.tsx | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 208d92df0a51..8ef3a60e1064 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -36,6 +36,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; +import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; type PolicyForList = { @@ -78,34 +79,35 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { fetchTags(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]); const tagList = useMemo( () => policyTagLists .map((policyTagList) => - lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare).map((value) => ({ - value: value.name, - text: value.name, - keyForList: value.name, - isSelected: !!selectedTags[value.name], - pendingAction: value.pendingAction, - errors: value.errors ?? undefined, - enabled: value.enabled, - rightElement: ( - - - {value.enabled ? translate('workspace.common.enabled') : translate('workspace.common.disabled')} - - - + lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare) + .filter((value): value is OnyxCommon.OnyxValueWithOfflineFeedback => typeof value === 'object' && value !== null) + .map((value) => ({ + value: value.name, + text: value.name, + keyForList: value.name, + isSelected: !!selectedTags[value.name], + pendingAction: value.pendingAction, + errors: value.errors ?? undefined, + enabled: value.enabled, + rightElement: ( + + + {value.enabled ? translate('workspace.common.enabled') : translate('workspace.common.disabled')} + + + + - - ), - })), + ), + })), ) .flat(), [policyTagLists, selectedTags, styles.alignSelfCenter, styles.flexRow, styles.label, styles.p1, styles.pl2, styles.textSupporting, theme.icon, translate], From 872e99b19accb264995965a465d47d13fb12a5fa Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 26 Mar 2024 01:17:11 +0700 Subject: [PATCH 08/10] Handle weird ts error in github action --- src/libs/OptionsListUtils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index ce76dfdac7b2..43652ec87262 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -919,8 +919,12 @@ function sortCategories(categories: Record): Category[] { function sortTags(tags: Record | Tag[]) { const tagsArray = Array.isArray(tags) ? tags : Object.values(tags); - // Use lodash's sortBy to ensure consistency with oldDot - return lodashSortBy(tagsArray, 'name', localeCompare); + // Use lodash's sortBy to ensure consistency with oldDot. + return lodashSortBy( + tagsArray.filter((tag) => 'name' in tag), + 'name', + localeCompare, + ); } /** From 12b10507e88efd19d3fd388ce790e256ad05256b Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 26 Mar 2024 05:50:52 +0700 Subject: [PATCH 09/10] fix typecheck error --- src/libs/OptionsListUtils.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 43652ec87262..ac975d11fce7 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -920,11 +920,7 @@ function sortTags(tags: Record | Tag[]) { const tagsArray = Array.isArray(tags) ? tags : Object.values(tags); // Use lodash's sortBy to ensure consistency with oldDot. - return lodashSortBy( - tagsArray.filter((tag) => 'name' in tag), - 'name', - localeCompare, - ); + return lodashSortBy(tagsArray, 'name', localeCompare) as Tag[]; } /** From c870552791466ff2e6f6e349de88760393ee1a59 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Wed, 27 Mar 2024 07:39:14 +0700 Subject: [PATCH 10/10] change typescript type pattern --- .../workspace/tags/WorkspaceTagsPage.tsx | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 2107fbb6ac5c..54cbe27b67d4 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -84,34 +84,33 @@ function WorkspaceTagsPage({policyTags, route}: WorkspaceTagsPageProps) { () => policyTagLists .map((policyTagList) => - lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare) - .filter((value): value is OnyxCommon.OnyxValueWithOfflineFeedback => typeof value === 'object' && value !== null) - .map((value) => { - const isDisabled = value.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; - return { - value: value.name, - text: value.name, - keyForList: value.name, - isSelected: !!selectedTags[value.name], - pendingAction: value.pendingAction, - errors: value.errors ?? undefined, - enabled: value.enabled, - isDisabled, - rightElement: ( - - - {value.enabled ? translate('workspace.common.enabled') : translate('workspace.common.disabled')} - - - - + lodashSortBy(Object.values(policyTagList.tags || []), 'name', localeCompare).map((value) => { + const tag = value as OnyxCommon.OnyxValueWithOfflineFeedback; + const isDisabled = tag.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; + return { + value: tag.name, + text: tag.name, + keyForList: tag.name, + isSelected: !!selectedTags[tag.name], + pendingAction: tag.pendingAction, + errors: tag.errors ?? undefined, + enabled: tag.enabled, + isDisabled, + rightElement: ( + + + {tag.enabled ? translate('workspace.common.enabled') : translate('workspace.common.disabled')} + + + - ), - }; - }), + + ), + }; + }), ) .flat(), [policyTagLists, selectedTags, styles.alignSelfCenter, styles.flexRow, styles.label, styles.p1, styles.pl2, styles.textSupporting, theme.icon, translate],