edit song GUI
This commit is contained in:
@@ -1,3 +1,2 @@
|
|||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
<router-outlet name="detail"></router-outlet>
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
|
||||||
import { ODataModule } from 'odata-v4-ng';
|
import { ODataModule } from 'odata-v4-ng';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
@@ -9,29 +9,37 @@ import { AppComponent } from './app.component';
|
|||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||||
|
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatTableModule } from '@angular/material/table';
|
import { MatTableModule } from '@angular/material/table';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
|
import { MatRadioModule } from '@angular/material/radio';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
|
||||||
import { TableComponent } from './components/songs/table/table.component';
|
import { TableComponent } from './components/songs/table/table.component';
|
||||||
import { SongsComponent } from './components/songs/songs.component';
|
import { SongsComponent } from './components/songs/songs.component';
|
||||||
import { SongComponent } from './components/songs/song/song.component';
|
import { SongComponent } from './components/songs/song/song.component';
|
||||||
|
import { SongEditComponent } from './components/songs/song-edit/song-edit.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent, SongsComponent, TableComponent, SongComponent],
|
declarations: [AppComponent, SongsComponent, TableComponent, SongComponent, SongEditComponent],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
ODataModule,
|
ODataModule,
|
||||||
|
|
||||||
|
MatInputModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
|
MatRadioModule,
|
||||||
|
MatSelectModule,
|
||||||
|
|
||||||
FontAwesomeModule
|
FontAwesomeModule
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<div class="song-detail-container">
|
||||||
|
<mat-card class="mat-elevation-z8" [@blend] *ngIf="form">
|
||||||
|
<mat-card-header>
|
||||||
|
<div mat-card-avatar>
|
||||||
|
<button mat-icon-button (click)="onBack()">
|
||||||
|
<fa-icon [icon]="faArrow"></fa-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<mat-card-title>Titel bearbeiten</mat-card-title>
|
||||||
|
<!-- <mat-card-subtitle>{{ song.Key }} - {{ song.Tempo }}</mat-card-subtitle> -->
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<form>
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="Titel"
|
||||||
|
[formControl]="form.controls.Name"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
<div class="row">
|
||||||
|
<mat-radio-group [formControl]="form.controls.SongType">
|
||||||
|
<mat-radio-button value="Praise">Lobpreis</mat-radio-button>
|
||||||
|
<mat-radio-button value="Worship">Anbetung</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Tonart</mat-label>
|
||||||
|
<mat-select [formControl]="form.controls.Key">
|
||||||
|
<mat-option *ngFor="let key of keys" [value]="key">
|
||||||
|
{{ key }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="Tempo"
|
||||||
|
[formControl]="form.controls.Tempo"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<mat-form-field>
|
||||||
|
<textarea
|
||||||
|
matInput
|
||||||
|
placeholder="Liedtext"
|
||||||
|
[formControl]="form.controls.Text"
|
||||||
|
[matTextareaAutosize]="true"
|
||||||
|
></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
</form>
|
||||||
|
</mat-card-content>
|
||||||
|
<!-- <mat-card-actions>
|
||||||
|
<button mat-button (click)="onClickDownload()">Herunterladen</button>
|
||||||
|
<button mat-button (click)="onClickEdit()">
|
||||||
|
<fa-icon [icon]="faEdit"></fa-icon> Bearbeiten
|
||||||
|
</button>
|
||||||
|
</mat-card-actions> -->
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr 1fr;
|
||||||
|
grid-column-gap: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { SongsService } from 'src/app/data/songs.service';
|
||||||
|
import { FormGroup } from '@angular/forms';
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef
|
||||||
|
} from '@angular/core';
|
||||||
|
import { blend } from 'src/app/services/animation';
|
||||||
|
import { EditSongService } from 'src/app/data/edit-song.service';
|
||||||
|
import { faLongArrowAltLeft } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-song-edit',
|
||||||
|
templateUrl: './song-edit.component.html',
|
||||||
|
styleUrls: ['./song-edit.component.less'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
animations: [blend]
|
||||||
|
})
|
||||||
|
export class SongEditComponent implements OnInit {
|
||||||
|
public form: FormGroup = null;
|
||||||
|
public faArrow = faLongArrowAltLeft;
|
||||||
|
public keys = [
|
||||||
|
'C',
|
||||||
|
'C#',
|
||||||
|
'Db',
|
||||||
|
'D',
|
||||||
|
'D#',
|
||||||
|
'Eb',
|
||||||
|
'E',
|
||||||
|
'F',
|
||||||
|
'F#',
|
||||||
|
'Gb',
|
||||||
|
'G',
|
||||||
|
'G#',
|
||||||
|
'Ab',
|
||||||
|
'A',
|
||||||
|
'A#',
|
||||||
|
'B',
|
||||||
|
'H',
|
||||||
|
'c',
|
||||||
|
'c#',
|
||||||
|
'db',
|
||||||
|
'd',
|
||||||
|
'd#',
|
||||||
|
'eb',
|
||||||
|
'e',
|
||||||
|
'f',
|
||||||
|
'f#',
|
||||||
|
'gb',
|
||||||
|
'g',
|
||||||
|
'g#',
|
||||||
|
'ab',
|
||||||
|
'a',
|
||||||
|
'A#',
|
||||||
|
'b',
|
||||||
|
'h'
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private editSongService: EditSongService,
|
||||||
|
private songsService: SongsService,
|
||||||
|
private change: ChangeDetectorRef
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.form = this.editSongService.initEditForm();
|
||||||
|
this.change.markForCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onBack(): void {
|
||||||
|
this.songsService.edit = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,9 @@
|
|||||||
</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>
|
||||||
|
<button mat-button (click)="onClickEdit()">
|
||||||
|
<fa-icon [icon]="faEdit"></fa-icon> Bearbeiten
|
||||||
|
</button>
|
||||||
</mat-card-actions>
|
</mat-card-actions>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,33 +4,22 @@ import {
|
|||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
ChangeDetectorRef
|
ChangeDetectorRef
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { faLongArrowAltLeft } from '@fortawesome/free-solid-svg-icons';
|
import { faLongArrowAltLeft, faEdit } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { Song } from 'src/app/models/song.model';
|
import { Song } from 'src/app/models/song.model';
|
||||||
import { DownloadService } from 'src/app/data/download.service';
|
import { DownloadService } from 'src/app/data/download.service';
|
||||||
import { trigger, transition, style, animate } from '@angular/animations';
|
import { blend } from 'src/app/services/animation';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-song',
|
selector: 'app-song',
|
||||||
templateUrl: './song.component.html',
|
templateUrl: './song.component.html',
|
||||||
styleUrls: ['./song.component.less'],
|
styleUrls: ['./song.component.less'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
animations: [
|
animations: [blend]
|
||||||
trigger('blend', [
|
|
||||||
transition(':enter', [
|
|
||||||
style({ opacity: 0 }),
|
|
||||||
animate('700ms', style({ opacity: 0 })),
|
|
||||||
animate('300ms', style({ opacity: 1 }))
|
|
||||||
]),
|
|
||||||
transition(':leave', [
|
|
||||||
style({ opacity: 1 }),
|
|
||||||
animate('300ms', style({ opacity: 0 }))
|
|
||||||
])
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
export class SongComponent {
|
export class SongComponent {
|
||||||
public song: Song;
|
public song: Song;
|
||||||
public faArrow = faLongArrowAltLeft;
|
public faArrow = faLongArrowAltLeft;
|
||||||
|
public faEdit = faEdit;
|
||||||
public selectedSongId = 0;
|
public selectedSongId = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -58,6 +47,10 @@ export class SongComponent {
|
|||||||
this.downloadService.get(id, false);
|
this.downloadService.get(id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onClickEdit(): void {
|
||||||
|
this.songService.edit = true;
|
||||||
|
}
|
||||||
|
|
||||||
public get text(): string[] {
|
public get text(): string[] {
|
||||||
return this.song.Text.split(/\r?\n/).filter(_ => _ !== ' ');
|
return this.song.Text.split(/\r?\n/).filter(_ => _ !== ' ');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
<app-table></app-table>
|
<app-table></app-table>
|
||||||
<app-song></app-song>
|
<app-song *ngIf="!songsService.edit"></app-song>
|
||||||
|
<app-song-edit *ngIf="songsService.edit"></app-song-edit>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { SongsService } from 'src/app/data/songs.service';
|
|||||||
styleUrls: ['./songs.component.less']
|
styleUrls: ['./songs.component.less']
|
||||||
})
|
})
|
||||||
export class SongsComponent {
|
export class SongsComponent {
|
||||||
constructor(songService: SongsService) {
|
constructor(public songsService: SongsService) {
|
||||||
songService.loadSongList();
|
songsService.loadSongList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ import { FormGroup, FormControl, Validators } from '@angular/forms';
|
|||||||
})
|
})
|
||||||
export class EditSongService {
|
export class EditSongService {
|
||||||
|
|
||||||
constructor(private songService: SongsService) { }
|
constructor(private songsService: SongsService) { }
|
||||||
|
|
||||||
public initEditForm(song: Song): FormGroup {
|
public initEditForm(): FormGroup {
|
||||||
|
const song = this.songsService.selectedSong.value;
|
||||||
const form = new FormGroup({
|
const form = new FormGroup({
|
||||||
ID: new FormControl(song.ID),
|
ID: new FormControl(song.ID),
|
||||||
Number: new FormControl(song.Number),
|
Number: new FormControl(song.Number),
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { BehaviorSubject } from 'rxjs';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class SongsService extends OdataService {
|
export class SongsService extends OdataService {
|
||||||
|
public edit = false;
|
||||||
|
|
||||||
public songs: BehaviorSubject<Song[]> = new BehaviorSubject<Song[]>([]);
|
public songs: BehaviorSubject<Song[]> = new BehaviorSubject<Song[]>([]);
|
||||||
public selectedSong: BehaviorSubject<Song> = new BehaviorSubject<Song>(null);
|
public selectedSong: BehaviorSubject<Song> = new BehaviorSubject<Song>(null);
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ export class SongsService extends OdataService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public selectSong(id: number): void {
|
public selectSong(id: number): void {
|
||||||
|
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);
|
this.selectedSong.next(song);
|
||||||
|
|||||||
13
WEB/src/app/services/animation.ts
Normal file
13
WEB/src/app/services/animation.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { trigger, transition, style, animate } from '@angular/animations';
|
||||||
|
|
||||||
|
export const blend = trigger('blend', [
|
||||||
|
transition(':enter', [
|
||||||
|
style({ opacity: 0 }),
|
||||||
|
animate('700ms', style({ opacity: 0 })),
|
||||||
|
animate('300ms', style({ opacity: 1 }))
|
||||||
|
]),
|
||||||
|
transition(':leave', [
|
||||||
|
style({ opacity: 1 }),
|
||||||
|
animate('300ms', style({ opacity: 0 }))
|
||||||
|
])
|
||||||
|
]);
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
@@ -70,6 +69,34 @@ html {
|
|||||||
border-top-left-radius: 0px;
|
border-top-left-radius: 0px;
|
||||||
transition: all 300ms ease-in-out;
|
transition: all 300ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-card {
|
||||||
|
width: 500px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fffd;
|
||||||
|
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;
|
||||||
|
.mat-form-field-infix {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
.mat-radio-button {
|
||||||
|
margin: 15px 10px 0 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user