Skip to content

Commit 31567ce

Browse files
committed
Add stepper max
1 parent 30f2b2f commit 31567ce

File tree

7 files changed

+47
-6
lines changed

7 files changed

+47
-6
lines changed

site/src/components/Workspace/Workspace.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export interface WorkspaceProps {
3838
onDeadlineMinus: (hours: number) => void
3939
deadlinePlusEnabled: () => boolean
4040
deadlineMinusEnabled: () => boolean
41+
maxDeadlineIncrease: number
42+
maxDeadlineDecrease: number
4143
}
4244
handleStart: () => void
4345
handleStop: () => void
@@ -121,6 +123,8 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
121123
onDeadlinePlus={scheduleProps.onDeadlinePlus}
122124
deadlineMinusEnabled={scheduleProps.deadlineMinusEnabled}
123125
deadlinePlusEnabled={scheduleProps.deadlinePlusEnabled}
126+
maxDeadlineDecrease={scheduleProps.maxDeadlineDecrease}
127+
maxDeadlineIncrease={scheduleProps.maxDeadlineIncrease}
124128
canUpdateWorkspace={canUpdateWorkspace}
125129
/>
126130
<WorkspaceActions

site/src/components/WorkspaceScheduleButton/EditHours.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import { useTranslation } from "react-i18next"
77

88
interface EditHoursProps {
99
handleSubmit: (hours: number) => void
10+
max: number
1011
}
1112

12-
export const EditHours = ({ handleSubmit }: EditHoursProps): JSX.Element => {
13+
export const EditHours = ({ handleSubmit, max }: EditHoursProps): JSX.Element => {
1314
const { t } = useTranslation("workspacePage")
1415
const [hours, setHours] = useState(1)
1516
const styles = useStyles()
@@ -19,7 +20,7 @@ export const EditHours = ({ handleSubmit }: EditHoursProps): JSX.Element => {
1920
<Stack direction="row" alignItems="baseline" spacing={1}>
2021
<TextField
2122
className={styles.inputField}
22-
inputProps={{ min: 0, step: 1 }}
23+
inputProps={{ min: 0, max, step: 1 }}
2324
label={t("workspaceScheduleButton.hours")}
2425
value={hours}
2526
onChange={(e) => setHours(parseInt(e.target.value))}

site/src/components/WorkspaceScheduleButton/WorkspaceScheduleButton.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import dayjs from "dayjs"
22
import utc from "dayjs/plugin/utc"
33
import * as TypesGen from "../../api/typesGenerated"
44
import * as Mocks from "../../testHelpers/entities"
5-
import { shouldDisplayPlusMinus } from "./WorkspaceScheduleButton"
5+
import { canEditDeadline } from "./WorkspaceScheduleButton"
66

77
dayjs.extend(utc)
88

@@ -13,15 +13,15 @@ describe("WorkspaceScheduleButton", () => {
1313
const workspace: TypesGen.Workspace = Mocks.MockStoppedWorkspace
1414

1515
// Then: shouldDisplayPlusMinus should be false
16-
expect(shouldDisplayPlusMinus(workspace)).toBeFalsy()
16+
expect(canEditDeadline(workspace)).toBeFalsy()
1717
})
1818

1919
it("should display if the workspace is running", () => {
2020
// Given: a stopped workspace
2121
const workspace: TypesGen.Workspace = Mocks.MockWorkspace
2222

2323
// Then: shouldDisplayPlusMinus should be false
24-
expect(shouldDisplayPlusMinus(workspace)).toBeTruthy()
24+
expect(canEditDeadline(workspace)).toBeTruthy()
2525
})
2626
})
2727
})

site/src/components/WorkspaceScheduleButton/WorkspaceScheduleButton.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export interface WorkspaceScheduleButtonProps {
5050
onDeadlineMinus: (hours: number) => void
5151
deadlineMinusEnabled: () => boolean
5252
deadlinePlusEnabled: () => boolean
53+
maxDeadlineIncrease: number
54+
maxDeadlineDecrease: number
5355
canUpdateWorkspace: boolean
5456
}
5557

