diff --git a/apps/site/assets/css/_schedule-page.scss b/apps/site/assets/css/_schedule-page.scss index 061a00b516..e35ef51ec5 100644 --- a/apps/site/assets/css/_schedule-page.scss +++ b/apps/site/assets/css/_schedule-page.scss @@ -370,3 +370,51 @@ justify-content: space-evenly; padding: $base-spacing / 2; } + +.schedule-finder__spinner, +.schedule-finder__spinner::before, +.schedule-finder__spinner::after { + animation: load7 1.8s infinite ease-in-out; + animation-fill-mode: both; + border-radius: 50%; + height: 2.5em; + width: 2.5em; +} + +.schedule-finder__spinner { + animation-delay: -.16s; + color: $brand-primary; + font-size: 10px; + margin: 80px auto; + position: relative; + text-indent: -9999em; + transform: translateZ(0); +} + +.schedule-finder__spinner::before, +.schedule-finder__spinner::after { + content: ''; + position: absolute; + top: 0; +} + +.schedule-finder__spinner::before { + animation-delay: -.32s; + left: -3.5em; +} + +.schedule-finder__spinner::after { + left: 3.5em; +} + +@keyframes load7 { + 0%, + 80%, + 100% { + box-shadow: 0 2.5em 0 -1.3em; + } + + 40% { + box-shadow: 0 2.5em 0 0; + } +} diff --git a/apps/site/assets/ts/schedule/__tests__/ScheduleModalTest.tsx b/apps/site/assets/ts/schedule/__tests__/ScheduleModalTest.tsx index c85c25b160..c045ba39c6 100644 --- a/apps/site/assets/ts/schedule/__tests__/ScheduleModalTest.tsx +++ b/apps/site/assets/ts/schedule/__tests__/ScheduleModalTest.tsx @@ -87,7 +87,6 @@ describe("ScheduleModal", () => { selectedOrigin={stops[0].id} selectedDirection={0} services={[]} - serviceSchedules={{}} /> ); }); @@ -105,7 +104,6 @@ describe("ScheduleModal", () => { selectedOrigin={null} selectedDirection={0} services={[]} - serviceSchedules={{}} /> ); expect(tree!.toJSON()).toBeNull(); @@ -122,7 +120,6 @@ describe("ScheduleModal", () => { selectedOrigin={stops[0].id} selectedDirection={null} services={[]} - serviceSchedules={{}} /> ); expect(tree!.toJSON()).toBeNull(); diff --git a/apps/site/assets/ts/schedule/__tests__/ServiceSelectorTest.tsx b/apps/site/assets/ts/schedule/__tests__/ServiceSelectorTest.tsx index 67d314ed8e..3b13d0386c 100644 --- a/apps/site/assets/ts/schedule/__tests__/ServiceSelectorTest.tsx +++ b/apps/site/assets/ts/schedule/__tests__/ServiceSelectorTest.tsx @@ -2,7 +2,10 @@ import React from "react"; import renderer from "react-test-renderer"; import { createReactRoot } from "../../app/helpers/testUtils"; import serviceData from "./serviceData.json"; -import ServiceSelector from "../components/schedule-finder/ServiceSelector"; +import { + fetchSchedule, + ServiceSelector +} from "../components/schedule-finder/ServiceSelector"; import { ServiceSchedule } from "../components/__schedule.js"; import { ServiceWithServiceDate } from "../../__v3api"; @@ -72,12 +75,100 @@ describe("ServiceSelector", () => { it("it renders", () => { createReactRoot(); const tree = renderer.create( - + ); expect(tree).toMatchSnapshot(); }); + + describe("fetchSchedule", () => { + it("fetches the selected schedule", async () => { + window.fetch = jest.fn().mockImplementation( + () => + new Promise((resolve: Function) => + resolve({ + json: () => { + return { + by_trip: "by_trip_data", + trip_order: "trip_order_data" + }; + }, + ok: true, + status: 200, + statusText: "OK" + }) + ) + ); + + var loadingSpy = jest.fn(); + var serviceScheduleSpy = jest.fn(); + + await await fetchSchedule( + services, + "BUS319-P-Sa-02", + "83", + 1, + loadingSpy, + serviceScheduleSpy + ); + + expect(window.fetch).toHaveBeenCalledWith( + "/schedules/schedule_api?id=83&date=2019-08-31&direction_id=1" + ); + + expect(loadingSpy).toHaveBeenCalledTimes(2); + expect(loadingSpy).toHaveBeenCalledWith(true); + expect(loadingSpy).toHaveBeenLastCalledWith(false); + + expect(serviceScheduleSpy).toHaveBeenCalledTimes(1); + expect(serviceScheduleSpy).toHaveBeenCalledWith({ + by_trip: "by_trip_data", + trip_order: "trip_order_data" + }); + }), + it("fails quietly if called with an invalid service ID", () => { + window.fetch = jest.fn(); + var loadingSpy = jest.fn(); + var serviceScheduleSpy = jest.fn(); + + fetchSchedule( + services, + "BAD-SERVICE-ID", + "83", + 1, + loadingSpy, + serviceScheduleSpy + ); + expect(window.fetch).not.toHaveBeenCalled(); + }), + it("throws an error if the fetch fails", async () => { + window.fetch = jest.fn().mockImplementation( + () => + new Promise((resolve: Function) => + resolve({ + ok: false, + status: 500, + statusText: "you broke it" + }) + ) + ); + + var loadingSpy = jest.fn(); + var serviceScheduleSpy = jest.fn(); + + await fetchSchedule( + services, + "BUS319-P-Sa-02", + "83", + 1, + loadingSpy, + serviceScheduleSpy + ); + + expect(loadingSpy).toHaveBeenCalledTimes(2); + expect(loadingSpy).toHaveBeenCalledWith(true); + expect(loadingSpy).toHaveBeenLastCalledWith(false); + + expect(serviceScheduleSpy).not.toHaveBeenCalled(); + }); + }); }); diff --git a/apps/site/assets/ts/schedule/__tests__/__snapshots__/ServiceSelectorTest.tsx.snap b/apps/site/assets/ts/schedule/__tests__/__snapshots__/ServiceSelectorTest.tsx.snap index 6a2c826002..590fa2acce 100644 --- a/apps/site/assets/ts/schedule/__tests__/__snapshots__/ServiceSelectorTest.tsx.snap +++ b/apps/site/assets/ts/schedule/__tests__/__snapshots__/ServiceSelectorTest.tsx.snap @@ -73,5741 +73,9 @@ Array [ ,
-
- First Trip -
- 05:36 AM -
- Last Trip -
- 01:02 AM + Loading...
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Departs - - Destination -
- 05:36 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:46 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:55 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:03 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:10 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:17 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:24 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:31 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:37 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:43 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:49 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:54 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:59 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:03 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:05 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:09 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:10 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:13 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:14 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:19 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:21 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:24 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:26 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:27 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:32 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:33 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:37 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:39 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:42 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:44 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:46 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:50 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:51 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:55 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:57 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:59 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:01 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:03 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:07 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:08 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:12 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:15 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:17 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:21 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:22 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:25 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:26 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:31 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:33 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:35 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:38 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:39 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:43 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:45 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:48 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:51 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:53 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:56 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:57 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:03 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:05 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:09 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:13 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:14 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:20 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:23 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:27 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:31 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:33 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:39 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:40 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:50 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:05 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:17 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 10:20 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:35 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:44 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 10:50 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:56 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 11:05 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:20 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:35 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:50 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:53 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 12:05 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:08 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 12:14 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:24 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:34 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:36 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 12:44 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:54 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:02 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 01:04 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:14 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:23 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 01:24 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:32 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 01:34 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:44 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:54 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 02:04 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 02:14 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 02:24 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 02:33 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 02:38 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 02:43 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 02:53 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 03:02 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 03:12 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 03:23 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 03:32 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 03:42 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 03:45 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 03:52 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 03:53 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:01 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:03 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:09 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:13 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:19 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:22 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:24 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:27 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:31 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:33 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:38 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:39 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:43 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:45 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:48 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:51 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:53 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 04:54 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 04:58 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:00 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:03 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:06 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:08 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:12 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:13 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:18 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:20 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:23 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:27 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:28 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:32 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:33 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:38 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:41 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:43 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:47 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:48 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:53 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 05:55 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 05:58 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:01 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 06:02 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:07 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:09 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 06:12 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:16 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 06:17 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:22 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:23 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 06:27 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:32 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:37 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:42 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:47 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:52 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 06:57 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:02 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:06 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:12 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:17 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:23 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:25 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:29 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:38 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:46 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 07:49 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:53 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 07:59 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:09 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:18 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:25 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:38 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 08:48 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 08:51 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:04 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:17 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:30 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:43 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 09:48 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 09:56 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:09 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:12 PM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 10:22 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:35 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 10:48 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:01 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:14 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:29 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:44 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 11:59 PM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:14 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:24 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
- 12:30 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 12:50 AM - -
-
-
- SL2 -
-
-
- Drydock -
- 01:02 AM - -
-
-
- Silver Line Way - South Station -
-
-
- Silver Line Way -
, ] `; diff --git a/apps/site/assets/ts/schedule/components/ScheduleFinder.tsx b/apps/site/assets/ts/schedule/components/ScheduleFinder.tsx index f425a70590..1923751ae8 100644 --- a/apps/site/assets/ts/schedule/components/ScheduleFinder.tsx +++ b/apps/site/assets/ts/schedule/components/ScheduleFinder.tsx @@ -58,8 +58,7 @@ const ScheduleFinder = ({ hideHeader, route, services, - stops, - serviceSchedules + stops }: Props): ReactElement => { const { direction_destinations: directionDestinations, @@ -263,7 +262,6 @@ const ScheduleFinder = ({ selectedOrigin={state.selectedOrigin} services={services} stops={stops} - serviceSchedules={serviceSchedules} /> )} diff --git a/apps/site/assets/ts/schedule/components/schedule-finder/ScheduleModalContent.tsx b/apps/site/assets/ts/schedule/components/schedule-finder/ScheduleModalContent.tsx index a677e65552..744c0b00e9 100644 --- a/apps/site/assets/ts/schedule/components/schedule-finder/ScheduleModalContent.tsx +++ b/apps/site/assets/ts/schedule/components/schedule-finder/ScheduleModalContent.tsx @@ -2,7 +2,7 @@ import React, { ReactElement, useReducer, useEffect } from "react"; import { SelectedDirection, SelectedOrigin } from "../ScheduleFinder"; import UpcomingDepartures from "./UpcomingDepartures"; import { Route, RouteType, ServiceWithServiceDate } from "../../../__v3api"; -import { SimpleStop, StopPrediction, ServiceSchedule } from "../__schedule"; +import { SimpleStop, StopPrediction } from "../__schedule"; import isSilverLine from "../../../helpers/silver-line"; import ServiceSelector from "./ServiceSelector"; @@ -89,7 +89,6 @@ interface Props { selectedOrigin: SelectedOrigin; services: ServiceWithServiceDate[]; stops: SimpleStop[]; - serviceSchedules: ServiceSchedule; } const ScheduleModalContent = ({ @@ -103,8 +102,7 @@ const ScheduleModalContent = ({ selectedDirection, selectedOrigin, services, - stops, - serviceSchedules + stops }: Props): ReactElement | null => { const [state, dispatch] = useReducer(reducer, { data: null, @@ -139,7 +137,7 @@ const ScheduleModalContent = ({ diff --git a/apps/site/assets/ts/schedule/components/schedule-finder/ServiceSelector.tsx b/apps/site/assets/ts/schedule/components/schedule-finder/ServiceSelector.tsx index 3b735dfa88..b91222e44a 100644 --- a/apps/site/assets/ts/schedule/components/schedule-finder/ServiceSelector.tsx +++ b/apps/site/assets/ts/schedule/components/schedule-finder/ServiceSelector.tsx @@ -1,4 +1,11 @@ -import React, { ReactElement, useState, useRef } from "react"; +import React, { + Dispatch, + ReactElement, + SetStateAction, + useEffect, + useState, + useRef +} from "react"; import SelectContainer from "./SelectContainer"; import { ServiceWithServiceDate, @@ -15,7 +22,7 @@ import { serviceDays, hasMultipleWeekdaySchedules } from "../../../helpers/service"; -import { ServiceSchedule, ServiceScheduleInfo } from "../__schedule"; +import { ServiceScheduleInfo } from "../__schedule"; import { RoutePillSmall } from "./UpcomingDepartures"; import { modeIcon } from "../../../helpers/icon"; @@ -29,7 +36,7 @@ const optGroupTitles: { [key in ServiceOptGroup]: string } = { interface Props { services: ServiceWithServiceDate[]; - serviceSchedules: ServiceSchedule; + routeId: string; directionId: DirectionId; } @@ -100,23 +107,75 @@ const getTodaysScheduleId = ( return todayService ? todayService.service.id : ""; }; -const ServiceSelector = ({ +export const fetchSchedule = ( + services: ServiceWithServiceDate[], + selectedServiceId: string, + routeId: string, + directionId: DirectionId, + setIsLoading: Dispatch>, + setSelectedServiceSchedule: Dispatch> +): void => { + setIsLoading(true); + + const selectedService = services.find( + service => service.id === selectedServiceId + ); + + if (!selectedService) { + return; + } + + if (window.fetch) { + window + .fetch( + `/schedules/schedule_api?id=${routeId}&date=${ + selectedService.end_date + }&direction_id=${directionId}` + ) + .then(response => { + setIsLoading(false); + if (response.ok) return response.json(); + throw new Error(response.statusText); + }) + .then(json => setSelectedServiceSchedule(json)); + } +}; + +export const ServiceSelector = ({ services, - serviceSchedules, + routeId, directionId }: Props): ReactElement | null => { const ref = useRef(null); - const [state, setState] = useState({ selectedServiceId: "" }); - if (services.length <= 0 || Object.keys(serviceSchedules).length <= 0) - return null; + + const [selectedServiceId, setSelectedServiceId] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [selectedServiceSchedule, setSelectedServiceSchedule] = useState(null); + + useEffect( + () => + fetchSchedule( + services, + selectedServiceId, + routeId, + directionId, + setIsLoading, + setSelectedServiceSchedule + ), + [services, directionId, routeId, selectedServiceId] + ); + + if (services.length <= 0) return null; + const servicesByOptGroup: ServicesKeyedByGroup = services .map((service: ServiceWithServiceDate) => groupServiceByDate(service)) .reduce(groupByType, { current: [], holiday: [], other: [] }); const defaultServiceId = getTodaysScheduleId(servicesByOptGroup); - const selectedServiceId = state.selectedServiceId || defaultServiceId; - const selectedServiceSchedule = - serviceSchedules[selectedServiceId][directionId]; + + if (!selectedServiceId) { + setSelectedServiceId(defaultServiceId); + } return ( <> @@ -129,8 +188,9 @@ const ServiceSelector = ({ className="schedule-finder__select" defaultValue={defaultServiceId} onChange={(): void => { + /* istanbul ignore next */ if (ref && ref.current) { - setState({ selectedServiceId: ref.current.value }); + setSelectedServiceId(ref.current.value); } }} > @@ -155,7 +215,12 @@ const ServiceSelector = ({ - + + {isLoading &&
Loading...
} + + {!isLoading && selectedServiceSchedule && ( + + )} ); }; diff --git a/apps/site/lib/site_web/controllers/schedule/line_controller.ex b/apps/site/lib/site_web/controllers/schedule/line_controller.ex index 1599ed26c3..2a8883bb1a 100644 --- a/apps/site/lib/site_web/controllers/schedule/line_controller.ex +++ b/apps/site/lib/site_web/controllers/schedule/line_controller.ex @@ -40,34 +40,6 @@ defmodule SiteWeb.ScheduleController.LineController do end end - @spec get_schedules(binary, any, any) :: %{by_trip: map, trip_order: [any]} - def get_schedules(route_id, date, direction_id) do - services = - Enum.map( - Schedules.Repo.by_route_ids([route_id], date: date, direction_id: direction_id), - &Map.update!(&1, :route, fn route -> Route.to_json_safe(route) end) - ) - - services_by_trip = - services - |> Enum.map(&Map.update!(&1, :time, fn time -> Timex.format!(time, "{0h12}:{m} {AM}") end)) - |> Enum.group_by(& &1.trip.id) - - ordered_trips = services |> Enum.sort_by(& &1.time) |> Enum.map(& &1.trip.id) |> Enum.uniq() - %{by_trip: services_by_trip, trip_order: ordered_trips} - end - - def schedules_for_service(route_id, services) do - services - |> Enum.reduce(%{}, fn %{start_date: date, id: service_id}, acc -> - Map.put(acc, service_id, %{ - service_id: service_id, - "0": get_schedules(route_id, date, 0), - "1": get_schedules(route_id, date, 1) - }) - end) - end - def assign_schedule_page_data(conn) do service_date = Util.service_date() services = Services.Repo.by_route_id(conn.assigns.route.id) @@ -101,7 +73,6 @@ defmodule SiteWeb.ScheduleController.LineController do services |> Enum.sort_by(&sort_services_by_date/1) |> Enum.map(&Map.put(&1, :service_date, service_date)), - service_schedules: schedules_for_service(conn.assigns.route.id, services), schedule_note: ScheduleNote.new(conn.assigns.route), stops: simple_stop_list(conn.assigns.all_stops), direction_id: conn.assigns.direction_id, diff --git a/apps/site/lib/site_web/controllers/schedule/schedule_api.ex b/apps/site/lib/site_web/controllers/schedule/schedule_api.ex new file mode 100644 index 0000000000..4e43c0cf4d --- /dev/null +++ b/apps/site/lib/site_web/controllers/schedule/schedule_api.ex @@ -0,0 +1,27 @@ +defmodule SiteWeb.ScheduleController.ScheduleApi do + use SiteWeb, :controller + + def show(conn, %{"id" => route_id, "date" => date, "direction_id" => direction_id}) do + {:ok, date} = Date.from_iso8601(date) + schedule_data = get_schedules(route_id, date, direction_id) + + json(conn, schedule_data) + end + + @spec get_schedules(binary, any, any) :: %{by_trip: map, trip_order: [any]} + def get_schedules(route_id, date, direction_id) do + schedules = + Enum.map( + Schedules.Repo.by_route_ids([route_id], date: date, direction_id: direction_id), + &Map.update!(&1, :route, fn route -> Routes.Route.to_json_safe(route) end) + ) + + schedules_by_trip = + schedules + |> Enum.map(&Map.update!(&1, :time, fn time -> Timex.format!(time, "{0h12}:{m} {AM}") end)) + |> Enum.group_by(& &1.trip.id) + + ordered_trips = schedules |> Enum.sort_by(& &1.time) |> Enum.map(& &1.trip.id) |> Enum.uniq() + %{by_trip: schedules_by_trip, trip_order: ordered_trips} + end +end diff --git a/apps/site/lib/site_web/router.ex b/apps/site/lib/site_web/router.ex index 26c51e77be..553f0e8c8b 100644 --- a/apps/site/lib/site_web/router.ex +++ b/apps/site/lib/site_web/router.ex @@ -109,6 +109,7 @@ defmodule SiteWeb.Router do get("/schedules", ModeController, :index) get("/schedules/predictions_api", ModeController, :predictions_api) + get("/schedules/schedule_api", ScheduleController.ScheduleApi, :show) get("/schedules/subway", ModeController, :subway) get("/schedules/bus", ModeController, :bus) get("/schedules/ferry", ModeController, :ferry)