sprinklers3/app/components/RunSectionForm.tsx

108 lines
3.4 KiB
TypeScript
Raw Normal View History

import { computed } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
2017-10-14 01:51:22 -06:00
import { DropdownItemProps, DropdownProps, Form, Header, Segment } from "semantic-ui-react";
2018-06-25 17:37:36 -06:00
import { UiStore } from "@app/state";
2017-10-10 16:34:02 -06:00
import { Duration } from "@common/Duration";
2017-10-03 12:18:30 -06:00
import log from "@common/logger";
2018-06-26 11:53:22 -06:00
import { Section, SprinklersDevice } from "@common/sprinklers";
2018-06-25 17:37:36 -06:00
import { RunSectionResponse } from "@common/sprinklers/requests";
import DurationInput from "./DurationInput";
@observer
export default class RunSectionForm extends React.Component<{
2018-06-26 11:53:22 -06:00
device: SprinklersDevice,
2018-06-25 17:37:36 -06:00
uiStore: UiStore,
}, {
duration: Duration,
section: number | "",
}> {
2018-04-12 17:27:42 -06:00
constructor(props: any, context?: any) {
super(props, context);
this.state = {
2017-10-10 16:34:02 -06:00
duration: new Duration(0, 0),
section: "",
};
}
render() {
const { section, duration } = this.state;
2017-09-07 15:52:51 -06:00
return (
<Segment>
<Header>Run Section</Header>
<Form>
2017-10-31 17:23:27 -06:00
<Form.Select
label="Section"
placeholder="Section"
options={this.sectionOptions}
value={section}
onChange={this.onSectionChange}
/>
<DurationInput
duration={duration}
onDurationChange={this.onDurationChange}
/>
{/*Label must be &nbsp; to align it properly*/}
<Form.Button
label="&nbsp;"
primary
onClick={this.run}
disabled={!this.isValid}
>
Run
</Form.Button>
2017-09-07 15:52:51 -06:00
</Form>
</Segment>
);
}
2017-08-29 22:42:56 -06:00
private onSectionChange = (e: React.SyntheticEvent<HTMLElement>, v: DropdownProps) => {
this.setState({ section: v.value as number });
}
private onDurationChange = (newDuration: Duration) => {
this.setState({ duration: newDuration });
}
2017-08-29 22:42:56 -06:00
private run = (e: React.SyntheticEvent<HTMLElement>) => {
e.preventDefault();
2017-08-29 22:42:56 -06:00
if (typeof this.state.section !== "number") {
return;
}
2018-06-26 11:53:22 -06:00
const section: Section = this.props.device.sections[this.state.section];
2017-10-03 12:18:30 -06:00
const { duration } = this.state;
2017-10-10 16:34:02 -06:00
section.run(duration.toSeconds())
2018-06-25 17:37:36 -06:00
.then(this.onRunSuccess)
.catch(this.onRunError);
}
private onRunSuccess = (result: RunSectionResponse) => {
log.debug({ result }, "requested section run");
this.props.uiStore.addMessage({
2018-06-26 11:53:22 -06:00
success: true, header: "Section running",
content: result.message, timeout: 2000,
2018-06-25 17:37:36 -06:00
});
}
private onRunError = (err: RunSectionResponse) => {
log.error(err, "error running section");
this.props.uiStore.addMessage({
2018-06-26 11:53:22 -06:00
error: true, header: "Error running section",
2018-06-25 17:37:36 -06:00
content: err.message,
});
}
private get isValid(): boolean {
return typeof this.state.section === "number";
}
@computed
private get sectionOptions(): DropdownItemProps[] {
2018-06-26 11:53:22 -06:00
return this.props.device.sections.map((s, i) => ({
text: s ? s.name : null,
value: i,
}));
}
}