From 0e555b4041657c1abf1d919298cb3beef8259ca2 Mon Sep 17 00:00:00 2001 From: Brett Mayen Date: Sun, 4 Oct 2020 08:42:13 -0400 Subject: [PATCH] feat(assessments): add custom table filter matchMode to filter Testers array --- frontend/src/app/app.service.ts | 15 +-- .../assessments/assessments.component.html | 113 ++++++++++-------- .../app/assessments/assessments.component.ts | 81 +++++++++++-- 3 files changed, 144 insertions(+), 65 deletions(-) diff --git a/frontend/src/app/app.service.ts b/frontend/src/app/app.service.ts index a2513af4..04292851 100644 --- a/frontend/src/app/app.service.ts +++ b/frontend/src/app/app.service.ts @@ -11,6 +11,7 @@ import { environment } from '../environments/environment'; }) export class AppService { constructor(private http: HttpClient, private sanitizer: DomSanitizer) {} + api = environment.apiUrl; // TODO: Delete this monstrosity that I have created // Please forgive me coding gods! @@ -165,7 +166,7 @@ export class AppService { .get(`${this.api}/assessment/${id}`) .toPromise() .then((res) => { - return res; + return res as object[]; }); } @@ -271,7 +272,7 @@ export class AppService { createAsset(asset: Asset) { return this.http.post( `${this.api}/organization/${asset.organization}/asset`, - asset + asset, ); } @@ -297,7 +298,7 @@ export class AppService { updateAsset(asset: Asset) { return this.http.patch( `${this.api}/organization/${asset.organization}/asset/${asset.id}`, - asset + asset, ); } @@ -338,11 +339,11 @@ export class AppService { updateAssessment( assessment: Assessment, assessmentId: number, - assetId: number + assetId: number, ) { return this.http.patch( `${this.api}/asset/${assetId}/assessment/${assessmentId}`, - assessment + assessment, ); } @@ -354,7 +355,7 @@ export class AppService { */ getAssessment(assetId: number, assessmentId: number) { return this.http.get( - `${this.api}/asset/${assetId}/assessment/${assessmentId}` + `${this.api}/asset/${assetId}/assessment/${assessmentId}`, ); } @@ -406,7 +407,7 @@ export class AppService { return this.http.post( `${this.api}/report/generate`, generateObject, - httpOptions + httpOptions, ); } diff --git a/frontend/src/app/assessments/assessments.component.html b/frontend/src/app/assessments/assessments.component.html index e9db637a..542d457f 100644 --- a/frontend/src/app/assessments/assessments.component.html +++ b/frontend/src/app/assessments/assessments.component.html @@ -1,71 +1,88 @@
- - + + + - Assessment ID - - Assessment Name - - Testers - - Jira ID - Start Date - - End Date + + {{col.header}} + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + + {{ assessment.id }} {{ assessment?.name }} -
+
{{tester?.firstName}} {{tester?.lastName}},
{{ assessment?.jiraId - }} + }} {{ assessment?.startDate | date: "shortDate":'UTC' }} {{ assessment?.endDate | date: "shortDate":'UTC' }} diff --git a/frontend/src/app/assessments/assessments.component.ts b/frontend/src/app/assessments/assessments.component.ts index ec338ae3..e0363d4d 100644 --- a/frontend/src/app/assessments/assessments.component.ts +++ b/frontend/src/app/assessments/assessments.component.ts @@ -1,11 +1,17 @@ import { Component, OnInit, ViewChild } from '@angular/core'; +import { FilterUtils } from 'primeng/utils'; import { AppService } from '../app.service'; import { AlertService } from '../alert/alert.service'; import { ActivatedRoute, Router } from '@angular/router'; import { Assessment } from '../assessment-form/Assessment'; import { Table } from 'primeng/table'; -import { UserService } from '../user.service'; import { User } from '../interfaces/User'; +import { UserService } from '../user.service'; + +// User decorated with compound name field +interface FormattedUser extends User { + name: string; +} @Component({ selector: 'app-assessments', @@ -16,28 +22,69 @@ export class AssessmentsComponent implements OnInit { assessmentAry: any = []; assetId: number; orgId: number; - testers: User[]; + testers: FormattedUser[]; @ViewChild('assessmentTable') table: Table; + cols = [ + { + field: 'id', + filterMatchMode: 'contains', + header: 'Assessment ID', + }, + { + field: 'name', + filterMatchMode: 'contains', + header: 'Assessment Name', + }, + { + field: 'testers', + filterMatchMode: 'arrayCompare', + header: 'Testers', + }, + { + field: 'jiraId', + filterMatchMode: 'contains', + header: 'Jira ID', + }, + { + field: 'startDate', + filterMatchMode: 'equals', + header: 'Start Date', + }, + { + field: 'startDate', + filterMatchMode: 'equals', + header: 'End Date', + }, + ]; + constructor( public activatedRoute: ActivatedRoute, public router: Router, public appService: AppService, public alertService: AlertService, - public userService: UserService + public userService: UserService, ) {} ngOnInit() { this.activatedRoute.data.subscribe( - ({ assessments }) => (this.assessmentAry = assessments) + ({assessments}) => { + this.assessmentAry = assessments; + }, ); this.activatedRoute.params.subscribe((params) => { this.assetId = params.assetId; this.orgId = params.orgId; }); this.userService.getUsers().subscribe((testers) => { - this.testers = testers; + // add a composite 'name' field to the Testers to display in MultiSelect + this.testers = testers.map((tester) => ({ + ...tester, + name: this.formatName(tester), + })); }); + + this.addArrayCompareTableFilter(); } /** @@ -97,11 +144,6 @@ export class AssessmentsComponent implements OnInit { } } - onTesterChange(event) { - const selectedTesterAry = event.value.map((x) => x.id); - this.table.filter(selectedTesterAry, 'testers', 'in'); - } - onDateSelect(value, type) { const date = new Date(value); date.setUTCHours(0, 0, 0, 0); @@ -111,4 +153,23 @@ export class AssessmentsComponent implements OnInit { this.table.filter(date.toISOString(), 'endDate', 'equals'); } } + + /** + * Create custom table filter "matchMode" to compare multiselect filter array values to array of values in a table row field + */ + private addArrayCompareTableFilter() { + // @ts-ignore-next-line + FilterUtils.arrayCompare = (values: User[], selections: FormattedUser[]) => { + return values.some((value) => { + return !!selections.some((selection) => selection.name === this.formatName(value)); + }); + }; + } + + /** + * Format composite name from first and last name fields + */ + private formatName(user) { + return `${user.firstName} ${user.lastName}`; + } }