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

Add manager mctest tooltips to create expense flow #57480

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6699,6 +6699,8 @@ const CONST = {
LHN_WORKSPACE_CHAT_TOOLTIP: 'workspaceChatLHNTooltip',
GLOBAL_CREATE_TOOLTIP: 'globalCreateTooltip',
SCAN_TEST_TOOLTIP: 'scanTestTooltip',
SCAN_TEST_TOOLTIP_MANAGER: 'scanTestTooltipManager',
SCAN_TEST_CONFIRMATION: 'scanTestConfirmation',
},
SMART_BANNER_HEIGHT: 152,

Expand Down
41 changes: 38 additions & 3 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import {calculateAmount, insertTagIntoTransactionTagsString, isMovingTransaction
import Log from '@libs/Log';
import {validateAmount} from '@libs/MoneyRequestUtils';
import Navigation from '@libs/Navigation/Navigation';
import {getIOUConfirmationOptionsFromPayeePersonalDetail, hasEnabledOptions} from '@libs/OptionsListUtils';
import {getIOUConfirmationOptionsFromPayeePersonalDetail, hasEnabledOptions, isSelectedManagerMcTest} from '@libs/OptionsListUtils';
import Permissions from '@libs/Permissions';
import {getDistanceRateCustomUnitRate, getTagLists, isTaxTrackingEnabled} from '@libs/PolicyUtils';
import type {OptionData} from '@libs/ReportUtils';
import playSound, {SOUNDS} from '@libs/Sound';
Expand Down Expand Up @@ -65,11 +66,13 @@ import FormHelpMessage from './FormHelpMessage';
import MoneyRequestAmountInput from './MoneyRequestAmountInput';
import MoneyRequestConfirmationListFooter from './MoneyRequestConfirmationListFooter';
import {PressableWithFeedback} from './Pressable';
import {useProductTrainingContext} from './ProductTrainingContext';
import SelectionList from './SelectionList';
import type {SectionListDataType} from './SelectionList/types';
import UserListItem from './SelectionList/UserListItem';
import SettlementButton from './SettlementButton';
import Text from './Text';
import EducationalTooltip from './Tooltip/EducationalTooltip';

type MoneyRequestConfirmationListProps = {
/** Callback to inform parent modal of success */
Expand Down Expand Up @@ -215,6 +218,11 @@ function MoneyRequestConfirmationList({
const [policyCategoriesDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT}${policyID}`);
const [lastSelectedDistanceRates] = useOnyx(ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES);
const [currencyList] = useOnyx(ONYXKEYS.CURRENCY_LIST);
const [betas] = useOnyx(ONYXKEYS.BETAS);
const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip} = useProductTrainingContext(
CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_CONFIRMATION,
Permissions.canUseManagerMcTest(betas) && selectedParticipantsProp.some((participant) => isSelectedManagerMcTest(participant.login)),
);

const policy = policyReal ?? policyDraft;
const policyCategories = policyCategoriesReal ?? policyCategoriesDraft;
Expand Down Expand Up @@ -967,10 +975,37 @@ function MoneyRequestConfirmationList({
/>
)}

{button}
<EducationalTooltip
shouldRender={shouldShowProductTrainingTooltip}
renderTooltipContent={renderProductTrainingTooltip}
anchorAlignment={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
}}
wrapperStyle={styles.productTrainingTooltipWrapper}
shouldHideOnNavigate
shiftVertical={-10}
>
<View>{button}</View>
</EducationalTooltip>
</>
);
}, [isReadOnly, iouType, confirm, isConfirmed, bankAccountRoute, iouCurrencyCode, policyID, splitOrRequestOptions, styles.ph1, styles.mb2, errorMessage]);
}, [
isReadOnly,
iouType,
confirm,
bankAccountRoute,
iouCurrencyCode,
policyID,
isConfirmed,
splitOrRequestOptions,
errorMessage,
styles.ph1,
styles.mb2,
styles.productTrainingTooltipWrapper,
shouldShowProductTrainingTooltip,
renderProductTrainingTooltip,
]);

const listFooterContent = (
<MoneyRequestConfirmationListFooter
Expand Down
28 changes: 23 additions & 5 deletions src/components/ProductTrainingContext/TOOLTIPS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const {
LHN_WORKSPACE_CHAT_TOOLTIP,
GLOBAL_CREATE_TOOLTIP,
SCAN_TEST_TOOLTIP,
SCAN_TEST_TOOLTIP_MANAGER,
SCAN_TEST_CONFIRMATION,
} = CONST.PRODUCT_TRAINING_TOOLTIP_NAMES;

type ProductTrainingTooltipName = ValueOf<typeof CONST.PRODUCT_TRAINING_TOOLTIP_NAMES>;
Expand Down Expand Up @@ -119,18 +121,34 @@ const TOOLTIPS: Record<ProductTrainingTooltipName, TooltipData> = {
content: [
{text: 'productTrainingTooltip.scanTestTooltip.part1', isBold: false},
{text: 'productTrainingTooltip.scanTestTooltip.part2', isBold: true},
],
onHideTooltip: () => dismissProductTraining(SCAN_TEST_TOOLTIP),
name: SCAN_TEST_TOOLTIP,
priority: 900,
shouldShow: () => true,
shouldRenderActionButtons: true,
},
[SCAN_TEST_TOOLTIP_MANAGER]: {
content: [
{text: 'productTrainingTooltip.scanTestTooltip.part3', isBold: false},
{text: 'productTrainingTooltip.scanTestTooltip.part4', isBold: true},
{text: 'productTrainingTooltip.scanTestTooltip.part5', isBold: false},
],
onHideTooltip: () => dismissProductTraining(SCAN_TEST_TOOLTIP_MANAGER),
name: SCAN_TEST_TOOLTIP_MANAGER,
priority: 1000,
shouldShow: () => true,
},
[SCAN_TEST_CONFIRMATION]: {
content: [
{text: 'productTrainingTooltip.scanTestTooltip.part6', isBold: false},
{text: 'productTrainingTooltip.scanTestTooltip.part7', isBold: true},
{text: 'productTrainingTooltip.scanTestTooltip.part8', isBold: false},
],
onHideTooltip: () => dismissProductTraining(SCAN_TEST_TOOLTIP),
name: SCAN_TEST_TOOLTIP,
priority: 900,
shouldShow: () => false,
shouldRenderActionButtons: true,
onHideTooltip: () => dismissProductTraining(SCAN_TEST_CONFIRMATION),
name: SCAN_TEST_CONFIRMATION,
priority: 1100,
shouldShow: () => true,
},
};

Expand Down
13 changes: 10 additions & 3 deletions src/components/ProductTrainingContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,13 @@ function ProductTrainingContextProvider({children}: ChildrenProps) {
}

// 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
if (tooltipName !== CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.QUICK_ACTION_BUTTON && isModalVisible) {
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 &&
isModalVisible
) {
return false;
}

Expand Down Expand Up @@ -211,7 +217,7 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou
</Text>
</View>
{!!tooltip?.shouldRenderActionButtons && (
<View style={[styles.alignItemsCenter, styles.justifyContentBetween, styles.flexRow, styles.ph1, styles.pb1]}>
<View style={[styles.alignItemsCenter, styles.justifyContentBetween, styles.flexRow, styles.ph1, styles.pb2, styles.pt1]}>
<Button
success
text={translate('productTrainingTooltip.scanTestTooltip.tryItOut')}
Expand All @@ -235,9 +241,10 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou
styles.justifyContentCenter,
styles.mw100,
styles.p2,
styles.pb1,
styles.pb2,
styles.ph1,
styles.productTrainingTooltipText,
styles.pt1,
styles.textAlignCenter,
styles.textBold,
styles.textWrap,
Expand Down
132 changes: 77 additions & 55 deletions src/components/SelectionList/InviteMemberListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import {Str} from 'expensify-common';
import React, {useCallback} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import {FallbackAvatar} from '@components/Icon/Expensicons';
import MultipleAvatars from '@components/MultipleAvatars';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import {useProductTrainingContext} from '@components/ProductTrainingContext';
import SelectCircle from '@components/SelectCircle';
import SubscriptAvatar from '@components/SubscriptAvatar';
import Text from '@components/Text';
import TextWithTooltip from '@components/TextWithTooltip';
import EducationalTooltip from '@components/Tooltip/EducationalTooltip';
import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {getIsUserSubmittedExpenseOrScannedReceipt, isSelectedManagerMcTest} from '@libs/OptionsListUtils';
import Permissions from '@libs/Permissions';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Icon} from '@src/types/onyx/OnyxCommon';
import BaseListItem from './BaseListItem';
import type {InviteMemberListItemProps, ListItem} from './types';
Expand Down Expand Up @@ -42,6 +48,11 @@ function InviteMemberListItem<TItem extends ListItem>({
const theme = useTheme();
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
const [betas] = useOnyx(ONYXKEYS.BETAS);
const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip} = useProductTrainingContext(
CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_TOOLTIP_MANAGER,
!getIsUserSubmittedExpenseOrScannedReceipt() && Permissions.canUseManagerMcTest(betas) && isSelectedManagerMcTest(item.login),
);

const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;
const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar;
Expand Down Expand Up @@ -84,64 +95,75 @@ function InviteMemberListItem<TItem extends ListItem>({
shouldDisplayRBR={!shouldShowCheckBox}
>
{(hovered?: boolean) => (
<>
{!!item.icons &&
(item.shouldShowSubscript ? (
<SubscriptAvatar
mainAvatar={item.icons.at(0) ?? fallbackIcon}
secondaryAvatar={item.icons.at(1)}
showTooltip={showTooltip}
backgroundColor={hovered && !isFocused ? hoveredBackgroundColor : subscriptAvatarBorderColor}
/>
) : (
<MultipleAvatars
icons={item.icons}
shouldShowTooltip={showTooltip}
secondAvatarStyle={[
StyleUtils.getBackgroundAndBorderStyle(theme.sidebar),
isFocused ? StyleUtils.getBackgroundAndBorderStyle(focusedBackgroundColor) : undefined,
hovered && !isFocused ? StyleUtils.getBackgroundAndBorderStyle(hoveredBackgroundColor) : undefined,
]}
/>
))}
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsStretch, styles.optionRow]}>
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={Str.removeSMSDomain(item.text ?? '')}
style={[
styles.optionDisplayName,
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
item.isBold !== false && styles.sidebarLinkTextBold,
styles.pre,
item.alternateText ? styles.mb1 : null,
]}
/>
<EducationalTooltip
shouldRender={shouldShowProductTrainingTooltip}
renderTooltipContent={renderProductTrainingTooltip}
anchorAlignment={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
}}
shouldHideOnNavigate
wrapperStyle={styles.productTrainingTooltipWrapper}
>
<View style={[styles.flexRow, styles.alignItemsCenter, styles.flex1]}>
{!!item.icons &&
(item.shouldShowSubscript ? (
<SubscriptAvatar
mainAvatar={item.icons.at(0) ?? fallbackIcon}
secondaryAvatar={item.icons.at(1)}
showTooltip={showTooltip}
backgroundColor={hovered && !isFocused ? hoveredBackgroundColor : subscriptAvatarBorderColor}
/>
) : (
<MultipleAvatars
icons={item.icons}
shouldShowTooltip={showTooltip}
secondAvatarStyle={[
StyleUtils.getBackgroundAndBorderStyle(theme.sidebar),
isFocused ? StyleUtils.getBackgroundAndBorderStyle(focusedBackgroundColor) : undefined,
hovered && !isFocused ? StyleUtils.getBackgroundAndBorderStyle(hoveredBackgroundColor) : undefined,
]}
/>
))}
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsStretch, styles.optionRow]}>
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={Str.removeSMSDomain(item.text ?? '')}
style={[
styles.optionDisplayName,
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
item.isBold !== false && styles.sidebarLinkTextBold,
styles.pre,
item.alternateText ? styles.mb1 : null,
]}
/>
</View>
{!!item.alternateText && (
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={Str.removeSMSDomain(item.alternateText ?? '')}
style={[styles.textLabelSupporting, styles.lh16, styles.pre]}
/>
)}
</View>
{!!item.alternateText && (
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={Str.removeSMSDomain(item.alternateText ?? '')}
style={[styles.textLabelSupporting, styles.lh16, styles.pre]}
/>
{!!item.rightElement && item.rightElement}
{!!shouldShowCheckBox && (
<PressableWithFeedback
onPress={handleCheckboxPress}
disabled={isDisabled}
role={CONST.ROLE.BUTTON}
accessibilityLabel={item.text ?? ''}
style={[styles.ml2, styles.optionSelectCircle]}
>
<SelectCircle
isChecked={item.isSelected ?? false}
selectCircleStyles={styles.ml0}
/>
</PressableWithFeedback>
)}
</View>
{!!item.rightElement && item.rightElement}
{!!shouldShowCheckBox && (
<PressableWithFeedback
onPress={handleCheckboxPress}
disabled={isDisabled}
role={CONST.ROLE.BUTTON}
accessibilityLabel={item.text ?? ''}
style={[styles.ml2, styles.optionSelectCircle]}
>
<SelectCircle
isChecked={item.isSelected ?? false}
selectCircleStyles={styles.ml0}
/>
</PressableWithFeedback>
)}
</>
</EducationalTooltip>
)}
</BaseListItem>
);
Expand Down
Loading