import { Component, Input, OnInit } from '@angular/core'; import { VulnerabilitySummary, VulnerabilitySeverity } from '../service/index'; import { TranslateService } from '@ngx-translate/core'; import { VULNERABILITY_SCAN_STATUS } from '../utils'; export const MIN_TIP_WIDTH = 5; export const MAX_TIP_WIDTH = 100; @Component({ selector: 'hbr-vulnerability-summary-chart', templateUrl: './result-tip.componnent.html', styleUrls: ['./scanning.scss'] }) export class ResultTipComponent implements OnInit { _tipTitle: string = ""; _highCount: number = 0; _mediumCount: number = 0; _lowCount: number = 0; _unknownCount: number = 0; _noneCount: number = 0; totalPackages: number = 0; packagesWithVul: number = 0; @Input() summary: VulnerabilitySummary = { scan_status: VULNERABILITY_SCAN_STATUS.unknown, severity: VulnerabilitySeverity.UNKNOWN, update_time: new Date(), components: { total: 0, summary: [] } }; get scanLevel(){ let level; if (this._highCount && this._highCount >= 1) { level = VulnerabilitySeverity.HIGH; }else if (this._mediumCount && this._mediumCount >= 1) { level = VulnerabilitySeverity.MEDIUM; }else if (this._lowCount && this._lowCount >= 1) { level = VulnerabilitySeverity.LOW; }else if (this._unknownCount && this._unknownCount >= 1) { level = VulnerabilitySeverity.UNKNOWN; }else if (this.totalPackages === 0) { level = VulnerabilitySeverity.UNKNOWN; } else { level = VulnerabilitySeverity.NONE; } return level; } constructor(private translate: TranslateService) { } ngOnInit(): void { this.totalPackages = this.summary && this.summary.components ? this.summary.components.total : 0; if (this.summary && this.summary.components && this.summary.components.summary) { this.summary.components.summary.forEach(item => { if (item.severity !== VulnerabilitySeverity.NONE) { this.packagesWithVul += item.count; } switch (item.severity) { case VulnerabilitySeverity.UNKNOWN: this._unknownCount += item.count; break; case VulnerabilitySeverity.NONE: this._noneCount += item.count; break; case VulnerabilitySeverity.LOW: this._lowCount += item.count; break; case VulnerabilitySeverity.MEDIUM: this._mediumCount += item.count; break; case VulnerabilitySeverity.HIGH: this._highCount += item.count; break; default: break; } }); } this.translate.get(this.packageText(this.totalPackages)).subscribe((p1: string) => { this.translate.get(this.unitText(this.packagesWithVul)).subscribe((vul: string) => { if (this.totalPackages === 0) { this.translate.get('VULNERABILITY.CHART.TOOLTIPS_TITLE_ZERO').subscribe( (res: string) => { this._tipTitle = res; }); } else { let messageKey = 'VULNERABILITY.CHART.TOOLTIPS_TITLE_SINGULAR'; if (this.packagesWithVul > 1) { messageKey = 'VULNERABILITY.CHART.TOOLTIPS_TITLE'; } this.translate.get(messageKey, { totalVulnerability: this.packagesWithVul, totalPackages: this.totalPackages, package: p1, vulnerability: vul }).subscribe((res: string) => this._tipTitle = res); } }); }); } tipWidth(severity: VulnerabilitySeverity): string { let n: number = 0; let m: number = this.totalPackages; if (m === 0) { // If no packages recognized, then show grey if (severity === VulnerabilitySeverity.UNKNOWN) { return MAX_TIP_WIDTH + 'px'; } else { return 0 + 'px'; } } switch (severity) { case VulnerabilitySeverity.HIGH: n = this.highCount; break; case VulnerabilitySeverity.MEDIUM: n = this.mediumCount; break; case VulnerabilitySeverity.LOW: n = this.lowCount; break; case VulnerabilitySeverity.UNKNOWN: n = this.unknownCount; break; case VulnerabilitySeverity.NONE: // Show all the left as green bar n = m - (this.highCount + this.mediumCount + this.lowCount + this.unknownCount); if (n < 0) { n = 0; } break; default: n = 0; break; } let width: number = Math.round((n / m) * MAX_TIP_WIDTH); if (width > 0 && width < MIN_TIP_WIDTH) { width = MIN_TIP_WIDTH; } return width + 'px'; } unitText(count: number): string { if (count > 1) { return "VULNERABILITY.PLURAL"; } return "VULNERABILITY.SINGULAR"; } packageText(count: number): string { return count > 1 ? "VULNERABILITY.PACKAGES" : "VULNERABILITY.PACKAGE"; } public get completeTimestamp(): Date { return this.summary && this.summary.update_time ? this.summary.update_time : new Date(); } public get hasHigh(): boolean { return this.highCount > 0; } public get hasMedium(): boolean { return this.mediumCount > 0; } public get hasLow(): boolean { return this.lowCount > 0; } public get hasUnknown(): boolean { return this.unknownCount > 0; } public get hasNone(): boolean { return this.noneCount > 0; } public get tipTitle(): string { return this._tipTitle; } public get highCount(): number { return this._highCount; } public get mediumCount(): number { return this._mediumCount; } public get lowCount(): number { return this._lowCount; } public get unknownCount(): number { return this._unknownCount; } public get noneCount(): number { return this._noneCount; } public get highSuffix(): string { return this.unitText(this.highCount); } public get mediumSuffix(): string { return this.unitText(this.mediumCount); } public get lowSuffix(): string { return this.unitText(this.lowCount); } public get unknownSuffix(): string { return this.unitText(this.unknownCount); } public get noneSuffix(): string { return this.unitText(this.noneCount); } public get maxWidth(): string { return (MAX_TIP_WIDTH + 20) + "px"; } }