Skip to content

Commit

Permalink
Merge branch 'dev' into remove-is-transit
Browse files Browse the repository at this point in the history
  • Loading branch information
amy-corson-ibigroup authored Oct 2, 2024
2 parents 122a944 + 8c85cb8 commit 426bccb
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 189 deletions.
9 changes: 9 additions & 0 deletions example-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ persistence:
# iconUrl: ''
# href: ''

### These settings are only used for the field trip features.
dateTime:
timeFormat: h:mm a
dateFormat: MM/dd/yyyy

map:
initLat: 45.52
initLon: -122.682
Expand Down Expand Up @@ -411,6 +416,8 @@ itinerary:
displayA11yError: false
# Whether to display itinerary info in the side of the preview or next to the departure times
showInlineItinerarySummary: false
# Whether to sync the sort type with the depart/arrive time in the date/time modal
syncSortWithDepartArrive: true
# The sort option to use by default
# Available sort options: 'BEST', 'DURATION', 'ARRIVALTIME', 'WALKTIME', 'COST', 'DEPARTURETIME'
# defaultSort: "BEST" # Default
Expand All @@ -429,6 +436,8 @@ itinerary:
advancedSettingsPanel:
# Show button in advanced panel that allows users to save and return
saveAndReturnButton: true
# Prevent users from selecting a single day for saving trips.
disableSingleItineraryDays: false

# The transitOperators key is a list of transit operators that can be used to
# order transit agencies when sorting by route. Also, this can optionally
Expand Down
1 change: 1 addition & 0 deletions i18n/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ components:
SavedTripScreen:
itineraryLoaded: Itinerary loaded
itineraryLoading: Loading itinerary
selectAtLeastOneDay: Please select at least one day to monitor.
tooManyTrips: >
You already have reached the maximum of five saved trips. Please remove
unused trips from your saved trips, and try again.
Expand Down
1 change: 1 addition & 0 deletions i18n/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ components:
SavedTripScreen:
itineraryLoaded: Trajet chargé
itineraryLoading: Chargement du trajet
selectAtLeastOneDay: Veuillez choisir au moins un jour pour le suivi.
tooManyTrips: >
Vous avez déjà atteint le nombre maximum de 5 trajets enregistrés.
Veuillez supprimer les trajets enregistrés qui sont inutilisés, puis
Expand Down
76 changes: 0 additions & 76 deletions lib/components/form/date-time-modal.js

This file was deleted.

116 changes: 116 additions & 0 deletions lib/components/form/date-time-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { connect } from 'react-redux'
import coreUtils from '@opentripplanner/core-utils'
import React, { useCallback } from 'react'

import * as formActions from '../../actions/form'
import * as narrativeActions from '../../actions/narrative'
import { AppConfig } from '../../util/config-types'
import { AppReduxState, FilterType, SortType } from '../../util/state-types'

import { StyledDateTimeSelector } from './styled'

type Props = {
config: AppConfig
date: string
dateFormatLegacy?: string
departArrive: DepartArriveValue
setQueryParam: (params: any) => void
sort: SortType
time: string
timeFormatLegacy?: string
updateItineraryFilter: (payload: FilterType) => void
}

type DepartArriveValue = 'NOW' | 'DEPART' | 'ARRIVE'

const DepartArriveTypeMap: Record<
DepartArriveValue,
FilterType['sort']['type']
> = {
ARRIVE: 'ARRIVALTIME',
DEPART: 'DEPARTURETIME',
NOW: 'DURATION'
}

function DateTimeModal({
config,
date,
dateFormatLegacy,
departArrive,
setQueryParam,
sort,
time,
timeFormatLegacy,
updateItineraryFilter
}: Props) {
const { homeTimezone, isTouchScreenOnDesktop } = config
const touchClassName = isTouchScreenOnDesktop
? 'with-desktop-touchscreen'
: ''

const syncSortWithDepartArrive = config?.itinerary?.syncSortWithDepartArrive
// Note the side effect that this will resort the results of a previous query
// if the user changes the depart/arrive setting before the query is run.
const setQueryParamMiddleware = useCallback(
(params: any) => {
if (syncSortWithDepartArrive) {
updateItineraryFilter({
sort: {
...sort,
type: DepartArriveTypeMap[params.departArrive as DepartArriveValue]
}
})
}
setQueryParam(params)
},
[setQueryParam, updateItineraryFilter, sort, syncSortWithDepartArrive]
)
return (
<div className="date-time-modal">
<div className="main-panel">
<StyledDateTimeSelector
className={`date-time-selector ${touchClassName}`}
date={date}
dateFormatLegacy={dateFormatLegacy}
departArrive={departArrive}
onQueryParamChange={setQueryParamMiddleware}
time={time}
// These props below are for legacy browsers
// that don't support `<input type="time|date">`.
// These props are not relevant in modern browsers,
// where `<input type="time|date">` already
// formats the time|date according to the OS settings.
// eslint-disable-next-line react/jsx-sort-props
timeFormatLegacy={timeFormatLegacy}
timeZone={homeTimezone}
/>
</div>
</div>
)
}

