Skip to content

Commit

Permalink
Merge branch 'dev' into add-tos-from-config
Browse files Browse the repository at this point in the history
  • Loading branch information
amy-corson-ibigroup authored Dec 5, 2023
2 parents 07c3c9f + 14f33a5 commit 8038f2c
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 132 deletions.
1 change: 1 addition & 0 deletions example-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ itinerary:
# BUS: # Any OTP mode
# color: 00FF00 # HEX color without the # (like GTFS)
# textColor: FFFFFF # HEX color without the # (like GTFS)
# routeIcons: false # If set to false, no mode icons in the route viewer
# - feedId: TriMet
# agencyId: TRIMET
# name: TriMet
Expand Down
4 changes: 0 additions & 4 deletions lib/actions/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { getSecureFetchOptions } from '../util/middleware'
import { getStopViewerConfig } from '../util/state'

import { MainPanelContent } from './ui-constants'
import { setVisibleItinerary } from './narrative'
import v1Actions from './apiV1'
import v2Actions from './apiV2'

Expand Down Expand Up @@ -139,9 +138,6 @@ export function updateOtpUrlParams(state, searchId) {
params.ui_activeItinerary = -1
// At the same time, reset/delete the ui_itineraryView param.
params.ui_itineraryView = undefined
if (config.itinerary?.showFirstResultByDefault) {
dispatch(setVisibleItinerary({ index: 0 }))
}
// Merge in the provided OTP params and update the URL.
dispatch(setUrlSearch(Object.assign(params, otpParams)))
}
Expand Down
7 changes: 6 additions & 1 deletion lib/actions/apiV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,12 @@ export const findRoute = (params) =>
})
})

