From 609876bbb3c11f13a5dbb0a6daca1e6acb526098 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 16 Jan 2024 02:41:11 -0700 Subject: [PATCH 1/6] Migrated to TypeScript. --- src/components/TagPicker.tsx | 132 ++++++++++++++++++ src/components/TagPicker/index.js | 94 ------------- .../TagPicker/tagPickerPropTypes.js | 41 ------ src/libs/PolicyUtils.ts | 5 +- 4 files changed, 134 insertions(+), 138 deletions(-) create mode 100644 src/components/TagPicker.tsx delete mode 100644 src/components/TagPicker/index.js delete mode 100644 src/components/TagPicker/tagPickerPropTypes.js diff --git a/src/components/TagPicker.tsx b/src/components/TagPicker.tsx new file mode 100644 index 000000000000..868fe7776567 --- /dev/null +++ b/src/components/TagPicker.tsx @@ -0,0 +1,132 @@ +import {useMemo, useState} from 'react'; +import type {OnyxCollection} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; +import useLocalize from '@hooks/useLocalize'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {PolicyTags, RecentlyUsedTags} from '@src/types/onyx'; +import OptionsSelector from './OptionsSelector'; + +type TagPickerOnyxProps = { + /** Collection of tags attached to a policy */ + policyTags: OnyxCollection; + + /** List of recently used tags */ + policyRecentlyUsedTags: OnyxCollection; + + /** Should show the selected option that is disabled? */ + shouldShowDisabledAndSelectedOption?: boolean; +}; + +type TagPickerProps = TagPickerOnyxProps & { + /** The policyID we are getting tags for */ + // eslint-disable-next-line react/no-unused-prop-types + policyID: string; + + /** The selected tag of the money request */ + selectedTag: string; + + /** The name of tag list we are getting tags for */ + tag: string; + + /** Callback to submit the selected tag */ + onSubmit: () => void; + + /** + * Safe area insets required for reflecting the portion of the view, + * that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. + */ + insets: Record; +}; + +function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, shouldShowDisabledAndSelectedOption, insets, onSubmit}: TagPickerProps) { + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); + const {translate} = useLocalize(); + const [searchValue, setSearchValue] = useState(''); + + const policyTagList = PolicyUtils.getTagList(policyTags, tag); + const policyTagsCount = Object.values(policyTagList).filter((policyTag) => policyTag.enabled).length; + const isTagsCountBelowThreshold = policyTagsCount < CONST.TAG_LIST_THRESHOLD; + + const shouldShowTextInput = !isTagsCountBelowThreshold; + + const selectedOptions = useMemo(() => { + if (!selectedTag) { + return []; + } + + return [ + { + name: selectedTag, + enabled: true, + accountID: null, + }, + ]; + }, [selectedTag]); + + const enabledTags = useMemo(() => { + if (!shouldShowDisabledAndSelectedOption) { + return policyTagList; + } + const selectedNames = selectedOptions.map((s) => s.name); + const tags = [...selectedOptions, ...Object.values(policyTagList).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; + + return tags; + }, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]); + + // + const sections = useMemo(() => { + const policyRecentlyUsedTagsList = policyRecentlyUsedTags?.tag ?? []; + + // TODO: Remove this and one line under once OptionsListUtils (https://github.com/Expensify/App/issues/24921) is migrated to TypeScript. + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return ( + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/issues/24921) is migrated to TypeScript. + OptionsListUtils.getFilteredOptions({}, {}, [], searchValue, selectedOptions, [], false, false, false, {}, [], true, enabledTags, policyRecentlyUsedTagsList, false).tagOptions + ); + }, [searchValue, enabledTags, selectedOptions, policyRecentlyUsedTags?.tag]); + + const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList((sections?.[0]?.data?.length ?? 0) > 0, searchValue); + + // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/issues/24921) is migrated to TypeScript. + const selectedOptionKey = sections[0]?.data?.filter((policyTag) => policyTag.searchText === selectedTag)?.[0]?.keyForList; + + return ( + + ); +} + +TagPicker.displayName = 'TagPicker'; + +export default withOnyx({ + policyTags: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}` as typeof ONYXKEYS.COLLECTION.POLICY_TAGS, + }, + policyRecentlyUsedTags: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}` as typeof ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS, + }, +})(TagPicker); diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js deleted file mode 100644 index e258472eae93..000000000000 --- a/src/components/TagPicker/index.js +++ /dev/null @@ -1,94 +0,0 @@ -import lodashGet from 'lodash/get'; -import React, {useMemo, useState} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; -import OptionsSelector from '@components/OptionsSelector'; -import useLocalize from '@hooks/useLocalize'; -import useStyleUtils from '@hooks/useStyleUtils'; -import useThemeStyles from '@hooks/useThemeStyles'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as PolicyUtils from '@libs/PolicyUtils'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import {defaultProps, propTypes} from './tagPickerPropTypes'; - -function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, shouldShowDisabledAndSelectedOption, insets, onSubmit}) { - const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); - const {translate} = useLocalize(); - const [searchValue, setSearchValue] = useState(''); - - const policyRecentlyUsedTagsList = lodashGet(policyRecentlyUsedTags, tag, []); - const policyTagList = PolicyUtils.getTagList(policyTags, tag); - const policyTagsCount = _.size(_.filter(policyTagList, (policyTag) => policyTag.enabled)); - const isTagsCountBelowThreshold = policyTagsCount < CONST.TAG_LIST_THRESHOLD; - - const shouldShowTextInput = !isTagsCountBelowThreshold; - - const selectedOptions = useMemo(() => { - if (!selectedTag) { - return []; - } - - return [ - { - name: selectedTag, - enabled: true, - accountID: null, - }, - ]; - }, [selectedTag]); - - const enabledTags = useMemo(() => { - if (!shouldShowDisabledAndSelectedOption) { - return policyTagList; - } - const selectedNames = _.map(selectedOptions, (s) => s.name); - const tags = [...selectedOptions, ..._.filter(policyTagList, (policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; - return tags; - }, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]); - - const sections = useMemo( - () => OptionsListUtils.getFilteredOptions({}, {}, [], searchValue, selectedOptions, [], false, false, false, {}, [], true, enabledTags, policyRecentlyUsedTagsList, false).tagOptions, - [searchValue, enabledTags, selectedOptions, policyRecentlyUsedTagsList], - ); - - const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList(lodashGet(sections, '[0].data.length', 0) > 0, searchValue); - - const selectedOptionKey = lodashGet(_.filter(lodashGet(sections, '[0].data', []), (policyTag) => policyTag.searchText === selectedTag)[0], 'keyForList'); - - return ( - - ); -} - -TagPicker.displayName = 'TagPicker'; -TagPicker.propTypes = propTypes; -TagPicker.defaultProps = defaultProps; - -export default withOnyx({ - policyTags: { - key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, - }, - policyRecentlyUsedTags: { - key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, - }, -})(TagPicker); diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js deleted file mode 100644 index b98f7f6ef8e9..000000000000 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ /dev/null @@ -1,41 +0,0 @@ -import PropTypes from 'prop-types'; -import tagPropTypes from '@components/tagPropTypes'; -import safeAreaInsetPropTypes from '@pages/safeAreaInsetPropTypes'; - -const propTypes = { - /** The policyID we are getting tags for */ - policyID: PropTypes.string.isRequired, - - /** The selected tag of the money request */ - selectedTag: PropTypes.string.isRequired, - - /** The name of tag list we are getting tags for */ - tag: PropTypes.string.isRequired, - - /** Callback to submit the selected tag */ - onSubmit: PropTypes.func.isRequired, - - /** - * Safe area insets required for reflecting the portion of the view, - * that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. - */ - insets: safeAreaInsetPropTypes.isRequired, - - /* Onyx Props */ - /** Collection of tags attached to a policy */ - policyTags: tagPropTypes, - - /** List of recently used tags */ - policyRecentlyUsedTags: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)), - - /** Should show the selected option that is disabled? */ - shouldShowDisabledAndSelectedOption: PropTypes.bool, -}; - -const defaultProps = { - policyTags: {}, - policyRecentlyUsedTags: {}, - shouldShowDisabledAndSelectedOption: false, -}; - -export {propTypes, defaultProps}; diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 0cab97299324..e08d602341dc 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -184,14 +184,13 @@ function getTagListName(policyTags: OnyxEntry) { /** * Gets the tags of a policy for a specific key. Defaults to the first tag if no key is provided. */ -function getTagList(policyTags: OnyxCollection, tagKey: string) { +function getTagList(policyTags: OnyxCollection, tagKey: string): PolicyTags { if (Object.keys(policyTags ?? {})?.length === 0) { return {}; } const policyTagKey = tagKey ?? Object.keys(policyTags ?? {})[0]; - - return policyTags?.[policyTagKey]?.tags ?? {}; + return (policyTags?.[policyTagKey]?.tags as unknown as PolicyTags) ?? {}; } function isPendingDeletePolicy(policy: OnyxEntry): boolean { From 28d24d57f8d28523e73872cdbd9cba4716369529 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 16 Jan 2024 02:55:42 -0700 Subject: [PATCH 2/6] Added SafeAreaInsetProps.ts --- src/components/TagPicker.tsx | 3 ++- src/pages/SafeAreaInsetProps.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/pages/SafeAreaInsetProps.ts diff --git a/src/components/TagPicker.tsx b/src/components/TagPicker.tsx index 868fe7776567..aa80e5c1d141 100644 --- a/src/components/TagPicker.tsx +++ b/src/components/TagPicker.tsx @@ -6,6 +6,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; +import type SafeAreaInsetProps from '@pages/SafeAreaInsetProps'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PolicyTags, RecentlyUsedTags} from '@src/types/onyx'; @@ -40,7 +41,7 @@ type TagPickerProps = TagPickerOnyxProps & { * Safe area insets required for reflecting the portion of the view, * that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. */ - insets: Record; + insets: SafeAreaInsetProps; }; function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, shouldShowDisabledAndSelectedOption, insets, onSubmit}: TagPickerProps) { diff --git a/src/pages/SafeAreaInsetProps.ts b/src/pages/SafeAreaInsetProps.ts new file mode 100644 index 000000000000..3317eb58d7e4 --- /dev/null +++ b/src/pages/SafeAreaInsetProps.ts @@ -0,0 +1,8 @@ +type SafeAreaInsetProps = { + top: number; + left: number; + right: number; + bottom: number; +}; + +export default SafeAreaInsetProps; From bf031632be964ef4596c46074e5bcdaaf52261eb Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 23 Jan 2024 02:53:53 -0700 Subject: [PATCH 3/6] Merged main & requested changes. --- src/components/TagPicker.tsx | 13 +++++++------ src/libs/PolicyUtils.ts | 2 +- src/pages/SafeAreaInsetProps.ts | 8 -------- src/types/onyx/PolicyTag.ts | 1 + 4 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 src/pages/SafeAreaInsetProps.ts diff --git a/src/components/TagPicker.tsx b/src/components/TagPicker.tsx index aa80e5c1d141..1b1c5ca9d845 100644 --- a/src/components/TagPicker.tsx +++ b/src/components/TagPicker.tsx @@ -6,10 +6,10 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import type SafeAreaInsetProps from '@pages/SafeAreaInsetProps'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PolicyTags, RecentlyUsedTags} from '@src/types/onyx'; +import type {EdgeInsets} from "react-native-safe-area-context"; import OptionsSelector from './OptionsSelector'; type TagPickerOnyxProps = { @@ -18,13 +18,11 @@ type TagPickerOnyxProps = { /** List of recently used tags */ policyRecentlyUsedTags: OnyxCollection; - - /** Should show the selected option that is disabled? */ - shouldShowDisabledAndSelectedOption?: boolean; }; type TagPickerProps = TagPickerOnyxProps & { /** The policyID we are getting tags for */ + // It's used in withOnyx HOC. // eslint-disable-next-line react/no-unused-prop-types policyID: string; @@ -41,10 +39,13 @@ type TagPickerProps = TagPickerOnyxProps & { * Safe area insets required for reflecting the portion of the view, * that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. */ - insets: SafeAreaInsetProps; + insets: EdgeInsets; + + /** Should show the selected option that is disabled? */ + shouldShowDisabledAndSelectedOption?: boolean; }; -function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, shouldShowDisabledAndSelectedOption, insets, onSubmit}: TagPickerProps) { +function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, shouldShowDisabledAndSelectedOption = false, insets, onSubmit}: TagPickerProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index eeb69c4536fd..47aafbec7980 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -191,7 +191,7 @@ function getTagList(policyTags: OnyxCollection, tagKey: string): Pol } const policyTagKey = tagKey ?? Object.keys(policyTags ?? {})[0]; - return (policyTags?.[policyTagKey]?.tags as unknown as PolicyTags) ?? {}; + return policyTags?.[policyTagKey]?.tags ?? {}; } /** diff --git a/src/pages/SafeAreaInsetProps.ts b/src/pages/SafeAreaInsetProps.ts deleted file mode 100644 index 3317eb58d7e4..000000000000 --- a/src/pages/SafeAreaInsetProps.ts +++ /dev/null @@ -1,8 +0,0 @@ -type SafeAreaInsetProps = { - top: number; - left: number; - right: number; - bottom: number; -}; - -export default SafeAreaInsetProps; diff --git a/src/types/onyx/PolicyTag.ts b/src/types/onyx/PolicyTag.ts index 58a21dcf4df5..e9b909b1748a 100644 --- a/src/types/onyx/PolicyTag.ts +++ b/src/types/onyx/PolicyTag.ts @@ -8,6 +8,7 @@ type PolicyTag = { /** "General Ledger code" that corresponds to this tag in an accounting system. Similar to an ID. */ // eslint-disable-next-line @typescript-eslint/naming-convention 'GL Code': string; + tags: PolicyTags; }; type PolicyTags = Record; From ba83997abb76fb553eccb655e0cef8c85b0a11a0 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Mon, 29 Jan 2024 23:00:14 -0700 Subject: [PATCH 4/6] Requested changes. --- .../{TagPicker.tsx => TagPicker/index.tsx} | 25 ++++++++----------- src/libs/PolicyUtils.ts | 3 ++- 2 files changed, 13 insertions(+), 15 deletions(-) rename src/components/{TagPicker.tsx => TagPicker/index.tsx} (83%) diff --git a/src/components/TagPicker.tsx b/src/components/TagPicker/index.tsx similarity index 83% rename from src/components/TagPicker.tsx rename to src/components/TagPicker/index.tsx index 1b1c5ca9d845..52d8214f0e5c 100644 --- a/src/components/TagPicker.tsx +++ b/src/components/TagPicker/index.tsx @@ -1,23 +1,22 @@ import {useMemo, useState} from 'react'; -import type {OnyxCollection} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; +import type {EdgeInsets} from 'react-native-safe-area-context'; import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as PolicyUtils from '@libs/PolicyUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PolicyTags, RecentlyUsedTags} from '@src/types/onyx'; -import type {EdgeInsets} from "react-native-safe-area-context"; -import OptionsSelector from './OptionsSelector'; +import OptionsSelector from '@components/OptionsSelector'; type TagPickerOnyxProps = { /** Collection of tags attached to a policy */ - policyTags: OnyxCollection; + policyTags: OnyxEntry; /** List of recently used tags */ - policyRecentlyUsedTags: OnyxCollection; + policyRecentlyUsedTags: OnyxEntry; }; type TagPickerProps = TagPickerOnyxProps & { @@ -51,8 +50,8 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, should const {translate} = useLocalize(); const [searchValue, setSearchValue] = useState(''); - const policyTagList = PolicyUtils.getTagList(policyTags, tag); - const policyTagsCount = Object.values(policyTagList).filter((policyTag) => policyTag.enabled).length; + const policyTagList = policyTags?.[tag]?.tags; + const policyTagsCount = Object.values(policyTagList ?? {}).filter((policyTag) => policyTag.enabled).length; const isTagsCountBelowThreshold = policyTagsCount < CONST.TAG_LIST_THRESHOLD; const shouldShowTextInput = !isTagsCountBelowThreshold; @@ -73,12 +72,11 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, should const enabledTags = useMemo(() => { if (!shouldShowDisabledAndSelectedOption) { - return policyTagList; + return Object.values(policyTagList ?? {}); } const selectedNames = selectedOptions.map((s) => s.name); - const tags = [...selectedOptions, ...Object.values(policyTagList).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; - return tags; + return [...selectedOptions, ...Object.values(policyTagList ?? {}).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; }, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]); // @@ -95,7 +93,6 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, should const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList((sections?.[0]?.data?.length ?? 0) > 0, searchValue); - // @ts-expect-error TODO: Remove this once OptionsListUtils (https://github.com/Expensify/App/issues/24921) is migrated to TypeScript. const selectedOptionKey = sections[0]?.data?.filter((policyTag) => policyTag.searchText === selectedTag)?.[0]?.keyForList; return ( @@ -126,9 +123,9 @@ TagPicker.displayName = 'TagPicker'; export default withOnyx({ policyTags: { - key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}` as typeof ONYXKEYS.COLLECTION.POLICY_TAGS, + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, }, policyRecentlyUsedTags: { - key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}` as typeof ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS, + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, }, })(TagPicker); diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 47aafbec7980..b8ed62f93082 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -185,12 +185,13 @@ function getTagListName(policyTags: OnyxEntry) { /** * Gets the tags of a policy for a specific key. Defaults to the first tag if no key is provided. */ -function getTagList(policyTags: OnyxCollection, tagKey: string): PolicyTags { +function getTagList(policyTags: OnyxCollection, tagKey: string) { if (Object.keys(policyTags ?? {})?.length === 0) { return {}; } const policyTagKey = tagKey ?? Object.keys(policyTags ?? {})[0]; + return policyTags?.[policyTagKey]?.tags ?? {}; } From 6f3b720d73edddfeaae1f2057826bfc096bb1abc Mon Sep 17 00:00:00 2001 From: fvlvte Date: Tue, 30 Jan 2024 02:54:15 -0700 Subject: [PATCH 5/6] Requested changes. --- src/components/TagPicker/index.tsx | 11 ++++++----- src/libs/PolicyUtils.ts | 2 +- src/types/onyx/PolicyTag.ts | 2 ++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/TagPicker/index.tsx b/src/components/TagPicker/index.tsx index 52d8214f0e5c..e2dcd129f842 100644 --- a/src/components/TagPicker/index.tsx +++ b/src/components/TagPicker/index.tsx @@ -2,14 +2,15 @@ import {useMemo, useState} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import type {EdgeInsets} from 'react-native-safe-area-context'; +import OptionsSelector from '@components/OptionsSelector'; import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {PolicyTags, RecentlyUsedTags} from '@src/types/onyx'; -import OptionsSelector from '@components/OptionsSelector'; type TagPickerOnyxProps = { /** Collection of tags attached to a policy */ @@ -50,8 +51,8 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, should const {translate} = useLocalize(); const [searchValue, setSearchValue] = useState(''); - const policyTagList = policyTags?.[tag]?.tags; - const policyTagsCount = Object.values(policyTagList ?? {}).filter((policyTag) => policyTag.enabled).length; + const policyTagList = PolicyUtils.getTagList(policyTags, tag); + const policyTagsCount = Object.values(policyTagList).filter((policyTag) => policyTag.enabled).length; const isTagsCountBelowThreshold = policyTagsCount < CONST.TAG_LIST_THRESHOLD; const shouldShowTextInput = !isTagsCountBelowThreshold; @@ -72,11 +73,11 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, should const enabledTags = useMemo(() => { if (!shouldShowDisabledAndSelectedOption) { - return Object.values(policyTagList ?? {}); + return policyTagList; } const selectedNames = selectedOptions.map((s) => s.name); - return [...selectedOptions, ...Object.values(policyTagList ?? {}).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; + return [...selectedOptions, ...Object.values(policyTagList).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; }, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]); // diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index b8ed62f93082..65255665809f 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -185,7 +185,7 @@ function getTagListName(policyTags: OnyxEntry) { /** * Gets the tags of a policy for a specific key. Defaults to the first tag if no key is provided. */ -function getTagList(policyTags: OnyxCollection, tagKey: string) { +function getTagList(policyTags: OnyxEntry, tagKey: string) { if (Object.keys(policyTags ?? {})?.length === 0) { return {}; } diff --git a/src/types/onyx/PolicyTag.ts b/src/types/onyx/PolicyTag.ts index e9b909b1748a..43ad5cd07044 100644 --- a/src/types/onyx/PolicyTag.ts +++ b/src/types/onyx/PolicyTag.ts @@ -8,6 +8,8 @@ type PolicyTag = { /** "General Ledger code" that corresponds to this tag in an accounting system. Similar to an ID. */ // eslint-disable-next-line @typescript-eslint/naming-convention 'GL Code': string; + + /** Tags included in the policy */ tags: PolicyTags; }; From df71d710fa92ff9340a3a61c772b57d9debbd788 Mon Sep 17 00:00:00 2001 From: fvlvte Date: Thu, 1 Feb 2024 03:03:30 -0700 Subject: [PATCH 6/6] Requested change. --- src/components/TagPicker/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/TagPicker/index.tsx b/src/components/TagPicker/index.tsx index e2dcd129f842..a6fbfa1f87e8 100644 --- a/src/components/TagPicker/index.tsx +++ b/src/components/TagPicker/index.tsx @@ -80,7 +80,6 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, should return [...selectedOptions, ...Object.values(policyTagList).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; }, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]); - // const sections = useMemo(() => { const policyRecentlyUsedTagsList = policyRecentlyUsedTags?.tag ?? [];