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:
2020-10-01 20:51:22 +05:30
parent 40e79ff949
commit 1350870f9e
545 changed files with 8455 additions and 7036 deletions

View File

@ -5,59 +5,93 @@
</mat-card-title-group>
<mat-card-content>
<form [formGroup]="form" fxLayout="column">
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
fxLayoutGap.lt-md="0px">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<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" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
fxLayoutGap.lt-md="0px">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex="75">
<mat-label>Name</mat-label>
<input matInput #nameElement placeholder="Name" formControlName="name">
<input matInput #nameElement placeholder="Name" formControlName="name" />
</mat-form-field>
<mat-form-field fxFlex="25">
<mat-label>Units</mat-label>
<input matInput placeholder="Units" formControlName="units">
<input matInput placeholder="Units" formControlName="units" />
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
fxLayoutGap.lt-md="0px">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Fraction</mat-label>
<input matInput type="number" placeholder="Fraction" formControlName="fraction">
<input matInput type="number" placeholder="Fraction" formControlName="fraction" />
</mat-form-field>
<mat-form-field cdk-overlay-origin="">
<mat-label>Fraction Units</mat-label>
<input matInput placeholder="Fraction Units" formControlName="fractionUnits">
<input matInput placeholder="Fraction Units" formControlName="fractionUnits" />
</mat-form-field>
<mat-form-field cdk-overlay-origin="">
<mat-label>Yield</mat-label>
<input matInput type="number" placeholder="Yield" formControlName="productYield">
<input matInput type="number" placeholder="Yield" formControlName="productYield" />
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
fxLayoutGap.lt-md="0px">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>{{item.isPurchased ? 'Purchase Price' : 'Cost Price' }}</mat-label>
<input matInput type="number" placeholder="{{item.isPurchased ? 'Purchase Price' : 'Cost Price' }}"
formControlName="price">
<mat-label>{{ item.isPurchased ? 'Purchase Price' : 'Cost Price' }}</mat-label>
<input
matInput
type="number"
placeholder="{{ item.isPurchased ? 'Purchase Price' : 'Cost Price' }}"
formControlName="price"
/>
</mat-form-field>
<mat-form-field fxFlex [hidden]="!item.isSold">
<mat-label>Sale Price</mat-label>
<input matInput type="number" placeholder="Sale Price" formControlName="salePrice">
<input matInput type="number" placeholder="Sale Price" formControlName="salePrice" />
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
fxLayoutGap.lt-md="0px">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-checkbox formControlName="isPurchased">Is Purchased?</mat-checkbox>
<mat-checkbox formControlName="isSold">Is Sold?</mat-checkbox>
<mat-checkbox formControlName="isActive">Is Active?</mat-checkbox>
</div>
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
fxLayoutGap.lt-md="0px">
<div
fxLayout="row"
fxLayoutAlign="space-around start"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
>
<mat-form-field fxFlex>
<mat-label>Product Type</mat-label>
<mat-select placeholder="Product Group" formControlName="productGroup">
@ -71,7 +105,9 @@
</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>
</div>

View File

