Adder Global Loading spiner for api calls
This commit is contained in:
parent
1d53333667
commit
c1250b7649
@ -1,7 +1,8 @@
|
|||||||
<main>
|
<main>
|
||||||
<app-contact-sidebar></app-contact-sidebar>
|
<app-spinner></app-spinner>
|
||||||
<div class="main-content">
|
<app-contact-sidebar></app-contact-sidebar>
|
||||||
<app-navbar></app-navbar>
|
<div class="main-content">
|
||||||
<router-outlet></router-outlet>
|
<app-navbar></app-navbar>
|
||||||
</div>
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { LoaderService } from './services/loader.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -6,5 +7,5 @@ import { Component } from '@angular/core';
|
|||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'my-portfolio';
|
constructor(public loaderSvc: LoaderService) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { ContactSidebarComponent } from './contact-sidebar/contact-sidebar.component';
|
import { ContactSidebarComponent } from './contact-sidebar/contact-sidebar.component';
|
||||||
@ -11,12 +11,13 @@ import { ProjectsComponent } from './projects/projects.component';
|
|||||||
import { BlogComponent } from './blog/blog.component';
|
import { BlogComponent } from './blog/blog.component';
|
||||||
import { ContactComponent } from './contact/contact.component';
|
import { ContactComponent } from './contact/contact.component';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AuthInterceptor } from './http-interceptors/auth.interceptor';
|
|
||||||
import { httpInterceptorProviders } from './http-interceptors';
|
import { httpInterceptorProviders } from './http-interceptors';
|
||||||
|
import { SpinnerComponent } from './spinner/spinner.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
SpinnerComponent,
|
||||||
ContactSidebarComponent,
|
ContactSidebarComponent,
|
||||||
NavbarComponent,
|
NavbarComponent,
|
||||||
AboutComponent,
|
AboutComponent,
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { HTTP_INTERCEPTORS } from "@angular/common/http";
|
import { HTTP_INTERCEPTORS } from "@angular/common/http";
|
||||||
|
|
||||||
import { AuthInterceptor } from "./auth.interceptor";
|
import { AuthInterceptor } from "./auth.interceptor";
|
||||||
|
import { LoadingInterceptor } from "./loading.interceptor";
|
||||||
|
|
||||||
export const httpInterceptorProviders = [
|
export const httpInterceptorProviders = [
|
||||||
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true}
|
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
|
||||||
|
{provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true}
|
||||||
]
|
]
|
||||||
27
src/app/http-interceptors/loading.interceptor.ts
Normal file
27
src/app/http-interceptors/loading.interceptor.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
|
||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Observable, finalize } from "rxjs";
|
||||||
|
import { LoaderService } from "../services/loader.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LoadingInterceptor implements HttpInterceptor {
|
||||||
|
|
||||||
|
private totalRequests: number = 0;
|
||||||
|
|
||||||
|
constructor(private loadingSvc: LoaderService) { }
|
||||||
|
|
||||||
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
this.totalRequests++;
|
||||||
|
this.loadingSvc.setLoading(true);
|
||||||
|
return next.handle(req).pipe(
|
||||||
|
finalize(
|
||||||
|
() => {
|
||||||
|
this.totalRequests--;
|
||||||
|
if (this.totalRequests == 0) {
|
||||||
|
this.loadingSvc.setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/services/loader.service.spec.ts
Normal file
16
src/app/services/loader.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoaderService } from './loader.service';
|
||||||
|
|
||||||
|
describe('LoaderService', () => {
|
||||||
|
let service: LoaderService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(LoaderService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
16
src/app/services/loader.service.ts
Normal file
16
src/app/services/loader.service.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class LoaderService {
|
||||||
|
private loading: boolean = false;
|
||||||
|
|
||||||
|
setLoading(loading: boolean){
|
||||||
|
this.loading = loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoading(): boolean{
|
||||||
|
return this.loading;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/app/spinner/spinner.component.html
Normal file
3
src/app/spinner/spinner.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div *ngIf="this.loader.getLoading()" class="cssload-container">
|
||||||
|
<div class="cssload-speeding-wheel"></div>
|
||||||
|
</div>
|
||||||
65
src/app/spinner/spinner.component.scss
Normal file
65
src/app/spinner/spinner.component.scss
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
.cssload-container {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cssload-speeding-wheel {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 48%;
|
||||||
|
top: 40%;
|
||||||
|
width: 63px;
|
||||||
|
height: 63px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 4px solid hsl(45, 54%, 58%);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-left-color: transparent;
|
||||||
|
border-right-color: transparent;
|
||||||
|
animation: cssload-spin 500ms infinite linear;
|
||||||
|
-o-animation: cssload-spin 500ms infinite linear;
|
||||||
|
-ms-animation: cssload-spin 500ms infinite linear;
|
||||||
|
-webkit-animation: cssload-spin 500ms infinite linear;
|
||||||
|
-moz-animation: cssload-spin 500ms infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes cssload-spin {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-o-keyframes cssload-spin {
|
||||||
|
100% {
|
||||||
|
-o-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-ms-keyframes cssload-spin {
|
||||||
|
100% {
|
||||||
|
-ms-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes cssload-spin {
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes cssload-spin {
|
||||||
|
100% {
|
||||||
|
-moz-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/app/spinner/spinner.component.spec.ts
Normal file
23
src/app/spinner/spinner.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SpinnerComponent } from './spinner.component';
|
||||||
|
|
||||||
|
describe('SpinnerComponent', () => {
|
||||||
|
let component: SpinnerComponent;
|
||||||
|
let fixture: ComponentFixture<SpinnerComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [SpinnerComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(SpinnerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
14
src/app/spinner/spinner.component.ts
Normal file
14
src/app/spinner/spinner.component.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Component, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { LoaderService } from '../services/loader.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-spinner',
|
||||||
|
templateUrl: './spinner.component.html',
|
||||||
|
styleUrl: './spinner.component.scss',
|
||||||
|
encapsulation: ViewEncapsulation.ShadowDom
|
||||||
|
})
|
||||||
|
export class SpinnerComponent {
|
||||||
|
|
||||||
|
constructor(public loader: LoaderService) {
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user