Skip to content

Commit

Permalink
Merge pull request #41818 from Expensify/revert-40979-move-leave-butt…
Browse files Browse the repository at this point in the history
…on-into-row-of-the-report-details-page

[CP Staging] Revert "Move Leave button into a row of the Report Details page"

(cherry picked from commit 6b4d3ae)
  • Loading branch information
marcaaron authored and OSBotify committed May 7, 2024
1 parent d03f0fa commit b709e1f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 72 deletions.
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2055,6 +2055,7 @@ const CONST = {
INFO: 'info',
},
REPORT_DETAILS_MENU_ITEM: {
SHARE_CODE: 'shareCode',
MEMBERS: 'member',
INVITE: 'invite',
SETTINGS: 'settings',
Expand Down
40 changes: 29 additions & 11 deletions src/components/ChatDetailsQuickActionsBar.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from 'react';
import React, {useState} from 'react';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import * as Report from '@userActions/Report';
import ROUTES from '@src/ROUTES';
import type {Report as OnyxReportType} from '@src/types/onyx';
import Button from './Button';
import ConfirmModal from './ConfirmModal';
import * as Expensicons from './Icon/Expensicons';

type ChatDetailsQuickActionsBarProps = {
Expand All @@ -15,26 +14,45 @@ type ChatDetailsQuickActionsBarProps = {

function ChatDetailsQuickActionsBar({report}: ChatDetailsQuickActionsBarProps) {
const styles = useThemeStyles();
const [isLastMemberLeavingGroupModalVisible, setIsLastMemberLeavingGroupModalVisible] = useState(false);
const {translate} = useLocalize();
const isPinned = !!report.isPinned;
return (
<View style={[styles.flexRow, styles.ph5, styles.mb5]}>
<View style={[styles.flex1, styles.pr3]}>
<ConfirmModal
danger
title={translate('groupChat.lastMemberTitle')}
isVisible={isLastMemberLeavingGroupModalVisible}
onConfirm={() => {
setIsLastMemberLeavingGroupModalVisible(false);
Report.leaveGroupChat(report.reportID);
}}
onCancel={() => setIsLastMemberLeavingGroupModalVisible(false)}
prompt={translate('groupChat.lastMemberWarning')}
confirmText={translate('common.leave')}
cancelText={translate('common.cancel')}
/>
<Button
onPress={() => Report.togglePinnedState(report.reportID, isPinned)}
icon={Expensicons.Pin}
onPress={() => {
if (Object.keys(report?.participants ?? {}).length === 1) {
setIsLastMemberLeavingGroupModalVisible(true);
return;
}

Report.leaveGroupChat(report.reportID);
}}
icon={Expensicons.Exit}
style={styles.flex1}
text={isPinned ? translate('common.unPin') : translate('common.pin')}
text={translate('common.leave')}
/>
</View>
<View style={[styles.flex1]}>
<Button
onPress={() => {
Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS_SHARE_CODE.getRoute(report?.reportID ?? ''));
}}
icon={Expensicons.QrCode}
onPress={() => Report.togglePinnedState(report.reportID, isPinned)}
icon={Expensicons.Pin}
style={styles.flex1}
text={translate('common.share')}
text={isPinned ? translate('common.unPin') : translate('common.pin')}
/>
</View>
</View>
Expand Down
2 changes: 1 addition & 1 deletion src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const isPolicyEmployee = (policyID: string, policies: OnyxCollection<Policy>): b
/**
* Checks if the current user is an owner (creator) of the policy.
*/
const isPolicyOwner = (policy: OnyxEntry<Policy> | EmptyObject, currentUserAccountID: number): boolean => policy?.ownerAccountID === currentUserAccountID;
const isPolicyOwner = (policy: OnyxEntry<Policy>, currentUserAccountID: number): boolean => policy?.ownerAccountID === currentUserAccountID;

/**
* Create an object mapping member emails to their accountIDs. Filter for members without errors, and get the login email from the personalDetail object using the accountID.
Expand Down
2 changes: 1 addition & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6393,7 +6393,7 @@ function hasActionsWithErrors(reportID: string): boolean {
return Object.values(reportActions).some((action) => !isEmptyObject(action.errors));
}

function canLeavePolicyExpenseChat(report: OnyxEntry<Report>, policy: OnyxEntry<Policy> | EmptyObject): boolean {
function canLeavePolicyExpenseChat(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>): boolean {
return isPolicyExpenseChat(report) && !(PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPolicyOwner(policy, currentUserAccountID ?? -1) || isReportOwner(report));
}

Expand Down
76 changes: 17 additions & 59 deletions src/pages/ReportDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useRoute} from '@react-navigation/native';
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import React, {useEffect, useMemo} from 'react';
import {View} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
Expand Down Expand Up @@ -29,7 +29,6 @@ import * as OptionsListUtils from '@libs/OptionsListUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as Report from '@userActions/Report';
import ConfirmModal from '@src/components/ConfirmModal';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
Expand All @@ -50,7 +49,6 @@ type ReportDetailsPageMenuItem = {
action: () => void;
brickRoadIndicator?: ValueOf<typeof CONST.BRICK_ROAD_INDICATOR_STATUS>;
subtitle?: number;
shouldShowRightIcon?: boolean;
};

type ReportDetailsPageOnyxProps = {
Expand All @@ -67,12 +65,10 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
const {isOffline} = useNetwork();
const styles = useThemeStyles();
const route = useRoute();
const [isLastMemberLeavingGroupModalVisible, setIsLastMemberLeavingGroupModalVisible] = useState(false);
const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? ''}`], [policies, report?.policyID]);
const isPolicyAdmin = useMemo(() => PolicyUtils.isPolicyAdmin(policy ?? null), [policy]);
const isPolicyEmployee = useMemo(() => PolicyUtils.isPolicyEmployee(report?.policyID ?? '', policies), [report?.policyID, policies]);
const shouldUseFullTitle = useMemo(() => ReportUtils.shouldUseFullTitleToDisplay(report), [report]);
const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report);
const isChatRoom = useMemo(() => ReportUtils.isChatRoom(report), [report]);
const isUserCreatedPolicyRoom = useMemo(() => ReportUtils.isUserCreatedPolicyRoom(report), [report]);
const isDefaultRoom = useMemo(() => ReportUtils.isDefaultRoom(report), [report]);
Expand All @@ -83,8 +79,6 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
const isInvoiceReport = useMemo(() => ReportUtils.isInvoiceReport(report), [report]);
const canEditReportDescription = useMemo(() => ReportUtils.canEditReportDescription(report, policy), [report, policy]);
const shouldShowReportDescription = isChatRoom && (canEditReportDescription || report.description !== '');
const canLeaveRoom = ReportUtils.canLeaveRoom(report, isPolicyEmployee);
const canLeavePolicyExpenseChat = ReportUtils.canLeavePolicyExpenseChat(report, policy ?? {});

// eslint-disable-next-line react-hooks/exhaustive-deps -- policy is a dependency because `getChatRoomSubtitle` calls `getPolicyName` which in turn retrieves the value from the `policy` value stored in Onyx
const chatRoomSubtitle = useMemo(() => ReportUtils.getChatRoomSubtitle(report), [report, policy]);
Expand All @@ -105,11 +99,10 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
return !pendingMember || pendingMember.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ? accountID : [];
});

const isGroupDMChat = useMemo(() => ReportUtils.isDM(report) && participants.length > 1, [report, participants.length]);
const isPrivateNotesFetchTriggered = report?.isLoadingPrivateNotes !== undefined;

const isSelfDM = useMemo(() => ReportUtils.isSelfDM(report), [report]);
const canLeave =
!isSelfDM && (isChatThread || isUserCreatedPolicyRoom || canLeaveRoom || canLeavePolicyExpenseChat) && report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;

useEffect(() => {
// Do not fetch private notes if isLoadingPrivateNotes is already defined, or if the network is offline, or if the report is a self DM.
Expand All @@ -120,22 +113,23 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
Report.getReportPrivateNote(report?.reportID ?? '');
}, [report?.reportID, isOffline, isPrivateNotesFetchTriggered, isSelfDM]);

const leaveChat = useCallback(() => {
if (isChatRoom) {
const isWorkspaceMemberLeavingWorkspaceRoom = (report.visibility === CONST.REPORT.VISIBILITY.RESTRICTED || isPolicyExpenseChat) && isPolicyEmployee;
Report.leaveRoom(report.reportID, isWorkspaceMemberLeavingWorkspaceRoom);
return;
}
Report.leaveGroupChat(report.reportID);
}, [isChatRoom, isPolicyEmployee, isPolicyExpenseChat, report.reportID, report.visibility]);

const menuItems: ReportDetailsPageMenuItem[] = useMemo(() => {
const items: ReportDetailsPageMenuItem[] = [];

if (isSelfDM) {
return [];
}

if (!isGroupDMChat) {
items.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.SHARE_CODE,
translationKey: 'common.shareCode',
icon: Expensicons.QrCode,
isAnonymousAction: true,
action: () => Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS_SHARE_CODE.getRoute(report?.reportID ?? '')),
});
}

if (isArchivedRoom) {
return items;
}
Expand Down Expand Up @@ -202,27 +196,10 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
});
}

if (isGroupChat || (isChatRoom && canLeave)) {
items.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM,
translationKey: 'common.leave',
icon: Expensicons.Exit,
isAnonymousAction: true,
shouldShowRightIcon: false,
action: () => {
if (Object.keys(report?.participants ?? {}).length === 1 && isGroupChat) {
setIsLastMemberLeavingGroupModalVisible(true);
return;
}

leaveChat();
},
});
}

return items;
}, [
isSelfDM,
isGroupDMChat,
isArchivedRoom,
isGroupChat,
isDefaultRoom,
Expand All @@ -232,12 +209,9 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
participants.length,
report,
isMoneyRequestReport,
isChatRoom,
canLeave,
isInvoiceReport,
activeChatMembers.length,
session,
leaveChat,
isInvoiceReport,
]);

const displayNamesWithTooltips = useMemo(() => {
Expand Down Expand Up @@ -346,10 +320,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
</View>
</View>
{shouldShowReportDescription && (
<OfflineWithFeedback
pendingAction={report.pendingFields?.description}
style={styles.mb5}
>
<OfflineWithFeedback pendingAction={report.pendingFields?.description}>
<MenuItemWithTopDescription
shouldShowRightIcon={canEditReportDescription}
interactive={canEditReportDescription}
Expand All @@ -361,7 +332,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
/>
</OfflineWithFeedback>
)}
{(isGroupChat || isChatRoom) && <ChatDetailsQuickActionsBar report={report} />}
{isGroupChat && <ChatDetailsQuickActionsBar report={report} />}
{menuItems.map((item) => {
const brickRoadIndicator =
ReportUtils.hasReportNameError(report) && item.key === CONST.REPORT_DETAILS_MENU_ITEM.SETTINGS ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined;
Expand All @@ -373,25 +344,12 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
icon={item.icon}
onPress={item.action}
isAnonymousAction={item.isAnonymousAction}
shouldShowRightIcon={item.shouldShowRightIcon ?? true}
shouldShowRightIcon
brickRoadIndicator={brickRoadIndicator ?? item.brickRoadIndicator}
/>
);
})}
</ScrollView>
<ConfirmModal
danger
title={translate('groupChat.lastMemberTitle')}
isVisible={isLastMemberLeavingGroupModalVisible}
onConfirm={() => {
setIsLastMemberLeavingGroupModalVisible(false);
Report.leaveGroupChat(report.reportID);
}}
onCancel={() => setIsLastMemberLeavingGroupModalVisible(false)}
prompt={translate('groupChat.lastMemberWarning')}
confirmText={translate('common.leave')}
cancelText={translate('common.cancel')}
/>
</FullPageNotFoundView>
</ScreenWrapper>
);
Expand Down

0 comments on commit b709e1f

Please sign in to comment.