@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {ProductDetailComponent} from './product-detail.component';
import { ProductDetailComponent } from './product-detail.component';
describe('ProductDetailComponent', () => {
let component: ProductDetailComponent;
@ -8,9 +8,8 @@ describe('ProductDetailComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ProductDetailComponent]
})
.compileComponents();
declarations: [ProductDetailComponent],
}).compileComponents();
}));
beforeEach(() => {

View File

@ -1,17 +1,17 @@
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ToasterService} from '../../core/toaster.service';
import {ActivatedRoute, Router} from '@angular/router';
import {ProductService} from '../product.service';
import {Product} from '../../core/product';
import {ProductGroup} from '../../core/product-group';
import {ConfirmDialogComponent} from '../../shared/confirm-dialog/confirm-dialog.component';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ToasterService } from '../../core/toaster.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ProductService } from '../product.service';
import { Product } from '../../core/product';
import { ProductGroup } from '../../core/product-group';
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
import { MatDialog } from '@angular/material/dialog';
import {FormBuilder, FormGroup} from '@angular/forms';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-product-detail',
templateUrl: './product-detail.component.html',
styleUrls: ['./product-detail.component.css']
styleUrls: ['./product-detail.component.css'],
})
export class ProductDetailComponent implements OnInit, AfterViewInit {
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
@ -25,14 +25,14 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
private dialog: MatDialog,
private fb: FormBuilder,
private toaster: ToasterService,
private ser: ProductService
private ser: ProductService,
) {
this.createForm();
}
createForm() {
this.form = this.fb.group({
code: {value: '', disabled: true},
code: { value: '', disabled: true },
name: '',
units: '',
fraction: '',
@ -43,16 +43,15 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
isPurchased: '',
isSold: '',
isActive: '',
productGroup: ''
productGroup: '',
});
}
ngOnInit() {
this.route.data
.subscribe((data: { item: Product, productGroups: ProductGroup[] }) => {
this.productGroups = data.productGroups;
this.showItem(data.item);
});
this.route.data.subscribe((data: { item: Product; productGroups: ProductGroup[] }) => {
this.productGroups = data.productGroups;
this.showItem(data.item);
});
}
showItem(item: Product) {
@ -69,7 +68,7 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
isPurchased: this.item.isPurchased,
isSold: this.item.isSold,
isActive: this.item.isActive,
productGroup: this.item.productGroup.id ? this.item.productGroup.id : ''
productGroup: this.item.productGroup.id ? this.item.productGroup.id : '',
});
}
@ -80,35 +79,33 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
}
save() {
this.ser.saveOrUpdate(this.getItem())
.subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/products');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.saveOrUpdate(this.getItem()).subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/products');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
delete() {
this.ser.delete(this.item.id)
.subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/products');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.delete(this.item.id).subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/products');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
confirmDelete(): void {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
width: '250px',
data: {title: 'Delete Product?', content: 'Are you sure? This cannot be undone.'}
data: { title: 'Delete Product?', content: 'Are you sure? This cannot be undone.' },
});
dialogRef.afterClosed().subscribe((result: boolean) => {

View File

@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ProductListResolverService} from './product-list-resolver.service';
import { ProductListResolverService } from './product-list-resolver.service';
describe('ProductListResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ProductListResolverService]
providers: [ProductListResolverService],
});
});
it('should be created', inject([ProductListResolverService], (service: ProductListResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[ProductListResolverService],
(service: ProductListResolverService) => {
expect(service).toBeTruthy();
},
));
});

View File

