From 286a9a189db0079d4ef15e5f268a8c42e4ceddc6 Mon Sep 17 00:00:00 2001 From: "michele.artini" Date: Fri, 3 Feb 2023 14:55:39 +0100 Subject: [PATCH] spinner --- .../src/app/app.component.html | 7 +++- .../src/app/app.component.ts | 3 +- .../dnet-is-application/src/app/app.module.ts | 21 +++++++--- .../src/app/common/spinner.service.ts | 38 +++++++++++++++++++ frontends/dnet-is-application/src/styles.css | 15 +++++++- 5 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 frontends/dnet-is-application/src/app/common/spinner.service.ts diff --git a/frontends/dnet-is-application/src/app/app.component.html b/frontends/dnet-is-application/src/app/app.component.html index 35186275..2b5ac62f 100644 --- a/frontends/dnet-is-application/src/app/app.component.html +++ b/frontends/dnet-is-application/src/app/app.component.html @@ -1,3 +1,7 @@ +
+ +
+ - \ No newline at end of file + + diff --git a/frontends/dnet-is-application/src/app/app.component.ts b/frontends/dnet-is-application/src/app/app.component.ts index 1a02c86c..d9d78bc2 100644 --- a/frontends/dnet-is-application/src/app/app.component.ts +++ b/frontends/dnet-is-application/src/app/app.component.ts @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; +import { SpinnerService } from './common/spinner.service'; @Component({ selector: 'app-root', @@ -17,7 +18,7 @@ export class AppComponent { shareReplay() ); - constructor(private breakpointObserver: BreakpointObserver) {} + constructor(private breakpointObserver: BreakpointObserver, public spinnerService: SpinnerService) {} } diff --git a/frontends/dnet-is-application/src/app/app.module.ts b/frontends/dnet-is-application/src/app/app.module.ts index 70619647..f881cb21 100644 --- a/frontends/dnet-is-application/src/app/app.module.ts +++ b/frontends/dnet-is-application/src/app/app.module.ts @@ -4,9 +4,9 @@ import { FilterPipe } from './common/filter.pipe'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { InfoComponent } from './info/info.component'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { LayoutModule } from '@angular/cdk/layout'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatButtonModule } from '@angular/material/button'; @@ -32,6 +32,8 @@ import { ContextsComponent, ContextViewerComponent, ContextParamsDialog } from ' import { VocabulariesComponent, VocabularyEditorComponent, VocDialog, VocTermDialog } from './vocabularies/vocabularies.component'; import { DsmSearchComponent, DsmResultsComponent, DsmApiComponent, DsmAddApiDialog, DsmBrowseDialog } from './dsm/dsm.component'; import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { SpinnerHttpInterceptor } from './common/spinner.service'; @NgModule({ declarations: [ @@ -60,11 +62,13 @@ import { MatPaginatorModule } from '@angular/material/paginator'; DsmBrowseDialog ], imports: [ + BrowserModule, + BrowserAnimationsModule, + HttpClientModule, BrowserModule, AppRoutingModule, FormsModule, HttpClientModule, - NoopAnimationsModule, LayoutModule, MatToolbarModule, MatButtonModule, @@ -83,9 +87,14 @@ import { MatPaginatorModule } from '@angular/material/paginator'; MatSortModule, ReactiveFormsModule, MatSnackBarModule, - MatPaginatorModule + MatPaginatorModule, + MatProgressSpinnerModule ], - providers: [], - bootstrap: [AppComponent] + providers: [{ + provide: HTTP_INTERCEPTORS, + useClass: SpinnerHttpInterceptor, + multi: true + }], + bootstrap: [ AppComponent ] }) export class AppModule { } diff --git a/frontends/dnet-is-application/src/app/common/spinner.service.ts b/frontends/dnet-is-application/src/app/common/spinner.service.ts new file mode 100644 index 00000000..1aafe32e --- /dev/null +++ b/frontends/dnet-is-application/src/app/common/spinner.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { Observable } from 'rxjs'; +import { HttpInterceptor, HttpResponse } from '@angular/common/http'; +import { HttpRequest } from '@angular/common/http'; +import { HttpHandler } from '@angular/common/http'; +import { HttpEvent } from '@angular/common/http'; +import { tap } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class SpinnerService { + visibility: BehaviorSubject; + + constructor() { this.visibility = new BehaviorSubject(false); } + + show() { this.visibility.next(true); } + hide() { this.visibility.next(false);} +} + +@Injectable() +export class SpinnerHttpInterceptor implements HttpInterceptor { + + constructor(private spinnerService: SpinnerService) { } + + intercept(req: HttpRequest, next: HttpHandler): Observable> { + + this.spinnerService.show(); + + return next.handle(req) + .pipe(tap((event: HttpEvent) => { + if (event instanceof HttpResponse) { + this.spinnerService.hide(); + } + }, (error) => { + this.spinnerService.hide(); + })); + } +} diff --git a/frontends/dnet-is-application/src/styles.css b/frontends/dnet-is-application/src/styles.css index 734e3273..5076dbb1 100644 --- a/frontends/dnet-is-application/src/styles.css +++ b/frontends/dnet-is-application/src/styles.css @@ -94,4 +94,17 @@ th, td { margin-left: 2em !important; margin-right: 2em !important; font-size: 0.75em !important; -} \ No newline at end of file +} + +.spinner { + position: absolute; + width: 300px; + left: 0; + right: 0; + top: 40%; + margin: auto; + z-index: 10000; +} + +.spinner * { margin: auto; } + \ No newline at end of file