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
31 changes: 0 additions & 31 deletions src/pages/home/HeaderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import Button from '@components/Button';
import CaretWrapper from '@components/CaretWrapper';
import ConfirmModal from '@components/ConfirmModal';
import DisplayNames from '@components/DisplayNames';
import Icon from '@components/Icon';
// eslint-disable-next-line no-restricted-imports
Expand All @@ -22,9 +21,6 @@ import SidePanelButton from '@components/SidePanel/SidePanelButton';
import TaskHeaderActionButton from '@components/TaskHeaderActionButton';
import Text from '@components/Text';
import Tooltip from '@components/Tooltip';
import useAncestors from '@hooks/useAncestors';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useHasOutstandingChildTask from '@hooks/useHasOutstandingChildTask';
import useHasTeam2025Pricing from '@hooks/useHasTeam2025Pricing';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLoadingBarVisibility from '@hooks/useLoadingBarVisibility';
Expand Down Expand Up @@ -76,7 +72,6 @@ import EarlyDiscountBanner from '@pages/settings/Subscription/CardSection/Billin
import FreeTrial from '@pages/settings/Subscription/FreeTrial';
import {joinRoom} from '@userActions/Report';
import {callFunctionIfActionIsAllowed} from '@userActions/Session';
import {deleteTask} from '@userActions/Task';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import SCREENS from '@src/SCREENS';
Expand Down Expand Up @@ -108,7 +103,6 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth} = useResponsiveLayout();
const route = useRoute();
const [isDeleteTaskConfirmModalVisible, setIsDeleteTaskConfirmModalVisible] = React.useState(false);
const invoiceReceiverPolicyID = report?.invoiceReceiver && 'policyID' in report.invoiceReceiver ? report.invoiceReceiver.policyID : undefined;
const [invoiceReceiverPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${invoiceReceiverPolicyID}`, {canBeMissing: true});
const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(report?.parentReportID) ?? getNonEmptyStringOnyxID(report?.reportID)}`, {canBeMissing: true});
Expand All @@ -121,11 +115,9 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
const [firstDayFreeTrial] = useOnyx(ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL, {canBeMissing: true});
const [lastDayFreeTrial] = useOnyx(ONYXKEYS.NVP_LAST_DAY_FREE_TRIAL, {canBeMissing: true});
const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true});
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`, {canBeMissing: true});
const [reportMetadata] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}${report?.reportID}`, {canBeMissing: true});
const isReportArchived = isArchivedReport(reportNameValuePairs);
const hasOutstandingChildTask = useHasOutstandingChildTask(report);

const {translate, localeCompare, formatPhoneNumber} = useLocalize();
const theme = useTheme();
Expand Down Expand Up @@ -163,7 +155,6 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
// This is used to ensure that we display the text exactly as the user entered it when displaying thread header text, instead of parsing their text to HTML.
const shouldParseFullTitle = parentReportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT && !isGroupChat;
const subscriptionPlan = useSubscriptionPlan();
const ancestors = useAncestors(report);

