Skip to content
Merged
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ const CONST = {
BILLABLE: 'billable',
NON_BILLABLE: 'nonBillable',
},

TASK_TITLE_DISABLED_RULES: ['image'],
// Note: Group and Self-DM excluded as these are not tied to a Workspace
WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT, chatTypes.INVOICE],
ANDROID_PACKAGE_NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,15 @@ function AnchorRenderer({tnode, style, key}: AnchorRendererProps) {
// eslint-disable-next-line react/jsx-props-no-multi-spaces
target={htmlAttribs.target || '_blank'}
rel={htmlAttribs.rel || 'noopener noreferrer'}
style={[style, parentStyle, textDecorationLineStyle, styles.textUnderlinePositionUnder, styles.textDecorationSkipInkNone, isChildOfTaskTitle && styles.taskTitleMenuItem]}
style={[
style,
parentStyle,
textDecorationLineStyle,
styles.textUnderlinePositionUnder,
styles.textDecorationSkipInkNone,
isChildOfTaskTitle && styles.taskTitleMenuItem,
styles.dInlineFlex,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display inline flex for the anchor caused an issue #90362

]}
key={key}
// Only pass the press handler for internal links. For public links or whitelisted internal links fallback to default link handling
onPress={internalNewExpensifyPath || internalExpensifyPath ? () => openLink(attrHref, environmentURL, isAttachment) : undefined}
Expand All @@ -88,7 +96,14 @@ function AnchorRenderer({tnode, style, key}: AnchorRendererProps) {
return (
<Text
key={props.key}
style={[props.childTnode.getNativeStyles(), parentStyle, textDecorationLineStyle, styles.textUnderlinePositionUnder, styles.textDecorationSkipInkNone]}
style={[
props.childTnode.getNativeStyles(),
parentStyle,
textDecorationLineStyle,
styles.textUnderlinePositionUnder,
styles.textDecorationSkipInkNone,
styles.dInlineFlex,
]}
>
{props.childTnode.data}
</Text>
Expand Down
6 changes: 5 additions & 1 deletion src/components/ReportActionItem/TaskPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import ControlSelection from '@libs/ControlSelection';
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
import getButtonState from '@libs/getButtonState';
import Navigation from '@libs/Navigation/Navigation';
import Parser from '@libs/Parser';
import {isCanceledTaskReport, isOpenTaskReport, isReportManager} from '@libs/ReportUtils';
import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -64,6 +65,9 @@ function TaskPreview({taskReportID, action, contextMenuAnchor, chatReportID, che
const {translate} = useLocalize();
const theme = useTheme();
const [taskReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`);
const taskTitle = action?.childReportName ?? taskReport?.reportName ?? '';

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which change is currently fixing the issue #58269 ?

@mananjadhav, I missed that initially, its now updated. We had to used action?.childReportName if it's available.


const taskTitleWithoutImage = Parser.replace(Parser.htmlToMarkdown(taskTitle), {disabledRules: [...CONST.TASK_TITLE_DISABLED_RULES]});

// The reportAction might not contain details regarding the taskReport
// Only the direct parent reportAction will contain details about the taskReport
Expand Down Expand Up @@ -127,7 +131,7 @@ function TaskPreview({taskReportID, action, contextMenuAnchor, chatReportID, che
</UserDetailsTooltip>
)}
<View style={[styles.alignSelfCenter, styles.flex1]}>
<RenderHTML html={`<comment>${taskReport?.reportName ?? action?.childReportName ?? ''}</comment>`} />
<RenderHTML html={`<comment>${taskTitleWithoutImage}</comment>`} />
</View>
</View>
{shouldShowGreenDotIndicator && (
Expand Down
4 changes: 3 additions & 1 deletion src/components/ReportActionItem/TaskView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import convertToLTR from '@libs/convertToLTR';
import getButtonState from '@libs/getButtonState';
import Navigation from '@libs/Navigation/Navigation';
import {getAvatarsForAccountIDs, getPersonalDetailsForAccountIDs} from '@libs/OptionsListUtils';
import Parser from '@libs/Parser';
import {getDisplayNameForParticipant, getDisplayNamesWithTooltips, isCompletedTaskReport, isOpenTaskReport} from '@libs/ReportUtils';
import {isActiveTaskEditRoute} from '@libs/TaskUtils';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
Expand All @@ -44,7 +45,8 @@ function TaskView({report}: TaskViewProps) {
useEffect(() => {
setTaskReport(report);
}, [report]);
const taskTitle = `<task-title>${convertToLTR(report?.reportName ?? '')}</task-title>`;
const titleWithoutImage = Parser.replace(Parser.htmlToMarkdown(report?.reportName ?? ''), {disabledRules: [...CONST.TASK_TITLE_DISABLED_RULES]});
const taskTitle = `<task-title>${convertToLTR(titleWithoutImage)}</task-title>`;
const assigneeTooltipDetails = getDisplayNamesWithTooltips(getPersonalDetailsForAccountIDs(report?.managerID ? [report?.managerID] : [], personalDetails), false);

const isOpen = isOpenTaskReport(report);
Expand Down
8 changes: 7 additions & 1 deletion src/components/Search/SearchAutocompleteList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
parseForAutocomplete,
} from '@libs/SearchAutocompleteUtils';
import {buildSearchQueryJSON, buildUserReadableQueryString, sanitizeSearchValue} from '@libs/SearchQueryUtils';
import StringUtils from '@libs/StringUtils';
import Timing from '@userActions/Timing';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -478,7 +479,12 @@ function SearchAutocompleteList(
sections.push({title: translate('search.recentSearches'), data: recentSearchesData});
}

const styledRecentReports = recentReportsOptions.map((item) => ({...item, pressableStyle: styles.br2, wrapperStyle: [styles.pr3, styles.pl3]}));
const styledRecentReports = recentReportsOptions.map((item) => ({
...item,
pressableStyle: styles.br2,
text: StringUtils.lineBreaksToSpaces(item.text),
wrapperStyle: [styles.pr3, styles.pl3],
}));
sections.push({title: autocompleteQueryValue.trim() === '' ? translate('search.recentChats') : undefined, data: styledRecentReports});

if (autocompleteSuggestions.length > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search/SearchRouter/SearchRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function SearchRouter({onRouterClose, shouldHideInputCaret}: SearchRouterProps,
{
data: [
{
text: `${translate('search.searchIn')} ${reportForContextualSearch.text ?? reportForContextualSearch.alternateText}`,
text: StringUtils.lineBreaksToSpaces(`${translate('search.searchIn')} ${reportForContextualSearch.text ?? reportForContextualSearch.alternateText}`),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix this issue where search router was displaying task reports with multiline title. Task - Task with multiline title is not displayed correctly in search list #58192

singleIcon: Expensicons.MagnifyingGlass,
searchQuery: reportQueryValue,
autocompleteID,
Expand Down
9 changes: 5 additions & 4 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4862,7 +4862,7 @@ function completeShortMention(text: string): string {
* For comments shorter than or equal to 10k chars, convert the comment from MD into HTML because that's how it is stored in the database
* For longer comments, skip parsing, but still escape the text, and display plaintext for performance reasons. It takes over 40s to parse a 100k long string!!
*/
function getParsedComment(text: string, parsingDetails?: ParsingDetails, mediaAttributes?: Record<string, string>): string {
function getParsedComment(text: string, parsingDetails?: ParsingDetails, mediaAttributes?: Record<string, string>, disabledRules?: string[]): string {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these by better typed? Say disabledRules?: MarkdownType[] ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MarkdownType[] is has different properties, it does not have image.

let isGroupPolicyReport = false;
if (parsingDetails?.reportID) {
const currentReport = getReportOrDraftReport(parsingDetails?.reportID);
Expand All @@ -4877,11 +4877,12 @@ function getParsedComment(text: string, parsingDetails?: ParsingDetails, mediaAt
}

const textWithMention = completeShortMention(text);
const rules = disabledRules ?? [];

return text.length <= CONST.MAX_MARKUP_LENGTH
? Parser.replace(textWithMention, {
shouldEscapeText: parsingDetails?.shouldEscapeText,
disabledRules: isGroupPolicyReport ? [] : ['reportMentions'],
disabledRules: isGroupPolicyReport ? [...rules] : ['reportMentions', ...rules],
extras: {mediaAttributeCache: mediaAttributes},
})
: lodashEscape(text);
Expand Down Expand Up @@ -6506,7 +6507,7 @@ function buildOptimisticEditedTaskFieldReportAction({title, description}: Task):
{
type: CONST.REPORT.MESSAGE.TYPE.COMMENT,
text: changelog,
html: getParsedComment(changelog),
html: getParsedComment(changelog, undefined, undefined, title !== undefined ? [...CONST.TASK_TITLE_DISABLED_RULES] : undefined),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure why we want to spread (...) the value and then pass it as array []. Why not just pass CONST.TASK_TITLE_DISABLED_RULES ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason we spread (...) CONST.TASK_TITLE_DISABLED_RULES into a new array ([]) is because of TypeScript's strict type checking regarding readonly arrays and mutable arrays.

},
],
person: [
Expand Down Expand Up @@ -6851,7 +6852,7 @@ function buildOptimisticTaskReport(

return {
reportID: generateReportID(),
reportName: getParsedComment(title ?? ''),
reportName: getParsedComment(title ?? '', undefined, undefined, [...CONST.TASK_TITLE_DISABLED_RULES]),
description: getParsedComment(description ?? '', {}, mediaAttributes),
ownerAccountID,
participants,
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ function editTask(report: OnyxTypes.Report, {title, description}: OnyxTypes.Task

// Ensure title is defined before parsing it with getParsedComment. If title is undefined, fall back to reportName from report.
// Trim the final parsed title for consistency.
const reportName = title ? ReportUtils.getParsedComment(title) : report?.reportName ?? '';
const reportName = title ? ReportUtils.getParsedComment(title, undefined, undefined, [...CONST.TASK_TITLE_DISABLED_RULES]) : report?.reportName ?? '';
const parsedTitle = (reportName ?? '').trim();

// Description can be unset, so we default to an empty string if so
Expand Down
1 change: 1 addition & 0 deletions src/pages/tasks/NewTaskPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ function NewTaskPage({route}: NewTaskPageProps) {
shouldShowRightIcon
rightLabel={translate('common.required')}
shouldParseTitle
excludedMarkdownRules={[...CONST.TASK_TITLE_DISABLED_RULES]}
/>
<MenuItemWithTopDescription
description={translate('task.description')}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/tasks/TaskTitlePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function TaskTitlePage({report, currentUserPersonalDetails}: TaskTitlePageProps)
({title}: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_TASK_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.EDIT_TASK_FORM> => {
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.EDIT_TASK_FORM> = {};

const parsedTitle = getParsedComment(title);
const parsedTitle = getParsedComment(title, undefined, undefined, [...CONST.TASK_TITLE_DISABLED_RULES]);
const parsedTitleLength = getCommentLength(parsedTitle);

if (!parsedTitle) {
Expand Down Expand Up @@ -110,7 +110,7 @@ function TaskTitlePage({report, currentUserPersonalDetails}: TaskTitlePageProps)
name={INPUT_IDS.TITLE}
label={translate('task.title')}
accessibilityLabel={translate('task.title')}
defaultValue={Parser.htmlToMarkdown(report?.reportName ?? '')}
defaultValue={Parser.htmlToMarkdown(report?.reportName ?? '', {})}
ref={(element: AnimatedTextInputRef) => {
if (!element) {
return;
Expand Down
6 changes: 4 additions & 2 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4278,18 +4278,20 @@ const styles = (theme: ThemeColors) =>
...writingDirection.ltr,
...headlineFont,
fontSize: variables.fontSizeXLarge,
lineHeight: variables.lineHeightSizeh2,
lineHeight: variables.lineHeighTaskTitle,
maxWidth: '100%',
...wordBreak.breakWord,
textUnderlineOffset: -1,
},

taskTitleMenuItemItalic: {
...writingDirection.ltr,
...headlineItalicFont,
fontSize: variables.fontSizeXLarge,
lineHeight: variables.lineHeightSizeh2,
lineHeight: variables.lineHeighTaskTitle,
maxWidth: '100%',
...wordBreak.breakWord,
textUnderlineOffset: -1,
},

taskDescriptionMenuItem: {
Expand Down
2 changes: 1 addition & 1 deletion src/styles/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ function getCodeFontSize(isInsideH1: boolean, isInsideTaskTitle?: boolean) {
return 15;
}
if (isInsideTaskTitle) {
return 19;
return 18;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Expensify/design can you confirm the value?

}
return 13;
}
Expand Down
1 change: 1 addition & 0 deletions src/styles/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export default {
lineHeightXXXLarge: getValueUsingPixelRatio(32, 37),
lineHeightSizeh1: getValueUsingPixelRatio(28, 32),
lineHeightSizeh2: getValueUsingPixelRatio(24, 28),
lineHeighTaskTitle: getValueUsingPixelRatio(26, 30),
lineHeightSignInHeroXSmall: getValueUsingPixelRatio(32, 37),
inputHeight: getValueUsingPixelRatio(52, 72),
inputHeightSmall: 28,
Expand Down
Loading