Skip to content

Commit 1d881bd

Browse files
authored
Merge pull request #451 from opentripplanner/dev
Patch Release: September 8, 2021
2 parents c37ac4d + bdd8951 commit 1d881bd

14 files changed

+107
-88
lines changed

example-config.yml

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ api:
4242
persistence:
4343
enabled: true
4444
strategy: localStorage
45+
### This variable hides the "more info" link when accepting the terms of storage.
46+
### If no terms of storage page content is set, this removes an otherwise dead link
47+
### False is default in that if the value isn't set, the link isn't shown
48+
# terms_of_storage: true
4549

4650
### If using the OTP Middleware to store user profiles
4751
### with Auth0 as the authentication mechanism,

lib/actions/api.js

+27-13
Original file line numberDiff line numberDiff line change
@@ -723,18 +723,7 @@ function createQueryAction (endpoint, responseAction, errorAction, options = {})
723723
return async function (dispatch, getState) {
724724
const state = getState()
725725
const { config } = state.otp
726-
let url
727-
if (
728-
options.serviceId &&
729-
config.alternateTransitIndex &&
730-
config.alternateTransitIndex.services.includes(options.serviceId)
731-
) {
732-
console.log('Using alt service for ' + options.serviceId)
733-
url = config.alternateTransitIndex.apiRoot + endpoint
734-
} else {
735-
const api = config.api
736-
url = `${api.host}${api.port ? ':' + api.port : ''}${api.path}/${endpoint}`
737-
}
726+
const url = makeApiUrl(config, endpoint, options)
738727

739728
if (!options.noThrottle) {
740729
// don't make a request to a URL that has already seen the same request
@@ -750,9 +739,10 @@ function createQueryAction (endpoint, responseAction, errorAction, options = {})
750739
throttledUrls[throttleKey] = now()
751740
}
752741
}
742+
753743
let payload
754744
try {
755-
const response = await fetch(url, options.fetchOptions)
745+
const response = await fetch(url, getOtpFetchOptions(state))
756746
if (response.status >= 400) {
757747
const error = new Error('Received error from server')
758748
error.response = response
@@ -775,6 +765,30 @@ function createQueryAction (endpoint, responseAction, errorAction, options = {})
775765
}
776766
}
777767

768+
/**
769+
* Creates the URL to use for making an API request.
770+
*
771+
* @param {Object} config The app-wide config
772+
* @param {string} endpoint The API endpoint path
773+
* @param {Object} options The options object for the API request
774+
* @return {string} The URL to use for making the http request
775+
*/
776+
function makeApiUrl (config, endpoint, options) {
777+
let url
778+
if (
779+
options.serviceId &&
780+
config.alternateTransitIndex &&
781+
config.alternateTransitIndex.services.includes(options.serviceId)
782+
) {
783+
console.log('Using alt service for ' + options.serviceId)
784+
url = config.alternateTransitIndex.apiRoot + endpoint
785+
} else {
786+
const api = config.api
787+
url = `${api.host}${api.port ? ':' + api.port : ''}${api.path}/${endpoint}`
788+
}
789+
return url
790+
}
791+
778792
// TODO: Determine how we might be able to use GraphQL with the alternative
779793
// transit index. Currently this is not easily possible because the alternative
780794
// transit index does not have support for GraphQL and handling both Rest and

lib/components/admin/call-taker.css

+11
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,14 @@
99
.otp .advanced-search-options {
1010
box-shadow: 0px 5px 3px 0px rgba(0,0,0,0.32157);
1111
}
12+
13+
.otp .search-options {
14+
display: flex;
15+
justify-content: space-between;
16+
flex-flow: row wrap;
17+
}
18+
19+
.otp .search-options > * {
20+
margin-bottom: 5px;
21+
height: 24px;
22+
}

lib/components/admin/field-trip-list.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Loading from '../narrative/loading'
1010
import {getVisibleRequests, TABS} from '../../util/call-taker'
1111
import {FETCH_STATUS} from '../../util/constants'
1212

