Merge pull request #7224 from pureshine/replication_ng

Refactor replication-task page according to the new design
This commit is contained in:
Wenkai Yin 2019-03-29 17:19:31 +08:00 committed by GitHub
commit 1491cf1846
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 358 additions and 164 deletions

View File

@ -42,6 +42,19 @@ import { RouterTestingModule } from '@angular/router/testing';
import { of } from "rxjs";
describe("CreateEditRuleComponent (inline template)", () => {
let mockEndpoint: Endpoint = {
id: 1,
credential: {
access_key: "admin",
access_secret: "",
type: "basic"
},
description: "test",
insecure: false,
name: "target_01",
type: "Harbor",
url: "https://10.117.4.151"
};
let mockRules: ReplicationRule[] = [
{
id: 1,
@ -205,6 +218,8 @@ describe("CreateEditRuleComponent (inline template)", () => {
let spyJobs: jasmine.Spy;
let spyAdapter: jasmine.Spy;
let spyEndpoint: jasmine.Spy;
let spyEndpoints: jasmine.Spy;
let config: IServiceConfig = {
replicationBaseEndpoint: "/api/replication/testing",
@ -262,10 +277,14 @@ describe("CreateEditRuleComponent (inline template)", () => {
spyAdapter = spyOn(replicationService, "getReplicationAdapter").and.returnValues(
of(mockAdapter));
spyEndpoint = spyOn(endpointService, "getEndpoints").and.returnValues(
spyEndpoints = spyOn(endpointService, "getEndpoints").and.returnValues(
of(mockEndpoints)
);
spyEndpoint = spyOn(endpointService, "getEndpoint").and.returnValue(
of(mockEndpoint)
);
fixture.detectChanges();
});

View File

@ -10,14 +10,13 @@
<clr-dg-column class="min-width">{{'REPLICATION.SRC_NAMESPACE' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.REPLICATION_MODE' | translate}}</clr-dg-column>
<clr-dg-column class="min-width">{{'REPLICATION.DESTINATION_NAMESPACE' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.LAST_REPLICATION' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.REPLICATION_TRIGGER' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'description'">{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
<clr-dg-row *clrDgItems="let p of changedRules; let i=index" [clrDgItem]="p" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
<clr-dg-cell>{{p.name}}</clr-dg-cell>
<clr-dg-cell class="min-width">
{{p.src_registry_id>0? srcRegistry : 'current'}} : {{p.src_namespaces?.length>0 ? p.src_namespaces[0]: ''}}
{{p.src_registry_id? registryName[i]:'current'}} : {{p.src_namespaces?.length>0 ? p.src_namespaces[0]: ''}}
<clr-tooltip>
<clr-icon *ngIf="p.src_namespaces && p.src_namespaces.length > 1" clrTooltipTrigger shape="ellipsis-horizontal" size="18"></clr-icon>
<clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen>
@ -29,9 +28,8 @@
{{p.src_registry_id>0? 'pull-based' : 'push-based'}}
</clr-dg-cell>
<clr-dg-cell class="min-width">
{{p.dest_registry_id>0? srcRegistry : 'current'}} : {{p.dest_namespace? p.dest_namespace: ''}}
{{p.dest_registry_id? registryName[i]: 'current'}} : {{p.dest_namespace? p.dest_namespace: ''}}
</clr-dg-cell>
<clr-dg-cell>{{p.update_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{p.trigger ? p.trigger.type : ''}}</clr-dg-cell>
<clr-dg-cell>
{{p.description ? trancatedDescription(p.description) : '-'}}

View File

@ -15,8 +15,23 @@ import { SERVICE_CONFIG, IServiceConfig } from '../service.config';
import { ReplicationService, ReplicationDefaultService } from '../service/replication.service';
import { OperationService } from "../operation/operation.service";
import { of } from 'rxjs';
import { EndpointService, EndpointDefaultService } from "../service/endpoint.service";
import { Endpoint } from "../service/interface";
describe('ListReplicationRuleComponent (inline template)', () => {
let mockEndpoint: Endpoint = {
id: 1,
credential: {
access_key: "admin",
access_secret: "",
type: "basic"
},
description: "test",
insecure: false,
name: "target_01",
type: "Harbor",
url: "https://10.117.4.151"
};
let mockRules: ReplicationRule[] = [
{
@ -49,10 +64,16 @@ describe('ListReplicationRuleComponent (inline template)', () => {
let replicationService: ReplicationService;
let endpointService: EndpointService;
let spyRules: jasmine.Spy;
let spyEndpoint: jasmine.Spy;
let config: IServiceConfig = {
replicationRuleEndpoint: '/api/policies/replication/testing'
replicationRuleEndpoint: '/api/policies/replication/testing',
systemInfoEndpoint: "/api/endpoints/testing"
};
beforeEach(async(() => {
@ -69,7 +90,8 @@ describe('ListReplicationRuleComponent (inline template)', () => {
ErrorHandler,
{ provide: SERVICE_CONFIG, useValue: config },
{ provide: ReplicationService, useClass: ReplicationDefaultService },
{ provide: OperationService }
{ provide: OperationService },
{ provide: EndpointService, useClass: EndpointDefaultService }
]
});
}));
@ -79,6 +101,11 @@ describe('ListReplicationRuleComponent (inline template)', () => {
comp = fixture.componentInstance;
replicationService = fixture.debugElement.injector.get(ReplicationService);
spyRules = spyOn(replicationService, 'getReplicationRules').and.returnValues(of(mockRules));
endpointService = fixture.debugElement.injector.get(EndpointService);
spyEndpoint = spyOn(endpointService, "getEndpoint").and.returnValue(
of(mockEndpoint)
);
fixture.detectChanges();
});

View File

@ -27,9 +27,9 @@ import {
import { Comparator } from "../service/interface";
import { TranslateService } from "@ngx-translate/core";
import { map, catchError } from "rxjs/operators";
import { Observable, forkJoin, throwError as observableThrowError } from "rxjs";
import { Observable, forkJoin, of, throwError as observableThrowError } from "rxjs";
import { ReplicationService } from "../service/replication.service";
import { EndpointService } from "../service/endpoint.service";
import {
ReplicationJob,
ReplicationJobItem,
@ -82,7 +82,9 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
changedRules: ReplicationRule[];
ruleName: string;
canDeleteRule: boolean;
srcRegistry: string = 'docker hub';
registryName: [] = [];
desRegistry: [] = [];
currentRegistry: string;
selectedRow: ReplicationRule;
@ -96,6 +98,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
enabledComparator: Comparator<ReplicationRule> = new CustomComparator<ReplicationRule>("enabled", "number");
constructor(private replicationService: ReplicationService,
private endpointService: EndpointService,
private translateService: TranslateService,
private errorHandler: ErrorHandler,
private operationService: OperationService,
@ -116,6 +119,9 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
if (!this.projectScope) {
this.retrieveRules();
}
this.translateService.get("REPLICATION.CURRENT").subscribe((res: string) => {
this.currentRegistry = res;
});
}
ngOnChanges(changes: SimpleChanges): void {
let proIdChange: SimpleChange = changes["projectId"];
@ -140,13 +146,36 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
// job list hidden
this.hideJobs.emit();
this.changedRules = this.rules;
this.loading = false;
// get registry name
let targetLists: ReplicationRule[] = rules;
if (targetLists && targetLists.length) {
let registryList: any[] = [];
targetLists.forEach(target => {
let tartId: number;
if (target.src_registry_id > 0) {
tartId = target.src_registry_id;
} else {
tartId = target.dest_registry_id;
}
registryList.push(this.getRegistry(tartId));
});
forkJoin(...registryList).subscribe((item) => {
this.selectedRow = null;
this.registryName = item.map(target => target.name);
this.loading = false;
});
}
}, error => {
this.errorHandler.error(error);
this.loading = false;
});
}
getRegistry(endpointId) {
return this.endpointService.getEndpoint(endpointId);
}
replicateRule(rule: ReplicationRule): void {
this.replicateManual.emit(rule);
}

View File

@ -1,117 +1,135 @@
<div class="replication-tasks">
<section class="overview-section">
<div class="title-wrapper clr-row">
<div class="clr-col-lg-9">
<div>
<a (click)="onBack()" class="onback">< {{'PROJECT_DETAIL.REPLICATION'| translate}}</a>
</div>
<div class="title-block clr-row">
<div class="clr-col-2">
<h2 class="custom-h2">{{'REPLICATION.REPLICATION_EXECUTION'| translate}}</h2>
<h4>{{executionId}}</h4>
</div>
<div class="clr-col-3">
<span class="label label-info" *ngIf="executions === 'InProgress'">In Progress</span>
<span class="label label-success" *ngIf="executions === 'success'">Success</span>
<span class="label label-danger" *ngIf="executions=== 'failture'">Failture</span>
</div>
</div>
</div>
<div class="clr-col-3">
<button class="btn btn-outline" (click)="stopJob()" [disabled]="stopOnGoing">{{'REPLICATION.STOPJOB' | translate}}</button>
</div>
<section class="overview-section">
<div class="title-wrapper">
<div>
<div>
<a (click)="onBack()" class="onback"><{{'PROJECT_DETAIL.REPLICATION'|
translate}}</a>
</div>
<div class="execution-block row">
<div class="clr-col-sm-12 clr-col-md-6">
<div class="flex-block">
<section class="execution-detail-label">
<section class="detail-row">
<span class="label label-purple detail-span">{{'REPLICATION.SUCCESS'| translate}}</span>
<div class="execution-details">{{'1'}}</div>
</section>
<section class="detail-row">
<span class="label label-red detail-span">{{'REPLICATION.FAILTURE'| translate}}</span>
<div class="execution-details">{{'2'}}</div>
</section>
<section class="detail-row">
<span class="label label-light-blue detail-span">{{'REPLICATION.IN_PROGRESS'| translate}}</span>
<div class="execution-details">{{'3'}}</div>
</section>
</section>
</div>
<div class="title-block">
<div>
<h2 class="custom-h2 h2-style">{{'REPLICATION.REPLICATION_EXECUTION'|
translate}}</h2>
<span class="id-divider"></span>
<h2 class="custom-h2 h2-style">{{executionId}}</h2>
</div>
<div>
<div class="status-progress" *ngIf="executions === 'InProgress'">
<span class="spinner spinner-inline"></span>
<span>{{'REPLICATION.IN_PROGRESS'| translate}}</span>
</div>
<div class="clr-col-sm-12 clr-col-md-6">
<div class="executions-detail">
<div class="policy">
<label>{{'REPLICATION.POLICY' | translate}} :</label>
<span>{{'My 1st policy'}}</span>
</div>
<div class="trigger">
<label for="">{{'REPLICATION.TRIGGER_MODE' | translate}} :</label>
<span>{{'Schedule'}}</span>
</div>
<div class="start-time">
<label for="">{{'REPLICATION.CREATION_TIME' | translate}} :</label>
<span>{{'3/14/19, 2:26 PM'}}</span>
</div>
</div>
<div class="status-success" *ngIf="executions === 'success'">
<clr-icon size="18" shape="success-standard" class="color-green"></clr-icon>
<span>{{'REPLICATION.SUCCESS'| translate}}</span>
</div>
<div class="status-failed" *ngIf="executions === 'failed'">
<clr-icon size="18" shape="error-standard" class="color-red"></clr-icon>
<span>{{'REPLICATION.FAILTURE'| translate}}</span>
</div>
</div>
<div>
<button class="btn btn-primary btn-sm" (click)="stopJob()"
[disabled]="stopOnGoing">{{'REPLICATION.STOPJOB' | translate}}</button>
</div>
</div>
</section>
</div>
<div class="tasks-detail">
<h3 class="modal-title">Tasks</h3>
<div class="row flex-items-xs-between flex-items-xs-bottom">
<div class="action-select">
<div class="select filterTag" [hidden]="!isOpenFilterTag">
<select>
<option value="username">{{"AUDIT_LOG.USERNAME" | translate | lowercase}}</option>
<option value="repository">{{"CONFIG.REPOSITORY" | translate | lowercase}}</option>
<option value="tag">{{"REPOSITORY.TAG" | translate | lowercase}}</option>
<option value="operation">{{"AUDIT_LOG.OPERATION" | translate | lowercase}}</option>
</select>
</div>
<hbr-filter [withDivider]="true" (openFlag)="openFilter($event)" filterPlaceholder='{{"AUDIT_LOG.FILTER_PLACEHOLDER" | translate}}'></hbr-filter>
<span class="refresh-btn">
<clr-icon shape="refresh"></clr-icon>
<span class="spinner spinner-inline" hidden></span>
</span>
</div>
</div>
<clr-datagrid [(clrDgSelected)]="selectedRow">
<clr-dg-column>{{'REPLICATION.TASK_ID'| translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'resource_type'">{{'REPLICATION.RECOURCE_TYPE' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'src_resource'">{{'REPLICATION.RECOURCE' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'dst_resource'">{{'REPLICATION.DESTINATION' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'status'">{{'REPLICATION.STATUS' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="startTimeComparator">{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="endTimeComparator">{{'REPLICATION.END_TIME' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.LOGS' | translate}}</clr-dg-column>
<clr-dg-row *clrDgItems="let t of tasks">
<clr-dg-cell>{{t.id}}</clr-dg-cell>
<clr-dg-cell>{{t.resource_type}}</clr-dg-cell>
<clr-dg-cell>{{t.src_resource}}</clr-dg-cell>
<clr-dg-cell>{{t.dst_resource}}</clr-dg-cell>
<clr-dg-cell>{{t.status}}</clr-dg-cell>
<clr-dg-cell>{{t.start_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{t.end_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>
<span *ngIf="t.status=='InProgress'; else elseBlock" class="label">{{'REPLICATION.NO_LOGS' | translate}}</span>
<ng-template #elseBlock>
<a target="_blank" [href]="viewLog(t.id)">
<clr-icon shape="list"></clr-icon>
</a>
</ng-template>
</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}}
-
{{pagination.lastItem +1 }} {{'ROBOT_ACCOUNT.OF' |
translate}} </span>
{{pagination.totalItems }} {{'ROBOT_ACCOUNT.ITEMS' | translate}}
<clr-dg-pagination #pagination [clrDgPageSize]="15"></clr-dg-pagination>
</clr-dg-footer>
</clr-datagrid>
</div>
<div class="execution-block">
<div class="executions-detail">
<div class="policy">
<label>{{'REPLICATION.POLICY' | translate}} :</label>
<span>{{'My 1st policy'}}</span>
</div>
<div class="trigger">
<label for="">{{'REPLICATION.TRIGGER_MODE' | translate}} :</label>
<span>{{'Schedule'}}</span>
</div>
<div class="start-time">
<label for="">{{'REPLICATION.CREATION_TIME' | translate}} :</label>
<span>{{'3/14/19, 2:26 PM'}}</span>
</div>
</div>
<div class="flex-block">
<section class="execution-detail-label">
<section class="detail-row">
<span class="label label-purple detail-span">{{'REPLICATION.SUCCESS'| translate}}</span>
<div class="execution-details">{{'1'}}</div>
</section>
<section class="detail-row">
<span class="label label-red detail-span">{{'REPLICATION.FAILTURE'| translate}}</span>
<div class="execution-details">{{'2'}}</div>
</section>
<section class="detail-row">
<span class="label label-light-blue detail-span">{{'REPLICATION.IN_PROGRESS'| translate}}</span>
<div class="execution-details">{{'3'}}</div>
</section>
</section>
</div>
</div>
</section>
<div class="tasks-detail">
<h3 class="modal-title">Tasks</h3>
<div class="row flex-items-xs-between flex-items-xs-bottom">
<div class="action-select">
<div class="select filterTag" [hidden]="!isOpenFilterTag">
<select>
<option value="recourceType">{{'REPLICATION.RECOURCE_TYPE' |translate}}</option>
<option value="recource">{{'REPLICATION.RECOURCE' | translate}}</option>
<option value="destination">{{'REPLICATION.DESTINATION' | translate}}</option>
<option value="status">{{'REPLICATION.STATUS' | translate}}</option>
</select>
</div>
<hbr-filter [withDivider]="true" (openFlag)="openFilter($event)"
filterPlaceholder='{{"REPLICATION.FILTER_PLACEHOLDER" | translate}}'></hbr-filter>
<span class="refresh-btn">
<clr-icon shape="refresh"></clr-icon>
<span class="spinner spinner-inline" hidden></span>
</span>
</div>
</div>
<clr-datagrid [(clrDgSelected)]="selectedRow" [clrDgLoading]="loading">
<clr-dg-column>{{'REPLICATION.TASK_ID'| translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'resource_type'">{{'REPLICATION.RECOURCE_TYPE'
| translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'src_resource'">{{'REPLICATION.RECOURCE' |
translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'dst_resource'">{{'REPLICATION.DESTINATION' |
translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'status'">{{'REPLICATION.STATUS' |
translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="startTimeComparator">{{'REPLICATION.CREATION_TIME'
| translate}}</clr-dg-column>
<clr-dg-column [clrDgSortBy]="endTimeComparator">{{'REPLICATION.END_TIME'
| translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.LOGS' | translate}}</clr-dg-column>
<clr-dg-row *clrDgItems="let t of tasks">
<clr-dg-cell>{{t.id}}</clr-dg-cell>
<clr-dg-cell>{{t.resource_type}}</clr-dg-cell>
<clr-dg-cell>{{t.src_resource}}</clr-dg-cell>
<clr-dg-cell>{{t.dst_resource}}</clr-dg-cell>
<clr-dg-cell>{{t.status}}</clr-dg-cell>
<clr-dg-cell>{{t.start_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{t.end_time | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>
<span *ngIf="t.status=='InProgress'; else elseBlock" class="label">{{'REPLICATION.NO_LOGS'
| translate}}</span>
<ng-template #elseBlock>
<a target="_blank" [href]="viewLog(t.id)">
<clr-icon shape="list"></clr-icon>
</a>
</ng-template>
</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}}
-
{{pagination.lastItem +1 }} {{'ROBOT_ACCOUNT.OF' |
translate}} </span>
{{pagination.totalItems }} {{'ROBOT_ACCOUNT.ITEMS' | translate}}
<clr-dg-pagination #pagination [clrDgPageSize]="15"></clr-dg-pagination>
</clr-dg-footer>
</clr-datagrid>
</div>
</div>

View File

@ -3,11 +3,33 @@
.title-wrapper {
.onback{
color: #007cbb;
font-size: 12px;
font-size: 14px;
cursor: pointer;
}
h4 {
margin-top: 8px;
.title-block {
display: flex;
align-items: center;
>div:first-child {
width: 210px;
}
>div:nth-child(2) {
width: 140px;
span {
color: #007cbb;
font-size: 12px;
margin-left: 10px;
}
}
.id-divider {
display: inline-block;
height: 25px;
width: 2px;
background-color: #cccccc;
margin: 0 20px;
}
.h2-style {
display: inline-block;
}
}
}
.execution-block {
@ -21,7 +43,6 @@
display: flex;
.detail-span {
flex:0 0 100px;
font-weight: 600;
margin-top: 10px;
}
.execution-details {
@ -31,9 +52,14 @@
}
}
.executions-detail {
font-weight: 600;
span {
margin-left: 5px;
width: 400px;
label {
display: inline-block;
color: black;
width: 120px;
}
>div {
margin-top: 10px;
}
}
}
@ -60,4 +86,4 @@
}
}
}
}
}

View File

@ -1,8 +1,8 @@
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';
import { ReplicationService } from "../../service/replication.service";
import { map, catchError } from "rxjs/operators";
import { Observable, forkJoin, throwError as observableThrowError } from "rxjs";
import { TranslateService } from '@ngx-translate/core';
import { finalize } from "rxjs/operators";
import { ErrorHandler } from "../../error-handler/error-handler";
import { ReplicationJob, ReplicationTasks, Comparator, ReplicationJobItem } from "../../service/interface";
import { CustomComparator } from "../../utils";
@ -14,7 +14,11 @@ import { CustomComparator } from "../../utils";
export class ReplicationTasksComponent implements OnInit {
isOpenFilterTag: boolean;
selectedRow: [];
loading = false;
searchTask: string;
defaultFilter = "recourceType";
tasks: ReplicationTasks[] = [];
tasksCopy: ReplicationTasks[] = [];
stopOnGoing: boolean;
executions: string = 'InProgress';
@Input() executionId: string;
@ -26,15 +30,16 @@ export class ReplicationTasksComponent implements OnInit {
>("end_time", "date");
constructor(
private translate: TranslateService,
private router: Router,
private replicationService: ReplicationService,
private errorHandler: ErrorHandler,
) { }
ngOnInit(): void {
// this.getExecutions();
this.getTasks();
this.clrLoadTasks();
// this.executions.status = 'success';
this.searchTask = '';
}
// getExecutions(): void {
@ -54,9 +59,12 @@ export class ReplicationTasksComponent implements OnInit {
stopJob() {
this.stopOnGoing = true;
this.replicationService.stopJobs(this.executionId)
.subscribe(res => {
.subscribe(response => {
this.stopOnGoing = false;
// this.getExecutions();
this.translate.get("REPLICATION.STOP_SUCCESS", { param: this.executionId }).subscribe((res: string) => {
this.errorHandler.info(res);
});
},
error => {
this.errorHandler.error(error);
@ -64,13 +72,33 @@ export class ReplicationTasksComponent implements OnInit {
}
viewLog(taskId: number | string): string {
return this.replicationService.getJobBaseUrl() + "/" + this.executionId + "/tasks/" + taskId + "/log";
return this.replicationService.getJobBaseUrl() + "/executions/" + this.executionId + "/tasks/" + taskId + "/log";
}
getTasks(): void {
clrLoadTasks(): void {
this.loading = true;
this.replicationService.getReplicationTasks(this.executionId)
.pipe(finalize(() => (this.loading = false)))
.subscribe(tasks => {
this.tasks = tasks.map(x => Object.assign({}, x));
if (this.defaultFilter === 'recourceType') {
this.tasks = tasks.filter(x =>
x.resource_type.includes(this.searchTask)
);
} else if (this.defaultFilter === 'recource') {
this.tasks = tasks.filter(x =>
x.src_resource.includes(this.searchTask)
);
} else if (this.defaultFilter === 'destination') {
this.tasks = tasks.filter(x =>
x.dst_resource.includes(this.searchTask)
);
} else {
this.tasks = tasks.filter(x =>
x.status.includes(this.searchTask)
);
}
this.tasksCopy = tasks.map(x => Object.assign({}, x));
},
error => {
this.errorHandler.error(error);
@ -80,12 +108,31 @@ export class ReplicationTasksComponent implements OnInit {
this.router.navigate(["harbor", "replications"]);
}
selectFilter($event: any): void {
this.defaultFilter = $event['target'].value;
this.doSearch(this.searchTask);
}
// refresh icon
refreshTasks(): void {
this.searchTask = '';
this.clrLoadTasks();
}
doSearch(value: string): void {
if (!value) {
return;
}
this.searchTask = value.trim();
this.clrLoadTasks();
}
openFilter(isOpen: boolean): void {
if (isOpen) {
this.isOpenFilterTag = true;
} else {
this.isOpenFilterTag = false;
}
}
}
}

View File

@ -26,7 +26,7 @@
<h5 class="flex-items-xs-bottom option-left-down">{{'REPLICATION.REPLICATION_EXECUTIONS' | translate}}</h5>
<div class="flex-items-xs-bottom option-right-down">
<button class="btn btn-link" (click)="toggleSearchJobOptionalName(currentJobSearchOption)">{{toggleJobSearchOption[currentJobSearchOption] | translate}}</button>
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_JOBS_PLACEHOLDER" | translate}}' (filterEvt)="doSearchJobs($event)"
<hbr-filter [withDivider]="true" filterPlaceholder='{{"REPLICATION.FILTER_EXECUTIONS_PLACEHOLDER" | translate}}' (filterEvt)="doSearchJobs($event)"
[currentValue]="search.repoName"></hbr-filter>
<span class="refresh-btn" (click)="refreshJobs()">
<clr-icon shape="refresh"></clr-icon>

View File

@ -28,7 +28,7 @@
}
.row-right {
padding-right: 50px;
margin-left: 564px;
}
.replication-row {

View File

@ -27,6 +27,20 @@ import { of } from 'rxjs';
describe('Replication Component (inline template)', () => {
let mockEndpoint: Endpoint = {
id: 1,
credential: {
access_key: "admin",
access_secret: "",
type: "basic"
},
description: "test",
insecure: false,
name: "target_01",
type: "Harbor",
url: "https://10.117.4.151"
};
let mockRules: ReplicationRule[] = [
{
@ -128,6 +142,7 @@ describe('Replication Component (inline template)', () => {
let spyRules: jasmine.Spy;
let spyJobs: jasmine.Spy;
let spyEndpoint: jasmine.Spy;
let spyEndpoints: jasmine.Spy;
let deGrids: DebugElement[];
let deRules: DebugElement;
@ -138,7 +153,7 @@ describe('Replication Component (inline template)', () => {
let config: IServiceConfig = {
replicationRuleEndpoint: '/api/policies/replication/testing',
replicationBaseEndpoint: '/api/replication/testing'
systemInfoEndpoint: "/api/endpoints/testing"
};
beforeEach(async(() => {
@ -187,8 +202,8 @@ describe('Replication Component (inline template)', () => {
spyJobs = spyOn(replicationService, 'getExecutions').and.returnValues(of(mockJob));
spyEndpoint = spyOn(endpointService, 'getEndpoints').and.returnValues(of(mockEndpoints));
spyEndpoints = spyOn(endpointService, 'getEndpoints').and.returnValues(of(mockEndpoints));
spyEndpoint = spyOn(endpointService, "getEndpoint").and.returnValue(of(mockEndpoint));
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();

View File

@ -278,7 +278,7 @@ export class ReplicationDefaultService extends ReplicationService {
if (!executionId) {
return observableThrowError("Bad argument");
}
let url: string = `${this._replicateUrl}/${executionId}/tasks`;
let url: string = `${this._replicateUrl}/executions/${executionId}/tasks`;
return this.http
.get(url, HTTP_GET_OPTIONS)
.pipe(map(response => response.json() as ReplicationTasks)
@ -385,10 +385,10 @@ export class ReplicationDefaultService extends ReplicationService {
if (!queryParams) {
queryParams = new RequestQueryParams();
}
let url: string = `${this._replicateUrl}/executions`;
queryParams.set("policy_id", "" + ruleId);
return this.http
.get(this._replicateUrl, buildHttpRequestOptions(queryParams))
.get(url, buildHttpRequestOptions(queryParams))
.pipe(map(response => {
let result: ReplicationJob = {
metadata: {
@ -435,7 +435,7 @@ export class ReplicationDefaultService extends ReplicationService {
if (!jobId || jobId <= 0) {
return observableThrowError("Bad request argument.");
}
let requestUrl: string = `${this._replicateUrl}/${jobId}`;
let requestUrl: string = `${this._replicateUrl}/executions/${jobId}`;
return this.http
.put(

View File

@ -331,7 +331,10 @@
"OF": "of"
},
"REPLICATION": {
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirm Stop Executions",
"STOP_SUCCESS": "Stop Execution {{param}} Successful",
"STOP_SUMMARY": "Do you want to stop the executions {{param}}?",
"TASK_ID":"Task ID",
"RECOURCE_TYPE": "Recource Type",
@ -340,14 +343,14 @@
"POLICY": "Policy",
"DURATION": "Duration",
"SUCCESS_RATE": "Success Rate",
"SUCCESS": "Success",
"FAILTURE": "Failture",
"IN_PROGRESS": "In Progress",
"SUCCESS": "SUCCESS",
"FAILTURE": "FAILTURE",
"IN_PROGRESS": "IN PROGRESS",
"REPLICATION_RULE": "Replication Rule",
"NEW_REPLICATION_RULE": "New Replication Rule",
"ENDPOINTS": "Endpoints",
"FILTER_POLICIES_PLACEHOLDER": "Filter Rules",
"FILTER_JOBS_PLACEHOLDER": "Filter Jobs",
"FILTER_EXECUTIONS_PLACEHOLDER": "Filter Executions",
"DELETION_TITLE": "Confirm Rules Deletion",
"DELETION_SUMMARY": "Do you want to delete rules {{param}}?",
"REPLICATION_TITLE": "Confirm Rules replication",

View File

@ -330,7 +330,10 @@
"OF": "of"
},
"REPLICATION": {
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme Stop Executions",
"STOP_SUCCESS": "Stop Execution {{param}} Successful",
"STOP_SUMMARY": "De que desea detener las ejecuciones {{param}}?",
"TASK_ID":"Task ID",
"RECOURCE_TYPE": "Recource Type",
@ -339,16 +342,16 @@
"POLICY": "Policy",
"DURATION": "Duration",
"SUCCESS_RATE": "Success Rate",
"SUCCESS": "Success",
"FAILTURE": "Failture",
"IN_PROGRESS": "In Progress",
"SUCCESS": "SUCCESS",
"FAILTURE": "FAILTURE",
"IN_PROGRESS": "IN PROGRESS",
"STOP_EXECUTIONS": "Stop Execution",
"ID":"ID",
"REPLICATION_RULE": "Reglas de Replicación",
"NEW_REPLICATION_RULE": "Nueva Regla de Replicación",
"ENDPOINTS": "Endpoints",
"FILTER_POLICIES_PLACEHOLDER": "Filtrar Reglas",
"FILTER_JOBS_PLACEHOLDER": "Filtrar Trabajos",
"FILTER_EXECUTIONS_PLACEHOLDER": "Filter Ejecuciones",
"DELETION_TITLE": "Confirmar Eliminación de Regla",
"DELETION_SUMMARY": "¿Quiere eliminar la regla {{param}}?",
"DELETION_TITLE_FAILURE": "failed to delete Rule Deletion",

View File

@ -315,7 +315,10 @@
"OF": "de"
},
"REPLICATION": {
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirmer arrêter les exécutions",
"STOP_SUCCESS": "Stop Execution {{param}} Successful",
"STOP_SUMMARY": "Voulez-vous arrêter les exécutions {{param}}?",
"TASK_ID":"Task ID",
"RECOURCE_TYPE": "Recource Type",
@ -324,16 +327,16 @@
"POLICY": "Policy",
"DURATION": "Duration",
"SUCCESS_RATE": "Success Rate",
"SUCCESS": "Success",
"FAILTURE": "Failture",
"IN_PROGRESS": "In Progress",
"SUCCESS": "SUCCESS",
"FAILTURE": "FAILTURE",
"IN_PROGRESS": "IN PROGRESS",
"STOP_EXECUTIONS": "Stop Execution",
"ID":"ID",
"REPLICATION_RULE": "Règle de Réplication",
"NEW_REPLICATION_RULE": "Nouvelle Règle de Réplication",
"ENDPOINTS": "Points finaux",
"FILTER_POLICIES_PLACEHOLDER": "Filtrer les Règles",
"FILTER_JOBS_PLACEHOLDER": "Filtrer les Travaux",
"FILTER_EXECUTIONS_PLACEHOLDER": "Filter Exécutions",
"DELETION_TITLE": "Confirmer la suppression de la Règle",
"DELETION_SUMMARY": "Voulez-vous supprimer la règle {{param}} ?",
"DELETION_TITLE_FAILURE": "n'a pas supprimé la règle",

View File

@ -329,7 +329,10 @@
"OF": "de"
},
"REPLICATION": {
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme as execuções de parada",
"STOP_SUCCESS": "Stop Execution {{param}} Successful",
"STOP_SUMMARY": "Você quer parar as execuções? {{param}}?",
"TASK_ID":"Task ID",
"RECOURCE_TYPE": "Recource Type",
@ -338,16 +341,16 @@
"POLICY": "Policy",
"DURATION": "Duration",
"SUCCESS_RATE": "Success Rate",
"SUCCESS": "Success",
"FAILTURE": "Failture",
"IN_PROGRESS": "In Progress",
"SUCCESS": "SUCCESS",
"FAILTURE": "FAILTURE",
"IN_PROGRESS": "IN PROGRESS",
"STOP_EXECUTIONS": "Stop Execution",
"ID":"ID",
"REPLICATION_RULE": "Regra de replicação",
"NEW_REPLICATION_RULE": "Nova regra de replicação",
"ENDPOINTS": "Endpoints",
"FILTER_POLICIES_PLACEHOLDER": "Filtrar regras",
"FILTER_JOBS_PLACEHOLDER": "Filtrar tarefas",
"FILTER_EXECUTIONS_PLACEHOLDER": "Execuções de Filtro",
"DELETION_TITLE": "Confirmar remoção de regras",
"DELETION_SUMMARY": "Você quer remover a regra {{param}}?",
"REPLICATION_TITLE": "Confirmar regras de replicação",

View File

@ -330,7 +330,10 @@
"OF": "共计"
},
"REPLICATION": {
"CURRENT": "当前仓库",
"FILTER_PLACEHOLDER": "过滤任务",
"STOP_TITLE": "确认停止任务",
"STOP_SUCCESS": "停止任务 {{param}} 成功",
"STOP_SUMMARY": "确认停止任务{{param}}?",
"TASK_ID":"任务ID",
"RECOURCE_TYPE": "源类型",
@ -348,7 +351,7 @@
"NEW_REPLICATION_RULE": "新建规则",
"ENDPOINTS": "目标",
"FILTER_POLICIES_PLACEHOLDER": "过滤规则",
"FILTER_JOBS_PLACEHOLDER": "过滤任务",
"FILTER_EXECUTIONS_PLACEHOLDER": "过滤任务",
"DELETION_TITLE": "删除规则确认",
"DELETION_SUMMARY": "确认删除规则 {{param}}?",
"DELETION_TITLE_FAILURE": "规则确认删除失败",