cleanup and fixes
parent
75b72e13da
commit
3a20d17eaf
|
@ -126,6 +126,8 @@ export class API {
|
|||
/** Rather than returning ALL logs, returns a filtered subset.
|
||||
* /api/logs/search */
|
||||
get filteredLogsPath() { return `${this.baseUrl}/api/logs/search`; }
|
||||
/** /api/logs/ */
|
||||
get logsPath() { return `${this.baseUrl}/api/logs/`; }
|
||||
/** /api/webcam_feed */
|
||||
get webcamFeedPath() { return `${this.baseUrl}/api/webcam_feeds/`; }
|
||||
/** /api/web_app_config */
|
||||
|
|
|
@ -261,7 +261,7 @@ export function urlFor(tag: ResourceName) {
|
|||
FbosConfig: API.current.fbosConfigPath,
|
||||
FirmwareConfig: API.current.firmwareConfigPath,
|
||||
Image: API.current.imagesPath,
|
||||
Log: API.current.filteredLogsPath,
|
||||
Log: API.current.logsPath,
|
||||
Peripheral: API.current.peripheralsPath,
|
||||
PinBinding: API.current.pinBindingPath,
|
||||
PlantTemplate: API.current.plantTemplatePath,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as React from "react";
|
||||
import { Row, Col } from "../ui/index";
|
||||
import { KeyValRowProps } from "./key_val_show_row";
|
||||
import { t } from "../i18next_wrapper";
|
||||
|
||||
interface Props extends KeyValRowProps {
|
||||
onLabelChange(e: React.ChangeEvent<HTMLInputElement>): void;
|
||||
|
@ -26,7 +27,8 @@ export function KeyValEditRow(p: Props) {
|
|||
</Col>
|
||||
<Col xs={2}>
|
||||
<button
|
||||
className="red fb-button"
|
||||
className="red fb-button del-button"
|
||||
title={t("Delete")}
|
||||
onClick={p.onClick}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
|
|
|
@ -10,10 +10,10 @@ import { TaggedPeripheral, TaggedSensor } from "farmbot";
|
|||
import { UUID } from "../resources/interfaces";
|
||||
import { isNumber } from "lodash";
|
||||
|
||||
const MODES: { [s: string]: string } = {
|
||||
const MODES = (): { [s: string]: string } => ({
|
||||
0: t("Digital"),
|
||||
1: t("Analog")
|
||||
};
|
||||
});
|
||||
|
||||
interface NameInputBoxProps {
|
||||
dispatch: Function;
|
||||
|
@ -53,11 +53,11 @@ interface ModeDropdownProps {
|
|||
|
||||
export const ModeDropdown = (props: ModeDropdownProps) =>
|
||||
<FBSelect
|
||||
onChange={d => {
|
||||
props.dispatch(edit(props.resource, { mode: parseInt(d.value.toString(), 10) }));
|
||||
}}
|
||||
selectedItem={{ label: MODES[props.value], value: props.value }}
|
||||
list={PIN_MODES} />;
|
||||
onChange={d => props.dispatch(edit(props.resource, {
|
||||
mode: parseInt(d.value.toString(), 10)
|
||||
}))}
|
||||
selectedItem={{ label: MODES()[props.value], value: props.value }}
|
||||
list={PIN_MODES()} />;
|
||||
|
||||
interface DeleteButtonProps {
|
||||
dispatch: Function;
|
||||
|
@ -66,15 +66,12 @@ interface DeleteButtonProps {
|
|||
onDestroy?: Function;
|
||||
}
|
||||
|
||||
const DELETE_BTN = <i className="fa fa-times" />;
|
||||
|
||||
export const DeleteButton = (props: DeleteButtonProps) =>
|
||||
<button
|
||||
className="red fb-button"
|
||||
onClick={() => {
|
||||
props
|
||||
.dispatch(destroy(props.uuid))
|
||||
.then(props.onDestroy || (() => { }));
|
||||
}}>
|
||||
{props.children ? props.children : DELETE_BTN}
|
||||
className="red fb-button del-button"
|
||||
title={t("Delete")}
|
||||
onClick={() =>
|
||||
props.dispatch(destroy(props.uuid))
|
||||
.then(props.onDestroy || (() => { }))}>
|
||||
{props.children || <i className="fa fa-times" />}
|
||||
</button >;
|
||||
|
|
|
@ -238,7 +238,7 @@
|
|||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
width: 8em;
|
||||
width: 40%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-left: 1rem;
|
||||
|
|
|
@ -469,9 +469,3 @@
|
|||
min-width: 7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.point-panel-content {
|
||||
.point-search-item-name {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -396,7 +396,9 @@ a {
|
|||
margin-left: 0.5rem;
|
||||
}
|
||||
.fb-button {
|
||||
margin-top: 0.5rem;
|
||||
&.green {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
.bindings-list {
|
||||
margin-bottom: 1rem;
|
||||
|
@ -404,7 +406,7 @@ a {
|
|||
}
|
||||
.stock-pin-bindings-button {
|
||||
button {
|
||||
margin: 0;
|
||||
margin: 0 !important;
|
||||
}
|
||||
i {
|
||||
margin-right: 0.5rem;
|
||||
|
@ -1012,10 +1014,13 @@ ul {
|
|||
|
||||
.logs-table {
|
||||
background: $white;
|
||||
div {
|
||||
.log-verbosity-saucer, .saucer {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
button {
|
||||
float: none;
|
||||
}
|
||||
thead {
|
||||
background: $gray;
|
||||
}
|
||||
|
@ -1096,9 +1101,6 @@ ul {
|
|||
color: $dark_gray;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.del-button {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.fb-button {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
@ -1153,6 +1155,16 @@ ul {
|
|||
}
|
||||
}
|
||||
|
||||
.sensors-widget,
|
||||
.webcam-widget,
|
||||
.peripherals-widget,
|
||||
.tools-widget,
|
||||
.toolbay-widget {
|
||||
.del-button {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.farmware-step-input-fields {
|
||||
label {
|
||||
padding-top: 1rem;
|
||||
|
|
|
@ -25,6 +25,7 @@ export class DiagnosticDumpRow extends React.Component<Props, {}> {
|
|||
<Col xs={1}>
|
||||
<button
|
||||
className="red fb-button del-button"
|
||||
title={t("Delete")}
|
||||
onClick={this.destroy}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
|
|
|
@ -114,7 +114,7 @@ export const colorFromThrottle =
|
|||
const THROTTLE_COLOR_KEY = () => ({
|
||||
red: t("active"),
|
||||
yellow: t("occurred"),
|
||||
green: t("clear")
|
||||
green: t("ok")
|
||||
});
|
||||
|
||||
interface ThrottleIndicatorProps {
|
||||
|
|
|
@ -45,7 +45,8 @@ export const PinBindingsList = (props: PinBindingsListProps) => {
|
|||
</Col>
|
||||
<Col xs={PinBindingColWidth.button}>
|
||||
<button
|
||||
className={`fb-button ${delBtnColor(pin_number)}`}
|
||||
className={`fb-button ${delBtnColor(pin_number)} del-button`}
|
||||
title={t("Delete")}
|
||||
onClick={() => deleteBinding(pin_number, x.uuid)}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
|
|
|
@ -34,7 +34,7 @@ export class ImageFilterMenu
|
|||
this.state = {};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
UNSAFE_componentWillMount() {
|
||||
const { newestDate, toOldest } = this.props.imageAgeInfo;
|
||||
const beginDatetime = this.props.getConfigValue("photo_filter_begin");
|
||||
this.setState({
|
||||
|
|
|
@ -73,7 +73,7 @@ export class SpreadCircle extends
|
|||
React.Component<SpreadCircleProps, SpreadCircleState> {
|
||||
state: SpreadCircleState = { spread: undefined };
|
||||
|
||||
componentWillMount = () => {
|
||||
UNSAFE_componentWillMount = () => {
|
||||
cachedCrop(this.props.plant.body.openfarm_slug)
|
||||
.then(({ spread }) => this.setState({ spread }));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as React from "react";
|
||||
|
||||
import { Row, Col, BlurableInput } from "../../ui";
|
||||
import { error } from "../../toast/toast";
|
||||
import { isNumber, isString } from "lodash";
|
||||
|
@ -62,7 +61,8 @@ const ApplyGardenButton =
|
|||
const DestroyGardenButton =
|
||||
(props: { dispatch: Function, gardenUuid: string }) =>
|
||||
<button
|
||||
className="fb-button red"
|
||||
className="fb-button red del-button"
|
||||
title={t("Delete")}
|
||||
onClick={() => props.dispatch(destroySavedGarden(props.gardenUuid))}>
|
||||
<i className="fa fa-times" />
|
||||
</button>;
|
||||
|
|
|
@ -123,7 +123,7 @@ export class FarmwarePage extends React.Component<FarmwareProps, {}> {
|
|||
return isBotOnline(this.props.syncStatus, this.props.botToMqttStatus);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
UNSAFE_componentWillMount() {
|
||||
if (window.innerWidth > 450) {
|
||||
this.props.dispatch({
|
||||
type: Actions.SELECT_FARMWARE,
|
||||
|
|
|
@ -39,8 +39,8 @@ export class HotKeys extends React.Component<Props, Partial<State>> {
|
|||
onClose={this.toggle("guideOpen")}>
|
||||
<div className={hotkeyGuideClasses}>
|
||||
<h3>{t("Hotkeys")}</h3>
|
||||
<i
|
||||
className="fa fa-times"
|
||||
<i className="fa fa-times"
|
||||
title={t("Close")}
|
||||
onClick={this.toggle("guideOpen")} />
|
||||
{this.hotkeys(this.props.dispatch, "")
|
||||
.map(hotkey => <Row key={hotkey.combo}>
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import * as React from "react";
|
||||
import { TaggedLog } from "farmbot";
|
||||
import { TaggedLog, ALLOWED_MESSAGE_TYPES } from "farmbot";
|
||||
import { LogsState, LogsTableProps, Filters } from "../interfaces";
|
||||
import { formatLogTime } from "../index";
|
||||
import { Classes } from "@blueprintjs/core";
|
||||
import { isNumber, startCase } from "lodash";
|
||||
import { t } from "../../i18next_wrapper";
|
||||
import { TimeSettings } from "../../interfaces";
|
||||
import { UUID } from "../../resources/interfaces";
|
||||
|
||||
interface LogsRowProps {
|
||||
tlog: TaggedLog;
|
||||
dispatch: Function;
|
||||
timeSettings: TimeSettings;
|
||||
}
|
||||
|
||||
|
@ -18,18 +20,31 @@ export const xyzTableEntry =
|
|||
? `${x}, ${y}, ${z}`
|
||||
: t("Unknown");
|
||||
|
||||
interface LogVerbositySaucerProps {
|
||||
uuid: UUID;
|
||||
verbosity: number | undefined;
|
||||
type: ALLOWED_MESSAGE_TYPES;
|
||||
dispatch: Function;
|
||||
}
|
||||
|
||||
const LogVerbositySaucer = (props: LogVerbositySaucerProps) =>
|
||||
<div className="log-verbosity-saucer">
|
||||
<div className={`saucer ${props.type}`}>
|
||||
<p>
|
||||
{props.verbosity}
|
||||
</p>
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
/** A log is displayed in a single row of the logs table. */
|
||||
const LogsRow = ({ tlog, timeSettings }: LogsRowProps) => {
|
||||
const LogsRow = ({ tlog, timeSettings, dispatch }: LogsRowProps) => {
|
||||
const { uuid } = tlog;
|
||||
const { x, y, z, verbosity, type, created_at, message } = tlog.body;
|
||||
const { x, y, z, verbosity, type, created_at, message, id } = tlog.body;
|
||||
const time = formatLogTime(created_at || NaN, timeSettings);
|
||||
return <tr key={uuid}>
|
||||
return <tr key={uuid} id={"" + id}>
|
||||
<td>
|
||||
<div className={`saucer ${type}`}>
|
||||
<p>
|
||||
{verbosity}
|
||||
</p>
|
||||
</div>
|
||||
<LogVerbositySaucer
|
||||
uuid={uuid} dispatch={dispatch} verbosity={verbosity} type={type} />
|
||||
{t(startCase(type))}
|
||||
</td>
|
||||
<td>
|
||||
|
@ -63,12 +78,12 @@ export const LogsTable = (props: LogsTableProps) => {
|
|||
</thead>
|
||||
<tbody>
|
||||
{filterByVerbosity(getFilterLevel(props.state), props.logs)
|
||||
.map((log: TaggedLog) => {
|
||||
return <LogsRow
|
||||
.map((log: TaggedLog) =>
|
||||
<LogsRow
|
||||
key={log.uuid}
|
||||
tlog={log}
|
||||
timeSettings={props.timeSettings} />;
|
||||
})}
|
||||
dispatch={props.dispatch}
|
||||
timeSettings={props.timeSettings} />)}
|
||||
</tbody>
|
||||
</table>;
|
||||
};
|
||||
|
|
|
@ -118,6 +118,7 @@ export class Logs extends React.Component<LogsProps, Partial<LogsState>> {
|
|||
</Row>
|
||||
<Row>
|
||||
<LogsTable logs={this.props.logs}
|
||||
dispatch={this.props.dispatch}
|
||||
state={this.state}
|
||||
timeSettings={this.props.timeSettings} />
|
||||
</Row>
|
||||
|
|
|
@ -20,6 +20,7 @@ export interface LogsState extends Filters {
|
|||
|
||||
export interface LogsTableProps {
|
||||
logs: TaggedLog[];
|
||||
dispatch: Function;
|
||||
state: LogsState;
|
||||
timeSettings: TimeSettings;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ export const RegimenBackButton = (props: RegimenBackButtonProps) => {
|
|||
|
||||
@connect(mapStateToProps)
|
||||
export class Regimens extends React.Component<Props, {}> {
|
||||
componentWillMount() {
|
||||
UNSAFE_componentWillMount() {
|
||||
if (!this.props.current) { setActiveRegimenByName(); }
|
||||
}
|
||||
|
||||
|
|
|
@ -14,50 +14,50 @@ import { Provider } from "react-redux";
|
|||
interface RootComponentProps { store: Store; }
|
||||
|
||||
export const attachAppToDom = () => {
|
||||
attachToRoot(RootComponent, { store: _store });
|
||||
// tslint:disable-next-line:no-any
|
||||
_store.dispatch(ready() as any);
|
||||
attachToRoot(RootComponent, { store: _store });
|
||||
// tslint:disable-next-line:no-any
|
||||
_store.dispatch(ready() as any);
|
||||
};
|
||||
|
||||
interface RootComponentState {
|
||||
Route: React.ComponentType;
|
||||
ChildRoute?: React.ComponentType;
|
||||
Route: React.ComponentType;
|
||||
ChildRoute?: React.ComponentType;
|
||||
}
|
||||
|
||||
export class RootComponent extends React.Component<RootComponentProps, RootComponentState> {
|
||||
state: RootComponentState = { Route: () => <div>Loading...</div> };
|
||||
state: RootComponentState = { Route: () => <div>Loading...</div> };
|
||||
|
||||
componentWillMount() {
|
||||
const notLoggedIn = !Session.fetchStoredToken();
|
||||
const currentLocation = history.getCurrentLocation().pathname;
|
||||
const restrictedArea = currentLocation.includes("/app");
|
||||
(notLoggedIn && restrictedArea && Session.clear());
|
||||
}
|
||||
|
||||
changeRoute =
|
||||
(Route: React.ComponentType, ChildRoute?: React.ComponentType) => {
|
||||
this.setState({ Route: Route, ChildRoute });
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const main_routes = UNBOUND_ROUTES.map(bindTo => bindTo(this.changeRoute));
|
||||
new Router(main_routes).enableHtml5Routing("/app").init();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { Route } = this.state;
|
||||
const { ChildRoute } = this.state;
|
||||
const props = ChildRoute ? { children: <ChildRoute /> } : {};
|
||||
try {
|
||||
return <ErrorBoundary>
|
||||
<Provider store={_store}>
|
||||
<App {...{} as App["props"]}>
|
||||
<Route {...props} />
|
||||
</App>
|
||||
</Provider>
|
||||
</ErrorBoundary>;
|
||||
} catch (error) {
|
||||
return <p> Problem loading page.</p>;
|
||||
}
|
||||
UNSAFE_componentWillMount() {
|
||||
const notLoggedIn = !Session.fetchStoredToken();
|
||||
const currentLocation = history.getCurrentLocation().pathname;
|
||||
const restrictedArea = currentLocation.includes("/app");
|
||||
(notLoggedIn && restrictedArea && Session.clear());
|
||||
}
|
||||
|
||||
changeRoute =
|
||||
(Route: React.ComponentType, ChildRoute?: React.ComponentType) => {
|
||||
this.setState({ Route: Route, ChildRoute });
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const main_routes = UNBOUND_ROUTES.map(bindTo => bindTo(this.changeRoute));
|
||||
new Router(main_routes).enableHtml5Routing("/app").init();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { Route } = this.state;
|
||||
const { ChildRoute } = this.state;
|
||||
const props = ChildRoute ? { children: <ChildRoute /> } : {};
|
||||
try {
|
||||
return <ErrorBoundary>
|
||||
<Provider store={_store}>
|
||||
<App {...{} as App["props"]}>
|
||||
<Route {...props} />
|
||||
</App>
|
||||
</Provider>
|
||||
</ErrorBoundary>;
|
||||
} catch (error) {
|
||||
return <p> Problem loading page.</p>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ export const SequenceBackButton = (props: SequenceBackButtonProps) => {
|
|||
|
||||
@connect(mapStateToProps)
|
||||
export class Sequences extends React.Component<Props, {}> {
|
||||
componentWillMount() {
|
||||
UNSAFE_componentWillMount() {
|
||||
if (!this.props.sequence) { setActiveSequenceByName(); }
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,13 @@ describe("Pin tile support functions", () => {
|
|||
}
|
||||
|
||||
it("PIN_MODES", () => {
|
||||
expect(PIN_MODES[0].value).toEqual(1);
|
||||
expect(PIN_MODES[0].label).toEqual("Analog");
|
||||
expect(PIN_MODES()[0].value).toEqual(1);
|
||||
expect(PIN_MODES()[0].label).toEqual("Analog");
|
||||
});
|
||||
|
||||
it("PIN_VALUES", () => {
|
||||
expect(PIN_VALUES[0].value).toEqual(1);
|
||||
expect(PIN_VALUES[0].label).toEqual("ON");
|
||||
expect(PIN_VALUES()[0].value).toEqual(1);
|
||||
expect(PIN_VALUES()[0].label).toEqual("ON");
|
||||
});
|
||||
|
||||
it("currentModeSelection()", () => {
|
||||
|
@ -67,7 +67,7 @@ describe("Pin tile support functions", () => {
|
|||
const p = fakeProps();
|
||||
p.currentStep.args.pin_mode = 0;
|
||||
p.currentStep.args.pin_value = 0;
|
||||
setPinMode(PIN_MODES[0], p);
|
||||
setPinMode(PIN_MODES()[0], p);
|
||||
const step = p.currentStep;
|
||||
mockEditStep.mock.calls[0][0].executor(step);
|
||||
expect(step.args.pin_mode).toEqual(1);
|
||||
|
@ -85,7 +85,7 @@ describe("Pin tile support functions", () => {
|
|||
it("setPinValue()", () => {
|
||||
const p = fakeProps();
|
||||
p.currentStep.args.pin_value = 5;
|
||||
setPinValue(PIN_VALUES[0], p);
|
||||
setPinValue(PIN_VALUES()[0], p);
|
||||
const step = p.currentStep;
|
||||
mockEditStep.mock.calls[0][0].executor(step);
|
||||
expect(step.args.pin_value).toEqual(1);
|
||||
|
|
|
@ -15,12 +15,12 @@ enum PinMode {
|
|||
const isPinMode = (x: any): x is ALLOWED_PIN_MODES =>
|
||||
Object.values(PinMode).includes(x);
|
||||
|
||||
export const PIN_MODES = [
|
||||
export const PIN_MODES = () => [
|
||||
{ value: PinMode.analog, label: t("Analog") },
|
||||
{ value: PinMode.digital, label: t("Digital") }
|
||||
];
|
||||
|
||||
export const PIN_VALUES = [
|
||||
export const PIN_VALUES = () => [
|
||||
{ value: 1, label: t("ON") },
|
||||
{ value: 0, label: t("OFF") }
|
||||
];
|
||||
|
|
|
@ -19,7 +19,7 @@ export function PinMode(props: StepParams) {
|
|||
key={JSON.stringify(props.currentSequence)}
|
||||
onChange={(x) => setPinMode(x, props)}
|
||||
selectedItem={currentModeSelection(props.currentStep)}
|
||||
list={PIN_MODES} />
|
||||
list={PIN_MODES()} />
|
||||
</Col>;
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ export function TileWritePin(props: StepParams) {
|
|||
key={JSON.stringify(props.currentSequence)}
|
||||
onChange={x => setPinValue(x, props)}
|
||||
selectedItem={currentValueSelection(currentStep)}
|
||||
list={PIN_VALUES} />;
|
||||
list={PIN_VALUES()} />;
|
||||
|
||||
const className = "write-pin-step";
|
||||
const { pin_number } = currentStep.args;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { ToolListAndFormProps } from "../interfaces";
|
||||
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
|
@ -73,7 +72,7 @@ export class ToolForm extends React.Component<ToolListAndFormProps, {}> {
|
|||
<Col xs={2}>
|
||||
<button
|
||||
className={`fb-button red ${inSlotClass} del-button`}
|
||||
title={isActive(tool) ? t("in slot") : ""}
|
||||
title={isActive(tool) ? t("in slot") : t("Delete")}
|
||||
onClick={() => dispatch(destroy(tool.uuid))}>
|
||||
<i className="fa fa-times"></i>
|
||||
</button>
|
||||
|
|
|
@ -56,6 +56,7 @@ export function ToolSlotRow(props: ToolSlotRowProps) {
|
|||
<Col xs={1}>
|
||||
<button
|
||||
className="red fb-button del-button"
|
||||
title={t("Delete")}
|
||||
onClick={() => dispatch(destroy(slot.uuid))}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
|
|
Loading…
Reference in New Issue