diff --git a/src/Ombi/ClientApp/src/app/components/button/button.component.scss b/src/Ombi/ClientApp/src/app/components/button/button.component.scss index bb360e287..e69de29bb 100644 --- a/src/Ombi/ClientApp/src/app/components/button/button.component.scss +++ b/src/Ombi/ClientApp/src/app/components/button/button.component.scss @@ -1,18 +0,0 @@ -.detailed-container { - width: 400px; - - - - - ::ng-deep .poster { - border-radius: 10px; - opacity: 1; - display: block; - width: 100%; - height: auto; - transition: .5s ease; - backface-visibility: hidden; - } - -} - diff --git a/src/Ombi/ClientApp/src/app/components/button/button.component.ts b/src/Ombi/ClientApp/src/app/components/button/button.component.ts index 3e14f6aa6..3909c44ce 100644 --- a/src/Ombi/ClientApp/src/app/components/button/button.component.ts +++ b/src/Ombi/ClientApp/src/app/components/button/button.component.ts @@ -17,7 +17,7 @@ import { MatButtonModule } from "@angular/material/button"; @Input() public text: string; @Input() public id: string; - @Input() public type: string; + @Input() public type: string = "primary"; @Input() public class: string; @Input('data-toggle') public dataToggle: string; @Input('data-target') public dataTarget: string; diff --git a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.html b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.html index 9cbfb09a8..bba8c37ff 100644 --- a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.html +++ b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.html @@ -1,7 +1,7 @@ -
+
- +
@@ -20,6 +20,11 @@

{{'MediaDetails.Status' | translate}} {{getStatus(request) | translate}}

