Skip to content

Commit

Permalink
Merge pull request #49172 from Expensify/georgia-fixIOUpreview
Browse files Browse the repository at this point in the history
[ReportPreview / Avatars] Fix avatar styles and headline for Ecards, invoices, and group expense reports
  • Loading branch information
grgia authored Sep 26, 2024
2 parents bc106fa + b704277 commit b215aa8
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 86 deletions.
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const CONST = {
},

// Note: Group and Self-DM excluded as these are not tied to a Workspace
WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT],
WORKSPACE_ROOM_TYPES: [chatTypes.POLICY_ADMINS, chatTypes.POLICY_ANNOUNCE, chatTypes.DOMAIN_ALL, chatTypes.POLICY_ROOM, chatTypes.POLICY_EXPENSE_CHAT, chatTypes.INVOICE],
ANDROID_PACKAGE_NAME,
WORKSPACE_ENABLE_FEATURE_REDIRECT_DELAY: 100,
ANIMATED_HIGHLIGHT_ENTRY_DELAY: 50,
Expand Down
47 changes: 39 additions & 8 deletions src/libs/ReportActionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -994,20 +994,20 @@ const iouRequestTypes = new Set<ValueOf<typeof CONST.IOU.REPORT_ACTION_TYPE>>([
CONST.IOU.REPORT_ACTION_TYPE.TRACK,
]);

/**
* Gets the reportID for the transaction thread associated with a report by iterating over the reportActions and identifying the IOU report actions.
* Returns a reportID if there is exactly one transaction thread for the report, and null otherwise.
*/
function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEntry<ReportActions> | ReportAction[], isOffline: boolean | undefined = undefined): string | undefined {
// If the report is not an IOU, Expense report, or Invoice, it shouldn't be treated as one-transaction report.
function getMoneyRequestActions(
reportID: string,
reportActions: OnyxEntry<ReportActions> | ReportAction[],
isOffline: boolean | undefined = undefined,
): Array<ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU>> {
// If the report is not an IOU, Expense report, or Invoice, it shouldn't have money request actions.
const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
if (report?.type !== CONST.REPORT.TYPE.IOU && report?.type !== CONST.REPORT.TYPE.EXPENSE && report?.type !== CONST.REPORT.TYPE.INVOICE) {
return;
return [];
}

const reportActionsArray = Array.isArray(reportActions) ? reportActions : Object.values(reportActions ?? {});
if (!reportActionsArray.length) {
return;
return [];
}

const iouRequestActions = [];
Expand Down Expand Up @@ -1035,6 +1035,15 @@ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEn
iouRequestActions.push(action);
}
}
return iouRequestActions;
}

