mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Add a placeholder to the cards for the security-hub (#19536)
1. Related issue #19249 Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
7718134301
commit
30730c6716
@ -119,43 +119,55 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block pt-1">
|
||||
<div
|
||||
class="clr-row row"
|
||||
*ngFor="let item of securitySummary?.dangerous_artifacts">
|
||||
<div class="clr-col">
|
||||
<a
|
||||
class="search"
|
||||
href="javascript:void(0)"
|
||||
appScrollAnchor="{{ vulId }}"
|
||||
(click)="searchRepoClick(item)"
|
||||
title="{{ item.repository_name }}">
|
||||
<span class="ellipsis">
|
||||
<clr-icon shape="search"></clr-icon
|
||||
>{{ item.repository_name }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="clr-col" title="{{ item?.digest }}">
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
[routerLink]="
|
||||
getDigestLink(
|
||||
item?.project_id,
|
||||
item?.repository_name,
|
||||
item.digest
|
||||
)
|
||||
"
|
||||
><span class="ellipsis">{{
|
||||
item?.digest?.slice(0, 15)
|
||||
}}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="clr-col">
|
||||
<div class="single-bar-container">
|
||||
<app-single-bar
|
||||
[dangerousArtifact]="item"></app-single-bar>
|
||||
<ng-container *ngIf="securitySummary?.dangerous_artifacts?.length"
|
||||
><div
|
||||
class="clr-row row"
|
||||
*ngFor="let item of securitySummary?.dangerous_artifacts">
|
||||
<div class="clr-col">
|
||||
<a
|
||||
class="search"
|
||||
href="javascript:void(0)"
|
||||
appScrollAnchor="{{ vulId }}"
|
||||
(click)="searchRepoClick(item)"
|
||||
title="{{ item.repository_name }}">
|
||||
<span class="ellipsis">
|
||||
<clr-icon shape="search"></clr-icon
|
||||
>{{ item.repository_name }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clr-col" title="{{ item?.digest }}">
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
[routerLink]="
|
||||
getDigestLink(
|
||||
item?.project_id,
|
||||
item?.repository_name,
|
||||
item.digest
|
||||
)
|
||||
"
|
||||
><span class="ellipsis">{{
|
||||
item?.digest?.slice(0, 15)
|
||||
}}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="clr-col">
|
||||
<div class="single-bar-container">
|
||||
<app-single-bar
|
||||
[dangerousArtifact]="item"></app-single-bar>
|
||||
</div>
|
||||
</div></div
|
||||
></ng-container>
|
||||
<div
|
||||
class="datagrid-placeholder"
|
||||
*ngIf="
|
||||
!loadingSummary &&
|
||||
!securitySummary?.dangerous_artifacts?.length
|
||||
">
|
||||
<div class="datagrid-placeholder-image"></div>
|
||||
<span class="datagrid-placeholder-content">{{
|
||||
'SECURITY_HUB.NO_VUL' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -178,67 +190,91 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block pt-1">
|
||||
<div
|
||||
class="clr-row row"
|
||||
*ngFor="let item of securitySummary?.dangerous_cves">
|
||||
<div class="clr-col-4">
|
||||
<a
|
||||
class="search"
|
||||
href="javascript:void(0)"
|
||||
appScrollAnchor="{{ vulId }}"
|
||||
(click)="searchCVEClick(item?.cve_id)"
|
||||
title="{{ item.cve_id }}">
|
||||
<span class="ellipsis">
|
||||
<clr-icon shape="search"></clr-icon
|
||||
>{{ item.cve_id }}
|
||||
<ng-container *ngIf="securitySummary?.dangerous_cves?.length"
|
||||
><div
|
||||
class="clr-row row"
|
||||
*ngFor="let item of securitySummary?.dangerous_cves">
|
||||
<div class="clr-col-4">
|
||||
<a
|
||||
class="search"
|
||||
href="javascript:void(0)"
|
||||
appScrollAnchor="{{ vulId }}"
|
||||
(click)="searchCVEClick(item?.cve_id)"
|
||||
title="{{ item.cve_id }}">
|
||||
<span class="ellipsis">
|
||||
<clr-icon shape="search"></clr-icon
|
||||
>{{ item.cve_id }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="clr-col-2">
|
||||
<ng-container [ngSwitch]="item.severity">
|
||||
<span
|
||||
*ngSwitchCase="'Critical'"
|
||||
class="label label-critical no-border"
|
||||
>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'High'"
|
||||
class="label label-danger no-border"
|
||||
>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'Medium'"
|
||||
class="label label-medium no-border"
|
||||
>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'Low'"
|
||||
class="label label-low no-border"
|
||||
>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'None'"
|
||||
class="label label-none no-border"
|
||||
>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span
|
||||
>
|
||||
<span *ngSwitchDefault>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="clr-col-2">
|
||||
{{ item?.cvss_score_v3 }}
|
||||
</div>
|
||||
<div class="clr-col-4 ellipsis">
|
||||
<span
|
||||
*ngIf="item?.version"
|
||||
title="{{ item?.package + '@' + item?.version }}">
|
||||
{{ item?.package + '@' + item?.version }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="clr-col-2">
|
||||
<ng-container [ngSwitch]="item.severity">
|
||||
<span
|
||||
*ngSwitchCase="'Critical'"
|
||||
class="label label-critical no-border"
|
||||
>{{ severityText(item.severity) | translate }}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'High'"
|
||||
class="label label-danger no-border"
|
||||
>{{ severityText(item.severity) | translate }}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'Medium'"
|
||||
class="label label-medium no-border"
|
||||
>{{ severityText(item.severity) | translate }}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'Low'"
|
||||
class="label label-low no-border"
|
||||
>{{ severityText(item.severity) | translate }}</span
|
||||
>
|
||||
<span
|
||||
*ngSwitchCase="'None'"
|
||||
class="label label-none no-border"
|
||||
>{{ severityText(item.severity) | translate }}</span
|
||||
>
|
||||
<span *ngSwitchDefault>{{
|
||||
severityText(item.severity) | translate
|
||||
}}</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="clr-col-2">
|
||||
{{ item?.cvss_score_v3 }}
|
||||
</div>
|
||||
<div class="clr-col-4 ellipsis">
|
||||
<span
|
||||
*ngIf="item?.version"
|
||||
title="{{ item?.package + '@' + item?.version }}">
|
||||
{{ item?.package + '@' + item?.version }}
|
||||
</span>
|
||||
<span *ngIf="!item?.version" title="{{ item?.package }}">
|
||||
{{ item?.package }}
|
||||
</span>
|
||||
</div>
|
||||
*ngIf="!item?.version"
|
||||
title="{{ item?.package }}">
|
||||
{{ item?.package }}
|
||||
</span>
|
||||
</div>
|
||||
</div></ng-container
|
||||
>
|
||||
<div
|
||||
class="datagrid-placeholder"
|
||||
*ngIf="
|
||||
!loadingSummary && !securitySummary?.dangerous_cves?.length
|
||||
">
|
||||
<div class="datagrid-placeholder-image"></div>
|
||||
<span class="datagrid-placeholder-content">{{
|
||||
'SECURITY_HUB.NO_VUL' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -110,3 +110,25 @@ $row-height: 48px;
|
||||
.label {
|
||||
min-width: 3rem;
|
||||
}
|
||||
|
||||
.datagrid-placeholder {
|
||||
margin-top: 2.5rem;
|
||||
border-top: 0;
|
||||
padding: 0.6rem;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-size: .8rem;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
.datagrid-placeholder-image {
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
margin-bottom: 0.6rem;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%220%200%2060%2072%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%0A%20%20%20%20%3Cdefs%3E%0A%20%20%20%20%20%20%20%20%3Cellipse%20id%3D%22path-1%22%20cx%3D%2230%22%20cy%3D%2261.7666667%22%20rx%3D%2215.4512904%22%20ry%3D%224.73333333%22%3E%3C%2Fellipse%3E%0A%20%20%20%20%20%20%20%20%3Cmask%20id%3D%22mask-2%22%20maskContentUnits%3D%22userSpaceOnUse%22%20maskUnits%3D%22objectBoundingBox%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2230.9025808%22%20height%3D%229.46666667%22%20fill%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cuse%20xlink%3Ahref%3D%22%23path-1%22%3E%3C%2Fuse%3E%0A%20%20%20%20%20%20%20%20%3C%2Fmask%3E%0A%20%20%20%20%3C%2Fdefs%3E%0A%20%20%20%20%3Cg%20id%3D%22Page-1%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%20%20%20%20%3Cg%20id%3D%22Artboard%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cuse%20id%3D%22Oval-10%22%20stroke%3D%22%23C1DFEF%22%20mask%3D%22url(%23mask-2)%22%20stroke-width%3D%222.8%22%20stroke-linecap%3D%22square%22%20stroke-dasharray%3D%223%2C6%2C3%2C5%22%20xlink%3Ahref%3D%22%23path-1%22%3E%3C%2Fuse%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M38.4613647%2C18.1642456%20L30.9890137%2C34.9141846%20L31%2C47%20L32.5977783%2C46.5167236%20L32.5977783%2C34.9141846%20L51.0673218%2C15.7560425%20C51.0673218%2C15.7560425%2048.6295166%2C16.6542969%2044.9628906%2C17.3392334%20C41.2962646%2C18.0241699%2038.4613647%2C18.1642456%2038.4613647%2C18.1642456%20Z%22%20id%3D%22Path-195%22%20fill%3D%22%23C1DFEF%22%3E%3C%2Fpath%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M4.74639226%2C12.5661855%20L4.62065726%2C12.1605348%20L5.3515414%2C11.1625044%20L5.77622385%2C11.159939%20L6.20936309%2C12.5573481%20L4.74639226%2C12.5661855%20Z%20M6.20936309%2C12.5573481%20L6.32542632%2C12.9317954%20L28.4963855%2C34.8796718%20L28.4963855%2C47.8096691%20L32.6%2C46.4836513%20L32.6%2C34.8992365%20L53.973494%2C12.7035813%20L53.973494%2C12.2688201%20L6.20936309%2C12.5573481%20Z%20M55.373494%2C10.8603376%20L55.373494%2C13.2680664%20L34%2C35.4637216%20L34%2C47.5025401%20L27.0963855%2C49.7333333%20L27.0963855%2C35.4637219%20L5.09179688%2C13.680542%20L4.31325301%2C11.1687764%20L55.373494%2C10.8603376%20Z%22%20id%3D%22Path-149%22%20fill%3D%22%237FBDDD%22%3E%3C%2Fpath%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cellipse%20id%3D%22Oval-9%22%20fill%3D%22%23FFFFFF%22%20cx%3D%2230%22%20cy%3D%2211.785654%22%20rx%3D%2226%22%20ry%3D%226.78565401%22%3E%3C%2Fellipse%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M30%2C17.171308%20C36.8772177%2C17.171308%2043.3112282%2C16.4610701%2048.0312371%2C15.2292106%20C50.2777611%2C14.6428977%2052.0507619%2C13.9579677%2053.2216231%2C13.2354973%20C54.1938565%2C12.6355886%2054.6%2C12.1175891%2054.6%2C11.785654%20C54.6%2C11.4537189%2054.1938565%2C10.9357194%2053.2216231%2C10.3358107%20C52.0507619%2C9.61334032%2050.2777611%2C8.92841034%2048.0312371%2C8.34209746%20C43.3112282%2C7.11023795%2036.8772177%2C6.4%2030%2C6.4%20C23.1227823%2C6.4%2016.6887718%2C7.11023795%2011.9687629%2C8.34209746%20C9.72223886%2C8.92841034%207.94923814%2C9.61334032%206.77837689%2C10.3358107%20C5.8061435%2C10.9357194%205.4%2C11.4537189%205.4%2C11.785654%20C5.4%2C12.1175891%205.8061435%2C12.6355886%206.77837689%2C13.2354973%20C7.94923814%2C13.9579677%209.72223886%2C14.6428977%2011.9687629%2C15.2292106%20C16.6887718%2C16.4610701%2023.1227823%2C17.171308%2030%2C17.171308%20Z%20M30%2C18.571308%20C15.6405965%2C18.571308%204%2C15.5332672%204%2C11.785654%20C4%2C8.03804078%2015.6405965%2C5%2030%2C5%20C44.3594035%2C5%2056%2C8.03804078%2056%2C11.785654%20C56%2C15.5332672%2044.3594035%2C18.571308%2030%2C18.571308%20Z%22%20id%3D%22Oval-9-Copy%22%20fill%3D%22%237FBDDD%22%3E%3C%2Fpath%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M18.2608643%2C7.14562988%20L22.727356%2C16.9047241%20C22.727356%2C16.9047241%2015.3006592%2C16.3911743%2010.276001%2C14.7511597%20C5.25134277%2C13.111145%205.38031006%2C11.8284302%205.38031006%2C11.6882935%20C5.38031006%2C10.4832831%208.16633152%2C9.41877716%2011.114563%2C8.57324219%20C14.549319%2C7.58817492%2018.2608643%2C7.14562988%2018.2608643%2C7.14562988%20Z%22%20id%3D%22Path-196%22%20fill%3D%22%23C1DFEF%22%3E%3C%2Fpath%3E%0A%20%20%20%20%20%20%20%20%3C%2Fg%3E%0A%20%20%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E");
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import {
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DangerousArtifact } from '../../../../../../../ng-swagger-gen/models/dangerous-artifact';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-vulnerability-summary',
|
||||
@ -45,6 +46,7 @@ export class VulnerabilitySummaryComponent implements OnInit, OnDestroy {
|
||||
chart: any;
|
||||
@ViewChild('pieChart', { static: true })
|
||||
pieChartEle: ElementRef;
|
||||
loadingSummary: boolean = false;
|
||||
constructor(
|
||||
private securityHubService: SecurityhubService,
|
||||
private messageHandler: MessageHandlerService,
|
||||
@ -74,11 +76,13 @@ export class VulnerabilitySummaryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
this.loadingSummary = true;
|
||||
this.securityHubService
|
||||
.getSecuritySummary({
|
||||
withDangerousArtifact: true,
|
||||
withDangerousCve: true,
|
||||
})
|
||||
.pipe(finalize(() => (this.loadingSummary = false)))
|
||||
.subscribe({
|
||||
next: res => {
|
||||
this.securitySummary = res;
|
||||
|
Loading…
Reference in New Issue
Block a user