Skip to content
Open
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
3 changes: 1 addition & 2 deletions src/libs/OptionsListUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ import {
isArchivedNonExpenseReport,
isChatThread,
isDM,
isDraftReport,
isExpenseReport,
isHiddenForCurrentUser,
isInvoiceRoom,
Expand Down Expand Up @@ -1267,7 +1266,7 @@ function getReportOption(
}
}
}
option.isDisabled = !!reportDraft || isDraftReport(participant.reportID);
option.isDisabled = !!reportDraft;
Comment thread
daledah marked this conversation as resolved.
option.isSelected = participant.selected;
option.selected = participant.selected; // Keep for backwards compatibility
option.brickRoadIndicator = null;
Expand Down
6 changes: 4 additions & 2 deletions src/pages/Share/SubmitDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import type {ShareNavigatorParamList} from '@libs/Navigation/types';
import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils';
import {hasOnlyPersonalPolicies as hasOnlyPersonalPoliciesUtil, isPaidGroupPolicy} from '@libs/PolicyUtils';
import {shouldValidateFile} from '@libs/ReceiptUtils';
import {isSelfDM} from '@libs/ReportUtils';
import {isMoneyRequestReport, isSelfDM} from '@libs/ReportUtils';
import {getDefaultTaxCode, getTaxValue} from '@libs/TransactionUtils';
import DraftWorkspaceOpener from '@pages/iou/request/step/confirmation/DraftWorkspaceOpener';
import CONST from '@src/CONST';
Expand All @@ -68,6 +68,8 @@ function SubmitDetailsPage({
const [unknownUserDetails] = useOnyx(ONYXKEYS.SHARE_UNKNOWN_USER_DETAILS);
const [personalDetails] = useOnyx(`${ONYXKEYS.PERSONAL_DETAILS_LIST}`);
const report: OnyxEntry<ReportType> = useReportOrReportDraft(reportOrAccountID);
const reportIDToCheck = isMoneyRequestReport(report) ? report?.chatReportID : report?.reportID;
const [reportDraft] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportIDToCheck}`);
const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`);
const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${CONST.IOU.OPTIMISTIC_TRANSACTION_ID}`);
const transactionReport = useReportOrReportDraft(transaction?.reportID);
Expand Down Expand Up @@ -175,7 +177,7 @@ function SubmitDetailsPage({
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${participant.reportID}`];
return participant?.accountID
? getParticipantsOption(participant, personalDetails)
: getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived);
: getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, reportDraft);
});

const isPolicyExpenseChat = useMemo(() => participants?.some((participant) => participant.isPolicyExpenseChat), [participants]);
Expand Down
4 changes: 3 additions & 1 deletion src/pages/iou/request/step/IOURequestStepAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ function IOURequestStepAmount({
const [ownerBillingGracePeriodEnd] = useOnyx(ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END);
const isEditing = action === CONST.IOU.ACTION.EDIT;
const {duplicateTransactions, duplicateTransactionViolations} = useDuplicateTransactionsAndViolations(isEditing && transactionID ? [transactionID] : []);
const reportIDToCheck = isMoneyRequestReport(report) ? report?.chatReportID : report?.reportID;
const [reportDraft] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportIDToCheck}`);
const reportAttributesDerived = useReportAttributes();
const privateIsArchivedMap = usePrivateIsArchivedMap();
const isSplitBill = iouType === CONST.IOU.TYPE.SPLIT;
Expand Down Expand Up @@ -246,7 +248,7 @@ function IOURequestStepAmount({
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${participant.reportID}`];
return participantAccountID
? getParticipantsOption(participant, personalDetails)
: getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived);
: getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, reportDraft);
});
const backendAmount = convertToBackendAmount(Number.parseFloat(amount));

Expand Down
8 changes: 4 additions & 4 deletions src/pages/iou/request/step/IOURequestStepConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ function IOURequestStepConfirmation({
() => resolveReportForMoneyRequest({transaction, transactionReport, routeReport: reportWithDraftFallback, policy: policyReal}),
[transaction, transactionReport, reportWithDraftFallback, policyReal],
);
const [reportDrafts] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT);

const {policy} = usePolicyForTransaction({
transaction: initialTransaction,
Expand Down Expand Up @@ -261,13 +262,12 @@ function IOURequestStepConfirmation({
return participant;
}
const privateIsArchived = privateIsArchivedMap[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${participant.reportID}`];
const participantReportDraft = reportDrafts?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${participant.reportID}`];
return participant.accountID
? getParticipantsOption(participant, personalDetails)
: getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived);
: getReportOption(participant, privateIsArchived, policy, personalDetails, conciergeReportID, reportAttributesDerived, participantReportDraft);
}) ?? [],
// getReportOrDraftReport (called inside getReportOption) falls back to its module-level allReportsDraft
// connection, so we don't need to subscribe to COLLECTION.REPORT_DRAFT here.
[transaction?.participants, iouType, personalDetails, reportAttributesDerived, privateIsArchivedMap, policy, conciergeReportID],
[transaction?.participants, iouType, personalDetails, reportAttributesDerived, privateIsArchivedMap, policy, conciergeReportID, reportDrafts],
);

const defaultParticipants = useMemo(() => {
Expand Down
55 changes: 55 additions & 0 deletions tests/unit/OptionsListUtilsTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6082,6 +6082,61 @@ describe('OptionsListUtils', () => {

expect(option.isDisabled).toBe(true);
});

it('should not disable option when reportDraft is undefined for a regular report', async () => {
const reportID = '200';
const report: Report = {
reportID,
reportName: 'Regular Report',
type: CONST.REPORT.TYPE.CHAT,
};

await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, report);
await waitForBatchedUpdates();

const participant: Participant = {reportID, selected: false};

// Pass reportDraft = undefined → not a draft, should NOT be disabled
const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined);

expect(option.isDisabled).toBeFalsy();
});

it('should disable option when reportDraft is explicitly passed', async () => {
const reportID = '201';
const draftReport: Report = {
reportID,
reportName: 'Explicit Draft Report',
type: CONST.REPORT.TYPE.CHAT,
};

const participant: Participant = {reportID, selected: false};

// Pass reportDraft explicitly → should be disabled regardless of Onyx state
const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, draftReport);

expect(option.isDisabled).toBe(true);
});

it('should not disable option when reportDraft param is undefined even if report exists in REPORT_DRAFT', async () => {
const reportID = '202';
const draftReport: Report = {
reportID,
reportName: 'Global Draft Report',
type: CONST.REPORT.TYPE.CHAT,
};

// Draft exists in Onyx but is NOT passed as param
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`, draftReport);
await waitForBatchedUpdates();

const participant: Participant = {reportID, selected: false};

// Callers are responsible for passing reportDraft explicitly — undefined means not disabled
const option = getReportOption(participant, undefined, POLICY, {}, undefined, undefined, undefined);

expect(option.isDisabled).toBeFalsy();
});
});

describe('getReportDisplayOption', () => {
Expand Down
Loading