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

tweak: Active and Past detours use edited directions #2884

Merged
merged 13 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions assets/css/_autosized_textarea.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.c-autosized-textarea {
display: grid;
// The main area that the textarea and the "'Sizer" occupy
grid-template-areas: "slot";

&::after, // "Sizer"
> textarea {
grid-area: slot;
}

&::after {
content: attr(data-replicated-value) " ";
white-space: pre-wrap;
visibility: hidden;
}
> textarea {
resize: none;
overflow: hidden;
}
&::after,
> textarea {
border: 1px solid $list-group-border-color;
padding: 0.5rem;
font: inherit;
margin-bottom: 1rem;
line-height: 1.5rem;
}
}
1 change: 1 addition & 0 deletions assets/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ $vpp-location-padding: 1rem;
@import "leaflet";
@import "skate_ui";

@import "autosized_textarea";
@import "basic_notification_modal";
@import "circle_x_icon";
@import "card";
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
54 changes: 41 additions & 13 deletions assets/src/components/detours/detourPanels/detourFinishedPanel.tsx
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,32 @@ export const DetourFinishedPanel = ({
<BsIcons.ArrowLeft /> Edit
</Button>

<Form.Control
as="textarea"
value={detourText}
onChange={({ target: { value } }) => onChangeDetourText(value)}
className="flex-grow-1 mb-3"
style={{
resize: "none",
}}
/>
<h2 className="c-diversion-panel__h2">Directions</h2>
{/*
We need a way to let the form area take up exactly the space of its content
(to avoid double scrollbars). We used this approach:
https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas

The result is that the Form.Control has an invisible twin that helps the
wrapper grow to the appropriate size, and then the Form.Control likewise
assumes that space. All formatting between the Form.Control and the ::after
pseudo-element must be identical: border, padding, margin, font.
*/}
<div
className="c-autosized-textarea"
data-replicated-value={editableDirections}
>
<Form.Control
as="textarea"
value={editableDirections}
onChange={({ target: { value } }) => onChangeDetourText(value)}
/>
</div>

{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
79 changes: 41 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 @@ -50,6 +49,10 @@ const displayFieldsFromRouteAndPattern = (
return { routeName, routeDirection, routeOrigin, routeDescription, shape }
}

const parseIntoDirectionsList = (directions: string) => {
return directions.split("\n").map((direction) => ({ instruction: direction }))
}

firestack marked this conversation as resolved.
Show resolved Hide resolved
interface DiversionPageFunctions {
onClose: () => void
}
Expand Down Expand Up @@ -113,16 +116,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 +139,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 +247,16 @@ export const DiversionPage = ({
return (
<DetourFinishedPanel
onNavigateBack={editDetour}
detourText={textArea}
onChangeDetourText={setTextArea}
copyableDetourText={copyableDetourText}
editableDirections={editedDirections || ""}
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,8 +340,12 @@ export const DiversionPage = ({
} else if (snapshot.matches({ "Detour Drawing": "Active" })) {
return (
<ActiveDetourPanel
detourText="Hello World"
directions={extendedDirections}
copyableDetourText={copyableDetourText}
directions={
editedDirections
? parseIntoDirectionsList(editedDirections)
: undefined
}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
connectionPoints?.end?.name ?? "N/A",
Expand Down Expand Up @@ -386,8 +385,12 @@ export const DiversionPage = ({
} else if (snapshot.matches({ "Detour Drawing": "Past" })) {
return (
<PastDetourPanel
detourText="Hello World"
directions={extendedDirections}
copyableDetourText={copyableDetourText}
directions={
editedDirections
? parseIntoDirectionsList(editedDirections)
: undefined
}
connectionPoints={[
connectionPoints?.start?.name ?? "N/A",
connectionPoints?.end?.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
Loading
Loading