diff --git a/assets/css/_basic_notification_modal.scss b/assets/css/_basic_notification_modal.scss new file mode 100644 index 000000000..fca731b4d --- /dev/null +++ b/assets/css/_basic_notification_modal.scss @@ -0,0 +1,13 @@ +.c-basic-notification-modal { + display: flex; + flex-direction: column; +} + +.c-basic-notification-modal__close-button { + width: 1rem; + margin-left: auto; +} + +.c-basic-notification-modal__body { + margin-top: 1rem; +} diff --git a/assets/css/_inactive_notification_modal.scss b/assets/css/_inactive_notification_modal.scss deleted file mode 100644 index e9ff0fd32..000000000 --- a/assets/css/_inactive_notification_modal.scss +++ /dev/null @@ -1,24 +0,0 @@ -.c-inactive-notification-modal__close-button { - height: 1rem; - position: relative; - - button { - position: absolute; - right: 0; - - svg { - height: 1rem; - } - } -} - -.c-inactive-notification-modal__body { - margin-top: 1rem; -} - -.c-inactive-notification-modal__buttons { - display: flex; - height: 2rem; - justify-content: center; - margin-top: 1.5rem; -} diff --git a/assets/css/app.scss b/assets/css/app.scss index 80eb07136..fa9be7f3d 100644 --- a/assets/css/app.scss +++ b/assets/css/app.scss @@ -31,6 +31,7 @@ $vpp-location-padding: 1rem; @import "leaflet"; @import "skate_ui"; +@import "basic_notification_modal"; @import "circle_x_icon"; @import "card"; @import "circle_button"; @@ -48,7 +49,6 @@ $vpp-location-padding: 1rem; @import "filter_accordion"; @import "garage_filter"; @import "icon_alert_circle"; -@import "inactive_notification_modal"; @import "incoming_box"; @import "input_modal"; @import "ladder_page"; diff --git a/assets/src/components/notificationModals/basicNotificationModal.tsx b/assets/src/components/notificationModals/basicNotificationModal.tsx new file mode 100644 index 000000000..d5aef7488 --- /dev/null +++ b/assets/src/components/notificationModals/basicNotificationModal.tsx @@ -0,0 +1,44 @@ +import React, { useContext } from "react" +import { Modal } from "@restart/ui" +import { setNotification } from "../../state" +import { StateDispatchContext } from "../../contexts/stateDispatchContext" +import { OldCloseIcon } from "../../helpers/icon" + +const BasicNotificationModal = ({ + title, + body, +}: { + title: string + body: string +}) => { + const [, dispatch] = useContext(StateDispatchContext) + + const closeModal = () => { + dispatch(setNotification()) + } + + return ( + ( +
+ )} + > +
+ {/* TODO: Close button IS tab-able, but not visually given focus */} + +
{title}
+
{body}
+
+ + ) +} + +export default BasicNotificationModal diff --git a/assets/src/components/notificationModals/chelseaLoweredNotificationModal.tsx b/assets/src/components/notificationModals/chelseaLoweredNotificationModal.tsx index ed2414e78..83042ea31 100644 --- a/assets/src/components/notificationModals/chelseaLoweredNotificationModal.tsx +++ b/assets/src/components/notificationModals/chelseaLoweredNotificationModal.tsx @@ -1,30 +1,12 @@ -import React, { useContext } from "react" -import { StateDispatchContext } from "../../contexts/stateDispatchContext" -import { OldCloseIcon } from "../../helpers/icon" -import { setNotification } from "../../state" +import React from "react" +import BasicNotificationModal from "./basicNotificationModal" const ChelseaLoweredNotificationModal = () => { - const [, dispatch] = useContext(StateDispatchContext) - - const closeModal = () => { - dispatch(setNotification()) - } - return ( - <> -
-
- -
-
Chelsea St Bridge Lowered
-
- OCC reported that the Chelsea St Bridge has been lowered. -
-
-
- + ) } diff --git a/assets/src/components/notificationModals/chelseaRaisedNotificationModal.tsx b/assets/src/components/notificationModals/chelseaRaisedNotificationModal.tsx index 3f4b68060..e264eec90 100644 --- a/assets/src/components/notificationModals/chelseaRaisedNotificationModal.tsx +++ b/assets/src/components/notificationModals/chelseaRaisedNotificationModal.tsx @@ -1,21 +1,13 @@ -import React, { useContext } from "react" -import { StateDispatchContext } from "../../contexts/stateDispatchContext" -import { OldCloseIcon } from "../../helpers/icon" -import { setNotification } from "../../state" +import React from "react" import { Notification } from "../../realtime.d" import { formattedTime } from "../../util/dateTime" +import BasicNotificationModal from "./basicNotificationModal" const ChelseaRaisedNotificationModal = ({ notification, }: { notification: Notification }) => { - const [, dispatch] = useContext(StateDispatchContext) - - const closeModal = () => { - dispatch(setNotification()) - } - const contentString = (endDate: Date | null): string => { if (endDate) return ( @@ -27,20 +19,10 @@ const ChelseaRaisedNotificationModal = ({ } return ( - <> -
-
- -
-
Chelsea St Bridge Raised
-
- {contentString(notification.endTime)} -
-
-
- + ) } diff --git a/assets/src/components/notificationModals/inactiveNotificationModal.tsx b/assets/src/components/notificationModals/inactiveNotificationModal.tsx index 18202857d..986a3e04d 100644 --- a/assets/src/components/notificationModals/inactiveNotificationModal.tsx +++ b/assets/src/components/notificationModals/inactiveNotificationModal.tsx @@ -1,13 +1,11 @@ -import React, { useContext } from "react" +import React from "react" import Loading from "../loading" -import { StateDispatchContext } from "../../contexts/stateDispatchContext" import { useMinischeduleRuns } from "../../hooks/useMinischedule" -import { OldCloseIcon } from "../../helpers/icon" import { Activity, Run, Piece, Trip } from "../../minischedule" import { Notification, RunId } from "../../realtime.d" -import { setNotification } from "../../state" import { now, serviceDaySeconds } from "../../util/dateTime" import { title } from "../notificationCard" +import BasicNotificationModal from "./basicNotificationModal" type RunScheduleRelationship = "current" | "break" | "past" @@ -16,16 +14,10 @@ const InactiveNotificationModal = ({ }: { notification: Notification }) => { - const [, dispatch] = useContext(StateDispatchContext) - const runs: (Run | null)[] | undefined = useMinischeduleRuns( notification.tripIds ) - const closeModal = () => { - dispatch(setNotification()) - } - if (runs !== undefined) { const uniqueRuns = Object.values( (runs.filter((run) => run !== null) as Run[]).reduce( @@ -38,22 +30,10 @@ const InactiveNotificationModal = ({ ) return ( - <> -
-
- -
-
- {title(notification.reason)} NOTIFICATION -
-
- {bodyCopy(notification, uniqueRuns)} -
-
-
- + ) } diff --git a/assets/tests/components/__snapshots__/modal.test.tsx.snap b/assets/tests/components/__snapshots__/modal.test.tsx.snap index 377e94a87..2ee0fd6a1 100644 --- a/assets/tests/components/__snapshots__/modal.test.tsx.snap +++ b/assets/tests/components/__snapshots__/modal.test.tsx.snap @@ -1,149 +1,152 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Modal renders Chelsea Lowered modal 1`] = ` -[ + +
+ , -
, -] +
+ `; exports[`Modal renders Chelsea Raised modal 1`] = ` -[ + +
+ , -
, -] +
+ `; exports[`Modal renders inactive notification modal when appropriate 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`Modal renders loading modal when appropriate 1`] = ` -[ -
+ +
- ", - } - } - /> +
+ + + +
+
+ Loading... +
- Loading... -
-
, -
, -] + aria-hidden="true" + class="c-modal-backdrop" + /> +
+ `; diff --git a/assets/tests/components/modal.test.tsx b/assets/tests/components/modal.test.tsx index 850fa50c9..840346faf 100644 --- a/assets/tests/components/modal.test.tsx +++ b/assets/tests/components/modal.test.tsx @@ -1,6 +1,5 @@ import { jest, describe, test, expect } from "@jest/globals" import React from "react" -import renderer from "react-test-renderer" import { render } from "@testing-library/react" import Modal from "../../src/components/modal" import { StateDispatchProvider } from "../../src/contexts/stateDispatchContext" @@ -45,12 +44,12 @@ describe("Modal", () => { }) .build(), }) - const tree = renderer.create( + const { baseElement } = render( ) - expect(tree).toMatchSnapshot() + expect(baseElement).toMatchSnapshot() }) test("renders loading modal when appropriate", () => { @@ -77,12 +76,12 @@ describe("Modal", () => { }) .build(), }) - const tree = renderer.create( + const { baseElement } = render( ) - expect(tree).toMatchSnapshot() + expect(baseElement).toMatchSnapshot() }) test("renders create preset modal", () => { @@ -190,12 +189,12 @@ describe("Modal", () => { }) .build(), }) - const tree = renderer.create( + const { baseElement } = render( ) - expect(tree).toMatchSnapshot() + expect(baseElement).toMatchSnapshot() }) test("renders Chelsea Lowered modal", () => { @@ -222,11 +221,11 @@ describe("Modal", () => { }) .build(), }) - const tree = renderer.create( + const { baseElement } = render( ) - expect(tree).toMatchSnapshot() + expect(baseElement).toMatchSnapshot() }) }) diff --git a/assets/tests/components/notificationModals/__snapshots__/inactiveStateModal.test.tsx.snap b/assets/tests/components/notificationModals/__snapshots__/inactiveStateModal.test.tsx.snap index a3b6d3c13..97bd116dd 100644 --- a/assets/tests/components/notificationModals/__snapshots__/inactiveStateModal.test.tsx.snap +++ b/assets/tests/components/notificationModals/__snapshots__/inactiveStateModal.test.tsx.snap @@ -1,323 +1,329 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`InactiveNotificationModal renders for a notification with a run currently on break 1`] = ` -[ + +
+ , -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with a run that finished in the past 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with a run that has only nonrevenue work left 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with multiple current runs 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with multiple upcoming runs 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with no runs 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with one current run 1`] = ` -[ + +
+
, -
, -] +
+ `; exports[`InactiveNotificationModal renders for a notification with one upcoming run 1`] = ` -[ + +
+
, -
, -] +
+ `; -exports[`InactiveNotificationModal renders loading message 1`] = `"loading..."`; +exports[`InactiveNotificationModal renders loading message 1`] = ` + +
+ loading... +
+ +`; diff --git a/assets/tests/components/notificationModals/inactiveStateModal.test.tsx b/assets/tests/components/notificationModals/inactiveStateModal.test.tsx index dadb52931..0b1256d69 100644 --- a/assets/tests/components/notificationModals/inactiveStateModal.test.tsx +++ b/assets/tests/components/notificationModals/inactiveStateModal.test.tsx @@ -1,6 +1,6 @@ import { jest, describe, test, expect } from "@jest/globals" import React from "react" -import renderer from "react-test-renderer" +import { render } from "@testing-library/react" import InactiveNotificationModal from "../../../src/components/notificationModals/inactiveNotificationModal" import { Break, Piece, Run, Trip } from "../../../src/minischedule" import { useMinischeduleRuns } from "../../../src/hooks/useMinischedule" @@ -69,18 +69,18 @@ describe("InactiveNotificationModal", () => { test("renders loading message", () => { jest.mocked(useMinischeduleRuns).mockImplementationOnce(() => undefined) - const tree = renderer - .create() - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with no runs", () => { jest.mocked(useMinischeduleRuns).mockImplementationOnce(() => []) - const tree = renderer - .create() - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with one current run", () => { @@ -90,14 +90,12 @@ describe("InactiveNotificationModal", () => { activities: [piece], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with multiple current runs", () => { @@ -111,14 +109,12 @@ describe("InactiveNotificationModal", () => { activities: [{ ...piece, startTime: 1200, endTime: 1400 }], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with one upcoming run", () => { @@ -128,14 +124,12 @@ describe("InactiveNotificationModal", () => { activities: [{ ...piece, startTime: 1100, endTime: 1300 }], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with multiple upcoming runs", () => { @@ -149,14 +143,12 @@ describe("InactiveNotificationModal", () => { activities: [{ ...piece, startTime: 1400, endTime: 1600 }], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with a run currently on break", () => { @@ -166,14 +158,12 @@ describe("InactiveNotificationModal", () => { activities: [breakk], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with a run that finished in the past", () => { @@ -201,14 +191,12 @@ describe("InactiveNotificationModal", () => { ], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) test("renders for a notification with a run that has only nonrevenue work left", () => { @@ -228,13 +216,11 @@ describe("InactiveNotificationModal", () => { ], } as Run, ]) - const tree = renderer - .create( - - ) - .toJSON() - expect(tree).toMatchSnapshot() + const { baseElement } = render( + + ) + expect(baseElement).toMatchSnapshot() }) })