Skip to content

Commit 96e1f7e

Browse files
committed
fix: enhance compliance report view
1 parent 04ddf99 commit 96e1f7e

File tree

10 files changed

+69
-102
lines changed

10 files changed

+69
-102
lines changed

frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.html

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ <h5 class="card-title mb-0 text-uppercase label-header d-flex align-items-center
3636
<th (sort)="onSortBy($event)"
3737
[isSortable]="true"
3838
[sortEvent]="sortEvent"
39-
[sortable]="'config_report_name'"
39+
[sortable]="'configReportName'"
4040
appColumnSortable
4141
class="font-weight-semibold cursor-pointer">
4242
Security Control Name
@@ -46,9 +46,8 @@ <h5 class="card-title mb-0 text-uppercase label-header d-flex align-items-center
4646
</tr>
4747
</thead>
4848
<tbody *ngIf="reports$ | async as reports;">
49-
<tr class="cursor-pointer" (click)="reportDetail=report"
50-
*ngFor="let report of reports; let index = index"
51-
style="position: relative; z-index: 1;">
49+
<tr class="cursor-pointer" (click)="reportDetail = report"
50+
*ngFor="let report of reports; let index = index" style="position: relative; z-index: 1;">
5251
<td style="width: 5%; position: relative; z-index: 0;"
5352
[ngClass]="(report.configReportNote && report.configReportNote !== '') || report.status === 'complaint' ? 'border-left-success' : 'border-left-danger'"
5453
[ngStyle]="(report.configReportNote && report.configReportNote !== '') || report.status === 'complaint' ? {'border-left': '5px solid green !important;'} : {'border-left': '5px solid red !important;'}">
@@ -109,8 +108,7 @@ <h5 class="card-title mb-0 text-uppercase label-header d-flex align-items-center
109108
<div *ngIf="reportDetail" class="utm-right-container">
110109
<div (click)="reportDetail= undefined" class="overlay overlay-lg col-md-7"></div>
111110
<div class="card utm-right-action utm-right-action-lg ml-0">
112-
<div
113-
[ngClass]="(reportDetail.configReportNote && reportDetail.configReportNote !== '') || reportDetail.status === 'complaint' ? 'border-left-success' : 'border-left-danger'"
111+
<div [ngClass]="(reportDetail.configReportNote && reportDetail.configReportNote !== '') || reportDetail.status === 'complaint' ? 'border-left-success' : 'border-left-danger'"
114112
class="title d-flex justify-content-between align-items-center border-bottom-1
115113
border-bottom-grey-100 pl-3 pt-3 pr-3 pb-0">
116114
<h6 class="card-title text-blue-800 font-weight-light">

frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ export class ComplianceReportsViewComponent implements OnInit, OnChanges, OnDest
3838
page = 0;
3939
totalItems = 0;
4040
sortEvent: SortEvent = {
41-
column: 'config_report_name',
41+
column: 'configReportName',
4242
direction: 'desc'
4343
};
4444
destroy$: Subject<void> = new Subject();
45-
sort = 'config_report_name,desc';
45+
sort = 'configReportName,desc';
4646
search: string;
4747

4848
constructor(private reportsService: CpReportsService,
@@ -64,6 +64,7 @@ export class ComplianceReportsViewComponent implements OnInit, OnChanges, OnDest
6464
standardId: this.section.standardId,
6565
sectionId: this.section.id,
6666
expandDashboard: true,
67+
setStatus: true,
6768
sort: this.sort,
6869
search: this.search ? this.search : null,
6970
})),

frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.html

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<div class="w-100" *ngIf="compliance$ | async as compliance">
2-
<div [ngClass]="(report.status === 'complaint' || report.status === 'in_progress') ? 'border-left-success' : 'border-left-danger'">
2+
<div [ngClass]="isComplaint() ? 'border-left-success' : 'border-left-danger'">
33
<div class="d-flex justify-content-around align-content-center py-1" style="border-bottom: 1px solid #ccc;">
44
<div style="padding-left: 10px" class="w-100">
55
<span class="text-blue-800 font-weight-light mr-2">Status:</span>
6-
<span [ngClass]="compliance.rows.length > 0 ? 'text-success' : 'text-danger'"
6+
<span [ngClass]="isComplaint() ? 'text-success' : 'text-danger'"
77
class="span-small-icon d-flex justify-content-start align-items-center">
8-
{{ report.status === 'complaint' ? 'Compliant' : 'Non compliant' }}
8+
{{ isComplaint() ? 'Compliant' : 'Non compliant' }}
99
</span>
1010
</div>
1111

@@ -58,7 +58,17 @@
5858
<app-utm-collapsible-text class="font-size-base" [maxLength]="200" [text]="report.configSolution"></app-utm-collapsible-text>
5959
</div>
6060

61-
<ng-container *ngIf="report.status === 'non_complaint' && report.configRemediation">
61+
<ng-container *ngIf="report.configReportNote">
62+
<div class="alert-details w-100 d-flex justify-content-start align-items-center mt-3">
63+
<span class="text-blue-800 font-weight-light mr-2">Compliance note:</span>
64+
</div>
65+
66+
<div class="alert-details w-100 d-flex justify-content-start align-items-center mb-2">
67+
<app-utm-collapsible-text class="font-size-base" [maxLength]="200" [text]="report.configReportNote"></app-utm-collapsible-text>
68+
</div>
69+
</ng-container>
70+
71+
<ng-container *ngIf="!isComplaint() && report.configRemediation">
6272
<div class="alert-details w-100 d-flex justify-content-start align-items-center mt-3">
6373
<span class="text-blue-800 font-weight-light mr-2">Compliance remediation:</span>
6474
</div>

frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {TimeWindowsService} from '../../../shared/components/utm-cp-section/time
1111
import {ComplianceReportType} from '../../../shared/type/compliance-report.type';
1212
import {ExportPdfService} from "../../../../shared/services/util/export-pdf.service";
1313
import {UtmToastService} from "../../../../shared/alert/utm-toast.service";
14+
import {ComplianceStatusEnum} from "../../../shared/enums/compliance-status.enum";
1415

