npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@maestrodimateo/ngx-workflow

v0.5.1

Published

Angular library for configuring Laravel Workflow circuits, baskets, transitions, actions and conditions

Readme

@maestrodimateo/ngx-workflow

Angular library for configuring Laravel Workflow circuits, baskets, transitions, actions and conditions.

Drop a single <wf-workflow-admin /> component into your app and get a full visual workflow designer built with Angular Material.


Table of contents


Requirements

  • Angular >= 20
  • Angular Material >= 20
  • A Laravel backend with maestrodimateo/laravel-workflow installed

Installation

npm install @maestrodimateo/ngx-workflow

Make sure Angular Material is set up in your project:

ng add @angular/material

Setup

1. Provide the library configuration

// app.config.ts
import { provideHttpClient } from '@angular/common/http';
import { provideWorkflow } from '@maestrodimateo/ngx-workflow';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(),
    provideWorkflow({ apiBaseUrl: 'https://api.example.com/workflow' }),
  ],
};

The apiBaseUrl must point to the Laravel route prefix where the workflow API is mounted (typically /workflow).

2. Authentication

The library sends HTTP requests via Angular's HttpClient. To attach your auth token, add an interceptor:

// auth.interceptor.ts
import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = localStorage.getItem('token'); // or your auth service
  if (token) {
    req = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } });
  }
  return next(req);
};

// app.config.ts
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withInterceptors([authInterceptor])),
    provideWorkflow({ apiBaseUrl: 'https://api.example.com/workflow' }),
  ],
};

Usage

Full admin (one component does everything)

import { Component } from '@angular/core';
import { WorkflowAdminComponent } from '@maestrodimateo/ngx-workflow';

@Component({
  imports: [WorkflowAdminComponent],
  template: `<wf-workflow-admin />`,
  styles: `:host { display: block; height: 100vh; }`,
})
export class WorkflowPage {}

This single component gives you:

  • Circuit list — create, edit, delete, import/export JSON
  • Visual canvas designer — drag-and-drop baskets, SVG arrows, pan, zoom
  • Basket forms — create/edit with colors, roles
  • Transition configuration — attach actions and conditions
  • Message template editor — with variable interpolation

You can also use it inside a route:

// app.routes.ts
import { WorkflowPage } from './workflow.page';

export const routes: Routes = [
  { path: 'admin/workflow', component: WorkflowPage },
];

Individual components

For custom layouts, use each component independently:

import {
  CircuitListComponent,
  CircuitFormComponent,
  BasketFormComponent,
  TransitionConfigComponent,
  MessageEditorComponent,
  WorkflowCanvasComponent,
  WorkflowApiService,
  WorkflowConfig,
} from '@maestrodimateo/ngx-workflow';

Circuit list

<wf-circuit-list
  (selected)="openCircuit($event)"
  (createClicked)="showCreateForm()"
  (editClicked)="showEditForm($event)"
  (deleted)="onDeleted($event)"
  (imported)="onImported($event)"
/>

| Output | Type | Description | |---|---|---| | selected | Circuit | A circuit was clicked | | createClicked | void | "New circuit" button was clicked | | editClicked | Circuit | Edit button was clicked | | deleted | Circuit | A circuit was deleted | | imported | Circuit | A circuit was imported from JSON |

Circuit form

<wf-circuit-form
  [circuit]="existingCircuit"
  [config]="workflowConfig"
  (saved)="onCircuitSaved($event)"
  (cancelled)="goBack()"
/>

| Input | Type | Description | |---|---|---| | circuit | Circuit \| undefined | Pass existing circuit to edit, omit to create | | config | WorkflowConfig \| undefined | Designer metadata (from GET /config) |

Canvas designer

<wf-canvas
  [circuitId]="circuit.id"
  (basketSelected)="selectBasket($event)"
  (transitionSelected)="configureTransition($event)"
  (connectionCreated)="createConnection($event)"
/>

| Input | Type | Description | |---|---|---| | circuitId | string | Required. The circuit to display |

| Output | Type | Description | |---|---|---| | basketSelected | Basket | A basket node was clicked | | transitionSelected | { from: Basket, to: Basket } | A transition arrow was clicked | | connectionCreated | { from: Basket, to: Basket } | A new connection was drawn port-to-port |

Canvas features:

  • Drag baskets to reposition (positions auto-saved to API)
  • Pan by clicking and dragging the background
  • Zoom with scroll wheel or +/− buttons
  • Create transitions by dragging from the right port (●) to a left port
  • Click arrows to configure transitions

