Improve components and change package.json

This commit is contained in:
Steven Zou 2017-06-20 16:48:42 +08:00
parent e60e4c12a6
commit 969066f2c7
20 changed files with 111 additions and 64 deletions

1
.gitignore vendored
View File

@ -44,3 +44,4 @@ src/ui_ng/aot/**/*.json
**/*ngfactory.ts **/*ngfactory.ts
**/aot **/aot
**/dist **/dist
**/.bin

View File

@ -80,6 +80,8 @@ If **projectId** is set to the id of specified project, then only show the repli
**projectId** is used to specify which projects the repositories are from. **projectId** is used to specify which projects the repositories are from.
**projectName** is used to generate the related commands for pushing images.
**hasSignedIn** is a user session related property to determined whether a valid user signed in session existing. This component supports anonymous user. **hasSignedIn** is a user session related property to determined whether a valid user signed in session existing. This component supports anonymous user.
**hasProjectAdminRole** is a user session related property to determined whether the current user has project administrator role. Some action menus might be disabled based on this property. **hasProjectAdminRole** is a user session related property to determined whether the current user has project administrator role. Some action menus might be disabled based on this property.
@ -87,7 +89,7 @@ If **projectId** is set to the id of specified project, then only show the repli
**tagClickEvent** is an @output event emitter for you to catch the tag click events. **tagClickEvent** is an @output event emitter for you to catch the tag click events.
``` ```
<hbr-repository-stackview [projectId]="..." [hasSignedIn]="..." [hasProjectAdminRole]="..." (tagClickEvent)="watchTagClickEvent($event)"></hbr-repository-stackview> <hbr-repository-stackview [projectId]="..." [projectName]="" [hasSignedIn]="..." [hasProjectAdminRole]="..." (tagClickEvent)="watchTagClickEvent($event)"></hbr-repository-stackview>
... ...

View File

@ -18,21 +18,21 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^4.1.3", "@angular/animations": "~4.1.3",
"@angular/common": "^4.1.3", "@angular/common": "~4.1.3",
"@angular/compiler": "^4.1.3", "@angular/compiler": "~4.1.3",
"@angular/core": "^4.1.3", "@angular/core": "~4.1.3",
"@angular/forms": "^4.1.3", "@angular/forms": "~4.1.3",
"@angular/http": "^4.1.3", "@angular/http": "~4.1.3",
"@angular/platform-browser": "^4.1.3", "@angular/platform-browser": "~4.1.3",
"@angular/platform-browser-dynamic": "^4.1.3", "@angular/platform-browser-dynamic": "~4.1.3",
"@angular/router": "^4.1.3", "@angular/router": "~4.1.3",
"@ngx-translate/core": "^6.0.0", "@ngx-translate/core": "^6.0.0",
"@ngx-translate/http-loader": "0.0.3", "@ngx-translate/http-loader": "0.0.3",
"@webcomponents/custom-elements": "1.0.0-alpha.3", "@webcomponents/custom-elements": "1.0.0-alpha.3",
"clarity-angular": "^0.9.7", "clarity-angular": "~0.9.8",
"clarity-icons": "^0.9.7", "clarity-icons": "~0.9.8",
"clarity-ui": "^0.9.7", "clarity-ui": "~0.9.8",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"intl": "^1.2.5", "intl": "^1.2.5",
"mutationobserver-shim": "^0.3.2", "mutationobserver-shim": "^0.3.2",
@ -45,12 +45,13 @@
}, },
"devDependencies": { "devDependencies": {
"@angular/cli": "^1.0.0", "@angular/cli": "^1.0.0",
"@angular/compiler-cli": "^4.0.1", "@angular/compiler-cli": "~4.1.3",
"@types/core-js": "^0.9.41", "@types/core-js": "^0.9.41",
"@types/jasmine": "~2.2.30", "@types/jasmine": "~2.2.30",
"@types/node": "^6.0.42", "@types/node": "^6.0.42",
"bootstrap": "4.0.0-alpha.5", "bootstrap": "4.0.0-alpha.5",
"codelyzer": "~2.0.0-beta.4", "codelyzer": "~2.0.0-beta.4",
"copyfiles": "^1.2.0",
"enhanced-resolve": "^3.0.0", "enhanced-resolve": "^3.0.0",
"jasmine-core": "2.4.1", "jasmine-core": "2.4.1",
"jasmine-spec-reporter": "2.5.0", "jasmine-spec-reporter": "2.5.0",
@ -61,14 +62,14 @@
"karma-phantomjs-launcher": "^1.0.0", "karma-phantomjs-launcher": "^1.0.0",
"karma-remap-istanbul": "^0.2.1", "karma-remap-istanbul": "^0.2.1",
"protractor": "^4.0.9", "protractor": "^4.0.9",
"rimraf": "^2.6.1",
"rollup": "^0.41.6", "rollup": "^0.41.6",
"rollup-plugin-node-resolve": "^3.0.0",
"ts-node": "1.2.1", "ts-node": "1.2.1",
"tslint": "^4.1.1", "tslint": "^4.1.1",
"typescript": "~2.2.0", "typescript": "~2.2.0",
"typings": "^1.4.0", "typings": "^1.4.0",
"uglify-js": "^2.8.22", "uglify-js": "^2.8.22",
"webdriver-manager": "10.2.5", "webdriver-manager": "10.2.5"
"rimraf": "^2.6.1",
"copyfiles": "^1.2.0"
} }
} }

