mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 17:17:46 +01:00
Update per comments.
This commit is contained in:
parent
227b440956
commit
5d3ed05a09
@ -8,7 +8,7 @@ import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation
|
||||
import { ReplicationComponent } from '../replication/replication.component';
|
||||
|
||||
import { ListReplicationRuleComponent } from '../list-replication-rule/list-replication-rule.component';
|
||||
import { ListReplicationJobComponent } from '../list-replication-job/list-replication-job.component';
|
||||
|
||||
import { CreateEditRuleComponent } from './create-edit-rule.component';
|
||||
import { DatePickerComponent } from '../datetime-picker/datetime-picker.component';
|
||||
import { DateValidatorDirective } from '../datetime-picker/date-validator.directive';
|
||||
@ -88,7 +88,7 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
|
||||
"repository": "library/busybox",
|
||||
"policy_id": 2,
|
||||
"operation": "transfer",
|
||||
"tags": null
|
||||
"tags": null
|
||||
}
|
||||
];
|
||||
|
||||
@ -171,7 +171,6 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
|
||||
declarations: [
|
||||
ReplicationComponent,
|
||||
ListReplicationRuleComponent,
|
||||
ListReplicationJobComponent,
|
||||
CreateEditRuleComponent,
|
||||
ConfirmationDialogComponent,
|
||||
DatePickerComponent,
|
||||
@ -188,26 +187,28 @@ describe('CreateEditRuleComponent (inline template)', ()=>{
|
||||
}));
|
||||
|
||||
beforeEach(()=>{
|
||||
|
||||
fixture = TestBed.createComponent(ReplicationComponent);
|
||||
fixtureCreate = TestBed.createComponent(CreateEditRuleComponent);
|
||||
|
||||
comp = fixture.componentInstance;
|
||||
comp.projectId = 1;
|
||||
comp.search.ruleId = 1;
|
||||
|
||||
compCreate = fixtureCreate.componentInstance;
|
||||
comp.projectId = 1;
|
||||
|
||||
replicationService = fixture.debugElement.injector.get(ReplicationService);
|
||||
endpointService = fixtureCreate.debugElement.injector.get(EndpointService);
|
||||
|
||||
|
||||
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));
|
||||
spyEndpoint = spyOn(endpointService, 'getEndpoints').and.returnValues(Promise.resolve(mockEndpoints));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
beforeEach(()=>{
|
||||
fixtureCreate = TestBed.createComponent(CreateEditRuleComponent);
|
||||
|
||||
compCreate = fixtureCreate.componentInstance;
|
||||
compCreate.projectId = 1;
|
||||
|
||||
endpointService = fixtureCreate.debugElement.injector.get(EndpointService);
|
||||
spyEndpoint = spyOn(endpointService, 'getEndpoints').and.returnValues(Promise.resolve(mockEndpoints));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
|
@ -208,7 +208,7 @@ export class CreateEditRuleComponent implements AfterViewChecked {
|
||||
}).catch(err=>this.errorHandler.error(err));
|
||||
} else {
|
||||
if(!this.projectId) {
|
||||
console.error('Project ID cannot be unset');
|
||||
this.errorHandler.error('Project ID cannot be unset');
|
||||
return;
|
||||
}
|
||||
this.actionType = ActionType.ADD_NEW;
|
||||
@ -378,12 +378,12 @@ export class CreateEditRuleComponent implements AfterViewChecked {
|
||||
for(let key in data) {
|
||||
let current = data[key];
|
||||
let origin: string = comparison[key];
|
||||
if(((this.actionType === ActionType.EDIT && !this.readonly && !current ) || current) && current !== origin) {
|
||||
this.hasChanged = true;
|
||||
if(((self.actionType === ActionType.EDIT && !self.readonly && !current ) || current) && current !== origin) {
|
||||
self.hasChanged = true;
|
||||
break;
|
||||
} else {
|
||||
this.hasChanged = false;
|
||||
this.inlineAlert.close();
|
||||
self.hasChanged = false;
|
||||
self.inlineAlert.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -10,7 +10,6 @@ import { TAG_DIRECTIVES } from './tag/index';
|
||||
import { REPLICATION_DIRECTIVES } from './replication/index';
|
||||
import { CREATE_EDIT_RULE_DIRECTIVES } from './create-edit-rule/index';
|
||||
import { LIST_REPLICATION_RULE_DIRECTIVES } from './list-replication-rule/index';
|
||||
import { LIST_REPLICATION_JOB_DIRECTIVES } from './list-replication-job/index';
|
||||
|
||||
import { CREATE_EDIT_ENDPOINT_DIRECTIVES } from './create-edit-endpoint/index';
|
||||
|
||||
@ -137,7 +136,6 @@ export function initConfig(translateService: TranslateService, config: IServiceC
|
||||
INLINE_ALERT_DIRECTIVES,
|
||||
REPLICATION_DIRECTIVES,
|
||||
LIST_REPLICATION_RULE_DIRECTIVES,
|
||||
LIST_REPLICATION_JOB_DIRECTIVES,
|
||||
CREATE_EDIT_RULE_DIRECTIVES,
|
||||
DATETIME_PICKER_DIRECTIVES
|
||||
],
|
||||
@ -153,7 +151,6 @@ export function initConfig(translateService: TranslateService, config: IServiceC
|
||||
INLINE_ALERT_DIRECTIVES,
|
||||
REPLICATION_DIRECTIVES,
|
||||
LIST_REPLICATION_RULE_DIRECTIVES,
|
||||
LIST_REPLICATION_JOB_DIRECTIVES,
|
||||
CREATE_EDIT_RULE_DIRECTIVES,
|
||||
DATETIME_PICKER_DIRECTIVES
|
||||
],
|
||||
|
@ -253,6 +253,7 @@ export const EN_US_LANG: any = {
|
||||
"CREATION_TIME": "Start Time",
|
||||
"END_TIME": "End Time",
|
||||
"LOGS": "Logs",
|
||||
"OF": "of",
|
||||
"ITEMS": "item(s)",
|
||||
"TOGGLE_ENABLE_TITLE": "Enable Rule",
|
||||
"CONFIRM_TOGGLE_ENABLE_POLICY": "After enabling the replication rule, all repositories under the project will be replicated to the destination registry. \nPlease confirm to continue.",
|
||||
|
@ -253,6 +253,7 @@ export const ZH_CN_LANG: any = {
|
||||
"CREATION_TIME": "创建时间",
|
||||
"END_TIME": "结束时间",
|
||||
"LOGS": "日志",
|
||||
"OF": "共计",
|
||||
"ITEMS": "条记录",
|
||||
"TOGGLE_ENABLE_TITLE": "启用规则",
|
||||
"CONFIRM_TOGGLE_ENABLE_POLICY": "启用规则后,该项目下的所有镜像仓库将复制到目标实例。\n请确认继续。",
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { Type } from '@angular/core';
|
||||
import { ListReplicationJobComponent } from './list-replication-job.component';
|
||||
|
||||
export const LIST_REPLICATION_JOB_DIRECTIVES: Type<any>[] = [
|
||||
ListReplicationJobComponent
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
export const REPLICATION_JOB_TEMPLATE: string = `
|
||||
<clr-datagrid (clrDgRefresh)="refresh($event)">
|
||||
<clr-dg-column>{{'REPLICATION.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.STATUS' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.OPERATION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.END_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.LOGS' | translate}}</clr-dg-column>
|
||||
<clr-dg-row *clrDgItems="let j of jobs" [clrDgItem]='j'>
|
||||
<clr-dg-cell>{{j.repository}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.status}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.operation}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.creation_time}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.update_time}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<a href="/api/jobs/replication/{{j.id}}/log" target="_BLANK">
|
||||
<clr-icon shape="clipboard"></clr-icon>
|
||||
</a>
|
||||
</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
{{ jobs ? jobs.length : 0 }} {{'REPLICATION.ITEMS' | translate}}
|
||||
<clr-dg-pagination [clrDgPageSize]="5"></clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid>`;
|
@ -1,94 +0,0 @@
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
import { DebugElement } from '@angular/core';
|
||||
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
|
||||
import { ListReplicationJobComponent } from '../list-replication-job/list-replication-job.component';
|
||||
import { ReplicationJob } from '../service/interface';
|
||||
|
||||
import { ErrorHandler } from '../error-handler/error-handler';
|
||||
import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
|
||||
import { ReplicationService, ReplicationDefaultService } from '../service/replication.service';
|
||||
|
||||
|
||||
describe('ListReplicationJobComponent (inline template)', ()=>{
|
||||
let mockJobs: ReplicationJob[] = [
|
||||
{
|
||||
"id": 1,
|
||||
"status": "stopped",
|
||||
"repository": "library/busybox",
|
||||
"policy_id": 1,
|
||||
"operation": "transfer",
|
||||
"tags": null
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"status": "stopped",
|
||||
"repository": "library/busybox",
|
||||
"policy_id": 1,
|
||||
"operation": "transfer",
|
||||
"tags": null
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"status": "stopped",
|
||||
"repository": "library/busybox",
|
||||
"policy_id": 2,
|
||||
"operation": "transfer",
|
||||
"tags": null
|
||||
}
|
||||
];
|
||||
|
||||
let fixture: ComponentFixture<ListReplicationJobComponent>;
|
||||
|
||||
let comp: ListReplicationJobComponent;
|
||||
|
||||
let replicationService: ReplicationService;
|
||||
|
||||
let spyJobs: jasmine.Spy;
|
||||
|
||||
let config: IServiceConfig = {
|
||||
replicationJobEndpoint: '/api/policies/replication/testing'
|
||||
};
|
||||
|
||||
beforeEach(async(()=>{
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
NoopAnimationsModule
|
||||
],
|
||||
declarations: [
|
||||
ListReplicationJobComponent
|
||||
],
|
||||
providers: [
|
||||
ErrorHandler,
|
||||
{ provide: SERVICE_CONFIG, useValue: config },
|
||||
{ provide: ReplicationService, useClass: ReplicationDefaultService }
|
||||
]
|
||||
});
|
||||
}));
|
||||
|
||||
beforeEach(()=>{
|
||||
fixture = TestBed.createComponent(ListReplicationJobComponent);
|
||||
comp = fixture.componentInstance;
|
||||
replicationService = fixture.debugElement.injector.get(ReplicationService);
|
||||
spyJobs = spyOn(replicationService, 'getJobs').and.returnValues(Promise.resolve(mockJobs));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('Should load and render data', async(()=>{
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(()=>{
|
||||
fixture.detectChanges();
|
||||
let de: DebugElement = fixture.debugElement.query(By.css('datagrid-cell'));
|
||||
expect(de).toBeTruthy();
|
||||
fixture.detectChanges();
|
||||
let el: HTMLElement = de.nativeElement;
|
||||
expect(el.textContent.trim()).toEqual('library/busybox');
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
@ -1,46 +0,0 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
import { ReplicationJob } from '../service/interface';
|
||||
import { State } from 'clarity-angular';
|
||||
import { ErrorHandler } from '../error-handler/error-handler';
|
||||
|
||||
import { REPLICATION_JOB_TEMPLATE } from './list-replication-job.component.html';
|
||||
|
||||
@Component({
|
||||
selector: 'list-replication-job',
|
||||
template: REPLICATION_JOB_TEMPLATE,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ListReplicationJobComponent {
|
||||
@Input() jobs: ReplicationJob[];
|
||||
@Input() totalRecordCount: number;
|
||||
@Input() totalPage: number;
|
||||
@Output() paginate = new EventEmitter<State>();
|
||||
|
||||
constructor(
|
||||
private errorHandler: ErrorHandler,
|
||||
private ref: ChangeDetectorRef) {
|
||||
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||
setTimeout(()=>clearInterval(hnd), 1000);
|
||||
}
|
||||
|
||||
pageOffset: number = 1;
|
||||
|
||||
refresh(state: State) {
|
||||
if(this.jobs) {
|
||||
this.paginate.emit(state);
|
||||
}
|
||||
}
|
||||
}
|
@ -33,5 +33,8 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
|
||||
{{ (p.enabled === 1 ? 'REPLICATION.ENABLED' : 'REPLICATION.DISABLED') | translate}}
|
||||
</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>{{ (rules ? rules.length : 0) }} {{'REPLICATION.ITEMS' | translate}}</clr-dg-footer>
|
||||
<clr-dg-footer>
|
||||
{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'REPLICATION.OF' | translate}} {{pagination.totalItems }} {{'REPLICATION.ITEMS' | translate}}
|
||||
<clr-dg-pagination #pagination [clrDgPageSize]="5"></clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid>`;
|
@ -27,6 +27,8 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { ErrorHandler } from '../error-handler/error-handler';
|
||||
import { toPromise } from '../utils';
|
||||
|
||||
import { State } from 'clarity-angular';
|
||||
|
||||
import { LIST_REPLICATION_RULE_TEMPLATE } from './list-replication-rule.component.html';
|
||||
|
||||
@Component({
|
||||
|
@ -46,6 +46,30 @@ export const REPLICATION_TEMPLATE: string = `
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<list-replication-job [jobs]="jobs" [totalPage]="jobsTotalPage" [totalRecordCount]="jobsTotalRecordCount" (paginate)="fetchReplicationJobs($event)"></list-replication-job>
|
||||
<clr-datagrid>
|
||||
<clr-dg-column>{{'REPLICATION.NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.STATUS' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.OPERATION' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.END_TIME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.LOGS' | translate}}</clr-dg-column>
|
||||
<clr-dg-row *clrDgItems="let j of jobs" [clrDgItem]='j'>
|
||||
<clr-dg-cell>{{j.repository}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.status}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.operation}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.creation_time}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{j.update_time}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
<a href="/api/jobs/replication/{{j.id}}/log" target="_BLANK">
|
||||
<clr-icon shape="clipboard"></clr-icon>
|
||||
</a>
|
||||
</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'REPLICATION.OF' | translate}}
|
||||
{{pagination.totalItems}} {{'REPLICATION.ITEMS' | translate}}
|
||||
<clr-dg-pagination #pagination [clrDgPageSize]="5"></clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
</div>`;
|
@ -7,7 +7,6 @@ import { SharedModule } from '../shared/shared.module';
|
||||
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
|
||||
import { ReplicationComponent } from './replication.component';
|
||||
import { ListReplicationRuleComponent } from '../list-replication-rule/list-replication-rule.component';
|
||||
import { ListReplicationJobComponent } from '../list-replication-job/list-replication-job.component';
|
||||
import { CreateEditRuleComponent } from '../create-edit-rule/create-edit-rule.component';
|
||||
import { DatePickerComponent } from '../datetime-picker/datetime-picker.component';
|
||||
import { DateValidatorDirective } from '../datetime-picker/date-validator.directive';
|
||||
@ -71,6 +70,7 @@ describe('Replication Component (inline template)', ()=>{
|
||||
"repository": "library/nginx",
|
||||
"policy_id": 1,
|
||||
"operation": "transfer",
|
||||
"update_time": new Date("2017-05-23 12:20:33"),
|
||||
"tags": null
|
||||
},
|
||||
{
|
||||
@ -79,6 +79,7 @@ describe('Replication Component (inline template)', ()=>{
|
||||
"repository": "library/mysql",
|
||||
"policy_id": 1,
|
||||
"operation": "transfer",
|
||||
"update_time": new Date("2017-05-27 12:20:33"),
|
||||
"tags": null
|
||||
},
|
||||
{
|
||||
@ -87,6 +88,7 @@ describe('Replication Component (inline template)', ()=>{
|
||||
"repository": "library/busybox",
|
||||
"policy_id": 2,
|
||||
"operation": "transfer",
|
||||
"update_time": new Date("2017-04-23 12:20:33"),
|
||||
"tags": null
|
||||
}
|
||||
];
|
||||
@ -169,7 +171,6 @@ describe('Replication Component (inline template)', ()=>{
|
||||
declarations: [
|
||||
ReplicationComponent,
|
||||
ListReplicationRuleComponent,
|
||||
ListReplicationJobComponent,
|
||||
CreateEditRuleComponent,
|
||||
ConfirmationDialogComponent,
|
||||
DatePickerComponent,
|
||||
@ -283,4 +284,17 @@ describe('Replication Component (inline template)', ()=>{
|
||||
expect(el.textContent.trim()).toEqual('library/mysql');
|
||||
});
|
||||
}));
|
||||
|
||||
it('Should filter replication jobs by date range', async(()=>{
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(()=>{
|
||||
fixture.detectChanges();
|
||||
comp.doJobSearchByStartTime('2017-05-01');
|
||||
comp.doJobSearchByEndTime('2015-05-25');
|
||||
let el: HTMLElement = deJobs.nativeElement;
|
||||
fixture.detectChanges();
|
||||
expect(el).toBeTruthy();
|
||||
expect(el.textContent.trim()).toEqual('library/nginx');
|
||||
});
|
||||
}))
|
||||
});
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import { Component, OnInit, ViewChild, Input } from '@angular/core';
|
||||
import { ResponseOptions } from '@angular/http';
|
||||
import { ResponseOptions, RequestOptions } from '@angular/http';
|
||||
import { NgModel } from '@angular/forms';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@ -24,8 +24,6 @@ import { ReplicationService } from '../service/replication.service';
|
||||
import { RequestQueryParams } from '../service/RequestQueryParams';
|
||||
import { ReplicationRule, ReplicationJob, Endpoint } from '../service/interface';
|
||||
|
||||
import { State } from 'clarity-angular';
|
||||
|
||||
import { toPromise } from '../utils';
|
||||
|
||||
import { REPLICATION_TEMPLATE } from './replication.component.html';
|
||||
@ -142,13 +140,8 @@ export class ReplicationComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
fetchReplicationJobs(state?: State) {
|
||||
if(state && state.page) {
|
||||
if(!state.page.to && state.page.to !== 0) {
|
||||
return;
|
||||
}
|
||||
this.search.page = state.page.to + 1;
|
||||
}
|
||||
fetchReplicationJobs() {
|
||||
|
||||
let params: RequestQueryParams = new RequestQueryParams();
|
||||
params.set('status', this.search.status);
|
||||
params.set('repository', this.search.repoName);
|
||||
|
Loading…
Reference in New Issue
Block a user