From 9fcc3120bd377134e598274d3c252700563984b7 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 22 Mar 2019 21:22:09 +0000 Subject: [PATCH] Added user management and also fixed the bug that Gabe pointed out with the availability on tv shows --- appveyor.yml | 2 +- .../card/discover-card-details.component.html | 2 +- .../ClientApp/src/app/interfaces/IUser.ts | 1 - .../src/app/my-nav/my-nav.component.ts | 3 +- .../app/settings/settingsmenu.component.html | 2 +- .../usermanagement-user.component.ts | 1 - .../usermanagement.component.html | 234 ++++++++---------- .../usermanagement.component.ts | 81 +++--- 8 files changed, 148 insertions(+), 178 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3c60a0006..62d87f8ab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.0.{build} +version: 4.0.{build} configuration: Release os: Visual Studio 2017 environment: diff --git a/src/Ombi/ClientApp/src/app/discover/card/discover-card-details.component.html b/src/Ombi/ClientApp/src/app/discover/card/discover-card-details.component.html index 943ba7e06..63dee260c 100644 --- a/src/Ombi/ClientApp/src/app/discover/card/discover-card-details.component.html +++ b/src/Ombi/ClientApp/src/app/discover/card/discover-card-details.component.html @@ -140,7 +140,7 @@ - diff --git a/src/Ombi/ClientApp/src/app/interfaces/IUser.ts b/src/Ombi/ClientApp/src/app/interfaces/IUser.ts index a44750040..0816ad42e 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IUser.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IUser.ts @@ -21,7 +21,6 @@ export interface IUser { episodeRequestQuota: IRemainingRequests | null; movieRequestQuota: IRemainingRequests | null; musicRequestQuota: IRemainingRequests | null; - checked: boolean; } export interface IUserQualityProfiles { diff --git a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts index b79a356a9..61db70589 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts +++ b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts @@ -28,7 +28,8 @@ export class MyNavComponent { public navItems: INavBar[] = [ { name: "NavigationBar.Discover", icon: "find_replace", link: "/discover" }, - { name: "NavigationBar.Requests", icon: "list", link: "/requests" }, + { name: "NavigationBar.Requests", icon: "list", link: "/requests" }, + { name: "NavigationBar.UserManagement", icon: "account_circle", link: "/usermanagement" }, { name: "NavigationBar.Settings", icon: "settings", link: "/Settings/About" }, ] diff --git a/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html index a8e94b89a..37a8e65c1 100644 --- a/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html @@ -5,7 +5,7 @@ - + diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts index 9940336ba..d467f02b7 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts @@ -66,7 +66,6 @@ export class UserManagementUserComponent implements OnInit { password: "", userName: "", userType: UserType.LocalUser, - checked: false, hasLoggedIn: false, lastLoggedIn: new Date(), episodeRequestLimit: 0, diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html index 5040e53a9..9a6adf97e 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html @@ -2,139 +2,121 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - Username - - - - - - - Alias - - - - - - - Email - - - - - - - Roles - - Requests Remaining - - Next Request Due - - Last Logged In - - - - - - User Type - - - - -
- - - - {{u.userName}} - - {{u.alias}} - - {{u.emailAddress}} - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + +
+ + + + + + Username {{element.userName}} Alias {{element.alias}} Email {{element.emailAddress}} Requests Remaining +
+ {{'UserManagment.MovieRemaining' | translate: {remaining: u.movieRequestQuota.remaining, total: u.movieRequestLimit} }} +
+
+ {{'UserManagment.TvRemaining' | translate: {remaining: u.episodeRequestQuota.remaining, total: u.episodeRequestLimit} }} +
+
+ {{'UserManagment.MusicRemaining' | translate: {remaining: u.musicRequestQuota.remaining, total: u.musicRequestLimit} }} +
+
Next Request Due +
+ {{'UserManagment.MovieDue' | translate: {date: (u.movieRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }} +
+
+ {{'UserManagment.TvDue' | translate: {date: (u.episodeRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }} +
+
+ {{'UserManagment.MusicDue' | translate: {date: (u.musicRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }} +
+
Last Logged In + + {{u.lastLoggedIn | amLocal | amDateFormat: 'l LT'}} + + + Not logged in yet! + User Type + Local User + Plex User + Emby User Roles +
{{claim.value}}
+
+ -
- {{'UserManagment.MovieRemaining' | translate: {remaining: u.movieRequestQuota.remaining, total: u.movieRequestLimit} }} -
-
- {{'UserManagment.TvRemaining' | translate: {remaining: u.episodeRequestQuota.remaining, total: u.episodeRequestLimit} }} -
-
- {{'UserManagment.MusicRemaining' | translate: {remaining: u.musicRequestQuota.remaining, total: u.musicRequestLimit} }} -
-
-
- {{'UserManagment.MovieDue' | translate: {date: (u.movieRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }} -
-
- {{'UserManagment.TvDue' | translate: {date: (u.episodeRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }} -
-
- {{'UserManagment.MusicDue' | translate: {date: (u.musicRequestQuota.nextRequest | amLocal | amDateFormat: 'l LT')} }} -
-
- - - {{u.lastLoggedIn | amLocal | amDateFormat: 'l LT'}} - - - Not logged in yet! - + + + + + +
+ + -
- Local User - Plex User - Emby User - - Details/Edit - - -
diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts index 98ec35081..8c76b2ac6 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.ts @@ -1,21 +1,25 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit, ViewChild } from "@angular/core"; import { ICheckbox, ICustomizationSettings, IEmailNotificationSettings, IUser } from "../interfaces"; import { IdentityService, NotificationService, SettingsService } from "../services"; +import { MatSort, MatTableDataSource } from "@angular/material"; +import { SelectionModel } from "@angular/cdk/collections"; @Component({ templateUrl: "./usermanagement.component.html", }) export class UserManagementComponent implements OnInit { + public displayedColumns: string[] = ['select', 'username', 'alias', 'email', 'roles', 'remainingRequests', + 'nextRequestDue', 'lastLoggedIn', 'userType', 'actions', 'welcome']; + public dataSource: MatTableDataSource; + + public selection = new SelectionModel(true, []); + @ViewChild(MatSort) public sort: MatSort; public users: IUser[]; public checkAll = false; public emailSettings: IEmailNotificationSettings; public customizationSettings: ICustomizationSettings; - - public order: string = "userName"; - public reverse = false; - public showBulkEdit = false; public availableClaims: ICheckbox[]; public bulkMovieLimit?: number; @@ -23,15 +27,15 @@ export class UserManagementComponent implements OnInit { public plexEnabled: boolean; constructor(private identityService: IdentityService, - private settingsService: SettingsService, - private notificationService: NotificationService, - private plexSettings: SettingsService) { } + private settingsService: SettingsService, + private notificationService: NotificationService, + private plexSettings: SettingsService) { } - public ngOnInit() { - this.users = []; - this.identityService.getUsers().subscribe(x => { - this.users = x; - }); + public async ngOnInit() { + this.users = await this.identityService.getUsers().toPromise(); + + this.dataSource = new MatTableDataSource(this.users); + this.dataSource.sort = this.sort; this.plexSettings.getPlex().subscribe(x => this.plexEnabled = x.enable); @@ -59,28 +63,12 @@ export class UserManagementComponent implements OnInit { this.notificationService.success(`Sent a welcome email to ${user.emailAddress}`); } - public checkAllBoxes() { - this.checkAll = !this.checkAll; - this.users.forEach(user => { - user.checked = this.checkAll; - }); - } - - public hasChecked(): boolean { - return this.users.some(x => { - return x.checked; - }); - } - public bulkUpdate() { const anyRoles = this.availableClaims.some(x => { return x.enabled; }); - this.users.forEach(x => { - if (!x.checked) { - return; - } + this.selection.selected.forEach(x => { if (anyRoles) { x.claims = this.availableClaims; } @@ -103,23 +91,24 @@ export class UserManagementComponent implements OnInit { this.bulkEpisodeLimit = undefined; } - public setOrder(value: string, el: any) { - el = el.toElement || el.relatedTarget || el.target || el.srcElement; + public isAllSelected() { + const numSelected = this.selection.selected.length; + const numRows = this.dataSource.data.length; + return numSelected === numRows; + } - if (el.nodeName === "A") { - el = el.parentElement; + + public masterToggle() { + this.isAllSelected() ? + this.selection.clear() : + this.dataSource.data.forEach(row => this.selection.select(row)); + } + + /** The label for the checkbox on the passed row */ + public checkboxLabel(row?: IUser): string { + if (!row) { + return `${this.isAllSelected() ? 'select' : 'deselect'} all`; } - - const parent = el.parentElement; - const previousFilter = parent.querySelector(".active"); - - if (this.order === value) { - this.reverse = !this.reverse; - } else { - previousFilter.className = ""; - el.className = "active"; - } - - this.order = value; + return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.id + 1}`; } }