Autor | SHA1 | Zpráva | Datum |
---|---|---|---|
|
481c37b21a | Add other name registration endpoints | před 3 roky |
|
890271cd70 | Add a register name service | před 3 roky |
|
e1877048c1 | Make notifications responsive | před 3 roky |
@@ -8,8 +8,11 @@ | |||
"watch": "ng build --watch --configuration development", | |||
"test": "ng test", | |||
"docker-build": "docker build -t b2rs-multi-stage-image .", | |||
"docker-create": "docker run --name b2rs-app-container -d -p 80:80 b2rs-multi-stage-image", | |||
"docker-build": "docker build -t b2rs-front-end-image .", | |||
"docker-tag": "docker tag b2rs-front-end-image:latest 834628752744.dkr.ecr.ap-southeast-1.amazonaws.com/b2rs-front-end-image:latest", | |||
"docker-push": "docker push 834628752744.dkr.ecr.ap-southeast-1.amazonaws.com/b2rs-front-end-image:latest", | |||
"docker-create": "docker run --name b2rs-app-container -d -p 80:80 b2rs-front-end-image", | |||
"docker-destroy": "docker container rm b2rs-app-container", | |||
"docker-start": "docker start b2rs-app-container", | |||
@@ -34,6 +34,7 @@ import { DashboardComponent } from './pages/dashboard/dashboard.component'; | |||
import { FilterViewCardComponent } from './pages/dashboard/filter-view-card/filter-view-card.component'; | |||
import { NavbarComponent } from './layout/navbar/navbar.component'; | |||
import { NotificationsListComponent } from './layout/notifications/notifications-list/notifications-list.component'; | |||
import { HttpClientModule } from '@angular/common/http'; | |||
@NgModule({ | |||
declarations: [ | |||
@@ -73,6 +74,7 @@ import { NotificationsListComponent } from './layout/notifications/notifications | |||
AppRoutingModule, | |||
FormsModule, | |||
FileUploadModule, | |||
HttpClientModule, | |||
], | |||
providers: [], | |||
bootstrap: [AppComponent] | |||
@@ -13,12 +13,16 @@ export class NavbarComponent implements OnInit, OnDestroy { | |||
showLogout: boolean = false; | |||
isShowingNotificationsSubscription: Subscription; | |||
loginRoleSubscription: Subscription; | |||
loginName: string = ''; | |||
notificationsCount: number = 0; | |||
constructor(loginService: LoginService, private notificationService: NotificationService) { | |||
this.loginName = loginService.getLoginName(); | |||
this.loginRoleSubscription = loginService.getLoginRoleObservable().subscribe(loginRole => { | |||
this.loginName = loginService.getLoginName(); | |||
}); | |||
this.notificationsCount = notificationService.getAllowedNotifications().length; | |||
this.isShowingNotificationsSubscription = this.notificationService.getIsShowingNotificationsObservable().subscribe(isShowingNotifications => this.isShowingNotifications = isShowingNotifications); | |||
@@ -35,6 +39,10 @@ export class NavbarComponent implements OnInit, OnDestroy { | |||
if (this.isShowingNotificationsSubscription) { | |||
this.isShowingNotificationsSubscription.unsubscribe(); | |||
} | |||
if (this.loginRoleSubscription) { | |||
this.loginRoleSubscription.unsubscribe(); | |||
} | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
<ul> | |||
<li *ngFor="let notification of allowedNotifications"> | |||
<a *ngIf="notification.redirectionUrl" [routerLink]="notification.redirectionUrl"> | |||
<a *ngIf="notification.redirectionUrl" (click)="closeNotifications()" [routerLink]="notification.redirectionUrl"> | |||
<h5> {{ notification.text }} </h5> | |||
<p *ngIf="notification.description"> {{ notification.description }} </p> | |||
<span class="time-stamp"> {{ notification.timeStamp }} </span> | |||
@@ -9,11 +9,15 @@ import { Notification, NotificationService } from 'src/app/services/notification | |||
export class NotificationsListComponent implements OnInit { | |||
allowedNotifications: Array<Notification> = []; | |||
constructor(notificationService: NotificationService) { | |||
constructor(private notificationService: NotificationService) { | |||
this.allowedNotifications = notificationService.getAllowedNotifications(); | |||
} | |||
ngOnInit(): void { | |||
} | |||
closeNotifications() { | |||
this.notificationService.setIsShowingNotifications(false); | |||
} | |||
} |
@@ -1,4 +1,5 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { Component, OnDestroy, OnInit } from '@angular/core'; | |||
import { Subscription } from 'rxjs'; | |||
import { LoginService } from 'src/app/services/login.service'; | |||
import { NotificationService } from 'src/app/services/notification.service'; | |||
@@ -7,19 +8,30 @@ import { NotificationService } from 'src/app/services/notification.service'; | |||
templateUrl: './tabs.component.html', | |||
styleUrls: ['./tabs.component.scss'] | |||
}) | |||
export class TabsComponent implements OnInit { | |||
export class TabsComponent implements OnInit, OnDestroy { | |||
showNotifications: boolean = false; | |||
showLogout: boolean = false; | |||
loginRoleSubscription: Subscription; | |||
loginName: string = ''; | |||
notificationsCount: number = 0; | |||
constructor(loginService: LoginService, notificationService: NotificationService) { | |||
this.loginName = loginService.getLoginName(); | |||
this.loginRoleSubscription = loginService.getLoginRoleObservable().subscribe(loginRole => { | |||
this.loginName = loginService.getLoginName(); | |||
}); | |||
this.notificationsCount = notificationService.getAllowedNotifications().length; | |||
} | |||
ngOnInit(): void { | |||
} | |||
ngOnDestroy(): void { | |||
if (this.loginRoleSubscription) { | |||
this.loginRoleSubscription.unsubscribe(); | |||
} | |||
} | |||
} |
@@ -1,7 +1,7 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
type State = 'VIEW INITIAL DETAILS'|'ENTER MORE DETAILS'|'ASSIGN COMMITTEE'|'REVIEW NON COMPLIANCE'|'CONCUR COMPLIANCE REVIEW'|'CLOSING REMARKS'|'PREPARE PRELIMINARY LETTER'|'RESPOND TO PRELIMINARY LETTER'; | |||
type Role = 'Investigator'|'Hod'|'Panel'|'Customer'; | |||
type Role = 'Investigator'|'Hod'|'Panel'|'Customer'|'Officer'; | |||
@Component({ | |||
selector: 'app-investigate-business-entities-and-individuals', | |||
@@ -41,6 +41,8 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||
this.loginRole = 'Panel'; | |||
} else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('customer')) { | |||
this.loginRole = 'Customer'; | |||
} else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('officer')) { | |||
this.loginRole = 'Officer'; | |||
} else { | |||
this.loginRole = 'Investigator'; | |||
} | |||
@@ -1,4 +1,5 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { LoginService } from 'src/app/services/login.service'; | |||
@Component({ | |||
selector: 'app-login', | |||
@@ -8,7 +9,7 @@ import { Component, OnInit } from '@angular/core'; | |||
export class LoginComponent implements OnInit { | |||
email = ''; | |||
constructor() { } | |||
constructor(private loginService: LoginService) { } | |||
ngOnInit(): void { | |||
} | |||
@@ -17,6 +18,7 @@ export class LoginComponent implements OnInit { | |||
this.email = email; | |||
localStorage.setItem('loginEmail', email); | |||
this.loginService.updateLoginRole(); | |||
} | |||
} |
@@ -77,7 +77,7 @@ | |||
<button class="common-button neutral" (click)="formState = 'INIT_REGISTER'"> | |||
Back | |||
</button> | |||
<button class="common-button" (click)="formState = 'SELECT_PLAN'"> | |||
<button class="common-button" (click)="registerName()"> | |||
Proceed | |||
</button> | |||
</div> | |||
@@ -150,7 +150,7 @@ | |||
<button class="common-button outline" (click)="print()"> | |||
</button> | |||
<button class="common-button" (click)="formState = 'RECEIPT'"> | |||
<button class="common-button" (click)="goToReceipt()"> | |||
View Receipt | |||
</button> | |||
</div> | |||
@@ -1,7 +1,17 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { DateInputProperties } from 'src/app/widgets/form/date-input/date-input.component'; | |||
import { GenericInputProperties } from 'src/app/widgets/form/generic-input/generic-input.component'; | |||
import { SelectInputProperties } from 'src/app/widgets/form/select-input/select-input.component'; | |||
import { RegisterBusinessNameService } from 'src/app/services/register-business-name.service'; | |||
export interface AcknowledgementRow { | |||
name: string, | |||
value: string | number, | |||
amount?: number, | |||
highlight?: boolean, | |||
}; | |||
export interface ReceiptRow { | |||
name: string, | |||
value: string | number, | |||
}; | |||
@Component({ | |||
selector: 'app-register-business', | |||
@@ -50,64 +60,11 @@ export class RegisterBusinessComponent implements OnInit { | |||
dropSuffixOptions = ['YES', 'NO']; | |||
acknowledgementDetails: Array<{ | |||
name: string, | |||
value: string | number, | |||
amount?: number, | |||
highlight?: boolean, | |||
}> = [{ | |||
name: 'UEM', | |||
value: '---' | |||
}, { | |||
name: 'Entity Name', | |||
value: this.nameToCheck | |||
}, { | |||
name: 'Transaction Number', | |||
value: '39047729362923293', | |||
highlight: true, | |||
}, { | |||
name: 'Receipt Number', | |||
value: 'ACRA38293', | |||
highlight: true | |||
}, { | |||
name: 'EP Reference No.', | |||
value: '20910038829384470' | |||
}, { | |||
name: 'Payment Date', | |||
value: '06/11/2021 11:28:01' | |||
}, { | |||
name: 'Description', | |||
value: 'Application for Business Name', | |||
amount: 15 | |||
}]; | |||
receiptDetails: Array<{ | |||
name: string, | |||
value: string | number, | |||
}> = [{ | |||
name: 'Receipt Number', | |||
value: 'ACRA38293', | |||
}, { | |||
name: 'ARN', | |||
value: 'ARN2021110294038', | |||
}, { | |||
name: 'EP Reference No.', | |||
value: '20910038829384470' | |||
}, { | |||
name: 'Tax ID', | |||
value: 'M9-0C038921', | |||
}, { | |||
name: 'Paid By', | |||
value: 'KOH YA TING', | |||
}, { | |||
name: 'Payment Date', | |||
value: '06/11/2021 11:28:01' | |||
}, { | |||
name: 'Paid Via', | |||
value: 'Net Banking', | |||
}]; | |||
constructor() { } | |||
acknowledgementDetails: Array<AcknowledgementRow> = []; | |||
receiptDetails: Array<ReceiptRow> = []; | |||
constructor(private registerBusinessNameService: RegisterBusinessNameService) { } | |||
ngOnInit(): void { | |||
} | |||
@@ -151,33 +108,52 @@ export class RegisterBusinessComponent implements OnInit { | |||
payForReservation() { | |||
this.paymentChild = window.open('/mock', '_blank', 'toolbar=0,status=0,width=626,height=436'); | |||
this.childCheck = window.setInterval(() => { | |||
this.childCheck = window.setInterval(async () => { | |||
if (this.paymentChild && this.paymentChild.closed) { | |||
this.formState = 'ACKNOWLEDGEMENT'; | |||
window.clearInterval(this.childCheck); | |||
this.childCheck = undefined; | |||
this.acknowledgementDetails = await this.registerBusinessNameService.getAcknowledgement(); | |||
} | |||
}, 1000); | |||
} | |||
checkName() { | |||
async goToReceipt() { | |||
this.formState = 'RECEIPT'; | |||
this.receiptDetails = await this.registerBusinessNameService.getReceipt(); | |||
} | |||
async checkName() { | |||
this.formState = 'INIT_REGISTER'; | |||
if (this.nameToCheck === `A'DROIT MANAGEMENT SERVICES`) { | |||
this.error = { | |||
message: this.nameToCheck + ' is unavailable. Entity with identical name exists', | |||
isUnique: false, | |||
isInvalid: false, | |||
}; | |||
} else { | |||
const nameCheckResponse = await this.registerBusinessNameService.checkName(this.nameToCheck); | |||
if (nameCheckResponse.status === `success`) { | |||
this.error = { | |||
message: this.nameToCheck + ' is available', | |||
isUnique: true, | |||
isInvalid: false | |||
}; | |||
} else { | |||
this.error = { | |||
message: this.nameToCheck + ' is unavailable. ' + nameCheckResponse.status, | |||
isUnique: false, | |||
isInvalid: false, | |||
}; | |||
} | |||
} | |||
async registerName() { | |||
await this.registerBusinessNameService.registerName( | |||
this.nameToCheck, | |||
this.selectedEntityType, | |||
this.selectedCompanyCategory, | |||
this.selectedCompanySuffix, | |||
this.selectedDropSuffix, | |||
); | |||
this.formState = 'SELECT_PLAN'; | |||
} | |||
print() { | |||
window.print(); | |||
} | |||
@@ -1,4 +1,5 @@ | |||
import { Injectable } from '@angular/core'; | |||
import { BehaviorSubject } from 'rxjs'; | |||
export type Role = 'Officer'|'Investigator'|'Hod'|'Panel'|'Customer'; | |||
@@ -7,8 +8,15 @@ export type Role = 'Officer'|'Investigator'|'Hod'|'Panel'|'Customer'; | |||
}) | |||
export class LoginService { | |||
private loginRole: Role; | |||
private loginRoleSubject: BehaviorSubject<string>; | |||
constructor() { | |||
this.loginRole = 'Customer'; | |||
this.loginRoleSubject = new BehaviorSubject(''); | |||
this.updateLoginRole(); | |||
} | |||
updateLoginRole() { | |||
const loginEmail = localStorage.getItem('loginEmail'); | |||
if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('hod')) { | |||
@@ -22,6 +30,8 @@ export class LoginService { | |||
} else { | |||
this.loginRole = 'Officer'; | |||
} | |||
this.loginRoleSubject.next(this.loginRole); | |||
} | |||
getLoginName() { | |||
@@ -34,6 +44,10 @@ export class LoginService { | |||
} | |||
} | |||
getLoginRoleObservable() { | |||
return this.loginRoleSubject.asObservable(); | |||
} | |||
getLoginRole() { | |||
return this.loginRole; | |||
} | |||
@@ -71,8 +71,10 @@ export class NotificationService { | |||
private allowedNotifications: Array<Notification> = []; | |||
constructor(loginService: LoginService) { | |||
const loginRole = loginService.getLoginRole(); | |||
this.allowedNotifications = this.notifications.filter(notification => notification.roles.includes(loginRole)); | |||
loginService.getLoginRoleObservable().subscribe(loginRoleObserved => { | |||
const loginRole = loginService.getLoginRole(); | |||
this.allowedNotifications = this.notifications.filter(notification => notification.roles.includes(loginRole)); | |||
}); | |||
} | |||
getAllowedNotifications() { | |||
@@ -0,0 +1,16 @@ | |||
import { TestBed } from '@angular/core/testing'; | |||
import { RegisterBusinessNameService } from './register-business-name.service'; | |||
describe('RegisterBusinessNameService', () => { | |||
let service: RegisterBusinessNameService; | |||
beforeEach(() => { | |||
TestBed.configureTestingModule({}); | |||
service = TestBed.inject(RegisterBusinessNameService); | |||
}); | |||
it('should be created', () => { | |||
expect(service).toBeTruthy(); | |||
}); | |||
}); |
@@ -0,0 +1,73 @@ | |||
import { Injectable } from '@angular/core'; | |||
import { HttpClient, HttpHeaders } from '@angular/common/http'; | |||
import { Observable, throwError } from 'rxjs'; | |||
import { catchError, retry } from 'rxjs/operators'; | |||
import { AcknowledgementRow, ReceiptRow } from '../pages/register-business/register-business.component'; | |||
export interface NameCheckRequest { | |||
name: string; | |||
} | |||
export interface NameCheckResponse { | |||
status: string; | |||
} | |||
export interface NameRegisterRequest { | |||
name: string; | |||
entityType: string; | |||
companyCategory: string; | |||
companySuffix: string; | |||
dropSuffix: string; | |||
} | |||
export interface NameRegisterResponse { | |||
status: string; | |||
} | |||
@Injectable({ | |||
providedIn: 'root' | |||
}) | |||
export class RegisterBusinessNameService { | |||
constructor(private http: HttpClient) { | |||
} | |||
checkName(name: string) { | |||
const nameCheckRequest: NameCheckRequest = { | |||
name, | |||
}; | |||
return new Promise<NameCheckResponse>((resolve, reject) => resolve({status: 'success'})); | |||
return this.http.post<NameCheckResponse>('http://localhost:10000/name-check/', nameCheckRequest).toPromise(); | |||
} | |||
registerName( | |||
name: string, | |||
entityType: string, | |||
companyCategory: string, | |||
companySuffix: string, | |||
dropSuffix: string, | |||
) { | |||
const nameRegisterRequest: NameRegisterRequest = { | |||
name, | |||
entityType, | |||
companyCategory, | |||
companySuffix, | |||
dropSuffix, | |||
}; | |||
return new Promise<NameCheckResponse>((resolve, reject) => resolve({status: 'success'})); | |||
return this.http.post<NameRegisterResponse>('http://localhost:8080/name-register/', nameRegisterRequest).toPromise(); | |||
} | |||
getAcknowledgement() { | |||
return this.http.get<Array<AcknowledgementRow>>('http://localhost:8080/acknowledgement/').toPromise(); | |||
} | |||
getReceipt() { | |||
return this.http.get<Array<ReceiptRow>>('http://localhost:8080/receipt/').toPromise(); | |||
} | |||
} |