farmbot-web-frontend
Version:
Farmbot web frontend.
106 lines (95 loc) • 3.48 kB
text/typescript
import * as Axios from "axios";
import { error } from "../logger";
import { Plant } from "./interfaces";
import { Thunk } from "../interfaces"
import { CropSearchResult, OpenFarm } from "./openfarm";
import { t } from "i18next";
const PLANT_URL = "/api/plants";
export function fetchPlants(baseUrl: string): Thunk {
let url = baseUrl + PLANT_URL;
return function (dispatch , getState) {
dispatch({ type: "FETCH_PLANTS_START" });
return Axios.get<Plant[]>(url)
.then((resp) => {
let payload = resp.data;
dispatch({ type: "FETCH_PLANTS_OK", payload });
})
.catch((payload) => {
error(t("Tried to download plants, but couldn't."));
dispatch({ type: "FETCH_PLANTS_ERR", payload });
});
};
};
export function savePlant(plant: Plant, baseUrl: string): Thunk {
let url = baseUrl + PLANT_URL;
return function (dispatch, getState) {
dispatch({ type: "SAVE_PLANT_START" });
return Axios.post<Plant>(url, plant)
.then((resp) => {
// so that no persisted data sticks around.
let payload: Plant = _.assign({}, plant, resp.data) as Plant;
dispatch({ type: "SAVE_PLANT_OK", payload });
})
.catch((payload) => {
error(t("Tried to save plant, but couldn't."));
dispatch({ type: "SAVE_PLANT_ERR", payload });
});
};
};
export function destroyPlant(plant: Plant, baseUrl: string): Thunk {
let url = baseUrl + PLANT_URL + "/" + plant.id;
return function (dispatch, getState) {
dispatch({ type: "DESTROY_PLANT_START" });
return Axios.delete<Plant>(url)
.then((resp) => {
let payload = plant;
dispatch({ type: "DESTROY_PLANT_OK", payload });
})
.catch((payload) => {
error(t("Tried to delete plant, but couldn't."));
dispatch({ type: "DESTROY_PLANT_ERR", payload });
});
};
};
let STUB_IMAGE = "http://placehold.it/200x150";
let url = (q: string) => `${OpenFarm.cropUrl}?include=pictures&filter=${q}`;
// If we do a search on keypress, we will DDoS OpenFarm.
// This function prevents that from happening by pausing X ms
// per keystroke.
let _openFarmSearchQuery = _.throttle((q: string) => Axios.get<CropSearchResult>(url(q)), 1500);
/** Search openfarm for crops. This is a throttled function, useful for live search. */
export function openFarmSearchQuery(query: string) { // TODO make less smelly
return function(dispatch: Function) {
dispatch({
type: "SEARCH_QUERY_CHANGE",
payload: query
});
return _openFarmSearchQuery(query)
.then((resp) => {
// Pluck ID and URL of user-submitted OpenFarm crops...
// EG: => { X1y3ZAA: "cabbage.png" }
let images: { [key: string]: string } = {};
_.get<OpenFarm.Included[]>(resp, "data.included", [])
.map(function (item) {
return {
id: item.id,
url: item.attributes.thumbnail_url
};
})
.map((val, acc) => images[val.id] = val.url);
let payload = resp
.data
.data
.map(function (datum) {
let crop = datum.attributes;
let id = _.get<string>(datum, "relationships.pictures.data[0].id");
return { crop, image: (images[id] || STUB_IMAGE) };
});
dispatch({
type: "OF_SEARCH_RESULTS_OK",
payload
});
})
.catch(function (error) { console.warn(error); });
};
};