@@ -63,6 +65,8 @@ export const WorkspaceScheduleButton: React.FC<
6365
onDeadlineMinus,
6466
deadlinePlusEnabled,
6567
deadlineMinusEnabled,
68+
maxDeadlineDecrease,
69+
maxDeadlineIncrease,
6670
canUpdateWorkspace,
6771
}) => {
6872
const { t } = useTranslation("workspacePage")
@@ -121,7 +125,7 @@ export const WorkspaceScheduleButton: React.FC<
121125
</IconButton>
122126
</span>
123127
<Maybe condition={editMode !== "off"}>
124-
<EditHours handleSubmit={handleSubmitHours} />
128+
<EditHours handleSubmit={handleSubmitHours} max={editMode === "add" ? maxDeadlineIncrease : maxDeadlineDecrease} />
125129
</Maybe>
126130
</Maybe>
127131
</Stack>

site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import dayjs from "dayjs"
44
import { useContext } from "react"
55
import { Helmet } from "react-helmet-async"
66
import { useTranslation } from "react-i18next"
7+
import { getMaxDeadline, getMaxDeadlineChange, getMinDeadline } from "util/schedule"
8+
//import { getMaxDeadlineDecrease, getMaxDeadlineIncrease } from "util/schedule"
79
import { selectFeatureVisibility } from "xServices/entitlements/entitlementsSelectors"
810
import { StateFrom } from "xstate"
911
import { DeleteDialog } from "../../components/Dialogs/DeleteDialog/DeleteDialog"
@@ -95,6 +97,8 @@ export const WorkspaceReadyPage = ({
9597
},
9698
deadlineMinusEnabled: () => !bannerState.matches("atMinDeadline"),
9799
deadlinePlusEnabled: () => !bannerState.matches("atMaxDeadline"),
100+
maxDeadlineDecrease: getMaxDeadlineChange(bannerState.context.workspace.deadline, getMinDeadline()),
101+
maxDeadlineIncrease: getMaxDeadlineChange(bannerState.context.workspace.deadline, getMaxDeadline(workspace, bannerState.context.template))
98102
}}
99103
isUpdating={workspaceState.hasTag("updating")}
100104
workspace={workspace}

site/src/util/schedule.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
deadlineExtensionMin,
1010
extractTimezone,
1111
getMaxDeadline,
12+
getMaxDeadlineChange,
1213
getMinDeadline,
1314
stripTimezone,
1415
} from "./schedule"
@@ -124,3 +125,19 @@ describe("canReduceDeadline", () => {
124125
expect(canReduceDeadline(dayjs().add(100, "years"))).toBeTruthy()
125126
})
126127
})
128+
129+
describe("getMaxDeadlineChange", () => {
130+
it("should return the number of hours you can add before hitting the max deadline", () => {
131+
const deadline = dayjs()
132+
const maxDeadline = dayjs().add(1, "hour").add(40, "minutes")
133+
// you can only add one hour even though the max is 1:40 away
134+
expect(getMaxDeadlineChange(deadline, maxDeadline)).toEqual(1)
135+
})
136+
137+
it("should return the number of hours you can subtract before hitting the min deadline", () => {
138+
const deadline = dayjs().add(2, "hours").add(40, "minutes")
139+
const minDeadline = dayjs()
140+
// you can only subtract 2 hours even though the min is 2:40 less
141+
expect(getMaxDeadlineChange(deadline, minDeadline)).toEqual(2)
142+
})
143+
})

site/src/util/schedule.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,14 @@ export function canReduceDeadline(deadline: dayjs.Dayjs): boolean {
167167

168168
export const getDeadline = (workspace: Workspace): dayjs.Dayjs =>
169169
dayjs(workspace.latest_build.deadline).utc()
170+
171+
/**
172+
* Get number of hours you can add or subtract to the current deadline before hitting the max or min deadline.
173+
* @param deadline
174+
* @param workspace
175+
* @param template
176+
* @returns number, in hours
177+
*/
178+
export const getMaxDeadlineChange = (deadline: dayjs.Dayjs, extremeDeadline: dayjs.Dayjs): number => {
179+
return Math.abs(deadline.diff(extremeDeadline, "hours"))
180+
}

0 commit comments

Comments
 (0)