From 4530052a228d9bc57a536a299329bfdf42121909 Mon Sep 17 00:00:00 2001 From: tanshu Date: Mon, 11 Jun 2018 22:14:04 +0530 Subject: [PATCH] ToCsvService to escape the fields during exportCsv. Auth Interceptor to check for logged out user. --- .../closing-stock/closing-stock.component.ts | 18 ++++++---- .../src/app/core/http-auth-interceptor.ts | 13 ++++++- overlord/src/app/ledger/ledger.component.ts | 20 +++++++---- .../raw-material-cost.component.ts | 34 ++++++++----------- .../src/app/shared/to-csv.service.spec.ts | 15 ++++++++ overlord/src/app/shared/to-csv.service.ts | 18 ++++++++++ 6 files changed, 84 insertions(+), 34 deletions(-) create mode 100644 overlord/src/app/shared/to-csv.service.spec.ts create mode 100644 overlord/src/app/shared/to-csv.service.ts diff --git a/overlord/src/app/closing-stock/closing-stock.component.ts b/overlord/src/app/closing-stock/closing-stock.component.ts index c4653a1a..13c51617 100644 --- a/overlord/src/app/closing-stock/closing-stock.component.ts +++ b/overlord/src/app/closing-stock/closing-stock.component.ts @@ -5,6 +5,7 @@ import {ClosingStock} from './closing-stock'; import {ActivatedRoute, Router} from '@angular/router'; import * as moment from 'moment'; import {FormBuilder, FormGroup} from '@angular/forms'; +import {ToCsvService} from '../shared/to-csv.service'; @Component({ selector: 'app-closing-stock', @@ -20,7 +21,7 @@ export class ClosingStockComponent implements OnInit { /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['product', 'group', 'quantity', 'amount']; - constructor(private route: ActivatedRoute, private router: Router, private fb: FormBuilder) { + constructor(private route: ActivatedRoute, private router: Router, private fb: FormBuilder, private toCsv: ToCsvService) { this.createForm(); } @@ -53,13 +54,16 @@ export class ClosingStockComponent implements OnInit { date: moment(formModel.date).format('DD-MMM-YYYY') }; } - exportCsv() { - const data: string[] = ['Product, Group, Quantity, Amount']; - data.push( - ...this.dataSource.data.map(x => '' + x.product + ', ' + x.group + ', ' + x.quantity + ', ' + x.amount) - ); - const csvData = new Blob([data.join('\n')], {type: 'text/csv;charset=utf-8;'}); + exportCsv() { + const headers = { + Product: 'product', + Group: 'group', + Quantity: 'quantity', + Amount: 'amount' + }; + + 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', 'closing-stock.csv'); diff --git a/overlord/src/app/core/http-auth-interceptor.ts b/overlord/src/app/core/http-auth-interceptor.ts index 173dab87..d8766067 100644 --- a/overlord/src/app/core/http-auth-interceptor.ts +++ b/overlord/src/app/core/http-auth-interceptor.ts @@ -20,8 +20,19 @@ export class HttpAuthInterceptor implements HttpInterceptor { .pipe( catchError((err: any, caught: Observable): ObservableInput<{}> => { if (err.status === 401) { - this.router.navigate(['login']); this.toaster.show('Danger', 'User has been logged out'); + const dialogRef = this.dialog.open(ConfirmDialogComponent, { + width: '250px', + data: { + title: 'Logged out!', + content: 'You have been logged out.\nYou can press Cancel to stay on page and login in another tab to resume here, or you can press Ok to navigate to the login page.' + } + }); + dialogRef.afterClosed().subscribe((result: boolean) => { + if (result) { + this.router.navigate(['login']); + } + }); } return observableOf(caught); } diff --git a/overlord/src/app/ledger/ledger.component.ts b/overlord/src/app/ledger/ledger.component.ts index d25060b0..6405fc8f 100644 --- a/overlord/src/app/ledger/ledger.component.ts +++ b/overlord/src/app/ledger/ledger.component.ts @@ -10,6 +10,7 @@ import {Ledger} from './ledger'; import {Account} from '../account/account'; import {LedgerService} from './ledger.service'; import {AccountService} from '../account/account.service'; +import {ToCsvService} from '../shared/to-csv.service'; @Component({ selector: 'app-ledger', @@ -36,6 +37,7 @@ export class LedgerComponent implements OnInit, AfterViewInit { private route: ActivatedRoute, private router: Router, private fb: FormBuilder, + private toCsv: ToCsvService, private ser: LedgerService, private accountSer: AccountService ) { @@ -140,13 +142,17 @@ export class LedgerComponent implements OnInit, AfterViewInit { } exportCsv() { - const data: string[] = ['Date , Name , Type , Narration , Debit , Credit , Running , Posted']; - data.push( - ...this.dataSource.data.map(x => x.date + ', ' + x.name + ', ' + x.type + ', ' + - x.narration + ', ' + x.debit + ', ' + x.credit + ', ' + x.running + ', ' + x.posted) - ); - - const csvData = new Blob([data.join('\n')], {type: 'text/csv;charset=utf-8;'}); + const headers = { + Date: 'date', + Name: 'name', + Type: 'type', + Narration: 'narration', + Debit: 'debit', + Credit: 'credit', + Running: 'running', + Posted: 'posted' + }; + 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', 'ledger.csv'); diff --git a/overlord/src/app/raw-material-cost/raw-material-cost.component.ts b/overlord/src/app/raw-material-cost/raw-material-cost.component.ts index 7676cbef..320ad40d 100644 --- a/overlord/src/app/raw-material-cost/raw-material-cost.component.ts +++ b/overlord/src/app/raw-material-cost/raw-material-cost.component.ts @@ -7,6 +7,7 @@ import * as moment from 'moment'; import {RawMaterialCostDataSource} from './raw-material-cost-datasource'; import {RawMaterialCost} from './raw-material-cost'; import {Product} from '../product/product'; +import {ToCsvService} from '../shared/to-csv.service'; @Component({ selector: 'app-raw-material-cost', @@ -32,11 +33,7 @@ export class RawMaterialCostComponent implements OnInit { products: Observable; - constructor( - private route: ActivatedRoute, - private router: Router, - private fb: FormBuilder - ) { + constructor(private route: ActivatedRoute, private router: Router, private fb: FormBuilder, private toCsv: ToCsvService) { this.createForm(); } @@ -80,21 +77,20 @@ export class RawMaterialCostComponent implements OnInit { } exportCsv() { - const data: string[] = []; - if (this.info.id) { - data.push( - 'Name, Group, Quantity, Net, Gross', - ...this.dataSource.data.map(x => x.name + ', ' + x.group + ', ' + x.quantity + ', ' + x.net + ', ' + x.gross) - ); - } else { - data.push( - 'Name, Issue, Sale, RMC', - ...this.dataSource.data.map(x => x.name + ', ' + x.issue + ', ' + x.sale + ', ' + x.rmc), - this.info.footer.name + ', ' + this.info.footer.issue + ', ' + this.info.footer.sale + ', ' + this.info.footer.rmc - ); - } + const headers = (this.info.id) ? { + Name: 'name', + Group: 'group', + Quantity: 'quantity', + Net: 'net', + Gross: 'gross' + } : { + Name: 'name', + Issue: 'issue', + Sale: 'sale', + RMC: 'rmc' + }; - const csvData = new Blob([data.join('\n')], {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', 'raw-material-cost.csv'); diff --git a/overlord/src/app/shared/to-csv.service.spec.ts b/overlord/src/app/shared/to-csv.service.spec.ts new file mode 100644 index 00000000..0fbf0883 --- /dev/null +++ b/overlord/src/app/shared/to-csv.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { ToCsvService } from './to-csv.service'; + +describe('ToCsvService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ToCsvService] + }); + }); + + it('should be created', inject([ToCsvService], (service: ToCsvService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/overlord/src/app/shared/to-csv.service.ts b/overlord/src/app/shared/to-csv.service.ts new file mode 100644 index 00000000..2ef1a007 --- /dev/null +++ b/overlord/src/app/shared/to-csv.service.ts @@ -0,0 +1,18 @@ +import {Injectable} from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class ToCsvService { + + constructor() { + } + + toCsv(headers: any, data: any[]): string { + const header = Object.keys(headers); + const replacer = (key, value) => value === null ? '' : value; + const csv = data.map(row => header.map(fieldName => JSON.stringify(row[headers[fieldName]], replacer)).join(',')); + csv.unshift(header.join(',')); + return csv.join('\r\n'); + } +}