Possible fix for move_abs / exec_seq bugs?

pull/338/head
Rick Carlino 2017-07-07 08:37:21 -05:00
parent 6dafdaed7e
commit ccc813e866
2 changed files with 23 additions and 18 deletions

View File

@ -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<RestResources["consumers"]>({
regimens,
@ -71,7 +73,7 @@ export function emptyState(): RestResources {
let initialState: RestResources = emptyState();
let afterEach = (state: RestResources, a: ReduxAction<any>) => {
let afterEach = (state: RestResources, a: ReduxAction<object>) => {
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<TaggedResource>(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<TaggedResource>("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()));

View File

@ -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
<Col xs={11}>
<BlurableInput value={sequence.body.name}
onCommit={(e) => {
dispatch(edit(sequence, { name: e.currentTarget.value }))
dispatch(edit(sequence, { name: e.currentTarget.value }));
}} />
</Col>
<ColorPicker current={sequence.body.color}
onChange={color => editCurrentSequence(dispatch, sequence, { color })} />
</Row>
{(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 <div key={wow}>
return <div key={readThatCommentAbove}>
<DropArea callback={onDrop(index, dispatch, sequence)} />
<StepDragger dispatch={dispatch}
step={currentStep}