From 87aeb62a2abeb1da8f67b8c75502c76b6e98e2ed Mon Sep 17 00:00:00 2001 From: benjamin Date: Sun, 24 Nov 2019 15:57:20 +0100 Subject: [PATCH] Basisimplementierung Songlist --- .angulardoc.json | 3 ++ .firebaserc | 5 ++ .gitignore | 1 + angular.json | 9 ++-- firebase.json | 20 ++++++++ firestore.indexes.json | 4 ++ firestore.rules | 16 +++++++ package.json | 1 + src/app/app-routing.module.ts | 19 ++++++-- src/app/app.component.html | 4 ++ src/app/app.component.less | 7 +++ src/app/app.component.spec.ts | 19 ++------ src/app/app.component.ts | 2 +- src/app/app.module.ts | 31 ++++++++---- .../application-frame.module.ts | 20 ++++++++ .../navigation/navigation.component.html | 5 ++ .../navigation/navigation.component.less | 40 ++++++++++++++++ .../navigation/navigation.component.spec.ts | 25 ++++++++++ .../navigation/navigation.component.ts | 16 +++++++ src/app/songs/models/song.ts | 10 ++++ .../songs/services/song-data.service.spec.ts | 41 ++++++++++++++++ src/app/songs/services/song-data.service.ts | 20 ++++++++ src/app/songs/services/song.service.spec.ts | 36 ++++++++++++++ src/app/songs/services/song.service.ts | 16 +++++++ .../list-item/list-item.component.html | 6 +++ .../list-item/list-item.component.less | 23 +++++++++ .../list-item/list-item.component.spec.ts | 25 ++++++++++ .../list-item/list-item.component.ts | 18 +++++++ .../songs/song-list/song-list.component.html | 3 ++ .../songs/song-list/song-list.component.less | 2 + .../song-list/song-list.component.spec.ts | 47 +++++++++++++++++++ .../songs/song-list/song-list.component.ts | 22 +++++++++ src/app/songs/song-list/song-list.module.ts | 20 ++++++++ src/app/songs/song/song.component.html | 1 + src/app/songs/song/song.component.less | 0 src/app/songs/song/song.component.spec.ts | 39 +++++++++++++++ src/app/songs/song/song.component.ts | 19 ++++++++ src/app/songs/songs-routing.module.ts | 24 ++++++++++ src/app/songs/songs.module.ts | 19 ++++++++ .../components/card/card.component.html | 3 ++ .../components/card/card.component.less | 12 +++++ .../components/card/card.component.spec.ts | 25 ++++++++++ .../components/card/card.component.ts | 17 +++++++ .../components/card/card.module.ts | 14 ++++++ .../song-type-translater.module.ts | 16 +++++++ .../song-type.pipe.spec.ts | 8 ++++ .../song-type-translater/song-type.pipe.ts | 19 ++++++++ src/custom-theme.scss | 1 - src/environments/environment.prod.ts | 5 +- src/environments/environment.ts | 5 +- src/index.html | 12 ++--- src/main.ts | 8 ++-- src/polyfills.ts | 2 +- src/styles.less | 4 -- src/styles/shadow.less | 19 ++++++++ src/styles/styles.less | 21 +++++++++ src/test.ts | 7 +-- 57 files changed, 777 insertions(+), 59 deletions(-) create mode 100644 .angulardoc.json create mode 100644 .firebaserc create mode 100644 firebase.json create mode 100644 firestore.indexes.json create mode 100644 firestore.rules create mode 100644 src/app/application-frame/application-frame.module.ts create mode 100644 src/app/application-frame/navigation/navigation.component.html create mode 100644 src/app/application-frame/navigation/navigation.component.less create mode 100644 src/app/application-frame/navigation/navigation.component.spec.ts create mode 100644 src/app/application-frame/navigation/navigation.component.ts create mode 100644 src/app/songs/models/song.ts create mode 100644 src/app/songs/services/song-data.service.spec.ts create mode 100644 src/app/songs/services/song-data.service.ts create mode 100644 src/app/songs/services/song.service.spec.ts create mode 100644 src/app/songs/services/song.service.ts create mode 100644 src/app/songs/song-list/list-item/list-item.component.html create mode 100644 src/app/songs/song-list/list-item/list-item.component.less create mode 100644 src/app/songs/song-list/list-item/list-item.component.spec.ts create mode 100644 src/app/songs/song-list/list-item/list-item.component.ts create mode 100644 src/app/songs/song-list/song-list.component.html create mode 100644 src/app/songs/song-list/song-list.component.less create mode 100644 src/app/songs/song-list/song-list.component.spec.ts create mode 100644 src/app/songs/song-list/song-list.component.ts create mode 100644 src/app/songs/song-list/song-list.module.ts create mode 100644 src/app/songs/song/song.component.html create mode 100644 src/app/songs/song/song.component.less create mode 100644 src/app/songs/song/song.component.spec.ts create mode 100644 src/app/songs/song/song.component.ts create mode 100644 src/app/songs/songs-routing.module.ts create mode 100644 src/app/songs/songs.module.ts create mode 100644 src/app/widget-modules/components/card/card.component.html create mode 100644 src/app/widget-modules/components/card/card.component.less create mode 100644 src/app/widget-modules/components/card/card.component.spec.ts create mode 100644 src/app/widget-modules/components/card/card.component.ts create mode 100644 src/app/widget-modules/components/card/card.module.ts create mode 100644 src/app/widget-modules/pipes/song-type-translater/song-type-translater.module.ts create mode 100644 src/app/widget-modules/pipes/song-type-translater/song-type.pipe.spec.ts create mode 100644 src/app/widget-modules/pipes/song-type-translater/song-type.pipe.ts delete mode 100644 src/styles.less create mode 100644 src/styles/shadow.less create mode 100644 src/styles/styles.less diff --git a/.angulardoc.json b/.angulardoc.json new file mode 100644 index 0000000..0c6f9a3 --- /dev/null +++ b/.angulardoc.json @@ -0,0 +1,3 @@ +{ + "repoId": "a3607a0e-3686-4664-8e33-0671e13cd437" +} \ No newline at end of file diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000..78eef2b --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "worshipgenerator" + } +} diff --git a/.gitignore b/.gitignore index c90b1bd..4b9e23c 100644 --- a/.gitignore +++ b/.gitignore @@ -314,3 +314,4 @@ testem.log # System Files .DS_Store Thumbs.db +firebase.ts diff --git a/angular.json b/angular.json index a104ea8..cc8e88a 100644 --- a/angular.json +++ b/angular.json @@ -30,7 +30,8 @@ ], "styles": [ "src/custom-theme.scss", - "src/styles.less" + "src/styles/styles.less", + "src/styles/shadow.less" ], "scripts": [] }, @@ -97,9 +98,7 @@ "src/assets", "src/manifest.webmanifest" ], - "styles": [ - "src/styles.less" - ], + "styles": [], "scripts": [] } }, @@ -132,4 +131,4 @@ } }, "defaultProject": "wgenerator" -} \ No newline at end of file +} diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..8eaafc5 --- /dev/null +++ b/firebase.json @@ -0,0 +1,20 @@ +{ + "firestore": { + "rules": "firestore.rules", + "indexes": "firestore.indexes.json" + }, + "hosting": { + "public": "dist/wgenerator", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ], + "rewrites": [ + { + "source": "**", + "destination": "/index.html" + } + ] + } +} diff --git a/firestore.indexes.json b/firestore.indexes.json new file mode 100644 index 0000000..415027e --- /dev/null +++ b/firestore.indexes.json @@ -0,0 +1,4 @@ +{ + "indexes": [], + "fieldOverrides": [] +} diff --git a/firestore.rules b/firestore.rules new file mode 100644 index 0000000..891369d --- /dev/null +++ b/firestore.rules @@ -0,0 +1,16 @@ +rules_version = '2'; +service cloud.firestore { + match /databases/{database}/documents { + match /user/{user} { + allow read: if true; + } + match /songs/{song} { + allow read: if true; + allow write: if true; + } + match /lastmodified/{lastmodified} { + allow read: if true; + allow write: if true; + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index 856dc07..ae331a3 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "ng": "ng", "start": "ng serve", "build": "ng build", + "deploy": "ng build --prod && firebase deploy", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 06c7342..0545bc6 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,11 +1,22 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; +import {NgModule} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; -const routes: Routes = []; +const routes: Routes = [ + { + path: '', + redirectTo: 'songs', + pathMatch: 'full' + }, + { + path: 'songs', + loadChildren: () => import('./songs/songs.module').then(m => m.SongsModule) + } +]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) -export class AppRoutingModule { } +export class AppRoutingModule { +} diff --git a/src/app/app.component.html b/src/app/app.component.html index e69de29..8a536da 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -0,0 +1,4 @@ + +
+ +
diff --git a/src/app/app.component.less b/src/app/app.component.less index e69de29..60306bd 100644 --- a/src/app/app.component.less +++ b/src/app/app.component.less @@ -0,0 +1,7 @@ +h1 { + color: red; +} + +.content { + margin-top: 80px; +} diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 74d3a5a..76edd53 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,6 +1,6 @@ -import { TestBed, async } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppComponent } from './app.component'; +import {async, TestBed} from '@angular/core/testing'; +import {RouterTestingModule} from '@angular/router/testing'; +import {AppComponent} from './app.component'; describe('AppComponent', () => { beforeEach(async(() => { @@ -19,17 +19,4 @@ describe('AppComponent', () => { const app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); }); - - it(`should have as title 'wgenerator'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('wgenerator'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('.content span').textContent).toContain('wgenerator app is running!'); - }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index acf9b7a..9c40218 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import {Component} from '@angular/core'; @Component({ selector: 'app-root', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 51b6d55..7fbe01d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,11 +1,14 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; +import {NgModule} from '@angular/core'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { environment } from '../environments/environment'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import {AppRoutingModule} from './app-routing.module'; +import {AppComponent} from './app.component'; +import {ServiceWorkerModule} from '@angular/service-worker'; +import {environment} from '../environments/environment'; +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {ApplicationFrameModule} from "./application-frame/application-frame.module"; +import {AngularFireModule} from "@angular/fire"; +import {AngularFirestoreModule} from "@angular/fire/firestore"; @NgModule({ declarations: [ @@ -14,10 +17,18 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; imports: [ BrowserModule, AppRoutingModule, - ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }), - BrowserAnimationsModule + ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production}), + BrowserAnimationsModule, + + ApplicationFrameModule, + + + AngularFireModule.initializeApp(environment.firebase), + AngularFirestoreModule.enablePersistence(), + ], providers: [], bootstrap: [AppComponent] }) -export class AppModule { } +export class AppModule { +} diff --git a/src/app/application-frame/application-frame.module.ts b/src/app/application-frame/application-frame.module.ts new file mode 100644 index 0000000..47c13d6 --- /dev/null +++ b/src/app/application-frame/application-frame.module.ts @@ -0,0 +1,20 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {NavigationComponent} from './navigation/navigation.component'; +import {RouterModule} from "@angular/router"; + + +@NgModule({ + declarations: [ + NavigationComponent + ], + imports: [ + CommonModule, + RouterModule + ], + exports: [ + NavigationComponent + ] +}) +export class ApplicationFrameModule { +} diff --git a/src/app/application-frame/navigation/navigation.component.html b/src/app/application-frame/navigation/navigation.component.html new file mode 100644 index 0000000..f6cc5ca --- /dev/null +++ b/src/app/application-frame/navigation/navigation.component.html @@ -0,0 +1,5 @@ + + + diff --git a/src/app/application-frame/navigation/navigation.component.less b/src/app/application-frame/navigation/navigation.component.less new file mode 100644 index 0000000..323492e --- /dev/null +++ b/src/app/application-frame/navigation/navigation.component.less @@ -0,0 +1,40 @@ +@import "../../../styles/styles"; +@import "../../../styles/shadow"; + +nav { + &.head { + position: fixed; + top: 0; + left: 0; + right: 0; + height: 60px; + background: @navigation-background; + .card-3; + + display: flex; + align-items: flex-end; + + a { + display: block; + height: 60px; + color: @navigation-link-color; + font-size: 20px; + font-weight: bold; + text-decoration: none; + padding: 20px; + box-sizing: border-box; + background: transparent; + transition: @transition; + + &:hover { + background: #eee; + } + + &.active { + background: @primary-color; + color: #fff; + } + } + + } +} diff --git a/src/app/application-frame/navigation/navigation.component.spec.ts b/src/app/application-frame/navigation/navigation.component.spec.ts new file mode 100644 index 0000000..65ce002 --- /dev/null +++ b/src/app/application-frame/navigation/navigation.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {NavigationComponent} from './navigation.component'; + +describe('NavigationComponent', () => { + let component: NavigationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [NavigationComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NavigationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/application-frame/navigation/navigation.component.ts b/src/app/application-frame/navigation/navigation.component.ts new file mode 100644 index 0000000..ce622aa --- /dev/null +++ b/src/app/application-frame/navigation/navigation.component.ts @@ -0,0 +1,16 @@ +import {Component, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-navigation', + templateUrl: './navigation.component.html', + styleUrls: ['./navigation.component.less'] +}) +export class NavigationComponent implements OnInit { + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/songs/models/song.ts b/src/app/songs/models/song.ts new file mode 100644 index 0000000..0b2bef5 --- /dev/null +++ b/src/app/songs/models/song.ts @@ -0,0 +1,10 @@ +export interface Song { + comment: string; + final: boolean; + key: string; + number: number; + tempo: number; + text: string; + title: string; + type: string; +} diff --git a/src/app/songs/services/song-data.service.spec.ts b/src/app/songs/services/song-data.service.spec.ts new file mode 100644 index 0000000..7f242fc --- /dev/null +++ b/src/app/songs/services/song-data.service.spec.ts @@ -0,0 +1,41 @@ +import {async, TestBed} from '@angular/core/testing'; + +import {SongDataService} from './song-data.service'; +import {AngularFirestore} from "@angular/fire/firestore"; +import {of} from "rxjs"; + +describe('SongDataService', () => { + + const songs = [ + {title: 'title1'} + ]; + + const angularFirestoreCollection = { + valueChanges: () => of(songs) + }; + + const mockAngularFirestore = { + collection: path => angularFirestoreCollection + }; + + beforeEach(() => TestBed.configureTestingModule({ + providers: [ + {provide: AngularFirestore, useValue: mockAngularFirestore} + ] + })); + + it('should be created', () => { + const service: SongDataService = TestBed.get(SongDataService); + expect(service).toBeTruthy(); + }); + + it('should list songs', async(() => { + const service: SongDataService = TestBed.get(SongDataService); + service.list().subscribe(songs => { + expect(songs).toEqual([ + {title: 'title1'} + ]); + } + ) + })); +}); diff --git a/src/app/songs/services/song-data.service.ts b/src/app/songs/services/song-data.service.ts new file mode 100644 index 0000000..4b1ee8e --- /dev/null +++ b/src/app/songs/services/song-data.service.ts @@ -0,0 +1,20 @@ +import {Injectable} from '@angular/core'; +import {AngularFirestore, AngularFirestoreCollection} from "@angular/fire/firestore"; +import {Song} from "../models/song"; +import {Observable} from "rxjs"; + +@Injectable({ + providedIn: 'root' +}) +export class SongDataService { + private songCollection: AngularFirestoreCollection; + private songs: Observable; + + constructor(private afs: AngularFirestore) { + this.songCollection = afs.collection('songs'); + this.songs = this.songCollection.valueChanges(); + } + + public list = (): Observable => this.songs; + +} diff --git a/src/app/songs/services/song.service.spec.ts b/src/app/songs/services/song.service.spec.ts new file mode 100644 index 0000000..2a5fd9e --- /dev/null +++ b/src/app/songs/services/song.service.spec.ts @@ -0,0 +1,36 @@ +import {async, TestBed} from '@angular/core/testing'; + +import {SongService} from './song.service'; +import {SongDataService} from "./song-data.service"; +import {of} from "rxjs"; + +describe('SongService', () => { + + const songs = [ + {title: 'title1'} + ]; + + const mockSongDataService = { + list: () => of(songs) + }; + + beforeEach(() => TestBed.configureTestingModule({ + providers: [ + {provide: SongDataService, useValue: mockSongDataService} + ] + })); + + it('should be created', () => { + const service: SongService = TestBed.get(SongService); + expect(service).toBeTruthy(); + }); + + it('should list songs', async(() => { + const service: SongService = TestBed.get(SongService); + service.list().subscribe(songs => { + expect(songs).toEqual([ + {title: 'title1'} + ]); + }); + })); +}); diff --git a/src/app/songs/services/song.service.ts b/src/app/songs/services/song.service.ts new file mode 100644 index 0000000..9139d12 --- /dev/null +++ b/src/app/songs/services/song.service.ts @@ -0,0 +1,16 @@ +import {Injectable} from '@angular/core'; +import {Observable} from "rxjs"; +import {Song} from "../models/song"; +import {SongDataService} from "./song-data.service"; + +@Injectable({ + providedIn: 'root' +}) +export class SongService { + + constructor(private songDataService: SongDataService) { + } + + public list = (): Observable => this.songDataService.list(); + +} diff --git a/src/app/songs/song-list/list-item/list-item.component.html b/src/app/songs/song-list/list-item/list-item.component.html new file mode 100644 index 0000000..09aae97 --- /dev/null +++ b/src/app/songs/song-list/list-item/list-item.component.html @@ -0,0 +1,6 @@ +
+
{{song.number}}
+
{{song.title}}
+
{{song.key}}
+
{{song.type | songType}}
+
diff --git a/src/app/songs/song-list/list-item/list-item.component.less b/src/app/songs/song-list/list-item/list-item.component.less new file mode 100644 index 0000000..6beff74 --- /dev/null +++ b/src/app/songs/song-list/list-item/list-item.component.less @@ -0,0 +1,23 @@ +@import "../../../../styles/styles"; + +.list-item { + padding: 10px 20px; + display: grid; + grid-template-columns: 50px auto 30px 100px; + + & > div { + display: flex; + align-items: center; + } + + cursor: pointer; + + &:hover { + background: @primary-color; + } +} + +.number { + font-size: 18px; + font-weight: bold; +} diff --git a/src/app/songs/song-list/list-item/list-item.component.spec.ts b/src/app/songs/song-list/list-item/list-item.component.spec.ts new file mode 100644 index 0000000..6fb7497 --- /dev/null +++ b/src/app/songs/song-list/list-item/list-item.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ListItemComponent} from './list-item.component'; + +describe('ListItemComponent', () => { + let component: ListItemComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ListItemComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ListItemComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/songs/song-list/list-item/list-item.component.ts b/src/app/songs/song-list/list-item/list-item.component.ts new file mode 100644 index 0000000..d7362da --- /dev/null +++ b/src/app/songs/song-list/list-item/list-item.component.ts @@ -0,0 +1,18 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {Song} from "../../models/song"; + +@Component({ + selector: 'app-list-item', + templateUrl: './list-item.component.html', + styleUrls: ['./list-item.component.less'] +}) +export class ListItemComponent implements OnInit { + @Input() public song: Song; + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/songs/song-list/song-list.component.html b/src/app/songs/song-list/song-list.component.html new file mode 100644 index 0000000..b5d0a73 --- /dev/null +++ b/src/app/songs/song-list/song-list.component.html @@ -0,0 +1,3 @@ + + + diff --git a/src/app/songs/song-list/song-list.component.less b/src/app/songs/song-list/song-list.component.less new file mode 100644 index 0000000..11c7349 --- /dev/null +++ b/src/app/songs/song-list/song-list.component.less @@ -0,0 +1,2 @@ +.song-list { +} diff --git a/src/app/songs/song-list/song-list.component.spec.ts b/src/app/songs/song-list/song-list.component.spec.ts new file mode 100644 index 0000000..79c736d --- /dev/null +++ b/src/app/songs/song-list/song-list.component.spec.ts @@ -0,0 +1,47 @@ +import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; + +import {SongListComponent} from './song-list.component'; +import {of} from "rxjs"; +import {SongService} from "../services/song.service"; +import {NO_ERRORS_SCHEMA} from "@angular/core"; + +describe('SongListComponent', () => { + let component: SongListComponent; + let fixture: ComponentFixture; + + const songs = [ + {title: 'title1'} + ]; + + const mockSongService = { + list: () => of(songs) + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SongListComponent], + providers: [ + {provide: SongService, useValue: mockSongService} + ], + schemas: [NO_ERRORS_SCHEMA] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SongListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should read songs from SongService', fakeAsync(() => { + tick(); + expect(component.songs).toEqual([ + {title: 'title1'} + ]); + })); +}); diff --git a/src/app/songs/song-list/song-list.component.ts b/src/app/songs/song-list/song-list.component.ts new file mode 100644 index 0000000..46ecdb8 --- /dev/null +++ b/src/app/songs/song-list/song-list.component.ts @@ -0,0 +1,22 @@ +import {Component, OnInit} from '@angular/core'; +import {SongService} from "../services/song.service"; +import {Song} from "../models/song"; + +@Component({ + selector: 'app-songs', + templateUrl: './song-list.component.html', + styleUrls: ['./song-list.component.less'] +}) +export class SongListComponent implements OnInit { + public songs: Song[]; + + constructor(private songService: SongService) { + } + + ngOnInit() { + this.songService.list().subscribe(songs => { + this.songs = songs.sort((a, b) => a.number - b.number); + }); + } + +} diff --git a/src/app/songs/song-list/song-list.module.ts b/src/app/songs/song-list/song-list.module.ts new file mode 100644 index 0000000..d381da9 --- /dev/null +++ b/src/app/songs/song-list/song-list.module.ts @@ -0,0 +1,20 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {SongListComponent} from "./song-list.component"; +import {ListItemComponent} from './list-item/list-item.component'; +import {CardModule} from "../../widget-modules/components/card/card.module"; +import {SongTypeTranslaterModule} from "../../widget-modules/pipes/song-type-translater/song-type-translater.module"; + + +@NgModule({ + declarations: [SongListComponent, ListItemComponent], + exports: [SongListComponent], + imports: [ + CommonModule, + + CardModule, + SongTypeTranslaterModule + ] +}) +export class SongListModule { +} diff --git a/src/app/songs/song/song.component.html b/src/app/songs/song/song.component.html new file mode 100644 index 0000000..4814b51 --- /dev/null +++ b/src/app/songs/song/song.component.html @@ -0,0 +1 @@ +

song works with songId: {{songId}}!

diff --git a/src/app/songs/song/song.component.less b/src/app/songs/song/song.component.less new file mode 100644 index 0000000..e69de29 diff --git a/src/app/songs/song/song.component.spec.ts b/src/app/songs/song/song.component.spec.ts new file mode 100644 index 0000000..d832ad3 --- /dev/null +++ b/src/app/songs/song/song.component.spec.ts @@ -0,0 +1,39 @@ +import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; + +import {SongComponent} from './song.component'; +import {of} from "rxjs"; +import {ActivatedRoute} from "@angular/router"; + +describe('SongComponent', () => { + let component: SongComponent; + let fixture: ComponentFixture; + + const mockActivatedRoute = { + params: of({songId: '4711'}) + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SongComponent], + providers: [ + {provide: ActivatedRoute, useValue: mockActivatedRoute} + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SongComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should provide songId', fakeAsync(() => { + tick(); + expect(component.songId).toBe('4711'); + })); +}); diff --git a/src/app/songs/song/song.component.ts b/src/app/songs/song/song.component.ts new file mode 100644 index 0000000..2fbb677 --- /dev/null +++ b/src/app/songs/song/song.component.ts @@ -0,0 +1,19 @@ +import {Component, OnInit} from '@angular/core'; +import {ActivatedRoute} from "@angular/router"; + +@Component({ + selector: 'app-song', + templateUrl: './song.component.html', + styleUrls: ['./song.component.less'] +}) +export class SongComponent implements OnInit { + public songId: string; + + constructor(private activatedRoute: ActivatedRoute) { + } + + public ngOnInit(): void { + this.activatedRoute.params.subscribe(params => this.songId = params.songId); + } + +} diff --git a/src/app/songs/songs-routing.module.ts b/src/app/songs/songs-routing.module.ts new file mode 100644 index 0000000..965e305 --- /dev/null +++ b/src/app/songs/songs-routing.module.ts @@ -0,0 +1,24 @@ +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"; + + +const routes: Routes = [ + { + path: '', + component: SongListComponent, + pathMatch: 'full' + }, + { + path: ':songId', + component: SongComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class SongsRoutingModule { +} diff --git a/src/app/songs/songs.module.ts b/src/app/songs/songs.module.ts new file mode 100644 index 0000000..d5cfdff --- /dev/null +++ b/src/app/songs/songs.module.ts @@ -0,0 +1,19 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; + +import {SongsRoutingModule} from './songs-routing.module'; +import {SongComponent} from './song/song.component'; +import {SongListModule} from "./song-list/song-list.module"; + + +@NgModule({ + declarations: [SongComponent], + imports: [ + CommonModule, + SongsRoutingModule, + SongListModule, + + ] +}) +export class SongsModule { +} diff --git a/src/app/widget-modules/components/card/card.component.html b/src/app/widget-modules/components/card/card.component.html new file mode 100644 index 0000000..c4656bb --- /dev/null +++ b/src/app/widget-modules/components/card/card.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/widget-modules/components/card/card.component.less b/src/app/widget-modules/components/card/card.component.less new file mode 100644 index 0000000..406bc3a --- /dev/null +++ b/src/app/widget-modules/components/card/card.component.less @@ -0,0 +1,12 @@ +@import "../../../../styles/shadow"; + +.card { + .card-3; + margin: 20px; + border-radius: 8px; + background: #fffe; + + &.padding { + padding: 20px; + } +} diff --git a/src/app/widget-modules/components/card/card.component.spec.ts b/src/app/widget-modules/components/card/card.component.spec.ts new file mode 100644 index 0000000..0dd70c1 --- /dev/null +++ b/src/app/widget-modules/components/card/card.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {CardComponent} from './card.component'; + +describe('CardComponent', () => { + let component: CardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [CardComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/widget-modules/components/card/card.component.ts b/src/app/widget-modules/components/card/card.component.ts new file mode 100644 index 0000000..a19b9f9 --- /dev/null +++ b/src/app/widget-modules/components/card/card.component.ts @@ -0,0 +1,17 @@ +import {Component, Input, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-card', + templateUrl: './card.component.html', + styleUrls: ['./card.component.less'] +}) +export class CardComponent implements OnInit { + @Input() padding = true; + + constructor() { + } + + ngOnInit() { + } + +} diff --git a/src/app/widget-modules/components/card/card.module.ts b/src/app/widget-modules/components/card/card.module.ts new file mode 100644 index 0000000..26e9a1b --- /dev/null +++ b/src/app/widget-modules/components/card/card.module.ts @@ -0,0 +1,14 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {CardComponent} from './card.component'; + + +@NgModule({ + declarations: [CardComponent], + exports: [CardComponent], + imports: [ + CommonModule + ] +}) +export class CardModule { +} diff --git a/src/app/widget-modules/pipes/song-type-translater/song-type-translater.module.ts b/src/app/widget-modules/pipes/song-type-translater/song-type-translater.module.ts new file mode 100644 index 0000000..0315466 --- /dev/null +++ b/src/app/widget-modules/pipes/song-type-translater/song-type-translater.module.ts @@ -0,0 +1,16 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {SongTypePipe} from './song-type.pipe'; + + +@NgModule({ + declarations: [SongTypePipe], + exports: [ + SongTypePipe + ], + imports: [ + CommonModule + ] +}) +export class SongTypeTranslaterModule { +} diff --git a/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.spec.ts b/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.spec.ts new file mode 100644 index 0000000..4d7f672 --- /dev/null +++ b/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.spec.ts @@ -0,0 +1,8 @@ +import {SongTypePipe} from './song-type.pipe'; + +describe('SongTypePipe', () => { + it('create an instance', () => { + const pipe = new SongTypePipe(); + expect(pipe).toBeTruthy(); + }); +}); 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 new file mode 100644 index 0000000..f24d35b --- /dev/null +++ b/src/app/widget-modules/pipes/song-type-translater/song-type.pipe.ts @@ -0,0 +1,19 @@ +import {Pipe, PipeTransform} from '@angular/core'; + +@Pipe({ + name: 'songType' +}) +export class SongTypePipe implements PipeTransform { + + transform(songTypeKey: string): string { + switch (songTypeKey) { + case "Worship": + return "Anbetung"; + case "Praise": + return "Lobpreis"; + default: + return "" + } + } + +} diff --git a/src/custom-theme.scss b/src/custom-theme.scss index 0422ea7..f8341a5 100644 --- a/src/custom-theme.scss +++ b/src/custom-theme.scss @@ -1,4 +1,3 @@ - // Custom Theming for Angular Material // For more information: https://material.angular.io/guide/theming @import '~@angular/material/theming'; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3612073..af944f3 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,6 @@ +import {firebase} from "./firebase"; + export const environment = { - production: true + production: true, + firebase: firebase }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 7b4f817..168b3f4 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -2,8 +2,11 @@ // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. // The list of file replacements can be found in `angular.json`. +import {firebase} from "./firebase"; + export const environment = { - production: false + production: false, + firebase: firebase }; /* diff --git a/src/index.html b/src/index.html index d1e8f7b..5509828 100644 --- a/src/index.html +++ b/src/index.html @@ -4,15 +4,15 @@ Wgenerator - - - - + + + + - - + + diff --git a/src/main.ts b/src/main.ts index 3b2b7d0..6569d23 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,9 @@ import 'hammerjs'; -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import {enableProdMode} from '@angular/core'; +import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; +import {AppModule} from './app/app.module'; +import {environment} from './environments/environment'; if (environment.production) { enableProdMode(); diff --git a/src/polyfills.ts b/src/polyfills.ts index aa665d6..099cf71 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -55,7 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** diff --git a/src/styles.less b/src/styles.less deleted file mode 100644 index 7e7239a..0000000 --- a/src/styles.less +++ /dev/null @@ -1,4 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ - -html, body { height: 100%; } -body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } diff --git a/src/styles/shadow.less b/src/styles/shadow.less new file mode 100644 index 0000000..0386cf2 --- /dev/null +++ b/src/styles/shadow.less @@ -0,0 +1,19 @@ +.card-1 { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); +} + +.card-2 { + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); +} + +.card-3 { + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); +} + +.card-4 { + box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); +} + +.card-5 { + box-shadow: 0 19px 38px rgba(0, 0, 0, 0.30), 0 15px 12px rgba(0, 0, 0, 0.22); +} diff --git a/src/styles/styles.less b/src/styles/styles.less new file mode 100644 index 0000000..1dbbb4d --- /dev/null +++ b/src/styles/styles.less @@ -0,0 +1,21 @@ +@primary-color: #5285ff; + +@navigation-background: #fffffff1; +@navigation-link-color: #555; + +@transition: all 300ms ease-in-out; + +html, body { + height: 100%; +} + +body { + margin: 0; + font-family: Roboto, "Helvetica Neue", sans-serif; + font-size: 14px; + + background: #373b44; /* fallback for old browsers */ + background: -webkit-linear-gradient(to top, #373b44, #4286f4); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to top, #373b44, #4286f4); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + background-attachment: fixed; +} diff --git a/src/test.ts b/src/test.ts index 1631789..ee6a363 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,11 +1,8 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js/dist/zone-testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import {getTestBed} from '@angular/core/testing'; +import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; declare const require: any;