|
|
|
@ -1,9 +1,10 @@
@@ -1,9 +1,10 @@
|
|
|
|
|
import * as React from "react"; |
|
|
|
|
import {SyntheticEvent} from "react"; |
|
|
|
|
import {computed} from "mobx"; |
|
|
|
|
import DevTools from "mobx-react-devtools"; |
|
|
|
|
import {observer} from "mobx-react"; |
|
|
|
|
import {SprinklersDevice, Section, Program, Duration, Schedule} from "./sprinklers"; |
|
|
|
|
import { Item, Table, Header, Segment, Form, Input, DropdownItemProps } from "semantic-ui-react"; |
|
|
|
|
import {Item, Table, Header, Segment, Form, Input, Button, DropdownItemProps, DropdownProps} from "semantic-ui-react"; |
|
|
|
|
import FontAwesome = require("react-fontawesome"); |
|
|
|
|
import * as classNames from "classnames"; |
|
|
|
|
|
|
|
|
@ -64,7 +65,7 @@ class DurationInput extends React.Component<{
@@ -64,7 +65,7 @@ class DurationInput extends React.Component<{
|
|
|
|
|
}, void> { |
|
|
|
|
public render() { |
|
|
|
|
const duration = this.props.duration; |
|
|
|
|
const editing = this.props.onDurationChange != null; |
|
|
|
|
// const editing = this.props.onDurationChange != null;
|
|
|
|
|
return <div className="field durationInput"> |
|
|
|
|
<label>Duration</label> |
|
|
|
|
<div className="fields"> |
|
|
|
@ -79,45 +80,72 @@ class DurationInput extends React.Component<{
@@ -79,45 +80,72 @@ class DurationInput extends React.Component<{
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private onMinutesChange = (e, {value}) => { |
|
|
|
|
this.props.onDurationChange(new Duration(Number(value), this.props.duration.seconds)); |
|
|
|
|
if (value.length === 0 || isNaN(value)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const newMinutes = parseInt(value, 10); |
|
|
|
|
this.props.onDurationChange(this.props.duration.withMinutes(newMinutes)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private onSecondsChange = (e, {value}) => { |
|
|
|
|
let newSeconds = Number(value); |
|
|
|
|
let newMinutes = this.props.duration.minutes; |
|
|
|
|
if (newSeconds >= 60) { |
|
|
|
|
newMinutes++; |
|
|
|
|
newSeconds = 0; |
|
|
|
|
} |
|
|
|
|
if (newSeconds < 0) { |
|
|
|
|
newMinutes = Math.max(0, newMinutes - 1); |
|
|
|
|
newSeconds = 59; |
|
|
|
|
if (value.length === 0 || isNaN(value)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
this.props.onDurationChange(new Duration(newMinutes, newSeconds)); |
|
|
|
|
const newSeconds = parseInt(value, 10); |
|
|
|
|
this.props.onDurationChange(this.props.duration.withSeconds(newSeconds)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@observer |
|
|
|
|
class RunSectionForm extends React.Component<{ sections: Section[] }, { duration: Duration }> { |
|
|
|
|
public componentWillMount() { |
|
|
|
|
this.setState({ |
|
|
|
|
class RunSectionForm extends React.Component<{ |
|
|
|
|
sections: Section[], |
|
|
|
|
}, { |
|
|
|
|
duration: Duration, |
|
|
|
|
section: number | "", |
|
|
|
|
}> { |
|
|
|
|
constructor() { |
|
|
|
|
super(); |
|
|
|
|
this.state = { |
|
|
|
|
duration: new Duration(1, 1), |
|
|
|
|
}); |
|
|
|
|
section: "", |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public render() { |
|
|
|
|
const {section, duration} = this.state; |
|
|
|
|
return <Segment> |
|
|
|
|
<Header>Run Section</Header> |
|
|
|
|
<Form> |
|
|
|
|
<Form.Group> |
|
|
|
|
<Form.Select label="Section" placeholder="Section" options={this.sectionOptions} /> |
|
|
|
|
<DurationInput duration={this.state.duration} |
|
|
|
|
onDurationChange={(newDuration) => this.setState({ duration: newDuration })} /> |
|
|
|
|
<Form.Select label="Section" placeholder="Section" options={this.sectionOptions} value={section} |
|
|
|
|
onChange={this.onSectionChange}/> |
|
|
|
|
<DurationInput duration={duration} onDurationChange={this.onDurationChange}/> |
|
|
|
|
{/*Label must be to align it properly*/} |
|
|
|
|
<Form.Button label=" " primary onClick={this.run} disabled={!this.isValid}>Run</Form.Button> |
|
|
|
|
</Form.Group> |
|
|
|
|
</Form> |
|
|
|
|
</Segment>; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private onSectionChange = (e: SyntheticEvent<HTMLElement>, v: DropdownProps) => { |
|
|
|
|
this.setState({section: v.value as number}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private onDurationChange = (newDuration: Duration) => { |
|
|
|
|
this.setState({duration: newDuration}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private run = (e: SyntheticEvent<HTMLElement>) => { |
|
|
|
|
e.preventDefault(); |
|
|
|
|
const section: Section = this.props.sections[this.state.section]; |
|
|
|
|
console.log(`should run section ${section} for ${this.state.duration}`); |
|
|
|
|
section.run(this.state.duration); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private get isValid(): boolean { |
|
|
|
|
return typeof this.state.section === "number"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@computed |
|
|
|
|
private get sectionOptions(): DropdownItemProps[] { |
|
|
|
|
return this.props.sections.map((s, i) => ({ |
|
|
|
@ -138,7 +166,7 @@ class ScheduleView extends React.PureComponent<{ schedule: Schedule }, void> {
@@ -138,7 +166,7 @@ class ScheduleView extends React.PureComponent<{ schedule: Schedule }, void> {
|
|
|
|
|
|
|
|
|
|
@observer |
|
|
|
|
class ProgramTable extends React.PureComponent<{ programs: Program[] }, void> { |
|
|
|
|
private static renderRow(program: Program, i: number) { |
|
|
|
|
private static renderRow(program: Program, i: number): JSX.Element[] { |
|
|
|
|
if (!program) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
@ -155,7 +183,7 @@ class ProgramTable extends React.PureComponent<{ programs: Program[] }, void> {
@@ -155,7 +183,7 @@ class ProgramTable extends React.PureComponent<{ programs: Program[] }, void> {
|
|
|
|
|
<Table.Cell className="program--sequence" colSpan="4"> |
|
|
|
|
<ul> |
|
|
|
|
{sequence.map((item) => |
|
|
|
|
(<li>Section {item.section + 1 + ""} for |
|
|
|
|
(<li>Section {item.section + 1 + ""} for |
|
|
|
|
{item.duration.minutes}M {item.duration.seconds}S</li>))} |
|
|
|
|
</ul> |
|
|
|
|
<ScheduleView schedule={schedule}/> |
|
|
|
|