edit song

This commit is contained in:
Benjamin Ifland
2019-03-25 12:19:33 +01:00
parent a46dae93db
commit 38268c3fc3
10 changed files with 107 additions and 58 deletions

View File

@@ -7,7 +7,7 @@
</button> </button>
</div> </div>
<mat-card-title>Titel bearbeiten</mat-card-title> <mat-card-title>Titel bearbeiten</mat-card-title>
<!-- <mat-card-subtitle>{{ song.Key }} - {{ song.Tempo }}</mat-card-subtitle> --> <mat-card-subtitle>Daten werden nach der Eingabe automatisch gespeichert</mat-card-subtitle>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<form> <form>
@@ -47,6 +47,14 @@
[matTextareaAutosize]="true" [matTextareaAutosize]="true"
></textarea> ></textarea>
</mat-form-field> </mat-form-field>
<mat-form-field>
<textarea
matInput
placeholder="Kommentare"
[formControl]="form.controls.Comments"
[matTextareaAutosize]="true"
></textarea>
</mat-form-field>
</form> </form>
</mat-card-content> </mat-card-content>
<!-- <mat-card-actions> <!-- <mat-card-actions>

View File

@@ -11,6 +11,8 @@
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<p *ngFor="let line of text">{{ line }}</p> <p *ngFor="let line of text">{{ line }}</p>
<br />
<p *ngFor="let line of comments">{{ line }}</p>
</mat-card-content> </mat-card-content>
<mat-card-actions> <mat-card-actions>
<button mat-button (click)="onClickDownload()">Herunterladen</button> <button mat-button (click)="onClickDownload()">Herunterladen</button>

View File

@@ -1,22 +1,4 @@
.mat-card { p {
width: 500px; margin: 0;
border-radius: 8px; min-height: 10px;
background: #fffe; }
margin: 20px;
box-sizing: border-box;
}
.mat-card-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 420px;
}
.mat-card-content {
white-space: pre-wrap;
}
.song-detail-container {
margin-left: 30vw;
}

View File

@@ -52,6 +52,10 @@ export class SongComponent {
} }
public get text(): string[] { public get text(): string[] {
return this.song.Text.split(/\r?\n/).filter(_ => _ !== ' '); return this.song.Text ? this.song.Text.split(/\r?\n/) : [];
}
public get comments(): string[] {
return this.song.Comments ? this.song.Comments.split(/\r?\n/) : [];
} }
} }

View File

@@ -1,27 +1,40 @@
import { Song } from 'src/app/models/song.model';
import { SongsService } from 'src/app/data/songs.service'; import { SongsService } from 'src/app/data/songs.service';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms'; import { FormGroup, FormControl, Validators } from '@angular/forms';
import { switchMap, tap } from 'rxjs/operators';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class EditSongService { export class EditSongService {
constructor(private songsService: SongsService) {}
constructor(private songsService: SongsService) { } public initEditForm(): FormGroup {
const song = this.songsService.selectedSong.value;
const form = new FormGroup({
ID: new FormControl(song.ID, { updateOn: 'blur' }),
Number: new FormControl(song.Number, { updateOn: 'blur' }),
Name: new FormControl(song.Name, {
updateOn: 'blur',
validators: Validators.required
}),
Text: new FormControl(song.Text, { updateOn: 'blur' }),
SongType: new FormControl(song.SongType, {
updateOn: 'blur',
validators: Validators.required
}),
Key: new FormControl(song.Key, { updateOn: 'blur' }),
Tempo: new FormControl(song.Tempo, { updateOn: 'blur' }),
Comments: new FormControl(song.Comments, { updateOn: 'blur' }),
});
public initEditForm(): FormGroup { const controls = Object.keys(form.controls);
const song = this.songsService.selectedSong.value; controls.forEach(control => {
const form = new FormGroup({ form.controls[control].valueChanges.pipe(
ID: new FormControl(song.ID), switchMap(value => this.songsService.patch(song.ID, control, value))
Number: new FormControl(song.Number), ).subscribe();
Name: new FormControl(song.Name, Validators.required), });
Text: new FormControl(song.Text),
SongType: new FormControl(song.SongType, Validators.required),
Key: new FormControl(song.Key),
Tempo: new FormControl(song.Tempo)
});
return form; return form;
} }
} }

View File

