Farmbot-Web-App/frontend/sequences/all_steps.tsx

73 lines
2.8 KiB
TypeScript

import * as React from "react";
import { TaggedSequence } from "farmbot";
import { SequenceBodyItem } from "farmbot/dist";
import { DropArea } from "../draggable/drop_area";
import { StepDragger } from "../draggable/step_dragger";
import { renderCeleryNode } from "./step_tiles/index";
import { ResourceIndex } from "../resources/interfaces";
import { getStepTag } from "../resources/sequence_tagging";
import { HardwareFlags, FarmwareData } from "./interfaces";
import { ShouldDisplay } from "../devices/interfaces";
import { AddCommandButton } from "./sequence_editor_middle_active";
import { ErrorBoundary } from "../error_boundary";
import { TileUnknown } from "./step_tiles/tile_unknown";
export interface AllStepsProps {
sequence: TaggedSequence;
onDrop(index: number, key: string): void;
dispatch: Function;
resources: ResourceIndex;
hardwareFlags?: HardwareFlags;
farmwareData?: FarmwareData;
shouldDisplay?: ShouldDisplay;
confirmStepDeletion: boolean;
showPins?: boolean;
expandStepOptions?: boolean;
}
export class AllSteps extends React.Component<AllStepsProps, {}> {
render() {
const { sequence, dispatch } = this.props;
const items = (sequence.body.body || [])
.map((currentStep: SequenceBodyItem, index) => {
/** 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 no matter where the step gets moved and
* allows React to diff the list correctly. */
const readThatCommentAbove = getStepTag(currentStep);
const stepProps = {
currentStep,
index,
dispatch,
currentSequence: sequence,
resources: this.props.resources,
hardwareFlags: this.props.hardwareFlags,
farmwareData: this.props.farmwareData,
shouldDisplay: this.props.shouldDisplay,
confirmStepDeletion: this.props.confirmStepDeletion,
showPins: this.props.showPins,
expandStepOptions: this.props.expandStepOptions,
};
return <div className="sequence-steps"
key={readThatCommentAbove}>
<AddCommandButton dispatch={dispatch} index={index} />
<DropArea callback={key => this.props.onDrop(index, key)} />
<StepDragger
dispatch={dispatch}
step={currentStep}
intent="step_move"
draggerId={index}>
<div className="sequence-step">
<ErrorBoundary fallback={<TileUnknown {...stepProps} />}>
{renderCeleryNode(stepProps)}
</ErrorBoundary>
</div>
</StepDragger>
</div>;
});
return <div className="all-steps">{items}</div>;
}
}