mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
feat(history): free layout supports move node into container operation
This commit is contained in:
parent
6c13bffbf3
commit
304cf69387
@ -17,6 +17,7 @@ import {
|
|||||||
FlowNodeJSON,
|
FlowNodeJSON,
|
||||||
MoveNodeConfig,
|
MoveNodeConfig,
|
||||||
OnNodeAddEvent,
|
OnNodeAddEvent,
|
||||||
|
OnNodeMoveEvent,
|
||||||
} from '../typings';
|
} from '../typings';
|
||||||
import { FlowDocument } from '../flow-document';
|
import { FlowDocument } from '../flow-document';
|
||||||
import { FlowNodeEntity } from '../entities';
|
import { FlowNodeEntity } from '../entities';
|
||||||
@ -38,9 +39,13 @@ export class FlowOperationBaseServiceImpl implements FlowOperationBaseService {
|
|||||||
|
|
||||||
protected toDispose = new DisposableCollection();
|
protected toDispose = new DisposableCollection();
|
||||||
|
|
||||||
|
private onNodeMoveEmitter = new Emitter<OnNodeMoveEvent>();
|
||||||
|
|
||||||
|
readonly onNodeMove = this.onNodeMoveEmitter.event;
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected init() {
|
protected init() {
|
||||||
this.toDispose.push(this.onNodeAddEmitter);
|
this.toDispose.pushAll([this.onNodeAddEmitter, this.onNodeMoveEmitter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
addNode(nodeJSON: FlowNodeJSON, config: AddNodeConfig = {}): FlowNodeEntity {
|
addNode(nodeJSON: FlowNodeJSON, config: AddNodeConfig = {}): FlowNodeEntity {
|
||||||
@ -127,7 +132,7 @@ export class FlowOperationBaseServiceImpl implements FlowOperationBaseService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let toIndex = typeof index === 'undefined' ? parent.children.length : index;
|
let toIndex = typeof index === 'undefined' ? newParentEntity.collapsedChildren.length : index;
|
||||||
|
|
||||||
return this.doMoveNode(entity, newParentEntity, toIndex);
|
return this.doMoveNode(entity, newParentEntity, toIndex);
|
||||||
}
|
}
|
||||||
@ -301,10 +306,23 @@ export class FlowOperationBaseServiceImpl implements FlowOperationBaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected doMoveNode(node: FlowNodeEntity, newParent: FlowNodeEntity, index: number) {
|
protected doMoveNode(node: FlowNodeEntity, newParent: FlowNodeEntity, index: number) {
|
||||||
return this.document.moveChildNodes({
|
if (!node.parent) {
|
||||||
|
throw new Error('root node cannot move');
|
||||||
|
}
|
||||||
|
|
||||||
|
const event: OnNodeMoveEvent = {
|
||||||
|
node,
|
||||||
|
fromParent: node.parent,
|
||||||
|
toParent: newParent,
|
||||||
|
fromIndex: this.getNodeIndex(node),
|
||||||
|
toIndex: index,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.document.moveChildNodes({
|
||||||
nodeIds: [this.toId(node)],
|
nodeIds: [this.toId(node)],
|
||||||
toParentId: this.toId(newParent),
|
toParentId: this.toId(newParent),
|
||||||
toIndex: index,
|
toIndex: index,
|
||||||
});
|
});
|
||||||
|
this.onNodeMoveEmitter.fire(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -233,6 +233,17 @@ export interface OnNodeAddEvent {
|
|||||||
data: AddNodeData;
|
data: AddNodeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点移动事件
|
||||||
|
*/
|
||||||
|
export interface OnNodeMoveEvent {
|
||||||
|
node: FlowNodeEntity;
|
||||||
|
fromParent: FlowNodeEntity;
|
||||||
|
fromIndex: number;
|
||||||
|
toParent: FlowNodeEntity;
|
||||||
|
toIndex: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FlowOperationBaseService extends Disposable {
|
export interface FlowOperationBaseService extends Disposable {
|
||||||
/**
|
/**
|
||||||
* 执行操作
|
* 执行操作
|
||||||
@ -300,6 +311,11 @@ export interface FlowOperationBaseService extends Disposable {
|
|||||||
* 添加节点的回调
|
* 添加节点的回调
|
||||||
*/
|
*/
|
||||||
onNodeAdd: Event<OnNodeAddEvent>;
|
onNodeAdd: Event<OnNodeAddEvent>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点移动的回调
|
||||||
|
*/
|
||||||
|
onNodeMove: Event<OnNodeMoveEvent>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FlowOperationBaseService = Symbol('FlowOperationBaseService');
|
export const FlowOperationBaseService = Symbol('FlowOperationBaseService');
|
||||||
|
|||||||
@ -2,3 +2,4 @@ export * from './workflow-select-service';
|
|||||||
export * from './workflow-hover-service';
|
export * from './workflow-hover-service';
|
||||||
export * from './workflow-drag-service';
|
export * from './workflow-drag-service';
|
||||||
export * from './workflow-reset-layout-service';
|
export * from './workflow-reset-layout-service';
|
||||||
|
export * from './workflow-operation-base-service';
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
import { inject } from 'inversify';
|
||||||
|
import { IPoint, Emitter } from '@flowgram.ai/utils';
|
||||||
|
import { FlowNodeEntityOrId, FlowOperationBaseServiceImpl } from '@flowgram.ai/document';
|
||||||
|
import { TransformData } from '@flowgram.ai/core';
|
||||||
|
|
||||||
|
import { WorkflowDocument } from '../workflow-document';
|
||||||
|
import {
|
||||||
|
NodePostionUpdateEvent,
|
||||||
|
WorkflowOperationBaseService,
|
||||||
|
} from '../typings/workflow-operation';
|
||||||
|
|
||||||
|
export class WorkflowOperationBaseServiceImpl
|
||||||
|
extends FlowOperationBaseServiceImpl
|
||||||
|
implements WorkflowOperationBaseService
|
||||||
|
{
|
||||||
|
@inject(WorkflowDocument)
|
||||||
|
protected declare document: WorkflowDocument;
|
||||||
|
|
||||||
|
private onNodePostionUpdateEmitter = new Emitter<NodePostionUpdateEvent>();
|
||||||
|
|
||||||
|
public readonly onNodePostionUpdate = this.onNodePostionUpdateEmitter.event;
|
||||||
|
|
||||||
|
updateNodePosition(nodeOrId: FlowNodeEntityOrId, position: IPoint): void {
|
||||||
|
const node = this.toNodeEntity(nodeOrId);
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const transformData = node.getData(TransformData);
|
||||||
|
const oldPosition = {
|
||||||
|
x: transformData.position.x,
|
||||||
|
y: transformData.position.y,
|
||||||
|
};
|
||||||
|
transformData.update({
|
||||||
|
position,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.onNodePostionUpdateEmitter.fire({
|
||||||
|
node,
|
||||||
|
oldPosition,
|
||||||
|
newPosition: position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ export * from './workflow-node';
|
|||||||
export * from './workflow-registry';
|
export * from './workflow-registry';
|
||||||
export * from './workflow-line';
|
export * from './workflow-line';
|
||||||
export * from './workflow-sub-canvas';
|
export * from './workflow-sub-canvas';
|
||||||
|
export * from './workflow-operation';
|
||||||
|
|
||||||
export const URLParams = Symbol('');
|
export const URLParams = Symbol('');
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { IPoint, Event } from '@flowgram.ai/utils';
|
||||||
|
import {
|
||||||
|
FlowNodeEntity,
|
||||||
|
FlowNodeEntityOrId,
|
||||||
|
FlowOperationBaseService,
|
||||||
|
} from '@flowgram.ai/document';
|
||||||
|
|
||||||
|
export interface NodePostionUpdateEvent {
|
||||||
|
node: FlowNodeEntity;
|
||||||
|
oldPosition: IPoint;
|
||||||
|
newPosition: IPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WorkflowOperationBaseService extends FlowOperationBaseService {
|
||||||
|
/**
|
||||||
|
* 节点位置更新事件
|
||||||
|
*/
|
||||||
|
readonly onNodePostionUpdate: Event<NodePostionUpdateEvent>;
|
||||||
|
/**
|
||||||
|
* 更新节点位置
|
||||||
|
* @param nodeOrId
|
||||||
|
* @param position
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
updateNodePosition(nodeOrId: FlowNodeEntityOrId, position: IPoint): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WorkflowOperationBaseService = Symbol('WorkflowOperationBaseService');
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { ContainerModule } from 'inversify';
|
import { ContainerModule } from 'inversify';
|
||||||
import { FlowDocument, FlowDocumentContribution } from '@flowgram.ai/document';
|
|
||||||
import { bindContributions } from '@flowgram.ai/utils';
|
import { bindContributions } from '@flowgram.ai/utils';
|
||||||
|
import { FlowDocument, FlowDocumentContribution } from '@flowgram.ai/document';
|
||||||
|
|
||||||
import { WorkflowLinesManager } from './workflow-lines-manager';
|
import { WorkflowLinesManager } from './workflow-lines-manager';
|
||||||
import {
|
import {
|
||||||
@ -10,12 +10,13 @@ import {
|
|||||||
import { WorkflowDocumentContribution } from './workflow-document-contribution';
|
import { WorkflowDocumentContribution } from './workflow-document-contribution';
|
||||||
import { WorkflowDocument, WorkflowDocumentProvider } from './workflow-document';
|
import { WorkflowDocument, WorkflowDocumentProvider } from './workflow-document';
|
||||||
import { getUrlParams } from './utils/get-url-params';
|
import { getUrlParams } from './utils/get-url-params';
|
||||||
import { URLParams } from './typings';
|
import { URLParams, WorkflowOperationBaseService } from './typings';
|
||||||
import {
|
import {
|
||||||
WorkflowDragService,
|
WorkflowDragService,
|
||||||
WorkflowHoverService,
|
WorkflowHoverService,
|
||||||
WorkflowSelectService,
|
WorkflowSelectService,
|
||||||
WorkflowResetLayoutService,
|
WorkflowResetLayoutService,
|
||||||
|
WorkflowOperationBaseServiceImpl,
|
||||||
} from './service';
|
} from './service';
|
||||||
import { FreeLayout } from './layout';
|
import { FreeLayout } from './layout';
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ export const WorkflowDocumentContainerModule = new ContainerModule(
|
|||||||
bind(WorkflowSelectService).toSelf().inSingletonScope();
|
bind(WorkflowSelectService).toSelf().inSingletonScope();
|
||||||
bind(WorkflowHoverService).toSelf().inSingletonScope();
|
bind(WorkflowHoverService).toSelf().inSingletonScope();
|
||||||
bind(WorkflowResetLayoutService).toSelf().inSingletonScope();
|
bind(WorkflowResetLayoutService).toSelf().inSingletonScope();
|
||||||
|
bind(WorkflowOperationBaseService).to(WorkflowOperationBaseServiceImpl).inSingletonScope();
|
||||||
bind(URLParams)
|
bind(URLParams)
|
||||||
.toDynamicValue(() => getUrlParams())
|
.toDynamicValue(() => getUrlParams())
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
@ -37,7 +39,7 @@ export const WorkflowDocumentContainerModule = new ContainerModule(
|
|||||||
});
|
});
|
||||||
rebind(FlowDocument).toService(WorkflowDocument);
|
rebind(FlowDocument).toService(WorkflowDocument);
|
||||||
bind(WorkflowDocumentProvider)
|
bind(WorkflowDocumentProvider)
|
||||||
.toDynamicValue(ctx => () => ctx.container.get(WorkflowDocument))
|
.toDynamicValue((ctx) => () => ctx.container.get(WorkflowDocument))
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -105,6 +105,32 @@ describe('history-operation-service moveNode', () => {
|
|||||||
expect(getNodeChildrenIds(root)).toEqual(['start_0', 'dynamicSplit_0', 'end_0']);
|
expect(getNodeChildrenIds(root)).toEqual(['start_0', 'dynamicSplit_0', 'end_0']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('move node with parent and without index', async () => {
|
||||||
|
const root = flowDocument.getNode('root');
|
||||||
|
const block0 = flowDocument.getNode('block_0');
|
||||||
|
|
||||||
|
flowOperationService.addNode(
|
||||||
|
{ id: 'test0', type: 'test' },
|
||||||
|
{
|
||||||
|
parent: block0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
flowDocument.addFromNode('start_0', {
|
||||||
|
type: 'test',
|
||||||
|
id: 'test1',
|
||||||
|
});
|
||||||
|
|
||||||
|
flowOperationService.moveNode('test1', { parent: 'block_0' });
|
||||||
|
|
||||||
|
expect(getNodeChildrenIds(root)).toEqual(['start_0', 'dynamicSplit_0', 'end_0']);
|
||||||
|
expect(getNodeChildrenIds(block0)).toEqual(['$blockOrderIcon$block_0', 'test0', 'test1']);
|
||||||
|
|
||||||
|
await historyService.undo();
|
||||||
|
expect(getNodeChildrenIds(root)).toEqual(['start_0', 'test1', 'dynamicSplit_0', 'end_0']);
|
||||||
|
expect(getNodeChildrenIds(block0)).toEqual(['$blockOrderIcon$block_0', 'test0']);
|
||||||
|
});
|
||||||
|
|
||||||
it('move node with parent and index', async () => {
|
it('move node with parent and index', async () => {
|
||||||
const root = flowDocument.getNode('root');
|
const root = flowDocument.getNode('root');
|
||||||
flowDocument.addFromNode('dynamicSplit_0', {
|
flowDocument.addFromNode('dynamicSplit_0', {
|
||||||
|
|||||||
@ -7,12 +7,14 @@ import {
|
|||||||
WorkflowDocument,
|
WorkflowDocument,
|
||||||
WorkflowResetLayoutService,
|
WorkflowResetLayoutService,
|
||||||
WorkflowDragService,
|
WorkflowDragService,
|
||||||
|
WorkflowOperationBaseService,
|
||||||
} from '@flowgram.ai/free-layout-core';
|
} from '@flowgram.ai/free-layout-core';
|
||||||
import { FlowNodeFormData } from '@flowgram.ai/form-core';
|
import { FlowNodeFormData } from '@flowgram.ai/form-core';
|
||||||
import { FormManager } from '@flowgram.ai/form-core';
|
import { FormManager } from '@flowgram.ai/form-core';
|
||||||
|
import { OperationType } from '@flowgram.ai/document';
|
||||||
import { type PluginContext, PositionData } from '@flowgram.ai/core';
|
import { type PluginContext, PositionData } from '@flowgram.ai/core';
|
||||||
|
|
||||||
import { type FreeHistoryPluginOptions, FreeOperationType } from './types';
|
import { DragNodeOperationValue, type FreeHistoryPluginOptions, FreeOperationType } from './types';
|
||||||
import { HistoryEntityManager } from './history-entity-manager';
|
import { HistoryEntityManager } from './history-entity-manager';
|
||||||
import { DragNodesHandler } from './handlers/drag-nodes-handler';
|
import { DragNodesHandler } from './handlers/drag-nodes-handler';
|
||||||
import { ChangeNodeDataHandler } from './handlers/change-node-data-handler';
|
import { ChangeNodeDataHandler } from './handlers/change-node-data-handler';
|
||||||
@ -40,6 +42,9 @@ export class FreeHistoryManager {
|
|||||||
|
|
||||||
private _toDispose: DisposableCollection = new DisposableCollection();
|
private _toDispose: DisposableCollection = new DisposableCollection();
|
||||||
|
|
||||||
|
@inject(WorkflowOperationBaseService)
|
||||||
|
private _operationService: WorkflowOperationBaseService;
|
||||||
|
|
||||||
onInit(ctx: PluginContext, opts: FreeHistoryPluginOptions) {
|
onInit(ctx: PluginContext, opts: FreeHistoryPluginOptions) {
|
||||||
const document = ctx.get<WorkflowDocument>(WorkflowDocument);
|
const document = ctx.get<WorkflowDocument>(WorkflowDocument);
|
||||||
const historyService = ctx.get<HistoryService>(HistoryService);
|
const historyService = ctx.get<HistoryService>(HistoryService);
|
||||||
@ -101,6 +106,39 @@ export class FreeHistoryManager {
|
|||||||
{ noApply: true }
|
{ noApply: true }
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
this._operationService.onNodeMove(({ node, fromParent, fromIndex, toParent, toIndex }) => {
|
||||||
|
historyService.pushOperation(
|
||||||
|
{
|
||||||
|
type: OperationType.moveChildNodes,
|
||||||
|
value: {
|
||||||
|
fromParentId: fromParent.id,
|
||||||
|
fromIndex,
|
||||||
|
nodeIds: [node.id],
|
||||||
|
toParentId: toParent.id,
|
||||||
|
toIndex,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
noApply: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
this._operationService.onNodePostionUpdate((event) => {
|
||||||
|
const value: DragNodeOperationValue = {
|
||||||
|
ids: [event.node.id],
|
||||||
|
value: [event.newPosition],
|
||||||
|
oldValue: [event.oldPosition],
|
||||||
|
};
|
||||||
|
historyService.pushOperation(
|
||||||
|
{
|
||||||
|
type: FreeOperationType.dragNodes,
|
||||||
|
value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
noApply: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
import { type OperationMeta } from '@flowgram.ai/history';
|
||||||
|
import { WorkflowDocument } from '@flowgram.ai/free-layout-core';
|
||||||
import { FlowNodeTransformData } from '@flowgram.ai/document';
|
import { FlowNodeTransformData } from '@flowgram.ai/document';
|
||||||
import { type PluginContext, TransformData } from '@flowgram.ai/core';
|
import { type PluginContext, TransformData } from '@flowgram.ai/core';
|
||||||
import { WorkflowDocument } from '@flowgram.ai/free-layout-core';
|
|
||||||
import { type OperationMeta } from '@flowgram.ai/history';
|
|
||||||
|
|
||||||
import { type DragNodeOperationValue, FreeOperationType } from '../types';
|
import { type DragNodeOperationValue, FreeOperationType } from '../types';
|
||||||
import { baseOperationMeta } from './base';
|
import { baseOperationMeta } from './base';
|
||||||
@ -9,7 +9,7 @@ import { baseOperationMeta } from './base';
|
|||||||
export const dragNodesOperationMeta: OperationMeta<DragNodeOperationValue, PluginContext, void> = {
|
export const dragNodesOperationMeta: OperationMeta<DragNodeOperationValue, PluginContext, void> = {
|
||||||
...baseOperationMeta,
|
...baseOperationMeta,
|
||||||
type: FreeOperationType.dragNodes,
|
type: FreeOperationType.dragNodes,
|
||||||
inverse: op => ({
|
inverse: (op) => ({
|
||||||
...op,
|
...op,
|
||||||
value: {
|
value: {
|
||||||
...op.value,
|
...op.value,
|
||||||
@ -35,7 +35,7 @@ export const dragNodesOperationMeta: OperationMeta<DragNodeOperationValue, Plugi
|
|||||||
});
|
});
|
||||||
// 嵌套情况下需将子节点 transform 设为 dirty
|
// 嵌套情况下需将子节点 transform 设为 dirty
|
||||||
if (node.collapsedChildren?.length > 0) {
|
if (node.collapsedChildren?.length > 0) {
|
||||||
node.collapsedChildren.forEach(childNode => {
|
node.collapsedChildren.forEach((childNode) => {
|
||||||
const childNodeTransformData =
|
const childNodeTransformData =
|
||||||
childNode.getData<FlowNodeTransformData>(FlowNodeTransformData);
|
childNode.getData<FlowNodeTransformData>(FlowNodeTransformData);
|
||||||
childNodeTransformData.fireChange();
|
childNodeTransformData.fireChange();
|
||||||
@ -43,5 +43,4 @@ export const dragNodesOperationMeta: OperationMeta<DragNodeOperationValue, Plugi
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
shouldMerge: () => false,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { resetLayoutOperationMeta } from './reset-layout';
|
import { resetLayoutOperationMeta } from './reset-layout';
|
||||||
|
import { moveChildNodesOperationMeta } from './move-child-nodes';
|
||||||
import { dragNodesOperationMeta } from './drag-nodes';
|
import { dragNodesOperationMeta } from './drag-nodes';
|
||||||
import { deleteNodeOperationMeta } from './delete-node';
|
import { deleteNodeOperationMeta } from './delete-node';
|
||||||
import { deleteLineOperationMeta } from './delete-line';
|
import { deleteLineOperationMeta } from './delete-line';
|
||||||
@ -14,4 +15,5 @@ export const operationMetas = [
|
|||||||
changeNodeDataOperationMeta,
|
changeNodeDataOperationMeta,
|
||||||
resetLayoutOperationMeta,
|
resetLayoutOperationMeta,
|
||||||
dragNodesOperationMeta,
|
dragNodesOperationMeta,
|
||||||
|
moveChildNodesOperationMeta,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
import { OperationMeta } from '@flowgram.ai/history';
|
||||||
|
import { WorkflowDocument } from '@flowgram.ai/free-layout-core';
|
||||||
|
import { MoveChildNodesOperationValue, OperationType } from '@flowgram.ai/document';
|
||||||
|
import { FlowNodeBaseType } from '@flowgram.ai/document';
|
||||||
|
import { PluginContext, TransformData } from '@flowgram.ai/core';
|
||||||
|
|
||||||
|
import { baseOperationMeta } from './base';
|
||||||
|
|
||||||
|
export const moveChildNodesOperationMeta: OperationMeta<
|
||||||
|
MoveChildNodesOperationValue,
|
||||||
|
PluginContext,
|
||||||
|
void
|
||||||
|
> = {
|
||||||
|
...baseOperationMeta,
|
||||||
|
type: OperationType.moveChildNodes,
|
||||||
|
inverse: (op) => ({
|
||||||
|
...op,
|
||||||
|
value: {
|
||||||
|
...op.value,
|
||||||
|
fromIndex: op.value.toIndex,
|
||||||
|
toIndex: op.value.fromIndex,
|
||||||
|
fromParentId: op.value.toParentId,
|
||||||
|
toParentId: op.value.fromParentId,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
apply: (operation, ctx: PluginContext) => {
|
||||||
|
const document = ctx.get<WorkflowDocument>(WorkflowDocument);
|
||||||
|
document.moveChildNodes(operation.value);
|
||||||
|
const fromContainer = document.getNode(operation.value.fromParentId);
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (fromContainer && fromContainer.flowNodeType !== FlowNodeBaseType.ROOT) {
|
||||||
|
const fromContainerTransformData = fromContainer.getData(TransformData);
|
||||||
|
fromContainerTransformData.fireChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -21,6 +21,7 @@ export enum FreeOperationType {
|
|||||||
changeNodeData = 'changeNodeData',
|
changeNodeData = 'changeNodeData',
|
||||||
resetLayout = 'resetLayout',
|
resetLayout = 'resetLayout',
|
||||||
dragNodes = 'dragNodes',
|
dragNodes = 'dragNodes',
|
||||||
|
moveChildNodes = 'moveChildNodes',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddOrDeleteLineOperationValue extends WorkflowLinePortInfo {
|
export interface AddOrDeleteLineOperationValue extends WorkflowLinePortInfo {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user