@suntelecoms/ngx-workflow-viewer
v1.2.4
Published
Visualiseur d'instances de workflow Angular — SUNTELECOMS
Maintainers
Readme
@suntelecoms/ngx-workflow-viewer
Angular 19 standalone component library for visualizing and interacting with BPM/workflow instances.
Installation
npm install @suntelecoms/ngx-workflow-viewerPeer dependencies: Angular ≥ 19, Angular Material ≥ 19, @suntelecoms/ngx-dynamic-form ≥ 1.4.1
Quick Start
1. Provide the library
// app.config.ts
import { provideNgxWorkflow } from '@suntelecoms/ngx-workflow-viewer';
export const appConfig: ApplicationConfig = {
providers: [
provideNgxWorkflow({ baseUrl: 'http://localhost:8080/api' }),
],
};2. Implement WorkflowStorageAdapter
@Injectable()
export class MyAdapter extends WorkflowStorageAdapter {
getInstance(id: string): Observable<WorkflowInstance> { ... }
getTasks(id: string): Observable<WorkflowTask[]> { ... }
getHistory(id: string): Observable<WorkflowHistoryEntry[]> { ... }
getTimeline(id: string): Observable<WorkflowTimelineEvent[]> { ... }
getVariables(id: string): Observable<WorkflowVariable[]> { ... }
getComments(id: string): Observable<WorkflowComment[]> { ... }
getAttachments(id: string): Observable<WorkflowAttachment[]> { ... }
getDiagram(id: string): Observable<string> { ... }
getLogs(id: string): Observable<WorkflowLog[]> { ... }
getActions(id: string): Observable<WorkflowAction[]> { ... }
advance(id: string, outcome: string, formData?: Record<string, any>, completedBy?: string): Observable<WorkflowInstance> { ... }
callServiceTask(url: string, method: string, body: Record<string, any>): Observable<Record<string, any>> { ... }
addComment(id: string, content: string, taskId?: string): Observable<WorkflowComment> { ... }
executeAction(id: string, actionId: string, data?: Record<string, any>): Observable<WorkflowInstance> { ... }
}Note: If your backend wraps responses in an envelope (
{ data: {...}, status: 'SUCCESS' }), unwrap it incallServiceTaskbefore returning:return req$.pipe(map(res => res?.data ?? res)).
3. Register the adapter and render
// app.config.ts
providers: [
provideNgxWorkflow({ baseUrl: 'http://localhost:8080/api' }),
{ provide: WorkflowStorageAdapter, useClass: MyAdapter },
]<!-- any component template -->
<ngx-workflow-viewer [instanceId]="id" [config]="cfg" />WorkflowViewerConfig
| Option | Type | Default | Description |
|---|---|---|---|
| showHeader | boolean | true | Instance header (name, status, dates) |
| showTimeline | boolean | true | Step timeline tab |
| showTasks | boolean | true | Tasks tab |
| showHistory | boolean | true | History tab |
| showVariables | boolean | true | Variables tab |
| showComments | boolean | true | Comments tab |
| showAttachments | boolean | true | Attachments tab |
| showDiagram | boolean | false | BPMN diagram tab |
| showLogs | boolean | false | Logs tab |
| showActions | boolean | true | Action buttons |
| showForm | boolean | true | Current task form / service task runner |
| showRequestSummary | boolean | true | Summary panel above the form |
| summarySections | { key, label }[] | [] | Instance variables to show in summary |
| formCompletedBy | string | 'user' | Static completedBy sent with advance() |
| formCompletedByField | string | — | Form field key whose value is used as completedBy (overrides formCompletedBy) |
| decisionMotifField | string | — | Form field key holding the rejection/rework reason |
| decisionMotifKey | string | 'decisionMotif' | Process variable name for the decision reason |
| decisionByKey | string | 'decisionBy' | Process variable name for the decision actor |
| decisionOutcomeKey | string | 'decisionOutcome' | Process variable name for the outcome (REJECTED|REWORK) |
| showPreviousDecisions | boolean | true | Show a "Décisions précédentes" panel above the form |
| outcomeLabels | Record<string, string> | — | Custom labels for outcome buttons, e.g. { NEXT: 'Valider', REJECTED: 'Refuser' } |
Features
Form rendering
When a task has a formCode and the library has FormConfigService populated (from @suntelecoms/ngx-dynamic-form), the form is rendered automatically. On submit, the library:
- Maps
decisionfield value (REJETER→REJECTED,RENVOI→REWORK, elseNEXT) - Enriches the payload with
decisionOutcome,decisionBy, anddecisionMotif - Calls
adapter.advance(instanceId, outcome, enrichedData, completedBy)
Service task auto-execution
Tasks with actor === 'systeme' are executed automatically when the page loads:
- With
serviceUrl: callsadapter.callServiceTask(url, method, body), readsserviceOutcomeFieldfrom the response to determineNEXTorREJECTED - Without
serviceUrl: advances directly withNEXT(backend handles the task internally)
// WorkflowTask fields used for service tasks
interface WorkflowTask {
actor?: string; // 'systeme' triggers auto-execution
serviceUrl?: string;
serviceMethod?: string; // default: 'POST'
serviceInputMapping?: Record<string, string>; // { bodyKey: varName }
serviceOutcomeField?: string; // field in response; false → REJECTED
outcomes?: Record<string, any>;
}Decision banner (rejection / rework)
WorkflowDecisionBannerComponent renders a banner when an instance is rejected or sent back for correction. It is displayed automatically in WorkflowViewerComponent when instance.status === 'REJECTED'.
You can also use it standalone:
<ngx-workflow-decision-banner
type="rejected"
[motif]="motif"
[by]="by"
/>| Input | Type | Description |
|---|---|---|
| type | 'rejected' \| 'rework' | Banner style — red for rejected, orange for rework |
| motif | string \| null | Reason text |
| by | string \| null | Decision actor login |
Previous decisions
When showPreviousDecisions: true (default), completed human steps appear above the current form so each actor sees the full decision chain. The panel reads from history[].metadata — populate metadata in your toHistoryEntry() mapping with the step's submittedData.
WorkflowStatus
type WorkflowStatus = 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'TERMINATED' | 'REJECTED';Changelog
1.2.3 — 2026-08-13
Fixed
- Form fields no longer lose focus or reset on keypress — the form config signal no longer depends on
cfg()input inside the effect, eliminating a rebuild cycle triggered by Angular signal input initialization
1.2.2 — 2026-08-13 (yanked — use 1.2.3)
Fixed
- Typing bug partially addressed (replaced
computedwitheffect+WritableSignal), but the effect still readcfg()indirectly viaoutcomeButtons(), causing a second rebuild when the input initialized
1.2.1 — 2026-08-13
New
- Outcome action buttons — when a task exposes 2+ outcomes (e.g. NEXT + REJECTED), the plugin replaces the
decisionselect field with explicit Approuver / Rejeter / Renvoyer pour correction buttons WorkflowViewerConfig.outcomeLabels— override any button label:{ NEXT: 'Valider', REJECTED: 'Refuser' }DynamicFormConfig.showSubmit(via@suntelecoms/[email protected]) — hides the form's built-in submit button when action buttons handle submission
Requires @suntelecoms/ngx-dynamic-form@^1.4.2
1.2.0 — 2026-08-13
New
WorkflowDecisionBannerComponent— standard BPM rejection/rework banner (type="rejected"|"rework",motif,byinputs); exported asDecisionBannerTypeWorkflowViewerConfig— six new options:formCompletedByField,decisionMotifField,decisionMotifKey,decisionByKey,decisionOutcomeKey,showPreviousDecisionsWorkflowStatus— extended with'REJECTED'and'IN_PROGRESS'WorkflowFormComponent— "Décisions précédentes" panel above the form (all prior human steps with decision badge + comment)WorkflowFormComponent— rework banner shown whendecisionOutcome === 'REWORK'WorkflowViewerComponent— rejection banner with motif/by read from variables + history fallback- Service task auto-execution: tasks without
serviceUrlnow auto-advance withNEXT(backend-internal tasks) - Service task outcome routing:
serviceOutcomeField === falsetriggersREJECTEDadvance
Fixed
WorkflowViewerService.isServiceTask— no longer requiresserviceUrl; detects systeme tasks byactoraloneWorkflowHeaderComponent—IN_PROGRESSandREJECTEDstatuses now display correct label/color/icon
1.1.0
WorkflowFormComponent— dynamic form rendering, request summary panel, service task spinner UIWorkflowStorageAdapter—callServiceTask()andadvance()abstract methodsWorkflowViewerConfig.showForm,showRequestSummary,summarySections,formCompletedBy
1.0.0
- Initial release:
WorkflowViewerComponent, tabbed navigation (timeline, tasks, history, variables, comments, attachments, diagram, logs, actions) WorkflowStorageAdapterpattern,provideNgxWorkflow(),HttpWorkflowAdapter,LocalWorkflowAdapter- Auth interceptor via
ngxWorkflowAuthInterceptor
