Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';

import Parser from '@libs/Parser';
import {getReportStatusColorStyle, getReportStatusTooltipTranslation, getReportStatusTranslation} from '@libs/ReportUtils';

import variables from '@styles/variables';
Expand Down Expand Up @@ -48,6 +49,7 @@ function ReportPreviewHeader() {
const selectReportName = useCallback((attributes: OnyxEntry<ReportAttributesDerivedValue>) => reportNameSelector(attributes, iouReportID), [iouReportID]);
const [derivedReportName] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {selector: selectReportName});
const reportName = derivedReportName ?? iouReport?.reportName ?? '';
const formattedReportName = useMemo(() => Parser.htmlToText(reportName || (action.childReportName ?? '')), [reportName, action.childReportName]);

/*
Show subtitle if at least one of the expenses is not being smart scanned, and either:
Expand Down Expand Up @@ -102,7 +104,7 @@ function ReportPreviewHeader() {
style={[styles.headerText]}
testID="MoneyRequestReportPreview-reportName"
>
{reportName || action.childReportName}
{formattedReportName}
</Text>
</Animated.View>
</View>
Expand Down
2 changes: 2 additions & 0 deletions src/libs/SearchUIUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2953,6 +2953,8 @@ function getReportSections({
if (isIOUReport) {
reportIDToTransactions[reportKey].reportName = getIOUReportName(translate, convertToDisplayString, data, reportIDToTransactions[reportKey]);
}

reportIDToTransactions[reportKey].reportName = StringUtils.lineBreaksToSpaces(Parser.htmlToText(reportIDToTransactions[reportKey].reportName ?? ''));
}
} else if (isTransactionEntry(key)) {
const transactionItem = {...data[key]};
Expand Down
28 changes: 28 additions & 0 deletions tests/unit/Search/SearchUIUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2798,6 +2798,34 @@ describe('SearchUIUtils', () => {
expect(result.find((item) => item.reportID === reportID2)?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
});

it('should decode HTML entities in the expense report name', () => {
const localSearchResults: OnyxTypes.SearchResults['data'] = {
...searchResults.data,
[`report_${reportID2}`]: {
...searchResults.data[`report_${reportID2}`],
reportName: 'A &amp; B &#39;C&#39;',
},
};

const result = getSectionsByType(
SearchUIUtils.getSections({
type: CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT,
data: localSearchResults,
currentAccountID: 2074551,
currentUserEmail: '',
translate: translateLocal,
formatPhoneNumber,
bankAccountList: {},
conciergeReportID: undefined,
convertToDisplayString,
reportAttributesDerivedValue: {},
}),
SearchUIUtils.isTransactionReportGroupListItemType,
)[0];

expect(result.find((item) => item.reportID === reportID2)?.reportName).toBe("A & B 'C'");
});

it('should use custom avatar from onyxPersonalDetailsList when search API personalDetailsList is absent', () => {
// Reproduce the bug: the search API response does not include the report owner in
// personalDetailsList (data.personalDetailsList is empty/undefined), so without the
Expand Down
Loading