diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 0974a9b1df66..39eaed735a46 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -7582,6 +7582,56 @@ const CONST = { REPORTS: 'NavigationTabBar-Reports', WORKSPACES: 'NavigationTabBar-Workspaces', ACCOUNT: 'NavigationTabBar-Account', + FLOATING_ACTION_BUTTON: 'NavigationTabBar-FloatingActionButton', + FLOATING_RECEIPT_BUTTON: 'NavigationTabBar-FloatingReceiptButton', + }, + FAB_MENU: { + CREATE_EXPENSE: 'FABMenu-CreateExpense', + TRACK_DISTANCE: 'FABMenu-TrackDistance', + CREATE_REPORT: 'FABMenu-CreateReport', + START_CHAT: 'FABMenu-StartChat', + SEND_INVOICE: 'FABMenu-SendInvoice', + BOOK_TRAVEL: 'FABMenu-BookTravel', + TEST_DRIVE: 'FABMenu-TestDrive', + NEW_WORKSPACE: 'FABMenu-NewWorkspace', + QUICK_ACTION: 'FABMenu-QuickAction', + }, + ATTACHMENT_CAROUSEL: { + PREVIOUS_BUTTON: 'AttachmentCarousel-PreviousButton', + NEXT_BUTTON: 'AttachmentCarousel-NextButton', + ITEM: 'AttachmentCarousel-Item', + MODERATION_BUTTON: 'AttachmentCarousel-ModerationButton', + RETRY_BUTTON: 'AttachmentView-RetryButton', + }, + ATTACHMENT_MODAL: { + SEND_BUTTON: 'AttachmentModal-SendButton', + IMAGE_ZOOM: 'AttachmentModal-ImageZoom', + }, + HEADER: { + BACK_BUTTON: 'Header-BackButton', + DOWNLOAD_BUTTON: 'Header-DownloadButton', + CLOSE_BUTTON: 'Header-CloseButton', + MORE_BUTTON: 'Header-MoreButton', + }, + VIDEO_PLAYER: { + PLAY_PAUSE_BUTTON: 'VideoPlayer-PlayPauseButton', + FULLSCREEN_BUTTON: 'VideoPlayer-FullscreenButton', + MORE_BUTTON: 'VideoPlayer-MoreButton', + EXPAND_BUTTON: 'VideoPlayer-ExpandButton', + THUMBNAIL: 'VideoPlayer-Thumbnail', + MUTE_BUTTON: 'VideoPlayer-MuteButton', + VIDEO: 'VideoPlayer-Video', + }, + HTML_RENDERER: { + IMAGE: 'HTMLRenderer-Image', + }, + RECEIPT: { + IMAGE: 'Receipt-Image', + }, + RECEIPT_MODAL: { + REPLACE_RECEIPT: 'ReceiptModal-ReplaceReceipt', + DOWNLOAD_RECEIPT: 'ReceiptModal-DownloadReceipt', + DELETE_RECEIPT: 'ReceiptModal-DeleteReceipt', }, HEADER_VIEW: { BACK_BUTTON: 'HeaderView-BackButton', diff --git a/src/components/Attachments/AttachmentCarousel/CarouselButtons.tsx b/src/components/Attachments/AttachmentCarousel/CarouselButtons.tsx index 01595c58f732..00a086c6f0f7 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselButtons.tsx +++ b/src/components/Attachments/AttachmentCarousel/CarouselButtons.tsx @@ -8,6 +8,7 @@ import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; type CarouselButtonsProps = { /** Where the arrows should be visible */ @@ -53,6 +54,7 @@ function CarouselButtons({page, attachments, shouldShowArrows, onBack, onForward onPress={onBack} onPressIn={cancelAutoHideArrow} onPressOut={autoHideArrow} + sentryLabel={CONST.SENTRY_LABEL.ATTACHMENT_CAROUSEL.PREVIOUS_BUTTON} /> @@ -68,6 +70,7 @@ function CarouselButtons({page, attachments, shouldShowArrows, onBack, onForward onPress={onForward} onPressIn={cancelAutoHideArrow} onPressOut={autoHideArrow} + sentryLabel={CONST.SENTRY_LABEL.ATTACHMENT_CAROUSEL.NEXT_BUTTON} /> diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.tsx b/src/components/Attachments/AttachmentCarousel/CarouselItem.tsx index 37bbf1f8dfb2..161dd5d8a488 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.tsx +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.tsx @@ -46,6 +46,7 @@ function CarouselItem({item, onPress, isFocused, isModalHovered, reportID}: Caro style={style} onPress={() => setIsHidden(!isHidden)} testID="moderationButton" + sentryLabel={CONST.SENTRY_LABEL.ATTACHMENT_CAROUSEL.MODERATION_BUTTON} > {children} diff --git a/src/components/Attachments/AttachmentView/AttachmentViewImage/index.tsx b/src/components/Attachments/AttachmentView/AttachmentViewImage/index.tsx index 533b650e63a6..59fe12874f27 100644 --- a/src/components/Attachments/AttachmentView/AttachmentViewImage/index.tsx +++ b/src/components/Attachments/AttachmentView/AttachmentViewImage/index.tsx @@ -38,6 +38,7 @@ function AttachmentViewImage({attachmentID, url, file, isAuthTokenRequired, load accessibilityRole={CONST.ROLE.BUTTON} // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing accessibilityLabel={file?.name || translate('attachmentView.unknownFilename')} + sentryLabel={CONST.SENTRY_LABEL.ATTACHMENT_CAROUSEL.ITEM} > {children} diff --git a/src/components/Attachments/AttachmentView/index.tsx b/src/components/Attachments/AttachmentView/index.tsx index 343ed555ee17..9392a1988b45 100644 --- a/src/components/Attachments/AttachmentView/index.tsx +++ b/src/components/Attachments/AttachmentView/index.tsx @@ -301,6 +301,7 @@ function AttachmentView({ } setImageError(false); }} + sentryLabel={CONST.SENTRY_LABEL.ATTACHMENT_CAROUSEL.RETRY_BUTTON} /> ); diff --git a/src/components/BaseMiniContextMenuItem.tsx b/src/components/BaseMiniContextMenuItem.tsx index c04f8436279c..23a4520eae8a 100644 --- a/src/components/BaseMiniContextMenuItem.tsx +++ b/src/components/BaseMiniContextMenuItem.tsx @@ -8,11 +8,12 @@ import getButtonState from '@libs/getButtonState'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import variables from '@styles/variables'; import CONST from '@src/CONST'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; import type {PressableRef} from './Pressable/GenericPressable/types'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Tooltip from './Tooltip/PopoverAnchorTooltip'; -type BaseMiniContextMenuItemProps = { +type BaseMiniContextMenuItemProps = WithSentryLabel & { /** * Text to display when hovering the menu item */ @@ -41,11 +42,6 @@ type BaseMiniContextMenuItemProps = { * Reference to the outer element */ ref?: PressableRef; - - /** - * Label for Sentry tracking - */ - sentryLabel?: string; }; /** diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 87d0ccebc018..265463dcc463 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -19,170 +19,169 @@ import HapticFeedback from '@libs/HapticFeedback'; import CONST from '@src/CONST'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; import type IconAsset from '@src/types/utils/IconAsset'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; import {getButtonRole} from './utils'; import validateSubmitShortcut from './validateSubmitShortcut'; -type ButtonProps = Partial & { - /** Should the press event bubble across multiple instances when Enter key triggers it. */ - allowBubble?: boolean; +type ButtonProps = Partial & + WithSentryLabel & { + /** Should the press event bubble across multiple instances when Enter key triggers it. */ + allowBubble?: boolean; - /** The icon asset to display to the right of the text */ - iconRight?: IconAsset; + /** The icon asset to display to the right of the text */ + iconRight?: IconAsset; - /** The fill color to pass into the icon. */ - iconFill?: string; + /** The fill color to pass into the icon. */ + iconFill?: string; - /** The fill color to pass into the icon when the button is hovered. */ - iconHoverFill?: string; + /** The fill color to pass into the icon when the button is hovered. */ + iconHoverFill?: string; - /** Any additional styles to pass to the left icon container. */ - iconStyles?: StyleProp; + /** Any additional styles to pass to the left icon container. */ + iconStyles?: StyleProp; - /** Any additional styles to pass to the right icon container. */ - iconRightStyles?: StyleProp; + /** Any additional styles to pass to the right icon container. */ + iconRightStyles?: StyleProp; - /** Any additional styles to pass to the icon wrapper container. */ - iconWrapperStyles?: StyleProp; + /** Any additional styles to pass to the icon wrapper container. */ + iconWrapperStyles?: StyleProp; - /** Extra-small sized button */ - extraSmall?: boolean; + /** Extra-small sized button */ + extraSmall?: boolean; - /** Small sized button */ - small?: boolean; + /** Small sized button */ + small?: boolean; - /** Large sized button */ - large?: boolean; + /** Large sized button */ + large?: boolean; - /** Medium sized button */ - medium?: boolean; + /** Medium sized button */ + medium?: boolean; - /** Indicates whether the button should be disabled and in the loading state */ - isLoading?: boolean; + /** Indicates whether the button should be disabled and in the loading state */ + isLoading?: boolean; - /** Indicates whether the button should be disabled */ - isDisabled?: boolean; + /** Indicates whether the button should be disabled */ + isDisabled?: boolean; - /** Invoked on mount and layout changes */ - onLayout?: (event: LayoutChangeEvent) => void; + /** Invoked on mount and layout changes */ + onLayout?: (event: LayoutChangeEvent) => void; - /** A function that is called when the button is clicked on */ - onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; + /** A function that is called when the button is clicked on */ + onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; - /** A function that is called when the button is long pressed */ - onLongPress?: (event?: GestureResponderEvent) => void; + /** A function that is called when the button is long pressed */ + onLongPress?: (event?: GestureResponderEvent) => void; - /** A function that is called when the button is pressed */ - onPressIn?: (event: GestureResponderEvent) => void; + /** A function that is called when the button is pressed */ + onPressIn?: (event: GestureResponderEvent) => void; - /** A function that is called when the button is released */ - onPressOut?: (event: GestureResponderEvent) => void; + /** A function that is called when the button is released */ + onPressOut?: (event: GestureResponderEvent) => void; - /** Callback that is called when mousedown is triggered. */ - onMouseDown?: (e: React.MouseEvent) => void; + /** Callback that is called when mousedown is triggered. */ + onMouseDown?: (e: React.MouseEvent) => void; - /** Call the onPress function when Enter key is pressed */ - pressOnEnter?: boolean; + /** Call the onPress function when Enter key is pressed */ + pressOnEnter?: boolean; - /** The priority to assign the enter key event listener. 0 is the highest priority. */ - enterKeyEventListenerPriority?: number; + /** The priority to assign the enter key event listener. 0 is the highest priority. */ + enterKeyEventListenerPriority?: number; - /** Additional styles to add after local styles. Applied to Pressable portion of button */ - style?: StyleProp; + /** Additional styles to add after local styles. Applied to Pressable portion of button */ + style?: StyleProp; - /** Additional styles to add to the component when it's disabled */ - disabledStyle?: StyleProp; + /** Additional styles to add to the component when it's disabled */ + disabledStyle?: StyleProp; - /** Additional button styles. Specific to the OpacityView of the button */ - innerStyles?: StyleProp; + /** Additional button styles. Specific to the OpacityView of the button */ + innerStyles?: StyleProp; - /** Additional text styles */ - textStyles?: StyleProp; + /** Additional text styles */ + textStyles?: StyleProp; - /** Additional text styles when the button is hovered */ - textHoverStyles?: StyleProp; + /** Additional text styles when the button is hovered */ + textHoverStyles?: StyleProp; - /** The number of lines to display for the primary text */ - primaryTextNumberOfLines?: number; + /** The number of lines to display for the primary text */ + primaryTextNumberOfLines?: number; - /** Whether we should use the default hover style */ - shouldUseDefaultHover?: boolean; + /** Whether we should use the default hover style */ + shouldUseDefaultHover?: boolean; - /** Additional hover styles */ - hoverStyles?: StyleProp; + /** Additional hover styles */ + hoverStyles?: StyleProp; - /** Whether we should use the success theme color */ - success?: boolean; + /** Whether we should use the success theme color */ + success?: boolean; - /** Whether we should use the danger theme color */ - danger?: boolean; + /** Whether we should use the danger theme color */ + danger?: boolean; - /** Whether we should display the button as a link */ - link?: boolean; + /** Whether we should display the button as a link */ + link?: boolean; - /** Should we remove the right border radius top + bottom? */ - shouldRemoveRightBorderRadius?: boolean; + /** Should we remove the right border radius top + bottom? */ + shouldRemoveRightBorderRadius?: boolean; - /** Should we remove the left border radius top + bottom? */ - shouldRemoveLeftBorderRadius?: boolean; + /** Should we remove the left border radius top + bottom? */ + shouldRemoveLeftBorderRadius?: boolean; - /** Should enable the haptic feedback? */ - shouldEnableHapticFeedback?: boolean; + /** Should enable the haptic feedback? */ + shouldEnableHapticFeedback?: boolean; - /** Should disable the long press? */ - isLongPressDisabled?: boolean; + /** Should disable the long press? */ + isLongPressDisabled?: boolean; - /** Id to use for this button */ - id?: string; + /** Id to use for this button */ + id?: string; - /** Accessibility label for the component */ - accessibilityLabel?: string; + /** Accessibility label for the component */ + accessibilityLabel?: string; - /** The icon asset to display to the left of the text */ - icon?: IconAsset | null; + /** The icon asset to display to the left of the text */ + icon?: IconAsset | null; - /** The text for the button label */ - text?: string; + /** The text for the button label */ + text?: string; - /** Boolean whether to display the right icon */ - shouldShowRightIcon?: boolean; + /** Boolean whether to display the right icon */ + shouldShowRightIcon?: boolean; - /** Whether the button should use split style or not */ - isSplitButton?: boolean; + /** Whether the button should use split style or not */ + isSplitButton?: boolean; - /** Whether button's content should be centered */ - isContentCentered?: boolean; + /** Whether button's content should be centered */ + isContentCentered?: boolean; - /** Whether the Enter keyboard listening is active whether or not the screen that contains the button is focused */ - isPressOnEnterActive?: boolean; + /** Whether the Enter keyboard listening is active whether or not the screen that contains the button is focused */ + isPressOnEnterActive?: boolean; - /** The testID of the button. Used to locate this view in end-to-end tests. */ - testID?: string; + /** The testID of the button. Used to locate this view in end-to-end tests. */ + testID?: string; - /** Whether is a nested button inside other button, since nesting buttons isn't valid html */ - isNested?: boolean; + /** Whether is a nested button inside other button, since nesting buttons isn't valid html */ + isNested?: boolean; - /** The text displays under the first line */ - secondLineText?: string; + /** The text displays under the first line */ + secondLineText?: string; - /** - * Whether the button should have a background layer in the color of theme.appBG. - * This is needed for buttons that allow content to display under them. - */ - shouldBlendOpacity?: boolean; + /** + * Whether the button should have a background layer in the color of theme.appBG. + * This is needed for buttons that allow content to display under them. + */ + shouldBlendOpacity?: boolean; - /** - * Reference to the outer element. - */ - ref?: ForwardedRef; + /** + * Reference to the outer element. + */ + ref?: ForwardedRef; - /** - * Whether the button should stay visually normal even when disabled. - */ - shouldStayNormalOnDisable?: boolean; - - /** Label for Sentry tracking. On web, this will be added as data-sentry-label attribute. */ - sentryLabel?: string; -}; + /** + * Whether the button should stay visually normal even when disabled. + */ + shouldStayNormalOnDisable?: boolean; + }; type KeyboardShortcutComponentProps = Pick; diff --git a/src/components/ButtonWithDropdownMenu/types.ts b/src/components/ButtonWithDropdownMenu/types.ts index 47458710d62e..ae479d2beff0 100644 --- a/src/components/ButtonWithDropdownMenu/types.ts +++ b/src/components/ButtonWithDropdownMenu/types.ts @@ -6,6 +6,7 @@ import type CONST from '@src/CONST'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type IconAsset from '@src/types/utils/IconAsset'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; type PaymentType = DeepValueOf; @@ -21,7 +22,7 @@ type ReportExportType = DeepValueOf; type OnboardingHelpType = DeepValueOf; -type DropdownOption = { +type DropdownOption = WithSentryLabel & { value: TValueType; text: string; icon?: IconAsset; @@ -49,11 +50,9 @@ type DropdownOption = { shouldShow?: boolean; /** Whether to show a loading spinner for this option */ shouldShowLoadingSpinnerIcon?: boolean; - /** Label for sentry to identify the dropdown option */ - sentryLabel?: string; }; -type ButtonWithDropdownMenuProps = { +type ButtonWithDropdownMenuProps = WithSentryLabel & { /** The custom text to display on the main button instead of selected option */ customText?: string; @@ -159,9 +158,6 @@ type ButtonWithDropdownMenuProps = { /** Reference to the outer element */ ref?: React.Ref; - - /** Label for the sentry to identify the button */ - sentryLabel?: string; }; type ButtonWithDropdownMenuRef = { diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 28bf3086eb1c..6e05f80574c2 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -7,66 +7,65 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import type {PressableRef} from './Pressable/GenericPressable/types'; import PressableWithFeedback from './Pressable/PressableWithFeedback'; -type CheckboxProps = Partial & { - /** Whether checkbox is checked */ - isChecked?: boolean; +type CheckboxProps = Partial & + WithSentryLabel & { + /** Whether checkbox is checked */ + isChecked?: boolean; - /** Whether checkbox is in the indeterminate (“mixed”) state */ - isIndeterminate?: boolean; + /** Whether checkbox is in the indeterminate (“mixed”) state */ + isIndeterminate?: boolean; - /** A function that is called when the box/label is pressed */ - onPress: () => void; + /** A function that is called when the box/label is pressed */ + onPress: () => void; - /** Should the input be styled for errors */ - hasError?: boolean; + /** Should the input be styled for errors */ + hasError?: boolean; - /** Should the input be disabled */ - disabled?: boolean; + /** Should the input be disabled */ + disabled?: boolean; - /** Additional styles to add to checkbox button */ - style?: StyleProp; + /** Additional styles to add to checkbox button */ + style?: StyleProp; - /** Additional styles to add to checkbox container */ - containerStyle?: StyleProp; + /** Additional styles to add to checkbox container */ + containerStyle?: StyleProp; - /** Callback that is called when mousedown is triggered. */ - onMouseDown?: MouseEventHandler; + /** Callback that is called when mousedown is triggered. */ + onMouseDown?: MouseEventHandler; - /** The size of the checkbox container */ - containerSize?: number; + /** The size of the checkbox container */ + containerSize?: number; - /** The border radius of the checkbox container */ - containerBorderRadius?: number; + /** The border radius of the checkbox container */ + containerBorderRadius?: number; - /** The size of the caret (checkmark) */ - caretSize?: number; + /** The size of the caret (checkmark) */ + caretSize?: number; - /** An accessibility label for the checkbox */ - accessibilityLabel: string; + /** An accessibility label for the checkbox */ + accessibilityLabel: string; - /** stop propagation of the mouse down event */ - shouldStopMouseDownPropagation?: boolean; + /** stop propagation of the mouse down event */ + shouldStopMouseDownPropagation?: boolean; - /** Whether the checkbox should be selected when pressing Enter key */ - shouldSelectOnPressEnter?: boolean; + /** Whether the checkbox should be selected when pressing Enter key */ + shouldSelectOnPressEnter?: boolean; - /** Additional styles to add to checkbox wrapper */ - wrapperStyle?: StyleProp; + /** Additional styles to add to checkbox wrapper */ + wrapperStyle?: StyleProp; - /** Used to locate this view in end-to-end tests. */ - testID?: string; + /** Used to locate this view in end-to-end tests. */ + testID?: string; - /** Reference to the outer element */ - ref?: ForwardedRef; - - /** Label for Sentry tracking. On web, this will be added as data-sentry-label attribute. */ - sentryLabel?: string; -}; + /** Reference to the outer element */ + ref?: ForwardedRef; + }; function Checkbox({ isChecked = false, diff --git a/src/components/ContextMenuItem.tsx b/src/components/ContextMenuItem.tsx index c9da9ff6fa95..125856bfb1d1 100644 --- a/src/components/ContextMenuItem.tsx +++ b/src/components/ContextMenuItem.tsx @@ -7,11 +7,12 @@ import useThrottledButtonState from '@hooks/useThrottledButtonState'; import useWindowDimensions from '@hooks/useWindowDimensions'; import getButtonState from '@libs/getButtonState'; import type IconAsset from '@src/types/utils/IconAsset'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; import BaseMiniContextMenuItem from './BaseMiniContextMenuItem'; import FocusableMenuItem from './FocusableMenuItem'; import Icon from './Icon'; -type ContextMenuItemProps = { +type ContextMenuItemProps = WithSentryLabel & { /** Icon Component */ icon: IconAsset; @@ -64,9 +65,6 @@ type ContextMenuItemProps = { /** Reference to the outer element */ ref?: ForwardedRef; - - /** Label for Sentry tracking */ - sentryLabel?: string; }; type ContextMenuItemHandle = { diff --git a/src/components/FloatingActionButton.tsx b/src/components/FloatingActionButton.tsx index e4a2c0744dd1..783fe383530a 100644 --- a/src/components/FloatingActionButton.tsx +++ b/src/components/FloatingActionButton.tsx @@ -12,6 +12,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import variables from '@styles/variables'; import CONST from '@src/CONST'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; import Icon from './Icon'; import {PlusCircle} from './Icon/Expensicons'; import {PressableWithFeedback, PressableWithoutFeedback} from './Pressable'; @@ -24,7 +25,7 @@ const SMALL_FAB_PATH = const AnimatedPath = Animated.createAnimatedComponent(Path); -type FloatingActionButtonProps = { +type FloatingActionButtonProps = WithSentryLabel & { /* Callback to fire on request to toggle the FloatingActionButton */ onPress: (event: GestureResponderEvent | KeyboardEvent | undefined) => void; @@ -44,7 +45,7 @@ type FloatingActionButtonProps = { ref?: ForwardedRef; }; -function FloatingActionButton({onPress, onLongPress, isActive, accessibilityLabel, role, ref}: FloatingActionButtonProps) { +function FloatingActionButton({onPress, onLongPress, isActive, accessibilityLabel, role, ref, sentryLabel}: FloatingActionButtonProps) { const {buttonDefaultBG, buttonHoveredBG, icon} = useTheme(); const styles = useThemeStyles(); const borderRadius = styles.floatingActionButton.borderRadius; @@ -116,6 +117,7 @@ function FloatingActionButton({onPress, onLongPress, isActive, accessibilityLabe role={role} shouldUseHapticsOnLongPress testID="floating-action-button" + sentryLabel={sentryLabel} > {({hovered}) => { isHovered.set(hovered); @@ -156,6 +158,7 @@ function FloatingActionButton({onPress, onLongPress, isActive, accessibilityLabe styles.flex1, ]} testID="create-action-button" + sentryLabel={sentryLabel} > void; @@ -23,7 +24,7 @@ type FloatingReceiptButtonProps = { role: Role; }; -function FloatingReceiptButton({onPress, accessibilityLabel, role}: FloatingReceiptButtonProps) { +function FloatingReceiptButton({onPress, accessibilityLabel, role, sentryLabel}: FloatingReceiptButtonProps) { const {successHover, textLight} = useTheme(); const styles = useThemeStyles(); const borderRadius = styles.floatingActionButton.borderRadius; @@ -53,6 +54,7 @@ function FloatingReceiptButton({onPress, accessibilityLabel, role}: FloatingRece role={role} shouldUseHapticsOnLongPress testID="floating-receipt-button" + sentryLabel={sentryLabel} > {({hovered}) => ( ) { shouldUseHapticsOnLongPress role={getButtonRole(true)} accessibilityLabel={translate('accessibilityHints.viewAttachment')} + sentryLabel={CONST.SENTRY_LABEL.HTML_RENDERER.IMAGE} > {thumbnailImageComponent} diff --git a/src/components/HeaderWithBackButton/index.tsx b/src/components/HeaderWithBackButton/index.tsx index e40e45281f84..4032dc08fd61 100755 --- a/src/components/HeaderWithBackButton/index.tsx +++ b/src/components/HeaderWithBackButton/index.tsx @@ -149,6 +149,7 @@ function HeaderWithBackButton({ style={[styles.touchableButtonImage]} role={CONST.ROLE.BUTTON} accessibilityLabel={threeDotsMenuItems.at(0)?.text ?? ''} + sentryLabel={threeDotsMenuItems.at(0)?.sentryLabel} > } @@ -167,6 +168,7 @@ function HeaderWithBackButton({ shouldOverlay={shouldOverlayDots} anchorAlignment={threeDotsAnchorAlignment} shouldSetModalVisibility={shouldSetModalVisibility} + sentryLabel={CONST.SENTRY_LABEL.HEADER.MORE_BUTTON} /> ); } @@ -222,6 +224,7 @@ function HeaderWithBackButton({ role={CONST.ROLE.BUTTON} accessibilityLabel={translate('common.back')} id={CONST.BACK_BUTTON_NATIVE_ID} + sentryLabel={CONST.SENTRY_LABEL.HEADER.BACK_BUTTON} > ; +type MenuItemBaseProps = ForwardedFSClassProps & + WithSentryLabel & { + /** Reference to the outer element */ + ref?: PressableRef | Ref; - /** Function to fire when component is pressed */ - onPress?: (event: GestureResponderEvent | KeyboardEvent) => void | Promise; + /** Function to fire when component is pressed */ + onPress?: (event: GestureResponderEvent | KeyboardEvent) => void | Promise; - /** Whether the menu item should be interactive at all */ - interactive?: boolean; + /** Whether the menu item should be interactive at all */ + interactive?: boolean; - /** Text to be shown as badge near the right end. */ - badgeText?: string; + /** Text to be shown as badge near the right end. */ + badgeText?: string; - /** Icon to display on the left side of the badge */ - badgeIcon?: IconAsset; + /** Icon to display on the left side of the badge */ + badgeIcon?: IconAsset; - /** Whether the badge should be shown as success */ - badgeSuccess?: boolean; + /** Whether the badge should be shown as success */ + badgeSuccess?: boolean; - /** Used to apply offline styles to child text components */ - style?: StyleProp; + /** Used to apply offline styles to child text components */ + style?: StyleProp; - /** Outer wrapper styles */ - outerWrapperStyle?: StyleProp; + /** Outer wrapper styles */ + outerWrapperStyle?: StyleProp; - /** Any additional styles to apply */ - wrapperStyle?: StyleProp; + /** Any additional styles to apply */ + wrapperStyle?: StyleProp; - /** Styles to apply on the title wrapper */ - titleWrapperStyle?: StyleProp; + /** Styles to apply on the title wrapper */ + titleWrapperStyle?: StyleProp; - /** Any additional styles to apply on the outer element */ - containerStyle?: StyleProp; + /** Any additional styles to apply on the outer element */ + containerStyle?: StyleProp; - /** Used to apply styles specifically to the title */ - titleStyle?: StyleProp; + /** Used to apply styles specifically to the title */ + titleStyle?: StyleProp; - /** Any additional styles to apply on the badge element */ - badgeStyle?: ViewStyle; + /** Any additional styles to apply on the badge element */ + badgeStyle?: ViewStyle; - /** Any additional styles to apply to the label */ - labelStyle?: StyleProp; + /** Any additional styles to apply to the label */ + labelStyle?: StyleProp; - /** Additional styles to style the description text below the title */ - descriptionTextStyle?: StyleProp; + /** Additional styles to style the description text below the title */ + descriptionTextStyle?: StyleProp; - /** The fill color to pass into the icon. */ - iconFill?: string | ((isHovered: boolean) => string); + /** The fill color to pass into the icon. */ + iconFill?: string | ((isHovered: boolean) => string); - /** Secondary icon to display on the left side of component, right of the icon */ - secondaryIcon?: IconAsset; + /** Secondary icon to display on the left side of component, right of the icon */ + secondaryIcon?: IconAsset; - /** The fill color to pass into the secondary icon. */ - secondaryIconFill?: string; + /** The fill color to pass into the secondary icon. */ + secondaryIconFill?: string; - /** Whether the secondary icon should have hover style */ - isSecondaryIconHoverable?: boolean; + /** Whether the secondary icon should have hover style */ + isSecondaryIconHoverable?: boolean; - /** Icon Width */ - iconWidth?: number; + /** Icon Width */ + iconWidth?: number; - /** Icon Height */ - iconHeight?: number; + /** Icon Height */ + iconHeight?: number; - /** Any additional styles to pass to the icon container. */ - iconStyles?: StyleProp; + /** Any additional styles to pass to the icon container. */ + iconStyles?: StyleProp; - /** Additional styles to pass to the icon itself */ - additionalIconStyles?: StyleProp; + /** Additional styles to pass to the icon itself */ + additionalIconStyles?: StyleProp; - /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ - fallbackIcon?: IconAsset; + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ + fallbackIcon?: IconAsset; - /** An icon to display under the main item */ - furtherDetailsIcon?: IconAsset; + /** An icon to display under the main item */ + furtherDetailsIcon?: IconAsset; - /** Boolean whether to display the title right icon */ - shouldShowTitleIcon?: boolean; + /** Boolean whether to display the title right icon */ + shouldShowTitleIcon?: boolean; - /** Icon to display at right side of title */ - titleIcon?: IconAsset; + /** Icon to display at right side of title */ + titleIcon?: IconAsset; - /** Boolean whether to display the right icon */ - shouldShowRightIcon?: boolean; + /** Boolean whether to display the right icon */ + shouldShowRightIcon?: boolean; - /** Overrides the icon for shouldShowRightIcon */ - iconRight?: IconAsset; + /** Overrides the icon for shouldShowRightIcon */ + iconRight?: IconAsset; - /** Should render component on the right */ - shouldShowRightComponent?: boolean; + /** Should render component on the right */ + shouldShowRightComponent?: boolean; - /** Component to be displayed on the right */ - rightComponent?: ReactNode; + /** Component to be displayed on the right */ + rightComponent?: ReactNode; - /** A description text to show under the title */ - description?: string; + /** A description text to show under the title */ + description?: string; - /** Text to show below menu item. This text is not interactive */ - helperText?: string; + /** Text to show below menu item. This text is not interactive */ + helperText?: string; - /** Any additional styles to pass to helper text. */ - helperTextStyle?: StyleProp; + /** Any additional styles to pass to helper text. */ + helperTextStyle?: StyleProp; - /** Should the description be shown above the title (instead of the other way around) */ - shouldShowDescriptionOnTop?: boolean; + /** Should the description be shown above the title (instead of the other way around) */ + shouldShowDescriptionOnTop?: boolean; - /** Error to display at the bottom of the component */ - errorText?: string | ReactNode; + /** Error to display at the bottom of the component */ + errorText?: string | ReactNode; - /** Any additional styles to pass to error text. */ - errorTextStyle?: StyleProp; + /** Any additional styles to pass to error text. */ + errorTextStyle?: StyleProp; - /** Hint to display at the bottom of the component */ - hintText?: string | ReactNode; + /** Hint to display at the bottom of the component */ + hintText?: string | ReactNode; - /** Should the error text red dot indicator be shown */ - shouldShowRedDotIndicator?: boolean; + /** Should the error text red dot indicator be shown */ + shouldShowRedDotIndicator?: boolean; - /** A boolean flag that gives the icon a green fill if true */ - success?: boolean; + /** A boolean flag that gives the icon a green fill if true */ + success?: boolean; - /** Whether item is focused or active */ - focused?: boolean; + /** Whether item is focused or active */ + focused?: boolean; - /** Should we disable this menu item? */ - disabled?: boolean; + /** Should we disable this menu item? */ + disabled?: boolean; - /** Text that appears above the title */ - label?: string; + /** Text that appears above the title */ + label?: string; - /** Character limit after which the menu item text will be truncated */ - characterLimit?: number; + /** Character limit after which the menu item text will be truncated */ + characterLimit?: number; - isLabelHoverable?: boolean; + isLabelHoverable?: boolean; - /** Label to be displayed on the right */ - rightLabel?: string; + /** Label to be displayed on the right */ + rightLabel?: string; - /** Text to display for the item */ - title?: string; + /** Text to display for the item */ + title?: string; - /** Component to display as the title */ - titleComponent?: ReactElement; + /** Component to display as the title */ + titleComponent?: ReactElement; - /** Any additional styles to apply to the container for title components */ - titleContainerStyle?: StyleProp; + /** Any additional styles to apply to the container for title components */ + titleContainerStyle?: StyleProp; - /** A right-aligned subtitle for this menu option */ - subtitle?: string | number; + /** A right-aligned subtitle for this menu option */ + subtitle?: string | number; - /** Should the title show with normal font weight (not bold) */ - shouldShowBasicTitle?: boolean; + /** Should the title show with normal font weight (not bold) */ + shouldShowBasicTitle?: boolean; - /** Should we make this selectable with a checkbox */ - shouldShowSelectedState?: boolean; + /** Should we make this selectable with a checkbox */ + shouldShowSelectedState?: boolean; - /** Should we truncate the title */ - shouldTruncateTitle?: boolean; + /** Should we truncate the title */ + shouldTruncateTitle?: boolean; - /** Whether this item is selected */ - isSelected?: boolean; + /** Whether this item is selected */ + isSelected?: boolean; - /** Prop to identify if we should load avatars vertically instead of diagonally */ - shouldStackHorizontally?: boolean; + /** Prop to identify if we should load avatars vertically instead of diagonally */ + shouldStackHorizontally?: boolean; - /** Prop to represent the size of the avatar images to be shown */ - avatarSize?: ValueOf; + /** Prop to represent the size of the avatar images to be shown */ + avatarSize?: ValueOf; - /** Affects avatar size */ - viewMode?: ValueOf; + /** Affects avatar size */ + viewMode?: ValueOf; - /** Used to truncate the text with an ellipsis after computing the text layout */ - numberOfLinesTitle?: number; + /** Used to truncate the text with an ellipsis after computing the text layout */ + numberOfLinesTitle?: number; - /** Used to truncate the description with an ellipsis after computing the text layout */ - numberOfLinesDescription?: number; + /** Used to truncate the description with an ellipsis after computing the text layout */ + numberOfLinesDescription?: number; - /** Whether we should use small avatar subscript sizing the for menu item */ - isSmallAvatarSubscriptMenu?: boolean; + /** Whether we should use small avatar subscript sizing the for menu item */ + isSmallAvatarSubscriptMenu?: boolean; - /** The type of brick road indicator to show. */ - brickRoadIndicator?: ValueOf; + /** The type of brick road indicator to show. */ + brickRoadIndicator?: ValueOf; - /** Should render the content in HTML format */ - shouldRenderAsHTML?: boolean; + /** Should render the content in HTML format */ + shouldRenderAsHTML?: boolean; - /** Whether or not the text should be escaped */ - shouldEscapeText?: boolean; + /** Whether or not the text should be escaped */ + shouldEscapeText?: boolean; - /** Should we grey out the menu item when it is disabled? */ - shouldGreyOutWhenDisabled?: boolean; + /** Should we grey out the menu item when it is disabled? */ + shouldGreyOutWhenDisabled?: boolean; - /** Should we remove the background color of the menu item */ - shouldRemoveBackground?: boolean; + /** Should we remove the background color of the menu item */ + shouldRemoveBackground?: boolean; - /** Should we remove the hover background color of the menu item */ - shouldRemoveHoverBackground?: boolean; + /** Should we remove the hover background color of the menu item */ + shouldRemoveHoverBackground?: boolean; - rightIconAccountID?: number | string; + rightIconAccountID?: number | string; - iconAccountID?: number; + iconAccountID?: number; - /** Should we use default cursor for disabled content */ - shouldUseDefaultCursorWhenDisabled?: boolean; + /** Should we use default cursor for disabled content */ + shouldUseDefaultCursorWhenDisabled?: boolean; - /** The action accept for anonymous user or not */ - isAnonymousAction?: boolean; + /** The action accept for anonymous user or not */ + isAnonymousAction?: boolean; - /** Flag to indicate whether or not text selection should be disabled from long-pressing the menu item. */ - shouldBlockSelection?: boolean; + /** Flag to indicate whether or not text selection should be disabled from long-pressing the menu item. */ + shouldBlockSelection?: boolean; - /** Whether should render title as HTML or as Text */ - shouldParseTitle?: boolean; + /** Whether should render title as HTML or as Text */ + shouldParseTitle?: boolean; - /** Whether should render helper text as HTML or as Text */ - shouldParseHelperText?: boolean; + /** Whether should render helper text as HTML or as Text */ + shouldParseHelperText?: boolean; - /** Whether should render hint text as HTML or as Text */ - shouldRenderHintAsHTML?: boolean; + /** Whether should render hint text as HTML or as Text */ + shouldRenderHintAsHTML?: boolean; - /** Whether should render error text as HTML or as Text */ - shouldRenderErrorAsHTML?: boolean; + /** Whether should render error text as HTML or as Text */ + shouldRenderErrorAsHTML?: boolean; - /** List of markdown rules that will be ignored */ - excludedMarkdownRules?: string[]; + /** List of markdown rules that will be ignored */ + excludedMarkdownRules?: string[]; - /** Should check anonymous user in onPress function */ - shouldCheckActionAllowedOnPress?: boolean; + /** Should check anonymous user in onPress function */ + shouldCheckActionAllowedOnPress?: boolean; - /** Text to display under the main item */ - furtherDetails?: string; + /** Text to display under the main item */ + furtherDetails?: string; - /** The maximum number of lines for further details text */ - furtherDetailsNumberOfLines?: number; + /** The maximum number of lines for further details text */ + furtherDetailsNumberOfLines?: number; - /** The further details additional style */ - furtherDetailsStyle?: StyleProp; + /** The further details additional style */ + furtherDetailsStyle?: StyleProp; - /** Render custom content under the main item */ - furtherDetailsComponent?: ReactElement; + /** Render custom content under the main item */ + furtherDetailsComponent?: ReactElement; - /** The function that should be called when this component is LongPressed or right-clicked. */ - onSecondaryInteraction?: (event: GestureResponderEvent | MouseEvent) => void; + /** The function that should be called when this component is LongPressed or right-clicked. */ + onSecondaryInteraction?: (event: GestureResponderEvent | MouseEvent) => void; - /** Array of objects that map display names to their corresponding tooltip */ - titleWithTooltips?: DisplayNameWithTooltip[] | undefined; + /** Array of objects that map display names to their corresponding tooltip */ + titleWithTooltips?: DisplayNameWithTooltip[] | undefined; - /** Icon should be displayed in its own color */ - displayInDefaultIconColor?: boolean; + /** Icon should be displayed in its own color */ + displayInDefaultIconColor?: boolean; - /** Determines how the icon should be resized to fit its container */ - contentFit?: ImageContentFit; + /** Determines how the icon should be resized to fit its container */ + contentFit?: ImageContentFit; - /** Is this in the Pane */ - isPaneMenu?: boolean; + /** Is this in the Pane */ + isPaneMenu?: boolean; - /** Adds padding to the left of the text when there is no icon. */ - shouldPutLeftPaddingWhenNoIcon?: boolean; + /** Adds padding to the left of the text when there is no icon. */ + shouldPutLeftPaddingWhenNoIcon?: boolean; - /** Handles what to do when the item is focused */ - onFocus?: () => void; + /** Handles what to do when the item is focused */ + onFocus?: () => void; - /** Handles what to do when the item loose focus */ - onBlur?: () => void; + /** Handles what to do when the item loose focus */ + onBlur?: () => void; - /** Optional account id if it's user avatar or policy id if it's workspace avatar */ - avatarID?: number | string; + /** Optional account id if it's user avatar or policy id if it's workspace avatar */ + avatarID?: number | string; - /** Whether to show the tooltip */ - shouldRenderTooltip?: boolean; + /** Whether to show the tooltip */ + shouldRenderTooltip?: boolean; - /** Anchor alignment of the tooltip */ - tooltipAnchorAlignment?: TooltipAnchorAlignment; + /** Anchor alignment of the tooltip */ + tooltipAnchorAlignment?: TooltipAnchorAlignment; - /** Additional styles for tooltip wrapper */ - tooltipWrapperStyle?: StyleProp; + /** Additional styles for tooltip wrapper */ + tooltipWrapperStyle?: StyleProp; - /** Any additional amount to manually adjust the horizontal position of the tooltip */ - tooltipShiftHorizontal?: number; + /** Any additional amount to manually adjust the horizontal position of the tooltip */ + tooltipShiftHorizontal?: number; - /** Any additional amount to manually adjust the vertical position of the tooltip */ - tooltipShiftVertical?: number; + /** Any additional amount to manually adjust the vertical position of the tooltip */ + tooltipShiftVertical?: number; - /** Render custom content inside the tooltip. */ - renderTooltipContent?: () => ReactNode; + /** Render custom content inside the tooltip. */ + renderTooltipContent?: () => ReactNode; - /** Callback to fire when the education tooltip is pressed */ - onEducationTooltipPress?: () => void; + /** Callback to fire when the education tooltip is pressed */ + onEducationTooltipPress?: () => void; - /** Whether the tooltip should hide on scroll */ - shouldHideOnScroll?: boolean; + /** Whether the tooltip should hide on scroll */ + shouldHideOnScroll?: boolean; - shouldShowLoadingSpinnerIcon?: boolean; + shouldShowLoadingSpinnerIcon?: boolean; - /** Should selected item be marked with checkmark */ - shouldShowSelectedItemCheck?: boolean; + /** Should selected item be marked with checkmark */ + shouldShowSelectedItemCheck?: boolean; - /** Should use auto width for the icon container. */ - shouldIconUseAutoWidthStyle?: boolean; + /** Should use auto width for the icon container. */ + shouldIconUseAutoWidthStyle?: boolean; - /** Should break word for room title */ - shouldBreakWord?: boolean; + /** Should break word for room title */ + shouldBreakWord?: boolean; - /** Pressable component Test ID. Used to locate the component in tests. */ - pressableTestID?: string; + /** Pressable component Test ID. Used to locate the component in tests. */ + pressableTestID?: string; - /** Whether to teleport the portal to the modal layer */ - shouldTeleportPortalToModalLayer?: boolean; + /** Whether to teleport the portal to the modal layer */ + shouldTeleportPortalToModalLayer?: boolean; - /** The value to copy in copy to clipboard action. Must be used in conjunction with `copyable=true`. Default value is `title` prop. */ - copyValue?: string; + /** The value to copy in copy to clipboard action. Must be used in conjunction with `copyable=true`. Default value is `title` prop. */ + copyValue?: string; - /** Should enable copy to clipboard action */ - copyable?: boolean; + /** Should enable copy to clipboard action */ + copyable?: boolean; - /** Plaid image for the bank */ - plaidUrl?: string; + /** Plaid image for the bank */ + plaidUrl?: string; - /** Report ID for the avatar */ - iconReportID?: string; + /** Report ID for the avatar */ + iconReportID?: string; - /** Report ID for the avatar on the right */ - rightIconReportID?: string; + /** Report ID for the avatar on the right */ + rightIconReportID?: string; - /** Whether the menu item contains nested submenu items. */ - hasSubMenuItems?: boolean; + /** Whether the menu item contains nested submenu items. */ + hasSubMenuItems?: boolean; - /** Whether the screen containing the item is focused */ - isFocused?: boolean; - - /** Label for Sentry tracking */ - sentryLabel?: string; -}; + /** Whether the screen containing the item is focused */ + isFocused?: boolean; + }; type MenuItemProps = (IconProps | AvatarProps | NoIcon) & MenuItemBaseProps; diff --git a/src/components/Pressable/GenericPressable/types.ts b/src/components/Pressable/GenericPressable/types.ts index cdd0505d4aca..44968328e0ec 100644 --- a/src/components/Pressable/GenericPressable/types.ts +++ b/src/components/Pressable/GenericPressable/types.ts @@ -5,6 +5,7 @@ import type {ValueOf} from 'type-fest'; import type {ForwardedFSClassProps} from '@libs/Fullstory/types'; import type {Shortcut} from '@libs/KeyboardShortcut'; import type CONST from '@src/CONST'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; type StylePropWithFunction = StyleProp | ((state: PressableStateCallbackType) => StyleProp); @@ -39,7 +40,8 @@ type RequiredAccessibilityLabel = type PressableProps = RNPressableProps & RequiredAccessibilityLabel & - ForwardedFSClassProps & { + ForwardedFSClassProps & + WithSentryLabel & { /** * onPress callback */ @@ -156,11 +158,6 @@ type PressableProps = RNPressableProps & */ isNested?: boolean; - /** - * Label for Sentry tracking. On web, this will be added as data-sentry-label attribute. - */ - sentryLabel?: string; - /** * Reference to the outer element. */ diff --git a/src/components/ReportActionItem/ReportActionItemImage.tsx b/src/components/ReportActionItem/ReportActionItemImage.tsx index a3a851b8a8f2..db558ba6cf4b 100644 --- a/src/components/ReportActionItem/ReportActionItemImage.tsx +++ b/src/components/ReportActionItem/ReportActionItemImage.tsx @@ -194,6 +194,7 @@ function ReportActionItemImage({ } accessibilityLabel={translate('accessibilityHints.viewAttachment')} accessibilityRole={CONST.ROLE.BUTTON} + sentryLabel={CONST.SENTRY_LABEL.RECEIPT.IMAGE} > runOnJS(setControlStatusState)(CONST.VIDEO_PLAYER.CONTROLS_STATUS.HIDE))); + controlsOpacity.set(withTiming(0, {duration: 500}, () => scheduleOnRN(setControlStatusState, CONST.VIDEO_PLAYER.CONTROLS_STATUS.HIDE))); }, [controlsOpacity, isEnded]); const debouncedHideControl = useMemo(() => debounce(hideControl, 1500), [hideControl]); @@ -445,6 +446,7 @@ function BaseVideoPlayer({ toggleControl(); }} style={[styles.flex1, styles.noSelect]} + sentryLabel={CONST.SENTRY_LABEL.VIDEO_PLAYER.VIDEO} > {shouldUseSharedVideoElement ? ( <> diff --git a/src/components/VideoPlayer/IconButton.tsx b/src/components/VideoPlayer/IconButton.tsx index 827b07035aef..a2af11c083c6 100644 --- a/src/components/VideoPlayer/IconButton.tsx +++ b/src/components/VideoPlayer/IconButton.tsx @@ -6,8 +6,9 @@ import Tooltip from '@components/Tooltip'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import type IconAsset from '@src/types/utils/IconAsset'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; -type IconButtonProps = { +type IconButtonProps = WithSentryLabel & { src: IconAsset; onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void | Promise; fill?: string; @@ -18,7 +19,7 @@ type IconButtonProps = { shouldForceRenderingTooltipBelow?: boolean; }; -function IconButton({src, fill = 'white', onPress, style, hoverStyle, tooltipText = '', small = false, shouldForceRenderingTooltipBelow = false}: IconButtonProps) { +function IconButton({src, fill = 'white', onPress, style, hoverStyle, tooltipText = '', small = false, shouldForceRenderingTooltipBelow = false, sentryLabel}: IconButtonProps) { const styles = useThemeStyles(); return ( )} diff --git a/src/components/VideoPlayer/VideoPlayerControls/index.tsx b/src/components/VideoPlayer/VideoPlayerControls/index.tsx index d26ea502e7d8..7a339979935b 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/index.tsx +++ b/src/components/VideoPlayer/VideoPlayerControls/index.tsx @@ -109,6 +109,7 @@ function VideoPlayerControls({ onPress={togglePlayCurrentVideo} style={styles.mr2} small={small} + sentryLabel={CONST.SENTRY_LABEL.VIDEO_PLAYER.PLAY_PAUSE_BUTTON} /> {shouldShowTime && ( @@ -126,12 +127,14 @@ function VideoPlayerControls({ onPress={enterFullScreenMode} style={iconSpacing} small={small} + sentryLabel={CONST.SENTRY_LABEL.VIDEO_PLAYER.FULLSCREEN_BUTTON} /> diff --git a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx index 545bb2b465c1..4d273ceafdde 100644 --- a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx +++ b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx @@ -62,6 +62,7 @@ function VideoPlayerThumbnail({thumbnailUrl, onPress, accessibilityLabel, isDele }); }} shouldUseHapticsOnLongPress + sentryLabel={CONST.SENTRY_LABEL.VIDEO_PLAYER.THUMBNAIL} > diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index ab5856111899..bfd8ca5f1d85 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -150,6 +150,7 @@ import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; import type {Beta, Card, Download as DownloadOnyx, OnyxInputOrEntry, Policy, PolicyTagLists, ReportAction, ReportActionReactions, Report as ReportType, Transaction} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; +import type WithSentryLabel from '@src/types/utils/SentryLabel'; import KeyboardUtils from '@src/utils/keyboard'; import type {ContextMenuAnchor} from './ReportActionContextMenu'; import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; @@ -242,7 +243,7 @@ type ContextMenuActionWithContent = { renderContent: RenderContent; }; -type ContextMenuActionWithIcon = { +type ContextMenuActionWithIcon = WithSentryLabel & { textTranslateKey: TranslationPaths; icon: | IconAsset @@ -273,7 +274,6 @@ type ContextMenuActionWithIcon = { >; onPress: OnPress; getDescription: GetDescription; - sentryLabel?: string; }; type ContextMenuAction = (ContextMenuActionWithContent | ContextMenuActionWithIcon) & { diff --git a/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx index b2571ee63e22..111ac98d74fd 100644 --- a/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx @@ -406,6 +406,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref } startMoneyRequest(CONST.IOU.TYPE.CREATE, reportID, undefined, undefined, undefined, allTransactionDrafts); }), + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.CREATE_EXPENSE, }, ]; }, [translate, shouldRedirectToExpensifyClassic, shouldUseNarrowLayout, allTransactionDrafts, reportID]); @@ -459,6 +460,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref onSelected, shouldCallAfterModalHide: shouldUseNarrowLayout, rightIconReportID: quickActionReport?.reportID, + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.QUICK_ACTION, }, ]; } @@ -485,6 +487,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref shouldCallAfterModalHide: shouldUseNarrowLayout, onSelected, rightIconReportID: policyChatForActivePolicy?.reportID, + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.QUICK_ACTION, }, ]; } @@ -550,6 +553,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref startDistanceRequest(CONST.IOU.TYPE.CREATE, reportID, lastDistanceExpenseType); }); }, + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.TRACK_DISTANCE, }, ...(shouldShowCreateReportOption ? [ @@ -585,6 +589,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(workspaceIDForReportCreation)); }); }, + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.CREATE_REPORT, }, ] : []), @@ -593,6 +598,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref text: translate('sidebarScreen.fabNewChat'), shouldCallAfterModalHide: shouldUseNarrowLayout, onSelected: () => interceptAnonymousUser(startNewChat), + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.START_CHAT, }, ...(canSendInvoice ? [ @@ -609,6 +615,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref startMoneyRequest(CONST.IOU.TYPE.INVOICE, reportID, undefined, undefined, undefined, allTransactionDrafts); }), + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.SEND_INVOICE, }, ] : []), @@ -618,6 +625,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref text: translate('travel.bookTravel'), rightIcon: isTravelEnabled && shouldOpenTravelDotLinkWeb() ? icons.NewWindow : undefined, onSelected: () => interceptAnonymousUser(() => openTravel()), + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.BOOK_TRAVEL, }, ], ...(!hasSeenTour @@ -628,6 +636,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref iconFill: theme.icon, text: translate('testDrive.quickAction.takeATwoMinuteTestDrive'), onSelected: () => interceptAnonymousUser(() => startTestDrive(introSelected, tryNewDot?.hasBeenAddedToNudgeMigration ?? false, isUserPaidPolicyMember)), + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.TEST_DRIVE, }, ] : []), @@ -643,6 +652,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref description: translate('workspace.new.getTheExpensifyCardAndMore'), shouldCallAfterModalHide: shouldUseNarrowLayout, onSelected: () => interceptAnonymousUser(() => Navigation.navigate(ROUTES.WORKSPACE_CONFIRMATION.getRoute(Navigation.getActiveRoute()))), + sentryLabel: CONST.SENTRY_LABEL.FAB_MENU.NEW_WORKSPACE, }, ] : []), @@ -695,6 +705,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, ref accessibilityLabel={translate('sidebarScreen.fabScanReceiptExplained')} role={CONST.ROLE.BUTTON} onPress={startQuickScan} + sentryLabel={CONST.SENTRY_LABEL.NAVIGATION_TAB_BAR.FLOATING_RECEIPT_BUTTON} /> )} ); diff --git a/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx b/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx index b5a9627197da..a4339380b0c4 100644 --- a/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx +++ b/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx @@ -349,6 +349,7 @@ function AttachmentModalBaseContent({ onPress={submitAndClose} isDisabled={isConfirmButtonDisabled || shouldDisableSendButton} pressOnEnter + sentryLabel={CONST.SENTRY_LABEL.ATTACHMENT_MODAL.SEND_BUTTON} /> )} diff --git a/src/pages/media/AttachmentModalScreen/routes/TransactionReceiptModalContent.tsx b/src/pages/media/AttachmentModalScreen/routes/TransactionReceiptModalContent.tsx index 0911fb1047d6..e40c22d6ae97 100644 --- a/src/pages/media/AttachmentModalScreen/routes/TransactionReceiptModalContent.tsx +++ b/src/pages/media/AttachmentModalScreen/routes/TransactionReceiptModalContent.tsx @@ -267,6 +267,7 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre ), }); }, + sentryLabel: CONST.SENTRY_LABEL.RECEIPT_MODAL.REPLACE_RECEIPT, }); } if ((!isOffline && allowDownload && !isLocalSource) || !!draftTransactionID) { @@ -274,6 +275,7 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre icon: icons.Download, text: translate('common.download'), onSelected: () => onDownloadAttachment({source: innerSource, file}), + sentryLabel: CONST.SENTRY_LABEL.RECEIPT_MODAL.DOWNLOAD_RECEIPT, }); } @@ -284,6 +286,7 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre text: translate('receipt.deleteReceipt'), onSelected: () => setIsDeleteReceiptConfirmModalVisible?.(true), shouldCallAfterModalHide: true, + sentryLabel: CONST.SENTRY_LABEL.RECEIPT_MODAL.DELETE_RECEIPT, }); } return menuItems; diff --git a/src/types/utils/SentryLabel.ts b/src/types/utils/SentryLabel.ts new file mode 100644 index 000000000000..a452e3e9469f --- /dev/null +++ b/src/types/utils/SentryLabel.ts @@ -0,0 +1,8 @@ +/** + * Label for Sentry tracking. On web, this will be added as data-sentry-label attribute. + */ +type WithSentryLabel = { + sentryLabel?: string; +}; + +export default WithSentryLabel;