Skip to main content

Initialize Sequential Workflow Designer with Angular

The designer is written in TypeScript with no dependencies, but to increase a developer experience we prepared a dedicated package for Angular. The package wraps a native component and provides a Angular style syntax.

Examples

Check our online examples.

🚀 Installation​

Install the following packages by NPM command:

npm i sequential-workflow-designer sequential-workflow-designer-angular

Add CSS files to your angular.json file.

{
"projects": {
"YOUR_APP": {
"architect": {
"build": {
"styles": [
"./node_modules/sequential-workflow-designer/css/designer.css",
"./node_modules/sequential-workflow-designer/css/designer-light.css",
"./node_modules/sequential-workflow-designer/css/designer-dark.css"
]
}
}
}
}
}

🎬 Usage​

Import the module:

import { SequentialWorkflowDesignerModule } from 'sequential-workflow-designer-angular';

@NgModule({
imports: [
SequentialWorkflowDesignerModule,
// ...
],
// ...
})
export class AppModule {}

Define a definition and a configuration.

export class AppComponent {
private designer?: Designer;
public definition: Definition = { /* ... */ };
public toolboxConfiguration: ToolboxConfiguration = { /* ... */ };
public stepsConfiguration: StepsConfiguration = { /* ... */ };
public validatorConfiguration: ValidatorConfiguration = { /* ... */ };
// ...
}

Define the following methods to handle the designer's events.

export class AppComponent {
//...
public onDesignerReady(designer: Designer) {
this.designer = designer;
}

public onDefinitionChanged(definition: Definition) {
this.definition = definition;
}

public onSelectedStepIdChanged(stepId: string | null) {
// ...
}
}

Additionally we need to define a few utils methods to handle the editor's logic.

export class AppComponent {
// ...
public updateName(step: Step, event: Event, context: StepEditorContext) {
step.name = (event.target as HTMLInputElement).value;
context.notifyNameChanged();
}

public updateProperty(properties: Properties, name: string, event: Event, context: RootEditorContext | StepEditorContext) {
properties[name] = (event.target as HTMLInputElement).value;
context.notifyPropertiesChanged();
}
}

Create a template for the root editor. The value of the editor variable implements the RootEditorWrapper interface.

<ng-template #rootEditor let-editor>
<h2>Root Editor</h2>

<h3>Velocity</h3>
<input type="number"
[value]="editor.definition.properties.velocity"
(input)="updateProperty(editor.definition.properties, 'velocity', $event, editor.context)" />
</ng-template>
interface RootEditorWrapper {
definition: Definition;
context: RootEditorContext;
isReadonly: boolean;
}

Create a template for the step editor. The value of the editor variable implements the StepEditorWrapper interface.

<ng-template #stepEditor let-editor>
<h2>Step Editor</h2>

<h3>Name</h3>
<input type="text"
[value]="editor.step.name"
(input)="updateName(editor.step, $event, editor.context)" />

<h3>Velocity</h3>
<input type="number"
[value]="editor.step.properties.velocity"
(input)="updateProperty(editor.step.properties, 'velocity', $event, editor.context)" />
</ng-template>
interface StepEditorWrapper {
step: Step;
definition: Definition;
context: StepEditorContext;
isReadonly: boolean;
}

At the end attach the designer:

<sqd-designer
theme="light"
[undoStackSize]="10"
[definition]="startDefinition"
[toolboxConfiguration]="toolboxConfiguration"
[stepsConfiguration]="stepsConfiguration"
[validatorConfiguration]="validatorConfiguration"
[controlBar]="true"
[contextMenu]="true"
[areEditorsHidden]="false"
[rootEditor]="rootEditor"
[stepEditor]="stepEditor"
(onReady)="onDesignerReady($event)"
(onDefinitionChanged)="onDefinitionChanged($event)"
(onSelectedStepIdChanged)="onSelectedStepIdChanged($event)">
</sqd-designer>

That's it!

🚧 Demo Project​

We prepared a demo project that shows how to use the designer in Angular.