BookMonkey 4 Diff

Files changed (11) hide show
  1. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/app.module.ts +16 -3
  2. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-details/book-details.component.html +8 -4
  3. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-form/book-form.component.ts +1 -2
  4. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-list/book-list.component.html +15 -8
  5. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-list/book-list.component.ts +6 -5
  6. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-list-item/book-list-item.component.html +3 -2
  7. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/form-messages/form-messages.component.ts +1 -0
  8. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/book-validators.ts +0 -1
  9. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/delay.directive.ts +20 -0
  10. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/isbn.pipe.ts +12 -0
  11. tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/zoom.directive.ts +15 -0
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/app.module.ts RENAMED
@@ -1,8 +1,10 @@
1
  import { CommonModule } from '@angular/common';
2
- import { NgModule } from '@angular/core';
3
  import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
4
  import { ReactiveFormsModule } from '@angular/forms';
5
  import { DateValueAccessorModule } from 'angular-date-value-accessor';
   
   
6
   
7
  import { AppRoutingModule } from './app-routing.module.one-app';
8
  import { AppComponent } from './app.component';
@@ -16,6 +18,9 @@
16
  import { CreateBookComponent } from './create-book/create-book.component';
17
  import { FormMessagesComponent } from './form-messages/form-messages.component';
18
  import { EditBookComponent } from './edit-book/edit-book.component';
   
   
   
19
   
20
  @NgModule({
21
  declarations: [
@@ -29,6 +34,9 @@
29
  CreateBookComponent,
30
  FormMessagesComponent,
31
  EditBookComponent,
   
   
   
32
  ],
33
  imports: [
34
  CommonModule,
@@ -38,8 +46,13 @@
38
  DateValueAccessorModule
39
  ],
40
  providers: [
41
- { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }
   
42
  ],
43
  bootstrap: [AppComponent]
44
  })
45
- export class AppModule { }
   
   
   
   
1
  import { CommonModule } from '@angular/common';
2
+ import { NgModule, LOCALE_ID } from '@angular/core';
3
  import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
4
  import { ReactiveFormsModule } from '@angular/forms';
5
  import { DateValueAccessorModule } from 'angular-date-value-accessor';
6
+ import localeDe from '@angular/common/locales/de';
7
+ import { registerLocaleData } from '@angular/common';
8
   
9
  import { AppRoutingModule } from './app-routing.module.one-app';
10
  import { AppComponent } from './app.component';
18
  import { CreateBookComponent } from './create-book/create-book.component';
19
  import { FormMessagesComponent } from './form-messages/form-messages.component';
20
  import { EditBookComponent } from './edit-book/edit-book.component';
21
+ import { IsbnPipe } from './shared/isbn.pipe';
22
+ import { ZoomDirective } from './shared/zoom.directive';
23
+ import { DelayDirective } from './shared/delay.directive';
24
   
25
  @NgModule({
26
  declarations: [
34
  CreateBookComponent,
35
  FormMessagesComponent,
36
  EditBookComponent,
37
+ IsbnPipe,
38
+ ZoomDirective,
39
+ DelayDirective
40
  ],
41
  imports: [
42
  CommonModule,
46
  DateValueAccessorModule
47
  ],
48
  providers: [
49
+ { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
50
+ { provide: LOCALE_ID, useValue: 'de' }
51
  ],
52
  bootstrap: [AppComponent]
53
  })
54
+ export class AppModule {
55
+ constructor() {
56
+ registerLocaleData(localeDe);
57
+ }
58
+ }
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-details/book-details.component.html RENAMED
@@ -11,16 +11,20 @@
11
  </div>
12
  <div class="four wide column">
13
  <h4>ISBN</h4>
14
- {{ book.isbn }}
15
  </div>
16
  <div class="four wide column">
17
  <h4>Erschienen</h4>
18
- {{ book.published }}
19
  </div>
20
  <div class="four wide column" *ngIf="book.rating">
21
  <h4>Rating</h4>
22
- <i class="yellow star icon"
23
- *ngFor="let r of getRating(book.rating)"></i>
   
   
   
   
24
  </div>
25
  </div>
26
  <h4>Beschreibung</h4>
11
  </div>
12
  <div class="four wide column">
13
  <h4>ISBN</h4>
14
+ {{ book.isbn | isbn }}
15
  </div>
16
  <div class="four wide column">
17
  <h4>Erschienen</h4>
18
+ {{ book.published | date:'longDate' }}
19
  </div>
20
  <div class="four wide column" *ngIf="book.rating">
21
  <h4>Rating</h4>
22
+ <ng-container
23
+ *ngFor="let r of getRating(book.rating);
24
+ index as i">
25
+ <i class="yellow star icon"
26
+ *bmDelay="500 + i * 200"></i>
27
+ </ng-container>
28
  </div>
29
  </div>
30
  <h4>Beschreibung</h4>
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-form/book-form.component.ts RENAMED
@@ -15,7 +15,6 @@
15
  bookForm: FormGroup;
16
   
17
  @Input() book?: Book;
18
-  
19
  @Input() set editing(isEditing: boolean) {
20
  const isbnControl = this.bookForm.get('isbn')!;
21
  if (isEditing) {
@@ -51,7 +50,7 @@
51
  });
52
  }
53
   
54
- ngOnInit(): void { }
55
   
56
  ngOnChanges() {
57
  if (this.book) {
15
  bookForm: FormGroup;
16
   
17
  @Input() book?: Book;
   
18
  @Input() set editing(isEditing: boolean) {
19
  const isbnControl = this.bookForm.get('isbn')!;
20
  if (isEditing) {
50
  });
51
  }
52
   
53
+ ngOnInit(): void {}
54
   
55
  ngOnChanges() {
56
  if (this.book) {
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-list/book-list.component.html RENAMED
@@ -1,12 +1,19 @@
1
  <div class="ui middle aligned selection divided list">
2
- <bm-book-list-item class="item"
3
- *ngFor="let b of books"
4
- [book]="b"
5
- [routerLink]="b.isbn"></bm-book-list-item>
   
   
   
   
   
6
   
7
- <div *ngIf="!books" class="ui active dimmer">
8
- <div class="ui large text loader">Daten werden geladen...</div>
9
- </div>
   
   
10
   
11
- <p *ngIf="books && !books.length">Es wurden noch keine Bücher eingetragen.</p>
12
  </div>
   
1
  <div class="ui middle aligned selection divided list">
2
+
3
+ <ng-container *ngIf="books$ | async as books; else loading">
4
+ <bm-book-list-item class="item"
5
+ *ngFor="let b of books"
6
+ [book]="b"
7
+ [routerLink]="b.isbn"></bm-book-list-item>
8
+
9
+ <p *ngIf="!books.length">Es wurden noch keine Bücher eingetragen.</p>
10
+ </ng-container>
11
   
12
+ <ng-template #loading>
13
+ <div class="ui active dimmer">
14
+ <div class="ui large text loader">Daten werden geladen...</div>
15
+ </div>
16
+ </ng-template>
17
   
   
18
  </div>
19
+
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-list/book-list.component.ts RENAMED
@@ -1,4 +1,5 @@
1
  import { Component, OnInit } from '@angular/core';
   
2
   
3
  import { Book } from '../shared/book';
4
  import { BookStoreService } from '../shared/book-store.service';
@@ -9,11 +10,11 @@
9
  styleUrls: ['./book-list.component.css']
10
  })
11
  export class BookListComponent implements OnInit {
12
- books: Book[] = [];
13
   
14
- constructor(private bs: BookStoreService) { }
15
-  
16
- ngOnInit(): void {
17
- this.bs.getAll().subscribe(res => this.books = res);
18
  }
   
   
19
  }
1
  import { Component, OnInit } from '@angular/core';
2
+ import { Observable } from 'rxjs';
3
   
4
  import { Book } from '../shared/book';
5
  import { BookStoreService } from '../shared/book-store.service';
10
  styleUrls: ['./book-list.component.css']
11
  })
12
  export class BookListComponent implements OnInit {
13
+ books$: Observable<Book[]>;
14
   
15
+ constructor(private bs: BookStoreService) {
16
+ this.books$ = this.bs.getAll();
   
   
17
  }
18
+  
19
+ ngOnInit(): void {}
20
  }
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/book-list-item/book-list-item.component.html RENAMED
@@ -1,7 +1,8 @@
1
  <ng-container *ngIf="book">
2
  <img class="ui tiny image"
3
  *ngIf="book.thumbnails && book.thumbnails[0] && book.thumbnails[0].url"
