Skip to content

Commit

Permalink
Merge pull request #859 from opentripplanner/external-link-icons
Browse files Browse the repository at this point in the history
Clarify Links That Open in New Window
  • Loading branch information
amy-corson-ibigroup authored May 2, 2023
2 parents bfe3aa3 + 12d3812 commit f230ae9
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 98 deletions.
1 change: 1 addition & 0 deletions i18n/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ common:
tripDurationFormat: >-
{hours, plural, =0 {} other {# hr }}{minutes} min { seconds, plural, =0 {}
other {# sec}}
linkOpensNewWindow: "(Opens new window)"
components:
A11yPrefs:
accessibilityRoutingByDefault: Prefer accessible trips by default
Expand Down
7 changes: 7 additions & 0 deletions lib/components/admin/field-trip-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
TICKET_TYPES
} from '../../util/call-taker'
import { IconWithText, StyledIconWrapper } from '../util/styledIcon'
import { NewWindowIconA11y } from '../util/externalLink'

import {
Bold,
Expand Down Expand Up @@ -98,6 +99,9 @@ class FieldTripDetails extends Component {
const { request, sessionId } = this.props
const cancelled = request.status === 'cancelled'
const printFieldTripLink = `/#/printFieldTrip/?requestId=${request.id}&sessionId=${sessionId}`
const StyledNewWindowIcon = () => (
<NewWindowIconA11y size={10} style={{ margin: '-3px 0 0 4px' }} />
)
return (
<div style={{ padding: '5px 10px 0px 10px' }}>
<DropdownButton
Expand All @@ -112,12 +116,15 @@ class FieldTripDetails extends Component {
target="_blank"
>
<IconWithText Icon={CommentDots}>Feedback link</IconWithText>
<StyledNewWindowIcon />
</MenuItem>
<MenuItem href={this._getRequestLink('receipt')} target="_blank">
<IconWithText Icon={FileAlt}>Receipt link</IconWithText>
<StyledNewWindowIcon />
</MenuItem>
<MenuItem href={printFieldTripLink} target="_blank">
<IconWithText Icon={Print}>Printable trip plan</IconWithText>
<StyledNewWindowIcon />
</MenuItem>
</DropdownButton>
<Button
Expand Down
9 changes: 7 additions & 2 deletions lib/components/admin/field-trip-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { IconWithText, StyledIconWrapper } from '../util/styledIcon'
import Loading from '../narrative/loading'

import { FieldTripRecordButton, WindowHeader } from './styled'
import { LinkOpensNewWindow } from '../util/externalLink'
import DraggableWindow from './draggable-window'
import FieldTripStatusIcon from './field-trip-status-icon'

Expand Down Expand Up @@ -185,8 +186,12 @@ class FieldTripList extends Component {
type="date"
value={date}
/>
<Button bsSize="xsmall" href={this._getReportUrl()} target="_blank">
View report
<Button bsSize="xsmall">
<LinkOpensNewWindow
contents="View report"
style={{ textDecoration: 'none' }}
url={this._getReportUrl()}
/>
</Button>
</>
}
Expand Down
82 changes: 0 additions & 82 deletions lib/components/user/terms-of-use-pane.js

This file was deleted.

105 changes: 105 additions & 0 deletions lib/components/user/terms-of-use-pane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Checkbox, ControlLabel, FormGroup } from 'react-bootstrap'
import { connect } from 'react-redux'
import { FormattedMessage, useIntl } from 'react-intl'
import React, { FormEventHandler } from 'react'

import { LinkOpensNewWindow } from '../util/externalLink'
import {
TERMS_OF_SERVICE_PATH,
TERMS_OF_STORAGE_PATH
} from '../../util/constants'

/**
* User terms of use pane.
*/
const TermsOfUsePane = ({
disableCheckTerms,
handleBlur,
handleChange,
values: userData
}: {
disableCheckTerms: boolean
handleBlur: () => void
handleChange: FormEventHandler<Checkbox>
values: {
hasConsentedToTerms: boolean
storeTripHistory: boolean
}
}) => {
const intl = useIntl()
const { hasConsentedToTerms, storeTripHistory } = userData

return (
<div>
<ControlLabel>
<FormattedMessage id="components.TermsOfUsePane.mustAgreeToTerms" />
</ControlLabel>
<FormGroup>
<Checkbox
checked={hasConsentedToTerms}
disabled={disableCheckTerms}
name="hasConsentedToTerms"
onBlur={disableCheckTerms ? undefined : handleBlur}
onChange={disableCheckTerms ? undefined : handleChange}
>
<FormattedMessage
id="components.TermsOfUsePane.termsOfServiceStatement"
values={{
termsOfUseLink: (contents: JSX.Element) => (
<LinkOpensNewWindow
contents={contents}
inline
url={`/#${TERMS_OF_SERVICE_PATH}`}
/>
)
}}
/>
</Checkbox>
</FormGroup>
<FormGroup>
<Checkbox
checked={storeTripHistory}
name="storeTripHistory"
onBlur={handleBlur}
onChange={(e) => {
// Show alert when user is unchecking the checkbox
if (storeTripHistory) {
// Do nothing if the user hits cancel
if (
// eslint-disable-next-line no-restricted-globals
!confirm(
intl.formatMessage({
id: 'components.TermsOfUsePane.confirmDeletionPrompt'
})
)
) {
return
}
}

handleChange(e)
}}
>
<FormattedMessage
id="components.TermsOfUsePane.termsOfStorageStatement"
values={{
termsOfStorageLink: (contents: JSX.Element) => (
<LinkOpensNewWindow
contents={contents}
inline
url={`/#${TERMS_OF_STORAGE_PATH}`}
/>
)
}}
/>
</Checkbox>
</FormGroup>
</div>
)
}
const mapStateToProps = (state: any) => {
return {
termsOfStorageSet: state.otp.config.persistence?.terms_of_storage
}
}
export default connect(mapStateToProps)(TermsOfUsePane)
62 changes: 62 additions & 0 deletions lib/components/util/externalLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { ExternalLinkAlt } from '@styled-icons/fa-solid'
import { useIntl } from 'react-intl'
import React, { HTMLAttributes } from 'react'

interface LinkProps extends HTMLAttributes<HTMLElement> {
contents: JSX.Element | string
gap?: number
inline?: boolean
size?: number
style?: React.CSSProperties
url: string
}

interface IconProps extends HTMLAttributes<HTMLElement> {
size?: number
style?: React.CSSProperties
}

export const NewWindowIconA11y = ({
size = 14,
style
}: IconProps): JSX.Element => {
const intl = useIntl()
return (
<ExternalLinkAlt
/* the "title" prop removes aria-hidden from styled-icons, so use the title as the aria-label as well
https://github.com/styled-icons/styled-icons#accessibility */
aria-labelledby="title"
height={size}
style={style}
title={intl.formatMessage({ id: 'common.linkOpensNewWindow' })}
/>
)
}

export const LinkOpensNewWindow = ({
contents,
gap = 6,
inline,
size = 14,
style,
url
}: LinkProps): JSX.Element => {
return (
<a
href={url}
rel="noreferrer"
style={{
alignItems: 'center',
display: `${inline ? 'inline-flex' : 'flex'}`,
flexDirection: 'row',
gap,
whiteSpace: 'nowrap',
...style
}}
target="_blank"
>
{contents}
<NewWindowIconA11y size={size} />
</a>
)
}
22 changes: 8 additions & 14 deletions lib/components/viewers/route-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { connect } from 'react-redux'
import { FormattedMessage, injectIntl } from 'react-intl'
import { getMostReadableTextColor } from '@opentripplanner/core-utils/lib/route'
import { Link } from '@styled-icons/fa-solid/Link'
import { LinkOpensNewWindow } from '../util/externalLink'
import PropTypes from 'prop-types'
import React, { Component } from 'react'

Expand All @@ -14,7 +14,6 @@ import {
import { findStopsForPattern } from '../../actions/api'
import { getOperatorName } from '../../util/state'
import { setHoveredStop, setViewedRoute, setViewedStop } from '../../actions/ui'
import { StyledIconWrapper } from '../util/styledIcon'

import {
Container,
Expand Down Expand Up @@ -145,20 +144,15 @@ class RouteDetails extends Component {
</>
)}
{url && (
<a
href={url}
rel="noreferrer"
<LinkOpensNewWindow
contents={
<FormattedMessage id="components.RouteDetails.moreDetails" />
}
style={{
color: getMostReadableTextColor(routeColor, route?.textColor),
whiteSpace: 'nowrap'
color: getMostReadableTextColor(routeColor, route?.textColor)
}}
target="_blank"
>
<StyledIconWrapper>
<Link />
</StyledIconWrapper>
<FormattedMessage id="components.RouteDetails.moreDetails" />
</a>
url={url}
/>
)}
</LogoLinkContainer>
</RouteNameContainer>
Expand Down

0 comments on commit f230ae9

Please sign in to comment.