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

chore/9616-rollback-link-with-analytics-component #9626

Merged
merged 7 commits into from
Sep 23, 2024
Merged
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
56 changes: 46 additions & 10 deletions VAMobile/src/components/AttachmentLink.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import React, { FC } from 'react'
import { AccessibilityProps, Pressable, PressableProps } from 'react-native'

import { a11yHintProp } from 'utils/accessibility'
import { useTheme } from 'utils/hooks'
import { featureEnabled } from 'utils/remoteConfig'

import Box from './Box'
import LinkWithAnalytics from './LinkWithAnalytics'
import TextView from './TextView'
import VAIcon from './VAIcon'

export type AttachmentLinkProps = {
/** Name of link/attachment */
Expand Down Expand Up @@ -31,15 +39,43 @@ const AttachmentLink: FC<AttachmentLinkProps> = ({
const text = [name, formattedSize].join(' ').trim()
const textA11y = [name, formattedSizeA11y].join(' ').trim()

return (
<LinkWithAnalytics
type="attachment"
text={text}
onPress={onPress}
a11yLabel={textA11y}
a11yHint={a11yHint}
a11yValue={a11yValue}
/>
)
const theme = useTheme()
if (featureEnabled('useOldLinkComponent')) {
const pressableProps: PressableProps = {
onPress: onPress,
accessibilityRole: 'button',
accessible: true,
}

const a11yProps: AccessibilityProps = {
accessibilityLabel: textA11y,
...a11yHintProp(a11yHint || ''),
accessibilityValue: a11yValue ? { text: a11yValue } : {},
}

return (
<Pressable {...a11yProps} {...pressableProps}>
<Box flexDirection={'row'} mr={theme.dimensions.gutter}>
<Box mt={theme.dimensions.attachmentIconTopMargin} mr={theme.dimensions.textIconMargin}>
<VAIcon name="PaperClip" width={16} height={16} fill={'link'} />
</Box>
<TextView mr={theme.dimensions.textIconMargin} variant={'MobileBodyLink'}>
{text}
</TextView>
</Box>
</Pressable>
)
} else {
return (
<LinkWithAnalytics
type="attachment"
text={text}
onPress={onPress}
a11yLabel={textA11y}
a11yHint={a11yHint}
a11yValue={a11yValue}
/>
)
}
}
export default AttachmentLink
42 changes: 34 additions & 8 deletions VAMobile/src/components/ClickForActionLinkDeprecated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,19 @@ export type LinkButtonProps = AccessibilityProps & {

/** optional function to fire analytic events when the link is clicked */
fireAnalytic?: () => void

/** color bypass */
colorOverride?: string

/** custom onPress */
customOnPress?: () => void

/** hide icon */
hideIcon?: boolean

/** disable padding */
disablePadding?: boolean

/** Optional TestID */
testID?: string
}
Expand All @@ -89,10 +100,16 @@ const ClickForActionLinkDeprecated: FC<LinkButtonProps> = ({
a11yLabel,
fireAnalytic,
colorOverride,
customOnPress,
hideIcon = false,
disablePadding = false,
testID,
...props
}) => {
const theme = useTheme()
const py = disablePadding ? 0 : theme.dimensions.buttonPadding
const pr = disablePadding ? 0 : theme.dimensions.gutter

const launchExternalLink = useExternalLink()

const onCalendarPress = async (): Promise<void> => {
Expand All @@ -109,6 +126,11 @@ const ClickForActionLinkDeprecated: FC<LinkButtonProps> = ({
}

const _onPress = async (): Promise<void> => {
if (customOnPress) {
customOnPress()
return
}

if (fireAnalytic) {
fireAnalytic()
}
Expand Down Expand Up @@ -176,14 +198,18 @@ const ClickForActionLinkDeprecated: FC<LinkButtonProps> = ({

return (
<TouchableWithoutFeedback testID={testID} {...pressableProps}>
<Box flexDirection={'row'} py={theme.dimensions.buttonPadding} alignItems={'center'}>
<VAIcon
name={getIconName()}
fill={colorOverride ? (colorOverride as ColorVariant) : 'link'}
fill2={colorOverride ? 'transparent' : ''}
width={25}
height={25}
/>
<Box flexDirection={'row'} alignItems={'center'} py={py} pr={pr}>
{!hideIcon && (
<Box pr={3}>
<VAIcon
name={getIconName()}
fill={colorOverride ? (colorOverride as ColorVariant) : 'link'}
fill2={colorOverride ? 'transparent' : ''}
width={25}
height={25}
/>
</Box>
)}
<Box flexShrink={1}>
<TextView {...textViewProps}>{displayedText}</TextView>
</Box>
Expand Down
73 changes: 68 additions & 5 deletions VAMobile/src/components/LinkWithAnalytics.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import React from 'react'

import { Link, LinkProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Link/Link'
import { LocationData } from '@department-of-veterans-affairs/mobile-component-library/src/utils/OSfunctions'
import _ from 'lodash'

import { Events } from 'constants/analytics'
import { logAnalyticsEvent } from 'utils/analytics'
import { useTheme } from 'utils/hooks'
import { isIOS } from 'utils/platform'
import { featureEnabled } from 'utils/remoteConfig'

import Box from './Box'
import ClickForActionLinkDeprecated, { LinkTypeOptionsConstants, LinkUrlIconType } from './ClickForActionLinkDeprecated'
import TextView from './TextView'

export type LinkWithAnalyticsProps = LinkProps & {
/** optional additional analytics function */
Expand All @@ -17,6 +22,28 @@ export type LinkWithAnalyticsProps = LinkProps & {
/** optional boolean to turn off padding */
disablePadding?: boolean
}
/** Function to convert location data into a URL for handling by Apple/Google Maps */
const FormDirectionsUrl = (location: LocationData): string => {
const { name, address, latitude, longitude } = location
const addressString = Object.values(address || {}).join(' ')

const APPLE_MAPS_BASE_URL = 'https://maps.apple.com/'
const GOOGLE_MAPS_BASE_URL = 'https://www.google.com/maps/dir/'

if (isIOS()) {
const queryString = new URLSearchParams({
t: 'm', // type: map
daddr: `${addressString}+${name}+${latitude},${longitude}`,
}).toString()
return `${APPLE_MAPS_BASE_URL}?${queryString}`
} else {
const queryString = new URLSearchParams({
api: '1',
destination: addressString || `${latitude},${longitude}`,
}).toString()
return `${GOOGLE_MAPS_BASE_URL}?${queryString}`
}
}

/** Wrapper for the Link component which adds analytics */
const LinkWithAnalytics = ({ analyticsOnPress, analyticsProps, disablePadding, ...props }: LinkWithAnalyticsProps) => {
Expand All @@ -36,11 +63,47 @@ const LinkWithAnalytics = ({ analyticsOnPress, analyticsProps, disablePadding, .
onConfirm: () => logAnalyticsEvent(Events.vama_link_confirm(definedProps)),
}

return (
<Box flexDirection={'row'} flexWrap="wrap" py={py} pr={pr}>
<Link analytics={analytics} icon={{ preventScaling: true }} {...props} />
</Box>
)
if (featureEnabled('useOldLinkComponent')) {
let linkType = ''
if (props.type === 'attachment') {
// this should never happen since we're handling attachments differently with the flag enabled
return <TextView>ERROR: Type "attachment" not supported with useOldLinkComponent enabled</TextView>
} else if (props.type === 'call TTY') {
linkType = 'callTTY'
} else {
linkType = props.type
}

// create URL from appointment location
const directionsURL = locationData ? FormDirectionsUrl(locationData) : ''

// hide icon when viewing a Secure Message with links in the body
const hideIcon = props.icon === 'no icon'

return (
<ClickForActionLinkDeprecated
displayedText={props.text}
linkType={LinkTypeOptionsConstants[linkType as keyof typeof LinkTypeOptionsConstants]}
numberOrUrlLink={props.url || props.phoneNumber || props.TTYnumber || props.textNumber || directionsURL}
linkUrlIconType={LinkUrlIconType.Arrow}
a11yLabel={props.a11yLabel || props.text}
fireAnalytic={() => {
props.analytics?.onPress?.()
analyticsOnPress && analyticsOnPress()
}}
customOnPress={props.onPress}
hideIcon={hideIcon}
disablePadding={disablePadding}
testID={props.testID}
/>
)
} else {
return (
<Box flexDirection={'row'} flexWrap="wrap" py={py} pr={pr}>
<Link analytics={analytics} icon={{ preventScaling: true }} {...props} />
</Box>
)
}
}

export default LinkWithAnalytics
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UseMutateFunction } from '@tanstack/react-query'
import { AppointmentAttributes } from 'api/types'
import { Box, TextArea } from 'components'
import { AppointmentDetailsSubType, AppointmentDetailsTypeConstants } from 'utils/appointments'
import { featureEnabled } from 'utils/remoteConfig'

import {
AppointmentCalendarButton,
Expand All @@ -17,6 +18,7 @@ import {
AppointmentProvider,
AppointmentReasonAndComment,
AppointmentTypeOfCare,
DEPRECATED_AppointmentCalendarButton,
} from './SharedComponents'

type ClaimExamAppointmentProps = {
Expand All @@ -40,12 +42,21 @@ function ClaimExamAppointment({
<TextArea>
<AppointmentDetailsModality attributes={attributes} subType={subType} type={type} />
<AppointmentDateAndTime attributes={attributes} subType={subType} />
<AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
{featureEnabled('useOldLinkComponent') ? (
<DEPRECATED_AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
) : (
<AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
)}
<AppointmentTypeOfCare attributes={attributes} subType={subType} type={type} />
<AppointmentPreferredModality subType={subType} type={type} />
<AppointmentProvider attributes={attributes} subType={subType} type={type} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
AppointmentDetailsSubTypeConstants,
AppointmentDetailsTypeConstants,
} from 'utils/appointments'
import { featureEnabled } from 'utils/remoteConfig'

import {
AppointmentCalendarButton,
Expand All @@ -21,6 +22,7 @@ import {
AppointmentReasonAndComment,
AppointmentTypeOfCare,
CommunityCarePendingLocation,
DEPRECATED_AppointmentCalendarButton,
} from './SharedComponents'

type CommunityCareAppointmentProps = {
Expand Down Expand Up @@ -50,12 +52,21 @@ function CommunityCareAppointment({
<TextArea>
<AppointmentDetailsModality attributes={attributes} subType={subType} type={type} />
<AppointmentDateAndTime attributes={attributes} subType={subType} />
<AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
{featureEnabled('useOldLinkComponent') ? (
<DEPRECATED_AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
) : (
<AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
)}
<AppointmentTypeOfCare attributes={attributes} subType={subType} type={type} />
<AppointmentProvider attributes={attributes} subType={subType} type={type} />
{isPending ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UseMutateFunction } from '@tanstack/react-query'
import { AppointmentAttributes } from 'api/types'
import { Box, TextArea } from 'components'
import { AppointmentDetailsSubType, AppointmentDetailsTypeConstants } from 'utils/appointments'
import { featureEnabled } from 'utils/remoteConfig'

import {
AppointmentCalendarButton,
Expand All @@ -17,6 +18,7 @@ import {
AppointmentProvider,
AppointmentReasonAndComment,
AppointmentTypeOfCare,
DEPRECATED_AppointmentCalendarButton,
} from './SharedComponents'

type InPersonVAAppointmentProps = {
Expand All @@ -40,12 +42,21 @@ function InPersonVAAppointment({
<TextArea>
<AppointmentDetailsModality attributes={attributes} subType={subType} type={type} />
<AppointmentDateAndTime attributes={attributes} subType={subType} />
<AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
{featureEnabled('useOldLinkComponent') ? (
<DEPRECATED_AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
) : (
<AppointmentCalendarButton
appointmentID={appointmentID}
attributes={attributes}
subType={subType}
type={type}
/>
)}
<AppointmentTypeOfCare attributes={attributes} subType={subType} type={type} />
<AppointmentPreferredModality subType={subType} type={type} />
<AppointmentProvider attributes={attributes} subType={subType} type={type} />
Expand Down
Loading
Loading