mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-02-23 17:49:49 +08:00
Merge pull request #142 from webzard-io/yinsw/operation
fix adjust order operation
This commit is contained in:
commit
2783efdc89
440
packages/editor/__fixture__/application.ts
Normal file
440
packages/editor/__fixture__/application.ts
Normal file
@ -0,0 +1,440 @@
|
||||
import { Application } from '../../core/lib';
|
||||
|
||||
export const ApplicationFixture: Record<string, Application> = {
|
||||
adjustOrderOperation: {
|
||||
kind: 'Application',
|
||||
version: 'example/v1',
|
||||
metadata: { name: 'dialog_component', description: 'dialog component example' },
|
||||
spec: {
|
||||
components: [
|
||||
{
|
||||
id: 'grid_layout1',
|
||||
type: 'core/v1/grid_layout',
|
||||
properties: {
|
||||
layout: [
|
||||
{
|
||||
w: 10,
|
||||
h: 15,
|
||||
x: 0,
|
||||
y: 0,
|
||||
i: 'tabs1',
|
||||
moved: false,
|
||||
static: false,
|
||||
isDraggable: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
traits: [],
|
||||
},
|
||||
{
|
||||
id: 'fetchUsers',
|
||||
type: 'core/v1/dummy',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/fetch',
|
||||
properties: {
|
||||
url: 'https://6177d4919c328300175f5b99.mockapi.io/users',
|
||||
method: 'get',
|
||||
lazy: false,
|
||||
headers: {},
|
||||
body: {},
|
||||
onComplete: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'usersTable',
|
||||
type: 'chakra_ui/v1/table',
|
||||
properties: {
|
||||
data: '{{fetchUsers.fetch.data}}',
|
||||
columns: [
|
||||
{ key: 'username', title: '用户名', type: 'link' },
|
||||
{ key: 'job', title: '职位', type: 'text' },
|
||||
{ key: 'area', title: '地区', type: 'text' },
|
||||
{
|
||||
key: 'createdTime',
|
||||
title: '创建时间',
|
||||
displayValue: "{{dayjs($listItem.createdTime).format('LL')}}",
|
||||
},
|
||||
],
|
||||
majorKey: 'id',
|
||||
rowsPerPage: '3',
|
||||
isMultiSelect: 'false',
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'tabContentVStack', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'userInfoContainer',
|
||||
type: 'chakra_ui/v1/vstack',
|
||||
properties: { spacing: '2', align: 'stretch' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'tabContentVStack', slot: 'content' } },
|
||||
},
|
||||
{
|
||||
type: 'core/v1/style',
|
||||
properties: {
|
||||
styleSlot: 'content',
|
||||
style: "{{!usersTable.selectedItem ? 'display: none' : ''}}",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'userInfoTitle',
|
||||
type: 'core/v1/text',
|
||||
properties: { value: { raw: '**基本信息**', format: 'md' } },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'hstack1',
|
||||
type: 'chakra_ui/v1/hstack',
|
||||
properties: { spacing: '24px', hideBorder: '' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
{
|
||||
type: 'core/v1/style',
|
||||
properties: { styleSlot: 'content', style: 'padding: 0; border: none' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'usernameLabel',
|
||||
type: 'core/v1/text',
|
||||
properties: { value: { raw: '**用户名**', format: 'md' } },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'usernameValue',
|
||||
type: 'core/v1/text',
|
||||
properties: {
|
||||
value: {
|
||||
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.username : ''}}",
|
||||
format: 'plain',
|
||||
},
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'divider1',
|
||||
type: 'chakra_ui/v1/divider',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'jobLabel',
|
||||
type: 'core/v1/text',
|
||||
properties: { value: { raw: '**职位**', format: 'md' } },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack2', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'hstack2',
|
||||
type: 'chakra_ui/v1/hstack',
|
||||
properties: { spacing: '24px', hideBorder: '' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
{
|
||||
type: 'core/v1/style',
|
||||
properties: { styleSlot: 'content', style: 'padding: 0; border: none' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'areaLabel',
|
||||
type: 'core/v1/text',
|
||||
properties: { value: { raw: '**地区**', format: 'md' } },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack3', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'areaValue',
|
||||
type: 'core/v1/text',
|
||||
properties: {
|
||||
value: {
|
||||
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.area : ''}}",
|
||||
format: 'plain',
|
||||
},
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack3', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'divider2',
|
||||
type: 'chakra_ui/v1/divider',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'createdTimeLabel',
|
||||
type: 'core/v1/text',
|
||||
properties: { value: { raw: '**创建时间**', format: 'md' } },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack4', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'createdTimeValue',
|
||||
type: 'core/v1/text',
|
||||
properties: {
|
||||
value: {
|
||||
raw: "{{usersTable.selectedItem ? dayjs(usersTable.selectedItem.createdTime).format('LL') : ''}}",
|
||||
format: 'plain',
|
||||
},
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack4', slot: 'content' } },
|
||||
},
|
||||
{ type: 'core/v1/style', properties: { string: { kind: {}, type: {} } } },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'hstack3',
|
||||
type: 'chakra_ui/v1/hstack',
|
||||
properties: { spacing: '24px', hideBorder: '' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
{
|
||||
type: 'core/v1/style',
|
||||
properties: { styleSlot: 'content', style: 'padding: 0; border: none' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'divider3',
|
||||
type: 'chakra_ui/v1/divider',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'hstack4',
|
||||
type: 'chakra_ui/v1/hstack',
|
||||
properties: { spacing: '24px', hideBorder: '' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'userInfoContainer', slot: 'content' } },
|
||||
},
|
||||
{
|
||||
type: 'core/v1/style',
|
||||
properties: { styleSlot: 'content', style: 'padding: 0; border: none' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'tabs1',
|
||||
type: 'chakra_ui/v1/tabs',
|
||||
properties: { tabNames: ['用户信息', '角色'], initialSelectedTabIndex: 0 },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'grid_layout1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'tabContentVStack',
|
||||
type: 'chakra_ui/v1/vstack',
|
||||
properties: { spacing: '24px' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'tabs1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'testtext',
|
||||
type: 'core/v1/text',
|
||||
properties: { value: { raw: '**测试角色**', format: 'md' } },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'tabs1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'jobValue',
|
||||
type: 'chakra_ui/v1/vstack',
|
||||
properties: { spacing: '1', align: 'stretch' },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'hstack2', slot: 'content' } },
|
||||
},
|
||||
{
|
||||
type: 'core/v1/style',
|
||||
properties: { styleSlot: 'content', style: 'padding: 0; border: none' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'link1',
|
||||
type: 'chakra_ui/v1/link',
|
||||
properties: {
|
||||
text: {
|
||||
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.job : ''}}",
|
||||
format: 'plain',
|
||||
},
|
||||
href: 'https://www.google.com',
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'jobValue', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'link2',
|
||||
type: 'chakra_ui/v1/link',
|
||||
properties: {
|
||||
text: {
|
||||
raw: "{{usersTable.selectedItem ? usersTable.selectedItem.job : ''}}",
|
||||
format: 'plain',
|
||||
},
|
||||
href: 'https://www.google.com',
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'jobValue', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'grid_layout2',
|
||||
type: 'core/v1/grid_layout',
|
||||
properties: {
|
||||
layout: [
|
||||
{ i: 'text10', x: 0, y: 0, w: 0, h: 0 },
|
||||
{ i: 'form1', x: 0, y: 0, w: 0, h: 0 },
|
||||
],
|
||||
},
|
||||
traits: [],
|
||||
},
|
||||
{
|
||||
id: 'form1',
|
||||
type: 'chakra_ui/v1/form',
|
||||
properties: { hideSubmit: false },
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'grid_layout2', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'button1',
|
||||
type: 'chakra_ui/v1/button',
|
||||
properties: {
|
||||
text: { raw: 'text', format: 'plain' },
|
||||
colorScheme: 'blue',
|
||||
isLoading: false,
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'form1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'button2',
|
||||
type: 'chakra_ui/v1/button',
|
||||
properties: {
|
||||
text: { raw: 'text', format: 'plain' },
|
||||
colorScheme: 'blue',
|
||||
isLoading: false,
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'form1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'button3',
|
||||
type: 'chakra_ui/v1/button',
|
||||
properties: {
|
||||
text: { raw: 'text', format: 'plain' },
|
||||
colorScheme: 'blue',
|
||||
isLoading: false,
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: { container: { id: 'form1', slot: 'content' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
File diff suppressed because it is too large
Load Diff
168
packages/editor/__tests__/operation/adjustComponentOrder.spec.ts
Normal file
168
packages/editor/__tests__/operation/adjustComponentOrder.spec.ts
Normal file
@ -0,0 +1,168 @@
|
||||
import { Application } from '@sunmao-ui/core';
|
||||
import { ApplicationFixture } from '../../__fixture__/application';
|
||||
import { AdjustComponentOrderLeafOperation } from '../../src/operations/leaf/component/adjustComponentOrderLeafOperation';
|
||||
describe('adjust component order operation', () => {
|
||||
let app: Application;
|
||||
let operation: AdjustComponentOrderLeafOperation;
|
||||
let warnSpy: jest.SpyInstance;
|
||||
|
||||
beforeAll(() => {
|
||||
warnSpy = jest.spyOn(console, 'warn');
|
||||
});
|
||||
|
||||
describe('move up top level component', () => {
|
||||
const stack: Application[] = [];
|
||||
beforeAll(() => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
stack[0] = app;
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'grid_layout2',
|
||||
orientation: 'up',
|
||||
});
|
||||
});
|
||||
it('should do operation', () => {
|
||||
stack[1] = operation.do(stack[0]);
|
||||
expect(stack[1].spec.components).toMatchSnapshot();
|
||||
});
|
||||
it('should undo operation', () => {
|
||||
stack[2] = operation.undo(stack[1]);
|
||||
expect(stack[2].spec.components).toEqual(stack[0].spec.components);
|
||||
});
|
||||
it('should redo operation', () => {
|
||||
stack[3] = operation.redo(stack[2]);
|
||||
expect(stack[3].spec.components).toEqual(stack[1].spec.components);
|
||||
});
|
||||
afterAll(() => {
|
||||
app = undefined;
|
||||
operation = undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('move down top level component', () => {
|
||||
const stack: Application[] = [];
|
||||
beforeAll(() => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
stack[0] = app;
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'grid_layout1',
|
||||
orientation: 'down',
|
||||
});
|
||||
});
|
||||
it('should do operation', () => {
|
||||
stack[1] = operation.do(stack[0]);
|
||||
expect(stack[1].spec.components).toMatchSnapshot();
|
||||
});
|
||||
it('should undo operation', () => {
|
||||
stack[2] = operation.undo(stack[1]);
|
||||
expect(stack[2].spec.components).toEqual(stack[0].spec.components);
|
||||
});
|
||||
it('should redo operation', () => {
|
||||
stack[3] = operation.redo(stack[2]);
|
||||
expect(stack[3].spec.components).toEqual(stack[1].spec.components);
|
||||
});
|
||||
afterAll(() => {
|
||||
app = undefined;
|
||||
operation = undefined;
|
||||
});
|
||||
});
|
||||
|
||||
it('should not move up top level component in the top', () => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'grid_layout1',
|
||||
orientation: 'up',
|
||||
});
|
||||
expect(operation.do(app)).toEqual(app);
|
||||
expect(warnSpy).toHaveBeenCalledWith('the element cannot move up');
|
||||
});
|
||||
|
||||
it('should not move down top level component in the bottom', () => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'grid_layout2',
|
||||
orientation: 'down',
|
||||
});
|
||||
expect(operation.do(app)).toEqual(app);
|
||||
expect(warnSpy).toHaveBeenCalledWith('the element cannot move down');
|
||||
});
|
||||
|
||||
describe('move up child component', () => {
|
||||
const stack: Application[] = [];
|
||||
beforeAll(() => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
stack[0] = app;
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'userInfoContainer',
|
||||
orientation: 'up',
|
||||
});
|
||||
});
|
||||
it('should do operation', () => {
|
||||
stack[1] = operation.do(stack[0]);
|
||||
expect(stack[1].spec.components).toMatchSnapshot();
|
||||
});
|
||||
it('should undo operation', () => {
|
||||
stack[2] = operation.undo(stack[1]);
|
||||
expect(stack[2].spec.components).toEqual(stack[0].spec.components);
|
||||
});
|
||||
it('should redo operation', () => {
|
||||
stack[3] = operation.redo(stack[2]);
|
||||
expect(stack[3].spec.components).toEqual(stack[1].spec.components);
|
||||
});
|
||||
afterAll(() => {
|
||||
app = undefined;
|
||||
operation = undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('move down child component', () => {
|
||||
const stack: Application[] = [];
|
||||
beforeAll(() => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
stack[0] = app;
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'usersTable',
|
||||
orientation: 'down',
|
||||
});
|
||||
});
|
||||
it('should do operation', () => {
|
||||
stack[1] = operation.do(stack[0]);
|
||||
expect(stack[1].spec.components).toMatchSnapshot();
|
||||
});
|
||||
it('should undo operation', () => {
|
||||
stack[2] = operation.undo(stack[1]);
|
||||
expect(stack[2].spec.components).toEqual(stack[0].spec.components);
|
||||
});
|
||||
it('should redo operation', () => {
|
||||
stack[3] = operation.redo(stack[2]);
|
||||
expect(stack[3].spec.components).toEqual(stack[1].spec.components);
|
||||
});
|
||||
afterAll(() => {
|
||||
app = undefined;
|
||||
operation = undefined;
|
||||
});
|
||||
});
|
||||
|
||||
it('should not move up child component in the top', () => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'usersTable',
|
||||
orientation: 'up',
|
||||
});
|
||||
expect(operation.do(app)).toEqual(app);
|
||||
expect(warnSpy).toHaveBeenCalledWith('the element cannot move up');
|
||||
});
|
||||
|
||||
it('should not move down child component in the bottom', () => {
|
||||
app = ApplicationFixture['adjustOrderOperation'];
|
||||
operation = new AdjustComponentOrderLeafOperation({
|
||||
componentId: 'userInfoContainer',
|
||||
orientation: 'down',
|
||||
});
|
||||
expect(operation.do(app)).toEqual(app);
|
||||
expect(warnSpy).toHaveBeenCalledWith('the element cannot move down');
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
warnSpy.mockClear();
|
||||
});
|
||||
});
|
@ -27,7 +27,10 @@ export class AdjustComponentOrderLeafOperation extends BaseLeafOperation<AdjustC
|
||||
case 'up':
|
||||
for (this.dest = this.index - 1; this.dest >= 0; this.dest--) {
|
||||
const nextComponent = draft.spec.components[this.dest];
|
||||
if (!nextComponent.traits.some(t => t.type === 'core/v1/slot')) {
|
||||
if (
|
||||
nextComponent.type !== 'core/v1/dummy' &&
|
||||
!nextComponent.traits.some(t => t.type === 'core/v1/slot')
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -98,53 +101,46 @@ export class AdjustComponentOrderLeafOperation extends BaseLeafOperation<AdjustC
|
||||
console.warn(`the element cannot move ${this.context.orientation}`);
|
||||
return;
|
||||
}
|
||||
if (movedElement) {
|
||||
switch (this.context.orientation) {
|
||||
case 'up': {
|
||||
const movedElement = draft.spec.components.splice(this.index, 1)[0];
|
||||
draft.spec.components.splice(this.dest - 1, 0, movedElement);
|
||||
break;
|
||||
}
|
||||
case 'down': {
|
||||
const movedElement = draft.spec.components.splice(this.index, 1)[0];
|
||||
draft.spec.components.splice(this.dest + 1, 0, movedElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const [highPos, lowPos] = [this.dest, this.index].sort();
|
||||
const lowComponent = draft.spec.components.splice(lowPos, 1)[0];
|
||||
const highComponent = draft.spec.components.splice(highPos, 1)[0];
|
||||
draft.spec.components.splice(lowPos - 1, 0, highComponent);
|
||||
draft.spec.components.splice(highPos, 0, lowComponent);
|
||||
});
|
||||
}
|
||||
redo(prev: Application): Application {
|
||||
return produce(prev, draft => {
|
||||
switch (this.context.orientation) {
|
||||
case 'up': {
|
||||
const movedElement = draft.spec.components.splice(this.index, 1)[0];
|
||||
draft.spec.components.splice(this.dest - 1, 0, movedElement);
|
||||
break;
|
||||
}
|
||||
case 'down': {
|
||||
const movedElement = draft.spec.components.splice(this.index, 1)[0];
|
||||
draft.spec.components.splice(this.dest + 1, 0, movedElement);
|
||||
break;
|
||||
}
|
||||
if (this.index === -1) {
|
||||
console.warn("operation hasn't been executed, cannot redo");
|
||||
}
|
||||
if (this.dest === -1) {
|
||||
console.warn('cannot redo, the operation was failed executing');
|
||||
return;
|
||||
}
|
||||
const lowPos = Math.max(this.dest, this.index);
|
||||
const highPos = Math.min(this.dest, this.index);
|
||||
const lowComponent = draft.spec.components.splice(lowPos, 1)[0];
|
||||
const highComponent = draft.spec.components.splice(highPos, 1)[0];
|
||||
draft.spec.components.splice(lowPos - 1, 0, highComponent);
|
||||
draft.spec.components.splice(highPos, 0, lowComponent);
|
||||
});
|
||||
}
|
||||
|
||||
undo(prev: Application): Application {
|
||||
return produce(prev, draft => {
|
||||
switch (this.context.orientation) {
|
||||
case 'up': {
|
||||
const movedElement = draft.spec.components.splice(this.dest - 1, 1)[0];
|
||||
draft.spec.components.splice(this.index, 0, movedElement);
|
||||
break;
|
||||
}
|
||||
case 'down': {
|
||||
const movedElement = draft.spec.components.splice(this.dest + 1, 1)[0];
|
||||
draft.spec.components.splice(this.index, 0, movedElement);
|
||||
break;
|
||||
}
|
||||
if (this.index === -1) {
|
||||
console.warn("cannot undo operation, the operation hasn't been executed.");
|
||||
}
|
||||
if (this.dest === -1) {
|
||||
console.warn('cannot undo, the operation was failed executing');
|
||||
return;
|
||||
}
|
||||
const lowPos = Math.max(this.dest, this.index);
|
||||
const highPos = Math.min(this.dest, this.index);
|
||||
const lowComponent = draft.spec.components.splice(lowPos, 1)[0];
|
||||
const highComponent = draft.spec.components.splice(highPos, 1)[0];
|
||||
draft.spec.components.splice(lowPos - 1, 0, highComponent);
|
||||
draft.spec.components.splice(highPos, 0, lowComponent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user