diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 01948e4..ae184d6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,16 +1,16 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from "@angular/forms"; +import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { routing } from './app.routing'; -import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http"; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { UserService } from './service/user.service'; import { EpisodeListComponent } from './episode-list/episode-list.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { EpisodeDetailsComponent } from './episode-details/episode-details.component'; import { LayoutModule } from '@angular/cdk/layout'; -import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatIconModule, MatListModule } from '@angular/material'; +import { MatToolbarModule, MatButtonModule, MatSidenavModule, MatIconModule, MatListModule, MatDialogModule } from '@angular/material'; import { UiModule } from './ui/ui.module'; import { FilterPipe } from './pipes/filter.pipe'; import { ExportComponent } from './export/export.component'; @@ -31,7 +31,8 @@ import { PostEditComponent } from './post-edit/post-edit.component'; import { PostComponent } from './post/post.component'; import { SidenavComponent } from './sidenav/sidenav.component'; import { LinkifyWithTextPipe } from './pipes/linkifyWithText.pipe'; -import {SafeResourceUrlPipe} from "./pipes/safeResourceUrl.pipe"; +import { SafeResourceUrlPipe } from './pipes/safeResourceUrl.pipe'; +import { ConfirmationDialogComponent } from './shared/confirmation-dialog/confirmation-dialog.component'; @NgModule({ @@ -56,7 +57,8 @@ import {SafeResourceUrlPipe} from "./pipes/safeResourceUrl.pipe"; PostDetailsComponent, PostEditComponent, PostComponent, - SidenavComponent + SidenavComponent, + ConfirmationDialogComponent ], imports: [ BrowserModule, @@ -70,9 +72,16 @@ import {SafeResourceUrlPipe} from "./pipes/safeResourceUrl.pipe"; MatSidenavModule, MatIconModule, MatListModule, + MatDialogModule, UiModule ], - providers: [ { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }, UserService], + entryComponents: [ + ConfirmationDialogComponent + ], + providers: [ + { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }, + UserService + ], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/app/episode-details/episode-details.component.html b/src/app/episode-details/episode-details.component.html index b19f85f..1244f74 100644 --- a/src/app/episode-details/episode-details.component.html +++ b/src/app/episode-details/episode-details.component.html @@ -6,7 +6,7 @@
- Current: {{ now | date:'hh:mm:ss EEEE dd LLL' }} + Current: {{ now$ | async | date:'hh:mm:ss EEEE dd LLL' }}
@@ -97,4 +97,4 @@

{{episode.name}}

