From c8492ec97849e8749733c9455b6fd0dbb8bd034b Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Thu, 6 Mar 2025 12:32:24 +0100
Subject: [PATCH 1/8] Update Migrate tooltips
---
src/CONST.ts | 8 +-
src/components/AccountSwitcher.tsx | 45 ++-
.../LHNOptionsList/OptionRowLHN.tsx | 2 +
.../ProductTrainingContext/TOOLTIPS.ts | 83 +++---
.../ProductTrainingContext/index.tsx | 3 +-
.../SearchPageHeader/SearchPageHeader.tsx | 46 +--
src/languages/en.ts | 46 +--
src/languages/es.ts | 44 +--
src/pages/Search/SearchTypeMenu.tsx | 43 ++-
.../ReportActionCompose.tsx | 266 ++++++++----------
.../sidebar/FloatingActionButtonPopover.tsx | 13 -
src/styles/variables.ts | 8 +-
src/types/onyx/DismissedProductTraining.ts | 20 +-
.../ProductTrainingContextProvider.tsx | 8 +-
14 files changed, 295 insertions(+), 340 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index b5cfc9d91aae..cf624e389b4e 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -6706,17 +6706,19 @@ const CONST = {
BASE_LIST_ITEM_TEST_ID: 'base-list-item-',
PRODUCT_TRAINING_TOOLTIP_NAMES: {
+ // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
+ // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
CONCEIRGE_LHN_GBR: 'conciergeLHNGBR',
RENAME_SAVED_SEARCH: 'renameSavedSearch',
- QUICK_ACTION_BUTTON: 'quickActionButton',
- WORKSAPCE_CHAT_CREATE: 'workspaceChatCreate',
- SEARCH_FILTER_BUTTON_TOOLTIP: 'filterButtonTooltip',
BOTTOM_NAV_INBOX_TOOLTIP: 'bottomNavInboxTooltip',
LHN_WORKSPACE_CHAT_TOOLTIP: 'workspaceChatLHNTooltip',
GLOBAL_CREATE_TOOLTIP: 'globalCreateTooltip',
SCAN_TEST_TOOLTIP: 'scanTestTooltip',
SCAN_TEST_TOOLTIP_MANAGER: 'scanTestTooltipManager',
SCAN_TEST_CONFIRMATION: 'scanTestConfirmation',
+ EXPENSE_REPORTS_FILTER: 'expenseReportsFilter',
+ GBR_RBR_CHAT: 'GBRRBRChat',
+ ACCOUNT_SWITCHER: 'accountSwitcher',
},
SMART_BANNER_HEIGHT: 152,
diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx
index ed2eae7a0a4c..27c8a0de246f 100644
--- a/src/components/AccountSwitcher.tsx
+++ b/src/components/AccountSwitcher.tsx
@@ -26,7 +26,9 @@ import * as Expensicons from './Icon/Expensicons';
import type {PopoverMenuItem} from './PopoverMenu';
import PopoverMenu from './PopoverMenu';
import {PressableWithFeedback} from './Pressable';
+import {useProductTrainingContext} from './ProductTrainingContext';
import Text from './Text';
+import EducationalTooltip from './Tooltip/EducationalTooltip';
function AccountSwitcher() {
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
@@ -49,6 +51,11 @@ function AccountSwitcher() {
const canSwitchAccounts = delegators.length > 0 || isActingAsDelegate;
const processedTextArray = EmojiUtils.splitTextWithEmojis(currentUserPersonalDetails?.displayName);
+ const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(
+ CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.ACCOUNT_SWITCHER,
+ canSwitchAccounts,
+ );
+
const createBaseMenuItem = (
personalDetails: PersonalDetails | undefined,
errors?: Errors,
@@ -124,14 +131,17 @@ function AccountSwitcher() {
return [currentUserMenuItem, ...delegatorMenuItems];
};
+ const onPressSwitcher = () => {
+ hideProductTrainingTooltip();
+ setShouldShowDelegatorMenu(!shouldShowDelegatorMenu);
+ };
+
return (
<>
{
- setShouldShowDelegatorMenu(!shouldShowDelegatorMenu);
- }}
+ onPress={onPressSwitcher}
ref={buttonRef}
interactive={canSwitchAccounts}
pressDimmingValue={canSwitchAccounts ? undefined : 1}
@@ -156,14 +166,27 @@ function AccountSwitcher() {
: currentUserPersonalDetails?.displayName}
{!!canSwitchAccounts && (
-
-
-
+
+
+
+
+
)}
{}, opti
const isReportsSplitNavigatorLast = useRootNavigationState((state) => state?.routes?.at(-1)?.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR);
+ // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
+ // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
const {tooltipToRender, shouldShowTooltip} = useMemo(() => {
const tooltip = shouldShowGetStartedTooltip ? CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.CONCEIRGE_LHN_GBR : CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;
const shouldShowTooltips = shouldShowWokspaceChatTooltip || shouldShowGetStartedTooltip;
diff --git a/src/components/ProductTrainingContext/TOOLTIPS.ts b/src/components/ProductTrainingContext/TOOLTIPS.ts
index 90e91166fba7..fbf0761dc1e6 100644
--- a/src/components/ProductTrainingContext/TOOLTIPS.ts
+++ b/src/components/ProductTrainingContext/TOOLTIPS.ts
@@ -6,15 +6,15 @@ import type {TranslationPaths} from '@src/languages/types';
const {
CONCEIRGE_LHN_GBR,
RENAME_SAVED_SEARCH,
- WORKSAPCE_CHAT_CREATE,
- QUICK_ACTION_BUTTON,
- SEARCH_FILTER_BUTTON_TOOLTIP,
BOTTOM_NAV_INBOX_TOOLTIP,
LHN_WORKSPACE_CHAT_TOOLTIP,
GLOBAL_CREATE_TOOLTIP,
SCAN_TEST_TOOLTIP,
SCAN_TEST_TOOLTIP_MANAGER,
SCAN_TEST_CONFIRMATION,
+ EXPENSE_REPORTS_FILTER,
+ GBR_RBR_CHAT,
+ ACCOUNT_SWITCHER,
} = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES;
type ProductTrainingTooltipName = ValueOf;
@@ -41,7 +41,9 @@ const TOOLTIPS: Record = {
onHideTooltip: () => dismissProductTraining(CONCEIRGE_LHN_GBR),
name: CONCEIRGE_LHN_GBR,
priority: 1300,
- shouldShow: ({shouldUseNarrowLayout}) => !!shouldUseNarrowLayout,
+ // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
+ // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
+ shouldShow: () => false,
},
[RENAME_SAVED_SEARCH]: {
content: [
@@ -61,60 +63,63 @@ const TOOLTIPS: Record = {
],
onHideTooltip: () => dismissProductTraining(GLOBAL_CREATE_TOOLTIP),
name: GLOBAL_CREATE_TOOLTIP,
- priority: 1200,
+ priority: 1950,
shouldShow: () => true,
},
- [QUICK_ACTION_BUTTON]: {
+ [BOTTOM_NAV_INBOX_TOOLTIP]: {
content: [
- {text: 'productTrainingTooltip.quickActionButton.part1', isBold: true},
- {text: 'productTrainingTooltip.quickActionButton.part2', isBold: false},
+ {text: 'productTrainingTooltip.bottomNavInboxTooltip.part1', isBold: false},
+ {text: 'productTrainingTooltip.bottomNavInboxTooltip.part2', isBold: true},
+ {text: 'productTrainingTooltip.bottomNavInboxTooltip.part3', isBold: false},
+ {text: 'productTrainingTooltip.bottomNavInboxTooltip.part4', isBold: true},
],
- onHideTooltip: () => dismissProductTraining(QUICK_ACTION_BUTTON),
- name: QUICK_ACTION_BUTTON,
- priority: 1150,
+ onHideTooltip: () => dismissProductTraining(BOTTOM_NAV_INBOX_TOOLTIP),
+ name: BOTTOM_NAV_INBOX_TOOLTIP,
+ priority: 1700,
shouldShow: () => true,
},
- [WORKSAPCE_CHAT_CREATE]: {
+ [LHN_WORKSPACE_CHAT_TOOLTIP]: {
content: [
- {text: 'productTrainingTooltip.workspaceChatCreate.part1', isBold: false},
- {text: 'productTrainingTooltip.workspaceChatCreate.part2', isBold: true},
- {text: 'productTrainingTooltip.workspaceChatCreate.part3', isBold: false},
+ {text: 'productTrainingTooltip.workspaceChatTooltip.part1', isBold: false},
+ {text: 'productTrainingTooltip.workspaceChatTooltip.part2', isBold: true},
],
- onHideTooltip: () => dismissProductTraining(WORKSAPCE_CHAT_CREATE),
- name: WORKSAPCE_CHAT_CREATE,
- priority: 1100,
+ onHideTooltip: () => dismissProductTraining(LHN_WORKSPACE_CHAT_TOOLTIP),
+ name: LHN_WORKSPACE_CHAT_TOOLTIP,
+ priority: 1800,
shouldShow: () => true,
},
- [SEARCH_FILTER_BUTTON_TOOLTIP]: {
+ [EXPENSE_REPORTS_FILTER]: {
content: [
- {text: 'productTrainingTooltip.searchFilterButtonTooltip.part1', isBold: true},
- {text: 'productTrainingTooltip.searchFilterButtonTooltip.part2', isBold: false},
+ {text: 'productTrainingTooltip.expenseReportsFilter.part1', isBold: false},
+ {text: 'productTrainingTooltip.expenseReportsFilter.part2', isBold: true},
+ {text: 'productTrainingTooltip.expenseReportsFilter.part3', isBold: false},
],
- onHideTooltip: () => dismissProductTraining(SEARCH_FILTER_BUTTON_TOOLTIP),
- name: SEARCH_FILTER_BUTTON_TOOLTIP,
- priority: 1000,
- shouldShow: () => true,
+ onHideTooltip: () => dismissProductTraining(EXPENSE_REPORTS_FILTER),
+ name: EXPENSE_REPORTS_FILTER,
+ priority: 2000,
+ shouldShow: ({shouldUseNarrowLayout}) => !shouldUseNarrowLayout,
},
- [BOTTOM_NAV_INBOX_TOOLTIP]: {
+ [GBR_RBR_CHAT]: {
content: [
- {text: 'productTrainingTooltip.bottomNavInboxTooltip.part1', isBold: true},
- {text: 'productTrainingTooltip.bottomNavInboxTooltip.part2', isBold: false},
- {text: 'productTrainingTooltip.bottomNavInboxTooltip.part3', isBold: false},
+ {text: 'productTrainingTooltip.GBRRBRChat.part1', isBold: false},
+ {text: 'productTrainingTooltip.GBRRBRChat.part2', isBold: true},
+ {text: 'productTrainingTooltip.GBRRBRChat.part3', isBold: false},
+ {text: 'productTrainingTooltip.GBRRBRChat.part4', isBold: true},
],
- onHideTooltip: () => dismissProductTraining(BOTTOM_NAV_INBOX_TOOLTIP),
- name: BOTTOM_NAV_INBOX_TOOLTIP,
- priority: 900,
+ onHideTooltip: () => dismissProductTraining(GBR_RBR_CHAT),
+ name: GBR_RBR_CHAT,
+ priority: 1900,
shouldShow: () => true,
},
- [LHN_WORKSPACE_CHAT_TOOLTIP]: {
+ [ACCOUNT_SWITCHER]: {
content: [
- {text: 'productTrainingTooltip.workspaceChatTooltip.part1', isBold: true},
- {text: 'productTrainingTooltip.workspaceChatTooltip.part2', isBold: false},
- {text: 'productTrainingTooltip.workspaceChatTooltip.part3', isBold: false},
+ {text: 'productTrainingTooltip.accountSwitcher.part1', isBold: false},
+ {text: 'productTrainingTooltip.accountSwitcher.part2', isBold: true},
+ {text: 'productTrainingTooltip.accountSwitcher.part3', isBold: false},
],
- onHideTooltip: () => dismissProductTraining(LHN_WORKSPACE_CHAT_TOOLTIP),
- name: LHN_WORKSPACE_CHAT_TOOLTIP,
- priority: 800,
+ onHideTooltip: () => dismissProductTraining(ACCOUNT_SWITCHER),
+ name: ACCOUNT_SWITCHER,
+ priority: 1600,
shouldShow: () => true,
},
[SCAN_TEST_TOOLTIP]: {
diff --git a/src/components/ProductTrainingContext/index.tsx b/src/components/ProductTrainingContext/index.tsx
index dabd209bf26b..fc2e232928be 100644
--- a/src/components/ProductTrainingContext/index.tsx
+++ b/src/components/ProductTrainingContext/index.tsx
@@ -100,9 +100,8 @@ function ProductTrainingContextProvider({children}: ChildrenProps) {
return false;
}
- // We need to make an exception for the QAB tooltip because it is shown in a modal, otherwise it would be hidden if a modal is visible
+ // We need to make an exception for these tooltips because it is shown in a modal, otherwise it would be hidden if a modal is visible
if (
- tooltipName !== CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.QUICK_ACTION_BUTTON &&
tooltipName !== CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_TOOLTIP &&
tooltipName !== CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_TOOLTIP_MANAGER &&
tooltipName !== CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_CONFIRMATION &&
diff --git a/src/components/Search/SearchPageHeader/SearchPageHeader.tsx b/src/components/Search/SearchPageHeader/SearchPageHeader.tsx
index a3b814650a23..71ea26a2662e 100644
--- a/src/components/Search/SearchPageHeader/SearchPageHeader.tsx
+++ b/src/components/Search/SearchPageHeader/SearchPageHeader.tsx
@@ -1,4 +1,3 @@
-import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useMemo, useState} from 'react';
import {InteractionManager, View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
@@ -9,10 +8,8 @@ import ConfirmModal from '@components/ConfirmModal';
import DecisionModal from '@components/DecisionModal';
import * as Expensicons from '@components/Icon/Expensicons';
import {usePersonalDetails} from '@components/OnyxProvider';
-import {useProductTrainingContext} from '@components/ProductTrainingContext';
import {useSearchContext} from '@components/Search/SearchContext';
import type {PaymentData, SearchQueryJSON} from '@components/Search/types';
-import EducationalTooltip from '@components/Tooltip/EducationalTooltip';
import useActiveWorkspace from '@hooks/useActiveWorkspace';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
@@ -75,24 +72,9 @@ function SearchPageHeader({queryJSON, searchName, searchRouterListVisible, hideS
const [isDeleteExpensesConfirmModalVisible, setIsDeleteExpensesConfirmModalVisible] = useState(false);
const [isOfflineModalVisible, setIsOfflineModalVisible] = useState(false);
const [isDownloadErrorModalVisible, setIsDownloadErrorModalVisible] = useState(false);
- const [isScreenFocused, setIsScreenFocused] = useState(false);
-
- const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(
- CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SEARCH_FILTER_BUTTON_TOOLTIP,
- isScreenFocused,
- );
const {status, hash} = queryJSON;
- useFocusEffect(
- useCallback(() => {
- setIsScreenFocused(true);
- return () => {
- setIsScreenFocused(false);
- };
- }, []),
- );
-
const selectedTransactionsKeys = Object.keys(selectedTransactions ?? {});
const handleDeleteExpenses = () => {
@@ -330,12 +312,11 @@ function SearchPageHeader({queryJSON, searchName, searchRouterListVisible, hideS
]);
const onFiltersButtonPress = useCallback(() => {
- hideProductTrainingTooltip();
const filterFormValues = buildFilterFormValuesFromQuery(queryJSON, policyCategories, policyTagsLists, currencyList, personalDetails, allCards, reports, taxRates);
updateAdvancedFilters(filterFormValues);
Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS);
- }, [allCards, currencyList, hideProductTrainingTooltip, personalDetails, policyCategories, policyTagsLists, queryJSON, reports, taxRates]);
+ }, [allCards, currencyList, personalDetails, policyCategories, policyTagsLists, queryJSON, reports, taxRates]);
const InputRightComponent = useMemo(() => {
return headerButtonsOptions.length > 0 && (!shouldUseNarrowLayout || selectionMode?.isEnabled) ? (
@@ -349,33 +330,18 @@ function SearchPageHeader({queryJSON, searchName, searchRouterListVisible, hideS
shouldUseStyleUtilityForAnchorPosition
/>
) : (
-
-
-
+
);
}, [
headerButtonsOptions,
onFiltersButtonPress,
- renderProductTrainingTooltip,
selectedTransactionsKeys.length,
- shouldShowProductTrainingTooltip,
styles.bgTransparent,
styles.borderNone,
- styles.productTrainingTooltipWrapper,
styles.searchAutocompleteInputResults,
translate,
selectionMode,
diff --git a/src/languages/en.ts b/src/languages/en.ts
index b33a358fc24c..8346529d0afa 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -5915,6 +5915,8 @@ const translations = {
},
},
productTrainingTooltip: {
+ // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
+ // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
conciergeLHNGBR: {
part1: 'Get started',
part2: ' here!',
@@ -5923,33 +5925,37 @@ const translations = {
part1: 'Rename your saved searches',
part2: ' here!',
},
- quickActionButton: {
- part1: 'Quick action!',
- part2: ' Just a tap away',
- },
- workspaceChatCreate: {
- part1: 'Submit your',
- part2: ' expenses',
- part3: ' here!',
- },
- searchFilterButtonTooltip: {
- part1: 'Customize your search',
- part2: ' here!',
- },
bottomNavInboxTooltip: {
- part1: 'Your to-do list',
- part2: '\n🟢 = ready for you',
- part3: ' 🔴 = needs review',
+ part1: 'Check what ',
+ part2: 'needs your attention',
+ part3: '\nand ',
+ part4: 'chat about expenses.',
},
workspaceChatTooltip: {
- part1: 'Submit expenses',
- part2: ' and chat with',
- part3: '\napprovers here!',
+ part1: 'Chat with ',
+ part2: 'approvers',
},
globalCreateTooltip: {
part1: 'Create expenses',
part2: ', start chatting,',
- part3: '\nand more!',
+ part3: '\nand more.',
+ part4: ' Try it out!',
+ },
+ GBRRBRChat: {
+ part1: 'You’ll see 🟢 on ',
+ part2: 'actions to take',
+ part3: ', and 🔴 on ',
+ part4: 'errors to review.',
+ },
+ expenseReportsFilter: {
+ part1: 'Welcome!\nFind all of your ',
+ part2: "company's reports",
+ part3: ' here.',
+ },
+ accountSwitcher: {
+ part1: 'Access your ',
+ part2: 'Copilot accounts',
+ part3: ' here',
},
scanTestTooltip: {
part1: 'Want to see how Scan works?',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index db54e7dad462..e303517af2be 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -6437,6 +6437,8 @@ const translations = {
},
},
productTrainingTooltip: {
+ // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
+ // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
conciergeLHNGBR: {
part1: '¡Comienza',
part2: ' aquÃ!',
@@ -6445,33 +6447,37 @@ const translations = {
part1: 'Renombra tus búsquedas guardadas',
part2: ' aquÃ',
},
- quickActionButton: {
- part1: '¡Acción rápida!',
- part2: ' A solo un toque',
- },
- workspaceChatCreate: {
- part1: 'EnvÃa tus',
- part2: ' gastos',
- part3: ' aquÃ',
- },
- searchFilterButtonTooltip: {
- part1: 'Personaliza tu búsqueda',
- part2: ' aquÃ!',
- },
bottomNavInboxTooltip: {
- part1: 'Tu lista de tareas',
- part2: '\n🟢 = listo para ti',
- part3: ' 🔴 = necesita revisión',
+ part1: 'Consulta lo que ',
+ part2: 'requiere tu atención',
+ part3: '\ny ',
+ part4: 'chatea sobre gastos.',
},
workspaceChatTooltip: {
- part1: 'EnvÃa gastos',
- part2: ' y chatea con',
- part3: '\naprobadores aquÃ!',
+ part1: 'Chatea con ',
+ part2: 'aprobadores',
},
globalCreateTooltip: {
part1: 'Crea gastos',
part2: ', comienza a chatear,',
part3: '\ny mucho más!',
+ part4: ' ¡Pruébalo!',
+ },
+ expenseReportsFilter: {
+ part1: '¡Bienvenido!\nEncuentra todos los ',
+ part2: 'informes de tu empresa',
+ part3: ' aquÃ.',
+ },
+ GBRRBRChat: {
+ part1: 'Verás 🟢 en ',
+ part2: 'acciones a realizar',
+ part3: ', y 🔴 en ',
+ part4: 'errores para revisar.',
+ },
+ accountSwitcher: {
+ part1: 'Accede a tus ',
+ part2: 'cuentas Copilot',
+ part3: ' aquÃ',
},
scanTestTooltip: {
part1: '¿Quieres ver cómo funciona Escanear?',
diff --git a/src/pages/Search/SearchTypeMenu.tsx b/src/pages/Search/SearchTypeMenu.tsx
index f01be69fd273..31a6f118f541 100644
--- a/src/pages/Search/SearchTypeMenu.tsx
+++ b/src/pages/Search/SearchTypeMenu.tsx
@@ -47,10 +47,17 @@ function SearchTypeMenu({queryJSON, shouldGroupByReports}: SearchTypeMenuProps)
const [savedSearches] = useOnyx(ONYXKEYS.SAVED_SEARCHES);
const {isOffline} = useNetwork();
const shouldShowSavedSearchesMenuItemTitle = Object.values(savedSearches ?? {}).filter((s) => s.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || isOffline).length > 0;
- const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(
- CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.RENAME_SAVED_SEARCH,
- shouldShowSavedSearchesMenuItemTitle,
- );
+ const {
+ shouldShowProductTrainingTooltip: shouldShowSavedSearchTooltip,
+ renderProductTrainingTooltip: renderSavedSearchTooltip,
+ hideProductTrainingTooltip: hideSavedSearchTooltip,
+ } = useProductTrainingContext(CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.RENAME_SAVED_SEARCH, shouldShowSavedSearchesMenuItemTitle);
+ const {
+ shouldShowProductTrainingTooltip: shouldShowExpenseReportsTypeTooltip,
+ renderProductTrainingTooltip: renderExpenseReportsTypeTooltip,
+ hideProductTrainingTooltip: hideExpenseReportsTypeTooltip,
+ } = useProductTrainingContext(CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.EXPENSE_REPORTS_FILTER, true);
+
const {showDeleteModal, DeleteConfirmModal} = useDeleteSavedSearch();
const [session] = useOnyx(ONYXKEYS.SESSION);
const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
@@ -84,9 +91,9 @@ function SearchTypeMenu({queryJSON, shouldGroupByReports}: SearchTypeMenuProps)
),
style: [styles.alignItemsCenter],
@@ -97,19 +104,19 @@ function SearchTypeMenu({queryJSON, shouldGroupByReports}: SearchTypeMenuProps)
tooltipShiftHorizontal: variables.savedSearchShiftHorizontal,
tooltipShiftVertical: variables.savedSearchShiftVertical,
tooltipWrapperStyle: [styles.mh4, styles.pv2, styles.productTrainingTooltipWrapper],
- renderTooltipContent: renderProductTrainingTooltip,
+ renderTooltipContent: renderSavedSearchTooltip,
};
},
[
hash,
getOverflowMenu,
- shouldShowProductTrainingTooltip,
- hideProductTrainingTooltip,
+ shouldShowSavedSearchTooltip,
+ hideSavedSearchTooltip,
styles.alignItemsCenter,
styles.mh4,
styles.pv2,
styles.productTrainingTooltipWrapper,
- renderProductTrainingTooltip,
+ renderSavedSearchTooltip,
personalDetails,
reports,
taxRates,
@@ -181,7 +188,12 @@ function SearchTypeMenu({queryJSON, shouldGroupByReports}: SearchTypeMenuProps)
>
{typeMenuItems.map((item, index) => {
+ const shouldShowTooltip = item.translationPath === 'common.expenseReports' && index !== activeItemIndex && shouldShowExpenseReportsTypeTooltip;
+
const onPress = singleExecution(() => {
+ if (shouldShowTooltip) {
+ hideExpenseReportsTypeTooltip();
+ }
clearAllFilters();
clearSelectedTransactions();
Navigation.navigate(item.getRoute(queryJSON.policyID));
@@ -200,6 +212,15 @@ function SearchTypeMenu({queryJSON, shouldGroupByReports}: SearchTypeMenuProps)
focused={index === activeItemIndex}
onPress={onPress}
shouldIconUseAutoWidthStyle
+ shouldRenderTooltip={shouldShowTooltip}
+ renderTooltipContent={renderExpenseReportsTypeTooltip}
+ tooltipAnchorAlignment={{
+ horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT,
+ vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
+ }}
+ tooltipShiftHorizontal={variables.expenseReportsTypeTooltipShiftHorizontal}
+ tooltipWrapperStyle={styles.productTrainingTooltipWrapper}
+ onEducationTooltipPress={onPress}
/>
);
})}
diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
index d89a20eea497..802ba748ba7f 100644
--- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
+++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
@@ -1,9 +1,8 @@
-import {useFocusEffect} from '@react-navigation/native';
import lodashDebounce from 'lodash/debounce';
import noop from 'lodash/noop';
import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import type {MeasureInWindowOnSuccessCallback, NativeSyntheticEvent, TextInputFocusEventData, TextInputSelectionChangeEventData} from 'react-native';
-import {InteractionManager, View} from 'react-native';
+import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import {runOnUI, useSharedValue} from 'react-native-reanimated';
@@ -17,8 +16,6 @@ import type {Mention} from '@components/MentionSuggestions';
import OfflineIndicator from '@components/OfflineIndicator';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {usePersonalDetails} from '@components/OnyxProvider';
-import {useProductTrainingContext} from '@components/ProductTrainingContext';
-import EducationalTooltip from '@components/Tooltip/EducationalTooltip';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useDebounce from '@hooks/useDebounce';
import useHandleExceedMaxCommentLength from '@hooks/useHandleExceedMaxCommentLength';
@@ -27,7 +24,6 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
-import useViewportOffsetTop from '@hooks/useViewportOffsetTop';
import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus';
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
import DomUtils from '@libs/DomUtils';
@@ -112,7 +108,6 @@ function ReportActionCompose({
reportID,
isReportReadyForDisplay = true,
lastReportAction,
- shouldShowEducationalTooltip,
onComposerFocus,
onComposerBlur,
didHideComposerInput,
@@ -121,32 +116,12 @@ function ReportActionCompose({
const {translate} = useLocalize();
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth, isMediumScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout();
- const offsetTop = useViewportOffsetTop();
const {isOffline} = useNetwork();
const actionButtonRef = useRef(null);
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const personalDetails = usePersonalDetails();
const [blockedFromConcierge] = useOnyx(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE);
const [shouldShowComposeInput = true] = useOnyx(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT);
- const [isScreenTransitionEnded, setIsScreenTransitionEnded] = useState(false);
-
- useFocusEffect(
- React.useCallback(() => {
- const task = InteractionManager.runAfterInteractions(() => {
- setIsScreenTransitionEnded(true);
- });
-
- return () => {
- task.cancel();
- setIsScreenTransitionEnded(false);
- };
- }, []),
- );
-
- const {renderProductTrainingTooltip, hideProductTrainingTooltip, shouldShowProductTrainingTooltip} = useProductTrainingContext(
- CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.WORKSAPCE_CHAT_CREATE,
- shouldShowEducationalTooltip && isScreenTransitionEnded,
- );
/**
* Updates the Highlight state of the composer
@@ -247,12 +222,11 @@ function ReportActionCompose({
);
const onAddActionPressed = useCallback(() => {
- hideProductTrainingTooltip();
if (!willBlurTextInputOnTapOutside) {
isKeyboardVisibleWhenShowingModalRef.current = !!composerRef.current?.isFocused();
}
composerRef.current?.blur();
- }, [hideProductTrainingTooltip]);
+ }, []);
const onItemSelected = useCallback(() => {
isKeyboardVisibleWhenShowingModalRef.current = false;
@@ -432,136 +406,120 @@ function ReportActionCompose({
style={isComposerFullSize ? styles.chatItemFullComposeRow : {}}
contentContainerStyle={isComposerFullSize ? styles.flex1 : {}}
>
- {
- setMenuVisibility(true);
- onAddActionPressed();
- }}
+
- setIsAttachmentPreviewActive(true)}
+ onModalHide={onAttachmentPreviewClose}
+ shouldDisableSendButton={!!exceededMaxLength}
>
- setIsAttachmentPreviewActive(true)}
- onModalHide={onAttachmentPreviewClose}
- shouldDisableSendButton={!!exceededMaxLength}
- >
- {({displayFileInModal}) => (
- <>
- {
- if (!shouldFocusInputOnScreenFocus) {
- return;
- }
- focus();
- }}
- actionButtonRef={actionButtonRef}
- shouldDisableAttachmentItem={!!exceededMaxLength}
- />
- {
- composerRef.current = ref ?? undefined;
- composerRefShared.set({
- clear: ref?.clear,
- });
- }}
- suggestionsRef={suggestionsRef}
- isNextModalWillOpenRef={isNextModalWillOpenRef}
- isScrollLikelyLayoutTriggered={isScrollLikelyLayoutTriggered}
- raiseIsScrollLikelyLayoutTriggered={raiseIsScrollLikelyLayoutTriggered}
- reportID={reportID}
- policyID={report?.policyID}
- includeChronos={chatIncludesChronos(report)}
- isGroupPolicyReport={isGroupPolicyReport}
- lastReportAction={lastReportAction}
- isMenuVisible={isMenuVisible}
- inputPlaceholder={inputPlaceholder}
- isComposerFullSize={isComposerFullSize}
- setIsFullComposerAvailable={setIsFullComposerAvailable}
- displayFileInModal={displayFileInModal}
- onCleared={submitForm}
- isBlockedFromConcierge={isBlockedFromConcierge}
- disabled={disabled}
- setIsCommentEmpty={setIsCommentEmpty}
- handleSendMessage={handleSendMessage}
- shouldShowComposeInput={shouldShowComposeInput}
- onFocus={onFocus}
- onBlur={onBlur}
- measureParentContainer={measureContainer}
- onValueChange={onValueChange}
- didHideComposerInput={didHideComposerInput}
- />
- {
- if (isAttachmentPreviewActive) {
- return;
- }
- const data = event.dataTransfer?.files[0];
- if (data) {
- data.uri = URL.createObjectURL(data);
- displayFileInModal(data);
- }
- }}
- />
- >
- )}
-
- {canUseTouchScreen() && isMediumScreenWidth ? null : (
- {
- if (isNavigating) {
- return;
- }
- const activeElementId = DomUtils.getActiveElement()?.id;
- if (activeElementId === CONST.COMPOSER.NATIVE_ID || activeElementId === CONST.EMOJI_PICKER_BUTTON_NATIVE_ID) {
- return;
- }
- focus();
- }}
- onEmojiSelected={(...args) => composerRef.current?.replaceSelectionWithText(...args)}
- emojiPickerID={report?.reportID}
- shiftVertical={emojiShiftVertical}
- />
+ {({displayFileInModal}) => (
+ <>
+ {
+ if (!shouldFocusInputOnScreenFocus) {
+ return;
+ }
+ focus();
+ }}
+ actionButtonRef={actionButtonRef}
+ shouldDisableAttachmentItem={!!exceededMaxLength}
+ />
+ {
+ composerRef.current = ref ?? undefined;
+ composerRefShared.set({
+ clear: ref?.clear,
+ });
+ }}
+ suggestionsRef={suggestionsRef}
+ isNextModalWillOpenRef={isNextModalWillOpenRef}
+ isScrollLikelyLayoutTriggered={isScrollLikelyLayoutTriggered}
+ raiseIsScrollLikelyLayoutTriggered={raiseIsScrollLikelyLayoutTriggered}
+ reportID={reportID}
+ policyID={report?.policyID}
+ includeChronos={chatIncludesChronos(report)}
+ isGroupPolicyReport={isGroupPolicyReport}
+ lastReportAction={lastReportAction}
+ isMenuVisible={isMenuVisible}
+ inputPlaceholder={inputPlaceholder}
+ isComposerFullSize={isComposerFullSize}
+ setIsFullComposerAvailable={setIsFullComposerAvailable}
+ displayFileInModal={displayFileInModal}
+ onCleared={submitForm}
+ isBlockedFromConcierge={isBlockedFromConcierge}
+ disabled={disabled}
+ setIsCommentEmpty={setIsCommentEmpty}
+ handleSendMessage={handleSendMessage}
+ shouldShowComposeInput={shouldShowComposeInput}
+ onFocus={onFocus}
+ onBlur={onBlur}
+ measureParentContainer={measureContainer}
+ onValueChange={onValueChange}
+ didHideComposerInput={didHideComposerInput}
+ />
+ {
+ if (isAttachmentPreviewActive) {
+ return;
+ }
+ const data = event.dataTransfer?.files[0];
+ if (data) {
+ data.uri = URL.createObjectURL(data);
+ displayFileInModal(data);
+ }
+ }}
+ />
+ >
)}
-
+ {canUseTouchScreen() && isMediumScreenWidth ? null : (
+ {
+ if (isNavigating) {
+ return;
+ }
+ const activeElementId = DomUtils.getActiveElement()?.id;
+ if (activeElementId === CONST.COMPOSER.NATIVE_ID || activeElementId === CONST.EMOJI_PICKER_BUTTON_NATIVE_ID) {
+ return;
+ }
+ focus();
+ }}
+ onEmojiSelected={(...args) => composerRef.current?.replaceSelectionWithText(...args)}
+ emojiPickerID={report?.reportID}
+ shiftVertical={emojiShiftVertical}
/>
-
-
+ )}
+
+
{
interceptAnonymousUser(() => {
- hideProductTrainingTooltip();
navigateToQuickAction(isValidReport, `${quickActionReport?.reportID ?? CONST.DEFAULT_NUMBER_ID}`, quickAction, selectOption);
});
};
@@ -359,7 +350,6 @@ function FloatingActionButtonPopover(_: unknown, ref: ForwardedRef {
interceptAnonymousUser(() => {
- hideProductTrainingTooltip();
if (policyChatForActivePolicy?.policyID && shouldRestrictUserBillableActions(policyChatForActivePolicy.policyID)) {
Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(policyChatForActivePolicy.policyID));
return;
@@ -394,15 +384,12 @@ function FloatingActionButtonPopover(_: unknown, ref: ForwardedRef {
Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {hasCompletedGuidedSetupFlow: true});
await waitForBatchedUpdatesWithAct();
- const testTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.CONCEIRGE_LHN_GBR;
+ const testTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.EXPENSE_REPORTS_FILTER;
const {result, rerender} = renderHook(() => useProductTrainingContext(testTooltip), {wrapper});
// Then narrow layout tooltip should not show
expect(result.current.shouldShowProductTrainingTooltip).toBe(false);
@@ -244,7 +244,7 @@ describe('ProductTrainingContextProvider', () => {
// Then only highest priority tooltip should show
const highPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GLOBAL_CREATE_TOOLTIP;
- const lowPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SEARCH_FILTER_BUTTON_TOOLTIP;
+ const lowPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;
const {result} = renderHook(
() => ({
@@ -264,7 +264,7 @@ describe('ProductTrainingContextProvider', () => {
Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {hasCompletedGuidedSetupFlow: true});
const date = new Date();
const highPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GLOBAL_CREATE_TOOLTIP;
- const lowPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SEARCH_FILTER_BUTTON_TOOLTIP;
+ const lowPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;
Onyx.merge(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {
migratedUserWelcomeModal: DateUtils.getDBTime(date.valueOf()),
@@ -296,7 +296,7 @@ describe('ProductTrainingContextProvider', () => {
await waitForBatchedUpdatesWithAct();
const highPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GLOBAL_CREATE_TOOLTIP;
- const lowPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SEARCH_FILTER_BUTTON_TOOLTIP;
+ const lowPriorityTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;
const {result} = renderHook(
() => ({
From 5d0e706bded7692fd4abd6b2552094980ed84ae8 Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Thu, 6 Mar 2025 12:53:37 +0100
Subject: [PATCH 2/8] fix lint errors
---
src/components/AccountSwitcher.tsx | 26 +++++++++----------
.../LHNOptionsList/OptionRowLHN.tsx | 4 +--
.../ReportActionCompose.tsx | 4 ---
.../FloatingActionButtonAndPopover.tsx | 13 ----------
src/styles/variables.ts | 4 ++-
src/types/onyx/DismissedProductTraining.ts | 6 +++++
6 files changed, 23 insertions(+), 34 deletions(-)
diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx
index 27c8a0de246f..06bcab8cd191 100644
--- a/src/components/AccountSwitcher.tsx
+++ b/src/components/AccountSwitcher.tsx
@@ -10,11 +10,11 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import {clearDelegatorErrors, connect, disconnect} from '@libs/actions/Delegate';
-import * as EmojiUtils from '@libs/EmojiUtils';
-import * as ErrorUtils from '@libs/ErrorUtils';
-import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
+import {getProcessedText, splitTextWithEmojis} from '@libs/EmojiUtils';
+import {getLatestError} from '@libs/ErrorUtils';
+import {getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils';
import variables from '@styles/variables';
-import * as Modal from '@userActions/Modal';
+import {close} from '@userActions/Modal';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetails} from '@src/types/onyx';
@@ -49,7 +49,7 @@ function AccountSwitcher() {
const isActingAsDelegate = !!account?.delegatedAccess?.delegate ?? false;
const canSwitchAccounts = delegators.length > 0 || isActingAsDelegate;
- const processedTextArray = EmojiUtils.splitTextWithEmojis(currentUserPersonalDetails?.displayName);
+ const processedTextArray = splitTextWithEmojis(currentUserPersonalDetails?.displayName);
const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(
CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.ACCOUNT_SWITCHER,
@@ -93,14 +93,14 @@ function AccountSwitcher() {
return [currentUserMenuItem];
}
- const delegatePersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(delegateEmail);
- const error = ErrorUtils.getLatestError(account?.delegatedAccess?.errorFields?.disconnect);
+ const delegatePersonalDetails = getPersonalDetailByEmail(delegateEmail);
+ const error = getLatestError(account?.delegatedAccess?.errorFields?.disconnect);
return [
createBaseMenuItem(delegatePersonalDetails, error, {
onSelected: () => {
if (isOffline) {
- Modal.close(() => setShouldShowOfflineModal(true));
+ close(() => setShouldShowOfflineModal(true));
return;
}
disconnect();
@@ -114,13 +114,13 @@ function AccountSwitcher() {
.filter(({email}) => email !== currentUserPersonalDetails.login)
.map(({email, role}) => {
const errorFields = account?.delegatedAccess?.errorFields ?? {};
- const error = ErrorUtils.getLatestError(errorFields?.connect?.[email]);
- const personalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(email);
+ const error = getLatestError(errorFields?.connect?.[email]);
+ const personalDetails = getPersonalDetailByEmail(email);
return createBaseMenuItem(personalDetails, error, {
badgeText: translate('delegate.role', {role}),
onSelected: () => {
if (isOffline) {
- Modal.close(() => setShouldShowOfflineModal(true));
+ close(() => setShouldShowOfflineModal(true));
return;
}
connect(email);
@@ -161,9 +161,7 @@ function AccountSwitcher() {
numberOfLines={1}
style={[styles.textBold, styles.textLarge, styles.flexShrink1]}
>
- {processedTextArray.length !== 0
- ? EmojiUtils.getProcessedText(processedTextArray, styles.initialSettingsUsernameEmoji)
- : currentUserPersonalDetails?.displayName}
+ {processedTextArray.length !== 0 ? getProcessedText(processedTextArray, styles.initialSettingsUsernameEmoji) : currentUserPersonalDetails?.displayName}
{!!canSwitchAccounts && (
{}, opti
horizontal: shouldShowWokspaceChatTooltip ? CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT : CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
}}
- shiftHorizontal={shouldShowWokspaceChatTooltip ? variables.workspaceLHNtooltipShiftHorizontal : variables.gbrTooltipShiftHorizontal}
- shiftVertical={shouldShowWokspaceChatTooltip ? 0 : variables.composerTooltipShiftVertical}
+ shiftHorizontal={shouldShowWokspaceChatTooltip ? variables.workspaceLHNTooltipShiftHorizontal : variables.gbrTooltipShiftHorizontal}
+ shiftVertical={shouldShowWokspaceChatTooltip ? 0 : variables.gbrTooltipShiftVertical}
wrapperStyle={styles.productTrainingTooltipWrapper}
onTooltipPress={onOptionPress}
>
diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
index 802ba748ba7f..91ae01fa7551 100644
--- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
+++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
@@ -36,7 +36,6 @@ import willBlurTextInputOnTapOutsideFunc from '@libs/willBlurTextInputOnTapOutsi
import ParticipantLocalTime from '@pages/home/report/ParticipantLocalTime';
import ReportDropUI from '@pages/home/report/ReportDropUI';
import ReportTypingIndicator from '@pages/home/report/ReportTypingIndicator';
-import variables from '@styles/variables';
import {hideEmojiPicker, isActive as isActiveEmojiPickerAction} from '@userActions/EmojiPickerAction';
import {addAttachment as addAttachmentReportActions, setIsComposerFullSize} from '@userActions/Report';
import Timing from '@userActions/Timing';
@@ -83,9 +82,6 @@ type ReportActionComposeProps = Pick {
- hideCreateMenu();
- onSelected();
- },
shouldShowSubscriptRightAvatar: isPolicyExpenseChat(quickActionReport),
},
];
@@ -419,10 +412,6 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT
text: translate('quickAction.scanReceipt'),
description: getReportName(policyChatForActivePolicy),
onSelected,
- onEducationTooltipPress: () => {
- hideCreateMenu();
- onSelected();
- },
shouldShowSubscriptRightAvatar: true,
},
];
@@ -433,8 +422,6 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT
translate,
styles.pt3,
styles.pb2,
- styles.popoverMenuItem.paddingVertical,
- styles.productTrainingTooltipWrapper,
quickActionAvatars,
quickAction,
policyChatForActivePolicy,
diff --git a/src/styles/variables.ts b/src/styles/variables.ts
index 1014a5a5524a..24fc9026414f 100644
--- a/src/styles/variables.ts
+++ b/src/styles/variables.ts
@@ -260,14 +260,16 @@ export default {
searchTypeColumnWidth: 52,
gbrTooltipShiftHorizontal: -15,
+ gbrTooltipShiftVertical: -10,
fabTooltipShiftHorizontal: -11,
- workspaceLHNtooltipShiftHorizontal: 23,
+ workspaceLHNTooltipShiftHorizontal: 23,
savedSearchShiftHorizontal: -10,
savedSearchShiftVertical: 6,
bottomTabInboxTooltipShiftHorizontal: 36,
expenseReportsTypeTooltipShiftHorizontal: 10,
accountSwitcherTooltipShiftVertical: 5,
+
inlineImagePreviewMinSize: 64,
inlineImagePreviewMaxSize: 148,
diff --git a/src/types/onyx/DismissedProductTraining.ts b/src/types/onyx/DismissedProductTraining.ts
index b0d6ee562c0c..be64eedda823 100644
--- a/src/types/onyx/DismissedProductTraining.ts
+++ b/src/types/onyx/DismissedProductTraining.ts
@@ -9,6 +9,7 @@ const {
SCAN_TEST_TOOLTIP,
SCAN_TEST_TOOLTIP_MANAGER,
SCAN_TEST_CONFIRMATION,
+ EXPENSE_REPORTS_FILTER,
} = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES;
/**
* This type is used to store the timestamp of when the user dismisses a product training ui elements.
@@ -60,6 +61,11 @@ type DismissedProductTraining = {
* When user dismisses the test manager on confirmantion page product training tooltip, we store the timestamp here.
*/
[SCAN_TEST_CONFIRMATION]: string;
+
+ /**
+ * When user dismisses the expenseReportsFilter product training tooltip, we store the timestamp here.
+ */
+ [EXPENSE_REPORTS_FILTER]: string;
};
export default DismissedProductTraining;
From 3c7462587a2a7e263c4657e0c30b03b41a19259b Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Thu, 6 Mar 2025 12:55:17 +0100
Subject: [PATCH 3/8] fix test
---
tests/ui/components/ProductTrainingContextProvider.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/ui/components/ProductTrainingContextProvider.tsx b/tests/ui/components/ProductTrainingContextProvider.tsx
index 2e91f0ab7ace..ad9c165fae90 100644
--- a/tests/ui/components/ProductTrainingContextProvider.tsx
+++ b/tests/ui/components/ProductTrainingContextProvider.tsx
@@ -200,7 +200,7 @@ describe('ProductTrainingContextProvider', () => {
const testTooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.EXPENSE_REPORTS_FILTER;
const {result, rerender} = renderHook(() => useProductTrainingContext(testTooltip), {wrapper});
// Then narrow layout tooltip should not show
- expect(result.current.shouldShowProductTrainingTooltip).toBe(false);
+ expect(result.current.shouldShowProductTrainingTooltip).toBe(true);
// When narrow layout changes to true
mockUseResponsiveLayout.mockReturnValue({...DEFAULT_USE_RESPONSIVE_LAYOUT_VALUE, shouldUseNarrowLayout: true});
@@ -208,7 +208,7 @@ describe('ProductTrainingContextProvider', () => {
await waitForBatchedUpdatesWithAct();
// Then narrow layout tooltip should show
- expect(result.current.shouldShowProductTrainingTooltip).toBe(true);
+ expect(result.current.shouldShowProductTrainingTooltip).toBe(false);
});
it('should handle wide layout specific tooltips based on screen width', async () => {
// When narrow layout is true
From e641b0497350cdb0f098fa37a1f056091ced7388 Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Thu, 6 Mar 2025 12:59:47 +0100
Subject: [PATCH 4/8] fix lint errors
---
src/components/AccountSwitcher.tsx | 2 +-
src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx | 1 -
src/styles/variables.ts | 1 -
3 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx
index 06bcab8cd191..a8e4d3e280b3 100644
--- a/src/components/AccountSwitcher.tsx
+++ b/src/components/AccountSwitcher.tsx
@@ -65,7 +65,7 @@ function AccountSwitcher() {
return {
text: personalDetails?.displayName ?? personalDetails?.login ?? '',
description: Str.removeSMSDomain(personalDetails?.login ?? ''),
- avatarID: personalDetails?.accountID ?? -1,
+ avatarID: personalDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID,
icon: personalDetails?.avatar ?? '',
iconType: CONST.ICON_TYPE_AVATAR,
outerWrapperStyle: shouldUseNarrowLayout ? {} : styles.accountSwitcherPopover,
diff --git a/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx
index f8363d682cab..731c3a15b705 100644
--- a/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx
+++ b/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx
@@ -431,7 +431,6 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT
hideQABSubtitle,
isValidReport,
selectOption,
- hideCreateMenu,
]);
const viewTourTaskReportID = introSelected?.viewTour;
diff --git a/src/styles/variables.ts b/src/styles/variables.ts
index 24fc9026414f..4efb8be2c2ea 100644
--- a/src/styles/variables.ts
+++ b/src/styles/variables.ts
@@ -269,7 +269,6 @@ export default {
expenseReportsTypeTooltipShiftHorizontal: 10,
accountSwitcherTooltipShiftVertical: 5,
-
inlineImagePreviewMinSize: 64,
inlineImagePreviewMaxSize: 148,
From 9418fe6219ec3f54e8fc9f8d2155baf4bc3e3d93 Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Thu, 6 Mar 2025 13:06:21 +0100
Subject: [PATCH 5/8] fix lint errors
---
src/pages/home/report/ReportFooter.tsx | 6 ------
src/types/onyx/DismissedProductTraining.ts | 12 ++++++++++++
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx
index a11d2052a0d9..1fb71405f5f8 100644
--- a/src/pages/home/report/ReportFooter.tsx
+++ b/src/pages/home/report/ReportFooter.tsx
@@ -15,7 +15,6 @@ import SwipeableView from '@components/SwipeableView';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
-import useScreenWrapperTranstionStatus from '@hooks/useScreenWrapperTransitionStatus';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import {addComment} from '@libs/actions/Report';
@@ -28,7 +27,6 @@ import {
canWriteInReport as canWriteInReportUtil,
isAdminsOnlyPostingRoom as isAdminsOnlyPostingRoomUtil,
isArchivedNonExpenseReport,
- isPolicyExpenseChat,
isPublicRoom,
isSystemChat as isSystemChatUtil,
} from '@libs/ReportUtils';
@@ -86,7 +84,6 @@ function ReportFooter({
const {translate} = useLocalize();
const {windowWidth} = useWindowDimensions();
const {shouldUseNarrowLayout} = useResponsiveLayout();
- const {didScreenTransitionEnd} = useScreenWrapperTranstionStatus();
const [shouldShowComposeInput] = useOnyx(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT, {initialValue: false});
const [isAnonymousUser = false] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.authTokenType === CONST.AUTH_TOKEN_TYPES.ANONYMOUS});
@@ -120,8 +117,6 @@ function ReportFooter({
const isAdminsOnlyPostingRoom = isAdminsOnlyPostingRoomUtil(report);
const isUserPolicyAdmin = isPolicyAdmin(policy);
- const shouldShowEducationalTooltip = isPolicyExpenseChat(report) && !!report.isOwnPolicyExpenseChat;
-
const allPersonalDetails = usePersonalDetails();
const handleCreateTask = useCallback(
@@ -228,7 +223,6 @@ function ReportFooter({
pendingAction={pendingAction}
isComposerFullSize={isComposerFullSize}
isReportReadyForDisplay={isReportReadyForDisplay}
- shouldShowEducationalTooltip={didScreenTransitionEnd && shouldShowEducationalTooltip}
didHideComposerInput={didHideComposerInput}
/>
diff --git a/src/types/onyx/DismissedProductTraining.ts b/src/types/onyx/DismissedProductTraining.ts
index be64eedda823..2ab942bedf50 100644
--- a/src/types/onyx/DismissedProductTraining.ts
+++ b/src/types/onyx/DismissedProductTraining.ts
@@ -10,6 +10,8 @@ const {
SCAN_TEST_TOOLTIP_MANAGER,
SCAN_TEST_CONFIRMATION,
EXPENSE_REPORTS_FILTER,
+ ACCOUNT_SWITCHER,
+ GBR_RBR_CHAT,
} = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES;
/**
* This type is used to store the timestamp of when the user dismisses a product training ui elements.
@@ -66,6 +68,16 @@ type DismissedProductTraining = {
* When user dismisses the expenseReportsFilter product training tooltip, we store the timestamp here.
*/
[EXPENSE_REPORTS_FILTER]: string;
+
+ /**
+ * When user dismisses the accountSwitcher product training tooltip, we store the timestamp here.
+ */
+ [ACCOUNT_SWITCHER]: string;
+
+ /**
+ * When user dismisses the gbrRbrChat product training tooltip, we store the timestamp here.
+ */
+ [GBR_RBR_CHAT]: string;
};
export default DismissedProductTraining;
From 6353eb40576ad25bb4920d5acf6a49eeeaf3465f Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Fri, 7 Mar 2025 16:21:33 +0100
Subject: [PATCH 6/8] fix lint error
---
src/pages/Search/SearchTypeMenu.tsx | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/pages/Search/SearchTypeMenu.tsx b/src/pages/Search/SearchTypeMenu.tsx
index 0090049ee3ae..bc4b92861c61 100644
--- a/src/pages/Search/SearchTypeMenu.tsx
+++ b/src/pages/Search/SearchTypeMenu.tsx
@@ -125,9 +125,6 @@ function SearchTypeMenu({queryJSON, shouldGroupByReports}: SearchTypeMenuProps)
personalDetails,
reports,
taxRates,
- shouldShowProductTrainingTooltip,
- hideProductTrainingTooltip,
- renderProductTrainingTooltip,
cardFeedNamesWithType,
],
);
From 69c20d4fd4fa80e7b35b33d28e2f6070dde31072 Mon Sep 17 00:00:00 2001
From: Rayane <77965000+rayane-d@users.noreply.github.com>
Date: Thu, 13 Mar 2025 16:19:39 +0100
Subject: [PATCH 7/8] update account switcher tooltip
---
src/components/AccountSwitcher.tsx | 104 +++++++++++++++--------------
src/styles/variables.ts | 3 +-
2 files changed, 55 insertions(+), 52 deletions(-)
diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx
index a8e4d3e280b3..ea4eec229056 100644
--- a/src/components/AccountSwitcher.tsx
+++ b/src/components/AccountSwitcher.tsx
@@ -138,44 +138,45 @@ function AccountSwitcher() {
return (
<>
-
-
-
-
-
-
- {processedTextArray.length !== 0 ? getProcessedText(processedTextArray, styles.initialSettingsUsernameEmoji) : currentUserPersonalDetails?.displayName}
-
- {!!canSwitchAccounts && (
-
+
+
+
+
+
+ {processedTextArray.length !== 0 ? getProcessedText(processedTextArray, styles.initialSettingsUsernameEmoji) : currentUserPersonalDetails?.displayName}
+
+ {!!canSwitchAccounts && (
-
- )}
-
-
- {Str.removeSMSDomain(currentUserPersonalDetails?.login ?? '')}
-
- {!!user?.isDebugModeEnabled && (
+ )}
+
- AccountID: {session?.accountID}
+ {Str.removeSMSDomain(currentUserPersonalDetails?.login ?? '')}
- )}
+ {!!user?.isDebugModeEnabled && (
+
+ AccountID: {session?.accountID}
+
+ )}
+
-
-
+
+
+
{!!canSwitchAccounts && (
Date: Thu, 13 Mar 2025 17:56:39 +0100
Subject: [PATCH 8/8] add GBR_RBR_CHAT tooltip
---
src/CONST.ts | 2 +-
.../LHNOptionsList/LHNOptionsList.tsx | 30 +++++++++++++++++--
.../LHNOptionsList/OptionRowLHN.tsx | 30 +++++++++++++++----
src/components/LHNOptionsList/types.ts | 6 ++++
src/languages/en.ts | 2 +-
src/languages/es.ts | 2 +-
6 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/src/CONST.ts b/src/CONST.ts
index 0cb74d563d50..87ce66a5d208 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -6796,7 +6796,7 @@ const CONST = {
SCAN_TEST_TOOLTIP_MANAGER: 'scanTestTooltipManager',
SCAN_TEST_CONFIRMATION: 'scanTestConfirmation',
EXPENSE_REPORTS_FILTER: 'expenseReportsFilter',
- GBR_RBR_CHAT: 'GBRRBRChat',
+ GBR_RBR_CHAT: 'chatGBRRBR',
ACCOUNT_SWITCHER: 'accountSwitcher',
},
SMART_BANNER_HEIGHT: 152,
diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx
index 6479478fef58..c537068aa9ae 100644
--- a/src/components/LHNOptionsList/LHNOptionsList.tsx
+++ b/src/components/LHNOptionsList/LHNOptionsList.tsx
@@ -9,6 +9,7 @@ import BlockingView from '@components/BlockingViews/BlockingView';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import LottieAnimations from '@components/LottieAnimations';
+import {useProductTrainingContext} from '@components/ProductTrainingContext';
import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider';
import TextBlock from '@components/TextBlock';
import useLHNEstimatedListSize from '@hooks/useLHNEstimatedListSize';
@@ -20,9 +21,9 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {isValidDraftComment} from '@libs/DraftCommentUtils';
import getPlatform from '@libs/getPlatform';
-import {getIOUReportIDOfLastAction, getLastMessageTextForReport} from '@libs/OptionsListUtils';
+import {getIOUReportIDOfLastAction, getLastMessageTextForReport, hasReportErrors} from '@libs/OptionsListUtils';
import {getOneTransactionThreadReportID, getOriginalMessage, getSortedReportActionsForDisplay, isMoneyRequestAction} from '@libs/ReportActionsUtils';
-import {canUserPerformWriteAction} from '@libs/ReportUtils';
+import {canUserPerformWriteAction, requiresAttentionFromCurrentUser} from '@libs/ReportUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -57,6 +58,27 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
const platform = getPlatform();
const isWebOrDesktop = platform === CONST.PLATFORM.WEB || platform === CONST.PLATFORM.DESKTOP;
+ const {shouldShowProductTrainingTooltip} = useProductTrainingContext(CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GBR_RBR_CHAT, true);
+ const firstReportIDWithGBRorRGR = useMemo(() => {
+ if (!shouldShowProductTrainingTooltip) {
+ return undefined;
+ }
+ return data.find((reportID) => {
+ const itemFullReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
+ const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`];
+ if (!itemFullReport) {
+ return false;
+ }
+ if (hasReportErrors(itemFullReport, itemReportActions)) {
+ return true;
+ }
+ const itemParentReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport?.parentReportID}`];
+ const itemParentReportAction = itemFullReport?.parentReportActionID ? itemParentReportActions?.[itemFullReport?.parentReportActionID] : undefined;
+ const hasGBR = requiresAttentionFromCurrentUser(itemFullReport, itemParentReportAction);
+ return hasGBR;
+ });
+ }, [shouldShowProductTrainingTooltip, data, reportActions, reports]);
+
// When the first item renders we want to call the onFirstItemRendered callback.
// At this point in time we know that the list is actually displaying items.
const hasCalledOnLayout = React.useRef(false);
@@ -179,6 +201,8 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
}
const lastMessageTextFromReport = getLastMessageTextForReport(itemFullReport, lastActorDetails, itemPolicy);
+ const shouldShowRBRorGPRTooltip = firstReportIDWithGBRorRGR === reportID;
+
return (
);
},
@@ -220,6 +245,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
transactionViolations,
onLayoutItem,
isOffline,
+ firstReportIDWithGBRorRGR,
],
);
diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx
index b622edd10168..90d1e6544997 100644
--- a/src/components/LHNOptionsList/OptionRowLHN.tsx
+++ b/src/components/LHNOptionsList/OptionRowLHN.tsx
@@ -12,6 +12,7 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {useSession} from '@components/OnyxProvider';
import PressableWithSecondaryInteraction from '@components/PressableWithSecondaryInteraction';
import {useProductTrainingContext} from '@components/ProductTrainingContext';
+import type {ProductTrainingTooltipName} from '@components/ProductTrainingContext/TOOLTIPS';
import SubscriptAvatar from '@components/SubscriptAvatar';
import Text from '@components/Text';
import Tooltip from '@components/Tooltip';
@@ -49,7 +50,17 @@ import ONYXKEYS from '@src/ONYXKEYS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type {OptionRowLHNProps} from './types';
-function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, optionItem, viewMode = 'default', style, onLayout = () => {}, hasDraftComment}: OptionRowLHNProps) {
+function OptionRowLHN({
+ reportID,
+ isFocused = false,
+ onSelectRow = () => {},
+ optionItem,
+ viewMode = 'default',
+ style,
+ onLayout = () => {},
+ hasDraftComment,
+ shouldShowRBRorGPRTooltip,
+}: OptionRowLHNProps) {
const theme = useTheme();
const styles = useThemeStyles();
const popoverAnchor = useRef(null);
@@ -69,16 +80,23 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
const isReportsSplitNavigatorLast = useRootNavigationState((state) => state?.routes?.at(-1)?.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR);
- // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
- // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
const {tooltipToRender, shouldShowTooltip} = useMemo(() => {
- const tooltip = shouldShowGetStartedTooltip ? CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.CONCEIRGE_LHN_GBR : CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;
- const shouldShowTooltips = shouldShowWokspaceChatTooltip || shouldShowGetStartedTooltip;
+ let tooltip: ProductTrainingTooltipName;
+ // TODO: CONCEIRGE_LHN_GBR tooltip will be replaced by a tooltip in the #admins room
+ // https://github.com/Expensify/App/issues/57045#issuecomment-2701455668
+ tooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.CONCEIRGE_LHN_GBR;
+ if (shouldShowWokspaceChatTooltip) {
+ tooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;
+ }
+ if (shouldShowRBRorGPRTooltip) {
+ tooltip = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GBR_RBR_CHAT;
+ }
+ const shouldShowTooltips = shouldShowRBRorGPRTooltip || shouldShowWokspaceChatTooltip || shouldShowGetStartedTooltip;
const shouldTooltipBeVisible = shouldUseNarrowLayout ? isScreenFocused && isReportsSplitNavigatorLast : isReportsSplitNavigatorLast && !isFullscreenVisible;
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
return {tooltipToRender: tooltip, shouldShowTooltip: shouldShowTooltips && shouldTooltipBeVisible};
- }, [shouldShowGetStartedTooltip, shouldShowWokspaceChatTooltip, isScreenFocused, shouldUseNarrowLayout, isReportsSplitNavigatorLast, isFullscreenVisible]);
+ }, [shouldShowRBRorGPRTooltip, shouldShowGetStartedTooltip, shouldShowWokspaceChatTooltip, isScreenFocused, shouldUseNarrowLayout, isReportsSplitNavigatorLast, isFullscreenVisible]);
const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(tooltipToRender, shouldShowTooltip);
diff --git a/src/components/LHNOptionsList/types.ts b/src/components/LHNOptionsList/types.ts
index 597523dd522a..e631b537e134 100644
--- a/src/components/LHNOptionsList/types.ts
+++ b/src/components/LHNOptionsList/types.ts
@@ -102,6 +102,9 @@ type OptionRowLHNDataProps = {
/** Callback to execute when the OptionList lays out */
onLayout?: (event: LayoutChangeEvent) => void;
+
+ /** Whether to show the educational tooltip for the GBR or RBR */
+ shouldShowRBRorGPRTooltip: boolean;
};
type OptionRowLHNProps = {
@@ -127,6 +130,9 @@ type OptionRowLHNProps = {
hasDraftComment: boolean;
onLayout?: (event: LayoutChangeEvent) => void;
+
+ /** Whether to show the educational tooltip on the GBR or RBR */
+ shouldShowRBRorGPRTooltip: boolean;
};
type RenderItemProps = {item: string};
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 40210be6cd66..0f95ea47bafc 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -5985,7 +5985,7 @@ const translations = {
GBRRBRChat: {
part1: 'You’ll see 🟢 on ',
part2: 'actions to take',
- part3: ', and 🔴 on ',
+ part3: ',\nand 🔴 on ',
part4: 'errors to review.',
},
expenseReportsFilter: {
diff --git a/src/languages/es.ts b/src/languages/es.ts
index b58d2627697b..f1172c7c73ff 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -6512,7 +6512,7 @@ const translations = {
GBRRBRChat: {
part1: 'Verás 🟢 en ',
part2: 'acciones a realizar',
- part3: ', y 🔴 en ',
+ part3: ',\ny 🔴 en ',
part4: 'errores para revisar.',
},
accountSwitcher: {