mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-25 03:35:21 +01:00
Update ui to fix some issues (#19101)
1. Add digest filter for vulnerability search, for #19023 2. Fixes #19104 Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
a036e4a7b0
commit
958bed2ee0
@ -19,6 +19,7 @@ import {
|
|||||||
} from './security-hub.interface';
|
} from './security-hub.interface';
|
||||||
import { ProjectService } from '../../../../../../ng-swagger-gen/services/project.service';
|
import { ProjectService } from '../../../../../../ng-swagger-gen/services/project.service';
|
||||||
import { VulnerabilityFilterComponent } from './vulnerability-filter/vulnerability-filter.component';
|
import { VulnerabilityFilterComponent } from './vulnerability-filter/vulnerability-filter.component';
|
||||||
|
import { DangerousArtifact } from '../../../../../../ng-swagger-gen/models/dangerous-artifact';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-security-hub',
|
selector: 'app-security-hub',
|
||||||
@ -174,8 +175,11 @@ export class SecurityHubComponent {
|
|||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
this.clrDgRefresh(this.state, [`${OptionType.CVE_ID}=${cveId}`]);
|
this.clrDgRefresh(this.state, [`${OptionType.CVE_ID}=${cveId}`]);
|
||||||
}
|
}
|
||||||
searchRepo(repoName: string) {
|
searchRepo(artifact: DangerousArtifact) {
|
||||||
this.vulnerabilityFilterComponent.selectedOptions = [OptionType.REPO];
|
this.vulnerabilityFilterComponent.selectedOptions = [
|
||||||
|
OptionType.REPO,
|
||||||
|
OptionType.DIGEST,
|
||||||
|
];
|
||||||
this.vulnerabilityFilterComponent.candidates = [
|
this.vulnerabilityFilterComponent.candidates = [
|
||||||
OptionType.CVE_ID,
|
OptionType.CVE_ID,
|
||||||
OptionType.SEVERITY,
|
OptionType.SEVERITY,
|
||||||
@ -185,8 +189,14 @@ export class SecurityHubComponent {
|
|||||||
OptionType.TAG,
|
OptionType.TAG,
|
||||||
];
|
];
|
||||||
this.vulnerabilityFilterComponent.valueMap = {};
|
this.vulnerabilityFilterComponent.valueMap = {};
|
||||||
this.vulnerabilityFilterComponent.valueMap[OptionType.REPO] = repoName;
|
this.vulnerabilityFilterComponent.valueMap[OptionType.REPO] =
|
||||||
|
artifact?.repository_name;
|
||||||
|
this.vulnerabilityFilterComponent.valueMap[OptionType.DIGEST] =
|
||||||
|
artifact?.digest;
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
this.clrDgRefresh(this.state, [`${OptionType.REPO}=${repoName}`]);
|
this.clrDgRefresh(this.state, [
|
||||||
|
`${OptionType.REPO}=${artifact?.repository_name}`,
|
||||||
|
`${OptionType.DIGEST}=${artifact?.digest}`,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ export enum OptionType {
|
|||||||
PACKAGE = 'package',
|
PACKAGE = 'package',
|
||||||
TAG = 'tag',
|
TAG = 'tag',
|
||||||
PROJECT_ID = 'project_id',
|
PROJECT_ID = 'project_id',
|
||||||
|
DIGEST = 'digest',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OptionType_I18n_Map = {
|
export const OptionType_I18n_Map = {
|
||||||
@ -32,6 +33,7 @@ export const OptionType_I18n_Map = {
|
|||||||
[OptionType.PACKAGE]: 'VULNERABILITY.GRID.COLUMN_PACKAGE',
|
[OptionType.PACKAGE]: 'VULNERABILITY.GRID.COLUMN_PACKAGE',
|
||||||
[OptionType.TAG]: 'REPLICATION.TAG',
|
[OptionType.TAG]: 'REPLICATION.TAG',
|
||||||
[OptionType.PROJECT_ID]: 'SECURITY_HUB.OPTION_PROJECT_ID_NAME',
|
[OptionType.PROJECT_ID]: 'SECURITY_HUB.OPTION_PROJECT_ID_NAME',
|
||||||
|
[OptionType.DIGEST]: 'P2P_PROVIDER.DIGEST',
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface OptionTypeValueMap {
|
export interface OptionTypeValueMap {
|
||||||
|
@ -24,6 +24,7 @@ export class VulnerabilityFilterComponent {
|
|||||||
OptionType.REPO,
|
OptionType.REPO,
|
||||||
OptionType.PACKAGE,
|
OptionType.PACKAGE,
|
||||||
OptionType.TAG,
|
OptionType.TAG,
|
||||||
|
OptionType.DIGEST,
|
||||||
];
|
];
|
||||||
allOptions: string[] = [
|
allOptions: string[] = [
|
||||||
OptionType.CVE_ID,
|
OptionType.CVE_ID,
|
||||||
@ -33,6 +34,7 @@ export class VulnerabilityFilterComponent {
|
|||||||
OptionType.REPO,
|
OptionType.REPO,
|
||||||
OptionType.PACKAGE,
|
OptionType.PACKAGE,
|
||||||
OptionType.TAG,
|
OptionType.TAG,
|
||||||
|
OptionType.DIGEST,
|
||||||
];
|
];
|
||||||
|
|
||||||
valueMap: OptionTypeValueMap = {};
|
valueMap: OptionTypeValueMap = {};
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
{{ securitySummary?.none_cnt || 0 }}
|
{{ securitySummary?.none_cnt || 0 }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clr-row">
|
<div class="clr-row" [hidden]="!securitySummary">
|
||||||
<div class="placeholder">
|
<div class="placeholder">
|
||||||
<div class="pie-chart" id="pie-chart"></div>
|
<div class="pie-chart" id="pie-chart"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -121,7 +121,7 @@
|
|||||||
class="search"
|
class="search"
|
||||||
href="javascript:void(0)"
|
href="javascript:void(0)"
|
||||||
appScrollAnchor="{{ vulId }}"
|
appScrollAnchor="{{ vulId }}"
|
||||||
(click)="searchRepoClick(item?.repository_name)"
|
(click)="searchRepoClick(item)"
|
||||||
title="{{ item.repository_name }}">
|
title="{{ item.repository_name }}">
|
||||||
<span class="ellipsis">
|
<span class="ellipsis">
|
||||||
<clr-icon shape="search"></clr-icon
|
<clr-icon shape="search"></clr-icon
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
HarborEvent,
|
HarborEvent,
|
||||||
} from '../../../../../services/event-service/event.service';
|
} from '../../../../../services/event-service/event.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { DangerousArtifact } from '../../../../../../../ng-swagger-gen/models/dangerous-artifact';
|
||||||
highchartsAccessibility(Highcharts);
|
highchartsAccessibility(Highcharts);
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -29,7 +30,7 @@ export class VulnerabilitySummaryComponent implements OnInit, OnDestroy {
|
|||||||
@Output()
|
@Output()
|
||||||
searchCVE = new EventEmitter<string>();
|
searchCVE = new EventEmitter<string>();
|
||||||
@Output()
|
@Output()
|
||||||
searchRepo = new EventEmitter<string>();
|
searchRepo = new EventEmitter<DangerousArtifact>();
|
||||||
securitySummary: SecuritySummary;
|
securitySummary: SecuritySummary;
|
||||||
readonly vulId: string = VUL_ID;
|
readonly vulId: string = VUL_ID;
|
||||||
readonly severityText = severityText;
|
readonly severityText = severityText;
|
||||||
@ -175,8 +176,8 @@ export class VulnerabilitySummaryComponent implements OnInit, OnDestroy {
|
|||||||
this.searchCVE.emit(cveId);
|
this.searchCVE.emit(cveId);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchRepoClick(repoName: string) {
|
searchRepoClick(artifact: DangerousArtifact) {
|
||||||
this.searchRepo.emit(repoName);
|
this.searchRepo.emit(artifact);
|
||||||
}
|
}
|
||||||
|
|
||||||
getColorByTheme(): string {
|
getColorByTheme(): string {
|
||||||
|
@ -37,8 +37,18 @@ export class AppConfigService {
|
|||||||
// Store the application configuration
|
// Store the application configuration
|
||||||
configurations: AppConfig = new AppConfig();
|
configurations: AppConfig = new AppConfig();
|
||||||
|
|
||||||
|
private _bannerMessageClosed: boolean = false;
|
||||||
|
|
||||||
constructor(private http: HttpClient, private cookie: CookieService) {}
|
constructor(private http: HttpClient, private cookie: CookieService) {}
|
||||||
|
|
||||||
|
setBannerMessageClosed(v: boolean) {
|
||||||
|
this._bannerMessageClosed = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBannerMessageClosed(): boolean {
|
||||||
|
return this._bannerMessageClosed;
|
||||||
|
}
|
||||||
|
|
||||||
public load(): Observable<AppConfig> {
|
public load(): Observable<AppConfig> {
|
||||||
return this.http.get(systemInfoEndpoint, HTTP_GET_OPTIONS).pipe(
|
return this.http.get(systemInfoEndpoint, HTTP_GET_OPTIONS).pipe(
|
||||||
map(response => {
|
map(response => {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*ngIf="hasValidBannerMessage()"
|
*ngIf="hasValidBannerMessage()"
|
||||||
[clrAlertType]="getBannerMessageType()"
|
[clrAlertType]="getBannerMessageType()"
|
||||||
[clrAlertAppLevel]="true"
|
[clrAlertAppLevel]="true"
|
||||||
|
[(clrAlertClosed)]="bannerMessageClosed"
|
||||||
[clrAlertClosable]="getBannerMessageClosable()">
|
[clrAlertClosable]="getBannerMessageClosable()">
|
||||||
<clr-alert-item>
|
<clr-alert-item>
|
||||||
<span class="alert-text banner-message">{{
|
<span class="alert-text banner-message">{{
|
||||||
|
@ -39,6 +39,15 @@ export class AppLevelAlertsComponent implements OnInit, OnDestroy {
|
|||||||
private jobServiceDashboardHealthCheckService: JobServiceDashboardHealthCheckService,
|
private jobServiceDashboardHealthCheckService: JobServiceDashboardHealthCheckService,
|
||||||
private appConfigService: AppConfigService
|
private appConfigService: AppConfigService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
get bannerMessageClosed(): boolean {
|
||||||
|
return this.appConfigService.getBannerMessageClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
set bannerMessageClosed(v: boolean) {
|
||||||
|
this.appConfigService.setBannerMessageClosed(v);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
|
Loading…
Reference in New Issue
Block a user