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
69 changes: 69 additions & 0 deletions src/pages/DynamicReportDetailsPage/ReportDetailsActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import useOnyx from '@hooks/useOnyx';
import useParentReportAction from '@hooks/useParentReportAction';

import {
isInvoiceReport as isInvoiceReportUtil,
isMoneyRequest as isMoneyRequestUtil,
isMoneyRequestReport as isMoneyRequestReportUtil,
isTrackExpenseReportNew as isTrackExpenseReportUtil,
} from '@libs/ReportUtils';

import ONYXKEYS from '@src/ONYXKEYS';

import React from 'react';

import type {ReportDetailsRequestData} from './types';

import getReportDetailsCaseID from './getReportDetailsCaseID';
import ReportDetailsRequestActions from './ReportDetailsRequestActions';
import ReportDetailsTaskDeleteAction from './ReportDetailsTaskDeleteAction';
import {CASES} from './types';

type ReportDetailsActionsProps = {
reportID: string;

/** Renders the menu rows. The request data is only passed for the money cases. */
renderMenu: (requestData?: ReportDetailsRequestData) => React.ReactNode;
Comment thread
sosek108 marked this conversation as resolved.

/** Confirms the delete, navigates away and then runs the passed delete */
showDeleteModal: (requestData: ReportDetailsRequestData | undefined, onDelete: () => void) => Promise<void>;

/** Deletes the expense described by the request data */
deleteTransaction: (requestData: ReportDetailsRequestData) => void;
};

/** Gates the money request subscriptions behind the caseID, so chats, rooms and tasks never mount them */
function ReportDetailsActions({reportID, renderMenu, showDeleteModal, deleteTransaction}: ReportDetailsActionsProps) {
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`);
const parentReportAction = useParentReportAction(report);
const caseID = getReportDetailsCaseID({
isMoneyRequestReport: isMoneyRequestReportUtil(report),
isInvoiceReport: isInvoiceReportUtil(report),
isMoneyRequest: isMoneyRequestUtil(report),
isTrackExpenseReport: isTrackExpenseReportUtil(report, parentReport, parentReportAction),
});

if (caseID === CASES.DEFAULT) {
return (
<>
{renderMenu()}
<ReportDetailsTaskDeleteAction
reportID={reportID}
showDeleteModal={showDeleteModal}
/>
</>
);
}

return (
<ReportDetailsRequestActions
reportID={reportID}
renderMenu={renderMenu}
showDeleteModal={showDeleteModal}
deleteTransaction={deleteTransaction}
/>
);
}

export default ReportDetailsActions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import MenuItemAction from '@components/MenuItem/presets/MenuItemAction';

import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';

import CONST from '@src/CONST';

import React from 'react';

import type {ReportDetailsRequestData} from './types';

import useReportDetailsRequestData from './useReportDetailsRequestData';

type ReportDetailsRequestActionsProps = {
reportID: string;

/** Renders the menu rows, including the track-expense rows built from the request data */
renderMenu: (requestData?: ReportDetailsRequestData) => React.ReactNode;

/** Confirms the delete, navigates away and then runs the passed delete */
showDeleteModal: (requestData: ReportDetailsRequestData | undefined, onDelete: () => void) => Promise<void>;

/** Deletes the expense described by the request data */
deleteTransaction: (requestData: ReportDetailsRequestData) => void;
};

/** Menu and Delete row of the money cases, the only place the request data subscriptions are mounted */
function ReportDetailsRequestActions({reportID, renderMenu, showDeleteModal, deleteTransaction}: ReportDetailsRequestActionsProps) {
const expensifyIcons = useMemoizedLazyExpensifyIcons(['ArrowSplit', 'Trashcan']);
const requestData = useReportDetailsRequestData(reportID);
const {shouldShowDeleteButton, shouldShowEditSplitOnDeleteAction, deleteMenuItemTitle} = requestData;

return (
<>
{renderMenu(requestData)}

{shouldShowDeleteButton && (
<MenuItemAction
key={CONST.REPORT_DETAILS_MENU_ITEM.DELETE}
icon={shouldShowEditSplitOnDeleteAction ? expensifyIcons.ArrowSplit : expensifyIcons.Trashcan}
title={deleteMenuItemTitle}
onPress={shouldShowEditSplitOnDeleteAction ? () => deleteTransaction(requestData) : () => showDeleteModal(requestData, () => deleteTransaction(requestData))}
/>
)}
</>
);
}

export default ReportDetailsRequestActions;
120 changes: 120 additions & 0 deletions src/pages/DynamicReportDetailsPage/ReportDetailsTaskDeleteAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import MenuItemAction from '@components/MenuItem/presets/MenuItemAction';

import useAncestors from '@hooks/useAncestors';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useHasOutstandingChildTask from '@hooks/useHasOutstandingChildTask';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useParentReportAction from '@hooks/useParentReportAction';
import useReportIsArchived from '@hooks/useReportIsArchived';

import Navigation from '@libs/Navigation/Navigation';
import {canWriteInReport, findLastAccessedReport, isCanceledTaskReport as isCanceledTaskReportUtil, isClosedReport, isTaskReport as isTaskReportUtil} from '@libs/ReportUtils';

import {canActionTask, canModifyTask} from '@userActions/Task';
import {deleteTask} from '@userActions/TaskDeletion';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type * as OnyxTypes from '@src/types/onyx';

import type {OnyxEntry} from 'react-native-onyx';

import {delegateEmailSelector} from '@selectors/Account';
import React from 'react';

import type {ReportDetailsRequestData} from './types';

type ReportDetailsTaskDeleteActionProps = {
reportID: string;

/** Confirms the delete, navigates away and then runs the passed delete */
showDeleteModal: (requestData: ReportDetailsRequestData | undefined, onDelete: () => void) => Promise<void>;
};

type ReportDetailsTaskDeleteActionContentProps = {
report: OnyxTypes.Report;
parentReport: OnyxEntry<OnyxTypes.Report>;
parentReportAction: OnyxEntry<OnyxTypes.ReportAction>;
currentUserAccountID: number;

/** Confirms the delete, navigates away and then runs the passed delete */
showDeleteModal: (requestData: ReportDetailsRequestData | undefined, onDelete: () => void) => Promise<void>;
};

function ReportDetailsTaskDeleteActionContent({report, parentReport, parentReportAction, currentUserAccountID, showDeleteModal}: ReportDetailsTaskDeleteActionContentProps) {
const {translate} = useLocalize();
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Trashcan']);
const taskDeleteBackTo = Navigation.getTopmostSearchReportRouteParams()?.backTo;
const hasOutstandingChildTask = useHasOutstandingChildTask(report);
const [guideAccountIDs] = useOnyx(ONYXKEYS.DERIVED.GUIDE_ACCOUNT_IDS);
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const [reportActionsForOriginalReportID] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`);
const [delegateEmail] = useOnyx(ONYXKEYS.ACCOUNT, {selector: delegateEmailSelector});
const isReportArchived = useReportIsArchived(report.reportID);
const ancestors = useAncestors(report);

