-
Notifications
You must be signed in to change notification settings - Fork 58
Only allow saving itineraries with transit and no rentals #266
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
Conversation
evansiroky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment.
lib/util/itinerary.js
Outdated
| // TODO: move to OTP-UI + add tests? | ||
| /** | ||
| * @returns true if at least one of the legs of the specified itinerary is a transit leg. | ||
| */ | ||
| export function itineraryHasTransit (itinerary) { | ||
| if (itinerary && itinerary.legs) { | ||
| for (const leg of itinerary.legs) { | ||
| if (coreUtils.itinerary.isTransit(leg.mode)) { | ||
| return true | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return false | ||
| } | ||
|
|
||
| // TODO: move to OTP-UI + add tests? | ||
| /** | ||
| * @returns true if at least one of the legs of the specified itinerary is a rental leg | ||
| * (e.g. CAR_RENT, BICYCLE_RENT, MICROMOBILITY_RENT). | ||
| */ | ||
| export function itineraryHasRental (itinerary) { | ||
| if (itinerary && itinerary.legs) { | ||
| for (const leg of itinerary.legs) { | ||
| if (leg.mode.indexOf('_RENT') > -1) { | ||
| return true | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return false | ||
| } | ||
|
|
||
| /** | ||
| * Determines whether an itinerary can be monitored. | ||
| * @returns true if at least one of the legs of the specified itinerary is | ||
| * a transit leg, and none of the legs is a rental leg (e.g. CAR_RENT, BICYCLE_RENT, etc.). | ||
| */ | ||
| export function itineraryCanBeMonitored (itinerary) { | ||
| return itineraryHasTransit(itinerary) && !itineraryHasRental(itinerary) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 3 functions could probably be combined into one so that a single loop occurs which checks each leg as needed. Furthermore, the coreUtils.itinerary.hasRental could be used. Also, this must check if a ridehail leg exists (coreUtils.itinerary.hasHail can be used). Also, I noticed that lib/util/state.js has a duplicate function of itineraryHasTransit. This redundancy should be avoided. Regarding testing, I think making tests for the itineraryCanBeMonitored would be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| {/* FIXME: only save if meets requirements (e.g., is transit + non-realtime mode) */} | ||
| {persistence && persistence.enabled | ||
| {/* Only save if itinerary has transit and no rental modes that cannot be guaranteed. */} | ||
| {persistence && persistence.enabled && itineraryCanBeMonitored(itineraries[activeItinerary]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I think we should maybe take this opportunity to encapsulate this button into its own component. There are a few states that could be represented here, that we haven't quite addressed yet:
- User is not logged in - in this instance, I think we should have the SaveTripButton render something like: "Please sign in to save trip"
- Persistence disabled - just return null
- itin cannot be monitored - we should probably disable the button and for now show a tooltip saying: "To save a trip it must contain a transit leg and no rental vehicles legs." Not sure if that's a great message long-term though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I agree it is probably the simpler solution for now.
- Agree
- How about for the disabled button text:
🚫 Cannot save? And for the tooltip, taken from the backend: "Only trips that include transit and no rentals or ride hailing can be saved/monitored."
landonreed
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Save trip button probably warrants a component at this stage. Also, what Evan said.
__tests__/util/itinerary.js
Outdated
|
|
||
| testCases.forEach(({ expected, itinerary, title }) => { | ||
| it(title, () => { | ||
| expect(itineraryCanBeMonitored(itinerary))[expected ? 'toBeTruthy' : 'toBeFalsy']() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since itineraryCanBeMonitored always returns exactly true or false, the readability of this assertion could be improved to be expect(...).toBe(expected).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, it was otherwise copy/paste from another test... Updated in. 4ccc522.
| const mapDispatchToProps = (dispatch, ownProps) => {} | ||
|
|
||
| export default connect(mapStateToProps, mapDispatchToProps)(SaveTripButton) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mapDispatchToProps is not a required argument, so this can be replaced with connect(mapStateToProps)(SaveTripButton)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated in 4ccc522.
evansiroky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 2 comments.
| const { persistence } = state.otp.config | ||
| const itineraries = getActiveItineraries(state.otp) | ||
| return { | ||
| itinerary: activeSearch && itineraries && itineraries[activeSearch.activeItinerary], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opportunity to use getActiveItinerary(state.otp) which handles all of this other getActiveSearch/getActiveItineraries logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Updated in 80b8a91.
| {user && | ||
| <span className='pull-right'><LinkButton to='/savetrip'>Save this option</LinkButton></span> | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I know this goes against what I previously stated, but we should keep the new SaveTrip button component here <SaveTripButton />. This was decided in conversation with Ritesh earlier last week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reinstated in 80b8a91.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dec353a uses <SaveTripButton /> in LineItinerary.
landonreed
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Conditional approval on a few final items.
Address PR comments. Reinstate trip button in LineItinerary.
|
🎉 This PR is included in version 2.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This PR shows the 'Save trip' button in the
NarrativeItinerariesif the selected itinerary has a transit leg and no rental legs, hides the button otherwise. The PR also removes the 'Save this option' trip button fromLineItinerary.