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-09-25 12:40:37 -06:00
|
|
|
selectAllPointGroups,
|
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-09-25 12:40:37 -06:00
|
|
|
TaggedTool, TaggedPoint, TaggedToolSlotPointer, Xyz, Vector3, TaggedPointGroup
|
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";
|
2017-11-28 17:01:35 -07:00
|
|
|
|
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[] {
|
2017-11-28 17:01:35 -07:00
|
|
|
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-11-28 17:01:35 -07:00
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
|
2019-01-13 17:16:22 -07:00
|
|
|
type PointerTypeName = Point["pointer_type"];
|
2019-09-25 12:40:37 -06:00
|
|
|
type DropdownHeadingId =
|
|
|
|
| PointerTypeName
|
|
|
|
| typeof TOOL
|
|
|
|
| "PointGroup"
|
|
|
|
| "Other";
|
2018-12-01 16:27:35 -07:00
|
|
|
|
2018-12-20 20:18:10 -07:00
|
|
|
/** Location selection menu section names. */
|
2018-12-01 16:27:35 -07:00
|
|
|
export const NAME_MAP: Record<DropdownHeadingId, string> = {
|
2018-03-14 19:12:21 -06:00
|
|
|
"GenericPointer": "Map Points",
|
|
|
|
"Plant": "Plants",
|
2020-02-20 19:38:50 -07:00
|
|
|
"ToolSlot": "Slots",
|
2019-04-15 19:23:58 -06:00
|
|
|
"Tool": "Tools and Seed Containers",
|
2019-09-25 12:40:37 -06:00
|
|
|
"PointGroup": "Groups",
|
2019-01-13 16:43:12 -07:00
|
|
|
"Other": "Other",
|
2018-03-14 19:12:21 -06:00
|
|
|
};
|
|
|
|
|
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
|
|
|
|
2020-02-07 16:05:16 -07:00
|
|
|
const points2ddi = (allPoints: TaggedPoint[], pointerType: PointerTypeName) =>
|
|
|
|
allPoints
|
|
|
|
.filter(x => x.body.pointer_type === pointerType)
|
|
|
|
.map(formatPoint)
|
|
|
|
.filter(x => parseInt("" + x.value) > 0);
|
2019-01-13 16:43:12 -07:00
|
|
|
|
2019-09-26 12:45:54 -06:00
|
|
|
export const groups2Ddi = (groups: TaggedPointGroup[]): DropDownItem[] => {
|
2019-09-25 12:40:37 -06:00
|
|
|
return groups
|
|
|
|
.filter(x => x.body.id)
|
|
|
|
.map(x => {
|
2019-09-26 09:23:23 -06:00
|
|
|
return { label: x.body.name, value: "" + x.body.id, headingId: "PointGroup" };
|
2019-09-25 12:40:37 -06:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
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-10-22 10:03:00 -06:00
|
|
|
additionalItems: DropDownItem[], displayGroups?: boolean): DropDownItem[] {
|
2020-02-07 16:05:16 -07:00
|
|
|
const allPoints = selectAllActivePoints(resources);
|
|
|
|
const plantDDI = points2ddi(allPoints, "Plant");
|
|
|
|
const genericPointerDDI = points2ddi(allPoints, "GenericPointer");
|
2019-06-04 16:07:52 -06:00
|
|
|
const toolDDI = activeToolDDIs(resources);
|
2019-10-21 09:47:13 -06:00
|
|
|
return [COORDINATE_DDI()]
|
2019-04-09 22:00:03 -06:00
|
|
|
.concat(additionalItems)
|
|
|
|
.concat(heading("Tool"))
|
2019-04-11 21:17:18 -06:00
|
|
|
.concat(toolDDI)
|
2019-01-13 16:43:12 -07:00
|
|
|
.concat(heading("Plant"))
|
2019-04-11 21:17:18 -06:00
|
|
|
.concat(plantDDI)
|
2019-01-13 16:43:12 -07:00
|
|
|
.concat(heading("GenericPointer"))
|
2019-10-21 09:47:13 -06:00
|
|
|
.concat(genericPointerDDI)
|
2019-10-22 10:03:00 -06:00
|
|
|
.concat(displayGroups ? heading("PointGroup") : [])
|
|
|
|
.concat(displayGroups ? groups2Ddi(selectAllPointGroups(resources)) : []);
|
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)" */
|
2018-11-30 10:06:20 -07:00
|
|
|
export const formatPoint = (p: TaggedPoint): DropDownItem => {
|
2018-03-14 19:12:21 -06:00
|
|
|
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-30 14:24:09 -06:00
|
|
|
};
|
2018-03-14 19:12:21 -06:00
|
|
|
};
|
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
|
|
|
? {
|
2020-02-20 19:38:50 -07:00
|
|
|
x: slot.body.x,
|
2019-06-07 18:26:55 -06:00
|
|
|
y: slot.body.y,
|
|
|
|
z: slot.body.z
|
|
|
|
}
|
2019-06-04 16:07:52 -06:00
|
|
|
: undefined;
|
2020-02-20 19:38:50 -07:00
|
|
|
const gantryMounted = !!slot?.body.gantry_mounted;
|
2019-06-04 16:07:52 -06:00
|
|
|
return {
|
2020-02-20 19:38:50 -07:00
|
|
|
label: dropDownName((name || "Untitled tool"), coordinate, gantryMounted),
|
2019-06-04 16:07:52 -06:00
|
|
|
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. */
|
2020-02-20 19:38:50 -07:00
|
|
|
export function dropDownName(name: string, v?: Record<Xyz, number | undefined>,
|
|
|
|
gantryMounted = false) {
|
2018-03-14 19:12:21 -06:00
|
|
|
let label = name || "untitled";
|
2019-06-07 18:26:55 -06:00
|
|
|
if (v) {
|
|
|
|
const labelFor = (axis: number | undefined) => isNumber(axis) ? axis : "---";
|
2020-02-20 19:38:50 -07:00
|
|
|
const xLabel = gantryMounted ? t("Gantry") : labelFor(v.x);
|
|
|
|
label += ` (${xLabel}, ${labelFor(v.y)}, ${labelFor(v.z)})`;
|
2019-06-07 18:26:55 -06:00
|
|
|
}
|
2018-09-11 12:11:57 -06:00
|
|
|
return capitalize(label);
|
2017-06-29 12:54:02 -06:00
|
|
|
}
|
2019-01-13 16:43:12 -07:00
|
|
|
|
2019-10-01 08:50:17 -06:00
|
|
|
export const ALL_POINT_LABELS = {
|
2019-01-13 16:43:12 -07:00
|
|
|
"Plant": "All plants",
|
|
|
|
"GenericPointer": "All map points",
|
2020-02-20 19:38:50 -07:00
|
|
|
"Tool": "All tools and seed containers",
|
|
|
|
"ToolSlot": "All slots",
|
2019-01-13 16:43:12 -07:00
|
|
|
};
|
|
|
|
|
2019-10-01 08:50:17 -06:00
|
|
|
export type EveryPointType = keyof typeof ALL_POINT_LABELS;
|
2019-01-13 16:43:12 -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 });
|