13+
import FieldTripStatusIcon from './field-trip-status-icon'
1314
import {FieldTripRecordButton, WindowHeader} from './styled'
1415
import DraggableWindow from './draggable-window'
1516

@@ -186,10 +187,6 @@ class FieldTripRequestRecord extends Component {
186187
onClick(request)
187188
}
188189

189-
_getStatusIcon = (status) => status
190-
? <Icon className='text-success' type='check' />
191-
: <Icon className='text-warning' type='exclamation-circle' />
192-
193190
render () {
194191
const {active, request} = this.props
195192
const style = {
@@ -223,10 +220,10 @@ class FieldTripRequestRecord extends Component {
223220
</span>
224221
<span style={{display: 'inline-block', width: '50%'}}>
225222
<span style={{marginLeft: '10px'}}>
226-
{this._getStatusIcon(inboundTripStatus)} Inbound
223+
<FieldTripStatusIcon ok={Boolean(outboundTripStatus)} /> Outbound
227224
</span>
228225
<span style={{marginLeft: '10px'}}>
229-
{this._getStatusIcon(outboundTripStatus)} Outbound
226+
<FieldTripStatusIcon ok={Boolean(inboundTripStatus)} /> Inbound
230227
</span>
231228
</span>
232229
<span style={{display: 'block', fontSize: '.9em'}}>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react'
2+
3+
import Icon from '../narrative/icon'
4+
5+
const FieldTripStatusIcon = ({ ok }) => (
6+
ok
7+
? <Icon className='text-success' type='check' />
8+
: <Icon className='text-warning' type='exclamation-circle' />
9+
)
10+
11+
export default FieldTripStatusIcon

lib/components/admin/trip-status.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { connect } from 'react-redux'
55

66
import * as fieldTripActions from '../../actions/field-trip'
77
import * as formActions from '../../actions/form'
8-
import Icon from '../narrative/icon'
98
import { getTripFromRequest } from '../../util/call-taker'
109

10+
import FieldTripStatusIcon from './field-trip-status-icon'
1111
import {
1212
Bold,
1313
Button,
@@ -47,13 +47,11 @@ class TripStatus extends Component {
4747
viewRequestTripItineraries(request, outbound)
4848
}
4949

50-
_renderStatusIcon = () => this.props.status
51-
? <Icon className='text-success' type='check' />
52-
: <Icon className='text-warning' type='exclamation-circle' />
50+
_tripIsPlanned = () => Boolean(this.props.status && this.props.trip)
5351

5452
_renderTripStatus = () => {
55-
const { status, trip } = this.props
56-
if (!status || !trip) {
53+
const { trip } = this.props
54+
if (!this._tripIsPlanned()) {
5755
return (
5856
<Para>
5957
No itineraries planned! Click Plan to plan trip.
@@ -92,7 +90,7 @@ class TripStatus extends Component {
9290
return (
9391
<Full>
9492
<Header>
95-
{this._renderStatusIcon()}
93+
<FieldTripStatusIcon ok={this._tripIsPlanned()} />
9694
{outbound ? 'Outbound' : 'Inbound'} trip
9795
<Button bsSize='xs' onClick={this._onPlanTrip}>Plan</Button>
9896
<Button

lib/components/app/call-taker-panel.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class CallTakerPanel extends Component {
187187
onClick={this._addPlace}
188188
to={to}
189189
/>
190-
<div className='search-options' style={{height: '30px'}}>
190+
<div className='search-options'>
191191
<DateTimeOptions
192192
date={date}
193193
departArrive={departArrive}
@@ -208,9 +208,7 @@ class CallTakerPanel extends Component {
208208
onClick={this._planTrip}
209209
style={{
210210
fontSize: '13px',
211-
padding: '0px 10px',
212-
position: 'absolute',
213-
right: '6px'
211+
padding: '1px 10px'
214212
}} >
215213
Plan
216214
</Button>
@@ -261,7 +259,7 @@ class CallTakerPanel extends Component {
261259
right: '0',
262260
// FIXME: This top pixel value can be variable dependent on
263261
// height of the form above. It may need to be specified differently
264-
top: 193 + intermediatePlaces.length * 45
262+
top: 210 + intermediatePlaces.length * 45
265263
}}
266264
/>
267265
</div>

lib/components/form/call-taker/date-time-options.js

+22-29
Original file line numberDiff line numberDiff line change
@@ -186,44 +186,37 @@ export default class DateTimeOptions extends Component {
186186
onKeyDown={onKeyDown}
187187
value={departArrive}
188188
>
189-
{departureOptions.map(o => (
190-
<option key={o.value} {...o} />
191-
))}
189+
{departureOptions.map(o => <option key={o.value} {...o} />)}
192190
</select>
193-
<span style={{display: 'inline-flex'}}>
194-
<OverlayTrigger
195-
overlay={<Tooltip id='time-tooltip'>{cleanTime}</Tooltip>}
196-
placement='bottom'
197-
trigger={['focus', 'hover']}
198-
>
199-
<input
200-
className='datetime-slim'
201-
onChange={this.handleTimeChange}
202-
onFocus={this.handleTimeFocus}
203-
onKeyDown={onKeyDown}
204-
style={{
205-
fontSize: 'inherit',
206-
lineHeight: '.8em',
207-
marginLeft: '3px',
208-
padding: '0px',
209-
width: '50px'
210-
}}
211-
value={timeInput || dateTime.format('H:mm')}
212-
/>
213-
</OverlayTrigger>
214-
</span>
191+
<OverlayTrigger
192+
overlay={<Tooltip id='time-tooltip'>{cleanTime}</Tooltip>}
193+
placement='bottom'
194+
trigger={['focus', 'hover']}
195+
>
196+
<input
197+
className='datetime-slim'
198+
onChange={this.handleTimeChange}
199+
onFocus={this.handleTimeFocus}
200+
onKeyDown={onKeyDown}
201+
style={{
202+
fontSize: 'inherit',
203+
lineHeight: '.8em',
204+
marginLeft: '3px',
205+
padding: '0px',
206+
width: '50px'
207+
}}
208+
value={timeInput || dateTime.format('H:mm')}
209+
/>
210+
</OverlayTrigger>
215211
<input
216212
className='datetime-slim'
217213
onChange={this.handleDateChange}
218214
onKeyDown={onKeyDown}
219215
style={{
220-
border: 'none',
221216
fontSize: '14px',
222-
left: '146px',
223217
lineHeight: '1em',
224218
outline: 'none',
225-
position: 'absolute',
226-
width: '101px'
219+
width: '109px'
227220
}}
228221
type='date'
229222
value={dateTime.format('YYYY-MM-DD')}

lib/components/form/call-taker/mode-dropdown.js

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ export default class ModeDropdown extends Component {
7474
onBlur={this._setMode}
7575
onChange={this._onChange}
7676
onKeyDown={onKeyDown}
77-
style={{position: 'absolute', right: '60px'}}
7877
value={this.modeToOptionValue(mode)}
7978
>
8079
{this._getModeOptions().map(o => (

lib/components/narrative/default/default-itinerary.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import FieldTripGroupSize from '../../admin/field-trip-itinerary-group-size'
88
import NarrativeItinerary from '../narrative-itinerary'
99
import ItineraryBody from '../line-itin/connected-itinerary-body'
1010
import SimpleRealtimeAnnotation from '../simple-realtime-annotation'
11+
import { getTotalFare } from '../../../util/state'
1112

1213
import ItinerarySummary from './itinerary-summary'
1314

14-
const { calculateFares, isBicycle, isMicromobility, isTransit } = coreUtils.itinerary
15+
const { isBicycle, isMicromobility, isTransit } = coreUtils.itinerary
1516

1617
/**
1718
* Obtains the description of an itinerary in the given locale.
@@ -125,14 +126,12 @@ const ITINERARY_ATTRIBUTES = [
125126
id: 'cost',
126127
order: 2,
127128
render: (itinerary, options) => {
128-
// Get unformatted transit fare portion only (in cents).
129-
const { transitFare } = calculateFares(itinerary)
130129
return (
131130
<FormattedNumber
132131
currency={options.currency}
133132
currencyDisplay='narrowSymbol'
134133
style='currency'
135-
value={transitFare / 100}
134+
value={getTotalFare(itinerary, options.configCosts) / 100}
136135
/>
137136
)
138137
}
@@ -194,6 +193,7 @@ class DefaultItinerary extends NarrativeItinerary {
194193
render () {
195194
const {
196195
active,
196+
configCosts,
197197
currency,
198198
expanded,
199199
itinerary,
@@ -246,6 +246,7 @@ class DefaultItinerary extends NarrativeItinerary {
246246
}
247247
options.LegIcon = LegIcon
248248
options.timeFormat = use24HourFormat ? 'H:mm' : 'h:mm a'
249+
options.configCosts = configCosts
249250
options.currency = currency
250251
return (
251252
<li className={`${attribute.id}${isSelected ? ' main' : ''}`} key={attribute.id}>
@@ -276,6 +277,7 @@ class DefaultItinerary extends NarrativeItinerary {
276277

277278
const mapStateToProps = (state, ownProps) => {
278279
return {
280+
configCosts: state.otp.config.itinerary?.costs,
279281
// The configured (ambient) currency is needed for rendering the cost
280282
// of itineraries whether they include a fare or not, in which case
281283
// we show $0.00 or its equivalent in the configured currency and selected locale.

lib/components/narrative/narrative-itineraries-header.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export default function NarrativeItinerariesHeader ({
9595
<select
9696
onBlur={onSortChange}
9797
onChange={onSortChange}
98-
value={sort.value}
98+
value={sort.type}
9999
>
100100
<option value='BEST'>Best option</option>
101101
<option value='DURATION'>Duration</option>

lib/components/user/terms-of-use-pane.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react'
2+
import { connect } from 'react-redux'
23
import { Checkbox, ControlLabel, FormGroup } from 'react-bootstrap'
34

45
import { TERMS_OF_SERVICE_PATH, TERMS_OF_STORAGE_PATH } from '../../util/constants'
@@ -10,6 +11,7 @@ const TermsOfUsePane = ({
1011
disableCheckTerms,
1112
handleBlur,
1213
handleChange,
14+
termsOfStorageSet,
1315
values: userData
1416
}) => {
1517
const {
@@ -46,11 +48,15 @@ const TermsOfUsePane = ({
4648
>
4749
{/* TODO: Implement the link */}
4850
Optional: I consent to the Trip Planner storing my historical planned trips in order to
49-
improve transit services in my area. <a href={`/#${TERMS_OF_STORAGE_PATH}`} target='_blank'>More info...</a>
51+
improve transit services in my area. {termsOfStorageSet && <a href={`/#${TERMS_OF_STORAGE_PATH}`} target='_blank'>More info...</a>}
5052
</Checkbox>
5153
</FormGroup>
5254
</div>
5355
)
5456
}
55-
56-
export default TermsOfUsePane
57+
const mapStateToProps = (state) => {
58+
return {
59+
termsOfStorageSet: state.otp.config.persistence?.terms_of_storage
60+
}
61+
}
62+
export default connect(mapStateToProps)(TermsOfUsePane)

lib/util/auth.js

-7
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ export const accountLinks = [
88
{
99
text: 'My account',
1010
url: ACCOUNT_PATH
11-
},
12-
{
13-
// Add a target attribute if you need the link to open in a new window, etc.
14-
// (supports the same values as <a target=... >).
15-
// target: '_blank',
16-
text: 'Help',
17-
url: '/help'
1811
}
1912
]
2013

0 commit comments

Comments
 (0)