ProcessMaker Developers Documentation
processmaker.comKnowledge CenterProcessMaker University
Guides
Guides
  • Getting Started
    • Installing ProcessMaker
  • Authentication
    • Creating a Client Application
    • Getting an Access Token
    • Getting a Refresh Token
  • Working with the API
    • Starting a Request via REST API
    • Starting a Request via Web Hook
  • Embedding Forms
    • Starting a Request via Anonymous Web Entry
    • Participating in a Workflow via Intermediate Web Entry (Anonymous)
    • Participating in a workflow via Intermediate Web Entry (Authenticated)
    • Angular Inbox Tutorial
      • Part 0: Overview
      • Part 1: Hello World
      • Part 2: Services & Dependencies
      • Part 3: Components
      • Part 4: The Inbox
      • Part 5: The Screen & Form Elements
  • Script Task Examples
    • PHP
  • Packages
    • ProcessMaker Platform Packages
      • Actions By Email Package
      • Advanced Screens Package
      • Advanced User Package
      • Auth Package
      • C# Package
      • Collections Package
      • Comments Package
      • Conversational Forms Package
      • Data Connector Package
      • Decision Tables Package
      • Documentation Package
      • DocuSign Package
      • Dynamic UI Package
      • File Manager Package
      • Google Places Package
      • IDP Package
      • Java Package
      • PDF Generator Package
      • PM Blocks Package
      • Process Optimization Package
      • Python Package
      • R Package
      • Saved Searches Package
      • Send Email Package
      • Signature Package
      • Slack Notification Package
      • Translations Package
      • Versioning Package
      • Vocabularies Package
      • Web Entry Package
    • Custom Packages
      • The Package Skeleton
      • Creating Your First ProcessMaker Package
Powered by GitBook
On this page
  • Overview
  • Step 1: The Router
  • Typescript
  • Step 2: RootComponent
  • Template
  • Typescript
  • Step 2: LoginComponent
  • Template
  • Typescript
  • Step 3: NavigationComponent
  • Template
  • Typescript
  • Step 4: AppBreadCrumbsComponent
  • Template
  • Typescript
  • Step 5: AppModule
  • Review
  • Next Steps
  1. Embedding Forms
  2. Angular Inbox Tutorial

Part 3: Components

Last updated 1 year ago

Overview

In this section, we'll explore the essential components of our application.

Completed code: /

  • (not technically a component but necessary)

Step 1: The Router

Before adding our components, we must configure the router and verify user authentication using our Guard.

Here is the updated code for the router.

The oauth/callback path is crucial for the OAuth 2.0 Authorization Flow.

Typescript

app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from '../components/login/login.component';

const routes: Routes = [
	{
		path: 'login',
		component: LoginComponent,
		runGuardsAndResolvers: 'always',
		title: 'Login',
	},
	{
		path: 'oauth/callback',
		component: LoginComponent,
		runGuardsAndResolvers: 'always',
	},
	{
		path: '',
		redirectTo: 'tasks',
		pathMatch: 'full',
		runGuardsAndResolvers: 'always',
	},
	{
		path: '**',
		redirectTo: 'tasks',
		runGuardsAndResolvers: 'always',
	},
];

@NgModule({
	imports: [RouterModule.forRoot(routes, { useHash: true })],
	exports: [RouterModule],
})
export class AppRoutingModule {}

The application will crash at this point, but that's ok! This is expected. We will fix it in a moment.

Step 2: RootComponent

Until now, we've used the default hello world template at src/app/components/app.component.ts. We'll remove this file, replacing it with the root component.

If you check the index.html file, you will see that there is an element app-root which is where the application will be embedded within.

Note how we have three new components in the root component.

  • app-navigation is where the top nav bar will be inserted.

  • app-breadcrumbs will show where you are in the application, right below the nav bar but above the main content section.

  • router-outlet is where the Angular router will inject the rest of the components dynamically, based on the logic we implement.

Template

app-root.component.html
<div class="main container-fluid">
	<app-navigation></app-navigation>
	<app-breadcrumbs></app-breadcrumbs>
	<router-outlet></router-outlet>
</div>

Typescript

app-root.component.ts
import { Component } from '@angular/core';

@Component({
	selector: 'app-root',
	templateUrl: './app-root.component.html',
})
export class AppComponent {
	title = 'pm4Angular';

	constructor() {}
}

Step 2: LoginComponent

Let's craft our inaugural component: the login page. The flow will use Authorization Code grant_type. This will redirect the user to the ProcessMaker installation you created the client application in, where they login and are then redirected back to the application with the authorization code.

The components we will be creating will consist of two files: the template file and the typescript file.

Template

login.component.html
<div class="main">
	<div class="row g-0">
		<div class="col">
			<div class="leftside">
				<div class="left-main">
					<div class="logo-container d-flex">
						<img
							class="mb-4"
							alt="ProcessMaker"
							src="/assets/img/PMLogo-png.webp"
							alt="" />
					</div>
					<div
						class="header-container mt-5 d-flex justify-content-center flex-column">
						<div class="title mt-3">
							<h2>Quickly preview your form tasks and screens.</h2>
						</div>

						<div class="button-text-container">
							<div class="sub-title mt-4">
								<h5 class="sub text-secondary mt-1">
									Welcome! Please login with your ProcessMaker credentials.
								</h5>

								<div class="button-container mt-4">
									<button
										(click)="login()"
										class="btn btn-primary btn-login w-100">
										Login with ProcessMaker
									</button>
									<hr class="divider mt-4" />
								</div>
							</div>
							<div class="">
								<small class="sub"
									>👋 <a class="link" href="#">Learn more</a> about
									ProcessMaker.</small
								>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="col">
			<div class="rightside">
				<div class="right-main">
					<div class="text-block">
						<h1>Automate</h1>
						<h1>Complex</h1>
						<h1>Workflows</h1>
					</div>
					<div class="square"></div>
				</div>
			</div>
		</div>
	</div>
