commit
8ac0c0625e
|
@ -212,6 +212,15 @@
|
|||
background-color: darken($panel_blue, 5%) !important;
|
||||
}
|
||||
}
|
||||
&.panel-navy {
|
||||
background-color: $panel_navy;
|
||||
box-shadow: 0 2px 0px 0px darken($panel_navy, 12%);
|
||||
&:focus,
|
||||
&:hover,
|
||||
&.active {
|
||||
background-color: darken($panel_navy, 5%) !important;
|
||||
}
|
||||
}
|
||||
&.panel-brown {
|
||||
background-color: $panel_brown;
|
||||
box-shadow: 0 2px 0px 0px darken($panel_brown, 12%);
|
||||
|
|
|
@ -47,6 +47,8 @@ $panel_medium_light_gray: #e6e6e6;
|
|||
$panel_light_gray: #f9fbfc;
|
||||
$panel_blue: #026365;
|
||||
$panel_light_blue: #f0f8f8;
|
||||
$panel_navy: #334970;
|
||||
$panel_light_navy: #f3f5f9;
|
||||
$panel_brown: #9e630a;
|
||||
$panel_light_brown: #fbf7f0;
|
||||
$panel_teal: #1eb287;
|
||||
|
|
|
@ -411,8 +411,6 @@
|
|||
}
|
||||
|
||||
.garden-snapshot {
|
||||
margin-left: 2rem;
|
||||
margin-right: 2rem;
|
||||
button {
|
||||
&.pseudo-disabled {
|
||||
cursor: not-allowed;
|
||||
|
@ -421,7 +419,7 @@
|
|||
}
|
||||
|
||||
.saved-garden-list {
|
||||
.saved-garden-row {
|
||||
.saved-garden-search-item {
|
||||
padding: 0.25rem;
|
||||
button {
|
||||
margin-bottom: 1rem;
|
||||
|
@ -431,7 +429,7 @@
|
|||
line-height: 3rem;
|
||||
cursor: pointer;
|
||||
padding-right: 0;
|
||||
label {
|
||||
span {
|
||||
margin: 0;
|
||||
pointer-events: none;
|
||||
margin-left: 1rem;
|
||||
|
@ -443,16 +441,6 @@
|
|||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: $light_gray;
|
||||
}
|
||||
&.selected {
|
||||
background: $gray;
|
||||
p,
|
||||
input {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
&.navy-panel {
|
||||
background-color: $panel_light_navy;
|
||||
div[class*="search-item"] {
|
||||
&:hover,
|
||||
&.hovered {
|
||||
background: darken($panel_light_navy, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.teal-panel {
|
||||
background-color: $panel_light_teal;
|
||||
div[class*="search-item"] {
|
||||
|
@ -161,6 +170,9 @@
|
|||
&.blue-panel {
|
||||
background-color: $panel_blue;
|
||||
}
|
||||
&.navy-panel {
|
||||
background-color: $panel_navy;
|
||||
}
|
||||
&.teal-panel {
|
||||
background-color: $panel_teal;
|
||||
}
|
||||
|
@ -321,25 +333,31 @@
|
|||
|
||||
.point-creation-panel {
|
||||
.panel-content {
|
||||
.row {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
margin-top: 1rem;
|
||||
label {
|
||||
margin-top: 0;
|
||||
}
|
||||
p {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
padding: 0 3rem;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
.fb-button {
|
||||
margin: 1rem;
|
||||
&.green {
|
||||
margin-right: 1.5rem;
|
||||
}
|
||||
&.delete {
|
||||
float: left;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
.saucer {
|
||||
margin-top: 0.25rem;
|
||||
margin-left: 1rem;
|
||||
margin: 1rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
.delete-row {
|
||||
padding-left: 1rem;
|
||||
margin: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,7 +368,7 @@
|
|||
margin: 1rem;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
.red {
|
||||
.fb-button & .red {
|
||||
display: block;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
@ -477,7 +495,7 @@
|
|||
}
|
||||
|
||||
.move-to-panel-content {
|
||||
margin-top: 6rem;
|
||||
margin-top: 1rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
button {
|
||||
|
@ -531,7 +549,10 @@
|
|||
.saved-garden-panel-content {
|
||||
padding: 0;
|
||||
.row {
|
||||
margin: 0;
|
||||
margin-top: 1rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
hr {
|
||||
width: 100%;
|
||||
|
@ -572,8 +593,6 @@
|
|||
}
|
||||
|
||||
.saved-garden-edit-panel-content {
|
||||
margin-left: 3rem;
|
||||
margin-right: 3rem;
|
||||
button {
|
||||
margin-left: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
|
@ -583,6 +602,9 @@
|
|||
text-align: center;
|
||||
padding: 3rem;
|
||||
}
|
||||
.row {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.clear-button {
|
||||
text-transform: uppercase;
|
||||
|
|
|
@ -875,7 +875,11 @@ ul {
|
|||
p,
|
||||
h5,
|
||||
a {
|
||||
color: $panel_green;
|
||||
color: $panel_navy;
|
||||
}
|
||||
.empty-state-graphic {
|
||||
filter: hue-rotate(135deg) brightness(0.5);
|
||||
color: $panel_navy;
|
||||
}
|
||||
}
|
||||
&.events {
|
||||
|
|
|
@ -38,7 +38,7 @@ type HOUR =
|
|||
type TimeTable = Record<HOUR, DropDownItem>;
|
||||
type EveryTimeTable = Record<PreferredHourFormat, TimeTable>;
|
||||
const TIME_TABLE_12H: TimeTable = {
|
||||
0: { label: "Midnight", value: 0 },
|
||||
0: { label: t("Midnight"), value: 0 },
|
||||
1: { label: "1:00 AM", value: 1 },
|
||||
2: { label: "2:00 AM", value: 2 },
|
||||
3: { label: "3:00 AM", value: 3 },
|
||||
|
@ -50,7 +50,7 @@ const TIME_TABLE_12H: TimeTable = {
|
|||
9: { label: "9:00 AM", value: 9 },
|
||||
10: { label: "10:00 AM", value: 10 },
|
||||
11: { label: "11:00 AM", value: 11 },
|
||||
12: { label: "Noon", value: 12 },
|
||||
12: { label: t("Noon"), value: 12 },
|
||||
13: { label: "1:00 PM", value: 13 },
|
||||
14: { label: "2:00 PM", value: 14 },
|
||||
15: { label: "3:00 PM", value: 15 },
|
||||
|
@ -62,7 +62,7 @@ const TIME_TABLE_12H: TimeTable = {
|
|||
21: { label: "9:00 PM", value: 21 },
|
||||
22: { label: "10:00 PM", value: 22 },
|
||||
23: { label: "11:00 PM", value: 23 },
|
||||
[IMMEDIATELY]: { label: "as soon as possible", value: IMMEDIATELY },
|
||||
[IMMEDIATELY]: { label: t("as soon as possible"), value: IMMEDIATELY },
|
||||
};
|
||||
const TIME_TABLE_24H: TimeTable = {
|
||||
0: { label: "00:00", value: 0 },
|
||||
|
@ -89,7 +89,7 @@ const TIME_TABLE_24H: TimeTable = {
|
|||
21: { label: "21:00", value: 21 },
|
||||
22: { label: "22:00", value: 22 },
|
||||
23: { label: "23:00", value: 23 },
|
||||
[IMMEDIATELY]: { label: "as soon as possible", value: IMMEDIATELY },
|
||||
[IMMEDIATELY]: { label: t("as soon as possible"), value: IMMEDIATELY },
|
||||
};
|
||||
|
||||
const DEFAULT_HOUR: keyof TimeTable = IMMEDIATELY;
|
||||
|
|
|
@ -40,7 +40,7 @@ describe("<DesignerNavTabs />", () => {
|
|||
mockPath = "/app/designer/gardens";
|
||||
mockDev = true;
|
||||
const wrapper = shallow(<DesignerNavTabs />);
|
||||
expect(wrapper.hasClass("green-panel")).toBeTruthy();
|
||||
expect(wrapper.hasClass("navy-panel")).toBeTruthy();
|
||||
expect(wrapper.html()).toContain("active");
|
||||
});
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ export enum PanelColor {
|
|||
lightGray = "light-gray",
|
||||
yellow = "yellow",
|
||||
blue = "blue",
|
||||
navy = "navy",
|
||||
teal = "teal",
|
||||
red = "red",
|
||||
}
|
||||
|
@ -36,7 +37,7 @@ export const TAB_COLOR: { [key in Panel]: PanelColor } = {
|
|||
[Panel.Map]: PanelColor.gray,
|
||||
[Panel.Plants]: PanelColor.green,
|
||||
[Panel.FarmEvents]: PanelColor.yellow,
|
||||
[Panel.SavedGardens]: PanelColor.green,
|
||||
[Panel.SavedGardens]: PanelColor.navy,
|
||||
[Panel.Tools]: PanelColor.gray,
|
||||
[Panel.Settings]: PanelColor.gray,
|
||||
[Panel.Points]: PanelColor.teal,
|
||||
|
|
|
@ -115,8 +115,8 @@ describe("<CreatePoints />", () => {
|
|||
const p = fakeProps();
|
||||
p.currentPoint = { cx: 0, cy: 0, r: 100 };
|
||||
const panel = mount<CreatePoints>(<CreatePoints {...p} />);
|
||||
const wrapper = shallow(panel.instance().PointName());
|
||||
wrapper.find("BlurableInput").simulate("commit", {
|
||||
const wrapper = shallow(panel.instance().PointProperties());
|
||||
wrapper.find("BlurableInput").first().simulate("commit", {
|
||||
currentTarget: { value: "new name" }
|
||||
});
|
||||
expect(p.dispatch).toHaveBeenCalledWith({
|
||||
|
@ -208,7 +208,7 @@ describe("<CreatePoints />", () => {
|
|||
const wrapper = shallow<CreatePoints>(<CreatePoints {...p} />);
|
||||
const PP = wrapper.instance().PointProperties;
|
||||
const component = shallow(<PP />);
|
||||
component.find("BlurableInput").first().simulate("commit", {
|
||||
component.find("BlurableInput").at(1).simulate("commit", {
|
||||
currentTarget: { value: "10" }
|
||||
});
|
||||
expect(p.dispatch).toHaveBeenCalledWith({
|
||||
|
|
|
@ -8,7 +8,7 @@ import { shallow } from "enzyme";
|
|||
import {
|
||||
EditPointLocation, EditPointLocationProps,
|
||||
EditPointRadius, EditPointRadiusProps,
|
||||
EditPointColor, EditPointColorProps, updatePoint,
|
||||
EditPointColor, EditPointColorProps, updatePoint, EditPointName, EditPointNameProps,
|
||||
} from "../point_edit_actions";
|
||||
import { fakePoint } from "../../../__test_support__/fake_state/resources";
|
||||
import { edit, save } from "../../../api/crud";
|
||||
|
@ -28,6 +28,22 @@ describe("updatePoint()", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("<EditPointName />", () => {
|
||||
const fakeProps = (): EditPointNameProps => ({
|
||||
updatePoint: jest.fn(),
|
||||
name: "point name",
|
||||
});
|
||||
|
||||
it("edits name", () => {
|
||||
const p = fakeProps();
|
||||
const wrapper = shallow(<EditPointName {...p} />);
|
||||
wrapper.find("BlurableInput").first().simulate("commit", {
|
||||
currentTarget: { value: "new point name" }
|
||||
});
|
||||
expect(p.updatePoint).toHaveBeenCalledWith({ name: "new point name" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("<EditPointLocation />", () => {
|
||||
const fakeProps = (): EditPointLocationProps => ({
|
||||
updatePoint: jest.fn(),
|
||||
|
|
|
@ -46,7 +46,7 @@ describe("<EditPoint />", () => {
|
|||
it("renders with points", () => {
|
||||
mockPath = "/app/designer/points/1";
|
||||
const wrapper = mount(<EditPoint {...fakeProps()} />);
|
||||
expect(wrapper.text()).toContain("Edit Point 1");
|
||||
expect(wrapper.text()).toContain("Edit point");
|
||||
});
|
||||
|
||||
it("moves the device to a particular point", () => {
|
||||
|
|
|
@ -5,7 +5,7 @@ jest.mock("../../../history", () => ({
|
|||
}));
|
||||
|
||||
import * as React from "react";
|
||||
import { mount } from "enzyme";
|
||||
import { mount, shallow } from "enzyme";
|
||||
import {
|
||||
RawEditWeed as EditWeed, EditWeedProps, mapStateToProps
|
||||
} from "../weeds_edit";
|
||||
|
@ -14,6 +14,8 @@ import { fakeState } from "../../../__test_support__/fake_state";
|
|||
import {
|
||||
buildResourceIndex
|
||||
} from "../../../__test_support__/resource_index_builder";
|
||||
import { Actions } from "../../../constants";
|
||||
import { DesignerPanelHeader } from "../designer_panel";
|
||||
|
||||
describe("<EditWeed />", () => {
|
||||
const fakeProps = (): EditWeedProps => ({
|
||||
|
@ -36,6 +38,19 @@ describe("<EditWeed />", () => {
|
|||
const wrapper = mount(<EditWeed {...p} />);
|
||||
expect(wrapper.text().toLowerCase()).toContain("edit");
|
||||
});
|
||||
|
||||
it("goes back", () => {
|
||||
mockPath = "/app/designer/weeds/1";
|
||||
const p = fakeProps();
|
||||
const point = fakePoint();
|
||||
point.body.id = 1;
|
||||
p.findPoint = () => point;
|
||||
const wrapper = shallow(<EditWeed {...p} />);
|
||||
wrapper.find(DesignerPanelHeader).simulate("back");
|
||||
expect(p.dispatch).toHaveBeenCalledWith({
|
||||
type: Actions.TOGGLE_HOVERED_POINT, payload: undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("mapStateToProps()", () => {
|
||||
|
|
|
@ -24,6 +24,7 @@ import { parseIntInput } from "../../util";
|
|||
import { t } from "../../i18next_wrapper";
|
||||
import { Panel } from "../panel_header";
|
||||
import { getPathArray } from "../../history";
|
||||
import { ListItem } from "./plant_panel";
|
||||
|
||||
export function mapStateToProps(props: Everything): CreatePointsProps {
|
||||
const { position } = props.bot.hardware.location_data;
|
||||
|
@ -178,54 +179,59 @@ export class RawCreatePoints
|
|||
this.cancel();
|
||||
this.loadDefaultPoint();
|
||||
}
|
||||
|
||||
PointName = () =>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<label>{t("Name")}</label>
|
||||
<BlurableInput
|
||||
name="name"
|
||||
type="text"
|
||||
onCommit={this.updateValue("name")}
|
||||
value={this.attr("name") || this.defaultName} />
|
||||
</Col>
|
||||
</Row>;
|
||||
|
||||
PointProperties = () => {
|
||||
return <Row>
|
||||
<Col xs={3}>
|
||||
<label>{t("X")}</label>
|
||||
<BlurableInput
|
||||
name="cx"
|
||||
type="number"
|
||||
onCommit={this.updateValue("cx")}
|
||||
value={this.attr("cx", this.props.deviceX)} />
|
||||
</Col>
|
||||
<Col xs={3}>
|
||||
<label>{t("Y")}</label>
|
||||
<BlurableInput
|
||||
name="cy"
|
||||
type="number"
|
||||
onCommit={this.updateValue("cy")}
|
||||
value={this.attr("cy", this.props.deviceY)} />
|
||||
</Col>
|
||||
<Col xs={3}>
|
||||
<label>{t("radius")}</label>
|
||||
<BlurableInput
|
||||
name="r"
|
||||
type="number"
|
||||
onCommit={this.updateValue("r")}
|
||||
value={this.attr("r")}
|
||||
min={0} />
|
||||
</Col>
|
||||
<Col xs={3}>
|
||||
<label>{t("color")}</label>
|
||||
<ColorPicker
|
||||
current={(this.attr("color") || this.defaultColor) as ResourceColor}
|
||||
onChange={this.changeColor} />
|
||||
</Col>
|
||||
</Row>;
|
||||
}
|
||||
PointProperties = () =>
|
||||
<ul>
|
||||
<li>
|
||||
<div>
|
||||
<label>{t("Name")}</label>
|
||||
<BlurableInput
|
||||
name="name"
|
||||
type="text"
|
||||
onCommit={this.updateValue("name")}
|
||||
value={this.attr("name") || this.defaultName} />
|
||||
</div>
|
||||
</li>
|
||||
<ListItem name={t("Location")}>
|
||||
<Row>
|
||||
<Col xs={6}>
|
||||
<label>{t("X (mm)")}</label>
|
||||
<BlurableInput
|
||||
name="cx"
|
||||
type="number"
|
||||
onCommit={this.updateValue("cx")}
|
||||
value={this.attr("cx", this.props.deviceX)} />
|
||||
</Col>
|
||||
<Col xs={6}>
|
||||
<label>{t("Y (mm)")}</label>
|
||||
<BlurableInput
|
||||
name="cy"
|
||||
type="number"
|
||||
onCommit={this.updateValue("cy")}
|
||||
value={this.attr("cy", this.props.deviceY)} />
|
||||
</Col>
|
||||
</Row>
|
||||
</ListItem>
|
||||
<ListItem name={t("Size")}>
|
||||
<Row>
|
||||
<Col xs={6}>
|
||||
<label>{t("radius")}</label>
|
||||
<BlurableInput
|
||||
name="r"
|
||||
type="number"
|
||||
onCommit={this.updateValue("r")}
|
||||
value={this.attr("r")}
|
||||
min={0} />
|
||||
</Col>
|
||||
</Row>
|
||||
</ListItem>
|
||||
<ListItem name={t("Color")}>
|
||||
<Row>
|
||||
<ColorPicker
|
||||
current={(this.attr("color") || this.defaultColor) as ResourceColor}
|
||||
onChange={this.changeColor} />
|
||||
</Row>
|
||||
</ListItem>
|
||||
</ul>
|
||||
|
||||
PointActions = () =>
|
||||
<Row>
|
||||
|
@ -272,7 +278,6 @@ export class RawCreatePoints
|
|||
backTo={`/app/designer/${this.panel}`}
|
||||
description={panelDescription} />
|
||||
<DesignerPanelContent panelName={"point-creation"}>
|
||||
<this.PointName />
|
||||
<this.PointProperties />
|
||||
<this.PointActions />
|
||||
{this.DeleteAllPoints(this.panel == "weeds" ? "weed" : "point")}
|
||||
|
|
|
@ -26,6 +26,13 @@ export interface EditPointPropertiesProps {
|
|||
|
||||
export const EditPointProperties = (props: EditPointPropertiesProps) =>
|
||||
<ul>
|
||||
<li>
|
||||
<div>
|
||||
<EditPointName
|
||||
name={props.point.body.name}
|
||||
updatePoint={props.updatePoint} />
|
||||
</div>
|
||||
</li>
|
||||
<ListItem name={t("Location")}>
|
||||
<EditPointLocation
|
||||
location={{ x: props.point.body.x, y: props.point.body.y }}
|
||||
|
@ -66,6 +73,22 @@ export const PointActions = ({ x, y, z, uuid, dispatch }: PointActionsProps) =>
|
|||
</button>
|
||||
</div>;
|
||||
|
||||
export interface EditPointNameProps {
|
||||
updatePoint(update: Partial<TaggedGenericPointer["body"]>): void;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const EditPointName = (props: EditPointNameProps) =>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<label>{t("Name")}</label>
|
||||
<BlurableInput
|
||||
type="text"
|
||||
value={props.name}
|
||||
onCommit={e => props.updatePoint({ name: e.currentTarget.value })} />
|
||||
</Col>
|
||||
</Row>;
|
||||
|
||||
export interface EditPointLocationProps {
|
||||
updatePoint(update: Partial<TaggedGenericPointer["body"]>): void;
|
||||
location: Record<"x" | "y", number>;
|
||||
|
|
|
@ -45,7 +45,7 @@ export class RawEditPoint extends React.Component<EditPointProps, {}> {
|
|||
<DesignerPanelHeader
|
||||
panelName={this.panelName}
|
||||
panel={Panel.Points}
|
||||
title={`${t("Edit")} ${point.body.name}`}
|
||||
title={t("Edit point")}
|
||||
backTo={this.backTo}
|
||||
onBack={() => this.props.dispatch({
|
||||
type: Actions.TOGGLE_HOVERED_POINT, payload: undefined
|
||||
|
|
|
@ -12,6 +12,7 @@ import { Panel } from "../panel_header";
|
|||
import {
|
||||
EditPointProperties, PointActions, updatePoint
|
||||
} from "./point_edit_actions";
|
||||
import { Actions } from "../../constants";
|
||||
|
||||
export interface EditWeedProps {
|
||||
dispatch: Function;
|
||||
|
@ -44,8 +45,11 @@ export class RawEditWeed extends React.Component<EditWeedProps, {}> {
|
|||
<DesignerPanelHeader
|
||||
panelName={this.panelName}
|
||||
panel={Panel.Weeds}
|
||||
title={`${t("Edit")} ${point.body.name}`}
|
||||
backTo={this.backTo}>
|
||||
title={t("Edit weed")}
|
||||
backTo={this.backTo}
|
||||
onBack={() => this.props.dispatch({
|
||||
type: Actions.TOGGLE_HOVERED_POINT, payload: undefined
|
||||
})}>
|
||||
</DesignerPanelHeader>
|
||||
<DesignerPanelContent panelName={this.panelName}>
|
||||
<EditPointProperties point={point}
|
||||
|
|
|
@ -87,7 +87,7 @@ export class RawEditGarden extends React.Component<EditGardenProps, {}> {
|
|||
{savedGarden
|
||||
? <div>
|
||||
<Row>
|
||||
<label>{t("Garden name")}</label>
|
||||
<label>{t("name")}</label>
|
||||
<BlurableInput
|
||||
value={savedGarden.body.name || ""}
|
||||
onCommit={e => {
|
||||
|
|
|
@ -13,7 +13,7 @@ export const GardenInfo = (props: SavedGardenInfoProps) => {
|
|||
return <div className="saved-garden-info"
|
||||
onClick={() => dispatch(openSavedGarden(savedGarden.uuid))}>
|
||||
<Col>
|
||||
<label>{savedGarden.body.name}</label>
|
||||
<span>{savedGarden.body.name}</span>
|
||||
<p>{props.plantTemplateCount} {t("plants")}</p>
|
||||
</Col>
|
||||
</div>;
|
||||
|
@ -21,8 +21,8 @@ export const GardenInfo = (props: SavedGardenInfoProps) => {
|
|||
|
||||
/** Info and actions for a single SavedGarden. */
|
||||
const SavedGardenItem = (props: SavedGardenItemProps) => {
|
||||
return <div
|
||||
className={`saved-garden-row ${props.gardenIsOpen ? "selected" : ""}`}>
|
||||
return <div className={
|
||||
`saved-garden-search-item ${props.gardenIsOpen ? "selected" : ""}`}>
|
||||
<GardenInfo
|
||||
savedGarden={props.savedGarden}
|
||||
plantTemplateCount={props.plantTemplateCount}
|
||||
|
|
|
@ -37,7 +37,7 @@ export class GardenSnapshot
|
|||
|
||||
render() {
|
||||
return <div className="garden-snapshot">
|
||||
<label>{t("new garden name")}</label>
|
||||
<label>{t("name")}</label>
|
||||
<input
|
||||
onChange={e => this.setState({ name: e.currentTarget.value })}
|
||||
value={this.state.name} />
|
||||
|
|
|
@ -103,6 +103,7 @@ namespace :api do
|
|||
end
|
||||
end
|
||||
|
||||
RELEASES_URL = "https://api.github.com/repos/farmbot/farmbot_os/releases"
|
||||
VERSION = "tag_name"
|
||||
TIMESTAMP = "created_at"
|
||||
PRERELEASE = "prerelease"
|
||||
|
@ -116,10 +117,9 @@ namespace :api do
|
|||
# 60 days is the current policy.
|
||||
cutoff = 60.days.ago
|
||||
# Download release data from github
|
||||
stringio = open("https://api.github.com/repos/farmbot/farmbot_os/releases")
|
||||
string = stringio.read
|
||||
data = JSON
|
||||
.parse(string)
|
||||
string_page_1 = open("#{RELEASES_URL}?per_page=100&page=1").read
|
||||
string_page_2 = open("#{RELEASES_URL}?per_page=100&page=2").read
|
||||
data = JSON.parse(string_page_1).push(*JSON.parse(string_page_2))
|
||||
.map { |x| x.slice(VERSION, TIMESTAMP, PRERELEASE) } # Only grab keys that matter
|
||||
.reject { |x| x.fetch(VERSION).include?("-") } # Remove RC/Beta releases
|
||||
.reject { |x| x.fetch(PRERELEASE) } # Remove pre-releases
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"@types/lodash": "4.14.149",
|
||||
"@types/markdown-it": "0.0.9",
|
||||
"@types/moxios": "0.4.9",
|
||||
"@types/node": "12.12.9",
|
||||
"@types/node": "12.12.11",
|
||||
"@types/promise-timeout": "1.3.0",
|
||||
"@types/react": "16.9.11",
|
||||
"@types/react-color": "3.0.1",
|
||||
|
@ -69,7 +69,7 @@
|
|||
"redux": "4.0.4",
|
||||
"redux-immutable-state-invariant": "2.1.0",
|
||||
"redux-thunk": "2.3.0",
|
||||
"sass": "1.23.6",
|
||||
"sass": "1.23.7",
|
||||
"sass-lint": "1.13.1",
|
||||
"takeme": "0.11.3",
|
||||
"ts-jest": "24.1.0",
|
||||
|
|
Loading…
Reference in New Issue