From 8aeffc3c8fd7111c51a1b7b6801cb1f861013d14 Mon Sep 17 00:00:00 2001 From: benjamin Date: Thu, 28 Nov 2019 22:25:52 +0100 Subject: [PATCH] edit and update data --- src/app/animations.ts | 2 +- src/app/app.component.less | 4 +- .../navigation/filter/filter.component.html | 2 +- .../filter/filter.component.spec.ts | 8 ++-- .../songs/services/song-data.service.spec.ts | 10 ++--- src/app/songs/services/song-data.service.ts | 13 ++++-- src/app/songs/services/song.service.spec.ts | 6 +-- src/app/songs/services/song.service.ts | 12 +++++ .../songs/song-list/song-list.component.html | 4 +- .../song-list/song-list.component.spec.ts | 4 +- .../songs/song-list/song-list.component.ts | 34 +++++++------- src/app/songs/song/edit/edit.component.html | 40 +++++++++++++++++ src/app/songs/song/edit/edit.component.less | 14 ++++++ .../songs/song/edit/edit.component.spec.ts | 25 +++++++++++ src/app/songs/song/edit/edit.component.ts | 44 +++++++++++++++++++ src/app/songs/song/edit/edit.module.ts | 34 ++++++++++++++ src/app/songs/song/edit/edit.service.spec.ts | 12 +++++ src/app/songs/song/edit/edit.service.ts | 23 ++++++++++ src/app/songs/song/song.component.html | 3 ++ src/app/songs/song/song.module.ts | 16 ++++--- src/app/songs/songs-routing.module.ts | 5 +++ src/app/songs/songs.module.ts | 4 +- .../button-row/button-row.component.html | 3 ++ .../button-row/button-row.component.less | 6 +++ .../button-row/button-row.component.spec.ts | 25 +++++++++++ .../button-row/button-row.component.ts | 16 +++++++ .../button-row/button-row.module.ts | 14 ++++++ .../components/card/card.component.html | 2 +- .../song-type-translater/song-type.pipe.ts | 2 +- src/environments/environment.prod.ts | 2 +- src/environments/environment.ts | 2 +- 31 files changed, 341 insertions(+), 50 deletions(-) create mode 100644 src/app/songs/song/edit/edit.component.html create mode 100644 src/app/songs/song/edit/edit.component.less create mode 100644 src/app/songs/song/edit/edit.component.spec.ts create mode 100644 src/app/songs/song/edit/edit.component.ts create mode 100644 src/app/songs/song/edit/edit.module.ts create mode 100644 src/app/songs/song/edit/edit.service.spec.ts create mode 100644 src/app/songs/song/edit/edit.service.ts create mode 100644 src/app/widget-modules/components/button-row/button-row.component.html create mode 100644 src/app/widget-modules/components/button-row/button-row.component.less create mode 100644 src/app/widget-modules/components/button-row/button-row.component.spec.ts create mode 100644 src/app/widget-modules/components/button-row/button-row.component.ts create mode 100644 src/app/widget-modules/components/button-row/button-row.module.ts diff --git a/src/app/animations.ts b/src/app/animations.ts index 77f3bf2..4dc96e5 100644 --- a/src/app/animations.ts +++ b/src/app/animations.ts @@ -1,4 +1,4 @@ -import {animate, query, stagger, state, style, transition, trigger} from '@angular/animations'; +import {animate, state, style, transition, trigger} from '@angular/animations'; export const fade = [ // the fade-in/fade-out animation. diff --git a/src/app/app.component.less b/src/app/app.component.less index 60306bd..aaeddb6 100644 --- a/src/app/app.component.less +++ b/src/app/app.component.less @@ -3,5 +3,7 @@ h1 { } .content { - margin-top: 80px; + margin-top: 60px; + display: flex; + justify-content: center; } diff --git a/src/app/application-frame/navigation/filter/filter.component.html b/src/app/application-frame/navigation/filter/filter.component.html index de22368..6a98267 100644 --- a/src/app/application-frame/navigation/filter/filter.component.html +++ b/src/app/application-frame/navigation/filter/filter.component.html @@ -1,2 +1,2 @@ - + diff --git a/src/app/application-frame/navigation/filter/filter.component.spec.ts b/src/app/application-frame/navigation/filter/filter.component.spec.ts index fc30049..4550630 100644 --- a/src/app/application-frame/navigation/filter/filter.component.spec.ts +++ b/src/app/application-frame/navigation/filter/filter.component.spec.ts @@ -1,6 +1,6 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; -import { FilterComponent } from './filter.component'; +import {FilterComponent} from './filter.component'; describe('FilterComponent', () => { let component: FilterComponent; @@ -8,9 +8,9 @@ describe('FilterComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ FilterComponent ] + declarations: [FilterComponent] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { diff --git a/src/app/songs/services/song-data.service.spec.ts b/src/app/songs/services/song-data.service.spec.ts index 1275d71..9e764be 100644 --- a/src/app/songs/services/song-data.service.spec.ts +++ b/src/app/songs/services/song-data.service.spec.ts @@ -15,7 +15,7 @@ describe('SongDataService', () => { }; const mockAngularFirestore = { - collection: path => angularFirestoreCollection + collection: () => angularFirestoreCollection }; beforeEach(() => TestBed.configureTestingModule({ @@ -31,11 +31,11 @@ describe('SongDataService', () => { it('should list songs', async(() => { const service: SongDataService = TestBed.get(SongDataService); - service.list().subscribe(songs => { - expect(songs).toEqual([ + service.list().subscribe(s => { + expect(s).toEqual([ {title: 'title1'} - ]); + ] as any); } - ) + ); })); }); diff --git a/src/app/songs/services/song-data.service.ts b/src/app/songs/services/song-data.service.ts index e9df2fd..5365ca5 100644 --- a/src/app/songs/services/song-data.service.ts +++ b/src/app/songs/services/song-data.service.ts @@ -22,11 +22,16 @@ export class SongDataService { } public list = (): Observable => this.songs; - public read = (songId: string): Observable => - this.afs.doc('songs/' + songId).valueChanges().pipe(map(song => ({ + + public read(songId: string): Observable { + return this.afs.doc('songs/' + songId).valueChanges().pipe(map(song => ({ ...song, id: songId - } as Song))) - + } as Song))); + } + public async update(songId: string, data: any): Promise { + await this.afs.doc('songs/' + songId).update(data); + } } + diff --git a/src/app/songs/services/song.service.spec.ts b/src/app/songs/services/song.service.spec.ts index 1523363..07a3ed4 100644 --- a/src/app/songs/services/song.service.spec.ts +++ b/src/app/songs/services/song.service.spec.ts @@ -27,10 +27,10 @@ describe('SongService', () => { it('should list songs', async(() => { const service: SongService = TestBed.get(SongService); - service.list$().subscribe(songs => { - expect(songs).toEqual([ + service.list$().subscribe(s => { + expect(s).toEqual([ {title: 'title1'} - ]); + ] as any); }); })); }); diff --git a/src/app/songs/services/song.service.ts b/src/app/songs/services/song.service.ts index 4a444a6..479d3f1 100644 --- a/src/app/songs/services/song.service.ts +++ b/src/app/songs/services/song.service.ts @@ -8,10 +8,22 @@ import {SongDataService} from './song-data.service'; }) export class SongService { + public TYPES = ['Praise', 'Worship']; + + 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 songDataService: SongDataService) { } public list$ = (): Observable => this.songDataService.list(); public read = (songId: string): Observable => this.songDataService.read(songId); + public async update(songId: string, data: any): Promise { + await this.songDataService.update(songId, data); + } + + } diff --git a/src/app/songs/song-list/song-list.component.html b/src/app/songs/song-list/song-list.component.html index d0a3347..04c84aa 100644 --- a/src/app/songs/song-list/song-list.component.html +++ b/src/app/songs/song-list/song-list.component.html @@ -1,3 +1,3 @@ - - + + diff --git a/src/app/songs/song-list/song-list.component.spec.ts b/src/app/songs/song-list/song-list.component.spec.ts index 49485d3..af85731 100644 --- a/src/app/songs/song-list/song-list.component.spec.ts +++ b/src/app/songs/song-list/song-list.component.spec.ts @@ -40,8 +40,8 @@ describe('SongListComponent', () => { it('should read songs from SongService', fakeAsync(() => { tick(); - expect(component.songs$).toEqual([ + expect(component.songs$).toEqual([ {title: 'title1'} - ]); + ] as any); })); }); diff --git a/src/app/songs/song-list/song-list.component.ts b/src/app/songs/song-list/song-list.component.ts index e4b4649..54e2306 100644 --- a/src/app/songs/song-list/song-list.component.ts +++ b/src/app/songs/song-list/song-list.component.ts @@ -13,10 +13,25 @@ import {ActivatedRoute} from '@angular/router'; animations: [fade] }) export class SongListComponent implements OnInit { - public songs$: Observable; constructor(private songService: SongService, private activatedRoute: ActivatedRoute) { } + public songs$: Observable; + + private static filter(song: Song, filterValue: string): boolean { + if (!filterValue) { + return true; + } + + const textMatch = song.text && SongListComponent.normalize(song.text).indexOf(SongListComponent.normalize(filterValue)) !== -1; + const titleMatch = song.title && SongListComponent.normalize(song.title).indexOf(SongListComponent.normalize(filterValue)) !== -1; + + return textMatch || titleMatch; + } + + private static normalize(input: string): string { + return input.toLowerCase().replace(/\s/g, ''); + } ngOnInit() { const filter$ = this.activatedRoute.queryParams.pipe( @@ -29,22 +44,7 @@ export class SongListComponent implements OnInit { ); this.songs$ = combineLatest([filter$, songs$]).pipe( - map(_ => _[1].filter(song => this.filter(song, _[0]))) + map(_ => _[1].filter(song => SongListComponent.filter(song, _[0]))) ); } - - private filter(song: Song, filterValue: string): boolean { - if (!filterValue) { - return true; - } - - const textMatch = song.text && this.normalize(song.text).indexOf(this.normalize(filterValue)) !== -1; - const titleMatch = song.title && this.normalize(song.title).indexOf(this.normalize(filterValue)) !== -1; - - return textMatch || titleMatch; - } - - private normalize( input: string): string { - return input.toLowerCase().replace(/\s/g, ''); - } } diff --git a/src/app/songs/song/edit/edit.component.html b/src/app/songs/song/edit/edit.component.html new file mode 100644 index 0000000..6c981d9 --- /dev/null +++ b/src/app/songs/song/edit/edit.component.html @@ -0,0 +1,40 @@ + + +
+ + Titel + + + +
+ + Typ + + {{type | songType}} + + + + Tonart + + {{key}} + + + + Tempo + + +
+ + + Songtext + + + + +
+ + + + + +
diff --git a/src/app/songs/song/edit/edit.component.less b/src/app/songs/song/edit/edit.component.less new file mode 100644 index 0000000..e02befa --- /dev/null +++ b/src/app/songs/song/edit/edit.component.less @@ -0,0 +1,14 @@ +.form { + margin-top: 20px; + width: 100%; + + > * { + width: 100%; + } + + .third { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + column-gap: 20px; + } +} diff --git a/src/app/songs/song/edit/edit.component.spec.ts b/src/app/songs/song/edit/edit.component.spec.ts new file mode 100644 index 0000000..d7a4920 --- /dev/null +++ b/src/app/songs/song/edit/edit.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {EditComponent} from './edit.component'; + +describe('EditComponent', () => { + let component: EditComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [EditComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/songs/song/edit/edit.component.ts b/src/app/songs/song/edit/edit.component.ts new file mode 100644 index 0000000..19cb554 --- /dev/null +++ b/src/app/songs/song/edit/edit.component.ts @@ -0,0 +1,44 @@ +import {Component, OnInit} from '@angular/core'; +import {Song} from '../../models/song'; +import {ActivatedRoute, Router} from '@angular/router'; +import {SongService} from '../../services/song.service'; +import {first, map, switchMap} from 'rxjs/operators'; +import {FormGroup} from '@angular/forms'; +import {EditService} from './edit.service'; + +@Component({ + selector: 'app-edit', + templateUrl: './edit.component.html', + styleUrls: ['./edit.component.less'] +}) +export class EditComponent implements OnInit { + public song: Song; + public form: FormGroup; + public keys = this.songService.KEYS; + public types = this.songService.TYPES; + + constructor( + private activatedRoute: ActivatedRoute, + private songService: SongService, + private editService: EditService, + private router: Router + ) { + } + + public ngOnInit(): void { + this.activatedRoute.params.pipe( + map(param => param.songId), + switchMap(songId => this.songService.read(songId)), + first() + ).subscribe(song => { + this.song = song; + this.form = this.editService.createSongForm(song); + }); + } + + public async onSave(): Promise { + const data = this.form.value; + await this.songService.update(this.song.id, data); + await this.router.navigateByUrl('songs/' + this.song.id); + } +} diff --git a/src/app/songs/song/edit/edit.module.ts b/src/app/songs/song/edit/edit.module.ts new file mode 100644 index 0000000..14c43fa --- /dev/null +++ b/src/app/songs/song/edit/edit.module.ts @@ -0,0 +1,34 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {EditComponent} from './edit.component'; +import {CardModule} from '../../../widget-modules/components/card/card.module'; +import {SongTypeTranslaterModule} from '../../../widget-modules/pipes/song-type-translater/song-type-translater.module'; +import {ReactiveFormsModule} from '@angular/forms'; +import {MatInputModule} from '@angular/material/input'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {MatSelectModule} from '@angular/material/select'; +import {MatButtonModule} from '@angular/material/button'; +import {ButtonRowModule} from '../../../widget-modules/components/button-row/button-row.module'; +import {RouterModule} from '@angular/router'; + + +@NgModule({ + declarations: [EditComponent], + exports: [EditComponent], + imports: [ + CommonModule, + CardModule, + SongTypeTranslaterModule, + ReactiveFormsModule, + RouterModule, + + MatInputModule, + MatButtonModule, + MatCheckboxModule, + MatSelectModule, + ButtonRowModule, + + ] +}) +export class EditModule { +} diff --git a/src/app/songs/song/edit/edit.service.spec.ts b/src/app/songs/song/edit/edit.service.spec.ts new file mode 100644 index 0000000..15a05e1 --- /dev/null +++ b/src/app/songs/song/edit/edit.service.spec.ts @@ -0,0 +1,12 @@ +import {TestBed} from '@angular/core/testing'; + +import {EditService} from './edit.service'; + +describe('EditService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: EditService = TestBed.get(EditService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/songs/song/edit/edit.service.ts b/src/app/songs/song/edit/edit.service.ts new file mode 100644 index 0000000..253de96 --- /dev/null +++ b/src/app/songs/song/edit/edit.service.ts @@ -0,0 +1,23 @@ +import {Injectable} from '@angular/core'; +import {Song} from '../../models/song'; +import {FormControl, FormGroup} from '@angular/forms'; + +@Injectable({ + providedIn: 'root' +}) +export class EditService { + + constructor() { + } + + public createSongForm(song: Song): FormGroup { + return new FormGroup({ + text: new FormControl(song.text), + title: new FormControl(song.title), + comment: new FormControl(song.comment), + key: new FormControl(song.key), + tempo: new FormControl(song.tempo), + type: new FormControl(song.type) + }); + } +} diff --git a/src/app/songs/song/song.component.html b/src/app/songs/song/song.component.html index ae0a53d..a0f4274 100644 --- a/src/app/songs/song/song.component.html +++ b/src/app/songs/song/song.component.html @@ -12,4 +12,7 @@ + + +
diff --git a/src/app/songs/song/song.module.ts b/src/app/songs/song/song.module.ts index 31db537..ddaae3a 100644 --- a/src/app/songs/song/song.module.ts +++ b/src/app/songs/song/song.module.ts @@ -1,9 +1,11 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; import {SongComponent} from './song.component'; import {CardModule} from '../../widget-modules/components/card/card.module'; import {SongTypeTranslaterModule} from '../../widget-modules/pipes/song-type-translater/song-type-translater.module'; - +import {MatButtonModule} from '@angular/material/button'; +import {ButtonRowModule} from '../../widget-modules/components/button-row/button-row.module'; +import {RouterModule} from '@angular/router'; @NgModule({ @@ -12,8 +14,12 @@ import {SongTypeTranslaterModule} from '../../widget-modules/pipes/song-type-tra imports: [ CommonModule, CardModule, + RouterModule, - SongTypeTranslaterModule + SongTypeTranslaterModule, + MatButtonModule, + ButtonRowModule, ] }) -export class SongModule { } +export class SongModule { +} diff --git a/src/app/songs/songs-routing.module.ts b/src/app/songs/songs-routing.module.ts index fc4e877..82f6ec7 100644 --- a/src/app/songs/songs-routing.module.ts +++ b/src/app/songs/songs-routing.module.ts @@ -2,6 +2,7 @@ import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; import {SongComponent} from './song/song.component'; import {SongListComponent} from './song-list/song-list.component'; +import {EditComponent} from './song/edit/edit.component'; const routes: Routes = [ @@ -10,6 +11,10 @@ const routes: Routes = [ component: SongListComponent, pathMatch: 'full' }, + { + path: ':songId/edit', + component: EditComponent + }, { path: ':songId', component: SongComponent diff --git a/src/app/songs/songs.module.ts b/src/app/songs/songs.module.ts index 6ac192e..6a9eee1 100644 --- a/src/app/songs/songs.module.ts +++ b/src/app/songs/songs.module.ts @@ -4,6 +4,7 @@ import {CommonModule} from '@angular/common'; import {SongsRoutingModule} from './songs-routing.module'; import {SongListModule} from './song-list/song-list.module'; import {SongModule} from './song/song.module'; +import {EditModule} from './song/edit/edit.module'; @NgModule({ declarations: [], @@ -11,7 +12,8 @@ import {SongModule} from './song/song.module'; CommonModule, SongsRoutingModule, SongListModule, - SongModule + SongModule, + EditModule ] }) export class SongsModule { diff --git a/src/app/widget-modules/components/button-row/button-row.component.html b/src/app/widget-modules/components/button-row/button-row.component.html new file mode 100644 index 0000000..93f8185 --- /dev/null +++ b/src/app/widget-modules/components/button-row/button-row.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/widget-modules/components/button-row/button-row.component.less b/src/app/widget-modules/components/button-row/button-row.component.less new file mode 100644 index 0000000..e0f28f9 --- /dev/null +++ b/src/app/widget-modules/components/button-row/button-row.component.less @@ -0,0 +1,6 @@ +.row { + display: flex; + flex-direction: row-reverse; + flex-wrap: wrap; + width: 100%; +} diff --git a/src/app/widget-modules/components/button-row/button-row.component.spec.ts b/src/app/widget-modules/components/button-row/button-row.component.spec.ts new file mode 100644 index 0000000..7cdcd0c --- /dev/null +++ b/src/app/widget-modules/components/button-row/button-row.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ButtonRowComponent} from './button-row.component'; + +describe('ButtonRowComponent', () => { + let component: ButtonRowComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ButtonRowComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ButtonRowComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/widget-modules/components/button-row/button-row.component.ts b/src/app/widget-modules/components/button-row/button-row.component.ts new file mode 100644 index 0000000..4ddaaec --- /dev/null +++ b/src/app/widget-modules/components/button-row/button-row.component.ts @@ -0,0 +1,16 @@ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-button-row', + templateUrl: './button-row.component.html', + styleUrls: ['./button-row.component.less'] +}) +export class ButtonRowComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/widget-modules/components/button-row/button-row.module.ts b/src/app/widget-modules/components/button-row/button-row.module.ts new file mode 100644 index 0000000..fc7cca8 --- /dev/null +++ b/src/app/widget-modules/components/button-row/button-row.module.ts @@ -0,0 +1,14 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {ButtonRowComponent} from './button-row.component'; + + +@NgModule({ + declarations: [ButtonRowComponent], + exports: [ButtonRowComponent], + imports: [ + CommonModule + ] +}) +export class ButtonRowModule { +} diff --git a/src/app/widget-modules/components/card/card.component.html b/src/app/widget-modules/components/card/card.component.html index c342020..0d528a8 100644 --- a/src/app/widget-modules/components/card/card.component.html +++ b/src/app/widget-modules/components/card/card.component.html @@ -1,4 +1,4 @@
-
{{heading}}
+
{{heading}}
diff --git a/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.ts b/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.ts index 142e69e..716caae 100644 --- a/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.ts +++ b/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.ts @@ -12,7 +12,7 @@ export class SongTypePipe implements PipeTransform { case 'Praise': return 'Lobpreis'; default: - return '' + return ''; } } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index c840f72..7d4dc0b 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -2,5 +2,5 @@ import {firebase} from './firebase'; export const environment = { production: true, - firebase: firebase + firebase }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 1ee723e..e7dac15 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -6,7 +6,7 @@ import {firebase} from './firebase'; export const environment = { production: false, - firebase: firebase + firebase }; /*