From 97a9052050f301bf1ec2728b1c26dfb070c1f175 Mon Sep 17 00:00:00 2001 From: Steven Zou Date: Mon, 24 Jul 2017 13:39:49 +0800 Subject: [PATCH] Enhance scanning status controlling --- .../config/registry-config.component.html.ts | 2 +- .../config/registry-config.component.spec.ts | 5 +- .../src/config/registry-config.component.ts | 26 +++--- ...vulnerability-config.component.template.ts | 7 +- .../vulnerability-config.component.ts | 93 ++++++++++++++----- .../create-edit-rule.component.spec.ts | 10 +- src/ui_ng/lib/src/harbor-library.module.ts | 14 ++- .../job-log-viewer.component.spec.ts | 12 +-- .../job-log-viewer.component.template.ts | 2 +- .../job-log-viewer.component.ts | 30 +++++- .../replication/replication.component.spec.ts | 4 +- .../repository-stackview.component.spec.ts | 4 +- src/ui_ng/lib/src/service.config.ts | 8 ++ src/ui_ng/lib/src/service/index.ts | 3 +- src/ui_ng/lib/src/service/interface.ts | 1 + .../lib/src/service/job-log.service.spec.ts | 39 ++++++++ src/ui_ng/lib/src/service/job-log.service.ts | 84 +++++++++++++++++ src/ui_ng/lib/src/tag/tag.component.css.ts | 1 - src/ui_ng/lib/src/tag/tag.component.spec.ts | 5 +- .../result-bar-chart.component.spec.ts | 11 ++- .../result-bar-chart.component.ts | 14 ++- .../vulnerability-scanning/scanning.css.ts | 1 + .../vulnerability-scanning/scanning.html.ts | 7 +- src/ui_ng/package.json | 2 +- src/ui_ng/src/app/app-config.ts | 2 + .../src/app/config/config.component.html | 2 +- src/ui_ng/src/app/config/config.component.ts | 4 - .../tag-repository.component.html | 2 +- .../tag-repository.component.ts | 16 +++- src/ui_ng/src/i18n/lang/en-us-lang.json | 8 +- src/ui_ng/src/i18n/lang/es-es-lang.json | 8 +- src/ui_ng/src/i18n/lang/zh-cn-lang.json | 8 +- 32 files changed, 345 insertions(+), 90 deletions(-) create mode 100644 src/ui_ng/lib/src/service/job-log.service.spec.ts create mode 100644 src/ui_ng/lib/src/service/job-log.service.ts diff --git a/src/ui_ng/lib/src/config/registry-config.component.html.ts b/src/ui_ng/lib/src/config/registry-config.component.html.ts index b2cdcceccf..a647ca0bb5 100644 --- a/src/ui_ng/lib/src/config/registry-config.component.html.ts +++ b/src/ui_ng/lib/src/config/registry-config.component.html.ts @@ -2,7 +2,7 @@ export const REGISTRY_CONFIG_HTML: string = `
- +
diff --git a/src/ui_ng/lib/src/config/registry-config.component.spec.ts b/src/ui_ng/lib/src/config/registry-config.component.spec.ts index c290411304..41e9fda507 100644 --- a/src/ui_ng/lib/src/config/registry-config.component.spec.ts +++ b/src/ui_ng/lib/src/config/registry-config.component.spec.ts @@ -52,7 +52,8 @@ describe('RegistryConfigComponent (inline template)', () => { "project_creation_restriction": "everyone", "self_registration": true, "has_ca_root": true, - "harbor_version": "v1.1.1-rc1-160-g565110d" + "harbor_version": "v1.1.1-rc1-160-g565110d", + "next_scan_all": 0 }; beforeEach(async(() => { @@ -85,7 +86,7 @@ describe('RegistryConfigComponent (inline template)', () => { systemInfoService = fixture.debugElement.injector.get(SystemInfoService); spy = spyOn(cfgService, 'getConfigurations').and.returnValue(Promise.resolve(mockConfig)); saveSpy = spyOn(cfgService, 'saveConfigurations').and.returnValue(Promise.resolve(true)); - spySystemInfo = spyOn(systemInfoService, 'getSystemInfo').and.returnValues(Promise.resolve(mockSystemInfo)); + spySystemInfo = spyOn(systemInfoService, 'getSystemInfo').and.returnValue(Promise.resolve(mockSystemInfo)); fixture.detectChanges(); }); diff --git a/src/ui_ng/lib/src/config/registry-config.component.ts b/src/ui_ng/lib/src/config/registry-config.component.ts index dcfa80c039..d963d7ce4d 100644 --- a/src/ui_ng/lib/src/config/registry-config.component.ts +++ b/src/ui_ng/lib/src/config/registry-config.component.ts @@ -54,17 +54,8 @@ export class RegistryConfigComponent implements OnInit { return this.systemInfo && this.systemInfo.with_clair; } - get clairDB(): ClairDBStatus { - return this.systemInfo && this.systemInfo.clair_vulnerability_status ? - this.systemInfo.clair_vulnerability_status : null; - } - ngOnInit(): void { - //Get system info - toPromise(this.systemInfoService.getSystemInfo()) - .then((info: SystemInfo) => this.systemInfo = info) - .catch(error => this.errorHandler.error(error)); - + this.loadSystemInfo(); //Initialize this.load(); } @@ -82,20 +73,25 @@ export class RegistryConfigComponent implements OnInit { return !this._isEmptyObject(this.getChanges()); } + //Get system info + loadSystemInfo(): void { + toPromise(this.systemInfoService.getSystemInfo()) + .then((info: SystemInfo) => this.systemInfo = info) + .catch(error => this.errorHandler.error(error)); + } + //Load configurations load(): void { this.onGoing = true; toPromise(this.configService.getConfigurations()) .then((config: Configuration) => { - this.onGoing = false; - this.configCopy = this._clone(config); this.config = config; + this.onGoing = false; }) .catch(error => { - this.onGoing = false; - this.errorHandler.error(error); + this.onGoing = false; }); } @@ -118,6 +114,8 @@ export class RegistryConfigComponent implements OnInit { }); //Reload to fetch all the updates this.load(); + //Reload all system info + //this.loadSystemInfo(); }) .catch(error => { this.onGoing = false; diff --git a/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.template.ts b/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.template.ts index d6f7506470..566a6c581e 100644 --- a/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.template.ts +++ b/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.template.ts @@ -12,13 +12,13 @@ export const VULNERABILITY_CONFIG_HTML: string = ` @@ -38,7 +38,8 @@ export const VULNERABILITY_CONFIG_HTML: string = `
- + + {{ 'CONFIG.SCANNING.NEXT_SCAN' | translate }} {{ nextScanTimestamp | date:'HH:mm' }}
diff --git a/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts b/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts index 6d30ca18a7..625bffff41 100644 --- a/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts +++ b/src/ui_ng/lib/src/config/vulnerability/vulnerability-config.component.ts @@ -1,9 +1,13 @@ -import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core'; +import { Component, Input, Output, EventEmitter, ViewChild, OnInit } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Configuration } from '../config'; import { VULNERABILITY_CONFIG_HTML, VULNERABILITY_CONFIG_STYLES } from './vulnerability-config.component.template'; -import { ScanningResultService } from '../../service/scanning.service'; +import { + ScanningResultService, + SystemInfo, + SystemInfoService +} from '../../service/index'; import { ErrorHandler } from '../../error-handler'; import { toPromise } from '../../utils'; import { TranslateService } from '@ngx-translate/core'; @@ -19,9 +23,10 @@ const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS; template: VULNERABILITY_CONFIG_HTML, styles: [VULNERABILITY_CONFIG_STYLES, REGISTRY_CONFIG_STYLES] }) -export class VulnerabilityConfigComponent { +export class VulnerabilityConfigComponent implements OnInit { _localTime: Date = new Date(); + onSubmitting: boolean = false; config: Configuration; openState: boolean = false; @Output() configChange: EventEmitter = new EventEmitter(); @@ -46,21 +51,37 @@ export class VulnerabilityConfigComponent { } @Input() showSubTitle: boolean = false; - @Input() clairDBStatus: ClairDBStatus; + systemInfo: SystemInfo; - get updatedTimestamp(): string { - if (this.clairDBStatus && this.clairDBStatus.overall_last_update > 0) { - return this.convertToLocalTime(this.clairDBStatus.overall_last_update*1000); + get scanAvailable(): boolean { + let dt: Date = new Date(); + return !this.onSubmitting && (this.nextScanTime <= 0 || dt.getTime() > ((this.nextScanTime + 30) * 1000)); + } + + get nextScanTimestamp(): Date { + return this.nextScanTime > 0 ? this.convertToLocalTime(this.nextScanTime) : null; + } + + get nextScanTime(): number { + return this.systemInfo && this.systemInfo.next_scan_all ? this.systemInfo.next_scan_all : 0; + } + + get updatedTimestamp(): Date { + if (this.systemInfo && + this.systemInfo.clair_vulnerability_status && + this.systemInfo.clair_vulnerability_status.overall_last_update > 0) { + return this.convertToLocalTime(this.systemInfo.clair_vulnerability_status.overall_last_update); } - return "--"; + return null; } get namespaceTimestamps(): ClairDetail[] { - if (this.clairDBStatus && - this.clairDBStatus.details && - this.clairDBStatus.details.length > 0) { - return this.clairDBStatus.details; + if (this.systemInfo && + this.systemInfo.clair_vulnerability_status && + this.systemInfo.clair_vulnerability_status.details && + this.systemInfo.clair_vulnerability_status.details.length > 0) { + return this.systemInfo.clair_vulnerability_status.details; } return []; @@ -207,31 +228,57 @@ export class VulnerabilityConfigComponent { } get isClairDBFullyReady(): boolean { - return this.clairDBStatus && this.clairDBStatus.overall_last_update > 0; + return this.systemInfo && + this.systemInfo.clair_vulnerability_status && + this.systemInfo.clair_vulnerability_status.overall_last_update > 0; } constructor( private scanningService: ScanningResultService, private errorHandler: ErrorHandler, - private translate: TranslateService) { } + private translate: TranslateService, + private systemInfoService: SystemInfoService + ) { } - convertToLocalTime(utcTime: number): string { - let offset: number = this._localTime.getTimezoneOffset() * 60; - let timeWithLocal: number = utcTime - offset; - let dt = new Date(); - dt.setTime(timeWithLocal); - return dt.toLocaleString(); + ngOnInit(): void { + this.getSystemInfo(); + } + + convertToLocalTime(utcTime: number): Date { + let dt: Date = new Date(); + dt.setTime(utcTime * 1000); + + return dt; } scanNow(): void { + if (this.onSubmitting) { + return;//Aoid duplicated submitting + } + + this.onSubmitting = true; toPromise(this.scanningService.startScanningAll()) .then(() => { this.translate.get("CONFIG.SCANNING.TRIGGER_SCAN_ALL_SUCCESS").subscribe((res: string) => { this.errorHandler.info(res); }); - //TODO: - //Change button disable status. + + //Update system info + this.getSystemInfo().then(() => { + this.onSubmitting = false; + }).catch(() => { + this.onSubmitting = false; + }); }) - .catch(error => this.errorHandler.error(error)) + .catch(error => { + this.errorHandler.error(error); + this.onSubmitting = false; + }); + } + + getSystemInfo(): Promise { + return toPromise(this.systemInfoService.getSystemInfo()) + .then((info: SystemInfo) => this.systemInfo = info) + .catch(error => this.errorHandler.error(error)); } } \ No newline at end of file diff --git a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts index 0c88b2f175..58d3f66a5f 100644 --- a/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts +++ b/src/ui_ng/lib/src/create-edit-rule/create-edit-rule.component.spec.ts @@ -18,7 +18,12 @@ import { ReplicationRule, ReplicationJob, Endpoint } from '../service/interface' import { ErrorHandler } from '../error-handler/error-handler'; import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; -import { ReplicationService, ReplicationDefaultService } from '../service/replication.service'; +import { + ReplicationService, + ReplicationDefaultService, + JobLogService, + JobLogDefaultService + } from '../service/index'; import { EndpointService, EndpointDefaultService } from '../service/endpoint.service'; import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component'; @@ -183,7 +188,8 @@ describe('CreateEditRuleComponent (inline template)', ()=>{ ErrorHandler, { provide: SERVICE_CONFIG, useValue: config }, { provide: ReplicationService, useClass: ReplicationDefaultService }, - { provide: EndpointService, useClass: EndpointDefaultService } + { provide: EndpointService, useClass: EndpointDefaultService }, + { provide: JobLogService, useClass: JobLogDefaultService } ] }); })); diff --git a/src/ui_ng/lib/src/harbor-library.module.ts b/src/ui_ng/lib/src/harbor-library.module.ts index 1af8b4a9f9..4b08acc0f8 100644 --- a/src/ui_ng/lib/src/harbor-library.module.ts +++ b/src/ui_ng/lib/src/harbor-library.module.ts @@ -41,7 +41,9 @@ import { ScanningResultService, ScanningResultDefaultService, ConfigurationService, - ConfigurationDefaultService + ConfigurationDefaultService, + JobLogService, + JobLogDefaultService } from './service/index'; import { ErrorHandler, @@ -74,7 +76,8 @@ export const DefaultServiceConfig: IServiceConfig = { langMessagePathForHttpLoader: "i18n/langs/", langMessageFileSuffixForHttpLoader: "-lang.json", localI18nMessageVariableMap: {}, - configurationEndpoint: "/api/configurations" + configurationEndpoint: "/api/configurations", + scanJobEndpoint: "/api/jobs/scan" }; /** @@ -112,7 +115,10 @@ export interface HarborModuleConfig { scanningService?: Provider, //Service implementation for configuration - configService?: Provider + configService?: Provider, + + //Service implementation for job log + jobLogService?: Provider } /** @@ -197,6 +203,7 @@ export class HarborLibraryModule { config.tagService || { provide: TagService, useClass: TagDefaultService }, config.scanningService || { provide: ScanningResultService, useClass: ScanningResultDefaultService }, config.configService || { provide: ConfigurationService, useClass: ConfigurationDefaultService }, + config.jobLogService || { provide: JobLogService, useClass: JobLogDefaultService }, //Do initializing TranslateServiceInitializer, { @@ -224,6 +231,7 @@ export class HarborLibraryModule { config.tagService || { provide: TagService, useClass: TagDefaultService }, config.scanningService || { provide: ScanningResultService, useClass: ScanningResultDefaultService }, config.configService || { provide: ConfigurationService, useClass: ConfigurationDefaultService }, + config.jobLogService || { provide: JobLogService, useClass: JobLogDefaultService }, ChannelService ] }; diff --git a/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.spec.ts b/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.spec.ts index 02defb2d5e..2780bbc9ae 100644 --- a/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.spec.ts +++ b/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.spec.ts @@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { DebugElement } from '@angular/core'; import { Observable } from 'rxjs/Observable'; -import { ReplicationService, ReplicationDefaultService } from '../service/index'; +import { JobLogService, JobLogDefaultService } from '../service/index'; import { JobLogViewerComponent } from './job-log-viewer.component'; import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; @@ -13,7 +13,7 @@ describe('JobLogViewerComponent (inline template)', () => { let component: JobLogViewerComponent; let fixture: ComponentFixture; let serviceConfig: IServiceConfig; - let replicationService: ReplicationService; + let jobLogService: JobLogDefaultService; let spy: jasmine.Spy; let testConfig: IServiceConfig = { replicationJobEndpoint: "/api/jobs/replication/testing" @@ -29,7 +29,7 @@ describe('JobLogViewerComponent (inline template)', () => { providers: [ ErrorHandler, { provide: SERVICE_CONFIG, useValue: testConfig }, - { provide: ReplicationService, useClass: ReplicationDefaultService } + { provide: JobLogService, useClass: JobLogDefaultService } ] }); })); @@ -39,9 +39,9 @@ describe('JobLogViewerComponent (inline template)', () => { component = fixture.componentInstance; serviceConfig = TestBed.get(SERVICE_CONFIG); - replicationService = fixture.debugElement.injector.get(ReplicationService); - spy = spyOn(replicationService, 'getJobLog') - .and.returnValues(Promise.resolve("job log text")); + jobLogService = fixture.debugElement.injector.get(JobLogService); + spy = spyOn(jobLogService, 'getJobLog') + .and.returnValue(Promise.resolve("job log text")); fixture.detectChanges(); }); diff --git a/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.template.ts b/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.template.ts index 5b4624edb4..567ee1a94d 100644 --- a/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.template.ts +++ b/src/ui_ng/lib/src/job-log-viewer/job-log-viewer.component.template.ts @@ -1,6 +1,6 @@ export const JOB_LOG_VIEWER_TEMPLATE: string = ` - + `; \ No newline at end of file diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 0dab15a1b0..d64f0a6f06 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.9.8", "clarity-ui": "^0.9.8", "core-js": "^2.4.1", - "harbor-ui": "0.3.24", + "harbor-ui": "0.3.42", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/app-config.ts b/src/ui_ng/src/app/app-config.ts index ce5ac5167f..0702cba128 100644 --- a/src/ui_ng/src/app/app-config.ts +++ b/src/ui_ng/src/app/app-config.ts @@ -30,6 +30,7 @@ export class AppConfig { overall_last_update: 0, details: [] }; + this.next_scan_all = 0; } with_notary: boolean; @@ -43,4 +44,5 @@ export class AppConfig { has_ca_root: boolean; harbor_version: string; clair_vulnerability_status?: ClairDBStatus; + next_scan_all: number; } \ No newline at end of file diff --git a/src/ui_ng/src/app/config/config.component.html b/src/ui_ng/src/app/config/config.component.html index 8895e863dc..cdc9f58c41 100644 --- a/src/ui_ng/src/app/config/config.component.html +++ b/src/ui_ng/src/app/config/config.component.html @@ -32,7 +32,7 @@
- +
diff --git a/src/ui_ng/src/app/config/config.component.ts b/src/ui_ng/src/app/config/config.component.ts index d1c8dcd6bc..85cff6aaec 100644 --- a/src/ui_ng/src/app/config/config.component.ts +++ b/src/ui_ng/src/app/config/config.component.ts @@ -85,10 +85,6 @@ export class ConfigurationComponent implements OnInit, OnDestroy { return this.appConfigService.getConfig().with_clair; } - public get clairDB(): ClairDBStatus { - return this.appConfigService.getConfig().clair_vulnerability_status; - } - isCurrentTabLink(tabId: string): boolean { return this.currentTabId === tabId; } diff --git a/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.html b/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.html index 0ef68de509..3305a4db74 100644 --- a/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.html +++ b/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.html @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts b/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts index c2d4b1eeab..4286bf6de2 100644 --- a/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts +++ b/src/ui_ng/src/app/repository/tag-repository/tag-repository.component.ts @@ -29,8 +29,6 @@ export class TagRepositoryComponent implements OnInit { repoName: string; hasProjectAdminRole: boolean = false; registryUrl: string; - withNotary: boolean; - hasSignedIn: boolean; constructor( private route: ActivatedRoute, @@ -40,7 +38,6 @@ export class TagRepositoryComponent implements OnInit { } ngOnInit() { - this.hasSignedIn = (this.session.getCurrentUser() !== null); let resolverData = this.route.snapshot.data; if (resolverData) { this.hasProjectAdminRole = (resolverData['projectResolver']).has_project_admin_role; @@ -49,7 +46,18 @@ export class TagRepositoryComponent implements OnInit { this.repoName = this.route.snapshot.params['repo']; this.registryUrl = this.appConfigService.getConfig().registry_url; - this.withNotary = this.appConfigService.getConfig().with_notary; + } + + get withNotary(): boolean { + return this.appConfigService.getConfig().with_notary; + } + + get withClair(): boolean { + return this.appConfigService.getConfig().with_clair; + } + + get hasSignedIn(): boolean { + return this.session.getCurrentUser() !== null; } watchTagClickEvt(tagEvt: TagClickEvent): void { diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json index 6745c5e56b..23f8c30951 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -416,7 +416,8 @@ "DAILY_POLICY": "Daily At", "REFRESH_POLICY": "Upon Refresh", "DB_REFRESH_TIME": "Database updated on", - "DB_NOT_READY": "Vulnerability database might not be fully ready!" + "DB_NOT_READY": "Vulnerability database might not be fully ready!", + "NEXT_SCAN": "Available after" }, "TEST_MAIL_SUCCESS": "Connection to mail server is verified.", "TEST_LDAP_SUCCESS": "Connection to LDAP server is verified.", @@ -464,7 +465,7 @@ "STATE": { "STOPPED": "Not Scanned", "QUEUED": "Queued", - "ERROR": "Error", + "ERROR": "View Log", "SCANNING": "Scanning", "UNKNOWN": "Unknown" }, @@ -496,7 +497,8 @@ "PLACEHOLDER": "Filter Vulnerabilities", "PACKAGE": "Package with", "PACKAGES": "Packages with", - "SCAN_NOW": "Scan" + "SCAN_NOW": "Scan", + "JOB_LOG_VIEWER": "View Scanning Job Log" }, "PUSH_IMAGE": { "TITLE": "Push Image", diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json index 84e423c4bf..9be60dcbb7 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -417,7 +417,8 @@ "DAILY_POLICY": "Daily At", "REFRESH_POLICY": "Upon Refresh", "DB_REFRESH_TIME": "Database updated on", - "DB_NOT_READY": "Vulnerability database might not be fully ready!" + "DB_NOT_READY": "Vulnerability database might not be fully ready!", + "NEXT_SCAN": "Available after" }, "TEST_MAIL_SUCCESS": "La conexión al servidor de correo ha sido verificada.", "TEST_LDAP_SUCCESS": "La conexión al servidor LDAP ha sido verificada.", @@ -463,7 +464,7 @@ "STATE": { "STOPPED": "Not Scanned", "QUEUED": "Queued", - "ERROR": "Error", + "ERROR": "View Log", "SCANNING": "Scanning", "UNKNOWN": "Unknown" }, @@ -495,7 +496,8 @@ "PLACEHOLDER": "Filter Vulnerabilities", "PACKAGE": "Package with", "PACKAGES": "Packages with", - "SCAN_NOW": "Scan" + "SCAN_NOW": "Scan", + "JOB_LOG_VIEWER": "View Scanning Job Log" }, "PUSH_IMAGE": { "TITLE": "Push Image", diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json index e7a33e58be..e979c19b6b 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -420,7 +420,8 @@ "DAILY_POLICY": "每日定时", "REFRESH_POLICY": "缺陷库刷新后", "DB_REFRESH_TIME": "数据库更新于", - "DB_NOT_READY": "缺陷数据库可能没有完全准备好!" + "DB_NOT_READY": "缺陷数据库可能没有完全准备好!", + "NEXT_SCAN": "下次可用时间" }, "TEST_MAIL_SUCCESS": "邮件服务器的连通正常。", "TEST_LDAP_SUCCESS": "LDAP服务器的连通正常。", @@ -468,7 +469,7 @@ "STATE": { "STOPPED": "未扫描", "QUEUED": "已入队列", - "ERROR": "错误", + "ERROR": "查看日志", "SCANNING": "扫描中", "UNKNOWN": "未知" }, @@ -500,7 +501,8 @@ "PLACEHOLDER": "过滤缺陷", "PACKAGE": "个组件有", "PACKAGES": "个组件有", - "SCAN_NOW": "扫描" + "SCAN_NOW": "扫描", + "JOB_LOG_VIEWER": "查看扫描日志" }, "PUSH_IMAGE": { "TITLE": "推送镜像",