@@ -28,6 +28,8 @@ import { MultiFileUploadComponent } from './widgets/form/multi-file-upload/multi | |||||
import { ReviewNonComplianceComponent } from './pages/investigate-business-entities-and-individuals/review-non-compliance/review-non-compliance.component'; | import { ReviewNonComplianceComponent } from './pages/investigate-business-entities-and-individuals/review-non-compliance/review-non-compliance.component'; | ||||
import { ConcurComplianceReviewComponent } from './pages/investigate-business-entities-and-individuals/concur-compliance-review/concur-compliance-review.component'; | import { ConcurComplianceReviewComponent } from './pages/investigate-business-entities-and-individuals/concur-compliance-review/concur-compliance-review.component'; | ||||
import { ClosingRemarksComponent } from './pages/investigate-business-entities-and-individuals/closing-remarks/closing-remarks.component'; | import { ClosingRemarksComponent } from './pages/investigate-business-entities-and-individuals/closing-remarks/closing-remarks.component'; | ||||
import { PreparePreliminaryLetterComponent } from './pages/investigate-business-entities-and-individuals/prepare-preliminary-letter/prepare-preliminary-letter.component'; | |||||
import { RespondToPreliminaryLetterComponent } from './pages/investigate-business-entities-and-individuals/respond-to-preliminary-letter/respond-to-preliminary-letter.component'; | |||||
@NgModule({ | @NgModule({ | ||||
declarations: [ | declarations: [ | ||||
@@ -54,7 +56,9 @@ import { ClosingRemarksComponent } from './pages/investigate-business-entities-a | |||||
MultiFileUploadComponent, | MultiFileUploadComponent, | ||||
ReviewNonComplianceComponent, | ReviewNonComplianceComponent, | ||||
ConcurComplianceReviewComponent, | ConcurComplianceReviewComponent, | ||||
ClosingRemarksComponent | |||||
ClosingRemarksComponent, | |||||
PreparePreliminaryLetterComponent, | |||||
RespondToPreliminaryLetterComponent | |||||
], | ], | ||||
imports: [ | imports: [ | ||||
BrowserModule, | BrowserModule, | ||||
@@ -31,6 +31,10 @@ export class NotificationsComponent implements OnInit { | |||||
text: 'Concur non-compliance for Entity Corp.', | text: 'Concur non-compliance for Entity Corp.', | ||||
timeStamp: '2 hours ago', | timeStamp: '2 hours ago', | ||||
redirectionUrl: '/tabs/investigate-business-entities-and-individuals', | redirectionUrl: '/tabs/investigate-business-entities-and-individuals', | ||||
}, { | |||||
text: 'Prepare preliminary letter', | |||||
timeStamp: '2 hours ago', | |||||
redirectionUrl: '/tabs/investigate-business-entities-and-individuals', | |||||
}, { | }, { | ||||
text: 'Investigation complete', | text: 'Investigation complete', | ||||
timeStamp: '1 hours ago', | timeStamp: '1 hours ago', | ||||
@@ -38,7 +38,7 @@ | |||||
*ngIf="state === 'REVIEW NON COMPLIANCE'" | *ngIf="state === 'REVIEW NON COMPLIANCE'" | ||||
[panelRemarks]="panelRemarks" | [panelRemarks]="panelRemarks" | ||||
[isNonCompliant]="isNonCompliant" | [isNonCompliant]="isNonCompliant" | ||||
(onNonComplianceUpdate)="isNonCompliant = $event" | |||||
(onNonComplianceUpdate)="updateIsNonCompliant($event)" | |||||
></app-review-non-compliance> | ></app-review-non-compliance> | ||||
<app-concur-compliance-review | <app-concur-compliance-review | ||||
@@ -50,6 +50,13 @@ | |||||
(onIsConcurringUpdate)="isPanelConcurring = $event" | (onIsConcurringUpdate)="isPanelConcurring = $event" | ||||
(onRemarksUpdate)="updatePanelRemarks($event)" | (onRemarksUpdate)="updatePanelRemarks($event)" | ||||
></app-concur-compliance-review> | ></app-concur-compliance-review> | ||||
<app-prepare-preliminary-letter | |||||
*ngIf="state === 'PREPARE PRELIMINARY LETTER'" | |||||
></app-prepare-preliminary-letter> | |||||
<app-respond-to-preliminary-letter | |||||
*ngIf="state === 'RESPOND TO PRELIMINARY LETTER'" | |||||
></app-respond-to-preliminary-letter> | |||||
<div class="form-action-buttons"> | <div class="form-action-buttons"> | ||||
<button class="common-button neutral" *ngIf="stateHistory.length > 0" (click)="goBack()"> | <button class="common-button neutral" *ngIf="stateHistory.length > 0" (click)="goBack()"> | ||||
@@ -1,7 +1,7 @@ | |||||
import { Component, OnInit } from '@angular/core'; | import { Component, OnInit } from '@angular/core'; | ||||
type State = 'VIEW INITIAL DETAILS'|'ENTER MORE DETAILS'|'ASSIGN COMMITTEE'|'REVIEW NON COMPLIANCE'|'CONCUR COMPLIANCE REVIEW'|'CLOSING REMARKS'; | |||||
type Role = 'Investigator'|'Hod'|'Panel'; | |||||
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'; | |||||
@Component({ | @Component({ | ||||
selector: 'app-investigate-business-entities-and-individuals', | selector: 'app-investigate-business-entities-and-individuals', | ||||
@@ -26,16 +26,21 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
constructor() { | constructor() { | ||||
const panelRemarks = localStorage.getItem('panelRemarks'); | const panelRemarks = localStorage.getItem('panelRemarks'); | ||||
if (panelRemarks) { | if (panelRemarks) { | ||||
this.panelRemarks = panelRemarks; | this.panelRemarks = panelRemarks; | ||||
} | } | ||||
this.isNonCompliant = localStorage.getItem('isNonCompliant') === 'true'; | |||||
const loginEmail = localStorage.getItem('loginEmail'); | const loginEmail = localStorage.getItem('loginEmail'); | ||||
if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('hod')) { | if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('hod')) { | ||||
this.loginRole = 'Hod'; | this.loginRole = 'Hod'; | ||||
} else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('panel')) { | } else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('panel')) { | ||||
this.loginRole = 'Panel'; | this.loginRole = 'Panel'; | ||||
} else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('customer')) { | |||||
this.loginRole = 'Customer'; | |||||
} else { | } else { | ||||
this.loginRole = 'Investigator'; | this.loginRole = 'Investigator'; | ||||
} | } | ||||
@@ -63,6 +68,14 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
this.state = 'CLOSING REMARKS'; | this.state = 'CLOSING REMARKS'; | ||||
this.executingRole = 'Investigator'; | this.executingRole = 'Investigator'; | ||||
break; | break; | ||||
case 'PREPARE PRELIMINARY LETTER': | |||||
this.state = 'PREPARE PRELIMINARY LETTER'; | |||||
this.executingRole = 'Investigator'; | |||||
break; | |||||
case 'RESPOND TO PRELIMINARY LETTER': | |||||
this.state = 'RESPOND TO PRELIMINARY LETTER'; | |||||
this.executingRole = 'Customer'; | |||||
break; | |||||
default: | default: | ||||
this.state = 'VIEW INITIAL DETAILS'; | this.state = 'VIEW INITIAL DETAILS'; | ||||
this.executingRole = 'Investigator'; | this.executingRole = 'Investigator'; | ||||
@@ -71,6 +84,11 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
this.canExecute = this.loginRole === this.executingRole; | this.canExecute = this.loginRole === this.executingRole; | ||||
} | } | ||||
updateIsNonCompliant(isNonCompliant: boolean) { | |||||
this.isNonCompliant = isNonCompliant; | |||||
localStorage.setItem('isNonCompliant', String(isNonCompliant)); | |||||
} | |||||
updatePanelRemarks(remarks: string) { | updatePanelRemarks(remarks: string) { | ||||
this.panelRemarks = remarks; | this.panelRemarks = remarks; | ||||
localStorage.setItem('panelRemarks', remarks); | localStorage.setItem('panelRemarks', remarks); | ||||
@@ -105,10 +123,18 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
if (!this.isPanelConcurring) { | if (!this.isPanelConcurring) { | ||||
this.state = 'REVIEW NON COMPLIANCE'; | this.state = 'REVIEW NON COMPLIANCE'; | ||||
} else { | } else { | ||||
this.state = 'CLOSING REMARKS'; | |||||
if (this.isNonCompliant) { | |||||
this.state = 'PREPARE PRELIMINARY LETTER'; | |||||
} else { | |||||
this.state = 'CLOSING REMARKS'; | |||||
} | |||||
} | } | ||||
this.executingRole = 'Investigator'; | this.executingRole = 'Investigator'; | ||||
break; | break; | ||||
case 'PREPARE PRELIMINARY LETTER': | |||||
this.state = 'RESPOND TO PRELIMINARY LETTER'; | |||||
this.executingRole = 'Customer'; | |||||
break; | |||||
} | } | ||||
localStorage.setItem('state', this.state); | localStorage.setItem('state', this.state); | ||||
@@ -0,0 +1,11 @@ | |||||
<div class="form-holder"> | |||||
<h3>Prepare preliminary letter for customer</h3> | |||||
<div class="two-column-holder"> | |||||
<app-generic-input | |||||
type="text" | |||||
label="Email" | |||||
placeholder="e.g. entity-name@mail.com" | |||||
></app-generic-input> | |||||
</div> | |||||
<app-multi-file-upload [maxNoOfFiles]="1" label="Preliminary letter"></app-multi-file-upload> | |||||
</div> |
@@ -0,0 +1,22 @@ | |||||
.form-holder { | |||||
width: calc(70% - 2rem); | |||||
padding: 4rem; | |||||
margin: 0 auto; | |||||
} | |||||
h3 { | |||||
font-size: 2rem; | |||||
color: var(--dark-grey); | |||||
filter: brightness(80%); | |||||
font-weight: 500; | |||||
margin: 2rem 0; | |||||
} | |||||
.two-column-holder { | |||||
display: grid; | |||||
grid-template-columns: 1fr 1fr; | |||||
& > * { | |||||
width: calc(100% - 2rem); | |||||
} | |||||
} |
@@ -0,0 +1,25 @@ | |||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
import { PreparePreliminaryLetterComponent } from './prepare-preliminary-letter.component'; | |||||
describe('PreparePreliminaryLetterComponent', () => { | |||||
let component: PreparePreliminaryLetterComponent; | |||||
let fixture: ComponentFixture<PreparePreliminaryLetterComponent>; | |||||
beforeEach(async () => { | |||||
await TestBed.configureTestingModule({ | |||||
declarations: [ PreparePreliminaryLetterComponent ] | |||||
}) | |||||
.compileComponents(); | |||||
}); | |||||
beforeEach(() => { | |||||
fixture = TestBed.createComponent(PreparePreliminaryLetterComponent); | |||||
component = fixture.componentInstance; | |||||
fixture.detectChanges(); | |||||
}); | |||||
it('should create', () => { | |||||
expect(component).toBeTruthy(); | |||||
}); | |||||
}); |
@@ -0,0 +1,15 @@ | |||||
import { Component, OnInit } from '@angular/core'; | |||||
@Component({ | |||||
selector: 'app-prepare-preliminary-letter', | |||||
templateUrl: './prepare-preliminary-letter.component.html', | |||||
styleUrls: ['./prepare-preliminary-letter.component.scss'] | |||||
}) | |||||
export class PreparePreliminaryLetterComponent implements OnInit { | |||||
constructor() { } | |||||
ngOnInit(): void { | |||||
} | |||||
} |
@@ -0,0 +1 @@ | |||||
<p>respond-to-preliminary-letter works!</p> |
@@ -0,0 +1,25 @@ | |||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
import { RespondToPreliminaryLetterComponent } from './respond-to-preliminary-letter.component'; | |||||
describe('RespondToPreliminaryLetterComponent', () => { | |||||
let component: RespondToPreliminaryLetterComponent; | |||||
let fixture: ComponentFixture<RespondToPreliminaryLetterComponent>; | |||||
beforeEach(async () => { | |||||
await TestBed.configureTestingModule({ | |||||
declarations: [ RespondToPreliminaryLetterComponent ] | |||||
}) | |||||
.compileComponents(); | |||||
}); | |||||
beforeEach(() => { | |||||
fixture = TestBed.createComponent(RespondToPreliminaryLetterComponent); | |||||
component = fixture.componentInstance; | |||||
fixture.detectChanges(); | |||||
}); | |||||
it('should create', () => { | |||||
expect(component).toBeTruthy(); | |||||
}); | |||||
}); |
@@ -0,0 +1,15 @@ | |||||
import { Component, OnInit } from '@angular/core'; | |||||
@Component({ | |||||
selector: 'app-respond-to-preliminary-letter', | |||||
templateUrl: './respond-to-preliminary-letter.component.html', | |||||
styleUrls: ['./respond-to-preliminary-letter.component.scss'] | |||||
}) | |||||
export class RespondToPreliminaryLetterComponent implements OnInit { | |||||
constructor() { } | |||||
ngOnInit(): void { | |||||
} | |||||
} |
@@ -8,7 +8,7 @@ | |||||
[extension]="file.extension" | [extension]="file.extension" | ||||
></app-file> | ></app-file> | ||||
</div> | </div> | ||||
<label> | |||||
<label *ngIf="isAddAllowed()"> | |||||
<input class="hidden-file-input" type="file" ng2FileSelect [uploader]="uploader" multiple (onFileSelected)="handleFilesDrop($event)" /> | <input class="hidden-file-input" type="file" ng2FileSelect [uploader]="uploader" multiple (onFileSelected)="handleFilesDrop($event)" /> | ||||
<div class="add-button"> | <div class="add-button"> | ||||
<img src="../../../../assets/icons/plus.svg" alt="Add file"> | <img src="../../../../assets/icons/plus.svg" alt="Add file"> | ||||
@@ -16,10 +16,11 @@ | |||||
</label> | </label> | ||||
</div> | </div> | ||||
<div ng2FileDrop | <div ng2FileDrop | ||||
*ngIf="isAddAllowed()" | |||||
[uploader]="uploader" | [uploader]="uploader" | ||||
(onFileDrop)="handleFilesDrop($event)" | (onFileDrop)="handleFilesDrop($event)" | ||||
class="file-drop-zone" | class="file-drop-zone" | ||||
> | > | ||||
Drag and drop files | |||||
Drag and drop file(s) | |||||
</div> | </div> | ||||
</div> | </div> |
@@ -15,7 +15,8 @@ interface FileInfo { | |||||
}) | }) | ||||
export class MultiFileUploadComponent implements OnInit { | export class MultiFileUploadComponent implements OnInit { | ||||
@Input() label = ''; | @Input() label = ''; | ||||
@Input() maxNoOfFiles?: number; | |||||
uploader: FileUploader = new FileUploader({ | uploader: FileUploader = new FileUploader({ | ||||
url: '' | url: '' | ||||
}); | }); | ||||
@@ -27,6 +28,10 @@ export class MultiFileUploadComponent implements OnInit { | |||||
ngOnInit(): void { | ngOnInit(): void { | ||||
} | } | ||||
isAddAllowed() { | |||||
return typeof this.maxNoOfFiles === 'undefined' || this.uploadedFiles.length < this.maxNoOfFiles; | |||||
} | |||||
handleFilesDrop(files: Array<File>) { | handleFilesDrop(files: Array<File>) { | ||||
for (const file of files) { | for (const file of files) { | ||||
const fileName = file.name; | const fileName = file.name; | ||||