Skip to content

Commit

Permalink
Implemented auto-layout
Browse files Browse the repository at this point in the history
  • Loading branch information
grkngrn committed Nov 7, 2022
1 parent d626695 commit 46d4b4d
Show file tree
Hide file tree
Showing 8 changed files with 632 additions and 12 deletions.
546 changes: 546 additions & 0 deletions src/designer/elsa-workflows-designer/package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/designer/elsa-workflows-designer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"generate": "stencil generate"
},
"dependencies": {
"@antv/layout": "^0.3.1",
"@antv/x6": "^1.32.2",
"@ctrl/tinycolor": "^3.4.1",
"@stencil/core": "^2.13.0",
Expand All @@ -49,12 +50,12 @@
"@fullhuman/postcss-purgecss": "^4.1.3",
"@stencil/postcss": "^2.1.0",
"@stencil/sass": "^1.5.2",
"@tailwindcss/forms": "^0.5.2",
"@tailwindcss/aspect-ratio": "^0.4.0",
"@tailwindcss/forms": "^0.5.2",
"@tailwindcss/typography": "^0.5.2",
"@types/js-cookie": "^3.0.2",
"@types/jquery": "^3.5.14",
"@types/jquery-mousewheel": "^3.1.9",
"@types/js-cookie": "^3.0.2",
"autoprefixer": "^10.4.5",
"postcss": "^8.4.12",
"tailwindcss": "^3.0.24"
Expand Down
7 changes: 7 additions & 0 deletions src/designer/elsa-workflows-designer/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ContextMenuAnchorPoint, MenuItem, MenuItemGroup } from "./components/sh
import { DropdownButtonItem, DropdownButtonOrigin } from "./components/shared/dropdown-button/models";
import { Flowchart, FlowchartNavigationItem } from "./modules/flowchart/models";
import { Graph } from "@antv/x6";
import { OutNode } from "@antv/layout";
import { AddActivityArgs as AddActivityArgs1, RenameActivityArgs as RenameActivityArgs1, UpdateActivityArgs as UpdateActivityArgs1 } from "./components/designer/canvas/canvas";
import { ActivityNodeShape } from "./modules/flowchart/shapes";
import { ActionDefinition, ActionInvokedArgs, ModalType } from "./components/shared/modal-dialog";
Expand Down Expand Up @@ -65,13 +66,15 @@ export namespace Components {
}
interface ElsaCanvas {
"addActivity": (args: AddActivityArgs) => Promise<Activity>;
"autoLayout": () => Promise<void>;
"exportGraph": () => Promise<Activity>;
"getRootComponent": () => Promise<ContainerActivityComponent>;
"importGraph": (root: Activity) => Promise<void>;
"interactiveMode": boolean;
"newRoot": () => Promise<Activity>;
"renameActivity": (args: RenameActivityArgs) => Promise<void>;
"reset": () => Promise<void>;
"scrollToStart": () => Promise<void>;
"updateActivity": (args: UpdateActivityArgs) => Promise<void>;
"updateLayout": () => Promise<void>;
"zoomToFit": () => Promise<void>;
Expand Down Expand Up @@ -116,6 +119,7 @@ export namespace Components {
}
interface ElsaFlowchart {
"addActivity": (args: AddActivityArgs) => Promise<Activity>;
"autoLayout": () => Promise<void>;
"export": () => Promise<Activity>;
"getCurrentLevel": () => Promise<Activity>;
"getGraph": () => Promise<Graph>;
Expand All @@ -124,6 +128,7 @@ export namespace Components {
"newRoot": () => Promise<Activity>;
"renameActivity": (args: RenameActivityArgs) => Promise<void>;
"reset": () => Promise<void>;
"scrollToStart": () => Promise<void>;
"updateActivity": (args: UpdateActivityArgs) => Promise<void>;
"updateLayout": () => Promise<void>;
"zoomToFit": () => Promise<void>;
Expand Down Expand Up @@ -253,6 +258,7 @@ export namespace Components {
"workflowDefinition"?: WorkflowDefinition;
}
interface ElsaWorkflowDefinitionEditorToolbar {
"autoLayout": () => Promise<void>;
"zoomToFit": () => Promise<void>;
}
interface ElsaWorkflowDefinitionEditorToolbox {
Expand Down Expand Up @@ -926,6 +932,7 @@ declare namespace LocalJSX {
"workflowDefinition"?: WorkflowDefinition;
}
interface ElsaWorkflowDefinitionEditorToolbar {
"autoLayout"?: () => Promise<void>;
"zoomToFit"?: () => Promise<void>;
}
interface ElsaWorkflowDefinitionEditorToolbox {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ export class Canvas {
return await this.root.zoomToFit();
}

@Method()
public async autoLayout(): Promise<void> {
return await this.root.autoLayout();
}

@Method()
public async scrollToStart(): Promise<void> {
return await this.root.scrollToStart();
}

@Method()
public async importGraph(root: Activity): Promise<void> {
return await this.root.import(root);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import FromJSONData = Model.FromJSONData;
import PointLike = Point.PointLike;
import FlowchartTunnel, {FlowchartState} from "./state";
import {generateUniqueActivityName} from "../../utils/generate-activity-name";
import { DagreLayout, OutNode} from '@antv/layout';

const FlowchartTypeName = 'Elsa.Flowchart';

Expand Down Expand Up @@ -110,6 +111,58 @@ export class FlowchartComponent implements ContainerActivityComponent {
graph.zoomToFit();
}

@Method()
async scrollToStart() {
const flowchartModel = this.getFlowchartModel();
const startActivity = flowchartModel.activities.find(x => x.id == flowchartModel.start);
if(startActivity != null){
const point: PointLike = this.graph.localToGraph(startActivity.metadata.designer.x, startActivity.metadata.designer.y);
this.graph.scrollToPoint(point.x, point.y);
}
}

@Method()
async autoLayout() {

const dagreLayout = new DagreLayout({
type: 'dagre',
rankdir: 'TB',
align: 'UL',
ranksep: 30,
nodesep: 15,
controlPoints: true,
});

let flowchartModel = this.getFlowchartModel();

let nodes = [];
let edges = [];

flowchartModel.activities.forEach(activity => {
const activityElement = document.querySelectorAll("[activity-id=\"" + activity.id + "\"]")[0].getBoundingClientRect();
nodes.push({id: activity.id, size: {width: activityElement.width, height: activityElement.height}, x: activity.metadata.designer.position.x, y: activity.metadata.designer.position.y})
});

flowchartModel.connections.forEach((connection, index) => {
edges.push({id:index, source: connection.source, target: connection.target});
});

let data = {nodes: nodes, edges: edges}
let newLayout = dagreLayout.layout(data);

newLayout.nodes.forEach(node => {
let outNode = node as OutNode;
let activity = flowchartModel.activities.find(x => x.id == node.id);
activity.metadata.designer.position.x = outNode.x;
activity.metadata.designer.position.y = outNode.y;

this.updateActivity({id: activity.id, originalId: activity.id, activity: activity});
});

this.import(this.activity);
this.scrollToStart();
}

@Method()
async addActivity(args: AddActivityArgs): Promise<Activity> {
const graph = this.graph;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export class WorkflowDefinitionEditor {
await this.updateWorkflowDefinition(workflowDefinition);
await this.canvas.importGraph(workflowDefinition.root);
await this.eventBus.emit(WorkflowEditorEventTypes.WorkflowDefinition.Imported, this, {workflowDefinition});
await this.canvas.scrollToStart();
}

// Updates the workflow definition without importing it into the designer.
Expand Down Expand Up @@ -233,6 +234,8 @@ export class WorkflowDefinitionEditor {

private onZoomToFit = async () => await this.canvas.zoomToFit()

private onAutoLayout = async () => await this.canvas.autoLayout()

private onActivityUpdated = async (e: CustomEvent<ActivityUpdatedArgs>) => {
await this.canvas.updateActivity({
id: e.detail.newId,
Expand Down Expand Up @@ -276,7 +279,7 @@ export class WorkflowDefinitionEditor {

return (
<div class="absolute inset-0" ref={el => this.container = el}>
<elsa-workflow-definition-editor-toolbar zoomToFit={this.onZoomToFit}/>
<elsa-workflow-definition-editor-toolbar zoomToFit={this.onZoomToFit} autoLayout={this.onAutoLayout}/>
<elsa-panel
class="elsa-activity-picker-container z-30"
position={PanelPosition.Left}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@ export class Toolbar {
@Prop()
public zoomToFit: () => Promise<void>;

@Prop()
public autoLayout: () => Promise<void>;

render() {
return (
<div class="elsa-panel-toolbar flex justify-center absolute border-b border-gray-200 top-0 px-1 pl-4 pb-2 text-sm bg-white z-10 space-x-2">
<elsa-tooltip tooltipPosition="right" tooltipContent={<p class="text-white text-sm">Currently in development</p>}>
<button class="btn btn-primary">
Auto-Layout
</button>
</elsa-tooltip>
<button
onClick={this.zoomToFit}
class="btn btn-primary"
>
<button class="btn btn-primary" onClick={this.autoLayout}>
Auto-Layout
</button>
<button onClick={this.zoomToFit}class="btn btn-primary">
Zoom to fit
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface ContainerActivityComponent {
export(): Promise<Activity>
import(root: Activity): Promise<void>;
zoomToFit(): Promise<void>;
autoLayout(): Promise<void>;
scrollToStart(): Promise<void>;
reset(): Promise<void>;
getCurrentLevel(): Promise<Activity>;
}

0 comments on commit 46d4b4d

Please sign in to comment.