in all in one
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"angular.enable-strict-mode-prompt": false
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
# CarParkValidation
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.2.3.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"CarParkValidation": {
|
||||
"projectType": "application",
|
||||
"schematics": {},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"allowedCommonJsDependencies": [
|
||||
"moment"
|
||||
],
|
||||
"outputPath": "dist/CarParkValidation",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||
"src/styles.css",
|
||||
"node_modules/material-design-icons/iconfont/material-icons.css",
|
||||
"node_modules/primeflex/primeflex.css",
|
||||
"node_modules/primeng/resources/primeng.min.css",
|
||||
"node_modules/primeng/resources/themes/bootstrap4-light-blue/theme.css"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "3mb",
|
||||
"maximumError": "5mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "6kb",
|
||||
"maximumError": "10kb"
|
||||
}
|
||||
]
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"buildTarget": "CarParkValidation:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "CarParkValidation:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "CarParkValidation:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "CarParkValidation:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||
"src/styles.css",
|
||||
"node_modules/material-design-icons/iconfont/material-icons.css",
|
||||
"node_modules/primeflex/primeflex.css"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"tsconfig.app.json",
|
||||
"tsconfig.spec.json",
|
||||
"e2e/tsconfig.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "CarParkValidation:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "CarParkValidation:serve:production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// @ts-check
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
|
||||
|
||||
/**
|
||||
* @type { import("protractor").Config }
|
||||
*/
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./src/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
browserName: 'chrome'
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: require('path').join(__dirname, './tsconfig.json')
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({
|
||||
spec: {
|
||||
displayStacktrace: StacktraceOption.PRETTY
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import { AppPage } from './app.po';
|
||||
import { browser, logging } from 'protractor';
|
||||
|
||||
describe('workspace-project App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getTitleText()).toEqual('CarParkValidation app is running!');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// Assert that there are no errors emitted from the browser
|
||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||
expect(logs).not.toContain(jasmine.objectContaining({
|
||||
level: logging.Level.SEVERE,
|
||||
} as logging.Entry));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo(): Promise<unknown> {
|
||||
return browser.get(browser.baseUrl) as Promise<unknown>;
|
||||
}
|
||||
|
||||
getTitleText(): Promise<string> {
|
||||
return element(by.css('app-root .content span')).getText() as Promise<string>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"module": "commonjs",
|
||||
"target": "es2018",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/CarParkValidation'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
||||
Generated
+15185
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "car-park-validation",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^17.3.4",
|
||||
"@angular/cdk": "^17.3.4",
|
||||
"@angular/common": "^17.3.4",
|
||||
"@angular/compiler": "^17.3.4",
|
||||
"@angular/core": "^17.3.4",
|
||||
"@angular/forms": "^17.3.4",
|
||||
"@angular/material": "^17.3.4",
|
||||
"@angular/material-moment-adapter": "^17.3.4",
|
||||
"@angular/platform-browser": "^17.3.4",
|
||||
"@angular/platform-browser-dynamic": "^17.3.4",
|
||||
"@angular/router": "^17.3.4",
|
||||
"material-design-icons": "^3.0.1",
|
||||
"moment": "^2.29.1",
|
||||
"primeflex": "^3.3.1",
|
||||
"primeicons": "^7.0.0",
|
||||
"primeng": "^17.13.0",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.0.0",
|
||||
"web-animations-js": "^2.3.2",
|
||||
"zone.js": "~0.14.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^17.3.4",
|
||||
"@angular/cli": "^17.3.4",
|
||||
"@angular/compiler-cli": "^17.3.4",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "~6.4.1",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~2.0.0",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.6.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.3.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "~5.4.5"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
td.mat-column-edit, .mat-column-delete {
|
||||
width: 35px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<div class="edit-content">
|
||||
<h3>Application Administrators</h3>
|
||||
<div class="addlink">
|
||||
<a [routerLink]='["/home/adminuser", 0]' [queryParams]="{returnUrl:'/home/adminuser'}">
|
||||
<i class="material-icons">playlist_add</i>
|
||||
Add User
|
||||
</a>
|
||||
</div>
|
||||
<mat-form-field>
|
||||
<mat-label>Filter</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event)" placeholder="Name all column" #input>
|
||||
</mat-form-field>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
||||
|
||||
<!-- Desciption Column -->
|
||||
<ng-container matColumnDef="stafflinkNo">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Stafflink Id</th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.stafflinkNo}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Name</th>
|
||||
<td mat-cell *matCellDef="let element">{{element.name}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- roleType Column -->
|
||||
<ng-container matColumnDef="roleType">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Role</th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.roleType}}
|
||||
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- ValidationPoint Column -->
|
||||
<ng-container matColumnDef="validationPoint">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Validation Point</th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.validationPoint}}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="edit" stickyEnd>
|
||||
<th mat-mdc-header-cell *matHeaderCellDef>Edit</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a [routerLink]='["/home/adminuser", element.id]' [queryParams]="{returnUrl:'/home/adminuser'}">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- active Column -->
|
||||
<ng-container matColumnDef="active">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Active</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-checkbox [checked]="element.active" name="active" color="primary">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="selection-pointer tr-mouseover"
|
||||
(click)="showEdit(row)"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
@@ -0,0 +1,91 @@
|
||||
import { Component, Inject, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||
|
||||
import { AdminUserView } from '../models';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
import { AdminUserService } from './adminuser.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
@Component({
|
||||
selector: 'adminuser-list',
|
||||
templateUrl: './adminuser.component.html',
|
||||
styleUrls: ['./adminuser.component.css']
|
||||
})
|
||||
export class AdminUserComponent implements OnInit, AfterViewInit {
|
||||
dataSource: MatTableDataSource<AdminUserView>;
|
||||
private subscription: Subscription = new Subscription();
|
||||
displayedColumns: string[] = ['stafflinkNo', 'name', 'roleType', 'validationPoint', 'active', 'edit'];
|
||||
msg = "[AdminUser component]";
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
|
||||
|
||||
/*
|
||||
private store: Store<appValidationState>
|
||||
*/
|
||||
constructor(
|
||||
private adminUserService: AdminUserService,
|
||||
private router: Router,
|
||||
private messageService: MessageService,
|
||||
) {
|
||||
|
||||
this.dataSource = new MatTableDataSource<AdminUserView>();
|
||||
}
|
||||
//KeyboardEvent
|
||||
applyFilter(event: Event) {
|
||||
const filterValue = (event.target as HTMLInputElement).value;
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscription.add(
|
||||
this.adminUserService.loadAdminusers().subscribe(result => {
|
||||
// console.log(this.msg + "onInit load Data", result);
|
||||
this.dataSource.data = result.data;
|
||||
}, error => {
|
||||
|
||||
console.log("error ", error);
|
||||
})
|
||||
|
||||
);
|
||||
|
||||
/*
|
||||
this.store.dispatch(validationActions.LoadValidationpoints());
|
||||
this.store.pipe(select(validationSelector.getAllValidations)).subscribe(result => this.dataSource.data = result);
|
||||
*/
|
||||
}
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.paginator = this.paginator;
|
||||
}
|
||||
|
||||
showEdit(item: AdminUserView) {
|
||||
console.log(this.msg + "on row click", item);
|
||||
this.router.navigate(['/home/adminuser/' + item.id], { queryParams: { returnUrl: '/home/adminuser' } });
|
||||
}
|
||||
deleteItem(id: number): void {
|
||||
|
||||
this.adminUserService.deleteAdminuser(id)
|
||||
.pipe(take(1))
|
||||
.subscribe(result => {
|
||||
console.log(this.msg + " deleteItem success", result);
|
||||
let data = this.dataSource.data;
|
||||
let index: number = data.findIndex(d => d.id === id);
|
||||
console.log(this.msg + "delete from datasource");
|
||||
data.splice(index, 1)
|
||||
this.dataSource.data = data;
|
||||
},
|
||||
error => console.error(error));
|
||||
console.log(this.msg + "click button to delete");
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
td.mat-column-edit, .mat-column-delete {
|
||||
width: 35px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<div class="edit-content">
|
||||
<div class="title">
|
||||
{{getEditText()}}
|
||||
</div>
|
||||
<form [formGroup]="adminuserForm" (ngSubmit)="onSubmit()" class="flex flex-column gap-2">
|
||||
<div class="flex flex-column">
|
||||
<mat-card>
|
||||
<div>
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Stafflink Number<strong class="app-require">*</strong></mat-label>
|
||||
<input matInput formControlName="stafflinkNo" (blur)="searchUser()" maxlength="10" name="stafflinkno"
|
||||
placeholder="Stafflink Number" required #mystaffid>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field class="w-full" appearance="outline">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput formControlName="name" maxlength="100" name="name" placeholder="Name" readonly>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Role<strong class="app-require">*</strong></mat-label>
|
||||
<mat-select formControlName="roleType" required>
|
||||
<mat-option>--</mat-option>
|
||||
<mat-option *ngFor="let role of Roles" [value]="role.id">
|
||||
{{role.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="f['roleType'].hasError('required')">Please choose Role</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Validation Point<strong class="app-require">*</strong></mat-label>
|
||||
<mat-select formControlName="validationPointId" required>
|
||||
<mat-option>--</mat-option>
|
||||
<mat-option *ngFor="let validationPoint of validationPoints" [value]="validationPoint.id">
|
||||
{{validationPoint.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="f['validationPointId'].hasError('required')">Please choose validation Point</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="active" color="primary">Active</mat-checkbox>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="flex justify-content-end mt-2">
|
||||
<button type="submit" class="mr-2" mat-raised-button color="primary" [disabled]="isFieldsChange">Submit</button>
|
||||
<button type="button" mat-raised-button color="primary" (click)="goBack()">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
<!--pre>{{ adminuserForm.value|json}}</pre-->
|
||||
</div>
|
||||
@@ -0,0 +1,178 @@
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { UntypedFormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Subject, pipe, Subscription } from 'rxjs';
|
||||
|
||||
import { AdminUser, Lookup, userRole } from '../models';
|
||||
import { LookupService, Utils } from '../shares';
|
||||
import { AdminUserService } from './adminuser.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'adminuser.edit.component.html',
|
||||
selector: 'adminuser-edit',
|
||||
styleUrls: ['adminuser.edit.component.css']
|
||||
})
|
||||
export class AdminUserEditComponent implements OnInit, OnDestroy {
|
||||
returnUrl = '';
|
||||
loginUser = '';
|
||||
_id = -1;
|
||||
Roles?: Lookup[];
|
||||
validationPoints?: Lookup[];
|
||||
msg = "[adminUser Component] ";
|
||||
//for focus input
|
||||
// @ViewChild('mystaffid') mystaffNo!: MatInput;
|
||||
isChange = true; // disable use false//true for not disable. make sure it true is disable button.
|
||||
private subscription: Subscription = new Subscription();
|
||||
subChanged$ = new Subject<boolean>();
|
||||
adminuserForm = this.formBuilder.group({
|
||||
id: [0], //Validators.required
|
||||
stafflinkNo: [''], //Validators.required
|
||||
name: [''], //Validators.required
|
||||
addedBy: [''], //Validators.required
|
||||
addedOn: [], //Validators.required
|
||||
active: [false], //Validators.required
|
||||
roleType: [0, Validators.required],
|
||||
validationPointId: [0, Validators.required]
|
||||
});
|
||||
constructor(private formBuilder: UntypedFormBuilder,
|
||||
private adminUserService: AdminUserService,
|
||||
private messageService: MessageService,
|
||||
private lookupService: LookupService,
|
||||
private router: Router, private route: ActivatedRoute,
|
||||
) {
|
||||
|
||||
this.Roles = [];
|
||||
let item: Lookup = { id: userRole.Admin, categoryId: userRole.Admin, description: 'Admin' };
|
||||
this.Roles.push(item);
|
||||
item = { id: userRole.Normal, categoryId: userRole.Normal, description: 'Normal' };
|
||||
this.Roles.push(item);
|
||||
this.subscription.add(this.lookupService.loadValidationPoint().subscribe(x => this.validationPoints = x.data,
|
||||
error => console.error(error)));
|
||||
}
|
||||
ngOnInit(): void {
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
const id = Number(this.route.snapshot.paramMap.get('id'));
|
||||
// now load thing up
|
||||
const user = Utils.getCurrentUser();
|
||||
// console.log(this.msg + "current login user ", user);
|
||||
if (user.username === '')
|
||||
alert("you are not login.");
|
||||
else
|
||||
this.loginUser = user.firstName;
|
||||
this._id = id;
|
||||
//console.log(this.msg + " " + id );
|
||||
this.subscription.add(this.adminuserForm.valueChanges.subscribe(x => this.isChange = false));
|
||||
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||
if (id > 0) {
|
||||
this.subscription.add(this.adminUserService.loadAdminuserById(id).subscribe(x => this.assignValue(x.data), error =>
|
||||
console.error(error.message)));
|
||||
}
|
||||
|
||||
}
|
||||
getEditText(): string {
|
||||
if (this._id > 0)
|
||||
return "Edit Admin User";
|
||||
else
|
||||
return "New Admin User";
|
||||
}
|
||||
// this for disable submit button
|
||||
get isFieldsChange() {
|
||||
const chan = this.isChange || !this.adminuserForm.valid; // this disable so need true valid = true not
|
||||
//console.log(this.msg + 'is fields change', chan);
|
||||
return chan;
|
||||
}
|
||||
searchUser(): void {
|
||||
const staffid = this.adminuserForm.controls["stafflinkNo"].value;
|
||||
// console.log(this.msg + " the staffid is ", staffid);
|
||||
if (staffid != '') {
|
||||
//this.form.controls['your form control name'].value
|
||||
this.adminUserService.getStaffLinkId(staffid).subscribe(x => {
|
||||
//console.log(this.msg + " this is stafflink no ", x);
|
||||
// now get current user.
|
||||
|
||||
if (x.data) {
|
||||
//this.error = true;
|
||||
const fname = x.data.firstName + " " + x.data.lastName;
|
||||
this.adminuserForm.patchValue({ name: fname, addedBy: this.loginUser });
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
this.messageService.add({ severity: 'error', summary: 'Error', detail: "can not find stafflinkNo:" + staffid });
|
||||
// this.adminuserForm.patchValue({name:x.data.firstName + " " + x.data.lastName
|
||||
}
|
||||
},
|
||||
error => {
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
this.messageService.add({ severity: 'error', summary: 'Error', detail: "please enter staff link no" });
|
||||
}
|
||||
}
|
||||
assignValue(adminuser: AdminUser): void {
|
||||
this.adminuserForm.patchValue({
|
||||
id: adminuser.id,
|
||||
stafflinkNo: adminuser.stafflinkNo,
|
||||
name: adminuser.name,
|
||||
addedBy: adminuser.addedBy,
|
||||
addedOn: adminuser.addedOn,
|
||||
active: adminuser.active,
|
||||
roleType: adminuser.roleType,
|
||||
validationPointId: adminuser.validationPointId
|
||||
});
|
||||
// disable use false//true for not disable.
|
||||
this.subChanged$.next(true);
|
||||
}
|
||||
|
||||
// convenience getter for easy access in form fields
|
||||
get f() { return this.adminuserForm.controls; }
|
||||
|
||||
onSubmit(): void {
|
||||
// if form valid then go save
|
||||
//make sure
|
||||
const okToSave = this.adminuserForm.valid;
|
||||
if (okToSave) {
|
||||
let adminuserValue = this.adminuserForm.value;
|
||||
|
||||
let adminuser: AdminUser = {
|
||||
id: adminuserValue.id,
|
||||
stafflinkNo: adminuserValue.stafflinkNo,
|
||||
name: adminuserValue.name,
|
||||
addedBy: adminuserValue.addedBy,
|
||||
addedOn: new Date(),
|
||||
active: adminuserValue.active,
|
||||
roleType: adminuserValue.roleType,
|
||||
validationPointId: adminuserValue.validationPointId,
|
||||
};
|
||||
this.subscription.add(
|
||||
this.adminUserService.saveAdminuser(adminuser).subscribe(x => {
|
||||
if (x.statusCode >= 1) {
|
||||
this.messageService.add({ severity: 'success', summary: 'Success', detail: "Save is OK" });
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
else {
|
||||
|
||||
this.messageService.add({ severity: 'error', summary: 'Error', detail: "Fail to save" });
|
||||
}
|
||||
|
||||
},
|
||||
error => {
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
goBack(): void {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AdminUser, AdminUserView, ResultModel,ConfigureUrl,User } from '../models';
|
||||
import { AppSettingService } from '../shares';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AdminUserService {
|
||||
|
||||
constructor(private http: HttpClient,
|
||||
private appSetting :AppSettingService
|
||||
) {}
|
||||
loadAdminusers(): Observable<ResultModel<AdminUserView[]>> {
|
||||
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||
//const baseUrl = ConfigureUrl.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||
return this.http.get<ResultModel<AdminUserView[]>>(baseUrl);
|
||||
}
|
||||
getStaffLinkId(staffid:string) :Observable<ResultModel<User>>{
|
||||
const userUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.userByStaffIdUrl;
|
||||
let params = new HttpParams().set("stafflinkNo", ""+staffid);
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
return this.http.get<ResultModel<User>>(userUrl, options);
|
||||
}
|
||||
loadAdminuserById(id:number): Observable<ResultModel<AdminUser>> {
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||
let params = new HttpParams().set("id", ""+id);
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
//return this.http.get<AdminUser>(this.baseUrl + 'api/Adminuser/LoadAdminuserById',options);
|
||||
return this.http.get<ResultModel<AdminUser>>(baseUrl + "/" + id);
|
||||
}
|
||||
saveAdminuser(jsData:AdminUser): Observable<ResultModel<number>> { //insert Adminuser
|
||||
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||
return this.http.post<ResultModel<number>>(baseUrl, jsData, config);
|
||||
}
|
||||
deleteAdminuser(id:number): Observable<ResultModel<number>>{
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||
return this.http.delete<ResultModel<number>>(baseUrl + "/" + id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './adminuser.component';
|
||||
export * from './adminuser.edit.component';
|
||||
export * from './adminuser.service';
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AdminUserComponent, AdminUserEditComponent } from './adminuser';
|
||||
import { ConcessionTypeComponent, ConcessiontypeEditComponent} from './concessiontype';
|
||||
import { ConcessionValidationComponent, ConcessionValidationEditComponent } from './concessionValidation';
|
||||
import { HomeComponent } from './home';
|
||||
import { LoginComponent } from './login';
|
||||
import { ValidationPointComponent, ValidationpointEditComponent } from './validationPoint';
|
||||
import { AuthGuard } from './route-guard';
|
||||
import {ConcessionvalidationReportComponent} from './concessionvalidationreport';
|
||||
const routes: Routes = [
|
||||
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: 'home', component: HomeComponent ,
|
||||
children: [
|
||||
{ path: 'adminuser', component: AdminUserComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' }} ,
|
||||
{ path: 'adminuser/:id', component: AdminUserEditComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' }},
|
||||
{ path: 'validationpoint', component: ValidationPointComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||
{ path: 'validationpoint/:id', component: ValidationpointEditComponent,canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||
{ path: 'concessiontype', component:ConcessionTypeComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' }},
|
||||
{ path: 'concessiontype/:id', component: ConcessiontypeEditComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' }},
|
||||
{ path: 'concessionvalidation', component: ConcessionValidationComponent, canActivate: [AuthGuard]},
|
||||
{ path: 'concessionvalidation/:id', component: ConcessionValidationEditComponent, canActivate: [AuthGuard]},
|
||||
|
||||
{ path: 'app-concessionvalidation-report', component: ConcessionvalidationReportComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' }},
|
||||
]
|
||||
},
|
||||
// otherwise redirect to home
|
||||
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
||||
{ path: '**', redirectTo: 'login' },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
@@ -0,0 +1,24 @@
|
||||
.container {
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
.mat-sidenav-container,.mat-sidenav-content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mat-sidenav{
|
||||
width:250px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding-left:25px;
|
||||
padding-right:15px;
|
||||
justify-content:space-around;
|
||||
}
|
||||
|
||||
.mat-toolbar {
|
||||
justify-content: start;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<router-outlet></router-outlet>
|
||||
<p-confirmDialog></p-confirmDialog>
|
||||
<p-toast></p-toast>
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'CarParkValidation';
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA, APP_INITIALIZER } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
import { AppMaterialModule } from './material/app.material.module';
|
||||
import { MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
|
||||
import { HomeComponent } from './home';
|
||||
import { LoginComponent } from './login';
|
||||
import { NavMenuComponent } from './nav-menu/nav-menu.component';
|
||||
import { NavToolarComponent } from './nav-toolbar/nav-toolbar.component';
|
||||
import { AuthenticationService } from './user-services/authentication.service';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
//here the custom components
|
||||
import { SetupModuleModule } from './setup-module/setup-module.module';
|
||||
import { ConcessionvalidationReportComponent } from './concessionvalidationreport';
|
||||
|
||||
import { AppSettingService, ErrorInterceptor, JwtInterceptor } from './shares';
|
||||
import { ConcessionValidationService, ConcessionValidationEditComponent, ConcessionValidationComponent } from './concessionValidation';
|
||||
import { NotFoundComponent } from './not-found/not-found.component';
|
||||
import { ServerErrorComponent } from './server-error/server-error.component';
|
||||
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
||||
import { ToastModule } from 'primeng/toast';
|
||||
import { MessageService, ConfirmationService } from 'primeng/api'
|
||||
import { CalendarModule } from 'primeng/calendar';
|
||||
|
||||
//and in the module providers
|
||||
// { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_MOMENT_FORMATS }
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
NavMenuComponent,
|
||||
HomeComponent,
|
||||
LoginComponent,
|
||||
NavToolarComponent,
|
||||
ConcessionValidationEditComponent,
|
||||
ConcessionValidationComponent,
|
||||
ConcessionvalidationReportComponent,
|
||||
NotFoundComponent,
|
||||
ServerErrorComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
AppMaterialModule,
|
||||
SetupModuleModule,
|
||||
AppRoutingModule,
|
||||
BrowserAnimationsModule,
|
||||
|
||||
ConfirmDialogModule,
|
||||
ToastModule,
|
||||
CalendarModule,
|
||||
|
||||
],
|
||||
providers: [
|
||||
MessageService,
|
||||
ConfirmationService,
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
multi: true,
|
||||
deps: [AppSettingService],
|
||||
useFactory: (appConfigService: AppSettingService) => () => appConfigService.loadAppSetting()
|
||||
},
|
||||
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB', multi: true },
|
||||
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
/*
|
||||
|
||||
|
||||
make star * small
|
||||
check start expiry make the
|
||||
the banner is red.
|
||||
#e02c2c
|
||||
*/
|
||||
/*
|
||||
ng build --base-href "/CarParkValidation/"
|
||||
ng build --base-href "/CarParkValidation/" -c production
|
||||
*/
|
||||
/*
|
||||
downgrade angular
|
||||
ng --version
|
||||
npm uninstall -g @angular/cli
|
||||
npm cache clean --force
|
||||
|
||||
npm install -g @angular/cli@10 or 11
|
||||
ng --version
|
||||
|
||||
|
||||
ng add @angular/material@10
|
||||
npm install ngx-toastr
|
||||
npm install ngx-ui-loader
|
||||
npm install moment
|
||||
npm i @angular/material-moment-adapter@10
|
||||
npm i @angular/flex-layout@10.0.0-beta.32
|
||||
npm install --save classlist.js
|
||||
npm install --save web-animations-js
|
||||
in the tsconfig.json
|
||||
change "target": "es2015", to target: es5 for IE
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
td.mat-column-edit, .mat-column-delete {
|
||||
width: 35px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<div class="edit-content">
|
||||
<h3>Concession Validation</h3>
|
||||
<div *ngIf="isAdmin">
|
||||
<div class="flex flex-row gap-2 w-full">
|
||||
<mat-form-field>
|
||||
<mat-label>Choose a from date</mat-label>
|
||||
<input matInput [(ngModel)]="fromDate" (focus)="pickerfrom.open()" [matDatepicker]="pickerfrom">
|
||||
<mat-datepicker-toggle matSuffix [for]="pickerfrom"></mat-datepicker-toggle>
|
||||
<mat-datepicker #pickerfrom></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>Choose a to date</mat-label>
|
||||
<input matInput [(ngModel)]="toDate" (focus)="pickerto.open()" [matDatepicker]="pickerto">
|
||||
<mat-datepicker-toggle matSuffix [for]="pickerto"></mat-datepicker-toggle>
|
||||
<mat-datepicker #pickerto></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<button mat-mini-fab color="primary" aria-label="loading record" (click)="onLoad()" matTooltip="Loading">
|
||||
<span class="material-icons">
|
||||
flash_on
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="addlink">
|
||||
<a [routerLink]='["/home/concessionvalidation", 0]' [queryParams]="{returnUrl:'/home/concessionvalidation'}"
|
||||
(click)="setDate()">
|
||||
<span class="inline-icon material-icons">add_task</span>
|
||||
Add Concession Validation
|
||||
</a>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
||||
<!-- validateDate Column -->
|
||||
<ng-container matColumnDef="validateDate">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Date </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.validateDate | date: 'dd/MM/yyyy HH:mm'}} </td>
|
||||
</ng-container>
|
||||
<!-- concessionType Column -->
|
||||
<ng-container matColumnDef="concessionType">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Concession Type </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.concessionType}} </td>
|
||||
</ng-container>
|
||||
<!-- concessionCard Column -->
|
||||
<ng-container matColumnDef="concessionCard">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Concession Card Number</th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.concessionCard}} </td>
|
||||
</ng-container>
|
||||
<!-- concessionHolder Column -->
|
||||
<ng-container matColumnDef="concessionHolder">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Concession Holder Name</th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.concessionHolder}} </td>
|
||||
</ng-container>
|
||||
<!-- validationPoint Column -->
|
||||
<ng-container matColumnDef="validationPoint">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Validation Point </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.validationPoint}} </td>
|
||||
</ng-container>
|
||||
<!-- concessionExpiry Column -->
|
||||
<ng-container matColumnDef="concessionExpiry">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef>Expiry date checked</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-checkbox [checked]="element.concessionExpiry" name="concessionExpiry" color="primary">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<div *ngIf="isAdmin">
|
||||
<!-- staffFirstName Column -->
|
||||
<ng-container matColumnDef="staffFirstName">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Staff Name</th>
|
||||
<td mat-cell *matCellDef="let element">{{element.staffFirstName}} {{element.staffLastName}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="edit" stickyEnd>
|
||||
<div *ngIf="isAdmin">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef>Edit</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
|
||||
<!--a [routerLink]='["/home/concessionvalidation", element.id]' [queryParams]="{returnUrl:'/home/concessionvalidation'}">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a-->
|
||||
<button mat-icon-button (click)="showEdit(element)" matTooltip="Edit"><mat-icon>edit</mat-icon></button>
|
||||
</td>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="delete" stickyEnd>
|
||||
<th mat-mdc-header-cell *matHeaderCellDef>Delete</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a (click)='deleteItem(element.id)'>
|
||||
<mat-icon matTooltip="Delete Record">delete</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
</div>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="tr-mouseover"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
@@ -0,0 +1,166 @@
|
||||
import { Component, OnInit, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
|
||||
import { ConcessionValidation } from '../models';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { Utils } from '../shares';
|
||||
|
||||
import { Router } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { ConcessionValidationService } from './concessionvalidation.service';
|
||||
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'concessionvalidation-list',
|
||||
templateUrl: './concessionvalidation.component.html',
|
||||
styleUrls: ['./concessionvalidation.component.css']
|
||||
})
|
||||
export class ConcessionValidationComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
dataSource: MatTableDataSource<ConcessionValidation>;
|
||||
isAdmin = false;
|
||||
isAllowFilter = true;
|
||||
fromDate = new Date();
|
||||
toDate = new Date();
|
||||
username = '';
|
||||
private subscription: Subscription = new Subscription();
|
||||
displayedColumns: string[] =
|
||||
[
|
||||
'validateDate',
|
||||
'concessionType',
|
||||
'concessionCard',
|
||||
'concessionHolder',
|
||||
'concessionExpiry',
|
||||
'validationPoint',
|
||||
];
|
||||
msg = "[ConcessionValidation component]";
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
|
||||
/*
|
||||
private store: Store<appValidationState>
|
||||
*/
|
||||
constructor(
|
||||
private concessionValidationService: ConcessionValidationService,
|
||||
private router: Router,
|
||||
private messageService: MessageService,
|
||||
private confirmationService: ConfirmationService,
|
||||
public dialog: MatDialog,
|
||||
) {
|
||||
this.dataSource = new MatTableDataSource<ConcessionValidation>();
|
||||
this.isAdmin = Utils.getIsAdmin();
|
||||
if (this.isAdmin) {
|
||||
this.displayedColumns =
|
||||
[
|
||||
'validateDate',
|
||||
'concessionType',
|
||||
'concessionCard',
|
||||
'concessionHolder',
|
||||
'concessionExpiry',
|
||||
'validationPoint',
|
||||
'staffFirstName',
|
||||
'edit',
|
||||
'delete'
|
||||
];
|
||||
}
|
||||
}
|
||||
//KeyboardEvent
|
||||
applyFilter(event: Event) {
|
||||
const filterValue = (event.target as HTMLInputElement).value;
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
ngOnInit(): void {
|
||||
const user = Utils.getCurrentUser();
|
||||
// console.log(this.msg + "current login user ", user);
|
||||
if (user.username === "") {
|
||||
user.username = "60249360";
|
||||
this.messageService.add({ severity: 'error', summary: 'Error', detail: "you are not login! using my number " + user.username });
|
||||
}
|
||||
this.username = user.username;
|
||||
if (this.isAdmin)
|
||||
this.username = '';
|
||||
const dateRange = this.concessionValidationService.getDate();
|
||||
// console.log("the date range for now ", dateRange);
|
||||
if (dateRange.fromDate != '')
|
||||
this.fromDate = dateRange.fromDate;
|
||||
if (dateRange.toDate != '')
|
||||
this.toDate = dateRange.toDate;
|
||||
this.onLoad();
|
||||
/*
|
||||
this.store.dispatch(validationActions.LoadValidationpoints());
|
||||
this.store.pipe(select(validationSelector.getAllValidations)).subscribe(result => this.dataSource.data = result);
|
||||
*/
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.paginator = this.paginator;
|
||||
}
|
||||
onLoad(): void {
|
||||
const cDate = this.fromDate;
|
||||
const tDate = this.toDate;
|
||||
|
||||
this.subscription.add(
|
||||
this.concessionValidationService.loadConcessionvalidationByStaffId(this.username, cDate, tDate).subscribe(result => {
|
||||
//console.log(this.msg + "onInit load Data by staffId "+ this.username, result);
|
||||
this.dataSource.data = result.data;
|
||||
}, error => console.error(error.message))
|
||||
);
|
||||
|
||||
//this.dataList$ = this.concessionValidationService.loadConcessionvalidationByStaffId(this.username, cDate, tDate)
|
||||
// .pipe(catchError(err => {this.toastr.error(err.message); return EMPTY}));
|
||||
}
|
||||
setDate(): void {
|
||||
this.concessionValidationService.setDateRange(this.fromDate, this.toDate);
|
||||
}
|
||||
showEdit(item: ConcessionValidation) {
|
||||
// console.log(this.msg + "on row click", item);
|
||||
this.setDate();
|
||||
this.router.navigate(['/home/concessionvalidation/' + item.id], { queryParams: { returnUrl: '/home/concessionvalidation' } });
|
||||
}
|
||||
|
||||
deleteItem(id: number): void {
|
||||
const message = "Are you sure you want to delete this?";
|
||||
const title = " Confirmation";
|
||||
this.confirmationService.confirm({
|
||||
|
||||
message: message,
|
||||
header: title,
|
||||
icon: 'pi pi-exclamation-triangle',
|
||||
|
||||
accept: () => {
|
||||
this.concessionValidationService.deleteConcessionvalidation(id)
|
||||
.subscribe(result => {
|
||||
console.log(this.msg + " deleteItem success", result);
|
||||
let data = this.dataSource.data;
|
||||
let index: number = data.findIndex(d => d.id === id);
|
||||
console.log(this.msg + "delete from datasource");
|
||||
data.splice(index, 1)
|
||||
this.dataSource.data = data;
|
||||
},
|
||||
error => {
|
||||
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
);
|
||||
},
|
||||
reject: () => {
|
||||
console.log(this.msg + "click on No to delete");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
td.mat-column-edit, .mat-column-delete {
|
||||
width: 35px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<div class="edit-content">
|
||||
<div class="title">
|
||||
{{getEditText()}}
|
||||
</div>
|
||||
<form [formGroup]="concessionvalidationForm" (ngSubmit)="onSubmit()">
|
||||
<div class="flex flex-column">
|
||||
<mat-card>
|
||||
<div class="m-2">
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Concession Card Number<strong class="app-require">*</strong></mat-label>
|
||||
<input matInput formControlName="concessionCard" maxlength="60" name="concessionCard" (blur)="searchCard()"
|
||||
placeholder="Concession Card Number" required>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="isAdmin" class="m-2">
|
||||
<label for="time" class="mr-2">Current Date</label>
|
||||
<p-calendar formControlName="validateDate" [showTime]="true" inputId="time"
|
||||
dateFormat="dd/mm/yy"></p-calendar>
|
||||
|
||||
</div>
|
||||
<!--end-->
|
||||
<div class="m-2">
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Concession Type<strong class="app-require">*</strong></mat-label>
|
||||
<mat-select formControlName="concessionTypeId" required>
|
||||
<mat-option>--</mat-option>
|
||||
<mat-option *ngFor="let concessionType of concessionTypes" [value]="concessionType.id">
|
||||
{{concessionType.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="f['concessionTypeId'].hasError('required')">Please choose concession Type</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="m-2">
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Concession Holder Name<strong class="app-require">*</strong></mat-label>
|
||||
<input matInput formControlName="concessionHolder" maxlength="100" name=""
|
||||
placeholder="Concession Holder Name" required>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
|
||||
<mat-checkbox formControlName="concessionExpiry" color="primary" required>Expiry date checked <strong
|
||||
class="app-require">*</strong></mat-checkbox>
|
||||
|
||||
<div *ngIf="isAdmin">
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Validation Point<strong class="app-require">*</strong></mat-label>
|
||||
<mat-select formControlName="validationPointId" required (selectionChange)="onSelectionChange($event)">
|
||||
<mat-option>--</mat-option>
|
||||
<mat-option *ngFor="let validationPoint of validationPoints" [value]="validationPoint.id">
|
||||
{{validationPoint.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="f['validationPointId'].hasError('required')">Please choose validation Point</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-content-end mt-2">
|
||||
<button class="mr-2" type="submit" mat-raised-button color="primary" [disabled]="isFieldsChange">Submit</button>
|
||||
<button type="button" mat-raised-button color="primary" (click)="goBack()">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
<!--pre>{{ concessionvalidationForm.value|json}}</pre-->
|
||||
</div>
|
||||
@@ -0,0 +1,277 @@
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { UntypedFormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
import { ConcessionValidation, Lookup, ResultModel } from '../models';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { LookupService } from '../shares';
|
||||
import { ConcessionValidationService } from './concessionvalidation.service';
|
||||
import { Utils } from '../shares';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import * as moment from 'moment';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
|
||||
import { ThemePalette } from '@angular/material/core';
|
||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||
|
||||
|
||||
@Component({
|
||||
templateUrl: 'concessionvalidation.edit.component.html',
|
||||
selector: 'concessionvalidation-edit',
|
||||
styleUrls: ['concessionvalidation.edit.component.css']
|
||||
})
|
||||
export class ConcessionValidationEditComponent implements OnInit, OnDestroy {
|
||||
returnUrl = "";
|
||||
msg = "[concessionvalidation edit Component] "
|
||||
isChange = true; // disable use false//true for not disable. make sure it true is disable button.
|
||||
subChanged$ = new Subject<boolean>();
|
||||
_id = -1;
|
||||
isAdmin = false;
|
||||
concessionTypes?: Lookup[];
|
||||
validationPoints?: Lookup[];
|
||||
public color: ThemePalette = 'primary';
|
||||
public minDate: moment.Moment;
|
||||
public maxDate: moment.Moment;
|
||||
private subscription: Subscription = new Subscription();
|
||||
concessionvalidationForm = this.formBuilder.group({
|
||||
id: [0], //Validators.required
|
||||
validateDate: [], //Validators.required
|
||||
concessionCard: ['', Validators.required],
|
||||
concessionHolder: ['', Validators.required],
|
||||
concessionExpiry: [false, Validators.required], //Validators.required
|
||||
concessionTypeId: [-1, Validators.min(1)],
|
||||
stafflinkNo: [''], //Validators.required
|
||||
validationPointId: [-1, Validators.min(1)],
|
||||
validationPoint: [''], //Validators.required
|
||||
staffFirstName: [''], //Validators.required
|
||||
staffLastName: [''], //Validators.required
|
||||
staffEmail: [''], //Validators.required
|
||||
active: [false], //Validators.required
|
||||
});
|
||||
constructor(private formBuilder: UntypedFormBuilder,
|
||||
private lookupService: LookupService,
|
||||
private concessionValidationService: ConcessionValidationService,
|
||||
private router: Router,
|
||||
public dialog: MatDialog,
|
||||
private confirmationService: ConfirmationService,
|
||||
private messageService: MessageService,
|
||||
private route: ActivatedRoute) {
|
||||
/*
|
||||
this.concessionTypes = [];
|
||||
let item:Lookup = {id:1,categoryId:0, description:'Health Care Card'};
|
||||
this.concessionTypes.push(item);
|
||||
item = {id:3,categoryId:1, description:'Gold Veterans Affairs Card'};
|
||||
this.concessionTypes.push(item);
|
||||
item = {id:3,categoryId:1, description:'Pensioner Concession Card'};
|
||||
this.concessionTypes.push(item);
|
||||
*/
|
||||
|
||||
}
|
||||
searchCard(): void {
|
||||
const cardNo = this.concessionvalidationForm.controls["concessionCard"].value;
|
||||
if (cardNo != "") {
|
||||
const card$ = this.concessionValidationService.loadConcessionvalidationByCard(cardNo);
|
||||
this.subscription.add(card$.subscribe({
|
||||
next: x => {
|
||||
if (x.statusCode == 1) {
|
||||
const data = x.data;
|
||||
this.concessionvalidationForm.patchValue({
|
||||
concessionHolder: data.concessionHolder,
|
||||
concessionTypeId: data.concessionTypeId,
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
const id = Number(this.route.snapshot.paramMap.get('id'));
|
||||
|
||||
// now load thing up
|
||||
this._id = id;
|
||||
|
||||
this.isAdmin = Utils.getIsAdmin();
|
||||
|
||||
this.subscription.add(this.lookupService.loadConcessionType().subscribe(x => this.concessionTypes = x.data,
|
||||
error => console.error(error)));
|
||||
this.subscription.add(this.lookupService.loadValidationPoint().subscribe(x => this.validationPoints = x.data,
|
||||
error => console.error(error)));
|
||||
this.subscription.add(this.concessionvalidationForm.valueChanges.subscribe(x => this.isChange = false));
|
||||
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||
const user = Utils.getCurrentUser();
|
||||
|
||||
console.log(this.msg + "current login user ", user);
|
||||
if (user.username === "") {
|
||||
user.username = "60249360";
|
||||
this.messageService.add({ severity: 'error', summary: 'Error', detail: "you are not login! using my number " + user.username });
|
||||
}
|
||||
|
||||
if (this._id < 1) {
|
||||
this.concessionvalidationForm.patchValue({
|
||||
validateDate: new Date(),
|
||||
stafflinkNo: user.username,
|
||||
staffFirstName: user.firstName,
|
||||
staffLastName: user.lastName,
|
||||
staffEmail: user.email,
|
||||
validationPointId: user.validationPointId,
|
||||
active: true
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.subscription.add(
|
||||
this.concessionValidationService.loadConcessionvalidationById(id)
|
||||
.subscribe(x => this.assignValue(x.data), error => console.log(error.message)));
|
||||
// console.log(this.msg + " load from db"+id);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
get isFieldsChange() {
|
||||
const chan = this.isChange || !this.concessionvalidationForm.valid; // this disable so need true valid = true not
|
||||
const fvalid = this.concessionvalidationForm.valid;
|
||||
// console.log(this.msg + "is fields change is valid: " + fvalid , chan,);
|
||||
return chan;
|
||||
}
|
||||
getEditText(): string {
|
||||
if (this._id > 0)
|
||||
return "Edit Concession Validation";
|
||||
else
|
||||
return "New Concession Validation";
|
||||
}
|
||||
onChangeValidation($event: Event) {
|
||||
//$event.target.value
|
||||
//this.selectedCar = (event.target as HTMLSelectElement).value;
|
||||
var val = ($event.target as HTMLSelectElement).value;
|
||||
// console.log("the log for val " , val);
|
||||
}
|
||||
onSelectionChange($event: MatSelectChange) {
|
||||
const text = $event.source.triggerValue;
|
||||
// console.log("this is selectionchange "+ "'" + text + "'");
|
||||
this.concessionvalidationForm.patchValue({ validationPoint: text });
|
||||
}
|
||||
assignValue(concessionvalidation: ConcessionValidation): void {
|
||||
this.concessionvalidationForm.patchValue({
|
||||
id: concessionvalidation.id,
|
||||
validateDate: moment(concessionvalidation.validateDate).toDate(),
|
||||
concessionCard: concessionvalidation.concessionCard,
|
||||
concessionHolder: concessionvalidation.concessionHolder,
|
||||
concessionExpiry: concessionvalidation.concessionExpiry,
|
||||
concessionTypeId: concessionvalidation.concessionTypeId,
|
||||
stafflinkNo: concessionvalidation.stafflinkNo,
|
||||
staffFirstName: concessionvalidation.staffFirstName,
|
||||
staffLastName: concessionvalidation.staffLastName,
|
||||
staffEmail: concessionvalidation.staffEmail,
|
||||
validationPointId: concessionvalidation.validationPointId,
|
||||
active: concessionvalidation.active,
|
||||
});
|
||||
// disable use false//true for not disable.
|
||||
this.subChanged$.next(true);
|
||||
|
||||
}
|
||||
|
||||
// convenience getter for easy access in form fields
|
||||
get f() { return this.concessionvalidationForm.controls; }
|
||||
|
||||
onSubmit(): void {
|
||||
const OkToSave = this.concessionvalidationForm.valid;
|
||||
if (OkToSave) {
|
||||
const concessionvalidationValue = this.concessionvalidationForm.value;
|
||||
const concessionvalidation: ConcessionValidation = {
|
||||
id: concessionvalidationValue.id,
|
||||
validateDate: moment(concessionvalidationValue.validateDate).toDate(),
|
||||
concessionCard: concessionvalidationValue.concessionCard,
|
||||
concessionHolder: concessionvalidationValue.concessionHolder,
|
||||
concessionExpiry: concessionvalidationValue.concessionExpiry,
|
||||
concessionTypeId: concessionvalidationValue.concessionTypeId,
|
||||
stafflinkNo: concessionvalidationValue.stafflinkNo,
|
||||
staffFirstName: concessionvalidationValue.staffFirstName,
|
||||
staffLastName: concessionvalidationValue.staffLastName,
|
||||
staffEmail: concessionvalidationValue.staffEmail,
|
||||
validationPointId: concessionvalidationValue.validationPointId,
|
||||
active: concessionvalidationValue.active,
|
||||
};
|
||||
// console.log(this.msg + "this is OKTOsave", concessionvalidation);
|
||||
//if edit mode just save it don't check
|
||||
if (concessionvalidation.id > 0) {
|
||||
this.saveConcession(concessionvalidation);
|
||||
}
|
||||
else {
|
||||
//check first only if new
|
||||
this.checkAndSave(concessionvalidation);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// console.log(this.msg + "this is NOT OKTOsave");
|
||||
this.messageService.add({ severity: 'error', summary: 'Error', detail: "please fill in the required fields" });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
checkAndSave(concessionvalidation: ConcessionValidation): void {
|
||||
const currentDate = moment(concessionvalidation.validateDate).format("YYYY-MM-DD");
|
||||
const id = concessionvalidation.id;
|
||||
this.subscription.add(
|
||||
this.concessionValidationService.checkConcessionValidationByStaff(concessionvalidation.stafflinkNo,
|
||||
concessionvalidation.concessionCard, currentDate, id)
|
||||
.subscribe(x => {
|
||||
let okTo = true;
|
||||
if (x.data < 0) {
|
||||
const message = "This card was used earlier today. Is it Ok to continue?";
|
||||
const title = "Alert";
|
||||
this.confirmationService.confirm({
|
||||
message: message,
|
||||
header: 'Confirmation',
|
||||
icon: 'pi pi-exclamation-triangle',
|
||||
accept: () => {
|
||||
this.saveConcession(concessionvalidation);
|
||||
},
|
||||
reject: () => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
this.saveConcession(concessionvalidation);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
saveConcession(concessionvalidation: ConcessionValidation): void {
|
||||
//console.log(this.msg + " Save Concession validation to server");
|
||||
this.subscription.add(
|
||||
this.concessionValidationService.saveConcessionvalidation(concessionvalidation)
|
||||
.subscribe(x => {
|
||||
if (x.statusCode >= 1) {
|
||||
this.messageService.add({ severity: 'success', summary: 'Success', detail: "Save is OK" });
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
else
|
||||
this.messageService.add({ severity: 'error', summary: 'Fail to Save', detail: x.message });
|
||||
|
||||
}, error => {
|
||||
const message = error || error.message;
|
||||
this.messageService.add({ severity: 'error', summary: 'Fail to Save', detail: message });
|
||||
console.log("error ", error);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
goBack(): void {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ConcessionValidation, ResultModel, ConfigureUrl } from '../models';
|
||||
import * as moment from 'moment';
|
||||
import { AppSettingService } from '../shares';
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ConcessionValidationService {
|
||||
private dateRange: any;
|
||||
constructor(private http: HttpClient,
|
||||
private appSetting: AppSettingService
|
||||
) {
|
||||
this.dateRange = {};
|
||||
this.dateRange.fromDate = '';
|
||||
this.dateRange.toDate = '';
|
||||
console.log("constructor concessionValidationService daterange", this.dateRange);
|
||||
}
|
||||
public setDateRange(fromDate: any, toDate: any) {
|
||||
this.dateRange.fromDate = moment(fromDate).toDate();
|
||||
this.dateRange.toDate = moment(toDate).toDate();
|
||||
// console.log("concessionValidationService setdaterange", this.dateRange);
|
||||
}
|
||||
public getDate(): any {
|
||||
// console.log("concessionValidationService getdaterange", this.dateRange);
|
||||
return this.dateRange;
|
||||
}
|
||||
loadConcessionvalidations(): Observable<ResultModel<ConcessionValidation[]>> {
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||
let config = { headers: { 'Content-Type': 'application/json' } };
|
||||
// console.log("the concession", baseUrl);
|
||||
return this.http.get<ResultModel<ConcessionValidation[]>>(baseUrl);
|
||||
}
|
||||
loadConcessionvalidationByStaffId(staffLinkId: string, fromDate: Date, toDate: Date): Observable<ResultModel<ConcessionValidation[]>> {
|
||||
this.setDateRange(fromDate, toDate);
|
||||
const strDate = moment(fromDate).format("YYYY-MM-DD");
|
||||
const strtoDate = moment(toDate).format("YYYY-MM-DD");
|
||||
const url = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationByIdUrl;
|
||||
const params = new HttpParams().set("staffLinkNo", staffLinkId)
|
||||
.set("fromDate", strDate)
|
||||
.set("toDate", strtoDate);
|
||||
const headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
const options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
//console.log("loadConcessionvalidationByStaffId url", url);
|
||||
return this.http.get<ResultModel<ConcessionValidation[]>>(url, options);
|
||||
}
|
||||
loadConcessionvalidationById(id: number): Observable<ResultModel<ConcessionValidation>> {
|
||||
let params = new HttpParams().set("id", "" + id);
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
//return this.http.get<Concessionvalidation>(this.baseUrl + 'api/Concessionvalidation/LoadConcessionvalidationById',options);
|
||||
return this.http.get<ResultModel<ConcessionValidation>>(baseUrl + "/" + id);
|
||||
}
|
||||
loadConcessionvalidationByCard(cardNo: string): Observable<ResultModel<ConcessionValidation>> {
|
||||
const data = { cardNo };
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl + "/GetConcessionCard";
|
||||
/*
|
||||
let params = new HttpParams().set("id", "" + id);
|
||||
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
*/
|
||||
//return this.http.get<Concessionvalidation>(this.baseUrl + 'api/Concessionvalidation/LoadConcessionvalidationById',options);
|
||||
return this.http.post<ResultModel<ConcessionValidation>>(baseUrl, data);
|
||||
}
|
||||
checkConcessionValidationByStaff(staffLinkNo: string, concessionCard: string, currentDate: string, id: number): Observable<ResultModel<number>> {
|
||||
let params = new HttpParams().set("staffLinkNo", staffLinkNo)
|
||||
.set("concessionCard", concessionCard)
|
||||
.set("currentDate", currentDate)
|
||||
.set("id", "" + id);
|
||||
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl;
|
||||
const url = baseUrl + "/" + ConfigureUrl.CheckConcessionValidationByStaffUrl;
|
||||
//return this.http.get<Concessionvalidation>(this.baseUrl + 'api/Concessionvalidation/LoadConcessionvalidationById',options);
|
||||
return this.http.get<ResultModel<number>>(url, options);
|
||||
}
|
||||
saveConcessionvalidation(item: ConcessionValidation): Observable<ResultModel<number>> { //insert Concessionvalidation
|
||||
let config = { headers: { 'Content-Type': 'application/json' } };
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||
return this.http.post<ResultModel<number>>(baseUrl, item, config);
|
||||
}
|
||||
deleteConcessionvalidation(Id: number): Observable<ResultModel<number>> {
|
||||
let config = { headers: { 'Content-Type': 'application/json' } };
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||
return this.http.delete<ResultModel<number>>(baseUrl + "/" + Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './concessionvalidation.component';
|
||||
export * from './concessionvalidation.edit.component';
|
||||
export * from './concessionvalidation.service';
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
td.mat-column-edit, .mat-column-delete {
|
||||
width: 35px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<div class="edit-content">
|
||||
<h3>Concession Type</h3>
|
||||
<div class="addlink">
|
||||
<a [routerLink]='["/home/concessiontype", 0]' [queryParams]="{returnUrl:'/home/concessiontype'}">
|
||||
<i class="material-icons">playlist_add</i>
|
||||
Add Concession Type
|
||||
</a>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
||||
|
||||
<!-- Desciption Column -->
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Concession Type</th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- active Column -->
|
||||
<ng-container matColumnDef="active">
|
||||
<th mat-mdc-header-cell *matHeaderCellDef mat-sort-header>Active</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-checkbox [checked]="element.active" name="active" color="primary">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="edit" stickyEnd>
|
||||
<th mat-mdc-header-cell *matHeaderCellDef>Edit</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a [routerLink]='["/home/concessiontype", element.id]' [queryParams]="{returnUrl:'/home/concessiontype'}">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="selection-pointer tr-mouseover"
|
||||
(click)="showEdit(row)"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Component, Inject, OnInit, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
import { ConcessionTypeService } from './concessiontype.service';
|
||||
import { ConcessionType } from '../models';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
|
||||
/* ngRx
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import * as validationActions from './store/actions/validationpoint.action';
|
||||
import * as validationSelector from './store/selectors/validationpoint.selector';
|
||||
import { appValidationState } from './store/reducers';
|
||||
*/
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { MessageService } from 'primeng/api';
|
||||
@Component({
|
||||
selector: 'concessiontype-list',
|
||||
templateUrl: './concessiontype.component.html',
|
||||
styleUrls: ['./concessiontype.component.css']
|
||||
})
|
||||
export class ConcessionTypeComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
dataSource: MatTableDataSource<ConcessionType>;
|
||||
|
||||
private subscription: Subscription = new Subscription();
|
||||
|
||||
displayedColumns: string[] = ['description', 'active', 'edit'];
|
||||
msg = "[concessionType.com]";
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
|
||||
|
||||
/*
|
||||
private store: Store<appValidationState>
|
||||
*/
|
||||
constructor(
|
||||
private concessionTypeService: ConcessionTypeService,
|
||||
private messageService: MessageService,
|
||||
private router: Router
|
||||
) {
|
||||
|
||||
this.dataSource = new MatTableDataSource<ConcessionType>();
|
||||
}
|
||||
/*
|
||||
applyFilter($event:any) {
|
||||
const filterValue = $event.target.value;
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.subscription.add(
|
||||
this.concessionTypeService.loadConcessiontypes().subscribe(result => {
|
||||
// console.log(this.msg + "onInit", result);
|
||||
this.dataSource.data = result.data;
|
||||
}, error => {
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
/*
|
||||
this.store.dispatch(validationActions.LoadValidationpoints());
|
||||
this.store.pipe(select(validationSelector.getAllValidations)).subscribe(result => this.dataSource.data = result);
|
||||
*/
|
||||
}
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.paginator = this.paginator;
|
||||
}
|
||||
|
||||
showEdit(item: ConcessionType) {
|
||||
console.log(this.msg + "on row click", item);
|
||||
this.router.navigate(['/home/concessiontype/' + item.id], { queryParams: { returnUrl: '/home/concessiontype' } });
|
||||
}
|
||||
deleteItem(id: number): void {
|
||||
|
||||
this.concessionTypeService.deleteConcessiontype(id)
|
||||
.pipe(take(1))
|
||||
.subscribe(result => {
|
||||
// console.log(this.msg + " deleteItem success", result);
|
||||
let data = this.dataSource.data;
|
||||
let index: number = data.findIndex(d => d.id === id);
|
||||
// console.log(this.msg + "delete from datasource");
|
||||
data.splice(index, 1)
|
||||
this.dataSource.data = data;
|
||||
},
|
||||
error => {
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
td.mat-column-edit, .mat-column-delete {
|
||||
width: 35px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<div class="edit-content">
|
||||
<div class="title"> {{getEditText()}} </div>
|
||||
<form [formGroup]="concessiontypeForm" (ngSubmit)="onSubmit()">
|
||||
<div class="flex flex-column">
|
||||
<mat-card>
|
||||
<input type="hidden" formControlName="id">
|
||||
<div>
|
||||
<mat-form-field class="w-full" appearance="outline" [hideRequiredMarker]="true">
|
||||
<mat-label>Concession Type<strong class="app-require">*</strong></mat-label>
|
||||
<input matInput formControlName="description" maxlength="80" name="Concession Type"
|
||||
placeholder="description" required>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="active" color="primary">Active</mat-checkbox>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="flex justify-content-end mt-2">
|
||||
<button class="mr-2" type="submit" mat-raised-button color="primary"
|
||||
[disabled]="isFieldsChange">Submit</button>
|
||||
<button type="button" mat-raised-button color="primary" (click)="goBack()">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
<!--pre>{{ concessiontypeForm.value|json}}</pre-->
|
||||
</div>
|
||||
@@ -0,0 +1,114 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { UntypedFormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { ConcessionType } from '../models';
|
||||
import { Subject, pipe, Subscription } from 'rxjs';
|
||||
import { ConcessionTypeService } from './concessiontype.service';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'concessiontype.edit.component.html',
|
||||
selector: 'concessiontype-edit',
|
||||
styleUrls: ['concessiontype.edit.component.css']
|
||||
})
|
||||
export class ConcessiontypeEditComponent implements OnInit {
|
||||
returnUrl = '';
|
||||
_id = -1;
|
||||
msg = "[Concession type edit Component] ";
|
||||
isChange = true; // disable use false//true for not disable. make sure it true is disable button.
|
||||
private subscription: Subscription = new Subscription();
|
||||
subChanged$ = new Subject<boolean>();
|
||||
concessiontypeForm = this.formBuilder.group({
|
||||
id: [0], //Validators.required
|
||||
description: [''], //Validators.required
|
||||
display: [''], //Validators.required
|
||||
active: [false], //Validators.required
|
||||
});
|
||||
constructor(private formBuilder: UntypedFormBuilder,
|
||||
private messageService: MessageService,
|
||||
private concessionTypeService: ConcessionTypeService,
|
||||
private route: ActivatedRoute, private router: Router) { }
|
||||
ngOnInit(): void {
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
const id = Number(this.route.snapshot.paramMap.get('id'));
|
||||
// now load thing up
|
||||
this.subscription.add(this.concessiontypeForm.valueChanges.subscribe(x => this.isChange = false));
|
||||
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||
if (id > 0) {
|
||||
this.subscription.add(
|
||||
this.concessionTypeService.loadConcessiontypeById(id).subscribe(x => {
|
||||
this.assignValue(x.data)
|
||||
}, error => {
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
getEditText(): string {
|
||||
if (this._id > 0)
|
||||
return "Edit Concession Type";
|
||||
else
|
||||
return "New Concession Type";
|
||||
}
|
||||
// this for disable submit button
|
||||
get isFieldsChange() {
|
||||
const chan = this.isChange || !this.concessiontypeForm.valid; // this disable so need true valid = true not
|
||||
//console.log(this.msg + 'is fields change', chan);
|
||||
return chan;
|
||||
}
|
||||
assignValue(concessiontype: ConcessionType): void {
|
||||
this.concessiontypeForm.patchValue({
|
||||
id: concessiontype.id,
|
||||
description: concessiontype.description,
|
||||
display: concessiontype.display,
|
||||
active: concessiontype.active,
|
||||
});
|
||||
// disable use false//true for not disable.
|
||||
this.subChanged$.next(true);
|
||||
|
||||
}
|
||||
|
||||
// convenience getter for easy access in form fields
|
||||
get f() { return this.concessiontypeForm.controls; }
|
||||
|
||||
onSubmit(): void {
|
||||
// if form valid then go save
|
||||
//make sure
|
||||
const okToSave = this.concessiontypeForm.valid;
|
||||
if (okToSave) {
|
||||
let concessiontypeValue = this.concessiontypeForm.value;
|
||||
let concessiontype: ConcessionType = {
|
||||
id: concessiontypeValue.id,
|
||||
description: concessiontypeValue.description,
|
||||
display: concessiontypeValue.display,
|
||||
active: concessiontypeValue.active,
|
||||
};
|
||||
|
||||
this.subscription.add(this.concessionTypeService.saveConcessiontype(concessiontype).subscribe(x => {
|
||||
//console.log("after save return is", x);
|
||||
if (x.statusCode > 0) {
|
||||
//alert("save ok");
|
||||
|
||||
this.messageService.add({ severity: 'success', summary: 'Success', detail: "Save is OK" });
|
||||
this.router.navigate([this.returnUrl]);
|
||||
//this.router.navigate(['/home/concessiontype'])
|
||||
}
|
||||
},
|
||||
error => {
|
||||
|
||||
console.log("error ", error);
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
goBack(): void {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ConcessionType, ResultModel, ConfigureUrl } from '../models';
|
||||
import { AppSettingService } from '../shares';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ConcessionTypeService {
|
||||
|
||||
constructor(private http: HttpClient,
|
||||
private appSetting :AppSettingService
|
||||
) {}
|
||||
loadConcessiontypes(): Observable<ResultModel<ConcessionType[]> > {
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" +ConfigureUrl.concessionTypeUrl;
|
||||
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||
return this.http.get<ResultModel<ConcessionType[]>>(baseUrl);
|
||||
}
|
||||
loadConcessiontypeById(id:number): Observable<ResultModel<ConcessionType>> {
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" +ConfigureUrl.concessionTypeUrl;
|
||||
let params = new HttpParams().set("id", ""+id);
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
|
||||
return this.http.get<ResultModel<ConcessionType>>(baseUrl +"/"+id);
|
||||
}
|
||||
saveConcessiontype(concessType:ConcessionType): Observable<ResultModel<number>> { //insert Concessiontype
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" +ConfigureUrl.concessionTypeUrl;
|
||||
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||
return this.http.post<ResultModel<number>>(baseUrl , concessType, config);
|
||||
}
|
||||
deleteConcessiontype(id:number): Observable<ResultModel<number>>{
|
||||
const baseUrl = this.appSetting.appSetting.baseUrl + "/" +ConfigureUrl.concessionTypeUrl;
|
||||
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||
return this.http.delete<ResultModel<number>>(baseUrl +"/" + id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './concessiontype.component';
|
||||
export * from './concessiontype.edit.component';
|
||||
export * from './concessiontype.service';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="edit-content">
|
||||
<h3>Concession Validation Report</h3>
|
||||
<form [formGroup]="concessionvalidationreportForm">
|
||||
<div class="flex flex-row gap-2">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Choose a from date</mat-label>
|
||||
<input matInput formControlName="fromDate" (focus)="pickerfrom.open()" [matDatepicker]="pickerfrom">
|
||||
<mat-datepicker-toggle matSuffix [for]="pickerfrom"></mat-datepicker-toggle>
|
||||
<mat-datepicker #pickerfrom></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Choose a to date</mat-label>
|
||||
<input matInput formControlName="toDate" (focus)="pickerto.open()" [matDatepicker]="pickerto">
|
||||
<mat-datepicker-toggle matSuffix [for]="pickerto"></mat-datepicker-toggle>
|
||||
<mat-datepicker #pickerto></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" mat-raised-button color="primary" (click)="onDownload()">Download</button>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<h3>User Report</h3>
|
||||
<div>
|
||||
<button type="button" mat-raised-button color="primary" (click)="onDownloadUser()">Download Users</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, Validators } from '@angular/forms';
|
||||
import * as moment from 'moment';
|
||||
import { HttpUtility, CommonUtilities } from '../shares';
|
||||
import { catchError, finalize } from 'rxjs/operators';
|
||||
import { EMPTY } from 'rxjs';
|
||||
|
||||
import { HttpResponse } from '@angular/common/http';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { MessageService } from 'primeng/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-concessionvalidation-report',
|
||||
templateUrl: './concessionvalidationreport.component.html',
|
||||
styleUrls: ['./concessionvalidationreport.component.css']
|
||||
})
|
||||
export class ConcessionvalidationReportComponent implements OnInit {
|
||||
msg = "[concessionvalidation] ";
|
||||
returnUrl = "";
|
||||
concessionvalidationreportForm = this.formBuilder.group({
|
||||
|
||||
fromDate: [new Date()], //Validators.required
|
||||
toDate: [new Date(), Validators.required],
|
||||
|
||||
});
|
||||
|
||||
constructor(
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private http: HttpUtility,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private messageService: MessageService
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
onDownload(): void {
|
||||
|
||||
const constDate = this.concessionvalidationreportForm.value;
|
||||
const fromDate = moment(constDate.fromDate).format("YYYY-MM-DD");
|
||||
const toDate = moment(constDate.toDate).format("YYYY-MM-DD");
|
||||
console.log(this.msg + "click on download", fromDate);
|
||||
|
||||
//GetReportFile
|
||||
this.http.getFileResponse(`api/v1/ConcessionValidation/GetReportFile?fromDate=${fromDate}&toDate=${toDate}`).pipe(
|
||||
catchError(err => {
|
||||
|
||||
return EMPTY;
|
||||
}),
|
||||
finalize(() => {
|
||||
|
||||
this.messageService.add({ severity: 'success', summary: 'Success', detail: "download completed ok to view now" });
|
||||
})).subscribe((response: HttpResponse<Blob>) => {
|
||||
if (response) {
|
||||
console.log("the download report response", response);
|
||||
CommonUtilities.downloadFile(response, 'report.xlsx');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onDownloadUser(): void {
|
||||
//GetReportFile
|
||||
this.http.getFileResponse(`api/v1/Users/GetReportFile`).pipe(
|
||||
catchError(err => {
|
||||
|
||||
return EMPTY;
|
||||
}),
|
||||
finalize(() => {
|
||||
this.messageService.add({ severity: 'success', summary: 'Success', detail: "download completed ok to view now" });
|
||||
})).subscribe((response: HttpResponse<Blob>) => {
|
||||
if (response) {
|
||||
console.log("the download user report response", response);
|
||||
CommonUtilities.downloadFile(response, 'UserReport.xlsx');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
this.assignValue();
|
||||
}
|
||||
|
||||
assignValue(): void {
|
||||
this.concessionvalidationreportForm.patchValue({
|
||||
fromDate: new Date(),
|
||||
toDate: moment(new Date()).add(30, 'd')
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './concessionvalidationreport.component';
|
||||
@@ -0,0 +1,29 @@
|
||||
.welcome {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mat-sidenav-container,
|
||||
.mat-sidenav-content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mat-sidenav {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding-left: 25px;
|
||||
padding-right: 15px;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.mat-toolbar {
|
||||
justify-content: space-between;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<div class="container">
|
||||
<app-nav-toolbar (toggleEvent)="showSidenav($event)"></app-nav-toolbar>
|
||||
<mat-sidenav-container>
|
||||
<mat-sidenav #sidenav role="navigation" position='end'>
|
||||
<app-nav-menu (closeMe)="onCloseSidenav($event)"></app-nav-menu>
|
||||
</mat-sidenav>
|
||||
<mat-sidenav-content>
|
||||
<main class="main-content">
|
||||
<router-outlet></router-outlet>
|
||||
</main>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
<mat-toolbar>
|
||||
<p class="text-black text-sm mr-2">release 05.12.2022 v1.2</p>
|
||||
<p class="text-blue-500 text-sm">power by angular {{ngVersion}}</p>
|
||||
</mat-toolbar>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Component,ViewChild,VERSION } from '@angular/core';
|
||||
import { MatSidenav } from '@angular/material/sidenav';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: ['./home.component.css']
|
||||
})
|
||||
export class HomeComponent {
|
||||
ngVersion = '';
|
||||
openSidenav = false;
|
||||
@ViewChild(MatSidenav) sidenav!: MatSidenav;
|
||||
constructor() {
|
||||
this.ngVersion = VERSION.full;
|
||||
}
|
||||
onCloseSidenav(e: boolean): void {
|
||||
this.sidenav.close();
|
||||
}
|
||||
showSidenav(event: boolean): void {
|
||||
|
||||
this.sidenav.toggle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__export(require("./home.component"));
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;AAAA,sCAAiC"}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './home.component';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__export(require("./login.component"));
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './login.component';
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
.btnloginRigh {
|
||||
display: flex;
|
||||
flex-direction:reverse;
|
||||
justify-content:flex-end;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<div style="position:absolute;top:50%;left:50%;transform: translate(-50%, -50%);">
|
||||
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
|
||||
<mat-card style="max-width:600px">
|
||||
<img mat-card-image src="assets/images/application_image.png" alt="Nepean Car Park Validation">
|
||||
<mat-card-content>
|
||||
<p>Please Login to Continue</p>
|
||||
<div class="flex flex-column">
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="username" matInput placeholder="StaffLinkNo/Employee no"
|
||||
[ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
|
||||
</mat-form-field>
|
||||
<div *ngIf="submitted && f.username.errors" class="invalid-feedback">
|
||||
<div *ngIf="f.username.errors.required">StaffLinkNo is required</div>
|
||||
</div>
|
||||
<mat-form-field>
|
||||
<input type="password" formControlName="password" matInput placeholder="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && f.password.errors }" />
|
||||
</mat-form-field>
|
||||
<div *ngIf="submitted && f.password.errors" class="invalid-feedback">
|
||||
<div *ngIf="f.password.errors.required">Password is required</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions class="btnloginRigh">
|
||||
<button pButton type="submit" label="Login" class="p-button-sm" [loading]="loading"></button>
|
||||
|
||||
</mat-card-actions>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger">{{error}}</div>
|
||||
</mat-card>
|
||||
<div>
|
||||
<mat-card style="max-width:600px;background-color:#e1e1e1; color:#222">
|
||||
<mat-card-content style="text-align:center;font-size:13px;">
|
||||
<p>
|
||||
Please NOTE access to this database is restricted to approved employees for parking validations only.
|
||||
If you require access to this database or further information, please email
|
||||
</p>
|
||||
<a href="mailto:{{adminEmail}}"> {{adminEmail}}
|
||||
</a>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { UntypedFormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { first } from 'rxjs/operators';
|
||||
|
||||
import { AuthenticationService } from '../user-services';
|
||||
import { AppSettingService } from '../shares';
|
||||
|
||||
@Component({
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css'],
|
||||
selector: 'login'
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
loginForm = this.formBuilder.group({
|
||||
username: ['', Validators.required],
|
||||
password: ['', Validators.required]
|
||||
});
|
||||
|
||||
loading = false;
|
||||
submitted = false;
|
||||
adminEmail = "";
|
||||
// get return url from route parameters or default to '/'
|
||||
returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/home/concessionvalidation';
|
||||
error = '';
|
||||
|
||||
constructor(
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private appSetting: AppSettingService,
|
||||
private authenticationService: AuthenticationService) {
|
||||
this.adminEmail = this.appSetting.appSetting.adminEmail;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
// reset login status
|
||||
this.authenticationService.logout();
|
||||
|
||||
|
||||
}
|
||||
|
||||
// convenience getter for easy access to form fields
|
||||
get f() { return this.loginForm.controls; }
|
||||
|
||||
onSubmit() {
|
||||
this.submitted = true;
|
||||
|
||||
// stop here if form is invalid
|
||||
if (this.loginForm.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.authenticationService.login(this.f.username.value, this.f.password.value)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
data => {
|
||||
this.loading = false;
|
||||
console.log("login result ", data);
|
||||
if (data == 1)
|
||||
this.router.navigate([this.returnUrl]);
|
||||
else {
|
||||
this.loginForm.patchValue({ password: '' });
|
||||
alert("Invalid Username or Password. Please try again.");
|
||||
|
||||
}
|
||||
},
|
||||
er => {
|
||||
console.log("error in login", er);
|
||||
this.error = er.message;
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatNativeDateModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatTreeModule } from '@angular/material/tree';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
|
||||
import {
|
||||
MatMomentDateModule
|
||||
} from '@angular/material-moment-adapter'
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatInputModule,
|
||||
MatDatepickerModule,
|
||||
MatFormFieldModule,
|
||||
MatTableModule,
|
||||
MatSortModule,
|
||||
MatPaginatorModule,
|
||||
MatNativeDateModule,
|
||||
MatMomentDateModule,
|
||||
MatCardModule,
|
||||
MatDialogModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
MatListModule,
|
||||
MatTabsModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTreeModule,
|
||||
MatTooltipModule,
|
||||
MatSnackBarModule,
|
||||
MatProgressBarModule,
|
||||
MatMenuModule,
|
||||
|
||||
MatExpansionModule,
|
||||
],
|
||||
exports: [
|
||||
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatInputModule,
|
||||
MatDatepickerModule,
|
||||
MatFormFieldModule,
|
||||
MatTableModule,
|
||||
MatSortModule,
|
||||
MatPaginatorModule,
|
||||
MatNativeDateModule,
|
||||
MatMomentDateModule,
|
||||
MatCardModule,
|
||||
MatDialogModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
MatListModule,
|
||||
MatTabsModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTreeModule,
|
||||
MatSnackBarModule,
|
||||
MatTooltipModule,
|
||||
MatProgressBarModule,
|
||||
|
||||
MatMenuModule,
|
||||
MatExpansionModule,
|
||||
|
||||
]
|
||||
})
|
||||
export class AppMaterialModule { }
|
||||
@@ -0,0 +1,21 @@
|
||||
export interface AdminUser {
|
||||
id: number,
|
||||
stafflinkNo: string,
|
||||
name: string,
|
||||
addedBy: string,
|
||||
addedOn: Date,
|
||||
active: boolean,
|
||||
roleType: number,
|
||||
validationPointId: number,
|
||||
}
|
||||
|
||||
export interface AdminUserView {
|
||||
id: number,
|
||||
stafflinkNo: string,
|
||||
name: string,
|
||||
addedBy: string,
|
||||
addedOn: Date,
|
||||
active: boolean,
|
||||
roleType: string,
|
||||
validationPoint: string,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface ConcessionType {
|
||||
id: number,
|
||||
description: string,
|
||||
display: string,
|
||||
active: boolean,
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export interface ConcessionValidation {
|
||||
id: number,
|
||||
validateDate: Date,
|
||||
concessionCard: string,
|
||||
concessionHolder: string,
|
||||
concessionExpiry: boolean,
|
||||
concessionTypeId: number,
|
||||
stafflinkNo: string,
|
||||
staffFirstName:string,
|
||||
staffLastName:string,
|
||||
staffEmail:string,
|
||||
validationPointId: number,
|
||||
active: boolean,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export enum ConfigureUrl
|
||||
{
|
||||
//baseUrl = "http://localhost:61744",
|
||||
|
||||
authenticateUrl = "api/v1/Users/Authenticate", //no use anymore
|
||||
loginADUrl = "api/v1/Users/LoginAD",
|
||||
loginApiUrl = "api/v1/Users/LoginApiAD",
|
||||
validationPoint = "api/v1/ValidationPoint", //no "/" at the front
|
||||
adminUserUrl = "api/v1/AdminUser",
|
||||
concessionValidationUrl = "api/v1/ConcessionValidation",
|
||||
concessionValidationByIdUrl = "api/v1/ConcessionValidation/ConcessionValidationByStaff",
|
||||
CheckConcessionValidationByStaffUrl = "api/v1/ConcessionValidation/CheckConcessionValidationByStaff",
|
||||
concessionTypeUrl = "api/v1/ConcessionType",
|
||||
userByStaffIdUrl = "api/v1/Users/SearchApiStaff",
|
||||
luConcessionTypeUrl = "api/v1/LookupCode/ConcessionTypes",
|
||||
luValidationPointUrl = "api/v1/LookupCode/ValidationPoints",
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
export const MIMEType = {
|
||||
png: 'image/png',
|
||||
jpg: 'image/jpg',
|
||||
jpeg: 'image/jpeg',
|
||||
gif: 'image/gif',
|
||||
txt: 'text/plain',
|
||||
pdf: 'application/pdf'
|
||||
};
|
||||
|
||||
|
||||
//for status of object 0 no change, 1 changed , -1 is deleted.
|
||||
export enum mState {
|
||||
Delete = -1,
|
||||
NoChange = 0,
|
||||
Modified = 1,
|
||||
New =2,
|
||||
};
|
||||
|
||||
export enum PickListType {
|
||||
Ok =0,
|
||||
BodyPart = 16, // Body Part
|
||||
Location = 17,
|
||||
Equipment = 18,
|
||||
LocationType = 19,
|
||||
CheckList = 20,
|
||||
Company = 21,
|
||||
NonConformance = 22,
|
||||
Occupation = 23,
|
||||
IncidentType = 24,
|
||||
InvestigationAgency = 25,
|
||||
OutCome = 26,
|
||||
Visibility = 27,
|
||||
Surface = 28,
|
||||
Lighting = 29,
|
||||
Weather = 30,
|
||||
CauseOfPrimaryInjury = 31,
|
||||
ContributingFactor = 32,
|
||||
HazardControlType = 33,
|
||||
}
|
||||
|
||||
export enum userRole {
|
||||
Normal = 1,
|
||||
Admin = 2,
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export * from './user';
|
||||
export * from './validationpoint';
|
||||
export * from './enum';
|
||||
export * from './resultmodel';
|
||||
export * from './adminuser';
|
||||
export * from './configureUrl';
|
||||
export * from './concessionvalidation';
|
||||
export * from './lookup';
|
||||
export * from './concessiontype';
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
export interface Lookup {
|
||||
id: number;
|
||||
categoryId: number;
|
||||
description: string;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
export interface treeLookupCode {
|
||||
id: number;
|
||||
code: string;
|
||||
description: string;
|
||||
canCheck: number; // 0 no 1 is yes
|
||||
hasChild: number; // 0 no 1 is yes
|
||||
}
|
||||
|
||||
export interface LookupCode {
|
||||
id: number;
|
||||
code: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface LookupEnumContainer {
|
||||
enumId: number;
|
||||
list: LookupCode[];
|
||||
}
|
||||
|
||||
export interface BusinessUnitLookup {
|
||||
id: number;
|
||||
abbreviation: string;
|
||||
levelID: number;
|
||||
name: string;
|
||||
parentID: number;
|
||||
}
|
||||
|
||||
export interface LookupBUData {
|
||||
allowMultiSelect: boolean;
|
||||
pickListTitle: string;
|
||||
lookupList: BusinessUnitLookup[];
|
||||
}
|
||||
|
||||
|
||||
export interface LookupData {
|
||||
allowMultiSelect:boolean;
|
||||
pickListTitle: string;
|
||||
lookupList: LookupCode[];
|
||||
};
|
||||
|
||||
export interface LookupCodeContainer {
|
||||
list: LookupCode[];
|
||||
totalPages: number;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
export interface PageQuery {
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
search: string;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import { Lookup } from './lookup';
|
||||
|
||||
export interface SharePersonContainer {
|
||||
list: PersonLite[];
|
||||
totalPages: number;
|
||||
}
|
||||
export interface PersonLite {
|
||||
id: number;
|
||||
firstName: string;
|
||||
surname: string;
|
||||
referenceNo: string;
|
||||
payrollNo: number;
|
||||
email: string;
|
||||
phoneNo: string;
|
||||
}
|
||||
|
||||
export interface PersonLookup {
|
||||
categorys: Lookup[];
|
||||
title: Lookup[]; ///for source
|
||||
positions: Lookup[]; ///for source
|
||||
companys: Lookup[];
|
||||
personStatus: Lookup[];
|
||||
englishLevel: Lookup[];
|
||||
yesNoPickList: Lookup[];
|
||||
language: Lookup[];
|
||||
residence: Lookup[];
|
||||
nationality: Lookup[];
|
||||
gender: Lookup[];
|
||||
|
||||
}
|
||||
|
||||
export interface PersonContainer {
|
||||
person: Person;
|
||||
|
||||
}
|
||||
|
||||
export class Person {
|
||||
id: number =0;
|
||||
titleId: number =0;
|
||||
firstName: string = '';
|
||||
surname: string = '';
|
||||
referenceNo: string = '';
|
||||
workNo: string = '';
|
||||
email: string = '';
|
||||
categoryId: number = 0;
|
||||
statusId: number = 0;
|
||||
statusDate: string = '';
|
||||
businessUnitId: number = 0;
|
||||
businessUnitDesc: string = '';
|
||||
}
|
||||
|
||||
export interface PersonDetail {
|
||||
street: string;
|
||||
postCode: string;
|
||||
suburb: string;
|
||||
state: string;
|
||||
country: string;
|
||||
home: string;
|
||||
fax: string;
|
||||
mobile: string;
|
||||
work: string;
|
||||
email: string;
|
||||
|
||||
mailStreetPostCode: string;
|
||||
mailPostCode: string;
|
||||
mailSuburb: string;
|
||||
mailState: string;
|
||||
mailCountry: string;
|
||||
|
||||
dateOfBirth: string;
|
||||
genderId: number;
|
||||
nationalityId: number;
|
||||
residenceId: number;
|
||||
englishLevelId: number;
|
||||
interpretRequired: number;
|
||||
|
||||
languageSpokenId: string;
|
||||
driverLicenceNo: string;
|
||||
expiryDate: string;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { treeLookupCode } from './lookupcode';
|
||||
|
||||
enum EnumLookup {
|
||||
BodyPart = 16,
|
||||
Location = 17,
|
||||
Equipment = 18,
|
||||
LocationType = 19,
|
||||
CheckList = 20
|
||||
}
|
||||
|
||||
export class DataNode {
|
||||
loaded: boolean = false;
|
||||
name: string ='';
|
||||
id: number = 0;
|
||||
children: DataNode[] =[];
|
||||
|
||||
}
|
||||
|
||||
export class UIDataNode {
|
||||
allowMultiSelect: boolean = false;
|
||||
pickListTitle: string = '';
|
||||
enumPickType: number = 0;
|
||||
children: treeLookupCode[] = [];
|
||||
}
|
||||
|
||||
/** Nested node */
|
||||
export class DataNode$ {
|
||||
childrenChange = new BehaviorSubject<DataNode$[]>([]);
|
||||
expanable = new BehaviorSubject<boolean>(true);
|
||||
|
||||
|
||||
get children(): DataNode$[] {
|
||||
return this.childrenChange.value;
|
||||
}
|
||||
get isExpanable(): boolean {
|
||||
return this.expanable.value;
|
||||
}
|
||||
constructor(public id: number,
|
||||
public name: string,
|
||||
public canCheck: boolean,
|
||||
public hasChildren: boolean,
|
||||
public parentId: number,
|
||||
public loadMoreParentItem: number | null = null) { }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface ResultModel<T> {
|
||||
data: T;
|
||||
message: string;
|
||||
statusCode:number;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export class User {
|
||||
id: number = 0;
|
||||
username: string = '';
|
||||
role: number = -1;
|
||||
firstName: string = '';
|
||||
lastName: string = '';
|
||||
email:string = '';
|
||||
token:string ='';
|
||||
validationPointId:number = 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface ValidationPoint {
|
||||
id: number,
|
||||
description: string,
|
||||
display: string,
|
||||
active: boolean,
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.mat-expansion-panel-header {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
a:hover,
|
||||
a:active {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.nav-caption{
|
||||
display:inline-block;
|
||||
padding-left: 10px;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<mat-nav-list>
|
||||
<a *ngIf="isAuth" mat-list-item [routerLink]='["/home/concessionvalidation"]' (click)='collapse()'>
|
||||
<mat-icon>assignment_turned_in</mat-icon><span class="nav-caption">Concession Validation</span>
|
||||
</a>
|
||||
<a *ngIf="isAdmin" mat-list-item [routerLink]='["/home/app-concessionvalidation-report"]' (click)='collapse()'>
|
||||
<mat-icon>description</mat-icon> <span class="nav-caption">Report</span>
|
||||
</a>
|
||||
<!--a *ngIf="isAdmin" mat-list-item href="http://nephmdb-sql007/CarParkValidationReport/Reports/ConcessionValidation.aspx" target="_blank" (click)='collapse()'>
|
||||
<mat-icon>description</mat-icon> <span class="nav-caption">Report 007</span>
|
||||
</a>
|
||||
<a *ngIf="isAdmin" mat-list-item href="http://virtapp-mdb048/CarParkValidationReport/Reports/ConcessionValidation.aspx" target="_blank" (click)='collapse()'>
|
||||
<mat-icon>description</mat-icon> <span class="nav-caption">Report 048</span>
|
||||
</a-->
|
||||
|
||||
<!--Admin menu-->
|
||||
<mat-accordion *ngIf="isAdmin">
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<mat-icon>settings</mat-icon> <span class="nav-caption">Settings</span>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<a mat-list-item [routerLink]='["/home/adminuser"]' (click)='collapse()'>
|
||||
<mat-icon>manage_accounts</mat-icon><span class="nav-caption">Admin User</span>
|
||||
</a>
|
||||
<a mat-list-item [routerLink]='["/home/concessiontype"]' (click)='collapse()'>
|
||||
<mat-icon>redeem</mat-icon> <span class="nav-caption">Concession Type</span>
|
||||
</a>
|
||||
<a mat-list-item [routerLink]='["/home/validationpoint"]' (click)='collapse()'>
|
||||
<mat-icon>report_problem</mat-icon> <span class="nav-caption">Validation Point</span>
|
||||
</a>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
<a *ngIf="!isAuth" mat-list-item [routerLink]='["/login"]' (click)='collapse()'>
|
||||
<mat-icon>input</mat-icon><span class="nav-caption">Login</span>
|
||||
</a>
|
||||
<a *ngIf="isAuth" mat-list-item [routerLink]='["/login"]' (click)='onLogout()'>
|
||||
<mat-icon>input</mat-icon><span class="nav-caption">Logout</span>
|
||||
</a>
|
||||
|
||||
</mat-nav-list>
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Component, EventEmitter, Output, OnInit, OnDestroy } from '@angular/core';
|
||||
import { AuthenticationService } from '../user-services';
|
||||
import { Subscription } from 'rxjs'
|
||||
import { Router } from '@angular/router';
|
||||
import { Utils } from '../shares';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-menu',
|
||||
templateUrl: './nav-menu.component.html',
|
||||
styleUrls: ['./nav-menu.component.css']
|
||||
})
|
||||
export class NavMenuComponent implements OnInit, OnDestroy{
|
||||
|
||||
isAuth = false;
|
||||
isAdmin = false;
|
||||
panelOpenState = false;
|
||||
authSubscription!: Subscription;
|
||||
@Output() closeMe: EventEmitter<boolean> = new EventEmitter();
|
||||
|
||||
|
||||
constructor(private authService: AuthenticationService, private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.authSubscription = this.authService.authChange.subscribe(currentUser => {
|
||||
this.isAuth = Utils.getIsAuth();
|
||||
this.isAdmin = Utils.getIsAdmin();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.authSubscription) {
|
||||
this.authSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
collapse() {
|
||||
this.closeMe.emit(true);
|
||||
}
|
||||
|
||||
onLogout() {
|
||||
console.log("onlogout click");
|
||||
this.collapse();
|
||||
this.authService.logout();
|
||||
// this.router.navigate(['/login']);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:active {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
|
||||
/* may be is not use anymore */
|
||||
li .glyphicon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.navigation-items {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Highlighting rules for nav menu items */
|
||||
li.link-active a,
|
||||
li.link-active a:hover,
|
||||
li.link-active a:focus {
|
||||
background-color: #4189C7;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Keep the nav menu independent of scrolling and on top of other items */
|
||||
.main-nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<mat-toolbar class="flex justify-content-between" style="background-color: #e12a40;">
|
||||
|
||||
<div style="margin-top: 5px;padding-right: 35px; cursor: pointer;height:70px;">
|
||||
<img (click)="onHome()" src="assets/images/application_image.png" alt="Parking Concession Validation Register"
|
||||
style="height:70px;width:320px" />
|
||||
</div>
|
||||
<div class="flex justify-content-end">
|
||||
<ul class="navigation-items">
|
||||
<li *ngIf="!isAuth">
|
||||
<a [routerLink]='["/login"]'>
|
||||
Login
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="font-bold text-white">
|
||||
{{currentUserName}}
|
||||
</div>
|
||||
<button (click)="onToggle()" mat-icon-button type="button"><mat-icon>arrow_drop_down</mat-icon></button>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
@@ -0,0 +1,51 @@
|
||||
import { AuthenticationService } from '../user-services';
|
||||
import { Subscription } from 'rxjs'
|
||||
import { Component, EventEmitter, Output, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Utils } from '../shares';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-toolbar',
|
||||
templateUrl: './nav-toolbar.component.html',
|
||||
styleUrls: ['./nav-toolbar.component.css']
|
||||
})
|
||||
export class NavToolarComponent implements OnInit, OnDestroy {
|
||||
isExpanded = false;
|
||||
isAuth = false;
|
||||
isAdmin = false;
|
||||
currentUserName = "";
|
||||
authSubscription: Subscription = new Subscription;
|
||||
@Output() toggleEvent: EventEmitter<boolean> = new EventEmitter();
|
||||
constructor(private authService: AuthenticationService,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.authSubscription = this.authService.authChange.subscribe(currentUser => {
|
||||
this.isAuth = Utils.getIsAuth();
|
||||
this.isAdmin = Utils.getIsAdmin();
|
||||
this.currentUserName = currentUser;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.authSubscription) {
|
||||
this.authSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
onHome() {
|
||||
this.router.navigate(['/home/concessionvalidation']);
|
||||
}
|
||||
onToggle() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
this.toggleEvent.emit(this.isExpanded);
|
||||
}
|
||||
onLogout() {
|
||||
this.authService.logout();
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<div class="container">
|
||||
<h1>Not found</h1>
|
||||
<button [routerLink]="['/']">Return to home page</button>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-found',
|
||||
templateUrl: './not-found.component.html',
|
||||
styleUrls: ['./not-found.component.css']
|
||||
})
|
||||
export class NotFoundComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export * from './person.component';
|
||||
export * from './person.list.component';
|
||||
export * from './person.edit.component';
|
||||
export * from './person.detail.edit.component';
|
||||
export * from './person.service';
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
th.mat-sort-header-sorted {
|
||||
color: black;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<h1>Person List</h1>
|
||||
|
||||
<p>This component demonstrates Person material table.</p>
|
||||
<mat-form-field>
|
||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter">
|
||||
</mat-form-field>
|
||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
||||
<!-- Id Column -->
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef> Id </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- ReferenceNo Column -->
|
||||
<ng-container matColumnDef="referenceNo">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> ReferenceNo </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.referenceNo}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- FirstName Column -->
|
||||
<ng-container matColumnDef="firstName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> FirstName </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.firstName}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Surname Column -->
|
||||
<ng-container matColumnDef="surname">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Surname </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.surname}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="edit" stickyEnd>
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a [routerLink]='["/person", element.id]' [queryParams]="{returnUrl:'/person'}">
|
||||
<mat-icon>border_color</mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSize]="5" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
|
||||
<!--
|
||||
|
||||
<p *ngIf="!persons"><em>Loading...</em></p>
|
||||
|
||||
<table class='table' *ngIf="persons">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>ReferenceNo</th>
|
||||
<th>First Name</th>
|
||||
<th>Surname</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let person of persons">
|
||||
<td> person.id </td>
|
||||
<td> person.referenceNo </td>
|
||||
<td> person.firstName </td>
|
||||
<td> person.surname </td>
|
||||
<td>
|
||||
<a [routerLink]='["/person", person.id]' [queryParams]="{returnUrl:'/person'}">
|
||||
<span class='glyphicon glyphicon-user'></span> Edit
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
-->
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Component, Inject, OnInit, AfterViewInit , ViewChild} from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { PersonService } from './person.service';
|
||||
import { Person } from '../models';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'person-data',
|
||||
templateUrl: './person.component.html',
|
||||
styleUrls: ['./person.component.css']
|
||||
})
|
||||
export class PersonComponent implements OnInit, AfterViewInit{
|
||||
|
||||
private _baseUrl: string;
|
||||
|
||||
dataSource: MatTableDataSource<Person>;
|
||||
displayedColumns: string[] = ['id', 'referenceNo', 'firstName', 'surname', 'edit'];
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
constructor(private http: HttpClient,
|
||||
private personService: PersonService,
|
||||
@Inject('BASE_URL') baseUrl: string) {
|
||||
this._baseUrl = baseUrl;
|
||||
this.dataSource = new MatTableDataSource<Person>();
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.sort = this.sort!;
|
||||
this.dataSource.paginator = this.paginator!;
|
||||
}
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.personService.loadPersons(10,1).subscribe(result => {
|
||||
console.log('Persons', result);
|
||||
this.dataSource.data = result;
|
||||
}, error => console.error(error));
|
||||
}
|
||||
|
||||
applyFilter($event:any) {
|
||||
const filterValue = $event.target.value;
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
|
||||
|
||||
<form [formGroup]="personDetailForm" >
|
||||
<div fxLayout
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="none"
|
||||
fxLayoutGap="10px"
|
||||
fxLayoutGap.xs="0">
|
||||
<div class="item1" fxFlex="30%" fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="home" matInput placeholder="Home">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="fax" matInput placeholder="Fax">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="mobile" matInput placeholder="Mobile">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="work" matInput placeholder="Work">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="email" formControlName="email" matInput placeholder="Email">
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="item2" fxFlex="30%" fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="street" matInput placeholder="Street">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="postCode" matInput placeholder="Post Code">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="suburb" matInput placeholder="Suburb">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="state" matInput placeholder="State">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="country" matInput placeholder="Country">
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<div class="item3" fxFlex fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="mailStreetPostCode" matInput placeholder="Street/PO Box">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="mailPostCode" matInput placeholder="Post Code">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="mailSuburb" matInput placeholder="Suburb">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="mailCountry" matInput placeholder="Country">
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
<!--second section this for space between two group.-->
|
||||
<div fxLayout="column" fxLayoutGap="10px"><p></p></div>
|
||||
<div
|
||||
fxLayout
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="none"
|
||||
fxLayoutGap="10px"
|
||||
fxLayoutGap.xs="0">
|
||||
|
||||
<div fxFlex="50%" class="item1" fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill>
|
||||
<mat-form-field>
|
||||
<input formControlName="dateOfBirth" matInput [matDatepicker]="DOBOnPicker" placeholder="Date Of Birth">
|
||||
<mat-datepicker-toggle matSuffix [for]="DOBOnPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #DOBOnPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<picklist-tree-comp [PickListDesc]="'Body Part'"
|
||||
[EnumPickListType]="getEnumBodyPartId()"
|
||||
[AllowMultiple]="true" [DialogTitle]="'Pick Body Part'"
|
||||
[placeholder]="'Body Part'" formControlName="genderId"></picklist-tree-comp>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Gender" formControlName="genderId">
|
||||
<mat-option *ngFor="let cs of lookup?.gender" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Nationality" formControlName="nationalityId">
|
||||
<mat-option *ngFor="let cs of lookup?.nationality" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Residence" formControlName="residenceId">
|
||||
<mat-option *ngFor="let cs of lookup?.residence" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="item2" fxFlex="30%" fxLayoutAlign="none stretch">
|
||||
<mat-card>
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="English Level" formControlName="englishLevelId">
|
||||
<mat-option *ngFor="let cs of lookup?.englishLevel" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Interpret Required" formControlName="interpretRequired">
|
||||
<mat-option *ngFor="let cs of lookup?.yesNoPickList" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Language Spoken" formControlName="languageSpokenId">
|
||||
<mat-option *ngFor="let cs of lookup?.language" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="driverLicenceNo" matInput placeholder="Driver Licence No">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input formControlName="expiryDate" matInput [matDatepicker]="expiryDateOnPicker" placeholder="Expirt Date">
|
||||
<mat-datepicker-toggle matSuffix [for]="expiryDateOnPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #expiryDateOnPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
@@ -0,0 +1,207 @@
|
||||
import { Component, OnInit, Input , Output, EventEmitter} from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { PersonDetail, LookupCode, PersonLookup, BusinessUnitLookup, LookupBUData, PickListType } from '../models';
|
||||
import { PersonService } from './person.service';
|
||||
import { OverlayService } from '../overlay/overlay.module';
|
||||
import { LookupService } from '../share/lookup.service';
|
||||
import { LookupTreeComponent } from '../share/lookup.tree.component';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'person.detail.edit.component.html',
|
||||
selector: 'person-detail-edit',
|
||||
styleUrls: ['person.detail.edit.component.css']
|
||||
})
|
||||
export class PersonDetailEditComponent implements OnInit {
|
||||
personDetailForm: FormGroup = this.formBuilder.group({
|
||||
street: [''],
|
||||
postCode: [''],
|
||||
suburb: [''],
|
||||
state: [''],
|
||||
country: [''],
|
||||
home: [''],
|
||||
fax: [''],
|
||||
mobile: [''],
|
||||
work: [''],
|
||||
email: [''],
|
||||
mailStreetPostCode: [''],
|
||||
mailPostCode: [''],
|
||||
mailSuburb: [''],
|
||||
mailState: [''],
|
||||
mailCountry: [''],
|
||||
dateOfBirth: [''],
|
||||
genderId: [0],
|
||||
nationalityId: [],
|
||||
residenceId: [0],
|
||||
englishLevelId: [0],
|
||||
interpretRequired: [0],
|
||||
languageSpokenId: [0],
|
||||
driverLicenceNo: [''],
|
||||
expiryDate: [''],
|
||||
});
|
||||
|
||||
loading = false;
|
||||
submitted = false;
|
||||
returnUrl: string= '';
|
||||
error = '';
|
||||
lookup: PersonLookup |undefined;
|
||||
@Input()
|
||||
set PersonDetailObj(value: PersonDetail) {
|
||||
this.assignValue(value);
|
||||
}
|
||||
@Output() detailFieldChangeEvent = new EventEmitter<any>();
|
||||
set Lookup(value: PersonLookup) {
|
||||
this.lookup = value;
|
||||
}
|
||||
constructor(
|
||||
private previewProgressSpinner: OverlayService,
|
||||
private lookupService: LookupService,
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private dialog: MatDialog,
|
||||
private personService: PersonService
|
||||
)
|
||||
{
|
||||
//this.lookup = { categorys: [], positions: [], companys: [], personStatus: [], englishLevel: [] };
|
||||
}
|
||||
|
||||
getEnumBodyPartId(): number {
|
||||
return PickListType.BodyPart;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
let id = this.route.snapshot.paramMap.get('id');
|
||||
this.buildFormGroup();
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
console.log('the return Url is ', this.returnUrl);
|
||||
|
||||
}
|
||||
|
||||
buildFormGroup(): void {
|
||||
|
||||
this.personDetailForm.valueChanges.subscribe(x => {
|
||||
console.log("the person detail edit component data fields are changes", x);
|
||||
console.log(" emit to listener etc ....");
|
||||
this.detailFieldChangeEvent.emit(true);
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
getPersonDetail() {
|
||||
const isChange = this.personDetailForm.dirty;
|
||||
if ( isChange) {
|
||||
const person = this.personDetailForm.value;
|
||||
|
||||
const personDetail: PersonDetail = {
|
||||
|
||||
street: person.street,
|
||||
postCode: person.postCode,
|
||||
state: person.state,
|
||||
suburb: person.suburb,
|
||||
country: person.country,
|
||||
home: person.home,
|
||||
mobile: person.mobile,
|
||||
work: person.work,
|
||||
email: person.email,
|
||||
fax: person.fax,
|
||||
|
||||
mailStreetPostCode: person.mailStreetPostCode,
|
||||
mailPostCode: person.mailPostCode,
|
||||
mailSuburb: person.mailSuburb,
|
||||
mailState: person.mailState,
|
||||
mailCountry: person.mailCountry,
|
||||
|
||||
dateOfBirth: person.dateOfBirth,
|
||||
genderId: person.genderId,
|
||||
nationalityId: person.nationalityId,
|
||||
residenceId: person.residenceId,
|
||||
englishLevelId: person.englishLevelId,
|
||||
interpretRequired: person.interpretRequired,
|
||||
|
||||
languageSpokenId: person.languageSpokenId,
|
||||
driverLicenceNo: person.driverLicenceNo,
|
||||
expiryDate: person.expiryDate
|
||||
|
||||
}
|
||||
|
||||
return personDetail;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
assignValue(person: PersonDetail):void {
|
||||
console.log("assign value ", person);
|
||||
this.personDetailForm.patchValue(
|
||||
{
|
||||
state: person.state,
|
||||
country: person.country,
|
||||
street: person.street,
|
||||
postCode: person.postCode,
|
||||
home: person.home,
|
||||
mobile: person.mobile,
|
||||
work: person.work,
|
||||
email: person.email,
|
||||
fax: person.fax,
|
||||
|
||||
mailStreetPostCode: person.mailStreetPostCode,
|
||||
mailPostCode: person.mailPostCode,
|
||||
mailSuburb: person.mailSuburb,
|
||||
mailState: person.mailState,
|
||||
mailCountry: person.mailCountry,
|
||||
|
||||
dateOfBirth: person.dateOfBirth,
|
||||
genderId: person.genderId,
|
||||
nationalityId: person.nationalityId,
|
||||
residenceId: person.residenceId,
|
||||
englishLevelId: person.englishLevelId,
|
||||
interpretRequired: person.interpretRequired,
|
||||
|
||||
languageSpoken: person.languageSpokenId,
|
||||
driverLicenceNo: person.driverLicenceNo,
|
||||
expiryDate: person.expiryDate
|
||||
});
|
||||
}
|
||||
// convenience getter for easy access to form fields
|
||||
get f() { return this.personDetailForm.controls; }
|
||||
|
||||
businessLookup(): void {
|
||||
console.log('lookup person Dialog click.');
|
||||
this.previewProgressSpinner.showLoading();
|
||||
this.lookupService.loadBusinessLookup(0).subscribe(result => {
|
||||
console.log('lookup business', result);
|
||||
this.previewProgressSpinner.close();
|
||||
|
||||
const dialogRef = this.openBULookup(result, true);
|
||||
dialogRef.afterClosed().subscribe((result: string | any[]) => {
|
||||
console.log('The dialog was closed patchValue', result);
|
||||
|
||||
if (result && result.length > 0) {
|
||||
let fitem = result[0];
|
||||
|
||||
this.personDetailForm.patchValue(
|
||||
{
|
||||
businessUnitId: fitem.id,
|
||||
businessUnitDesc : fitem.description
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}, error => console.error(error));
|
||||
}
|
||||
openBULookup(data: BusinessUnitLookup[], allowMulti: boolean): any {
|
||||
var lookup: LookupBUData = { allowMultiSelect: allowMulti, lookupList: data, pickListTitle: "Business Unit" };
|
||||
const dialogRef = this.dialog.open(LookupTreeComponent, {
|
||||
width: '600px',
|
||||
data: lookup
|
||||
});
|
||||
return dialogRef;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
.example-button-row button,
|
||||
.example-button-row a {
|
||||
margin-right: 2px;
|
||||
}
|
||||
form {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<form [formGroup]="personForm" (ngSubmit)="onSubmit()">
|
||||
<div >
|
||||
<button type="submit" mat-icon-button color="primary" [disabled]="isFieldsChange">
|
||||
<mat-icon title="Save" aria-label="Example icon-button with a heart icon">save</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div fxLayout
|
||||
fxLayout.xs="column"
|
||||
fxLayoutAlign="none"
|
||||
fxLayoutGap="10px"
|
||||
fxLayoutGap.xs="0">
|
||||
<div class="item1" fxFlex="20%" fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill>
|
||||
<input type="hidden" formControlName="id">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Title" formControlName="titleId">
|
||||
<mat-option *ngFor="let title of lookup?.title" [value]="title.id">
|
||||
{{title.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="referenceNo" matInput placeholder="Reference No">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="firstName" matInput placeholder="FirtName" [ngClass]="{ 'is-invalid': submitted && f.firstName.errors }">
|
||||
</mat-form-field>
|
||||
<div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
|
||||
<div *ngIf="f.firstname.errors!.required">firstname is required</div>
|
||||
</div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="surname" matInput placeholder="Surname" [ngClass]="{ 'is-invalid': submitted && f.surname.errors }">
|
||||
</mat-form-field>
|
||||
<div *ngIf="submitted && f.surname.errors" class="invalid-feedback">
|
||||
<div *ngIf="f.password.errors!.required">surname is required</div>
|
||||
</div>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="workNo" matInput placeholder="Telephone No">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" formControlName="email" matInput placeholder="Email">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Category" formControlName="categoryId">
|
||||
<mat-option *ngFor="let category of lookup?.categorys" [value]="category.id">
|
||||
{{category.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="item2" fxFlex="35%" fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill fxLayoutAlign="none stretch">
|
||||
<div fxLayout="column" fxLayoutAlign="none stretch">
|
||||
<business-lookup-comp [businessDesc]="personForm.value.businessUnitDesc" [placeholder]="'Business'" formControlName="businessUnitId"></business-lookup-comp>
|
||||
<div fxLayout="row" fxFill fxLayoutAlign="none stretch">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="Status" formControlName="statusId">
|
||||
<mat-option *ngFor="let cs of lookup?.personStatus" [value]="cs.id">
|
||||
{{cs.description}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Status Date" formControlName="statusDate" readonly>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<pre>{{ personForm.value|json}}</pre>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,209 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { Subject, pipe } from 'rxjs';
|
||||
import {Person, PersonContainer, PersonLookup, BusinessUnitLookup, LookupBUData, PersonDetail } from '../models';
|
||||
import { PersonService } from './person.service';
|
||||
import { OverlayService } from '../overlay/overlay.module';
|
||||
import { LookupService } from '../share/lookup.service';
|
||||
import { LookupTreeComponent } from '../share/lookup.tree.component';
|
||||
//import { PersonDetailEditComponent } from './person.detail.edit.component';
|
||||
|
||||
/* NgRx */
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import * as fromSelector from './store/selectors/person.selector';
|
||||
import * as fromAppState from './store/reducers/person.app.state';
|
||||
import * as fromActions from './store/actions/person.action';
|
||||
|
||||
|
||||
@Component({
|
||||
templateUrl: 'person.edit.component.html',
|
||||
selector: 'person-edit',
|
||||
styleUrls: ['person.edit.component.css']
|
||||
})
|
||||
export class PersonEditComponent implements OnInit {
|
||||
personForm: FormGroup = this.formBuilder.group({
|
||||
id: [0],
|
||||
businessUnitId: [0],
|
||||
titleId: [0],
|
||||
statusId: [{ value: 0, disabled: true }],
|
||||
categoryId: [0],
|
||||
statusDate: [''],
|
||||
email: [''],
|
||||
businessUnitDesc: [''],
|
||||
referenceNo: [''],
|
||||
firstName: ['', Validators.required],
|
||||
surname: ['', Validators.required],
|
||||
workNo: [''],
|
||||
});
|
||||
loading = false;
|
||||
submitted = false;
|
||||
returnUrl: string = '';
|
||||
isChange = true;
|
||||
subChanged$ = new Subject<boolean>();
|
||||
error = '';
|
||||
lookup: any;
|
||||
// @ViewChild(PersonDetailEditComponent, { static: true }) personDetailComp: PersonDetailEditComponent;
|
||||
constructor(
|
||||
private previewProgressSpinner: OverlayService,
|
||||
private lookupService: LookupService,
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private store: Store<fromAppState.AppState>,
|
||||
private dialog: MatDialog,
|
||||
private personService: PersonService) {
|
||||
this.lookup = {
|
||||
categorys: [], title: [], personStatus: [], yesNoPickList: [],
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
//let id = this.route.snapshot.paramMap.get('id');
|
||||
const id = this.route.snapshot.params.id;
|
||||
//subject track for change
|
||||
this.personForm.valueChanges.subscribe(x => this.isChange = false);
|
||||
this.subChanged$.subscribe(x => this.isChange = x);
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
console.log("the id:" + id);
|
||||
console.log("person id: ", this.route.snapshot);
|
||||
if (id) {
|
||||
this.store.dispatch(fromActions.LoadPersonById({ id: +id }));
|
||||
this.store.pipe(select(fromSelector.getPersonForEdit))
|
||||
.subscribe(result => {
|
||||
if (result != null) {
|
||||
// this.personDetailComp.PersonDetailObj = result.personDetail;
|
||||
this.assignValue(result.person);
|
||||
console.log("here the get person for edit is select from store", result);
|
||||
this.subChanged$.next(true); //reset it.
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
console.log("new Person empty from edit person");
|
||||
|
||||
//get lookup
|
||||
this.personService.loadPersonPickList().subscribe(result => {
|
||||
this.lookup = result;
|
||||
// this.personDetailComp.Lookup = this.lookup;
|
||||
console.log('the lookup for person ', this.lookup);
|
||||
});
|
||||
|
||||
|
||||
|
||||
this.store.pipe(select(fromSelector.getPersonStatusCode)).subscribe(
|
||||
/* go back to return url */
|
||||
no => {
|
||||
if (no < 0)
|
||||
{
|
||||
console.log('ERROR ');
|
||||
}
|
||||
else if (no == 1) {
|
||||
console.log('close Edit it! save already: ' + this.returnUrl);
|
||||
this.router.navigate([this.returnUrl]);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
assignValue(person: Person) {
|
||||
console.log("assign value ", person);
|
||||
this.personForm.patchValue(
|
||||
{
|
||||
id: person.id,
|
||||
firstName: person.firstName,
|
||||
surname: person.surname,
|
||||
titleId: person.titleId,
|
||||
workNo: person.workNo,
|
||||
referenceNo: person.referenceNo,
|
||||
email: person.email,
|
||||
|
||||
statusId: person.statusId,
|
||||
|
||||
categoryId: person.categoryId,
|
||||
statusDate: person.statusDate,
|
||||
businessUnitId: person.businessUnitId,
|
||||
businessUnitDesc: person.businessUnitDesc
|
||||
});
|
||||
}
|
||||
// convenience getter for easy access to form fields
|
||||
get f() { return this.personForm.controls; }
|
||||
|
||||
businessLookup(): void {
|
||||
console.log('lookup person Dialog click.');
|
||||
this.previewProgressSpinner.showLoading();
|
||||
this.lookupService.loadBusinessLookup(0).subscribe(result => {
|
||||
console.log('lookup business', result);
|
||||
this.previewProgressSpinner.close();
|
||||
|
||||
const dialogRef = this.openBULookup(result, false);
|
||||
dialogRef.afterClosed().subscribe((result: string | any[]) => {
|
||||
console.log('The dialog was closed patchValue', result);
|
||||
|
||||
if (result && result.length > 0) {
|
||||
const fitem = result[0];
|
||||
this.personForm.patchValue(
|
||||
{
|
||||
businessUnitId: fitem.id,
|
||||
businessUnitDesc : fitem.description
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}, error => console.error(error));
|
||||
}
|
||||
openBULookup(data: BusinessUnitLookup[], allowMulti: boolean): any {
|
||||
const lookup = { allowMultiSelect: allowMulti, lookupList: data, pickListTitle: "Business Unit" };
|
||||
const dialogRef = this.dialog.open(LookupTreeComponent, {
|
||||
width: '600px',
|
||||
data: lookup
|
||||
});
|
||||
return dialogRef;
|
||||
}
|
||||
onDetailChange(isChange: boolean) {
|
||||
console.log("<incidentReport Edit> Incident Detail Edit fire event ", isChange);
|
||||
this.subChanged$.next(false);
|
||||
}
|
||||
get isFieldsChange() {
|
||||
const chan = this.isChange;
|
||||
console.log('is fields change', chan);
|
||||
return chan;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.submitted = true;
|
||||
|
||||
// stop here if form is invalid
|
||||
if (this.personForm.invalid) {
|
||||
return;
|
||||
}
|
||||
const personValue = this.personForm.value;
|
||||
//console.log("save person Value", personValue);
|
||||
this.loading = true;
|
||||
const person: Person = {
|
||||
id: +personValue.id,
|
||||
firstName: personValue.firstName,
|
||||
surname: personValue.surname,
|
||||
titleId: personValue.titleId,
|
||||
|
||||
referenceNo: personValue.referenceNo,
|
||||
workNo: personValue.workNo,
|
||||
email: personValue.email,
|
||||
statusId: personValue.statusId,
|
||||
|
||||
categoryId: personValue.categoryId,
|
||||
statusDate: '',
|
||||
|
||||
businessUnitId: personValue.businessUnitId,
|
||||
businessUnitDesc: '',
|
||||
};
|
||||
|
||||
//const personDetail = this.personDetailComp.getPersonDetail();
|
||||
const personContainer: PersonContainer = { person: person };
|
||||
this.store.dispatch(fromActions.SavePerson({ personContainer }));
|
||||
this.store.pipe(select(fromSelector.getPersonMessage)).subscribe(error => this.error = error);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
th.mat-sort-header-sorted {
|
||||
color: black;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.containerflex {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.displayflex {
|
||||
position: relative;
|
||||
background: white;
|
||||
flex-flow: column;
|
||||
width: 30%;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
font-size: large;
|
||||
background: rgba(0, 0, 0, 0.5); /* Black see-through */
|
||||
}
|
||||
.mat-card:hover .overlay {
|
||||
opacity:0.8;
|
||||
}
|
||||
|
||||
.myButton {
|
||||
float: right;
|
||||
background-color: aqua;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<h1>Person List</h1>
|
||||
<button mat-button class="myButton" (click)="newPerson()">New</button>
|
||||
<mat-form-field>
|
||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter">
|
||||
</mat-form-field>
|
||||
<div class="containerflex" *ngIf="(persons$ | async) as persons">
|
||||
<div class="displayflex" *ngFor="let person of persons; let idx = index">
|
||||
<mat-card fxLayout="column" fxLayoutAlign="center center" >
|
||||
<div class="overlay" >
|
||||
<button mat-button class="myButton" (click)="editPerson(person.id)">edit</button>
|
||||
</div>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput placeholder="Reference No" [value]="person?.referenceNo">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput placeholder="First Name" [value]="person.firstName">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput placeholder="Surname Name" [value]="person.surname">
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
<!--<div fxFlex="33%" fxLayoutAlign="none stretch">
|
||||
<mat-card fxLayout="column" fxFill>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput placeholder="Reference No" [ngModel]="person.referenceNo">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput placeholder="First Name" [value]="person.firstName">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput placeholder="Last Name" [value]="person.lastName">
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>-->
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Component, Inject, OnInit, AfterViewInit , ViewChild} from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { PersonService } from './person.service';
|
||||
import { Person } from '../models';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
/* NgRx */
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import * as fromSelector from './store/selectors/person.selector';
|
||||
import * as fromAppState from './store/reducers/person.app.state';
|
||||
import * as fromActions from './store/actions/person.action';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'person-list-data',
|
||||
templateUrl: './person.list.component.html',
|
||||
styleUrls: ['./person.list.component.css']
|
||||
})
|
||||
export class PersonListComponent implements OnInit, AfterViewInit{
|
||||
|
||||
private _baseUrl: string;
|
||||
private _show: boolean;
|
||||
// persons: any[];
|
||||
_currentPos: number;
|
||||
persons$!: Observable<Person[]> | null;
|
||||
constructor(private http: HttpClient,
|
||||
private router: Router,
|
||||
private store: Store<fromAppState.AppState>,
|
||||
private personService: PersonService,
|
||||
|
||||
@Inject('BASE_URL') baseUrl: string) {
|
||||
this._baseUrl = baseUrl;
|
||||
this._show = false;
|
||||
this._currentPos = -1;
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
|
||||
this.store.dispatch(fromActions.LoadPersons({ pageSize: 10, currentPage: 1 }));
|
||||
this.persons$ = this.store.pipe(select(fromSelector.getAllPerson));
|
||||
|
||||
}
|
||||
editPerson(id: number) {
|
||||
console.log("edit person call " + id.toString());
|
||||
this.router.navigate(['/person/' + id.toString()], { queryParams: { returnUrl: '/person' } } );
|
||||
|
||||
}
|
||||
newPerson(): void {
|
||||
this.router.navigate(['/person/new'], { queryParams: { returnUrl: '/person' } });
|
||||
}
|
||||
|
||||
toogle(idx: number) {
|
||||
this._show = !this._show;
|
||||
this._currentPos = idx;
|
||||
}
|
||||
applyFilter($event:any) {
|
||||
const filterValue = $event.target.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { AppOverlayModule } from '../overlay/overlay.module';
|
||||
|
||||
import { PersonComponent } from './person.component';
|
||||
import { PersonDetailEditComponent } from './person.detail.edit.component';
|
||||
import { PersonEditComponent } from './person.edit.component';
|
||||
import { PersonListComponent } from './person.list.component';
|
||||
import { PersonService } from './person.service';
|
||||
import { ShareLookUpModule } from '../share/share.lookup.module';
|
||||
|
||||
import { AppMaterialModule } from '../material/app.material.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
/*NgRx*/
|
||||
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { reducers } from './store/reducers';
|
||||
import { effects } from './store/effects';
|
||||
import { JwtInterceptor } from '../helpers';
|
||||
import { AuthGuard } from '../helpers';
|
||||
|
||||
const personRoutes: Routes = [
|
||||
{ path: '', component: PersonListComponent, canActivate: [AuthGuard] },
|
||||
{
|
||||
path: 'new', component: PersonEditComponent, canActivate: [AuthGuard] ,
|
||||
data: {
|
||||
action: 1
|
||||
}
|
||||
},
|
||||
{ path: ':id', component: PersonEditComponent, canActivate: [AuthGuard] },
|
||||
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
PersonDetailEditComponent,
|
||||
PersonComponent,
|
||||
PersonListComponent,
|
||||
PersonEditComponent,
|
||||
|
||||
],
|
||||
exports: [
|
||||
PersonDetailEditComponent,
|
||||
PersonComponent,
|
||||
PersonListComponent,
|
||||
PersonEditComponent,
|
||||
],
|
||||
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpClientModule,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
AppOverlayModule,
|
||||
AppMaterialModule,
|
||||
ShareLookUpModule,
|
||||
RouterModule.forChild(personRoutes),
|
||||
StoreModule.forFeature('persons', reducers),
|
||||
EffectsModule.forFeature(effects),
|
||||
|
||||
],
|
||||
providers: [
|
||||
PersonService,
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
|
||||
],
|
||||
|
||||
})
|
||||
export class PersonModule { }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Person, PersonContainer, LookupCode, PersonLookup } from '../models';
|
||||
import { Observable } from 'rxjs';
|
||||
@Injectable()
|
||||
export class PersonService {
|
||||
|
||||
private _baseUrl: string;
|
||||
constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
|
||||
this._baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
savePerson(person: PersonContainer): Observable<number> {
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
//.set('authorization', 'Bearer ' + token);
|
||||
let options = {
|
||||
headers: headers
|
||||
};
|
||||
|
||||
console.log('save Person in savePersons serivice', person);
|
||||
return this.http.post<number>(this._baseUrl + 'api/Person/SavePerson', person, options);
|
||||
}
|
||||
|
||||
deletePerson(personId: number): Observable<any> {
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
//.set('authorization', 'Bearer ' + token);
|
||||
let options = {
|
||||
headers: headers
|
||||
};
|
||||
|
||||
console.log('deletePersons serivice', personId);
|
||||
return this.http.post<any>(this._baseUrl + 'api/Person/DeletePerson', personId, options);
|
||||
}
|
||||
|
||||
loadPersonById(id: number): Observable<PersonContainer> {
|
||||
console.log('get Person in loadPersonById serivice');
|
||||
let params = new HttpParams().set("personId", "" + id);
|
||||
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
//.set('authorization', 'Bearer ' + token);
|
||||
let options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
return this.http.get<PersonContainer>(this._baseUrl + 'api/Person/LoadPersonById', options);
|
||||
}
|
||||
|
||||
loadPersonPickList(): Observable<PersonLookup> {
|
||||
console.log('get loadPersonPickList serivice');
|
||||
return this.http.get<PersonLookup>(this._baseUrl + 'api/Person/LoadPersonPickList');
|
||||
}
|
||||
|
||||
loadPersons(pageSize: number, pageIndex: number ): Observable<Person[]>
|
||||
{
|
||||
console.log('get Person in loadPersons serivice');
|
||||
const params = new HttpParams().set("pageSize", "" + pageSize)
|
||||
.set("currentPage", "" + pageIndex);
|
||||
// .set("searchText", searchText)
|
||||
const headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||
const options = {
|
||||
headers: headers,
|
||||
params: params
|
||||
};
|
||||
|
||||
return this.http.get<Person[]>(this._baseUrl + 'api/Person/GetPersons', options);
|
||||
}
|
||||
|
||||
loadCategory(): Observable<LookupCode[]> {
|
||||
console.log('get Person in loadCategory serivice');
|
||||
return this.http.get<LookupCode[]>(this._baseUrl + 'api/Person/LoadCategory');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// Section 1
|
||||
|
||||
import { Action, createAction, props } from '@ngrx/store'
|
||||
import { Person, PersonContainer } from '../../../models';
|
||||
|
||||
// Section 2
|
||||
export enum ActionTypes {
|
||||
LOAD_PERSONS = '[PERSON] Loading Persons',
|
||||
LOAD_PERSONS_FAIL = '[PERSON] Load Persons Fail',
|
||||
LOAD_PERSONS_SUCCESS = '[PERSON] Load Persons Success',
|
||||
|
||||
LOAD_PERSON_BY_ID = '[PERSON] Loading Person By Id',
|
||||
LOAD_PERSON_BY_ID_FAIL = '[PERSON] Load Person By Id Fail',
|
||||
LOAD_PERSON_BY_ID_SUCCESS = '[PERSON] Load Person By Id Success',
|
||||
|
||||
SAVE_PERSON = '[PERSON] Starting Save',
|
||||
SAVE_PERSON_FAIL = '[PERSON] Save Fail',
|
||||
SAVE_PERSON_SUCCESS = '[PERSON] Save Success',
|
||||
DELETE_PERSON = '[PERSON] Delete',
|
||||
DELETE_PERSON_FAIL = '[PERSON] Delete Fail',
|
||||
DELETE_PERSON_SUCCESS = '[PERSON] Delete Success'
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const LoadPersonById = createAction(
|
||||
ActionTypes.LOAD_PERSON_BY_ID,
|
||||
props<{ id:number }>()
|
||||
);
|
||||
|
||||
export const LoadPersonByIdSuccess = createAction(
|
||||
ActionTypes.LOAD_PERSON_BY_ID_SUCCESS,
|
||||
props<{ personContainer: PersonContainer }>()
|
||||
);
|
||||
|
||||
export const LoadPersonByIdFail = createAction(
|
||||
ActionTypes.LOAD_PERSON_BY_ID_FAIL,
|
||||
props<{msg: any}>()
|
||||
);
|
||||
|
||||
// Section 3
|
||||
export const SavePerson = createAction (
|
||||
ActionTypes.SAVE_PERSON,
|
||||
props< {personContainer: PersonContainer}> ()
|
||||
);
|
||||
|
||||
export const SavePersonFail = createAction (
|
||||
ActionTypes.SAVE_PERSON_FAIL,
|
||||
props<{msg: any}>()
|
||||
);
|
||||
|
||||
export const SavePersonSuccess = createAction (
|
||||
ActionTypes.SAVE_PERSON_SUCCESS,
|
||||
props< {person: Person , message: string}>()
|
||||
|
||||
);
|
||||
|
||||
|
||||
export const DeletePerson = createAction (
|
||||
ActionTypes.DELETE_PERSON,
|
||||
props<{id: number}>()
|
||||
);
|
||||
|
||||
export const DeletePersonSuccess = createAction (
|
||||
ActionTypes.DELETE_PERSON_SUCCESS,
|
||||
props<{ id: number, message: string}> ()
|
||||
);
|
||||
|
||||
export const DeletePersonFail = createAction (
|
||||
ActionTypes.DELETE_PERSON_FAIL,
|
||||
props<{msg: any}>()
|
||||
);
|
||||
|
||||
export const LoadPersons = createAction(
|
||||
ActionTypes.LOAD_PERSONS,
|
||||
props<{pageSize:number, currentPage: number}>()
|
||||
);
|
||||
|
||||
// Succes
|
||||
export const LoadPersonsSuccess = createAction (
|
||||
ActionTypes.LOAD_PERSONS_SUCCESS,
|
||||
props<{persons: Person[]}>()
|
||||
);
|
||||
|
||||
// Fail
|
||||
export const LoadPersonsFail = createAction (
|
||||
ActionTypes.LOAD_PERSONS_FAIL,
|
||||
props<{msg: any}>()
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { PersonEffects } from './person.effect';
|
||||
|
||||
export const effects: any[] = [PersonEffects];
|
||||
|
||||
export * from './person.effect';
|
||||
@@ -0,0 +1,83 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Actions, Effect, ofType, createEffect } from '@ngrx/effects';
|
||||
import { map, switchMap, mergeMap, catchError } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import * as fromActions from '../actions/person.action';
|
||||
import { PersonService } from '../../person.service';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class PersonEffects {
|
||||
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private personService: PersonService
|
||||
) { }
|
||||
|
||||
loadPersonById$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(fromActions.LoadPersonById),
|
||||
switchMap((action) => {
|
||||
return this.personService.loadPersonById(action.id).pipe(
|
||||
map(person => fromActions.LoadPersonByIdSuccess({ personContainer: person })),
|
||||
catchError(err => observableOf(fromActions.LoadPersonByIdFail({ msg: err })))
|
||||
)
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
loadAllPerson$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(fromActions.LoadPersons),
|
||||
switchMap((action) => {
|
||||
return this.personService.loadPersons(action.pageSize, action.currentPage).pipe(
|
||||
map(Persons => fromActions.LoadPersonsSuccess({ persons: Persons })),
|
||||
catchError(err => observableOf(fromActions.LoadPersonsFail({ msg: err })))
|
||||
)
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
savePerson$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(fromActions.SavePerson),
|
||||
mergeMap(action => {
|
||||
return this.personService.savePerson(action.personContainer)
|
||||
.pipe(
|
||||
map(robj => {
|
||||
|
||||
let rperson = { ...action.personContainer.person, id: robj };
|
||||
rperson.id = robj;
|
||||
console.log("success effect save person", rperson);
|
||||
|
||||
return fromActions.SavePersonSuccess({ person: rperson, message: "" });
|
||||
}),
|
||||
|
||||
catchError(error => observableOf(fromActions.SavePersonFail({ msg: error })))
|
||||
); //end pipe
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
deletePerson$ = createEffect(() => this.actions$.pipe(
|
||||
ofType(fromActions.DeletePerson),
|
||||
mergeMap(action => {
|
||||
return this.personService
|
||||
.deletePerson(action.id)
|
||||
.pipe(
|
||||
map(robj => fromActions.DeletePersonSuccess({id:robj, message:""})),
|
||||
catchError(error => observableOf(fromActions.DeletePersonFail({msg:error})))
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
/*
|
||||
@Effect()
|
||||
searchArticleById$: Observable<Action> = this.actions$
|
||||
pipe( ofType<fromActions.GetByIdAction>(fromActions.GET_BY_ID),
|
||||
debounceTime(500),
|
||||
map(action => action.payload),
|
||||
switchMap(id =>
|
||||
this.hazardService.getArticleById(id)
|
||||
.map(res => new fromActions.GetByIdSuccessAction(res))
|
||||
);
|
||||
)
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import * as fromPerson from './person.reducer';
|
||||
import { ActionReducerMap, createFeatureSelector, ActionReducer, MetaReducer } from '@ngrx/store';
|
||||
import { appPersonState, AppState } from './person.app.state';
|
||||
import * as fromAppReducer from '../../../state/app.reducers';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
|
||||
export function logger(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
|
||||
return function (state, action): AppState {
|
||||
console.log('state', state);
|
||||
console.log('action', action);
|
||||
return reducer(state, action);
|
||||
};
|
||||
}
|
||||
|
||||
export const metaReducers: MetaReducer<AppState>[] = !environment.production
|
||||
? [logger]
|
||||
: [];
|
||||
|
||||
export const reducers: ActionReducerMap<AppState> = {
|
||||
persons: fromPerson.reducer,
|
||||
currentUser: fromAppReducer.PersonReducer,
|
||||
}
|
||||
|
||||
export * from './person.app.state';
|
||||
export const getPersonState = createFeatureSelector<AppState>(
|
||||
'persons'
|
||||
);
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Person, PersonContainer } from '../../../models';
|
||||
import * as fromAppState from '../../../state/app.state'
|
||||
|
||||
export interface AppState extends fromAppState.AppState {
|
||||
persons: appPersonState;
|
||||
}
|
||||
//status_code = -1 error
|
||||
//status_code = 1 sucess
|
||||
export interface appPersonState {
|
||||
entities: { [id: number]: Person };
|
||||
editPerson: PersonContainer | null;
|
||||
loaded: boolean;
|
||||
loading: boolean;
|
||||
statusCode: number;
|
||||
omessage: string;
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
import { Action, createReducer, on } from '@ngrx/store'
|
||||
import { Person } from '../../../models';
|
||||
import * as PersonActions from './../actions/person.action'
|
||||
import { appPersonState } from './person.app.state';
|
||||
|
||||
|
||||
// status_code
|
||||
export const initialState: appPersonState = { entities: {}, editPerson: null, loaded: false, loading: false, omessage: "init", statusCode: 0};
|
||||
|
||||
// Section 2
|
||||
const PersonReducer = createReducer(
|
||||
initialState,
|
||||
on(PersonActions.SavePersonSuccess, (state, action) =>
|
||||
{
|
||||
const pid = action.person.id;
|
||||
console.log("The payload is SAVE_PERSON_SUCCESS ", pid);
|
||||
const entities = {
|
||||
...state.entities,
|
||||
[pid]: action.person,
|
||||
|
||||
};
|
||||
|
||||
return {
|
||||
...state,
|
||||
entities,
|
||||
editPerson: null,
|
||||
statusCode: 1 //this is redirect to list component.
|
||||
};
|
||||
}),
|
||||
on(PersonActions.SavePersonFail, (state, { msg }) =>
|
||||
{
|
||||
|
||||
console.log("the payload is SAVE_PERSON_FAIL ", msg);
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
omessage: "ERROR " + msg,
|
||||
statusCode: -1
|
||||
};
|
||||
}),
|
||||
|
||||
on(PersonActions.LoadPersonByIdSuccess, (state, action) => {
|
||||
|
||||
return {
|
||||
...state,
|
||||
editPerson: action.personContainer,
|
||||
omessage: '',
|
||||
statusCode: 0
|
||||
};
|
||||
}
|
||||
),
|
||||
on(PersonActions.LoadPersonByIdFail, (state, action) => {
|
||||
|
||||
return {
|
||||
...state,
|
||||
editPerson: null,
|
||||
omessage: action.msg,
|
||||
statusCode: 0
|
||||
};
|
||||
}),
|
||||
on(PersonActions.LoadPersonByIdFail, (state, { msg }) =>
|
||||
{
|
||||
console.log("the load person by id fail ", msg);
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
omessage: "ERROR " + msg,
|
||||
editPerson: null,
|
||||
statusCode: -1
|
||||
};
|
||||
}),
|
||||
|
||||
on (PersonActions.LoadPersons, (state) =>
|
||||
{
|
||||
console.log("the load persons person.reducers");
|
||||
return {
|
||||
...state,
|
||||
loading: true,
|
||||
editPerson:null,
|
||||
statusCode: 0
|
||||
};
|
||||
}),
|
||||
|
||||
on(PersonActions.LoadPersonsSuccess, (state, { persons } ) =>
|
||||
{
|
||||
const entities = persons.reduce(
|
||||
(entities: { [id: number]: Person }, person: Person) => {
|
||||
return {
|
||||
...entities,
|
||||
[person.id]: person,
|
||||
|
||||
};
|
||||
},
|
||||
{
|
||||
...state.entities,
|
||||
|
||||
}
|
||||
);
|
||||
console.log('reducer PERSON load LOAD_PERSON_SUCCESS', persons);
|
||||
return {
|
||||
...state,
|
||||
entities,
|
||||
omessage: "",
|
||||
loading: false,
|
||||
loaded: true,
|
||||
editPerson: null,
|
||||
statusCode: 0,
|
||||
};
|
||||
|
||||
}
|
||||
),
|
||||
on(PersonActions.LoadPersonsFail, (state, { msg }) =>
|
||||
{
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
editPerson: null,
|
||||
omessage: "ERROR " + msg,
|
||||
statusCode: -1
|
||||
};
|
||||
}
|
||||
),
|
||||
on (PersonActions.DeletePerson, state =>
|
||||
{
|
||||
console.log('reducer Delete Person starting');
|
||||
return {
|
||||
...state,
|
||||
omessage:""
|
||||
};
|
||||
} ),
|
||||
on (PersonActions.DeletePersonSuccess , (state, action) =>
|
||||
{
|
||||
const pid = action.id;
|
||||
const { [pid]: removed, ...entities } = state.entities;
|
||||
|
||||
return {
|
||||
...state,
|
||||
entities,
|
||||
omessage: "Success",
|
||||
statusCode: 1
|
||||
};
|
||||
}
|
||||
),
|
||||
|
||||
on(PersonActions.DeletePersonFail, (state, { msg }) =>
|
||||
{
|
||||
return {
|
||||
...state,
|
||||
omessage: "ERROR " + msg,
|
||||
statusCode: -1
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export function reducer(state: appPersonState | undefined, action: Action)
|
||||
{
|
||||
return PersonReducer(state, action);
|
||||
}
|
||||
|
||||
export const getPersonEntities = (state: appPersonState) => state.entities;
|
||||
export const getPersonLoading = (state: appPersonState) => state.loading;
|
||||
export const getPersonLoaded = (state: appPersonState) => state.loaded;
|
||||
export const getPersonStatusCode = (state: appPersonState) => state.statusCode;
|
||||
export const getPersonMessage = (state: appPersonState) => state.omessage;
|
||||
export const getPersonForEdit = (state: appPersonState) => state.editPerson;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user