# Front-end access control

For each element of the user interface which is shown/hidden or enabled/disabled in the front-end based on an access control policy, a separate call is defined. These calls are subsequently bundled by the `PermissionService`, which is exported from `@valtimo/access-control`.

## Defining permissions

For a part of your user interface, for example a page, it is best to define all the permissions it needs to request in one file. In this file, define each permission to be requested separately, conforming to the interface `PermissionRequest`:

#### **`sample.permissions.ts`**

```typescript
import {PermissionRequest} from '@valtimo/access-control';

// Enums are defined for use in the below permissions. This is to avoid duplication, and is optional.
enum PERMISSION_ACTION {
    assign = 'ASSIGN',
    claim = 'CLAIM',
}

enum DOSSIER_DETAIL_PERMISSION_RESOURCE {
    domain = 'com.ritense.document.domain.impl.JsonSchemaDocument',
}

const CAN_CLAIM_CASE_PERMISSION: PermissionRequest = {
    action: PERMISSION_ACTION.claim,
    resource: DOSSIER_DETAIL_PERMISSION_RESOURCE.domain,
};

const CAN_ASSIGN_CASE_PERMISSION: PermissionRequest = {
    action: PERMISSION_ACTION.assign,
    resource: DOSSIER_DETAIL_PERMISSION_RESOURCE.domain,
};

export {CAN_CLAIM_CASE_PERMISSION, CAN_ASSIGN_CASE_PERMISSION}
```

## Using permissions

Permissions defined in the above example, are imported into your component code and transferred to the `PermissionService`, which returns an `Observable` emitting a `boolean` value for the respective permission:

#### **`sample.component.ts`**

```typescript
...
// import PermissionService
import {PermissionService} from '@valtimo/access-control';
...
// import previously defined permissions
import {
    CAN_CLAIM_CASE_PERMISSION,
    CAN_ASSIGN_CASE_PERMISSION,
} from '../permissions';
...

@Component({
    selector: 'sample-component',
    templateUrl: './sample-component.component.html',
    styleUrls: ['./sample-component.component.css'],
})
export class SampleComponent {

    // the permission to claim a case is defined directly as a component property
    public readonly canClaimCase$: Observable<boolean> = 
        this.permissionService.requestPermission(CAN_CLAIM_CASE_PERMISSION)
    
    // route paramaters are used to add dynamic context to the 'can assign case permission'
    public readonly canAssign$: Observable<boolean> = this.route.paramMap.pipe(
        switchMap((params: ParamMap) =>
            this.permissionService.requestPermission(
                // the defined permission itself
                CAN_ASSIGN_CASE_PERMISSION, 
                // context object as a second paramter
                {
                resource: DOSSIER_DETAIL_PERMISSION_RESOURCE.domain,
                identifier: params.get('documentId') ?? '',
            })
        )
    );
    
    constructor(
        ...
        // inject PermissionService
        private readonly permissionService: PermissionService
    ) {
    }
}
```

With each permission defined as an `Observable` emitting a `boolean` value, with its own component property, they may now be used in the template code of your component. To do this efficiently, it is recommended to use `async` pipes:

#### **`sample.component.html`**

```angular2html
<div class="container">
    <!--    The claim button is shown when a case can be claimed-->
    <button *ngIf="canClaimCase$ | async" (click)="claim()">
        Claim case
    </button>

    <!--    The assign button is enabled when a case can be assigned-->
    <button [disabled]="(canAssign$ | async) === false" (click)="assign()">
        Assign case
    </button>
</div>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.valtimo.nl/v12/features/access-control/for-developers/frontend-access-control.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