@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Product} from '../core/product';
import {Observable} from 'rxjs/internal/Observable';
import {ProductService} from './product.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Product } from '../core/product';
import { Observable } from 'rxjs/internal/Observable';
import { ProductService } from './product.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ProductListResolver implements Resolve<Product[]> {
constructor(private ser: ProductService) {
}
constructor(private ser: ProductService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product[]> {
return this.ser.list();

View File

@ -5,15 +5,17 @@ import { map, tap } from 'rxjs/operators';
import { merge, Observable, of as observableOf } from 'rxjs';
import { Product } from '../../core/product';
export class ProductListDataSource extends DataSource<Product> {
private filterValue: string;
constructor(private paginator: MatPaginator, private sort: MatSort, private filter: Observable<string>, public data: Product[]) {
constructor(
private paginator: MatPaginator,
private sort: MatSort,
private filter: Observable<string>,
public data: Product[],
) {
super();
this.filter = filter.pipe(
tap(x => this.filterValue = x)
);
this.filter = filter.pipe(tap((x) => (this.filterValue = x)));
}
connect(): Observable<Product[]> {
@ -21,35 +23,43 @@ export class ProductListDataSource extends DataSource<Product> {
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: Product[]) => 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: Product[]) => (this.paginator.length = x.length)),
)
.pipe(
map((x: any) => {
return this.getPagedData(this.getSortedData(x));
}),
);
}
disconnect() {
}
disconnect() {}
private getFilteredData(data: Product[]): Product[] {
const filter = (this.filterValue === undefined) ? '' : this.filterValue;
const filter = this.filterValue === undefined ? '' : this.filterValue;
return filter.split(' ').reduce((p: Product[], c: string) => {
return p.filter(x => {
const productString = (
x.code + ' ' + x.name + ' ' + x.units + ' ' + x.productGroup + (x.isPurchased ? ' purchased' : ' made')
+ (x.isSold ? 'sold' : 'used') + (x.isActive ? 'active' : 'deactive')
).toLowerCase();
return productString.indexOf(c) !== -1;
}
);
return p.filter((x) => {
const productString = (
x.code +
' ' +
x.name +
' ' +
x.units +
' ' +
x.productGroup +
(x.isPurchased ? ' purchased' : ' made') +
(x.isSold ? 'sold' : 'used') +
(x.isActive ? 'active' : 'deactive')
).toLowerCase();
return productString.indexOf(c) !== -1;
});
}, Object.assign([], data));
}

View File

@ -11,38 +11,54 @@
</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">
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
<mat-cell *matCellDef="let row"><a [routerLink]="['/products', row.id]">{{row.name}} ({{showExtended ?
row.fraction + ' ' + row.fractionUnits + ' = 1 ':''}}{{row.units}})</a></mat-cell>
<mat-cell *matCellDef="let row"
><a [routerLink]="['/products', row.id]"
>{{ row.name }} ({{
showExtended ? row.fraction + ' ' + row.fractionUnits + ' = 1 ' : ''
}}{{ row.units }})</a
></mat-cell
>
</ng-container>
<!-- Cost Price Column -->
<ng-container matColumnDef="costPrice">
<mat-header-cell *matHeaderCellDef mat-sort-header>Cost Price</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.costPrice | currency:'INR'}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.costPrice | currency: 'INR' }}</mat-cell>
</ng-container>
<!-- Yield Column -->
<ng-container matColumnDef="productYield">
<mat-header-cell *matHeaderCellDef mat-sort-header>Yield</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.productYield | percent:'1.2-2'}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.productYield | percent: '1.2-2' }}</mat-cell>
</ng-container>
<!-- Product Group Column -->
<ng-container matColumnDef="productGroup">
<mat-header-cell *matHeaderCellDef mat-sort-header>Product Group</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.productGroup}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.productGroup }}</mat-cell>
</ng-container>
<!-- Info Column -->
@ -52,35 +68,37 @@
<div layout="row">
<div flex>
<mat-icon>
{{ row.isPurchased ? "shopping_cart" : "remove_shopping_cart" }}
{{ row.isPurchased ? 'shopping_cart' : 'remove_shopping_cart' }}
</mat-icon>
<b> {{ row.isPurchased ? "Purchased" : "Made" }}</b>
<b> {{ row.isPurchased ? 'Purchased' : 'Made' }}</b>
</div>
<div flex>
<mat-icon>
{{ row.isSold ? "restaurant_menu" : "import_contacts" }}
{{ row.isSold ? 'restaurant_menu' : 'import_contacts' }}
</mat-icon>
<b> {{ row.isSold ? "Sold" : "Used" }}</b>
<b> {{ row.isSold ? 'Sold' : 'Used' }}</b>
</div>
<div flex>
<mat-icon>
{{ row.isActive ? "visibility" : "visibility_off" }}
{{ row.isActive ? 'visibility' : 'visibility_off' }}
</mat-icon>
<b> {{ row.isActive ? "Active" : "Deactivated" }}</b>
<b> {{ row.isActive ? 'Active' : 'Deactivated' }}</b>
</div>
</div>
</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, 5000]">
<mat-paginator
#paginator
[length]="dataSource.data.length"
[pageIndex]="0"
[pageSize]="50"
[pageSizeOptions]="[25, 50, 100, 250, 5000]"
>
</mat-paginator>
</mat-card-content>
</mat-card>

View File

@ -1,6 +1,6 @@
import {ComponentFixture, fakeAsync, TestBed} from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import {ProductListComponent} from './product-list.component';
import { ProductListComponent } from './product-list.component';
describe('ProductListComponent', () => {
let component: ProductListComponent;
@ -8,9 +8,8 @@ describe('ProductListComponent', () => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
declarations: [ProductListComponent]
})
.compileComponents();
declarations: [ProductListComponent],
}).compileComponents();
fixture = TestBed.createComponent(ProductListComponent);
component = fixture.componentInstance;