/**
* Gets the reportID for the transaction thread associated with a report by iterating over the reportActions and identifying the IOU report actions.
* Returns a reportID if there is exactly one transaction thread for the report, and null otherwise.
*/
function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEntry<ReportActions> | ReportAction[], isOffline: boolean | undefined = undefined): string | undefined {
const iouRequestActions = getMoneyRequestActions(reportID, reportActions, isOffline);

// If we don't have any IOU request actions, or we have more than one IOU request actions, this isn't a oneTransaction report
if (!iouRequestActions.length || iouRequestActions.length > 1) {
Expand All @@ -1054,6 +1063,27 @@ function getOneTransactionThreadReportID(reportID: string, reportActions: OnyxEn
return singleAction.childReportID;
}

/**
* Returns true if all transactions on the report have the same ownerID
*/
function hasSameActorForAllTransactions(reportID: string, reportActions: OnyxEntry<ReportActions> | ReportAction[], isOffline: boolean | undefined = undefined): boolean {
const iouRequestActions = getMoneyRequestActions(reportID, reportActions, isOffline);
if (!iouRequestActions.length) {
return true;
}

let actorID: number | undefined;

for (const action of iouRequestActions) {
if (actorID !== undefined && actorID !== action?.actorAccountID) {
return false;
}
actorID = action?.actorAccountID;
}

return true;
}

/**
* 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
Expand Down Expand Up @@ -1834,6 +1864,7 @@ export {
getRenamedAction,
isCardIssuedAction,
getCardIssuedMessage,
hasSameActorForAllTransactions,
};

export type {LastVisibleMessage};
27 changes: 18 additions & 9 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1580,12 +1580,20 @@ function hasOnlyNonReimbursableTransactions(iouReportID: string | undefined): bo
return transactions.every((transaction) => !TransactionUtils.getReimbursable(transaction));
}

/**
* Checks if a report has only transactions with same ownerID
*/
function isSingleActorMoneyReport(reportID: string): boolean {
const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? ([] as ReportAction[]);
return !!ReportActionsUtils.hasSameActorForAllTransactions(reportID, reportActions);
}

/**
* Checks if a report has only one transaction associated with it
*/
function isOneTransactionReport(reportID: string): boolean {
const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? ([] as ReportAction[]);
return ReportActionsUtils.getOneTransactionThreadReportID(reportID, reportActions) !== null;
return !!ReportActionsUtils.getOneTransactionThreadReportID(reportID, reportActions);
}

/*
Expand Down Expand Up @@ -2217,7 +2225,7 @@ function getIcons(
if (isChatThread(report)) {
const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID];

const actorAccountID = getReportActionActorAccountID(parentReportAction, report);
const actorAccountID = getReportActionActorAccountID(parentReportAction);
const actorDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(allPersonalDetails?.[actorAccountID ?? -1], '', false);
const actorIcon = {
id: actorAccountID,
Expand Down Expand Up @@ -2312,7 +2320,7 @@ function getIcons(
const isManager = currentUserAccountID === report?.managerID;

// For one transaction IOUs, display a simplified report icon
if (isOneTransactionReport(report?.reportID ?? '-1')) {
if (isOneTransactionReport(report?.reportID ?? '-1') || isSingleActorMoneyReport(report?.reportID ?? '-1')) {
return [ownerIcon];
}

Expand Down Expand Up @@ -4826,9 +4834,9 @@ function buildOptimisticReportPreview(
},
],
created,
accountID: iouReport?.managerID ?? -1,
accountID: iouReport?.ownerAccountID ?? -1,
// The preview is initially whispered if created with a receipt, so the actor is the current user as well
actorAccountID: hasReceipt ? currentUserAccountID : iouReport?.managerID ?? -1,
actorAccountID: hasReceipt ? currentUserAccountID : iouReport?.ownerAccountID ?? -1,
childReportID: childReportID ?? iouReport?.reportID,
childMoneyRequestCount: 1,
childLastMoneyRequestComment: comment,
Expand Down Expand Up @@ -6649,7 +6657,7 @@ function shouldReportShowSubscript(report: OnyxEntry<Report>): boolean {
return true;
}

if (isExpenseReport(report) && isOneTransactionReport(report?.reportID ?? '-1')) {
if (isExpenseReport(report)) {
return true;
}

Expand All @@ -6661,7 +6669,7 @@ function shouldReportShowSubscript(report: OnyxEntry<Report>): boolean {
return true;
}

if (isInvoiceRoom(report)) {
if (isInvoiceRoom(report) || isInvoiceReport(report)) {
return true;
}

Expand Down Expand Up @@ -7543,10 +7551,10 @@ function canLeaveChat(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>): boo
return (isChatThread(report) && !!getReportNotificationPreference(report)) || isUserCreatedPolicyRoom(report) || isNonAdminOrOwnerOfPolicyExpenseChat(report, policy);
}

function getReportActionActorAccountID(reportAction: OnyxInputOrEntry<ReportAction>, iouReport: OnyxInputOrEntry<Report> | undefined): number | undefined {
function getReportActionActorAccountID(reportAction: OnyxInputOrEntry<ReportAction>): number | undefined {
switch (reportAction?.actionName) {
case CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW:
return !isEmptyObject(iouReport) ? iouReport.managerID : reportAction?.childManagerAccountID;
return reportAction?.childOwnerAccountID ?? reportAction?.actorAccountID;

case CONST.REPORT.ACTIONS.TYPE.SUBMITTED:
return reportAction?.adminAccountID ?? reportAction?.actorAccountID;
Expand Down Expand Up @@ -8127,6 +8135,7 @@ export {
isIndividualInvoiceRoom,
isAuditor,
hasMissingInvoiceBankAccount,
isSingleActorMoneyReport,
};

export type {
Expand Down
Loading

0 comments on commit b215aa8

Please sign in to comment.