From ccc813e8662f89eef1edd5eb414769002051fa7a Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Fri, 7 Jul 2017 08:37:21 -0500 Subject: [PATCH] Possible fix for move_abs / exec_seq bugs? --- src/resources/reducer.ts | 14 +++++++--- .../sequence_editor_middle_active.tsx | 27 +++++++++---------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/resources/reducer.ts b/src/resources/reducer.ts index 719ec5ece..3b4a5cc38 100644 --- a/src/resources/reducer.ts +++ b/src/resources/reducer.ts @@ -6,7 +6,8 @@ import { TaggedResource, ResourceName, sanityCheck, - isTaggedResource + isTaggedResource, + TaggedSequence } from "./tagged_resources"; import { generateUuid, arrayWrap } from "./util"; import { EditResourceParams } from "../api/interfaces"; @@ -31,6 +32,7 @@ import { farmwareState } from "../farmware/reducer"; import { Actions } from "../constants"; +import { uuid as rando } from "farmbot/dist"; let consumerReducer = combineReducers({ regimens, @@ -71,7 +73,7 @@ export function emptyState(): RestResources { let initialState: RestResources = emptyState(); -let afterEach = (state: RestResources, a: ReduxAction) => { +let afterEach = (state: RestResources, a: ReduxAction) => { state.consumers = consumerReducer({ sequences: state.consumers.sequences, regimens: state.consumers.regimens, @@ -93,7 +95,7 @@ export let resourceReducer = generateReducer let cropInfo = crop.data.attributes; addToIndex(s.index, kind, cropInfo, generateUuid(undefined, kind)); } - }) + }); return s; }) .add(Actions.SAVE_RESOURCE_OK, (s, { payload }) => { @@ -183,6 +185,7 @@ export let resourceReducer = generateReducer original.dirty = true; sanityCheck(original); payload && isTaggedResource(original); + if (original.kind === "sequences") { setStepUuid(original); } return s; }) .add("INIT_RESOURCE", (s, { payload }) => { @@ -272,7 +275,7 @@ function removeFromIndex(index: ResourceIndex, tr: TaggedResource) { } function whoops(origin: string, kind: string) { - let msg = `${origin}/${kind}: No handler written for this one yet.` + let msg = `${origin}/${kind}: No handler written for this one yet.`; throw new Error(msg); } @@ -289,3 +292,6 @@ function reindexResource(i: ResourceIndex, r: TaggedResource) { removeFromIndex(i, r); addToIndex(i, r.kind, r.body, r.uuid); } + +let setStepUuid = (s: TaggedSequence) => (s.body.body || []) + .map(x => _.set(x, "uuid", rando())); diff --git a/src/sequences/sequence_editor_middle_active.tsx b/src/sequences/sequence_editor_middle_active.tsx index 7b8715b5f..37257357b 100644 --- a/src/sequences/sequence_editor_middle_active.tsx +++ b/src/sequences/sequence_editor_middle_active.tsx @@ -16,19 +16,20 @@ import { TaggedSequence } from "../resources/tagged_resources"; import { save, edit, destroy } from "../api/crud"; import { GetState } from "../redux/interfaces"; import { ToolTips } from "../constants"; +import { get } from "lodash"; -let onDrop = (index: number, dispatch: Function, sequence: TaggedSequence) => +let onDrop = (index: number, dispatch1: Function, sequence: TaggedSequence) => (key: string) => { - dispatch(function (dispatch: Function, getState: GetState) { - let dataXferObj = dispatch(stepGet(key)); + dispatch1(function (dispatch2: Function, getState: GetState) { + let dataXferObj = dispatch2(stepGet(key)); let step = dataXferObj.value; switch (dataXferObj.intent) { case "step_splice": - return dispatch(splice({ step, sequence, index })); + return dispatch2(splice({ step, sequence, index })); case "step_move": let action = move({ step, sequence, to: index, from: dataXferObj.draggerId }); - return dispatch(action); + return dispatch2(action); default: throw new Error("Got unexpected data transfer object."); } @@ -98,23 +99,21 @@ export class SequenceEditorMiddleActive { - dispatch(edit(sequence, { name: e.currentTarget.value })) + dispatch(edit(sequence, { name: e.currentTarget.value })); }} /> editCurrentSequence(dispatch, sequence, { color })} /> {(sequence.body.body || []).map((currentStep: SequenceBodyItem, index, arr) => { - /** HACK: If we wrote `key={index}` for this iterator, React's diff - * algorithm (probably?) loses track of which step has changed (and - * sometimes even mix up the state of completely different steps). + /** HACK: React's diff algorithm (probably?) can't keep track of steps + * via `index` alone- the content is too dynamic (copy/splice/pop/push) * To get around this, we add a `uuid` property to Steps that - * is guaranteed to be unique and allows React to diff the list - * correctly. - */ - let wow = (currentStep as any).uuid || index; + * is guaranteed to be unique no matter where the step gets moved and + * allows React to diff the list correctly. */ + let readThatCommentAbove = get(currentStep, "uuid", index); let currentSequence = sequence; - return
+ return