Skip to content
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

feat(StopPageDepartures): Omit uncommon Green Line branches/headsigns with no upcoming service #1786

Merged
merged 10 commits into from
Nov 14, 2023

Conversation

thecristen
Copy link
Collaborator

@thecristen thecristen commented Nov 2, 2023

Summary of changes

Asana Ticket: Omit uncommon Green Line branches/headsigns with no upcoming service

There are a couple extra commits because our code wasn't using the V3 API's canonical attribute for route patterns. Most of this PR's file changes are due to this.

The main part of this PR, in the final commit, checks the canonical value for subway route patterns against the list of departures to determine whether to hide a specific headsign. Additionally, if all the headsigns for a given route card end up hidden, the route card itself will also be hidden.

Before and After:

image

In the early morning when the other Green Line branches run trains this way, those schedules/predictions should show up on this page, though I haven't captured a screenshot for this yet.


General checks

  • Are the changes organized into self-contained commits with descriptive and well-formatted commit messages? This is a good practice that can facilitate easier reviews.
  • Testing. Do the changes include relevant passing updates to tests? This includes updating screenshots. Preferably tests are run locally to verify that there are no test failures created by these changes, before opening a PR.
  • Tech debt. Have you checked for tech debt you can address in the area you're working in? This can be a good time to address small issues, or create Asana tickets for larger issues.

@thecristen thecristen requested a review from a team as a code owner November 2, 2023 15:59
@thecristen thecristen requested review from i0sea and removed request for a team November 2, 2023 15:59
@thecristen thecristen added the dev-blue Deploy to dev-blue label Nov 2, 2023
@thecristen thecristen force-pushed the cbj/remove-uncommon-headsigns-without-service branch from 79516bb to 3eb9895 Compare November 9, 2023 14:22
@thecristen thecristen requested a review from skyqrose November 9, 2023 21:34
Copy link
Member

@skyqrose skyqrose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a bunch of comments, but they're all "I would have done this differently" minor refactoring suggestions. It all makes sense and looks good.

} from "../stop/stop-redesign-loader";
import { DepartureInfo } from "./departureInfo";

type RoutePatternGroup = GroupedRoutePatterns[keyof GroupedRoutePatterns];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this file should define

export interface RoutePatternWithPolyline
  extends Omit<RoutePattern, "representative_trip_polyline"> {
  representative_trip_polyline: Polyline;
}
export type RoutePatternId = string; // I'm assuming the groups are by id but maybe it's by headsign?
export type RoutePatternGroup = Record<
  RoutePatternId,
  {
    direction_id: DirectionId;
    route_patterns: RoutePatternWithPolyline[];
  },
>;
export type GroupedRoutePatterns = Record<string, RoutePatternGroup>;

and stop-redesign-loader should reference this file. The types were defined there before cuz that's where they were used, but having this general model file reference that specific use case seems backwards.

Also, there's two layers of grouping RoutePatternGroup and GroupedRoutePatterns, and it's unclear what the difference is. Type aliases for the string keys could help, or putting some hint in the type name could help.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the group keys to be references to the relevant objects (Route["id"] and RoutePattern["headsign"] in this case) and the end result should be way cleaner, thanks a million 🥳

Comment on lines +8 to +21
export type RoutePatternGroupEntries = [
keyof RoutePatternGroup,
RoutePatternGroup[keyof RoutePatternGroup]
][];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a pattern you expect to use again, you could consider defining in some util file somewhere (maybe helpers/object.ts)

export type ValueOf<T extends Object> = T[keyof T];
export type Entries<T extends Object> = [keyof T, ValueOf<T>];

].map(([, { route_patterns: routePatterns }]) =>
Math.min(...routePatterns.map(rp => rp.sort_order))
);
return orderA - orderB;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would lodash sortBy() work for this?

return isNonCanonical && departures.length === 0;
};

// eslint-disable-next-line import/prefer-default-export
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Sometimes the reason for disabling a lint rule is obvious, but this one isn't, and could use a comment.

@@ -19,24 +19,10 @@ const DepartureCard = ({
}: {
alertsForRoute: Alert[];
departuresForRoute: DepartureInfo[];
routePatternsByHeadsign: GroupedRoutePatterns[keyof GroupedRoutePatterns];
routePatternsByHeadsign: RoutePatternGroupEntries;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR moves the filtering+sorting out of this component and into the caller. That means that it needs to take the entries type now instead of the record type, which I think is a bit more awkward. I tend to prefer passing around the more data-like record type as long as possible, and only transform it to the display-like sorted list as late as possible to be closer to where it's displayed (though this is a very loose rule and there could be good reasons I don't see to do the processing earlier).


const isNoncanonicalAndNoDepartures = (
routePatterns: RoutePatternWithPolyline[],
departures: DepartureInfo[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't work purely on route patterns, it also uses departure info, so maybe it shouldn't belong in the general models/route-patterns file. This calculation is pretty specific to what you want to show on the stops page, so maybe it should go with the stops page components instead.

minBy(routePatterns, "sort_order")?.sort_order
);

export default { sortedGroupedRoutePatterns };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed when the definition above already has export const sortedGroupedRoutePatterns?

Base automatically changed from cbj/better-unserved-stops to master November 14, 2023 19:42
@thecristen thecristen force-pushed the cbj/remove-uncommon-headsigns-without-service branch from e539877 to 61fa99e Compare November 14, 2023 19:44
@thecristen thecristen removed the dev-blue Deploy to dev-blue label Nov 14, 2023
@thecristen thecristen merged commit dd76a63 into master Nov 14, 2023
17 of 18 checks passed
@thecristen thecristen deleted the cbj/remove-uncommon-headsigns-without-service branch November 14, 2023 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants