Farmbot-Web-App/frontend/farmware/farmware_list.tsx

135 lines
4.5 KiB
TypeScript
Raw Normal View History

2018-06-21 15:04:21 -06:00
import * as React from "react";
2019-03-20 14:18:19 -06:00
import { urlFriendly } from "../util";
2018-06-21 15:04:21 -06:00
import { Actions } from "../constants";
import { Farmwares } from "./interfaces";
import { getDevice } from "../device";
import { commandErr } from "../devices/actions";
import { FarmwareConfigMenu } from "./farmware_config_menu";
2018-08-20 16:38:12 -06:00
import { every, Dictionary } from "lodash";
2018-06-21 15:04:21 -06:00
import { Popover, Position } from "@blueprintjs/core";
import { Link } from "../link";
2018-11-09 13:40:36 -07:00
import { ShouldDisplay, Feature } from "../devices/interfaces";
import { initSave } from "../api/crud";
2018-11-05 18:37:09 -07:00
import { TaggedFarmwareInstallation } from "farmbot";
2019-04-02 13:59:37 -06:00
import { t } from "../i18next_wrapper";
2019-04-26 16:11:33 -06:00
import { getFormattedFarmwareName } from "./index";
2018-06-21 15:04:21 -06:00
2018-08-20 16:38:12 -06:00
const DISPLAY_NAMES: Dictionary<string> = {
"Photos": t("Photos"),
"Camera Calibration": t("Camera Calibration"),
"Weed Detector": t("Weed Detector"),
};
2018-06-21 15:04:21 -06:00
/** Farmware list links: selected or unselected. */
const farmwareListItem = (dispatch: Function, current: string | undefined) =>
(farmwareName: string) => {
const click = () => dispatch({
type: Actions.SELECT_FARMWARE,
payload: farmwareName
});
2019-04-26 16:11:33 -06:00
const selected = (farmwareName == getFormattedFarmwareName(current || ""))
2018-06-21 15:04:21 -06:00
|| (!current && farmwareName == "Photos")
? "selected" : "";
2018-08-20 16:38:12 -06:00
const displayName = Object.keys(DISPLAY_NAMES).includes(farmwareName)
? DISPLAY_NAMES[farmwareName]
: farmwareName;
2018-06-21 15:04:21 -06:00
return <Link
to={`/app/farmware/${urlFriendly(farmwareName)}`}
key={farmwareName}
onClick={click}>
2019-09-23 12:56:35 -06:00
<div className={`farmware-list-items ${selected}`}>
2018-08-20 16:38:12 -06:00
<p>{displayName}</p>
2018-06-21 15:04:21 -06:00
</div>
</Link>;
};
export interface FarmwareListProps {
current: string | undefined;
dispatch: Function;
farmwares: Farmwares;
showFirstParty: boolean;
firstPartyFarmwareNames: string[];
2018-11-02 13:53:17 -06:00
shouldDisplay: ShouldDisplay;
2018-11-05 18:37:09 -07:00
installations: TaggedFarmwareInstallation[];
2018-06-21 15:04:21 -06:00
}
interface FarmwareListState {
packageUrl: string;
}
export class FarmwareList
extends React.Component<FarmwareListProps, FarmwareListState> {
state: FarmwareListState = { packageUrl: "" };
2018-11-09 13:40:36 -07:00
clearUrl = () => this.setState({ packageUrl: "" });
2018-06-21 15:04:21 -06:00
install = () => {
2018-11-09 13:40:36 -07:00
const url = this.state.packageUrl;
if (url) {
this.props.shouldDisplay(Feature.api_farmware_installations)
2019-01-09 19:29:01 -07:00
? this.props.dispatch(initSave("FarmwareInstallation",
{ url, package: undefined, package_error: undefined }))
2018-11-09 13:40:36 -07:00
.then(this.clearUrl)
: getDevice()
.installFarmware(url)
.then(this.clearUrl)
.catch(commandErr("Farmware installation"));
2018-06-21 15:04:21 -06:00
} else {
alert(t("Enter a URL"));
}
}
firstPartyFarmwaresPresent = (firstPartyList: string[] | undefined) => {
2019-03-20 14:18:19 -06:00
const farmwareList = Object.values(this.props.farmwares).map(x => x.name);
const allPresent = every(firstPartyList, fw => farmwareList.includes(fw));
2018-06-21 15:04:21 -06:00
return allPresent;
}
render() {
const { current, dispatch, farmwares, showFirstParty, firstPartyFarmwareNames
} = this.props;
2019-03-20 14:18:19 -06:00
const listed1stPartyNames =
["take-photo", "camera-calibration", "plant-detection"];
const farmwareNames = Object.values(farmwares).map(fw => fw.name)
.filter(x => showFirstParty || !firstPartyFarmwareNames.includes(x))
.filter(x => !listed1stPartyNames.includes(x));
2018-06-21 15:04:21 -06:00
2019-12-30 09:09:34 -07:00
return <div className="farmware-list-panel-contents">
2018-06-21 15:04:21 -06:00
<div className="farmware-settings-menu">
<Popover position={Position.BOTTOM_RIGHT}>
2018-09-14 12:54:14 -06:00
<i className="fa fa-gear dark" />
2018-06-21 15:04:21 -06:00
<FarmwareConfigMenu
show={this.props.showFirstParty}
2018-11-02 13:53:17 -06:00
shouldDisplay={this.props.shouldDisplay}
2018-06-21 15:04:21 -06:00
dispatch={this.props.dispatch}
firstPartyFwsInstalled={
this.firstPartyFarmwaresPresent(
this.props.firstPartyFarmwareNames)} />
</Popover>
</div>
2019-04-26 16:11:33 -06:00
{Object.keys(DISPLAY_NAMES).map(farmwareListItem(dispatch, current))}
2018-06-21 15:04:21 -06:00
<hr />
<label>
{t("My Farmware")}
</label>
2019-03-20 14:18:19 -06:00
{farmwareNames.map(farmwareListItem(dispatch, current))}
2018-06-21 15:04:21 -06:00
<hr />
<label>
{t("Install new Farmware")}
</label>
<fieldset>
2020-02-28 09:34:28 -07:00
<input type="url" name="url"
2018-06-21 15:04:21 -06:00
placeholder={"https://...."}
value={this.state.packageUrl || ""}
onChange={e => this.setState({ packageUrl: e.currentTarget.value })} />
<button
className="fb-button green"
2020-02-28 09:34:28 -07:00
title={t("install Farmware")}
2018-06-21 15:04:21 -06:00
onClick={this.install}>
{t("Install")}
</button>
</fieldset>
</div>;
}
}