From baa863d02621b94fca406fbd6b38b005db6c4f52 Mon Sep 17 00:00:00 2001 From: Steven Zou Date: Thu, 3 Aug 2017 15:09:13 +0800 Subject: [PATCH] Fix issue #2879 (#2953) * Change vul result bar texts * Support server-driven pagination for replication jobs --- .../create-edit-rule.component.spec.ts | 11 +- .../replication/replication.component.html.ts | 9 +- .../replication/replication.component.spec.ts | 11 +- .../src/replication/replication.component.ts | 116 +++++++++++++++--- src/ui_ng/lib/src/service/interface.ts | 14 ++- .../lib/src/service/replication.service.ts | 36 ++++-- .../lib/src/service/repository.service.ts | 6 + .../result-tip.component.ts | 25 ++-- src/ui_ng/package.json | 2 +- .../src/app/log/audit-log.component.html | 5 +- src/ui_ng/src/app/log/audit-log.component.ts | 82 +++++++------ src/ui_ng/src/i18n/lang/en-us-lang.json | 5 +- src/ui_ng/src/i18n/lang/es-es-lang.json | 5 +- src/ui_ng/src/i18n/lang/zh-cn-lang.json | 5 +- 14 files changed, 232 insertions(+), 100 deletions(-) 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 58d3f66a5..c311615fc 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 @@ -14,7 +14,7 @@ import { DatePickerComponent } from '../datetime-picker/datetime-picker.componen import { DateValidatorDirective } from '../datetime-picker/date-validator.directive'; import { FilterComponent } from '../filter/filter.component'; import { InlineAlertComponent } from '../inline-alert/inline-alert.component'; -import { ReplicationRule, ReplicationJob, Endpoint } from '../service/interface'; +import { ReplicationRule, ReplicationJob, Endpoint, ReplicationJobItem } from '../service/interface'; import { ErrorHandler } from '../error-handler/error-handler'; import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; @@ -71,7 +71,7 @@ describe('CreateEditRuleComponent (inline template)', ()=>{ } ]; - let mockJobs: ReplicationJob[] = [ + let mockJobs: ReplicationJobItem[] = [ { "id": 1, "status": "stopped", @@ -98,6 +98,11 @@ describe('CreateEditRuleComponent (inline template)', ()=>{ } ]; + let mockJob: ReplicationJob = { + metadata: {xTotalCount: 3}, + data: mockJobs + }; + let mockEndpoints: Endpoint[] = [ { "id": 1, @@ -205,7 +210,7 @@ describe('CreateEditRuleComponent (inline template)', ()=>{ spyRules = spyOn(replicationService, 'getReplicationRules').and.returnValues(Promise.resolve(mockRules)); spyOneRule = spyOn(replicationService, 'getReplicationRule').and.returnValue(Promise.resolve(mockRule)); - spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJobs)); + spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJob)); fixture.detectChanges(); }); diff --git a/src/ui_ng/lib/src/replication/replication.component.html.ts b/src/ui_ng/lib/src/replication/replication.component.html.ts index d71f47378..cb374aa27 100644 --- a/src/ui_ng/lib/src/replication/replication.component.html.ts +++ b/src/ui_ng/lib/src/replication/replication.component.html.ts @@ -46,7 +46,7 @@ export const REPLICATION_TEMPLATE: string = `
- + {{'REPLICATION.NAME' | translate}} {{'REPLICATION.STATUS' | translate}} {{'REPLICATION.OPERATION' | translate}} @@ -54,7 +54,7 @@ export const REPLICATION_TEMPLATE: string = ` {{'REPLICATION.UPDATE_TIME' | translate}} {{'REPLICATION.LOGS' | translate}} {{'REPLICATION.JOB_PLACEHOLDER' | translate }} - + {{j.repository}} {{j.status}} {{j.operation}} @@ -66,13 +66,12 @@ export const REPLICATION_TEMPLATE: string = ` - - {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPLICATION.OF' | translate}} + {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPLICATION.OF' | translate}} {{pagination.totalItems}} {{'REPLICATION.ITEMS' | translate}} - +
diff --git a/src/ui_ng/lib/src/replication/replication.component.spec.ts b/src/ui_ng/lib/src/replication/replication.component.spec.ts index 0f9323b60..afc0d5c12 100644 --- a/src/ui_ng/lib/src/replication/replication.component.spec.ts +++ b/src/ui_ng/lib/src/replication/replication.component.spec.ts @@ -19,7 +19,7 @@ import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; import { ReplicationService, ReplicationDefaultService } from '../service/replication.service'; import { EndpointService, EndpointDefaultService } from '../service/endpoint.service'; import { JobLogViewerComponent } from '../job-log-viewer/job-log-viewer.component'; -import { JobLogService, JobLogDefaultService } from '../service/index'; +import { JobLogService, JobLogDefaultService, ReplicationJobItem } from '../service/index'; describe('Replication Component (inline template)', ()=>{ @@ -65,7 +65,7 @@ describe('Replication Component (inline template)', ()=>{ } ]; - let mockJobs: ReplicationJob[] = [ + let mockJobs: ReplicationJobItem[] = [ { "id": 1, "status": "error", @@ -95,6 +95,11 @@ describe('Replication Component (inline template)', ()=>{ } ]; + let mockJob: ReplicationJob = { + metadata: {xTotalCount: 3}, + data: mockJobs + }; + let mockEndpoints: Endpoint[] = [ { "id": 1, @@ -200,7 +205,7 @@ describe('Replication Component (inline template)', ()=>{ replicationService = fixture.debugElement.injector.get(ReplicationService); spyRules = spyOn(replicationService, 'getReplicationRules').and.returnValues(Promise.resolve(mockRules)); - spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJobs)); + spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJob)); fixture.detectChanges(); fixture.whenStable().then(()=>{ diff --git a/src/ui_ng/lib/src/replication/replication.component.ts b/src/ui_ng/lib/src/replication/replication.component.ts index c5768985f..168626672 100644 --- a/src/ui_ng/lib/src/replication/replication.component.ts +++ b/src/ui_ng/lib/src/replication/replication.component.ts @@ -23,9 +23,16 @@ import { ErrorHandler } from '../error-handler/error-handler'; import { ReplicationService } from '../service/replication.service'; import { RequestQueryParams } from '../service/RequestQueryParams'; -import { ReplicationRule, ReplicationJob, Endpoint } from '../service/interface'; +import { ReplicationRule, ReplicationJob, Endpoint, ReplicationJobItem } from '../service/interface'; -import { toPromise, CustomComparator } from '../utils'; +import { + toPromise, + CustomComparator, + DEFAULT_PAGE_SIZE, + doFiltering, + doSorting, + calculatePage +} from '../utils'; import { Comparator } from 'clarity-angular'; @@ -33,6 +40,7 @@ import { REPLICATION_TEMPLATE } from './replication.component.html'; import { REPLICATION_STYLE } from './replication.component.css'; import { JobLogViewerComponent } from '../job-log-viewer/index'; +import { State } from "clarity-angular"; const ruleStatus: { [key: string]: any } = [ { 'key': 'all', 'description': 'REPLICATION.ALL_STATUS' }, @@ -63,7 +71,7 @@ export class SearchOption { endTime: string = ''; endTimestamp: string = ''; page: number = 1; - pageSize: number = 5; + pageSize: number = DEFAULT_PAGE_SIZE; } @Component({ @@ -93,10 +101,7 @@ export class ReplicationComponent implements OnInit { rules: ReplicationRule[]; loading: boolean; - jobs: ReplicationJob[]; - - jobsTotalRecordCount: number; - jobsTotalPage: number; + jobs: ReplicationJobItem[]; toggleJobSearchOption = optionalSearch; currentJobSearchOption: number; @@ -113,6 +118,13 @@ export class ReplicationComponent implements OnInit { creationTimeComparator: Comparator = new CustomComparator('creation_time', 'date'); updateTimeComparator: Comparator = new CustomComparator('update_time', 'date'); + //Server driven pagination + currentPage: number = 1; + totalCount: number = 0; + pageSize: number = DEFAULT_PAGE_SIZE; + currentState: State; + jobsLoading: boolean = false; + constructor( private errorHandler: ErrorHandler, private replicationService: ReplicationService, @@ -123,6 +135,10 @@ export class ReplicationComponent implements OnInit { return !this.readonly && this.projectId ? true : false; } + public get showPaginationIndex(): boolean { + return this.totalCount > 0; + } + ngOnInit() { this.currentRuleStatus = this.ruleStatus[0]; this.currentJobStatus = this.jobStatus[0]; @@ -143,32 +159,78 @@ export class ReplicationComponent implements OnInit { } } - fetchReplicationJobs() { + //Server driven data loading + clrLoadJobs(state: State): void { + if (!state || !state.page || !this.search.ruleId) { + return; + } + this.currentState = state; + + let pageNumber: number = calculatePage(state); + if (pageNumber <= 0) { pageNumber = 1; } let params: RequestQueryParams = new RequestQueryParams(); - params.set('status', this.search.status); - params.set('repository', this.search.repoName); - params.set('start_time', this.search.startTimestamp); - params.set('end_time', this.search.endTimestamp); + //Pagination + params.set("page", '' + pageNumber); + params.set("page_size", '' + this.pageSize); + //Search by status + if (this.search.status.trim()) { + params.set('status', this.search.status); + } + //Search by repository + if (this.search.repoName.trim()) { + params.set('repository', this.search.repoName); + } + //Search by timestamps + if (this.search.startTimestamp.trim()) { + params.set('start_time', this.search.startTimestamp); + } + if (this.search.endTimestamp.trim()) { + params.set('end_time', this.search.endTimestamp); + } - toPromise(this.replicationService + this.jobsLoading = true; + toPromise(this.replicationService .getJobs(this.search.ruleId, params)) .then( response => { - this.jobs = response; + this.totalCount = response.metadata.xTotalCount; + this.jobs = response.data; + + //Do filtering and sorting + this.jobs = doFiltering(this.jobs, state); + this.jobs = doSorting(this.jobs, state); + + this.jobsLoading = false; + }).catch(error => { + this.jobsLoading = false; this.errorHandler.error(error); }); } + loadFirstPage(): void { + let st: State = this.currentState; + if (!st) { + st = { + page: {} + }; + } + st.page.size = this.pageSize; + st.page.from = 0; + st.page.to = this.pageSize - 1; + + this.clrLoadJobs(st); + } + selectOneRule(rule: ReplicationRule) { - if (rule) { + if (rule && rule.id) { this.search.ruleId = rule.id || ''; this.search.repoName = ''; this.search.status = ''; this.currentJobSearchOption = 0; this.currentJobStatus = { 'key': 'all', 'description': 'REPLICATION.ALL' }; - this.fetchReplicationJobs(); + this.loadFirstPage(); } } @@ -205,7 +267,7 @@ export class ReplicationComponent implements OnInit { doSearchJobs(repoName: string) { this.search.repoName = repoName; - this.fetchReplicationJobs(); + this.loadFirstPage(); } reloadRules(isReady: boolean) { @@ -220,7 +282,21 @@ export class ReplicationComponent implements OnInit { } refreshJobs() { - this.fetchReplicationJobs(); + this.search.repoName = ""; + this.search.startTimestamp = ""; + this.search.endTimestamp = ""; + this.search.status = ""; + + this.currentPage = 1; + + let st: State = { + page: { + from: 0, + to: this.pageSize - 1, + size: this.pageSize + } + }; + this.clrLoadJobs(st); } toggleSearchJobOptionalName(option: number) { @@ -229,12 +305,12 @@ export class ReplicationComponent implements OnInit { doJobSearchByStartTime(fromTimestamp: string) { this.search.startTimestamp = fromTimestamp; - this.fetchReplicationJobs(); + this.loadFirstPage(); } doJobSearchByEndTime(toTimestamp: string) { this.search.endTimestamp = toTimestamp; - this.fetchReplicationJobs(); + this.loadFirstPage(); } viewLog(jobId: number | string): void { diff --git a/src/ui_ng/lib/src/service/interface.ts b/src/ui_ng/lib/src/service/interface.ts index 17ecdf1be..b4697d233 100644 --- a/src/ui_ng/lib/src/service/interface.ts +++ b/src/ui_ng/lib/src/service/interface.ts @@ -100,7 +100,19 @@ export interface ReplicationRule extends Base { * @export * @interface ReplicationJob */ -export interface ReplicationJob extends Base { +export interface ReplicationJob { + metadata?: Metadata; + data: ReplicationJobItem[]; +} + +/** + * Interface for replication job item. + * + * @export + * @interface ReplicationJob + */ +export interface ReplicationJobItem extends Base { + [key: string]: any | any[] status: string; repository: string; policy_id: number; diff --git a/src/ui_ng/lib/src/service/replication.service.ts b/src/ui_ng/lib/src/service/replication.service.ts index f631b56ea..791340cdd 100644 --- a/src/ui_ng/lib/src/service/replication.service.ts +++ b/src/ui_ng/lib/src/service/replication.service.ts @@ -1,6 +1,6 @@ import { Observable } from 'rxjs/Observable'; import { RequestQueryParams } from './RequestQueryParams'; -import { ReplicationJob, ReplicationRule } from './interface'; +import { ReplicationJob, ReplicationRule, ReplicationJobItem } from './interface'; import { Injectable, Inject } from "@angular/core"; import 'rxjs/add/observable/of'; import { Http, RequestOptions } from '@angular/http'; @@ -109,11 +109,11 @@ export abstract class ReplicationService { * @abstract * @param {(number | string)} ruleId * @param {RequestQueryParams} [queryParams] - * @returns {(Observable | Promise | ReplicationJob)} + * @returns {(Observable | Promise | ReplicationJob)} * * @memberOf ReplicationService */ - abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationJob[]; + abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationJob; /** * Get the log of the specified job. @@ -238,7 +238,7 @@ export class ReplicationDefaultService extends ReplicationService { .catch(error => Promise.reject(error)); } - public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationJob[] { + public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationJob { if (!ruleId || ruleId <= 0) { return Promise.reject('Bad argument'); } @@ -249,7 +249,29 @@ export class ReplicationDefaultService extends ReplicationService { queryParams.set('policy_id', '' + ruleId); return this.http.get(this._jobBaseUrl, buildHttpRequestOptions(queryParams)).toPromise() - .then(response => response.json() as ReplicationJob[]) + .then(response => { + let result: ReplicationJob = { + metadata: { + xTotalCount: 0 + }, + data: [] + }; + + if (response && response.headers) { + let xHeader: string = response.headers.get("X-Total-Count"); + if (xHeader) { + result.metadata.xTotalCount = parseInt(xHeader, 0); + } + } + result.data = response.json() as ReplicationJobItem[]; + if (result.metadata.xTotalCount === 0) { + if (result.data && result.data.length > 0) { + result.metadata.xTotalCount = result.data.length; + } + } + + return result; + }) .catch(error => Promise.reject(error)); } @@ -260,7 +282,7 @@ export class ReplicationDefaultService extends ReplicationService { let logUrl: string = `${this._jobBaseUrl}/${jobId}/log`; return this.http.get(logUrl).toPromise() - .then(response => response.text()) - .catch(error => Promise.reject(error)); + .then(response => response.text()) + .catch(error => Promise.reject(error)); } } \ No newline at end of file diff --git a/src/ui_ng/lib/src/service/repository.service.ts b/src/ui_ng/lib/src/service/repository.service.ts index 0921c14c4..f64df9cf2 100644 --- a/src/ui_ng/lib/src/service/repository.service.ts +++ b/src/ui_ng/lib/src/service/repository.service.ts @@ -92,6 +92,12 @@ export class RepositoryDefaultService extends RepositoryService { result.data = response.json() as RepositoryItem[]; + if (result.metadata.xTotalCount === 0) { + if (result.data && result.data.length > 0) { + result.metadata.xTotalCount = result.data.length; + } + } + return result; }) .catch(error => Promise.reject(error)); diff --git a/src/ui_ng/lib/src/vulnerability-scanning/result-tip.component.ts b/src/ui_ng/lib/src/vulnerability-scanning/result-tip.component.ts index 570fe9b12..40d51a424 100644 --- a/src/ui_ng/lib/src/vulnerability-scanning/result-tip.component.ts +++ b/src/ui_ng/lib/src/vulnerability-scanning/result-tip.component.ts @@ -67,18 +67,19 @@ export class ResultTipComponent implements OnInit { }); } this.translate.get(this.packageText(this.totalPackages)).subscribe((p1: string) => { - this.translate.get(this.packageText(this.packagesWithVul)).subscribe((p2: string) => { - this.translate.get(this.unitText(this.packagesWithVul)).subscribe((vul: string) => { - this.translate.get('VULNERABILITY.CHART.TOOLTIPS_TITLE', - { - totalVulnerability: this.packagesWithVul, - totalPackages: this.totalPackages, - package: p1, - packageExt: p2, - vulnerability: vul - }) - .subscribe((res: string) => this._tipTitle = res); - }); + this.translate.get(this.unitText(this.packagesWithVul)).subscribe((vul: string) => { + let messageKey: string = "VULNERABILITY.CHART.TOOLTIPS_TITLE"; + if (this.packagesWithVul > 1) { + messageKey = "VULNERABILITY.CHART.TOOLTIPS_TITLE_SINGULAR"; + } + this.translate.get(messageKey, + { + totalVulnerability: this.packagesWithVul, + totalPackages: this.totalPackages, + package: p1, + vulnerability: vul + }) + .subscribe((res: string) => this._tipTitle = res); }); }); } diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 520987a56..debffadeb 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.66", + "harbor-ui": "0.3.91", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/log/audit-log.component.html b/src/ui_ng/src/app/log/audit-log.component.html index b51bd9dc6..2d8d70e76 100644 --- a/src/ui_ng/src/app/log/audit-log.component.html +++ b/src/ui_ng/src/app/log/audit-log.component.html @@ -56,9 +56,8 @@ {{l.op_time | date: 'short'}} - {{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'AUDIT_LOG.OF' | translate}} - {{pagination.totalItems }} {{'AUDIT_LOG.ITEMS' | translate}} - + {{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'AUDIT_LOG.OF' | translate}} {{pagination.totalItems }} {{'AUDIT_LOG.ITEMS' | translate}} + diff --git a/src/ui_ng/src/app/log/audit-log.component.ts b/src/ui_ng/src/app/log/audit-log.component.ts index 32159858c..1f4951dd8 100644 --- a/src/ui_ng/src/app/log/audit-log.component.ts +++ b/src/ui_ng/src/app/log/audit-log.component.ts @@ -25,7 +25,7 @@ import { AlertType } from '../shared/shared.const'; import { State } from 'clarity-angular'; -const optionalSearch: {} = {0: 'AUDIT_LOG.ADVANCED', 1: 'AUDIT_LOG.SIMPLE'}; +const optionalSearch: {} = { 0: 'AUDIT_LOG.ADVANCED', 1: 'AUDIT_LOG.SIMPLE' }; class FilterOption { key: string; @@ -46,7 +46,7 @@ class FilterOption { @Component({ selector: 'audit-log', templateUrl: './audit-log.component.html', - styleUrls: [ './audit-log.component.css' ] + styleUrls: ['./audit-log.component.css'] }) export class AuditLogComponent implements OnInit { @@ -54,24 +54,24 @@ export class AuditLogComponent implements OnInit { projectId: number; queryParam: AuditLog = new AuditLog(); auditLogs: AuditLog[]; - + toggleName = optionalSearch; currentOption: number = 0; - filterOptions: FilterOption[] = [ + filterOptions: FilterOption[] = [ new FilterOption('all', 'AUDIT_LOG.ALL_OPERATIONS', true), new FilterOption('pull', 'AUDIT_LOG.PULL', true), new FilterOption('push', 'AUDIT_LOG.PUSH', true), new FilterOption('create', 'AUDIT_LOG.CREATE', true), new FilterOption('delete', 'AUDIT_LOG.DELETE', true), - new FilterOption('others', 'AUDIT_LOG.OTHERS', true) - ]; + new FilterOption('others', 'AUDIT_LOG.OTHERS', true) + ]; pageOffset: number = 1; pageSize: number = 15; - totalRecordCount: number; + totalRecordCount: number = 0; currentPage: number; totalPage: number; - + @ViewChild('fromTime') fromTimeInput: NgModel; @ViewChild('toTime') toTimeInput: NgModel; @@ -83,35 +83,39 @@ export class AuditLogComponent implements OnInit { return this.toTimeInput.errors && this.toTimeInput.errors.dateValidator && (this.toTimeInput.dirty || this.toTimeInput.touched); } + get showPaginationIndex(): boolean { + return this.totalRecordCount > 0; + } + constructor(private route: ActivatedRoute, private router: Router, private auditLogService: AuditLogService, private messageHandlerService: MessageHandlerService) { //Get current user from registered resolver. - this.route.data.subscribe(data=>this.currentUser = data['auditLogResolver']); + this.route.data.subscribe(data => this.currentUser = data['auditLogResolver']); } ngOnInit(): void { this.projectId = +this.route.snapshot.parent.params['id']; this.queryParam.project_id = this.projectId; this.queryParam.page_size = this.pageSize; - + } retrieve(state?: State): void { - if(state) { + if (state) { this.queryParam.page = Math.ceil((state.page.to + 1) / this.pageSize); this.currentPage = this.queryParam.page; } this.auditLogService - .listAuditLogs(this.queryParam) - .subscribe( - response=>{ - this.totalRecordCount =parseInt(response.headers.get('x-total-count')); - this.auditLogs = response.json(); - }, - error=>{ - this.router.navigate(['/harbor', 'projects']); - this.messageHandlerService.handleError(error); - } - ); + .listAuditLogs(this.queryParam) + .subscribe( + response => { + this.totalRecordCount = parseInt(response.headers.get('x-total-count')); + this.auditLogs = response.json(); + }, + error => { + this.router.navigate(['/harbor', 'projects']); + this.messageHandlerService.handleError(error); + } + ); } doSearchAuditLogs(searchUsername: string): void { @@ -120,16 +124,16 @@ export class AuditLogComponent implements OnInit { } convertDate(strDate: string): string { - if(/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) { + if (/^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/.test(strDate)) { let parts = strDate.split(/[-\/]/); - strDate = parts[2] /*Year*/ + '-' +parts[1] /*Month*/ + '-' + parts[0] /*Date*/; + strDate = parts[2] /*Year*/ + '-' + parts[1] /*Month*/ + '-' + parts[0] /*Date*/; } return strDate; } doSearchByStartTime(strDate: string): void { this.queryParam.begin_timestamp = 0; - if(this.fromTimeInput.valid && strDate){ + if (this.fromTimeInput.valid && strDate) { strDate = this.convertDate(strDate); this.queryParam.begin_timestamp = new Date(strDate).getTime() / 1000; } @@ -138,7 +142,7 @@ export class AuditLogComponent implements OnInit { doSearchByEndTime(strDate: string): void { this.queryParam.end_timestamp = 0; - if(this.toTimeInput.valid && strDate) { + if (this.toTimeInput.valid && strDate) { strDate = this.convertDate(strDate); let oneDayOffset = 3600 * 24; this.queryParam.end_timestamp = new Date(strDate).getTime() / 1000 + oneDayOffset; @@ -149,19 +153,19 @@ export class AuditLogComponent implements OnInit { doSearchByOptions() { let selectAll = true; let operationFilter: string[] = []; - for(var i in this.filterOptions) { + for (var i in this.filterOptions) { let filterOption = this.filterOptions[i]; - if(filterOption.checked) { + if (filterOption.checked) { operationFilter.push('operation=' + this.filterOptions[i].key); - }else{ + } else { selectAll = false; } } - if(selectAll) { + if (selectAll) { operationFilter = []; } this.queryParam.keywords = operationFilter.join('&'); - this.retrieve(); + this.retrieve(); } toggleOptionalName(option: number): void { @@ -169,21 +173,21 @@ export class AuditLogComponent implements OnInit { } toggleFilterOption(option: string): void { - let selectedOption = this.filterOptions.find(value =>(value.key === option)); + let selectedOption = this.filterOptions.find(value => (value.key === option)); selectedOption.checked = !selectedOption.checked; - if(selectedOption.key === 'all') { - this.filterOptions.filter(value=> value.key !== selectedOption.key).forEach(value => value.checked = selectedOption.checked); + if (selectedOption.key === 'all') { + this.filterOptions.filter(value => value.key !== selectedOption.key).forEach(value => value.checked = selectedOption.checked); } else { - if(!selectedOption.checked) { - this.filterOptions.find(value=>value.key === 'all').checked = false; + if (!selectedOption.checked) { + this.filterOptions.find(value => value.key === 'all').checked = false; } let selectAll = true; - this.filterOptions.filter(value=> value.key !== 'all').forEach(value =>{ - if(!value.checked) { + this.filterOptions.filter(value => value.key !== 'all').forEach(value => { + if (!value.checked) { selectAll = false; } }); - this.filterOptions.find(value=>value.key === 'all').checked = selectAll; + this.filterOptions.find(value => value.key === 'all').checked = selectAll; } this.doSearchByOptions(); } 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 040f8e6b7..c69c2765f 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -487,8 +487,9 @@ "FOOT_OF": "of" }, "CHART": { - "SCANNING_TIME": "Scan completed datetime", - "TOOLTIPS_TITLE": "This image includes {{totalPackages}} {{package}} with {{vulnerability}} in {{totalVulnerability}} of the {{packageExt}}." + "SCANNING_TIME": "Scan completed time:", + "TOOLTIPS_TITLE": "{{totalVulnerability}} of {{totalPackages}} {{package}} have known {{vulnerability}}.", + "TOOLTIPS_TITLE_SINGULAR": "{{totalVulnerability}} of {{totalPackages}} {{package}} has known {{vulnerability}}." }, "SEVERITY": { "HIGH": "high", 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 797aee325..922993bc7 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -486,8 +486,9 @@ "FOOT_OF": "of" }, "CHART": { - "SCANNING_TIME": "Scan completed datetime", - "TOOLTIPS_TITLE": "This image includes {{totalPackages}} {{package}} with {{vulnerability}} in {{totalVulnerability}} of the {{packageExt}}." + "SCANNING_TIME": "Scan completed time:", + "TOOLTIPS_TITLE": "{{totalVulnerability}} of {{totalPackages}} {{package}} have known {{vulnerability}}.", + "TOOLTIPS_TITLE_SINGULAR": "{{totalVulnerability}} of {{totalPackages}} {{package}} has known {{vulnerability}}." }, "SEVERITY": { "HIGH": "high", 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 43c12b8f5..58ff8a20b 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -487,8 +487,9 @@ "FOOT_OF": "总共" }, "CHART": { - "SCANNING_TIME": "扫描完成", - "TOOLTIPS_TITLE": "在此镜像总共包含{{totalPackages}}{{package}},其中{{totalVulnerability}}个{{packageExt}}含有{{vulnerability}}。" + "SCANNING_TIME": "扫描完成时间:", + "TOOLTIPS_TITLE": "{{totalPackages}}个{{package}}中的{{totalVulnerability}}个含有{{vulnerability}}.", + "TOOLTIPS_TITLE_SINGULAR": "{{totalPackages}}个{{package}}中的{{totalVulnerability}}个含有{{vulnerability}}." }, "SEVERITY": { "HIGH": "严重",