Adding a metadata editor for shows

This commit is contained in:
Zoe Roux 2020-04-19 04:27:02 +02:00
parent e0c9b1f4d8
commit 6801bb620c
8 changed files with 170 additions and 6 deletions

View File

@ -35,6 +35,9 @@ import {AuthModule} from "./auth/auth.module";
import {AuthRoutingModule} from "./auth/auth-routing.module";
import { TrailerDialogComponent } from './trailer-dialog/trailer-dialog.component';
import {CollectionsListComponent} from "./collection-list/collections-list.component";
import { MetadataEditComponent } from './metadata-edit/metadata-edit.component';
import {MatChipsModule} from "@angular/material/chips";
import {MatAutocompleteModule} from "@angular/material/autocomplete";
@NgModule({
@ -52,7 +55,8 @@ import {CollectionsListComponent} from "./collection-list/collections-list.compo
PasswordValidator,
FallbackDirective,
TrailerDialogComponent,
CollectionsListComponent
CollectionsListComponent,
MetadataEditComponent
],
imports: [
BrowserModule,
@ -77,7 +81,9 @@ import {CollectionsListComponent} from "./collection-list/collections-list.compo
FormsModule,
MatTabsModule,
MatCheckboxModule,
AuthModule
AuthModule,
MatChipsModule,
MatAutocompleteModule
],
bootstrap: [AppComponent]
})

View File

