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

114 lines
3.7 KiB
TypeScript
Raw Normal View History

2017-10-05 04:21:06 -06:00
import * as React from "react";
2018-06-21 15:04:21 -06:00
import { Col, BlurableInput } from "../ui/index";
2019-03-20 14:18:19 -06:00
import { Pair, FarmwareConfig } from "farmbot";
2017-10-10 11:59:08 -06:00
import { getDevice } from "../device";
2018-11-01 11:17:18 -06:00
import {
ShouldDisplay, Feature, SaveFarmwareEnv, UserEnv
} from "../devices/interfaces";
2019-02-04 07:32:26 -07:00
import { kebabCase, toString, snakeCase } from "lodash";
2019-03-20 14:18:19 -06:00
import { FarmwareManifestInfo } from "./interfaces";
2019-04-02 13:59:37 -06:00
import { t } from "../i18next_wrapper";
2017-10-05 04:21:06 -06:00
2018-06-21 15:04:21 -06:00
export interface FarmwareFormProps {
2019-03-20 14:18:19 -06:00
farmware: FarmwareManifestInfo;
2019-12-27 11:37:54 -07:00
env: UserEnv;
2018-11-01 11:17:18 -06:00
shouldDisplay: ShouldDisplay;
saveFarmwareEnv: SaveFarmwareEnv;
dispatch: Function;
2019-04-09 19:15:50 -06:00
botOnline: boolean;
2017-10-05 04:21:06 -06:00
}
2018-05-18 16:34:12 -06:00
/** Namespace a Farmware config with the Farmware name. */
export function getConfigEnvName(farmwareName: string, configName: string) {
2019-02-04 07:32:26 -07:00
return `${snakeCase(farmwareName)}_${configName}`;
2018-05-18 16:34:12 -06:00
}
2017-10-10 22:29:12 -06:00
2018-06-21 15:04:21 -06:00
/** Farmware description and version info for help text contents. */
2019-09-23 12:56:35 -06:00
export function farmwareHelpText(farmware: FarmwareManifestInfo | undefined):
string {
2018-06-21 15:04:21 -06:00
if (farmware) {
const description = farmware.meta.description;
const versionString = " (version: " + farmware.meta.version + ")";
return description + versionString;
}
return "";
}
2017-10-10 22:29:12 -06:00
2018-06-21 15:04:21 -06:00
/** Return a div that includes all Farmware input fields. */
export function ConfigFields(props: {
2019-03-20 14:18:19 -06:00
farmware: FarmwareManifestInfo,
2018-11-01 11:17:18 -06:00
getValue: (farmwareName: string, currentConfig: FarmwareConfig) => string,
shouldDisplay: ShouldDisplay,
saveFarmwareEnv: SaveFarmwareEnv,
dispatch: Function,
2018-06-21 15:04:21 -06:00
}): JSX.Element {
/** Set a Farmware input value on FBOS. */
2018-05-18 16:34:12 -06:00
function inputChange(key: string) {
return (e: React.SyntheticEvent<HTMLInputElement>) => {
const value = e.currentTarget.value;
2018-11-01 11:17:18 -06:00
props.shouldDisplay(Feature.api_farmware_env)
? props.dispatch(props.saveFarmwareEnv(key, value))
: getDevice().setUserEnv({ [key]: value }).catch(() => { });
2018-05-18 16:34:12 -06:00
};
2017-10-10 22:29:12 -06:00
}
2018-06-21 15:04:21 -06:00
const { farmware, getValue } = props;
return <div>
{farmware.config.map(config => {
const configEnvName =
getConfigEnvName(farmware.name, config.name);
return <div key={config.name} id={config.name}>
<label>{config.label}</label>
<BlurableInput type="text"
onCommit={inputChange(configEnvName)}
value={getValue(farmware.name, config)} />
</div>;
})}
</div>;
}
/** Render a form with Farmware input fields. */
export function FarmwareForm(props: FarmwareFormProps): JSX.Element {
/** Get a Farmware input value from FBOS. */
2017-10-10 22:29:12 -06:00
function getValue(farmwareName: string, currentConfig: FarmwareConfig) {
2019-12-27 11:37:54 -07:00
return (env[getConfigEnvName(farmwareName, currentConfig.name)]
2019-02-04 07:32:26 -07:00
|| toString(currentConfig.value));
2017-10-10 22:29:12 -06:00
}
2018-06-21 15:04:21 -06:00
/** Execute a Farmware using the provided inputs. */
2017-10-10 22:29:12 -06:00
function run(farmwareName: string, config: FarmwareConfig[]) {
const pairs = config.map<Pair>((x) => {
2018-05-18 16:34:12 -06:00
const label = getConfigEnvName(farmwareName, x.name);
2017-10-10 22:29:12 -06:00
const value = getValue(farmwareName, x);
return { kind: "pair", args: { value, label } };
});
getDevice().execScript(farmwareName, pairs).catch(() => { });
2017-10-10 22:29:12 -06:00
}
2019-12-27 11:37:54 -07:00
const { farmware, env } = props;
2018-06-21 15:04:21 -06:00
return <Col key={farmware.name}>
2019-02-04 07:32:26 -07:00
<div className={kebabCase(farmware.name)}>
2018-06-21 15:04:21 -06:00
<button
className="fb-button green farmware-button"
2019-04-09 19:15:50 -06:00
disabled={!props.botOnline}
2018-06-21 15:04:21 -06:00
onClick={() => run(farmware.name, farmware.config)}>
{t("Run")}
</button>
<ConfigFields
farmware={farmware}
2018-11-01 11:17:18 -06:00
getValue={getValue}
shouldDisplay={props.shouldDisplay}
saveFarmwareEnv={props.saveFarmwareEnv}
dispatch={props.dispatch} />
2018-06-21 15:04:21 -06:00
</div>
</Col>;
}
/** Determine if a Farmware has requested inputs. */
2019-03-20 14:18:19 -06:00
export function needsFarmwareForm(farmware: FarmwareManifestInfo): Boolean {
2020-01-03 13:04:45 -07:00
const needsWidget = farmware.config?.length > 0;
2018-06-21 15:04:21 -06:00
return needsWidget;
2017-10-05 04:21:06 -06:00
}