mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 16:22:55 -07:00
Made a start on the Issues page
This commit is contained in:
parent
03fc7d4c19
commit
c787e58f3b
26 changed files with 244 additions and 86 deletions
|
@ -9,6 +9,7 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
{
|
||||
public interface IMovieEngineV2
|
||||
{
|
||||
Task<MovieFullInfoViewModel> GetMovieInfoByRequestId(int requestId, CancellationToken cancellationToken, string langCode = null);
|
||||
Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, CancellationToken cancellationToken, string langCode = null);
|
||||
Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId, string langCode);
|
||||
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
public interface IMusicSearchEngineV2
|
||||
{
|
||||
Task<ArtistInformation> GetArtistInformation(string artistId);
|
||||
Task<ArtistInformation> GetArtistInformationByRequestId(int requestId);
|
||||
Task<AlbumArt> GetReleaseGroupArt(string musicBrainzId, CancellationToken token);
|
||||
}
|
||||
}
|
|
@ -6,5 +6,6 @@ namespace Ombi.Core
|
|||
public interface ITVSearchEngineV2
|
||||
{
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowInformation(int tvdbid);
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId);
|
||||
}
|
||||
}
|
|
@ -48,6 +48,16 @@ namespace Ombi.Core.Engine.V2
|
|||
return await ProcessSingleMovie(movieInfo);
|
||||
}
|
||||
|
||||
public async Task<MovieFullInfoViewModel> GetMovieInfoByRequestId(int requestId, CancellationToken cancellationToken, string langCode = null)
|
||||
{
|
||||
langCode = await DefaultLanguageCode(langCode);
|
||||
var request = await RequestService.MovieRequestService.Find(requestId);
|
||||
var movieInfo = await Cache.GetOrAdd(nameof(GetFullMovieInformation) + request.TheMovieDbId + langCode,
|
||||
async () => await MovieApi.GetFullMovieInfo(request.TheMovieDbId, cancellationToken, langCode), DateTime.Now.AddHours(12), cancellationToken);
|
||||
|
||||
return await ProcessSingleMovie(movieInfo);
|
||||
}
|
||||
|
||||
public async Task<MovieCollectionsViewModel> GetCollection(int collectionId, CancellationToken cancellationToken, string langCode = null)
|
||||
{
|
||||
langCode = await DefaultLanguageCode(langCode);
|
||||
|
|
|
@ -119,6 +119,12 @@ namespace Ombi.Core.Engine.V2
|
|||
return new AlbumArt();
|
||||
}
|
||||
|
||||
public async Task<ArtistInformation> GetArtistInformationByRequestId(int requestId)
|
||||
{
|
||||
var request = await RequestService.MusicRequestRepository.Find(requestId);
|
||||
return await GetArtistInformation(request.ForeignArtistId);
|
||||
}
|
||||
|
||||
private List<BandMember> GetBandMembers(Artist artist)
|
||||
{
|
||||
var members = new List<BandMember>();
|
||||
|
|
|
@ -21,6 +21,7 @@ using Ombi.Core.Settings;
|
|||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Store.Repository;
|
||||
using TraktSharp.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Ombi.Core.Engine.V2
|
||||
{
|
||||
|
@ -48,6 +49,11 @@ namespace Ombi.Core.Engine.V2
|
|||
private IEmbyContentRepository EmbyContentRepo { get; }
|
||||
private ITraktApi TraktApi { get; }
|
||||
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId)
|
||||
{
|
||||
var request = await RequestService.TvRequestService.GetChild().Include(x => x.ParentRequest).FirstOrDefaultAsync(x => x.Id == requestId);
|
||||
return await GetShowInformation(request.ParentRequest.TvDbId);
|
||||
}
|
||||
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetShowInformation(int tvdbid)
|
||||
{
|
||||
|
@ -147,7 +153,7 @@ namespace Ombi.Core.Engine.V2
|
|||
private async Task<SearchFullInfoTvShowViewModel> GetExtraInfo(Task<TraktShow> showInfoTask, SearchFullInfoTvShowViewModel model)
|
||||
{
|
||||
var result = await showInfoTask;
|
||||
if(result == null)
|
||||
if (result == null)
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
<!-- <p-growl [value]="notificationService.messages" [life]="3000"></p-growl>
|
||||
<!-- <p-growl [value]="notificationService.messages" [life]="3000"></p-growl>
|
||||
<nav *ngIf="showNav" class="navbar navbar-default navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
|
@ -171,8 +170,8 @@
|
|||
|
||||
|
||||
<div>
|
||||
<app-my-nav [showNav]="showNav" [isAdmin]="isAdmin" [applicationName]="applicationName" [username]="username" (logoutClick)="logOut();"
|
||||
(themeChange)="onSetTheme($event)"></app-my-nav>
|
||||
<app-my-nav [showNav]="showNav" [isAdmin]="isAdmin" [applicationName]="applicationName" [username]="username" (logoutClick)="logOut();" (themeChange)="onSetTheme($event)">
|
||||
</app-my-nav>
|
||||
|
||||
|
||||
</div>
|
|
@ -25,7 +25,6 @@ export class AppComponent implements OnInit {
|
|||
|
||||
public customizationSettings: ICustomizationSettings;
|
||||
public customPageSettings: ICustomPage;
|
||||
public issuesEnabled = false;
|
||||
public user: ILocalUser;
|
||||
public showNav: boolean;
|
||||
public updateAvailable: boolean;
|
||||
|
@ -90,7 +89,6 @@ export class AppComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
});
|
||||
this.settingsService.issueEnabled().subscribe(x => this.issuesEnabled = x);
|
||||
this.settingsService.voteEnabled().subscribe(x => this.voteEnabled = x);
|
||||
|
||||
this.router.events.subscribe((event: NavigationStart) => {
|
||||
|
|
|
@ -32,4 +32,5 @@ export interface INavBar {
|
|||
name: string;
|
||||
link: string;
|
||||
requiresAdmin: boolean;
|
||||
enabled: boolean;
|
||||
}
|
|
@ -1,28 +1,21 @@
|
|||
<table mat-table
|
||||
[dataSource]="pendingIssues" multiTemplateDataRows
|
||||
class="mat-elevation-z8">
|
||||
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
|
||||
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
|
||||
</ng-container>
|
||||
<!-- <table mat-table [dataSource]="pendingIssues" multiTemplateDataRows class="mat-elevation-z8">
|
||||
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
|
||||
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
|
||||
<ng-container matColumnDef="expandedDetail">
|
||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplay.length">
|
||||
<div class="example-element-detail"
|
||||
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||
<div class="example-element-diagram">
|
||||
<div class="example-element-position"> {{element.requestId}} </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="expandedDetail">
|
||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplay.length">
|
||||
<div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||
<div class="example-element-diagram">
|
||||
<div class="example-element-position"> {{element.requestId}} </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
|
||||
<tr mat-row *matRowDef="let element; columns: columnsToDisplay;"
|
||||
class="example-element-row"
|
||||
[class.example-expanded-row]="expandedElement === element"
|
||||
(click)="expandedElement = expandedElement === element ? null : element">
|
||||
</tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||
</table>
|
||||
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
|
||||
<tr mat-row *matRowDef="let element; columns: columnsToDisplay;" class="example-element-row" [class.example-expanded-row]="expandedElement === element" (click)="expandedElement = expandedElement === element ? null : element">
|
||||
</tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||
</table> -->
|
|
@ -6,6 +6,7 @@ import { IIssueCount, IIssues, IPagenator, IssueStatus } from "../../../interfac
|
|||
import { COLUMNS } from "./issues-list.constants";
|
||||
|
||||
@Component({
|
||||
selector: "issues-list",
|
||||
templateUrl: "issues-list.component.html",
|
||||
})
|
||||
export class IssuesListComponent implements OnInit {
|
||||
|
|
|
@ -1,28 +1,25 @@
|
|||
<h1 id="issuesTitle" [translate]="'Issues.Title'"></h1>
|
||||
|
||||
<ngb-tabset *ngIf="count">
|
||||
<ngb-tab *ngIf="count.pending > 0">
|
||||
<ng-template ngbTabTitle>{{'Issues.PendingTitle' | translate}} <span class="badge">{{count.pending}}</span></ng-template>
|
||||
<ng-template ngbTabContent>
|
||||
<div *ngIf="pendingIssues">
|
||||
<issues-table [issues]="pendingIssues" (changePage)="changePagePending($event)" [totalRecords]="count.pending"></issues-table>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ngb-tab>
|
||||
<ngb-tab *ngIf="count.inProgress > 0">
|
||||
<ng-template ngbTabTitle>{{'Issues.InProgressTitle' | translate}} <span class="badge">{{count.inProgress}}</span></ng-template>
|
||||
<ng-template ngbTabContent>
|
||||
<div *ngIf="inProgressIssues">
|
||||
<issues-table [issues]="inProgressIssues" (changePage)="changePageInProg($event)" [totalRecords]="count.inProgress"></issues-table>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ngb-tab>
|
||||
<ngb-tab *ngIf="count.resolved > 0">
|
||||
<ng-template ngbTabTitle>{{'Issues.ResolvedTitle' | translate}} <span class="badge">{{count.resolved}}</span></ng-template>
|
||||
<ng-template ngbTabContent>
|
||||
<div *ngIf="resolvedIssues">
|
||||
<issues-table [issues]="resolvedIssues" (changePage)="changePageResolved($event)" [totalRecords]="count.resolved"></issues-table>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ngb-tab>
|
||||
</ngb-tabset>
|
||||
<div class="small-middle-container">
|
||||
<mat-tab-group>
|
||||
<mat-tab label="{{'Issues.PendingTitle' | translate}}">
|
||||
<ng-template matTabContent>
|
||||
<div *ngIf="pendingIssues">
|
||||
<issues-table [issues]="pendingIssues" (changePage)="changePagePending($event)" [totalRecords]="count.pending"></issues-table>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="inProgressIssues.length > 0" label="{{'Issues.InProgressTitle' | translate}}">
|
||||
<ng-template matTabContent>
|
||||
<div *ngIf="inProgressIssues">
|
||||
<issues-table [issues]="inProgressIssues" (changePage)="changePageInProg($event)" [totalRecords]="count.inProgress"></issues-table>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-tab>
|
||||
<mat-tab label="{{'Issues.ResolvedTitle' | translate}}">
|
||||
<ng-template matTabContent>
|
||||
<div *ngIf="resolvedIssues">
|
||||
<issues-table [issues]="resolvedIssues" (changePage)="changePageResolved($event)" [totalRecords]="count.resolved"></issues-table>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
4
src/Ombi/ClientApp/src/app/issues/issues.component.scss
Normal file
4
src/Ombi/ClientApp/src/app/issues/issues.component.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
.small-middle-container {
|
||||
margin: auto;
|
||||
width: 95%;
|
||||
}
|
|
@ -6,6 +6,7 @@ import { IIssueCount, IIssues, IPagenator, IssueStatus } from "../interfaces";
|
|||
|
||||
@Component({
|
||||
templateUrl: "issues.component.html",
|
||||
styleUrls: ['issues.component.scss']
|
||||
})
|
||||
export class IssuesComponent implements OnInit {
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import { IssuesListComponent } from "./components/issues-list/issues-list.compon
|
|||
import * as fromComponents from "./components";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", component: IssuesListComponent, canActivate: [AuthGuard] },
|
||||
{ path: "", component: IssuesComponent, canActivate: [AuthGuard] },
|
||||
{ path: ":id", component: IssueDetailsComponent, canActivate: [AuthGuard] },
|
||||
];
|
||||
|
||||
|
|
|
@ -1,4 +1,68 @@
|
|||
<table class="table table-striped table-hover table-responsive table-condensed">
|
||||
<table mat-table [dataSource]="issues" class="table" matSort matSortDisableClear>
|
||||
|
||||
|
||||
<ng-container matColumnDef="title">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Issues.ColumnTitle' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="category">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Issues.Category' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.issueCategory.value}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="subject">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Issues.Subject' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.subject}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Issues.Status' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{IssueStatus[element.status] | humanize}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="reportedBy">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Issues.ReportedBy' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.userReported.userAlias}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- <ng-container matColumnDef="requestedUser.requestedBy">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'Requests.RequestedBy' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.requestedUser?.userAlias}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="requestedDate">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.RequestDate' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.requestedDate | amLocal | amDateFormat: 'LL'}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.Status' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.status}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="requestStatus">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.RequestStatus' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.requestStatus | translate}} </td>
|
||||
</ng-container>-->
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button *ngIf="element.requestType === 1" mat-raised-button color="accent" [routerLink]="'/details/movie/request/' + element.requestId">{{ 'Issues.Details' | translate}}</button>
|
||||
<button *ngIf="element.requestType === 0" mat-raised-button color="accent" [routerLink]="'/details/tv/' + element.requestId">{{ 'Issues.Details' | translate}}</button>
|
||||
<button *ngIf="element.requestType === 2" mat-raised-button color="accent" [routerLink]="'/details/artist/' + element.requestId">{{ 'Issues.Details' | translate}}</button>
|
||||
<!-- <button mat-raised-button color="warn" (click)="openOptions(element)" *ngIf="isAdmin"> {{ 'Requests.Options' | translate}}</button> -->
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
||||
<!-- <table class="table table-striped table-hover table-responsive table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th (click)="setOrder('title', $event)">
|
||||
|
@ -52,4 +116,4 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p-paginator [rows]="rowCount" [totalRecords]="totalRecords" (onPageChange)="paginate($event)"></p-paginator>
|
||||
<p-paginator [rows]="rowCount" [totalRecords]="totalRecords" (onPageChange)="paginate($event)"></p-paginator> -->
|
|
@ -13,6 +13,7 @@ export class IssuesTableComponent {
|
|||
|
||||
@Output() public changePage = new EventEmitter<IPagenator>();
|
||||
|
||||
public displayedColumns = ["title", "category", "subject", "status", "reportedBy", "actions"]
|
||||
public IssueStatus = IssueStatus;
|
||||
|
||||
public order: string = "id";
|
||||
|
|
|
@ -30,14 +30,36 @@ export class MovieDetailsComponent {
|
|||
public dialog: MatDialog, private requestService: RequestService,
|
||||
public messageService: MessageService, private auth: AuthService) {
|
||||
this.route.params.subscribe((params: any) => {
|
||||
this.theMovidDbId = params.movieDbId;
|
||||
this.load();
|
||||
|
||||
this.theMovidDbId = params.movieDbId;
|
||||
if (params.requestId) {
|
||||
this.load(+params.requestId);
|
||||
} else {
|
||||
this.load(undefined);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public load() {
|
||||
public async load(requestId: number|undefined) {
|
||||
|
||||
this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser");
|
||||
|
||||
if (requestId) {
|
||||
var result = await this.searchService.getFullMovieDetailsByRequestId(requestId);
|
||||
this.theMovidDbId = result.id
|
||||
|
||||
this.movie = result;
|
||||
if (this.movie.requestId > 0) {
|
||||
// Load up this request
|
||||
this.hasRequest = true;
|
||||
this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId);
|
||||
}
|
||||
this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => {
|
||||
this.movie.background = this.sanitizer.bypassSecurityTrustStyle
|
||||
("url(" + x + ")");
|
||||
});
|
||||
} else {
|
||||
this.searchService.getFullMovieDetails(this.theMovidDbId).subscribe(async x => {
|
||||
this.movie = x;
|
||||
if (this.movie.requestId > 0) {
|
||||
|
@ -50,7 +72,7 @@ export class MovieDetailsComponent {
|
|||
("url(" + x + ")");
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public async request() {
|
||||
|
@ -87,7 +109,7 @@ export class MovieDetailsComponent {
|
|||
public async issue() {
|
||||
const dialogRef = this.dialog.open(NewIssueComponent, {
|
||||
width: '500px',
|
||||
data: {requestId: this.movieRequest ? this.movieRequest.id : null, requestType: RequestType.movie, imdbid: this.movie.imdbId}
|
||||
data: {requestId: this.movieRequest ? this.movieRequest.id : null, requestType: RequestType.movie, imdbid: this.movie.imdbId, title: this.movie.title}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,4 +10,5 @@ export interface IIssueDialogData {
|
|||
requestType: RequestType;
|
||||
requestId: number;
|
||||
imdbId: string;
|
||||
title: string;
|
||||
}
|
|
@ -31,7 +31,7 @@ export class NewIssueComponent implements OnInit {
|
|||
comments: [],
|
||||
requestId: data.requestId,
|
||||
requestType: data.requestType,
|
||||
title: "",
|
||||
title: data.title,
|
||||
providerId: data.imdbId,
|
||||
userReported: undefined,
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@ import { ArtistDetailsComponent } from "./components/artist/artist-details.compo
|
|||
|
||||
const routes: Routes = [
|
||||
{ path: "movie/:movieDbId", component: MovieDetailsComponent, canActivate: [AuthGuard] },
|
||||
{ path: "movie/request/:requestId", component: MovieDetailsComponent, canActivate: [AuthGuard] },
|
||||
{ path: "tv/:tvdbId/:search", component: TvDetailsComponent, canActivate: [AuthGuard] },
|
||||
{ path: "tv/:tvdbId", component: TvDetailsComponent, canActivate: [AuthGuard] },
|
||||
{ path: "artist/:artistId", component: ArtistDetailsComponent, canActivate: [AuthGuard] },
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<mat-toolbar>{{applicationName}}</mat-toolbar>
|
||||
<mat-nav-list>
|
||||
<span *ngFor="let nav of navItems">
|
||||
<a *ngIf="nav.requiresAdmin && isAdmin || !nav.requiresAdmin" mat-list-item [routerLink]="nav.link"
|
||||
<a *ngIf="(nav.requiresAdmin && isAdmin || !nav.requiresAdmin) && nav.enabled" mat-list-item [routerLink]="nav.link"
|
||||
[routerLinkActive]="getTheme()">
|
||||
<mat-icon aria-label="Side nav toggle icon">{{nav.icon}}</mat-icon>
|
||||
{{nav.name | translate}}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Observable } from 'rxjs';
|
|||
import { map } from 'rxjs/operators';
|
||||
import { INavBar } from '../interfaces/ICommon';
|
||||
import { StorageService } from '../shared/storage/storage-service';
|
||||
import { SettingsService } from '../services';
|
||||
|
||||
@Component({
|
||||
selector: 'app-my-nav',
|
||||
|
@ -24,27 +25,33 @@ export class MyNavComponent implements OnInit {
|
|||
@Output() public logoutClick = new EventEmitter();
|
||||
@Output() public themeChange = new EventEmitter<string>();
|
||||
public theme: string;
|
||||
public issuesEnabled: boolean = false;
|
||||
public navItems: INavBar[];
|
||||
|
||||
constructor(private breakpointObserver: BreakpointObserver,
|
||||
private settingsService: SettingsService,
|
||||
private store: StorageService) {
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
public async ngOnInit() {
|
||||
|
||||
this.issuesEnabled = await this.settingsService.issueEnabled().toPromise();
|
||||
console.log("issues enabled: " + this.issuesEnabled);
|
||||
this.theme = this.store.get("theme");
|
||||
if(!this.theme) {
|
||||
this.store.save("theme","dark");
|
||||
}
|
||||
this.navItems = [
|
||||
{ name: "NavigationBar.Discover", icon: "find_replace", link: "/discover", requiresAdmin: false, enabled: true },
|
||||
{ name: "NavigationBar.Requests", icon: "list", link: "/requests-list", requiresAdmin: false, enabled: true },
|
||||
{ name: "NavigationBar.Issues", icon: "notification_important", link: "/issues", requiresAdmin: false, enabled: this.issuesEnabled },
|
||||
{ name: "NavigationBar.UserManagement", icon: "account_circle", link: "/usermanagement", requiresAdmin: true, enabled: true },
|
||||
{ name: "NavigationBar.Calendar", icon: "calendar_today", link: "/calendar", requiresAdmin: false, enabled: true },
|
||||
{ name: "NavigationBar.Settings", icon: "settings", link: "/Settings/About", requiresAdmin: true, enabled: true },
|
||||
{ name: "NavigationBar.UserPreferences", icon: "person", link: "/user-preferences", requiresAdmin: false, enabled: true },
|
||||
];
|
||||
}
|
||||
|
||||
public navItems: INavBar[] = [
|
||||
{ name: "NavigationBar.Discover", icon: "find_replace", link: "/discover", requiresAdmin: false },
|
||||
{ name: "NavigationBar.Requests", icon: "list", link: "/requests-list", requiresAdmin: false },
|
||||
{ name: "NavigationBar.UserManagement", icon: "account_circle", link: "/usermanagement", requiresAdmin: true },
|
||||
{ name: "NavigationBar.Calendar", icon: "calendar_today", link: "/calendar", requiresAdmin: false },
|
||||
{ name: "NavigationBar.Settings", icon: "settings", link: "/Settings/About", requiresAdmin: true },
|
||||
{ name: "NavigationBar.UserPreferences", icon: "person", link: "/user-preferences", requiresAdmin: false },
|
||||
]
|
||||
|
||||
public logOut() {
|
||||
this.logoutClick.emit();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ export class SearchV2Service extends ServiceHelpers {
|
|||
public getFullMovieDetails(theMovieDbId: number): Observable<ISearchMovieResultV2> {
|
||||
return this.http.get<ISearchMovieResultV2>(`${this.url}/Movie/${theMovieDbId}`);
|
||||
}
|
||||
|
||||
public getFullMovieDetailsByRequestId(requestId: number): Promise<ISearchMovieResultV2> {
|
||||
return this.http.get<ISearchMovieResultV2>(`${this.url}/Movie/request/${requestId}`).toPromise();
|
||||
}
|
||||
|
||||
public getFullMovieDetailsPromise(theMovieDbId: number): Promise<ISearchMovieResultV2> {
|
||||
return this.http.get<ISearchMovieResultV2>(`${this.url}/Movie/${theMovieDbId}`).toPromise();
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ namespace Ombi.Controllers.V1
|
|||
/// <summary>
|
||||
/// Deletes a comment on a issue
|
||||
/// </summary>
|
||||
[HttpDelete("comments/{id:int}")]
|
||||
[HttpDelete("comments/{id}")]
|
||||
[PowerUser]
|
||||
public async Task<bool> DeleteComment(int id)
|
||||
{
|
||||
|
@ -256,6 +256,16 @@ namespace Ombi.Controllers.V1
|
|||
return true;
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[PowerUser]
|
||||
public async Task<bool> DeleteIssue(int id)
|
||||
{
|
||||
var issue = await _issues.GetAll().FirstOrDefaultAsync(x => x.Id == id);
|
||||
|
||||
await _issues.Delete(issue);
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpPost("status")]
|
||||
public async Task<bool> UpdateStatus([FromBody] IssueStateViewModel model)
|
||||
{
|
||||
|
|
|
@ -61,6 +61,15 @@ namespace Ombi.Controllers.V2
|
|||
return await _movieEngineV2.GetFullMovieInformation(movieDbId, Request.HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns details for a single movie
|
||||
/// </summary>
|
||||
[HttpGet("movie/request/{requestId}")]
|
||||
public async Task<MovieFullInfoViewModel> GetMovieByRequest(int requestId)
|
||||
{
|
||||
return await _movieEngineV2.GetMovieInfoByRequestId(requestId, Request.HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns basic information about the provided collection
|
||||
/// </summary>
|
||||
|
@ -83,6 +92,17 @@ namespace Ombi.Controllers.V2
|
|||
return await _tvEngineV2.GetShowInformation(tvdbid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns details for a single show
|
||||
/// </summary>
|
||||
/// <remarks>TVMaze is the TV Show Provider</remarks>
|
||||
///
|
||||
[HttpGet("tv/request/{requestId}")]
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetTvInfoByRequest(int requestId)
|
||||
{
|
||||
return await _tvEngineV2.GetShowByRequest(requestId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns details for a single show
|
||||
/// </summary>
|
||||
|
@ -357,6 +377,14 @@ namespace Ombi.Controllers.V2
|
|||
return await _musicEngine.GetArtistInformation(artistId);
|
||||
}
|
||||
|
||||
[HttpGet("artist/request/{requestId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
public async Task<ArtistInformation> GetArtistInformationByRequestId(int requestId)
|
||||
{
|
||||
return await _musicEngine.GetArtistInformationByRequestId(requestId);
|
||||
}
|
||||
|
||||
[HttpGet("releasegroupart/{musicBrainzId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesDefaultResponseType]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue