Moved from tslint to eslint as tslint was depreciated.
Added prettier and also prettied all the typescript files using prettier ESLint is using the AirBnB rules which are the most strict to lint the files.
This commit is contained in:
@ -1,40 +1,45 @@
|
||||
<mat-card>
|
||||
<mat-card-title-group>
|
||||
<mat-card-title>Employee</mat-card-title>
|
||||
<mat-icon matSuffix (click)="item.isStarred = !item.isStarred" class="pointer" [class.gold]="item.isStarred">
|
||||
{{ item.isStarred ? 'star' : 'star_border' }}
|
||||
</mat-icon>
|
||||
<mat-icon
|
||||
matSuffix
|
||||
(click)="item.isStarred = !item.isStarred"
|
||||
class="pointer"
|
||||
[class.gold]="item.isStarred"
|
||||
>
|
||||
{{ item.isStarred ? 'star' : 'star_border' }}
|
||||
</mat-icon>
|
||||
</mat-card-title-group>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<div fxLayout="row">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Code</mat-label>
|
||||
<input matInput placeholder="Code" formControlName="code">
|
||||
<input matInput placeholder="Code" formControlName="code" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput #nameElement placeholder="Name" formControlName="name">
|
||||
<input matInput #nameElement placeholder="Name" formControlName="name" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Designation</mat-label>
|
||||
<input matInput placeholder="Designation" formControlName="designation">
|
||||
<input matInput placeholder="Designation" formControlName="designation" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Salary</mat-label>
|
||||
<input matInput placeholder="Salary" formControlName="salary">
|
||||
<input matInput placeholder="Salary" formControlName="salary" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Points</mat-label>
|
||||
<input matInput placeholder="Points" formControlName="points">
|
||||
<input matInput placeholder="Points" formControlName="points" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row">
|
||||
@ -51,14 +56,26 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput [matDatepicker]="joiningDate" (focus)="joiningDate.open()" placeholder="Joining Date"
|
||||
formControlName="joiningDate" autocomplete="off">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="joiningDate"
|
||||
(focus)="joiningDate.open()"
|
||||
placeholder="Joining Date"
|
||||
formControlName="joiningDate"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="joiningDate"></mat-datepicker-toggle>
|
||||
<mat-datepicker #joiningDate></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngIf="!item.isActive" fxFlex>
|
||||
<input matInput [matDatepicker]="leavingDate" (focus)="leavingDate.open()" placeholder="Leaving Date"
|
||||
formControlName="leavingDate" autocomplete="off">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="leavingDate"
|
||||
(focus)="leavingDate.open()"
|
||||
placeholder="Leaving Date"
|
||||
formControlName="leavingDate"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="leavingDate"></mat-datepicker-toggle>
|
||||
<mat-datepicker #leavingDate></mat-datepicker>
|
||||
</mat-form-field>
|
||||
@ -66,6 +83,8 @@
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button color="primary" (click)="save()">Save</button>
|
||||
<button mat-raised-button color="warn" (click)="confirmDelete()" *ngIf="!!item.id">Delete</button>
|
||||
<button mat-raised-button color="warn" (click)="confirmDelete()" *ngIf="!!item.id">
|
||||
Delete
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {EmployeeDetailComponent} from './employee-detail.component';
|
||||
import { EmployeeDetailComponent } from './employee-detail.component';
|
||||
|
||||
describe('EmployeeDetailComponent', () => {
|
||||
let component: EmployeeDetailComponent;
|
||||
@ -8,9 +8,8 @@ describe('EmployeeDetailComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EmployeeDetailComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [EmployeeDetailComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||
import {FormBuilder, FormGroup} from '@angular/forms';
|
||||
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import * as moment from 'moment';
|
||||
|
||||
import {ToasterService} from '../../core/toaster.service';
|
||||
import {EmployeeService} from '../employee.service';
|
||||
import {Employee} from '../employee';
|
||||
import {CostCentre} from '../../core/cost-centre';
|
||||
import {ConfirmDialogComponent} from '../../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../../core/toaster.service';
|
||||
import { EmployeeService } from '../employee.service';
|
||||
import { Employee } from '../employee';
|
||||
import { CostCentre } from '../../core/cost-centre';
|
||||
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-employee-detail',
|
||||
templateUrl: './employee-detail.component.html',
|
||||
styleUrls: ['./employee-detail.component.css']
|
||||
styleUrls: ['./employee-detail.component.css'],
|
||||
})
|
||||
export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
|
||||
@ -28,7 +28,7 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
private dialog: MatDialog,
|
||||
private fb: FormBuilder,
|
||||
private toaster: ToasterService,
|
||||
private ser: EmployeeService
|
||||
private ser: EmployeeService,
|
||||
) {
|
||||
this.createForm();
|
||||
this.listenToIsActiveChanges();
|
||||
@ -36,7 +36,7 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
|
||||
createForm() {
|
||||
this.form = this.fb.group({
|
||||
code: {value: '', disabled: true},
|
||||
code: { value: '', disabled: true },
|
||||
name: '',
|
||||
designation: '',
|
||||
salary: '',
|
||||
@ -44,16 +44,15 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
isActive: '',
|
||||
costCentre: '',
|
||||
joiningDate: '',
|
||||
leavingDate: ''
|
||||
leavingDate: '',
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.data
|
||||
.subscribe((data: { item: Employee, costCentres: CostCentre[] }) => {
|
||||
this.costCentres = data.costCentres;
|
||||
this.showItem(data.item);
|
||||
});
|
||||
this.route.data.subscribe((data: { item: Employee; costCentres: CostCentre[] }) => {
|
||||
this.costCentres = data.costCentres;
|
||||
this.showItem(data.item);
|
||||
});
|
||||
}
|
||||
|
||||
showItem(item: Employee) {
|
||||
@ -66,8 +65,12 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
points: this.item.points || '',
|
||||
isActive: this.item.isActive,
|
||||
costCentre: this.item.costCentre.id,
|
||||
joiningDate: this.item.joiningDate ? moment(this.item.joiningDate, 'DD-MMM-YYYY').toDate() : '',
|
||||
leavingDate: this.item.isActive ? null : moment(this.item.leavingDate, 'DD-MMM-YYYY').toDate()
|
||||
joiningDate: this.item.joiningDate
|
||||
? moment(this.item.joiningDate, 'DD-MMM-YYYY').toDate()
|
||||
: '',
|
||||
leavingDate: this.item.isActive
|
||||
? null
|
||||
: moment(this.item.leavingDate, 'DD-MMM-YYYY').toDate(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -78,40 +81,37 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
listenToIsActiveChanges(): void {
|
||||
this.form.get('isActive').valueChanges
|
||||
.subscribe(x => this.item.isActive = x);
|
||||
this.form.get('isActive').valueChanges.subscribe((x) => (this.item.isActive = x));
|
||||
}
|
||||
|
||||
save() {
|
||||
this.ser.saveOrUpdate(this.getItem())
|
||||
.subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigateByUrl('/employees');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
}
|
||||
);
|
||||
this.ser.saveOrUpdate(this.getItem()).subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigateByUrl('/employees');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
delete() {
|
||||
this.ser.delete(this.item.id)
|
||||
.subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigateByUrl('/employees');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
}
|
||||
);
|
||||
this.ser.delete(this.item.id).subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigateByUrl('/employees');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
confirmDelete(): void {
|
||||
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
||||
width: '250px',
|
||||
data: {title: 'Delete Employee?', content: 'Are you sure? This cannot be undone.'}
|
||||
data: { title: 'Delete Employee?', content: 'Are you sure? This cannot be undone.' },
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((result: boolean) => {
|
||||
@ -130,7 +130,9 @@ export class EmployeeDetailComponent implements OnInit, AfterViewInit {
|
||||
this.item.isActive = formModel.isActive;
|
||||
this.item.costCentre.id = formModel.costCentre;
|
||||
this.item.joiningDate = moment(formModel.joiningDate).format('DD-MMM-YYYY');
|
||||
this.item.leavingDate = (this.item.isActive) ? null : moment(formModel.leavingDate).format('DD-MMM-YYYY');
|
||||
this.item.leavingDate = this.item.isActive
|
||||
? null
|
||||
: moment(formModel.leavingDate).format('DD-MMM-YYYY');
|
||||
return this.item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {EmployeeListResolverService} from './employee-list-resolver.service';
|
||||
import { EmployeeListResolverService } from './employee-list-resolver.service';
|
||||
|
||||
describe('EmployeeListResolverService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [EmployeeListResolverService]
|
||||
providers: [EmployeeListResolverService],
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([EmployeeListResolverService], (service: EmployeeListResolverService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
it('should be created', inject(
|
||||
[EmployeeListResolverService],
|
||||
(service: EmployeeListResolverService) => {
|
||||
expect(service).toBeTruthy();
|
||||
},
|
||||
));
|
||||
});
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
|
||||
import {Employee} from './employee';
|
||||
import {Observable} from 'rxjs/internal/Observable';
|
||||
import {EmployeeService} from './employee.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Employee } from './employee';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { EmployeeService } from './employee.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EmployeeListResolver implements Resolve<Employee[]> {
|
||||
|
||||
constructor(private ser: EmployeeService) {
|
||||
}
|
||||
constructor(private ser: EmployeeService) {}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Employee[]> {
|
||||
return this.ser.list();
|
||||
|
||||
@ -5,15 +5,17 @@ import { map, tap } from 'rxjs/operators';
|
||||
import { merge, Observable, of as observableOf } from 'rxjs';
|
||||
import { Employee } from '../employee';
|
||||
|
||||
|
||||
export class EmployeeListDataSource extends DataSource<Employee> {
|
||||
private filterValue: string;
|
||||
|
||||
constructor(private paginator: MatPaginator, private sort: MatSort, private filter: Observable<string>, public data: Employee[]) {
|
||||
constructor(
|
||||
private paginator: MatPaginator,
|
||||
private sort: MatSort,
|
||||
private filter: Observable<string>,
|
||||
public data: Employee[],
|
||||
) {
|
||||
super();
|
||||
this.filter = filter.pipe(
|
||||
tap(x => this.filterValue = x)
|
||||
);
|
||||
this.filter = filter.pipe(tap((x) => (this.filterValue = x)));
|
||||
}
|
||||
|
||||
connect(): Observable<Employee[]> {
|
||||
@ -21,34 +23,41 @@ export class EmployeeListDataSource extends DataSource<Employee> {
|
||||
observableOf(this.data),
|
||||
this.filter,
|
||||
this.paginator.page,
|
||||
this.sort.sortChange
|
||||
this.sort.sortChange,
|
||||
];
|
||||
|
||||
return merge(...dataMutations).pipe(
|
||||
map((x: any) => {
|
||||
return this.getFilteredData([...this.data]);
|
||||
}),
|
||||
tap((x: Employee[]) => this.paginator.length = x.length)
|
||||
).pipe(
|
||||
map((x: any) => {
|
||||
return this.getPagedData(this.getSortedData(x));
|
||||
})
|
||||
);
|
||||
return merge(...dataMutations)
|
||||
.pipe(
|
||||
map((x: any) => {
|
||||
return this.getFilteredData([...this.data]);
|
||||
}),
|
||||
tap((x: Employee[]) => (this.paginator.length = x.length)),
|
||||
)
|
||||
.pipe(
|
||||
map((x: any) => {
|
||||
return this.getPagedData(this.getSortedData(x));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
}
|
||||
disconnect() {}
|
||||
|
||||
private getFilteredData(data: Employee[]): Employee[] {
|
||||
const filter = (this.filterValue === undefined) ? '' : this.filterValue;
|
||||
const filter = this.filterValue === undefined ? '' : this.filterValue;
|
||||
return filter.split(' ').reduce((p: Employee[], c: string) => {
|
||||
return p.filter(x => {
|
||||
const employeeString = (
|
||||
x.code + ' ' + x.name + ' ' + x.designation + ' ' + x.costCentre + (x.isActive ? ' active' : ' inactive')
|
||||
).toLowerCase();
|
||||
return employeeString.indexOf(c) !== -1;
|
||||
}
|
||||
);
|
||||
return p.filter((x) => {
|
||||
const employeeString = (
|
||||
x.code +
|
||||
' ' +
|
||||
x.name +
|
||||
' ' +
|
||||
x.designation +
|
||||
' ' +
|
||||
x.costCentre +
|
||||
(x.isActive ? ' active' : ' inactive')
|
||||
).toLowerCase();
|
||||
return employeeString.indexOf(c) !== -1;
|
||||
});
|
||||
}, Object.assign([], data));
|
||||
}
|
||||
|
||||
|
||||
@ -11,19 +11,30 @@
|
||||
</mat-card-title-group>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px"
|
||||
fxLayoutAlign="space-around start">
|
||||
<div
|
||||
fxLayout="row"
|
||||
fxLayout.lt-md="column"
|
||||
fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px"
|
||||
fxLayoutAlign="space-around start"
|
||||
>
|
||||
<mat-form-field fxFlex>
|
||||
<input type="text" matInput #filterElement placeholder="Filter" formControlName="filter" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
#filterElement
|
||||
placeholder="Filter"
|
||||
formControlName="filter"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
|
||||
|
||||
<!-- Code Column -->
|
||||
<ng-container matColumnDef="code">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Code</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.code}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.code }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
@ -31,9 +42,8 @@
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">
|
||||
<a [routerLink]="['/employees', row.id]">
|
||||
<mat-icon matSuffix *ngIf="row.isStarred" class="gold">star
|
||||
</mat-icon>
|
||||
{{row.name}}
|
||||
<mat-icon matSuffix *ngIf="row.isStarred" class="gold">star </mat-icon>
|
||||
{{ row.name }}
|
||||
</a>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
@ -41,48 +51,50 @@
|
||||
<!-- Designation Column -->
|
||||
<ng-container matColumnDef="designation">
|
||||
<mat-header-cell *matHeaderCellDef>Designation</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.designation}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.designation }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Salary Column -->
|
||||
<ng-container matColumnDef="salary">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Salary</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.salary | currency:'INR'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.salary | currency: 'INR' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Points Column -->
|
||||
<ng-container matColumnDef="points">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Points</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.points | number:'1.2-2'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.points | number: '1.2-2' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Department Column -->
|
||||
<ng-container matColumnDef="department">
|
||||
<mat-header-cell *matHeaderCellDef>Department</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.costCentre}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.costCentre }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- JoiningDate Column -->
|
||||
<ng-container matColumnDef="joiningDate">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Joining On</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.joiningDate}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.joiningDate }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- LeavingDate Column -->
|
||||
<ng-container matColumnDef="leavingDate">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Left On</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.leavingDate}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.leavingDate }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator #paginator
|
||||
[length]="dataSource.data.length"
|
||||
[pageIndex]="0"
|
||||
[pageSize]="50"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]">
|
||||
<mat-paginator
|
||||
#paginator
|
||||
[length]="dataSource.data.length"
|
||||
[pageIndex]="0"
|
||||
[pageSize]="50"
|
||||
[pageSizeOptions]="[25, 50, 100, 250]"
|
||||
>
|
||||
</mat-paginator>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {ComponentFixture, fakeAsync, TestBed} from '@angular/core/testing';
|
||||
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {EmployeeListComponent} from './employee-list.component';
|
||||
import { EmployeeListComponent } from './employee-list.component';
|
||||
|
||||
describe('EmployeeListComponent', () => {
|
||||
let component: EmployeeListComponent;
|
||||
@ -8,9 +8,8 @@ describe('EmployeeListComponent', () => {
|
||||
|
||||
beforeEach(fakeAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EmployeeListComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [EmployeeListComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(EmployeeListComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import {EmployeeListDataSource} from './employee-list-datasource';
|
||||
import {Employee} from '../employee';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {FormBuilder, FormGroup} from '@angular/forms';
|
||||
import {Observable} from 'rxjs';
|
||||
import {debounceTime, distinctUntilChanged, startWith} from 'rxjs/operators';
|
||||
import {ToCsvService} from '../../shared/to-csv.service';
|
||||
import { EmployeeListDataSource } from './employee-list-datasource';
|
||||
import { Employee } from '../employee';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Observable } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, startWith } from 'rxjs/operators';
|
||||
import { ToCsvService } from '../../shared/to-csv.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-employee-list',
|
||||
templateUrl: './employee-list.component.html',
|
||||
styleUrls: ['./employee-list.component.css']
|
||||
styleUrls: ['./employee-list.component.css'],
|
||||
})
|
||||
export class EmployeeListComponent implements OnInit, AfterViewInit {
|
||||
@ViewChild('filterElement', { static: true }) filterElement: ElementRef;
|
||||
@ -24,7 +24,16 @@ export class EmployeeListComponent implements OnInit, AfterViewInit {
|
||||
list: Employee[];
|
||||
|
||||
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||
displayedColumns = ['code', 'name', 'designation', 'salary', 'points', 'department', 'joiningDate', 'leavingDate'];
|
||||
displayedColumns = [
|
||||
'code',
|
||||
'name',
|
||||
'designation',
|
||||
'salary',
|
||||
'points',
|
||||
'department',
|
||||
'joiningDate',
|
||||
'leavingDate',
|
||||
];
|
||||
|
||||
constructor(private route: ActivatedRoute, private fb: FormBuilder, private toCsv: ToCsvService) {
|
||||
this.createForm();
|
||||
@ -33,24 +42,20 @@ export class EmployeeListComponent implements OnInit, AfterViewInit {
|
||||
|
||||
createForm() {
|
||||
this.form = this.fb.group({
|
||||
filter: ''
|
||||
filter: '',
|
||||
});
|
||||
}
|
||||
|
||||
listenToFilterChange() {
|
||||
return this.form.get('filter').valueChanges
|
||||
.pipe(
|
||||
startWith(''),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
return this.form
|
||||
.get('filter')
|
||||
.valueChanges.pipe(startWith(''), debounceTime(150), distinctUntilChanged());
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.data
|
||||
.subscribe((data: { list: Employee[] }) => {
|
||||
this.list = data.list;
|
||||
});
|
||||
this.route.data.subscribe((data: { list: Employee[] }) => {
|
||||
this.list = data.list;
|
||||
});
|
||||
this.dataSource = new EmployeeListDataSource(this.paginator, this.sort, this.filter, this.list);
|
||||
}
|
||||
|
||||
@ -69,10 +74,12 @@ export class EmployeeListComponent implements OnInit, AfterViewInit {
|
||||
Points: 'points',
|
||||
Department: 'department',
|
||||
JoiningDate: 'joiningDate',
|
||||
LeavingDate: 'leavingDate'
|
||||
LeavingDate: 'leavingDate',
|
||||
};
|
||||
|
||||
const csvData = new Blob([this.toCsv.toCsv(headers, this.dataSource.data)], {type: 'text/csv;charset=utf-8;'});
|
||||
const csvData = new Blob([this.toCsv.toCsv(headers, this.dataSource.data)], {
|
||||
type: 'text/csv;charset=utf-8;',
|
||||
});
|
||||
const link = document.createElement('a');
|
||||
link.href = window.URL.createObjectURL(csvData);
|
||||
link.setAttribute('download', 'employees.csv');
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {EmployeeResolverService} from './employee-resolver.service';
|
||||
import { EmployeeResolverService } from './employee-resolver.service';
|
||||
|
||||
describe('EmployeeResolverService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [EmployeeDetailResolverService]
|
||||
providers: [EmployeeDetailResolverService],
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([EmployeeDetailResolverService], (service: EmployeeDetailResolverService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
it('should be created', inject(
|
||||
[EmployeeDetailResolverService],
|
||||
(service: EmployeeDetailResolverService) => {
|
||||
expect(service).toBeTruthy();
|
||||
},
|
||||
));
|
||||
});
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
|
||||
import {EmployeeService} from './employee.service';
|
||||
import {Employee} from './employee';
|
||||
import {Observable} from 'rxjs/internal/Observable';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { EmployeeService } from './employee.service';
|
||||
import { Employee } from './employee';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EmployeeResolver implements Resolve<Employee> {
|
||||
|
||||
constructor(private ser: EmployeeService, private router: Router) {
|
||||
}
|
||||
constructor(private ser: EmployeeService, private router: Router) {}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Employee> {
|
||||
const id = route.paramMap.get('id');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {EmployeeRoutingModule} from './employee-routing.module';
|
||||
import { EmployeeRoutingModule } from './employee-routing.module';
|
||||
|
||||
describe('EmployeeRoutingModule', () => {
|
||||
let employeeRoutingModule: EmployeeRoutingModule;
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import {EmployeeListResolver} from './employee-list-resolver.service';
|
||||
import {EmployeeResolver} from './employee-resolver.service';
|
||||
import {EmployeeDetailComponent} from './employee-detail/employee-detail.component';
|
||||
import {EmployeeListComponent} from './employee-list/employee-list.component';
|
||||
import { EmployeeListResolver } from './employee-list-resolver.service';
|
||||
import { EmployeeResolver } from './employee-resolver.service';
|
||||
import { EmployeeDetailComponent } from './employee-detail/employee-detail.component';
|
||||
import { EmployeeListComponent } from './employee-list/employee-list.component';
|
||||
|
||||
import {AuthGuard} from '../auth/auth-guard.service';
|
||||
import {CostCentreListResolver} from '../cost-centre/cost-centre-list-resolver.service';
|
||||
import { AuthGuard } from '../auth/auth-guard.service';
|
||||
import { CostCentreListResolver } from '../cost-centre/cost-centre-list-resolver.service';
|
||||
|
||||
const employeeRoutes: Routes = [
|
||||
{
|
||||
@ -16,51 +16,41 @@ const employeeRoutes: Routes = [
|
||||
component: EmployeeListComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
permission: 'Employees'
|
||||
permission: 'Employees',
|
||||
},
|
||||
resolve: {
|
||||
list: EmployeeListResolver
|
||||
}
|
||||
list: EmployeeListResolver,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'new',
|
||||
component: EmployeeDetailComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
permission: 'Employees'
|
||||
permission: 'Employees',
|
||||
},
|
||||
resolve: {
|
||||
item: EmployeeResolver,
|
||||
costCentres: CostCentreListResolver
|
||||
}
|
||||
costCentres: CostCentreListResolver,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: EmployeeDetailComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
permission: 'Employees'
|
||||
permission: 'Employees',
|
||||
},
|
||||
resolve: {
|
||||
item: EmployeeResolver,
|
||||
costCentres: CostCentreListResolver
|
||||
}
|
||||
}
|
||||
costCentres: CostCentreListResolver,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild(employeeRoutes)
|
||||
|
||||
],
|
||||
exports: [
|
||||
RouterModule
|
||||
],
|
||||
providers: [
|
||||
EmployeeListResolver,
|
||||
EmployeeResolver
|
||||
]
|
||||
imports: [CommonModule, RouterModule.forChild(employeeRoutes)],
|
||||
exports: [RouterModule],
|
||||
providers: [EmployeeListResolver, EmployeeResolver],
|
||||
})
|
||||
export class EmployeeRoutingModule {
|
||||
}
|
||||
export class EmployeeRoutingModule {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {EmployeeModule} from './employee.module';
|
||||
import { EmployeeModule } from './employee.module';
|
||||
|
||||
describe('EmployeeModule', () => {
|
||||
let employeeModule: EmployeeModule;
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import {EmployeeListComponent} from './employee-list/employee-list.component';
|
||||
import {EmployeeDetailComponent} from './employee-detail/employee-detail.component';
|
||||
import {EmployeeRoutingModule} from './employee-routing.module';
|
||||
import { EmployeeListComponent } from './employee-list/employee-list.component';
|
||||
import { EmployeeDetailComponent } from './employee-detail/employee-detail.component';
|
||||
import { EmployeeRoutingModule } from './employee-routing.module';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatOptionModule} from '@angular/material/core';
|
||||
import {
|
||||
DateAdapter,
|
||||
MAT_DATE_FORMATS,
|
||||
MAT_DATE_LOCALE,
|
||||
MatOptionModule,
|
||||
} from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
@ -17,10 +22,10 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import {CdkTableModule} from '@angular/cdk/table';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
import {FlexLayoutModule} from '@angular/flex-layout';
|
||||
import {MomentDateAdapter} from "@angular/material-moment-adapter";
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MomentDateAdapter } from '@angular/material-moment-adapter';
|
||||
|
||||
export const MY_FORMATS = {
|
||||
parse: {
|
||||
@ -53,16 +58,12 @@ export const MY_FORMATS = {
|
||||
MatSelectModule,
|
||||
MatCheckboxModule,
|
||||
ReactiveFormsModule,
|
||||
EmployeeRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
EmployeeListComponent,
|
||||
EmployeeDetailComponent
|
||||
EmployeeRoutingModule,
|
||||
],
|
||||
declarations: [EmployeeListComponent, EmployeeDetailComponent],
|
||||
providers: [
|
||||
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
|
||||
{provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
|
||||
]
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
|
||||
],
|
||||
})
|
||||
export class EmployeeModule {
|
||||
}
|
||||
export class EmployeeModule {}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {EmployeeService} from './employee.service';
|
||||
import { EmployeeService } from './employee.service';
|
||||
|
||||
describe('EmployeeService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [EmployeeService]
|
||||
providers: [EmployeeService],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,50 +1,52 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Observable} from 'rxjs/internal/Observable';
|
||||
import {catchError} from 'rxjs/operators';
|
||||
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import {Employee} from './employee';
|
||||
import {ErrorLoggerService} from '../core/error-logger.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Employee } from './employee';
|
||||
import { ErrorLoggerService } from '../core/error-logger.service';
|
||||
|
||||
const httpOptions = {
|
||||
headers: new HttpHeaders({'Content-Type': 'application/json'})
|
||||
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
|
||||
};
|
||||
|
||||
const url = '/api/employees';
|
||||
const serviceName = 'EmployeeService';
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class EmployeeService {
|
||||
|
||||
constructor(private http: HttpClient, private log: ErrorLoggerService) {
|
||||
}
|
||||
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
|
||||
|
||||
get(id: string): Observable<Employee> {
|
||||
const getUrl: string = (id === null) ? `${url}` : `${url}/${id}`;
|
||||
return <Observable<Employee>>this.http.get<Employee>(getUrl)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, `get id=${id}`))
|
||||
);
|
||||
const getUrl: string = id === null ? `${url}` : `${url}/${id}`;
|
||||
return <Observable<Employee>>(
|
||||
this.http
|
||||
.get<Employee>(getUrl)
|
||||
.pipe(catchError(this.log.handleError(serviceName, `get id=${id}`)))
|
||||
);
|
||||
}
|
||||
|
||||
list(): Observable<Employee[]> {
|
||||
return <Observable<Employee[]>>this.http.get<Employee[]>(`${url}/list`)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'list'))
|
||||
);
|
||||
return <Observable<Employee[]>>(
|
||||
this.http
|
||||
.get<Employee[]>(`${url}/list`)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'list')))
|
||||
);
|
||||
}
|
||||
|
||||
save(employee: Employee): Observable<Employee> {
|
||||
return <Observable<Employee>>this.http.post<Employee>(`${url}`, employee, httpOptions)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'save'))
|
||||
);
|
||||
return <Observable<Employee>>(
|
||||
this.http
|
||||
.post<Employee>(`${url}`, employee, httpOptions)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'save')))
|
||||
);
|
||||
}
|
||||
|
||||
update(employee: Employee): Observable<Employee> {
|
||||
return <Observable<Employee>>this.http.put<Employee>(`${url}/${employee.id}`, employee, httpOptions)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'update'))
|
||||
);
|
||||
return <Observable<Employee>>(
|
||||
this.http
|
||||
.put<Employee>(`${url}/${employee.id}`, employee, httpOptions)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'update')))
|
||||
);
|
||||
}
|
||||
|
||||
saveOrUpdate(employee: Employee): Observable<Employee> {
|
||||
@ -56,17 +58,19 @@ export class EmployeeService {
|
||||
}
|
||||
|
||||
delete(id: string): Observable<Employee> {
|
||||
return <Observable<Employee>>this.http.delete<Employee>(`${url}/${id}`, httpOptions)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'delete'))
|
||||
);
|
||||
return <Observable<Employee>>(
|
||||
this.http
|
||||
.delete<Employee>(`${url}/${id}`, httpOptions)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'delete')))
|
||||
);
|
||||
}
|
||||
|
||||
autocomplete(term: string): Observable<Employee[]> {
|
||||
const options = {params: new HttpParams().set('q', term)};
|
||||
return <Observable<Employee[]>>this.http.get<Employee[]>(`${url}/query`, options)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'autocomplete'))
|
||||
);
|
||||
const options = { params: new HttpParams().set('q', term) };
|
||||
return <Observable<Employee[]>>(
|
||||
this.http
|
||||
.get<Employee[]>(`${url}/query`, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'autocomplete')))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {CostCentre} from '../core/cost-centre';
|
||||
import { CostCentre } from '../core/cost-centre';
|
||||
|
||||
export class Employee {
|
||||
id: string;
|
||||
@ -12,5 +12,4 @@ export class Employee {
|
||||
joiningDate: string;
|
||||
leavingDate?: string;
|
||||
costCentre: CostCentre;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user