From beb006f9e68dfc560e39183a219a337937f7e7d8 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 13 Oct 2024 16:35:53 +0530 Subject: [PATCH 01/24] fix: Room - Create room whisper reappears when interacting with it after workspace is deleted. Signed-off-by: krishna2323 --- .../AttachmentCarousel/extractAttachments.ts | 5 +++-- .../AttachmentCarousel/index.native.tsx | 4 ++-- .../Attachments/AttachmentCarousel/index.tsx | 18 +++++++++++++++--- src/components/ParentNavigationSubtitle.tsx | 2 +- src/libs/OptionsListUtils.ts | 4 ++-- src/libs/ReportActionsUtils.ts | 19 ++++++++++++++----- src/libs/SidebarUtils.ts | 2 +- src/pages/home/ReportScreen.tsx | 5 ++++- src/pages/home/report/ReportActionsList.tsx | 4 ++-- 9 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts index 81ee6d08934b..69b0b8229f4a 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts +++ b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts @@ -19,7 +19,8 @@ function extractAttachments( accountID, parentReportAction, reportActions, - }: {privateNotes?: Record; accountID?: number; parentReportAction?: OnyxEntry; reportActions?: OnyxEntry}, + reportID, + }: {privateNotes?: Record; accountID?: number; parentReportAction?: OnyxEntry; reportActions?: OnyxEntry; reportID: string}, ) { const targetNote = privateNotes?.[Number(accountID)]?.note ?? ''; const attachments: Attachment[] = []; @@ -95,7 +96,7 @@ function extractAttachments( const actions = [...(parentReportAction ? [parentReportAction] : []), ...ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}))]; actions.forEach((action, key) => { - if (!ReportActionsUtils.shouldReportActionBeVisible(action, key) || ReportActionsUtils.isMoneyRequestAction(action)) { + if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, reportID) || ReportActionsUtils.isMoneyRequestAction(action)) { return; } diff --git a/src/components/Attachments/AttachmentCarousel/index.native.tsx b/src/components/Attachments/AttachmentCarousel/index.native.tsx index a8eb614202a7..9aa619eb1cda 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.native.tsx @@ -34,9 +34,9 @@ function AttachmentCarousel({report, source, onNavigate, setDownloadButtonVisibi const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined; let newAttachments: Attachment[] = []; if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) { - newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID, reportID: report.reportID}); } else { - newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions, reportID: report.reportID}); } let newIndex = newAttachments.findIndex(compareImage); diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx index a1408aaf400e..ac4975d85665 100644 --- a/src/components/Attachments/AttachmentCarousel/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.tsx @@ -76,9 +76,9 @@ function AttachmentCarousel({report, source, onNavigate, setDownloadButtonVisibi const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined; let newAttachments: Attachment[] = []; if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) { - newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID, reportID: report.reportID}); } else { - newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined, reportID: report.reportID}); } if (isEqual(attachments, newAttachments)) { @@ -117,7 +117,19 @@ function AttachmentCarousel({report, source, onNavigate, setDownloadButtonVisibi onNavigate(attachment); } } - }, [report.privateNotes, reportActions, parentReportActions, compareImage, report.parentReportActionID, attachments, setDownloadButtonVisibility, onNavigate, accountID, type]); + }, [ + report.privateNotes, + reportActions, + parentReportActions, + compareImage, + report.parentReportActionID, + attachments, + setDownloadButtonVisibility, + onNavigate, + accountID, + type, + report.reportID, + ]); // Scroll position is affected when window width is resized, so we readjust it on width changes useEffect(() => { diff --git a/src/components/ParentNavigationSubtitle.tsx b/src/components/ParentNavigationSubtitle.tsx index 997106f3e649..ef0f981a8c77 100644 --- a/src/components/ParentNavigationSubtitle.tsx +++ b/src/components/ParentNavigationSubtitle.tsx @@ -39,7 +39,7 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct { const parentAction = ReportActionsUtils.getReportAction(parentReportID, parentReportActionID ?? '-1'); - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1'); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1', parentReportID); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReportID)); if (isVisibleAction && !isOffline) { diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index fbf2f3b94c7c..2e19d5a9538f 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -327,7 +327,7 @@ Onyx.connect({ // does not match a closed or created state. const reportActionsForDisplay = sortedReportActions.filter( (reportAction, actionKey) => - ReportActionUtils.shouldReportActionBeVisible(reportAction, actionKey) && + ReportActionUtils.shouldReportActionBeVisible(reportAction, actionKey, reportID) && !ReportActionUtils.isWhisperAction(reportAction) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && @@ -677,7 +677,7 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails const iouReport = ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); const lastIOUMoneyReportAction = allSortedReportActions[iouReport?.reportID ?? '-1']?.find( (reportAction, key): reportAction is ReportAction => - ReportActionUtils.shouldReportActionBeVisible(reportAction, key) && + ReportActionUtils.shouldReportActionBeVisible(reportAction, key, reportID) && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && ReportActionUtils.isMoneyRequestAction(reportAction), ); diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 3b5e0a8eeaa3..105fbee48c31 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -27,6 +27,7 @@ import Parser from './Parser'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportConnection from './ReportConnection'; +import * as ReportUtils from './ReportUtils'; import type {OptimisticIOUReportAction, PartialReportAction} from './ReportUtils'; import StringUtils from './StringUtils'; // eslint-disable-next-line import/no-cycle @@ -630,7 +631,15 @@ const supportedActionTypes: ReportActionName[] = [...Object.values(otherActionTy * Checks if a reportAction is fit for display, meaning that it's not deprecated, is of a valid * and supported type, it's not deleted and also not closed. */ -function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number): boolean { +function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, reportID: string): boolean { + const report = ReportUtils.getReport(reportID); + if ( + (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPending(report?.reportID ?? '-1') || isActionableMentionWhisper(reportAction)) && + !ReportUtils.canUserPerformWriteAction(report) + ) { + return false; + } + if (!reportAction) { return false; } @@ -706,7 +715,7 @@ function isResolvedActionTrackExpense(reportAction: OnyxEntry): bo * Checks if a reportAction is fit for display as report last action, meaning that * it satisfies shouldReportActionBeVisible, it's not whisper action and not deleted. */ -function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry): boolean { +function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry, reportID: string): boolean { if (!reportAction) { return false; } @@ -718,7 +727,7 @@ function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry< // If a whisper action is the REPORT_PREVIEW action, we are displaying it. // If the action's message text is empty and it is not a deleted parent with visible child actions, hide it. Else, consider the action to be displayable. return ( - shouldReportActionBeVisible(reportAction, reportAction.reportActionID) && + shouldReportActionBeVisible(reportAction, reportAction.reportActionID, reportID) && !(isWhisperAction(reportAction) && !isReportPreviewAction(reportAction) && !isMoneyRequestAction(reportAction)) && !(isDeletedAction(reportAction) && !isDeletedParentAction(reportAction)) && !isResolvedActionTrackExpense(reportAction) @@ -760,7 +769,7 @@ function getLastVisibleAction(reportID: string, actionsToMerge: Record shouldReportActionBeVisibleAsLastAction(action)); + const visibleReportActions = reportActions.filter((action): action is ReportAction => shouldReportActionBeVisibleAsLastAction(action, reportID)); const sortedReportActions = getSortedReportActions(visibleReportActions, true); if (sortedReportActions.length === 0) { return undefined; @@ -1087,7 +1096,7 @@ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEn */ function doesReportHaveVisibleActions(reportID: string, actionsToMerge: ReportActions = {}): boolean { const reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge, true)); - const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action)); + const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action, reportID)); // Exclude the task system message and the created message const visibleReportActionsWithoutTaskSystemMessage = visibleReportActions.filter((action) => !isTaskAction(action) && !isCreatedAction(action)); diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index eb5b3c58cdef..4c2a245af9dc 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -46,7 +46,7 @@ Onyx.connect({ // The report is only visible if it is the last action not deleted that // does not match a closed or created state. const reportActionsForDisplay = actionsArray.filter( - (reportAction) => ReportActionsUtils.shouldReportActionBeVisibleAsLastAction(reportAction) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED, + (reportAction) => ReportActionsUtils.shouldReportActionBeVisibleAsLastAction(reportAction, reportID) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED, ); const reportAction = reportActionsForDisplay.at(-1); diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 8afeb0cf2307..56545e80aeae 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -335,7 +335,10 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro ? reportActions.length > 0 : reportActions.length >= CONST.REPORT.MIN_INITIAL_REPORT_ACTION_COUNT || isPendingActionExist || (doesCreatedActionExists() && reportActions.length > 0); - const isLinkedActionDeleted = useMemo(() => !!linkedAction && !ReportActionsUtils.shouldReportActionBeVisible(linkedAction, linkedAction.reportActionID), [linkedAction]); + const isLinkedActionDeleted = useMemo( + () => !!linkedAction && !ReportActionsUtils.shouldReportActionBeVisible(linkedAction, linkedAction.reportActionID, report?.reportID ?? '-1'), + [linkedAction, report?.reportID], + ); const prevIsLinkedActionDeleted = usePrevious(linkedAction ? isLinkedActionDeleted : undefined); const isLinkedActionInaccessibleWhisper = useMemo( () => !!linkedAction && ReportActionsUtils.isWhisperAction(linkedAction) && !(linkedAction?.whisperedToAccountIDs ?? []).includes(currentUserAccountID), diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index ce925d4375af..6025fe64ffb2 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -193,9 +193,9 @@ function ReportActionsList({ ReportActionsUtils.isDeletedParentAction(reportAction) || reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || reportAction.errors) && - ReportActionsUtils.shouldReportActionBeVisible(reportAction, reportAction.reportActionID), + ReportActionsUtils.shouldReportActionBeVisible(reportAction, reportAction.reportActionID, report.reportID), ), - [sortedReportActions, isOffline], + [sortedReportActions, isOffline, report.reportID], ); /** From 921f47429960cd6b5f1110e50f5bb7139a6736e2 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 13 Oct 2024 16:43:39 +0530 Subject: [PATCH 02/24] fix lint issues. Signed-off-by: krishna2323 --- src/libs/ReportActionsUtils.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 105fbee48c31..8681980163e6 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -28,7 +28,6 @@ import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportConnection from './ReportConnection'; import * as ReportUtils from './ReportUtils'; -import type {OptimisticIOUReportAction, PartialReportAction} from './ReportUtils'; import StringUtils from './StringUtils'; // eslint-disable-next-line import/no-cycle import * as TransactionUtils from './TransactionUtils'; @@ -123,7 +122,7 @@ function isCreatedAction(reportAction: OnyxInputOrEntry): boolean return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED; } -function isDeletedAction(reportAction: OnyxInputOrEntry): boolean { +function isDeletedAction(reportAction: OnyxInputOrEntry): boolean { const message = reportAction?.message ?? []; if (!Array.isArray(message)) { @@ -136,7 +135,7 @@ function isDeletedAction(reportAction: OnyxInputOrEntry): bo return (getReportActionMessage(reportAction)?.isDeletedParentAction ?? false) && (reportAction?.childVisibleActionCount ?? 0) > 0; } -function isReversedTransaction(reportAction: OnyxInputOrEntry) { +function isReversedTransaction(reportAction: OnyxInputOrEntry) { return (getReportActionMessage(reportAction)?.isReversedTransaction ?? false) && ((reportAction as ReportAction)?.childVisibleActionCount ?? 0) > 0; } @@ -360,7 +359,7 @@ function getParentReportAction(report: OnyxInputOrEntry): OnyxEntry): boolean { +function isSentMoneyReportAction(reportAction: OnyxEntry): boolean { return ( isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY && @@ -990,11 +989,11 @@ function isSplitBillAction(reportAction: OnyxInputOrEntry): report return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT; } -function isTrackExpenseAction(reportAction: OnyxEntry): reportAction is ReportAction { +function isTrackExpenseAction(reportAction: OnyxEntry): reportAction is ReportAction { return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.TRACK; } -function isPayAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction { +function isPayAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction { return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY; } @@ -1204,7 +1203,7 @@ function getMemberChangeMessageElements(reportAction: OnyxEntry): ]; } -function getReportActionHtml(reportAction: PartialReportAction): string { +function getReportActionHtml(reportAction: ReportUtils.PartialReportAction): string { return getReportActionMessage(reportAction)?.html ?? ''; } @@ -1220,7 +1219,7 @@ function getTextFromHtml(html?: string): string { return html ? Parser.htmlToText(html) : ''; } -function isOldDotLegacyAction(action: OldDotReportAction | PartialReportAction): action is PartialReportAction { +function isOldDotLegacyAction(action: OldDotReportAction | ReportUtils.PartialReportAction): action is ReportUtils.PartialReportAction { return [ CONST.REPORT.ACTIONS.TYPE.DELETED_ACCOUNT, CONST.REPORT.ACTIONS.TYPE.DONATION, @@ -1260,7 +1259,7 @@ function isOldDotReportAction(action: ReportAction | OldDotReportAction) { ].some((oldDotActionName) => oldDotActionName === action.actionName); } -function getMessageOfOldDotLegacyAction(legacyAction: PartialReportAction) { +function getMessageOfOldDotLegacyAction(legacyAction: ReportUtils.PartialReportAction) { if (!Array.isArray(legacyAction?.message)) { return getReportActionText(legacyAction); } @@ -1275,7 +1274,7 @@ function getMessageOfOldDotLegacyAction(legacyAction: PartialReportAction) { /** * Helper method to format message of OldDot Actions. */ -function getMessageOfOldDotReportAction(oldDotAction: PartialReportAction | OldDotReportAction, withMarkdown = true): string { +function getMessageOfOldDotReportAction(oldDotAction: ReportUtils.PartialReportAction | OldDotReportAction, withMarkdown = true): string { if (isOldDotLegacyAction(oldDotAction)) { return getMessageOfOldDotLegacyAction(oldDotAction); } From 597e24318607e9d089961b35b9d008ceef0c9894 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 13 Oct 2024 17:58:44 +0530 Subject: [PATCH 03/24] minor update. Signed-off-by: krishna2323 --- .../LHNOptionsList/LHNOptionsList.tsx | 2 +- src/hooks/usePaginatedReportActions.ts | 2 +- src/libs/Middleware/Pagination.ts | 4 +-- src/libs/ReportActionsUtils.ts | 31 ++++++++++--------- src/libs/actions/Report.ts | 2 +- src/pages/Debug/Report/DebugReportActions.tsx | 2 +- .../report/ReportActionItemParentAction.tsx | 6 +++- src/pages/home/report/ReportActionsView.tsx | 2 +- src/pages/home/report/ThreadDivider.tsx | 2 +- .../perf-test/ReportActionsUtils.perf-test.ts | 4 +-- tests/unit/ReportActionsUtilsTest.ts | 6 ++-- 11 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 08240a211804..b317d3020e2a 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -139,7 +139,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio : '-1'; const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const hasDraftComment = DraftCommentUtils.isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); - const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions); + const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions, reportID); const lastReportAction = sortedReportActions.at(0); // Get the transaction for the last report action diff --git a/src/hooks/usePaginatedReportActions.ts b/src/hooks/usePaginatedReportActions.ts index a32d4f7d3dd0..e3525dcf91f5 100644 --- a/src/hooks/usePaginatedReportActions.ts +++ b/src/hooks/usePaginatedReportActions.ts @@ -14,7 +14,7 @@ function usePaginatedReportActions(reportID?: string, reportActionID?: string) { const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportIDWithDefault}`, { canEvict: false, - selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID, true), }); const [reportActionPages] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES}${reportIDWithDefault}`); diff --git a/src/libs/Middleware/Pagination.ts b/src/libs/Middleware/Pagination.ts index bfa8183ac03b..7b3abdee849c 100644 --- a/src/libs/Middleware/Pagination.ts +++ b/src/libs/Middleware/Pagination.ts @@ -15,7 +15,7 @@ type PagedResource = OnyxValues[TResourc type PaginationCommonConfig = { resourceCollectionKey: TResourceKey; pageCollectionKey: TPageKey; - sortItems: (items: OnyxValues[TResourceKey]) => Array>; + sortItems: (items: OnyxValues[TResourceKey], reportID: string) => Array>; getItemID: (item: PagedResource) => string; }; @@ -96,7 +96,7 @@ const Pagination: Middleware = (requestResponse, request) => { // Create a new page based on the response const pageItems = (response.onyxData.find((data) => data.key === resourceKey)?.value ?? {}) as OnyxValues[typeof resourceCollectionKey]; - const sortedPageItems = sortItems(pageItems); + const sortedPageItems = sortItems(pageItems, resourceID); if (sortedPageItems.length === 0) { // Must have at least 1 action to create a page. Log.hmmm(`[Pagination] Did not receive any items in the response to ${request.command}`); diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 8681980163e6..8a1ff9431e28 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -27,7 +27,8 @@ import Parser from './Parser'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportConnection from './ReportConnection'; -import * as ReportUtils from './ReportUtils'; +import type {OptimisticIOUReportAction, PartialReportAction} from './ReportUtils'; +import {canUserPerformWriteAction, getReport} from './ReportUtils.ts'; import StringUtils from './StringUtils'; // eslint-disable-next-line import/no-cycle import * as TransactionUtils from './TransactionUtils'; @@ -122,7 +123,7 @@ function isCreatedAction(reportAction: OnyxInputOrEntry): boolean return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED; } -function isDeletedAction(reportAction: OnyxInputOrEntry): boolean { +function isDeletedAction(reportAction: OnyxInputOrEntry): boolean { const message = reportAction?.message ?? []; if (!Array.isArray(message)) { @@ -135,7 +136,7 @@ function isDeletedAction(reportAction: OnyxInputOrEntry): bo return (getReportActionMessage(reportAction)?.isDeletedParentAction ?? false) && (reportAction?.childVisibleActionCount ?? 0) > 0; } -function isReversedTransaction(reportAction: OnyxInputOrEntry) { +function isReversedTransaction(reportAction: OnyxInputOrEntry) { return (getReportActionMessage(reportAction)?.isReversedTransaction ?? false) && ((reportAction as ReportAction)?.childVisibleActionCount ?? 0) > 0; } @@ -359,7 +360,7 @@ function getParentReportAction(report: OnyxInputOrEntry): OnyxEntry): boolean { +function isSentMoneyReportAction(reportAction: OnyxEntry): boolean { return ( isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY && @@ -631,10 +632,10 @@ const supportedActionTypes: ReportActionName[] = [...Object.values(otherActionTy * and supported type, it's not deleted and also not closed. */ function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, reportID: string): boolean { - const report = ReportUtils.getReport(reportID); + const report = getReport(reportID); if ( (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPending(report?.reportID ?? '-1') || isActionableMentionWhisper(reportAction)) && - !ReportUtils.canUserPerformWriteAction(report) + !canUserPerformWriteAction(report) ) { return false; } @@ -834,7 +835,7 @@ function filterOutDeprecatedReportActions(reportActions: OnyxEntry | ReportAction[], shouldIncludeInvisibleActions = false): ReportAction[] { +function getSortedReportActionsForDisplay(reportActions: OnyxEntry | ReportAction[], reportID: string, shouldIncludeInvisibleActions = false): ReportAction[] { let filteredReportActions: ReportAction[] = []; if (!reportActions) { return []; @@ -844,7 +845,7 @@ function getSortedReportActionsForDisplay(reportActions: OnyxEntry shouldReportActionBeVisible(reportAction, key)) + .filter(([key, reportAction]) => shouldReportActionBeVisible(reportAction, key, reportID)) .map(([, reportAction]) => reportAction); } @@ -989,11 +990,11 @@ function isSplitBillAction(reportAction: OnyxInputOrEntry): report return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT; } -function isTrackExpenseAction(reportAction: OnyxEntry): reportAction is ReportAction { +function isTrackExpenseAction(reportAction: OnyxEntry): reportAction is ReportAction { return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.TRACK; } -function isPayAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction { +function isPayAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction { return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(reportAction)?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY; } @@ -1203,7 +1204,7 @@ function getMemberChangeMessageElements(reportAction: OnyxEntry): ]; } -function getReportActionHtml(reportAction: ReportUtils.PartialReportAction): string { +function getReportActionHtml(reportAction: PartialReportAction): string { return getReportActionMessage(reportAction)?.html ?? ''; } @@ -1219,7 +1220,7 @@ function getTextFromHtml(html?: string): string { return html ? Parser.htmlToText(html) : ''; } -function isOldDotLegacyAction(action: OldDotReportAction | ReportUtils.PartialReportAction): action is ReportUtils.PartialReportAction { +function isOldDotLegacyAction(action: OldDotReportAction | PartialReportAction): action is PartialReportAction { return [ CONST.REPORT.ACTIONS.TYPE.DELETED_ACCOUNT, CONST.REPORT.ACTIONS.TYPE.DONATION, @@ -1259,7 +1260,7 @@ function isOldDotReportAction(action: ReportAction | OldDotReportAction) { ].some((oldDotActionName) => oldDotActionName === action.actionName); } -function getMessageOfOldDotLegacyAction(legacyAction: ReportUtils.PartialReportAction) { +function getMessageOfOldDotLegacyAction(legacyAction: PartialReportAction) { if (!Array.isArray(legacyAction?.message)) { return getReportActionText(legacyAction); } @@ -1274,7 +1275,7 @@ function getMessageOfOldDotLegacyAction(legacyAction: ReportUtils.PartialReportA /** * Helper method to format message of OldDot Actions. */ -function getMessageOfOldDotReportAction(oldDotAction: ReportUtils.PartialReportAction | OldDotReportAction, withMarkdown = true): string { +function getMessageOfOldDotReportAction(oldDotAction: PartialReportAction | OldDotReportAction, withMarkdown = true): string { if (isOldDotLegacyAction(oldDotAction)) { return getMessageOfOldDotLegacyAction(oldDotAction); } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 13b14d380758..7ac929b9fad0 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -274,7 +274,7 @@ registerPaginationConfig({ nextCommand: READ_COMMANDS.GET_NEWER_ACTIONS, resourceCollectionKey: ONYXKEYS.COLLECTION.REPORT_ACTIONS, pageCollectionKey: ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES, - sortItems: (reportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true), + sortItems: (reportActions, reportID) => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportID, true), getItemID: (reportAction) => reportAction.reportActionID, }); diff --git a/src/pages/Debug/Report/DebugReportActions.tsx b/src/pages/Debug/Report/DebugReportActions.tsx index e7c4059fffe7..d25c9175a4b3 100644 --- a/src/pages/Debug/Report/DebugReportActions.tsx +++ b/src/pages/Debug/Report/DebugReportActions.tsx @@ -23,7 +23,7 @@ function DebugReportActions({reportID}: DebugReportActionsProps) { const styles = useThemeStyles(); const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, { canEvict: false, - selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID, true), }); const renderItem = ({item}: ListRenderItemInfo) => ( { - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(ancestor.reportAction, ancestor.reportAction.reportActionID ?? '-1'); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( + ancestor.reportAction, + ancestor.reportAction.reportActionID ?? '-1', + ancestor.report.reportID, + ); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); if (isVisibleAction && !isOffline) { diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index 8896611905ca..b58de22bc520 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -90,7 +90,7 @@ function ReportActionsView({ const route = useRoute>(); const [session] = useOnyx(ONYXKEYS.SESSION); const [transactionThreadReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID ?? -1}`, { - selector: (reportActions: OnyxEntry) => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true), + selector: (reportActions: OnyxEntry) => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, report.reportID, true), }); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID ?? -1}`); const prevTransactionThreadReport = usePrevious(transactionThreadReport); diff --git a/src/pages/home/report/ThreadDivider.tsx b/src/pages/home/report/ThreadDivider.tsx index d2ffa97f58b2..6fec617e4c37 100644 --- a/src/pages/home/report/ThreadDivider.tsx +++ b/src/pages/home/report/ThreadDivider.tsx @@ -47,7 +47,7 @@ function ThreadDivider({ancestor, isLinkDisabled = false}: ThreadDividerProps) { ) : ( { - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(ancestor.reportAction, ancestor.reportAction.reportActionID ?? '-1'); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(ancestor.reportAction, ancestor.reportAction.reportActionID ?? '-1', ancestor.report.reportID); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); if (isVisibleAction && !isOffline) { diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index a33a448cfee7..5e258436edc7 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -93,7 +93,7 @@ describe('ReportActionsUtils', () => { }); test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions); + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId); await waitForBatchedUpdates(); await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray)); @@ -132,7 +132,7 @@ describe('ReportActionsUtils', () => { test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions)); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId)); }); test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index d753069265f8..b6e29e89d025 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -302,7 +302,7 @@ describe('ReportActionsUtils', () => { }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1'); expect(result).toStrictEqual(input); }); @@ -392,7 +392,7 @@ describe('ReportActionsUtils', () => { ], }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1'); input.pop(); expect(result).toStrictEqual(input); }); @@ -437,7 +437,7 @@ describe('ReportActionsUtils', () => { message: [{html: '', type: 'Action type', text: 'Action text'}], }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1'); input.pop(); expect(result).toStrictEqual(input); }); From 352abf82c0e2c577133871a18813af3189dbe22b Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 13 Oct 2024 17:59:42 +0530 Subject: [PATCH 04/24] minor update. Signed-off-by: krishna2323 --- src/libs/Middleware/Pagination.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Middleware/Pagination.ts b/src/libs/Middleware/Pagination.ts index 7b3abdee849c..251609d1254c 100644 --- a/src/libs/Middleware/Pagination.ts +++ b/src/libs/Middleware/Pagination.ts @@ -115,7 +115,7 @@ const Pagination: Middleware = (requestResponse, request) => { const resourceCollections = resources.get(resourceCollectionKey) ?? {}; const existingItems = resourceCollections[resourceKey] ?? {}; const allItems = fastMerge(existingItems, pageItems, true); - const sortedAllItems = sortItems(allItems); + const sortedAllItems = sortItems(allItems, resourceID); const pagesCollections = pages.get(pageCollectionKey) ?? {}; const existingPages = pagesCollections[pageKey] ?? []; From 534c19e7e5fbd9c934bd725ef5570c9525012530 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 13 Oct 2024 21:44:24 +0530 Subject: [PATCH 05/24] fix lint issue. Signed-off-by: krishna2323 --- src/hooks/usePaginatedReportActions.ts | 2 +- src/libs/ReportActionsUtils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/usePaginatedReportActions.ts b/src/hooks/usePaginatedReportActions.ts index e3525dcf91f5..342d73b08bd8 100644 --- a/src/hooks/usePaginatedReportActions.ts +++ b/src/hooks/usePaginatedReportActions.ts @@ -14,7 +14,7 @@ function usePaginatedReportActions(reportID?: string, reportActionID?: string) { const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportIDWithDefault}`, { canEvict: false, - selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID, true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID ?? '-1', true), }); const [reportActionPages] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES}${reportIDWithDefault}`); diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 8a1ff9431e28..0807f8f95ed7 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -28,7 +28,7 @@ import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportConnection from './ReportConnection'; import type {OptimisticIOUReportAction, PartialReportAction} from './ReportUtils'; -import {canUserPerformWriteAction, getReport} from './ReportUtils.ts'; +import {canUserPerformWriteAction, getReport} from './ReportUtils'; import StringUtils from './StringUtils'; // eslint-disable-next-line import/no-cycle import * as TransactionUtils from './TransactionUtils'; From e602e696743a5f2554fc5cf4f86872776ac47e93 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 31 Oct 2024 04:56:08 +0530 Subject: [PATCH 06/24] pass 'canUserPerformWriteAction' to shouldReportActionBeVisible. Signed-off-by: krishna2323 --- .../AttachmentCarousel/extractAttachments.ts | 5 +- .../LHNOptionsList/LHNOptionsList.tsx | 4 +- src/components/ParentNavigationSubtitle.tsx | 5 +- src/hooks/usePaginatedReportActions.ts | 5 +- src/libs/OptionsListUtils.ts | 7 +- src/libs/ReportActionsUtils.ts | 33 ++--- src/libs/actions/Report.ts | 21 +++- src/pages/Debug/Report/DebugReportActions.tsx | 5 +- src/pages/home/ReportScreen.tsx | 6 +- .../report/ReportActionItemParentAction.tsx | 113 +++++++++--------- src/pages/home/report/ReportActionsList.tsx | 4 +- src/pages/home/report/ReportActionsView.tsx | 3 +- src/pages/home/report/ThreadDivider.tsx | 8 +- .../perf-test/ReportActionsUtils.perf-test.ts | 8 +- tests/unit/ReportActionsUtilsTest.ts | 6 +- 15 files changed, 137 insertions(+), 96 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts index 69b0b8229f4a..5ebaf8af673e 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts +++ b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts @@ -4,6 +4,7 @@ import type {ValueOf} from 'type-fest'; import type {Attachment} from '@components/Attachments/types'; import * as FileUtils from '@libs/fileDownload/FileUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; import CONST from '@src/CONST'; import type {ReportAction, ReportActions} from '@src/types/onyx'; @@ -24,6 +25,8 @@ function extractAttachments( ) { const targetNote = privateNotes?.[Number(accountID)]?.note ?? ''; const attachments: Attachment[] = []; + const report = ReportUtils.getReport(reportID); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); // We handle duplicate image sources by considering the first instance as original. Selecting any duplicate // and navigating back (<) shows the image preceding the first instance, not the selected duplicate's position. @@ -96,7 +99,7 @@ function extractAttachments( const actions = [...(parentReportAction ? [parentReportAction] : []), ...ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}))]; actions.forEach((action, key) => { - if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, reportID) || ReportActionsUtils.isMoneyRequestAction(action)) { + if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, reportID, canUserPerformWriteAction) || ReportActionsUtils.isMoneyRequestAction(action),) { return; } diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index b317d3020e2a..c03d7822f9e3 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -19,6 +19,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as DraftCommentUtils from '@libs/DraftCommentUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -139,7 +140,8 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio : '-1'; const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const hasDraftComment = DraftCommentUtils.isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); - const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions, reportID); + + const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions, reportID, ReportUtils.canUserPerformWriteAction(itemFullReport)); const lastReportAction = sortedReportActions.at(0); // Get the transaction for the last report action diff --git a/src/components/ParentNavigationSubtitle.tsx b/src/components/ParentNavigationSubtitle.tsx index ef0f981a8c77..248eaec9c9b1 100644 --- a/src/components/ParentNavigationSubtitle.tsx +++ b/src/components/ParentNavigationSubtitle.tsx @@ -5,6 +5,7 @@ import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import type {ParentNavigationSummaryParams} from '@src/languages/params'; import ROUTES from '@src/ROUTES'; @@ -29,6 +30,8 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct const {workspaceName, reportName} = parentNavigationSubtitleData; const {isOffline} = useNetwork(); const {translate} = useLocalize(); + const report = ReportUtils.getReport(parentReportID); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); // We should not display the parent navigation subtitle if the user does not have access to the parent chat (the reportName is empty in this case) if (!reportName) { @@ -39,7 +42,7 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct { const parentAction = ReportActionsUtils.getReportAction(parentReportID, parentReportActionID ?? '-1'); - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1', parentReportID); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1', parentReportID, canUserPerformWriteAction); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReportID)); if (isVisibleAction && !isOffline) { diff --git a/src/hooks/usePaginatedReportActions.ts b/src/hooks/usePaginatedReportActions.ts index 342d73b08bd8..6b476db46d7d 100644 --- a/src/hooks/usePaginatedReportActions.ts +++ b/src/hooks/usePaginatedReportActions.ts @@ -2,6 +2,7 @@ import {useMemo} from 'react'; import {useOnyx} from 'react-native-onyx'; import PaginationUtils from '@libs/PaginationUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import ONYXKEYS from '@src/ONYXKEYS'; /** @@ -11,10 +12,12 @@ function usePaginatedReportActions(reportID?: string, reportActionID?: string) { // Use `||` instead of `??` to handle empty string. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const reportIDWithDefault = reportID || '-1'; + const report = ReportUtils.getReport(reportIDWithDefault); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportIDWithDefault}`, { canEvict: false, - selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID ?? '-1', true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID ?? '-1', canUserPerformWriteAction, true), }); const [reportActionPages] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES}${reportIDWithDefault}`); diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index df4b75893336..9fd121fdfb5b 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -328,11 +328,14 @@ Onyx.connect({ lastReportActions[reportID] = firstReportAction; } + const report = ReportUtils.getReport(reportID); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); + // The report is only visible if it is the last action not deleted that // does not match a closed or created state. const reportActionsForDisplay = sortedReportActions.filter( (reportAction, actionKey) => - ReportActionUtils.shouldReportActionBeVisible(reportAction, actionKey, reportID) && + ReportActionUtils.shouldReportActionBeVisible(reportAction, actionKey, reportID, canUserPerformWriteAction) && !ReportActionUtils.isWhisperAction(reportAction) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && @@ -590,7 +593,7 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails const iouReport = ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); const lastIOUMoneyReportAction = allSortedReportActions[iouReport?.reportID ?? '-1']?.find( (reportAction, key): reportAction is ReportAction => - ReportActionUtils.shouldReportActionBeVisible(reportAction, key, reportID) && + ReportActionUtils.shouldReportActionBeVisible(reportAction, key, reportID, ReportUtils.canUserPerformWriteAction(report)) && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && ReportActionUtils.isMoneyRequestAction(reportAction), ); diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index be0efc67ce5b..7778cb29d552 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -28,7 +28,6 @@ import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportConnection from './ReportConnection'; import type {OptimisticIOUReportAction, PartialReportAction} from './ReportUtils'; -import {canUserPerformWriteAction, getReport} from './ReportUtils'; import StringUtils from './StringUtils'; // eslint-disable-next-line import/no-cycle import * as TransactionUtils from './TransactionUtils'; @@ -636,12 +635,8 @@ const supportedActionTypes: ReportActionName[] = [...Object.values(otherActionTy * Checks if a reportAction is fit for display, meaning that it's not deprecated, is of a valid * and supported type, it's not deleted and also not closed. */ -function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, reportID: string): boolean { - const report = getReport(reportID); - if ( - (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPending(report?.reportID ?? '-1') || isActionableMentionWhisper(reportAction)) && - !canUserPerformWriteAction(report) - ) { +function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, reportID: string, canUserPerformWriteAction?: boolean): boolean { + if ((isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPending(reportID ?? '-1') || isActionableMentionWhisper(reportAction)) && !canUserPerformWriteAction) { return false; } @@ -720,7 +715,7 @@ function isResolvedActionTrackExpense(reportAction: OnyxEntry): bo * Checks if a reportAction is fit for display as report last action, meaning that * it satisfies shouldReportActionBeVisible, it's not whisper action and not deleted. */ -function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry, reportID: string): boolean { +function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry, reportID: string, canUserPerformWriteAction?: boolean): boolean { if (!reportAction) { return false; } @@ -732,7 +727,7 @@ function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry< // If a whisper action is the REPORT_PREVIEW action, we are displaying it. // If the action's message text is empty and it is not a deleted parent with visible child actions, hide it. Else, consider the action to be displayable. return ( - shouldReportActionBeVisible(reportAction, reportAction.reportActionID, reportID) && + shouldReportActionBeVisible(reportAction, reportAction.reportActionID, reportID, canUserPerformWriteAction) && !(isWhisperAction(reportAction) && !isReportPreviewAction(reportAction) && !isMoneyRequestAction(reportAction)) && !(isDeletedAction(reportAction) && !isDeletedParentAction(reportAction)) && !isResolvedActionTrackExpense(reportAction) @@ -765,7 +760,7 @@ function replaceBaseURLInPolicyChangeLogAction(reportAction: ReportAction): Repo return updatedReportAction; } -function getLastVisibleAction(reportID: string, actionsToMerge: Record | null> = {}): OnyxEntry { +function getLastVisibleAction(reportID: string, canUserPerformWriteAction?: boolean, actionsToMerge: Record | null> = {}): OnyxEntry { let reportActions: Array = []; if (!isEmpty(actionsToMerge)) { reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge ?? {}, true)) as Array< @@ -774,7 +769,7 @@ function getLastVisibleAction(reportID: string, actionsToMerge: Record shouldReportActionBeVisibleAsLastAction(action, reportID)); + const visibleReportActions = reportActions.filter((action): action is ReportAction => shouldReportActionBeVisibleAsLastAction(action, reportID, canUserPerformWriteAction)); const sortedReportActions = getSortedReportActions(visibleReportActions, true); if (sortedReportActions.length === 0) { return undefined; @@ -796,10 +791,11 @@ function formatLastMessageText(lastMessageText: string) { function getLastVisibleMessage( reportID: string, + canUserPerformWriteAction?: boolean, actionsToMerge: Record | null> = {}, reportAction: OnyxInputOrEntry | undefined = undefined, ): LastVisibleMessage { - const lastVisibleAction = reportAction ?? getLastVisibleAction(reportID, actionsToMerge); + const lastVisibleAction = reportAction ?? getLastVisibleAction(reportID, canUserPerformWriteAction, actionsToMerge); const message = getReportActionMessage(lastVisibleAction); if (message && isReportMessageAttachment(message)) { @@ -840,7 +836,12 @@ function filterOutDeprecatedReportActions(reportActions: OnyxEntry | ReportAction[], reportID: string, shouldIncludeInvisibleActions = false): ReportAction[] { +function getSortedReportActionsForDisplay( + reportActions: OnyxEntry | ReportAction[], + reportID: string, + canUserPerformWriteAction?: boolean, + shouldIncludeInvisibleActions = false, +): ReportAction[] { let filteredReportActions: ReportAction[] = []; if (!reportActions) { return []; @@ -850,7 +851,7 @@ function getSortedReportActionsForDisplay(reportActions: OnyxEntry shouldReportActionBeVisible(reportAction, key, reportID)) + .filter(([key, reportAction]) => shouldReportActionBeVisible(reportAction, key, reportID, canUserPerformWriteAction)) .map(([, reportAction]) => reportAction); } @@ -1099,9 +1100,9 @@ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEn * When we delete certain reports, we want to check whether there are any visible actions left to display. * If there are no visible actions left (including system messages), we can hide the report from view entirely */ -function doesReportHaveVisibleActions(reportID: string, actionsToMerge: ReportActions = {}): boolean { +function doesReportHaveVisibleActions(reportID: string, canUserPerformWriteAction: boolean, actionsToMerge: ReportActions = {}): boolean { const reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge, true)); - const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action, reportID)); + const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action, reportID, canUserPerformWriteAction)); // Exclude the task system message and the created message const visibleReportActionsWithoutTaskSystemMessage = visibleReportActions.filter((action) => !isTaskAction(action) && !isCreatedAction(action)); diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index c219137e210c..03ad1de54b5d 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -279,7 +279,11 @@ registerPaginationConfig({ nextCommand: READ_COMMANDS.GET_NEWER_ACTIONS, resourceCollectionKey: ONYXKEYS.COLLECTION.REPORT_ACTIONS, pageCollectionKey: ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES, - sortItems: (reportActions, reportID) => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportID, true), + sortItems: (reportActions, reportID) => { + const report = ReportUtils.getReport(reportID); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); + return ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportID, canUserPerformWriteAction, true); + }, getItemID: (reportAction) => reportAction.reportActionID, }); @@ -1450,8 +1454,10 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { lastVisibleActionCreated: '', }; const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportUtils.getLastVisibleMessage(originalReportID, optimisticReportActions as ReportActions); + const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); if (lastMessageText || lastMessageTranslationKey) { - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(originalReportID, optimisticReportActions as ReportActions); + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(originalReportID, canUserPerformWriteAction, optimisticReportActions as ReportActions); const lastVisibleActionCreated = lastVisibleAction?.created; const lastActorAccountID = lastVisibleAction?.actorAccountID; optimisticReport = { @@ -1461,7 +1467,6 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { lastActorAccountID, }; } - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const didCommentMentionCurrentUser = ReportActionsUtils.didMessageMentionCurrentUser(reportAction); if (didCommentMentionCurrentUser && reportAction.created === report?.lastMentionedTime) { const reportActionsForReport = allReportActions?.[reportID]; @@ -1592,6 +1597,8 @@ function handleUserDeletedLinksInHtml(newCommentText: string, originalCommentMar /** Saves a new message for a comment. Marks the comment as edited, which will be reflected in the UI. */ function editReportComment(reportID: string, originalReportAction: OnyxEntry, textForNewComment: string, videoAttributeCache?: Record) { const originalReportID = ReportUtils.getOriginalReportID(reportID, originalReportAction); + const report = ReportUtils.getReport(originalReportID ?? '-1'); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); if (!originalReportID || !originalReportAction) { return; @@ -1657,7 +1664,7 @@ function editReportComment(reportID: string, originalReportAction: OnyxEntry ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID, true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID, canUserPerformWriteAction, true), }); const renderItem = ({item}: ListRenderItemInfo) => ( = CONST.REPORT.MIN_INITIAL_REPORT_ACTION_COUNT || isPendingActionExist || (doesCreatedActionExists() && reportActions.length > 0); const isLinkedActionDeleted = useMemo( - () => !!linkedAction && !ReportActionsUtils.shouldReportActionBeVisible(linkedAction, linkedAction.reportActionID, report?.reportID ?? '-1'), - [linkedAction, report?.reportID], + () => + !!linkedAction && + !ReportActionsUtils.shouldReportActionBeVisible(linkedAction, linkedAction.reportActionID, report?.reportID ?? '-1', ReportUtils.canUserPerformWriteAction(report)), + [linkedAction, report], ); const prevIsLinkedActionDeleted = usePrevious(linkedAction ? isLinkedActionDeleted : undefined); const isLinkedActionInaccessibleWhisper = useMemo( diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 98cd0448e047..67e16e5b068c 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -106,61 +106,66 @@ function ReportActionItemParentAction({ {/* eslint-disable-next-line react-compiler/react-compiler */} - {allAncestors.map((ancestor) => ( - Report.navigateToConciergeChatAndDeleteReport(ancestor.report.reportID)} - > - - {ReportActionsUtils.isTripPreview(ancestor?.reportAction) ? ( - - - - ) : ( - { - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( - ancestor.reportAction, - ancestor.reportAction.reportActionID ?? '-1', - ancestor.report.reportID, - ); - // Pop the thread report screen before navigating to the chat report. - Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); - if (isVisibleAction && !isOffline) { - // Pop the chat report screen before navigating to the linked report action. - Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1', ancestor.reportAction.reportActionID)); - } - } - : undefined - } - parentReportAction={parentReportAction} - report={ancestor.report} - reportActions={reportActions} - transactionThreadReport={transactionThreadReport} - action={ancestor.reportAction} - displayAsGroup={false} - isMostRecentIOUReportAction={false} - shouldDisplayNewMarker={ancestor.shouldDisplayNewMarker} - index={index} - isFirstVisibleReportAction={isFirstVisibleReportAction} - shouldUseThreadDividerLine={shouldUseThreadDividerLine} - hideThreadReplies + {allAncestors.map((ancestor) => { + const ancestorReport = ReportUtils.getReport(ancestor.report.reportID); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(ancestorReport); + return ( + Report.navigateToConciergeChatAndDeleteReport(ancestor.report.reportID)} + > + - )} - - ))} + {ReportActionsUtils.isTripPreview(ancestor?.reportAction) ? ( + + + + ) : ( + { + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( + ancestor.reportAction, + ancestor.reportAction.reportActionID ?? '-1', + ancestor.report.reportID, + canUserPerformWriteAction, + ); + // Pop the thread report screen before navigating to the chat report. + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); + if (isVisibleAction && !isOffline) { + // Pop the chat report screen before navigating to the linked report action. + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1', ancestor.reportAction.reportActionID)); + } + } + : undefined + } + parentReportAction={parentReportAction} + report={ancestor.report} + reportActions={reportActions} + transactionThreadReport={transactionThreadReport} + action={ancestor.reportAction} + displayAsGroup={false} + isMostRecentIOUReportAction={false} + shouldDisplayNewMarker={ancestor.shouldDisplayNewMarker} + index={index} + isFirstVisibleReportAction={isFirstVisibleReportAction} + shouldUseThreadDividerLine={shouldUseThreadDividerLine} + hideThreadReplies + /> + )} + + ); + })} {shouldDisplayReplyDivider && } ); diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 22eda76df1de..95ddd3f561f5 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -195,9 +195,9 @@ function ReportActionsList({ ReportActionsUtils.isDeletedParentAction(reportAction) || reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || reportAction.errors) && - ReportActionsUtils.shouldReportActionBeVisible(reportAction, reportAction.reportActionID, report.reportID), + ReportActionsUtils.shouldReportActionBeVisible(reportAction, reportAction.reportActionID, report.reportID, ReportUtils.canUserPerformWriteAction(report)), ), - [sortedReportActions, isOffline, report.reportID], + [sortedReportActions, isOffline, report], ); const lastAction = sortedVisibleReportActions.at(0); const sortedVisibleReportActionsObjects: OnyxTypes.ReportActions = useMemo( diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index b58de22bc520..fb1f848b677c 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -90,7 +90,8 @@ function ReportActionsView({ const route = useRoute>(); const [session] = useOnyx(ONYXKEYS.SESSION); const [transactionThreadReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID ?? -1}`, { - selector: (reportActions: OnyxEntry) => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, report.reportID, true), + selector: (reportActions: OnyxEntry) => + ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, report.reportID, ReportUtils.canUserPerformWriteAction(report), true), }); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID ?? -1}`); const prevTransactionThreadReport = usePrevious(transactionThreadReport); diff --git a/src/pages/home/report/ThreadDivider.tsx b/src/pages/home/report/ThreadDivider.tsx index 6fec617e4c37..290d173d9a5c 100644 --- a/src/pages/home/report/ThreadDivider.tsx +++ b/src/pages/home/report/ThreadDivider.tsx @@ -11,6 +11,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import type {Ancestor} from '@libs/ReportUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -47,7 +48,12 @@ function ThreadDivider({ancestor, isLinkDisabled = false}: ThreadDividerProps) { ) : ( { - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(ancestor.reportAction, ancestor.reportAction.reportActionID ?? '-1', ancestor.report.reportID); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( + ancestor.reportAction, + ancestor.reportAction.reportActionID ?? '-1', + ancestor.report.reportID, + ReportUtils.canUserPerformWriteAction(ancestor.report), + ); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); if (isVisibleAction && !isOffline) { diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index 5e258436edc7..d6c573e846e8 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -89,11 +89,11 @@ describe('ReportActionsUtils', () => { } as unknown as ReportActions; await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge)); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, true, actionsToMerge)); }); test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId); + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId, true); await waitForBatchedUpdates(); await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray)); @@ -127,12 +127,12 @@ describe('ReportActionsUtils', () => { } as unknown as ReportActions; await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge)); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, true, actionsToMerge)); }); test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId)); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId, true)); }); test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index 5f3f14971d8e..ef74f34f6413 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -306,7 +306,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, "1"); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1', true); expect(result).toStrictEqual(expectedOutput); }); @@ -401,7 +401,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, -1), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1'); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1', true); expect(result).toStrictEqual(expectedOutput); }); @@ -445,7 +445,7 @@ describe('ReportActionsUtils', () => { message: [{html: '', type: 'Action type', text: 'Action text'}], }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1'); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1', true); input.pop(); expect(result).toStrictEqual(input); }); From 7b32415551e04a96e2b0d7b75378c5350bc4cfbc Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 31 Oct 2024 05:00:04 +0530 Subject: [PATCH 07/24] fix tests. Signed-off-by: krishna2323 --- .../Attachments/AttachmentCarousel/extractAttachments.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts index 5ebaf8af673e..620b7ce4c01d 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts +++ b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts @@ -99,7 +99,7 @@ function extractAttachments( const actions = [...(parentReportAction ? [parentReportAction] : []), ...ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}))]; actions.forEach((action, key) => { - if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, reportID, canUserPerformWriteAction) || ReportActionsUtils.isMoneyRequestAction(action),) { + if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, reportID, canUserPerformWriteAction) || ReportActionsUtils.isMoneyRequestAction(action)) { return; } From 16ca72b963baaf7deda1e8d37a23294b13eb8a16 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 31 Oct 2024 05:10:41 +0530 Subject: [PATCH 08/24] fix: Unchanged files with check annotations. Signed-off-by: krishna2323 --- src/libs/ReportUtils.ts | 4 ++-- src/libs/SidebarUtils.ts | 2 +- src/libs/actions/Report.ts | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 7ad1b72dfebd..7b2d592057d1 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -8233,7 +8233,7 @@ function findPolicyExpenseChatByPolicyID(policyID: string): OnyxEntry { * @param actionsToMerge * @returns containing the calculated message preview data of the report */ -function getReportLastMessage(reportID: string, actionsToMerge?: ReportActions) { +function getReportLastMessage(reportID: string, canUserPerformWriteAction?: boolean, actionsToMerge?: ReportActions) { let result: Partial = { lastMessageTranslationKey: '', lastMessageText: '', @@ -8243,7 +8243,7 @@ function getReportLastMessage(reportID: string, actionsToMerge?: ReportActions) const {lastMessageText = '', lastMessageTranslationKey = ''} = getLastVisibleMessage(reportID, actionsToMerge); if (lastMessageText || lastMessageTranslationKey) { - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID, actionsToMerge); + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID, canUserPerformWriteAction, actionsToMerge); const lastVisibleActionCreated = lastVisibleAction?.created; const lastActorAccountID = lastVisibleAction?.actorAccountID; result = { diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 862750920bbc..d88698e7647a 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -485,7 +485,7 @@ function getOptionData({ result.alternateText = lastMessageTextFromReport.length > 0 ? ReportUtils.formatReportLastMessageText(Parser.htmlToText(lastMessageText)) - : ReportActionsUtils.getLastVisibleMessage(report.reportID, {}, lastAction)?.lastMessageText; + : ReportActionsUtils.getLastVisibleMessage(report.reportID, result.isAllowedToComment, {}, lastAction)?.lastMessageText; if (!result.alternateText) { result.alternateText = ReportUtils.formatReportLastMessageText(getWelcomeMessage(report, policy).messageText ?? Localize.translateLocal('report.noActivityYet')); } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 03ad1de54b5d..20bbaf404190 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3913,9 +3913,10 @@ function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEnt }, }; - const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); + const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, canUserPerformWriteAction, optimisticReportActions as ReportActions); + const reportUpdateDataWithCurrentLastMessage = { lastMessageTranslationKey: report?.lastMessageTranslationKey, lastMessageText: report?.lastMessageText, @@ -3988,9 +3989,10 @@ function resolveActionableReportMentionWhisper( }, }; - const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); - const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); + const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, canUserPerformWriteAction, optimisticReportActions as ReportActions); + const reportUpdateDataWithCurrentLastMessage = { lastMessageTranslationKey: report?.lastMessageTranslationKey, lastMessageText: report?.lastMessageText, From 95bec1fc21766cb15edd356762c84936782092c4 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 31 Oct 2024 05:16:54 +0530 Subject: [PATCH 09/24] minor fixes. Signed-off-by: krishna2323 --- src/libs/ReportUtils.ts | 10 ++++++---- src/libs/actions/Report.ts | 6 ++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 7b2d592057d1..a466561e2d83 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2609,7 +2609,7 @@ function buildOptimisticCancelPaymentReportAction(expenseReportID: string, amoun */ function getLastVisibleMessage(reportID: string | undefined, actionsToMerge: ReportActions = {}): LastVisibleMessage { const report = getReportOrDraftReport(reportID); - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID ?? '-1', actionsToMerge); + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID ?? '-1', canUserPerformWriteAction(report), actionsToMerge); // For Chat Report with deleted parent actions, let us fetch the correct message if (ReportActionsUtils.isDeletedParentAction(lastVisibleAction) && !isEmptyObject(report) && isChatReport(report)) { @@ -2620,7 +2620,7 @@ function getLastVisibleMessage(reportID: string | undefined, actionsToMerge: Rep } // Fetch the last visible message for report represented by reportID and based on actions to merge. - return ReportActionsUtils.getLastVisibleMessage(reportID ?? '-1', actionsToMerge); + return ReportActionsUtils.getLastVisibleMessage(reportID ?? '-1', canUserPerformWriteAction(report), actionsToMerge); } /** @@ -8231,9 +8231,10 @@ function findPolicyExpenseChatByPolicyID(policyID: string): OnyxEntry { * A function to get the report last message. This is usually used to restore the report message preview in LHN after report actions change. * @param reportID * @param actionsToMerge + * @param canUserPerformWriteActionInReport * @returns containing the calculated message preview data of the report */ -function getReportLastMessage(reportID: string, canUserPerformWriteAction?: boolean, actionsToMerge?: ReportActions) { +function getReportLastMessage(reportID: string, actionsToMerge?: ReportActions) { let result: Partial = { lastMessageTranslationKey: '', lastMessageText: '', @@ -8243,7 +8244,8 @@ function getReportLastMessage(reportID: string, canUserPerformWriteAction?: bool const {lastMessageText = '', lastMessageTranslationKey = ''} = getLastVisibleMessage(reportID, actionsToMerge); if (lastMessageText || lastMessageTranslationKey) { - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID, canUserPerformWriteAction, actionsToMerge); + const report = getReportOrDraftReport(reportID); + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID, canUserPerformWriteAction(report), actionsToMerge); const lastVisibleActionCreated = lastVisibleAction?.created; const lastActorAccountID = lastVisibleAction?.actorAccountID; result = { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 20bbaf404190..58b4be53e2f0 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3914,8 +3914,7 @@ function resolveActionableMentionWhisper(reportId: string, reportAction: OnyxEnt }; const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; - const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); - const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, canUserPerformWriteAction, optimisticReportActions as ReportActions); + const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { lastMessageTranslationKey: report?.lastMessageTranslationKey, @@ -3990,8 +3989,7 @@ function resolveActionableReportMentionWhisper( }; const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportId}`]; - const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); - const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, canUserPerformWriteAction, optimisticReportActions as ReportActions); + const reportUpdateDataWithPreviousLastMessage = ReportUtils.getReportLastMessage(reportId, optimisticReportActions as ReportActions); const reportUpdateDataWithCurrentLastMessage = { lastMessageTranslationKey: report?.lastMessageTranslationKey, From 0ac89334bd30ba159603543da120676bbf158781 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 31 Oct 2024 05:27:05 +0530 Subject: [PATCH 10/24] fix: TypeScript Checks. Signed-off-by: krishna2323 --- src/libs/actions/IOU.ts | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 7ce9b9dfb272..fc16084f91fb 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1734,8 +1734,12 @@ function getDeleteTrackExpenseInformation( }, ...(actionableWhisperReportActionID && {[actionableWhisperReportActionID]: {originalMessage: {resolution}}}), } as OnyxTypes.ReportActions; - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(chatReport?.reportID ?? '-1', updatedReportAction); - const {lastMessageText = '', lastMessageHtml = ''} = ReportActionsUtils.getLastVisibleMessage(chatReport?.reportID ?? '-1', updatedReportAction); + let canUserPerformWriteAction = true; + if (chatReport) { + canUserPerformWriteAction = !!ReportUtils.canUserPerformWriteAction(chatReport); + } + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(chatReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction); + const {lastMessageText = '', lastMessageHtml = ''} = ReportActionsUtils.getLastVisibleMessage(chatReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction); // STEP 4: Build Onyx data const optimisticData: OnyxUpdate[] = []; @@ -5705,8 +5709,12 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT }, } as Record>; - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1', updatedReportAction); - const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1', updatedReportAction).lastMessageText; + let canUserPerformWriteAction = true; + if (chatReport) { + canUserPerformWriteAction = !!ReportUtils.canUserPerformWriteAction(chatReport); + } + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction); + const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction).lastMessageText; const shouldDeleteIOUReport = iouReportLastMessageText.length === 0 && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) && (!transactionThreadID || shouldDeleteTransactionThread); @@ -5899,6 +5907,10 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo } if (shouldDeleteIOUReport) { + let canUserPerformWriteAction = true; + if (chatReport) { + canUserPerformWriteAction = !!ReportUtils.canUserPerformWriteAction(chatReport); + } onyxUpdates.push( { onyxMethod: Onyx.METHOD.MERGE, @@ -5906,8 +5918,12 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo value: { hasOutstandingChildRequest: false, iouReportID: null, - lastMessageText: ReportActionsUtils.getLastVisibleMessage(iouReport?.chatReportID ?? '-1', {[reportPreviewAction?.reportActionID ?? '-1']: null})?.lastMessageText, - lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(iouReport?.chatReportID ?? '-1', {[reportPreviewAction?.reportActionID ?? '-1']: null})?.created, + lastMessageText: ReportActionsUtils.getLastVisibleMessage(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, { + [reportPreviewAction?.reportActionID ?? '-1']: null, + })?.lastMessageText, + lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, { + [reportPreviewAction?.reportActionID ?? '-1']: null, + })?.created, }, }, { @@ -6015,14 +6031,21 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor } if (shouldDeleteIOUReport) { + let canUserPerformWriteAction = true; + if (chatReport) { + canUserPerformWriteAction = !!ReportUtils.canUserPerformWriteAction(chatReport); + } optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, value: { hasOutstandingChildRequest: false, iouReportID: null, - lastMessageText: ReportActionsUtils.getLastVisibleMessage(iouReport?.chatReportID ?? '-1', {[reportPreviewAction?.reportActionID ?? '-1']: null})?.lastMessageText, - lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(iouReport?.chatReportID ?? '-1', {[reportPreviewAction?.reportActionID ?? '-1']: null})?.created, + lastMessageText: ReportActionsUtils.getLastVisibleMessage(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, {[reportPreviewAction?.reportActionID ?? '-1']: null}) + ?.lastMessageText, + lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, { + [reportPreviewAction?.reportActionID ?? '-1']: null, + })?.created, }, }); optimisticData.push({ From 5fb19370ad8426a34892bf2d8a0d60b8d3b032fa Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 31 Oct 2024 05:36:29 +0530 Subject: [PATCH 11/24] fix: TypeScript Checks. Signed-off-by: krishna2323 --- src/libs/ReportActionsUtils.ts | 2 +- src/libs/actions/Task.ts | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 7778cb29d552..bd04628ea264 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1100,7 +1100,7 @@ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEn * When we delete certain reports, we want to check whether there are any visible actions left to display. * If there are no visible actions left (including system messages), we can hide the report from view entirely */ -function doesReportHaveVisibleActions(reportID: string, canUserPerformWriteAction: boolean, actionsToMerge: ReportActions = {}): boolean { +function doesReportHaveVisibleActions(reportID: string, canUserPerformWriteAction?: boolean, actionsToMerge: ReportActions = {}): boolean { const reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge, true)); const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action, reportID, canUserPerformWriteAction)); diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index c5a2442048fc..130023be885b 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -967,9 +967,10 @@ function deleteTask(report: OnyxEntry) { const optimisticReportActionID = optimisticCancelReportAction.reportActionID; const parentReportAction = getParentReportAction(report); const parentReport = getParentReport(report); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); // If the task report is the last visible action in the parent report, we should navigate back to the parent report - const shouldDeleteTaskReport = !ReportActionsUtils.doesReportHaveVisibleActions(report.reportID ?? '-1'); + const shouldDeleteTaskReport = !ReportActionsUtils.doesReportHaveVisibleActions(report.reportID ?? '-1', canUserPerformWriteAction); const optimisticReportAction: Partial = { pendingAction: shouldDeleteTaskReport ? CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, previousMessage: parentReportAction?.message, @@ -1006,8 +1007,14 @@ function deleteTask(report: OnyxEntry) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport?.reportID}`, value: { - lastMessageText: ReportActionsUtils.getLastVisibleMessage(parentReport?.reportID ?? '-1', optimisticReportActions as OnyxTypes.ReportActions).lastMessageText ?? '', - lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction(parentReport?.reportID ?? '-1', optimisticReportActions as OnyxTypes.ReportActions)?.created, + lastMessageText: + ReportActionsUtils.getLastVisibleMessage(parentReport?.reportID ?? '-1', canUserPerformWriteAction, optimisticReportActions as OnyxTypes.ReportActions).lastMessageText ?? + '', + lastVisibleActionCreated: ReportActionsUtils.getLastVisibleAction( + parentReport?.reportID ?? '-1', + canUserPerformWriteAction, + optimisticReportActions as OnyxTypes.ReportActions, + )?.created, hasOutstandingChildTask, }, }, From edf7c52fb9464d18297e71e69cb55f4dadc01f1f Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 6 Nov 2024 17:42:07 +0530 Subject: [PATCH 12/24] remove reportID parameter from shouldReportActionBeVisible. Signed-off-by: krishna2323 --- .../AttachmentCarousel/extractAttachments.ts | 2 +- .../LHNOptionsList/LHNOptionsList.tsx | 3 ++- src/components/ParentNavigationSubtitle.tsx | 6 +++-- src/hooks/usePaginatedReportActions.ts | 2 +- src/libs/OptionsListUtils.ts | 4 +-- src/libs/Permissions.ts | 1 + src/libs/ReportActionsUtils.ts | 27 ++++++++++--------- src/libs/SidebarUtils.ts | 6 +++-- src/libs/SubscriptionUtils.ts | 1 + src/libs/actions/Report.ts | 2 +- src/pages/Debug/Report/DebugReportActions.tsx | 4 +-- src/pages/home/ReportScreen.tsx | 4 +-- .../report/ReportActionItemParentAction.tsx | 1 - src/pages/home/report/ReportActionsList.tsx | 2 +- src/pages/home/report/ReportActionsView.tsx | 2 +- src/pages/home/report/ThreadDivider.tsx | 1 - .../perf-test/ReportActionsUtils.perf-test.ts | 4 +-- tests/unit/ReportActionsUtilsTest.ts | 6 ++--- 18 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts index 620b7ce4c01d..51d5cfb1d981 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachments.ts +++ b/src/components/Attachments/AttachmentCarousel/extractAttachments.ts @@ -99,7 +99,7 @@ function extractAttachments( const actions = [...(parentReportAction ? [parentReportAction] : []), ...ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}))]; actions.forEach((action, key) => { - if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, reportID, canUserPerformWriteAction) || ReportActionsUtils.isMoneyRequestAction(action)) { + if (!ReportActionsUtils.shouldReportActionBeVisible(action, key, canUserPerformWriteAction) || ReportActionsUtils.isMoneyRequestAction(action)) { return; } diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index c03d7822f9e3..9594e6ede24a 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -141,7 +141,8 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const hasDraftComment = DraftCommentUtils.isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); - const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions, reportID, ReportUtils.canUserPerformWriteAction(itemFullReport)); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(itemFullReport); + const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions, canUserPerformWriteAction); const lastReportAction = sortedReportActions.at(0); // Get the transaction for the last report action diff --git a/src/components/ParentNavigationSubtitle.tsx b/src/components/ParentNavigationSubtitle.tsx index 248eaec9c9b1..2b808432c6ab 100644 --- a/src/components/ParentNavigationSubtitle.tsx +++ b/src/components/ParentNavigationSubtitle.tsx @@ -1,5 +1,6 @@ import React from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -8,6 +9,7 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import type {ParentNavigationSummaryParams} from '@src/languages/params'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Text from './Text'; @@ -30,7 +32,7 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct const {workspaceName, reportName} = parentNavigationSubtitleData; const {isOffline} = useNetwork(); const {translate} = useLocalize(); - const report = ReportUtils.getReport(parentReportID); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`); const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); // We should not display the parent navigation subtitle if the user does not have access to the parent chat (the reportName is empty in this case) @@ -42,7 +44,7 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct { const parentAction = ReportActionsUtils.getReportAction(parentReportID, parentReportActionID ?? '-1'); - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1', parentReportID, canUserPerformWriteAction); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1', canUserPerformWriteAction); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReportID)); if (isVisibleAction && !isOffline) { diff --git a/src/hooks/usePaginatedReportActions.ts b/src/hooks/usePaginatedReportActions.ts index 6b476db46d7d..8bcc7c9ce539 100644 --- a/src/hooks/usePaginatedReportActions.ts +++ b/src/hooks/usePaginatedReportActions.ts @@ -17,7 +17,7 @@ function usePaginatedReportActions(reportID?: string, reportActionID?: string) { const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportIDWithDefault}`, { canEvict: false, - selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID ?? '-1', canUserPerformWriteAction, true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, canUserPerformWriteAction, true), }); const [reportActionPages] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES}${reportIDWithDefault}`); diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 0a92e482df7a..069db8e3419f 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -335,7 +335,7 @@ Onyx.connect({ // does not match a closed or created state. const reportActionsForDisplay = sortedReportActions.filter( (reportAction, actionKey) => - ReportActionUtils.shouldReportActionBeVisible(reportAction, actionKey, reportID, canUserPerformWriteAction) && + ReportActionUtils.shouldReportActionBeVisible(reportAction, actionKey, canUserPerformWriteAction) && !ReportActionUtils.isWhisperAction(reportAction) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && @@ -593,7 +593,7 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails const iouReport = ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); const lastIOUMoneyReportAction = allSortedReportActions[iouReport?.reportID ?? '-1']?.find( (reportAction, key): reportAction is ReportAction => - ReportActionUtils.shouldReportActionBeVisible(reportAction, key, reportID, ReportUtils.canUserPerformWriteAction(report)) && + ReportActionUtils.shouldReportActionBeVisible(reportAction, key, ReportUtils.canUserPerformWriteAction(report)) && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && ReportActionUtils.isMoneyRequestAction(reportAction), ); diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 0853bd9c18ce..7083f04fab93 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -4,6 +4,7 @@ import type {IOUType} from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; function canUseAllBetas(betas: OnyxEntry): boolean { + return true; return !!betas?.includes(CONST.BETAS.ALL); } diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index fd45d9843178..7118bf8445e9 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -635,8 +635,11 @@ const supportedActionTypes: ReportActionName[] = [...Object.values(otherActionTy * Checks if a reportAction is fit for display, meaning that it's not deprecated, is of a valid * and supported type, it's not deleted and also not closed. */ -function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, reportID: string, canUserPerformWriteAction?: boolean): boolean { - if ((isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPending(reportID ?? '-1') || isActionableMentionWhisper(reportAction)) && !canUserPerformWriteAction) { +function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, canUserPerformWriteAction?: boolean): boolean { + if ( + (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPendingReportAction(reportAction) || isActionableMentionWhisper(reportAction)) && + !canUserPerformWriteAction + ) { return false; } @@ -715,7 +718,7 @@ function isResolvedActionTrackExpense(reportAction: OnyxEntry): bo * Checks if a reportAction is fit for display as report last action, meaning that * it satisfies shouldReportActionBeVisible, it's not whisper action and not deleted. */ -function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry, reportID: string, canUserPerformWriteAction?: boolean): boolean { +function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry, canUserPerformWriteAction?: boolean): boolean { if (!reportAction) { return false; } @@ -727,7 +730,7 @@ function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry< // If a whisper action is the REPORT_PREVIEW action, we are displaying it. // If the action's message text is empty and it is not a deleted parent with visible child actions, hide it. Else, consider the action to be displayable. return ( - shouldReportActionBeVisible(reportAction, reportAction.reportActionID, reportID, canUserPerformWriteAction) && + shouldReportActionBeVisible(reportAction, reportAction.reportActionID, canUserPerformWriteAction) && !(isWhisperAction(reportAction) && !isReportPreviewAction(reportAction) && !isMoneyRequestAction(reportAction)) && !(isDeletedAction(reportAction) && !isDeletedParentAction(reportAction)) && !isResolvedActionTrackExpense(reportAction) @@ -769,7 +772,7 @@ function getLastVisibleAction(reportID: string, canUserPerformWriteAction?: bool } else { reportActions = Object.values(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}); } - const visibleReportActions = reportActions.filter((action): action is ReportAction => shouldReportActionBeVisibleAsLastAction(action, reportID, canUserPerformWriteAction)); + const visibleReportActions = reportActions.filter((action): action is ReportAction => shouldReportActionBeVisibleAsLastAction(action, canUserPerformWriteAction)); const sortedReportActions = getSortedReportActions(visibleReportActions, true); if (sortedReportActions.length === 0) { return undefined; @@ -838,7 +841,6 @@ function filterOutDeprecatedReportActions(reportActions: OnyxEntry | ReportAction[], - reportID: string, canUserPerformWriteAction?: boolean, shouldIncludeInvisibleActions = false, ): ReportAction[] { @@ -851,7 +853,7 @@ function getSortedReportActionsForDisplay( filteredReportActions = Object.values(reportActions).filter(Boolean); } else { filteredReportActions = Object.entries(reportActions) - .filter(([key, reportAction]) => shouldReportActionBeVisible(reportAction, key, reportID, canUserPerformWriteAction)) + .filter(([key, reportAction]) => shouldReportActionBeVisible(reportAction, key, canUserPerformWriteAction)) .map(([, reportAction]) => reportAction); } @@ -1102,7 +1104,7 @@ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEn */ function doesReportHaveVisibleActions(reportID: string, canUserPerformWriteAction?: boolean, actionsToMerge: ReportActions = {}): boolean { const reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge, true)); - const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action, reportID, canUserPerformWriteAction)); + const visibleReportActions = Object.values(reportActions ?? {}).filter((action) => shouldReportActionBeVisibleAsLastAction(action, canUserPerformWriteAction)); // Exclude the task system message and the created message const visibleReportActionsWithoutTaskSystemMessage = visibleReportActions.filter((action) => !isTaskAction(action) && !isCreatedAction(action)); @@ -1495,11 +1497,12 @@ function isActionableJoinRequest(reportAction: OnyxEntry): reportA return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST); } -function getActionableJoinRequestPendingReportAction(reportID: string): OnyxEntry { - const findPendingRequest = Object.values(getAllReportActions(reportID)).find( - (reportActionItem) => isActionableJoinRequest(reportActionItem) && getOriginalMessage(reportActionItem)?.choice === ('' as JoinWorkspaceResolution), - ); +function isActionableJoinRequestPendingReportAction(reportAction: OnyxEntry): boolean { + return isActionableJoinRequest(reportAction) && getOriginalMessage(reportAction)?.choice === ('' as JoinWorkspaceResolution); +} +function getActionableJoinRequestPendingReportAction(reportID: string): OnyxEntry { + const findPendingRequest = Object.values(getAllReportActions(reportID)).find((reportActionItem) => isActionableJoinRequestPendingReportAction(reportActionItem)); return findPendingRequest; } diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 49ed7392cec9..cbe7027e5939 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -41,13 +41,15 @@ Onyx.connect({ return; } const reportID = CollectionUtils.extractCollectionItemID(key); - + const report = ReportUtils.getReport(reportID); + const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); const actionsArray: ReportAction[] = ReportActionsUtils.getSortedReportActions(Object.values(actions)); // The report is only visible if it is the last action not deleted that // does not match a closed or created state. const reportActionsForDisplay = actionsArray.filter( - (reportAction) => ReportActionsUtils.shouldReportActionBeVisibleAsLastAction(reportAction, reportID) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED, + (reportAction) => + ReportActionsUtils.shouldReportActionBeVisibleAsLastAction(reportAction, canUserPerformWriteAction) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED, ); const reportAction = reportActionsForDisplay.at(-1); diff --git a/src/libs/SubscriptionUtils.ts b/src/libs/SubscriptionUtils.ts index f2ceef9069fa..6cbf6d5b0d9e 100644 --- a/src/libs/SubscriptionUtils.ts +++ b/src/libs/SubscriptionUtils.ts @@ -435,6 +435,7 @@ function doesUserHavePaymentCardAdded(): boolean { * Whether the user's billable actions should be restricted. */ function shouldRestrictUserBillableActions(policyID: string): boolean { + return false; const currentDate = new Date(); const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 63e578a6c513..1ec8375415d4 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -298,7 +298,7 @@ registerPaginationConfig({ sortItems: (reportActions, reportID) => { const report = ReportUtils.getReport(reportID); const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); - return ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportID, canUserPerformWriteAction, true); + return ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, canUserPerformWriteAction, true); }, getItemID: (reportAction) => reportAction.reportActionID, }); diff --git a/src/pages/Debug/Report/DebugReportActions.tsx b/src/pages/Debug/Report/DebugReportActions.tsx index f9f0a6e9a89c..9368ca5116bd 100644 --- a/src/pages/Debug/Report/DebugReportActions.tsx +++ b/src/pages/Debug/Report/DebugReportActions.tsx @@ -22,11 +22,11 @@ type DebugReportActionsProps = { function DebugReportActions({reportID}: DebugReportActionsProps) { const {translate, datetimeToCalendarTime} = useLocalize(); const styles = useThemeStyles(); - const report = ReportUtils.getReport(reportID); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, { canEvict: false, - selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, reportID, canUserPerformWriteAction, true), + selector: (allReportActions) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, canUserPerformWriteAction, true), }); const renderItem = ({item}: ListRenderItemInfo) => ( = CONST.REPORT.MIN_INITIAL_REPORT_ACTION_COUNT || isPendingActionExist || (doesCreatedActionExists() && reportActions.length > 0); const isLinkedActionDeleted = useMemo( - () => - !!linkedAction && - !ReportActionsUtils.shouldReportActionBeVisible(linkedAction, linkedAction.reportActionID, report?.reportID ?? '-1', ReportUtils.canUserPerformWriteAction(report)), + () => !!linkedAction && !ReportActionsUtils.shouldReportActionBeVisible(linkedAction, linkedAction.reportActionID, ReportUtils.canUserPerformWriteAction(report)), [linkedAction, report], ); const prevIsLinkedActionDeleted = usePrevious(linkedAction ? isLinkedActionDeleted : undefined); diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 67e16e5b068c..d66b91436b79 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -137,7 +137,6 @@ function ReportActionItemParentAction({ const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( ancestor.reportAction, ancestor.reportAction.reportActionID ?? '-1', - ancestor.report.reportID, canUserPerformWriteAction, ); // Pop the thread report screen before navigating to the chat report. diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index b8c4a92a185e..1090e09d0a6a 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -188,7 +188,7 @@ function ReportActionsList({ ReportActionsUtils.isDeletedParentAction(reportAction) || reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || reportAction.errors) && - ReportActionsUtils.shouldReportActionBeVisible(reportAction, reportAction.reportActionID, report.reportID, ReportUtils.canUserPerformWriteAction(report)), + ReportActionsUtils.shouldReportActionBeVisible(reportAction, reportAction.reportActionID, ReportUtils.canUserPerformWriteAction(report)), ), [sortedReportActions, isOffline, report], ); diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index fb1f848b677c..5319b7dc72bd 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -91,7 +91,7 @@ function ReportActionsView({ const [session] = useOnyx(ONYXKEYS.SESSION); const [transactionThreadReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID ?? -1}`, { selector: (reportActions: OnyxEntry) => - ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, report.reportID, ReportUtils.canUserPerformWriteAction(report), true), + ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, ReportUtils.canUserPerformWriteAction(report), true), }); const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID ?? -1}`); const prevTransactionThreadReport = usePrevious(transactionThreadReport); diff --git a/src/pages/home/report/ThreadDivider.tsx b/src/pages/home/report/ThreadDivider.tsx index 290d173d9a5c..0cf34d6f40e6 100644 --- a/src/pages/home/report/ThreadDivider.tsx +++ b/src/pages/home/report/ThreadDivider.tsx @@ -51,7 +51,6 @@ function ThreadDivider({ancestor, isLinkDisabled = false}: ThreadDividerProps) { const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( ancestor.reportAction, ancestor.reportAction.reportActionID ?? '-1', - ancestor.report.reportID, ReportUtils.canUserPerformWriteAction(ancestor.report), ); // Pop the thread report screen before navigating to the chat report. diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index d6c573e846e8..b0ebd7c0c10a 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -93,7 +93,7 @@ describe('ReportActionsUtils', () => { }); test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId, true); + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true); await waitForBatchedUpdates(); await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray)); @@ -132,7 +132,7 @@ describe('ReportActionsUtils', () => { test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, reportId, true)); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true)); }); test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index ef74f34f6413..b0d65517d12f 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -306,7 +306,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1', true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); expect(result).toStrictEqual(expectedOutput); }); @@ -401,7 +401,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, -1), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1', true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); expect(result).toStrictEqual(expectedOutput); }); @@ -445,7 +445,7 @@ describe('ReportActionsUtils', () => { message: [{html: '', type: 'Action type', text: 'Action text'}], }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, '1', true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); input.pop(); expect(result).toStrictEqual(input); }); From ea27cc36a326419c2246eb869392cb2567ad8a07 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 7 Nov 2024 13:15:12 +0530 Subject: [PATCH 13/24] remove redundant code. Signed-off-by: krishna2323 --- src/libs/Permissions.ts | 1 - src/libs/SubscriptionUtils.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 7083f04fab93..0853bd9c18ce 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -4,7 +4,6 @@ import type {IOUType} from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; function canUseAllBetas(betas: OnyxEntry): boolean { - return true; return !!betas?.includes(CONST.BETAS.ALL); } diff --git a/src/libs/SubscriptionUtils.ts b/src/libs/SubscriptionUtils.ts index 6cbf6d5b0d9e..f2ceef9069fa 100644 --- a/src/libs/SubscriptionUtils.ts +++ b/src/libs/SubscriptionUtils.ts @@ -435,7 +435,6 @@ function doesUserHavePaymentCardAdded(): boolean { * Whether the user's billable actions should be restricted. */ function shouldRestrictUserBillableActions(policyID: string): boolean { - return false; const currentDate = new Date(); const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; From 40b7435863a3eb15ba2f96128930ed0415ea6f9c Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 7 Nov 2024 13:30:54 +0530 Subject: [PATCH 14/24] minor update. Signed-off-by: krishna2323 --- src/libs/ReportActionsUtils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 7118bf8445e9..ccee59f64db7 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -636,6 +636,10 @@ const supportedActionTypes: ReportActionName[] = [...Object.values(otherActionTy * and supported type, it's not deleted and also not closed. */ function shouldReportActionBeVisible(reportAction: OnyxEntry, key: string | number, canUserPerformWriteAction?: boolean): boolean { + if (!reportAction) { + return false; + } + if ( (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPendingReportAction(reportAction) || isActionableMentionWhisper(reportAction)) && !canUserPerformWriteAction @@ -643,10 +647,6 @@ function shouldReportActionBeVisible(reportAction: OnyxEntry, key: return false; } - if (!reportAction) { - return false; - } - if (isReportActionDeprecated(reportAction, key)) { return false; } From c870f7534bac9855eac39e7eaf2642c0306cb06f Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Mon, 11 Nov 2024 10:56:28 +0530 Subject: [PATCH 15/24] minor update. Signed-off-by: krishna2323 --- src/libs/ReportActionsUtils.ts | 14 +++++++------- src/libs/ReportUtils.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index ccee59f64db7..8d828f457ece 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -640,13 +640,6 @@ function shouldReportActionBeVisible(reportAction: OnyxEntry, key: return false; } - if ( - (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPendingReportAction(reportAction) || isActionableMentionWhisper(reportAction)) && - !canUserPerformWriteAction - ) { - return false; - } - if (isReportActionDeprecated(reportAction, key)) { return false; } @@ -675,6 +668,13 @@ function shouldReportActionBeVisible(reportAction: OnyxEntry, key: return false; } + if ( + (isActionableReportMentionWhisper(reportAction) || isActionableJoinRequestPendingReportAction(reportAction) || isActionableMentionWhisper(reportAction)) && + !canUserPerformWriteAction + ) { + return false; + } + if (isTripPreview(reportAction)) { return true; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 52a1937b580e..316131993f1a 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -8321,7 +8321,7 @@ function getReportLastMessage(reportID: string, actionsToMerge?: ReportActions) const {lastMessageText = '', lastMessageTranslationKey = ''} = getLastVisibleMessage(reportID, actionsToMerge); if (lastMessageText || lastMessageTranslationKey) { - const report = getReportOrDraftReport(reportID); + const report = getReport(reportID); const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(reportID, canUserPerformWriteAction(report), actionsToMerge); const lastVisibleActionCreated = lastVisibleAction?.created; const lastActorAccountID = lastVisibleAction?.actorAccountID; From dfdfb191a56bced20df82737a1525bd681458f0b Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 13 Nov 2024 22:21:55 +0530 Subject: [PATCH 16/24] minor fix. Signed-off-by: krishna2323 --- src/hooks/usePaginatedReportActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/usePaginatedReportActions.ts b/src/hooks/usePaginatedReportActions.ts index 8bcc7c9ce539..791b6c47d1a0 100644 --- a/src/hooks/usePaginatedReportActions.ts +++ b/src/hooks/usePaginatedReportActions.ts @@ -12,7 +12,7 @@ function usePaginatedReportActions(reportID?: string, reportActionID?: string) { // Use `||` instead of `??` to handle empty string. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const reportIDWithDefault = reportID || '-1'; - const report = ReportUtils.getReport(reportIDWithDefault); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); const [sortedAllReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportIDWithDefault}`, { From 0e1da049d3dc09298742804f7fc1b398ca199d28 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 17 Nov 2024 00:02:10 +0530 Subject: [PATCH 17/24] add tests for ReportActionsUtils.getSortedReportActionsForDisplay. Signed-off-by: krishna2323 --- .../perf-test/ReportActionsUtils.perf-test.ts | 4 +- tests/unit/ReportActionsUtilsTest.ts | 111 +++++++++++++++++- 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index b0ebd7c0c10a..4190d7c1c089 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -93,7 +93,7 @@ describe('ReportActionsUtils', () => { }); test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true); + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true, true); await waitForBatchedUpdates(); await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray)); @@ -132,7 +132,7 @@ describe('ReportActionsUtils', () => { test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true)); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true, true)); }); test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index b0d65517d12f..b129900a14e4 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -306,7 +306,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, true); expect(result).toStrictEqual(expectedOutput); }); @@ -401,7 +401,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, -1), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, true); expect(result).toStrictEqual(expectedOutput); }); @@ -445,10 +445,115 @@ describe('ReportActionsUtils', () => { message: [{html: '', type: 'Action type', text: 'Action text'}], }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, true); input.pop(); expect(result).toStrictEqual(input); }); + + it('should filter whisper action in a archieved report', () => { + const input: ReportAction[] = [ + { + created: '2022-11-13 22:27:01.825', + reportActionID: '8401445780099176', + actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, + originalMessage: { + html: 'Hello world', + whisperedTo: [], + }, + message: [ + { + html: 'Hello world', + type: 'Action type', + text: 'Action text', + }, + ], + }, + { + created: '2022-11-12 22:27:01.825', + reportActionID: '6401435781022176', + actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER, + originalMessage: { + html: 'Hello world', + whisperedTo: [], + }, + message: [ + { + html: 'Hello world', + type: 'Action type', + text: 'Action text', + }, + ], + }, + { + created: '2022-11-11 22:27:01.825', + reportActionID: '2962390724708756', + actionName: CONST.REPORT.ACTIONS.TYPE.IOU, + originalMessage: { + amount: 0, + currency: 'USD', + type: 'split', // change to const + }, + message: [ + { + html: 'Hello world', + type: 'Action type', + text: 'Action text', + }, + ], + }, + { + created: '2022-11-10 22:27:01.825', + reportActionID: '1609646094152486', + actionName: CONST.REPORT.ACTIONS.TYPE.RENAMED, + originalMessage: { + html: 'Hello world', + lastModified: '2022-11-10 22:27:01.825', + oldName: 'old name', + newName: 'new name', + }, + message: [ + { + html: 'Hello world', + type: 'Action type', + text: 'Action text', + }, + ], + }, + { + created: '2022-11-09 22:27:01.825', + reportActionID: '8049485084562457', + actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER, + originalMessage: {}, + message: [{html: 'updated the Approval Mode from "Submit and Approve" to "Submit and Close"', type: 'Action type', text: 'Action text'}], + }, + { + created: '2022-11-08 22:27:06.825', + reportActionID: '1661970171066216', + actionName: CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_QUEUED, + originalMessage: { + paymentType: 'ACH', + }, + message: [{html: 'Waiting for the bank account', type: 'Action type', text: 'Action text'}], + }, + { + created: '2022-11-06 22:27:08.825', + reportActionID: '1661970171066220', + actionName: CONST.REPORT.ACTIONS.TYPE.TASK_EDITED, + originalMessage: { + html: 'Hello world', + whisperedTo: [], + }, + message: [{html: 'I have changed the task', type: 'Action type', text: 'Action text'}], + }, + ]; + + // Expected output should have the `CREATED` action at last + // eslint-disable-next-line rulesdir/prefer-at + const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, 4), ...input.slice(5)]; + + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, false); + expect(result).toStrictEqual(expectedOutput); + }); }); describe('getLastVisibleAction', () => { From 676c82247bcee7c46f1ec201e692d942ffecdc36 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 17 Nov 2024 14:55:59 +0530 Subject: [PATCH 18/24] fix unit tests. Signed-off-by: krishna2323 --- tests/unit/ReportActionsUtilsTest.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index b129900a14e4..9f4610fd94c1 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -547,11 +547,10 @@ describe('ReportActionsUtils', () => { }, ]; - // Expected output should have the `CREATED` action at last - // eslint-disable-next-line rulesdir/prefer-at + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, false); + // Expected output should filter out "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER" & "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER" action type const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, 4), ...input.slice(5)]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, false); expect(result).toStrictEqual(expectedOutput); }); }); From af332d716691ccd47e012229a90a0a4ec655d3df Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 17 Nov 2024 14:58:54 +0530 Subject: [PATCH 19/24] minor update. Signed-off-by: krishna2323 --- tests/unit/ReportActionsUtilsTest.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index 9f4610fd94c1..b2d310644de1 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -450,7 +450,7 @@ describe('ReportActionsUtils', () => { expect(result).toStrictEqual(input); }); - it('should filter whisper action in a archieved report', () => { + it('should filter whisper action in a archived report', () => { const input: ReportAction[] = [ { created: '2022-11-13 22:27:01.825', @@ -548,7 +548,8 @@ describe('ReportActionsUtils', () => { ]; const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, false); - // Expected output should filter out "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER" & "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER" action type + // Expected output should filter out "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER" & "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER" + // action type because "canUserPerformWriteAction" is false (report is archived) const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, 4), ...input.slice(5)]; expect(result).toStrictEqual(expectedOutput); From ed6c4ff37b5970b18b6a1e4fd3f253caf01aa775 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Sun, 17 Nov 2024 15:15:15 +0530 Subject: [PATCH 20/24] fix tests. Signed-off-by: krishna2323 --- tests/perf-test/ReportActionsUtils.perf-test.ts | 4 ++-- tests/unit/ReportActionsUtilsTest.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index 4190d7c1c089..b0ebd7c0c10a 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -93,7 +93,7 @@ describe('ReportActionsUtils', () => { }); test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true, true); + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true); await waitForBatchedUpdates(); await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray)); @@ -132,7 +132,7 @@ describe('ReportActionsUtils', () => { test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true, true)); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions, true)); }); test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index b2d310644de1..7528c29177cc 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -306,7 +306,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); expect(result).toStrictEqual(expectedOutput); }); @@ -401,7 +401,7 @@ describe('ReportActionsUtils', () => { // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, -1), input[1]]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); expect(result).toStrictEqual(expectedOutput); }); @@ -445,7 +445,7 @@ describe('ReportActionsUtils', () => { message: [{html: '', type: 'Action type', text: 'Action text'}], }, ]; - const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true, true); + const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, true); input.pop(); expect(result).toStrictEqual(input); }); From a3604223949e0d79ea53a1782f20b7dd499eef83 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Tue, 19 Nov 2024 14:42:42 +0530 Subject: [PATCH 21/24] update test input data and comments. Signed-off-by: krishna2323 --- tests/unit/ReportActionsUtilsTest.ts | 138 +++++++++++++++------------ 1 file changed, 78 insertions(+), 60 deletions(-) diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index 7528c29177cc..12e6c7ba2f92 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -450,72 +450,59 @@ describe('ReportActionsUtils', () => { expect(result).toStrictEqual(input); }); - it('should filter whisper action in a archived report', () => { + it('should filter actionable whisper actions e.g. "join", "create room" when room is archived', () => { const input: ReportAction[] = [ { - created: '2022-11-13 22:27:01.825', - reportActionID: '8401445780099176', - actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, - originalMessage: { - html: 'Hello world', - whisperedTo: [], - }, + created: '2024-11-19 07:59:27.352', + reportActionID: '2143762315092102133', + actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, message: [ { - html: 'Hello world', - type: 'Action type', - text: 'Action text', + type: 'TEXT', + style: 'strong', + text: 'You', }, - ], - }, - { - created: '2022-11-12 22:27:01.825', - reportActionID: '6401435781022176', - actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER, - originalMessage: { - html: 'Hello world', - whisperedTo: [], - }, - message: [ { - html: 'Hello world', - type: 'Action type', - text: 'Action text', + type: 'TEXT', + style: 'normal', + text: ' created this report', }, ], }, { - created: '2022-11-11 22:27:01.825', - reportActionID: '2962390724708756', - actionName: CONST.REPORT.ACTIONS.TYPE.IOU, + created: '2024-11-19 08:04:13.728', + reportActionID: '1607371725956675966', + actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, originalMessage: { - amount: 0, - currency: 'USD', - type: 'split', // change to const + html: '', + whisperedTo: [], + lastModified: '2024-11-19 08:04:13.728', + mentionedAccountIDs: [18301266], }, message: [ { - html: 'Hello world', - type: 'Action type', - text: 'Action text', + html: '', + text: '@as', + type: 'COMMENT', + whisperedTo: [], }, ], }, { - created: '2022-11-10 22:27:01.825', - reportActionID: '1609646094152486', - actionName: CONST.REPORT.ACTIONS.TYPE.RENAMED, + created: '2024-11-19 08:00:14.352', + reportActionID: '4655978522337302598', + actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, originalMessage: { - html: 'Hello world', - lastModified: '2022-11-10 22:27:01.825', - oldName: 'old name', - newName: 'new name', + html: '#join', + whisperedTo: [], + lastModified: '2024-11-19 08:00:14.352', }, message: [ { - html: 'Hello world', - type: 'Action type', - text: 'Action text', + html: '#join', + text: '#join', + type: 'COMMENT', + whisperedTo: [], }, ], }, @@ -523,34 +510,65 @@ describe('ReportActionsUtils', () => { created: '2022-11-09 22:27:01.825', reportActionID: '8049485084562457', actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER, - originalMessage: {}, - message: [{html: 'updated the Approval Mode from "Submit and Approve" to "Submit and Close"', type: 'Action type', text: 'Action text'}], + originalMessage: { + lastModified: '2024-11-19 08:00:14.353', + mentionedAccountIDs: [], + whisperedTo: [18301266], + }, + message: { + html: "Heads up, #join doesn't exist yet. Do you want to create it?", + text: "Heads up, #join doesn't exist yet. Do you want to create it?", + type: 'COMMENT', + whisperedTo: [18301266], + }, }, + { - created: '2022-11-08 22:27:06.825', - reportActionID: '1661970171066216', - actionName: CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_QUEUED, + created: '2022-11-12 22:27:01.825', + reportActionID: '6401435781022176', + actionName: CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER, originalMessage: { - paymentType: 'ACH', + inviteeAccountIDs: [18414674], + lastModified: '2024-11-19 08:04:25.813', + whisperedTo: [18301266], }, - message: [{html: 'Waiting for the bank account', type: 'Action type', text: 'Action text'}], + message: [ + { + html: "Heads up, isn't a member of this room.", + text: "Heads up, isn't a member of this room.", + type: 'COMMENT', + }, + ], }, { - created: '2022-11-06 22:27:08.825', - reportActionID: '1661970171066220', - actionName: CONST.REPORT.ACTIONS.TYPE.TASK_EDITED, + created: '2024-11-19 08:13:30.653', + reportActionID: '2700998753002050048', + actionName: CONST.REPORT.ACTIONS.TYPE.CLOSED, originalMessage: { - html: 'Hello world', - whisperedTo: [], + lastModified: '2024-11-19 08:13:30.653', + policyName: "As's Workspace 65", + reason: 'policyDeleted', }, - message: [{html: 'I have changed the task', type: 'Action type', text: 'Action text'}], + message: [ + { + type: 'TEXT', + style: 'strong', + text: 'You', + }, + { + type: 'TEXT', + style: 'normal', + text: ' closed this report', + }, + ], }, ]; const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, false); - // Expected output should filter out "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER" & "CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER" - // action type because "canUserPerformWriteAction" is false (report is archived) - const expectedOutput: ReportAction[] = [...input.slice(0, 1), ...input.slice(2, 4), ...input.slice(5)]; + // Expected output should filter out actionable whisper actions type e.g. "join", "create room" + // because "canUserPerformWriteAction" is false (report is archived) + // eslint-disable-next-line rulesdir/prefer-at + const expectedOutput: ReportAction[] = [...input.slice(1, 3), input[0]]; expect(result).toStrictEqual(expectedOutput); }); From 68d8fd61447bee19cd101f6b1be57d79cb52ba93 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 20 Nov 2024 02:50:12 +0530 Subject: [PATCH 22/24] update comments and input data. Signed-off-by: krishna2323 --- tests/unit/ReportActionsUtilsTest.ts | 56 +++++++--------------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index 12e6c7ba2f92..4e0f59cce032 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -451,24 +451,11 @@ describe('ReportActionsUtils', () => { }); it('should filter actionable whisper actions e.g. "join", "create room" when room is archived', () => { + // Given several different action types, including actionable whispers for creating, inviting and joining rooms, as well as non-actionable whispers + // - ADD_COMMENT + // - ACTIONABLE_REPORT_MENTION_WHISPER + // - ACTIONABLE_MENTION_WHISPER const input: ReportAction[] = [ - { - created: '2024-11-19 07:59:27.352', - reportActionID: '2143762315092102133', - actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, - message: [ - { - type: 'TEXT', - style: 'strong', - text: 'You', - }, - { - type: 'TEXT', - style: 'normal', - text: ' created this report', - }, - ], - }, { created: '2024-11-19 08:04:13.728', reportActionID: '1607371725956675966', @@ -540,35 +527,20 @@ describe('ReportActionsUtils', () => { }, ], }, - { - created: '2024-11-19 08:13:30.653', - reportActionID: '2700998753002050048', - actionName: CONST.REPORT.ACTIONS.TYPE.CLOSED, - originalMessage: { - lastModified: '2024-11-19 08:13:30.653', - policyName: "As's Workspace 65", - reason: 'policyDeleted', - }, - message: [ - { - type: 'TEXT', - style: 'strong', - text: 'You', - }, - { - type: 'TEXT', - style: 'normal', - text: ' closed this report', - }, - ], - }, ]; + // When the report actions are sorted for display with the second parameter (canUserPerformWriteAction) set to false (to simulate a report that has been archived) const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, false); - // Expected output should filter out actionable whisper actions type e.g. "join", "create room" - // because "canUserPerformWriteAction" is false (report is archived) + // Then the output should correctly filter out the actionable whisper types for "join", "inivite" and "create room" + // because the report is archived and making those actions not only doesn't make sense from a UX standpoint, + // but leads to server errors since those actions aren't possible. // eslint-disable-next-line rulesdir/prefer-at - const expectedOutput: ReportAction[] = [...input.slice(1, 3), input[0]]; + const expectedOutput: ReportAction[] = input.filter( + (action) => + action.actionName !== CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER && + action.actionName !== CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_JOIN_REQUEST && + action.actionName !== CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_MENTION_WHISPER, + ); expect(result).toStrictEqual(expectedOutput); }); From 7d32b416cdc49d55285ccffe5c9e82ec76507398 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 20 Nov 2024 02:58:05 +0530 Subject: [PATCH 23/24] minor update. Signed-off-by: krishna2323 --- tests/unit/ReportActionsUtilsTest.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index 4e0f59cce032..b444617bfd6f 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -531,9 +531,8 @@ describe('ReportActionsUtils', () => { // When the report actions are sorted for display with the second parameter (canUserPerformWriteAction) set to false (to simulate a report that has been archived) const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, false); - // Then the output should correctly filter out the actionable whisper types for "join", "inivite" and "create room" - // because the report is archived and making those actions not only doesn't make sense from a UX standpoint, - // but leads to server errors since those actions aren't possible. + // The output should correctly filter out the actionable whisper types for "join," "invite," and "create room" because the report is archived. + // Taking these actions not only doesn't make sense from a UX standpoint, but also leads to server errors since such actions are not possible. // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = input.filter( (action) => From 716c953b1d108f88b8a25a1e49b783421c1134a6 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 20 Nov 2024 15:02:21 +0530 Subject: [PATCH 24/24] remove 'eslint-disable-next-line' comment. Signed-off-by: krishna2323 --- tests/unit/ReportActionsUtilsTest.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/ReportActionsUtilsTest.ts b/tests/unit/ReportActionsUtilsTest.ts index b444617bfd6f..b94740375261 100644 --- a/tests/unit/ReportActionsUtilsTest.ts +++ b/tests/unit/ReportActionsUtilsTest.ts @@ -533,7 +533,6 @@ describe('ReportActionsUtils', () => { const result = ReportActionsUtils.getSortedReportActionsForDisplay(input, false); // The output should correctly filter out the actionable whisper types for "join," "invite," and "create room" because the report is archived. // Taking these actions not only doesn't make sense from a UX standpoint, but also leads to server errors since such actions are not possible. - // eslint-disable-next-line rulesdir/prefer-at const expectedOutput: ReportAction[] = input.filter( (action) => action.actionName !== CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_REPORT_MENTION_WHISPER &&