diff --git a/app/script/components/App.tsx b/app/script/components/App.tsx
index 75b70d6..4cf5524 100644
--- a/app/script/components/App.tsx
+++ b/app/script/components/App.tsx
@@ -1,22 +1,25 @@
-import "app/style/app.css";
-import "font-awesome/css/font-awesome.css";
-import {observer} from "mobx-react";
+import { observer } from "mobx-react";
import DevTools from "mobx-react-devtools";
import * as React from "react";
+import { Item } from "semantic-ui-react";
+import { DeviceView, MessagesView } from ".";
+import { SprinklersDevice } from "../sprinklers";
+import { UiStore } from "../ui";
+
+import "app/style/app.css";
+import "font-awesome/css/font-awesome.css";
import "semantic-ui-css/semantic.css";
-import {Item} from "semantic-ui-react";
-import {DeviceView, MessagesView} from ".";
-import {SprinklersDevice} from "../sprinklers";
-import {UiStore} from "../ui";
@observer
-export default class App extends React.PureComponent<{ device: SprinklersDevice, uiStore: UiStore }, any> {
+export default class App extends React.Component<{ device: SprinklersDevice, uiStore: UiStore }> {
render() {
- return
-
-
-
- ;
+ return (
+
+
+
+
+
+ );
}
}
diff --git a/app/script/components/DeviceView.tsx b/app/script/components/DeviceView.tsx
index 2671709..cf6caa6 100644
--- a/app/script/components/DeviceView.tsx
+++ b/app/script/components/DeviceView.tsx
@@ -7,19 +7,22 @@ import { ProgramTable, RunSectionForm, SectionRunnerView, SectionTable } from ".
import { SprinklersDevice } from "../sprinklers";
import FontAwesome = require("react-fontawesome");
-const ConnectionState = ({ connected }: { connected: boolean }) =>
- {
+ const classes = classNames({
"device--connectionState": true,
"device--connectionState-connected": connected,
"device--connectionState-disconnected": !connected,
- })}>
-
-
- {connected ? "Connected" : "Disconnected"}
- ;
+ });
+ return (
+
+
+ {connected ? "Connected" : "Disconnected"}
+
+ );
+};
@observer
-export default class DeviceView extends React.PureComponent<{ device: SprinklersDevice }, {}> {
+export default class DeviceView extends React.Component<{ device: SprinklersDevice }> {
render() {
const { id, connected, sections, programs, sectionRunner } = this.props.device;
return (
@@ -31,7 +34,7 @@ export default class DeviceView extends React.PureComponent<{ device: Sprinklers
-
+ Raspberry Pi Grinklers Instance
diff --git a/app/script/components/MessagesView.tsx b/app/script/components/MessagesView.tsx
index 3cd0c56..84e2c4f 100644
--- a/app/script/components/MessagesView.tsx
+++ b/app/script/components/MessagesView.tsx
@@ -1,30 +1,47 @@
-import {observer} from "mobx-react";
+import { observer } from "mobx-react";
import * as React from "react";
-import {CSSTransitionGroup} from "react-transition-group";
-import {Message} from "semantic-ui-react";
-import {Message as UiMessage, UiStore} from "../ui";
+import { Message, MessageList, TransitionGroup } from "semantic-ui-react";
+import { Message as UiMessage, UiStore } from "../ui";
+
+class MessageView extends React.Component<{
+ uiStore: UiStore,
+ message: UiMessage,
+ index: number,
+}> {
-@observer
-export default class MessagesView extends React.PureComponent<{ uiStore: UiStore }, {}> {
render() {
- return
-
- {this.props.uiStore.messages.map(this.renderMessage)}
-
-
;
+ const { id, header, content, type } = this.props.message;
+ return (
+
+ );
}
- private renderMessage = (message: UiMessage, index: number) => {
- const {header, content, type} = message;
- return this.dismiss(index)}/>;
+ private dismiss = () => {
+ const { uiStore, index } = this.props;
+ uiStore.messages.splice(index, 1);
}
+}
- private dismiss(index: number) {
- this.props.uiStore.messages.splice(index, 1);
+@observer
+export default class MessagesView extends React.Component<{ uiStore: UiStore }> {
+ render() {
+ const messages = this.props.uiStore.messages.map((message, index) => (
+
+ ));
+ return (
+
+
+ {messages}
+
+
+ );
}
}
diff --git a/app/script/components/ProgramTable.tsx b/app/script/components/ProgramTable.tsx
index 2f867d9..604f507 100644
--- a/app/script/components/ProgramTable.tsx
+++ b/app/script/components/ProgramTable.tsx
@@ -1,10 +1,10 @@
-import {observer} from "mobx-react";
+import { observer } from "mobx-react";
import * as React from "react";
-import {Table} from "semantic-ui-react";
-import {Program, Schedule} from "../sprinklers";
+import { Table } from "semantic-ui-react";
+import { Program, Schedule } from "../sprinklers";
@observer
-export class ScheduleView extends React.PureComponent<{ schedule: Schedule }, {}> {
+export class ScheduleView extends React.Component<{ schedule: Schedule }> {
render() {
return (
{JSON.stringify(this.props.schedule)}
@@ -13,35 +13,39 @@ export class ScheduleView extends React.PureComponent<{ schedule: Schedule }, {}
}
@observer
-export default class ProgramTable extends React.PureComponent<{ programs: Program[] }, {}> {
+export default class ProgramTable extends React.Component<{ programs: Program[] }> {
private static renderRows(program: Program, i: number): JSX.Element[] | null {
if (!program) {
return null;
}
- const {name, running, enabled, schedule, sequence} = program;
- return [
+ const { name, running, enabled, schedule, sequence } = program;
+ const sequenceItems = sequence.map((item, index) => (
+ Section {item.section + 1 + ""} for
+ {item.duration.minutes}M {item.duration.seconds}S
+ ));
+ 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
))}
+ {sequenceItems}
-
+
- ,
- ];
+ )];
}
render() {
+ const programRows = Array.prototype.concat.apply([],
+ this.props.programs.map(ProgramTable.renderRows));
+
return (
@@ -56,9 +60,7 @@ export default class ProgramTable extends React.PureComponent<{ programs: Progra
- {
- Array.prototype.concat.apply([], this.props.programs.map(ProgramTable.renderRows))
- }
+ {programRows}
);
diff --git a/app/script/components/SectionTable.tsx b/app/script/components/SectionTable.tsx
index 37ccefa..1c6a00a 100644
--- a/app/script/components/SectionTable.tsx
+++ b/app/script/components/SectionTable.tsx
@@ -1,38 +1,41 @@
import * as classNames from "classnames";
-import {observer} from "mobx-react";
+import { observer } from "mobx-react";
import * as React from "react";
-import {Table} from "semantic-ui-react";
+import { Table } from "semantic-ui-react";
-import {Section} from "../sprinklers";
+import { Section } from "../sprinklers";
import FontAwesome = require("react-fontawesome");
/* tslint:disable:object-literal-sort-keys */
@observer
-export default class SectionTable extends React.PureComponent<{ sections: Section[] }, {}> {
+export default class SectionTable extends React.Component<{ sections: Section[] }> {
private static renderRow(section: Section, index: number) {
if (!section) {
return null;
}
- const {name, state} = section;
+ const { name, state } = section;
+ const sectionStateClass = classNames({
+ "section--state": true,
+ "section--state-true": state,
+ "section--state-false": !state,
+ });
+ const sectionState = state ?
+ ( Irrigating)
+ : "Not irrigating";
return (
{"" + (index + 1)}
{name}
- {state ?
- ( Irrigating)
- : "Not irrigating"}
-
+ {sectionState}
);
}
render() {
- return (
+ const rows = this.props.sections.map(SectionTable.renderRow);
+ return (
+
Sections
@@ -44,9 +47,7 @@ export default class SectionTable extends React.PureComponent<{ sections: Sectio
- {
- this.props.sections.map(SectionTable.renderRow)
- }
+ {rows}
);
diff --git a/app/script/index.tsx b/app/script/index.tsx
index e8607c5..9317fbb 100644
--- a/app/script/index.tsx
+++ b/app/script/index.tsx
@@ -14,15 +14,19 @@ uiStore.addMessage(new Message("asdf", "boo!", Message.Type.Error));
const rootElem = document.getElementById("app");
-ReactDOM.render(
-
-, rootElem);
+const doRender = (Component: typeof App) => {
+ ReactDOM.render((
+
+
+
+ ), rootElem);
+};
+
+doRender(App);
if (module.hot) {
module.hot.accept("./components/App", () => {
const NextApp = require("./components/App").default as typeof App;
- ReactDOM.render(
-
- , rootElem);
+ doRender(NextApp);
});
}
diff --git a/app/script/ui.ts b/app/script/ui.ts
index ae92de0..33ec45e 100644
--- a/app/script/ui.ts
+++ b/app/script/ui.ts
@@ -1,4 +1,5 @@
import {observable} from "mobx";
+import { getRandomId } from "./utils";
export class Message {
id: string;
@@ -7,7 +8,7 @@ export class Message {
type: Message.Type = Message.Type.Default;
constructor(header: string, content: string = "", type: Message.Type = Message.Type.Default) {
- this.id = "" + Math.floor(Math.random() * 1000000000);
+ this.id = "" + getRandomId();
this.header = header;
this.content = content;
this.type = type;
diff --git a/app/script/utils.ts b/app/script/utils.ts
index 6435fa8..5bbeb65 100644
--- a/app/script/utils.ts
+++ b/app/script/utils.ts
@@ -7,3 +7,7 @@ export function checkedIndexOf(o: T | number, arr: T[], type: string = "objec
}
return idx;
}
+
+export function getRandomId() {
+ return Math.floor(Math.random() * 1000000000);
+}
diff --git a/app/style/app.css b/app/style/app.css
index 0686b64..fafee8b 100644
--- a/app/style/app.css
+++ b/app/style/app.css
@@ -46,31 +46,4 @@
left: 12px;
right: 12px;
z-index: 1000;
-}
-
-.message-enter,
-.message-appear {
- opacity: 0.01;
-}
-
-.message-enter.message-enter-active,
-.message-appear.message-appear-active {
- opacity: 1;
- transition: all 500ms ease-in;
-}
-
-.message-leave {
- /*opacity: 1;*/
- transform-origin: top;
- overflow-y: hidden;
-}
-
-.message-leave.message-leave-active {
- /*opacity: 0.01;*/
- transform: scaleY(0.01);
- /*height: 0;*/
- margin-top: 0;
- padding-top: 0;
- padding-bottom: 0;
- transition: all 500ms ease-in;
}
\ No newline at end of file
diff --git a/package.json b/package.json
index cd833bb..feb9fa8 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,7 @@
"style-loader": "^0.18.1",
"ts-loader": "^2.1.0",
"tslint": "^5.4.2",
+ "tslint-react": "^3.2.0",
"typescript": "^2.3.4",
"webpack": "^3.0.0",
"webpack-dev-server": "^2.4.4"
diff --git a/tslint.json b/tslint.json
index 1c0575b..389bdbf 100644
--- a/tslint.json
+++ b/tslint.json
@@ -1,7 +1,7 @@
{
- "defaultSeverity": "error",
+ "defaultSeverity": "warning",
"extends": [
- "tslint:latest"
+ "tslint:latest", "tslint-react"
],
"jsRules": {},
"rules": {
@@ -33,7 +33,8 @@
"no-submodule-imports": false,
"no-unused-variable": [
true
- ]
+ ],
+ "jsx-boolean-value": [ true, "never" ]
},
"rulesDirectory": []
}
diff --git a/yarn.lock b/yarn.lock
index 0333983..5d7eabb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4248,6 +4248,12 @@ tslib@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.1.tgz#bc8004164691923a79fe8378bbeb3da2017538ec"
+tslint-react@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-3.2.0.tgz#851fb505201c63d0343c51726e6364f7e9ad2e99"
+ dependencies:
+ tsutils "^2.8.0"
+
tslint@^5.4.2:
version "5.7.0"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.7.0.tgz#c25e0d0c92fa1201c2bc30e844e08e682b4f3552"
@@ -4263,6 +4269,12 @@ tslint@^5.4.2:
tslib "^1.7.1"
tsutils "^2.8.1"
+tsutils@^2.8.0:
+ version "2.8.2"
+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.8.2.tgz#2c1486ba431260845b0ac6f902afd9d708a8ea6a"
+ dependencies:
+ tslib "^1.7.1"
+
tsutils@^2.8.1:
version "2.8.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.8.1.tgz#3771404e7ca9f0bedf5d919a47a4b1890a68efff"