View File

@ -19,21 +19,21 @@
}, },
"homepage": "https://github.com/vmware/harbor#readme", "homepage": "https://github.com/vmware/harbor#readme",
"peerDependencies": { "peerDependencies": {
"@angular/animations": "^4.1.3", "@angular/animations": "~4.1.3",
"@angular/common": "^4.1.3", "@angular/common": "~4.1.3",
"@angular/compiler": "^4.1.3", "@angular/compiler": "~4.1.3",
"@angular/core": "^4.1.3", "@angular/core": "~4.1.3",
"@angular/forms": "^4.1.3", "@angular/forms": "~4.1.3",
"@angular/http": "^4.1.3", "@angular/http": "~4.1.3",
"@angular/platform-browser": "^4.1.3", "@angular/platform-browser": "~4.1.3",
"@angular/platform-browser-dynamic": "^4.1.3", "@angular/platform-browser-dynamic": "~4.1.3",
"@angular/router": "^4.1.3", "@angular/router": "~4.1.3",
"@ngx-translate/core": "^6.0.0", "@ngx-translate/core": "^6.0.0",
"@ngx-translate/http-loader": "0.0.3", "@ngx-translate/http-loader": "0.0.3",
"@webcomponents/custom-elements": "1.0.0-alpha.3", "@webcomponents/custom-elements": "1.0.0-alpha.3",
"clarity-angular": "^0.9.7", "clarity-angular": "~0.9.8",
"clarity-icons": "^0.9.7", "clarity-icons": "~0.9.8",
"clarity-ui": "^0.9.7", "clarity-ui": "~0.9.8",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"intl": "^1.2.5", "intl": "^1.2.5",
"mutationobserver-shim": "^0.3.2", "mutationobserver-shim": "^0.3.2",

View File

@ -1,3 +1,5 @@
import resolve from 'rollup-plugin-node-resolve';
export default { export default {
entry: 'dist/index.js', entry: 'dist/index.js',
dest: 'dist/bundles/harborui.umd.js', dest: 'dist/bundles/harborui.umd.js',
@ -11,10 +13,14 @@ export default {
'@angular/forms', '@angular/forms',
'@angular/platform-browser', '@angular/platform-browser',
'@angular/http', '@angular/http',
'@angular/router',
'clarity-angular', 'clarity-angular',
'@ngx-translate/core', '@ngx-translate/core',
'@ngx-translate/http-loader', '@ngx-translate/http-loader',
'ngx-cookie',
'ngx-clipboard',
'rxjs', 'rxjs',
'rxjs/Rx',
'rxjs/Subject', 'rxjs/Subject',
'rxjs/Observable', 'rxjs/Observable',
'rxjs/add/observable/of', 'rxjs/add/observable/of',
@ -29,8 +35,15 @@ export default {
'@angular/forms': 'ng.forms', '@angular/forms': 'ng.forms',
'@angular/http': 'ng.http', '@angular/http': 'ng.http',
'@angular/platform-browser': 'ng.platformBrowser', '@angular/platform-browser': 'ng.platformBrowser',
'@angular/router': 'ng.router',
'ngx-clipboard': 'ngx.clipboard',
'clarity-angular': 'ng.clarity',
'ngx-cookie': 'ngx.cookie',
'@ngx-translate/core': 'ngx.translate',
'@ngx-translate/http-loader': 'ngx.translate',
'rxjs': 'rxjs', 'rxjs': 'rxjs',
'rxjs/Subject': 'rxjs.Subject', 'rxjs/Subject': 'rxjs.Subject',
'rxjs/Rx': 'Rx',
'rxjs/Observable': 'Rx', 'rxjs/Observable': 'Rx',
'rxjs/ReplaySubject': 'Rx', 'rxjs/ReplaySubject': 'Rx',
'rxjs/add/operator/map': 'Rx.Observable.prototype', 'rxjs/add/operator/map': 'Rx.Observable.prototype',
@ -50,5 +63,10 @@ export default {
// console.warn everything else // console.warn everything else
console.warn(warning.message); console.warn(warning.message);
},
plugins: [resolve({
customResolveOptions: {
moduleDirectory: 'node_modules'
} }
})]
} }

View File

@ -39,4 +39,8 @@ export const PUSH_IMAGE_STYLE: string = `
min-width: 360px; min-width: 360px;
max-width: 720px; max-width: 720px;
} }
.btn-font {
font-size: 14px !important;
}
`; `;

View File

@ -1,7 +1,7 @@
export const PUSH_IMAGE_HTML: string = ` export const PUSH_IMAGE_HTML: string = `
<div> <div>
<clr-dropdown [clrMenuPosition]="'bottom-right'"> <clr-dropdown [clrMenuPosition]="'bottom-right'">
<button class="btn btn-link" clrDropdownToggle (click)="onclick()"> <button class="btn btn-link btn-font" clrDropdownToggle (click)="onclick()">
{{ 'PUSH_IMAGE.TITLE' | translate | uppercase}} {{ 'PUSH_IMAGE.TITLE' | translate | uppercase}}
<clr-icon shape="caret down"></clr-icon> <clr-icon shape="caret down"></clr-icon>
</button> </button>
@ -10,10 +10,12 @@ export const PUSH_IMAGE_HTML: string = `
<section> <section>
<span><h5 class="h5-override">{{ 'PUSH_IMAGE.TITLE' | translate }}</h5></span> <span><h5 class="h5-override">{{ 'PUSH_IMAGE.TITLE' | translate }}</h5></span>
<span> <span>
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right"> <clr-tooltip [clrTooltipDirection]="'top-right'" [clrTooltipSize]="'md'">
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon> <clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
<span class="tooltip-content">{{ 'PUSH_IMAGE.TOOLTIP' | translate }}</span> <clr-tooltip-content>
</a> {{ 'PUSH_IMAGE.TOOLTIP' | translate }}
</clr-tooltip-content>
</clr-tooltip>
</span> </span>
</section> </section>
<section> <section>

View File

@ -1,9 +1,10 @@
export const REPOSITORY_STACKVIEW_TEMPLATE: string = ` export const REPOSITORY_STACKVIEW_TEMPLATE: string = `
<div> <div>
<div class="row"> <div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="height: 24px;"> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="height: 32px;">
<div class="row flex-items-xs-right option-right"> <div class="row flex-items-xs-right option-right">
<div class="flex-xs-middle"> <div class="flex-xs-middle">
<hbr-push-image-button style="display: inline-block;" [registryUrl]="registryUrl" [projectName]="projectName"></hbr-push-image-button>
<hbr-filter [withDivider]="true" filterPlaceholder="{{'REPOSITORY.FILTER_FOR_REPOSITORIES' | translate}}" (filter)="doSearchRepoNames($event)"></hbr-filter> <hbr-filter [withDivider]="true" filterPlaceholder="{{'REPOSITORY.FILTER_FOR_REPOSITORIES' | translate}}" (filter)="doSearchRepoNames($event)"></hbr-filter>
<span class="refresh-btn" (click)="refresh()"><clr-icon shape="refresh"></clr-icon></span> <span class="refresh-btn" (click)="refresh()"><clr-icon shape="refresh"></clr-icon></span>
</div> </div>

View File

@ -15,6 +15,8 @@ import { RepositoryService, RepositoryDefaultService } from '../service/reposito
import { TagService, TagDefaultService } from '../service/tag.service'; import { TagService, TagDefaultService } from '../service/tag.service';
import { SystemInfoService, SystemInfoDefaultService } from '../service/system-info.service'; import { SystemInfoService, SystemInfoDefaultService } from '../service/system-info.service';
import { VULNERABILITY_DIRECTIVES } from '../vulnerability-scanning/index'; import { VULNERABILITY_DIRECTIVES } from '../vulnerability-scanning/index';
import { PUSH_IMAGE_BUTTON_DIRECTIVES } from '../push-image/index';
import { INLINE_ALERT_DIRECTIVES } from '../inline-alert/index';
import { click } from '../utils'; import { click } from '../utils';
@ -92,7 +94,9 @@ describe('RepositoryComponentStackview (inline template)', () => {
TagComponent, TagComponent,
ConfirmationDialogComponent, ConfirmationDialogComponent,
FilterComponent, FilterComponent,
VULNERABILITY_DIRECTIVES VULNERABILITY_DIRECTIVES,
PUSH_IMAGE_BUTTON_DIRECTIVES,
INLINE_ALERT_DIRECTIVES
], ],
providers: [ providers: [
ErrorHandler, ErrorHandler,

View File

@ -41,6 +41,7 @@ import { Tag, TagClickEvent } from '../service/interface';
export class RepositoryStackviewComponent implements OnInit { export class RepositoryStackviewComponent implements OnInit {
@Input() projectId: number; @Input() projectId: number;
@Input() projectName: string = "unknown";
@Input() hasSignedIn: boolean; @Input() hasSignedIn: boolean;
@Input() hasProjectAdminRole: boolean; @Input() hasProjectAdminRole: boolean;

View File

@ -61,6 +61,8 @@ export class ResultGridComponent implements OnInit {
return 'VULNERABILITY.SEVERITY.MEDIUM'; return 'VULNERABILITY.SEVERITY.MEDIUM';
case VulnerabilitySeverity.LOW: case VulnerabilitySeverity.LOW:
return 'VULNERABILITY.SEVERITY.LOW'; return 'VULNERABILITY.SEVERITY.LOW';
case VulnerabilitySeverity.NONE:
return 'VULNERABILITY.SEVERITY.NEGLIGIBLE';
case VulnerabilitySeverity.UNKNOWN: case VulnerabilitySeverity.UNKNOWN:
return 'VULNERABILITY.SEVERITY.UNKNOWN'; return 'VULNERABILITY.SEVERITY.UNKNOWN';
default: default:

View File

@ -41,7 +41,9 @@ export class ResultTipComponent implements OnInit {
this.totalPackages = this.summary && this.summary.components ? this.summary.components.total : 0; this.totalPackages = this.summary && this.summary.components ? this.summary.components.total : 0;
if (this.summary && this.summary.components && this.summary.components.summary) { if (this.summary && this.summary.components && this.summary.components.summary) {
this.summary.components.summary.forEach(item => { this.summary.components.summary.forEach(item => {
if (item.severity != VulnerabilitySeverity.NONE) {
this.packagesWithVul += item.count this.packagesWithVul += item.count
}
switch (item.severity) { switch (item.severity) {
case VulnerabilitySeverity.UNKNOWN: case VulnerabilitySeverity.UNKNOWN:

View File

@ -1,8 +1,6 @@
export const SCANNING_STYLES: string = ` export const SCANNING_STYLES: string = `
.bar-wrapper { .bar-wrapper {
width: 120px; width: 120px;
height: 24px;
display: inline-block;
} }
.bar-state { .bar-state {
text-align: center !important; text-align: center !important;
@ -18,7 +16,6 @@ export const SCANNING_STYLES: string = `
.tip-wrapper { .tip-wrapper {
display: inline-block; display: inline-block;
height: 10px; height: 10px;
max-height: 10px;
max-width: 120px; max-width: 120px;
} }
.tip-position { .tip-position {

View File

@ -62,7 +62,13 @@ export const GRID_COMPONENT_HTML: string = `
<clr-dg-placeholder>{{'VULNERABILITY.GRID.PLACEHOLDER' | translate}}</clr-dg-placeholder> <clr-dg-placeholder>{{'VULNERABILITY.GRID.PLACEHOLDER' | translate}}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let res of scanningResults"> <clr-dg-row *clrDgItems="let res of scanningResults">
<clr-dg-cell>{{res.id}}</clr-dg-cell> <clr-dg-cell>{{res.id}}</clr-dg-cell>
<clr-dg-cell>{{severityText(res.severity) | translate}}</clr-dg-cell> <clr-dg-cell [ngSwitch]="res.severity">
<span *ngSwitchCase="5" class="label label-danger">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="4" class="label label-warning">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="3" class="label label-success">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchCase="1" class="label label-info">{{severityText(res.severity) | translate}}</span>
<span *ngSwitchDefault>{{severityText(res.severity) | translate}}</span>
</clr-dg-cell>
<clr-dg-cell>{{res.package}}</clr-dg-cell> <clr-dg-cell>{{res.package}}</clr-dg-cell>
<clr-dg-cell>{{res.version}}</clr-dg-cell> <clr-dg-cell>{{res.version}}</clr-dg-cell>
<clr-dg-cell>{{res.fixedVersion}}</clr-dg-cell> <clr-dg-cell>{{res.fixedVersion}}</clr-dg-cell>

View File

@ -1,6 +1,6 @@
{ {
"name": "harbor", "name": "harbor",
"version": "1.1.0", "version": "1.2.0",
"description": "Harbor UI with Clarity", "description": "Harbor UI with Clarity",
"angular-cli": {}, "angular-cli": {},
"scripts": { "scripts": {
@ -13,25 +13,25 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^4.1.3", "@angular/animations": "~4.1.3",
"@angular/common": "^4.1.3", "@angular/common": "~4.1.3",
"@angular/compiler": "^4.1.3", "@angular/compiler": "~4.1.3",
"@angular/compiler-cli": "^4.0.2", "@angular/compiler-cli": "~4.1.3",
"@angular/core": "^4.1.3", "@angular/core": "~4.1.3",
"@angular/forms": "^4.1.3", "@angular/forms": "~4.1.3",
"@angular/http": "^4.1.3", "@angular/http": "~4.1.3",
"@angular/platform-browser": "^4.1.3", "@angular/platform-browser": "~4.1.3",
"@angular/platform-browser-dynamic": "^4.1.3", "@angular/platform-browser-dynamic": "~4.1.3",
"@angular/router": "^4.1.3", "@angular/router": "~4.1.3",
"@ngx-translate/core": "^6.0.0", "@ngx-translate/core": "^6.0.0",
"@ngx-translate/http-loader": "0.0.3", "@ngx-translate/http-loader": "0.0.3",
"@types/jquery": "^2.0.41", "@types/jquery": "^2.0.41",
"@webcomponents/custom-elements": "1.0.0-alpha.3", "@webcomponents/custom-elements": "1.0.0-alpha.3",
"clarity-angular": "^0.9.7", "clarity-angular": "^0.9.8",
"clarity-icons": "^0.9.7", "clarity-icons": "^0.9.8",
"clarity-ui": "^0.9.7", "clarity-ui": "^0.9.8",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"harbor-ui": "^0.1.99", "harbor-ui": "^0.2.12",
"intl": "^1.2.5", "intl": "^1.2.5",
"mutationobserver-shim": "^0.3.2", "mutationobserver-shim": "^0.3.2",
"ngx-clipboard": "^8.0.2", "ngx-clipboard": "^8.0.2",
@ -43,7 +43,7 @@
}, },
"devDependencies": { "devDependencies": {
"@angular/cli": "^1.0.0", "@angular/cli": "^1.0.0",
"@angular/compiler-cli": "^4.0.2", "@angular/compiler-cli": "~4.1.3",
"@types/core-js": "^0.9.34", "@types/core-js": "^0.9.34",
"@types/jasmine": "~2.2.30", "@types/jasmine": "~2.2.30",
"@types/node": "^6.0.42", "@types/node": "^6.0.42",

View File

@ -1,3 +1,3 @@
<div style="margin-top: 24px;"> <div style="margin-top: 24px;">
<hbr-repository-stackview [projectId]="projectId" [hasSignedIn]="hasSignedIn" [hasProjectAdminRole]="hasProjectAdminRole" (tagClickEvent)="watchTagClickEvent($event)"></hbr-repository-stackview> <hbr-repository-stackview [projectId]="projectId" [projectName]="projectName" [hasSignedIn]="hasSignedIn" [hasProjectAdminRole]="hasProjectAdminRole" (tagClickEvent)="watchTagClickEvent($event)"></hbr-repository-stackview>
</div> </div>

View File

@ -27,6 +27,7 @@ export class RepositoryPageComponent implements OnInit {
projectId: number; projectId: number;
hasProjectAdminRole: boolean; hasProjectAdminRole: boolean;
hasSignedIn: boolean; hasSignedIn: boolean;
projectName: string;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -39,7 +40,9 @@ export class RepositoryPageComponent implements OnInit {
this.projectId = this.route.snapshot.parent.params['id']; this.projectId = this.route.snapshot.parent.params['id'];
let resolverData = this.route.snapshot.parent.data; let resolverData = this.route.snapshot.parent.data;
if (resolverData) { if (resolverData) {
this.hasProjectAdminRole = (<Project>resolverData['projectResolver']).has_project_admin_role; let pro: Project = <Project>resolverData['projectResolver'];
this.hasProjectAdminRole = pro.has_project_admin_role;
this.projectName = pro.name;
} }
this.hasSignedIn = this.session.getCurrentUser() !== null; this.hasSignedIn = this.session.getCurrentUser() !== null;
} }

View File

@ -465,12 +465,13 @@
}, },
"CHART": { "CHART": {
"SCANNING_TIME": "Scan completed", "SCANNING_TIME": "Scan completed",
"TOOLTIPS_TITLE": "This tag has {{totalVulnerability}} vulnerabilities across {{totalPackages}} packages." "TOOLTIPS_TITLE": "This tag has {{totalVulnerability}} packages with vulnerabilities across all {{totalPackages}} packages."
}, },
"SEVERITY": { "SEVERITY": {
"HIGH": "High level", "HIGH": "High level",
"MEDIUM": "Medium level", "MEDIUM": "Medium level",
"LOW": "Low level", "LOW": "Low level",
"NEGLIGIBLE": "Negligible",
"UNKNOWN": "Unknown", "UNKNOWN": "Unknown",
"NONE": "None" "NONE": "None"
}, },

View File

@ -464,12 +464,13 @@
}, },
"CHART": { "CHART": {
"SCANNING_TIME": "Scan completed", "SCANNING_TIME": "Scan completed",
"TOOLTIPS_TITLE": "This tag has {{totalVulnerability}} vulnerabilities across {{totalPackages}} packages." "TOOLTIPS_TITLE": "This tag has {{totalVulnerability}} packages with vulnerabilities across all {{totalPackages}} packages."
}, },
"SEVERITY": { "SEVERITY": {
"HIGH": "High level", "HIGH": "High level",
"MEDIUM": "Medium level", "MEDIUM": "Medium level",
"LOW": "Low level", "LOW": "Low level",
"NEGLIGIBLE": "Negligible",
"UNKNOWN": "Unknown", "UNKNOWN": "Unknown",
"NONE": "None" "NONE": "None"
}, },

View File

@ -465,12 +465,13 @@
}, },
"CHART": { "CHART": {
"SCANNING_TIME": "扫描完成", "SCANNING_TIME": "扫描完成",
"TOOLTIPS_TITLE": "在此镜像的{{totalPackages}}包中扫描出{{totalVulnerability}}缺陷。" "TOOLTIPS_TITLE": "在此镜像的{{totalPackages}}包中扫描出{{totalVulnerability}}个有缺陷的包。"
}, },
"SEVERITY": { "SEVERITY": {
"HIGH": "严重", "HIGH": "严重",
"MEDIUM": "中等", "MEDIUM": "中等",
"LOW": "一般", "LOW": "一般",
"NEGLIGIBLE": "可忽略",
"UNKNOWN": "未知", "UNKNOWN": "未知",
"NONE": "无" "NONE": "无"
}, },