This commit is contained in:
gabrielburnworth 2018-05-15 16:05:35 -07:00
parent e1949ad5de
commit 668e530458
23 changed files with 90 additions and 55 deletions

View file

@ -10,13 +10,13 @@
// As of right now, all the menus appear from floated icons in the widgets. // As of right now, all the menus appear from floated icons in the widgets.
.widget-header { .widget-header {
.pt-popover-target { .pt-popover-wrapper {
float: right; float: right;
} }
} }
.device-widget { .device-widget {
.pt-popover-target { .pt-popover-wrapper {
width: 100%; width: 100%;
} }
.pt-icon-standard { .pt-icon-standard {
@ -74,10 +74,11 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
display: inline-block; display: inline-block;
padding-right: 1rem;
} }
} }
.pt-popover-target { .pt-popover-wrapper {
position: relative; position: relative;
display: block; display: block;
* { * {
@ -92,7 +93,7 @@
font-size: 1.6rem !important; font-size: 1.6rem !important;
} }
.nav-right .pt-popover-target { .nav-right .pt-popover-wrapper {
transition: all 0.2s ease; transition: all 0.2s ease;
text-transform: uppercase; text-transform: uppercase;
color: $gray; color: $gray;

View file

@ -340,7 +340,7 @@
} }
.caret-menu-button { .caret-menu-button {
display: inline; display: inline;
margin-left: 0.5rem; margin-left: 0.25rem;
font-weight: bold; font-weight: bold;
font-size: medium; font-size: medium;
cursor: pointer; cursor: pointer;

View file

@ -8,6 +8,13 @@ body {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.color-picker-col {
padding: 0;
.pt-popover-target {
float: left;
}
}
.colorpicker-menu { .colorpicker-menu {
padding: 0; padding: 0;
.pt-popover-arrow-fill { .pt-popover-arrow-fill {
@ -574,6 +581,14 @@ ul {
margin-top: 10%; margin-top: 10%;
} }
.farmware-selection-panel {
.filter-search {
i {
top: 38% !important;
}
}
}
.logs { .logs {
.row { .row {
@media screen and (max-width: 974px) { @media screen and (max-width: 974px) {
@ -586,6 +601,9 @@ ul {
margin-left: 1rem; margin-left: 1rem;
margin-top: 0.25rem; margin-top: 0.25rem;
} }
.pt-popover-target {
float: right;
}
} }
.logs-settings-menu { .logs-settings-menu {
@ -596,9 +614,10 @@ ul {
float: left; float: left;
margin-right: 10px; margin-right: 10px;
} }
.pt-popover-target { .pt-popover-wrapper {
display: inline; display: inline-block;
margin-left: 1rem; margin-left: 1rem;
margin-top: 0.5rem;
} }
} }
@ -670,6 +689,11 @@ ul {
.fb-button { .fb-button {
margin-top: 1rem; margin-top: 1rem;
} }
.filter-search {
i {
top: 38% !important;
}
}
} }
.sensors-widget { .sensors-widget {

View file

@ -51,6 +51,15 @@ select {
} }
.filter-search { .filter-search {
span {
width: 100%;
}
i {
position: absolute;
right: 0.65rem;
top: 30%;
color: $dark_gray
}
&.dim { &.dim {
Button { Button {
background: darken($white, 2%) !important; background: darken($white, 2%) !important;

View file

@ -113,11 +113,11 @@ nav {
} }
} }
} }
.pt-tether-target-attached-bottom.pt-overlay-content { .pt-overlay-content {
margin-top: 1.6rem; margin-top: 1.6rem;
color: $white; color: $white;
} }
.pt-popover-target { .pt-popover-wrapper {
a { a {
color: $white; color: $white;
} }

View file

@ -32,7 +32,7 @@
padding: .75rem 1rem; padding: .75rem 1rem;
border-top-left-radius: 3px; border-top-left-radius: 3px;
border-top-right-radius: 3px; border-top-right-radius: 3px;
.pt-popover-target { .pt-popover-wrapper {
float: right; float: right;
margin-top: 0.1rem; margin-top: 0.1rem;
} }
@ -102,7 +102,7 @@
.step-warning { .step-warning {
display: inline-block; display: inline-block;
float: none; float: none;
.pt-popover-target { .pt-popover-wrapper {
float: left; float: left;
} }
} }

View file

@ -27,14 +27,14 @@ describe("<CameraSelection/>", () => {
it("doesn't render camera", () => { it("doesn't render camera", () => {
const cameraSelection = mount(<CameraSelection {...fakeProps()} />); const cameraSelection = mount(<CameraSelection {...fakeProps()} />);
expect(cameraSelection.find("button").text()).toContain("USB Camera"); expect(cameraSelection.find("button").text()).toEqual("USB Camera");
}); });
it("renders camera", () => { it("renders camera", () => {
const p = fakeProps(); const p = fakeProps();
p.env = { "camera": "\"RPI\"" }; p.env = { "camera": "\"RPI\"" };
const cameraSelection = mount(<CameraSelection {...p} />); const cameraSelection = mount(<CameraSelection {...p} />);
expect(cameraSelection.find("button").text()).toContain("Raspberry Pi Camera"); expect(cameraSelection.find("button").text()).toEqual("Raspberry Pi Camera");
}); });
it("changes camera", () => { it("changes camera", () => {

View file

@ -18,6 +18,7 @@ export function LayerToggle({ label, value, onClick, popover }: LayerToggleProps
{label} {label}
{popover && {popover &&
<Popover <Popover
targetClassName={"caret-menu-button"}
position={Position.BOTTOM_RIGHT} position={Position.BOTTOM_RIGHT}
className={"caret-menu-button"}> className={"caret-menu-button"}>
<i className="fa fa-caret-down" title={t("filter")} /> <i className="fa fa-caret-down" title={t("filter")} />

View file

@ -29,7 +29,7 @@ export function FarmwareConfigMenu(props: FarmwareConfigMenuProps) {
<button <button
className="fb-button gray fa fa-download" className="fb-button gray fa fa-download"
onClick={() => { onClick={() => {
const p = getDevice().installFirstPartyFarmware() const p = getDevice().installFirstPartyFarmware();
p && p.catch(commandErr("Farmware installation")); p && p.catch(commandErr("Farmware installation"));
}} }}
disabled={props.firstPartyFwsInstalled} /> disabled={props.firstPartyFwsInstalled} />
@ -178,7 +178,7 @@ export class FarmwarePanel extends React.Component<FWProps, Partial<FWState>> {
</fieldset> </fieldset>
</Row> </Row>
<Row> <Row>
<fieldset> <fieldset className="farmware-selection-panel">
<Col xs={12}> <Col xs={12}>
<FBSelect <FBSelect
key={"farmware_" + this.selectedItem()} key={"farmware_" + this.selectedItem()}

View file

@ -4,7 +4,7 @@ import { WeedDetectorConfig } from "./config";
import { WidgetHeader } from "../../ui/index"; import { WidgetHeader } from "../../ui/index";
import { WD_ENV } from "./remote_env/interfaces"; import { WD_ENV } from "./remote_env/interfaces";
import { envSave } from "./remote_env/actions"; import { envSave } from "./remote_env/actions";
import { Popover, PopoverInteractionKind } from "@blueprintjs/core"; import { Popover } from "@blueprintjs/core";
import { DocSlug } from "../../ui/index"; import { DocSlug } from "../../ui/index";
type ClickHandler = React.EventHandler<React.MouseEvent<HTMLButtonElement>>; type ClickHandler = React.EventHandler<React.MouseEvent<HTMLButtonElement>>;
@ -58,8 +58,7 @@ export function TitleBar({
{t("Calibrate")} {t("Calibrate")}
</button> </button>
<div hidden={!env}> <div hidden={!env}>
<Popover <Popover>
interactionKind={PopoverInteractionKind.CLICK_TARGET_ONLY}>
<i className="fa fa-cog" /> <i className="fa fa-cog" />
{(env && <WeedDetectorConfig {(env && <WeedDetectorConfig
values={env} values={env}

View file

@ -11,11 +11,7 @@ import { NavLinks } from "./nav_links";
import { TickerList } from "./ticker_list"; import { TickerList } from "./ticker_list";
import { AdditionalMenu } from "./additional_menu"; import { AdditionalMenu } from "./additional_menu";
import { MobileMenu } from "./mobile_menu"; import { MobileMenu } from "./mobile_menu";
import { import { Popover, Position } from "@blueprintjs/core";
Popover,
Position,
PopoverInteractionKind
} from "@blueprintjs/core";
import { ErrorBoundary } from "../error_boundary"; import { ErrorBoundary } from "../error_boundary";
export class NavBar extends React.Component<NavBarProps, Partial<NavBarState>> { export class NavBar extends React.Component<NavBarProps, Partial<NavBarState>> {
@ -82,16 +78,16 @@ export class NavBar extends React.Component<NavBarProps, Partial<NavBarState>> {
</div> </div>
<div className="nav-right"> <div className="nav-right">
<Popover <Popover
interactionKind={PopoverInteractionKind.HOVER} position={Position.BOTTOM_RIGHT}
target={ isOpen={accountMenuOpen}
onClose={this.close("accountMenuOpen")}
usePortal={false}>
<div className="nav-name" <div className="nav-name"
onClick={this.toggle("accountMenuOpen")}> onClick={this.toggle("accountMenuOpen")}>
{firstName} {firstName}
</div>} </div>
position={Position.BOTTOM_RIGHT} {AdditionalMenu({ logout: this.logout, close })}
content={AdditionalMenu({ logout: this.logout, close })} </Popover>
isOpen={accountMenuOpen}
onClose={this.close("accountMenuOpen")} />
<EStopButton <EStopButton
bot={this.props.bot} bot={this.props.bot}
user={this.props.user} /> user={this.props.user} />

View file

@ -25,8 +25,10 @@ export function RegimenNameInput({ regimen, dispatch }: RegimenProps) {
onChange={write({ dispatch, regimen })} onChange={write({ dispatch, regimen })}
value={value} /> value={value} />
</Col> </Col>
<Col xs={1} className="color-picker-col">
<ColorPicker <ColorPicker
current={(regimen && regimen.body.color) || "gray"} current={(regimen && regimen.body.color) || "gray"}
onChange={(color) => dispatch(editRegimen(regimen, { color }))} /> onChange={(color) => dispatch(editRegimen(regimen, { color }))} />
</Col>
</Row>; </Row>;
} }

View file

@ -25,7 +25,7 @@ describe("<SequenceSelectBox />", () => {
it("renders", () => { it("renders", () => {
const wrapper = mount(<SequenceSelectBox {...fakeProps()} />); const wrapper = mount(<SequenceSelectBox {...fakeProps()} />);
expect(wrapper.text()).toContain("None"); expect(wrapper.text()).toEqual("None");
}); });
it("returns list: none selected", () => { it("returns list: none selected", () => {

View file

@ -74,9 +74,11 @@ export class SequenceEditorMiddleActive extends
dispatch(edit(sequence, { name: e.currentTarget.value })); dispatch(edit(sequence, { name: e.currentTarget.value }));
}} /> }} />
</Col> </Col>
<Col xs={1} className="color-picker-col">
<ColorPicker <ColorPicker
current={sequence.body.color} current={sequence.body.color}
onChange={color => editCurrentSequence(dispatch, sequence, { color })} /> onChange={color => editCurrentSequence(dispatch, sequence, { color })} />
</Col>
</Row> </Row>
{shouldDisplay(Feature.variables) && {shouldDisplay(Feature.variables) &&
<LocalsList <LocalsList

View file

@ -69,7 +69,7 @@ describe("<TileExecuteScript/>", () => {
const p = fakeProps(); const p = fakeProps();
p.farmwareInfo = undefined; p.farmwareInfo = undefined;
const wrapper = mount(<TileExecuteScript {...p} />); const wrapper = mount(<TileExecuteScript {...p} />);
expect(wrapper.find("button").text()).toContain("Manual Input"); expect(wrapper.find("button").text()).toEqual("Manual Input");
expect(wrapper.find("label").at(1).text()).toEqual("Manual input"); expect(wrapper.find("label").at(1).text()).toEqual("Manual input");
expect(wrapper.find("input").at(1).props().value).toEqual("farmware-to-execute"); expect(wrapper.find("input").at(1).props().value).toEqual("farmware-to-execute");
}); });

View file

@ -38,16 +38,16 @@ describe("<TileIf/>", () => {
expect(inputs.first().props().placeholder).toEqual("If Statement"); expect(inputs.first().props().placeholder).toEqual("If Statement");
expect(block.text()).toContain("IF..."); expect(block.text()).toContain("IF...");
expect(labels.at(0).text()).toEqual("Variable"); expect(labels.at(0).text()).toEqual("Variable");
expect(buttons.at(0).text()).toContain("Pin 0"); expect(buttons.at(0).text()).toEqual("Pin 0");
expect(labels.at(1).text()).toEqual("Operator"); expect(labels.at(1).text()).toEqual("Operator");
expect(buttons.at(1).text()).toContain("is"); expect(buttons.at(1).text()).toEqual("is");
expect(labels.at(2).text()).toEqual("Value"); expect(labels.at(2).text()).toEqual("Value");
expect(inputs.at(1).props().value).toEqual(0); expect(inputs.at(1).props().value).toEqual(0);
expect(block.text()).toContain("THEN..."); expect(block.text()).toContain("THEN...");
expect(labels.at(3).text()).toEqual("Execute Sequence"); expect(labels.at(3).text()).toEqual("Execute Sequence");
expect(buttons.at(2).text()).toContain("None"); expect(buttons.at(2).text()).toEqual("None");
expect(block.text()).toContain("ELSE..."); expect(block.text()).toContain("ELSE...");
expect(labels.at(4).text()).toEqual("Execute Sequence"); expect(labels.at(4).text()).toEqual("Execute Sequence");
expect(buttons.at(3).text()).toContain("None"); expect(buttons.at(3).text()).toEqual("None");
}); });
}); });

View file

@ -61,7 +61,7 @@ describe("<TileMoveAbsolute/>", () => {
expect(buttons.length).toEqual(1); expect(buttons.length).toEqual(1);
expect(inputs.first().props().placeholder).toEqual("Move Absolute"); expect(inputs.first().props().placeholder).toEqual("Move Absolute");
expect(labels.at(0).text().toLowerCase()).toEqual("import coordinates from"); expect(labels.at(0).text().toLowerCase()).toEqual("import coordinates from");
expect(buttons.at(0).text()).toContain("None"); expect(buttons.at(0).text()).toEqual("None");
checkField(block, 1, "x (mm)", "1"); checkField(block, 1, "x (mm)", "1");
checkField(block, 2, "y (mm)", "2"); checkField(block, 2, "y (mm)", "2");
checkField(block, 3, "z (mm)", "3"); checkField(block, 3, "z (mm)", "3");

View file

@ -38,6 +38,6 @@ describe("<TileReadPin/>", () => {
expect(labels.at(1).text()).toEqual("Data Label"); expect(labels.at(1).text()).toEqual("Data Label");
expect(inputs.at(1).props().value).toEqual("pinlabel"); expect(inputs.at(1).props().value).toEqual("pinlabel");
expect(labels.at(2).text()).toEqual("Pin Mode"); expect(labels.at(2).text()).toEqual("Pin Mode");
expect(buttons.at(0).text()).toContain("Pin 3"); expect(buttons.at(0).text()).toEqual("Pin 3");
}); });
}); });

View file

@ -41,7 +41,7 @@ describe("<TileSendMessage/>", () => {
expect(inputs.first().props().placeholder).toEqual("Send Message"); expect(inputs.first().props().placeholder).toEqual("Send Message");
expect(labels.at(0).text()).toEqual("Message"); expect(labels.at(0).text()).toEqual("Message");
expect(inputs.at(1).props().value).toEqual("send this message"); expect(inputs.at(1).props().value).toEqual("send this message");
expect(buttons.at(0).text()).toContain("Info"); expect(buttons.at(0).text()).toEqual("Info");
expect(labels.at(1).text()).toEqual("Ticker Notification"); expect(labels.at(1).text()).toEqual("Ticker Notification");
expect(inputs.at(2).props().checked).toBeTruthy(); expect(inputs.at(2).props().checked).toBeTruthy();
expect(inputs.at(2).props().disabled).toBeTruthy(); expect(inputs.at(2).props().disabled).toBeTruthy();

View file

@ -37,7 +37,7 @@ describe("<TileWritePin/>", () => {
expect(inputs.at(1).props().value).toEqual(2); expect(inputs.at(1).props().value).toEqual(2);
expect(labels.at(1).text()).toEqual("Value"); expect(labels.at(1).text()).toEqual("Value");
expect(labels.at(2).text()).toEqual("Pin Mode"); expect(labels.at(2).text()).toEqual("Pin Mode");
expect(buttons.at(0).text()).toContain("Pin 3"); expect(buttons.at(0).text()).toEqual("Pin 3");
}); });
it("renders inputs: Digital", () => { it("renders inputs: Digital", () => {
@ -54,8 +54,8 @@ describe("<TileWritePin/>", () => {
expect(inputs.first().props().placeholder).toEqual("Write Pin"); expect(inputs.first().props().placeholder).toEqual("Write Pin");
expect(labels.at(0).text()).toEqual("Pin"); expect(labels.at(0).text()).toEqual("Pin");
expect(labels.at(1).text()).toEqual("Value"); expect(labels.at(1).text()).toEqual("Value");
expect(buttons.at(0).text()).toContain("Pin 3"); expect(buttons.at(0).text()).toEqual("Pin 3");
expect(labels.at(2).text()).toEqual("Pin Mode"); expect(labels.at(2).text()).toEqual("Pin Mode");
expect(buttons.at(1).text()).toContain("ON"); expect(buttons.at(1).text()).toEqual("ON");
}); });
}); });

View file

@ -35,7 +35,7 @@ describe("<StepHeader />", () => {
it("renders", () => { it("renders", () => {
const wrapper = mount(<StepHeader {...fakeProps} />); const wrapper = mount(<StepHeader {...fakeProps} />);
const div = wrapper.find("div").last(); const div = wrapper.find("div").at(2);
expect(div.hasClass("step-header")).toBeTruthy(); expect(div.hasClass("step-header")).toBeTruthy();
expect(div.hasClass("step-class")).toBeTruthy(); expect(div.hasClass("step-class")).toBeTruthy();
}); });

View file

@ -14,14 +14,14 @@ describe("<FBSelect />", () => {
it("renders", () => { it("renders", () => {
const p = fakeProps(); const p = fakeProps();
const wrapper = mount(<FBSelect {...p} />); const wrapper = mount(<FBSelect {...p} />);
expect(wrapper.text()).toContain("None"); expect(wrapper.text()).toEqual("None");
}); });
it("renders item", () => { it("renders item", () => {
const p = fakeProps(); const p = fakeProps();
p.selectedItem = { value: "item", label: "Item" }; p.selectedItem = { value: "item", label: "Item" };
const wrapper = mount(<FBSelect {...p} />); const wrapper = mount(<FBSelect {...p} />);
expect(wrapper.text()).toContain("Item"); expect(wrapper.text()).toEqual("Item");
}); });
it("allows empty", () => { it("allows empty", () => {

View file

@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
import { t } from "i18next"; import { t } from "i18next";
import { Button, Classes, MenuItem } from "@blueprintjs/core"; import { Button, Classes, MenuItem, Alignment } from "@blueprintjs/core";
import { Select, ItemRenderer } from "@blueprintjs/select"; import { Select, ItemRenderer } from "@blueprintjs/select";
import { DropDownItem } from "./fb_select"; import { DropDownItem } from "./fb_select";
@ -38,8 +38,9 @@ export class FilterSearch extends React.Component<Props, Partial<State>> {
onItemSelect={this.handleValueChange} onItemSelect={this.handleValueChange}
popoverProps={{ popoverClassName: minimal ? Classes.MINIMAL : "" }}> popoverProps={{ popoverClassName: minimal ? Classes.MINIMAL : "" }}>
<Button <Button
rightIcon="double-caret-vertical" alignText={Alignment.LEFT}
text={item ? item.label : t("(No selection)")} /> text={item ? item.label : t("(No selection)")} />
<i className="fa fa-caret-down fa-lg" />
</SelectComponent>; </SelectComponent>;
} }