toast notifications

This commit is contained in:
Jason Kulatunga 2022-10-10 18:03:00 -07:00
parent 2e21176ad7
commit 2401ab66c7
15 changed files with 147 additions and 9 deletions

View File

@ -1,5 +1,6 @@
<div> <div>
<app-header *ngIf="showHeader"></app-header> <app-header *ngIf="showHeader"></app-header>
<app-toast aria-live="polite" aria-atomic="true"></app-toast>
<div class="az-content-wrapper"> <div class="az-content-wrapper">
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>

View File

@ -3,6 +3,7 @@ import {NavigationEnd, Router} from '@angular/router';
import {fromWorker} from 'observable-webworker'; import {fromWorker} from 'observable-webworker';
import {Observable, of} from 'rxjs'; import {Observable, of} from 'rxjs';
import {QueueService} from './workers/queue.service'; import {QueueService} from './workers/queue.service';
import {ToastService} from './services/toast.service';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -16,7 +17,7 @@ export class AppComponent implements OnInit {
showHeader:boolean = false; showHeader:boolean = false;
showFooter:boolean = true; showFooter:boolean = true;
constructor(private router: Router, private queueService: QueueService) {} constructor(private router: Router, private queueService: QueueService, private toastService: ToastService) {}
ngOnInit() { ngOnInit() {

View File

@ -32,6 +32,7 @@ import {ListDiagnosticReportComponent} from './list-generic-resource/list-diagno
import {ListGoalComponent} from './list-generic-resource/list-goal.component'; import {ListGoalComponent} from './list-generic-resource/list-goal.component';
import { ListFallbackResourceComponent } from './list-fallback-resource/list-fallback-resource.component'; import { ListFallbackResourceComponent } from './list-fallback-resource/list-fallback-resource.component';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import { ToastComponent } from './toast/toast.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -70,6 +71,7 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
ResourceListComponent, ResourceListComponent,
ResourceListOutletDirective, ResourceListOutletDirective,
ListFallbackResourceComponent, ListFallbackResourceComponent,
ToastComponent,
], ],
exports: [ exports: [
ComponentsSidebarComponent, ComponentsSidebarComponent,
@ -99,7 +101,8 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
ListDiagnosticReportComponent, ListDiagnosticReportComponent,
ListGoalComponent, ListGoalComponent,
ResourceListComponent, ResourceListComponent,
ResourceListOutletDirective ResourceListOutletDirective,
ToastComponent,
] ]
}) })

View File