@ -0,0 +1,68 @@
<h2 mat-dialog-title>Editing metadata of {{this.show.title}}</h2>
<div matDialogContent>
<form #showForm="ngForm">
<mat-form-field class="w-100">
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="this.show.title" name="title">
</mat-form-field>
<mat-form-field class="w-100">
<mat-label>Overview</mat-label>
<textarea matInput [(ngModel)]="this.show.overview" name="overview"></textarea>
</mat-form-field>
<mat-form-field class="w-25 pr-3">
<mat-label>Start Year</mat-label>
<input matInput [(ngModel)]="this.show.startYear" name="startYear" type="number" [max]="this.show.endYear"/>
</mat-form-field>
<mat-form-field class="w-25 pr-3">
<mat-label>End Year</mat-label>
<input matInput [(ngModel)]="this.show.endYear" name="endYear" type="number" [min]="this.show.startYear"/>
</mat-form-field>
<mat-form-field class="w-50">
<mat-label>Status</mat-label>
<mat-select>
<mat-option value="Finished">Finished</mat-option>
<mat-option value="Airing">Airing</mat-option>
<mat-option value="Planned">Planned</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="w-100">
<mat-label>Genres</mat-label>
<mat-chip-list #genreList>
<mat-chip *ngFor="let genre of this.show.genres" (removed)="removeGenre(genre)" removable="true">
{{genre.name}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input #genreInput placeholder="New genre..." [matChipInputFor]="genreList" (matChipInputTokenEnd)="addGenre($event)"
[matAutocomplete]="genreAuto" />
<mat-autocomplete #genreAuto="matAutocomplete" (optionSelected)="autocompleteGenre($event)">
<mat-option *ngFor="let genre of this.allGenres" [value]="genre">
{{genre.name}}
</mat-option>
</mat-autocomplete>
</mat-chip-list>
</mat-form-field>
<mat-form-field class="w-100">
<mat-label>Trailer</mat-label>
<input matInput [(ngModel)]="this.show.trailerUrl" name="trailer">
</mat-form-field>
<mat-form-field class="w-100">
<mat-label>Studio</mat-label>
<input matInput [value]="this.show.studio?.name" (input)="this.show.studio = {slug: null, name: $event.target.value}"
[matAutocomplete]="studioAuto" name="studio">
<mat-autocomplete #studioAuto="matAutocomplete">
<mat-option *ngFor="let studio of this.allStudios" [value]="studio.name">
{{studio.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
</div>
<div mat-dialog-actions align="end">
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button (click)="apply()">Apply</button>
</div>

View File

@ -0,0 +1,71 @@
import {Component, ElementRef, Inject, OnInit, ViewChild} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {HttpClient} from "@angular/common/http";
import {Show} from "../../models/show";
import {Genre} from "../../models/genre";
import {MatChipInputEvent} from "@angular/material/chips";
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
import {FormControl} from "@angular/forms";
import {Studio} from "../../models/studio";
@Component({
selector: 'app-metadata-edit',
templateUrl: './metadata-edit.component.html',
styleUrls: ['./metadata-edit.component.scss']
})
export class MetadataEditComponent implements OnInit
{
@ViewChild("genreInput") genreInput: ElementRef<HTMLInputElement>;
private allGenres: Genre[];
private allStudios: Studio[];
constructor(public dialogRef: MatDialogRef<MetadataEditComponent>, @Inject(MAT_DIALOG_DATA) public show: Show, private http: HttpClient)
{
this.http.get<Genre[]>("/api/genres").subscribe(result =>
{
this.allGenres = result;
});
this.http.get<Studio[]>("/api/studios").subscribe(result =>
{
this.allStudios = result;
});
}
ngOnInit(): void
{
}
apply(): void
{
this.http.post("/api/show/edit/" + this.show.slug, this.show).subscribe(() =>
{
this.dialogRef.close(this.show);
});
}
addGenre(event: MatChipInputEvent)
{
const input = event.input;
const value = event.value;
let genre: Genre = {slug: null, name: value};
this.show.genres.push(genre);
if (input)
input.value = "";
}
removeGenre(genre: Genre): void
{
console.log("Removing a genre");
console.log(genre);
const i = this.show.genres.indexOf(genre);
this.show.genres.splice(i, 1);
}
autocompleteGenre(event: MatAutocompleteSelectedEvent): void
{
this.show.genres.push(event.option.value);
this.genreInput.nativeElement.value = '';
}
}

View File

@ -26,7 +26,7 @@
<button mat-icon-button matTooltipPosition="above" matTooltip="Watched">
<mat-icon>done</mat-icon>
</button>
<button mat-icon-button matTooltipPosition="above" matTooltip="More">
<button mat-icon-button matTooltipPosition="above" matTooltip="More" [matMenuTriggerFor]="showMenu">
<mat-icon>more_horiz</mat-icon>
</button>
</div>
@ -39,12 +39,16 @@
</div>
</div>
</div>
<mat-menu #showMenu="matMenu">
<button mat-menu-item (click)="editMetadata()">Edit metadata</button>
</mat-menu>
<div class="row pt-3 d-md-none">
<div class="col">
<p class="mr-1 d-inline-block">Studio: <b><a routerLink="/studio/{{this.show.studio?.slug}}">{{this.show.studio?.name}}</a></b></p>
<div class="d-sm-none">
<p>Genres: <span *ngFor="let genre of this.show.genres; let isLast = last"><b><a routerLink="/genre/{{genre.slug}}">{{genre.name}}</a></b>{{isLast ? "" : ", "}}</span></p>
<p>Genres: <span *ngFor="let genre of this.show.genres; let isLast = last"><b><a routerLink="/genre/{{genre.slug}}">{{genre.name}}</a></b>{{isLast ? "" : ", "}}</span></p>
</div>
</div>
</div>

View File

@ -7,6 +7,8 @@ import { Episode } from "../../models/episode";
import { Show } from "../../models/show";
import {MatDialog} from "@angular/material/dialog";
import {TrailerDialogComponent} from "../trailer-dialog/trailer-dialog.component";
import {MetadataEditComponent} from "../metadata-edit/metadata-edit.component";
import {Account} from "../../models/account";
@Component({
selector: 'app-show-details',
@ -92,6 +94,15 @@ export class ShowDetailsComponent implements OnInit
openTrailer()
{
this.dialog.open(TrailerDialogComponent, {width: "80%", height: "45vw", data: this.show.trailerUrl});
this.dialog.open(TrailerDialogComponent, {width: "80%", height: "45vw", data: this.show.trailerUrl, panelClass: "panel"});
}
editMetadata()
{
this.dialog.open(MetadataEditComponent, {width: "80%", data: this.show}).afterClosed().subscribe((result: Show) =>
{
if (result)
this.show = result;
});
}
}

View File

@ -0,0 +1,4 @@
.panel .mat-dialog-container
{
overflow-y: hidden;
}

View File

@ -7,7 +7,7 @@ export interface Show
{
slug: string;
title: string;
Aliases: string[];
aliases: string[];
overview: string;
genres: Genre[];
status: string;