Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-direct to Classic when creating expenses for non-migrated users #51804 #51979

Merged
merged 12 commits into from
Nov 11, 2024
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,10 @@ const translations = {
listOfChats: 'List of chats',
saveTheWorld: 'Save the world',
tooltip: 'Get started here!',
redirectToExpensifyClassicModal: {
title: 'Coming soon',
description: "We're fine-tuning a few more bits and pieces of New Expensify to accommodate your specific setup. In the meantime, head over to Expensify Classic.",
},
},
allSettingsScreen: {
subscription: 'Subscription',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,10 @@ const translations = {
listOfChats: 'lista de chats',
saveTheWorld: 'Salvar el mundo',
tooltip: '¡Comienza aquí!',
redirectToExpensifyClassicModal: {
title: 'Próximamente',
description: 'Estamos ajustando algunos detalles de New Expensify para adaptarla a tu configuración específica. Mientras tanto, dirígete a Expensify Classic.',
},
},
allSettingsScreen: {
subscription: 'Suscripcion',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {View} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import type {SvgProps} from 'react-native-svg';
import ConfirmModal from '@components/ConfirmModal';
import FloatingActionButton from '@components/FloatingActionButton';
import * as Expensicons from '@components/Icon/Expensicons';
import type {PopoverMenuItem} from '@components/PopoverMenu';
Expand Down Expand Up @@ -168,6 +169,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
const [hasSeenTrackTraining] = useOnyx(ONYXKEYS.NVP_HAS_SEEN_TRACK_TRAINING);

const [isCreateMenuActive, setIsCreateMenuActive] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const fabRef = useRef<HTMLDivElement>(null);
const {windowHeight} = useWindowDimensions();
const {shouldUseNarrowLayout} = useResponsiveLayout();
Expand All @@ -183,6 +185,18 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
const [hasSeenTour = false] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
selector: hasSeenTourSelector,
});
/**
* There are scenarios where users who have not yet had their group workspace-chats in NewDot (isPolicyExpenseChatEnabled). In those scenarios, things can get confusing if they try to submit/track expenses. To address this, we block them from Creating, Tracking, Submitting expenses from NewDot if they are:
* 1. on at least one group policy
* 2. none of the group policies they are a member of have isPolicyExpenseChatEnabled=true
*/
const shouldRedirectToExpensifyClassic = useMemo(() => {
const groupPolicies = Object.values(allPolicies ?? {}).filter((policy) => ReportUtils.isGroupPolicy(policy?.type ?? ''));
if (groupPolicies.length === 0) {
return false;
}
return !groupPolicies.some((policy) => !!policy?.isPolicyExpenseChatEnabled);
}, [allPolicies]);

const quickActionAvatars = useMemo(() => {
if (quickActionReport) {
Expand Down Expand Up @@ -358,15 +372,20 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
{
icon: getIconForAction(CONST.IOU.TYPE.CREATE),
text: translate('iou.createExpense'),
shouldCallAfterModalHide: shouldRedirectToExpensifyClassic,
onSelected: () =>
interceptAnonymousUser(() =>
interceptAnonymousUser(() => {
if (shouldRedirectToExpensifyClassic) {
setModalVisible(true);
return;
}
IOU.startMoneyRequest(
CONST.IOU.TYPE.CREATE,
// When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used
// for all of the routes in the creation flow.
ReportUtils.generateReportID(),
),
),
);
}),
},
];
}
Expand All @@ -377,16 +396,21 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
{
icon: getIconForAction(CONST.IOU.TYPE.TRACK),
text: translate('iou.trackExpense'),
shouldCallAfterModalHide: shouldRedirectToExpensifyClassic,
onSelected: () => {
interceptAnonymousUser(() =>
if (shouldRedirectToExpensifyClassic) {
setModalVisible(true);
return;
}
interceptAnonymousUser(() => {
IOU.startMoneyRequest(
CONST.IOU.TYPE.TRACK,
// When starting to create a track expense from the global FAB, we need to retrieve selfDM reportID.
// If it doesn't exist, we generate a random optimistic reportID and use it for all of the routes in the creation flow.
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
ReportUtils.findSelfDMReportID() || ReportUtils.generateReportID(),
),
);
);
});
if (!hasSeenTrackTraining && !isOffline) {
setTimeout(() => {
Navigation.navigate(ROUTES.TRACK_TRAINING_MODAL);
Expand All @@ -399,18 +423,24 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
{
icon: getIconForAction(CONST.IOU.TYPE.REQUEST),
text: translate('iou.submitExpense'),
shouldCallAfterModalHide: shouldRedirectToExpensifyClassic,
onSelected: () =>
interceptAnonymousUser(() =>
interceptAnonymousUser(() => {
if (shouldRedirectToExpensifyClassic) {
setModalVisible(true);
return;
}

IOU.startMoneyRequest(
CONST.IOU.TYPE.SUBMIT,
// When starting to create an expense from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used
// for all of the routes in the creation flow.
ReportUtils.generateReportID(),
),
),
);
}),
},
];
}, [canUseCombinedTrackSubmit, translate, selfDMReportID, hasSeenTrackTraining, isOffline]);
}, [canUseCombinedTrackSubmit, translate, selfDMReportID, hasSeenTrackTraining, isOffline, shouldRedirectToExpensifyClassic]);

const quickActionMenuItems = useMemo(() => {
// Define common properties in baseQuickAction
Expand Down Expand Up @@ -503,15 +533,21 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
{
icon: Expensicons.InvoiceGeneric,
text: translate('workspace.invoices.sendInvoice'),
shouldCallAfterModalHide: shouldRedirectToExpensifyClassic,
onSelected: () =>
interceptAnonymousUser(() =>
interceptAnonymousUser(() => {
ishpaul777 marked this conversation as resolved.
Show resolved Hide resolved
if (shouldRedirectToExpensifyClassic) {
setModalVisible(true);
return;
}

IOU.startMoneyRequest(
CONST.IOU.TYPE.INVOICE,
// When starting to create an invoice from the global FAB, there is not an existing report yet. A random optimistic reportID is generated and used
// for all of the routes in the creation flow.
ReportUtils.generateReportID(),
),
),
);
}),
},
]
: []),
Expand Down Expand Up @@ -558,6 +594,18 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl
withoutOverlay
anchorRef={fabRef}
/>
<ConfirmModal
prompt={translate('sidebarScreen.redirectToExpensifyClassicModal.description')}
isVisible={modalVisible}
onConfirm={() => {
setModalVisible(false);
Link.openOldDotLink(CONST.OLDDOT_URLS.INBOX);
}}
onCancel={() => setModalVisible(false)}
title={translate('sidebarScreen.redirectToExpensifyClassicModal.title')}
confirmText={translate('exitSurvey.goToExpensifyClassic')}
cancelText={translate('common.cancel')}
/>
<FloatingActionButton
accessibilityLabel={translate('sidebarScreen.fabNewChatExplained')}
role={CONST.ROLE.BUTTON}
Expand Down
Loading