refactor sequence steps

pull/582/head
gabrielburnworth 2017-12-15 15:09:24 -08:00
parent 6593605d98
commit 2275c66bc3
21 changed files with 561 additions and 607 deletions

View File

@ -32,7 +32,7 @@ export function StepDragger({ dispatch,
children,
intent,
draggerId }: StepDraggerProps) {
return <div draggable={true}
return <div
onDragStart={stepDragEventHandler(dispatch,
step,
intent,

View File

@ -26,7 +26,7 @@ export function StepButton({ children, step, color, dispatch, current }:
step={step}
intent="step_splice"
draggerId={NULL_DRAGGER_ID} >
<button
<button draggable={true}
className={`fb-button full-width block ${color}`}
onClick={stepClick(dispatch, step, current)} >
{children}

View File

@ -1,6 +1,5 @@
import * as _ from "lodash";
import * as React from "react";
import { splice, remove } from "../step_tiles/index";
import { StepParams } from "../interfaces";
import { t } from "i18next";
import { DropDownItem, Row, Col } from "../../ui";
@ -10,9 +9,8 @@ import { TaggedSequence } from "../../resources/tagged_resources";
import { ResourceIndex } from "../../resources/interfaces";
import { editStep } from "../../api/crud";
import { FBSelect } from "../../ui/new_fb_select";
import { StepIconGroup } from "../step_icon_group";
import { StepTitleBar } from "./step_title_bar";
import { ToolTips } from "../../constants";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
export function ExecuteBlock(p: StepParams) {
if (p.currentStep.kind === "execute") {
@ -84,44 +82,23 @@ export class RefactoredExecuteBlock extends React.Component<ExecBlockParams, {}>
render() {
const props = this.props;
const { dispatch, currentStep, index, currentSequence } = props;
return (<div>
<div className="step-wrapper">
const className = "execute-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.EXECUTE_SEQUENCE}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col sm={12}>
<div className="step-header execute-step">
<StepTitleBar
step={currentStep}
index={index}
dispatch={dispatch}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
index,
step: currentStep,
sequence: currentSequence
}))}
onTrash={() => remove({
dispatch,
index,
sequence: currentSequence
})}
helpText={t(ToolTips.EXECUTE_SEQUENCE)} />
</div>
<Col xs={12}>
<label>{t("Sequence")}</label>
<this.SequenceSelectBox />
</Col>
</Row>
<Row>
<Col sm={12}>
<div className="step-content execute-step">
<Row>
<Col sm={12}>
<label>{t("Sequence")}</label>
<this.SequenceSelectBox />
</Col>
</Row>
</div>
</Col>
</Row>
</div>
</div>);
</StepContent>
</StepWrapper>;
}
}

View File

@ -1,53 +1,36 @@
import * as React from "react";
import { StepParams } from "../interfaces";
import { StepTitleBar } from "./step_title_bar";
import { splice, remove } from "./index";
import { t } from "i18next";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { StepInputBox } from "../inputs/step_input_box";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
import { Row, Col } from "../../ui/index";
export function TileExecuteScript({ dispatch, currentStep, index, currentSequence }: StepParams) {
export function TileExecuteScript({
dispatch, currentStep, index, currentSequence }: StepParams) {
if (currentStep.kind === "execute_script") {
return (<div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header execute-script-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.EXECUTE_SCRIPT)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content execute-script-step">
<div className="row">
<div className="col-xs-12">
<label>{t("Package Name")}</label>
<StepInputBox dispatch={dispatch}
index={index}
step={currentStep}
sequence={currentSequence}
field="label" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>);
const className = "execute-script-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.EXECUTE_SCRIPT}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={12}>
<label>{t("Package Name")}</label>
<StepInputBox dispatch={dispatch}
index={index}
step={currentStep}
sequence={currentSequence}
field="label" />
</Col>
</Row>
</StepContent>
</StepWrapper>;
} else {
return <p> ERROR </p>;
}

View File

@ -1,7 +1,4 @@
import * as React from "react";
import { t } from "i18next";
import { splice, remove } from "./index";
import { StepTitleBar } from "./step_title_bar";
import { FindHome, ALLOWED_AXIS } from "farmbot";
import { StepParams } from "../interfaces";
import { TaggedSequence } from "../../resources/tagged_resources";
@ -9,7 +6,8 @@ import { ResourceIndex } from "../../resources/interfaces";
import { overwrite } from "../../api/crud";
import { defensiveClone } from "../../util";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
import { Row, Col } from "../../ui/index";
export function TileFindHome(props: StepParams) {
if (props.currentStep.kind === "find_home") {
@ -50,58 +48,42 @@ class InnerFindHome extends React.Component<FindHomeParams, {}> {
render() {
const { dispatch, index, currentStep, currentSequence } = this.props;
return <div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header find-home-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
onClone={() => dispatch(splice({
step: currentStep,
sequence: currentSequence,
index
}))}
helpText={t(ToolTips.FIND_HOME)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content find-home-step">
<div className="row">
<div className="col-xs-12">
<div className="bottom-content">
<div className="channel-fields">
<form>
{AXIS_CHOICES.map((axis, i) => {
return <div key={i} style={{ display: "inline" }}>
<label>
<input type="radio"
value={axis}
onChange={(e) => {
const nextVal =
e.currentTarget.value as typeof axis;
this.handleUpdate(nextVal);
}}
checked={this.isSelected(axis)} />
{" "} Find {axis}
</label>
</div>;
})}
</form>
</div>
</div>
</div>
const className = "find-home-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.FIND_HOME}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={12}>
<div className="bottom-content">
<div className="channel-fields">
<form>
{AXIS_CHOICES.map((axis, i) => {
return <div key={i} style={{ display: "inline" }}>
<label>
<input type="radio"
value={axis}
onChange={(e) => {
const nextVal =
e.currentTarget.value as typeof axis;
this.handleUpdate(nextVal);
}}
checked={this.isSelected(axis)} />
{" "} Find {axis}
</label>
</div>;
})}
</form>
</div>
</div>
</div>
</div>
</div>
</div>;
</Col>
</Row>
</StepContent>
</StepWrapper>;
}
}

View File

@ -2,14 +2,15 @@ import * as React from "react";
import { IfParams, seqDropDown, IfBlockDropDownHandler } from "./index";
import { t } from "i18next";
import { FBSelect } from "../../../ui/new_fb_select";
import { Row, Col } from "../../../ui/index";
export function Else(props: IfParams) {
const { onChange, selectedItem } = IfBlockDropDownHandler(props, "_else");
return <div>
<div className="col-xs-12 col-md-12">
return <Row>
<Col xs={12} md={12}>
<h4>{t("ELSE...")}</h4>
</div>
<div className="col-xs-12 col-md-12">
</Col>
<Col xs={12} md={12}>
<label>{t("Execute Sequence")}</label>
<FBSelect
allowEmpty={true}
@ -17,6 +18,6 @@ export function Else(props: IfParams) {
placeholder="Sequence..."
onChange={onChange}
selectedItem={selectedItem()} />
</div>
</div>;
</Col>
</Row>;
}

View File

@ -7,7 +7,7 @@ import { FBSelect, NULL_CHOICE } from "../../../ui/new_fb_select";
import { DropDownItem } from "../../../ui/fb_select";
import { defensiveClone } from "../../../util";
import { overwrite } from "../../../api/crud";
import { Col } from "../../../ui/index";
import { Col, Row } from "../../../ui/index";
import { ALLOWED_OPS } from "farmbot/dist";
const IS_UNDEFINED: ALLOWED_OPS = "is_undefined";
@ -40,7 +40,7 @@ export function If_(props: IfParams) {
};
}
return <div>
return <Row>
<Col xs={12}>
<h4 className="top">IF...</h4>
</Col>
@ -68,5 +68,5 @@ export function If_(props: IfParams) {
index={index}
field="rhs" />
</Col>
</div>;
</Row>;
}

View File

@ -6,8 +6,7 @@ import { TaggedSequence } from "../../../resources/tagged_resources";
import { If, Execute, Nothing } from "farmbot/dist";
import { ResourceIndex } from "../../../resources/interfaces";
import { selectAllSequences, findSequenceById } from "../../../resources/selectors";
import { splice, remove, isRecursive } from "../index";
import { StepTitleBar } from "../step_title_bar";
import { isRecursive } from "../index";
import { If_ } from "./if";
import { Then } from "./then";
import { Else } from "./else";
@ -16,7 +15,7 @@ import { overwrite } from "../../../api/crud";
import { NULL_CHOICE } from "../../../ui/fb_select";
import { range } from "lodash";
import { ToolTips } from "../../../constants";
import { StepIconGroup } from "../../step_icon_group";
import { StepWrapper, StepHeader, StepContent } from "../../step_ui/index";
export interface IfParams {
currentSequence: TaggedSequence;
@ -82,43 +81,29 @@ export function InnerIf(props: IfParams) {
currentStep,
currentSequence
} = props;
const stuff = { dispatch, step: currentStep, sequence: currentSequence, index };
const recursive = isRecursive(currentStep, currentSequence);
return <div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header if-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice(stuff))}
onTrash={() => remove(stuff)}
helpText={t(ToolTips.IF)} />
{recursive && (
<span>
<i className="fa fa-exclamation-triangle"></i>
&nbsp;{t("Recursive condition.")}
</span>
)}
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content if-step">
<div className="row">
<If_ {...props} />
<Then {...props} />
<Else {...props} />
</div>
</div>
</div>
</div>
</div>
</div>;
const className = "if-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.IF}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index}>
{recursive && (
<span>
<i className="fa fa-exclamation-triangle"></i>
&nbsp;{t("Recursive condition.")}
</span>
)}
</StepHeader>
<StepContent className={className}>
<If_ {...props} />
<Then {...props} />
<Else {...props} />
</StepContent>
</StepWrapper>;
}
/** Creates a function that can be used in the `onChange` event of a _else or

View File

@ -2,14 +2,15 @@ import * as React from "react";
import { IfParams, seqDropDown, IfBlockDropDownHandler } from "./index";
import { t } from "i18next";
import { FBSelect } from "../../../ui/new_fb_select";
import { Row, Col } from "../../../ui/index";
export function Then(props: IfParams) {
const { onChange, selectedItem } = IfBlockDropDownHandler(props, "_then");
return <div>
<div className="col-xs-12 col-md-12">
return <Row>
<Col xs={12} md={12}>
<h4>{t("THEN...")}</h4>
</div>
<div className="col-xs-12 col-md-12">
</Col>
<Col xs={12} md={12}>
<label>{t("Execute Sequence")}</label>
<FBSelect
allowEmpty={true}
@ -17,6 +18,6 @@ export function Then(props: IfParams) {
placeholder="Sequence..."
onChange={onChange}
selectedItem={selectedItem()} />
</div>
</div>;
</Col>
</Row>;
}

View File

@ -1,8 +1,8 @@
import * as _ from "lodash";
import * as React from "react";
import { t } from "i18next";
import { Component } from "react";
import { StepParams } from "../interfaces";
import { splice, remove } from "./index";
import { MoveAbsState } from "../interfaces";
import {
Tool,
@ -16,8 +16,6 @@ import {
Row,
Col
} from "../../ui";
import { t } from "i18next";
import { StepTitleBar } from "./step_title_bar";
import {
isTaggedSequence,
TaggedTool,
@ -34,8 +32,8 @@ import { Xyz } from "../../devices/interfaces";
import { TileMoveAbsSelect } from "./tile_move_absolute/select";
import { InputBox } from "./tile_move_absolute/input_box";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { extractParent } from "../locals_list";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
interface Args {
location: Tool | Coordinate | Point | Identifier;
@ -129,63 +127,53 @@ export class TileMoveAbsolute extends Component<StepParams, MoveAbsState> {
throw new Error("WHOOPS!");
}
return <div className="step-wrapper">
<Row>
<Col sm={12}>
<div className="step-header move-absolute-step">
<StepTitleBar index={index} dispatch={dispatch} step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.MOVE_ABSOLUTE)} />
</div>
</Col>
</Row>
<Row>
<Col sm={12}>
<div className="step-content move-absolute-step">
<Row>
<Col md={12}>
<label>{t("Import coordinates from")}</label>
<TileMoveAbsSelect
resources={this.resources}
selectedItem={this.args.location}
onChange={(location) => this.updateArgs({ location })} />
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("x", "location")}
disabled={this.xyzDisabled}
name="location-x"
value={this.getAxisValue("x")}>
{t("X (mm)")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("y", "location")}
disabled={this.xyzDisabled}
name="location-y"
value={this.getAxisValue("y")}>
{t("Y (mm)")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("z", "location")}
name="location-z"
disabled={this.xyzDisabled}
value={this.getAxisValue("z")}>
{t("Z (mm)")}
</InputBox>
</Col>
<Col xs={3}>
{/*<label>
const className = "move-absolute-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.MOVE_ABSOLUTE}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col md={12}>
<label>{t("Import coordinates from")}</label>
<TileMoveAbsSelect
resources={this.resources}
selectedItem={this.args.location}
onChange={(location) => this.updateArgs({ location })} />
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("x", "location")}
disabled={this.xyzDisabled}
name="location-x"
value={this.getAxisValue("x")}>
{t("X (mm)")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("y", "location")}
disabled={this.xyzDisabled}
name="location-y"
value={this.getAxisValue("y")}>
{t("Y (mm)")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("z", "location")}
name="location-z"
disabled={this.xyzDisabled}
value={this.getAxisValue("z")}>
{t("Z (mm)")}
</InputBox>
</Col>
<Col xs={3}>
{/*<label>
{t("Speed (%)")}
</label>
<StepInputBox
@ -194,37 +182,35 @@ export class TileMoveAbsolute extends Component<StepParams, MoveAbsState> {
index={index}
dispatch={this.props.dispatch}
sequence={this.props.currentSequence} />*/}
</Col>
</Row>
<Row>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("x", "offset")}
name="offset-x"
value={this.getOffsetValue("x")}>
{t("X-Offset")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("y", "offset")}
name="offset-y"
value={this.getOffsetValue("y")}>
{t("Y-Offset")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("z", "offset")}
name="offset-z"
value={this.getOffsetValue("z")}>
{t("Z-Offset")}
</InputBox>
</Col>
</Row>
</div>
</Col>
</Row>
</div>;
</Col>
</Row>
<Row>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("x", "offset")}
name="offset-x"
value={this.getOffsetValue("x")}>
{t("X-Offset")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("y", "offset")}
name="offset-y"
value={this.getOffsetValue("y")}>
{t("Y-Offset")}
</InputBox>
</Col>
<Col xs={3}>
<InputBox
onCommit={this.updateInputValue("z", "offset")}
name="offset-z"
value={this.getOffsetValue("z")}>
{t("Z-Offset")}
</InputBox>
</Col>
</Row>
</StepContent>
</StepWrapper>;
}
}

