From 2f0555fb2ab709a48c35ffaf829053d00c36ec1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Tue, 5 Mar 2024 10:19:14 +0100 Subject: [PATCH] fixing complexity --- src/libs/SidebarUtils.ts | 9 ++- src/pages/home/sidebar/SidebarLinksData.js | 76 +++++++++++++--------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 94912c93083d..9da36a23c74d 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -173,7 +173,7 @@ function sortArchivedReports(reports: Report[], isInDefaultMode: boolean) { /** * @returns An array of reportIDs sorted in the proper order */ -function getOrderedReportIDs( +function getGroupedReports( currentReportId: string | null, allReports: Record, betas: Beta[], @@ -183,7 +183,7 @@ function getOrderedReportIDs( transactionViolations: OnyxCollection, currentPolicyID = '', policyMemberAccountIDs: number[] = [], -): string[] { +): Report[][] { const isInGSDMode = priorityMode === CONST.PRIORITY_MODE.GSD; const isInDefaultMode = !isInGSDMode; const allReportsDictValues = Object.values(allReports); @@ -213,8 +213,7 @@ function getOrderedReportIDs( // Now that we have all the reports grouped and sorted, they must be flattened into an array and only return the reportID. // The order the arrays are concatenated in matters and will determine the order that the groups are displayed in the sidebar. - const LHNReports = [...pinnedAndGBRReports, ...draftReports, ...nonArchivedReports, ...archivedReports].map((report) => report.reportID); - return LHNReports; + return [pinnedAndGBRReports, draftReports, nonArchivedReports, archivedReports]; } /** @@ -440,6 +439,6 @@ function getOptionData({ export default { getOptionData, - getOrderedReportIDs, + getGroupedReports, sortDraftReports, }; diff --git a/src/pages/home/sidebar/SidebarLinksData.js b/src/pages/home/sidebar/SidebarLinksData.js index 621294b80044..247f78e6626d 100644 --- a/src/pages/home/sidebar/SidebarLinksData.js +++ b/src/pages/home/sidebar/SidebarLinksData.js @@ -1,4 +1,5 @@ import {deepEqual} from 'fast-equals'; +import {keys, map} from 'lodash'; import lodashGet from 'lodash/get'; import lodashMap from 'lodash/map'; import PropTypes from 'prop-types'; @@ -16,6 +17,7 @@ import useLocalize from '@hooks/useLocalize'; import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; +import {hasValidDraftComment} from '@libs/DraftCommentStore'; import {getPolicyMembersByIdWithoutCurrentUser} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import SidebarUtils from '@libs/SidebarUtils'; @@ -93,6 +95,8 @@ const propTypes = { ), }), + reportsDraftComments: PropTypes.objectOf(PropTypes.string), + ...withCurrentUserPersonalDetailsPropTypes, }; @@ -105,9 +109,17 @@ const defaultProps = { policyMembers: {}, transactionViolations: {}, allReportActions: {}, + reportsDraftComments: {}, ...withCurrentUserPersonalDetailsDefaultProps, }; +const useReportsWithDrafts = (reports, drafts) => { + const reportIDsWithDrafts = useMemo(() => map(keys(drafts), (k) => k.replace(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, '')), [drafts]); + const reportsWithDrafts = useMemo(() => reportIDsWithDrafts.filter(hasValidDraftComment).map((reportID) => reports[ONYXKEYS.COLLECTION.REPORT + reportID]), []); + + return reportsWithDrafts; +}; + function SidebarLinksData({ isFocused, allReportActions, @@ -123,6 +135,7 @@ function SidebarLinksData({ policyMembers, transactionViolations, currentUserPersonalDetails, + reportsDraftComments, }) { const styles = useThemeStyles(); const {activeWorkspaceID} = useActiveWorkspace(); @@ -136,40 +149,22 @@ function SidebarLinksData({ const reportIDsRef = useRef(null); const isLoading = isLoadingApp; - const optionListItems = useMemo(() => { - const reportIDs = SidebarUtils.getOrderedReportIDs( - null, - chatReports, - betas, - policies, - priorityMode, - allReportActions, - transactionViolations, - activeWorkspaceID, - policyMemberAccountIDs, - ); - if (deepEqual(reportIDsRef.current, reportIDs)) { - return reportIDsRef.current; - } + const reportsWithDrafts = useReportsWithDrafts(chatReports, reportsDraftComments); - // 1. We need to update existing reports only once while loading because they are updated several times during loading and causes this regression: https://github.com/Expensify/App/issues/24596#issuecomment-1681679531 - // 2. If the user is offline, we need to update the reports unconditionally, since the loading of report data might be stuck in this case. - // 3. Changing priority mode to Most Recent will call OpenApp. If there is an existing reports and the priority mode is updated, we want to immediately update the list instead of waiting the OpenApp request to complete - if (!isLoading || !reportIDsRef.current || network.isOffline || (reportIDsRef.current && prevPriorityMode !== priorityMode)) { - reportIDsRef.current = reportIDs; - } - return reportIDsRef.current || []; - }, [chatReports, betas, policies, priorityMode, allReportActions, transactionViolations, activeWorkspaceID, policyMemberAccountIDs, isLoading, network.isOffline, prevPriorityMode]); + const groupedReports = useMemo( + () => SidebarUtils.getGroupedReports(null, chatReports, betas, policies, priorityMode, allReportActions, transactionViolations, activeWorkspaceID, policyMemberAccountIDs), + [chatReports, betas, policies, priorityMode, allReportActions, transactionViolations, activeWorkspaceID, policyMemberAccountIDs], + ); // We need to make sure the current report is in the list of reports, but we do not want // to have to re-generate the list every time the currentReportID changes. To do that // we first generate the list as if there was no current report, then here we check if // the current report is missing from the list, which should very rarely happen. In this // case we re-generate the list a 2nd time with the current report included. - const optionListItemsWithCurrentReport = useMemo(() => { - if (currentReportID && !_.contains(optionListItems, currentReportID)) { - return SidebarUtils.getOrderedReportIDs( + const groupedReportsWithCurrentReport = useMemo(() => { + if (currentReportID && groupedReports.some((group) => group.some((report) => report.reportID === currentReportID)) === false) { + return SidebarUtils.getGroupedReports( currentReportID, chatReports, betas, @@ -181,8 +176,27 @@ function SidebarLinksData({ policyMemberAccountIDs, ); } - return optionListItems; - }, [currentReportID, optionListItems, chatReports, betas, policies, priorityMode, allReportActions, transactionViolations, activeWorkspaceID, policyMemberAccountIDs]); + return groupedReports; + }, [currentReportID, groupedReports, chatReports, betas, policies, priorityMode, allReportActions, transactionViolations, activeWorkspaceID, policyMemberAccountIDs]); + + const orderedReportIDs = useMemo(() => { + // Substituting the first group with the reports with drafts + groupedReports[1] = reportsWithDrafts; + + const reportIDs = groupedReportsWithCurrentReport.flat().map((report) => report.reportID); + + if (deepEqual(reportIDsRef.current, reportIDs)) { + return reportIDsRef.current; + } + + // 1. We need to update existing reports only once while loading because they are updated several times during loading and causes this regression: https://github.com/Expensify/App/issues/24596#issuecomment-1681679531 + // 2. If the user is offline, we need to update the reports unconditionally, since the loading of report data might be stuck in this case. + // 3. Changing priority mode to Most Recent will call OpenApp. If there is an existing reports and the priority mode is updated, we want to immediately update the list instead of waiting the OpenApp request to complete + if (!isLoading || !reportIDsRef.current || network.isOffline || (reportIDsRef.current && prevPriorityMode !== priorityMode)) { + reportIDsRef.current = reportIDs; + } + return reportIDsRef.current || []; + }, [groupedReportsWithCurrentReport, reportsWithDrafts, isLoading, network.isOffline, prevPriorityMode, priorityMode]); const currentReportIDRef = useRef(currentReportID); currentReportIDRef.current = currentReportID; @@ -202,7 +216,7 @@ function SidebarLinksData({ // Data props: isActiveReport={isActiveReport} isLoading={isLoading} - optionListItems={optionListItemsWithCurrentReport} + optionListItems={orderedReportIDs} activeWorkspaceID={activeWorkspaceID} /> @@ -332,5 +346,9 @@ export default compose( key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, initialValue: {}, }, + reportsDraftComments: { + key: ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT, + initialValue: {}, + }, }), )(SidebarLinksData);