From 2a9c4e78e33a1b0cac64cb7589c71abd79f08e7a Mon Sep 17 00:00:00 2001 From: daledah Date: Thu, 9 Jan 2025 16:45:08 +0700 Subject: [PATCH 1/4] fix: highlight parent conversation when go back in offline --- src/components/ParentNavigationSubtitle.tsx | 4 +--- src/libs/PaginationUtils.ts | 3 ++- src/pages/home/report/ReportActionItemParentAction.tsx | 4 +--- src/pages/home/report/ThreadDivider.tsx | 4 +--- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/components/ParentNavigationSubtitle.tsx b/src/components/ParentNavigationSubtitle.tsx index 1896bc4f5f07..e59eae2b2f28 100644 --- a/src/components/ParentNavigationSubtitle.tsx +++ b/src/components/ParentNavigationSubtitle.tsx @@ -2,7 +2,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'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; @@ -30,7 +29,6 @@ type ParentNavigationSubtitleProps = { function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportActionID, parentReportID = '', pressableStyles}: ParentNavigationSubtitleProps) { const styles = useThemeStyles(); const {workspaceName, reportName} = parentNavigationSubtitleData; - const {isOffline} = useNetwork(); const {translate} = useLocalize(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`); const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); @@ -47,7 +45,7 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct 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) { + if (isVisibleAction) { // Pop the chat report screen before navigating to the linked report action. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReportID, parentReportActionID), true); } diff --git a/src/libs/PaginationUtils.ts b/src/libs/PaginationUtils.ts index 1cb3e7295c27..59302abd2d43 100644 --- a/src/libs/PaginationUtils.ts +++ b/src/libs/PaginationUtils.ts @@ -173,7 +173,8 @@ function getContinuousChain( id?: string, ): {data: TResource[]; hasNextPage: boolean; hasPreviousPage: boolean} { if (pages.length === 0) { - return {data: id ? [] : sortedItems, hasNextPage: false, hasPreviousPage: false}; + const dataItem = sortedItems.find((item) => getID(item) === id); + return {data: id && !dataItem ? [] : sortedItems, hasNextPage: false, hasPreviousPage: false}; } const pagesWithIndexes = getPagesWithIndexes(sortedItems, pages, getID); diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 5976ac5de725..12963df38c46 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -4,7 +4,6 @@ import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import TripDetailsView from '@components/ReportActionItem/TripDetailsView'; -import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import onyxSubscribe from '@libs/onyxSubscribe'; @@ -68,7 +67,6 @@ function ReportActionItemParentAction({ const ancestorIDs = useRef(ReportUtils.getAllAncestorReportActionIDs(report)); const ancestorReports = useRef>>({}); const [allAncestors, setAllAncestors] = useState([]); - const {isOffline} = useNetwork(); useEffect(() => { const unsubscribeReports: Array<() => void> = []; @@ -143,7 +141,7 @@ function ReportActionItemParentAction({ ); // 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) { + if (isVisibleAction) { // 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)); } diff --git a/src/pages/home/report/ThreadDivider.tsx b/src/pages/home/report/ThreadDivider.tsx index 0cf34d6f40e6..bb7679c18870 100644 --- a/src/pages/home/report/ThreadDivider.tsx +++ b/src/pages/home/report/ThreadDivider.tsx @@ -5,7 +5,6 @@ import * as Expensicons from '@components/Icon/Expensicons'; import {PressableWithoutFeedback} from '@components/Pressable'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; -import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; @@ -28,7 +27,6 @@ function ThreadDivider({ancestor, isLinkDisabled = false}: ThreadDividerProps) { const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); - const {isOffline} = useNetwork(); return ( Date: Fri, 10 Jan 2025 12:04:35 +0700 Subject: [PATCH 2/4] fix lint --- src/components/ParentNavigationSubtitle.tsx | 4 ++-- .../home/report/ReportActionItemParentAction.tsx | 13 +++++++------ src/pages/home/report/ThreadDivider.tsx | 6 +++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/ParentNavigationSubtitle.tsx b/src/components/ParentNavigationSubtitle.tsx index e59eae2b2f28..424c24545708 100644 --- a/src/components/ParentNavigationSubtitle.tsx +++ b/src/components/ParentNavigationSubtitle.tsx @@ -41,8 +41,8 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct return ( { - const parentAction = ReportActionsUtils.getReportAction(parentReportID, parentReportActionID ?? '-1'); - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? '-1', canUserPerformWriteAction); + const parentAction = ReportActionsUtils.getReportAction(parentReportID, parentReportActionID); + const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? CONST.DEFAULT_NUMBER_ID, canUserPerformWriteAction); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReportID)); if (isVisibleAction) { diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index 12963df38c46..7760c6a2e16f 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -10,6 +10,7 @@ import onyxSubscribe from '@libs/onyxSubscribe'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as Report from '@userActions/Report'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; @@ -120,30 +121,30 @@ function ReportActionItemParentAction({ > {ReportActionsUtils.isTripPreview(ancestor?.reportAction) ? ( ) : ( { const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( ancestor.reportAction, - ancestor.reportAction.reportActionID ?? '-1', + ancestor.reportAction.reportActionID, canUserPerformWriteAction, ); // Pop the thread report screen before navigating to the chat report. - Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID ?? '-1')); + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID)); if (isVisibleAction) { // 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)); + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID, ancestor.reportAction.reportActionID)); } } : undefined diff --git a/src/pages/home/report/ThreadDivider.tsx b/src/pages/home/report/ThreadDivider.tsx index bb7679c18870..57d2474a7d8b 100644 --- a/src/pages/home/report/ThreadDivider.tsx +++ b/src/pages/home/report/ThreadDivider.tsx @@ -48,14 +48,14 @@ function ThreadDivider({ancestor, isLinkDisabled = false}: ThreadDividerProps) { onPress={() => { const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( ancestor.reportAction, - ancestor.reportAction.reportActionID ?? '-1', + ancestor.reportAction.reportActionID, 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')); + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID)); if (isVisibleAction) { // 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)); + Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID, ancestor.reportAction.reportActionID)); } }} accessibilityLabel={translate('threads.thread')} From 5bb5550ee03791ca8fdc0cd207a33161e2d81cfa Mon Sep 17 00:00:00 2001 From: daledah Date: Fri, 10 Jan 2025 12:14:45 +0700 Subject: [PATCH 3/4] fix test --- tests/unit/PaginationUtilsTest.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/unit/PaginationUtilsTest.ts b/tests/unit/PaginationUtilsTest.ts index e5f4ce7675e8..28e754ce5ff7 100644 --- a/tests/unit/PaginationUtilsTest.ts +++ b/tests/unit/PaginationUtilsTest.ts @@ -163,7 +163,7 @@ describe('PaginationUtils', () => { expect(result.hasNextPage).toBe(false); }); - it('given an input ID and the report only contains pending actions, it will return an empty array', () => { + it('given an input ID and the report only contains pending actions, it will return all actions', () => { const input = createItems([ // Given these sortedItems '7', @@ -178,8 +178,31 @@ describe('PaginationUtils', () => { const pages: Pages = []; // Expect these sortedItems - const expectedResult: Item[] = []; + const expectedResult = [...input]; const result = PaginationUtils.getContinuousChain(input, pages, getID, '4'); + // Expect the result to be the same + expect(result.data).toStrictEqual(expectedResult); + expect(result.hasPreviousPage).toBe(false); + expect(result.hasNextPage).toBe(false); + }); + + it('given an input ID of 8 which does not exist in Onyx and the report only contains pending actions, it will return an empty array', () => { + const input = createItems([ + // Given these sortedItems + '7', + '6', + '5', + '4', + '3', + '2', + '1', + ]); + + const pages: Pages = []; + + // Expect these sortedItems + const expectedResult: Item[] = []; + const result = PaginationUtils.getContinuousChain(input, pages, getID, '8'); expect(result.data).toStrictEqual(expectedResult); expect(result.hasPreviousPage).toBe(false); expect(result.hasNextPage).toBe(false); From 7f4b9a2abb78d0e313017a7ed16716fe772cbe31 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 15 Jan 2025 16:04:25 +0700 Subject: [PATCH 4/4] fix: lint --- src/components/ParentNavigationSubtitle.tsx | 10 +++++----- src/pages/home/report/ThreadDivider.tsx | 10 +++------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/components/ParentNavigationSubtitle.tsx b/src/components/ParentNavigationSubtitle.tsx index 424c24545708..f9d84fb423bb 100644 --- a/src/components/ParentNavigationSubtitle.tsx +++ b/src/components/ParentNavigationSubtitle.tsx @@ -4,8 +4,8 @@ import {useOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; -import * as ReportUtils from '@libs/ReportUtils'; +import {getReportAction, shouldReportActionBeVisible} from '@libs/ReportActionsUtils'; +import {canUserPerformWriteAction as canUserPerformWriteActionReportUtils} from '@libs/ReportUtils'; import CONST from '@src/CONST'; import type {ParentNavigationSummaryParams} from '@src/languages/params'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -31,7 +31,7 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct const {workspaceName, reportName} = parentNavigationSubtitleData; const {translate} = useLocalize(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`); - const canUserPerformWriteAction = ReportUtils.canUserPerformWriteAction(report); + const canUserPerformWriteAction = canUserPerformWriteActionReportUtils(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) { @@ -41,8 +41,8 @@ function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportAct return ( { - const parentAction = ReportActionsUtils.getReportAction(parentReportID, parentReportActionID); - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? CONST.DEFAULT_NUMBER_ID, canUserPerformWriteAction); + const parentAction = getReportAction(parentReportID, parentReportActionID); + const isVisibleAction = shouldReportActionBeVisible(parentAction, parentAction?.reportActionID ?? CONST.DEFAULT_NUMBER_ID, canUserPerformWriteAction); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReportID)); if (isVisibleAction) { diff --git a/src/pages/home/report/ThreadDivider.tsx b/src/pages/home/report/ThreadDivider.tsx index 57d2474a7d8b..7bb03c42ac82 100644 --- a/src/pages/home/report/ThreadDivider.tsx +++ b/src/pages/home/report/ThreadDivider.tsx @@ -8,9 +8,9 @@ import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import {shouldReportActionBeVisible} from '@libs/ReportActionsUtils'; +import {canUserPerformWriteAction} from '@libs/ReportUtils'; 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'; @@ -46,11 +46,7 @@ function ThreadDivider({ancestor, isLinkDisabled = false}: ThreadDividerProps) { ) : ( { - const isVisibleAction = ReportActionsUtils.shouldReportActionBeVisible( - ancestor.reportAction, - ancestor.reportAction.reportActionID, - ReportUtils.canUserPerformWriteAction(ancestor.report), - ); + const isVisibleAction = shouldReportActionBeVisible(ancestor.reportAction, ancestor.reportAction.reportActionID, canUserPerformWriteAction(ancestor.report)); // Pop the thread report screen before navigating to the chat report. Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID)); if (isVisibleAction) {