Farmbot-Web-App/frontend/farmware/state_to_props.ts

141 lines
5.1 KiB
TypeScript

import { Everything } from "../interfaces";
import {
selectAllImages, maybeGetDevice, maybeGetTimeSettings,
} from "../resources/selectors";
import {
FarmwareProps, Feature, SaveFarmwareEnv, UserEnv, ShouldDisplay, BotState,
} from "../devices/interfaces";
import { prepopulateEnv } from "./weed_detector/remote_env/selectors";
import {
selectAllFarmwareEnvs, selectAllFarmwareInstallations,
} from "../resources/selectors_by_kind";
import {
determineInstalledOsVersion,
createShouldDisplayFn,
betterCompact,
} from "../util";
import { ResourceIndex } from "../resources/interfaces";
import { TaggedFarmwareEnv, JobProgress } from "farmbot";
import { save, edit, initSave } from "../api/crud";
import { chain } from "lodash";
import { FarmwareManifestInfo, Farmwares } from "./interfaces";
import { manifestInfo, manifestInfoPending } from "./generate_manifest_info";
import { t } from "../i18next_wrapper";
import { getStatus } from "../connectivity/reducer_support";
import { DevSettings } from "../account/dev/dev_support";
import { getWebAppConfigValue } from "../config_storage/actions";
/** Edit an existing Farmware env variable or add a new one. */
export const saveOrEditFarmwareEnv = (ri: ResourceIndex): SaveFarmwareEnv =>
(key: string, value: string) => (dispatch: Function) => {
const fwEnvLookup: Record<string, TaggedFarmwareEnv> = {};
selectAllFarmwareEnvs(ri)
.map(x => { fwEnvLookup[x.body.key] = x; });
if (Object.keys(fwEnvLookup).includes(key)) {
const fwEnv = fwEnvLookup[key];
dispatch(edit(fwEnv, { value }));
dispatch(save(fwEnv.uuid));
} else {
dispatch(initSave("FarmwareEnv", { key, value }));
}
};
export const isPendingInstallation = (farmware: FarmwareManifestInfo | undefined) =>
!farmware || farmware.installation_pending;
export const reduceFarmwareEnv =
(ri: ResourceIndex): UserEnv => {
const farmwareEnv: UserEnv = {};
selectAllFarmwareEnvs(ri)
.map(x => { farmwareEnv[x.body.key] = "" + x.body.value; });
return farmwareEnv;
};
export const getEnv =
(ri: ResourceIndex, shouldDisplay: ShouldDisplay, bot: BotState) =>
shouldDisplay(Feature.api_farmware_env)
? reduceFarmwareEnv(ri)
: bot.hardware.user_env;
export const getShouldDisplayFn = (ri: ResourceIndex, bot: BotState) => {
const lookupData = bot.minOsFeatureData;
const installed = determineInstalledOsVersion(bot, maybeGetDevice(ri));
const override = DevSettings.overriddenFbosVersion();
const shouldDisplay = createShouldDisplayFn(installed, lookupData, override);
return shouldDisplay;
};
export function mapStateToProps(props: Everything): FarmwareProps {
const images = chain(selectAllImages(props.resources.index))
.sortBy(x => x.body.id)
.reverse()
.value();
const firstImage = images[0];
const currentImage = images
.filter(i => i.uuid === props.resources.consumers.farmware.currentImage)[0]
|| firstImage;
const botStateFarmwares = props.bot.hardware.process_info.farmwares;
const { currentFarmware, firstPartyFarmwareNames, infoOpen } =
props.resources.consumers.farmware;
const shouldDisplay = getShouldDisplayFn(props.resources.index, props.bot);
const env = getEnv(props.resources.index, shouldDisplay, props.bot);
const taggedFarmwareInstallations =
selectAllFarmwareInstallations(props.resources.index);
const namePendingInstall =
(packageName: string | undefined, id: number | undefined): string => {
const nameBase = packageName || `${t("Unknown Farmware")} ${id}`;
const pendingInstall = ` (${t("pending install")}...)`;
return nameBase + pendingInstall;
};
const farmwares: Farmwares = {};
Object.values(botStateFarmwares).map((fm: unknown) => {
const info = manifestInfo(fm);
farmwares[info.name] = manifestInfo(fm);
});
shouldDisplay(Feature.api_farmware_installations) &&
taggedFarmwareInstallations.map(x => {
const n = namePendingInstall(x.body.package, x.body.id);
const alreadyAdded = Object.keys(farmwares).includes(x.body.package || n);
const alreadyInstalled = Object.values(farmwares)
.map(fw => fw.url).includes(x.body.url);
if (x.body.id && !alreadyAdded && !alreadyInstalled) {
farmwares[n] = manifestInfoPending(n, x.body.url);
}
});
const jobs = props.bot.hardware.jobs || {};
const imageJobNames = Object.keys(jobs).filter(x => x != "FBOS_OTA");
const imageJobs: JobProgress[] =
chain(betterCompact(imageJobNames.map(x => jobs[x])))
.sortBy("time")
.reverse()
.value();
const botToMqttStatus = getStatus(props.bot.connectivity.uptime["bot.mqtt"]);
const syncStatus = props.bot.hardware.informational_settings.sync_status;
return {
timeSettings: maybeGetTimeSettings(props.resources.index),
currentFarmware,
farmwares,
botToMqttStatus,
wDEnv: prepopulateEnv(env),
env,
dispatch: props.dispatch,
currentImage,
images,
syncStatus,
getConfigValue: getWebAppConfigValue(() => props),
firstPartyFarmwareNames,
shouldDisplay,
saveFarmwareEnv: saveOrEditFarmwareEnv(props.resources.index),
taggedFarmwareInstallations,
imageJobs,
infoOpen,
};
}