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
3 changes: 3 additions & 0 deletions src/components/ReportActionItem/MoneyRequestReceiptView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ function MoneyRequestReceiptView({

const [isLoading, setIsLoading] = useState(true);
const parentReportAction = report?.parentReportActionID ? parentReportActions?.[report.parentReportActionID] : undefined;
const [parentReportActionChildReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(parentReportAction?.childReportID)}`);

const originalReportID = useOriginalReportID(report?.reportID, parentReportAction);
const {iouReport, chatReport: chatIOUReport, isChatIOUReportArchived} = useGetIOUReportFromReportAction(parentReportAction);
const isTrackExpense = !mergeTransactionID && isTrackExpenseReportNew(report, parentReport, parentReportAction);
Expand Down Expand Up @@ -429,6 +431,7 @@ function MoneyRequestReceiptView({
transaction?.transactionID ?? linkedTransactionID,
parentReportAction,
report.reportID,
parentReportActionChildReport,
iouReport,
chatIOUReport,
isChatIOUReportArchived,
Expand Down
2 changes: 2 additions & 0 deletions src/components/Search/SearchList/ListItem/ChatListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function ChatListItem<TItem extends ListItem>({
}: ChatListItemProps<TItem>) {
const reportActionItem = item as unknown as ReportActionListItemType;
const [reportStable] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.reportID}`, {selector: getStableReportSelector});
const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.childReportID}`);
const personalDetails = usePersonalDetails();
const styles = useThemeStyles();
const theme = useTheme();
Expand Down Expand Up @@ -79,6 +80,7 @@ function ChatListItem<TItem extends ListItem>({
<ReportActionItem
action={reportActionItem}
report={reportStable}
transactionThreadReport={transactionThreadReport}
onPress={handlePress}
parentReportAction={undefined}
displayAsGroup={false}
Expand Down
4 changes: 1 addition & 3 deletions src/libs/actions/IOU/DeleteMoneyRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,13 @@ function cleanUpMoneyRequest(
transactionID: string,
reportAction: OnyxTypes.ReportAction,
reportID: string,
transactionThreadReport: OnyxEntry<OnyxTypes.Report>,
iouReport: OnyxEntry<OnyxTypes.Report>,
chatReport: OnyxEntry<OnyxTypes.Report>,
isChatIOUReportArchived: boolean | undefined,
originalReportID: string | undefined,
isSingleTransactionView = false,
) {
const allReports = getAllReports();
const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportAction.childReportID}`];

const {shouldDeleteTransactionThread, shouldDeleteIOUReport, updatedReportAction, updatedIOUReport, updatedReportPreviewAction, transactionThreadID, reportPreviewAction} =
prepareToCleanUpMoneyRequest(transactionID, reportAction, transactionThreadReport, iouReport, chatReport, isChatIOUReportArchived, false);

Expand Down
32 changes: 26 additions & 6 deletions src/pages/Debug/ReportAction/DebugReportActionCreatePage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useCallback, useState} from 'react';
import React, {useCallback, useMemo, useState} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import Button from '@components/Button';
Expand Down Expand Up @@ -28,6 +28,19 @@ import type {PersonalDetailsList, ReportAction, Session} from '@src/types/onyx';

type DebugReportActionCreatePageProps = PlatformStackScreenProps<DebugParamList, typeof SCREENS.DEBUG.REPORT_ACTION_CREATE>;

function isParsedReportAction(value: unknown): value is ReportAction {
return typeof value === 'object' && value !== null && 'reportActionID' in value;
}

function parseReportActionJSON(draftReportAction: string): ReportAction | null {
try {
const parsedReportAction: unknown = JSON.parse(draftReportAction.replaceAll('\n', ''));
return isParsedReportAction(parsedReportAction) ? parsedReportAction : null;
} catch {
return null;
}
}

