feat(employees): Implemented loader inside employees-list when pagination/filtering. (TV-597)

Squashed commit of the following:

commit 9e41609f515909fac8618f8cae9ce29409e62748
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Thu Sep 16 07:36:21 2021 +0200

    Removed old classes

commit 7be9f46dcd08be3cdec5e92bb237ad8fa6d1c373
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Sep 15 14:23:53 2021 +0200

    Added new loader component and implmented loader inside employees-list
This commit is contained in:
Erik Tiekstra
2021-09-16 10:09:14 +02:00
parent 3bfb8d8be1
commit bc8b09d0dc
17 changed files with 99 additions and 30 deletions

View File

@@ -1,4 +1,5 @@
<div class="employees-list">
<msfa-loader *ngIf="employeesLoading" [fullScreen]="true"></msfa-loader>
<digi-table af-variation="secondary">
<table>
<thead>

View File

@@ -1,6 +1,7 @@
@import 'variables/gutters';
.employees-list {
position: relative;
// &__column-head {
// // padding: 0;
// }

View File

@@ -14,6 +14,7 @@ import { Sort } from '@msfa-models/sort.model';
export class EmployeesListComponent {
@Input() employees: EmployeeCompact[];
@Input() paginationMeta: PaginationMeta;
@Input() employeesLoading: boolean;
@Input() sort: Sort<keyof EmployeeCompactResponse>;
@Output() sorted = new EventEmitter<keyof EmployeeCompactResponse>();
@Output() paginated = new EventEmitter<number>();

View File

@@ -1,12 +1,13 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { EmployeesListComponent } from './employees-list.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [EmployeesListComponent],
imports: [CommonModule, RouterModule],
imports: [CommonModule, RouterModule, LoaderModule],
exports: [EmployeesListComponent],
})
export class EmployeesListModule {}

View File

@@ -39,6 +39,7 @@
*ngIf="employeesData$ | async as employeesData; else loadingRef"
[employees]="employeesData.data"
[paginationMeta]="employeesData.meta"
[employeesLoading]="employeesLoading$ | async"
[sort]="sort$ | async"
(sorted)="handleEmployeesSort($event)"
(paginated)="setNewPage($event)"

View File

@@ -16,6 +16,7 @@ export class EmployeesComponent {
private _searchValue$ = new BehaviorSubject<string>('');
onlyEmployeesWithoutAuthorization$: Observable<boolean> = this.employeeService.onlyEmployeesWithoutAuthorization$;
employeesData$: Observable<EmployeesData> = this.employeeService.employeesData$;
employeesLoading$: Observable<boolean> = this.employeeService.employeesLoading$;
sort$: Observable<Sort<keyof EmployeeCompactResponse>> = this.employeeService.sort$;
iconType = IconType;

View File

@@ -36,7 +36,5 @@
</msfa-layout>
<ng-template #loadingRef>
<div class="msfa__loading-wrapper msfa__loading-wrapper--full-screen">
<digi-icon-spinner class="msfa__spinner"></digi-icon-spinner>
</div>
<msfa-loader [fullScreen]="true"></msfa-loader>
</ng-template>

View File

@@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { StartComponent } from './start.component';
@NgModule({
@@ -13,6 +14,7 @@ import { StartComponent } from './start.component';
RouterModule.forChild([{ path: '', component: StartComponent }]),
LayoutModule,
DigiNgCardModule,
LoaderModule,
],
})
export class StartModule {}

View File

@@ -19,9 +19,4 @@
<msfa-footer class="msfa__footer"></msfa-footer>
</div>
<div
*ngIf="(userLoading$ | async) || (rolesLoading$ | async)"
class="msfa__loading-wrapper msfa__loading-wrapper--full-screen"
>
<digi-icon-spinner class="msfa__spinner"></digi-icon-spinner>
</div>
<msfa-loader *ngIf="(userLoading$ | async) || (rolesLoading$ | async)" [fullScreen]="true"></msfa-loader>

View File