Basket form

<wf-basket-form
  [circuitId]="circuit.id"
  [basket]="existingBasket"
  [config]="workflowConfig"
  (saved)="onBasketSaved($event)"
  (cancelled)="goBack()"
/>

Transition config

<wf-transition-config
  [fromId]="sourceBasket.id"
  [toId]="targetBasket.id"
  [config]="workflowConfig"
  (saved)="onTransitionSaved($event)"
  (cancelled)="goBack()"
/>

Message editor

<wf-message-editor
  [circuitId]="circuit.id"
  [message]="existingMessage"
  [config]="workflowConfig"
  (saved)="onMessageSaved($event)"
  (cancelled)="goBack()"
/>

Click on variable chips to insert {{ variable }} into the content field.

API service

For fully custom integrations, inject WorkflowApiService directly:

import { WorkflowApiService } from '@maestrodimateo/ngx-workflow';

@Component({ ... })
export class MyComponent {
  private readonly api = inject(WorkflowApiService);

  ngOnInit() {
    // Fetch designer metadata
    this.api.getConfig().subscribe(config => { ... });

    // CRUD circuits
    this.api.getCircuits().subscribe(circuits => { ... });
    this.api.createCircuit({ name: 'Invoice approval', targetModel: 'App\\Models\\Invoice' });

    // Baskets
    this.api.getBaskets(circuitId).subscribe(baskets => { ... });
    this.api.createBasket({ name: 'Review', status: 'REVIEW', color: '#2563eb', circuit_id: circuitId });

    // Transitions
    this.api.updateTransition(fromId, toId, { label: 'Approve', actions: [...], conditions: [...] });

    // Connect two baskets
    this.api.connectBaskets(targetBasket, sourceBasketId);

    // Messages
    this.api.getMessages(circuitId).subscribe(messages => { ... });

    // Export / Import
    this.api.exportCircuit(circuitId).subscribe(json => { ... });
    this.api.importCircuit(file).subscribe(circuit => { ... });
  }
}

Component reference

| Selector | Description | |---|---| | <wf-workflow-admin> | Full admin — all-in-one component | | <wf-circuit-list> | Circuit list with CRUD, import/export | | <wf-circuit-form> | Circuit create/edit form | | <wf-canvas> | Visual drag-and-drop designer canvas | | <wf-basket-form> | Basket create/edit form | | <wf-transition-config> | Transition actions & conditions config | | <wf-message-editor> | Message template editor |


Theming

The library uses Angular Material components and respects your app's Material theme. The canvas uses Material Design CSS tokens (--mat-sys-primary, --mat-sys-surface, --mat-sys-outline, etc.) so it adapts automatically to your theme, including dark mode.

No additional CSS is needed beyond your standard Angular Material setup.


Laravel backend setup

Install the Laravel package:

composer require maestrodimateo/laravel-workflow
php artisan vendor:publish --tag=workflow-config
php artisan vendor:publish --tag=workflow-migrations
php artisan migrate

The API routes are automatically registered under the configured prefix (default: /workflow). Make sure the route middleware is set to api + your auth guard:

// config/workflow.php
'routes' => [
    'prefix'     => 'workflow',
    'middleware'  => ['api', 'auth:sanctum'],
],

API endpoints

All endpoints are relative to the configured apiBaseUrl.

| Method | Endpoint | Description | |---|---|---| | GET | /config | Designer metadata (colors, actions, conditions, models, roles) | | GET | /circuits | List all circuits | | POST | /circuits | Create a circuit | | GET | /circuits/{id} | Get a circuit | | PUT | /circuits/{id} | Update a circuit | | DELETE | /circuits/{id} | Delete a circuit | | GET | /circuits/{id}/baskets | List baskets of a circuit | | POST | /baskets | Create a basket | | PUT | /baskets/{id} | Update a basket | | DELETE | /baskets/{id} | Delete a basket | | PATCH | /circuits/{id}/positions | Save canvas basket positions | | PUT | /transitions/{from}/{to} | Configure transition (actions, conditions) | | GET | /circuits/{id}/messages | List messages of a circuit | | POST | /circuits/{id}/messages | Create a message | | PUT | /circuits/{id}/messages/{mid} | Update a message | | DELETE | /circuits/{id}/messages/{mid} | Delete a message | | GET | /circuits/{id}/export | Export circuit as JSON | | POST | /circuits/import | Import circuit from JSON file |


License

MIT