From 2c8eda839c7f5dc68822866c5cc0d9494ff62174 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Tue, 9 Sep 2025 14:04:51 +0530 Subject: [PATCH 1/3] Refactor Onyx.Connect for ONYXKEYS.COLLECTION.REPORT in TaskUtils.ts --- src/libs/OptionsListUtils/index.ts | 3 ++- src/libs/TaskUtils.ts | 25 +++++-------------- .../BaseReportActionContextMenu.tsx | 1 + .../report/ContextMenu/ContextMenuActions.tsx | 5 ++-- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index 8e2f9ecb470a..9db29faccb2a 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -621,7 +621,8 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails } else if (isTaskAction(lastReportAction)) { lastMessageTextFromReport = formatReportLastMessageText(getTaskReportActionMessage(lastReportAction).text); } else if (isCreatedTaskReportAction(lastReportAction)) { - lastMessageTextFromReport = getTaskCreatedMessage(lastReportAction); + const lastReportActionChildReport = lastReportAction?.childReportID ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${lastReportAction.childReportID}`] : undefined; + lastMessageTextFromReport = getTaskCreatedMessage(lastReportAction, lastReportActionChildReport); } else if ( isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED) || isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED_AND_CLOSED) || diff --git a/src/libs/TaskUtils.ts b/src/libs/TaskUtils.ts index 7377f29548c2..1da5966d6ab4 100644 --- a/src/libs/TaskUtils.ts +++ b/src/libs/TaskUtils.ts @@ -1,7 +1,5 @@ -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; import type {Message} from '@src/types/onyx/ReportAction'; @@ -11,15 +9,6 @@ import Navigation from './Navigation/Navigation'; import Parser from './Parser'; import {getReportActionHtml, getReportActionText} from './ReportActionsUtils'; -let allReports: OnyxCollection = {}; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => { - allReports = value; - }, -}); - /** * Check if the active route belongs to task edit flow. */ @@ -52,23 +41,21 @@ function getTaskReportActionMessage(action: OnyxEntry): Pick, fallbackTitle = '', shouldReturnMarkdown = false): string { +function getTaskTitleFromReport(taskReport?: OnyxEntry, fallbackTitle = '', shouldReturnMarkdown = false): string { // We need to check for reportID, not just reportName, because when a receiver opens the task for the first time, // an optimistic report is created with the only property - reportName: 'Chat report', // and it will be displayed as the task title without checking for reportID to be present. - const title = taskReport?.reportID && taskReport.reportName ? taskReport.reportName : fallbackTitle; + const title = taskReport && taskReport?.reportID && taskReport.reportName ? taskReport.reportName : fallbackTitle; return shouldReturnMarkdown ? Parser.htmlToMarkdown(title) : Parser.htmlToText(title).trim(); } -function getTaskTitle(taskReportID: string | undefined, fallbackTitle = '', shouldReturnMarkdown = false): string { - const taskReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]; +function getTaskTitle(taskReport?: Report, fallbackTitle = '', shouldReturnMarkdown = false): string { return getTaskTitleFromReport(taskReport, fallbackTitle, shouldReturnMarkdown); } -function getTaskCreatedMessage(reportAction: OnyxEntry, shouldReturnMarkdown = false) { - const taskReportID = reportAction?.childReportID; - const taskTitle = getTaskTitle(taskReportID, reportAction?.childReportName, shouldReturnMarkdown); +function getTaskCreatedMessage(reportAction: OnyxEntry, taskReport?: Report, shouldReturnMarkdown = false) { + const taskTitle = getTaskTitle(taskReport, reportAction?.childReportName, shouldReturnMarkdown); return taskTitle ? translateLocal('task.messages.created', {title: taskTitle}) : ''; } diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 140fa0e36304..3a8c37e381d2 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -355,6 +355,7 @@ function BaseReportActionContextMenu({ card, originalReport, isTryNewDotNVPDismissed, + childReport, }; if ('renderContent' in contextAction) { diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index dddf6422fcf9..e19f3672a9de 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -200,6 +200,7 @@ type ContextMenuActionPayload = { card?: Card; originalReport: OnyxEntry; isTryNewDotNVPDismissed?: boolean; + childReport?: OnyxEntry; }; type OnPress = (closePopover: boolean, payload: ContextMenuActionPayload, selection?: string, reportID?: string, draftMessage?: string) => void; @@ -497,7 +498,7 @@ const ContextMenuActions: ContextMenuAction[] = [ // If return value is true, we switch the `text` and `icon` on // `ContextMenuItem` with `successText` and `successIcon` which will fall back to // the `text` and `icon` - onPress: (closePopover, {reportAction, transaction, selection, report, reportID, card, originalReport, isTryNewDotNVPDismissed}) => { + onPress: (closePopover, {reportAction, transaction, selection, report, reportID, card, originalReport, isTryNewDotNVPDismissed, childReport}) => { const isReportPreviewAction = isReportPreviewActionReportActionsUtils(reportAction); const messageHtml = getActionHtml(reportAction); const messageText = getReportActionMessageText(reportAction); @@ -528,7 +529,7 @@ const ContextMenuActions: ContextMenuAction[] = [ setClipboardMessage(displayMessage); } } else if (isCreatedTaskReportAction(reportAction)) { - const taskPreviewMessage = getTaskCreatedMessage(reportAction, true); + const taskPreviewMessage = getTaskCreatedMessage(reportAction, childReport, true); Clipboard.setString(taskPreviewMessage); } else if (isMemberChangeAction(reportAction)) { const logMessage = getMemberChangeMessageFragment(reportAction, getReportName).html ?? ''; From 07e4bc5ceda1fb961677e07c7e52f051cf3003f6 Mon Sep 17 00:00:00 2001 From: Rajat Date: Thu, 2 Oct 2025 13:24:05 +0530 Subject: [PATCH 2/3] Update types and small updates Co-authored-by: Kevin Brian Bader <56457735+ikevin127@users.noreply.github.com> --- src/libs/OptionsListUtils/index.ts | 3 +-- src/libs/TaskUtils.ts | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index 48838bf0c518..e9180056081b 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -643,8 +643,7 @@ function getLastMessageTextForReport({ } else if (isTaskAction(lastReportAction)) { lastMessageTextFromReport = formatReportLastMessageText(getTaskReportActionMessage(lastReportAction).text); } else if (isCreatedTaskReportAction(lastReportAction)) { - const lastReportActionChildReport = lastReportAction?.childReportID ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${lastReportAction.childReportID}`] : undefined; - lastMessageTextFromReport = getTaskCreatedMessage(lastReportAction, lastReportActionChildReport); + lastMessageTextFromReport = getTaskCreatedMessage(lastReportAction, getReportOrDraftReport(lastReportAction?.childReportID)); } else if ( isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED) || isActionOfType(lastReportAction, CONST.REPORT.ACTIONS.TYPE.SUBMITTED_AND_CLOSED) || diff --git a/src/libs/TaskUtils.ts b/src/libs/TaskUtils.ts index 1da5966d6ab4..2ff1369e7521 100644 --- a/src/libs/TaskUtils.ts +++ b/src/libs/TaskUtils.ts @@ -45,16 +45,16 @@ function getTaskTitleFromReport(taskReport?: OnyxEntry, fallbackTitle = // We need to check for reportID, not just reportName, because when a receiver opens the task for the first time, // an optimistic report is created with the only property - reportName: 'Chat report', // and it will be displayed as the task title without checking for reportID to be present. - const title = taskReport && taskReport?.reportID && taskReport.reportName ? taskReport.reportName : fallbackTitle; + const title = taskReport?.reportID && taskReport.reportName ? taskReport.reportName : fallbackTitle; return shouldReturnMarkdown ? Parser.htmlToMarkdown(title) : Parser.htmlToText(title).trim(); } -function getTaskTitle(taskReport?: Report, fallbackTitle = '', shouldReturnMarkdown = false): string { +function getTaskTitle(taskReport?: OnyxEntry, fallbackTitle = '', shouldReturnMarkdown = false): string { return getTaskTitleFromReport(taskReport, fallbackTitle, shouldReturnMarkdown); } -function getTaskCreatedMessage(reportAction: OnyxEntry, taskReport?: Report, shouldReturnMarkdown = false) { +function getTaskCreatedMessage(reportAction: OnyxEntry, taskReport?: OnyxEntry, shouldReturnMarkdown = false) { const taskTitle = getTaskTitle(taskReport, reportAction?.childReportName, shouldReturnMarkdown); return taskTitle ? translateLocal('task.messages.created', {title: taskTitle}) : ''; } From 3cd024cdf030fcc65e5c5cd20ec29b964c85daad Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Thu, 2 Oct 2025 16:06:55 +0530 Subject: [PATCH 3/3] Add unit tests --- tests/unit/libs/TaskutilsTest.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/unit/libs/TaskutilsTest.ts diff --git a/tests/unit/libs/TaskutilsTest.ts b/tests/unit/libs/TaskutilsTest.ts new file mode 100644 index 000000000000..11529a6f9ebf --- /dev/null +++ b/tests/unit/libs/TaskutilsTest.ts @@ -0,0 +1,31 @@ +import {getTaskTitle} from '../../../src/libs/TaskUtils'; +import {createRegularTaskReport} from '../../utils/collections/reports'; + +jest.mock('../../../src/libs/Localize'); + +describe('TaskUtils', () => { + describe('getTaskTitle', () => { + it('should return the task title from the report', () => { + const taskReport = createRegularTaskReport(1, 123); + taskReport.reportName = 'Task Title'; + expect(getTaskTitle(taskReport)).toBe('Task Title'); + }); + + it('should return the fallback title if reportName is not present', () => { + const taskReport = {reportID: '123'}; + expect(getTaskTitle(taskReport, 'Fallback Title')).toBe('Fallback Title'); + }); + + it('should return the fallback title if reportID is not present', () => { + const taskReport = createRegularTaskReport(1, 123); + taskReport.reportID = ''; + expect(getTaskTitle(taskReport, 'Fallback Title')).toBe('Fallback Title'); + }); + + it('should return the title in markdown if shouldReturnMarkdown is true', () => { + const taskReport = createRegularTaskReport(1, 123); + taskReport.reportName = 'Task Title'; + expect(getTaskTitle(taskReport, '', true)).toBe('*Task* Title'); + }); + }); +});