4
- [src]="book.thumbnails[0].url">
   
5
  <div class="content">
6
  <div class="header">{{ book.title }}</div>
7
  <div *ngIf="book.subtitle" class="description">{{ book.subtitle }}</div>
@@ -10,7 +11,7 @@
10
  {{ author }}<span *ngIf="!l">, </span>
11
  </span>
12
  <br>
13
- ISBN {{ book.isbn }}
14
  </div>
15
  </div>
16
  </ng-container>
1
  <ng-container *ngIf="book">
2
  <img class="ui tiny image"
3
  *ngIf="book.thumbnails && book.thumbnails[0] && book.thumbnails[0].url"
4
+ [src]="book.thumbnails[0].url"
5
+ bmZoom>
6
  <div class="content">
7
  <div class="header">{{ book.title }}</div>
8
  <div *ngIf="book.subtitle" class="description">{{ book.subtitle }}</div>
11
  {{ author }}<span *ngIf="!l">, </span>
12
  </span>
13
  <br>
14
+ ISBN {{ book.isbn | isbn }}
15
  </div>
16
  </div>
17
  </ng-container>
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/form-messages/form-messages.component.ts RENAMED
@@ -11,6 +11,7 @@
11
  @Input() control?: AbstractControl | null;
12
  @Input() controlName?: string;
13
   
   
14
  private allMessages: { [key: string]: { [key: string]: string } } = {
15
  title: {
16
  required: 'Ein Buchtitel muss angegeben werden.'
11
  @Input() control?: AbstractControl | null;
12
  @Input() controlName?: string;
13
   
14
+  
15
  private allMessages: { [key: string]: { [key: string]: string } } = {
16
  title: {
17
  required: 'Ein Buchtitel muss angegeben werden.'
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/book-validators.ts RENAMED
@@ -17,7 +17,6 @@
17
  }
18
  }
19
   
20
-
21
  static atLeastOneAuthor(controlArray: AbstractControl): ValidationErrors | null {
22
  if ((controlArray as FormArray).controls.some((el: AbstractControl) => el.value)) {
23
  return null;
17
  }
18
  }
19
   
   
20
  static atLeastOneAuthor(controlArray: AbstractControl): ValidationErrors | null {
21
  if ((controlArray as FormArray).controls.some((el: AbstractControl) => el.value)) {
22
  return null;
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/delay.directive.ts RENAMED
@@ -0,0 +1,20 @@
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
1
+ import { Directive, OnInit, Input, TemplateRef, ViewContainerRef } from '@angular/core';
2
+  
3
+ @Directive({
4
+ selector: '[bmDelay]'
5
+ })
6
+ export class DelayDirective implements OnInit {
7
+ @Input() bmDelay: number = 100;
8
+  
9
+ constructor(
10
+ private templateRef: TemplateRef<any>,
11
+ private viewContainerRef: ViewContainerRef
12
+ ) { }
13
+  
14
+ ngOnInit(): void {
15
+ setTimeout(() => {
16
+ this.viewContainerRef.createEmbeddedView(this.templateRef);
17
+ }, this.bmDelay);
18
+ }
19
+  
20
+ }
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/isbn.pipe.ts RENAMED
@@ -0,0 +1,12 @@
   
   
   
   
   
   
   
   
   
   
   
   
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+  
3
+ @Pipe({
4
+ name: 'isbn'
5
+ })
6
+ export class IsbnPipe implements PipeTransform {
7
+  
8
+ transform(value: string | null): string {
9
+ if (!value) { return ''; }
10
+ return `${value.substr(0, 3)}-${value.substr(3)}`;
11
+ }
12
+ }
tmp/src/app/book-monkey/{iteration-4/custom-validation → iteration-5/directives}/shared/zoom.directive.ts RENAMED
@@ -0,0 +1,15 @@
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
1
+ import { Directive, HostBinding, HostListener } from '@angular/core';
2
+  
3
+ @Directive({
4
+ selector: '[bmZoom]'
5
+ })
6
+ export class ZoomDirective {
7
+ @HostBinding('class.small') isZoomed: boolean = false;
8
+  
9
+ @HostListener('mouseenter') onMouseEnter() {
10
+ this.isZoomed = true;
11
+ }
12
+ @HostListener('mouseleave') onMouseLeave() {
13
+ this.isZoomed = false;
14
+ }
15
+ }