Skip to content

Commit

Permalink
Merge pull request #35306 from callstack-internal/feat/troubleshootin…
Browse files Browse the repository at this point in the history
…g-section

feat: Troubleshooting page & resetting Onyx state
  • Loading branch information
techievivek authored Feb 14, 2024
2 parents 0be27f2 + 319d378 commit 756f846
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 17 deletions.
Binary file added assets/animations/Desk.lottie
Binary file not shown.
1 change: 1 addition & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ const ROUTES = {
SETTINGS_STATUS_CLEAR_AFTER: 'settings/profile/status/clear-after',
SETTINGS_STATUS_CLEAR_AFTER_DATE: 'settings/profile/status/clear-after/date',
SETTINGS_STATUS_CLEAR_AFTER_TIME: 'settings/profile/status/clear-after/time',
SETTINGS_TROUBLESHOOT: 'settings/troubleshoot',

KEYBOARD_SHORTCUTS: 'keyboard-shortcuts',

Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const SCREENS = {
CLOSE: 'Settings_Close',
TWO_FACTOR_AUTH: 'Settings_TwoFactorAuth',
REPORT_CARD_LOST_OR_DAMAGED: 'Settings_ReportCardLostOrDamaged',
TROUBLESHOOT: 'Settings_Troubleshoot',

PROFILE: {
ROOT: 'Settings_Profile',
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import Download from '@assets/images/download.svg';
import DragAndDrop from '@assets/images/drag-and-drop.svg';
import DragHandles from '@assets/images/drag-handles.svg';
import Emoji from '@assets/images/emoji.svg';
import Lightbulb from '@assets/images/emojiCategoryIcons/light-bulb.svg';
import EmptyStateAttachReceipt from '@assets/images/empty-state__attach-receipt.svg';
import EmptyStateRoutePending from '@assets/images/emptystate__routepending.svg';
import EReceiptIcon from '@assets/images/eReceiptIcon.svg';
Expand Down Expand Up @@ -280,4 +281,5 @@ export {
Instagram,
ChatBubbleAdd,
ChatBubbleUnread,
Lightbulb,
};
5 changes: 5 additions & 0 deletions src/components/LottieAnimations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ const DotLottieAnimations = {
h: 240,
backgroundColor: colors.yellow600,
},
Desk: {
file: require('@assets/animations/Desk.lottie'),
w: 200,
h: 120,
},
} satisfies Record<string, DotLottieAnimation>;

export default DotLottieAnimations;
9 changes: 9 additions & 0 deletions src/components/TestToolMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ApiUtils from '@libs/ApiUtils';
import compose from '@libs/compose';
import * as Network from '@userActions/Network';
Expand All @@ -13,6 +14,7 @@ import Button from './Button';
import {withNetwork} from './OnyxProvider';
import Switch from './Switch';
import TestToolRow from './TestToolRow';
import Text from './Text';

type TestToolMenuOnyxProps = {
/** User object in Onyx */
Expand All @@ -27,9 +29,16 @@ const USER_DEFAULT: UserOnyx = {shouldUseStagingServer: undefined, isSubscribedT

function TestToolMenu({user = USER_DEFAULT, network}: TestToolMenuProps) {
const shouldUseStagingServer = user?.shouldUseStagingServer ?? ApiUtils.isUsingStagingApi();
const styles = useThemeStyles();

return (
<>
<Text
style={[styles.textLabelSupporting, styles.mb4]}
numberOfLines={1}
>
Test Preferences
</Text>
{/* Option to switch between staging and default api endpoints.
This enables QA, internal testers and external devs to take advantage of sandbox environments for 3rd party services like Plaid and Onfido.
This toggle is not rendered for internal devs as they make environment changes directly to the .env file. */}
Expand Down
9 changes: 9 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ export default {
viewTheCode: 'View the code',
viewOpenJobs: 'View open jobs',
reportABug: 'Report a bug',
troubleshoot: 'Troubleshoot',
},
appDownloadLinks: {
android: {
Expand All @@ -822,6 +823,14 @@ export default {
label: 'macOS',
},
},
troubleshoot: {
clearCacheAndRestart: 'Clear cache and restart',
viewConsole: 'View debug console',
description: 'Use the tools below to help troubleshoot the Expensify experience. If you encounter any issues, please',
submitBug: 'submit a bug',
confirmResetDescription: 'All unsent draft messages will be lost, but the rest of your data is safe.',
resetAndRefresh: 'Reset and refresh',
},
goToExpensifyClassic: 'Go to Expensify Classic',
security: 'Security',
signOut: 'Sign out',
Expand Down
9 changes: 9 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,7 @@ export default {
viewTheCode: 'Ver código',
viewOpenJobs: 'Ver trabajos disponibles',
reportABug: 'Reportar un error',
troubleshoot: 'Solución de problemas',
},
appDownloadLinks: {
android: {
Expand All @@ -817,6 +818,14 @@ export default {
label: 'macOS',
},
},
troubleshoot: {
clearCacheAndRestart: 'Borrar caché y reiniciar',
viewConsole: 'Ver la consola de depuración',
description: 'Utilice las herramientas que aparecen a continuación para solucionar los problemas de Expensify. Si tiene algún problema, por favor',
submitBug: 'envíe un error',
confirmResetDescription: 'Todos los borradores no enviados se perderán, pero el resto de tus datos estarán a salvo.',
resetAndRefresh: 'Restablecer y actualizar',
},
security: 'Seguridad',
signOut: 'Desconectar',
signOutConfirmationText: 'Si cierras sesión perderás los cambios hechos mientras estabas desconectado',
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.SETTINGS.CLOSE]: () => require('../../../pages/settings/Security/CloseAccountPage').default as React.ComponentType,
[SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: () => require('../../../pages/settings/AppDownloadLinks').default as React.ComponentType,
[SCREENS.SETTINGS.LOUNGE_ACCESS]: () => require('../../../pages/settings/Profile/LoungeAccessPage').default as React.ComponentType,
[SCREENS.SETTINGS.TROUBLESHOOT]: () => require('../../../pages/settings/AboutPage/TroubleshootPage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: () => require('../../../pages/settings/Profile/PersonalDetails/AddressPage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.DOMAIN_CARD]: () => require('../../../pages/settings/Wallet/ExpensifyCardPage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.REPORT_VIRTUAL_CARD_FRAUD]: () => require('../../../pages/settings/Wallet/ReportVirtualCardFraudPage').default as React.ComponentType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS,
],
[SCREENS.SETTINGS.SECURITY]: [SCREENS.SETTINGS.TWO_FACTOR_AUTH, SCREENS.SETTINGS.CLOSE],
[SCREENS.SETTINGS.ABOUT]: [SCREENS.SETTINGS.APP_DOWNLOAD_LINKS, SCREENS.KEYBOARD_SHORTCUTS],
[SCREENS.SETTINGS.ABOUT]: [SCREENS.SETTINGS.APP_DOWNLOAD_LINKS, SCREENS.KEYBOARD_SHORTCUTS, SCREENS.SETTINGS.TROUBLESHOOT],
};

export default FULL_SCREEN_TO_RHP_MAPPING;
4 changes: 4 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
path: ROUTES.SETTINGS_APP_DOWNLOAD_LINKS,
exact: true,
},
[SCREENS.SETTINGS.TROUBLESHOOT]: {
path: ROUTES.SETTINGS_TROUBLESHOOT,
exact: true,
},
[SCREENS.SETTINGS.PROFILE.CONTACT_METHODS]: {
path: ROUTES.SETTINGS_CONTACT_METHODS.route,
exact: true,
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.SECURITY]: undefined;
[SCREENS.SETTINGS.ABOUT]: undefined;
[SCREENS.SETTINGS.APP_DOWNLOAD_LINKS]: undefined;
[SCREENS.SETTINGS.TROUBLESHOOT]: undefined;
[SCREENS.SETTINGS.LOUNGE_ACCESS]: undefined;
[SCREENS.SETTINGS.WALLET.ROOT]: undefined;
[SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS]: undefined;
Expand Down
5 changes: 5 additions & 0 deletions src/pages/settings/AboutPage/AboutPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ function AboutPage() {
},
link: CONST.UPWORK_URL,
},
{
translationKey: 'initialSettingsPage.aboutPage.troubleshoot',
icon: Expensicons.Lightbulb,
action: waitForNavigate(() => Navigation.navigate(ROUTES.SETTINGS_TROUBLESHOOT)),
},
{
translationKey: 'initialSettingsPage.aboutPage.reportABug',
icon: Expensicons.Bug,
Expand Down
120 changes: 120 additions & 0 deletions src/pages/settings/AboutPage/TroubleshootPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React, {useMemo, useState} from 'react';
import {View} from 'react-native';
import Onyx from 'react-native-onyx';
import type {SvgProps} from 'react-native-svg';
import ConfirmModal from '@components/ConfirmModal';
import * as Expensicons from '@components/Icon/Expensicons';
import IllustratedHeaderPageLayout from '@components/IllustratedHeaderPageLayout';
import LottieAnimations from '@components/LottieAnimations';
import MenuItemList from '@components/MenuItemList';
import TestToolMenu from '@components/TestToolMenu';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import * as App from '@userActions/App';
import * as Report from '@userActions/Report';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type {OnyxKey} from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';

const keysToPreserve: OnyxKey[] = [
ONYXKEYS.ACCOUNT,
ONYXKEYS.IS_CHECKING_PUBLIC_ROOM,
ONYXKEYS.IS_LOADING_APP,
ONYXKEYS.IS_SIDEBAR_LOADED,
ONYXKEYS.MODAL,
ONYXKEYS.NETWORK,
ONYXKEYS.SESSION,
ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT,
ONYXKEYS.NVP_TRY_FOCUS_MODE,
ONYXKEYS.PREFERRED_THEME,
ONYXKEYS.NVP_PREFERRED_LOCALE,
];

type BaseMenuItem = {
translationKey: TranslationPaths;
icon: React.FC<SvgProps>;
action: () => void;
};

function TroubleshootPage() {
const {translate} = useLocalize();
const theme = useTheme();
const styles = useThemeStyles();
const {isProduction} = useEnvironment();
const [isConfirmationModalVisible, setIsConfirmationModalVisible] = useState(false);

const menuItems = useMemo(() => {
const baseMenuItems: BaseMenuItem[] = [
{
translationKey: 'initialSettingsPage.troubleshoot.clearCacheAndRestart',
icon: Expensicons.RotateLeft,
action: () => setIsConfirmationModalVisible(true),
},
];

return baseMenuItems.map((item) => ({
key: item.translationKey,
title: translate(item.translationKey),
icon: item.icon,
onPress: item.action,
}));
}, [translate]);

return (
<IllustratedHeaderPageLayout
title={translate('initialSettingsPage.aboutPage.troubleshoot')}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_ABOUT)}
backgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.TROUBLESHOOT].backgroundColor}
illustration={LottieAnimations.Desk}
testID={TroubleshootPage.displayName}
>
<View style={[styles.settingsPageBody, styles.ph5]}>
<Text style={[styles.textHeadline, styles.mb1]}>{translate('initialSettingsPage.aboutPage.troubleshoot')}</Text>
<Text style={styles.mb4}>
<Text>{translate('initialSettingsPage.troubleshoot.description')}</Text>{' '}
<TextLink
style={styles.link}
onPress={() => Report.navigateToConciergeChat()}
>
{translate('initialSettingsPage.troubleshoot.submitBug')}
</TextLink>
</Text>
</View>
<MenuItemList
menuItems={menuItems}
shouldUseSingleExecution
/>
{/* Enable additional test features in non-production environments */}
{!isProduction && (
<View style={[styles.ml5, styles.mr8, styles.mt6]}>
<TestToolMenu />
</View>
)}
<ConfirmModal
title={translate('common.areYouSure')}
isVisible={isConfirmationModalVisible}
onConfirm={() => {
setIsConfirmationModalVisible(false);
Onyx.clear(keysToPreserve).then(() => {
App.openApp();
});
}}
onCancel={() => setIsConfirmationModalVisible(false)}
prompt={translate('initialSettingsPage.troubleshoot.confirmResetDescription')}
confirmText={translate('initialSettingsPage.troubleshoot.resetAndRefresh')}
cancelText={translate('common.cancel')}
/>
</IllustratedHeaderPageLayout>
);
}

TroubleshootPage.displayName = 'TroubleshootPage';

export default TroubleshootPage;
16 changes: 0 additions & 16 deletions src/pages/settings/Preferences/PreferencesPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import ScreenWrapper from '@components/ScreenWrapper';
import Section from '@components/Section';
import Switch from '@components/Switch';
import TestToolMenu from '@components/TestToolMenu';
import Text from '@components/Text';
import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
Expand Down Expand Up @@ -44,7 +42,6 @@ const defaultProps = {

function PreferencesPage(props) {
const styles = useThemeStyles();
const {isProduction} = useEnvironment();
const {translate, preferredLocale} = useLocalize();
const {isSmallScreenWidth} = useWindowDimensions();

Expand Down Expand Up @@ -125,19 +122,6 @@ function PreferencesPage(props) {
/>
</View>
</Section>
{!isProduction && (
<Section
title={translate('preferencesPage.testSection.title')}
subtitle={translate('preferencesPage.testSection.subtitle')}
isCentralPane
subtitleMuted
titleStyles={styles.accountSettingsSectionTitle}
>
<View style={styles.mt5}>
<TestToolMenu />
</View>
</Section>
)}
</View>
</ScrollView>
</ScreenWrapper>
Expand Down
4 changes: 4 additions & 0 deletions src/styles/theme/themes/dark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ const darkTheme = {
backgroundColor: colors.productDark100,
statusBarStyle: CONST.STATUS_BAR_STYLE.LIGHT_CONTENT,
},
[SCREENS.SETTINGS.TROUBLESHOOT]: {
backgroundColor: colors.blue700,
statusBarStyle: CONST.STATUS_BAR_STYLE.LIGHT_CONTENT,
},
[SCREENS.REFERRAL_DETAILS]: {
backgroundColor: colors.pink800,
statusBarStyle: CONST.STATUS_BAR_STYLE.LIGHT_CONTENT,
Expand Down
4 changes: 4 additions & 0 deletions src/styles/theme/themes/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ const lightTheme = {
backgroundColor: colors.productLight100,
statusBarStyle: CONST.STATUS_BAR_STYLE.DARK_CONTENT,
},
[SCREENS.SETTINGS.TROUBLESHOOT]: {
backgroundColor: colors.blue700,
statusBarStyle: CONST.STATUS_BAR_STYLE.LIGHT_CONTENT,
},
[SCREENS.REFERRAL_DETAILS]: {
backgroundColor: colors.pink800,
statusBarStyle: CONST.STATUS_BAR_STYLE.LIGHT_CONTENT,
Expand Down

0 comments on commit 756f846

Please sign in to comment.