diff --git a/web/src/app/rotations/RotationCreateDialog.tsx b/web/src/app/rotations/RotationCreateDialog.tsx index 68d72d703d..f5fc02454e 100644 --- a/web/src/app/rotations/RotationCreateDialog.tsx +++ b/web/src/app/rotations/RotationCreateDialog.tsx @@ -5,16 +5,7 @@ import FormDialog from '../dialogs/FormDialog' import RotationForm from './RotationForm' import { DateTime } from 'luxon' import { Redirect } from 'wouter' - -interface Value { - name: string - description: string - timeZone: string - type: string - start: string - shiftLength: number - favorite: boolean -} +import { CreateRotationInput } from '../../schema' const mutation = gql` mutation ($input: CreateRotationInput!) { @@ -31,7 +22,7 @@ const mutation = gql` ` const RotationCreateDialog = (props: { onClose?: () => void }): JSX.Element => { - const [value, setValue] = useState({ + const [value, setValue] = useState({ name: '', description: '', timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone, diff --git a/web/src/app/rotations/RotationEditDialog.tsx b/web/src/app/rotations/RotationEditDialog.tsx index 92cfffda59..2e0db7ba95 100644 --- a/web/src/app/rotations/RotationEditDialog.tsx +++ b/web/src/app/rotations/RotationEditDialog.tsx @@ -6,15 +6,7 @@ import FormDialog from '../dialogs/FormDialog' import RotationForm from './RotationForm' import Spinner from '../loading/components/Spinner' import { GenericError } from '../error-pages' - -interface Value { - name: string - description: string - timeZone: string - type: string - shiftLength: number - start: string -} +import { CreateRotationInput } from '../../schema' const query = gql` query ($id: ID!) { @@ -41,7 +33,7 @@ export default function RotationEditDialog(props: { rotationID: string onClose: () => void }): JSX.Element { - const [value, setValue] = useState(null) + const [value, setValue] = useState(null) const [{ fetching, error, data }] = useQuery({ query, diff --git a/web/src/app/rotations/RotationForm.js b/web/src/app/rotations/RotationForm.tsx similarity index 86% rename from web/src/app/rotations/RotationForm.js rename to web/src/app/rotations/RotationForm.tsx index 100f7c69ca..4eb718494a 100644 --- a/web/src/app/rotations/RotationForm.js +++ b/web/src/app/rotations/RotationForm.tsx @@ -1,5 +1,4 @@ import React, { useState } from 'react' -import p from 'prop-types' import { TextField, Grid, @@ -18,6 +17,15 @@ import { TimeZoneSelect } from '../selection' import { ISODateTimePicker } from '../util/ISOPickers' import NumberField from '../util/NumberField' import Spinner from '../loading/components/Spinner' +import { FieldError } from '../util/errutil' +import { RotationType, CreateRotationInput } from '../../schema' + +interface RotationFormProps { + value: CreateRotationInput + errors: FieldError[] + onChange: (value: CreateRotationInput) => void + disabled?: boolean +} const query = gql` query calcRotationHandoffTimes($input: CalcRotationHandoffTimesInput) { @@ -48,7 +56,7 @@ const useStyles = makeStyles({ // getHours converts a count and one of ['hourly', 'daily', 'weekly'] // into length in hours e.g. (2, daily) => 48 -function getHours(count, unit) { +function getHours(count: number, unit: RotationType): number { const lookup = { hourly: 1, daily: 24, @@ -57,7 +65,7 @@ function getHours(count, unit) { return lookup[unit] * count } -export default function RotationForm(props) { +export default function RotationForm(props: RotationFormProps): JSX.Element { const { value } = props const classes = useStyles() const localZone = DateTime.local().zone.name @@ -70,7 +78,7 @@ export default function RotationForm(props) { handoff: value.start, from: value.start, timeZone: value.timeZone, - shiftLengthHours: getHours(value.shiftLength, value.type), + shiftLengthHours: getHours(value.shiftLength as number, value.type), count: 3, }, }, @@ -81,7 +89,7 @@ export default function RotationForm(props) { const isHandoffValid = DateTime.fromISO(value.start).isValid const nextHandoffs = isCalculating ? [] - : data.calcRotationHandoffTimes.map((iso) => + : data.calcRotationHandoffTimes.map((iso: string) => DateTime.fromISO(iso) .setZone(configZone) .toLocaleString(DateTime.DATETIME_FULL), @@ -182,7 +190,7 @@ export default function RotationForm(props) { {isHandoffValid ? (
    - {nextHandoffs.map((text, i) => ( + {nextHandoffs.map((text: string, i: number) => ( ) } - -RotationForm.propTypes = { - value: p.shape({ - name: p.string.isRequired, - description: p.string.isRequired, - timeZone: p.string.isRequired, - type: p.oneOf(rotationTypes).isRequired, - shiftLength: p.number.isRequired, - start: p.string.isRequired, - }).isRequired, - - errors: p.arrayOf( - p.shape({ - field: p.oneOf([ - 'name', - 'description', - 'timeZone', - 'type', - 'start', - 'shiftLength', - ]).isRequired, - message: p.string.isRequired, - }), - ), - - onChange: p.func.isRequired, - disabled: p.bool, -}