const getInitialReportAction = (reportID: string, session: OnyxEntry<Session>, personalDetailsList: OnyxEntry<PersonalDetailsList>) =>
DebugUtils.stringifyJSON({
actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT,
Expand All @@ -50,15 +63,21 @@ function DebugReportActionCreatePage({
const [personalDetailsList] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);
const [draftReportAction, setDraftReportAction] = useState<string>(() => getInitialReportAction(reportID, session, personalDetailsList));

const reportAction = useMemo(() => parseReportActionJSON(draftReportAction), [draftReportAction]);

const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportAction?.childReportID}`);

const [error, setError] = useState<string>();

const createReportAction = useCallback(() => {
const parsedReportAction = JSON.parse(draftReportAction.replaceAll('\n', '')) as ReportAction;
if (!reportAction) {
return;
}
Debug.mergeDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {
[parsedReportAction.reportActionID]: parsedReportAction,
[reportAction.reportActionID]: reportAction,
});
Navigation.navigate(ROUTES.DEBUG_REPORT_TAB_ACTIONS.getRoute(reportID));
}, [draftReportAction, reportID]);
}, [reportAction, reportID]);

const editJSON = useCallback(
(updatedJSON: string) => {
Expand Down Expand Up @@ -105,9 +124,10 @@ function DebugReportActionCreatePage({
</View>
<View>
<Text style={[styles.textLabelSupporting, styles.mb2]}>{translate('debug.preview')}</Text>
{!error ? (
{!error && reportAction ? (
<ReportActionItem
action={JSON.parse(draftReportAction.replaceAll('\n', '')) as ReportAction}
action={reportAction}
transactionThreadReport={transactionThreadReport}
report={{reportID}}
parentReportAction={undefined}
displayAsGroup={false}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/Debug/ReportAction/DebugReportActionPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ type DebugReportActionPreviewProps = {
function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPreviewProps) {
const personalDetails = usePersonalDetails();
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportAction?.childReportID}`);

return (
<ScrollView>
<ReportActionItem
action={reportAction ?? ({} as ReportAction)}

@ikevin127 ikevin127 May 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Type Casting (FORBIDDEN) [existed before this PR]

action={reportAction ?? ({} as ReportAction)}
report={report ?? ({} as Report)}

An empty object cast to ReportAction is a type safety hole. If downstream logic expects fields on ReportAction (like childReportID), this would produce confusing runtime errors.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think this is fine. This is a debugging-related page not a user facing one.

transactionThreadReport={transactionThreadReport}
report={report ?? ({} as Report)}
parentReportAction={undefined}
displayAsGroup={false}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function DuplicateTransactionItem({transaction, onPreviewPressed}: DuplicateTran
const originalReportID = getOriginalReportID(reportStable?.reportID, action, reportActions);

const [draftMessage] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`);
const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${action?.childReportID}`);

const [linkedTransactionRouteError] = useOnyx(
`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(isMoneyRequestAction(action) ? getOriginalMessage(action)?.IOUTransactionID : undefined)}`,
Expand All @@ -61,6 +62,7 @@ function DuplicateTransactionItem({transaction, onPreviewPressed}: DuplicateTran
<ReportActionItem
action={action}
report={reportStable}
transactionThreadReport={transactionThreadReport}
parentReportAction={getReportAction(reportStable?.parentReportID, reportStable?.parentReportActionID)}
displayAsGroup={false}
shouldDisplayNewMarker={false}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/inbox/report/PureReportActionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ type PureReportActionItemProps = {
report: OnyxEntry<OnyxTypes.Report>;

/** The transaction thread report associated with the report for this action, if any */
transactionThreadReport?: OnyxEntry<OnyxTypes.Report>;
transactionThreadReport: OnyxEntry<OnyxTypes.Report>;
Comment thread
parasharrajat marked this conversation as resolved.

/** Report action belonging to the report's parent */
parentReportAction: OnyxEntry<OnyxTypes.ReportAction>;
Expand Down Expand Up @@ -234,7 +234,7 @@ function PureReportActionItem({
const dismissError = () => {
const transactionID = isMoneyRequestAction(action) ? getOriginalMessage(action)?.IOUTransactionID : undefined;
if (isSendingMoney && transactionID && reportID) {
cleanUpMoneyRequest(transactionID, action, reportID, report, chatReport, undefined, originalReportID, true);
cleanUpMoneyRequest(transactionID, action, reportID, transactionThreadReport, report, chatReport, undefined, originalReportID, true);
return;
}
if (action.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && isReportActionLinked) {
Expand Down
1 change: 1 addition & 0 deletions tests/ui/ClearReportActionErrorsUITest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ describe('ClearReportActionErrors UI', () => {
<PortalProvider>
<PureReportActionItem
report={report}
transactionThreadReport={undefined}
parentReportAction={undefined}
action={action}
displayAsGroup={false}
Expand Down
Loading
Loading