Skip to content

Commit

Permalink
part way to figuring out the issues. but need to go update #21
Browse files Browse the repository at this point in the history
  • Loading branch information
alan-stokes committed Nov 7, 2023
1 parent 1987721 commit 9796c84
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 94 deletions.
33 changes: 31 additions & 2 deletions src/main/webui/src/observations/edit.group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { SubmitButton } from '../commonButtons/save.tsx';
import { useParams } from 'react-router-dom';
import { useQueryClient } from '@tanstack/react-query';
import { ReactElement } from 'react';
import { randomId } from '@mantine/hooks';
import { TimingWindowGui } from './timingWindowGui.tsx';

/**
* the different types of observation.
Expand All @@ -37,7 +39,7 @@ export interface ObservationFormValues {
targetDBId: number | undefined,
techGoalId: number | undefined,
fieldId: number | undefined
timingWindows: TimingWindows,
timingWindows: TimingWindowGui[],
}

/**
Expand Down Expand Up @@ -78,7 +80,6 @@ export default function ObservationEditGroup(props: ObservationProps): ReactElem
return ConvertToTimingWindowGui(timingWindow);}) :
[emptyTimingWindow];


const form: UseFormReturnType<ObservationFormValues> = useForm<ObservationFormValues>({
initialValues: {
observationType: observationType,
Expand Down Expand Up @@ -183,6 +184,34 @@ export default function ObservationEditGroup(props: ObservationProps): ReactElem
)
}

/*
Type TimingWindow in proposalToolSchemas.ts has 'startTime' and 'endTime' as date strings (ISO8601 strings).
We need to convert these to type Date before using them with the 'DateTimePicker' element
*/
function ConvertToTimingWindowGui(input: TimingWindow) : TimingWindowGui {
return ({
startTime: new Date(input.startTime!),
endTime: new Date(input.endTime!),
note: input.note!,
isAvoidConstraint: input.isAvoidConstraint!,
key: randomId()
})
}

/*
Note: API expects the Dates as the number of seconds since the posix epoch
*/
// @ts-ignore
function ConvertToTimingWindowApi(input: TimingWindowGui) : TimingWindowApi {
return ({
"@type": "proposal:TimingWindow",
startTime: input.startTime!.getTime(),
endTime: input.endTime!.getTime(),
note: input.note,
isAvoidConstraint: input.isAvoidConstraint
})
}


