2018-08-28 11:07:10 +02:00
|
|
|
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
|
2018-07-12 14:11:31 +02:00
|
|
|
|
2018-08-28 11:07:10 +02:00
|
|
|
import { OperatorService, Permission } from 'app/core/services/operator.service';
|
2018-07-23 16:42:17 +02:00
|
|
|
import { OpenSlidesComponent } from 'app/openslides.component';
|
2018-07-06 09:38:25 +02:00
|
|
|
|
2018-07-12 14:11:31 +02:00
|
|
|
/**
|
|
|
|
* Directive to check if the {@link OperatorService} has the correct permissions to access certain functions
|
|
|
|
*
|
|
|
|
* Successor of os-perms in OpenSlides 2.2
|
2018-09-03 17:57:20 +02:00
|
|
|
* @example <div *osPerms="'perm'" ..> ... < /div>
|
|
|
|
* @example <div *osPerms="['perm1', 'perm2']" ..> ... < /div>
|
2018-07-12 14:11:31 +02:00
|
|
|
*/
|
2018-07-06 09:38:25 +02:00
|
|
|
@Directive({
|
2018-09-03 17:57:20 +02:00
|
|
|
selector: '[osPerms]'
|
2018-07-06 09:38:25 +02:00
|
|
|
})
|
2018-09-03 17:57:20 +02:00
|
|
|
export class PermsDirective extends OpenSlidesComponent {
|
2018-07-12 14:11:31 +02:00
|
|
|
/**
|
2018-08-28 11:07:10 +02:00
|
|
|
* Holds the required permissions the access a feature
|
2018-07-12 14:11:31 +02:00
|
|
|
*/
|
2018-08-28 11:07:10 +02:00
|
|
|
private permissions: Permission[] = [];
|
2018-07-12 14:11:31 +02:00
|
|
|
|
|
|
|
/**
|
2018-08-28 11:07:10 +02:00
|
|
|
* Holds the value of the last permission check. Therefore one can check, if the
|
|
|
|
* permission has changes, to save unnecessary view updates, if not.
|
2018-07-12 14:11:31 +02:00
|
|
|
*/
|
2018-08-28 11:07:10 +02:00
|
|
|
private lastPermissionCheckResult = false;
|
2018-07-06 09:38:25 +02:00
|
|
|
|
2018-09-18 18:27:14 +02:00
|
|
|
/**
|
|
|
|
* Alternative to the permissions. Used in special case where a combination
|
|
|
|
* with *ngIf would be required.
|
|
|
|
*
|
|
|
|
* # Example:
|
|
|
|
*
|
|
|
|
* The div will render if the permission `user.can_manage` is set
|
|
|
|
* or if `this.ownPage` is `true`
|
|
|
|
* ```html
|
|
|
|
* <div *osPerms="'users.can_manage';or:ownPage"> something </div>
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
private alternative: boolean;
|
|
|
|
|
2018-11-08 11:33:30 +01:00
|
|
|
/**
|
|
|
|
* Switch, to invert the result of checkPermission. Usefull for using osPerms as if-else:
|
|
|
|
* For one element you can use `*osPerms="'perm'"` and for the else-element use
|
|
|
|
* `*osPerms="'perm';complement: true"`.
|
|
|
|
*/
|
|
|
|
private complement: boolean;
|
|
|
|
|
2018-07-12 14:11:31 +02:00
|
|
|
/**
|
2018-08-28 11:07:10 +02:00
|
|
|
* Constructs the directive once. Observes the operator for it's groups so the
|
|
|
|
* directive can perform changes dynamically
|
2018-07-12 14:11:31 +02:00
|
|
|
*
|
|
|
|
* @param template inner part of the HTML container
|
|
|
|
* @param viewContainer outer part of the HTML container (for example a `<div>`)
|
|
|
|
* @param operator OperatorService
|
|
|
|
*/
|
2018-08-29 13:21:25 +02:00
|
|
|
public constructor(
|
2018-07-06 09:38:25 +02:00
|
|
|
private template: TemplateRef<any>,
|
2018-07-12 14:11:31 +02:00
|
|
|
private viewContainer: ViewContainerRef,
|
2018-07-06 09:38:25 +02:00
|
|
|
private operator: OperatorService
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
|
|
|
|
// observe groups of operator, so the directive can actively react to changes
|
|
|
|
this.operator.getObservable().subscribe(content => {
|
2018-08-28 11:07:10 +02:00
|
|
|
this.updateView();
|
2018-07-06 09:38:25 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-07-12 14:11:31 +02:00
|
|
|
/**
|
|
|
|
* Comes directly from the view.
|
2018-08-28 11:07:10 +02:00
|
|
|
* The value defines the requires permissions as an array or a single permission.
|
2018-07-12 14:11:31 +02:00
|
|
|
*/
|
2018-07-06 09:38:25 +02:00
|
|
|
@Input()
|
2018-09-07 13:12:59 +02:00
|
|
|
public set osPerms(value: string | string[]) {
|
2018-08-28 11:07:10 +02:00
|
|
|
if (!value) {
|
|
|
|
value = [];
|
|
|
|
} else if (typeof value === 'string') {
|
|
|
|
value = [value];
|
|
|
|
}
|
2018-07-06 09:38:25 +02:00
|
|
|
this.permissions = value;
|
|
|
|
this.updateView();
|
|
|
|
}
|
|
|
|
|
2018-09-18 18:27:14 +02:00
|
|
|
/**
|
|
|
|
* Comes from the view.
|
|
|
|
* `;or:` turns into osPermsOr during runtime.
|
|
|
|
*/
|
|
|
|
@Input('osPermsOr')
|
|
|
|
public set osPermsAlt(value: boolean) {
|
|
|
|
this.alternative = value;
|
|
|
|
this.updateView();
|
|
|
|
}
|
|
|
|
|
2018-11-08 11:33:30 +01:00
|
|
|
/**
|
|
|
|
* COmes from the view.
|
|
|
|
*/
|
|
|
|
@Input('osPermsComplement')
|
|
|
|
public set osPermsComplement(value: boolean) {
|
|
|
|
this.complement = value;
|
|
|
|
this.updateView();
|
|
|
|
}
|
|
|
|
|
2018-07-12 14:11:31 +02:00
|
|
|
/**
|
|
|
|
* Shows or hides certain content in the view.
|
|
|
|
*/
|
2018-07-06 09:38:25 +02:00
|
|
|
private updateView(): void {
|
2018-08-28 11:07:10 +02:00
|
|
|
const hasPerms = this.checkPermissions();
|
|
|
|
const permsChanged = hasPerms !== this.lastPermissionCheckResult;
|
|
|
|
|
2018-09-18 18:27:14 +02:00
|
|
|
if ((hasPerms && permsChanged) || this.alternative) {
|
2018-08-28 11:07:10 +02:00
|
|
|
// clean up and add the template
|
|
|
|
this.viewContainer.clear();
|
2018-07-06 09:38:25 +02:00
|
|
|
this.viewContainer.createEmbeddedView(this.template);
|
2018-08-28 11:07:10 +02:00
|
|
|
} else if (!hasPerms) {
|
2018-07-06 09:38:25 +02:00
|
|
|
// will remove the content of the container
|
|
|
|
this.viewContainer.clear();
|
|
|
|
}
|
2018-08-28 11:07:10 +02:00
|
|
|
this.lastPermissionCheckResult = hasPerms;
|
2018-07-06 09:38:25 +02:00
|
|
|
}
|
|
|
|
|
2018-07-12 14:11:31 +02:00
|
|
|
/**
|
|
|
|
* Compare the required permissions with the users permissions.
|
|
|
|
* Returns true if the users permissions fit.
|
|
|
|
*/
|
2018-07-06 09:38:25 +02:00
|
|
|
private checkPermissions(): boolean {
|
2018-11-08 11:33:30 +01:00
|
|
|
const hasPerms = this.permissions.length === 0 || this.operator.hasPerms(...this.permissions);
|
|
|
|
if (this.complement) {
|
|
|
|
return !hasPerms;
|
|
|
|
} else {
|
|
|
|
return hasPerms;
|
|
|
|
}
|
2018-07-06 09:38:25 +02:00
|
|
|
}
|
|
|
|
}
|