Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7152cdf
expose value from a derived value
TMisiukiewicz May 8, 2025
fabc6e1
replace in SidebarUtils
TMisiukiewicz May 8, 2025
ceccba1
replace in OptionListUtils
TMisiukiewicz May 8, 2025
e61a304
replace occurencies of getAllReportErrors
TMisiukiewicz May 8, 2025
2667e86
fix CI jobs
TMisiukiewicz May 9, 2025
6f69d6e
fix lint job
TMisiukiewicz May 9, 2025
5f7c427
fix lint changed in DebugReportPage
TMisiukiewicz May 9, 2025
943c19e
Merge remote-tracking branch 'upstream/main' into perf/use-getAllRepo…
TMisiukiewicz May 12, 2025
d8722a8
reduce diff
TMisiukiewicz May 12, 2025
ada6305
update submodule
TMisiukiewicz May 12, 2025
2d64a4e
fix changed files
TMisiukiewicz May 12, 2025
99033c4
fix CI jobs
TMisiukiewicz May 12, 2025
03cf3c5
Merge branch 'main' into perf/use-getAllReportErrors-from-derived-value
TMisiukiewicz May 13, 2025
04449d7
Merge branch 'main' into perf/use-getAllReportErrors-from-derived-value
TMisiukiewicz May 21, 2025
c18b10d
use reportAttributes from param
TMisiukiewicz May 21, 2025
631692f
update submodule
TMisiukiewicz May 21, 2025
6d8d833
remove deprecated getTransaction from SidebarUtils
TMisiukiewicz May 21, 2025
5631a63
Merge remote-tracking branch 'upstream/main' into perf/use-getAllRepo…
TMisiukiewicz May 22, 2025
00760da
remove hasReportErrors
TMisiukiewicz May 22, 2025
29445ff
migrate from deprecated getTransaction
TMisiukiewicz May 22, 2025
11d6ee4
update deps in DebugReportPage
TMisiukiewicz May 22, 2025
bd560a2
update submodule
TMisiukiewicz May 22, 2025
5f7386c
add getAllReportErrors tests
TMisiukiewicz May 22, 2025
629804e
update submodule
TMisiukiewicz May 22, 2025
e800e07
Merge remote-tracking branch 'upstream/main' into perf/use-getAllRepo…
TMisiukiewicz May 23, 2025
9fcf485
Merge remote-tracking branch 'upstream/main' into perf/use-getAllRepo…
TMisiukiewicz May 26, 2025
f8c828d
Merge remote-tracking branch 'upstream/main' into perf/use-getAllRepo…
TMisiukiewicz May 27, 2025
317f3be
Merge remote-tracking branch 'upstream/main' into perf/use-getAllRepo…
TMisiukiewicz May 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/components/LHNOptionsList/LHNOptionsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {isValidDraftComment} from '@libs/DraftCommentUtils';
import getPlatform from '@libs/getPlatform';
import Log from '@libs/Log';
import {getIOUReportIDOfLastAction, getLastMessageTextForReport, hasReportErrors} from '@libs/OptionsListUtils';
import {getIOUReportIDOfLastAction, getLastMessageTextForReport} from '@libs/OptionsListUtils';
import {getOneTransactionThreadReportID, getOriginalMessage, getSortedReportActionsForDisplay, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {canUserPerformWriteAction, getReportAttributes} from '@libs/ReportUtils';
import {canUserPerformWriteAction} from '@libs/ReportUtils';
import isProductTrainingElementDismissed from '@libs/TooltipUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetails, Report} from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
import OptionRowLHNData from './OptionRowLHNData';
import OptionRowRendererComponent from './OptionRowRendererComponent';
Expand Down Expand Up @@ -69,19 +70,19 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
return undefined;
}
const firstReportWithGBRorRBR = data.find((report) => {
const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`];
const itemReportErrors = reportAttributes?.[report.reportID]?.reportErrors;
if (!report) {
return false;
}
if (hasReportErrors(report, itemReportActions)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We can completely remove this hasReportErrors method here

function hasReportErrors(report: Report, reportActions: OnyxEntry<ReportActions>) {
return !isEmptyObject(getAllReportErrors(report, reportActions));
}

if (!isEmptyObject(itemReportErrors)) {
return true;
}
const hasGBR = getReportAttributes(report.reportID, reportAttributes)?.requiresAttention;
const hasGBR = reportAttributes?.[report.reportID]?.requiresAttention;
return hasGBR;
});

return firstReportWithGBRorRBR?.reportID;
}, [isGBRorRBRTooltipDismissed, data, reportActions, reportAttributes]);
}, [isGBRorRBRTooltipDismissed, data, reportAttributes]);

// When the first item renders we want to call the onFirstItemRendered callback.
// At this point in time we know that the list is actually displaying items.
Expand Down
1 change: 0 additions & 1 deletion src/components/LHNOptionsList/OptionRowLHNData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ function OptionRowLHNData({
reportAttributes,
oneTransactionThreadReport,
reportNameValuePairs,
reportActions,
personalDetails,
preferredLocale: preferredLocale ?? CONST.LOCALES.DEFAULT,
policy,
Expand Down
13 changes: 11 additions & 2 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Beta, Policy, Report, ReportAction, ReportActions, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
import type {Errors} from '@src/types/onyx/OnyxCommon';
import type {Comment} from '@src/types/onyx/Transaction';
import {getLinkedTransactionID} from './ReportActionsUtils';
import {getReasonAndReportActionThatRequiresAttention, reasonForReportToBeInOptionList, shouldDisplayViolationsRBRInLHN} from './ReportUtils';
Expand Down Expand Up @@ -1379,8 +1380,16 @@ type RBRReasonAndReportAction = {
/**
* Gets the report action that is causing the RBR to show up in LHN
*/
function getReasonAndReportActionForRBRInLHNRow(report: Report, reportActions: OnyxEntry<ReportActions>, hasViolations: boolean, isArchivedReport = false): RBRReasonAndReportAction | null {
const {reason, reportAction} = SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(report, reportActions, hasViolations, transactionViolations, isArchivedReport) ?? {};
function getReasonAndReportActionForRBRInLHNRow(
report: Report,
reportActions: OnyxEntry<ReportActions>,
transactions: OnyxCollection<Transaction>,
hasViolations: boolean,
reportErrors: Errors,
isArchivedReport = false,
): RBRReasonAndReportAction | null {
const {reason, reportAction} =
SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(report, reportActions, hasViolations, reportErrors, transactions, transactionViolations, isArchivedReport) ?? {};

if (reason) {
return {reason: `debug.reasonRBR.${reason}`, reportAction};
Expand Down
92 changes: 29 additions & 63 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
Report,
ReportAction,
ReportActions,
ReportAttributesDerivedValue,
ReportNameValuePairs,
TransactionViolation,
} from '@src/types/onyx';
Expand Down Expand Up @@ -88,7 +89,6 @@ import {
import {
canUserPerformWriteAction,
formatReportLastMessageText,
getAllReportErrors,
getChatByParticipants,
getChatRoomSubtitle,
getDeletedParentActionMessageForChatReport,
Expand Down Expand Up @@ -451,6 +451,12 @@ Onyx.connect({
callback: (value) => (nvpDismissedProductTraining = value),
});

let reportAttributesDerivedValue: ReportAttributesDerivedValue['reports'] | undefined;
Onyx.connect({
key: ONYXKEYS.DERIVED.REPORT_ATTRIBUTES,
callback: (value) => (reportAttributesDerivedValue = value?.reports),
});

/**
* @param defaultValues {login: accountID} In workspace invite page, when new user is added we pass available data to opt in
* @returns Returns avatar data for a list of user accountIDs
Expand Down Expand Up @@ -846,20 +852,10 @@ function getLastMessageTextForReport(
return lastMessageTextFromReport || (report?.lastMessageText ?? '');
}

function hasReportErrors(report: Report, reportActions: OnyxEntry<ReportActions>) {
return !isEmptyObject(getAllReportErrors(report, reportActions));
}

/**
* Creates a report list option
*/
function createOption(
accountIDs: number[],
personalDetails: OnyxInputOrEntry<PersonalDetailsList>,
report: OnyxInputOrEntry<Report>,
reportActions: ReportActions,
config?: PreviewConfig,
): OptionData {
function createOption(accountIDs: number[], personalDetails: OnyxInputOrEntry<PersonalDetailsList>, report: OnyxInputOrEntry<Report>, config?: PreviewConfig): OptionData {
const {showChatPreviewLine = false, forcePolicyNamePreview = false, showPersonalDetails = false, selected, isSelected, isDisabled} = config ?? {};
const result: OptionData = {
text: undefined,
Expand Down Expand Up @@ -919,8 +915,8 @@ function createOption(
result.shouldShowSubscript = shouldReportShowSubscript(report);
result.isPolicyExpenseChat = reportUtilsIsPolicyExpenseChat(report);
result.isOwnPolicyExpenseChat = report.isOwnPolicyExpenseChat ?? false;
result.allReportErrors = getAllReportErrors(report, reportActions);
result.brickRoadIndicator = hasReportErrors(report, reportActions) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : '';
result.allReportErrors = reportAttributesDerivedValue?.[report.reportID]?.reportErrors ?? {};
result.brickRoadIndicator = !isEmptyObject(result.allReportErrors) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : '';
result.pendingAction = report.pendingFields ? report.pendingFields.addWorkspaceRoom ?? report.pendingFields.createChat : undefined;
result.ownerAccountID = report.ownerAccountID;
result.reportID = report.reportID;
Expand Down Expand Up @@ -999,16 +995,10 @@ function getReportOption(participant: Participant): OptionData {
const report = getReportOrDraftReport(participant.reportID);
const visibleParticipantAccountIDs = getParticipantsAccountIDsForDisplay(report, true);

const option = createOption(
visibleParticipantAccountIDs,
allPersonalDetails ?? {},
!isEmptyObject(report) ? report : undefined,
{},
{
showChatPreviewLine: false,
forcePolicyNamePreview: false,
},
);
const option = createOption(visibleParticipantAccountIDs, allPersonalDetails ?? {}, !isEmptyObject(report) ? report : undefined, {
showChatPreviewLine: false,
forcePolicyNamePreview: false,
});

// Update text & alternateText because createOption returns workspace name only if report is owned by the user
if (option.isSelfDM) {
Expand Down Expand Up @@ -1043,16 +1033,10 @@ function getReportOption(participant: Participant): OptionData {
function getReportDisplayOption(report: OnyxEntry<Report>, unknownUserDetails: OnyxEntry<Participant>): OptionData {
const visibleParticipantAccountIDs = getParticipantsAccountIDsForDisplay(report, true);

const option = createOption(
visibleParticipantAccountIDs,
allPersonalDetails ?? {},
!isEmptyObject(report) ? report : undefined,
{},
{
showChatPreviewLine: false,
forcePolicyNamePreview: false,
},
);
const option = createOption(visibleParticipantAccountIDs, allPersonalDetails ?? {}, !isEmptyObject(report) ? report : undefined, {
showChatPreviewLine: false,
forcePolicyNamePreview: false,
});

// Update text & alternateText because createOption returns workspace name only if report is owned by the user
if (option.isSelfDM) {
Expand Down Expand Up @@ -1084,16 +1068,10 @@ function getPolicyExpenseReportOption(participant: Participant | OptionData): Op
.filter(([, reportParticipant]) => reportParticipant && !isHiddenForCurrentUser(reportParticipant.notificationPreference))
.map(([accountID]) => Number(accountID));

const option = createOption(
visibleParticipantAccountIDs,
allPersonalDetails ?? {},
!isEmptyObject(expenseReport) ? expenseReport : null,
{},
{
showChatPreviewLine: false,
forcePolicyNamePreview: false,
},
);
const option = createOption(visibleParticipantAccountIDs, allPersonalDetails ?? {}, !isEmptyObject(expenseReport) ? expenseReport : null, {
showChatPreviewLine: false,
forcePolicyNamePreview: false,
});

// Update text & alternateText because createOption returns workspace name only if report is owned by the user
option.text = getPolicyName({report: expenseReport});
Expand Down Expand Up @@ -1222,7 +1200,7 @@ function processReport(
reportMapEntry,
reportOption: {
item: report,
...createOption(accountIDs, personalDetails, report, {}),
...createOption(accountIDs, personalDetails, report),
},
};
}
Expand All @@ -1248,13 +1226,9 @@ function createOptionList(personalDetails: OnyxEntry<PersonalDetailsList>, repor

const allPersonalDetailsOptions = Object.values(personalDetails ?? {}).map((personalDetail) => ({
item: personalDetail,
...createOption(
[personalDetail?.accountID ?? CONST.DEFAULT_NUMBER_ID],
personalDetails,
reportMapForAccountIDs[personalDetail?.accountID ?? CONST.DEFAULT_NUMBER_ID],
{},
{showPersonalDetails: true},
),
...createOption([personalDetail?.accountID ?? CONST.DEFAULT_NUMBER_ID], personalDetails, reportMapForAccountIDs[personalDetail?.accountID ?? CONST.DEFAULT_NUMBER_ID], {
showPersonalDetails: true,
}),
}));

return {
Expand All @@ -1268,7 +1242,7 @@ function createOptionFromReport(report: Report, personalDetails: OnyxEntry<Perso

return {
item: report,
...createOption(accountIDs, personalDetails, report, {}),
...createOption(accountIDs, personalDetails, report),
};
}

Expand Down Expand Up @@ -1419,14 +1393,7 @@ function canCreateOptimisticPersonalDetailOption({
* - If prop shouldAcceptName = true, the searchValue can be also a normal string
* - The searchValue isn't the current personal detail login
*/
function getUserToInviteOption({
searchValue,
loginsToExclude = {},
selectedOptions = [],
reportActions = {},
showChatPreviewLine = false,
shouldAcceptName = false,
}: GetUserToInviteConfig): OptionData | null {
function getUserToInviteOption({searchValue, loginsToExclude = {}, selectedOptions = [], showChatPreviewLine = false, shouldAcceptName = false}: GetUserToInviteConfig): OptionData | null {
if (!searchValue) {
return null;
}
Expand All @@ -1451,7 +1418,7 @@ function getUserToInviteOption({
login: searchValue,
},
};
const userToInvite = createOption([optimisticAccountID], personalDetailsExtended, null, reportActions, {
const userToInvite = createOption([optimisticAccountID], personalDetailsExtended, null, {
showChatPreviewLine,
});
userToInvite.isOptimisticAccount = true;
Expand Down Expand Up @@ -2476,7 +2443,6 @@ export {
getAttendeeOptions,
getAlternateText,
getReportDisplayOption,
hasReportErrors,
combineOrderingOfReportsAndPersonalDetails,
filterWorkspaceChats,
orderWorkspaceOptions,
Expand Down
21 changes: 7 additions & 14 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7788,9 +7788,13 @@ function getAllReportErrors(report: OnyxEntry<Report>, reportActions: OnyxEntry<
return allReportErrors;
}

function hasReportErrorsOtherThanFailedReceipt(report: Report, doesReportHaveViolations: boolean, transactionViolations: OnyxCollection<TransactionViolation[]>) {
const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`] ?? {};
const allReportErrors = getAllReportErrors(report, reportActions) ?? {};
function hasReportErrorsOtherThanFailedReceipt(
report: Report,
doesReportHaveViolations: boolean,
transactionViolations: OnyxCollection<TransactionViolation[]>,
reportAttributes?: ReportAttributesDerivedValue['reports'],
) {
const allReportErrors = reportAttributes?.[report?.reportID]?.reportErrors ?? {};
const transactionReportActions = getAllReportActions(report.reportID);
const oneTransactionThreadReportID = getOneTransactionThreadReportID(report.reportID, transactionReportActions, undefined);
let doesTransactionThreadReportHasViolations = false;
Expand Down Expand Up @@ -10785,16 +10789,6 @@ function findReportIDForAction(action?: ReportAction): string | undefined {
})
?.replace(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`, '');
}

function getReportAttributes(reportID: string | undefined, reportAttributes?: ReportAttributesDerivedValue['reports']) {
const attributes = reportAttributes ?? reportAttributesDerivedValue;

if (!reportID || !attributes?.[reportID]) {
return;
}
return attributes[reportID];
}

export {
addDomainToShortMention,
completeShortMention,
Expand Down Expand Up @@ -11173,7 +11167,6 @@ export {
isAllowedToSubmitDraftExpenseReport,
findReportIDForAction,
isWorkspaceEligibleForReportChange,
getReportAttributes,
navigateOnDeleteExpense,
};

Expand Down
Loading
Loading