diff --git a/webpack/sequences/__tests__/locals_list_test.tsx b/webpack/sequences/__tests__/locals_list_test.tsx
index d85b255ab..f678d0859 100644
--- a/webpack/sequences/__tests__/locals_list_test.tsx
+++ b/webpack/sequences/__tests__/locals_list_test.tsx
@@ -5,9 +5,6 @@ import {
} from "../locals_list";
import {
VariableDeclaration,
- ParameterDeclaration,
- Tool,
- Point,
Coordinate
} from "farmbot";
import {
@@ -23,12 +20,7 @@ import {
InputBox, generateList, handleSelect
} from "../step_tiles/tile_move_absolute/index";
import {
- extractParent,
- setParent,
- guessFromDataType,
- guessVecFromLabel,
ParentVariableFormProps,
- PARENT,
LocalsListProps,
} from "../locals_list_support";
import { DELETE_ME_LATER } from "../../resources/interfaces";
@@ -36,7 +28,6 @@ import { DELETE_ME_LATER } from "../../resources/interfaces";
const coord: Coordinate = { kind: "coordinate", args: { x: 1, y: 2, z: 3 } };
const t = fakeTool();
t.body.id = 5;
-const tool: Tool = { kind: "tool", args: { tool_id: t.body.id } };
const mrGoodVar: VariableDeclaration = {
// https://en.wikipedia.org/wiki/Mr._Goodbar
kind: "variable_declaration",
@@ -53,162 +44,10 @@ const fakeProps = (): LocalsListProps => {
};
};
-describe("extractParent()", () => {
- const irrelevant: VariableDeclaration = {
- kind: "variable_declaration",
- args: { label: "nope", data_value: coord }
- };
-
- const paramDeclr: ParameterDeclaration = {
- kind: "parameter_declaration",
- args: { label: "parent", data_type: "coordinate" }
- };
-
- it("returns undefined on empty arrays", () => {
- expect(extractParent([])).toBeUndefined();
- expect(extractParent()).toBeUndefined();
- });
-
- it("returns undefined on arrays that don't have a parent", () => {
- expect(extractParent([irrelevant])).toBeUndefined();
- });
-
- it("returns parent if it is a PARAMETER declaration.", () => {
- const result = extractParent([paramDeclr]);
- expect(result).toBeDefined();
- expect(result).toBe(paramDeclr);
- });
-
- it("returns the first result found", () => {
- const paramIsFirst = [paramDeclr, mrGoodVar, irrelevant];
- const r1 = extractParent(paramIsFirst);
- if (r1) {
- expect(r1.kind).toBe("parameter_declaration");
- expect(r1.args.label).toBe("parent");
- } else {
- fail();
- }
-
- const varIsFirst = [irrelevant, mrGoodVar, paramDeclr];
- const r2 = extractParent(varIsFirst);
- if (r2) {
- expect(r2.kind).toBe("variable_declaration");
- expect(r2.args.label).toBe("parent");
- } else {
- fail();
- }
- });
-});
-
-describe("setParent()", () => {
- const point: Point = {
- kind: "point",
- args: { pointer_type: "point", pointer_id: 5 }
- };
-
- it("deals with parameter declarations", () => {
- const data_value: ParameterDeclaration = {
- kind: "parameter_declaration", args: { label: "---", data_type: "point" }
- };
- const sequence = fakeSequence();
- const expected = {
- kind: "scope_declaration",
- args: {},
- body: [{
- kind: "parameter_declaration",
- args: { label: "parent", data_type: "point" }
- }]
- };
- const result = setParent(sequence, data_value);
- const actual = result.args.locals;
-
- expect(actual.args).toEqual(expected.args);
- expect(actual.body).toEqual(expected.body);
- expect(actual.kind).toEqual(expected.kind);
- });
-
- it("crashes on `identifier` nodes (no re-binding of vars yet)", () => {
- const seq = fakeSequence();
- const cb = () =>
- setParent(seq, { kind: "identifier", args: { label: "foo" } });
- expect(cb).toThrow();
- });
-
- it("sets tools, points and coordinates as new `parent` var", () => {
- const seq = fakeSequence();
- [tool, point, coord].map(item => {
- const result = setParent(seq, item).args.locals.body || [];
- expect(result.length).toEqual(1);
- const parent = result[0];
- expect(parent.args.label).toEqual("parent");
- expect(parent.kind).toEqual("variable_declaration");
- (parent.kind === "variable_declaration") &&
- expect(parent.args.data_value).toBe(item);
- });
- });
-});
-
-describe("guessFromDataType()", () => {
- it("returns undefined if not coord", () => {
- expect(guessFromDataType(tool)).toBe(undefined);
- });
-
- it("returns coord.args", () => {
- expect(guessFromDataType(coord)).toBe(coord.args);
- });
-});
-
-describe("guessVecFromLabel()", () => {
- it("returns undefined on malformed strings", () => {
- [
- "",
- "))((1,(),2,3)",
- " ()()()",
- "Alphabetical (a, b, c)",
- "tool 1,2,3",
- "Something else (test123)",
- "Tool_1512679072 ",
- "Tool"
- ].map(bad => {
- expect(guessVecFromLabel(bad)).toBeUndefined();
- });
- });
- it("returns vec3 on well formed strings", () => {
- [
- {
- string: "Point_1512679072 (20, 50, 0)",
- expectation: { x: 20, y: 50, z: 0 }
- },
- {
- string: "carrot (360, 290, 0)",
- expectation: { x: 360, y: 290, z: 0 }
- },
- {
- string: "Safe-Remove Weed (633, 450, 0)",
- expectation: { x: 633, y: 450, z: 0 }
- },
- {
- string: "Point_1512679072 (0, 100, 0)",
- expectation: { x: 0, y: 100, z: 0 }
- }
- ].map(xmp => {
- const result = guessVecFromLabel(xmp.string);
- if (result) {
- expect(result.x).toBe(xmp.expectation.x);
- expect(result.y).toBe(xmp.expectation.y);
- expect(result.y).toBe(xmp.expectation.y);
- } else {
- fail("No result obtained.");
- }
- });
- });
-});
-
describe("", () => {
it("renders correct UI components", () => {
const props: ParentVariableFormProps = {
- betterParent: DELETE_ME_LATER,
- deprecatedParent: mrGoodVar,
+ parent: DELETE_ME_LATER,
sequence: fakeSequence(),
resources: buildResourceIndex().index,
onChange: jest.fn()
@@ -221,7 +60,7 @@ describe("", () => {
expect(selects.length).toBe(1);
const p = selects.first().props();
expect(p.allowEmpty).toBe(true);
- const choices = generateList(props.resources, [PARENT]);
+ const choices = generateList(props.resources, []);
expect(p.list).toEqual(choices);
const choice = choices[1];
p.onChange(choice);
diff --git a/webpack/sequences/locals_list.tsx b/webpack/sequences/locals_list.tsx
index aace00dc2..3b28e14e1 100644
--- a/webpack/sequences/locals_list.tsx
+++ b/webpack/sequences/locals_list.tsx
@@ -1,15 +1,12 @@
import * as React from "react";
-import {
- ParentVariableFormProps,
- PARENT,
- LocalsListProps
-} from "./locals_list_support";
import { Row, Col, FBSelect } from "../ui";
import { t } from "i18next";
import {
generateList
} from "./step_tiles/tile_move_absolute/generate_list";
import { InputBox } from "./step_tiles/tile_move_absolute/input_box";
+import { handleSelect } from "./step_tiles/tile_move_absolute/handle_select";
+import { ParentVariableFormProps, LocalsListProps, PARENT } from "./locals_list_support";
const REWRITE_THIS = () => {
console.error("Re write this callback, OK? RC");
@@ -19,9 +16,9 @@ const REWRITE_THIS = () => {
* Allows the user to chose the value of the `parent` variable, etc. */
export const ParentVariableForm =
(props: ParentVariableFormProps) => {
- const { sequence, resources } = props;
- const { x, y, z } = props.betterParent.location;
- const isDisabled = !props.betterParent.editable;
+ const { sequence, resources, onChange } = props;
+ const { x, y, z } = props.parent.location;
+ const isDisabled = !props.parent.editable;
return
@@ -31,11 +28,12 @@ export const ParentVariableForm =
key={JSON.stringify(sequence)}
allowEmpty={true}
list={generateList(resources, [PARENT])}
- selectedItem={props.betterParent.dropdown}
- onChange={(x) => {
- console.log("REIMPLEMENT ME:");
- console.dir(x);
- } />
+ selectedItem={props.parent.dropdown}
+ onChange={(ddi) => {
+ console.error("FINISH ME");
+ handleSelect(props.resources, ddi);
+ onChange({ x: -23, y: -23, z: -23 });
+ }} />
@@ -73,11 +71,10 @@ export const ParentVariableForm =
/** List of local variable declarations for a sequence. If no variables are
* found, shows nothing. */
export const LocalsList = (props: LocalsListProps) => {
- const betterParent = props.variableData["parent"];
- return betterParent
+ const parent = props.variableData["parent"];
+ return parent
?
diff --git a/webpack/sequences/locals_list_support.ts b/webpack/sequences/locals_list_support.ts
index 219e3977b..15fa5494f 100644
--- a/webpack/sequences/locals_list_support.ts
+++ b/webpack/sequences/locals_list_support.ts
@@ -1,18 +1,11 @@
import {
- ParameterDeclaration,
- VariableDeclaration,
+ TaggedSequence,
Vector3,
- ScopeDeclarationBodyItem
} from "farmbot";
import { ResourceIndex, VariableNameSet } from "../resources/interfaces";
-import { CeleryVariable } from "./step_tiles/tile_move_absolute/index";
-import { TaggedSequence } from "farmbot";
-import { defensiveClone } from "../util";
-import { isNaN } from "lodash";
import { SequenceMeta } from "../resources/sequence_meta";
type OnChange = (data_type: Vector3) => void;
-type DataValue = VariableDeclaration["args"]["data_value"];
export interface LocalsListProps {
variableData: VariableNameSet;
@@ -22,8 +15,7 @@ export interface LocalsListProps {
}
export interface ParentVariableFormProps {
- betterParent: SequenceMeta;
- deprecatedParent: VariableDeclaration | ParameterDeclaration;
+ parent: SequenceMeta;
sequence: TaggedSequence;
resources: ResourceIndex;
onChange: OnChange;
@@ -32,88 +24,7 @@ export interface ParentVariableFormProps {
export const PARENT =
({ value: "parent", label: "Parent", headingId: "parameter" });
-const KINDS = ["parameter_declaration", "variable_declaration"];
-/** Given an array of variable declarations (or undefined), finds the "parent"
- * special identifier */
export const extractParent =
- (list?: ScopeDeclarationBodyItem[]): ScopeDeclarationBodyItem | undefined => {
- const p = (list ? list : []).filter(x => {
- const isParent = x.args.label === "parent";
- const isVar = KINDS.includes(x.kind);
- return isVar && isParent;
- })[0];
- switch (p && p.kind) {
- case "variable_declaration":
- case "parameter_declaration":
- return p;
- default:
- return undefined;
- }
- };
-
-/** Takes a sequence and data_value. Turn the data_value into the sequence's new
- * `parent` variable. This is a _pure function_. */
-export const setParent =
- (sequence: TaggedSequence, data_value: CeleryVariable) => {
- const nextSeq: typeof sequence.body = defensiveClone(sequence.body);
- switch (data_value.kind) {
- case "tool":
- case "point":
- case "coordinate":
- nextSeq.args.locals = {
- kind: "scope_declaration",
- args: {},
- body: [
- {
- kind: "variable_declaration",
- args: {
- label: "parent",
- data_value
- }
- }
- ]
- };
- break;
- case "parameter_declaration":
- nextSeq.args.locals = {
- kind: "scope_declaration",
- args: {},
- body: [{
- kind: "parameter_declaration",
- args: { label: "parent", data_type: "point" }
- }]
- };
- break;
- default:
- throw new Error("Bad kind in setParent(): " + data_value.kind);
- }
- return nextSeq;
- };
-
-/** If variable is a coordinate, just use the coordinates. */
-export const guessFromDataType =
- (x: DataValue): Vector3 | undefined => (x.kind === "coordinate") ?
- x.args : undefined;
-
-/** GLORIOUS hack: We spend a *lot* of time in the sequence editor looking up
-* resource x/y/z. It's resource intensive and often hard to understand.
-* Instead of adding more selectors and complexity, we make a "best effort"
-* attempt to read the resource's `x`, `y`, `z` that are cached (as strings)
-* in the drop down label.
-*
-* String manipulation is bad, but I think it is warranted here: */
-export const guessVecFromLabel =
- (label: string): Vector3 | undefined => {
- const step1 = label
- .trim()
- .replace(")", "")
- .replace(/^\s+|\s+$/g, "")
- .split(/\(|\,/);
- const vec = step1
- .slice(Math.max(step1.length - 3, 1))
- .map(x => parseInt(x, 10))
- .filter(x => !isNaN(x));
-
- return (vec.length === 3) ?
- { x: vec[0], y: vec[1], z: vec[2] } : undefined;
+ (i: ResourceIndex, uuid: string): SequenceMeta | undefined => {
+ return (i.sequenceMetas[uuid] || {}).parent;
};
diff --git a/webpack/sequences/sequence_editor_middle_active.tsx b/webpack/sequences/sequence_editor_middle_active.tsx
index a024bc4e3..a7b06bc22 100644
--- a/webpack/sequences/sequence_editor_middle_active.tsx
+++ b/webpack/sequences/sequence_editor_middle_active.tsx
@@ -96,11 +96,12 @@ const SequenceHeader = (props: SequenceHeaderProps) => {
export class SequenceEditorMiddleActive extends
React.Component {
get stepSectionHeight() {
+ const { resources, sequence } = this.props;
const variable = this.props.shouldDisplay(Feature.variables)
- ? !!extractParent(this.props.sequence.body.args.locals.body)
- : false;
+ ? !!extractParent(resources, sequence.uuid) : false;
return `calc(100vh - ${variable ? "38" : "25"}rem)`;
}
+
render() {
const { dispatch, sequence } = this.props;
return