Farmbot-Web-App/frontend/sequences/locals_list/location_form_list.ts

151 lines
4.8 KiB
TypeScript
Raw Normal View History

2019-01-13 17:16:22 -07:00
import { ResourceIndex } from "../../resources/interfaces";
2017-06-29 12:54:02 -06:00
import {
2018-09-20 13:59:13 -06:00
selectAllToolSlotPointers,
2019-06-04 16:07:52 -06:00
selectAllActivePoints,
maybeFindToolById,
2019-01-13 17:16:22 -07:00
} from "../../resources/selectors";
import { betterCompact } from "../../util";
2019-06-04 16:07:52 -06:00
import {
2019-06-21 15:46:11 -06:00
TaggedTool, TaggedPoint, TaggedToolSlotPointer, Xyz, Vector3
2019-06-04 16:07:52 -06:00
} from "farmbot";
2019-01-13 17:16:22 -07:00
import { DropDownItem } from "../../ui";
2019-06-07 18:26:55 -06:00
import { capitalize, isNumber } from "lodash";
2019-01-13 17:16:22 -07:00
import { Point } from "farmbot/dist/resources/api_resources";
2019-04-02 13:59:37 -06:00
import { t } from "../../i18next_wrapper";
2019-01-13 17:16:22 -07:00
const TOOL: "Tool" = "Tool";
2018-12-20 20:18:10 -07:00
/** Return tool and location for all tools currently in tool slots. */
2019-06-04 16:07:52 -06:00
export function activeToolDDIs(resources: ResourceIndex): DropDownItem[] {
const slots = selectAllToolSlotPointers(resources);
return betterCompact(slots
2019-06-04 16:07:52 -06:00
.map(slot => {
const tool = maybeFindToolById(resources, slot.body.tool_id);
if (tool) { return formatTool(tool, slot); }
2018-12-20 20:18:10 -07:00
}))
2019-06-04 16:07:52 -06:00
.filter(x => parseInt("" + x.value) > 0);
}
2017-06-29 12:54:02 -06:00
2019-01-13 17:16:22 -07:00
type PointerTypeName = Point["pointer_type"];
2019-01-13 16:43:12 -07:00
type DropdownHeadingId = PointerTypeName | typeof TOOL | "Other";
2018-12-20 20:18:10 -07:00
/** Location selection menu section names. */
export const NAME_MAP: Record<DropdownHeadingId, string> = {
"GenericPointer": "Map Points",
"Plant": "Plants",
"ToolSlot": "Tool Slots",
"Tool": "Tools and Seed Containers",
2019-01-13 16:43:12 -07:00
"Other": "Other",
};
2019-02-06 18:36:11 -07:00
const heading = (name: DropdownHeadingId): DropDownItem[] => ([{
2019-01-13 16:43:12 -07:00
label: t(NAME_MAP[name]),
heading: true,
value: 0,
headingId: name
2019-02-06 18:36:11 -07:00
}]);
2019-01-13 16:43:12 -07:00
const ddiFrom = (points: TaggedPoint[], pointerType: PointerTypeName) => points
.filter(x => x.body.pointer_type === pointerType)
.map(formatPoint)
.filter(x => parseInt("" + x.value) > 0);
const maybeGroup = (display: boolean) =>
(groupDDI: DropDownItem): DropDownItem[] =>
display ? [groupDDI] : [];
2018-12-20 20:18:10 -07:00
/** Location selection menu items. */
2019-01-16 19:24:59 -07:00
export function locationFormList(resources: ResourceIndex,
2019-01-13 16:43:12 -07:00
additionalItems: DropDownItem[], displayGroups?: boolean): DropDownItem[] {
2019-01-16 19:24:59 -07:00
const points = selectAllActivePoints(resources)
2019-01-13 16:43:12 -07:00
.filter(x => x.body.pointer_type !== "ToolSlot");
const plantDDI = ddiFrom(points, "Plant");
const genericPointerDDI = ddiFrom(points, "GenericPointer");
2019-06-04 16:07:52 -06:00
const toolDDI = activeToolDDIs(resources);
2019-01-13 16:43:12 -07:00
const group = maybeGroup(!!displayGroups);
2019-04-09 22:00:03 -06:00
return [COORDINATE_DDI()]
.concat(additionalItems)
.concat(heading("Tool"))
2019-01-13 16:43:12 -07:00
.concat(group(everyPointDDI("Tool")))
.concat(group(everyPointDDI("ToolSlot")))
2019-04-11 21:17:18 -06:00
.concat(toolDDI)
2019-01-13 16:43:12 -07:00
.concat(heading("Plant"))
.concat(group(everyPointDDI("Plant")))
2019-04-11 21:17:18 -06:00
.concat(plantDDI)
2019-01-13 16:43:12 -07:00
.concat(heading("GenericPointer"))
2019-04-11 21:17:18 -06:00
.concat(group(everyPointDDI("GenericPointer")))
.concat(genericPointerDDI);
2017-06-29 12:54:02 -06:00
}
2018-12-20 20:18:10 -07:00
/** Create drop down item with label; i.e., "Point/Plant (1, 2, 3)" */
export const formatPoint = (p: TaggedPoint): DropDownItem => {
const { id, name, pointer_type, x, y, z } = p.body;
return {
label: dropDownName(name, { x, y, z }),
value: "" + id,
2018-11-30 12:31:10 -07:00
headingId: pointer_type
};
};
2017-06-29 12:54:02 -06:00
2018-12-20 20:18:10 -07:00
/** Create drop down item with label; i.e., "Tool (1, 2, 3)" */
2019-06-04 16:07:52 -06:00
export const formatTool =
(tool: TaggedTool, slot: TaggedToolSlotPointer | undefined): DropDownItem => {
const { id, name } = tool.body;
const coordinate = slot
2019-06-07 18:26:55 -06:00
? {
x: slot.body.gantry_mounted ? undefined : slot.body.x,
y: slot.body.y,
z: slot.body.z
}
2019-06-04 16:07:52 -06:00
: undefined;
return {
label: dropDownName((name || "Untitled tool"), coordinate),
value: "" + id,
headingId: TOOL
};
2017-06-29 12:54:02 -06:00
};
/** Uniformly generate a label for things that have an X/Y/Z value. */
2019-06-07 18:26:55 -06:00
export function dropDownName(name: string, v?: Record<Xyz, number | undefined>) {
let label = name || "untitled";
2019-06-07 18:26:55 -06:00
if (v) {
const labelFor = (axis: number | undefined) => isNumber(axis) ? axis : "---";
label += ` (${labelFor(v.x)}, ${labelFor(v.y)}, ${labelFor(v.z)})`;
}
return capitalize(label);
2017-06-29 12:54:02 -06:00
}
2019-01-13 16:43:12 -07:00
export const EVERY_POINT_LABEL = {
"Plant": "All plants",
"GenericPointer": "All map points",
"Tool": "All tools",
"ToolSlot": "All tool slots",
};
export type EveryPointType = keyof typeof EVERY_POINT_LABEL;
const isEveryPointType = (x: string): x is EveryPointType =>
Object.keys(EVERY_POINT_LABEL).includes(x);
export const safeEveryPointType = (x: string): EveryPointType => {
if (isEveryPointType(x)) {
return x;
} else {
throw new Error(`'${x}' is not of type EveryPointType`);
}
};
2019-01-16 18:51:25 -07:00
export const everyPointDDI = (value: EveryPointType): DropDownItem =>
2019-01-16 19:24:59 -07:00
({ value, label: t(EVERY_POINT_LABEL[value]), headingId: "every_point" });
2019-01-16 18:51:25 -07:00
2019-06-21 15:46:11 -06:00
export const COORDINATE_DDI = (vector?: Vector3): DropDownItem => ({
label: vector
? `${t("Coordinate")} (${vector.x}, ${vector.y}, ${vector.z})`
: t("Custom Coordinates"),
value: vector ? JSON.stringify(vector) : "",
headingId: "Coordinate"
});
2019-01-16 18:51:25 -07:00
2019-01-16 19:24:59 -07:00
export const NO_VALUE_SELECTED_DDI = (): DropDownItem =>
({ label: t("Select a location"), value: "", isNull: true });