first time include all file

This commit is contained in:
2026-06-18 21:39:20 +10:00
commit d48a07a0fe
285 changed files with 31416 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# 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
ij_typescript_use_double_quotes = false
[*.md]
max_line_length = off
trim_trailing_whitespace = false
+2
View File
@@ -0,0 +1,2 @@
{
}
+32
View File
@@ -0,0 +1,32 @@
FROM node:20.18.0 AS build
RUN mkdir -p /app
WORKDIR /app
COPY ["./*.json", "./"]
RUN npm install -g @angular/cli
COPY . .
# Run command in Virtual directory
RUN npm cache clean --force
RUN npm install
#RUN ng build --configuration=production
RUN ng build --configuration=production
FROM nginx:latest
#### copy nginx conf
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
#COPY --from=build app/dist/carParkvalidation/browser /usr/share/nginx/html
#### copy artifact build from the 'build environment'
COPY --from=build /app/dist/carparkvalidation/browser /usr/share/nginx/html
#CMD ["nginx", "-g", "daemon off;"]
EXPOSE 80
#docker build -t my_angular_app:latest .
#docker run --name carval -d -p 4200:80 varlidate_ui
#npm error code ENOENT
+11
View File
@@ -0,0 +1,11 @@
FROM node:20.18.0 AS build
RUN npm install -g @angular/cli
RUN mkdir -p /app
WORKDIR /app
COPY . .
RUN npm install
#CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/assets/settings.template.json > /usr/share/nginx/html/assets/settings.json && exec nginx -g 'daemon off;'"]
CMD [ "ng" ,"serve", "--host", "0.0.0.0" ]
#image_name is app name like "carparkValidationui"
#docker build -t carparkvalidation:latest .
#docker run -d -p 4200:4200 --name carval carparkValidationui
+27
View File
@@ -0,0 +1,27 @@
# Myfirst
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.10.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application 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.
## 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 a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## 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.dev/tools/cli) page.
+101
View File
@@ -0,0 +1,101 @@
{
"$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:application",
"options": {
"outputPath": "dist/carparkvalidation",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css",
"node_modules/primeng/resources/primeng.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "5MB",
"maximumError": "4MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kB",
"maximumError": "4kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "CarParkValidation:build:production"
},
"development": {
"buildTarget": "CarParkValidation:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
}
},
"cli": {
"analytics": false
}
}
+20
View File
@@ -0,0 +1,20 @@
server {
listen 80;
sendfile on;
default_type application/octet-stream;
gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.";
gzip_min_length 256;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 9;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html =404;
}
}
+13896
View File
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
{
"name": "CarParkValidation",
"version": "1.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^18.2.0",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
"@angular/forms": "^18.2.0",
"@angular/material": "^18.2.10",
"@angular/material-moment-adapter": "^18.2.10",
"@angular/platform-browser": "^18.2.0",
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"moment": "^2.30.1",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
"primeng": "^17.18.11",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.2.10",
"@angular/cli": "^18.2.10",
"@angular/compiler-cli": "^18.2.0",
"@types/jasmine": "~5.1.0",
"autoprefixer": "^10.4.20",
"jasmine-core": "~5.2.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.15",
"typescript": "~5.5.2"
}
}
View File
+9
View File
@@ -0,0 +1,9 @@
{
"baseUrl": "http://localhost:8080",
"baseUrl_local": "http://nephmdb-sql007/CarParkValidationAPI",
"loginUrl": "api/login",
"updatePersonUrl": "api/updatePerson",
"getAllUrl": "api/v1/Users/GetAllUsers",
"authenticateUrl": "api/v1/Users/Authenticate",
"validationPoint":"api/v1/ValidationPoint"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

@@ -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">
<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>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8" >
<!-- Desciption Column -->
<ng-container matColumnDef="stafflinkNo">
<th mat-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-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-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-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-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-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,100 @@
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';
/* 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 { Subscription } from 'rxjs';
import { Router } from '@angular/router';
import { AdminUserService } from './adminuser.service';
@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,
) {
this.dataSource = new MatTableDataSource<AdminUserView>();
}
/*
applyFilter($event:any) {
const filterValue = $event.target.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 => {
const message = error || error.message;
//this.toastr.error(message);
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,59 @@
<div class="edit-content">
<div class="title">
{{getEditText()}}
</div>
<form [formGroup]="adminuserForm" (ngSubmit)="onSubmit()" fxLayout="column" fxLayoutGap="10px" >
<div class="flex flex-column">
<div>
<mat-form-field 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>
<mat-checkbox formControlName="active" color="primary">Active</mat-checkbox>
</div>
<div class="flex flex-row">
<div class="ml-2">
<mat-form-field appearance="outline">
<mat-label>Name</mat-label>
<input matInput formControlName="name" maxlength="100" name="name" placeholder="Name" readonly>
</mat-form-field>
</div>
<div class="ml-2">
<mat-form-field 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>
<div class="flex flex-row">
<div class="ml-2">
<mat-form-field 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>
</div>
<div class="flex flex-row gap-2 justify-content-end">
<button 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>{{ adminuserForm.value|json}}</pre-->
</div>
@@ -0,0 +1,181 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, 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';
@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: FormGroup;
constructor(private formBuilder: FormBuilder,
private adminUserService: AdminUserService,
private lookupService: LookupService,
private router: Router, private route: ActivatedRoute,
) {
this.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]
});
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({
next: x => this.assignValue(x.data),
error: x =>console.error(x)
}
));
//this.toastr.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.toastr.error("can not find stafflinkNo:" + staffid);
// this.adminuserForm.patchValue({name:x.data.firstName + " " + x.data.lastName
}
},
error => {
const message = error || error.message;
// this.toastr.error(message);
console.log("error ", error);
}
);
}
else
{
//this.toastr.error("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.toastr.success("save is ok");
this.router.navigate([this.returnUrl]);
}
},
error => {
const message = error || error.message;
//this.toastr.error(message);
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);
}
}
+4
View File
@@ -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 { }
+24
View File
@@ -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;
}
+2
View File
@@ -0,0 +1,2 @@
<router-outlet></router-outlet>
@@ -0,0 +1,35 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'CarParkValidation'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('CarParkValidation');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('CarParkValidation app is running!');
});
});
+10
View File
@@ -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';
}
+139
View File
@@ -0,0 +1,139 @@
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 { HttpClient } from '@angular/common/http';
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';
//and in the module providers
// { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_MOMENT_FORMATS }
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
LoginComponent,
NavToolarComponent,
ConcessionValidationEditComponent,
ConcessionValidationComponent,
ConcessionvalidationReportComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
FormsModule,
HttpClientModule,
AppMaterialModule,
SetupModuleModule,
AppRoutingModule,
BrowserAnimationsModule,
],
providers: [
{
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/" --prod
*/
/*
downgrade angular
ng --version
npm uninstall -g @angular/cli
npm cache clean --force
npm install moment
npm i @angular/material-moment-adapter@10
// for angular datetime picker
*/
/*
tailwind css
and daisy UI
npm install -d tailwindcss
npx tailwindcss init
now install daisyUI
npm i -D daisyui@latest
tailwind.config.js
/* @type {import('tailwindcss').Config} */
//module.exports = {
// >>>>>>>>> content: ["./src/**/*.{html,ts}"], <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// theme: {
// extend: {},
// },
// >>>>>>>>>>>>>>>>>>plugins: [require('daisyui'),], <<<<<<<<<<<<<<<<<<<<<<<
//}
/*
style.css
@import "primeng/resources/themes/lara-light-blue/theme.css";
@import "primeng/resources/primeng.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
// this is override for primeng
@layer tailwind-base, primeng, tailwind-utilities;
@layer tailwind-base {
@tailwind base;
}
@layer primeng;
@layer tailwind-utilities {
@tailwind components;
@tailwind utilities;
}
files.associations
"files.associations": {
"*.css": "tailwindcss"
}
*/
@@ -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,91 @@
<div class="edit-content">
<h3>Concession Validation</h3>
<div *ngIf="isAdmin">
<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">
<mat-icon>bolt</mat-icon>
</button>
</div>
<div class="addlink">
<a [routerLink]='["/home/concessionvalidation", 0]' [queryParams]="{returnUrl:'/home/concessionvalidation'}" (click)="setDate()">
<i class="material-icons">add_task</i>
Add Concession Validation
</a>
</div>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- validateDate Column -->
<ng-container matColumnDef="validateDate">
<th mat-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-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-header-cell *matHeaderCellDef mat-sort-header>Concession Card</th>
<td mat-cell *matCellDef="let element"> {{element.concessionCard}} </td>
</ng-container>
<!-- concessionHolder Column -->
<ng-container matColumnDef="concessionHolder">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Concession Holder</th>
<td mat-cell *matCellDef="let element"> {{element.concessionHolder}} </td>
</ng-container>
<!-- validationPoint Column -->
<ng-container matColumnDef="validationPoint">
<th mat-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-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-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-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)" ><mat-icon>edit</mat-icon></button>
</td>
</div>
</ng-container>
<ng-container matColumnDef="delete" stickyEnd>
<th mat-header-cell *matHeaderCellDef>Delete</th>
<td mat-cell *matCellDef="let element">
<a (click)='deleteItem(element.id)'>
<mat-icon>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,170 @@
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';
/* 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 { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { ConcessionValidationService } from './concessionvalidation.service';
import { MatDialog } from '@angular/material/dialog';
import { Utils } from '../shares';
@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,
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'
];
}
}
/*
applyFilter($event:any) {
const filterValue = $event.target.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.toastr.warning("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))
);
}
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";
/*
MessageBox.show(this.dialog, message, title, '', MessageBoxButton.YesNo,
false, MessageBoxStyle.Simple, "450px").subscribe(x => {
if (x.result == "yes")
{
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 =>
{
const message = error || error.message;
this.toastr.error(message);
console.log("error ", error);
}
);
}
else
{
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,81 @@
<div class="edit-content">
<div class="title">
{{getEditText()}}
</div>
<form [formGroup]="concessionvalidationForm" (ngSubmit)="onSubmit()" fxLayout="column" fxLayoutGap="10px">
<div class="flex flex-row">
<mat-card >
<!-- OLD one
<div *ngIf="isAdmin" fxLayout="row" fxLayout.xs="column" fxLayoutGap="7px" fxLayoutGap.sm="0px" >
<mat-form-field appearance="outline" [hideRequiredMarker]="true">
<mat-label>Choose a date<strong class="app-require">*</strong></mat-label>
<input matInput formControlName="validateDate" (focus)="picker.open()" [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</div>
-->
<!--Date and time picker
try this one now -->
<div *ngIf="isAdmin" >
<mat-form-field>
<input matInput placeholder="Date Time" formControlName="validateDate">
<mat-icon matSuffix matTooltip="click to pick date">today</mat-icon>
<!--owl-date-time #dt1></owl-date-time-->
</mat-form-field>
</div>
<div class="grid grid-cols-2 gap-3">
<!--end-->
<div >
<mat-form-field 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>
<mat-form-field fxFlex appearance="outline" [hideRequiredMarker]="true">
<mat-label>Concession Card<strong class="app-require">*</strong></mat-label>
<input matInput formControlName="concessionCard" maxlength="60"
name="concessionCard" placeholder="Concession Card" required>
</mat-form-field>
</div>
<div>
<mat-form-field fxFlex appearance="outline" [hideRequiredMarker]="true" >
<mat-label>Concession Holder<strong class="app-require">*</strong></mat-label>
<input matInput formControlName="concessionHolder" maxlength="100" name="" placeholder="Concession Holder" required >
</mat-form-field>
</div>
<div>
<mat-checkbox formControlName="concessionExpiry" color="primary">Expiry date checked</mat-checkbox>
</div>
<div *ngIf="isAdmin" fxLayout="row" fxLayout.xs="column" fxLayoutGap="7px" fxLayoutGap.sm="0px">
<mat-form-field fxFlex 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 flex-row gap-2 mt-2 justify-end">
<button 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,282 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, 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 { MatDialog } from '@angular/material/dialog';
import moment from 'moment';
import { ThemePalette } from '@angular/material/core';
@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|null = null;
public maxDate: moment.Moment|null = null;
private subscription :Subscription = new Subscription();
concessionvalidationForm:FormGroup;
constructor(private formBuilder: FormBuilder,
private lookupService: LookupService,
private concessionValidationService: ConcessionValidationService,
private router: Router,
public dialog: MatDialog,
private route :ActivatedRoute) {
this.concessionvalidationForm = this.formBuilder.group({
id: [0], //Validators.required
validateDate: [], //Validators.required
concessionCard: ['',Validators.required],
concessionHolder: ['', Validators.required],
concessionExpiry: [false], //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
});
/*
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);
*/
}
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.toastr.warning("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({
next: x=> this.assignValue(x.data),
error: e => console.error(e.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: concessionvalidation.validateDate,
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.toastr.error("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";
/*
okTo = confirm(message);
if (okTo == true)
{
this.saveConcession(concessionvalidation);
}
else
{
this.router.navigate([this.returnUrl]);
}
*/
/*
MessageBox.show(this.dialog, message, title,
'', MessageBoxButton.YesNo,
false, MessageBoxStyle.Simple, "400px").subscribe(x => {
if (x.result === "yes")
{
//console.log(this.msg + "after confirm", x);
this.saveConcession(concessionvalidation);
}
else
{
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({
next: x => {
if (x.statusCode >= 1) {
//this.toastr.success("Save is ok");
this.router.navigate([this.returnUrl]);
}
//this.toastr.error("Fail to Save " + x.message);
}, error: e => {
const message = e || e.message;
//this.toastr.error(message);
console.log("error ", e);
}
}));
}
goBack(): void {
this.router.navigate([this.returnUrl]);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
@@ -0,0 +1,87 @@
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 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[]>> {
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);
}
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,40 @@
<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-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-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-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,105 @@
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';
@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 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 => {
const message = error || error.message;
// this.toastr.error(message);
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 => {
const message = error || error.message;
// this.toastr.error(message);
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,24 @@
<div class="edit-content">
<div class="title"> {{getEditText()}} </div>
<form [formGroup]="concessiontypeForm" (ngSubmit)="onSubmit()" class="flex flex-column">
<div >
<mat-card >
<input type="hidden" formControlName="id">
<div >
<mat-form-field fxFlex 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 flex-row gap-2 mt-2">
<button 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,120 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, 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';
@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: FormGroup;
constructor(private formBuilder: FormBuilder,
private concessionTypeService: ConcessionTypeService,
private route: ActivatedRoute,private router: Router) {
this.concessiontypeForm = this.formBuilder.group({
id: [0], //Validators.required
description: [''], //Validators.required
display: [''], //Validators.required
active: [false], //Validators.required
});
}
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 => {
const message = error || error.message;
//this.toastr.error(message);
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.toastr.success("save is ok");
this.router.navigate([this.returnUrl]);
//this.router.navigate(['/home/concessiontype'])
}
},
error => {
const message = error || error.message;
//this.toastr.error(message);
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,23 @@
<div class="edit-content">
<h3>Concession Validation Report</h3>
<form [formGroup]="concessionvalidationreportForm">
<div fxLayout="row" fxLayoutGap="7px" fxLayoutGap.xs="0px">
<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 fxLayoutGap="10px" >
<button type="button" mat-raised-button color="primary" (click)="onDownload()">Download</button>
</div>
</form>
</div>
@@ -0,0 +1,74 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import 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';
@Component({
selector: 'app-concessionvalidation-report',
templateUrl: './concessionvalidationreport.component.html',
styleUrls: ['./concessionvalidationreport.component.css']
})
export class ConcessionvalidationReportComponent implements OnInit {
msg ="[concessionvalidation] ";
returnUrl="";
concessionvalidationreportForm:FormGroup;
constructor(
private formBuilder: FormBuilder,
private http: HttpUtility,
private router: Router,
private route :ActivatedRoute,
) {
this.concessionvalidationreportForm = this.formBuilder.group({
fromDate: [new Date()], //Validators.required
toDate: [new Date(),Validators.required],
});
}
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 => {
// this.toastr.error(err.message);
return EMPTY;
}),
finalize(() => {
//this.toastr.success("download completed ok to view now");
})).subscribe((response: HttpResponse<Blob>) => {
if (response) {
console.log("the download report response", response);
CommonUtilities.downloadFile(response, 'report.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,27 @@
.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: start;
}
@@ -0,0 +1,18 @@
<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 fxLayoutAlign="space-between end">
<p style="color:black;font-size:small;">release 07.09.2021 v1.0</p>
<p style="color:darkblue;font-size: small;">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();
}
}
+7
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;AAAA,sCAAiC"}
+2
View File
@@ -0,0 +1,2 @@
export * from './home.component';
+7
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;AAAA,uCAAkC"}
+2
View File
@@ -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,42 @@
<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="/images/application_image.png" alt="Nepean Car Park Validation">
<mat-card-content>
<p>Please Login to Continue</p>
<div >
<mat-form-field class="w-full">
<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 class="w-full">
<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="loginForm.value.password.errors.required">Password is required</div>
</div>
</div>
</mat-card-content>
<mat-card-actions class="btnloginRigh">
<button mat-raised-button color="primary" class="btn btn-primary">Login</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 that access to this database is restricted to CPVR employees only. If you require any information in relation to this database or require access,
<br>
please email at
</p>
<a href="mailto:NBMLHD-CarParkAdmin@health.nsw.gov.au"> NBMLHD-CarParkAdmin
</a>
</mat-card-content>
</mat-card>
</div>
</form>
</div>
@@ -0,0 +1,81 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';
import { AuthenticationService } from '../user-services';
@Component({
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
selector: 'login'
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
loading = false;
submitted = false;
returnUrl ="";
// get return url from route parameters or default to '/'
error = '';
constructor(
private formBuilder: FormBuilder,
private route: ActivatedRoute,
private router: Router,
private authenticationService: AuthenticationService) {
this.loginForm = this.formBuilder.group({
username: ['', Validators.required],
password: ['', Validators.required]
});
}
ngOnInit() {
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/home/concessionvalidation';
// reset login status
this.authenticationService.logout();
}
// convenience getter for easy access to form fields
get f() { return this.loginForm.value; }
onSubmit() {
this.submitted = true;
// stop here if form is invalid
if (this.loginForm.invalid) {
return;
}
const user = this.loginForm.value.username;
const pass = this.loginForm.value.password;
console.log("the form", this.loginForm, user,pass);
this.loading = true;
this.authenticationService.login(user,pass)
.pipe(first())
.subscribe({
next: 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.");
}
},
error: er => {
console.log("error in login", er);
this.error = er.message;
this.loading = false;
}
});
}
}
@@ -0,0 +1,95 @@
import { NgModule } from '@angular/core';
//import {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';
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,
// NgxMaterialTimepickerModule,
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,
// NgxMaterialTimepickerModule,
MatMenuModule,
MatExpansionModule,
]
})
export class AppMaterialModule { }
@@ -0,0 +1,26 @@
export interface ActionEditData {
parentType: number;
parentId: number;
actionId: number;
}
export interface ActionModel {
id: number;
businessUnitId: number;
assignedById: number;
assignedToId: number;
assignedByDesc?: string;
assignedToDesc?: string;
statusId: number;
referenceTypeId: number;
referenceId: number;
referenceNo: string;
reference: string;
description: string;
comments: string;
name: string;
assignedOn: string;
dueOn: string;
closedOn: string;
statusDate: string;
isDelete: boolean;
}
+21
View File
@@ -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,
}
+31
View File
@@ -0,0 +1,31 @@
import { mState } from './enum';
export interface AttachmentTitleSave {
id: number;
description: string;
mstate: mState;
}
export interface Attachment {
id: number;
mstate: mState;
description: string;
dateAttached: string;
attachedByDesc: string;
fileName: string;
attachmentType?: string;
attachedById: number;
ContentId: number;
formData?: FormData;
}
export interface AttachmentSource {
isNew: number;
id: number;
parentType: number;
parentId: number;
fileName: string;
description: string;
attachmentType: number;
}
+87
View File
@@ -0,0 +1,87 @@
export interface AuditEditData {
auditId: number;
}
export interface AuditItemPopup {
auditItem: AuditItem;
index: number;
}
export interface AuditItem {
id: number;
itemId: number;
category?: string;
name?: string;
wasThere: string;
riskRating: string;
nonConformance:string;
comments: string;
}
export interface AuditLookup {
}
export interface Audit{
id: number;
checkList: string;
percentage: string;
dueDate: string;
referenceNo: string;
}
export interface AuditSave {
id: number;
assessorId: number;
resultId: number;
businessUnitId: number;
checkListId: number;
auditScheduleId: number;
assignedById: number;
siteContractor: number;
auditFrequency: number;
locationId: string;
completedOn: string;
assignedOn: string;
startDate: string;
dueDate: string;
startedOn: string;
reviewResultId: number;
reviewClosedDate: string;
auditGeneralComments: string;
itemList: AuditItem[];
}
export interface AuditEdit {
id: number;
typeId: number;
categoryId: number;
assessorId: number; //assign to
assessorDesc?: string;
resultId: number;
status?: string;
businessUnitId: number;
checkListId: number;
checkListDesc?: string;
auditScheduleId: number;
assignedById: number;
assignedByDesc?: string;
siteContractor: number;
siteContractorDesc?: string;
auditFrequency: number;
locationId: string;
percentCompleted: number; //double
comments: string;
referenceNo: string;
statusDate: string;
completedOn: string;
assignedOn: string;
startDate: string;
dueDate: string;
startedOn: string;
createdOn: string;
reviewResultId: number;
reviewClosedDate: string;
auditGeneralComments: string;
itemList: AuditItem[];
}
+38
View File
@@ -0,0 +1,38 @@
import { Lookup } from './lookup';
export class ClaimLookup {
claimSharing: Lookup[] =[];
claimWCNotified: Lookup[] =[];
claimType: Lookup[] = [];
claimWCStatus: Lookup[] =[];
claimWCLiability: Lookup[] = [];
claimLiability: Lookup[] =[];
claimCategory: Lookup[] =[];
dutyStatus: Lookup[]=[];
}
export class Claim {
id: number =0;
referenceNo: string ='';
workCoverClaimNo: string ='';
revisedClaimNo: string ='';
sharing: number =0;
businessUnitId: number=0;
businessUnitDesc: string='';
createOn: string='';
policyNo: string='';
wcNotified: number =0;
acceptanceDate: string='';
periodFromDate: string='';
periodToDate: string='';
liability: number =0;
category: number=0;
wcStatus: number=0;
claimType: number=0;
wcLiability: number=0;
injuryNo: number=0;
tariffRateNoId: number=0;
secondaryPsych: number=0;
}
@@ -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,
}
+9
View File
@@ -0,0 +1,9 @@
export class ConfigureAPI
{
static baseUrl: "http://localhost:61744";
static loginUrl: "api/login";
static updatePersonUrl: "api/updatePerson";
static getAllUrl: "api/v1/Users/GetAllUsers";
static authenticateUrl: "api/v1/Users/Authenticate";
static validationPoint:"api/v1/ValidationPoint";
}
@@ -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",
}
+44
View File
@@ -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,
};
+258
View File
@@ -0,0 +1,258 @@
import { Lookup } from './lookup';
import { LookupCode } from './lookupcode';
import { mState } from './enum';
export interface HazardLookup {
category: Lookup[];
hazardReason: Lookup[]; ///for source
hazardType: Lookup[];
hazardStatus: Lookup[];
likeliHood: Lookup[];
consequence: Lookup[];
outCome: Lookup[];
}
export interface HazardControlTimeLookup {
controlTimeFrame: Lookup[];
}
export interface HazardExposeLookup {
//in descript.edit.com
frequencyOfExposure: Lookup[];
durationOfExposure: Lookup[];
typeOfExposure: Lookup[];
}
export interface HazardRiskLookup {
//in descript.edit.com
riskRatingConsequence: Lookup[];
hazardRating: Lookup[];
riskRationLikelihood: Lookup[];
}
export interface HazardContainer {
hazard: Hazard | null;
hazardDetail: HazardDetail |null;
hazardNonConformace: HazardNonConformance |null;
classification?: HazardClassification;
assessment?: HazardAssessmentTab;
conclusion?: HazardConclusion;
}
export interface Hazard {
id: number;
referenceNo: string;
hazardName: string;
reasonId: number;
reporterFirstName: string;
reporterSurname: string;
reporterEmail: string;
reporterTelephoneNo: string;
supervisorFirstName: string;
supervisorSurname: string;
supervisorEmail: string;
identifiedDate: string;
identifiedTime: string;
reportedDate: string;
reportedTime: string;
incidentId: number;
statusId: number;
statusDate: string;
businessUnitId: number;
businessUnitDesc?: string;
description: string;
typeDesc?: string;
typeId: number;
categoryId: number;
categoryDesc?: string;
jobFile: string;
}
export interface PeopleExposed {
id: number;
parentId:number;
name: string;
comments: string;
state: mState;
}
export interface NonConformance {
id: number;
state: mState;
typeId: number;
typeDesc: string;
categoryId: number;
categoryDesc: string;
parentId: number;
}
export interface HazardNonConformance {
nonConformanceList: NonConformance[];
}
export interface HazardDetail {
//detail
id: number;
hazardSuburbId: number;
hazardSuburbDesc: string;
locationType: string;
address: string;
postCode: string;
peopleExposed: PeopleExposed[];
}
export interface HazardInvestigate {
needToBeReferred: number;
conclusionId: number;
//pe
investigatorId: number;
investigatorDesc: string;
investigatorDueDate: string;
hasPINBeenIssued: number;
//person
issuedById: number;
issuedToId: number;
issuedByDesc: string;
issuedToDesc: string;
noOfPeopleExposed: number;
percentOfPeopleExposed: number;
frequencyOfExposure: number;
durationOfExposure: number;
typeOfExposure: number;
worstInjuryIllness: number;
}
export interface HazardProduct {
id: number;
category: string;
description: string;
}
export interface HazardEquipment {
id: number;
category: string;
description: string;
}
export interface HazardVersion {
id: number;
date: string;
version: string;
status: number;
}
export interface ReviewList {
id: number;
name: string;
role: string;
}
export interface HazardAssessmentContainer {
assessment: HazardAssessment;
roleLookup: LookupCode[];
}
export interface HazardAssessment {
id: number;
role: string;
roleId: number;
name: string;
detail: string;
}
export interface HazardRisk {
id: number;
name: string;
description: string;
}
export interface HazardRiskContainer {
risk: HazardRisk;
}
export interface HazardRisks {
id: number;
name: string;
aspect: string;
impact: string;
untreatedRiskRating: string;
treatedRiskRating: string;
}
export interface HazardHistory {
conclusion: number; //HazardBase
finalise: number; //RiskRating.
reviewDate: string //RiskRating
comments: string; //RiskRating;
newComments: string;
}
export interface HazardRiskHiControl {
id: number;
controlType: number;
practicable: number;
}
export interface HazardRiskControlPickList {
controlType: LookupCode[];
practicable: LookupCode[];
}
export interface HazardRiskDetailContainer {
riskDetail: HazardRiskHiControl;
lookup: HazardRiskControlPickList;
}
export interface HazardClassification {
id: number;
likeliHoodId: number;
consequenceId: number;
riskRating: string;
riskLevel: string;
classificationEmail: string;
classificationTelephoneNo: string;
classificationAssignTo: number;
classificationAssignToDesc: string;
}
export interface HazardAssessmentTab {
id: number;
comments: string;
consequence: string;
eliminated: number;
expectedDate: string;
hazardStillExist: number;
likeliHood: string;
riskLevel: string;
riskRating: string;
controlStrategy: ControlStrategy[];
}
export interface ControlStrategy {
id: number;
state: mState;
itemId: number;
itemIdDesc: string;
}
export interface HazardConclusion {
id: number;
comments: string;
completedDate: string;
completedTime: string;
conclusion: number;
isInvestigationCompleted: number;
officerDesc: string;
officerEmail: string;
officerId: number;
officerPhoneNo: string;
}
@@ -0,0 +1,272 @@
import { Lookup } from './lookup';
import { InjuryReportSave } from './injuryReport';
import { mState } from './enum';
export interface IncidentDetailSave {
// incidentId: number;
address: string;
locationType: string;
suburb: number;
postCode: string;
injuryPersons: IncidentDetailPerson[];
// injuryPersons: InjuryReportSave[];
}
export interface IncidentDetailFinalSave {
// id: number;
incidentId: number;
address: string;
locationType: string;
suburb: number;
postCode: string;
injuryPersons: InjuryReportSave[];
}
/*
incidentId: number;
linkId: number;
injuryPersons: InjuryReport;
}
/*
this.boxActivity.DataField = IncidentReportDataObject.Fields.Description;
this.boxActivity.DataObject = incidentReport;
this.boxUnexpectantly.DataField = IncidentReportDataObject.Fields.IncidentDetails;
this.boxUnexpectantly.DataObject = incidentReport;
this.boxInjurySustained.DataField = IncidentReportMiscDataObject.Fields.HowInjuriesSustained;
this.boxInjurySustained.DataObject = incidentReport;
this.boxPreventative.DataField = IncidentReportMiscDataObject.Fields.PreventativeAction;
this.boxPreventative.DataObject = incidentReport;
this.boxMainTasks.DataField = IncidentReportMiscDataObject.Fields.MainTasks;
this.boxMainTasks.DataObject = incidentReport;
this.boxExperienceYear.DataField = IncidentReportMiscDataObject.Fields.WorkerExperienceYear;
this.boxExperienceYear.DataObject = incidentReport;
this.boxExperienceMonth.DataField = IncidentReportMiscDataObject.Fields.WorkerExperienceMonth;
*/
export interface IncidentPreliminaryInvestigation // second tab
{
id: number;
description: string; //incidentReport
incidentDetails: string; //incidentReport
howInjuriesSustained: string;
preventativeAction: string;
mainTasks: string;
workerExperienceYear: number;
workerExperienceMonth: number;
witnessList: IncidentWitness[];
}
export interface IncidentWitness {
state: mState;
id: number;
firstName: string;
surname: string;
telephoneNo: string;
email: string;
statement: string;
}
/*
this.columnFirstName.DataField = IncidentReportWitnessDataObject.Fields.FirstName;
this.columnSurname.DataField = IncidentReportWitnessDataObject.Fields.Surname;
this.columnTelephoneNo.DataField = IncidentReportWitnessDataObject.Fields.TelephoneNo;
this.columnEmail.DataField = IncidentReportWitnessDataObject.Fields.Email;
this.columnStatement.DataField = IncidentReportWitnessDataObject.Fields.Statement;
*/
export interface IncidentReportContainer {
incidentReport: IncidentReport;
incidentDetail: IncidentDetail; //first tab
incidentPreliminary: IncidentPreliminaryInvestigation; //second tab
classification?: IncidentClassification; //third tab
investigation?: IncidentInvestigation; //four tab;
causeFactor?: IncidentCauseFactor;//fiv tab;
conclusion?: IncidentConclusion;
}
export interface IncidentDetail {//first tab
id: number;
address: string;
locationType: string;
suburb: number;
suburbDesc: string;
postCode: string;
injuryReport: IncidentDetailPerson[];
}
export interface IncidentDetailPerson {
state: mState;
id: number;
// incidentId: number;
linkId: number;
firstName: string;
surname: string;
}
export interface IncidentReport {
id: number;
referenceNo: string;
incidentDate: string;
incidentTime: string;
typeId: number;
typeDesc?: string;
categoryId: number;
categoryDesc?: string;
incidentOccured: number;
reportedDate: string;
reportedTime: string;
incidentName: string;
classificationId: number;
jobFile: string;
status?: string;
statusDate: string;
reporterFirstName: string;
reporterSurname: string;
reporterEmail: string;
reporterTelephoneNo: string;
supervisorFirstName: string;
supervisorSurname: string;
supervisorEmail: string;
supervisorTelephoneNo: string;
supervisorMobileNo: string;
supervisorOccupation: number;
supervisorOccupationDesc?: string;
isHazardCaused: number;
isReporterInjured: number;
businessUnitId: number;
businessUnitDesc?: string;
}
export interface IncidentReportSave {
id: number;
businessUnitId: number;
referenceNo: string;
incidentDate: string;
incidentTime: string;
typeId: number;
categoryId: number;
incidentOccured: number;
reportedDate: string;
reportedTime: string;
incidentName: string;
classificationId: number;
jobFile: string;
statusDate?: string;
reporterFirstName: string;
reporterSurname: string;
reporterEmail: string;
reporterTelephoneNo: string;
supervisorFirstName: string;
supervisorSurname: string;
supervisorEmail: string;
supervisorTelephoneNo: string;
supervisorMobileNo: string;
supervisorOccupation: number;
isHazardCaused: number;
isReporterInjured: number;
}
export interface IncidentContainerSave {
incidentPersonDetail?: IncidentDetailFinalSave;
incidentReport: IncidentReportSave;
incidentDetail?: IncidentPreliminaryInvestigation;
classification?: IncidentClassification;
investigation?: IncidentInvestigation;
causefactor?: IncidentCauseFactor;
conclusion?: IncidentConclusion;
}
export interface IncidentLookup {
category: Lookup[];
incidentClass: Lookup[];
classification: Lookup[];
incidentType: Lookup[];
occured: Lookup[];
incidentStatus: Lookup[];
positions: Lookup[];
}
export interface IncidentClassification {
classificationId: number;
isNotifiableIncident: number;
investigationAssignedTo: number;
investigationAssignedDesc?: string;
investigatorEmail?: string;
investigatorTelephoneNo?: string;
investigationAgencyList: IncidentAgency[];
}
export interface IncidentAgency {
id: number;
state: mState;
agencyId: number;
agencyDesc: string;
notified: string;
eventNumber: string;
}
export interface IncidentConclusion {
id: number;
assetInvolved: string;
investigationCompletingOfficer: number;
isInvestigationCompleted: number;
investigationCompletingOfficerDesc: string;
investigationCompletedOn: string;
comments: string;
completingOfficerTelephoneNo: string;
completingOfficerEmail: string;
conclusion: number;
//action tab
hazardReportRequired: number;
}
export interface IncidentInvestigation {
id: number;
assetInvolved: string;
taskDescription: string;
locationInformation: string;
detailedIncidentDescription: string;
injurySustained: string;
investigationProcess: string;
surface: number;
visibility: number;
lighting: number;
weather: number;
investCauses: IncidentInvestCausePrimary[];
}
export interface IncidentInvestCausePrimary {
id: number;
state: mState;
causeId: number;
causeName: string;
}
export interface IncidentCauseFactor {
otherContributingFactors: string;
contributionFactorList: IncContribFactor[];
}
export interface IncContribFactor {
id: number;
state: mState;
causeId: number;
causeDesc?: string;
categoryId: number;
categoryDesc?: string;
}
export interface IncidentInvestigateLK
{
lighting: Lookup[];
visibility: Lookup[];
surface: Lookup[];
weather: Lookup[];
}
+9
View File
@@ -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,76 @@
import { Lookup } from './lookup';
import { mState } from './enum';
export interface InjuryReportSave {
state: mState;
id: number;
// parentId: number;
linkId: number;
details: Personinjurydetail;
treatments: Personinjurytreatment;
}
//using in incident for now.
export interface InjuryReport {
state: mState;
id: number; //injuryreport id linkid in the details.id
// firstName: string;
// surname: string;
// parentId: number;
// linkId: number;
details?: Personinjurydetail;
treatments?: Personinjurytreatment;
}
/*
*/
export interface InjuryLookup {
employeeType: Lookup[];
treatmentType: Lookup[];
employmentStatus: Lookup[];
proportionWorkedPriorToIncident: Lookup[];
natureOfInjury: Lookup[];
}
export interface Personinjurytreatment {
id: number;
aggravationOfPreviousInjury: number;
treatmentGiven: number ;
treatmentType: number;
firstAidDetail: string;
treatmentDate: string;
treatmentTime: string;
dominantSide: number;
treatmentLocation: string;
intendToLeaveWork: number;
// firstAidProvider: string;
//firstAidProviderType: number;
//speciality: number;
bodyInjurys: InjuryBody[];
state: mState;
newId: number; //new id
}
export interface InjuryBody {
bodilyLocation: number;
bodilyLocationDesc: string;
id: number;
natureOfInjury: number;
natureOfInjuryDesc: string;
state: mState;
}
export interface Personinjurydetail {
id: number;
state: mState;
firstName: string;
surname: string;
telephoneNo: string;
email: string;
bornOn: string;
preferredLanguage: string;
payrollNo: string;
occupation: number;
occupationDesc: string;
employmentType: number;
employmentStatus: number;
proportionWorkedPriorIncident: number;
personAccountOfIncident: string;
}
+7
View File
@@ -0,0 +1,7 @@
export interface Lookup {
id: number;
categoryId: number;
description: string;
};
+44
View File
@@ -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;
}
+7
View File
@@ -0,0 +1,7 @@
export interface PageQuery {
pageIndex: number;
pageSize: number;
search: string;
};
+80
View File
@@ -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;
}
+45
View File
@@ -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,18 @@
export class Rehabilitation {
id: number = 0;
referenceNo: string = '';
rehabCaseDate: string = '';
claimNo: string = '';
personId: number = 0;
insurerClaimNo: string = '';
policyNo: string = '';
policyComments: string = '';
statusId: number = 0;
requireTreatment: number = 0;
abilityId: number = 0;
restrictionsId: number = 0;
currentDutiesId: number = 0;
selectedDuties: string = '';
incidentId: number = 0;
insurerContactId: number = 0;
}
@@ -0,0 +1,5 @@
export interface ResultModel<T> {
data: T;
message: string;
statusCode:number;
}
+41
View File
@@ -0,0 +1,41 @@
import { BehaviorSubject } from 'rxjs';
export interface Suburb {
id: string; // should contain three part 1 Id, 2 StartName , 3 EndName
recordId: number; // should contain three part 1 Id, 2 StartName , 3 EndName
name:string;
level: number;
parentId: number;
hasChild: boolean;
postCode: string;
}
export interface SuburbCode {
id: number;
parentId: number;
name: string;
postCode: string;
nodeId: string;
}
export interface SuburbContainer {
list: SuburbCode[];
totalPages: number;
}
/** Nested node */
export class suburbNode {
childrenChange = new BehaviorSubject<suburbNode[]>([]);
get children(): suburbNode[] {
return this.childrenChange.value;
}
constructor(public id: string,
public name: string,
public recordId: number,
public parentId: number,
public hasChildren = false,
public loadMoreParentItem: number | null = null) { }
}
+10
View File
@@ -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|null |undefined;
description: string |null |undefined;
display: string |null |undefined;
active: boolean |null |undefined
}
@@ -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,35 @@
<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>
<!--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,76 @@
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;
}
@media (min-width: 768px) {
/* On small screens, convert the nav menu to a vertical sidebar */
.main-nav {
height: 100%;
width: calc(25% - 20px);
}
.navbar {
border-radius: 0px;
border-width: 0px;
height: 100%;
}
.navbar-header {
float: none;
}
.navbar-collapse {
border-top: 1px solid #444;
padding: 0px;
}
.navbar ul {
float: none;
}
.navbar li {
float: none;
font-size: 15px;
margin: 6px;
}
.navbar li a {
padding: 10px 16px;
border-radius: 4px;
}
.navbar a {
/* If a menu item's text is too long, truncate it */
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
@@ -0,0 +1,23 @@
<mat-toolbar class="app-toolbar flex justify-content-between">
<div style="margin-top: 5px;padding-right: 35px; cursor: pointer;height:70px;">
<img (click)="onHome()" src="/images/application_image.png" alt="Parking Concession Validation Register" style="height:70px;width:320px"/>
</div>
<div >
<ul class="navigation-items">
<li *ngIf="!isAuth">
<a [routerLink]='["/login"]'>
Login
</a>
</li>
</ul>
<div>
{{currentUserName}}
</div>
<div class="flex justify-content-end">
<button (click)="onToggle()" mat-icon-button type="button"><mat-icon>arrow_drop_down</mat-icon></button>
</div>
</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,15 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OverlayModule } from '@angular/cdk/overlay';
import { OverlayService } from './overlay.service';
export { OverlayService } from './overlay.service';
@NgModule({
imports: [
CommonModule,
OverlayModule
],
providers: [OverlayService],
})
export class AppOverlayModule { }
@@ -0,0 +1,39 @@
import { Injectable, TemplateRef, ViewContainerRef } from '@angular/core';
import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
import { ProgressSpinnerComponent } from '../progress-spinner/progress-spinner.component';
@Injectable()
export class OverlayService {
public overlayRef: OverlayRef;
constructor(private overlay: Overlay) {
this.overlayRef = overlay.create();
}
open(config: AppOverlayConfig, component: any) {
const positionStrategy = this.overlay.position()
.global()
.centerHorizontally()
.centerVertically();
config['positionStrategy'] = positionStrategy;
// Returns an OverlayRef which is a PortalHost
this.overlayRef = this.overlay.create(config);
// Create ComponentPortal that can be attached to a PortalHost
const componentPortal = new ComponentPortal(component);
// Attach ComponentPortal to PortalHost
this.overlayRef.attach(componentPortal);
}
showLoading() {
if (this.overlayRef)
this.overlayRef.detach();
this.open({ hasBackdrop: true }, ProgressSpinnerComponent);
}
close(){
this.overlayRef.detach();
}
}
export interface AppOverlayConfig extends OverlayConfig { }
@@ -0,0 +1 @@
<mat-spinner></mat-spinner>
@@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-progress-spinner',
templateUrl: './progress-spinner.component.html',
styleUrls: ['./progress-spinner.component.css']
})
export class ProgressSpinnerComponent {
}
@@ -0,0 +1,45 @@
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Utils } from '../shares';
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
msg ="[AuthGuard] ";
constructor(private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const roleAllowed = (route.data as any).roleAllowed;
const user = Utils.getCurrentUser();
const userRole = Utils.getUserRole(user);
let hasLoggedIn = Utils.getIsAuth();
console.log(this.msg + " the userlogin ", user);
if (hasLoggedIn) {
if (roleAllowed != undefined)
{
console.log("[auth-guard] ther roleAllow ", roleAllowed);
if (roleAllowed.indexOf(userRole) != -1) {
return true;
}
else {
this.router.navigate(['/login']);
return false;
}
}
else //if no role define just return hasLoggedIn
{
return hasLoggedIn;
}
}
else
{
this.router.navigate(['/login']);
return false;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
}
+7
View File
@@ -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("./auth.guard"));
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;AAAA,kCAA6B"}

Some files were not shown because too many files have changed in this diff Show More