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

service maint: allow specifying a custom end time #3815

Merged
merged 4 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
60 changes: 42 additions & 18 deletions web/src/app/services/ServiceMaintenanceDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useState, useEffect } from 'react'
import { gql, useMutation } from 'urql'
import { RadioGroup, Radio } from '@mui/material'

import { RadioGroup, Radio, Typography } from '@mui/material'
import FormControlLabel from '@mui/material/FormControlLabel'
import FormControl from '@mui/material/FormControl'
import FormDialog from '../dialogs/FormDialog'
import { nonFieldErrors } from '../util/errutil'
import { DateTime } from 'luxon'
import { Time } from '../util/Time'
import { ISODateTimePicker } from '../util/ISOPickers'

interface Props {
serviceID: string
Expand All @@ -18,26 +18,48 @@ interface Props {
function label(hours: number): JSX.Element {
return (
<span>
For <Time duration={{ hours }} /> (
<Time duration={{ hours }} /> (
<Time prefix='ends ' time={DateTime.local().plus({ hours }).toISO()} />)
</span>
)
}

function ServiceMaintenanceForm(props: {
onChange: (val: number) => void
selectedIndex: number
value: DateTime
onChange: (val: DateTime) => void
}): JSX.Element {
const [selectedOption, setSelectedOption] = useState(1)

function handleOption(value: number): void {
setSelectedOption(value)
if (value === -1) return
props.onChange(DateTime.local().plus({ hours: value }))
}

return (
<FormControl>
<RadioGroup
value={props.selectedIndex}
onChange={(e) => props.onChange(parseInt(e.target.value, 10))}
value={selectedOption}
onChange={(e) => handleOption(parseInt(e.target.value, 10))}
>
<FormControlLabel value={1} control={<Radio />} label={label(1)} />
<FormControlLabel value={2} control={<Radio />} label={label(2)} />
<FormControlLabel value={4} control={<Radio />} label={label(4)} />
<FormControlLabel value={-1} control={<Radio />} label='Until...' />
</RadioGroup>
<ISODateTimePicker
label='Select a date'
helperText='Within 24 hours'
value={props.value.toISO()}
disabled={selectedOption !== -1}
onChange={(iso) => props.onChange(DateTime.fromISO(iso))}
min={DateTime.local().plus({ hours: 1 }).toISO()}
max={DateTime.local().plus({ hours: 24 }).toISO()}
sx={{
marginLeft: (theme) => theme.spacing(3.75),
marginTop: (theme) => theme.spacing(1),
}}
/>
</FormControl>
)
}
Expand All @@ -51,7 +73,7 @@ const mutation = gql`
export default function ServiceMaintenanceModeDialog(
props: Props,
): JSX.Element {
const [selectedHours, setSelectedHours] = useState(1)
const [endTime, setEndTime] = useState(DateTime.local().plus({ hours: 1 }))
const [updateServiceStatus, updateService] = useMutation(mutation)

useEffect(() => {
Expand All @@ -64,12 +86,16 @@ export default function ServiceMaintenanceModeDialog(
maxWidth='sm'
title='Set Maintenance Mode'
subTitle={
<React.Fragment>
<Typography>
Pause all outgoing notifications and escalations for{' '}
<Time duration={{ hours: selectedHours }} />. Incoming alerts will
still be created and will continue as normal after maintenance mode
ends.
</React.Fragment>
<Time
duration={{
hours: Math.ceil(endTime.diffNow('hours').hours),
}}
/>
. Incoming alerts will still be created and will continue as normal
after maintenance mode ends.
</Typography>
}
loading={updateServiceStatus.fetching}
errors={nonFieldErrors(updateServiceStatus.error)}
Expand All @@ -79,9 +105,7 @@ export default function ServiceMaintenanceModeDialog(
{
input: {
id: props.serviceID,
maintenanceExpiresAt: DateTime.local()
.plus({ hours: selectedHours })
.toISO(),
maintenanceExpiresAt: endTime.toISO(),
},
},
{
Expand All @@ -91,8 +115,8 @@ export default function ServiceMaintenanceModeDialog(
}
form={
<ServiceMaintenanceForm
onChange={(value) => setSelectedHours(value)}
selectedIndex={selectedHours}
onChange={(value) => setEndTime(value)}
value={endTime}
/>
}
/>
Expand Down
3 changes: 3 additions & 0 deletions web/src/app/util/ISOPickers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ interface ISOPickerProps extends ISOTextFieldProps {
type ISOTextFieldProps = Partial<Omit<TextFieldProps, 'value' | 'onChange'>> & {
value?: string
onChange: (value: string) => void

min?: string
max?: string
}

function ISOPicker(props: ISOPickerProps): JSX.Element {
Expand Down
Loading