# Part 4: The Inbox

## Overview

With the core services and components in place, we'll now interface with the ProcessMaker API.

Completed code: [live example](https://stackblitz.com/edit/stackblitz-starters-qdoure) / [download example](https://github.com/ProcessMaker/angular4pm/tree/part-4/src)

## Step 1: Environment Details

Ensure you have the subsequent details ready for this section:

* Client ID
* Client Secret
* FQDN for your ProcessMaker installation
* OAuth Token URL
* OAuth Redirect URI
* OAuth Authorization URL

You can see what a sample `environment.ts` file looks like below. This is where you will add the above information.

<details>

<summary><code>environment.ts</code></summary>

```typescript
export const environment = {
	production: false,
	apiDomain: 'localhost',
	apiPath: '/api/1.0',
	apiProtocol: 'http://',
	clientId: '19',
	clientSecret: 'Psn9cxcGFKO1GO4ZZ9TgOhQtAjt0Wmzjc58vw8Lq',
	oauthUrl: 'http://localhost/oauth/token',
	redirectUri: 'http://localhost:4200/#/oauth/callback',
	oauthAuthorizeUrl: 'http://localhost/oauth/authorize',
	customCss: false,
	calcProps: true,
};
```

</details>

## Step 2: TasksComponent

The `TasksComponent` relies on the `ScreenComponent`, which we'll address in the subsequent section. We'll omit it for now and reintroduce it when we're set to render the form.

### Template

<details>

<summary><code>app-tasks.component.html</code></summary>

```html
<div class="container-fluid">
	<div class="table-container mt-4">
		<div class="mb-2">
			<h2>Your pending tasks</h2>
			<h5 class="text-secondary">View your assigned tasks.</h5>
		</div>
		<table id="mytable" class="table align-middle mb-0 bg-white">
			<thead class="bg-light">
				<tr class="header-row">
					<th>ID #</th>
					<th>Task Name</th>
					<th>Status</th>
					<th>Assignee</th>
					<th>Process</th>
					<th>Due</th>
					<th></th>
				</tr>
			</thead>
			<tbody>
				<tr *ngIf="!userTasks.length">
					<td colspan="6">
						<p>Loading...</p>
					</td>
				</tr>
				<tr *ngFor="let task of userTasks">
					<td>
						<p class="fw-bold fw-normal mb-1">{{ task.process_request_id }}</p>
					</td>
					<td>
						<p class="fw-bold fw-normal mb-1">{{ task.element_name }}</p>
					</td>

					<td>
						<div [ngSwitch]="task.advanceStatus">
							<span
								*ngSwitchCase="'overdue'"
								class="badge badge-danger rounded-pill d-inline"
								style="text-transform: capitalize"
								>{{ task.advanceStatus }}</span
							>
							<span
								*ngSwitchCase="'completed'"
								class="badge badge-primary rounded-pill d-inline"
								style="text-transform: capitalize"
								>{{ task.advanceStatus }}</span
							>
							<span
								*ngSwitchCase="'open'"
								class="badge badge-success rounded-pill d-inline"
								style="text-transform: capitalize"
								>{{ task.advanceStatus }}</span
							>
						</div>
					</td>

					<td>{{ task.user.firstname }} {{ task.user.lastname }}</td>
					<td>{{ task.process_request.name }}</td>
					<td>
						<div>
							<span>{{ task.due_at }}</span>
						</div>
					</td>
					<td>
						<button
							(click)="openScreen(task.process_request_id, task.id)"
							type="button"
							class="btn btn-link btn-sm btn-rounded text-primary">
							<i class="me-1 bi-window-sidebar text-primary"></i>
							View Task
						</button>
					</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>

```

</details>

### Typescript

<details>

<summary><code>app-tasks.component.ts</code></summary>

```typescript
// Import necessary Angular core modules
import { Component, OnInit } from '@angular/core';
// Import Angular routing modules
import { ActivatedRoute, Router } from '@angular/router';
// Import services related to ProcessRequests and Tasks
import { ProcessRequestsService, TasksService } from 'api';
// Import local database service
import { DbService } from 'src/app/services/db.service';

// Define the Task interface to represent the structure of a task
interface Task {
	process_request_id: string; // ID of the associated process request
	element_name: string; // Name of the element
	advanceStatus: string; // Status of the task advancement
	user: { firstname: string; lastname: string }; // User information
	process_request: { name: string }; // Process request information
	due_at: string; // Due date for the task
	id: string; // Unique ID for the task
}

// Component metadata
@Component({
	selector: 'app-tasks', // Selector used in templates
	templateUrl: './app-tasks.component.html', // Path to the HTML template
})
// TasksComponent class definition
export class TasksComponent implements OnInit {
	// Pagination properties
	pagination = {
		currentPage: 1, // Current page number
		itemsPerPage: 10, // Number of items per page
		lastPage: null, // Last page number
		totalItems: null, // Total number of items
	};

	// Selected request and task properties
	selectedRequest: Request | null = null;
	selectedTask: Task | null = null;
	userTasks: Task[] = []; // Array to hold user tasks
	color = 'green'; // Color property (usage not shown in provided code)

	// Constructor with dependency injection
	constructor(
		private requestApi: ProcessRequestsService, // Process request service
		private tasksApi: TasksService, // Task service
		private route: ActivatedRoute, // Activated route information
		private router: Router, // Router service for navigation
		private db: DbService // Database service
	) {}

	// ngOnInit lifecycle hook
	ngOnInit() {
		// Load access token from the database
		const accessToken = this.db.load('access_token') as string | undefined;
		// If access token exists, set it in the task API configuration
		if (accessToken) {
			this.tasksApi.configuration.credentials['pm_api_bearer'] = accessToken;
		}

		// Call getTasks method from tasksApi with parameters null and 'ACTIVE'
		this.tasksApi.getTasks(undefined, 'ACTIVE').subscribe(
			(response: any) => {
				// Handle successful response
				this.userTasks = response.data; // Assign user tasks from response data
				// Create a new ScreenComponent instance
				console.log(this.userTasks);
			},
			(error) => {
				// Handle error response
				console.log(error); // Log the error to the console
			}
		);
	}

	// Method to open a form with given processRequestId and taskId
	openScreen(processRequestId: string, taskId: string) {
		// Navigate to the 'form' route with parameters
		this.router.navigate([
			'screen',
			{
				processRequestId: processRequestId,
				taskId: taskId,
			},
		]);
	}

	// Placeholder method for getting a user task by ID
	getUserTask(id: string) {}

	// Placeholder method for getting user tasks by ID
	getUserTasks(id: string) {}
}
```

</details>

## Step 3: Update the Router

Integrate the new components and their respective paths into the router. The following code demonstrates how to import these components and establish a route for the inbox view.

<details>

<summary><code>app-routing.module.ts</code></summary>

{% code overflow="wrap" %}
```typescript
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from '../components/login/login.component';
import { TasksComponent } from '../components/tasks/app-tasks.component';
import { AuthGuard } from '../guards/auth.guard';

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

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

</details>

## Step 4: Update AppModule

Now we just need to incorporate the `TasksComponent` into the `AppModule` declaration.

<details>

<summary><code>app.module.ts</code></summary>

{% code overflow="wrap" %}
```typescript
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';
import { TasksComponent } from './components/tasks/app-tasks.component';

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

```
{% endcode %}

</details>

## Review

If you are following along with the tutorial, you should now be able to see your tasks, in your new Angular Inbox!

<figure><img src="https://1243566085-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPyTHGwZ0VereJkRNmGxE%2Fuploads%2F4VnkD5vfMEgGdctSelEA%2Fimage.png?alt=media&#x26;token=601ff77c-a096-49f4-b9ca-4ec1a3f4490c" alt=""><figcaption><p>Angular Inbox for ProcessMaker</p></figcaption></figure>

## Next Steps

{% content-ref url="part-5-the-screen-and-form-elements" %}
[part-5-the-screen-and-form-elements](part-5-the-screen-and-form-elements)
{% endcontent-ref %}
