Skip to content

Commit

Permalink
feat: Move detour text creation to state machine; allow edits
Browse files Browse the repository at this point in the history
  • Loading branch information
hannahpurcell committed Oct 18, 2024
1 parent b0d3ffa commit ed9026d
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 41 deletions.
48 changes: 10 additions & 38 deletions assets/src/components/detours/diversionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, {
ComponentPropsWithoutRef,
PropsWithChildren,
useContext,
useEffect,
useState,
} from "react"
import { DrawDetourPanel } from "./detourPanels/drawDetourPanel"
Expand Down Expand Up @@ -113,16 +112,17 @@ export const DiversionPage = ({
: { input: useDetourProps.originalRoute }
)

const [textArea, setTextArea] = useState("")

// I considered moving this to the statemachine, but
// this would disrupt existing Active Detours in prod
const nearestIntersectionDirection = [
{ instruction: "From " + nearestIntersection },
]
const extendedDirections = directions
? nearestIntersectionDirection.concat(directions)
: undefined

const { route, routePattern, routePatterns } = snapshot.context
const { route, routePattern, routePatterns, editedDetourText } =
snapshot.context
const routePatternsById = Object.fromEntries(
routePatterns?.map((rp) => [rp.id, rp]) ?? []
)
Expand All @@ -137,36 +137,6 @@ export const DiversionPage = ({
? displayFieldsFromRouteAndPattern(route, routePattern)
: {}

useEffect(() => {
if (snapshot.matches({ "Detour Drawing": "Share Detour" })) {
setTextArea(
[
`Detour ${routeName} ${routeDirection}`,
routeOrigin,
,
"Connection Points:",
connectionPoints?.start?.name ?? "N/A",
connectionPoints?.end?.name ?? "N/A",
,
`Missed Stops (${missedStops?.length}):`,
...(missedStops?.map(({ name }) => name) ?? ["no stops"]),
,
"Turn-by-Turn Directions:",
...(extendedDirections?.map((v) => v.instruction) ?? []),
].join("\n")
)
}
}, [
snapshot,
routeName,
routeDirection,
routeOrigin,
extendedDirections,
missedStops,
connectionPoints?.start?.name,
connectionPoints?.end?.name,
])

const routes = useContext(RoutesContext)
const epochNowInSeconds = useCurrentTimeSeconds()

Expand Down Expand Up @@ -254,8 +224,10 @@ export const DiversionPage = ({
return (
<DetourFinishedPanel
onNavigateBack={editDetour}
detourText={textArea}
onChangeDetourText={setTextArea}
detourText={editedDetourText || ""}
onChangeDetourText={(detourText: string) =>
send({ type: "detour.share.edit-directions", detourText })
}
onActivateDetour={
inTestGroup(TestGroups.DetoursList)
? () => {
Expand Down Expand Up @@ -339,7 +311,7 @@ export const DiversionPage = ({
} else if (snapshot.matches({ "Detour Drawing": "Active" })) {
return (
<ActiveDetourPanel
detourText="Hello World"
detourText={editedDetourText || ""}
directions={extendedDirections}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
Expand Down Expand Up @@ -380,7 +352,7 @@ export const DiversionPage = ({
} else if (snapshot.matches({ "Detour Drawing": "Past" })) {
return (
<PastDetourPanel
detourText="Hello World"
detourText={editedDetourText || ""}
directions={extendedDirections}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
Expand Down
44 changes: 43 additions & 1 deletion assets/src/models/createDetourMachine.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { setup, assign, fromPromise, ActorLogicFrom, InputFrom } from "xstate"
import { RoutePatternId, ShapePoint } from "../schedule"
import { Route, RouteId, RoutePattern } from "../schedule"
import { Ok, Result } from "../util/result"
import { isOk, Ok, Result } from "../util/result"
import {
FetchDetourDirectionsError,
fetchDetourDirections,
Expand Down Expand Up @@ -30,6 +30,8 @@ export const createDetourMachine = setup({

finishedDetour: FinishedDetour | undefined | null

editedDetourText?: string

selectedDuration?: string
selectedReason?: string
},
Expand Down Expand Up @@ -66,6 +68,7 @@ export const createDetourMachine = setup({
| { type: "detour.edit.place-waypoint-on-route"; location: ShapePoint }
| { type: "detour.edit.place-waypoint"; location: ShapePoint }
| { type: "detour.edit.undo" }
| { type: "detour.share.edit-directions"; detourText: string }
| { type: "detour.share.copy-detour"; detourText: string }
| { type: "detour.share.open-activate-modal" }
| {
Expand Down Expand Up @@ -472,6 +475,39 @@ export const createDetourMachine = setup({

onDone: {
target: "Share Detour",
actions: assign({
editedDetourText: ({ context }) => {
const routeName = context.route?.name
const routeDirection =
context.routePattern &&
context.route?.directionNames[
context.routePattern.directionId
]
const routeOrigin = context.routePattern?.name
const missedStops = context.finishedDetour?.missedStops

const detourShape =
context.detourShape && isOk(context.detourShape)
? context.detourShape.ok
: null

return [
`Detour ${routeName} ${routeDirection}`,
routeOrigin,
,
"Connection Points:",
context.finishedDetour?.connectionPoint?.start?.name ?? "N/A",
context.finishedDetour?.connectionPoint?.end?.name ?? "N/A",
,
`Missed Stops (${missedStops?.length}):`,
...(missedStops?.map(({ name }) => name) ?? ["no stops"]),
,
"Turn-by-Turn Directions:",
"From " + context.nearestIntersection,
...(detourShape?.directions?.map((v) => v.instruction) ?? []),
].join("\n")
},
}),
},
},
"Share Detour": {
Expand All @@ -490,6 +526,12 @@ export const createDetourMachine = setup({
"detour.share.open-activate-modal": {
target: "Activating",
},
"detour.share.edit-directions": {
target: "Reviewing",
actions: assign({
editedDetourText: ({ event }) => event.detourText,
}),
},
},
},
Activating: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,20 @@ exports[`Detours Page: Open a Detour renders detour details in an open drawer on
<textarea
class="flex-grow-1 mb-3 form-control"
style="resize: none;"
/>
>
Detour 2 Outbound
Route pattern From A2 - To B2
Connection Points:
N/A
N/A
Missed Stops (undefined):
no stops
Turn-by-Turn Directions:
From null
</textarea>
</div>
<div
class="border-top d-flex mt-auto d-flex flex-column"
Expand Down Expand Up @@ -1232,7 +1245,20 @@ exports[`Detours Page: Open a Detour renders detour details modal to match mocke
<textarea
class="flex-grow-1 mb-3 form-control"
style="resize: none;"
/>
>
Detour 1 Outbound
Route pattern From A1 - To B1
Connection Points:
N/A
N/A
Missed Stops (undefined):
no stops
Turn-by-Turn Directions:
From null
</textarea>
</div>
<div
class="border-top d-flex mt-auto d-flex flex-column"
Expand Down
22 changes: 22 additions & 0 deletions assets/tests/components/detours/diversionPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,28 @@ describe("DiversionPage", () => {
).toBeVisible()
})

test("'View Draft Detour' screen allows user to edit detour text", async () => {
const { container } = render(<DiversionPage />)

act(() => {
fireEvent.click(originalRouteShape.get(container))
})

act(() => {
fireEvent.click(originalRouteShape.get(container))
})

await userEvent.click(reviewDetourButton.get())

const input = screen.getByRole("textbox") as HTMLInputElement

act(() => {
fireEvent.change(input, { target: { value: "Hello World" } })
})

expect(input.value).toBe("Hello World")
})

test("Attempting to close the page calls the onClose callback", async () => {
const onClose = jest.fn()

Expand Down

0 comments on commit ed9026d

Please sign in to comment.