View File

@ -12,10 +12,9 @@ import { ToCsvService } from '../../shared/to-csv.service';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
styleUrls: ['./product-list.component.css'],
})
export class ProductListComponent implements OnInit, AfterViewInit {
constructor(private route: ActivatedRoute, private fb: FormBuilder, private toCsv: ToCsvService) {
this.showExtended = false;
this.createForm();
@ -48,24 +47,20 @@ export class ProductListComponent 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: Product[] }) => {
this.list = data.list;
});
this.route.data.subscribe((data: { list: Product[] }) => {
this.list = data.list;
});
this.dataSource = new ProductListDataSource(this.paginator, this.sort, this.filter, this.list);
}
@ -84,10 +79,12 @@ export class ProductListComponent implements OnInit, AfterViewInit {
FractionUnits: 'fractionUnits',
CostPrice: 'costPrice',
Yield: 'yield',
ProductGroup: 'productGroup'
ProductGroup: 'productGroup',
};
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', 'products.csv');

View File

@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ProductResolverService} from './product-resolver.service';
import { ProductResolverService } from './product-resolver.service';
describe('ProductResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ProductDetailResolverService]
providers: [ProductDetailResolverService],
});
});
it('should be created', inject([ProductDetailResolverService], (service: ProductDetailResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[ProductDetailResolverService],
(service: ProductDetailResolverService) => {
expect(service).toBeTruthy();
},
));
});

View File

@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {ProductService} from './product.service';
import {Product} from '../core/product';
import {Observable} from 'rxjs/internal/Observable';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { ProductService } from './product.service';
import { Product } from '../core/product';
import { Observable } from 'rxjs/internal/Observable';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ProductResolver implements Resolve<Product> {
constructor(private ser: ProductService, private router: Router) {
}
constructor(private ser: ProductService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product> {
const id = route.paramMap.get('id');

View File

@ -1,4 +1,4 @@
import {ProductRoutingModule} from './product-routing.module';
import { ProductRoutingModule } from './product-routing.module';
describe('ProductRoutingModule', () => {
let productRoutingModule: ProductRoutingModule;

View File

@ -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 {ProductListResolver} from './product-list-resolver.service';
import {ProductResolver} from './product-resolver.service';
import {ProductDetailComponent} from './product-detail/product-detail.component';
import {ProductListComponent} from './product-list/product-list.component';
import { ProductListResolver } from './product-list-resolver.service';
import { ProductResolver } from './product-resolver.service';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { ProductListComponent } from './product-list/product-list.component';
import {AuthGuard} from '../auth/auth-guard.service';
import {ProductGroupListResolver} from '../product-group/product-group-list-resolver.service';
import { AuthGuard } from '../auth/auth-guard.service';
import { ProductGroupListResolver } from '../product-group/product-group-list-resolver.service';
const productRoutes: Routes = [
{
@ -16,51 +16,41 @@ const productRoutes: Routes = [
component: ProductListComponent,
canActivate: [AuthGuard],
data: {
permission: 'Products'
permission: 'Products',
},
resolve: {
list: ProductListResolver
}
list: ProductListResolver,
},
},
{
path: 'new',
component: ProductDetailComponent,
canActivate: [AuthGuard],
data: {
permission: 'Products'
permission: 'Products',
},
resolve: {
item: ProductResolver,
productGroups: ProductGroupListResolver
}
productGroups: ProductGroupListResolver,
},
},
{
path: ':id',
component: ProductDetailComponent,
canActivate: [AuthGuard],
data: {
permission: 'Products'
permission: 'Products',
},
resolve: {
item: ProductResolver,
productGroups: ProductGroupListResolver
}
}
productGroups: ProductGroupListResolver,
},
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(productRoutes)
],
exports: [
RouterModule
],
providers: [
ProductListResolver,
ProductResolver
]
imports: [CommonModule, RouterModule.forChild(productRoutes)],
exports: [RouterModule],
providers: [ProductListResolver, ProductResolver],
})
export class ProductRoutingModule {
}
export class ProductRoutingModule {}

View File

@ -1,4 +1,4 @@
import {ProductModule} from './product.module';
import { ProductModule } from './product.module';
describe('ProductModule', () => {
let productModule: ProductModule;

View File

@ -1,9 +1,9 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {ProductListComponent} from './product-list/product-list.component';
import {ProductDetailComponent} from './product-detail/product-detail.component';
import {ProductRoutingModule} from './product-routing.module';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { ProductRoutingModule } from './product-routing.module';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
@ -15,9 +15,9 @@ 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 { CdkTableModule } from '@angular/cdk/table';
import { ReactiveFormsModule } from '@angular/forms';
import { FlexLayoutModule } from '@angular/flex-layout';
@NgModule({
imports: [
@ -36,12 +36,8 @@ import {FlexLayoutModule} from '@angular/flex-layout';
MatSelectModule,
MatCheckboxModule,
ReactiveFormsModule,
ProductRoutingModule
ProductRoutingModule,
],
declarations: [
ProductListComponent,
ProductDetailComponent
]
declarations: [ProductListComponent, ProductDetailComponent],
})
export class ProductModule {
}
export class ProductModule {}

View File

@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ProductService} from './product.service';
import { ProductService } from './product.service';
describe('ProductService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ProductService]
providers: [ProductService],
});
});