+
+
+ +
+
diff --git a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.scss b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.scss index 3dd9685e8..ac5b3b2d1 100644 --- a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.scss +++ b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.scss @@ -2,7 +2,7 @@ .detailed-container { width: 400px; - height: auto; + height: 250px; margin: 10px; padding: 10px; border-radius: 10px; @@ -10,6 +10,7 @@ @media (max-width:768px) { width: 200px; + height: auto; } background-color: $ombi-background-accent; @@ -36,12 +37,19 @@ border-radius: 10px; opacity: 1; display: block; + height: 225px; width: 100%; - height: 200px; transition: .5s ease; backface-visibility: hidden; border: 1px solid #35465c; } + .action-items { + @media (min-width:768px) { + bottom: 0; + position: absolute; + z-index: 0i; + } + } } diff --git a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.stories.ts b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.stories.ts index 239c5ab33..cf1d1db5a 100644 --- a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.stories.ts +++ b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.stories.ts @@ -67,6 +67,7 @@ NewMovieRequest.args = { overview: 'The Matrix is a movie about a group of people who are forced to fight against a powerful computer system that controls them.', releaseDate: new Date(2020, 1, 1), } as IRecentlyRequested, + isAdmin: false, }; export const MovieNoUsername = Template.bind({}); @@ -206,4 +207,60 @@ TvNoUsername.args = { mediaId: '603', releaseDate: new Date(2020, 1, 1), } as IRecentlyRequested, +}; + +export const AdminNewMovie = Template.bind({}); +// More on args: https://storybook.js.org/docs/angular/writing-stories/args +AdminNewMovie.args = { + request: { + title: 'The Matrix', + approved: false, + available: false, + tvPartiallyAvailable: false, + requestDate: new Date(2022, 1, 1), + username: 'John Doe', + userId: '12345', + type: RequestType.movie, + mediaId: '603', + overview: 'The Matrix is a movie about a group of people who are forced to fight against a powerful computer system that controls them.', + releaseDate: new Date(2020, 1, 1), + } as IRecentlyRequested, + isAdmin: true, +}; + +export const AdminTvShow = Template.bind({}); +// More on args: https://storybook.js.org/docs/angular/writing-stories/args +AdminTvShow.args = { + request: { + title: 'For All Mankind', + approved: false, + available: false, + tvPartiallyAvailable: true, + requestDate: new Date(2022, 1, 1), + userId: '12345', + type: RequestType.tvShow, + mediaId: '603', + username: 'John Doe', + releaseDate: new Date(2020, 1, 1), + } as IRecentlyRequested, + isAdmin: true, +}; + +export const AdminApprovedMovie = Template.bind({}); +// More on args: https://storybook.js.org/docs/angular/writing-stories/args +AdminApprovedMovie.args = { + request: { + title: 'The Matrix', + approved: true, + available: false, + tvPartiallyAvailable: false, + requestDate: new Date(2022, 1, 1), + username: 'John Doe', + userId: '12345', + type: RequestType.movie, + mediaId: '603', + overview: 'The Matrix is a movie about a group of people who are forced to fight against a powerful computer system that controls them.', + releaseDate: new Date(2020, 1, 1), + } as IRecentlyRequested, + isAdmin: true, }; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.ts b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.ts index e4f1a092d..3b3794190 100644 --- a/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.ts +++ b/src/Ombi/ClientApp/src/app/components/detailed-card/detailed-card.component.ts @@ -7,14 +7,14 @@ import { DomSanitizer, SafeStyle } from "@angular/platform-browser"; @Component({ standalone: false, selector: 'ombi-detailed-card', - changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: './detailed-card.component.html', styleUrls: ['./detailed-card.component.scss'] }) export class DetailedCardComponent implements OnInit, OnDestroy { @Input() public request: IRecentlyRequested; - + @Input() public isAdmin: boolean = false; @Output() public onClick: EventEmitter = new EventEmitter(); + @Output() public onApprove: EventEmitter = new EventEmitter(); public RequestType = RequestType; public loading: false; @@ -62,6 +62,10 @@ import { DomSanitizer, SafeStyle } from "@angular/platform-browser"; this.onClick.emit(); } + public approve() { + this.onApprove.emit(); + } + public getClass(request: IRecentlyRequested) { if (request.available || request.tvPartiallyAvailable) { return "success"; diff --git a/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.html b/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.html index 561eec552..f1b2a8057 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.html @@ -1,5 +1,5 @@ - + - + \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.ts b/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.ts index 866284cb2..e869abc13 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/recently-requested-list/recently-requested-list.component.ts @@ -1,15 +1,13 @@ -import { Component, OnInit, Input, ViewChild, Output, EventEmitter, OnDestroy } from "@angular/core"; -import { DiscoverOption, IDiscoverCardResult } from "../../interfaces"; -import { IRecentlyRequested, ISearchMovieResult, ISearchTvResult, RequestType } from "../../../interfaces"; -import { SearchV2Service } from "../../../services"; -import { StorageService } from "../../../shared/storage/storage-service"; -import { MatButtonToggleChange } from '@angular/material/button-toggle'; +import { Component, OnInit, Input, ViewChild, OnDestroy } from "@angular/core"; +import { IRecentlyRequested, IRequestEngineResult, RequestType } from "../../../interfaces"; import { Carousel } from 'primeng/carousel'; -import { FeaturesFacade } from "../../../state/features/features.facade"; import { ResponsiveOptions } from "../carousel.options"; import { RequestServiceV2 } from "app/services/requestV2.service"; -import { Subject, takeUntil } from "rxjs"; +import { finalize, map, Observable, Subject, takeUntil, tap } from "rxjs"; import { Router } from "@angular/router"; +import { AuthService } from "app/auth/auth.service"; +import { NotificationService, RequestService } from "app/services"; +import { TranslateService } from "@ngx-translate/core"; export enum DiscoverType { Upcoming, @@ -30,21 +28,22 @@ export class RecentlyRequestedListComponent implements OnInit, OnDestroy { @Input() public isAdmin: boolean; @ViewChild('carousel', {static: false}) carousel: Carousel; - - public requests: IRecentlyRequested[]; + public requests$: Observable; public responsiveOptions: any; public RequestType = RequestType; public loadingFlag: boolean; public DiscoverType = DiscoverType; - public is4kEnabled = false; private $loadSub = new Subject(); - constructor(private requestService: RequestServiceV2, - private featureFacade: FeaturesFacade, - private router: Router) { - Carousel.prototype.onTouchMove = () => {}, + constructor(private requestServiceV2: RequestServiceV2, + private requestService: RequestService, + private router: Router, + private authService: AuthService, + private notificationService: NotificationService, + private translateService: TranslateService) { + Carousel.prototype.onTouchMove = () => {}; this.responsiveOptions = ResponsiveOptions; } @@ -54,14 +53,43 @@ export class RecentlyRequestedListComponent implements OnInit, OnDestroy { } public ngOnInit() { - this.loading(); this.loadData(); + this.isAdmin = this.authService.isAdmin(); } public navigate(request: IRecentlyRequested) { this.router.navigate([this.generateDetailsLink(request), request.mediaId]); } + public approve(request: IRecentlyRequested) { + switch(request.type) { + case RequestType.movie: + this.requestService.approveMovie({id: request.requestId, is4K: false}).pipe( + map((res) => this.handleApproval(res, request)) + ).subscribe(); + break; + case RequestType.tvShow: + this.requestService.approveChild({id: request.requestId}).pipe( + tap((res) => this.handleApproval(res, request)) + ).subscribe(); + break; + case RequestType.album: + this.requestService.approveAlbum({id: request.requestId}).pipe( + tap((res) => this.handleApproval(res, request)) + ).subscribe(); + break; + } + } + + private handleApproval(result: IRequestEngineResult, request: IRecentlyRequested) { + if (result.result) { + this.notificationService.success(this.translateService.instant("Requests.SuccessfullyApproved")); + request.approved = true; + } else { + this.notificationService.error(result.errorMessage); + } + } + private generateDetailsLink(request: IRecentlyRequested): string { switch (request.type) { case RequestType.movie: @@ -74,13 +102,13 @@ export class RecentlyRequestedListComponent implements OnInit, OnDestroy { } private loadData() { - this.requestService.getRecentlyRequested().pipe(takeUntil(this.$loadSub)).subscribe(x => { - this.requests = x; - this.finishLoading(); - }); + this.requests$ = this.requestServiceV2.getRecentlyRequested().pipe( + tap(() => this.loading()), + takeUntil(this.$loadSub), + finalize(() => this.finishLoading()) + ); } - private loading() { this.loadingFlag = true; } diff --git a/src/Ombi/databasea.json b/src/Ombi/databasea.json deleted file mode 100644 index c849cd56a..000000000 --- a/src/Ombi/databasea.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "OmbiDatabase": { - "Type": "MySQL", - "ConnectionString": "Server=192.168.68.118;Port=3306;Database=Ombi;User=ombi;" - }, - "SettingsDatabase": { - "Type": "MySQL", - "ConnectionString": "Server=192.168.68.118;Port=3306;Database=Ombi;User=ombi;" - }, - "ExternalDatabase": { - "Type": "MySQL", - "ConnectionString": "Server=192.168.68.118;Port=3306;Database=Ombi;User=ombi;" - } -}