const deleteTransaction = () => {
deleteTask(
report,
parentReport,
isReportArchived,
currentUserAccountID,
hasOutstandingChildTask,
parentReportAction,
conciergeReportID,
delegateEmail,
reportActionsForOriginalReportID,
{
ancestors,
shouldNavigateBack: !taskDeleteBackTo,
lastAccessedReportID: findLastAccessedReport(false, guideAccountIDs, false, report.reportID)?.reportID,
},
);
};

return (
<MenuItemAction
key={CONST.REPORT_DETAILS_MENU_ITEM.DELETE}
icon={expensifyIcons.Trashcan}
title={translate('common.delete')}
onPress={() => showDeleteModal(undefined, deleteTransaction)}
/>
);
}

/** The Delete row of a task, rendered for the default case where no money request data exists */
function ReportDetailsTaskDeleteAction({reportID, showDeleteModal}: ReportDetailsTaskDeleteActionProps) {
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`);
const parentReportAction = useParentReportAction(report);
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const currentUserAccountID = currentUserPersonalDetails?.accountID;
const isParentReportArchived = useReportIsArchived(parentReport?.reportID);

const shouldShowTaskDeleteButton =
isTaskReportUtil(report) &&
!isCanceledTaskReportUtil(report, parentReportAction) &&
canWriteInReport(report) &&
report?.stateNum !== CONST.REPORT.STATE_NUM.APPROVED &&
!isClosedReport(report) &&
canModifyTask(report, currentUserAccountID, isParentReportArchived) &&
canActionTask(report, parentReportAction, currentUserAccountID, parentReport, isParentReportArchived);

if (!report?.reportID || !shouldShowTaskDeleteButton) {
return null;
}

return (
<ReportDetailsTaskDeleteActionContent
report={report}
parentReport={parentReport}
parentReportAction={parentReportAction}
currentUserAccountID={currentUserAccountID}
showDeleteModal={showDeleteModal}
/>
);
}

export default ReportDetailsTaskDeleteAction;
Loading
Loading