| @@ -18,6 +18,7 @@ | |||||
| "@angular/platform-browser": "~12.2.0", | "@angular/platform-browser": "~12.2.0", | ||||
| "@angular/platform-browser-dynamic": "~12.2.0", | "@angular/platform-browser-dynamic": "~12.2.0", | ||||
| "@angular/router": "~12.2.0", | "@angular/router": "~12.2.0", | ||||
| "ng2-file-upload": "^1.4.0", | |||||
| "rxjs": "~6.6.0", | "rxjs": "~6.6.0", | ||||
| "tslib": "^2.3.0", | "tslib": "^2.3.0", | ||||
| "zone.js": "~0.11.4" | "zone.js": "~0.11.4" | ||||
| @@ -1,5 +1,6 @@ | |||||
| import { NgModule } from '@angular/core'; | import { NgModule } from '@angular/core'; | ||||
| import { BrowserModule } from '@angular/platform-browser'; | import { BrowserModule } from '@angular/platform-browser'; | ||||
| import { FileUploadModule } from 'ng2-file-upload'; | |||||
| import { AppRoutingModule } from './app-routing.module'; | import { AppRoutingModule } from './app-routing.module'; | ||||
| import { AppComponent } from './app.component'; | import { AppComponent } from './app.component'; | ||||
| @@ -22,6 +23,8 @@ import { InvestigateBusinessEntitiesAndIndividualsComponent } from './pages/inve | |||||
| import { ViewCaseDetailsComponent } from './pages/investigate-business-entities-and-individuals/view-case-details/view-case-details.component'; | import { ViewCaseDetailsComponent } from './pages/investigate-business-entities-and-individuals/view-case-details/view-case-details.component'; | ||||
| import { ModifyCaseDetailsComponent } from './pages/investigate-business-entities-and-individuals/modify-case-details/modify-case-details.component'; | import { ModifyCaseDetailsComponent } from './pages/investigate-business-entities-and-individuals/modify-case-details/modify-case-details.component'; | ||||
| import { AssignPanelComponent } from './pages/investigate-business-entities-and-individuals/assign-panel/assign-panel.component'; | import { AssignPanelComponent } from './pages/investigate-business-entities-and-individuals/assign-panel/assign-panel.component'; | ||||
| import { TextareaComponent } from './widgets/form/textarea/textarea.component'; | |||||
| import { MultiFileUploadComponent } from './widgets/form/multi-file-upload/multi-file-upload.component'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| @@ -43,12 +46,15 @@ import { AssignPanelComponent } from './pages/investigate-business-entities-and- | |||||
| InvestigateBusinessEntitiesAndIndividualsComponent, | InvestigateBusinessEntitiesAndIndividualsComponent, | ||||
| ViewCaseDetailsComponent, | ViewCaseDetailsComponent, | ||||
| ModifyCaseDetailsComponent, | ModifyCaseDetailsComponent, | ||||
| AssignPanelComponent | |||||
| AssignPanelComponent, | |||||
| TextareaComponent, | |||||
| MultiFileUploadComponent | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| AppRoutingModule, | AppRoutingModule, | ||||
| FormsModule | |||||
| FormsModule, | |||||
| FileUploadModule, | |||||
| ], | ], | ||||
| providers: [], | providers: [], | ||||
| bootstrap: [AppComponent] | bootstrap: [AppComponent] | ||||
| @@ -17,7 +17,7 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
| proceed() { | proceed() { | ||||
| this.stateHistory.push(this.state); | this.stateHistory.push(this.state); | ||||
| switch (this.state) { | switch (this.state) { | ||||
| case 'VIEW INITIAL DETAILS': | case 'VIEW INITIAL DETAILS': | ||||
| if (this.hasEnoughData) { | if (this.hasEnoughData) { | ||||
| @@ -25,6 +25,10 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
| } else { | } else { | ||||
| this.state = 'ENTER MORE DETAILS'; | this.state = 'ENTER MORE DETAILS'; | ||||
| } | } | ||||
| break; | |||||
| case 'ENTER MORE DETAILS': | |||||
| this.state = 'ASSIGN COMMITTEE'; | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1 +1,17 @@ | |||||
| <p>modify-case-details works!</p> | |||||
| <div class="form-holder"> | |||||
| <h3>Add further information for the case</h3> | |||||
| <div class="two-column-holder"> | |||||
| <app-date-input | |||||
| label="Date of contacting source" | |||||
| ></app-date-input> | |||||
| <app-generic-input | |||||
| type="text" | |||||
| label="Name of source" | |||||
| placeholder="e.g. Jermey Stevens" | |||||
| ></app-generic-input> | |||||
| </div> | |||||
| <app-textarea | |||||
| label="Remarks" | |||||
| ></app-textarea> | |||||
| <app-multi-file-upload label="Documents"></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); | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,5 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | import { Component, OnInit } from '@angular/core'; | ||||
| import { FileUploader } from 'ng2-file-upload'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-modify-case-details', | selector: 'app-modify-case-details', | ||||
| @@ -6,10 +7,17 @@ import { Component, OnInit } from '@angular/core'; | |||||
| styleUrls: ['./modify-case-details.component.scss'] | styleUrls: ['./modify-case-details.component.scss'] | ||||
| }) | }) | ||||
| export class ModifyCaseDetailsComponent implements OnInit { | export class ModifyCaseDetailsComponent implements OnInit { | ||||
| uploader: FileUploader = new FileUploader({ | |||||
| url: '' | |||||
| }); | |||||
| constructor() { } | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| handleFilesDrop(files: Array<File>) { | |||||
| console.log(files); | |||||
| } | |||||
| } | } | ||||
| @@ -24,7 +24,7 @@ | |||||
| <div class="prompt-data-outreach"> | <div class="prompt-data-outreach"> | ||||
| <label> | <label> | ||||
| <input type="checkbox" [(ngModel)]="hasEnoughData" (ngModelChange)="toggleHasData($event)"> | <input type="checkbox" [(ngModel)]="hasEnoughData" (ngModelChange)="toggleHasData($event)"> | ||||
| <span>Is this data enough to proceed with investigation?</span> | |||||
| <span>There is enough data to proceed with investigation</span> | |||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -1,5 +1,5 @@ | |||||
| <div class="input-holder"> | <div class="input-holder"> | ||||
| <input [type]="type" [placeholder]="placeholder"> | |||||
| <input [type]="type" [placeholder]="placeholder ? placeholder : ''"> | |||||
| <label> {{ label }}: </label> | <label> {{ label }}: </label> | ||||
| </div> | </div> | ||||
| @@ -0,0 +1,25 @@ | |||||
| <div class="input-holder"> | |||||
| <div class="label"> {{ label }}: </div> | |||||
| <div class="files-holder"> | |||||
| <div *ngFor="let file of uploadedFiles" class="file-holder"> | |||||
| <app-file | |||||
| [name]="file.name" | |||||
| [sizeInBytes]="file.sizeInBytes" | |||||
| [extension]="file.extension" | |||||
| ></app-file> | |||||
| </div> | |||||
| <label> | |||||
| <input class="hidden-file-input" type="file" ng2FileSelect [uploader]="uploader" multiple (onFileSelected)="handleFilesDrop($event)" /> | |||||
| <div class="add-button"> | |||||
| <img src="../../../../assets/icons/plus.svg" alt="Add file"> | |||||
| </div> | |||||
| </label> | |||||
| </div> | |||||
| <div ng2FileDrop | |||||
| [uploader]="uploader" | |||||
| (onFileDrop)="handleFilesDrop($event)" | |||||
| class="file-drop-zone" | |||||
| > | |||||
| Drag and drop files | |||||
| </div> | |||||
| </div> | |||||
| @@ -0,0 +1,51 @@ | |||||
| .label { | |||||
| font-size: 1.4rem; | |||||
| color: var(--primary); | |||||
| font-weight: 400; | |||||
| letter-spacing: 0.5px; | |||||
| margin-bottom: 5px; | |||||
| } | |||||
| .input-holder { | |||||
| width: 100%; | |||||
| margin: 1.5rem 0; | |||||
| position: relative; | |||||
| } | |||||
| .hidden-file-input { | |||||
| display: none; | |||||
| } | |||||
| .add-button { | |||||
| display: inline-flex; | |||||
| justify-content: center; | |||||
| border: 1px solid var(--border-grey); | |||||
| border-radius: 1rem; | |||||
| width: 5.5rem; | |||||
| height: 7rem; | |||||
| margin-bottom: 15px; | |||||
| cursor: pointer; | |||||
| img { | |||||
| width: 40%; | |||||
| height: auto; | |||||
| } | |||||
| } | |||||
| .file-drop-zone { | |||||
| border: 2px dotted var(--secondary); | |||||
| padding: 35px; | |||||
| font-size: 16px; | |||||
| color: var(--secondary); | |||||
| text-align: center; | |||||
| } | |||||
| .files-holder { | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| .file-holder { | |||||
| margin-right: 15px; | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { MultiFileUploadComponent } from './multi-file-upload.component'; | |||||
| describe('MultiFileUploadComponent', () => { | |||||
| let component: MultiFileUploadComponent; | |||||
| let fixture: ComponentFixture<MultiFileUploadComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [ MultiFileUploadComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| }); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(MultiFileUploadComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,47 @@ | |||||
| import { Component, Input, OnInit } from '@angular/core'; | |||||
| import { FileUploader } from 'ng2-file-upload'; | |||||
| interface FileInfo { | |||||
| name: string, | |||||
| sizeInBytes: number, | |||||
| extension: string, | |||||
| link?: string, | |||||
| } | |||||
| @Component({ | |||||
| selector: 'app-multi-file-upload', | |||||
| templateUrl: './multi-file-upload.component.html', | |||||
| styleUrls: ['./multi-file-upload.component.scss'] | |||||
| }) | |||||
| export class MultiFileUploadComponent implements OnInit { | |||||
| @Input() label = ''; | |||||
| uploader: FileUploader = new FileUploader({ | |||||
| url: '' | |||||
| }); | |||||
| uploadedFiles: Array<FileInfo> = []; | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| handleFilesDrop(files: Array<File>) { | |||||
| for (const file of files) { | |||||
| const fileName = file.name; | |||||
| const extensionSeparatorIndex = fileName.lastIndexOf('.'); | |||||
| const name = fileName.substring(0, extensionSeparatorIndex); | |||||
| const extension = fileName.substring(extensionSeparatorIndex + 1); | |||||
| const sizeInBytes = file.size; | |||||
| this.uploadedFiles.push({ | |||||
| name, | |||||
| extension, | |||||
| sizeInBytes, | |||||
| }); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,4 @@ | |||||
| <div class="input-holder"> | |||||
| <label> {{ label }}: </label> | |||||
| <textarea [placeholder]="placeholder ? placeholder : ''"></textarea> | |||||
| </div> | |||||
| @@ -0,0 +1,50 @@ | |||||
| .input-holder { | |||||
| width: 100%; | |||||
| margin: 1.5rem 0; | |||||
| position: relative; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: flex-start; | |||||
| label { | |||||
| font-size: 1.4rem; | |||||
| background-color: white; | |||||
| color: var(--primary); | |||||
| position: absolute; | |||||
| top: 2.2rem; | |||||
| left: -0.5rem; | |||||
| padding: 0 0.5rem; | |||||
| font-weight: 400; | |||||
| letter-spacing: 0.5px; | |||||
| transform: translate(2.5rem, -3rem); | |||||
| } | |||||
| textarea { | |||||
| display: block; | |||||
| width: 100%; | |||||
| border-radius: 2rem; | |||||
| height: 8rem; | |||||
| border: 1px solid var(--border-grey); | |||||
| padding: 1rem 2rem; | |||||
| font-size: 1.5rem; | |||||
| letter-spacing: 0.5px; | |||||
| color: var(--dark-grey); | |||||
| background-color: white; | |||||
| resize: vertical; | |||||
| &:focus { | |||||
| border-color: var(--highlight); | |||||
| &~label { | |||||
| color: var(--highlight); | |||||
| } | |||||
| } | |||||
| } | |||||
| img { | |||||
| position: relative; | |||||
| transform: translateX(-4rem); | |||||
| pointer-events: none; | |||||
| background-color: white; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { TextareaComponent } from './textarea.component'; | |||||
| describe('TextareaComponent', () => { | |||||
| let component: TextareaComponent; | |||||
| let fixture: ComponentFixture<TextareaComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [ TextareaComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| }); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(TextareaComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,17 @@ | |||||
| import { Component, Input, OnInit } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-textarea', | |||||
| templateUrl: './textarea.component.html', | |||||
| styleUrls: ['./textarea.component.scss'] | |||||
| }) | |||||
| export class TextareaComponent implements OnInit { | |||||
| @Input() label = ''; | |||||
| @Input() placeholder: string|undefined; | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,6 @@ | |||||
| <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"> | |||||
| <g id="Group_82" data-name="Group 82" transform="translate(1 1)"> | |||||
| <line id="Line_36" data-name="Line 36" y2="10" transform="translate(5)" fill="none" stroke="#6d654e" stroke-linecap="round" stroke-width="2"/> | |||||
| <line id="Line_37" data-name="Line 37" y2="10" transform="translate(10 5) rotate(90)" fill="none" stroke="#6d654e" stroke-linecap="round" stroke-width="2"/> | |||||
| </g> | |||||
| </svg> | |||||