@@ -4,6 +4,7 @@ import { HttpClient } from '@angular/common/http';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { MarkdownModule } from 'ngx-markdown';
import { LoaderModule } from '../loader/loader.module';
import { FooterModule } from './components/footer/footer.module';
import { NavigationModule } from './components/navigation/navigation.module';
import { SidebarModule } from './components/sidebar/sidebar.module';
@@ -22,6 +23,7 @@ import { LayoutComponent } from './layout.component';
FooterModule,
MarkdownModule.forRoot({ loader: HttpClient }),
DigiNgNavigationBreadcrumbsModule,
LoaderModule,
],
exports: [LayoutComponent],
})

View File

@@ -0,0 +1,3 @@
<div [ngClass]="classes">
<digi-icon-spinner class="loader__spinner"></digi-icon-spinner>
</div>

View File

@@ -0,0 +1,22 @@
@import 'mixins/backdrop';
@keyframes spinning {
to {
transform: rotate(360deg);
}
}
.loader {
display: flex;
align-items: center;
justify-content: center;
&--full-screen {
@include msfa__backdrop(1000);
}
&__spinner {
display: inline-flex;
animation: spinning 1s linear infinite;
}
}

View File

@@ -0,0 +1,26 @@
/* tslint:disable:no-unused-variable */
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LoaderComponent } from './loader.component';
describe('LoaderComponent', () => {
let component: LoaderComponent;
let fixture: ComponentFixture<LoaderComponent>;
beforeEach(async(() => {
void TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [LoaderComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoaderComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,19 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'msfa-loader',
templateUrl: './loader.component.html',
styleUrls: ['./loader.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoaderComponent {
private readonly _defaultClass = 'loader';
@Input() fullScreen = false;
get classes(): string {
if (this.fullScreen) {
return `${this._defaultClass} ${this._defaultClass}--full-screen`;
}
return this._defaultClass;
}
}

View File

@@ -0,0 +1,12 @@
import { DigiNgDialogModule } from '@af/digi-ng/_dialog/dialog';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { LoaderComponent } from './loader.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [LoaderComponent],
imports: [CommonModule, DigiNgDialogModule],
exports: [LoaderComponent],
})
export class LoaderModule {}

View File

@@ -44,6 +44,8 @@ export class EmployeeService extends UnsubscribeDirective {
public lastDeletedEmployee$: Observable<Employee> = this._lastDeletedEmployee$.asObservable();
private _employeeToDelete$ = new BehaviorSubject<Employee>(null);
public employeeToDelete$: Observable<Employee> = this._employeeToDelete$.asObservable();
private _employeesLoading$ = new BehaviorSubject<boolean>(false);
public employeesLoading$: Observable<boolean> = this._employeesLoading$.asObservable();
constructor(private httpClient: HttpClient, private errorService: ErrorService) {
super();
@@ -110,11 +112,13 @@ export class EmployeeService extends UnsubscribeDirective {
if (onlyEmployeesWithoutAuthorization) {
params.onlyEmployeesWithoutAuthorization = onlyEmployeesWithoutAuthorization?.toString();
}
this._employeesLoading$.next(true);
return this.httpClient
.get<EmployeesDataResponse>(this._apiBaseUrl, { params })
.pipe(
map(({ data, meta }) => {
this._employeesLoading$.next(false);
return { data: data.map(employee => mapResponseToEmployeeCompact(employee)), meta };
})
);

View File

@@ -4,12 +4,6 @@
@import 'mixins/icon';
@import 'mixins/link';
@keyframes spinning {
to {
transform: rotate(360deg);
}
}
* {
font-family: var(--digi--typography--font-family);
box-sizing: border-box;
@@ -74,20 +68,6 @@ dl {
@include msfa__backdrop;
}
&__loading-wrapper {
display: flex;
align-items: center;
justify-content: center;
&--full-screen {
@include msfa__backdrop(1000);
}
}
&__spinner {
display: inline-flex;
animation: spinning 1s linear infinite;
}
&__digi-icon {
display: inline-flex;
}