const shouldShowSubtitle = () => {
if (!subtitle) {
Expand Down Expand Up @@ -382,28 +373,6 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
{!isInSidePanel && <SidePanelButton style={styles.ml2} />}
{shouldDisplaySearchRouter && <SearchButton />}
</View>
<ConfirmModal
isVisible={isDeleteTaskConfirmModalVisible}
onConfirm={() => {
setIsDeleteTaskConfirmModalVisible(false);
deleteTask(
report,
parentReport,
isReportArchived,
currentUserPersonalDetails.accountID,
hasOutstandingChildTask,
parentReportAction ?? undefined,
ancestors,
);
}}
onCancel={() => setIsDeleteTaskConfirmModalVisible(false)}
title={translate('task.deleteTask')}
prompt={translate('task.deleteConfirmation')}
confirmText={translate('common.delete')}
cancelText={translate('common.cancel')}
danger
shouldEnableNewFocusManagement
/>
</View>
)}
</View>
Expand Down
133 changes: 63 additions & 70 deletions src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import type {EmitterSubscription, GestureResponderEvent, NativeTouchEvent, View}
import {DeviceEventEmitter, Dimensions, InteractionManager} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {Actions, ActionSheetAwareScrollViewContext} from '@components/ActionSheetAwareScrollView';
import ConfirmModal from '@components/ConfirmModal';
import {ModalActions} from '@components/Modal/Global/ModalContext';
import PopoverWithMeasuredContent from '@components/PopoverWithMeasuredContent';
import {useSearchContext} from '@components/Search/SearchContext';
import useAncestors from '@hooks/useAncestors';
import useConfirmModal from '@hooks/useConfirmModal';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useDeleteTransactions from '@hooks/useDeleteTransactions';
import useDuplicateTransactionsAndViolations from '@hooks/useDuplicateTransactionsAndViolations';
Expand Down Expand Up @@ -49,6 +50,7 @@ type PopoverReportActionContextMenuProps = {

function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuProps) {
const {translate} = useLocalize();
const {showConfirmModal} = useConfirmModal();
const reportIDRef = useRef<string | undefined>(undefined);
const typeRef = useRef<ContextMenuType | undefined>(undefined);
const reportActionRef = useRef<NonNullable<OnyxEntry<ReportAction>> | null>(null);
Expand All @@ -75,8 +77,6 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
const {email} = useCurrentUserPersonalDetails();

const [isPopoverVisible, setIsPopoverVisible] = useState(false);
const [isDeleteCommentConfirmModalVisible, setIsDeleteCommentConfirmModalVisible] = useState(false);
const [shouldSetModalVisibilityForDeleteConfirmation, setShouldSetModalVisibilityForDeleteConfirmation] = useState(true);

const [isRoomArchived, setIsRoomArchived] = useState(false);
const [isChronosReportEnabled, setIsChronosReportEnabled] = useState(false);
Expand Down Expand Up @@ -104,7 +104,6 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
const onPopoverHide = useRef(() => {});
const onEmojiPickerToggle = useRef<undefined | ((state: boolean) => void)>(undefined);
const onCancelDeleteModal = useRef(() => {});
const onConfirmDeleteModal = useRef(() => {});

const onPopoverHideActionCallback = useRef(() => {});
const callbackWhenDeleteModalHide = useRef(() => {});
Expand Down Expand Up @@ -343,8 +342,7 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
}
ancestorsRef.current = ancestors;
}, [originalReport, ancestors]);
const confirmDeleteAndHideModal = useCallback(() => {
callbackWhenDeleteModalHide.current = runAndResetCallback(onConfirmDeleteModal.current);
const performDelete = useCallback(() => {
const reportAction = reportActionRef.current;
if (isMoneyRequestAction(reportAction)) {
const originalMessage = getOriginalMessage(reportAction);
Expand Down Expand Up @@ -375,7 +373,6 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
}

DeviceEventEmitter.emit(`deletedReportAction_${reportIDRef.current}`, reportAction?.reportActionID);
setIsDeleteCommentConfirmModalVisible(false);
}, [
report,
iouReport,
Expand All @@ -392,27 +389,42 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
violations,
]);

const hideDeleteModal = () => {
const hideDeleteModal = useCallback(() => {
callbackWhenDeleteModalHide.current = () => (onCancelDeleteModal.current = runAndResetCallback(onCancelDeleteModal.current));
setIsDeleteCommentConfirmModalVisible(false);
setShouldSetModalVisibilityForDeleteConfirmation(true);
setIsRoomArchived(false);
setIsChronosReportEnabled(false);
setIsChatPinned(false);
setHasUnreadMessages(false);
};
}, []);

/** Opens the Confirm delete action modal */
const showDeleteModal: ReportActionContextMenu['showDeleteModal'] = (reportID, reportAction, shouldSetModalVisibility = true, onConfirm = () => {}, onCancel = () => {}) => {
onCancelDeleteModal.current = onCancel;
const showDeleteModal: ReportActionContextMenu['showDeleteModal'] = useCallback(
async (reportID, reportAction, shouldSetModalVisibility = true, onConfirm = () => {}, onCancel = () => {}) => {
reportIDRef.current = reportID;
reportActionRef.current = reportAction ?? null;

const result = await showConfirmModal({
title: translate('reportActionContextMenu.deleteAction', {action: reportAction}),
prompt: translate('reportActionContextMenu.deleteConfirmation', {action: reportAction}),
confirmText: translate('common.delete'),
cancelText: translate('common.cancel'),
danger: true,
shouldSetModalVisibility,
});

onConfirmDeleteModal.current = onConfirm;
reportIDRef.current = reportID;
reportActionRef.current = reportAction ?? null;
if (result.action === ModalActions.CONFIRM) {
onConfirm();
performDelete();
} else {
onCancel();
}

setShouldSetModalVisibilityForDeleteConfirmation(shouldSetModalVisibility);
setIsDeleteCommentConfirmModalVisible(true);
};
// Clear refs and run callbacks AFTER the action is performed
clearActiveReportAction();
callbackWhenDeleteModalHide.current();
},
[showConfirmModal, translate, performDelete],
);

useImperativeHandle(ref, () => ({
showContextMenu,
Expand All @@ -428,60 +440,41 @@ function PopoverReportActionContextMenu({ref}: PopoverReportActionContextMenuPro
composerToRefocusOnCloseEmojiPicker: composerToRefocusOnClose,
}));

const reportAction = reportActionRef.current;

return (
<>
<PopoverWithMeasuredContent
<PopoverWithMeasuredContent
isVisible={isPopoverVisible}
onClose={() => hideContextMenu()}
onModalShow={runAndResetOnPopoverShow}
onModalHide={runAndResetOnPopoverHide}
anchorPosition={popoverAnchorPosition.current}
animationIn="fadeIn"
disableAnimation={false}
shouldSetModalVisibility={false}
fullscreen
withoutOverlay={isWithoutOverlay}
anchorDimensions={contextMenuDimensions.current}
anchorRef={anchorRef}
shouldSwitchPositionIfOverflow={shouldSwitchPositionIfOverflow}
>
<BaseReportActionContextMenu
isVisible={isPopoverVisible}
onClose={() => hideContextMenu()}
onModalShow={runAndResetOnPopoverShow}
onModalHide={runAndResetOnPopoverHide}
anchorPosition={popoverAnchorPosition.current}
animationIn="fadeIn"
disableAnimation={false}
shouldSetModalVisibility={false}
fullscreen
withoutOverlay={isWithoutOverlay}
anchorDimensions={contextMenuDimensions.current}
anchorRef={anchorRef}
shouldSwitchPositionIfOverflow={shouldSwitchPositionIfOverflow}
>
<BaseReportActionContextMenu
isVisible={isPopoverVisible}
type={typeRef.current}
reportID={reportIDRef.current}
reportActionID={reportActionIDRef.current}
draftMessage={reportActionDraftMessageRef.current}
selection={selectionRef.current}
isArchivedRoom={isRoomArchived}
isChronosReport={isChronosReportEnabled}
isPinnedChat={isChatPinned}
isUnreadChat={hasUnreadMessages}
isThreadReportParentAction={isThreadReportParentAction}
anchor={contextMenuTargetNode}
contentRef={contentRef}
originalReportID={originalReportIDRef.current}
disabledActions={disabledActions}
setIsEmojiPickerActive={onEmojiPickerToggle.current}
/>
</PopoverWithMeasuredContent>
<ConfirmModal
title={translate('reportActionContextMenu.deleteAction', {action: reportAction})}
isVisible={isDeleteCommentConfirmModalVisible}
shouldSetModalVisibility={shouldSetModalVisibilityForDeleteConfirmation}
onConfirm={confirmDeleteAndHideModal}
onCancel={hideDeleteModal}
onModalHide={() => {
clearActiveReportAction();
callbackWhenDeleteModalHide.current();
}}
prompt={translate('reportActionContextMenu.deleteConfirmation', {action: reportAction})}
confirmText={translate('common.delete')}
cancelText={translate('common.cancel')}
danger
type={typeRef.current}
reportID={reportIDRef.current}
reportActionID={reportActionIDRef.current}
draftMessage={reportActionDraftMessageRef.current}
selection={selectionRef.current}
isArchivedRoom={isRoomArchived}
isChronosReport={isChronosReportEnabled}
isPinnedChat={isChatPinned}
isUnreadChat={hasUnreadMessages}
isThreadReportParentAction={isThreadReportParentAction}
anchor={contextMenuTargetNode}
contentRef={contentRef}
originalReportID={originalReportIDRef.current}
disabledActions={disabledActions}
setIsEmojiPickerActive={onEmojiPickerToggle.current}
/>
</>
</PopoverWithMeasuredContent>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type HideContextMenu = (params?: HideContextMenuParams) => void;
type ReportActionContextMenu = {
showContextMenu: ShowContextMenu;
hideContextMenu: HideContextMenu;
showDeleteModal: (reportID: string, reportAction: OnyxEntry<ReportAction>, shouldSetModalVisibility?: boolean, onConfirm?: OnConfirm, onCancel?: OnCancel) => void;
showDeleteModal: (reportID: string, reportAction: OnyxEntry<ReportAction>, shouldSetModalVisibility?: boolean, onConfirm?: OnConfirm, onCancel?: OnCancel) => Promise<void>;
hideDeleteModal: () => void;
isActiveReportAction: (accountID: string | number) => boolean;
instanceIDRef: RefObject<string>;
Expand Down
Loading
Loading