@@ -1,29 +1,45 @@
import { ODataService, ODataQuery } from 'odata-v4-ng'; import { ODataService, ODataQuery } from "odata-v4-ng";
import { Observable } from 'rxjs'; import { Observable } from "rxjs";
import { map } from 'rxjs/operators'; import { map, tap } from "rxjs/operators";
import { base } from './urls'; import { base } from "./urls";
export class OdataService { export class OdataService {
private url: string; private url: string;
constructor(private odataService: ODataService, private entity: string) { constructor(private odataService: ODataService, private entity: string) {
this.url = base + '/odata/'; this.url = base + "/odata/";
} }
public list<TResponse>(): Observable<TResponse[]> { public list<TResponse>(properties: string[]): Observable<TResponse[]> {
const query = new ODataQuery(this.odataService, this.url).entitySet( const query = new ODataQuery(this.odataService, this.url)
this.entity .entitySet(this.entity)
); .select(properties);
const get = query.get().pipe(map(_ => _.toPropertyValue<TResponse[]>())); const get = query.get().pipe(map(_ => _.toPropertyValue<TResponse[]>()));
return get; return get;
} }
public get<TResponse>(id: number): Observable<TResponse> { public get<TResponse>(
id: number,
properties: string[]
): Observable<TResponse> {
const query = new ODataQuery(this.odataService, this.url) const query = new ODataQuery(this.odataService, this.url)
.entitySet(this.entity) .entitySet(this.entity)
.entityKey(id); .entityKey(id)
.select(properties);
const get = query.get().pipe(map(_ => _.toEntity<TResponse>())); const get = query.get().pipe(map(_ => _.toEntity<TResponse>()));
return get; return get;
} }
public patch(id: number, control: string, value: any): Observable<boolean> {
const valueSet = { [control]: value };
const query = new ODataQuery(this.odataService, this.url)
.entitySet(this.entity)
.entityKey(id);
const get = query.patch(valueSet).pipe(
map(() => true)
);
return get;
}
} }

View File

@@ -2,7 +2,8 @@ import { Injectable } from '@angular/core';
import { ODataService } from 'odata-v4-ng'; import { ODataService } from 'odata-v4-ng';
import { OdataService } from './odata.service'; import { OdataService } from './odata.service';
import { Song } from '../models/song.model'; import { Song } from '../models/song.model';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -18,17 +19,39 @@ export class SongsService extends OdataService {
} }
public loadSongList(): void { public loadSongList(): void {
this.list<Song>().subscribe(_ => this.songs.next(_)); const properties = ['ID', 'Name', 'Number', 'SongType', 'Key', 'Tempo'];
this.list<Song>(properties).subscribe(_ => this.songs.next(_));
} }
public selectSong(id: number): void { public selectSong(id: number): void {
this.edit = false; this.edit = false;
const filter = this.songs.value.filter(_ => _.ID === id); const filter = this.songs.value.filter(_ => _.ID === id);
const song = filter.length === 1 ? filter[0] : null; const song = filter.length === 1 ? filter[0] : null;
this.selectedSong.next(song); if (!song) {
return;
}
this.get<Song>(id, ['Text', 'Comments']).subscribe(_ => {
song.Text = _.Text;
song.Comments = _.Comments;
this.selectedSong.next(song);
});
} }
public resetSelectedSong() { public resetSelectedSong() {
this.selectedSong.next(null); this.selectedSong.next(null);
} }
public patch(id: number, control: string, value: any): Observable<boolean> {
const patch = super.patch(id, control, value).pipe(
tap(() => {
const songs = this.songs.value;
const song = songs.filter(_ => _.ID === id)[0];
song[control] = value;
this.songs.next(songs);
this.selectedSong.next(song);
})
);
return patch;
}
} }

View File

@@ -1 +1,2 @@
export const base = 'http://test.benjamin-ifland.de/'; // export const base = 'http://192.168.178.20/API';
export const base = 'http://test.benjamin-ifland.de';

View File

@@ -3,11 +3,11 @@ import { trigger, transition, style, animate } from '@angular/animations';
export const blend = trigger('blend', [ export const blend = trigger('blend', [
transition(':enter', [ transition(':enter', [
style({ opacity: 0 }), style({ opacity: 0 }),
animate('700ms', style({ opacity: 0 })), animate('200ms', style({ opacity: 0 })),
animate('300ms', style({ opacity: 1 })) animate('300ms', style({ opacity: 1 }))
]), ]),
transition(':leave', [ transition(':leave', [
style({ opacity: 1 }), style({ opacity: 1 }),
animate('300ms', style({ opacity: 0 })) animate('300ms', style({ opacity: 0 }))
]) ])
]); ]);

View File

@@ -73,7 +73,7 @@ html {
} }
.mat-card { .mat-card {
width: 500px; width: 600px;
border-radius: 8px; border-radius: 8px;
background: #fffd; background: #fffd;
margin: 20px; margin: 20px;
@@ -84,7 +84,7 @@ html {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
width: 420px; width: 520px;
} }
.mat-card-content { .mat-card-content {