/**
* const handleSave = (timingWindow : TimingWindowApi) => {
Expand Down
8 changes: 8 additions & 0 deletions src/main/webui/src/observations/timingWindowGui.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//type to use for the DateTimePickers
export type TimingWindowGui = {
startTime: Date | null,
endTime: Date | null,
note: string,
isAvoidConstraint: boolean,
key: string
}
166 changes: 74 additions & 92 deletions src/main/webui/src/observations/timingWindows.form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {randomId} from "@mantine/hooks";
import '@mantine/dates/styles.css'
import AddButton from "../commonButtons/add.tsx";
import { ObservationFormValues } from './edit.group.tsx';
import {TimingWindow} from "../generated/proposalToolSchemas.ts";
import { AccordionDelete } from '../commonButtons/accordianControls.tsx';
import { ReactElement } from 'react';
import { TimingWindowGui } from './timingWindowGui.tsx';


//Providing a UI for a TimingWindow: {start: Date, end: Date, note: string, isAvoidConstraint: boolean}
Expand All @@ -26,15 +27,6 @@ import { AccordionDelete } from '../commonButtons/accordianControls.tsx';
//As a general reminder, Radio observations can be done at any time but Optical observations can occur only after
// sunset. In both cases the target must be above the horizon at the time

//type to use for the DateTimePickers
type TimingWindowGui = {
startTime: Date | null,
endTime: Date | null,
note: string,
isAvoidConstraint: boolean,
key: string
}

//type to use to pass data to the API
type TimingWindowApi = {
"@type": string,
Expand All @@ -44,38 +36,27 @@ type TimingWindowApi = {
isAvoidConstraint: boolean,
}

export default function TimingWindowsForm(form: UseFormReturnType<ObservationFormValues>) {
/**
*
* @param {UseFormReturnType<ObservationFormValues>} form the form containing all the data to display.
* @return {ReactElement} the HTML for the timing windows panel.
* @constructor
*/
export default function TimingWindowsForm(
form: UseFormReturnType<ObservationFormValues>): ReactElement {
let emptyTimingWindow : TimingWindowGui = {
startTime: null, endTime: null, note: '', isAvoidConstraint: false, key: randomId()
}

/*
Type TimingWindow in proposalToolSchemas.ts has 'startTime' and 'endTime' as date strings (ISO8601 strings).
We need to convert these to type Date before using them with the 'DateTimePicker' element
*/
function ConvertToTimingWindowGui(input: TimingWindow) : TimingWindowGui {
return ({
startTime: new Date(input.startTime!),
endTime: new Date(input.endTime!),
note: input.note!,
isAvoidConstraint: input.isAvoidConstraint!,
key: randomId()
})
startTime: null,
endTime: null,
note: '',
isAvoidConstraint: false,
key: randomId()
}

/*
Note: API expects the Dates as the number of seconds since the posix epoch
/**
* handles the deletion of a timing window.
*
* @param {number} index the index in the table.
*/
function ConvertToTimingWindowApi(input: TimingWindowGui) : TimingWindowApi {
return ({
"@type": "proposal:TimingWindow",
startTime: input.startTime!.getTime(),
endTime: input.endTime!.getTime(),
note: input.note,
isAvoidConstraint: input.isAvoidConstraint
})
}

const handleDelete = (index: number) => {
alert("Removes the list item only - does not yet delete the timing window from the database")
form.removeListItem('timingWindows', index);
Expand All @@ -89,60 +70,61 @@ export default function TimingWindowsForm(form: UseFormReturnType<ObservationFor
let avoidCol = 1;
let noteCol = 3;

const windowsList = form.values.timingWindows.timingWindows.map((item, index) => {
let labelIndex = index + 1;
// @ts-ignore
return (
<Accordion.Item value={labelIndex.toString()} key={item.key}>
<AccordionDelete
title={"Window " + labelIndex}
deleteProps={{
toolTipLabel: 'delete timing window ' + labelIndex,
onClick: () => handleDelete(index)
}}
/>
<Accordion.Panel>
<Grid columns={nCols} gutter={"md"}>
<Grid.Col span={{base: nCols, lg: rangeCol}}>
<DateTimePicker
placeholder={"start time"}
minDate={new Date()}
{...form.getInputProps(`timingWindows.${index}.startTime`)}
/>
<Space h={"xs"}/>
<DateTimePicker
placeholder={"end time"}
minDate={new Date()}
{...form.getInputProps(`timingWindows.${index}.endTime`)}
/>
</Grid.Col>
<Grid.Col span={{base: nCols, lg: avoidCol}}>
<Switch
onLabel={"avoid"}
offLabel={""}
size={"xl"}
color={'grape'}
radius={'xs'}
mt={"1.5rem"}
{...form.getInputProps(`timingWindows.${index}.isAvoidConstraint`, {type: 'checkbox'})}
/>
</Grid.Col>
<Grid.Col span={{base: nCols, lg: noteCol}}>
<Textarea
autosize
minRows={3}
maxRows={3}
maxLength={150}
description={150 - form.values.timingWindows.timingWindows[index].note.length + "/150"}
inputWrapperOrder={['label', 'error', 'input', 'description']}
placeholder={"add optional note"}
{...form.getInputProps(`timingWindows.${index}.note`)}
/>
</Grid.Col>
</Grid>
</Accordion.Panel>
</Accordion.Item>
)
const windowsList = form.values.timingWindows.map(
(item: TimingWindowGui, index: number) => {
let labelIndex = index + 1;
// @ts-ignore
return (
<Accordion.Item value={labelIndex.toString()} key={item.key}>
<AccordionDelete
title={"Window " + labelIndex}
deleteProps={{
toolTipLabel: 'delete timing window ' + labelIndex,
onClick: () => handleDelete(index)
}}
/>
<Accordion.Panel>
<Grid columns={nCols} gutter={"md"}>
<Grid.Col span={{base: nCols, lg: rangeCol}}>
<DateTimePicker
placeholder={"start time"}
minDate={new Date()}
{...form.getInputProps(`timingWindows.${index}.startTime`)}
/>
<Space h={"xs"}/>
<DateTimePicker
placeholder={"end time"}
minDate={new Date()}
{...form.getInputProps(`timingWindows.${index}.endTime`)}
/>
</Grid.Col>
<Grid.Col span={{base: nCols, lg: avoidCol}}>
<Switch
onLabel={"avoid"}
offLabel={""}
size={"xl"}
color={'grape'}
radius={'xs'}
mt={"1.5rem"}
{...form.getInputProps(`timingWindows.${index}.isAvoidConstraint`, {type: 'checkbox'})}
/>
</Grid.Col>
<Grid.Col span={{base: nCols, lg: noteCol}}>
<Textarea
autosize
minRows={3}
maxRows={3}
maxLength={150}
description={150 - form.values.timingWindows[index].note.length + "/150"}
inputWrapperOrder={['label', 'error', 'input', 'description']}
placeholder={"add optional note"}
{...form.getInputProps(`timingWindows.${index}.note`)}
/>
</Grid.Col>
</Grid>
</Accordion.Panel>
</Accordion.Item>
)
});

return (
Expand Down

0 comments on commit 9796c84

Please sign in to comment.