|
|
@ -2,139 +2,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<button type="button" class="btn btn-success-outline" data-test="adduserbtn" [routerLink]="['/usermanagement/user']">Add User To Ombi</button>
|
|
|
|
<button type="button" mat-raised-button color="primary" data-test="adduserbtn" [routerLink]="['/usermanagement/user']">Add User To Ombi</button>
|
|
|
|
|
|
|
|
|
|
|
|
<button type="button" style="float:right;" class="btn btn-primary-outline"(click)="showBulkEdit = !showBulkEdit" [disabled]="!hasChecked()">Bulk Edit</button>
|
|
|
|
<button type="button" style="float:right;" mat-raised-button color="primary" (click)="showBulkEdit = !showBulkEdit" [disabled]="this.selection.selected.length <= 0">Bulk Edit</button>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Table -->
|
|
|
|
<table *ngIf="dataSource" mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
|
|
|
<table class="table table-striped table-hover table-responsive table-condensed table-usermanagement">
|
|
|
|
|
|
|
|
<thead>
|
|
|
|
<ng-container matColumnDef="select">
|
|
|
|
<tr>
|
|
|
|
<th mat-header-cell *matHeaderCellDef>
|
|
|
|
<th style="width:1%">
|
|
|
|
<mat-checkbox (change)="$event ? masterToggle() : null"
|
|
|
|
<a>
|
|
|
|
[checked]="selection.hasValue() && isAllSelected()"
|
|
|
|
<td class="checkbox" data-label="Select:">
|
|
|
|
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
|
|
|
<input id="all" type="checkbox" ng-checked="checkAll" (change)="checkAllBoxes()">
|
|
|
|
[aria-label]="checkboxLabel()">
|
|
|
|
<label for="all"></label>
|
|
|
|
</mat-checkbox>
|
|
|
|
</td>
|
|
|
|
</th>
|
|
|
|
</a>
|
|
|
|
<td mat-cell *matCellDef="let row">
|
|
|
|
</th>
|
|
|
|
<mat-checkbox (click)="$event.stopPropagation()"
|
|
|
|
<th class="active" (click)="setOrder('userName', $event)">
|
|
|
|
(change)="$event ? selection.toggle(row) : null"
|
|
|
|
<a>
|
|
|
|
[checked]="selection.isSelected(row)"
|
|
|
|
Username
|
|
|
|
[aria-label]="checkboxLabel(row)">
|
|
|
|
</a>
|
|
|
|
</mat-checkbox>
|
|
|
|
<span *ngIf="order === 'userName'">
|
|
|
|
</td>
|
|
|
|
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
|
|
|
</ng-container>
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</th>
|
|
|
|
<ng-container matColumnDef="username">
|
|
|
|
<th (click)="setOrder('alias', $event)">
|
|
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Username </th>
|
|
|
|
<a>
|
|
|
|
<td mat-cell *matCellDef="let element"> {{element.userName}} </td>
|
|
|
|
Alias
|
|
|
|
</ng-container>
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<span *ngIf="order === 'alias'">
|
|
|
|
<ng-container matColumnDef="alias">
|
|
|
|
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
|
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th>
|
|
|
|
</span>
|
|
|
|
<td mat-cell *matCellDef="let element"> {{element.alias}} </td>
|
|
|
|
</th>
|
|
|
|
</ng-container>
|
|
|
|
<th (click)="setOrder('emailAddress', $event)">
|
|
|
|
|
|
|
|
<a>
|
|
|
|
<ng-container matColumnDef="email">
|
|
|
|
Email
|
|
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
|
|
|
|
</a>
|
|
|
|
<td mat-cell *matCellDef="let element"> {{element.emailAddress}} </td>
|
|
|
|
<span *ngIf="order === 'emailAddress'">
|
|
|
|
</ng-container>
|
|
|
|
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span>
|
|
|
|
|
|
|
|
<span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
|
|
|
<ng-container matColumnDef="remainingRequests">
|
|
|
|
</span>
|
|
|
|
<th mat-header-cell *matHeaderCellDef> Requests Remaining </th>
|
|
|
|
</th>
|
|
|
|
<td mat-cell *matCellDef="let u">
|
|
|
|
<th>
|
|
|
|
<div *ngIf="u.movieRequestQuota != null && u.movieRequestQuota.hasLimit">
|
|
|
|
Roles
|
|
|
|
{{'UserManagment.MovieRemaining' | translate: {remaining: u.movieRequestQuota.remaining, total: u.movieRequestLimit} }}
|
|
|
|
</th>
|
|
|
|
</div>
|
|
|
|
<th>
|
|
|
|
<div *ngIf="u.episodeRequestQuota != null && u.episodeRequestQuota.hasLimit">
|
|
|
|
Requests Remaining
|
|
|
|
{{'UserManagment.TvRemaining' | translate: {remaining: u.episodeRequestQuota.remaining, total: u.episodeRequestLimit} }}
|
|
|
|
</th>
|
|
|
|
</div>
|
|
|
|
<th>
|
|
|
|
<div *ngIf="u.musicRequestQuota != null && u.musicRequestQuota.hasLimit">
|
|
|
|
Next Request Due
|
|
|
|
{{'UserManagment.MusicRemaining' | translate: {remaining: u.musicRequestQuota.remaining, total: u.musicRequestLimit} }}
|
|
|
|
</th>
|
|
|
|
</div>
|
|
|
|
<th (click)="setOrder('lastLoggedIn', $event)">
|
|
|
|
</td>
|
|
|
|
<a> Last Logged In</a>
|
|
|
|
</ng-container>
|
|
|
|
<span *ngIf="order === 'lastLoggedIn'">
|
|
|
|
|
|
|
|
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
|
|
|
<ng-container matColumnDef="nextRequestDue">
|
|
|
|
</span>
|
|
|
|
<th mat-header-cell *matHeaderCellDef> Next Request Due </th>
|
|
|
|
</th>
|
|
|
|
<td mat-cell *matCellDef="let u">
|
|
|
|
<th (click)="setOrder('userType', $event)">
|
|
|
|
<div *ngIf="u.movieRequestQuota != null && u.movieRequestQuota.remaining != u.movieRequestLimit">
|
|
|
|
<a>
|
|
|
|
{{'UserManagment.MovieDue' | translate: {date: (u.movieRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }}
|
|
|
|
User Type
|
|
|
|
</div>
|
|
|
|
</a>
|
|
|
|
<div *ngIf="u.episodeRequestQuota != null && u.episodeRequestQuota.remaining != u.episodeRequestLimit">
|
|
|
|
<span *ngIf="order === 'userType'">
|
|
|
|
{{'UserManagment.TvDue' | translate: {date: (u.episodeRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }}
|
|
|
|
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
|
|
|
</div>
|
|
|
|
</span>
|
|
|
|
<div *ngIf="u.musicRequestQuota != null && u.musicRequestQuota.remaining != u.musicRequestLimit">
|
|
|
|
</th>
|
|
|
|
{{'UserManagment.MusicDue' | translate: {date: (u.musicRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }}
|
|
|
|
</tr>
|
|
|
|
</div>
|
|
|
|
</thead>
|
|
|
|
</td>
|
|
|
|
<tbody>
|
|
|
|
</ng-container>
|
|
|
|
<tr *ngFor="let u of users | orderBy: order : reverse : 'case-insensitive'">
|
|
|
|
<ng-container matColumnDef="lastLoggedIn">
|
|
|
|
<td class="checkbox" data-label="Select:">
|
|
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Last Logged In </th>
|
|
|
|
<input id="{{u.id}}" type="checkbox" [(ngModel)]="u.checked">
|
|
|
|
<td mat-cell *matCellDef="let u">
|
|
|
|
<label for="{{u.id}}"></label>
|
|
|
|
<span *ngIf="u.lastLoggedIn">
|
|
|
|
</td>
|
|
|
|
{{u.lastLoggedIn | amLocal | amDateFormat: 'l LT'}}
|
|
|
|
<td class="td-labelled" data-label="Username:">
|
|
|
|
</span>
|
|
|
|
{{u.userName}}
|
|
|
|
<span *ngIf="!u.lastLoggedIn">
|
|
|
|
</td>
|
|
|
|
Not logged in yet!
|
|
|
|
<td class="td-labelled" data-label="Alias:">
|
|
|
|
</span> </td>
|
|
|
|
{{u.alias}}
|
|
|
|
</ng-container>
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td class="td-labelled" data-label="Email:">
|
|
|
|
<ng-container matColumnDef="userType">
|
|
|
|
{{u.emailAddress}}
|
|
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> User Type </th>
|
|
|
|
</td>
|
|
|
|
<td mat-cell *matCellDef="let u">
|
|
|
|
<td class="td-labelled" data-label="Roles:">
|
|
|
|
<span *ngIf="u.userType === 1">Local User</span>
|
|
|
|
<div *ngFor="let claim of u.claims">
|
|
|
|
<span *ngIf="u.userType === 2">Plex User</span>
|
|
|
|
|
|
|
|
<span *ngIf="u.userType === 3">Emby User</span> </td>
|
|
|
|
|
|
|
|
</ng-container>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ng-container matColumnDef="roles">
|
|
|
|
|
|
|
|
<th mat-header-cell *matHeaderCellDef> Roles </th>
|
|
|
|
|
|
|
|
<td mat-cell *matCellDef="let element">
|
|
|
|
|
|
|
|
<div *ngFor="let claim of element.claims">
|
|
|
|
<span *ngIf="claim.enabled">{{claim.value}}</span>
|
|
|
|
<span *ngIf="claim.enabled">{{claim.value}}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
</ng-container>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ng-container matColumnDef="actions">
|
|
|
|
|
|
|
|
<th mat-header-cell *matHeaderCellDef> </th>
|
|
|
|
|
|
|
|
<td mat-cell *matCellDef="let u">
|
|
|
|
|
|
|
|
<button mat-raised-button color="accent" [routerLink]="['/usermanagement/user/' + u.id]">Details/Edit</button>
|
|
|
|
</td>
|
|
|
|
</td>
|
|
|
|
<td class="td-labelled" data-label="Requests Remaining">
|
|
|
|
</ng-container>
|
|
|
|
<div *ngIf="u.movieRequestQuota != null && u.movieRequestQuota.hasLimit">
|
|
|
|
|
|
|
|
{{'UserManagment.MovieRemaining' | translate: {remaining: u.movieRequestQuota.remaining, total: u.movieRequestLimit} }}
|
|
|
|
<ng-container matColumnDef="welcome">
|
|
|
|
</div>
|
|
|
|
<th mat-header-cell *matHeaderCellDef> </th>
|
|
|
|
<div *ngIf="u.episodeRequestQuota != null && u.episodeRequestQuota.hasLimit">
|
|
|
|
<td mat-cell *matCellDef="let u">
|
|
|
|
{{'UserManagment.TvRemaining' | translate: {remaining: u.episodeRequestQuota.remaining, total: u.episodeRequestLimit} }}
|
|
|
|
<button *ngIf="!u.hasLoggedIn" mat-raised-button color="accent" (click)="welcomeEmail(u)" [disabled]="!customizationSettings.applicationUrl">Send Welcome Email</button>
|
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
<div *ngIf="u.musicRequestQuota != null && u.musicRequestQuota.hasLimit">
|
|
|
|
</ng-container>
|
|
|
|
{{'UserManagment.MusicRemaining' | translate: {remaining: u.musicRequestQuota.remaining, total: u.musicRequestLimit} }}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
|
|
</td>
|
|
|
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
|
|
|
<td class="td-labelled" data-label="Request Due">
|
|
|
|
</table>
|
|
|
|
<div *ngIf="u.movieRequestQuota != null && u.movieRequestQuota.remaining != u.movieRequestLimit">
|
|
|
|
|
|
|
|
{{'UserManagment.MovieDue' | translate: {date: (u.movieRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }}
|
|
|
|
<!-- Table -->
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div *ngIf="u.episodeRequestQuota != null && u.episodeRequestQuota.remaining != u.episodeRequestLimit">
|
|
|
|
|
|
|
|
{{'UserManagment.TvDue' | translate: {date: (u.episodeRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div *ngIf="u.musicRequestQuota != null && u.musicRequestQuota.remaining != u.musicRequestLimit">
|
|
|
|
|
|
|
|
{{'UserManagment.MusicDue' | translate: {date: (u.musicRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td class="td-labelled" data-label="Last Logged In:">
|
|
|
|
|
|
|
|
<!-- {{u.lastLoggedIn | date: 'short'}} -->
|
|
|
|
|
|
|
|
<span *ngIf="u.lastLoggedIn">
|
|
|
|
|
|
|
|
{{u.lastLoggedIn | amLocal | amDateFormat: 'l LT'}}
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span *ngIf="!u.lastLoggedIn">
|
|
|
|
|
|
|
|
Not logged in yet!
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td class="td-labelled" data-label="User Type:">
|
|
|
|
|
|
|
|
<span *ngIf="u.userType === 1">Local User</span>
|
|
|
|
|
|
|
|
<span *ngIf="u.userType === 2">Plex User</span>
|
|
|
|
|
|
|
|
<span *ngIf="u.userType === 3">Emby User</span>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td>
|
|
|
|
|
|
|
|
<a id="edit{{u.userName}}" [routerLink]="['/usermanagement/user/' + u.id]" class="btn btn-sm btn-info-outline">Details/Edit</a>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
<td *ngIf="customizationSettings">
|
|
|
|
|
|
|
|
<button *ngIf="!u.hasLoggedIn" (click)="welcomeEmail(u)" [disabled]="!customizationSettings.applicationUrl" class="btn btn-sm btn-info-outline">Send Welcome Email</button>
|
|
|
|
|
|
|
|
</td>
|
|
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<p-sidebar [(visible)]="showBulkEdit" position="right" styleClass="ui-sidebar-md side-back">
|
|
|
|
<p-sidebar [(visible)]="showBulkEdit" position="right" styleClass="ui-sidebar-md side-back">
|
|
|
|