mobile sequence step reorder controls

This commit is contained in:
gabrielburnworth 2018-08-27 13:32:37 -07:00
parent 1c05dde5fe
commit 73b37cc0b5
4 changed files with 90 additions and 13 deletions

View file

@ -108,6 +108,12 @@
}
}
.step-up-down-arrows {
text-align: center;
display: inline-block;
font-size: 2rem;
}
.step-control {
margin-top: 0.3rem;
margin-left: 2rem;

View file

@ -0,0 +1,52 @@
jest.mock("../step_tiles", () => ({
splice: jest.fn(),
remove: jest.fn(),
move: jest.fn(),
}));
import * as React from "react";
import { mount, shallow } from "enzyme";
import { StepIconGroup, StepIconBarProps } from "../step_icon_group";
import { fakeSequence } from "../../__test_support__/fake_state/resources";
import { splice, remove, move } from "../step_tiles";
describe("<StepIconGroup />", () => {
const fakeProps = (): StepIconBarProps => ({
index: 0,
dispatch: jest.fn(),
step: { kind: "wait", args: { milliseconds: 100 } },
sequence: fakeSequence(),
helpText: "helpful text",
});
it("renders", () => {
const wrapper = mount(<StepIconGroup {...fakeProps()} />);
expect(wrapper.find("i").length).toEqual(4);
});
it("deletes step", () => {
const wrapper = mount(<StepIconGroup {...fakeProps()} />);
wrapper.find("i").at(2).simulate("click");
expect(remove).toHaveBeenCalledWith(expect.objectContaining({ index: 0 }));
});
it("duplicates step", () => {
const wrapper = mount(<StepIconGroup {...fakeProps()} />);
wrapper.find("i").at(1).simulate("click");
expect(splice).toHaveBeenCalledWith(expect.objectContaining({
index: 0,
step: fakeProps().step
}));
});
it("moves step", () => {
const wrapper = shallow(<StepIconGroup {...fakeProps()} />);
// tslint:disable-next-line:no-any
(wrapper.find("StepUpDownButtonPopover").props() as any).onMove(-1)();
expect(move).toHaveBeenCalledWith(expect.objectContaining({
from: 0,
to: 0,
step: fakeProps().step
}));
});
});

View file

@ -1,17 +1,40 @@
import * as React from "react";
import { Help } from "../ui/help";
import { Popover, Position } from "@blueprintjs/core";
import { SequenceBodyItem, TaggedSequence } from "farmbot";
import { splice, remove, move } from "./step_tiles";
interface StepIconBarProps {
onClone(): void;
onTrash(): void;
export interface StepIconBarProps {
index: number;
dispatch: Function;
step: SequenceBodyItem;
sequence: TaggedSequence;
helpText: string;
}
export function StepUpDownButtonPopover(
{ onMove }: { onMove: (d: number) => () => void }) {
return <Popover position={Position.TOP} usePortal={false}>
<i className="fa fa-arrows-v step-control" />
<div className={"step-up-down-arrows"}>
<i className="fa fa-arrow-circle-up" onClick={onMove(-1)} />
<i className="fa fa-arrow-circle-down" onClick={onMove(2)} />
</div>
</Popover>;
}
export function StepIconGroup(props: StepIconBarProps) {
const { onClone, onTrash, helpText } = props;
const { index, dispatch, step, sequence, helpText } = props;
const onClone = () => dispatch(splice({ step, index, sequence }));
const onTrash = () => remove({ dispatch, index, sequence });
const onMove = (delta: number) => () => {
const to = Math.max(index + delta, 0);
dispatch(move({ step, sequence, from: index, to }));
};
return <span>
<i className="fa fa-arrows-v step-control" />
<StepUpDownButtonPopover onMove={onMove} />
<i className="fa fa-clone step-control" onClick={onClone} />
<i className="fa fa-trash step-control" onClick={onTrash} />
<Help text={helpText} />

View file

@ -4,7 +4,6 @@ import { Row, Col } from "../../ui/index";
import { TaggedSequence, SequenceBodyItem } from "farmbot";
import { StepTitleBar } from "../step_tiles/step_title_bar";
import { StepIconGroup } from "../step_icon_group";
import { splice, remove } from "../step_tiles/index";
export interface StepHeaderProps {
children?: React.ReactNode;
@ -34,13 +33,10 @@ export function StepHeader(props: StepHeaderProps) {
step={currentStep}
sequence={currentSequence} />
<StepIconGroup
onClone={() => dispatch(splice({
step: currentStep,
index,
sequence: currentSequence
}))}
onTrash={() =>
remove({ dispatch, index, sequence: currentSequence })}
index={index}
dispatch={dispatch}
step={currentStep}
sequence={currentSequence}
helpText={t(helpText)} />
{props.children}
</div>