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, Button, DropdownItemProps, DropdownProps, Message} from "semantic-ui-react"; import FontAwesome = require("react-fontawesome"); import * as classNames from "classnames"; import "semantic-ui-css/semantic.css"; import "font-awesome/css/font-awesome.css"; import "app/style/app.css"; import {Message as UiMessage, UiStore} from "./ui"; /* tslint:disable:object-literal-sort-keys */ @observer class SectionTable extends React.PureComponent<{ sections: Section[] }, void> { private static renderRow(section: Section, index: number) { if (!section) { return null; } const {name, state} = section; return ( {"" + (index + 1)} {name} {state ? ( Irrigating) : "Not irrigating"} ); } public render() { return ( Sections # Name State { this.props.sections.map(SectionTable.renderRow) }
); } } class DurationInput extends React.Component<{ duration: Duration, onDurationChange?: (newDuration: Duration) => void; }, void> { public render() { const duration = this.props.duration; // const editing = this.props.onDurationChange != null; return
; } private onMinutesChange = (e, {value}) => { if (value.length === 0 || isNaN(value)) { return; } const newMinutes = parseInt(value, 10); this.props.onDurationChange(this.props.duration.withMinutes(newMinutes)); } private onSecondsChange = (e, {value}) => { if (value.length === 0 || isNaN(value)) { return; } const newSeconds = parseInt(value, 10); this.props.onDurationChange(this.props.duration.withSeconds(newSeconds)); } } @observer 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
Run Section
{/*Label must be   to align it properly*/} Run
; } private onSectionChange = (e: SyntheticEvent, v: DropdownProps) => { this.setState({section: v.value as number}); } private onDurationChange = (newDuration: Duration) => { this.setState({duration: newDuration}); } private run = (e: SyntheticEvent) => { 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) .then((a) => console.log("ran section", a)) .catch((err) => console.error("error running section", err)); } private get isValid(): boolean { return typeof this.state.section === "number"; } @computed private get sectionOptions(): DropdownItemProps[] { return this.props.sections.map((s, i) => ({ text: s ? s.name : null, value: i, })); } } @observer class ScheduleView extends React.PureComponent<{ schedule: Schedule }, void> { public render() { return (
{JSON.stringify(this.props.schedule)}
); } } @observer class ProgramTable extends React.PureComponent<{ programs: Program[] }, void> { private static renderRow(program: Program, i: number): JSX.Element[] { if (!program) { return null; } const {name, running, enabled, schedule, sequence} = program; return [ {"" + (i + 1)} {name} {running ? "Running" : "Not running"} {enabled ? "Enabled" : "Not enabled"} ,
    {sequence.map((item) => (
  • Section {item.section + 1 + ""} for  {item.duration.minutes}M {item.duration.seconds}S
  • ))}
, ]; } public render() { return ( Programs # Name Running? Enabled? { Array.prototype.concat.apply([], this.props.programs.map(ProgramTable.renderRow)) }
); } } const ConnectionState = ({connected}: { connected: boolean }) =>   {connected ? "Connected" : "Disconnected"} ; @observer class DeviceView extends React.PureComponent<{ device: SprinklersDevice }, void> { public render() { const {id, connected, sections, programs} = this.props.device; return ( ("app/images/raspberry_pi.png")}/>
Device {id}
); } } @observer class MessagesView extends React.PureComponent<{uiStore: UiStore}, void> { public render() { return
{this.props.uiStore.messages.map(this.renderMessage)}
; } private renderMessage = (message: UiMessage, index: number) => { const {header, content, type} = message; return this.dismiss(index)}/>; } private dismiss(index: number) { this.props.uiStore.messages.splice(index, 1); } } @observer export default class App extends React.PureComponent<{ device: SprinklersDevice, uiStore: UiStore }, any> { public render() { return ; } }