Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: TTA-193 add service and interceptor for spinner loading
  • Loading branch information
Andres Cabrera authored and Andres Cabrera committed Oct 6, 2022
commit 3ff389baed3219490996779145eaa196b989c38d
24 changes: 22 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
import { NgxMaskModule, IConfig } from 'ngx-mask';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ToastrModule } from 'ngx-toastr';
import { OverlayRef, ToastrModule } from 'ngx-toastr';
import { CommonModule, DatePipe } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component } from '@angular/core';
import { NgModule, Component, Injectable } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { DataTablesModule } from 'angular-datatables';
import { ComponentPortal } from '@angular/cdk/portal';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { MatMomentDateModule } from '@angular/material-moment-adapter';
import { NgxPaginationModule } from 'ngx-pagination';
import { AutocompleteLibModule } from 'angular-ng-autocomplete';
import { CalendarModule, DateAdapter } from 'angular-calendar';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
import { Observable, Subscription } from 'rxjs';
import { OverlayModule } from '@angular/cdk/overlay';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
Expand Down Expand Up @@ -95,7 +100,12 @@ import { SearchUserComponent } from './modules/shared/components/search-user/sea
import { TimeRangeCustomComponent } from './modules/reports/components/time-range-custom/time-range-custom.component';
import { TimeRangeHeaderComponent } from './modules/reports/components/time-range-custom/time-range-header/time-range-header.component';
import { TimeRangeOptionsComponent } from './modules/reports/components/time-range-custom/time-range-options/time-range-options.component';
<<<<<<< HEAD
import { PageLoaderComponent } from './page-loader/page-loader.component';
=======
import { SpinnerOverlayComponent } from './modules/shared/components/spinner-overlay/spinner-overlay.component';
import { SpinnerInterceptor } from './modules/shared/interceptors/spinner.interceptor';
>>>>>>> d58b5ef (feat: TTA-193 add service and interceptor for spinner loading)

const maskConfig: Partial<IConfig> = {
validation: false,
Expand Down Expand Up @@ -155,7 +165,11 @@ const maskConfig: Partial<IConfig> = {
TimeRangeCustomComponent,
TimeRangeHeaderComponent,
TimeRangeOptionsComponent,
<<<<<<< HEAD
PageLoaderComponent,
=======
SpinnerOverlayComponent,
>>>>>>> d58b5ef (feat: TTA-193 add service and interceptor for spinner loading)
],
imports: [
NgxMaskModule.forRoot(maskConfig),
Expand All @@ -174,6 +188,7 @@ const maskConfig: Partial<IConfig> = {
DataTablesModule,
AutocompleteLibModule,
NgxMaterialTimepickerModule,
MatProgressSpinnerModule,
UiSwitchModule,
DragDropModule,
MatIconModule,
Expand Down Expand Up @@ -208,6 +223,11 @@ const maskConfig: Partial<IConfig> = {
useClass: InjectTokenInterceptor,
multi: true,
},
{
provide: HTTP_INTERCEPTORS,
useClass: SpinnerInterceptor,
multi: true,
},
DatePipe,
CookieService,
{provide: Window, useValue: window}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mat-spinner diameter="80" color="accent"></mat-spinner>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SpinnerOverlayComponent } from './spinner-overlay.component';

describe('SpinnerOverlayComponent', () => {
let component: SpinnerOverlayComponent;
let fixture: ComponentFixture<SpinnerOverlayComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SpinnerOverlayComponent ]
})
.compileComponents();

fixture = TestBed.createComponent(SpinnerOverlayComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from '@angular/core';

@Component({
selector: 'app-spinner-overlay',
templateUrl: './spinner-overlay.component.html',
styleUrls: ['./spinner-overlay.component.scss'],
})

export class SpinnerOverlayComponent {
constructor() {}
}
16 changes: 16 additions & 0 deletions src/app/modules/shared/interceptors/spinner.interceptor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { SpinnerInterceptor } from './spinner.interceptor';

describe('SpinnerInterceptorService', () => {
let service: SpinnerInterceptor;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(SpinnerInterceptor);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
25 changes: 25 additions & 0 deletions src/app/modules/shared/interceptors/spinner.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { SpinnerOverlayService } from '../services/spinner-overlay.service';

@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {
constructor(private readonly spinnerOverlayService: SpinnerOverlayService) {}

intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const spinnerSubscription: Subscription = this.spinnerOverlayService.spinner$.subscribe();
return next
.handle(req)
.pipe(finalize(() => spinnerSubscription.unsubscribe()));
}
}
16 changes: 16 additions & 0 deletions src/app/modules/shared/services/spinner-overlay.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { SpinnerOverlayService } from './spinner-overlay.service';

describe('SpinnerOverlayService', () => {
let service: SpinnerOverlayService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(SpinnerOverlayService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
43 changes: 43 additions & 0 deletions src/app/modules/shared/services/spinner-overlay.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { Injectable } from '@angular/core';
import { defer, NEVER } from 'rxjs';
import { finalize, share } from 'rxjs/operators';
import { SpinnerOverlayComponent } from './../components/spinner-overlay/spinner-overlay.component';

@Injectable({
providedIn: 'root',
})
export class SpinnerOverlayService {
private overlayRef: OverlayRef = undefined;

constructor(private readonly overlay: Overlay) {}

public readonly spinner$ = defer(() => {
this.show();
return NEVER.pipe(
finalize(() => {
this.hide();
})
);
}).pipe(share());

private show(): void {
Promise.resolve(null).then(() => {
this.overlayRef = this.overlay.create({
positionStrategy: this.overlay
.position()
.global()
.centerHorizontally()
.centerVertically(),
hasBackdrop: true,
});
this.overlayRef.attach(new ComponentPortal(SpinnerOverlayComponent));
});
}

private hide(): void {
this.overlayRef.detach();
this.overlayRef = undefined;
}
}