diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexServerDialogData.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexServerDialogData.ts new file mode 100644 index 000000000..703ab297a --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexServerDialogData.ts @@ -0,0 +1,7 @@ +import { IPlexServer } from "../../../../interfaces"; + +export interface PlexServerDialogData { + server: IPlexServer; + deleted?: boolean; + closed?: boolean; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts index 1569393f8..e6ffcfb23 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts @@ -1,2 +1,3 @@ export * from './PlexSyncType'; -export * from './PlexCreds'; \ No newline at end of file +export * from './PlexCreds'; +export * from './PlexServerDialogData'; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.html b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.html new file mode 100644 index 000000000..401bfef5c --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.html @@ -0,0 +1,111 @@ +

Server Configuration

+ +

Connection

+ + + + + + + + + Server Name + + Auto populated during discovery of the server if left empty. + + +
+ + Hostname / IP + + Must be specified. + + + + Port + + Must be specified. + Must be a number. + + + + SSL + +
+ + + Plex Authorization Token + + Must be specified. + + + + Machine Identifier + + Must be specified. + + + + Externally Facing Hostname + + + This will be the external address that users will navigate to when they press the 'View On Plex' button +
+ Current URL: "{{this.data.server.serverHostname}}/web/app#!/server/{{this.data.server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334" + Current URL: "https://app.plex.tv/web/app#!/server/{{this.data.server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334" + +
+
+ +

Libraries

+
+ +
+
+ +
+
+
+ {{lib.title}} +
+
+
+
+ +
+ + + + + + + + + \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.scss b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.scss new file mode 100644 index 000000000..33ad7a09b --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.scss @@ -0,0 +1,27 @@ +@media (max-width: 978px) { + ::ng-deep .mat-dialog-container { + overflow: unset; + display: flex; + flex-direction: column; + + .mat-dialog-content{ + max-height: unset; + } + + .mat-dialog-actions{ + min-height: unset; + } + + emby-server-dialog-component { + display: flex; + flex-direction: column; + min-height: 1px; + } + } +} + +::ng-deep mat-form-field .mat-form-field { + &-subscript-wrapper { + position: static; + } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.ts new file mode 100644 index 000000000..5ea545599 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-server-dialog/plex-server-dialog.component.ts @@ -0,0 +1,79 @@ +import { Component, Inject } from "@angular/core"; +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; + +import { + PlexService, + NotificationService, + TesterService, +} from "../../../../services"; +import { take } from "rxjs"; +import { IPlexLibrariesSettings, IPlexServer } from "../../../../interfaces"; +import { PlexServerDialogData } from "../models"; + +@Component({ + selector: "plex-server-dialog-component", + templateUrl: "plex-server-dialog.component.html", + styleUrls: ["plex-server-dialog.component.scss"], +}) +export class PlexServerDialogComponent { + + + public password: string; + public username: string; + + constructor( + private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: PlexServerDialogData, + private notificationService: NotificationService, + private testerService: TesterService, + private plexService: PlexService + ) { + } + + + public cancel() { + this.dialogRef.close({closed: true}); + } + + public testPlex() { + this.testerService.plexTest(this.data.server).pipe(take(1)) + .subscribe(x => { + if (x === true) { + this.notificationService.success(`Successfully connected to the Plex server ${this.data.server.name}!`); + } else { + this.notificationService.error(`We could not connect to the Plex server ${this.data.server.name}!`); + } + }); +} + + public delete() { + this.dialogRef.close({deleted: true}); + } + + public save() { + this.dialogRef.close({server: this.data.server}); + } + + public loadLibraries() { + if (this.data.server.ip == null) { + this.notificationService.error("Plex is not yet configured correctly"); + return; + } + this.plexService.getLibraries(this.data.server).subscribe(x => { + this.data.server.plexSelectedLibraries = []; + if (x.successful) { + x.data.mediaContainer.directory.forEach((item) => { + const lib: IPlexLibrariesSettings = { + key: item.key, + title: item.title, + enabled: false, + }; + this.data.server.plexSelectedLibraries.push(lib); + }); + } else { + this.notificationService.error(x.message); + } + }); + } + +} diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html index 53b0eed29..e88d86040 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html @@ -14,36 +14,98 @@
+ +
+ +
+ + + + +
+
+ +
+
- - +
+ Please select the server: +
+
+
+ + + +
+ +
+ + + + {{s.name}} + + +
+
+
-
- -
-
-
- - +

Servers

+ + + + - - - + + + + + + +
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
-
diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss index 7acdcf6f0..b6e3bd73e 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss @@ -21,4 +21,26 @@ ::ng-deep div .mat-tab-body-content { overflow: hidden; -} \ No newline at end of file +} +.server-card { + margin: 0em 1em 1em 0; + width: 13em; + min-height: 8em; + + button { + text-align: center; + align-content: center; + white-space: normal; + overflow-wrap: anywhere; + height: 100%; + width: 100%; + } + + i { + margin-top: 0.25em; + } + + h3 { + margin: 0; + } + } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts index d026fd1dd..712b77dc1 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts @@ -8,7 +8,8 @@ import { MatTabChangeEvent, MatTabGroup } from "@angular/material/tabs"; import {UntypedFormControl} from '@angular/forms'; import { MatDialog } from "@angular/material/dialog"; import { PlexWatchlistComponent } from "./components/watchlist/plex-watchlist.component"; -import { PlexCreds, PlexSyncType } from "./components/models"; +import { PlexServerDialogComponent } from "./components/plex-server-dialog/plex-server-dialog.component"; +import { PlexCreds, PlexServerDialogData, PlexSyncType } from "./components/models"; @Component({ templateUrl: "./plex.component.html", @@ -21,9 +22,14 @@ export class PlexComponent implements OnInit, OnDestroy { selected = new UntypedFormControl(0); @ViewChild("tabGroup", {static: false}) public tagGroup: MatTabGroup; + + public username: string; + public password: string; + public advanced = false; private subscriptions = new Subject(); + public PlexSyncType = PlexSyncType; constructor( private settingsService: SettingsService, @@ -39,8 +45,8 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public requestServers({ username, password }: PlexCreds) { - this.plexService.getServers(username, password).pipe( + public requestServers() { + this.plexService.getServers(this.username, this.password).pipe( takeUntil(this.subscriptions), ).subscribe(x => { if (x.success) { @@ -53,7 +59,9 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public selectServer(selectedServer: IPlexServerResponse, server: IPlexServer) { + public selectServer(selectedServer: IPlexServerResponse) { + const server = { name: "New" + this.settings.servers.length + "*", id: Math.floor(Math.random() * (99999 - 0 + 1) + 1) }; + var splitServers = selectedServer.localAddresses.split(","); if (splitServers.length > 1) { server.ip = splitServers[splitServers.length - 1]; @@ -68,6 +76,7 @@ export class PlexComponent implements OnInit, OnDestroy { server.serverHostname = ""; this.notificationService.success(`Selected ${server.name}!`); + this.newServer(server); } public testPlex(server: IPlexServer) { @@ -167,6 +176,34 @@ export class PlexComponent implements OnInit, OnDestroy { } } + public edit(server: IPlexServer) { + const data: PlexServerDialogData = { + server: server, + }; + const dialog = this.dialog.open(PlexServerDialogComponent, { + width: "700px", + data: data, + panelClass: "modal-panel", + }); + dialog.afterClosed().subscribe((x) => { + console.log(x); + }); + } + + public newServer(server: IPlexServer) { + if(!server) { + server = { name: "New" + this.settings.servers.length + "*", id: Math.floor(Math.random() * (99999 - 0 + 1) + 1) }; + } + const dialog = this.dialog.open(PlexServerDialogComponent, { + width: "700px", + data: {server: server}, + panelClass: "modal-panel", + }); + dialog.afterClosed().subscribe((x) => { + console.log(x); + }); + } + private runCacher(): void { this.jobService.runPlexCacher().subscribe(x => { if (x) { diff --git a/src/Ombi/ClientApp/src/app/settings/settings.module.ts b/src/Ombi/ClientApp/src/app/settings/settings.module.ts index a1b530f11..990e89837 100644 --- a/src/Ombi/ClientApp/src/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/src/app/settings/settings.module.ts @@ -50,7 +50,7 @@ import { LandingPageComponent } from "./landingpage/landingpage.component"; import { LidarrComponent } from "./lidarr/lidarr.component"; import { LogsComponent } from "./logs/logs.component"; import { MassEmailComponent } from "./massemail/massemail.component"; -import { MatDialogModule } from "@angular/material/dialog"; +import { MatDialogActions, MatDialogModule } from "@angular/material/dialog"; import { MatMenuModule } from "@angular/material/menu"; import { MattermostComponent } from "./notifications/mattermost.component"; import {MenuModule} from "primeng/menu"; @@ -86,6 +86,7 @@ import { WikiComponent } from "./wiki.component"; import { PlexWatchlistComponent } from "./plex/components/watchlist/plex-watchlist.component"; import { PlexFormComponent } from "./plex/components/plex-form/plex-form.component"; import { PlexFormFieldComponent } from "./plex/components/form-field/plex-form-field.component"; +import { PlexServerDialogComponent } from "./plex/components/plex-server-dialog/plex-server-dialog.component"; const routes: Routes = [ { path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] }, @@ -146,7 +147,7 @@ const routes: Routes = [ DialogModule, SharedModule, MatMenuModule, - MatDialogModule + MatDialogModule, ], declarations: [ SettingsMenuComponent, @@ -195,6 +196,7 @@ const routes: Routes = [ PlexWatchlistComponent, PlexFormComponent, PlexFormFieldComponent, + PlexServerDialogComponent, ], exports: [ RouterModule,