</div>

Typescript

login.component.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/services/auth.service';
import { ActivatedRoute } from '@angular/router';

@Component({
	selector: 'app-login',
	templateUrl: './login.component.html',
})
export class LoginComponent implements OnInit {
	// Injecting AuthService and ActivatedRoute to handle authentication and route parameters
	constructor(
		public authService: AuthService,
		private activatedRoute: ActivatedRoute
	) {}

	ngOnInit() {
		// Subscribing to query parameters to detect the authorization code
		this.activatedRoute.queryParams.subscribe((params) => {
			// Checking if the 'code' parameter is present
			if (params['code']) {
				// Calling getAccessToken method in AuthService to handle the OAuth token exchange
				// No need for then or catch here as the AuthService method takes care of the response handling
				this.authService.getAccessToken(params['code']);
			}
		});
	}

	// Method to initiate the login process by calling the login method in AuthService
	login() {
		this.authService.login();
	}

	// Method to initiate the logout process by calling the logout method in AuthService
	logout() {
		this.authService.logout();
	}
}

Step 3: NavigationComponent

The navigation component houses the header logo and a logout button.

The ngIf="authService.authenticated" ensures the navbar displays only when the user is authenticated using our auth service.

Template

navigation.component.html
<nav
	*ngIf="authService.authenticated"
	class="header-container d-flex justify-content-between table-container navbar navbar-light bg-light">
	<a style="all: unset; cursor: pointer" routerLink="/tasks">
		<div class="header-text-container d-flex flex-row align-items-end">
			<img src="/assets/img/PMLOGO.png" alt="" style="height: 87px" />
			<h1 class="display-4">ProcessMaker</h1>
		</div>
	</a>
	<div class="header-text-container mt-6 d-flex align-items-end">
		<button (click)="logout()" class="btn btn-danger btn-login w-100">
			<i class="me-1 text-light bi bi-arrow-left-right"></i> Log Out
		</button>
	</div>
</nav>

Typescript

navigation.component.ts
import { Component } from '@angular/core';
import { AuthService } from 'src/app/services/auth.service';
import { DbService } from 'src/app/services/db.service';
import { ActivatedRoute, Router } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';

@Component({
	selector: 'app-navigation',
	templateUrl: './navigation.component.html',
})
export class NavigationComponent {
	title: any;
	homeCrumb: any;
	currentCrumb: any;
	constructor(
		public authService: AuthService,
		public db: DbService,
		public route: ActivatedRoute,
		public router: Router,
		public browserModule: BrowserModule
	) {}

	// Method to log out the user by calling the logout method from the AuthService
	logout() {
		this.authService.logout();
	}
}

Step 4: AppBreadCrumbsComponent

Template

app-breadcrumbs.component.html
<nav
	class="pt-2 rounded-corners"
	*ngIf="authService.authenticated"
	aria-label="breadcrumb">
	<ol class="breadcrumb">
		<li class="breadcrumb-item">
			<a href="">{{ homePageTitle() }}</a>
		</li>
		<li class="breadcrumb-item active" aria-current="page">
			{{ currentPageTitle() }}
		</li>
	</ol>
</nav>

Typescript

app-breadcrumbs.component.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/services/auth.service';
import { DbService } from 'src/app/services/db.service';
import { ActivatedRoute, Router } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
@Component({
	selector: 'app-breadcrumbs',
	templateUrl: './app-breadcrumbs.component.html',
})
export class AppBreadcrumbsComponent implements OnInit {
	title: any;
	homeCrumb: any;
	currentCrumb: any;
	constructor(
		public authService: AuthService,
		public db: DbService,
		public route: ActivatedRoute,
		public router: Router,
		public browserModule: BrowserModule
	) {}

	ngOnInit(): void {}
	currentPageTitle() {
		return (this.title = window.document.title);
	}
	homePageTitle() {
		return (this.homeCrumb = 'Home');
	}
}

Step 5: AppModule

The updated app.module.ts contains the dependencies:

  • Router

  • RootComponent

  • LoginComponent

  • NavigationComponent

  • AppBreadCrumbsComponent

app.module.ts
import { NgModule } from '@angular/core';
import '@angular/compiler';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { AppRoutingModule } from './routing/app-routing.module';
import { RootComponent } from './components/root/app-root.component';
import { LoginComponent } from './components/login/login.component';
import { NavigationComponent } from './components/nav/navigation.component';
import { AppBreadcrumbsComponent } from './components/breadcrumbs/app-breadcrumbs.component';

@NgModule({
	declarations: [
		RootComponent,
		LoginComponent,
		NavigationComponent,
		AppBreadcrumbsComponent,
	],
	imports: [
		BrowserModule,
		HttpClientModule,
		FormsModule,
		ReactiveFormsModule,
		CommonModule,
		AppRoutingModule,
	],
	providers: [],
	bootstrap: [RootComponent],
})
export class AppModule {}

Review

By following the steps, navigating to http://localhost:4200/#/login should display the login page.

With the correct OAuth credentials and Client Application setup, logging into ProcessMaker should redirect you back to the login page, now displaying the navbar and breadcrumbs, indicating a successful login.

Next Steps

Part 4: The Inbox
live example
download example
The Router
RootComponent
LoginComponent
NavigationComponent
AppBreadCrumbsComponent
Login
navbar authenticated