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:
tanshu committed 2020-10-01 21:28:12 +05:30
1 parent 40e79ff949
commit 1350870f9e
545 files changed
+8455 -7036

No files matched your search

+4
View File
@@ -39,3 +39,7 @@ source env/bin/activate
```bash
python3 -m pip install pyramid waitress sqlalchemy zope.sqlalchemy psycopg2
```
## Prettier - to format typescript files
```npx prettier --write src/app/```
+213
View File
@@ -0,0 +1,213 @@
/*
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
https://github.com/typescript-eslint/tslint-to-eslint-config
It represents the closest reasonable ESLint configuration to this
project's original TSLint configuration.
We recommend eventually switching this configuration to extend from
the recommended rulesets in typescript-eslint.
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
Happy linting! 💖
*/
module.exports = {
"extends": [
"plugin:@angular-eslint/recommended",
// AirBnB Styleguide rules
"airbnb-typescript/base",
// Settings for Prettier
"prettier/@typescript-eslint",
"plugin:prettier/recommended",
],
"env": {
"browser": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
},
"plugins": [
"eslint-plugin-import",
"eslint-plugin-jsdoc",
"@angular-eslint/eslint-plugin",
"@typescript-eslint",
"@typescript-eslint/tslint"
],
"overrides": [
{
files: ['*.ts'],
extends: [
// AirBnB Styleguide rules
'airbnb-typescript/base',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
},
},
]
"rules": {
"@angular-eslint/component-class-suffix": "error",
"@angular-eslint/directive-class-suffix": "error",
"@angular-eslint/no-host-metadata-property": "error",
"@angular-eslint/no-input-rename": "error",
"@angular-eslint/no-inputs-metadata-property": "error",
"@angular-eslint/no-output-on-prefix": "error",
"@angular-eslint/no-output-rename": "error",
"@angular-eslint/no-outputs-metadata-property": "error",
"@angular-eslint/use-lifecycle-interface": "error",
"@angular-eslint/use-pipe-transform-interface": "error",
"@typescript-eslint/consistent-type-definitions": "error",
"@typescript-eslint/dot-notation": "off",
"@typescript-eslint/explicit-member-accessibility": [
"off",
{
"accessibility": "explicit"
}
],
"@typescript-eslint/indent": "error",
"@typescript-eslint/member-delimiter-style": [
"error",
{
"multiline": {
"delimiter": "semi",
"requireLast": true
},
"singleline": {
"delimiter": "semi",
"requireLast": false
}
}
],
"@typescript-eslint/member-ordering": "error",
"@typescript-eslint/naming-convention": "error",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-inferrable-types": [
"error",
{
"ignoreParameters": true
}
],
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-non-null-assertion": "error",
"@typescript-eslint/no-unused-expressions": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/quotes": [
"error",
"single"
],
"@typescript-eslint/semi": [
"error",
"always"
],
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unified-signatures": "error",
"arrow-body-style": "error",
"brace-style": [
"error",
"1tbs"
],
"constructor-super": "error",
"curly": "error",
"eol-last": "error",
"eqeqeq": [
"error",
"smart"
],
"guard-for-in": "error",
"id-blacklist": "off",
"id-match": "off",
"import/no-deprecated": "warn",
"jsdoc/no-types": "error",
"max-len": [
"error",
{
"code": 140
}
],
"no-bitwise": "error",
"no-caller": "error",
"no-console": [
"error",
{
"allow": [
"log",
"dirxml",
"warn",
"error",
"dir",
"timeLog",
"assert",
"clear",
"count",
"countReset",
"group",
"groupCollapsed",
"groupEnd",
"table",
"Console",
"markTimeline",
"profile",
"profileEnd",
"timeline",
"timelineEnd",
"timeStamp",
"context"
]
}
],
"no-debugger": "error",
"no-empty": "off",
"no-eval": "error",
"no-fallthrough": "error",
"no-new-wrappers": "error",
"no-restricted-imports": [
"error",
"rxjs/Rx"
],
"no-shadow": [
"error",
{
"hoist": "all"
}
],
"no-throw-literal": "error",
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-underscore-dangle": "off",
"no-unused-labels": "error",
"no-var": "error",
"prefer-const": "error",
"radix": "error",
"spaced-comment": [
"error",
"always",
{
"markers": [
"/"
]
}
],
"@typescript-eslint/tslint/config": [
"error",
{
"rules": {
"import-spacing": true,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}
]
}
};
+8
View File
@@ -0,0 +1,8 @@
module.exports = {
trailingComma: "all",
tabWidth: 2,
semi: true,
singleQuote: true,
bracketSpacing: true,
printWidth: 100
};
+2 -1
View File
@@ -97,8 +97,9 @@
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"builder": "@angular-eslint/builder:lint",
"options": {
"eslintConfig": ".eslintrc.js",
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
+1 -1
View File
@@ -1,5 +1,5 @@
{
"extends": "../tsconfig.base.json",
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "commonjs",
+31 -20
View File
@@ -1,29 +1,28 @@
{
"name": "overlord",
"version": "7.2.0",
"version": "7.3.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"postinstall": "ngcc"
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^10.0.4",
"@angular/cdk": "^10.0.2",
"@angular/common": "^10.0.4",
"@angular/compiler": "^10.0.4",
"@angular/core": "^10.0.4",
"@angular/animations": "^10.1.4",
"@angular/cdk": "^10.2.3",
"@angular/common": "^10.1.4",
"@angular/compiler": "^10.1.4",
"@angular/core": "^10.1.4",
"@angular/flex-layout": "^10.0.0-beta.32",
"@angular/forms": "^10.0.4",
"@angular/material": "^10.0.2",
"@angular/material-moment-adapter": "^10.0.2",
"@angular/platform-browser": "^10.0.4",
"@angular/platform-browser-dynamic": "^10.0.4",
"@angular/router": "^10.0.4",
"@angular/forms": "^10.1.4",
"@angular/material": "^10.2.3",
"@angular/material-moment-adapter": "^10.2.3",
"@angular/platform-browser": "^10.1.4",
"@angular/platform-browser-dynamic": "^10.1.4",
"@angular/router": "^10.1.4",
"@ngx-loading-bar/core": "^5.1.0",
"@ngx-loading-bar/http-client": "^5.1.0",
"@ngx-loading-bar/router": "^5.1.0",
@@ -31,20 +30,32 @@
"core-js": "^3.6.5",
"mathjs": "^7.1.0",
"moment": "^2.27.0",
"rxjs": "^6.6.0",
"rxjs": "^6.6.3",
"rxjs-tslint": "^0.1.5",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1000.3",
"@angular/cli": "^10.0.3",
"@angular/compiler-cli": "^10.0.4",
"@angular/language-service": "^10.0.4",
"@angular-devkit/build-angular": "~0.1001.4",
"@angular-eslint/builder": "0.4.0-beta.2",
"@angular-eslint/eslint-plugin": "0.4.0-beta.2",
"@angular-eslint/eslint-plugin-template": "0.4.0-beta.2",
"@angular-eslint/schematics": "^0.4.0-beta.2",
"@angular-eslint/template-parser": "0.4.0-beta.2",
"@angular/cli": "^10.1.4",
"@angular/compiler-cli": "^10.1.4",
"@angular/language-service": "^10.1.4",
"@types/jasmine": "^3.5.11",
"@types/jasminewd2": "^2.0.3",
"@types/node": "^14.0.23",
"@typescript-eslint/eslint-plugin": "3.9.0",
"@typescript-eslint/parser": "3.9.0",
"codelyzer": "^6.0.0",
"eslint": "^7.6.0",
"eslint-config-airbnb-typescript": "^11.0.0",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.1.4",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "^5.1.0",
@@ -52,10 +63,10 @@
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.5.0",
"prettier": "^2.1.2",
"protractor": "~7.0.0",
"standard-version": "^8.0.2",
"ts-node": "^8.10.2",
"tslint": "~6.1.0",
"typescript": "3.9.6"
}
}
@@ -2,28 +2,48 @@
<mat-card fxFlex>
<mat-card-title-group>
<mat-card-title>Account</mat-card-title>
<mat-icon matSuffix (click)="item.isStarred = !item.isStarred" class="pointer" [class.gold]="item.isStarred">
<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" 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>
<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" 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>Account Type</mat-label>
<mat-select placeholder="Account Type" formControlName="type">
@@ -33,13 +53,23 @@
</mat-select>
</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="isActive">Is Active?</mat-checkbox>
<mat-checkbox formControlName="isReconcilable">Is Reconcilable?</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>Cost Centre</mat-label>
<mat-select placeholder="Cost Centre" formControlName="costCentre">
@@ -53,7 +83,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>
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {AccountDetailComponent} from './account-detail.component';
import { AccountDetailComponent } from './account-detail.component';
describe('AccountDetailComponent', () => {
let component: AccountDetailComponent;
@@ -8,9 +8,8 @@ describe('AccountDetailComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AccountDetailComponent]
})
.compileComponents();
declarations: [AccountDetailComponent],
}).compileComponents();
}));
beforeEach(() => {
@@ -1,18 +1,18 @@
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ToasterService} from '../../core/toaster.service';
import {ActivatedRoute, Router} from '@angular/router';
import {AccountService} from '../../core/account.service';
import {Account} from '../../core/account';
import {AccountType} from '../../core/account-type';
import {CostCentre} from '../../core/cost-centre';
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 { AccountService } from '../../core/account.service';
import { Account } from '../../core/account';
import { AccountType } from '../../core/account-type';
import { CostCentre } from '../../core/cost-centre';
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-account-detail',
templateUrl: './account-detail.component.html',
styleUrls: ['./account-detail.component.css']
styleUrls: ['./account-detail.component.css'],
})
export class AccountDetailComponent implements OnInit, AfterViewInit {
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
@@ -27,29 +27,30 @@ export class AccountDetailComponent implements OnInit, AfterViewInit {
private dialog: MatDialog,
private fb: FormBuilder,
private toaster: ToasterService,
private ser: AccountService
private ser: AccountService,
) {
this.createForm();
}
createForm() {
this.form = this.fb.group({
code: {value: '', disabled: true},
code: { value: '', disabled: true },
name: '',
type: '',
isActive: '',
isReconcilable: '',
costCentre: ''
costCentre: '',
});
}
ngOnInit() {
this.route.data
.subscribe((data: { item: Account, accountTypes: AccountType[], costCentres: CostCentre[] }) => {
this.route.data.subscribe(
(data: { item: Account; accountTypes: AccountType[]; costCentres: CostCentre[] }) => {
this.accountTypes = data.accountTypes;
this.costCentres = data.costCentres;
this.showItem(data.item);
});
},
);
}
showItem(item: Account) {
@@ -60,7 +61,7 @@ export class AccountDetailComponent implements OnInit, AfterViewInit {
type: this.item.type,
isActive: this.item.isActive,
isReconcilable: this.item.isReconcilable,
costCentre: this.item.costCentre.id
costCentre: this.item.costCentre.id,
});
}
@@ -71,35 +72,33 @@ export class AccountDetailComponent implements OnInit, AfterViewInit {
}
save() {
this.ser.saveOrUpdate(this.getItem())
.subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/accounts');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.saveOrUpdate(this.getItem()).subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/accounts');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
delete() {
this.ser.delete(this.item.id)
.subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/accounts');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.delete(this.item.id).subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/accounts');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
confirmDelete(): void {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
width: '250px',
data: {title: 'Delete Account?', content: 'Are you sure? This cannot be undone.'}
data: { title: 'Delete Account?', content: 'Are you sure? This cannot be undone.' },
});
dialogRef.afterClosed().subscribe((result: boolean) => {
@@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AccountListResolverService} from './account-list-resolver.service';
import { AccountListResolverService } from './account-list-resolver.service';
describe('AccountListResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AccountListResolverService]
providers: [AccountListResolverService],
});
});
it('should be created', inject([AccountListResolverService], (service: AccountListResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[AccountListResolverService],
(service: AccountListResolverService) => {
expect(service).toBeTruthy();
},
));
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Account} from '../core/account';
import {Observable} from 'rxjs/internal/Observable';
import {AccountService} from '../core/account.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Account } from '../core/account';
import { Observable } from 'rxjs/internal/Observable';
import { AccountService } from '../core/account.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AccountListResolver implements Resolve<Account[]> {
constructor(private ser: AccountService) {
}
constructor(private ser: AccountService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Account[]> {
return this.ser.list();
@@ -5,15 +5,17 @@ import { map, tap } from 'rxjs/operators';
import { merge, Observable, of as observableOf } from 'rxjs';
import { Account } from '../../core/account';
export class AccountListDataSource extends DataSource<Account> {
private filterValue: string;
constructor(private paginator: MatPaginator, private sort: MatSort, private filter: Observable<string>, public data: Account[]) {
constructor(
private paginator: MatPaginator,
private sort: MatSort,
private filter: Observable<string>,
public data: Account[],
) {
super();
this.filter = filter.pipe(
tap(x => this.filterValue = x)
);
this.filter = filter.pipe(tap((x) => (this.filterValue = x)));
}
connect(): Observable<Account[]> {
@@ -21,34 +23,39 @@ export class AccountListDataSource extends DataSource<Account> {
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: Account[]) => 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: Account[]) => (this.paginator.length = x.length)),
)
.pipe(
map((x: any) => {
return this.getPagedData(this.getSortedData(x));
}),
);
}
disconnect() {
}
disconnect() {}
private getFilteredData(data: Account[]): Account[] {
const filter = (this.filterValue === undefined) ? '' : this.filterValue;
const filter = this.filterValue === undefined ? '' : this.filterValue;
return filter.split(' ').reduce((p: Account[], c: string) => {
return p.filter(x => {
const accountString = (
x.name + ' ' + x.type + ' ' + x.costCentre + (x.isActive ? ' active' : ' inactive')
).toLowerCase();
return accountString.indexOf(c) !== -1;
}
);
return p.filter((x) => {
const accountString = (
x.name +
' ' +
x.type +
' ' +
x.costCentre +
(x.isActive ? ' active' : ' inactive')
).toLowerCase();
return accountString.indexOf(c) !== -1;
});
}, Object.assign([], data));
}
@@ -8,23 +8,33 @@
</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]="['/accounts', 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>
@@ -32,36 +42,38 @@
<!-- Type Column -->
<ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header>Type</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.type}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.type }}</mat-cell>
</ng-container>
<!-- Is Active? Column -->
<ng-container matColumnDef="isActive">
<mat-header-cell *matHeaderCellDef mat-sort-header>Is Active?</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.isActive}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.isActive }}</mat-cell>
</ng-container>
<!-- Is Reconcilable? Column -->
<ng-container matColumnDef="isReconcilable">
<mat-header-cell *matHeaderCellDef mat-sort-header>Is Reconcilable?</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.isReconcilable}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.isReconcilable }}</mat-cell>
</ng-container>
<!-- Cost Centre Column -->
<ng-container matColumnDef="costCentre">
<mat-header-cell *matHeaderCellDef mat-sort-header>Cost Centre</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.costCentre}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.costCentre }}</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 {AccountListComponent} from './account-list.component';
import { AccountListComponent } from './account-list.component';
describe('AccountListComponent', () => {
let component: AccountListComponent;
@@ -8,9 +8,8 @@ describe('AccountListComponent', () => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
declarations: [AccountListComponent]
})
.compileComponents();
declarations: [AccountListComponent],
}).compileComponents();
fixture = TestBed.createComponent(AccountListComponent);
component = fixture.componentInstance;
@@ -1,17 +1,17 @@
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 {AccountListDataSource} from './account-list-datasource';
import {Account} from '../../core/account';
import {ActivatedRoute} from '@angular/router';
import {Observable} from 'rxjs';
import {FormBuilder, FormGroup} from '@angular/forms';
import {debounceTime, distinctUntilChanged, startWith} from 'rxjs/operators';
import { AccountListDataSource } from './account-list-datasource';
import { Account } from '../../core/account';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { FormBuilder, FormGroup } from '@angular/forms';
import { debounceTime, distinctUntilChanged, startWith } from 'rxjs/operators';
@Component({
selector: 'app-account-list',
templateUrl: './account-list.component.html',
styleUrls: ['./account-list.component.css']
styleUrls: ['./account-list.component.css'],
})
export class AccountListComponent implements OnInit, AfterViewInit {
@ViewChild('filterElement', { static: true }) filterElement: ElementRef;
@@ -32,24 +32,20 @@ export class AccountListComponent 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: Account[] }) => {
this.list = data.list;
});
this.route.data.subscribe((data: { list: Account[] }) => {
this.list = data.list;
});
this.dataSource = new AccountListDataSource(this.paginator, this.sort, this.filter, this.list);
}
@@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AccountResolverService} from './account-resolver.service';
import { AccountResolverService } from './account-resolver.service';
describe('AccountResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AccountDetailResolverService]
providers: [AccountDetailResolverService],
});
});
it('should be created', inject([AccountDetailResolverService], (service: AccountDetailResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[AccountDetailResolverService],
(service: AccountDetailResolverService) => {
expect(service).toBeTruthy();
},
));
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {AccountService} from '../core/account.service';
import {Account} from '../core/account';
import {Observable} from 'rxjs/internal/Observable';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { AccountService } from '../core/account.service';
import { Account } from '../core/account';
import { Observable } from 'rxjs/internal/Observable';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AccountResolver implements Resolve<Account> {
constructor(private ser: AccountService, private router: Router) {
}
constructor(private ser: AccountService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Account> {
const id = route.paramMap.get('id');
@@ -1,4 +1,4 @@
import {AccountRoutingModule} from './account-routing.module';
import { AccountRoutingModule } from './account-routing.module';
describe('AccountRoutingModule', () => {
let accountRoutingModule: AccountRoutingModule;
@@ -1,15 +1,15 @@
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 {AccountListResolver} from './account-list-resolver.service';
import {AccountResolver} from './account-resolver.service';
import {AccountTypeResolver} from './account-type-resolver.service';
import {AccountDetailComponent} from './account-detail/account-detail.component';
import {AccountListComponent} from './account-list/account-list.component';
import { AccountListResolver } from './account-list-resolver.service';
import { AccountResolver } from './account-resolver.service';
import { AccountTypeResolver } from './account-type-resolver.service';
import { AccountDetailComponent } from './account-detail/account-detail.component';
import { AccountListComponent } from './account-list/account-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 accountRoutes: Routes = [
{
@@ -17,53 +17,43 @@ const accountRoutes: Routes = [
component: AccountListComponent,
canActivate: [AuthGuard],
data: {
permission: 'Accounts'
permission: 'Accounts',
},
resolve: {
list: AccountListResolver
}
list: AccountListResolver,
},
},
{
path: 'new',
component: AccountDetailComponent,
canActivate: [AuthGuard],
data: {
permission: 'Accounts'
permission: 'Accounts',
},
resolve: {
item: AccountResolver,
accountTypes: AccountTypeResolver,
costCentres: CostCentreListResolver
}
costCentres: CostCentreListResolver,
},
},
{
path: ':id',
component: AccountDetailComponent,
canActivate: [AuthGuard],
data: {
permission: 'Accounts'
permission: 'Accounts',
},
resolve: {
item: AccountResolver,
accountTypes: AccountTypeResolver,
costCentres: CostCentreListResolver
}
}
costCentres: CostCentreListResolver,
},
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(accountRoutes)
],
exports: [
RouterModule
],
providers: [
AccountListResolver,
AccountResolver
]
imports: [CommonModule, RouterModule.forChild(accountRoutes)],
exports: [RouterModule],
providers: [AccountListResolver, AccountResolver],
})
export class AccountRoutingModule {
}
export class AccountRoutingModule {}
@@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AccountTypeResolverService} from './account-type-resolver.service';
import { AccountTypeResolverService } from './account-type-resolver.service';
describe('AccountTypeResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AccountTypeResolverService]
providers: [AccountTypeResolverService],
});
});
it('should be created', inject([AccountTypeResolverService], (service: AccountTypeResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[AccountTypeResolverService],
(service: AccountTypeResolverService) => {
expect(service).toBeTruthy();
},
));
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {AccountType} from '../core/account-type';
import {Observable} from 'rxjs/internal/Observable';
import {AccountTypeService} from './account-type.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { AccountType } from '../core/account-type';
import { Observable } from 'rxjs/internal/Observable';
import { AccountTypeService } from './account-type.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AccountTypeResolver implements Resolve<AccountType[]> {
constructor(private ser: AccountTypeService) {
}
constructor(private ser: AccountTypeService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<AccountType[]> {
return this.ser.list();
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AccountTypeService} from './account-type.service';
import { AccountTypeService } from './account-type.service';
describe('AccountTypeService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AccountTypeService]
providers: [AccountTypeService],
});
});
@@ -1,26 +1,22 @@
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/internal/Observable';
import {AccountType} from '../core/account-type';
import {catchError} from 'rxjs/operators';
import {HttpClient} from '@angular/common/http';
import {ErrorLoggerService} from '../core/error-logger.service';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { AccountType } from '../core/account-type';
import { catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { ErrorLoggerService } from '../core/error-logger.service';
const url = '/api/account-types';
const serviceName = 'AccountTypeService';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AccountTypeService {
constructor(
private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
list(): Observable<AccountType[]> {
return <Observable<AccountType[]>>this.http.get<AccountType[]>(url)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);
return <Observable<AccountType[]>>(
this.http.get<AccountType[]>(url).pipe(catchError(this.log.handleError(serviceName, 'list')))
);
}
}
@@ -1,4 +1,4 @@
import {AccountModule} from './account.module';
import { AccountModule } from './account.module';
describe('AccountModule', () => {
let accountModule: AccountModule;
+11 -15
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 {AccountListComponent} from './account-list/account-list.component';
import {AccountDetailComponent} from './account-detail/account-detail.component';
import {AccountRoutingModule} from './account-routing.module';
import { AccountListComponent } from './account-list/account-list.component';
import { AccountDetailComponent } from './account-detail/account-detail.component';
import { AccountRoutingModule } from './account-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,
AccountRoutingModule
AccountRoutingModule,
],
declarations: [
AccountListComponent,
AccountDetailComponent
]
declarations: [AccountListComponent, AccountDetailComponent],
})
export class AccountModule {
}
export class AccountModule {}
+1 -1
View File
@@ -1,4 +1,4 @@
import {AppRoutingModule} from './app-routing.module';
import { AppRoutingModule } from './app-routing.module';
describe('AppRoutingModule', () => {
let appRoutingModule: AppRoutingModule;
+73 -53
View File
@@ -1,165 +1,185 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {LoginComponent} from './auth/login/login.component';
import {RouterModule, Routes} from '@angular/router';
import {LogoutComponent} from './auth/logout/logout.component';
import {HomeComponent} from './home/home.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from './auth/login/login.component';
import { RouterModule, Routes } from '@angular/router';
import { LogoutComponent } from './auth/logout/logout.component';
import { HomeComponent } from './home/home.component';
const appRoutes: Routes = [
{
path: 'accounts',
loadChildren: () => import('./account/account.module').then(mod => mod.AccountModule)
loadChildren: () => import('./account/account.module').then((mod) => mod.AccountModule),
},
{
path: 'attendance',
loadChildren: () => import('./attendance/attendance.module').then(mod => mod.AttendanceModule)
loadChildren: () =>
import('./attendance/attendance.module').then((mod) => mod.AttendanceModule),
},
{
path: 'balance-sheet',
loadChildren: () => import('./balance-sheet/balance-sheet.module').then(mod => mod.BalanceSheetModule)
loadChildren: () =>
import('./balance-sheet/balance-sheet.module').then((mod) => mod.BalanceSheetModule),
},
{
path: 'cash-flow',
loadChildren: () => import('./cash-flow/cash-flow.module').then(mod => mod.CashFlowModule)
loadChildren: () => import('./cash-flow/cash-flow.module').then((mod) => mod.CashFlowModule),
},
{
path: 'clients',
loadChildren: () => import('./client/client.module').then(mod => mod.ClientModule)
loadChildren: () => import('./client/client.module').then((mod) => mod.ClientModule),
},
{
path: 'closing-stock',
loadChildren: () => import('./closing-stock/closing-stock.module').then(mod => mod.ClosingStockModule)
loadChildren: () =>
import('./closing-stock/closing-stock.module').then((mod) => mod.ClosingStockModule),
},
{
path: 'cost-centres',
loadChildren: () => import('./cost-centre/cost-centre.module').then(mod => mod.CostCentreModule)
loadChildren: () =>
import('./cost-centre/cost-centre.module').then((mod) => mod.CostCentreModule),
},
{
path: 'daybook',
loadChildren: () => import('./daybook/daybook.module').then(mod => mod.DaybookModule)
loadChildren: () => import('./daybook/daybook.module').then((mod) => mod.DaybookModule),
},
{
path: 'employees',
loadChildren: () => import('./employee/employee.module').then(mod => mod.EmployeeModule)
loadChildren: () => import('./employee/employee.module').then((mod) => mod.EmployeeModule),
},
{
path: 'employee-attendance',
loadChildren: () => import('./employee-attendance/employee-attendance.module').then(mod => mod.EmployeeAttendanceModule)
loadChildren: () =>
import('./employee-attendance/employee-attendance.module').then(
(mod) => mod.EmployeeAttendanceModule,
),
},
{
path: 'employee-benefits',
loadChildren: () => import('./employee-benefits/employee-benefits.module').then(mod => mod.EmployeeBenefitsModule)
loadChildren: () =>
import('./employee-benefits/employee-benefits.module').then(
(mod) => mod.EmployeeBenefitsModule,
),
},
{
path: 'employee-functions',
loadChildren: () => import('./employee-functions/employee-functions.module').then(mod => mod.EmployeeFunctionsModule)
loadChildren: () =>
import('./employee-functions/employee-functions.module').then(
(mod) => mod.EmployeeFunctionsModule,
),
},
{
path: 'roles',
loadChildren: () => import('./role/role.module').then(mod => mod.RoleModule)
loadChildren: () => import('./role/role.module').then((mod) => mod.RoleModule),
},
{
path: 'incentive',
loadChildren: () => import('./incentive/incentive.module').then(mod => mod.IncentiveModule)
loadChildren: () => import('./incentive/incentive.module').then((mod) => mod.IncentiveModule),
},
{
path: 'issue',
loadChildren: () => import('./issue/issue.module').then(mod => mod.IssueModule)
loadChildren: () => import('./issue/issue.module').then((mod) => mod.IssueModule),
},
{
path: 'journal',
loadChildren: () => import('./journal/journal.module').then(mod => mod.JournalModule)
loadChildren: () => import('./journal/journal.module').then((mod) => mod.JournalModule),
},
{
path: 'ledger',
loadChildren: () => import('./ledger/ledger.module').then(mod => mod.LedgerModule)
loadChildren: () => import('./ledger/ledger.module').then((mod) => mod.LedgerModule),
},
{
path: 'net-transactions',
loadChildren: () => import('./net-transactions/net-transactions.module').then(mod => mod.NetTransactionsModule)
loadChildren: () =>
import('./net-transactions/net-transactions.module').then((mod) => mod.NetTransactionsModule),
},
{
path: 'payment',
loadChildren: () => import('./payment/payment.module').then(mod => mod.PaymentModule)
loadChildren: () => import('./payment/payment.module').then((mod) => mod.PaymentModule),
},
{
path: 'products',
loadChildren: () => import('./product/product.module').then(mod => mod.ProductModule)
loadChildren: () => import('./product/product.module').then((mod) => mod.ProductModule),
},
{
path: 'product-groups',
loadChildren: () => import('./product-group/product-group.module').then(mod => mod.ProductGroupModule)
loadChildren: () =>
import('./product-group/product-group.module').then((mod) => mod.ProductGroupModule),
},
{
path: 'product-ledger',
loadChildren: () => import('./product-ledger/product-ledger.module').then(mod => mod.ProductLedgerModule)
loadChildren: () =>
import('./product-ledger/product-ledger.module').then((mod) => mod.ProductLedgerModule),
},
{
path: 'profit-loss',
loadChildren: () => import('./profit-loss/profit-loss.module').then(mod => mod.ProfitLossModule)
loadChildren: () =>
import('./profit-loss/profit-loss.module').then((mod) => mod.ProfitLossModule),
},
{
path: 'purchase',
loadChildren: () => import('./purchase/purchase.module').then(mod => mod.PurchaseModule)
loadChildren: () => import('./purchase/purchase.module').then((mod) => mod.PurchaseModule),
},
{
path: 'purchase-entries',
loadChildren: () => import('./purchase-entries/purchase-entries.module').then(mod => mod.PurchaseEntriesModule)
loadChildren: () =>
import('./purchase-entries/purchase-entries.module').then((mod) => mod.PurchaseEntriesModule),
},
{
path: 'purchases',
loadChildren: () => import('./purchases/purchases.module').then(mod => mod.PurchasesModule)
loadChildren: () => import('./purchases/purchases.module').then((mod) => mod.PurchasesModule),
},
{
path: 'raw-material-cost',
loadChildren: () => import('./raw-material-cost/raw-material-cost.module').then(mod => mod.RawMaterialCostModule)
loadChildren: () =>
import('./raw-material-cost/raw-material-cost.module').then(
(mod) => mod.RawMaterialCostModule,
),
},
{
path: 'receipt',
loadChildren: () => import('./receipt/receipt.module').then(mod => mod.ReceiptModule)
loadChildren: () => import('./receipt/receipt.module').then((mod) => mod.ReceiptModule),
},
{
path: 'purchase-return',
loadChildren: () => import('./purchase-return/purchase-return.module').then(mod => mod.PurchaseReturnModule)
loadChildren: () =>
import('./purchase-return/purchase-return.module').then((mod) => mod.PurchaseReturnModule),
},
{
path: 'settings',
loadChildren: () => import('./settings/settings.module').then(mod => mod.SettingsModule)
loadChildren: () => import('./settings/settings.module').then((mod) => mod.SettingsModule),
},
{
path: 'stock-movement',
loadChildren: () => import('./stock-movement/stock-movement.module').then(mod => mod.StockMovementModule)
loadChildren: () =>
import('./stock-movement/stock-movement.module').then((mod) => mod.StockMovementModule),
},
{
path: 'trial-balance',
loadChildren: () => import('./trial-balance/trial-balance.module').then(mod => mod.TrialBalanceModule)
loadChildren: () =>
import('./trial-balance/trial-balance.module').then((mod) => mod.TrialBalanceModule),
},
{
path: 'unposted',
loadChildren: () => import('./unposted/unposted.module').then(mod => mod.UnpostedModule)
loadChildren: () => import('./unposted/unposted.module').then((mod) => mod.UnpostedModule),
},
{
path: 'users',
loadChildren: () => import('./user/user.module').then(mod => mod.UserModule)
loadChildren: () => import('./user/user.module').then((mod) => mod.UserModule),
},
{path: 'login', component: LoginComponent},
{path: 'logout', component: LogoutComponent},
{path: '', component: HomeComponent},
{ path: 'login', component: LoginComponent },
{ path: 'logout', component: LogoutComponent },
{ path: '', component: HomeComponent },
];
@NgModule({
imports: [
CommonModule,
RouterModule.forRoot(
appRoutes,
{
onSameUrlNavigation: 'reload',
// enableTracing: true <-- debugging purposes only
}
)
RouterModule.forRoot(appRoutes, {
onSameUrlNavigation: 'reload',
// enableTracing: true <-- debugging purposes only
}),
],
exports: [RouterModule],
declarations: []
declarations: [],
})
export class AppRoutingModule {
}
export class AppRoutingModule {}
+3 -5
View File
@@ -1,12 +1,10 @@
import {async, TestBed} from '@angular/core/testing';
import {AppComponent} from './app.component';
import { async, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
declarations: [AppComponent],
}).compileComponents();
}));
it('should create the app', async(() => {
+2 -2
View File
@@ -1,9 +1,9 @@
import {Component} from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'app';
+23 -31
View File
@@ -1,10 +1,10 @@
import {BrowserModule} from '@angular/platform-browser';
import {LOCALE_ID, NgModule} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { LOCALE_ID, NgModule } from '@angular/core';
import enIN from '@angular/common/locales/en-IN';
import {AppComponent} from './app.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {LayoutModule} from '@angular/cdk/layout';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@angular/cdk/layout';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider';
@@ -19,33 +19,27 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { MatToolbarModule } from '@angular/material/toolbar';
import {LoginComponent} from './auth/login/login.component';
import {AppRoutingModule} from './app-routing.module';
import {ReactiveFormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import {AuthService} from './auth/auth.service';
import {LogoutComponent} from './auth/logout/logout.component';
import {CoreModule} from './core/core.module';
import {SharedModule} from './shared/shared.module';
import {HomeComponent} from './home/home.component';
import {registerLocaleData} from '@angular/common';
import {FlexLayoutModule} from "@angular/flex-layout";
import {HotkeyModule} from "angular2-hotkeys";
import { LoginComponent } from './auth/login/login.component';
import { AppRoutingModule } from './app-routing.module';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { LogoutComponent } from './auth/logout/logout.component';
import { CoreModule } from './core/core.module';
import { SharedModule } from './shared/shared.module';
import { HomeComponent } from './home/home.component';
import { registerLocaleData } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { HotkeyModule } from 'angular2-hotkeys';
registerLocaleData(enIN);
@NgModule({
declarations: [
AppComponent,
LoginComponent,
LogoutComponent,
HomeComponent
],
declarations: [AppComponent, LoginComponent, LogoutComponent, HomeComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
FlexLayoutModule.withConfig({useColumnBasisZero: true}),
FlexLayoutModule.withConfig({ useColumnBasisZero: true }),
HotkeyModule.forRoot(),
HttpClientModule,
LayoutModule,
@@ -66,11 +60,9 @@ registerLocaleData(enIN);
ReactiveFormsModule,
SharedModule,
CoreModule,
AppRoutingModule
AppRoutingModule,
],
providers: [{provide: LOCALE_ID, useValue: 'en-IN'},
AuthService],
bootstrap: [AppComponent]
providers: [{ provide: LOCALE_ID, useValue: 'en-IN' }, AuthService],
bootstrap: [AppComponent],
})
export class AppModule {
}
export class AppModule {}
@@ -1,10 +1,8 @@
import {DataSource} from '@angular/cdk/collections';
import {Observable} from 'rxjs';
import {AttendanceItem} from './attendance';
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs';
import { AttendanceItem } from './attendance';
export class AttendanceDataSource extends DataSource<AttendanceItem> {
constructor(private data: Observable<AttendanceItem[]>) {
super();
}
@@ -13,6 +11,5 @@ export class AttendanceDataSource extends DataSource<AttendanceItem> {
return this.data;
}
disconnect() {
}
disconnect() {}
}
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AttendanceResolver} from './attendance-resolver.service';
import { AttendanceResolver } from './attendance-resolver.service';
describe('AttendanceResolver', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AttendanceResolver]
providers: [AttendanceResolver],
});
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs/internal/Observable';
import {AttendanceService} from './attendance.service';
import {Attendance} from './attendance';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { AttendanceService } from './attendance.service';
import { Attendance } from './attendance';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AttendanceResolver implements Resolve<Attendance> {
constructor(private ser: AttendanceService) {
}
constructor(private ser: AttendanceService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Attendance> {
const date = route.paramMap.get('date');
@@ -1,4 +1,4 @@
import {AttendanceRoutingModule} from './attendance-routing.module';
import { AttendanceRoutingModule } from './attendance-routing.module';
describe('AttendanceRoutingModule', () => {
let attendanceRoutingModule: AttendanceRoutingModule;
@@ -1,10 +1,10 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule, Routes} from '@angular/router';
import {AttendanceResolver} from './attendance-resolver.service';
import {AuthGuard} from '../auth/auth-guard.service';
import {AttendanceComponent} from './attendance.component';
import {AttendanceTypeResolver} from './attendance-type-resolver.service';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { AttendanceResolver } from './attendance-resolver.service';
import { AuthGuard } from '../auth/auth-guard.service';
import { AttendanceComponent } from './attendance.component';
import { AttendanceTypeResolver } from './attendance-type-resolver.service';
const attendanceRoutes: Routes = [
{
@@ -12,41 +12,32 @@ const attendanceRoutes: Routes = [
component: AttendanceComponent,
canActivate: [AuthGuard],
data: {
permission: 'Attendance'
permission: 'Attendance',
},
resolve: {
info: AttendanceResolver,
attendanceTypes: AttendanceTypeResolver
attendanceTypes: AttendanceTypeResolver,
},
runGuardsAndResolvers: 'always'
runGuardsAndResolvers: 'always',
},
{
path: ':date',
component: AttendanceComponent,
canActivate: [AuthGuard],
data: {
permission: 'Attendance'
permission: 'Attendance',
},
resolve: {
info: AttendanceResolver,
attendanceTypes: AttendanceTypeResolver
attendanceTypes: AttendanceTypeResolver,
},
runGuardsAndResolvers: 'always'
}
runGuardsAndResolvers: 'always',
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(attendanceRoutes)
],
exports: [
RouterModule
],
providers: [
AttendanceResolver
]
imports: [CommonModule, RouterModule.forChild(attendanceRoutes)],
exports: [RouterModule],
providers: [AttendanceResolver],
})
export class AttendanceRoutingModule {
}
export class AttendanceRoutingModule {}
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs/internal/Observable';
import {AttendanceType} from './attendance-type';
import {AttendanceTypeService} from './attendance-type.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { AttendanceType } from './attendance-type';
import { AttendanceTypeService } from './attendance-type.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class AttendanceTypeResolver implements Resolve<AttendanceType[]> {
constructor(private ser: AttendanceTypeService) {
}
constructor(private ser: AttendanceTypeService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<AttendanceType[]> {
return this.ser.list();
@@ -1,23 +1,22 @@
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/internal/Observable';
import {catchError} from 'rxjs/operators';
import {HttpClient} from '@angular/common/http';
import {ErrorLoggerService} from '../core/error-logger.service';
import {AttendanceType} from './attendance-type';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { ErrorLoggerService } from '../core/error-logger.service';
import { AttendanceType } from './attendance-type';
const url = '/api/attendance-types';
const serviceName = 'AttendanceTypeService';
@Injectable({providedIn: 'root'})
@Injectable({ providedIn: 'root' })
export class AttendanceTypeService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
list(): Observable<AttendanceType[]> {
return <Observable<AttendanceType[]>>this.http.get<AttendanceType[]>(url)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);
return <Observable<AttendanceType[]>>(
this.http
.get<AttendanceType[]>(url)
.pipe(catchError(this.log.handleError(serviceName, 'list')))
);
}
}
@@ -8,46 +8,46 @@
justify-content: center;
}
.present :not(.no-bg){
background-color: #228B22;
.present :not(.no-bg) {
background-color: #228b22;
}
.off-day :not(.no-bg){
background-color: #87CEFA;
.off-day :not(.no-bg) {
background-color: #87cefa;
}
.on-leave :not(.no-bg){
background-color: #CD5C5C;
.on-leave :not(.no-bg) {
background-color: #cd5c5c;
}
.absent :not(.no-bg){
background-color: #CD0000;
.absent :not(.no-bg) {
background-color: #cd0000;
}
.half-day :not(.no-bg){
background-color: #98FB98;
.half-day :not(.no-bg) {
background-color: #98fb98;
}
.double-duty :not(.no-bg){
.double-duty :not(.no-bg) {
background-color: #006400;
}
.paid-leave-availed :not(.no-bg){
background-color: #EEEE00;
.paid-leave-availed :not(.no-bg) {
background-color: #eeee00;
}
.casual-leave-availed :not(.no-bg){
.casual-leave-availed :not(.no-bg) {
background-color: #800080;
}
.compensatory-off :not(.no-bg){
background-color: #F5DEB3;
.compensatory-off :not(.no-bg) {
background-color: #f5deb3;
}
.half-day-pl :not(.no-bg){
background-color: #FFF68F;
.half-day-pl :not(.no-bg) {
background-color: #fff68f;
}
.half-day-cl :not(.no-bg){
background-color: #FF00FF;
.half-day-cl :not(.no-bg) {
background-color: #ff00ff;
}
@@ -6,37 +6,42 @@
<form [formGroup]="form" fxLayout="column">
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
<mat-form-field fxFlex="80">
<input matInput [matDatepicker]="date" (focus)="date.open()" placeholder="Date" formControlName="date"
autocomplete="off">
<input
matInput
[matDatepicker]="date"
(focus)="date.open()"
placeholder="Date"
formControlName="date"
autocomplete="off"
/>
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
<mat-datepicker #date></mat-datepicker>
</mat-form-field>
<button mat-raised-button color="primary" (click)="show()" fxFlex="20">Show</button>
</div>
<mat-table #table [dataSource]="dataSource" formArrayName="attendances">
<!-- Code Column -->
<ng-container matColumnDef="code">
<mat-header-cell *matHeaderCellDef class="right">Code</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{row.code}}</mat-cell>
<mat-cell *matCellDef="let row" class="right">{{ row.code }}</mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.name }}</mat-cell>
</ng-container>
<!-- 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>
<!-- Department Column -->
<ng-container matColumnDef="department">
<mat-header-cell *matHeaderCellDef>Department</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.department}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.department }}</mat-cell>
</ng-container>
<!-- Status Column -->
@@ -55,23 +60,34 @@
<ng-container matColumnDef="prints">
<mat-header-cell *matHeaderCellDef>Prints</mat-header-cell>
<mat-cell *matCellDef="let row; let i = index" class="no-bg">
{{row.prints}}
<mat-icon *ngIf="!form.controls.attendances.controls[i].pristine">new_releases</mat-icon>
{{ row.prints }}
<mat-icon *ngIf="!form.controls.attendances.controls[i].pristine"
>new_releases</mat-icon
>
<mat-chip-list class="no-bg">
<mat-chip *ngIf="row.hoursWorked.length" class="no-bg" [selected]="true"
[color]="row.fullDay === true ? 'primary' : 'warn'">
{{row.hoursWorked}}
<mat-chip
*ngIf="row.hoursWorked.length"
class="no-bg"
[selected]="true"
[color]="row.fullDay === true ? 'primary' : 'warn'"
>
{{ row.hoursWorked }}
</mat-chip>
</mat-chip-list>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; let i = index; columns: displayedColumns;" [class]="getClass(i)"></mat-row>
<mat-row
*matRowDef="let row; let i = index; columns: displayedColumns"
[class]="getClass(i)"
></mat-row>
</mat-table>
</form>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" (click)="save()" [disabled]="form.pristine">Save</button>
<button mat-raised-button color="primary" (click)="save()" [disabled]="form.pristine">
Save
</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 {AttendanceComponent} from './attendance.component';
import { AttendanceComponent } from './attendance.component';
describe('AttendanceComponent', () => {
let component: AttendanceComponent;
@@ -8,9 +8,8 @@ describe('AttendanceComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AttendanceComponent]
})
.compileComponents();
declarations: [AttendanceComponent],
}).compileComponents();
}));
beforeEach(() => {
@@ -1,20 +1,20 @@
import {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormGroup} from '@angular/forms';
import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import {ActivatedRoute, Router} from '@angular/router';
import {BehaviorSubject} from 'rxjs';
import {AttendanceDataSource} from './attendance-datasource';
import { ActivatedRoute, Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { AttendanceDataSource } from './attendance-datasource';
import * as moment from 'moment';
import {AuthService} from '../auth/auth.service';
import {ToasterService} from '../core/toaster.service';
import {AttendanceService} from './attendance.service';
import {AttendanceType} from './attendance-type';
import {Attendance, AttendanceItem} from './attendance';
import { AuthService } from '../auth/auth.service';
import { ToasterService } from '../core/toaster.service';
import { AttendanceService } from './attendance.service';
import { AttendanceType } from './attendance-type';
import { Attendance, AttendanceItem } from './attendance';
@Component({
selector: 'app-attendance',
templateUrl: './attendance.component.html',
styleUrls: ['./attendance.component.css']
styleUrls: ['./attendance.component.css'],
})
export class AttendanceComponent implements OnInit {
public attendanceObservable = new BehaviorSubject<AttendanceItem[]>([]);
@@ -33,7 +33,7 @@ export class AttendanceComponent implements OnInit {
private dialog: MatDialog,
private toaster: ToasterService,
private auth: AuthService,
private ser: AttendanceService
private ser: AttendanceService,
) {
this.createForm();
}
@@ -41,32 +41,34 @@ export class AttendanceComponent implements OnInit {
createForm() {
this.form = this.fb.group({
date: '',
attendances: this.fb.array([])
attendances: this.fb.array([]),
});
}
ngOnInit() {
this.route.data
.subscribe((data: { info: Attendance, attendanceTypes: AttendanceType[] }) => {
this.info = data.info;
this.attendanceTypes = data.attendanceTypes;
this.form.get('date').setValue(moment(this.info.date, 'DD-MMM-YYYY').toDate());
this.form.setControl('attendances', this.fb.array(
this.info.body.map(
x => this.fb.group({
attendanceType: x.attendanceType.id
})
)
));
this.dataSource = new AttendanceDataSource(this.attendanceObservable);
this.attendanceObservable.next(this.info.body);
});
this.route.data.subscribe((data: { info: Attendance; attendanceTypes: AttendanceType[] }) => {
this.info = data.info;
this.attendanceTypes = data.attendanceTypes;
this.form.get('date').setValue(moment(this.info.date, 'DD-MMM-YYYY').toDate());
this.form.setControl(
'attendances',
this.fb.array(
this.info.body.map((x) =>
this.fb.group({
attendanceType: x.attendanceType.id,
}),
),
),
);
this.dataSource = new AttendanceDataSource(this.attendanceObservable);
this.attendanceObservable.next(this.info.body);
});
}
getClass(index: number) {
const array = this.form.get('attendances') as FormArray;
const id = array.controls[index].value.attendanceType;
const name: string = this.attendanceTypes.filter(x => x.id === id)[0].name;
const name: string = this.attendanceTypes.filter((x) => x.id === id)[0].name;
return name.toLowerCase().replace(/(\s+\+\s+)|(\s+)/g, '-');
}
@@ -76,15 +78,14 @@ export class AttendanceComponent implements OnInit {
}
save() {
this.ser.save(this.getAttendance())
.subscribe(
(result) => {
this.toaster.show('Success', '');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.save(this.getAttendance()).subscribe(
(result) => {
this.toaster.show('Success', '');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
getAttendance(): Attendance {
@@ -1,4 +1,4 @@
import {AttendanceModule} from './attendance.module';
import { AttendanceModule } from './attendance.module';
describe('AttendanceModule', () => {
let attendanceModule: AttendanceModule;
@@ -1,11 +1,16 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatNativeDateModule } from '@angular/material/core';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
MatNativeDateModule,
} from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
@@ -16,14 +21,14 @@ 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 {SharedModule} from '../shared/shared.module';
import {ReactiveFormsModule} from '@angular/forms';
import {CdkTableModule} from '@angular/cdk/table';
import {AttendanceRoutingModule} from './attendance-routing.module';
import {AttendanceComponent} from './attendance.component';
import {MomentDateAdapter} from '@angular/material-moment-adapter';
import {A11yModule} from '@angular/cdk/a11y';
import {FlexLayoutModule} from '@angular/flex-layout';
import { SharedModule } from '../shared/shared.module';
import { ReactiveFormsModule } from '@angular/forms';
import { CdkTableModule } from '@angular/cdk/table';
import { AttendanceRoutingModule } from './attendance-routing.module';
import { AttendanceComponent } from './attendance.component';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { A11yModule } from '@angular/cdk/a11y';
import { FlexLayoutModule } from '@angular/flex-layout';
export const MY_FORMATS = {
parse: {
@@ -61,15 +66,12 @@ export const MY_FORMATS = {
MatTableModule,
ReactiveFormsModule,
SharedModule,
AttendanceRoutingModule
],
declarations: [
AttendanceComponent
AttendanceRoutingModule,
],
declarations: [AttendanceComponent],
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 AttendanceModule {
}
export class AttendanceModule {}
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {VoucherService} from './attendance.service';
import { VoucherService } from './attendance.service';
describe('AttendanceService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [VoucherService]
providers: [VoucherService],
});
});
@@ -1,35 +1,35 @@
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/internal/Observable';
import {catchError} from 'rxjs/operators';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Attendance} from './attendance';
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 } from '@angular/common/http';
import { Attendance } from './attendance';
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/attendance';
const serviceName = 'AttendanceService';
@Injectable({providedIn: 'root'})
@Injectable({ providedIn: 'root' })
export class AttendanceService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
get(date: string): Observable<Attendance> {
const getUrl: string = (date === null) ? url : `${url}/${date}`;
return <Observable<Attendance>>this.http.get<Attendance>(getUrl)
.pipe(
catchError(this.log.handleError(serviceName, `get date=${date}`))
);
const getUrl: string = date === null ? url : `${url}/${date}`;
return <Observable<Attendance>>(
this.http
.get<Attendance>(getUrl)
.pipe(catchError(this.log.handleError(serviceName, `get date=${date}`)))
);
}
save(attendance: Attendance): Observable<Attendance> {
return <Observable<Attendance>>this.http.post<Attendance>(`${url}/${attendance.date}`, attendance, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'save'))
);
return <Observable<Attendance>>(
this.http
.post<Attendance>(`${url}/${attendance.date}`, attendance, httpOptions)
.pipe(catchError(this.log.handleError(serviceName, 'save')))
);
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
import {AttendanceType} from './attendance-type';
import { AttendanceType } from './attendance-type';
export class Attendance {
date: string;
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AuthGuardService} from './auth-guard.service';
import { AuthGuardService } from './auth-guard.service';
describe('AuthGuardService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AuthGuardService]
providers: [AuthGuardService],
});
});
+12 -13
View File
@@ -1,26 +1,26 @@
import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import {AuthService} from './auth.service';
import {ToasterService} from '../core/toaster.service';
import { AuthService } from './auth.service';
import { ToasterService } from '../core/toaster.service';
@Injectable({providedIn: 'root'})
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private authService: AuthService,
private toaster: ToasterService
) {
}
private toaster: ToasterService,
) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const user = this.authService.user;
const permission = (route.data['permission'] === undefined) ? route.data['permission'] : route.data['permission']
.replace(/ /g, '-')
.toLowerCase();
const permission =
route.data['permission'] === undefined
? route.data['permission']
: route.data['permission'].replace(/ /g, '-').toLowerCase();
if (!user) {
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
if (permission !== undefined && user.perms.indexOf(permission) === -1) {
@@ -29,6 +29,5 @@ export class AuthGuard implements CanActivate {
}
// logged in so return true
return true;
}
}
+3 -3
View File
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {AuthService} from './auth.service';
import { AuthService } from './auth.service';
describe('AuthService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [AuthService]
providers: [AuthService],
});
});
+35 -24
View File
@@ -10,7 +10,7 @@ const loginUrl = '/token';
const refreshUrl = '/refresh';
const JWT_USER = 'JWT_USER';
@Injectable({providedIn: 'root'})
@Injectable({ providedIn: 'root' })
export class AuthService {
private currentUserSubject: BehaviorSubject<User>;
public currentUser: Observable<User>;
@@ -57,23 +57,31 @@ export class AuthService {
formData.append('password', password);
formData.append('otp', otp);
formData.append('grant_type', 'password');
return this.http.post<any>(loginUrl, formData)
.pipe(map(u => u.access_token))
.pipe(map(u => this.parseJwt(u)))
.pipe(map(user => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem(JWT_USER, JSON.stringify(user));
this.currentUserSubject.next(user);
return user;
}));
return this.http
.post<any>(loginUrl, formData)
.pipe(map((u) => u.access_token))
.pipe(map((u) => this.parseJwt(u)))
.pipe(
map((user) => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem(JWT_USER, JSON.stringify(user));
this.currentUserSubject.next(user);
return user;
}),
);
}
parseJwt(token): User {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
const jsonPayload = decodeURIComponent(
atob(base64)
.split('')
.map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
})
.join(''),
);
const decoded = JSON.parse(jsonPayload);
return new User({
@@ -82,12 +90,12 @@ export class AuthService {
lockedOut: decoded.lockedOut,
perms: decoded.scopes,
access_token: token,
exp: decoded.exp
exp: decoded.exp,
});
}
needsRefreshing(): boolean {
return Date.now() > (this.user.exp - (environment.ACCESS_TOKEN_REFRESH_MINUTES * 60)) * 1000;
return Date.now() > (this.user.exp - environment.ACCESS_TOKEN_REFRESH_MINUTES * 60) * 1000;
}
logout() {
@@ -97,14 +105,17 @@ export class AuthService {
}
refreshToken() {
return this.http.post<any>(refreshUrl, {})
.pipe(map(u => u.access_token))
.pipe(map(u => this.parseJwt(u)))
.pipe(map(user => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem(JWT_USER, JSON.stringify(user));
this.currentUserSubject.next(user);
return user;
}));
return this.http
.post<any>(refreshUrl, {})
.pipe(map((u) => u.access_token))
.pipe(map((u) => this.parseJwt(u)))
.pipe(
map((user) => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem(JWT_USER, JSON.stringify(user));
this.currentUserSubject.next(user);
return user;
}),
);
}
}
@@ -7,23 +7,36 @@
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
<mat-form-field fxFlex>
<mat-label>Username</mat-label>
<input matInput #nameElement placeholder="Username" formControlName="username">
<input matInput #nameElement placeholder="Username" formControlName="username" />
</mat-form-field>
</div>
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
<mat-form-field fxFlex>
<mat-label>Password</mat-label>
<input matInput placeholder="Password" formControlName="password" [type]="hide ? 'password' : 'text'"
(keyup.enter)="login()">
<mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon>
<input
matInput
placeholder="Password"
formControlName="password"
[type]="hide ? 'password' : 'text'"
(keyup.enter)="login()"
/>
<mat-icon matSuffix (click)="hide = !hide">{{
hide ? 'visibility' : 'visibility_off'
}}</mat-icon>
</mat-form-field>
</div>
<mat-divider></mat-divider>
<h2 *ngIf="showOtp">Client ID: {{clientId}}</h2>
<div fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px" *ngIf="showOtp">
<h2 *ngIf="showOtp">Client ID: {{ clientId }}</h2>
<div
fxLayout="row"
fxLayout.lt-md="column"
fxLayoutGap="20px"
fxLayoutGap.lt-md="0px"
*ngIf="showOtp"
>
<mat-form-field fxFlex>
<mat-label>Otp</mat-label>
<input matInput placeholder="Otp" formControlName="otp">
<input matInput placeholder="Otp" formControlName="otp" />
</mat-form-field>
</div>
</form>
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {LoginComponent} from './login.component';
import { LoginComponent } from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
@@ -8,9 +8,8 @@ describe('LoginComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LoginComponent]
})
.compileComponents();
declarations: [LoginComponent],
}).compileComponents();
}));
beforeEach(() => {
+73 -71
View File
@@ -1,71 +1,73 @@
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {AuthService} from '../auth.service';
import {ActivatedRoute, Router} from '@angular/router';
import {ToasterService} from '../../core/toaster.service';
import {FormBuilder, FormGroup} from '@angular/forms';
import {CookieService} from '../../shared/cookie.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit, AfterViewInit {
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
form: FormGroup;
hide: boolean;
showOtp: boolean;
clientId: string;
private returnUrl: string;
constructor(private route: ActivatedRoute,
private auth: AuthService,
private router: Router,
private toaster: ToasterService,
private cs: CookieService,
private fb: FormBuilder
) {
this.hide = true;
this.showOtp = false;
this.createForm();
}
createForm() {
this.form = this.fb.group({
username: '',
password: '',
otp: ''
});
}
ngOnInit() {
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
ngAfterViewInit() {
setTimeout(() => {
this.nameElement.nativeElement.focus();
}, 0);
}
login(): void {
const formModel = this.form.value;
const username = formModel.username;
const password = formModel.password;
const otp = formModel.otp;
this.auth.login(username, password, otp)
// .pipe(first())
.subscribe(
data => {
this.router.navigate([this.returnUrl]);
},
(error) => {
if (error.status === 401 && 'Client is not registered' === error.error.detail) {
this.showOtp = true;
this.clientId = this.cs.getCookie('client_id');
}
this.toaster.show('Danger', error.error.details);
}
)
}
}
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AuthService } from '../auth.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ToasterService } from '../../core/toaster.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { CookieService } from '../../shared/cookie.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit, AfterViewInit {
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
form: FormGroup;
hide: boolean;
showOtp: boolean;
clientId: string;
private returnUrl: string;
constructor(
private route: ActivatedRoute,
private auth: AuthService,
private router: Router,
private toaster: ToasterService,
private cs: CookieService,
private fb: FormBuilder,
) {
this.hide = true;
this.showOtp = false;
this.createForm();
}
createForm() {
this.form = this.fb.group({
username: '',
password: '',
otp: '',
});
}
ngOnInit() {
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
ngAfterViewInit() {
setTimeout(() => {
this.nameElement.nativeElement.focus();
}, 0);
}
login(): void {
const formModel = this.form.value;
const username = formModel.username;
const password = formModel.password;
const otp = formModel.otp;
this.auth
.login(username, password, otp)
// .pipe(first())
.subscribe(
(data) => {
this.router.navigate([this.returnUrl]);
},
(error) => {
if (error.status === 401 && 'Client is not registered' === error.error.detail) {
this.showOtp = true;
this.clientId = this.cs.getCookie('client_id');
}
this.toaster.show('Danger', error.error.details);
},
);
}
}
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {LogoutComponent} from './logout.component';
import { LogoutComponent } from './logout.component';
describe('LogoutComponent', () => {
let component: LogoutComponent;
@@ -8,9 +8,8 @@ describe('LogoutComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LogoutComponent]
})
.compileComponents();
declarations: [LogoutComponent],
}).compileComponents();
}));
beforeEach(() => {
@@ -1,19 +1,16 @@
import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {AuthService} from '../auth.service';
import {ToasterService} from '../../core/toaster.service';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../auth.service';
import { ToasterService } from '../../core/toaster.service';
@Component({
selector: 'app-logout',
template: ''
template: '',
})
export class LogoutComponent implements OnInit {
constructor(private auth: AuthService, private router: Router, private toaster: ToasterService) {
}
constructor(private auth: AuthService, private router: Router, private toaster: ToasterService) {}
ngOnInit() {
this.auth.logout();
}
}
@@ -1,33 +1,28 @@
import {DataSource} from '@angular/cdk/collections';
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import {map} from 'rxjs/operators';
import {merge, Observable, of as observableOf} from 'rxjs';
import { map } from 'rxjs/operators';
import { merge, Observable, of as observableOf } from 'rxjs';
export class BalanceSheetDataSource extends DataSource<any> {
constructor(private paginator: MatPaginator, private sort: MatSort, public data: any[]) {
super();
}
connect(): Observable<any[]> {
const dataMutations = [
observableOf(this.data),
this.paginator.page,
this.sort.sortChange
];
const dataMutations = [observableOf(this.data), this.paginator.page, this.sort.sortChange];
// Set the paginators length
this.paginator.length = this.data.length;
return merge(...dataMutations).pipe(map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}));
return merge(...dataMutations).pipe(
map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}),
);
}
disconnect() {
}
disconnect() {}
private getPagedData(data: any[]) {
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {BalanceSheetResolver} from './balance-sheet-resolver.service';
import { BalanceSheetResolver } from './balance-sheet-resolver.service';
describe('BalanceSheetResolver', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [BalanceSheetResolver]
providers: [BalanceSheetResolver],
});
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs/internal/Observable';
import {BalanceSheet} from './balance-sheet';
import {BalanceSheetService} from './balance-sheet.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { BalanceSheet } from './balance-sheet';
import { BalanceSheetService } from './balance-sheet.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class BalanceSheetResolver implements Resolve<BalanceSheet> {
constructor(private ser: BalanceSheetService) {
}
constructor(private ser: BalanceSheetService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<BalanceSheet> {
const date = route.paramMap.get('date');
@@ -1,4 +1,4 @@
import {BalanceSheetRoutingModule} from './balance-sheet-routing.module';
import { BalanceSheetRoutingModule } from './balance-sheet-routing.module';
describe('BalanceSheetRoutingModule', () => {
let balanceSheetRoutingModule: BalanceSheetRoutingModule;
@@ -1,9 +1,9 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule, Routes} from '@angular/router';
import {BalanceSheetResolver} from './balance-sheet-resolver.service';
import {AuthGuard} from '../auth/auth-guard.service';
import {BalanceSheetComponent} from './balance-sheet.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { BalanceSheetResolver } from './balance-sheet-resolver.service';
import { AuthGuard } from '../auth/auth-guard.service';
import { BalanceSheetComponent } from './balance-sheet.component';
const balanceSheetRoutes: Routes = [
{
@@ -11,37 +11,28 @@ const balanceSheetRoutes: Routes = [
component: BalanceSheetComponent,
canActivate: [AuthGuard],
data: {
permission: 'Balance Sheet'
permission: 'Balance Sheet',
},
resolve: {
info: BalanceSheetResolver
}
info: BalanceSheetResolver,
},
},
{
path: ':date',
component: BalanceSheetComponent,
canActivate: [AuthGuard],
data: {
permission: 'Balance Sheet'
permission: 'Balance Sheet',
},
resolve: {
info: BalanceSheetResolver
}
}
info: BalanceSheetResolver,
},
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(balanceSheetRoutes)
],
exports: [
RouterModule
],
providers: [
BalanceSheetResolver
]
imports: [CommonModule, RouterModule.forChild(balanceSheetRoutes)],
exports: [RouterModule],
providers: [BalanceSheetResolver],
})
export class BalanceSheetRoutingModule {
}
export class BalanceSheetRoutingModule {}
@@ -4,11 +4,22 @@
</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 matInput [matDatepicker]="dateInput" (focus)="dateInput.open()" placeholder="Date"
formControlName="date" autocomplete="off">
<input
matInput
[matDatepicker]="dateInput"
(focus)="dateInput.open()"
placeholder="Date"
formControlName="date"
autocomplete="off"
/>
<mat-datepicker-toggle matSuffix [for]="dateInput"></mat-datepicker-toggle>
<mat-datepicker #dateInput></mat-datepicker>
</mat-form-field>
@@ -16,48 +27,54 @@
</div>
</form>
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
<!-- Group Column -->
<ng-container matColumnDef="group">
<mat-header-cell *matHeaderCellDef mat-sort-header>Group</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.group}}</mat-cell>
<mat-footer-cell *matFooterCellDef>{{info.footer?.group}}</mat-footer-cell>
<mat-cell *matCellDef="let row">{{ row.group }}</mat-cell>
<mat-footer-cell *matFooterCellDef>{{ info.footer?.group }}</mat-footer-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
<mat-footer-cell *matFooterCellDef>{{info.footer?.name}}</mat-footer-cell>
<mat-cell *matCellDef="let row">{{ row.name }}</mat-cell>
<mat-footer-cell *matFooterCellDef>{{ info.footer?.name }}</mat-footer-cell>
</ng-container>
<!-- SubAmount Column -->
<ng-container matColumnDef="subAmount">
<mat-header-cell *matHeaderCellDef mat-sort-header class="right">Amount</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{row.subAmount | currency:'INR' | clear}}</mat-cell>
<mat-footer-cell *matFooterCellDef class="right">{{info.footer?.subAmount | currency:'INR' | clear}}
<mat-cell *matCellDef="let row" class="right">{{
row.subAmount | currency: 'INR' | clear
}}</mat-cell>
<mat-footer-cell *matFooterCellDef class="right"
>{{ info.footer?.subAmount | currency: 'INR' | clear }}
</mat-footer-cell>
</ng-container>
<!-- Total Column -->
<ng-container matColumnDef="total">
<mat-header-cell *matHeaderCellDef mat-sort-header class="right">Total</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{row.amount | currency:'INR' | clear}}</mat-cell>
<mat-footer-cell *matFooterCellDef class="right">{{info.footer?.amount | currency:'INR' | clear}}
<mat-cell *matCellDef="let row" class="right">{{
row.amount | currency: 'INR' | clear
}}</mat-cell>
<mat-footer-cell *matFooterCellDef class="right"
>{{ info.footer?.amount | currency: 'INR' | clear }}
</mat-footer-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-footer-row *matFooterRowDef="displayedColumns"></mat-footer-row>
</mat-table>
<mat-paginator #paginator
[length]="dataSource.data.length"
[pageIndex]="0"
[pageSize]="50"
[pageSizeOptions]="[25, 50, 100, 250, 300, 5000]">
<mat-paginator
#paginator
[length]="dataSource.data.length"
[pageIndex]="0"
[pageSize]="50"
[pageSizeOptions]="[25, 50, 100, 250, 300, 5000]"
>
</mat-paginator>
</mat-card-content>
</mat-card>
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {BalanceSheetComponent} from './balance-sheet.component';
import { BalanceSheetComponent } from './balance-sheet.component';
describe('BalanceSheetComponent', () => {
let component: BalanceSheetComponent;
@@ -8,9 +8,8 @@ describe('BalanceSheetComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [BalanceSheetComponent]
})
.compileComponents();
declarations: [BalanceSheetComponent],
}).compileComponents();
}));
beforeEach(() => {
@@ -1,16 +1,16 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import {BalanceSheetDataSource} from './balance-sheet-datasource';
import {BalanceSheet} from './balance-sheet';
import {ActivatedRoute, Router} from '@angular/router';
import { BalanceSheetDataSource } from './balance-sheet-datasource';
import { BalanceSheet } from './balance-sheet';
import { ActivatedRoute, Router } from '@angular/router';
import * as moment from 'moment';
import {FormBuilder, FormGroup} from '@angular/forms';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-balance-sheet',
templateUrl: './balance-sheet.component.html',
styleUrls: ['./balance-sheet.component.css']
styleUrls: ['./balance-sheet.component.css'],
})
export class BalanceSheetComponent implements OnInit {
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@@ -27,18 +27,17 @@ export class BalanceSheetComponent implements OnInit {
createForm() {
this.form = this.fb.group({
date: ''
date: '',
});
}
ngOnInit() {
this.route.data
.subscribe((data: { info: BalanceSheet }) => {
this.info = data.info;
this.form.setValue({
date: moment(this.info.date, 'DD-MMM-YYYY').toDate()
});
this.route.data.subscribe((data: { info: BalanceSheet }) => {
this.info = data.info;
this.form.setValue({
date: moment(this.info.date, 'DD-MMM-YYYY').toDate(),
});
});
this.dataSource = new BalanceSheetDataSource(this.paginator, this.sort, this.info.body);
}
@@ -49,6 +48,6 @@ export class BalanceSheetComponent implements OnInit {
getDate(): string {
const formModel = this.form.value;
return moment(formModel.date).format('DD-MMM-YYYY');
return moment(formModel.date).format('DD-MMM-YYYY');
}
}
@@ -1,4 +1,4 @@
import {BalanceSheetModule} from './balance-sheet.module';
import { BalanceSheetModule } from './balance-sheet.module';
describe('BalanceSheetModule', () => {
let balanceSheetModule: BalanceSheetModule;
@@ -1,9 +1,14 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
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, MatNativeDateModule } from '@angular/material/core';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
MatNativeDateModule,
} from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
@@ -11,13 +16,13 @@ import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import {SharedModule} from '../shared/shared.module';
import {CdkTableModule} from '@angular/cdk/table';
import {BalanceSheetRoutingModule} from './balance-sheet-routing.module';
import {BalanceSheetComponent} from './balance-sheet.component';
import {MomentDateAdapter} from '@angular/material-moment-adapter';
import {FlexLayoutModule} from '@angular/flex-layout';
import {ReactiveFormsModule} from '@angular/forms';
import { SharedModule } from '../shared/shared.module';
import { CdkTableModule } from '@angular/cdk/table';
import { BalanceSheetRoutingModule } from './balance-sheet-routing.module';
import { BalanceSheetComponent } from './balance-sheet.component';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { FlexLayoutModule } from '@angular/flex-layout';
import { ReactiveFormsModule } from '@angular/forms';
export const MY_FORMATS = {
parse: {
@@ -49,15 +54,12 @@ export const MY_FORMATS = {
MatTableModule,
ReactiveFormsModule,
SharedModule,
BalanceSheetRoutingModule
],
declarations: [
BalanceSheetComponent
BalanceSheetRoutingModule,
],
declarations: [BalanceSheetComponent],
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 BalanceSheetModule {
}
export class BalanceSheetModule {}
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {BalanceSheetService} from './balance-sheet.service';
import { BalanceSheetService } from './balance-sheet.service';
describe('BalanceSheetService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [BalanceSheetService]
providers: [BalanceSheetService],
});
});
@@ -1,31 +1,29 @@
import {Injectable} from '@angular/core';
import {catchError} from 'rxjs/operators';
import {Observable} from 'rxjs/internal/Observable';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {BalanceSheet} from './balance-sheet';
import {ErrorLoggerService} from '../core/error-logger.service';
import { Injectable } from '@angular/core';
import { catchError } from 'rxjs/operators';
import { Observable } from 'rxjs/internal/Observable';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BalanceSheet } from './balance-sheet';
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/balance-sheet';
const serviceName = 'BalanceSheetService';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class BalanceSheetService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
list(date: string): Observable<BalanceSheet> {
const listUrl = (date === null) ? url : `${url}/${date}`;
return <Observable<BalanceSheet>>this.http.get<BalanceSheet>(listUrl)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);
const listUrl = date === null ? url : `${url}/${date}`;
return <Observable<BalanceSheet>>(
this.http
.get<BalanceSheet>(listUrl)
.pipe(catchError(this.log.handleError(serviceName, 'list')))
);
}
}
@@ -1,10 +1,8 @@
import {DataSource} from '@angular/cdk/collections';
import {Observable, of as observableOf} from 'rxjs';
import {CashFlowItem} from './cash-flow';
import { DataSource } from '@angular/cdk/collections';
import { Observable, of as observableOf } from 'rxjs';
import { CashFlowItem } from './cash-flow';
export class CashFlowDataSource extends DataSource<CashFlowItem> {
constructor(private data: CashFlowItem[]) {
super();
}
@@ -13,6 +11,5 @@ export class CashFlowDataSource extends DataSource<CashFlowItem> {
return observableOf(this.data);
}
disconnect() {
}
disconnect() {}
}
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {CashFlowResolver} from './cash-flow-resolver.service';
import { CashFlowResolver } from './cash-flow-resolver.service';
describe('CashFlowResolver', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CashFlowResolver]
providers: [CashFlowResolver],
});
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs/internal/Observable';
import {CashFlow} from './cash-flow';
import {CashFlowService} from './cash-flow.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { CashFlow } from './cash-flow';
import { CashFlowService } from './cash-flow.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class CashFlowResolver implements Resolve<CashFlow> {
constructor(private ser: CashFlowService) {
}
constructor(private ser: CashFlowService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<CashFlow> {
const id = route.paramMap.get('id');
@@ -1,4 +1,4 @@
import {CashFlowRoutingModule} from './cash-flow-routing.module';
import { CashFlowRoutingModule } from './cash-flow-routing.module';
describe('CashFlowRoutingModule', () => {
let cashFlowRoutingModule: CashFlowRoutingModule;
@@ -1,9 +1,9 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule, Routes} from '@angular/router';
import {CashFlowResolver} from './cash-flow-resolver.service';
import {AuthGuard} from '../auth/auth-guard.service';
import {CashFlowComponent} from './cash-flow.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { CashFlowResolver } from './cash-flow-resolver.service';
import { AuthGuard } from '../auth/auth-guard.service';
import { CashFlowComponent } from './cash-flow.component';
const cashFlowRoutes: Routes = [
{
@@ -11,39 +11,30 @@ const cashFlowRoutes: Routes = [
component: CashFlowComponent,
canActivate: [AuthGuard],
data: {
permission: 'Cash Flow'
permission: 'Cash Flow',
},
resolve: {
info: CashFlowResolver
info: CashFlowResolver,
},
runGuardsAndResolvers: 'always'
runGuardsAndResolvers: 'always',
},
{
path: ':id',
component: CashFlowComponent,
canActivate: [AuthGuard],
data: {
permission: 'Cash Flow'
permission: 'Cash Flow',
},
resolve: {
info: CashFlowResolver
info: CashFlowResolver,
},
runGuardsAndResolvers: 'always'
}
runGuardsAndResolvers: 'always',
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(cashFlowRoutes)
],
exports: [
RouterModule
],
providers: [
CashFlowResolver
]
imports: [CommonModule, RouterModule.forChild(cashFlowRoutes)],
exports: [RouterModule],
providers: [CashFlowResolver],
})
export class CashFlowRoutingModule {
}
export class CashFlowRoutingModule {}
@@ -4,17 +4,34 @@
</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="40">
<input matInput [matDatepicker]="startDate" (focus)="startDate.open()" placeholder="Start Date"
formControlName="startDate" autocomplete="off">
<input
matInput
[matDatepicker]="startDate"
(focus)="startDate.open()"
placeholder="Start Date"
formControlName="startDate"
autocomplete="off"
/>
<mat-datepicker-toggle matSuffix [for]="startDate"></mat-datepicker-toggle>
<mat-datepicker #startDate></mat-datepicker>
</mat-form-field>
<mat-form-field fxFlex="40">
<input matInput [matDatepicker]="finishDate" (focus)="finishDate.open()" placeholder="Finish Date"
formControlName="finishDate" autocomplete="off">
<input
matInput
[matDatepicker]="finishDate"
(focus)="finishDate.open()"
placeholder="Finish Date"
formControlName="finishDate"
autocomplete="off"
/>
<mat-datepicker-toggle matSuffix [for]="finishDate"></mat-datepicker-toggle>
<mat-datepicker #finishDate></mat-datepicker>
</mat-form-field>
@@ -22,21 +39,28 @@
</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]="row.url" [queryParams]="{startDate: info.startDate, finishDate: info.finishDate}">{{row.name}} </a></mat-cell>
<mat-cell *matCellDef="let row"
><a
[routerLink]="row.url"
[queryParams]="{ startDate: info.startDate, finishDate: info.finishDate }"
>{{ row.name }}
</a></mat-cell
>
</ng-container>
<!-- Amount Column -->
<ng-container matColumnDef="amount">
<mat-header-cell *matHeaderCellDef mat-sort-header class="right">Amount</mat-header-cell>
<mat-cell *matCellDef="let row" class="right">{{row.amount | currency:'INR' | clear}}</mat-cell>
<mat-cell *matCellDef="let row" class="right">{{
row.amount | currency: 'INR' | clear
}}</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-card-content>
</mat-card>
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {CashFlowComponent} from './cash-flow.component';
import { CashFlowComponent } from './cash-flow.component';
describe('CashFlowComponent', () => {
let component: CashFlowComponent;
@@ -8,9 +8,8 @@ describe('CashFlowComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CashFlowComponent]
})
.compileComponents();
declarations: [CashFlowComponent],
}).compileComponents();
}));
beforeEach(() => {
@@ -1,14 +1,14 @@
import {Component, OnInit} from '@angular/core';
import {CashFlowDataSource} from './cash-flow-datasource';
import {CashFlow} from './cash-flow';
import {ActivatedRoute, Router} from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { CashFlowDataSource } from './cash-flow-datasource';
import { CashFlow } from './cash-flow';
import { ActivatedRoute, Router } from '@angular/router';
import * as moment from 'moment';
import {FormBuilder, FormGroup} from '@angular/forms';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-cash-flow',
templateUrl: './cash-flow.component.html',
styleUrls: ['./cash-flow.component.css']
styleUrls: ['./cash-flow.component.css'],
})
export class CashFlowComponent implements OnInit {
dataSource: CashFlowDataSource;
@@ -24,20 +24,19 @@ export class CashFlowComponent implements OnInit {
createForm() {
this.form = this.fb.group({
startDate: '',
finishDate: ''
finishDate: '',
});
}
ngOnInit() {
this.route.data
.subscribe((data: { info: CashFlow }) => {
this.info = data.info;
this.form.setValue({
startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(),
finishDate: moment(this.info.finishDate, 'DD-MMM-YYYY').toDate()
});
this.dataSource = new CashFlowDataSource(CashFlow.Data(this.info));
this.route.data.subscribe((data: { info: CashFlow }) => {
this.info = data.info;
this.form.setValue({
startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(),
finishDate: moment(this.info.finishDate, 'DD-MMM-YYYY').toDate(),
});
this.dataSource = new CashFlowDataSource(CashFlow.Data(this.info));
});
}
show() {
@@ -45,8 +44,8 @@ export class CashFlowComponent implements OnInit {
this.router.navigate(['cash-flow'], {
queryParams: {
startDate: info.startDate,
finishDate: info.finishDate
}
finishDate: info.finishDate,
},
});
}
@@ -55,7 +54,7 @@ export class CashFlowComponent implements OnInit {
return {
startDate: moment(formModel.startDate).format('DD-MMM-YYYY'),
finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY')
finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'),
};
}
}
@@ -1,4 +1,4 @@
import {CashFlowModule} from './cash-flow.module';
import { CashFlowModule } from './cash-flow.module';
describe('CashFlowModule', () => {
let cashFlowModule: CashFlowModule;
+21 -19
View File
@@ -1,9 +1,14 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
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, MatNativeDateModule } from '@angular/material/core';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
MatNativeDateModule,
} from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
@@ -11,13 +16,13 @@ import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import {SharedModule} from '../shared/shared.module';
import {CdkTableModule} from '@angular/cdk/table';
import {CashFlowRoutingModule} from './cash-flow-routing.module';
import {CashFlowComponent} from './cash-flow.component';
import {MomentDateAdapter} from '@angular/material-moment-adapter';
import {FlexLayoutModule} from '@angular/flex-layout';
import {ReactiveFormsModule} from '@angular/forms';
import { SharedModule } from '../shared/shared.module';
import { CdkTableModule } from '@angular/cdk/table';
import { CashFlowRoutingModule } from './cash-flow-routing.module';
import { CashFlowComponent } from './cash-flow.component';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { FlexLayoutModule } from '@angular/flex-layout';
import { ReactiveFormsModule } from '@angular/forms';
export const MY_FORMATS = {
parse: {
@@ -49,15 +54,12 @@ export const MY_FORMATS = {
MatTableModule,
ReactiveFormsModule,
SharedModule,
CashFlowRoutingModule
],
declarations: [
CashFlowComponent
CashFlowRoutingModule,
],
declarations: [CashFlowComponent],
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 CashFlowModule {
}
export class CashFlowModule {}
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {CashFlowService} from './cash-flow.service';
import { CashFlowService } from './cash-flow.service';
describe('CashFlowService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CashFlowService]
providers: [CashFlowService],
});
});
+16 -18
View File
@@ -1,38 +1,36 @@
import {Injectable} from '@angular/core';
import {catchError} from 'rxjs/operators';
import {Observable} from 'rxjs/internal/Observable';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {CashFlow} from './cash-flow';
import {ErrorLoggerService} from '../core/error-logger.service';
import { Injectable } from '@angular/core';
import { catchError } from 'rxjs/operators';
import { Observable } from 'rxjs/internal/Observable';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { CashFlow } from './cash-flow';
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/cash-flow';
const serviceName = 'CashFlowService';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class CashFlowService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
list(id: string, startDate: string, finishDate: string): Observable<CashFlow> {
const options = {params: new HttpParams()};
const options = { params: new HttpParams() };
if (startDate !== null) {
options.params = options.params.set('s', startDate);
}
if (finishDate !== null) {
options.params = options.params.set('f', finishDate);
}
const listUrl = (id === null) ? ( (startDate || finishDate) ? `${url}/data` : url) : `${url}/${id}`;
return <Observable<CashFlow>>this.http.get<CashFlow>(listUrl, options)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);
const listUrl = id === null ? (startDate || finishDate ? `${url}/data` : url) : `${url}/${id}`;
return <Observable<CashFlow>>(
this.http
.get<CashFlow>(listUrl, options)
.pipe(catchError(this.log.handleError(serviceName, 'list')))
);
}
}
+6 -1
View File
@@ -11,7 +11,12 @@ export class CashFlowItem {
export class CashFlow {
startDate: string;
finishDate: string;
body?: { operating: CashFlowItem[], investing: CashFlowItem[], financing: CashFlowItem[], details: CashFlowItem[] };
body?: {
operating: CashFlowItem[];
investing: CashFlowItem[];
financing: CashFlowItem[];
details: CashFlowItem[];
};
footer?: CashFlowItem[];
static Data(value): CashFlowItem[] {
@@ -5,29 +5,49 @@
</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>
<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" 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="enabled">Is Enabled?</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>OTP</mat-label>
<input matInput placeholder="OTP" formControlName="otp">
<input matInput placeholder="OTP" formControlName="otp" />
</mat-form-field>
</div>
</form>
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {ClientDetailComponent} from './client-detail.component';
import { ClientDetailComponent } from './client-detail.component';
describe('ClientDetailComponent', () => {
let component: ClientDetailComponent;
@@ -8,9 +8,8 @@ describe('ClientDetailComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ClientDetailComponent]
})
.compileComponents();
declarations: [ClientDetailComponent],
}).compileComponents();
}));
beforeEach(() => {
@@ -1,17 +1,17 @@
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import {ClientService} from '../client.service';
import {Client} from '../client';
import {ActivatedRoute, Router} from '@angular/router';
import {ToasterService} from '../../core/toaster.service';
import {ConfirmDialogComponent} from '../../shared/confirm-dialog/confirm-dialog.component';
import { ClientService } from '../client.service';
import { Client } from '../client';
import { ActivatedRoute, Router } from '@angular/router';
import { ToasterService } from '../../core/toaster.service';
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-client-detail',
templateUrl: './client-detail.component.html',
styleUrls: ['./client-detail.component.css']
styleUrls: ['./client-detail.component.css'],
})
export class ClientDetailComponent implements OnInit, AfterViewInit {
@ViewChild('nameElement', { static: true }) nameElement: ElementRef;
@@ -24,25 +24,24 @@ export class ClientDetailComponent implements OnInit, AfterViewInit {
private dialog: MatDialog,
private fb: FormBuilder,
private toaster: ToasterService,
private ser: ClientService
private ser: ClientService,
) {
this.createForm();
}
createForm() {
this.form = this.fb.group({
code: {value: '', disabled: true},
code: { value: '', disabled: true },
name: '',
enabled: false,
otp: ''
otp: '',
});
}
ngOnInit() {
this.route.data
.subscribe((data: { item: Client }) => {
this.showItem(data.item);
});
this.route.data.subscribe((data: { item: Client }) => {
this.showItem(data.item);
});
}
showItem(item: Client) {
@@ -51,7 +50,7 @@ export class ClientDetailComponent implements OnInit, AfterViewInit {
code: this.item.code || '(Auto)',
name: this.item.name,
enabled: this.item.enabled,
otp: this.item.otp
otp: this.item.otp,
});
}
@@ -62,35 +61,33 @@ export class ClientDetailComponent implements OnInit, AfterViewInit {
}
save() {
this.ser.update(this.getItem())
.subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/clients');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.update(this.getItem()).subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/clients');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
delete() {
this.ser.delete(this.item.id)
.subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/clients');
},
(error) => {
this.toaster.show('Danger', error);
}
);
this.ser.delete(this.item.id).subscribe(
(result) => {
this.toaster.show('Success', '');
this.router.navigateByUrl('/clients');
},
(error) => {
this.toaster.show('Danger', error);
},
);
}
confirmDelete(): void {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
width: '250px',
data: {title: 'Delete Client?', content: 'Are you sure? This cannot be undone.'}
data: { title: 'Delete Client?', content: 'Are you sure? This cannot be undone.' },
});
dialogRef.afterClosed().subscribe((result: boolean) => {
@@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ClientListResolverService} from './client-list-resolver.service';
import { ClientListResolverService } from './client-list-resolver.service';
describe('ClientListResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ClientListResolverService]
providers: [ClientListResolverService],
});
});
it('should be created', inject([ClientListResolverService], (service: ClientListResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[ClientListResolverService],
(service: ClientListResolverService) => {
expect(service).toBeTruthy();
},
));
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {Client} from './client';
import {Observable} from 'rxjs/internal/Observable';
import {ClientService} from './client.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { Client } from './client';
import { Observable } from 'rxjs/internal/Observable';
import { ClientService } from './client.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ClientListResolver implements Resolve<Client[]> {
constructor(private ser: ClientService, private router: Router) {
}
constructor(private ser: ClientService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Client[]> {
return this.ser.list();
@@ -1,33 +1,29 @@
import {DataSource} from '@angular/cdk/collections';
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import {map} from 'rxjs/operators';
import {merge, Observable, of as observableOf} from 'rxjs';
import {Client} from '../client';
import { map } from 'rxjs/operators';
import { merge, Observable, of as observableOf } from 'rxjs';
import { Client } from '../client';
export class ClientListDataSource extends DataSource<Client> {
constructor(private paginator: MatPaginator, private sort: MatSort, public data: Client[]) {
super();
}
connect(): Observable<Client[]> {
const dataMutations = [
observableOf(this.data),
this.paginator.page,
this.sort.sortChange
];
const dataMutations = [observableOf(this.data), this.paginator.page, this.sort.sortChange];
// Set the paginators length
this.paginator.length = this.data.length;
return merge(...dataMutations).pipe(map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}));
return merge(...dataMutations).pipe(
map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}),
);
}
disconnect() {
}
disconnect() {}
private getPagedData(data: Client[]) {
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
@@ -4,52 +4,55 @@
</mat-card-title-group>
<mat-card-content>
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
<!-- Code Column -->
<ng-container matColumnDef="code">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</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 -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
<mat-cell *matCellDef="let row"><a [routerLink]="['/clients', row.id]">{{row.name}}</a></mat-cell>
<mat-cell *matCellDef="let row"
><a [routerLink]="['/clients', row.id]">{{ row.name }}</a></mat-cell
>
</ng-container>
<!-- Enabled Column -->
<ng-container matColumnDef="enabled">
<mat-header-cell *matHeaderCellDef mat-sort-header>Is Enabled?</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.enabled}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.enabled }}</mat-cell>
</ng-container>
<!-- OTP Column -->
<ng-container matColumnDef="otp">
<mat-header-cell *matHeaderCellDef mat-sort-header>otp</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.otp}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.otp }}</mat-cell>
</ng-container>
<!-- Created Column -->
<ng-container matColumnDef="created">
<mat-header-cell *matHeaderCellDef mat-sort-header>Created</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.created | localTime}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.created | localTime }}</mat-cell>
</ng-container>
<!-- Last Login Column -->
<ng-container matColumnDef="lastLogin">
<mat-header-cell *matHeaderCellDef mat-sort-header>Last Login</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.lastLogin | localTime}}</mat-cell>
<mat-cell *matCellDef="let row">{{ row.lastLogin | localTime }}</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 {ClientListComponent} from './client-list.component';
import { ClientListComponent } from './client-list.component';
describe('ClientListComponent', () => {
let component: ClientListComponent;
@@ -8,9 +8,8 @@ describe('ClientListComponent', () => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
declarations: [ClientListComponent]
})
.compileComponents();
declarations: [ClientListComponent],
}).compileComponents();
fixture = TestBed.createComponent(ClientListComponent);
component = fixture.componentInstance;
@@ -1,14 +1,14 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import {ClientListDataSource} from './client-list-datasource';
import {Client} from '../client';
import {ActivatedRoute} from '@angular/router';
import { ClientListDataSource } from './client-list-datasource';
import { Client } from '../client';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-client-list',
templateUrl: './client-list.component.html',
styleUrls: ['./client-list.component.css']
styleUrls: ['./client-list.component.css'],
})
export class ClientListComponent implements OnInit {
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@@ -18,14 +18,12 @@ export class ClientListComponent implements OnInit {
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['code', 'name', 'enabled', 'otp', 'created', 'lastLogin'];
constructor(private route: ActivatedRoute) {
}
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.data
.subscribe((data: { list: Client[] }) => {
this.list = data.list;
});
this.route.data.subscribe((data: { list: Client[] }) => {
this.list = data.list;
});
this.dataSource = new ClientListDataSource(this.paginator, this.sort, this.list);
}
}
@@ -1,15 +1,18 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ClientResolverService} from './client-resolver.service';
import { ClientResolverService } from './client-resolver.service';
describe('ClientResolverService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ClientDetailResolverService]
providers: [ClientDetailResolverService],
});
});
it('should be created', inject([ClientDetailResolverService], (service: ClientDetailResolverService) => {
expect(service).toBeTruthy();
}));
it('should be created', inject(
[ClientDetailResolverService],
(service: ClientDetailResolverService) => {
expect(service).toBeTruthy();
},
));
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {ClientService} from './client.service';
import {Client} from './client';
import {Observable} from 'rxjs/internal/Observable';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { ClientService } from './client.service';
import { Client } from './client';
import { Observable } from 'rxjs/internal/Observable';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ClientResolver implements Resolve<Client> {
constructor(private ser: ClientService, private router: Router) {
}
constructor(private ser: ClientService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Client> {
const id = route.paramMap.get('id');
@@ -1,4 +1,4 @@
import {ClientRoutingModule} from './client-routing.module';
import { ClientRoutingModule } from './client-routing.module';
describe('ClientRoutingModule', () => {
let clientRoutingModule: ClientRoutingModule;
@@ -1,11 +1,11 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule, Routes} from '@angular/router';
import {ClientListResolver} from './client-list-resolver.service';
import {ClientResolver} from './client-resolver.service';
import {ClientListComponent} from './client-list/client-list.component';
import {ClientDetailComponent} from './client-detail/client-detail.component';
import {AuthGuard} from '../auth/auth-guard.service';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { ClientListResolver } from './client-list-resolver.service';
import { ClientResolver } from './client-resolver.service';
import { ClientListComponent } from './client-list/client-list.component';
import { ClientDetailComponent } from './client-detail/client-detail.component';
import { AuthGuard } from '../auth/auth-guard.service';
const clientRoutes: Routes = [
{
@@ -13,38 +13,28 @@ const clientRoutes: Routes = [
component: ClientListComponent,
canActivate: [AuthGuard],
data: {
permission: 'Cost Centres'
permission: 'Cost Centres',
},
resolve: {
list: ClientListResolver
}
list: ClientListResolver,
},
},
{
path: ':id',
component: ClientDetailComponent,
canActivate: [AuthGuard],
data: {
permission: 'Cost Centres'
permission: 'Cost Centres',
},
resolve: {
item: ClientResolver
}
}
item: ClientResolver,
},
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(clientRoutes)
],
exports: [
RouterModule
],
providers: [
ClientListResolver,
ClientResolver
]
imports: [CommonModule, RouterModule.forChild(clientRoutes)],
exports: [RouterModule],
providers: [ClientListResolver, ClientResolver],
})
export class ClientRoutingModule {
}
export class ClientRoutingModule {}
@@ -1,4 +1,4 @@
import {ClientModule} from './client.module';
import { ClientModule } from './client.module';
describe('ClientModule', () => {
let clientModule: ClientModule;
+12 -16
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 {ClientListComponent} from './client-list/client-list.component';
import {ClientDetailComponent} from './client-detail/client-detail.component';
import {ClientRoutingModule} from './client-routing.module';
import { ClientListComponent } from './client-list/client-list.component';
import { ClientDetailComponent } from './client-detail/client-detail.component';
import { ClientRoutingModule } from './client-routing.module';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
@@ -13,10 +13,10 @@ import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import {CdkTableModule} from '@angular/cdk/table';
import {SharedModule} from '../shared/shared.module';
import {FlexLayoutModule} from '@angular/flex-layout';
import {ReactiveFormsModule} from '@angular/forms';
import { CdkTableModule } from '@angular/cdk/table';
import { SharedModule } from '../shared/shared.module';
import { FlexLayoutModule } from '@angular/flex-layout';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
@@ -34,12 +34,8 @@ import {ReactiveFormsModule} from '@angular/forms';
MatTableModule,
ReactiveFormsModule,
SharedModule,
ClientRoutingModule
ClientRoutingModule,
],
declarations: [
ClientListComponent,
ClientDetailComponent
]
declarations: [ClientListComponent, ClientDetailComponent],
})
export class ClientModule {
}
export class ClientModule {}
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ClientService} from './client.service';
import { ClientService } from './client.service';
describe('ClientService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ClientService]
providers: [ClientService],
});
});
+30 -27
View File
@@ -1,49 +1,52 @@
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {ErrorLoggerService} from '../core/error-logger.service';
import {catchError} from 'rxjs/operators';
import {Observable} from 'rxjs/internal/Observable';
import {Client} from './client';
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { ErrorLoggerService } from '../core/error-logger.service';
import { catchError } from 'rxjs/operators';
import { Observable } from 'rxjs/internal/Observable';
import { Client } from './client';
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
};
const url = '/api/clients';
const serviceName = 'ClientService';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ClientService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
get(id: string): Observable<Client> {
const getUrl: string = (id === null) ? url : `${url}/${id}`;
return <Observable<Client>>this.http.get<Client>(getUrl)
.pipe(
catchError(this.log.handleError(serviceName, `get id=${id}`))
);
const getUrl: string = id === null ? url : `${url}/${id}`;
return <Observable<Client>>(
this.http
.get<Client>(getUrl)
.pipe(catchError(this.log.handleError(serviceName, `get id=${id}`)))
);
}
list(): Observable<Client[]> {
return <Observable<Client[]>>this.http.get<Client[]>(`${url}/list`)
.pipe(
catchError(this.log.handleError(serviceName, 'list'))
);
return <Observable<Client[]>>(
this.http
.get<Client[]>(`${url}/list`)
.pipe(catchError(this.log.handleError(serviceName, 'list')))
);
}
update(client: Client): Observable<Client> {
return <Observable<Client>>this.http.put<Client>(`${url}/${client.id}`, client, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'update'))
);
return <Observable<Client>>(
this.http
.put<Client>(`${url}/${client.id}`, client, httpOptions)
.pipe(catchError(this.log.handleError(serviceName, 'update')))
);
}
delete(id: string): Observable<Client> {
return <Observable<Client>>this.http.delete<Client>(`${url}/${id}`, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'delete'))
);
return <Observable<Client>>(
this.http
.delete<Client>(`${url}/${id}`, httpOptions)
.pipe(catchError(this.log.handleError(serviceName, 'delete')))
);
}
}
@@ -1,34 +1,33 @@
import {DataSource} from '@angular/cdk/collections';
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import {map} from 'rxjs/operators';
import {merge, Observable, of as observableOf} from 'rxjs';
import {ClosingStockItem} from './closing-stock';
import { map } from 'rxjs/operators';
import { merge, Observable, of as observableOf } from 'rxjs';
import { ClosingStockItem } from './closing-stock';
export class ClosingStockDataSource extends DataSource<ClosingStockItem> {
constructor(private paginator: MatPaginator, private sort: MatSort, public data: ClosingStockItem[]) {
constructor(
private paginator: MatPaginator,
private sort: MatSort,
public data: ClosingStockItem[],
) {
super();
}
connect(): Observable<ClosingStockItem[]> {
const dataMutations = [
observableOf(this.data),
this.paginator.page,
this.sort.sortChange
];
const dataMutations = [observableOf(this.data), this.paginator.page, this.sort.sortChange];
// Set the paginators length
this.paginator.length = this.data.length;
return merge(...dataMutations).pipe(map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}));
return merge(...dataMutations).pipe(
map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}),
);
}
disconnect() {
}
disconnect() {}
private getPagedData(data: ClosingStockItem[]) {
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
@@ -1,11 +1,11 @@
import {inject, TestBed} from '@angular/core/testing';
import { inject, TestBed } from '@angular/core/testing';
import {ClosingStockResolver} from './closing-stock-resolver.service';
import { ClosingStockResolver } from './closing-stock-resolver.service';
describe('ClosingStockResolver', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ClosingStockResolver]
providers: [ClosingStockResolver],
});
});
@@ -1,16 +1,14 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs/internal/Observable';
import {ClosingStock} from './closing-stock';
import {ClosingStockService} from './closing-stock.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { ClosingStock } from './closing-stock';
import { ClosingStockService } from './closing-stock.service';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ClosingStockResolver implements Resolve<ClosingStock> {
constructor(private ser: ClosingStockService) {
}
constructor(private ser: ClosingStockService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ClosingStock> {
const date = route.paramMap.get('date');
Loaded 100 of 545 files, more files were not shown because too many files have changed in this diff. Show more