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: Editable directions in state machine #2880

Merged
merged 10 commits into from
Oct 31, 2024
4 changes: 4 additions & 0 deletions assets/css/_diversion_page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@
flex: 1 1 0;
overflow-y: auto;
}

.form-control {
min-height: 200px;
}
hannahpurcell marked this conversation as resolved.
Show resolved Hide resolved
}

.c-diversion-panel__origin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import inTestGroup, { TestGroups } from "../../../userInTestGroup"

export interface ActiveDetourPanelProps extends PropsWithChildren {
detourText: string
copyableDetourText: string
directions?: DetourDirection[]
connectionPoints?: [string, string]
missedStops?: Stop[]
Expand All @@ -30,7 +30,7 @@ export interface ActiveDetourPanelProps extends PropsWithChildren {
}

export const ActiveDetourPanel = ({
detourText,
copyableDetourText,
directions,
connectionPoints,
missedStops,
Expand Down Expand Up @@ -63,7 +63,7 @@ export const ActiveDetourPanel = ({
{backButton}
{/* TODO: temporary test group until I get the copy logic hooked up */}
{inTestGroup(TestGroups.CopyButton) && (
<CopyButton detourText={detourText} />
<CopyButton detourText={copyableDetourText} />
)}
</Panel.Header>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,37 @@ import React, { PropsWithChildren } from "react"
import { Button, Form } from "react-bootstrap"
import * as BsIcons from "../../../helpers/bsIcons"
import { Panel } from "../diversionPage"
import { CopyButton } from "../detourPanelComponents"
import {
ConnectionPoints,
CopyButton,
MissedStops,
} from "../detourPanelComponents"
import { Stop } from "../../../schedule"

interface DetourFinishedPanelProps extends PropsWithChildren {
onNavigateBack: () => void
detourText: string
copyableDetourText: string
editableDirections: string
connectionPoints?: [string, string]
missedStops?: Stop[]
onChangeDetourText: (value: string) => void
onActivateDetour?: () => void
}

export const DetourFinishedPanel = ({
onNavigateBack,
detourText,
copyableDetourText,
editableDirections,
connectionPoints,
missedStops,
onChangeDetourText,
onActivateDetour,
children,
}: DetourFinishedPanelProps) => (
<Panel as="article" className="c-diversion-panel">
<Panel.Header>
<h1 className="c-diversion-panel__h1 my-3">View Draft Detour</h1>
<CopyButton detourText={detourText} />
<CopyButton detourText={copyableDetourText} />
</Panel.Header>

<Panel.Body className="d-flex flex-column">
Expand All @@ -35,15 +46,21 @@ export const DetourFinishedPanel = ({
<BsIcons.ArrowLeft /> Edit
</Button>

<h2 className="c-diversion-panel__h2">Directions</h2>
<Form.Control
as="textarea"
value={detourText}
value={editableDirections}
onChange={({ target: { value } }) => onChangeDetourText(value)}
className="flex-grow-1 mb-3"
style={{
resize: "none",
}}
/>

{connectionPoints && (
<ConnectionPoints connectionPoints={connectionPoints} />
)}
{missedStops && <MissedStops missedStops={missedStops} />}
</Panel.Body.ScrollArea>

<Panel.Body.Footer className="d-flex flex-column">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import inTestGroup, { TestGroups } from "../../../userInTestGroup"

export interface PastDetourPanelProps {
detourText: string
copyableDetourText: string
directions?: DetourDirection[]
connectionPoints: [string, string]
missedStops?: Stop[]
Expand All @@ -25,7 +25,7 @@ export interface PastDetourPanelProps {
}

export const PastDetourPanel = ({
detourText,
copyableDetourText,
directions,
connectionPoints,
missedStops,
Expand All @@ -40,7 +40,7 @@ export const PastDetourPanel = ({
<h1 className="c-diversion-panel__h1 my-3">View Past Detour</h1>
{/* TODO: temporary test group until I get the copy logic hooked up */}
{inTestGroup(TestGroups.CopyButton) && (
<CopyButton detourText={detourText} />
<CopyButton detourText={copyableDetourText} />
)}
</Panel.Header>

Expand Down
67 changes: 31 additions & 36 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,15 @@ export const DiversionPage = ({
: { input: useDetourProps.originalRoute }
)

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

const nearestIntersectionDirection = [
{ instruction: "From " + nearestIntersection },
]
const extendedDirections = directions
? nearestIntersectionDirection.concat(directions)
: undefined

const { route, routePattern, routePatterns } = snapshot.context
const { route, routePattern, routePatterns, editedDirections } =
snapshot.context
const routePatternsById = Object.fromEntries(
routePatterns?.map((rp) => [rp.id, rp]) ?? []
)
Expand All @@ -137,35 +135,20 @@ 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,
const copyableDetourText = [
`Detour ${routeName} ${routeDirection}`,
routeOrigin,
extendedDirections,
missedStops,
connectionPoints?.start?.name,
connectionPoints?.end?.name,
])
,
"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")

const routes = useContext(RoutesContext)
const epochNowInSeconds = useCurrentTimeSeconds()
Expand Down Expand Up @@ -260,8 +243,20 @@ export const DiversionPage = ({
return (
<DetourFinishedPanel
onNavigateBack={editDetour}
detourText={textArea}
onChangeDetourText={setTextArea}
copyableDetourText={copyableDetourText}
// Include fallback if editedDirections was not initialized on an older detour
editableDirections={
editedDirections ||
(extendedDirections?.map((v) => v.instruction).join("\n") ?? "")
}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
connectionPoints?.end?.name ?? "N/A",
]}
missedStops={missedStops}
onChangeDetourText={(detourText: string) =>
send({ type: "detour.share.edit-directions", detourText })
}
onActivateDetour={
inTestGroup(TestGroups.DetoursList)
? () => {
Expand Down Expand Up @@ -345,7 +340,7 @@ export const DiversionPage = ({
} else if (snapshot.matches({ "Detour Drawing": "Active" })) {
return (
<ActiveDetourPanel
detourText="Hello World"
copyableDetourText={copyableDetourText}
directions={extendedDirections}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
Expand Down Expand Up @@ -386,7 +381,7 @@ export const DiversionPage = ({
} else if (snapshot.matches({ "Detour Drawing": "Past" })) {
return (
<PastDetourPanel
detourText="Hello World"
copyableDetourText={copyableDetourText}
directions={extendedDirections}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
Expand Down
24 changes: 23 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

editedDirections?: 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,19 @@ export const createDetourMachine = setup({

onDone: {
target: "Share Detour",
actions: assign({
editedDirections: ({ context }) => {
const detourShape =
context.detourShape && isOk(context.detourShape)
? context.detourShape.ok
: null

return [
"From " + context.nearestIntersection,
...(detourShape?.directions?.map((v) => v.instruction) ?? []),
].join("\n")
},
}),
},
},
"Share Detour": {
Expand All @@ -490,6 +506,12 @@ export const createDetourMachine = setup({
"detour.share.open-activate-modal": {
target: "Activating",
},
"detour.share.edit-directions": {
target: "Reviewing",
actions: assign({
editedDirections: ({ event }) => event.detourText,
}),
},
},
},
Activating: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,12 @@ import React from "react"
import { ActiveDetourPanel } from "../../../src/components/detours/detourPanels/activeDetourPanel"
import { stopFactory } from "../../../tests/factories/stop"

const defaulText = [
"Detour:",
"66 Harvard via Allston from",
"Andrew Station",
"Outbound",
"",
"Turn-by-Turn Directions:",
const defaultText = [
"Start at Centre St & John St",
"Right on John St",
"Left on Abbotsford Rd",
"Right on Boston St",
"Regular Route",
"",
"Connection Points:",
"Centre St & John St",
"Boston St",
"",
"Missed Stops (3):",
"Example St @ Sample Ave",
"Example St opp Random Way",
"Example St @ Fake Blvd",
].join("\n")

const meta = {
Expand All @@ -34,7 +19,7 @@ const meta = {
stretch: true,
},
args: {
detourText: defaulText,
copyableDetourText: defaultText,
directions: [
{ instruction: "Start at Centre St & John St" },
{ instruction: "Right on John St" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@ const defaultText = [
"Harvard Ave @ Commonwealth Ave",
].join("\n")

const turnByTurn = [
"From Harvard St & Babcock St",
"Right on Babcock St.",
"Regular Route",
].join("\n")

const meta = {
component: DetourFinishedPanel,
parameters: {
layout: "fullscreen",
stretch: true,
},
args: {
detourText: defaultText,
copyableDetourText: defaultText,
editableDirections: turnByTurn,
},
// The bootstrap CSS reset is supposed to set box-sizing: border-box by
// default, we should be able to remove this after that is added
Expand Down
Loading
Loading