diff --git a/src/components/TagPicker/index.tsx b/src/components/TagPicker/index.tsx index 9d3a70d4d50c..946a4889b4c7 100644 --- a/src/components/TagPicker/index.tsx +++ b/src/components/TagPicker/index.tsx @@ -38,11 +38,13 @@ type TagPickerProps = { /** Should show the selected option that is disabled? */ shouldShowDisabledAndSelectedOption?: boolean; + shouldOrderListByTagName?: boolean; + /** Indicates which tag list index was selected */ tagListIndex: number; }; -function TagPicker({selectedTag, tagListName, policyID, tagListIndex, shouldShowDisabledAndSelectedOption = false, onSubmit}: TagPickerProps) { +function TagPicker({selectedTag, tagListName, policyID, tagListIndex, shouldShowDisabledAndSelectedOption = false, shouldOrderListByTagName = false, onSubmit}: TagPickerProps) { const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`); const [policyRecentlyUsedTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`); const styles = useThemeStyles(); @@ -79,19 +81,24 @@ function TagPicker({selectedTag, tagListName, policyID, tagListIndex, shouldShow return [...selectedOptions, ...Object.values(policyTagList.tags).filter((policyTag) => policyTag.enabled && !selectedNames.includes(policyTag.name))]; }, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]); - const sections = useMemo( - () => - OptionsListUtils.getFilteredOptions({ - searchValue, - selectedOptions, - includeP2P: false, - includeTags: true, - tags: enabledTags, - recentlyUsedTags: policyRecentlyUsedTagsList, - canInviteUser: false, - }).tagOptions, - [searchValue, enabledTags, selectedOptions, policyRecentlyUsedTagsList], - ); + const sections = useMemo(() => { + const options = OptionsListUtils.getFilteredOptions({ + searchValue, + selectedOptions, + includeP2P: false, + includeTags: true, + tags: enabledTags, + recentlyUsedTags: policyRecentlyUsedTagsList, + canInviteUser: false, + }).tagOptions; + + return shouldOrderListByTagName + ? options.map((option) => ({ + ...option, + data: option.data.sort((a, b) => a.text?.localeCompare(b.text ?? '') ?? 0), + })) + : options; + }, [searchValue, selectedOptions, enabledTags, policyRecentlyUsedTagsList, shouldOrderListByTagName]); const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList((sections?.at(0)?.data?.length ?? 0) > 0, searchValue); diff --git a/src/pages/Debug/DebugDetails.tsx b/src/pages/Debug/DebugDetails.tsx index d6ef905283e9..247915f4e431 100644 --- a/src/pages/Debug/DebugDetails.tsx +++ b/src/pages/Debug/DebugDetails.tsx @@ -16,6 +16,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import type {ObjectType, OnyxDataType} from '@libs/DebugUtils'; import DebugUtils from '@libs/DebugUtils'; import Navigation from '@libs/Navigation/Navigation'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import Debug from '@userActions/Debug'; import type CONST from '@src/CONST'; @@ -53,6 +54,7 @@ function DebugDetails({formType, data, children, onSave, onDelete, validate}: De const [formDraftData] = useOnyx(ONYXKEYS.FORMS.DEBUG_DETAILS_FORM_DRAFT); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${(data as OnyxEntry)?.reportID ?? ''}`); const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${report?.policyID}`); + const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]); const booleanFields = useMemo( () => Object.entries(data ?? {}) @@ -65,16 +67,13 @@ function DebugDetails({formType, data, children, onSave, onDelete, validate}: De Object.entries(data ?? {}) .filter((entry): entry is [string, string] => { // Tag picker needs to be hidden when the policy has no tags available to pick - if ( - entry[0] === TRANSACTION_FORM_INPUT_IDS.TAG && - !Object.values(policyTags ?? {}).some((policyTagList) => PolicyUtils.getCountOfEnabledTagsOfList(policyTagList.tags)) - ) { + if (entry[0] === TRANSACTION_FORM_INPUT_IDS.TAG && !OptionsListUtils.hasEnabledTags(policyTagLists)) { return false; } return DETAILS_CONSTANT_FIELDS[formType].some(({fieldName}) => fieldName === entry[0]); }) .sort((a, b) => a[0].localeCompare(b[0])), - [data, formType, policyTags], + [data, formType, policyTagLists], ); const numberFields = useMemo( () => diff --git a/src/pages/Debug/DebugDetailsConstantPickerPage.tsx b/src/pages/Debug/DebugDetailsConstantPickerPage.tsx index aa30efc4c907..205bfc7bb48c 100644 --- a/src/pages/Debug/DebugDetailsConstantPickerPage.tsx +++ b/src/pages/Debug/DebugDetailsConstantPickerPage.tsx @@ -14,6 +14,7 @@ import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; import TRANSACTION_FORM_INPUT_IDS from '@src/types/form/DebugTransactionForm'; import ConstantPicker from './ConstantPicker'; +import DebugTagPicker from './DebugTagPicker'; type DebugDetailsConstantPickerPageProps = StackScreenProps; @@ -55,12 +56,10 @@ function DebugDetailsConstantPickerPage({ } if (fieldName === TRANSACTION_FORM_INPUT_IDS.TAG) { return ( - ); } diff --git a/src/pages/Debug/DebugTagPicker.tsx b/src/pages/Debug/DebugTagPicker.tsx new file mode 100644 index 000000000000..2c3707b59fde --- /dev/null +++ b/src/pages/Debug/DebugTagPicker.tsx @@ -0,0 +1,71 @@ +import React, {useCallback, useMemo, useState} from 'react'; +import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import Button from '@components/Button'; +import type {ListItem} from '@components/SelectionList/types'; +import TagPicker from '@components/TagPicker'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as IOUUtils from '@libs/IOUUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; +import * as TransactionUtils from '@libs/TransactionUtils'; +import ONYXKEYS from '@src/ONYXKEYS'; + +type DebugTagPickerProps = { + policyID: string; + tagName?: string; + onSubmit: (item: ListItem) => void; +}; + +function DebugTagPicker({policyID, tagName = '', onSubmit}: DebugTagPickerProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const [newTagName, setNewTagName] = useState(tagName); + const selectedTags = useMemo(() => TransactionUtils.getTagArrayFromName(newTagName), [newTagName]); + const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`); + const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]); + + const updateTagName = useCallback( + (index: number) => + ({text}: ListItem) => { + const newTag = text === selectedTags.at(index) ? undefined : text; + setNewTagName(IOUUtils.insertTagIntoTransactionTagsString(newTagName, newTag ?? '', index)); + }, + [newTagName, selectedTags], + ); + + const submitTag = useCallback(() => { + onSubmit({text: newTagName}); + }, [newTagName, onSubmit]); + + return ( + + + {policyTagLists.map(({name}, index) => ( + + {policyTagLists.length > 1 && {name}} + + + ))} + + +