diff --git a/src/components/Search/SearchFiltersChatsSelector.tsx b/src/components/Search/SearchFiltersChatsSelector.tsx index 2ef2a6999e748..34b532b1b58b2 100644 --- a/src/components/Search/SearchFiltersChatsSelector.tsx +++ b/src/components/Search/SearchFiltersChatsSelector.tsx @@ -11,6 +11,7 @@ import usePrivateIsArchivedMap from '@hooks/usePrivateIsArchivedMap'; import useReportAttributes from '@hooks/useReportAttributes'; import useScreenWrapperTransitionStatus from '@hooks/useScreenWrapperTransitionStatus'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; +import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; import {createOptionFromReport, filterAndOrderOptions, formatSectionsFromSearchTerm, getAlternateText, getSearchOptions} from '@libs/OptionsListUtils'; import type {Option} from '@libs/OptionsListUtils'; import type {OptionWithKey, SelectionListSections} from '@libs/OptionsListUtils/types'; @@ -64,6 +65,7 @@ function SearchFiltersChatsSelector({initialReportIDs, onFiltersUpdate, isScreen const [draftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT); const privateIsArchivedMap = usePrivateIsArchivedMap(); const [nvpDismissedProductTraining] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING); + const [policyTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS); const selectedOptions: OptionData[] = selectedReportIDs.map((id) => { const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${id}`]; @@ -71,7 +73,8 @@ function SearchFiltersChatsSelector({initialReportIDs, onFiltersUpdate, isScreen const report = getSelectedOptionData(createOptionFromReport({...reportData, reportID: id}, personalDetails, currentUserAccountID, privateIsArchived, reportAttributesDerived)); const isReportArchived = !!privateIsArchived; const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${reportData?.policyID}`]; - const alternateText = getAlternateText(report, {}, isReportArchived, currentUserEmail, policy, {}, undefined, undefined, reportAttributesDerived); + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; + const alternateText = getAlternateText(report, {}, isReportArchived, currentUserEmail, policy, {}, undefined, undefined, reportAttributesDerived, reportPolicyTags); return {...report, alternateText}; }); diff --git a/src/hooks/useSearchSelector.base.ts b/src/hooks/useSearchSelector.base.ts index 76a4f6dbadaa3..9d950647dcdd6 100644 --- a/src/hooks/useSearchSelector.base.ts +++ b/src/hooks/useSearchSelector.base.ts @@ -177,6 +177,7 @@ function useSearchSelectorBase({ const currentUserAccountID = currentUserPersonalDetails.accountID; const currentUserEmail = currentUserPersonalDetails.email ?? ''; const personalDetails = usePersonalDetails(); + const [allPolicyTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS); const onListEndReached = useDebounce( useCallback(() => { @@ -231,6 +232,7 @@ function useSearchSelectorBase({ personalDetails, countryCode, reportAttributesDerived: reportAttributesDerived?.reports, + allPolicyTags, }); case CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_GENERAL: return getValidOptions(optionsWithContacts, allPolicies, draftComments, nvpDismissedProductTraining, loginList, currentUserAccountID, currentUserEmail, { @@ -246,6 +248,7 @@ function useSearchSelectorBase({ personalDetails, countryCode, reportAttributesDerived: reportAttributesDerived?.reports, + allPolicyTags, }); case CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_SHARE_DESTINATION: return getValidOptions(optionsWithContacts, allPolicies, draftComments, nvpDismissedProductTraining, loginList, currentUserAccountID, currentUserEmail, { @@ -268,6 +271,7 @@ function useSearchSelectorBase({ personalDetails, countryCode, reportAttributesDerived: reportAttributesDerived?.reports, + allPolicyTags, }); case CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_ATTENDEES: return getValidOptions(optionsWithContacts, allPolicies, draftComments, nvpDismissedProductTraining, loginList, currentUserAccountID, currentUserEmail, { @@ -289,6 +293,7 @@ function useSearchSelectorBase({ personalDetails, countryCode, reportAttributesDerived: reportAttributesDerived?.reports, + allPolicyTags, }); default: return getEmptyOptions(); @@ -319,6 +324,7 @@ function useSearchSelectorBase({ personalDetails, reportAttributesDerived?.reports, trimmedSearchInput, + allPolicyTags, ]); const isOptionSelected = useMemo(() => { diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index ec670a7e64e1c..2530ec6561898 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -11,6 +11,7 @@ import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleCon import type {PrivateIsArchivedMap} from '@hooks/usePrivateIsArchivedMap'; import {getEnabledCategoriesCount} from '@libs/CategoryUtils'; import filterArrayByMatch from '@libs/filterArrayByMatch'; +import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; import {isReportMessageAttachment} from '@libs/isReportMessageAttachment'; import {formatPhoneNumber as formatPhoneNumberPhoneUtils} from '@libs/LocalePhoneNumber'; // eslint-disable-next-line @typescript-eslint/no-deprecated @@ -427,6 +428,7 @@ function getAlternateText( visibleReportActionsData: VisibleReportActionsDerivedValue = {}, translate?: LocalizedTranslate, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxEntry, ) { const report = getReportOrDraftReport(option.reportID); const isAdminRoom = reportUtilsIsAdminRoom(report); @@ -445,6 +447,7 @@ function getAlternateText( isReportArchived, visibleReportActionsDataParam: visibleReportActionsData, reportAttributesDerived, + policyTags, currentUserLogin, }); const reportPrefix = getReportSubtitlePrefix(report); @@ -943,6 +946,7 @@ function getLastMessageTextForReport({ /** * Creates a report list option - optimized for SearchOption context */ +// eslint-disable-next-line max-params, @typescript-eslint/max-params -- this should be handled in the separate issue function createOption( accountIDs: number[], personalDetails: OnyxInputOrEntry, @@ -951,6 +955,7 @@ function createOption( privateIsArchived: string | undefined, config?: PreviewConfig, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, translate?: LocalizedTranslate, ): SearchOptionData { @@ -1035,6 +1040,7 @@ function createOption( isReportArchived: !!result.private_isArchived, visibleReportActionsDataParam: visibleReportActionsData, reportAttributesDerived, + policyTags, currentUserLogin, }); result.alternateText = @@ -1051,6 +1057,7 @@ function createOption( visibleReportActionsData, translateFn, reportAttributesDerived, + policyTags, ); const computedReportName = getReportName(report, reportAttributesDerived); @@ -1104,10 +1111,12 @@ function getReportOption( personalDetails: OnyxEntry, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], reportDrafts?: OnyxCollection, + policyTags?: OnyxCollection, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ): OptionData { const report = getReportOrDraftReport(participant.reportID, undefined, undefined, reportDrafts); const visibleParticipantAccountIDs = getParticipantsAccountIDsForDisplay(report, true); + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; const option = createOption( visibleParticipantAccountIDs, @@ -1120,6 +1129,7 @@ function getReportOption( forcePolicyNamePreview: false, }, reportAttributesDerived, + reportPolicyTags, visibleReportActionsData, ); @@ -1164,6 +1174,7 @@ function getReportDisplayOption( personalDetails: OnyxEntry, privateIsArchived: string | undefined, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ): OptionData { const visibleParticipantAccountIDs = getParticipantsAccountIDsForDisplay(report, true); @@ -1179,6 +1190,7 @@ function getReportDisplayOption( forcePolicyNamePreview: false, }, reportAttributesDerived, + policyTags, visibleReportActionsData, ); @@ -1215,6 +1227,7 @@ function getPolicyExpenseReportOption( personalDetails: OnyxEntry, expenseReport: OnyxEntry, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ): SearchOptionData { const visibleParticipantAccountIDs = Object.entries(expenseReport?.participants ?? {}) @@ -1232,6 +1245,7 @@ function getPolicyExpenseReportOption( forcePolicyNamePreview: false, }, reportAttributesDerived, + policyTags, visibleReportActionsData, ); @@ -1344,6 +1358,7 @@ function processReport( privateIsArchived: string | undefined, currentUserAccountID: number, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ): { reportMapEntry?: [number, Report]; // The entry to add to reportMapForAccountIDs if applicable @@ -1368,7 +1383,7 @@ function processReport( reportMapEntry, reportOption: { item: report, - ...createOption(accountIDs, personalDetails, report, currentUserAccountID, privateIsArchived, undefined, reportAttributesDerived, visibleReportActionsData), + ...createOption(accountIDs, personalDetails, report, currentUserAccountID, privateIsArchived, undefined, reportAttributesDerived, policyTags, visibleReportActionsData), }, }; } @@ -1379,6 +1394,7 @@ function createOptionList( privateIsArchivedMap: PrivateIsArchivedMap, reports: OnyxCollection, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxCollection, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ) { const span = Sentry.startInactiveSpan({name: 'createOptionList'}); @@ -1389,7 +1405,16 @@ function createOptionList( if (reports) { for (const report of Object.values(reports)) { const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`]; - const {reportMapEntry, reportOption} = processReport(report, personalDetails, privateIsArchived, currentUserAccountID, reportAttributesDerived, visibleReportActionsData); + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; + const {reportMapEntry, reportOption} = processReport( + report, + personalDetails, + privateIsArchived, + currentUserAccountID, + reportAttributesDerived, + reportPolicyTags, + visibleReportActionsData, + ); if (reportMapEntry) { const [accountID, reportValue] = reportMapEntry; @@ -1405,6 +1430,8 @@ function createOptionList( const allPersonalDetailsOptions = Object.values(personalDetails ?? {}).map((personalDetail) => { const report = reportMapForAccountIDs[personalDetail?.accountID ?? CONST.DEFAULT_NUMBER_ID]; const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`]; + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; + return { item: personalDetail, ...createOption( @@ -1417,6 +1444,7 @@ function createOptionList( showPersonalDetails: true, }, reportAttributesDerived, + reportPolicyTags, visibleReportActionsData, ), }; @@ -1459,6 +1487,7 @@ function createFilteredOptionList( searchTerm?: string; betas?: OnyxEntry; } = {}, + policyTags?: OnyxCollection, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ) { const {maxRecentReports = 500, includeP2P = true, searchTerm = ''} = options; @@ -1510,8 +1539,16 @@ function createFilteredOptionList( const reportOptions: Array> = []; for (const report of limitedReports) { const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`]; - const {reportMapEntry, reportOption} = processReport(report, personalDetails, privateIsArchived, currentUserAccountID, reportAttributesDerived, visibleReportActionsData); - + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; + const {reportMapEntry, reportOption} = processReport( + report, + personalDetails, + privateIsArchived, + currentUserAccountID, + reportAttributesDerived, + reportPolicyTags, + visibleReportActionsData, + ); if (reportMapEntry) { const [accountID, reportValue] = reportMapEntry; @@ -1540,6 +1577,7 @@ function createFilteredOptionList( const report = reportMapForAccountIDs[accountID]; const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`]; + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; return { item: personalDetail, ...createOption( @@ -1550,6 +1588,7 @@ function createFilteredOptionList( privateIsArchived, {showPersonalDetails: true}, reportAttributesDerived, + reportPolicyTags, visibleReportActionsData, ), }; @@ -1569,13 +1608,14 @@ function createOptionFromReport( privateIsArchived: string | undefined, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], config?: PreviewConfig, + policyTags?: OnyxEntry, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, ) { const accountIDs = getParticipantsAccountIDsForDisplay(report); return { item: report, - ...createOption(accountIDs, personalDetails, report, currentUserAccountID, privateIsArchived, config, reportAttributesDerived, visibleReportActionsData), + ...createOption(accountIDs, personalDetails, report, currentUserAccountID, privateIsArchived, config, reportAttributesDerived, policyTags, visibleReportActionsData), }; } @@ -1899,7 +1939,17 @@ function getUserToInviteOption({ login: searchValue, }, }; - const userToInvite = createOption([optimisticAccountID], personalDetailsExtended, null, currentUserAccountID, undefined, {showChatPreviewLine}, undefined, visibleReportActionsData); + const userToInvite = createOption( + [optimisticAccountID], + personalDetailsExtended, + null, + currentUserAccountID, + undefined, + {showChatPreviewLine}, + undefined, + undefined, + visibleReportActionsData, + ); userToInvite.isOptimisticAccount = true; userToInvite.login = searchValue; @@ -2184,6 +2234,7 @@ function prepareReportOptionsForDisplay( config: GetValidReportsConfig, visibleReportActionsData: VisibleReportActionsDerivedValue = {}, reportAttributesDerived?: ReportAttributesDerivedValue['reports'], + policyTags?: OnyxCollection, ): Array> { const { showChatPreviewLine = false, @@ -2210,6 +2261,8 @@ function prepareReportOptionsForDisplay( continue; } const report = option.item; + const reportPolicyTags = policyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(report?.policyID)}`]; + /** * By default, generated options does not have the chat preview line enabled. * If showChatPreviewLine or forcePolicyNamePreview are true, let's generate and overwrite the alternate text. @@ -2225,6 +2278,7 @@ function prepareReportOptionsForDisplay( visibleReportActionsData, undefined, reportAttributesDerived, + reportPolicyTags, ); const isSelected = isReportSelected(option, selectedOptions); @@ -2365,6 +2419,7 @@ function getValidOptions( maxRecentReportElements = undefined, shouldAcceptName = false, personalDetails, + allPolicyTags, countryCode = CONST.DEFAULT_COUNTRY_CODE, visibleReportActionsData = {}, reportAttributesDerived, @@ -2473,6 +2528,7 @@ function getValidOptions( }, visibleReportActionsData, reportAttributesDerived, + allPolicyTags, ).at(0); } @@ -2494,6 +2550,7 @@ function getValidOptions( }, visibleReportActionsData, reportAttributesDerived, + allPolicyTags, ); workspaceChats = prepareReportOptionsForDisplay( @@ -2511,6 +2568,7 @@ function getValidOptions( }, visibleReportActionsData, reportAttributesDerived, + allPolicyTags, ); } else if (recentAttendees && recentAttendees?.length > 0) { recentAttendees.filter((attendee) => { @@ -2636,6 +2694,7 @@ type SearchOptionsConfig = { currentUserEmail: string; personalDetails?: OnyxEntry; reportAttributesDerived?: ReportAttributesDerivedValue['reports']; + allPolicyTags?: OnyxCollection; }; /** @@ -2663,6 +2722,7 @@ function getSearchOptions({ currentUserEmail, reportAttributesDerived, personalDetails, + allPolicyTags, }: SearchOptionsConfig): Options { const optionList = getValidOptions(options, policyCollection, draftComments, nvpDismissedProductTraining, loginList, currentUserAccountID, currentUserEmail, { betas, @@ -2688,6 +2748,7 @@ function getSearchOptions({ countryCode, visibleReportActionsData, reportAttributesDerived, + allPolicyTags, }); return optionList; diff --git a/src/libs/OptionsListUtils/types.ts b/src/libs/OptionsListUtils/types.ts index 52cadd2b00a6c..b5ef8448b05d5 100644 --- a/src/libs/OptionsListUtils/types.ts +++ b/src/libs/OptionsListUtils/types.ts @@ -8,6 +8,7 @@ import type { Login, PersonalDetails, PersonalDetailsList, + PolicyTagLists, Report, ReportActions, ReportAttributesDerivedValue, @@ -174,6 +175,7 @@ type GetValidReportsConfig = { shouldUnreadBeBold?: boolean; shouldAlwaysIncludeDM?: boolean; personalDetails?: OnyxEntry; + allPolicyTags?: OnyxCollection; } & GetValidOptionsSharedConfig; type IsValidReportsConfig = Pick< diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index bd66a42cf757c..53e490aeb87d7 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -72,6 +72,7 @@ function useOptions(reportAttributesDerived: ReportAttributesDerivedValue['repor const {contacts} = useContactImport(); const [draftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT); const allPersonalDetails = usePersonalDetails(); + const [allPolicyTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS); const { options: listOptions, @@ -110,6 +111,7 @@ function useOptions(reportAttributesDerived: ReportAttributesDerivedValue['repor includeSelfDM: true, shouldAlwaysIncludeDM: true, personalDetails: allPersonalDetails, + allPolicyTags, countryCode, reportAttributesDerived, },