Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 23 additions & 17 deletions src/components/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ function Badge({
[styles.defaultBadge, styles.condensedBadge, styles.alignSelfCenter, styles.ml2, StyleUtils, success, error, environment, badgeStyles, isCondensed, isStrong],
);

if (!text && !icon) {
return null;
}

return (
<Wrapper
style={pressable ? wrapperStyles : wrapperStyles({focused: false, hovered: false, isDisabled: false, isScreenReaderActive: false, pressed: false})}
Expand All @@ -102,7 +106,7 @@ function Badge({
accessible={false}
>
{!!icon && (
<View style={[styles.mr1, iconStyles]}>
<View style={[!!text && styles.mr1, iconStyles]}>
<Icon
width={iconSize}
height={iconSize}
Expand All @@ -111,22 +115,24 @@ function Badge({
/>
</View>
)}
<Text
style={[
styles.badgeText,
styles.textStrong,
isCondensed && styles.condensedBadgeText,
!isStrong && !success && !error && styles.badgeDefaultText,
!isStrong && success && styles.badgeSuccessText,
!isStrong && error && styles.badgeDangerText,
isStrong && (success || error) && styles.badgeStrongText,
textStyles,
isDeleted ? styles.offlineFeedbackDeleted : {},
]}
numberOfLines={1}
>
{text}
</Text>
{!!text && (
<Text
style={[
styles.badgeText,
styles.textStrong,
isCondensed && styles.condensedBadgeText,
!isStrong && !success && !error && styles.badgeDefaultText,
!isStrong && success && styles.badgeSuccessText,
!isStrong && error && styles.badgeDangerText,
isStrong && (success || error) && styles.badgeStrongText,
textStyles,
isDeleted ? styles.offlineFeedbackDeleted : {},
]}
numberOfLines={1}
>
{text}
</Text>
)}
</Wrapper>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ function OptionRowLHN({
) : (
<Badge
icon={expensifyIcons.Pin}
text={translate('common.pinned')}
text=""
badgeStyles={isOptionFocused && styles.badgeDefaultActive}
isCondensed
isStrong
Expand Down
1 change: 1 addition & 0 deletions src/components/LHNOptionsList/OptionRowLHNData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ function OptionRowLHNData({
fullReport,
reportAttributes?.brickRoadStatus,
reportAttributes?.actionBadge,
reportAttributes?.actionTargetReportActionID,
reportAttributes?.reportName,
areReportErrorsEqual,
oneTransactionThreadReport,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/OptionsListUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
getReportSubtitlePrefix,
getReportTransactions,
getUnreportedTransactionMessage,
getViolatingReportIDForRBRInLHN,
hasIOUWaitingOnCurrentUserBankAccount,
isArchivedNonExpenseReport,
isChatThread,
Expand All @@ -151,7 +152,6 @@
isPolicyExpenseChat as reportUtilsIsPolicyExpenseChat,
isSelfDM as reportUtilsIsSelfDM,
isTaskReport as reportUtilsIsTaskReport,
shouldDisplayViolationsRBRInLHN,
shouldReportBeInOptionList,
} from '@libs/ReportUtils';
import StringUtils from '@libs/StringUtils';
Expand Down Expand Up @@ -208,7 +208,7 @@
*/

let allReports: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 211 in src/libs/OptionsListUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function

Check warning on line 211 in src/libs/OptionsListUtils/index.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -220,7 +220,7 @@
const allSortedReportActions: Record<string, ReportAction[]> = {};
const cachedOneTransactionThreadReportIDs: Record<string, string | undefined> = {};
let allReportActions: OnyxCollection<ReportActions>;
Onyx.connect({

Check warning on line 223 in src/libs/OptionsListUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function

Check warning on line 223 in src/libs/OptionsListUtils/index.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
waitForCollectionCallback: true,
callback: (actions) => {
Expand Down Expand Up @@ -265,7 +265,7 @@
});

let activePolicyID: OnyxEntry<string>;
Onyx.connect({

Check warning on line 268 in src/libs/OptionsListUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function

Check warning on line 268 in src/libs/OptionsListUtils/index.ts

View workflow job for this annotation

GitHub Actions / ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.NVP_ACTIVE_POLICY_ID,
callback: (value) => (activePolicyID = value),
});
Expand Down Expand Up @@ -2106,7 +2106,7 @@
isTimeRequest = false,
} = config;
const topmostReportId = Navigation.getTopmostReportId();
const doesReportHaveViolations = shouldDisplayViolationsRBRInLHN(option.item, transactionViolations);
const doesReportHaveViolations = !!getViolatingReportIDForRBRInLHN(option.item, transactionViolations);

const shouldBeInOptionList = shouldReportBeInOptionList({
report: option.item,
Expand Down
108 changes: 58 additions & 50 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@
allReportErrors?: Errors;
brickRoadIndicator?: ValueOf<typeof CONST.BRICK_ROAD_INDICATOR_STATUS> | '' | null;
actionBadge?: ValueOf<typeof CONST.REPORT.ACTION_BADGE>;
actionTargetReportActionID?: string;
tooltipText?: string | null;
alternateTextMaxLines?: number;
boldStyle?: boolean;
Expand Down Expand Up @@ -1049,7 +1050,7 @@
};

let conciergeReportIDOnyxConnect: OnyxEntry<string>;
Onyx.connect({

Check warning on line 1053 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.CONCIERGE_REPORT_ID,
callback: (value) => {
conciergeReportIDOnyxConnect = value;
Expand All @@ -1057,7 +1058,7 @@
});

const defaultAvatarBuildingIconTestID = 'SvgDefaultAvatarBuilding Icon';
Onyx.connect({

Check warning on line 1061 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
// When signed out, val is undefined
Expand All @@ -1075,7 +1076,7 @@
let allPersonalDetails: OnyxEntry<PersonalDetailsList>;
let allPersonalDetailLogins: string[];
let currentUserPersonalDetails: OnyxEntry<PersonalDetails>;
Onyx.connect({

Check warning on line 1079 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
if (currentUserAccountID) {
Expand All @@ -1087,7 +1088,7 @@
});

let allReportsDraft: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 1091 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_DRAFT,
waitForCollectionCallback: true,
callback: (value) => (allReportsDraft = value),
Expand All @@ -1095,7 +1096,7 @@

let allPolicies: OnyxCollection<Policy>;
let policiesArray: Policy[] = [];
Onyx.connect({

Check warning on line 1099 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -1105,7 +1106,7 @@
});

let allPolicyDrafts: OnyxCollection<Policy>;
Onyx.connect({

Check warning on line 1109 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY_DRAFTS,
waitForCollectionCallback: true,
callback: (value) => (allPolicyDrafts = value),
Expand All @@ -1113,7 +1114,7 @@

let allReports: OnyxCollection<Report>;
let reportsByPolicyID: ReportByPolicyMap;
Onyx.connect({

Check warning on line 1117 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand Down Expand Up @@ -9091,67 +9092,51 @@
}

/**
* Should we display a RBR on the LHN on this report due to violations?
* Returns the reportID of the first child expense report that has violations under the same policy,
* or undefined if none found. Used to find the REPORT_PREVIEW action to deep-link to.
*/
function shouldDisplayViolationsRBRInLHN(report: OnyxEntry<Report>, transactionViolations: OnyxCollection<TransactionViolation[]>): boolean {
function getViolatingReportIDForRBRInLHN(report: OnyxEntry<Report>, transactionViolations: OnyxCollection<TransactionViolation[]>): string | null {
// We only show the RBR in the highest level, which is the expense chat
if (!report || !isPolicyExpenseChat(report)) {
return false;
return null;
}

// We only show the RBR to the submitter
if (!isCurrentUserSubmitter(report)) {
return false;
return null;
}
if (!report.policyID || !reportsByPolicyID) {
return false;
return null;
}

// If any report has a violation, then it should have a RBR
const potentialReports = Object.values(reportsByPolicyID[report.policyID] ?? {}) ?? [];
return potentialReports.some((potentialReport) => {
if (!potentialReport) {
return false;
}
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${potentialReport.policyID}`];
const transactions = getReportTransactions(potentialReport.reportID);
const violatingReport = potentialReports
// eslint-disable-next-line rulesdir/prefer-locale-compare-from-context
.sort((a, b) => (a?.created ?? '').localeCompare(b?.created ?? ''))
.find((potentialReport) => {
if (!potentialReport) {
return false;
}
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${potentialReport.policyID}`];
const transactions = getReportTransactions(potentialReport.reportID);

// Allow both open and processing reports to show RBR for violations
if (!isOpenOrProcessingReport(potentialReport)) {
return false;
}
// Allow both open and processing reports to show RBR for violations
if (!isOpenOrProcessingReport(potentialReport)) {
return false;
}
Comment on lines +9121 to +9127
Copy link
Contributor

Choose a reason for hiding this comment

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

we dont neeed to access it so early

Suggested change
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${potentialReport.policyID}`];
const transactions = getReportTransactions(potentialReport.reportID);
// Allow both open and processing reports to show RBR for violations
if (!isOpenOrProcessingReport(potentialReport)) {
return false;
}
// Allow both open and processing reports to show RBR for violations
if (!isOpenOrProcessingReport(potentialReport)) {
return false;
}
// Allow both open and processing reports to show RBR for violations
if (!isOpenOrProcessingReport(potentialReport)) {
return false;
}
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${potentialReport.policyID}`];
const transactions = getReportTransactions(potentialReport.reportID);


return (
!isInvoiceReport(potentialReport) &&
ViolationsUtils.hasVisibleViolationsForUser(
potentialReport,
transactionViolations,
currentUserEmail ?? '',
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
policy,
transactions,
) &&
(hasViolations(
potentialReport.reportID,
transactionViolations,
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
currentUserEmail ?? '',
true,
transactions,
potentialReport,
policy,
) ||
hasWarningTypeViolations(
potentialReport.reportID,
return (
!isInvoiceReport(potentialReport) &&
ViolationsUtils.hasVisibleViolationsForUser(
potentialReport,
transactionViolations,
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
currentUserEmail ?? '',
true,
transactions,
potentialReport,
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
policy,
) ||
hasNoticeTypeViolations(
transactions,
) &&
(hasViolations(
potentialReport.reportID,
transactionViolations,
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
Expand All @@ -9160,9 +9145,30 @@
transactions,
potentialReport,
policy,
))
);
});
) ||
hasWarningTypeViolations(
potentialReport.reportID,
transactionViolations,
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
currentUserEmail ?? '',
true,
transactions,
potentialReport,
policy,
) ||
hasNoticeTypeViolations(
potentialReport.reportID,
transactionViolations,
currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID,
currentUserEmail ?? '',
true,
transactions,
potentialReport,
policy,
))
);
});
return violatingReport ? violatingReport.reportID : null;
}

/**
Expand Down Expand Up @@ -9393,7 +9399,7 @@
let doesTransactionThreadReportHasViolations = false;
if (oneTransactionThreadReportID) {
const transactionReport = getReport(oneTransactionThreadReportID, allReports);
doesTransactionThreadReportHasViolations = !!transactionReport && shouldDisplayViolationsRBRInLHN(transactionReport, transactionViolations);
doesTransactionThreadReportHasViolations = !!transactionReport && !!getViolatingReportIDForRBRInLHN(transactionReport, transactionViolations);
}
return (
doesTransactionThreadReportHasViolations ||
Expand Down Expand Up @@ -12741,16 +12747,17 @@
transactionViolations: OnyxCollection<TransactionViolation[]>;
isReportArchived: boolean;
actionBadge?: ValueOf<typeof CONST.REPORT.ACTION_BADGE>;
actionTargetReportActionID?: string;
}) {
const reportActionsList = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`];
const parentReportActionsList = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`];
const hasViolationsToDisplayInLHN = shouldDisplayViolationsRBRInLHN(report, transactionViolations);
const hasViolationsToDisplayInLHN = !!getViolatingReportIDForRBRInLHN(report, transactionViolations);
const hasAnyTypeOfViolations = hasViolationsToDisplayInLHN;
const reportErrors = getAllReportErrors(report, reportActionsList, isReportArchived);
const hasErrors = Object.entries(reportErrors ?? {}).length > 0;
const oneTransactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActionsList);
const parentReportAction = report?.parentReportActionID ? parentReportActionsList?.[report.parentReportActionID] : undefined;
const {reason, actionBadge} = getReasonAndReportActionThatRequiresAttention(report, parentReportAction, isReportArchived) ?? {};
const {reason, actionBadge, reportAction} = getReasonAndReportActionThatRequiresAttention(report, parentReportAction, isReportArchived) ?? {};

return {
hasViolationsToDisplayInLHN,
Expand All @@ -12761,6 +12768,7 @@
parentReportAction,
requiresAttention: !!reason,
actionBadge,
actionTargetReportActionID: reportAction?.reportActionID,
};
}

Expand Down Expand Up @@ -13273,6 +13281,7 @@
getDisplayedReportID,
getTransactionsWithReceipts,
getUserDetailTooltipText,
getViolatingReportIDForRBRInLHN,
getWhisperDisplayNames,
getWorkspaceChats,
getWorkspaceIcon,
Expand Down Expand Up @@ -13413,7 +13422,6 @@
shouldDisableRename,
shouldDisableThread,
shouldDisplayThreadReplies,
shouldDisplayViolationsRBRInLHN,
shouldReportBeInOptionList,
shouldReportShowSubscript,
shouldShowFlagComment,
Expand Down
33 changes: 12 additions & 21 deletions src/libs/SidebarUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
getIntegrationSyncFailedMessage,
getInvoiceCompanyNameUpdateMessage,
getInvoiceCompanyWebsiteUpdateMessage,
getIOUReportIDFromReportActionPreview,
getLastVisibleMessage,
getMessageOfOldDotReportAction,
getOriginalMessage,
Expand Down Expand Up @@ -151,6 +152,7 @@ import {
getReportParticipantsTitle,
getReportSubtitlePrefix,
getUnreportedTransactionMessage,
getViolatingReportIDForRBRInLHN,
getWorkspaceNameUpdatedMessage,
hasReportErrorsOtherThanFailedReceipt,
isAdminRoom,
Expand Down Expand Up @@ -182,7 +184,6 @@ import {
isUnread,
isUnreadWithMention,
isWorkspaceTaskReport,
shouldDisplayViolationsRBRInLHN,
shouldReportBeInOptionList,
shouldReportShowSubscript,
} from './ReportUtils';
Expand Down Expand Up @@ -246,7 +247,7 @@ function shouldDisplayReportInLHN(

// Get report metadata and status
const parentReportAction = getReportAction(report?.parentReportID, report?.parentReportActionID);
const doesReportHaveViolations = shouldDisplayViolationsRBRInLHN(report, transactionViolations);
const doesReportHaveViolations = !!getViolatingReportIDForRBRInLHN(report, transactionViolations);
const isHidden = isHiddenForCurrentUser(report);
const isFocused = report.reportID === currentReportId;
const chatReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.chatReportID}`];
Expand Down Expand Up @@ -627,20 +628,23 @@ function getReasonAndReportActionThatHasRedBrickRoad(
transactionViolations?: OnyxCollection<TransactionViolation[]>,
isReportArchived = false,
): ReasonAndReportActionThatHasRedBrickRoad | null {
const {reportAction} = getAllReportActionsErrorsAndReportActionThatRequiresAttention(report, reportActions, isReportArchived);
const errors = reportErrors;
const hasErrors = Object.keys(errors).length !== 0;

if (isReportArchived) {
return null;
}

if (shouldDisplayViolationsRBRInLHN(report, transactionViolations)) {
const violatingReportID = getViolatingReportIDForRBRInLHN(report, transactionViolations);
if (violatingReportID) {
const reportPreviewAction = Object.values(reportActions ?? {}).find((action) => getIOUReportIDFromReportActionPreview(action) === violatingReportID);
return {
reason: CONST.RBR_REASONS.HAS_TRANSACTION_THREAD_VIOLATIONS,
reportAction: reportPreviewAction,
};
}

const {reportAction} = getAllReportActionsErrorsAndReportActionThatRequiresAttention(report, reportActions, isReportArchived);
Copy link
Contributor

Choose a reason for hiding this comment

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

for Follow up: Since we do not care about the errors here, can you use different method that only gets the report action?

const errors = reportErrors;
const hasErrors = Object.keys(errors).length !== 0;

if (hasErrors) {
return {
reason: CONST.RBR_REASONS.HAS_ERRORS,
Expand All @@ -657,19 +661,6 @@ function getReasonAndReportActionThatHasRedBrickRoad(
return getReceiptUploadErrorReason(report, chatReport, reportActions, transactions);
}

function shouldShowRedBrickRoad(
report: Report,
chatReport: OnyxEntry<Report>,
reportActions: OnyxEntry<ReportActions>,
hasViolations: boolean,
reportErrors: Errors,
transactions: OnyxCollection<Transaction>,
transactionViolations?: OnyxCollection<TransactionViolation[]>,
isReportArchived = false,
) {
return !!getReasonAndReportActionThatHasRedBrickRoad(report, chatReport, reportActions, hasViolations, reportErrors, transactions, transactionViolations, isReportArchived);
}

/**
* Gets all the data necessary for rendering an OptionRowLHN component
*/
Expand Down Expand Up @@ -792,6 +783,7 @@ function getOptionData({
result.pendingAction = report.pendingFields?.addWorkspaceRoom ?? report.pendingFields?.createChat;
result.brickRoadIndicator = reportAttributes?.brickRoadStatus;
result.actionBadge = reportAttributes?.actionBadge;
result.actionTargetReportActionID = reportAttributes?.actionTargetReportActionID;
result.ownerAccountID = report.ownerAccountID;
result.managerID = report.managerID;
result.reportID = report.reportID;
Expand Down Expand Up @@ -1360,7 +1352,6 @@ export default {
combineReportCategories,
getWelcomeMessage,
getReasonAndReportActionThatHasRedBrickRoad,
shouldShowRedBrickRoad,
getReportsToDisplayInLHN,
updateReportsToDisplayInLHN,
shouldDisplayReportInLHN,
Expand Down
Loading
Loading