@ -0,0 +1,17 @@
<div class="pos-absolute t-10 r-10">
<ngb-toast
*ngFor="let toast of toastService.toasts"
[class]="toast.displayClass"
[autohide]="true"
[delay]="toast.delay || 5000"
(hidden)="toastService.remove(toast)"
>
<ng-template ngbToastHeader>
<h6 class="tx-inverse tx-14 mg-b-0 mg-r-auto">{{toast.title}}</h6>
<small>11 mins ago</small>
</ng-template>
{{ toast.message }}
</ngb-toast>
</div>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ToastComponent } from './toast.component';
describe('ToastComponent', () => {
let component: ToastComponent;
let fixture: ComponentFixture<ToastComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ToastComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(ToastComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import {Component, OnInit, TemplateRef} from '@angular/core';
import {ToastService} from '../../services/toast.service';
@Component({
selector: 'app-toast',
templateUrl: './toast.component.html',
styleUrls: ['./toast.component.scss']
})
export class ToastComponent implements OnInit {
constructor(public toastService: ToastService) {}
ngOnInit(): void {
}
}

View File

@ -0,0 +1,11 @@
export enum ToastType {
Error = "error",
Info = "info"
}
export class ToastNotification {
title?: string
message: string
type: ToastType = ToastType.Info
displayClass: string = 'demo-static-toast'
}

View File

@ -1,7 +1,9 @@
import { Component, OnInit } from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {User} from '../../../lib/models/fasten/user'; import {User} from '../../../lib/models/fasten/user';
import {FastenDbService} from '../../services/fasten-db.service'; import {FastenDbService} from '../../services/fasten-db.service';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {ToastService} from '../../services/toast.service';
import {ToastNotification, ToastType} from '../../models/fasten/toast';
@Component({ @Component({
selector: 'app-auth-signin', selector: 'app-auth-signin',
@ -13,7 +15,7 @@ export class AuthSigninComponent implements OnInit {
existingUser: User = new User() existingUser: User = new User()
errorMsg: string = "" errorMsg: string = ""
constructor(private fastenDb: FastenDbService, private router: Router) { } constructor(private fastenDb: FastenDbService, private router: Router, private toastService: ToastService) { }
ngOnInit(): void { ngOnInit(): void {
} }
@ -29,6 +31,10 @@ export class AuthSigninComponent implements OnInit {
} else{ } else{
this.errorMsg = "an unknown error occurred during sign-in" this.errorMsg = "an unknown error occurred during sign-in"
} }
const toastNotificaiton = new ToastNotification()
toastNotificaiton.type = ToastType.Error
toastNotificaiton.message = this.errorMsg
this.toastService.show(toastNotificaiton)
}) })
} }

View File

@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core';
import {FastenDbService} from '../../services/fasten-db.service'; import {FastenDbService} from '../../services/fasten-db.service';
import {User} from '../../../lib/models/fasten/user'; import {User} from '../../../lib/models/fasten/user';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {ToastNotification, ToastType} from '../../models/fasten/toast';
import {ToastService} from '../../services/toast.service';
@Component({ @Component({
selector: 'app-auth-signup', selector: 'app-auth-signup',
@ -16,7 +18,8 @@ export class AuthSignupComponent implements OnInit {
constructor( constructor(
// private fastenApi: FastenApiService, // private fastenApi: FastenApiService,
private fastenDb: FastenDbService, private fastenDb: FastenDbService,
private router: Router private router: Router,
private toastService: ToastService
) { } ) { }
ngOnInit(): void { ngOnInit(): void {
@ -40,6 +43,11 @@ export class AuthSignupComponent implements OnInit {
} else { } else {
this.errorMsg = "an unknown error occurred during sign-up" this.errorMsg = "an unknown error occurred during sign-up"
} }
const toastNotificaiton = new ToastNotification()
toastNotificaiton.type = ToastType.Error
toastNotificaiton.message = this.errorMsg
this.toastService.show(toastNotificaiton)
}) })
} }

View File

@ -23,9 +23,9 @@
<div *ngFor="let sourceInfo of connectedSourceList" class="col-sm-3 mg-b-20 px-3"> <div *ngFor="let sourceInfo of connectedSourceList" class="col-sm-3 mg-b-20 px-3">
<div class="card h-100 d-flex align-items-center justify-content-center p-3 rounded-0 cursor-pointer"> <div class="card h-100 d-flex align-items-center justify-content-center p-3 rounded-0 cursor-pointer">
<div (click)="openModal(contentModalRef, sourceInfo)" class="card-body"> <div (click)="openModal(contentModalRef, sourceInfo)" class="card-body">
<img [src]="'assets/sources/'+sourceInfo.metadata['source_type']+'.png'" alt="client" class="img-fluid"> <img [src]="'assets/sources/'+sourceInfo?.metadata['source_type']+'.png'" alt="client" class="img-fluid">
<div *ngIf="status[sourceInfo.source['source_type']]" class="progress"> <div *ngIf="status[sourceInfo.source?.source_type]" class="progress">
<div [style.width]="status[sourceInfo.source['source_type']] == 'authorize' ? '33%' : '66%'" class="bg-indigo progress-bar progress-bar-striped progress-bar-animated" role="progressbar"></div> <div [style.width]="status[sourceInfo?.source?.source_type] == 'authorize' ? '33%' : '66%'" class="bg-indigo progress-bar progress-bar-striped progress-bar-animated" role="progressbar"></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -67,8 +67,11 @@ export class FastenDbService extends PouchdbRepository {
} }
public async Logout(): Promise<any> { public async Logout(): Promise<any> {
localStorage.removeItem("current_user")
let remotePouchDb = new PouchDB(this.getRemoteUserDb(localStorage.getItem("current_user")), {skip_setup: true});
await remotePouchDb.logOut()
await this.Close() await this.Close()
localStorage.removeItem("current_user")
} }
public async IsAuthenticated(): Promise<boolean> { public async IsAuthenticated(): Promise<boolean> {
if(!this.localPouchDb){ if(!this.localPouchDb){

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ToastService } from './toast.service';
describe('ToastService', () => {
let service: ToastService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ToastService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,31 @@
import {Injectable} from '@angular/core';
import {ToastNotification, ToastType} from '../models/fasten/toast';
@Injectable({
providedIn: 'root'
})
export class ToastService {
toasts: ToastNotification[] = [];
constructor() { }
show(toastNotification: ToastNotification) {
if(!toastNotification.title){
toastNotification.title = toastNotification.type == ToastType.Error ? "Error" : "Notification"
}
if(toastNotification.type == ToastType.Error){
toastNotification.displayClass += ' bg-danger text-light'
}
this.toasts.push(toastNotification);
}
remove(toast) {
this.toasts = this.toasts.filter(t => t !== toast);
}
clear() {
this.toasts.splice(0, this.toasts.length);
}
}

View File

@ -64,3 +64,6 @@ import 'zone.js/dist/zone'; // Included with Angular CLI.
//required for PouchDB //required for PouchDB
(window as any).global = window; (window as any).global = window;
// required for toast
import '@angular/localize/init';