1516
@Component({
1617
selector: 'app-compliance-report-detail',
@@ -20,14 +21,15 @@ import {UtmToastService} from "../../../../shared/alert/utm-toast.service";
2021
export class ComplianceReportDetailComponent implements OnInit {
2122
request = {
2223
page: 0,
23-
size: 10000,
24+
size: 10,
2425
sort: 'order,asc',
2526
'idDashboard.equals': 0
2627
};
2728
_report: ComplianceReportType;
2829
compliance$!: Observable<any>;
2930
csvExport = false;
3031
printFormat = false;
32+
ComplianceStatusEnum = ComplianceStatusEnum;
3133

3234
constructor(private utmRenderVisualization: UtmRenderVisualization,
3335
private runVisualization: RunVisualizationService,
@@ -135,4 +137,8 @@ export class ComplianceReportDetailComponent implements OnInit {
135137
});
136138
}
137139

140+
isComplaint() {
141+
return this.report.configReportStatus === ComplianceStatusEnum.COMPLAINT
142+
|| (this.report.configReportNote && this.report.configReportNote !== '');
143+
}
138144
}

frontend/src/app/compliance/compliance-reports-view/components/compliance-status/compliance-status.component.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
<ng-container *ngIf="template === 'default'">
2-
<div *ngIf="compliance$ | async as compliance">
3-
<span [ngClass]="compliance.status ? 'text-success' : 'text-danger'"
2+
<div>
3+
<span [ngClass]="report.configReportStatus === ComplianceStatus.COMPLAINT ? 'text-success' : 'text-danger'"
44
class="span-small-icon d-flex justify-content-start align-items-center">
5-
{{ compliance.status ? 'Compliant' : 'Non compliant' }}
5+
{{ isComplaint() ? 'Compliant' : 'Non compliant' }}
66
</span>
77
</div>
88
</ng-container>
99

1010
<ng-container *ngIf="template === 'dropdown'">
11-
<div *ngIf="compliance$ | async as compliance" (click)="onClick($event)" ngbDropdown container="body" #drop="ngbDropdown">
11+
<div (click)="onClick($event)" ngbDropdown container="body" #drop="ngbDropdown">
1212
<a class="btn btn-light btn-sm"
13-
[ngClass]="(report.configReportNote && report.configReportNote !== '') || compliance.status ? 'text-success' : 'text-danger'"
13+
[ngClass]="(report.configReportNote && report.configReportNote !== '') || report.configReportStatus === ComplianceStatus.COMPLAINT ? 'text-success' : 'text-danger'"
1414
ngbDropdownToggle>
1515
<span class="indicator-progress" *ngIf="changing">
1616
<span class="spinner-border spinner-border-sm align-middle me-2"></span>
1717
</span>
1818
<span>
19-
{{ compliance.status || (report.configReportNote && report.configReportNote !== '') ? 'Compliant' : 'Non compliant' }}
19+
{{ isComplaint() ? 'Compliant' : 'Non compliant' }}
2020
</span>
2121
<button class="toggle-button">
2222
<i class="icon-arrow-down32 font-size-sm text-dark"></i>
@@ -26,12 +26,12 @@
2626
<div
2727
class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-semibold font-size-sm py-2 px-3"
2828
ngbDropdownMenu>
29-
<div *ngIf="report.status === 'non_complaint'" class="menu-item px-2 cursor-pointer menu-hover"
30-
(click)="changeStatusTo('complaint'); drop.close()">
29+
<div *ngIf="!isComplaint()" class="menu-item px-2 cursor-pointer menu-hover"
30+
(click)="changeStatusTo(ComplianceStatus.COMPLAINT); drop.close()">
3131
<a style="font-size: 12px" class="menu-link px-2 fw-bolder text-success">{{ 'Complaint' }}</a>
3232
</div>
33-
<div *ngIf="report.status === 'complaint'" class="menu-item px-2 cursor-pointer menu-hover"
34-
(click)="changeStatusTo('non_complaint'); drop.close()">
33+
<div *ngIf="isComplaint()" class="menu-item px-2 cursor-pointer menu-hover"
34+
(click)="changeStatusTo(ComplianceStatus.NON_COMPLAINT); drop.close()">
3535
<a style="font-size: 12px" class="menu-link px-2 fw-bolder text-danger">{{ 'Non compliant' }}</a>
3636
</div>
3737
</div>
Lines changed: 15 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
22
import {Observable} from 'rxjs';
3-
import {concatMap, filter, map, startWith, tap} from 'rxjs/operators';
43
import {ModalService} from '../../../../core/modal/modal.service';
54
import {UtmRenderVisualization} from '../../../../dashboard/shared/services/utm-render-visualization.service';
65
import {RunVisualizationService} from '../../../../graphic-builder/shared/services/run-visualization.service';
6+
import {UtmDashboardVisualizationType} from '../../../../shared/chart/types/dashboard/utm-dashboard-visualization.type';
77
import {VisualizationType} from '../../../../shared/chart/types/visualization.type';
88
import {ModalAddNoteComponent} from '../../../../shared/components/utm/util/modal-add-note/modal-add-note.component';
99
import {ChartTypeEnum} from '../../../../shared/enums/chart-type.enum';
1010
import {TimeWindowsService} from '../../../shared/components/utm-cp-section/time-windows.service';
11+
import {ComplianceStatusEnum} from '../../../shared/enums/compliance-status.enum';
1112
import {ComplianceReportType} from '../../../shared/type/compliance-report.type';
12-
import {UtmDashboardVisualizationType} from '../../../../shared/chart/types/dashboard/utm-dashboard-visualization.type';
1313

1414

1515
export type ComplianceStatus = 'complaint' | 'non_complaint';
@@ -23,78 +23,19 @@ export type ComplianceStatus = 'complaint' | 'non_complaint';
2323
export class ComplianceStatusComponent implements OnInit {
2424
@Input() template: 'default' | 'dropdown' = 'default';
2525
private _report: ComplianceReportType;
26-
compliance$: Observable<{ status: boolean }> = null;
27-
request = {
28-
page: 0,
29-
size: 10000,
30-
sort: 'order,asc',
31-
'idDashboard.equals': 0
32-
};
3326
vis: VisualizationType;
3427

35-
@Output() isCompliant = new EventEmitter<boolean>();
3628
@Output() visualization = new EventEmitter<any>();
3729
changing: any;
3830
status: ComplianceStatus = 'complaint';
3931
loading = false;
32+
ComplianceStatus = ComplianceStatusEnum;
4033

41-
constructor(private utmRenderVisualization: UtmRenderVisualization,
42-
private runVisualization: RunVisualizationService,
43-
private timeWindowsService: TimeWindowsService,
34+
constructor(private timeWindowsService: TimeWindowsService,
4435
private modalService: ModalService) {
4536
}
4637

47-
ngOnInit() {
48-
/*this.compliance$ = this.utmRenderVisualization.onRefresh$
49-
.pipe(
50-
filter((refresh) => !!refresh),
51-
concatMap(() => this.utmRenderVisualization.query(this.request)
52-
.pipe(
53-
map(response => response.body.filter(vis =>
54-
vis.visualization.chartType === ChartTypeEnum.TABLE_CHART || vis.visualization.chartType === ChartTypeEnum.LIST_CHART
55-
)),
56-
filter(vis => vis.length > 0),
57-
map(vis => {
58-
this.visualization.emit(vis);
59-
return vis[0].visualization;
60-
}),
61-
tap( vis => {
62-
const time = vis.filterType.find( filterType => filterType.field === '@timestamp');
63-
if (time) {
64-
this.timeWindowsService.changeTimeWindows({
65-
reportId: this.report.id,
66-
time: time.value[0]
67-
});
68-
}
69-
}),
70-
concatMap((vis: VisualizationType) => this.runVisualization.run(vis)),
71-
map(run => {
72-
const isCompliant = run[0] && run[0].rows.length > 0;
73-
this.report.status = isCompliant || this.report.note && this.report.note !== '' ? 'complaint'
74-
: 'non_complaint';
75-
this.isCompliant.emit(isCompliant);
76-
return {
77-
status: isCompliant
78-
};
79-
})
80-
))
81-
);*/
82-
83-
this.compliance$ = this.utmRenderVisualization.onRefresh$
84-
.pipe(
85-
filter((refresh) => !!refresh),
86-
concatMap(() => this.runVisualization.run(this.vis)),
87-
map(run => {
88-
const isCompliant = run[0] && run[0].rows.length > 0;
89-
this.report.status = isCompliant || this.report.configReportNote && this.report.configReportNote !== '' ? 'complaint'
90-
: 'non_complaint';
91-
this.isCompliant.emit(isCompliant);
92-
return {
93-
status: isCompliant
94-
};
95-
}),
96-
);
97-
}
38+
ngOnInit() {}
9839

9940
@Input() set report(value: ComplianceReportType) {
10041
if (value) {
@@ -113,8 +54,6 @@ export class ComplianceStatusComponent implements OnInit {
11354
time: time.value[0]
11455
});
11556
}
116-
117-
this.utmRenderVisualization.notifyRefresh(true);
11857
}
11958
}
12059

@@ -126,9 +65,10 @@ export class ComplianceStatusComponent implements OnInit {
12665
event.stopPropagation();
12766
}
12867

129-
changeStatusTo(status: ComplianceStatus) {
68+
changeStatusTo(status: ComplianceStatusEnum) {
13069
const modalRef = this.modalService.open(ModalAddNoteComponent, {centered: true});
13170
modalRef.componentInstance.report = this.report;
71+
modalRef.componentInstance.isComplaint = this.isComplaint();
13272
modalRef.componentInstance.header = 'Confirm status change';
13373
modalRef.componentInstance.message = this.getModalMessage(status);
13474
modalRef.componentInstance.confirmBtnText = 'Confirm';
@@ -140,20 +80,25 @@ export class ComplianceStatusComponent implements OnInit {
14080
});
14181
}
14282

143-
getModalMessage(status: ComplianceStatus) {
144-
return status === 'complaint'
83+
getModalMessage(status: ComplianceStatusEnum) {
84+
return !this.isComplaint()
14585
? `You are about to change the compliance status to <b>Complaint (External Tool)</b>.
14686
<br><br>
14787
Please note that you must provide a detailed note explaining where and how this compliance
14888
is being fulfilled using the external tool.
14989
<br><br>
15090
Are you sure you want to proceed?`
151-
: status === 'non_complaint'
91+
: this.isComplaint()
15292
? `You are about to change the compliance status to <b>Non Compliant</b>.
15393
<br><br>
15494
Please note that the note associated with this compliance will be permanently removed.
15595
<br><br>
15696
Are you sure you want to proceed?`
15797
: '';
15898
}
99+
100+
isComplaint() {
101+
return this.report.configReportStatus === ComplianceStatusEnum.COMPLAINT
102+
|| (this.report.configReportNote && this.report.configReportNote !== '');
103+
}
159104
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum ComplianceStatusEnum {
2+
COMPLAINT = 'COMPLAINT',
3+
NON_COMPLAINT = 'NON_COMPLAINT'
4+
}

frontend/src/app/compliance/shared/type/compliance-report.type.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {ComplianceTypeEnum} from '../enums/compliance-type.enum';
66
import {ComplianceStandardSectionType} from './compliance-standard-section.type';
77
import {ComplianceTemplateParams} from './compliance-template-params.type';
88
import {UtmDashboardVisualizationType} from '../../../shared/chart/types/dashboard/utm-dashboard-visualization.type';
9+
import {ComplianceStatusEnum} from '../enums/compliance-status.enum';
910

1011
export class ComplianceReportType {
1112
columns?: UtmFieldType[];
@@ -32,5 +33,7 @@ export class ComplianceReportType {
3233
status?: string;
3334
configReportNote?: string;
3435
configReportName?: string;
36+
configReportRemediation?: string;
37+
configReportStatus?: ComplianceStatusEnum;
3538
dashboard?: UtmDashboardVisualizationType[];
3639
}

frontend/src/app/shared/components/utm/util/modal-add-note/modal-add-note.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{{textDisplay}}
66
</div>
77
<label [innerHTML]="message" class="font-weight-light modal-message"></label>
8-
<div *ngIf="report.status === 'non_complaint'" class="w-100 mt-2">
8+
<div *ngIf="!isComplaint" class="w-100 mt-2">
99
<form #noteForm="ngForm">
1010
<textarea [(ngModel)]="note" #noteField="ngModel" required class="form-control" name="note" rows="5"></textarea>
1111
<div *ngIf="noteField.invalid && noteField.dirty" class="text-danger">
@@ -18,7 +18,7 @@
1818
<i class="icon-cancel-circle2"></i>
1919
Cancel
2020
</button>
21-
<button [disabled]="report.status === 'non_complaint' && note === ''" (click)="confirm()" [ngClass]="confirmBtnType" class="btn utm-button utm-button-primary">
21+
<button [disabled]="(!isComplaint && note === '')" (click)="confirm()" [ngClass]="confirmBtnType" class="btn utm-button utm-button-primary">
2222
<i [ngClass]="confirmBtnIcon" class="icon-database-remove"></i>
2323
{{confirmBtnText}}
2424
</button>

0 commit comments

Comments
 (0)