0 votes
902 views
in Integrations by

1 Answer

0 votes
by (30.6k points)

A headless portal = your own front end (Angular) that lists tasks, opens them and starts processes through the BPM REST API, rendering either your own forms or the BPM coaches inside an iframe. A minimal, working Angular service + component:

// bpm.service.ts (Angular 15+) - same origin as BPM (proxy /rest to the BPM server in dev: proxy.conf.json)
@Injectable({ providedIn: 'root' })
export class BpmService {
  private csrf?: string;
  constructor(private http: HttpClient) {}
  async token(): Promise<string> {
    if (this.csrf) return this.csrf;
    const r: any = await firstValueFrom(this.http.post('/rest/bpm/wle/v1/system/login', { refresh_groups: false, requested_lifetime: 7200 }));
    return this.csrf = r.csrf_token;                                   // BAW 20+ / CP4BA; on 8.5.x skip the token
  }
  async myTasks(): Promise<any[]> {
    const r: any = await firstValueFrom(this.http.put('/rest/bpm/wle/v1/search/query?organization=byTask&run=true&filterByCurrentUser=true&size=100&condition=taskStatus%7CReceived', null,
      { headers: { BPMCSRFToken: await this.token() } }));
    return r.data.data;                                                 // taskId, taskSubject, taskDueDate, instanceId, bpdName
  }
  async taskData(id: string) { return (await firstValueFrom(this.http.get<any>(`/rest/bpm/wle/v1/task/${{id}}?parts=data`))).data.data.variables; }
  async finish(id: string, output: any) {
    return firstValueFrom(this.http.put(`/rest/bpm/wle/v1/task/${{id}}?action=finish&params=${{encodeURIComponent(JSON.stringify(output))}}&parts=none`, null, { headers: { BPMCSRFToken: await this.token() } }));
  }
  async start(bpdId: string, snapshotId: string, input: any) {
    return firstValueFrom(this.http.post(`/rest/bpm/wle/v1/process?action=start&bpdId=${{bpdId}}&snapshotId=${{snapshotId}}&params=${{encodeURIComponent(JSON.stringify(input))}}&parts=header`, null, { headers: { BPMCSRFToken: await this.token() } }));
  }
}
<!-- task-list.component.html: own list, coach rendered by BPM inside an iframe when the task's form is a coach -->
<table><tr *ngFor="let t of tasks" (click)="open(t)"><td>{{ t.taskSubject }}</td><td>{{ t.taskDueDate | date }}</td><td>{{ t.bpdName }}</td></tr></table>
<iframe *ngIf="current" [src]="('/teamworks/process.lsw?zWorkflowState=1&zTaskId=' + current.taskId) | safeUrl" style="width:100%;height:80vh;border:0"></iframe>
<!-- or render your own Angular form from taskData() and complete with finish() - the "external implementation" route (question 2898) -->

Authentication: same origin (reverse proxy the SPA and BPM under one host) so that the BPM session cookie authenticates the calls; on CP4BA use the Zen session or a bearer token from IAM. Notifications: poll the task list every 30-60 s (there is no push API on traditional BAW; BAW 21+ / CP4BA offer the WebSocket notifications that Workplace uses). Everything Process Portal does (claim, reassign, comments, search, start) exists in the REST API, so the headless portal is a UI project, not an integration project.

References

Related questions

0 votes
1 answer 2.5k views
0 votes
1 answer 1.5k views
0 votes
1 answer 2.9k views
0 votes
1 answer 1.7k views
+1 vote
1 answer 2.5k views
0 votes
1 answer 1.3k views

723 questions

807 answers

98 comments

4.9k users

Join BPM Community Discord Channel

Welcome to BPM Tips Q&A, Community wiki/forum where you can ask questions and receive answers from other IBM BPM experts and members of the community. Users with 2000 points will automatically be promoted to expert level.
Created by Dosvak LLC
Our Youtube Channel
...