- \ No newline at end of file + diff --git a/src/app/episode-details/episode-details.component.ts b/src/app/episode-details/episode-details.component.ts index 4e8686a..8ca1aaa 100644 --- a/src/app/episode-details/episode-details.component.ts +++ b/src/app/episode-details/episode-details.component.ts @@ -1,11 +1,12 @@ import { Component, OnInit, Input } from '@angular/core'; -import { EpisodeService } from '../service/episode.service'; -import { Episode } from '../model/episode'; import { Location } from '@angular/common'; import { ActivatedRoute, Router, NavigationEnd } from '@angular/router'; import { FormBuilder, Validators, FormGroup } from '@angular/forms'; +import { map, share } from 'rxjs/operators'; +import { interval } from 'rxjs'; +import { EpisodeService } from '../service/episode.service'; +import { Episode } from '../model/episode'; import { Theme } from '../model/theme'; -import { filter } from 'rxjs/operators'; import { environment } from '../../environments/environment'; import { User } from '../model/user'; import { LoggedUserService } from '../service/logged-user.service'; @@ -17,24 +18,20 @@ import { LoggedUserService } from '../service/logged-user.service'; }) export class EpisodeDetailsComponent implements OnInit { - public now: Date = new Date(); episode: Episode; addForm: FormGroup; currentUser: User; - editableTheme: Theme - + editableTheme: Theme; updateForm: FormGroup; + now$ = interval(1000).pipe(map(x => new Date()), share()); + constructor(private formBuilder: FormBuilder, - private router: Router, - private route: ActivatedRoute, + private router: Router, + private route: ActivatedRoute, private episodeService: EpisodeService, - private sessionUserService: LoggedUserService, - private location: Location) { - setInterval(() => { - this.now = new Date(); - }, 1); - } + private sessionUserService: LoggedUserService, + private location: Location) { } ngOnInit() { this.addForm = this.formBuilder.group({ diff --git a/src/app/episode-list/episode-list.component.ts b/src/app/episode-list/episode-list.component.ts index 63a60a3..20ff0c9 100644 --- a/src/app/episode-list/episode-list.component.ts +++ b/src/app/episode-list/episode-list.component.ts @@ -6,6 +6,9 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Location } from '@angular/common'; import { User } from '../model/user'; import { LoggedUserService } from '../service/logged-user.service'; +import { ConfirmationDialogComponent } from '../shared/confirmation-dialog/confirmation-dialog.component'; +import { filter, switchMapTo, take } from 'rxjs/operators'; +import { MatDialog } from '@angular/material'; @Component({ selector: 'app-episode-list', @@ -17,12 +20,13 @@ export class EpisodeListComponent implements OnInit { episodes: Episode[]; selectedEpisode: Episode; addForm: FormGroup; - currentUser: User - added: boolean - error: Object + currentUser: User; + added: boolean; + error: Object; - constructor(private formBuilder: FormBuilder, - private router: Router, + constructor(private formBuilder: FormBuilder, + private router: Router, + private dialog: MatDialog, private episodeService: EpisodeService, private sessionUserService: LoggedUserService) { } @@ -34,17 +38,17 @@ export class EpisodeListComponent implements OnInit { this.currentUser = this.sessionUserService.getSessionUser(); this.episodeService.getAllEpisodes() - .subscribe(data => this.episodes = data) + .subscribe(data => this.episodes = data); } - showDetails(episode: Episode){ + showDetails(episode: Episode) { this.router.navigate([`episode-details/${episode.id}`]); } onSelect(episode: Episode): void { this.selectedEpisode = episode; this.getAllEpisodes(); - this.showDetails(episode); + this.showDetails(episode); } onSubmit() { @@ -52,10 +56,10 @@ export class EpisodeListComponent implements OnInit { .subscribe(data => { this.addForm.reset(); this.getAllEpisodes(); - this.added = true; - }, + this.added = true; + }, error => { - this.error = error + this.error = error; }); } @@ -63,14 +67,23 @@ export class EpisodeListComponent implements OnInit { this.router.navigate(['add-episode']); } - removeEpisode(episode: Episode){ - this.episodeService.removeEpisode(episode.id).subscribe(data => { + removeEpisode(episode: Episode) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + width: '350px', + data: `Do you confirm the deletion of episode ${episode.name}?` + }); + dialogRef.afterClosed().pipe( + take(1), + filter(Boolean), + switchMapTo(this.episodeService.removeEpisode(episode.id)) + ) + .subscribe(data => { this.getAllEpisodes(); }); } getAllEpisodes(): void { this.episodeService.getAllEpisodes() - .subscribe(data => this.episodes = data) + .subscribe(data => this.episodes = data); } } diff --git a/src/app/shared/confirmation-dialog/confirmation-dialog.component.css b/src/app/shared/confirmation-dialog/confirmation-dialog.component.css new file mode 100644 index 0000000..2261cba --- /dev/null +++ b/src/app/shared/confirmation-dialog/confirmation-dialog.component.css @@ -0,0 +1,3 @@ +.mat-dialog-actions { + justify-content: flex-end; +} diff --git a/src/app/shared/confirmation-dialog/confirmation-dialog.component.html b/src/app/shared/confirmation-dialog/confirmation-dialog.component.html new file mode 100644 index 0000000..4fe3555 --- /dev/null +++ b/src/app/shared/confirmation-dialog/confirmation-dialog.component.html @@ -0,0 +1,7 @@ +
+ {{message}} +
+
+ + +
diff --git a/src/app/shared/confirmation-dialog/confirmation-dialog.component.spec.ts b/src/app/shared/confirmation-dialog/confirmation-dialog.component.spec.ts new file mode 100644 index 0000000..4610829 --- /dev/null +++ b/src/app/shared/confirmation-dialog/confirmation-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConfirmationDialogComponent } from './confirmation-dialog.component'; + +describe('ConfirmationDialogComponent', () => { + let component: ConfirmationDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ConfirmationDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ConfirmationDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/confirmation-dialog/confirmation-dialog.component.ts b/src/app/shared/confirmation-dialog/confirmation-dialog.component.ts new file mode 100644 index 0000000..99391b4 --- /dev/null +++ b/src/app/shared/confirmation-dialog/confirmation-dialog.component.ts @@ -0,0 +1,20 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; + +@Component({ + selector: 'app-confirmation-dialog', + templateUrl: './confirmation-dialog.component.html', + styleUrls: ['./confirmation-dialog.component.css'] +}) +export class ConfirmationDialogComponent implements OnInit { + + constructor(private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public message: string) { } + + ngOnInit() { + } + + onNoClick() { + this.dialogRef.close(false); + } +} diff --git a/src/styles.css b/src/styles.css index 195c191..f38c45d 100644 --- a/src/styles.css +++ b/src/styles.css @@ -15,4 +15,12 @@ body { .comma-list:last-child::after { content: ""; -} \ No newline at end of file +} + +.ng-valid[required], .ng-valid.required { + border-left: 5px solid #42A948; /* green */ +} + +.ng-invalid.ng-touched:not(form) { + border-left: 5px solid #a94442; /* red */ +}