filteredPatterns.forEach((pattern) => {
// Fallback for if the filtering removes all patterns
// If this happens, it is not possible to know which pattern to keep
;(filteredPatterns.length > 0
? filteredPatterns
: newRoute.patterns
).forEach((pattern) => {
const patternStops = pattern.stops.map((stop) => {
const color =
stop.routes?.length > 0 &&
Expand Down
52 changes: 27 additions & 25 deletions lib/components/form/call-taker/advanced-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ class AdvancedOptions extends Component {
})
}

_setBikeTolerance = ({ bikeTolerance }) => {
_setBikeReluctance = ({ bikeReluctance }) => {
this.props.setUrlSearch({
bikeTolerance
bikeReluctance
})
}

Expand Down Expand Up @@ -221,6 +221,10 @@ class AdvancedOptions extends Component {
title: modeObj.label
}
})
const bikeEnabled = hasBike(
currentModes?.map((m) => m.mode).join(',') || ''
)
const bikeString = bikeEnabled ? 'Biking' : 'Walking'
return (
<div>
<div
Expand All @@ -231,34 +235,32 @@ class AdvancedOptions extends Component {
}}
>
<DropdownSelector
label={intl.formatMessage({
id: 'components.AdvancedOptions.walkTolerance'
})}
name="walkReluctance"
onChange={this._setWalkTolerance}
label={
bikeEnabled
? intl.formatMessage({
id: 'components.AdvancedOptions.bikeTolerance'
})
: intl.formatMessage({
id: 'components.AdvancedOptions.walkTolerance'
})
}
name={bikeEnabled ? 'bikeReluctance' : 'walkReluctance'}
onChange={
bikeEnabled ? this._setBikeReluctance : this._setWalkTolerance
}
options={[
{ text: 'Normal Walking', value: 3 },
{ text: 'Avoid Walking', value: 15 },
{ text: 'Prefer walking', value: 1 }
{ text: `Normal ${bikeString}`, value: 3 },
{ text: `Avoid ${bikeString}`, value: 15 },
{ text: `Prefer ${bikeString}`, value: 1 }
]}
style={{ display: 'block', width: '33ch' }}
value={this.props.modeSettingValues.walkReluctance}
value={
bikeEnabled
? this.props.modeSettingValues.bikeReluctance
: this.props.modeSettingValues.walkReluctance
}
/>

{hasBike(currentModes?.map((m) => m.mode).join(',') || '') ? (
<SliderSelector
label={intl.formatMessage({
id: 'components.AdvancedOptions.bikeTolerance'
})}
max={5}
min={0}
name="bikeTolerance"
onChange={this._setBikeTolerance}
step={1}
style={{ display: 'block', marginRight: '10px', width: '150px' }}
value={this.props.modeSettingValues.bikeTolerance}
/>
) : null}
<StyledSubmodeSelector
modes={transitModes}
onChange={this._onSubModeChange}
Expand Down
31 changes: 28 additions & 3 deletions lib/components/narrative/narrative-itineraries.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,16 @@ class NarrativeItineraries extends Component {
)
}

componentDidUpdate() {
componentDidUpdate(prevProps) {
// If set in URL, set the active itinerary in the state, once.
const {
activeItinerary,
activeSearch,
itineraryConfig,
mergedItineraries,
setActiveItinerary,
setVisibleItinerary
setVisibleItinerary,
visibleItinerary
} = this.props
const { ui_activeItinerary: uiActiveItinerary } =
coreUtils.query.getUrlParams() || {}
Expand All @@ -350,6 +353,27 @@ class NarrativeItineraries extends Component {
setActiveItinerary({ index: +uiActiveItinerary })
setVisibleItinerary({ index: +uiActiveItinerary })
}

/**
* Showing the first result by default is a lot more complicated now that we have
* fixed indices. We must update the visible itinerary here instead of in the redux state.
* Also, we need to update whenever new items arrive, to make sure that the highlighted
* itinerary is indeed the first one.
*
* Finally, we need to make sure we only update if the data changes, not if the user actually
* highlighted something else on their own.
*/
if (itineraryConfig?.showFirstResultByDefault) {
if (
activeItinerary === -1 &&
(visibleItinerary === null || visibleItinerary === false) &&
prevProps.mergedItineraries.length !== mergedItineraries.length
) {
setVisibleItinerary({
index: mergedItineraries?.length > 0 && mergedItineraries?.[0].index
})
}
}
}

// eslint-disable-next-line complexity
Expand Down Expand Up @@ -531,7 +555,7 @@ const reduceErrorsFromResponse = (acc, cur) => {

const mapStateToProps = (state) => {
const { config, filter } = state.otp
const { co2, errorMessages, modes } = config
const { co2, errorMessages, itinerary, modes } = config
const { sort } = filter

const activeSearch = getActiveSearch(state)
Expand Down Expand Up @@ -590,6 +614,7 @@ const mapStateToProps = (state) => {
groupItineraries,
groupTransitModes,
itineraries: allItineraries,
itineraryConfig: itinerary,
itineraryIsExpanded,
// use a key so that the NarrativeItineraries component and its state is
// reset each time a new search is shown
Expand Down
4 changes: 2 additions & 2 deletions lib/components/user/monitored-trip/saved-trip-editor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FormattedMessage, useIntl } from 'react-intl'
import React, { ComponentType } from 'react'

import { MonitoredTrip } from '../types'
import BackLink from '../back-link'
import PageTitle from '../../util/page-title'
import StackedPanesWithSave from '../stacked-panes-with-save'
Expand All @@ -9,8 +10,7 @@ interface Props {
isCreating: boolean
onCancel: () => void
panes: Record<string, ComponentType>
// TODO: Combine monitored trip types
values: Record<string, unknown>
values: MonitoredTrip
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable react/prop-types */
import { Button, Panel } from 'react-bootstrap'
import { connect } from 'react-redux'
import { FormattedMessage, injectIntl, useIntl } from 'react-intl'
import { FormattedMessage, injectIntl, IntlShape, useIntl } from 'react-intl'
import { Pause } from '@styled-icons/fa-solid/Pause'
import { PencilAlt } from '@styled-icons/fa-solid/PencilAlt'
import { Play } from '@styled-icons/fa-solid/Play'
Expand All @@ -11,8 +10,10 @@ import React, { Component } from 'react'

import * as uiActions from '../../../actions/ui'
import * as userActions from '../../../actions/user'
import { AppReduxState } from '../../../util/state-types'
import { IconWithText } from '../../util/styledIcon'
import { InlineLoading } from '../../narrative/loading'
import { MonitoredTrip } from '../types'
import {
PageHeading,
TripHeader,
Expand All @@ -29,15 +30,34 @@ import withLoggedInUserSupport from '../with-logged-in-user-support'

import TripSummaryPane from './trip-summary-pane'

interface ItemProps {
confirmAndDeleteUserMonitoredTrip: (id: string, intl: IntlShape) => void
intl: IntlShape
routeTo: (url: any) => void
togglePauseTrip: (trip: MonitoredTrip, intl: IntlShape) => void
trip: MonitoredTrip
}

interface ItemState {
pendingRequest: 'pause' | 'delete' | false
}

interface Props {
trips?: MonitoredTrip[]
}

/**
* This class manages events and rendering for one item in the saved trip list.
*/
class TripListItem extends Component {
state = {
pendingRequest: false
class TripListItem extends Component<ItemProps, ItemState> {
constructor(props: ItemProps) {
super(props)
this.state = {
pendingRequest: false
}
}

componentDidUpdate = (prevProps) => {
componentDidUpdate = (prevProps: ItemProps) => {
if (prevProps.trip.isActive !== this.props.trip.isActive) {
this.setState({ pendingRequest: false })
}
Expand Down Expand Up @@ -160,7 +180,7 @@ const ConnectedTripListItem = connect(
/**
* This component displays the list of saved trips for the logged-in user.
*/
const SavedTripList = ({ trips }) => {
const SavedTripList = ({ trips }: Props) => {
const intl = useIntl()
let content

Expand Down Expand Up @@ -212,17 +232,15 @@ const SavedTripList = ({ trips }) => {

// connect to the redux store

const mapStateToProps = (state) => {
const mapStateToProps = (state: AppReduxState) => {
return {
trips: state.user.loggedInUserMonitoredTrips
}
}

const mapDispatchToProps = {}

export default withLoggedInUserSupport(
withAuthenticationRequired(
connect(mapStateToProps, mapDispatchToProps)(SavedTripList),
connect(mapStateToProps)(SavedTripList),
RETURN_TO_CURRENT_ROUTE
),
true
Expand Down
Loading

0 comments on commit 8038f2c

Please sign in to comment.