View File

@ -1,73 +1,57 @@
import * as React from "react";
import { StepTitleBar } from "./step_title_bar";
import { splice, remove } from "./index";
import { t } from "i18next";
import { StepInputBox } from "../inputs/step_input_box";
import { StepParams } from "../interfaces";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
import { Row, Col } from "../../ui/index";
export function TileMoveRelative({ dispatch, currentStep, index, currentSequence }: StepParams) {
return <div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header move-relative-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.MOVE_RELATIVE)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content move-relative-step">
<div className="row">
<div className="col-xs-6 col-md-3">
<label>{t("X (mm)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="x" />
</div>
<div className="col-xs-6 col-md-3">
<label>{t("Y (mm)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="y" />
</div>
<div className="col-xs-6 col-md-3">
<label>{t("Z (mm)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="z" />
</div>
<div className="col-xs-6 col-md-3">
{/* <label>{t("Speed (%)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="speed" /> */}
</div>
</div>
</div>
</div>
</div>
</div>
</div>;
export function TileMoveRelative({
dispatch, currentStep, index, currentSequence }: StepParams) {
const className = "move-relative-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.MOVE_RELATIVE}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={6} md={3}>
<label>{t("X (mm)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="x" />
</Col>
<Col xs={6} md={3}>
<label>{t("Y (mm)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="y" />
</Col>
<Col xs={6} md={3}>
<label>{t("Z (mm)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="z" />
</Col>
<Col xs={6} md={3}>
{/* <label>{t("Speed (%)")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="speed" /> */}
</Col>
</Row>
</StepContent>
</StepWrapper>;
}

View File

@ -1,67 +1,50 @@
import * as React from "react";
import { StepTitleBar } from "./step_title_bar";
import { splice, remove } from "./index";
import { t } from "i18next";
import { StepInputBox } from "../inputs/step_input_box";
import { StepParams } from "../interfaces";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { FBSelect } from "../../ui/new_fb_select";
import { setPinMode, PIN_MODES, currentModeSelection } from "./tile_pin_support";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
import { Row, Col } from "../../ui/index";
export function TileReadPin(props: StepParams) {
const { dispatch, currentStep, index, currentSequence } = props;
return <div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header read-pin-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.READ_PIN)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content read-pin-step">
<div className="row">
<div className="col-xs-6 col-md-3">
<label>{t("Pin Number")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="pin_number" />
</div>
<div className="col-xs-6 col-md-3">
<label>{t("Data Label")}</label>
<StepInputBox dispatch={dispatch}
index={index}
step={currentStep}
sequence={currentSequence}
field="label" />
</div>
<div className="col-xs-6 col-md-3">
<label>{t("Pin Mode")}</label>
<FBSelect
onChange={(x) => setPinMode(x, props)}
selectedItem={currentModeSelection(currentStep)}
list={PIN_MODES} />
</div>
</div>
</div>
</div>
</div>
</div>
</div>;
const className = "read-pin-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.READ_PIN}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={6} md={3}>
<label>{t("Pin Number")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="pin_number" />
</Col>
<Col xs={6} md={3}>
<label>{t("Data Label")}</label>
<StepInputBox dispatch={dispatch}
index={index}
step={currentStep}
sequence={currentSequence}
field="label" />
</Col>
<Col xs={6} md={3}>
<label>{t("Pin Mode")}</label>
<FBSelect
onChange={(x) => setPinMode(x, props)}
selectedItem={currentModeSelection(currentStep)}
list={PIN_MODES} />
</Col>
</Row>
</StepContent>
</StepWrapper>;
}

View File

@ -1,6 +1,4 @@
import * as React from "react";
import { splice, remove } from "./index";
import { StepTitleBar } from "./step_title_bar";
import { DropDownItem, Row, Col } from "../../ui";
import { t } from "i18next";
import { StepInputBox } from "../inputs/step_input_box";
@ -18,7 +16,8 @@ import {
channel,
MESSAGE_STATUSES_DDI
} from "./tile_send_message_support";
import { StepIconGroup } from "../step_icon_group";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
type ChannelName = ALLOWED_CHANNEL_NAMES;
export function TileSendMessage(props: StepParams) {
if (props.currentStep.kind === "send_message") {
@ -95,72 +94,55 @@ class RefactoredSendMessage
render() {
const { dispatch, index, currentStep, currentSequence } = this.props;
const className = "send-message-step";
return <div>
<div className="step-wrapper">
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.SEND_MESSAGE}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col sm={12}>
<div className="step-header send-message-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
sequence: currentSequence,
index
}))}
onTrash={() => remove({
dispatch, index, sequence: currentSequence
})}
helpText={t(ToolTips.SEND_MESSAGE)} />
</div>
</Col>
</Row>
<Row>
<Col sm={12}>
<div className="step-content send-message-step">
<Row>
<Col xs={12}>
<label>{t("Message")}</label>
<span className="char-limit">
{this.message.length}/300
<Col xs={12}>
<label>{t("Message")}</label>
<span className="char-limit">
{this.message.length}/300
</span>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="message" />
<div className="bottom-content">
<div className="channel-options">
<FBSelect
onChange={this.setMsgType}
selectedItem={this.currentSelection}
list={MESSAGE_STATUSES} />
</div>
<div className="channel-fields">
<div>{EACH_CHANNEL.map((chan, inx) => {
return <fieldset key={inx}>
<label htmlFor={chan.name}>
{chan.label}
</label>
<input type="checkbox"
id={chan.name}
onChange={this.toggle(chan.name)}
checked={
this.hasChannel(chan.name) || chan.alwaysOn}
disabled={chan.alwaysOn} />
</fieldset>;
})}</div>
</div>
</div>
</Col>
</Row>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="message" />
<div className="bottom-content">
<div className="channel-options">
<FBSelect
onChange={this.setMsgType}
selectedItem={this.currentSelection}
list={MESSAGE_STATUSES} />
</div>
<div className="channel-fields">
<div>{EACH_CHANNEL.map((chan, inx) => {
return <fieldset key={inx}>
<label htmlFor={chan.name}>
{chan.label}
</label>
<input type="checkbox"
id={chan.name}
onChange={this.toggle(chan.name)}
checked={
this.hasChannel(chan.name) || chan.alwaysOn}
disabled={chan.alwaysOn} />
</fieldset>;
})}
</div>
</div>
</div>
</Col>
</Row>
</div>
</div>;
</StepContent>
</StepWrapper>;
}
}

View File

@ -1,48 +1,30 @@
import * as React from "react";
import { StepParams } from "../interfaces";
import { StepTitleBar } from "./step_title_bar";
import { splice, remove } from "./index";
import { t } from "i18next";
import { Link } from "react-router";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { StepWrapper, StepHeader, StepContent } from "../step_ui";
import { Col, Row } from "../../ui/index";
export function TileTakePhoto({ dispatch, currentStep, index, currentSequence }: StepParams) {
return (<div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header take-photo-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.TAKE_PHOTO)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content take-photo-step">
<div className="row">
<div className="col-xs-12">
<p>
Photos are viewable from the <Link to="/app/farmware">
farmware page</Link>.
export function TileTakePhoto({
dispatch, currentStep, index, currentSequence }: StepParams) {
const className = "take-photo-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.TAKE_PHOTO}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={12}>
<p>
Photos are viewable from the <Link to="/app/farmware">
farmware page</Link>.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>);
</Col>
</Row>
</StepContent>
</StepWrapper>;
}

View File

@ -1,50 +1,34 @@
import * as React from "react";
import { StepTitleBar } from "./step_title_bar";
import { splice, remove } from "./index";
import { t } from "i18next";
import { StepInputBox } from "../inputs/step_input_box";
import { StepParams } from "../interfaces";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
import { Row, Col } from "../../ui/index";
export function TileWait({ dispatch, currentStep, index, currentSequence }: StepParams) {
return (<div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header wait-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
sequence: currentSequence,
index
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.WAIT)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content wait-step">
<div className="row">
<div className="col-xs-6 col-md-3">
<label>{t("Time in milliseconds")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="milliseconds" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>);
export function TileWait({
dispatch, currentStep, index, currentSequence }: StepParams) {
const className = "wait-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.WAIT}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={6} md={3}>
<label>{t("Time in milliseconds")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="milliseconds" />
</Col>
</Row>
</StepContent>
</StepWrapper>;
}

View File

@ -1,16 +1,15 @@
import * as React from "react";
import { StepTitleBar } from "./step_title_bar";
import { splice, remove } from "./index";
import { t } from "i18next";
import { StepInputBox } from "../inputs/step_input_box";
import { StepParams } from "../interfaces";
import { ToolTips } from "../../constants";
import { StepIconGroup } from "../step_icon_group";
import { FBSelect } from "../../ui/new_fb_select";
import {
setPinMode, PIN_MODES, setPinValue, currentValueSelection,
PIN_VALUES, currentModeSelection
} from "./tile_pin_support";
import { StepWrapper, StepHeader, StepContent } from "../step_ui/index";
import { Row, Col } from "../../ui/index";
export function TileWritePin(props: StepParams) {
const { dispatch, currentStep, index, currentSequence } = props;
@ -30,53 +29,37 @@ export function TileWritePin(props: StepParams) {
}
}
};
return (<div>
<div className="step-wrapper">
<div className="row">
<div className="col-sm-12">
<div className="step-header write-pin-step">
<StepTitleBar index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() => remove({ dispatch, index, sequence: currentSequence })}
helpText={t(ToolTips.WRITE_PIN)} />
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="step-content write-pin-step">
<div className="row">
<div className="col-xs-6 col-md-3">
<label>{t("Pin Number")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="pin_number" />
</div>
<div className="col-xs-6 col-md-3">
<label>{t("Value")}</label>
{pinValueField()}
</div>
<div className="col-xs-6 col-md-3">
<label>{t("Pin Mode")}</label>
<FBSelect
onChange={(x) => setPinMode(x, props)}
selectedItem={currentModeSelection(currentStep)}
list={PIN_MODES} />
</div>
</div>
</div>
</div>
</div>
</div>
</div>);
const className = "write-pin-step";
return <StepWrapper>
<StepHeader
className={className}
helpText={ToolTips.WRITE_PIN}
currentSequence={currentSequence}
currentStep={currentStep}
dispatch={dispatch}
index={index} />
<StepContent className={className}>
<Row>
<Col xs={6} md={3}>
<label>{t("Pin Number")}</label>
<StepInputBox dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
index={index}
field="pin_number" />
</Col>
<Col xs={6} md={3}>
<label>{t("Value")}</label>
{pinValueField()}
</Col>
<Col xs={6} md={3}>
<label>{t("Pin Mode")}</label>
<FBSelect
onChange={(x) => setPinMode(x, props)}
selectedItem={currentModeSelection(currentStep)}
list={PIN_MODES} />
</Col>
</Row>
</StepContent>
</StepWrapper>;
}

View File

@ -0,0 +1,54 @@
import * as React from "react";
import { mount } from "enzyme";
import {
StepWrapper,
StepHeader,
StepContent,
StepHeaderProps
} from "../index";
import { fakeSequence } from "../../../__test_support__/fake_state/resources";
describe("<StepWrapper />", () => {
it("renders", () => {
const wrapper = mount(<StepWrapper />);
expect(wrapper.find("div").hasClass("step-wrapper")).toBeTruthy();
});
it("renders with extra className", () => {
const wrapper = mount(<StepWrapper className={"step-class"} />);
expect(wrapper.find("div").hasClass("step-class")).toBeTruthy();
});
});
describe("<StepHeader />", () => {
const fakeProps: StepHeaderProps = {
className: "step-class",
helpText: "help text",
currentSequence: fakeSequence(),
currentStep: { kind: "take_photo", args: {} },
dispatch: jest.fn(),
index: 0,
children: "child"
};
it("renders", () => {
const wrapper = mount(<StepHeader {...fakeProps} />);
const div = wrapper.find("div").last();
expect(div.hasClass("step-header")).toBeTruthy();
expect(div.hasClass("step-class")).toBeTruthy();
});
it("renders with children", () => {
const wrapper = mount(<StepHeader {...fakeProps} />);
expect(wrapper.text()).toContain("child");
});
});
describe("<StepContent />", () => {
it("renders", () => {
const wrapper = mount(<StepContent className={"step-class"} />);
const div = wrapper.find("div").last();
expect(div.hasClass("step-content")).toBeTruthy();
expect(div.hasClass("step-class")).toBeTruthy();
});
});

View File

@ -0,0 +1,3 @@
export * from "./step_wrapper";
export * from "./step_header";
export * from "./step_content";

View File

@ -0,0 +1,19 @@
import * as React from "react";
import { JSXChildren } from "../../util";
import { Row, Col } from "../../ui/index";
interface StepContentProps {
children?: JSXChildren;
className: string;
}
export function StepContent(props: StepContentProps) {
const { className } = props;
return <Row>
<Col sm={12}>
<div className={`step-content ${className}`}>
{props.children}
</div>
</Col>
</Row>;
}

View File

@ -0,0 +1,51 @@
import * as React from "react";
import { t } from "i18next";
import { JSXChildren } from "../../util";
import { Row, Col } from "../../ui/index";
import { TaggedSequence } from "../../resources/tagged_resources";
import { SequenceBodyItem } from "farmbot";
import { StepTitleBar } from "../step_tiles/step_title_bar";
import { StepIconGroup } from "../step_icon_group";
import { splice, remove } from "../step_tiles/index";
export interface StepHeaderProps {
children?: JSXChildren;
className: string;
helpText: string;
currentSequence: TaggedSequence;
currentStep: SequenceBodyItem;
dispatch: Function;
index: number;
}
export function StepHeader(props: StepHeaderProps) {
const {
className,
helpText,
currentSequence,
currentStep,
dispatch,
index
} = props;
return <Row>
<Col sm={12}>
<div className={`step-header ${className}`} draggable={true}>
<StepTitleBar
index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() =>
remove({ dispatch, index, sequence: currentSequence })}
helpText={t(helpText)} />
{props.children}
</div>
</Col>
</Row>;
}

View File

@ -0,0 +1,14 @@
import * as React from "react";
import { JSXChildren } from "../../util";
interface StepWrapperProps {
children?: JSXChildren;
className?: string;
}
export function StepWrapper(props: StepWrapperProps) {
const { className } = props;
return <div className={`step-wrapper ${className ? className : ""}`}>
{props.children}
</div>;
}