Skip to content

Commit

Permalink
Merge pull request Expensify#54247 from callstack-internal/chore/migr…
Browse files Browse the repository at this point in the history
…ate-pendingChatMembers

migrate pendingChatMembers to reportMetadata
  • Loading branch information
puneetlath authored Dec 24, 2024
2 parents 5c750c5 + be6c47b commit ad99c20
Show file tree
Hide file tree
Showing 17 changed files with 441 additions and 187 deletions.
7 changes: 0 additions & 7 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,12 +529,6 @@ function validateReportDraftProperty(key: keyof Report, value: string) {
},
'number',
);
case 'pendingChatMembers':
return validateArray<ArrayElement<Report, 'pendingChatMembers'>>(value, {
accountID: 'string',
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION,
errors: 'object',
});
case 'fieldList':
return validateObject<ObjectElement<Report, 'fieldList'>>(
value,
Expand Down Expand Up @@ -616,7 +610,6 @@ function validateReportDraftProperty(key: keyof Report, value: string) {
iouReportID: CONST.RED_BRICK_ROAD_PENDING_ACTION,
preexistingReportID: CONST.RED_BRICK_ROAD_PENDING_ACTION,
nonReimbursableTotal: CONST.RED_BRICK_ROAD_PENDING_ACTION,
pendingChatMembers: CONST.RED_BRICK_ROAD_PENDING_ACTION,
fieldList: CONST.RED_BRICK_ROAD_PENDING_ACTION,
permissions: CONST.RED_BRICK_ROAD_PENDING_ACTION,
tripData: CONST.RED_BRICK_ROAD_PENDING_ACTION,
Expand Down
12 changes: 11 additions & 1 deletion src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,13 @@ const isPolicyUser = (policy: OnyxInputOrEntry<Policy>, currentUserLogin?: strin
const isPolicyAuditor = (policy: OnyxInputOrEntry<Policy>, currentUserLogin?: string): boolean =>
(policy?.role ?? (currentUserLogin && policy?.employeeList?.[currentUserLogin]?.role)) === CONST.POLICY.ROLE.AUDITOR;

const isPolicyEmployee = (policyID: string, policies: OnyxCollection<Policy>): boolean => Object.values(policies ?? {}).some((policy) => policy?.id === policyID);
const isPolicyEmployee = (policyID: string | undefined, policies: OnyxCollection<Policy>): boolean => {
if (!policyID) {
return false;
}

return Object.values(policies ?? {}).some((policy) => policy?.id === policyID);
};

/**
* Checks if the current user is an owner (creator) of the policy.
Expand Down Expand Up @@ -1112,6 +1118,10 @@ function hasVBBA(policyID: string) {
}

function getTagApproverRule(policyOrID: string | SearchPolicy | OnyxEntry<Policy>, tagName: string) {
if (!policyOrID) {
return;
}

const policy = typeof policyOrID === 'string' ? getPolicy(policyOrID) : policyOrID;

const approvalRules = policy?.rules?.approvalRules ?? [];
Expand Down
12 changes: 10 additions & 2 deletions src/libs/ReportActionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,11 @@ function getLinkedTransactionID(reportActionOrID: string | OnyxEntry<ReportActio
return getOriginalMessage(reportAction)?.IOUTransactionID ?? null;
}

function getReportAction(reportID: string, reportActionID: string): ReportAction | undefined {
function getReportAction(reportID: string | undefined, reportActionID: string | undefined): ReportAction | undefined {
if (!reportID || !reportActionID) {
return undefined;
}

return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]?.[reportActionID];
}

Expand Down Expand Up @@ -1599,7 +1603,11 @@ function getIOUActionForReportID(reportID: string, transactionID: string): OnyxE
/**
* Get the track expense actionable whisper of the corresponding track expense
*/
function getTrackExpenseActionableWhisper(transactionID: string, chatReportID: string) {
function getTrackExpenseActionableWhisper(transactionID: string | undefined, chatReportID: string | undefined) {
if (!transactionID || !chatReportID) {
return undefined;
}

const chatReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`] ?? {};
return Object.values(chatReportActions).find((action: ReportAction) => isActionableTrackExpense(action) && getOriginalMessage(action)?.transactionID === transactionID);
}
Expand Down
48 changes: 40 additions & 8 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ import type {ErrorFields, Errors, Icon, PendingAction} from '@src/types/onyx/Ony
import type {OriginalMessageChangeLog, PaymentMethodType} from '@src/types/onyx/OriginalMessage';
import type {Status} from '@src/types/onyx/PersonalDetails';
import type {ConnectionName} from '@src/types/onyx/Policy';
import type {NotificationPreference, Participants, PendingChatMember, Participant as ReportParticipant} from '@src/types/onyx/Report';
import type {NotificationPreference, Participants, Participant as ReportParticipant} from '@src/types/onyx/Report';
import type {Message, OldDotReportAction, ReportActions} from '@src/types/onyx/ReportAction';
import type {PendingChatMember} from '@src/types/onyx/ReportMetadata';
import type {SearchPolicy, SearchReport, SearchTransaction} from '@src/types/onyx/SearchResults';
import type {Comment, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
Expand Down Expand Up @@ -384,6 +385,7 @@ type OptimisticWorkspaceChats = {
expenseChatData: OptimisticChatReport;
expenseReportActionData: Record<string, OptimisticCreatedReportAction>;
expenseCreatedReportActionID: string;
pendingChatMembers: PendingChatMember[];
};

type OptimisticModifiedExpenseReportAction = Pick<
Expand Down Expand Up @@ -701,6 +703,7 @@ Onyx.connect({
});

let allReportMetadata: OnyxCollection<ReportMetadata>;
const allReportMetadataKeyValue: Record<string, ReportMetadata> = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT_METADATA,
waitForCollectionCallback: true,
Expand All @@ -709,6 +712,15 @@ Onyx.connect({
return;
}
allReportMetadata = value;

Object.entries(value).forEach(([reportID, reportMetadata]) => {
if (!reportMetadata) {
return;
}

const [, id] = reportID.split('_');
allReportMetadataKeyValue[id] = reportMetadata;
});
},
});

Expand Down Expand Up @@ -1759,7 +1771,11 @@ function isPayAtEndExpenseReport(reportID: string, transactions: Transaction[] |
/**
* Checks if a report is a transaction thread associated with a report that has only one transaction
*/
function isOneTransactionThread(reportID: string, parentReportID: string, threadParentReportAction: OnyxEntry<ReportAction>): boolean {
function isOneTransactionThread(reportID: string | undefined, parentReportID: string | undefined, threadParentReportAction: OnyxEntry<ReportAction>): boolean {
if (!reportID || !parentReportID) {
return false;
}

const parentReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`] ?? ([] as ReportAction[]);
const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(parentReportID, parentReportActions);
return reportID === transactionThreadReportID && !ReportActionsUtils.isSentMoneyReportAction(threadParentReportAction);
Expand Down Expand Up @@ -2213,6 +2229,7 @@ function getDisplayNameForParticipant(

function getParticipantsAccountIDsForDisplay(report: OnyxEntry<Report>, shouldExcludeHidden = false, shouldExcludeDeleted = false, shouldForceExcludeCurrentUser = false): number[] {
const reportParticipants = report?.participants ?? {};
const reportMetadata = getReportMetadata(report?.reportID);
let participantsEntries = Object.entries(reportParticipants);

// We should not show participants that have an optimistic entry with the same login in the personal details
Expand Down Expand Up @@ -2252,7 +2269,7 @@ function getParticipantsAccountIDsForDisplay(report: OnyxEntry<Report>, shouldEx

if (
shouldExcludeDeleted &&
report?.pendingChatMembers?.findLast((member) => Number(member.accountID) === accountID)?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE
reportMetadata?.pendingChatMembers?.findLast((member) => Number(member.accountID) === accountID)?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE
) {
return false;
}
Expand Down Expand Up @@ -2313,8 +2330,10 @@ function getGroupChatName(participants?: SelectedParticipant[], shouldApplyLimit
return report.reportName;
}

const reportMetadata = getReportMetadata(report?.reportID);

const pendingMemberAccountIDs = new Set(
report?.pendingChatMembers?.filter((member) => member.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE).map((member) => member.accountID),
reportMetadata?.pendingChatMembers?.filter((member) => member.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE).map((member) => member.accountID),
);
let participantAccountIDs =
participants?.map((participant) => participant.accountID) ??
Expand Down Expand Up @@ -3017,7 +3036,11 @@ function getTitleReportField(reportFields: Record<string, PolicyReportField>) {
/**
* Get the key for a report field
*/
function getReportFieldKey(reportFieldId: string) {
function getReportFieldKey(reportFieldId: string | undefined) {
if (!reportFieldId) {
return '';
}

// We don't need to add `expensify_` prefix to the title field key, because backend stored title under a unique key `text_title`,
// and all the other report field keys are stored under `expensify_FIELD_ID`.
if (reportFieldId === CONST.REPORT_FIELD_TITLE_FIELD_ID) {
Expand Down Expand Up @@ -6071,7 +6094,6 @@ function buildOptimisticWorkspaceChats(policyID: string, policyName: string, exp
false,
policyName,
),
pendingChatMembers,
};
const adminsChatReportID = adminsChatData.reportID;
const adminsCreatedAction = buildOptimisticCreatedReportAction(CONST.POLICY.OWNER_EMAIL_FAKE);
Expand Down Expand Up @@ -6111,6 +6133,7 @@ function buildOptimisticWorkspaceChats(policyID: string, policyName: string, exp
expenseChatData,
expenseReportActionData,
expenseCreatedReportActionID: expenseReportCreatedAction.reportActionID,
pendingChatMembers,
};
}

Expand Down Expand Up @@ -8225,7 +8248,16 @@ function createDraftWorkspaceAndNavigateToConfirmationScreen(transactionID: stri
}
}

function createDraftTransactionAndNavigateToParticipantSelector(transactionID: string, reportID: string, actionName: IOUAction, reportActionID: string): void {
function createDraftTransactionAndNavigateToParticipantSelector(
transactionID: string | undefined,
reportID: string | undefined,
actionName: IOUAction,
reportActionID: string | undefined,
): void {
if (!transactionID || !reportID || !reportActionID) {
return;
}

const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction);
const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? ([] as ReportAction[]);

Expand Down Expand Up @@ -8538,7 +8570,7 @@ function hasInvoiceReports() {
}

function getReportMetadata(reportID?: string) {
return allReportMetadata?.[`${ONYXKEYS.COLLECTION.REPORT_METADATA}${reportID}`];
return allReportMetadataKeyValue[reportID ?? '-1'];
}

export {
Expand Down
29 changes: 25 additions & 4 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5748,7 +5748,11 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT
* @param isSingleTransactionView - whether we are in the transaction thread report
* @returns The URL to navigate to
*/
function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): Route | undefined {
function getNavigationUrlOnMoneyRequestDelete(transactionID: string | undefined, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): Route | undefined {
if (!transactionID) {
return undefined;
}

const {shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport} = prepareToCleanUpMoneyRequest(transactionID, reportAction);

// Determine which report to navigate back to
Expand All @@ -5771,7 +5775,16 @@ function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportActio
* @param isSingleTransactionView - Whether we're in single transaction view
* @returns The URL to navigate to
*/
function getNavigationUrlAfterTrackExpenseDelete(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): Route | undefined {
function getNavigationUrlAfterTrackExpenseDelete(
chatReportID: string | undefined,
transactionID: string | undefined,
reportAction: OnyxTypes.ReportAction,
isSingleTransactionView = false,
): Route | undefined {
if (!chatReportID || !transactionID) {
return undefined;
}

const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null;

// If not a self DM, handle it as a regular money request
Expand Down Expand Up @@ -5946,7 +5959,11 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo
* @param isSingleTransactionView - whether we are in the transaction thread report
* @return the url to navigate back once the money request is deleted
*/
function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) {
function deleteMoneyRequest(transactionID: string | undefined, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) {
if (!transactionID) {
return;
}

// STEP 1: Calculate and prepare the data
const {
shouldDeleteTransactionThread,
Expand Down Expand Up @@ -6207,7 +6224,11 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor
return urlToNavigateBack;
}

function deleteTrackExpense(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) {
function deleteTrackExpense(chatReportID: string | undefined, transactionID: string | undefined, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) {
if (!chatReportID || !transactionID) {
return;
}

const urlToNavigateBack = getNavigationUrlAfterTrackExpenseDelete(chatReportID, transactionID, reportAction, isSingleTransactionView);

// STEP 1: Get all collections we're updating
Expand Down
Loading

0 comments on commit ad99c20

Please sign in to comment.