View File

@ -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 {Product} from '../core/product';
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 { Product } from '../core/product';
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/products';
const serviceName = 'ProductService';
@Injectable({providedIn: 'root'})
@Injectable({ providedIn: 'root' })
export class ProductService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
get(id: string): Observable<Product> {
const getUrl: string = (id === null) ? `${url}` : `${url}/${id}`;
return <Observable<Product>>this.http.get<Product>(getUrl)
.pipe(
catchError(this.log.handleError(serviceName, `get id=${id}`))
);
const getUrl: string = id === null ? `${url}` : `${url}/${id}`;
return <Observable<Product>>(
this.http
.get<Product>(getUrl)
.pipe(catchError(this.log.handleError(serviceName, `get id=${id}`)))
);
}
list(): Observable<Product[]> {
return <Observable<Product[]>>this.http.get<Product[]>(`${url}/list`)
.pipe(
catchError(this.log.handleError(serviceName, 'getList'))
);
return <Observable<Product[]>>(
this.http
.get<Product[]>(`${url}/list`)
.pipe(catchError(this.log.handleError(serviceName, 'getList')))
);
}
save(product: Product): Observable<Product> {
return <Observable<Product>>this.http.post<Product>(`${url}`, product, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'save'))
);
return <Observable<Product>>(
this.http
.post<Product>(`${url}`, product, httpOptions)
.pipe(catchError(this.log.handleError(serviceName, 'save')))
);
}
update(product: Product): Observable<Product> {
return <Observable<Product>>this.http.put<Product>(`${url}/${product.id}`, product, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'update'))
);
return <Observable<Product>>(
this.http
.put<Product>(`${url}/${product.id}`, product, httpOptions)
.pipe(catchError(this.log.handleError(serviceName, 'update')))
);
}
saveOrUpdate(product: Product): Observable<Product> {
@ -56,17 +58,19 @@ export class ProductService {
}
delete(id: string): Observable<Product> {
return <Observable<Product>>this.http.delete<Product>(`${url}/${id}`, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'delete'))
);
return <Observable<Product>>(
this.http
.delete<Product>(`${url}/${id}`, httpOptions)
.pipe(catchError(this.log.handleError(serviceName, 'delete')))
);
}
autocomplete(query: string): Observable<Product[]> {
const options = {params: new HttpParams().set('q', query)};
return <Observable<Product[]>>this.http.get<Product[]>(`${url}/query`, options)
.pipe(
catchError(this.log.handleError(serviceName, 'autocomplete'))
);
const options = { params: new HttpParams().set('q', query) };
return <Observable<Product[]>>(
this.http
.get<Product[]>(`${url}/query`, options)
.pipe(catchError(this.log.handleError(serviceName, 'autocomplete')))
);
}
}