From 32b94503dd60c201685f20c015736ae5fb7012e4 Mon Sep 17 00:00:00 2001 From: Abhay Chawla Date: Tue, 26 Jun 2018 17:01:43 +0530 Subject: [PATCH] feat: add progress bar (#66) Add progress bar for loading data via http requests. Fixes #65 --- src/app/core/core.module.ts | 4 +++ src/app/core/progress-bar.service.spec.ts | 15 ++++++++++ src/app/core/progress-bar.service.ts | 35 +++++++++++++++++++++++ src/app/core/progress.interceptor.ts | 26 +++++++++++++++++ src/app/core/shell/shell.component.html | 1 + src/app/core/shell/shell.component.ts | 8 +++++- 6 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/app/core/progress-bar.service.spec.ts create mode 100644 src/app/core/progress-bar.service.ts create mode 100644 src/app/core/progress.interceptor.ts diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 796674551..158f21544 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -45,6 +45,8 @@ import { AuthenticationGuard } from './authentication/authentication.guard'; import { I18nService } from './i18n.service'; import { HttpService } from './http/http.service'; import { HttpCacheService } from './http/http-cache.service'; +import { ProgressBarService } from './progress-bar.service'; +import { ProgressInterceptor } from './progress.interceptor'; import { ApiPrefixInterceptor } from './http/api-prefix.interceptor'; import { ErrorHandlerInterceptor } from './http/error-handler.interceptor'; import { CacheInterceptor } from './http/cache.interceptor'; @@ -145,6 +147,8 @@ import { BreadcrumbComponent } from './shell/breadcrumb/breadcrumb.component'; AuthenticationGuard, I18nService, HttpCacheService, + ProgressBarService, + ProgressInterceptor, ApiPrefixInterceptor, ErrorHandlerInterceptor, CacheInterceptor, diff --git a/src/app/core/progress-bar.service.spec.ts b/src/app/core/progress-bar.service.spec.ts new file mode 100644 index 000000000..60a2cedfb --- /dev/null +++ b/src/app/core/progress-bar.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { ProgressBarService } from './progress-bar.service'; + +describe('ProgressBarService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ProgressBarService] + }); + }); + + it('should be created', inject([ProgressBarService], (service: ProgressBarService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/core/progress-bar.service.ts b/src/app/core/progress-bar.service.ts new file mode 100644 index 000000000..3644fdda9 --- /dev/null +++ b/src/app/core/progress-bar.service.ts @@ -0,0 +1,35 @@ +import { Injectable, EventEmitter } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class ProgressBarService { + + public updateProgressBar: EventEmitter; + private requestsRunning = 0; + + constructor() { + this.updateProgressBar = new EventEmitter(); + } + + public getRequestsRunning(): number { + return this.requestsRunning; + } + + public increase(): void { + this.requestsRunning++; + if (this.requestsRunning === 1) { + this.updateProgressBar.emit('indeterminate'); + } + } + + public decrease(): void { + if (this.requestsRunning > 0) { + this.requestsRunning--; + if (this.requestsRunning === 0) { + this.updateProgressBar.emit('none'); + } + } + } + +} diff --git a/src/app/core/progress.interceptor.ts b/src/app/core/progress.interceptor.ts new file mode 100644 index 000000000..19fea0c3c --- /dev/null +++ b/src/app/core/progress.interceptor.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; + +import { Observable } from 'rxjs'; +import { tap } from 'rxjs/operators'; + +import { ProgressBarService } from './progress-bar.service'; + +@Injectable() +export class ProgressInterceptor implements HttpInterceptor { + + constructor(private progressBarService: ProgressBarService) { } + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + this.progressBarService.increase(); + return next + .handle(request).pipe( + tap(event => { + if (event instanceof HttpResponse) { + this.progressBarService.decrease(); + } + }) + ); + } + +} diff --git a/src/app/core/shell/shell.component.html b/src/app/core/shell/shell.component.html index 8d750a5de..8f2e2c495 100644 --- a/src/app/core/shell/shell.component.html +++ b/src/app/core/shell/shell.component.html @@ -18,6 +18,7 @@ + diff --git a/src/app/core/shell/shell.component.ts b/src/app/core/shell/shell.component.ts index b67ee69a5..9445c7a78 100644 --- a/src/app/core/shell/shell.component.ts +++ b/src/app/core/shell/shell.component.ts @@ -3,6 +3,7 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { ProgressBarService } from '../progress-bar.service'; @Component({ selector: 'mifosx-shell', @@ -16,10 +17,15 @@ export class ShellComponent implements OnInit { map(result => result.matches) ); sidenavCollapsed = false; + progressBarMode: string; - constructor(private breakpointObserver: BreakpointObserver) { } + constructor(private breakpointObserver: BreakpointObserver, + private progressBarService: ProgressBarService) { } ngOnInit() { + this.progressBarService.updateProgressBar.subscribe((mode: string) => { + this.progressBarMode = mode; + }); } toggleCollapse($event: boolean) {