Skip to content

Commit

Permalink
feat: Change detour duration modal (#2928)
Browse files Browse the repository at this point in the history
* feat: Add change duration button, icon, and user group

* feat: set up UI flow, add editedSelectedDuration to state machine

* test: build out editedDuration test suite
  • Loading branch information
hannahpurcell authored Jan 24, 2025
1 parent 8afe772 commit bb0fc04
Show file tree
Hide file tree
Showing 9 changed files with 376 additions and 12 deletions.
14 changes: 10 additions & 4 deletions assets/src/components/detours/activateDetourModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { PropsWithChildren } from "react"
import { Button, Form, Modal } from "react-bootstrap"
import { StepperBar } from "../stepperBar"

const possibleDurations = [
export const possibleDurations = [
"1 hour",
"2 hours",
"3 hours",
Expand Down Expand Up @@ -42,23 +42,29 @@ interface SurroundingModalProps extends PropsWithChildren {
onNext?: () => void
onBack?: () => void
onActivate?: () => void
nextStepButton?: string
modalTitle?: string
}

interface FSElementProps {
nextStepLabel: string | undefined
}

const SurroundingModal = ({
export const SurroundingModal = ({
onCancel,
onNext,
onBack,
onActivate,
children,
nextStepLabel,
nextStepButton,
modalTitle,
}: SurroundingModalProps & FSElementProps) => (
<Modal show animation={false} onHide={onCancel}>
<Modal.Header closeButton>
<h3 className="fs-3 fw-semibold lh-sm my-1">Start detour</h3>
<h3 className="fs-3 fw-semibold lh-sm my-1">
{modalTitle || "Start detour"}
</h3>
</Modal.Header>
<Modal.Body>{children}</Modal.Body>
<Modal.Footer>
Expand All @@ -85,7 +91,7 @@ const SurroundingModal = ({
onClick={onNext}
data-fs-element={nextStepLabel}
>
Next
{nextStepButton || "Next"}
</Button>
)}
</Modal.Footer>
Expand Down
46 changes: 46 additions & 0 deletions assets/src/components/detours/changeDurationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from "react"
import { Form } from "react-bootstrap"
import { possibleDurations, SurroundingModal } from "./activateDetourModal"

const ChangingDuration = ({
onSelectDuration,
selectedDuration,
editedSelectedDuration,
}: {
onSelectDuration: (duration: string) => void
selectedDuration?: string
editedSelectedDuration?: string
}) => (
<>
<span className="mb-4">
<span className="fw-bold">Previous time length</span>{" "}
<span>(estimate)</span>
<p className="mt-2" data-testid="change-detour-duration-previous-time">
{selectedDuration}
</p>
</span>
<p>
<span className="fw-bold">New time length</span> <span>(estimate)</span>
</p>
<Form>
{possibleDurations.map((duration) => (
<Form.Check
className="mb-2"
onChange={() => {
onSelectDuration(duration)
}}
id={`duration-${duration}`}
key={`duration-${duration}`}
type="radio"
label={duration}
checked={editedSelectedDuration === duration}
/>
))}
</Form>
</>
)

export const ChangeDuration = {
Modal: SurroundingModal,
Body: ChangingDuration,
}
31 changes: 30 additions & 1 deletion assets/src/components/detours/diversionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import useScreenSize from "../../hooks/useScreenSize"
import { Drawer } from "../drawer"
import { isMobile } from "../../util/screenSize"
import { AffectedRoute } from "./detourPanelComponents"
import { ChangeDuration } from "./changeDurationModal"
import { deleteDetour } from "../../api"

const displayFieldsFromRouteAndPattern = (
Expand Down Expand Up @@ -114,6 +115,8 @@ export const DiversionPage = ({

selectedDuration,
selectedReason,

editedSelectedDuration,
} = useDetour(
"snapshot" in useDetourProps
? { snapshot: useDetourProps.snapshot }
Expand Down Expand Up @@ -447,7 +450,7 @@ export const DiversionPage = ({
userInTestGroup(TestGroups.DetoursPilot) &&
userInTestGroup(TestGroups.ChangeDetourDuration)
? () => {
//send({ type: "detour.active.open-change-duration-modal" })
send({ type: "detour.active.open-change-duration-modal" })
}
: undefined
}
Expand All @@ -471,6 +474,32 @@ export const DiversionPage = ({
routeDirection={routeDirection || "??"}
/>
) : null}
{snapshot.matches({
"Detour Drawing": { Active: "Changing Duration" },
}) ? (
<ChangeDuration.Modal
onCancel={() =>
send({ type: "detour.active.change-duration-modal.cancel" })
}
onNext={() =>
send({ type: "detour.active.change-duration-modal.done" })
}
nextStepButton="Done"
nextStepLabel="Confirm Duration"
modalTitle="Change detour duration"
>
<ChangeDuration.Body
onSelectDuration={(selectedDuration: string) => {
send({
type: "detour.active.change-duration-modal.select-duration",
duration: selectedDuration,
})
}}
selectedDuration={selectedDuration}
editedSelectedDuration={editedSelectedDuration}
/>
</ChangeDuration.Modal>
) : null}
</ActiveDetourPanel>
)
} else if (snapshot.matches({ "Detour Drawing": "Past" })) {
Expand Down
6 changes: 6 additions & 0 deletions assets/src/hooks/useDetour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const useDetour = (input: UseDetourInput) => {
nearestIntersection,
selectedDuration,
selectedReason,
editedSelectedDuration,
} = snapshot.context

const { result: unfinishedDetour } = useApiCall({
Expand Down Expand Up @@ -224,5 +225,10 @@ export const useDetour = (input: UseDetourInput) => {
* Detour reason as selected in the activate-detour flow
*/
selectedReason,

/**
* Detour duration while editing is in progress
*/
editedSelectedDuration,
}
}
38 changes: 38 additions & 0 deletions assets/src/models/createDetourMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export const createDetourMachine = setup({
selectedReason?: string

activatedAt?: Date

editedSelectedDuration?: string
},

input: {} as
Expand Down Expand Up @@ -87,6 +89,13 @@ export const createDetourMachine = setup({
| { type: "detour.share.activate-modal.cancel" }
| { type: "detour.share.activate-modal.back" }
| { type: "detour.share.activate-modal.activate" }
| { type: "detour.active.open-change-duration-modal" }
| {
type: "detour.active.change-duration-modal.select-duration"
duration: string
}
| { type: "detour.active.change-duration-modal.done" }
| { type: "detour.active.change-duration-modal.cancel" }
| { type: "detour.active.open-deactivate-modal" }
| { type: "detour.active.deactivate-modal.deactivate" }
| { type: "detour.active.deactivate-modal.cancel" }
Expand Down Expand Up @@ -671,6 +680,14 @@ export const createDetourMachine = setup({
"detour.active.open-deactivate-modal": {
target: "Deactivating",
},
"detour.active.open-change-duration-modal": {
target: "Changing Duration",
actions: assign({
editedSelectedDuration: ({
context: { selectedDuration },
}) => selectedDuration,
}),
},
},
},
Deactivating: {
Expand All @@ -683,6 +700,27 @@ export const createDetourMachine = setup({
},
},
},
"Changing Duration": {
on: {
"detour.active.change-duration-modal.select-duration": {
target: "Changing Duration",
actions: assign({
editedSelectedDuration: ({ event }) => event.duration,
}),
},
"detour.active.change-duration-modal.done": {
target: "Reviewing",
actions: assign({
selectedDuration: ({
context: { editedSelectedDuration },
}) => editedSelectedDuration,
}),
},
"detour.active.change-duration-modal.cancel": {
target: "Reviewing",
},
},
},
Done: { type: "final" },
},
onDone: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ exports[`Detours Page: Open a Detour renders detour details in an open drawer on
<div
class="pb-1 fs-4 fw-semibold"
>
Headsign 8
Headsign A
</div>
<div
class="c-detours-table__route-info-direction fs-6"
Expand Down Expand Up @@ -1017,7 +1017,7 @@ exports[`Detours Page: Open a Detour renders detour details modal to match mocke
<div
class="pb-1 fs-4 fw-semibold"
>
Headsign 5
Headsign A
</div>
<div
class="c-detours-table__route-info-direction fs-6"
Expand Down
Loading

0 comments on commit bb0fc04

Please sign in to comment.