const mapStateToProps = (state: AppReduxState) => {
const { date, departArrive, time } = state.otp.currentQuery
const config = state.otp.config
const { sort } = state.otp.filter
return {
config,
date,
// This prop is for legacy browsers (see render method above).
// @ts-expect-error Mismatched config types
dateFormatLegacy: coreUtils.time.getDateFormat(config),
departArrive,
sort,
time,
// This prop is for legacy browsers (see render method above).
// @ts-expect-error Mismatched config types
timeFormatLegacy: coreUtils.time.getTimeFormat(config)
}
}

const mapDispatchToProps = {
setQueryParam: formActions.setQueryParam,
updateItineraryFilter: narrativeActions.updateItineraryFilter
}

export default connect(mapStateToProps, mapDispatchToProps)(DateTimeModal)
10 changes: 1 addition & 9 deletions lib/components/narrative/narrative-itineraries-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export default function NarrativeItinerariesHeader({
enabledSortModes,
errors,
itineraries,
itinerary,
itineraryIsExpanded,
onSortChange,
onSortDirChange,
Expand Down Expand Up @@ -109,13 +108,6 @@ export default function NarrativeItinerariesHeader({
const sortOptionsArr = sortOptions(intl, enabledSortModes)
const sortText = sortOptionsArr.find((x) => x.value === sort.type)?.text

const handleSortClick = useCallback(
(value) => {
onSortChange(value)
},
[onSortChange]
)

return (
<div
className="options header"
Expand Down Expand Up @@ -222,7 +214,7 @@ export default function NarrativeItinerariesHeader({
<li className="sort-option" key={sortOption.value}>
<UnstyledButton
aria-selected={sortText === sortOption.text || undefined}
onClick={() => handleSortClick(sortOption.value)}
onClick={() => onSortChange(sortOption.value)}
role="option"
>
{sortOption.text}
Expand Down
39 changes: 36 additions & 3 deletions lib/components/user/monitored-trip/saved-trip-screen.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,14 @@ class SavedTripScreen extends Component {
}

render() {
const { isCreating, itinerary, loggedInUser, monitoredTrips, pending } =
this.props
const {
disableSingleItineraryDays,
isCreating,
itinerary,
loggedInUser,
monitoredTrips,
pending
} = this.props
const isAwaiting = !monitoredTrips || (isCreating && pending)

let screenContents
Expand All @@ -176,7 +182,32 @@ class SavedTripScreen extends Component {
// Text constant is used to allow format.js command line tool to keep track of
// which IDs are in the code.
.notOneOf(otherTripNames, 'trip-name-already-used')
const validationSchema = yup.object(clonedSchemaShape)
const validationSchema = yup
.object(clonedSchemaShape)
// If disableSingleItineraryDays is true, test to see if at least one day checkbox is checked
.test('dayofweek', 'Please select one day', function (obj) {
if (
obj.monday ||
obj.tuesday ||
obj.wednesday ||
obj.thursday ||
obj.friday ||
obj.saturday ||
obj.sunday ||
!disableSingleItineraryDays
) {
return true
}

/* Hack: because the selected days values are not grouped, we need to assign this error to one of the
checkboxes so that form validates correctly. Monday makes sure the focus is on the first checkbox. */

return new yup.ValidationError(
'Please select at least one day to monitor',
obj.monday,
'monday'
)
})

screenContents = (
<Formik
Expand Down Expand Up @@ -236,8 +267,10 @@ const mapStateToProps = (state, ownProps) => {
const pending = activeSearch ? Boolean(activeSearch.pending) : false
const itineraries = getActiveItineraries(state) || []
const tripId = ownProps.match.params.id
const { disableSingleItineraryDays } = state.otp.config
return {
activeSearchId: state.otp.activeSearchId,
disableSingleItineraryDays,
homeTimezone: state.otp.config.homeTimezone,
isCreating: tripId === 'new',
itinerary: itineraries[activeItinerary],
Expand Down
Loading

0 comments on commit 426bccb

Please sign in to comment.