Add shareable replication component

This commit is contained in:
kunw 2017-05-17 13:29:27 +08:00
parent de88cccf77
commit 2da0bfa8b9
22 changed files with 1182 additions and 18 deletions

View File

@ -62,7 +62,6 @@ export class CreateEditEndpointComponent implements AfterViewChecked {
currentForm: NgForm;
hasChanged: boolean;
endpointHasChanged: boolean;
targetNameHasChanged: boolean;
@ -263,7 +262,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked {
ngAfterViewChecked(): void {
this.targetForm = this.currentForm;
if(this.targetForm) {
let comparison: {[key: string]: string} = {
let comparison: {[key: string]: any} = {
targetName: this.initVal.name,
endpointUrl: this.initVal.endpoint,
username: this.initVal.username,

View File

@ -0,0 +1,5 @@
export const CREATE_EDIT_RULE_STYLE: string = `
.form-group-label-override {
font-size: 14px;
font-weight: 400;
}`;

View File

@ -0,0 +1,88 @@
export const CREATE_EDIT_RULE_TEMPLATE: string = `
<clr-modal [(clrModalOpen)]="createEditRuleOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
<h3 class="modal-title">{{modalTitle}}</h3>
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
<div class="modal-body" style="max-height: 85vh;">
<form #ruleForm="ngForm">
<section class="form-block">
<div class="alert alert-warning" *ngIf="!editable">
<div class="alert-item">
<span class="alert-text">
{{'REPLICATION.CANNOT_EDIT' | translate}}
</span>
</div>
</div>
<div class="form-group">
<label for="policy_name" class="col-md-4 form-group-label-override">{{'REPLICATION.NAME' | translate}}<span style="color: red">*</span></label>
<label for="policy_name" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="name.errors && (name.dirty || name.touched)" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
<input type="text" id="policy_name" [(ngModel)]="createEditRule.name" name="name" size="20" #name="ngModel" required [readonly]="readonly">
<span class="tooltip-content" *ngIf="name.errors && name.errors.required && (name.dirty || name.touched)">
{{'REPLICATION.NAME_IS_REQUIRED' | translate}}
</span>
</label>
</div>
<div class="form-group">
<label for="policy_description" class="col-md-4 form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
<textarea class="col-md-8" id="policy_description" row="3" [(ngModel)]="createEditRule.description" name="description" size="20" #description="ngModel" [readonly]="readonly"></textarea>
</div>
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.ENABLE' | translate}}</label>
<div class="checkbox-inline">
<input type="checkbox" id="policy_enable" [(ngModel)]="createEditRule.enable" name="enable" #enable="ngModel" [disabled]="untoggleable">
<label for="policy_enable"></label>
</div>
</div>
<div class="form-group">
<label for="destination_name" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_NAME' | translate}}<span style="color: red">*</span></label>
<div class="select" *ngIf="!isCreateEndpoint">
<select id="destination_name" [(ngModel)]="createEditRule.endpointId" name="endpointId" (change)="selectEndpoint()" [disabled]="testOngoing || readonly">
<option *ngFor="let t of endpoints" [value]="t.id" [selected]="t.id == createEditRule.endpointId">{{t.name}}</option>
</select>
</div>
<label class="col-md-8" *ngIf="isCreateEndpoint" for="destination_name" aria-haspopup="true" role="tooltip" [class.invalid]="endpointName.errors && (endpointName.dirty || endpointName.touched)"
class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
<input type="text" id="destination_name" [(ngModel)]="createEditRule.endpointName" name="endpointName" size="8" #endpointName="ngModel" value="" required>
<span class="tooltip-content" *ngIf="endpointName.errors && endpointName.errors.required && (endpointName.dirty || endpointName.touched)">
{{'REPLICATION.DESTINATION_NAME_IS_REQUIRED' | translate}}
</span>
</label>
<div class="checkbox-inline" *ngIf="showNewDestination">
<input type="checkbox" id="check_new" (click)="newEndpoint(checkedAddNew.checked)" #checkedAddNew [checked]="isCreateEndpoint" [disabled]="testOngoing || readonly">
<label for="check_new">{{'REPLICATION.NEW_DESTINATION' | translate}}</label>
</div>
</div>
<div class="form-group">
<label for="destination_url" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_URL' | translate}}<span style="color: red">*</span></label>
<label for="destination_url" class="col-md-8" aria-haspopup="true" role="tooltip" [class.invalid]="endpointUrl.errors && (endpointUrl.dirty || endpointUrl.touched)"
class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
<input type="text" id="destination_url" [disabled]="testOngoing" [readonly]="readonly || !isCreateEndpoint"
[(ngModel)]="createEditRule.endpointUrl" size="20" name="endpointUrl" required #endpointUrl="ngModel">
<span class="tooltip-content" *ngIf="endpointUrl.errors && endpointUrl.errors.required && (endpointUrl.dirty || endpointUrl.touched)">
{{'REPLICATION.DESTINATION_URL_IS_REQUIRED' | translate}}
</span>
</label>
</div>
<div class="form-group">
<label for="destination_username" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_USERNAME' | translate}}</label>
<input type="text" class="col-md-8" id="destination_username" [disabled]="testOngoing" [readonly]="readonly || !isCreateEndpoint"
[(ngModel)]="createEditRule.username" size="20" name="username" #username="ngModel">
</div>
<div class="form-group">
<label for="destination_password" class="col-md-4 form-group-label-override">{{'REPLICATION.DESTINATION_PASSWORD' | translate}}</label>
<input type="password" class="col-md-8" id="destination_password" [disabled]="testOngoing" [readonly]="readonly || !isCreateEndpoint"
[(ngModel)]="createEditRule.password" size="20" name="password" #password="ngModel">
</div>
<div class="form-group">
<label for="spin" class="col-md-4"></label>
<span class="col-md-8 spinner spinner-inline" [hidden]="!testOngoing"></span>
<span [style.color]="!pingStatus ? 'red': ''" class="form-group-label-override">{{ pingTestMessage }}</span>
</div>
</section>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline" (click)="testConnection()" [disabled]="testOngoing">{{'REPLICATION.TEST_CONNECTION' | translate}}</button>
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate }}</button>
<button type="submit" class="btn btn-primary" [disabled]="!ruleForm.form.valid || testOngoing || !editable" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
</div>
</clr-modal>`;

View File

@ -0,0 +1,417 @@
// 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, OnInit, ViewChild, AfterViewChecked } from '@angular/core';
import { NgForm } from '@angular/forms';
import { ReplicationService } from '../service/replication.service';
import { EndpointService } from '../service/endpoint.service';
import { ErrorHandler } from '../error-handler/error-handler';
import { ActionType } from '../shared/shared.const';
import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
import { ReplicationRule } from '../service/interface';
import { Endpoint } from '../service/interface';
import { TranslateService } from '@ngx-translate/core';
import { CREATE_EDIT_RULE_STYLE } from './create-edit-rule.component.css';
import { CREATE_EDIT_RULE_TEMPLATE } from './create-edit-rule.component.html';
import { toPromise } from '../utils';
/**
* Rule form model.
*/
export interface CreateEditRule {
ruleId?: number | string;
name?: string;
description?: string;
enable?: boolean;
endpointId?: number | string;
endpointName?: string;
endpointUrl?: string;
username?: string;
password?: string;
}
const FAKE_PASSWORD: string = 'ywJZnDTM';
@Component({
selector: 'create-edit-rule',
template: CREATE_EDIT_RULE_TEMPLATE,
styles: [ CREATE_EDIT_RULE_STYLE ]
})
export class CreateEditRuleComponent implements OnInit, AfterViewChecked {
modalTitle: string;
createEditRuleOpened: boolean;
createEditRule: CreateEditRule = this.initCreateEditRule;
initVal: CreateEditRule = this.initCreateEditRule;
actionType: ActionType;
isCreateEndpoint: boolean;
@Input() projectId: number;
@Output() reload = new EventEmitter();
endpoints: Endpoint[];
pingTestMessage: string;
testOngoing: boolean;
pingStatus: boolean;
ruleForm: NgForm;
staticBackdrop: boolean = true;
closable: boolean = false;
@ViewChild('ruleForm')
currentForm: NgForm;
hasChanged: boolean;
editable: boolean;
get initCreateEditRule(): CreateEditRule {
return {
endpointId: '',
name: '',
enable: false,
description: '',
endpointName: '',
endpointUrl: '',
username: '',
password: ''
};
}
get initReplicationRule(): ReplicationRule {
return {
project_id: '',
project_name: '',
target_id: '',
target_name: '',
enabled: 0,
description: '',
cron_str: '',
error_job_count: 0,
deleted: 0
};
}
get initEndpoint(): Endpoint {
return {
endpoint: '',
name: '',
username: '',
password: '',
type: 0
};
}
@ViewChild(InlineAlertComponent)
inlineAlert: InlineAlertComponent;
get readonly(): boolean {
return this.actionType === ActionType.EDIT && (this.createEditRule.enable || false);
}
get untoggleable(): boolean {
return this.actionType === ActionType.EDIT && (this.initVal.enable || false);
}
get showNewDestination(): boolean {
return this.actionType === ActionType.ADD_NEW || (!this.createEditRule.enable || false);
}
constructor(
private replicationService: ReplicationService,
private endpointService: EndpointService,
private errorHandler: ErrorHandler,
private translateService: TranslateService) {}
prepareTargets(endpointId?: number | string) {
toPromise<Endpoint[]>(this.endpointService
.getEndpoints())
.then(endpoints=>{
this.endpoints = endpoints;
if(this.endpoints && this.endpoints.length > 0) {
let initialEndpoint: Endpoint | undefined;
(endpointId) ? initialEndpoint = this.endpoints.find(t=>t.id===endpointId) : initialEndpoint = this.endpoints[0];
if(!initialEndpoint) {
return;
}
this.createEditRule.endpointId = initialEndpoint.id;
this.createEditRule.endpointName = initialEndpoint.name;
this.createEditRule.endpointUrl = initialEndpoint.endpoint;
this.createEditRule.username = initialEndpoint.username;
this.createEditRule.password = FAKE_PASSWORD;
this.initVal.endpointId = this.createEditRule.endpointId;
this.initVal.endpointUrl = this.createEditRule.endpointUrl;
this.initVal.username = this.createEditRule.username;
this.initVal.password = this.createEditRule.password;
}
})
.catch(error=>{
this.errorHandler.error(error);
this.createEditRuleOpened = false;
});
}
ngOnInit(): void {}
openCreateEditRule(editable: boolean, ruleId?: number | string): void {
this.createEditRuleOpened = true;
this.createEditRule = this.initCreateEditRule;
if(!this.createEditRule) {
return;
}
this.editable = editable;
this.isCreateEndpoint = false;
this.hasChanged = false;
this.pingTestMessage = '';
this.pingStatus = true;
this.testOngoing = false;
if(ruleId) {
this.actionType = ActionType.EDIT;
this.translateService.get('REPLICATION.EDIT_POLICY_TITLE').subscribe(res=>this.modalTitle=res);
toPromise<ReplicationRule>(this.replicationService
.getReplicationRule(ruleId))
.then(rule=>{
this.createEditRule.ruleId = ruleId;
this.createEditRule.name = rule.name;
this.createEditRule.description = rule.description;
this.createEditRule.enable = rule.enabled === 1? true : false;
this.prepareTargets(rule.target_id);
this.initVal.name = this.createEditRule.name;
this.initVal.description = this.createEditRule.description;
this.initVal.enable = this.createEditRule.enable;
}
)
} else {
this.actionType = ActionType.ADD_NEW;
this.translateService.get('REPLICATION.ADD_POLICY').subscribe(res=>this.modalTitle=res);
this.prepareTargets();
}
}
newEndpoint(checkedAddNew: boolean): void {
this.isCreateEndpoint = checkedAddNew;
if(this.isCreateEndpoint) {
this.createEditRule.endpointName = '';
this.createEditRule.endpointUrl = '';
this.createEditRule.username = '';
this.createEditRule.password = '';
} else {
this.prepareTargets();
}
}
selectEndpoint(): void {
let result: Endpoint | undefined = this.endpoints.find(target=>target.id == this.createEditRule.endpointId);
if(result) {
this.createEditRule.endpointId = result.id;
this.createEditRule.endpointUrl = result.endpoint;
this.createEditRule.username = result.username;
this.createEditRule.password = FAKE_PASSWORD;
}
}
getRuleByForm(): ReplicationRule {
let rule: ReplicationRule = this.initReplicationRule;
rule.project_id = this.projectId;
rule.id = this.createEditRule.endpointId;
rule.name = this.createEditRule.name;
rule.description = this.createEditRule.description;
rule.enabled = this.createEditRule.enable ? 1 : 0;
rule.target_id = this.createEditRule.endpointId || '';
return rule;
}
getEndpointByForm(): Endpoint {
let endpoint: Endpoint = this.initEndpoint;
endpoint.id = this.createEditRule.ruleId;
endpoint.name = this.createEditRule.endpointName || '';
endpoint.endpoint = this.createEditRule.endpointUrl || '';
endpoint.username = this.createEditRule.username;
endpoint.password = this.createEditRule.password;
return endpoint;
}
createReplicationRule(): void {
toPromise<ReplicationRule>(this.replicationService
.createReplicationRule(this.getRuleByForm()))
.then(response=>{
this.translateService.get('REPLICATION.CREATED_SUCCESS')
.subscribe(res=>this.errorHandler.info(res));
this.createEditRuleOpened = false;
this.reload.emit(true);
})
.catch(error=>{
if (error.status === 409) {
this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
} else {
this.inlineAlert.showInlineError(error);
}
console.error('Failed to create policy:' + error.status + ', error message:' + JSON.stringify(error['_body']));
});
}
updateReplicationRule(): void {
toPromise<ReplicationRule>(this.replicationService
.updateReplicationRule(this.getRuleByForm()))
.then(()=>{
this.translateService.get('REPLICATION.UPDATED_SUCCESS')
.subscribe(res=>this.errorHandler.info(res));
this.createEditRuleOpened = false;
this.reload.emit(true);
})
.catch(error=>{
if (error.status === 409) {
this.inlineAlert.showInlineError('REPLICATION.POLICY_ALREADY_EXISTS');
} else {
this.inlineAlert.showInlineError(error);
}
console.error('Failed to create policy and target:' + error.status + ', error message:' + JSON.stringify(error['_body']));
}
);
}
createWithEndpoint(actionType: ActionType): void {
toPromise<Endpoint>(this.endpointService
.createEndpoint(this.getEndpointByForm()))
.then(()=>{
toPromise<Endpoint[]>(this.endpointService
.getEndpoints(this.createEditRule.endpointName))
.then(endpoints=>{
if(endpoints && endpoints.length > 0) {
let addedEndpoint: Endpoint = endpoints[0];
this.createEditRule.endpointId = addedEndpoint.id;
switch(actionType) {
case ActionType.ADD_NEW:
this.createReplicationRule();
break;
case ActionType.EDIT:
this.updateReplicationRule();
break;
}
}
})
.catch(error=>{
this.inlineAlert.showInlineError(error);
this.errorHandler.error(error);
});
})
.catch(error=>{
this.inlineAlert.showInlineError(error);
this.errorHandler.error(error);
});
}
onSubmit() {
if(this.isCreateEndpoint) {
this.createWithEndpoint(this.actionType);
} else {
switch(this.actionType) {
case ActionType.ADD_NEW:
this.createReplicationRule();
break;
case ActionType.EDIT:
this.updateReplicationRule();
break;
}
}
}
onCancel() {
if(this.hasChanged) {
this.inlineAlert.showInlineConfirmation({message: 'ALERT.FORM_CHANGE_CONFIRMATION'});
} else {
this.createEditRuleOpened = false;
this.ruleForm.reset();
}
}
confirmCancel(confirmed: boolean) {
this.createEditRuleOpened = false;
this.inlineAlert.close();
this.ruleForm.reset();
}
ngAfterViewChecked(): void {
this.ruleForm = this.currentForm;
if(this.ruleForm) {
let comparison: {[key: string]: any} = {
targetName: this.initVal.name,
endpointUrl: this.initVal.endpointUrl,
username: this.initVal.username,
password: this.initVal.password
};
let self: CreateEditRuleComponent | any = this;
if(self) {
self.ruleForm.valueChanges.subscribe((data: any)=>{
for(let key in data) {
let origin = data[key];
let current = comparison[key];
if(((this.actionType === ActionType.EDIT && !this.readonly && !current ) || current) && current !== origin) {
this.hasChanged = true;
break;
} else {
this.hasChanged = false;
this.inlineAlert.close();
}
}
});
}
}
}
testConnection() {
this.pingStatus = true;
this.translateService.get('REPLICATION.TESTING_CONNECTION').subscribe(res=>this.pingTestMessage=res);
this.testOngoing = !this.testOngoing;
let pingTarget: Endpoint = this.initEndpoint;
if(this.isCreateEndpoint) {
pingTarget.endpoint = this.createEditRule.endpointUrl || '';
pingTarget.username = this.createEditRule.username;
pingTarget.password = this.createEditRule.password;
} else {
pingTarget.id = this.createEditRule.endpointId;
}
toPromise<Endpoint>(this.endpointService
.pingEndpoint(pingTarget))
.then(()=>{
this.testOngoing = !this.testOngoing;
this.translateService.get('REPLICATION.TEST_CONNECTION_SUCCESS').subscribe(res=>this.pingTestMessage=res);
this.pingStatus = true;
})
.catch(error=>{
this.testOngoing = !this.testOngoing;
this.translateService.get('REPLICATION.TEST_CONNECTION_FAILURE').subscribe(res=>this.pingTestMessage=res);
this.pingStatus = false;
});
}
}

View File

@ -0,0 +1,7 @@
import { Type } from '@angular/core';
import { CreateEditRuleComponent } from './create-edit-rule.component';
export const CREATE_EDIT_RULE_DIRECTIVES: Type<any>[] = [
CreateEditRuleComponent
];

View File

@ -163,13 +163,12 @@ export class EndpointComponent implements OnInit {
}
deleteTarget(target: Endpoint) {
console.log('Endpoint:' + JSON.stringify(target));
if (target) {
let targetId = target.id;
let deletionMessage = new ConfirmationMessage(
'REPLICATION.DELETION_TITLE_TARGET',
'REPLICATION.DELETION_SUMMARY_TARGET',
target.name,
target.name || '',
target.id,
ConfirmationTargets.TARGET,
ConfirmationButtons.DELETE_CANCEL);

View File

@ -7,6 +7,11 @@ import { REPOSITORY_DIRECTIVES } from './repository/index';
import { LIST_REPOSITORY_DIRECTIVES } from './list-repository/index';
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';
import { SERVICE_CONFIG, IServiceConfig } from './service.config';
@ -128,7 +133,11 @@ export function initConfig(translateService: TranslateService, config: IServiceC
TAG_DIRECTIVES,
CREATE_EDIT_ENDPOINT_DIRECTIVES,
CONFIRMATION_DIALOG_DIRECTIVES,
INLINE_ALERT_DIRECTIVES
INLINE_ALERT_DIRECTIVES,
REPLICATION_DIRECTIVES,
LIST_REPLICATION_RULE_DIRECTIVES,
LIST_REPLICATION_JOB_DIRECTIVES,
CREATE_EDIT_RULE_DIRECTIVES
],
exports: [
LOG_DIRECTIVES,
@ -139,7 +148,11 @@ export function initConfig(translateService: TranslateService, config: IServiceC
TAG_DIRECTIVES,
CREATE_EDIT_ENDPOINT_DIRECTIVES,
CONFIRMATION_DIALOG_DIRECTIVES,
INLINE_ALERT_DIRECTIVES
INLINE_ALERT_DIRECTIVES,
REPLICATION_DIRECTIVES,
LIST_REPLICATION_RULE_DIRECTIVES,
LIST_REPLICATION_JOB_DIRECTIVES,
CREATE_EDIT_RULE_DIRECTIVES
],
providers: []
})

View File

@ -5,4 +5,7 @@ export * from './error-handler/index';
//export * from './utils';
export * from './log/index';
export * from './filter/index';
export * from './endpoint/index';
export * from './endpoint/index';
export * from './repository/index';
export * from './tag/index';
export * from './replication/index';

View File

@ -0,0 +1,6 @@
import { Type } from '@angular/core';
import { ListReplicationJobComponent } from './list-replication-job.component';
export const LIST_REPLICATION_JOB_DIRECTIVES: Type<any>[] = [
ListReplicationJobComponent
];

View File

@ -0,0 +1 @@
export const REPLICATION_JOB_STYLE: string = ``;

View File

@ -0,0 +1,25 @@
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 *ngFor="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 | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{j.update_time | date: 'short'}}</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>
{{ totalRecordCount }} {{'REPLICATION.ITEMS' | translate}}
<clr-dg-pagination [clrDgPageSize]="pageOffset" [clrDgTotalItems]="totalPage"></clr-dg-pagination>
</clr-dg-footer>
</clr-datagrid>`;

View File

@ -0,0 +1,47 @@
// 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_STYLE } from './list-replication-job.component.css';
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);
}
}
}

View File

@ -0,0 +1,7 @@
import { Type } from '@angular/core';
import { ListReplicationRuleComponent } from './list-replication-rule.component';
export const LIST_REPLICATION_RULE_DIRECTIVES: Type<any>[] = [
ListReplicationRuleComponent
];

View File

@ -0,0 +1 @@
export const LIST_REPLICATION_RULE_STYLE: string = ``;

View File

@ -0,0 +1,37 @@
export const LIST_REPLICATION_RULE_TEMPLATE: string = `
<confirmation-dialog #toggleConfirmDialog (confirmAction)="toggleConfirm($event)"></confirmation-dialog>
<confirmation-dialog #deletionConfirmDialog (confirmAction)="deletionConfirm($event)"></confirmation-dialog>
<clr-datagrid>
<clr-dg-column>{{'REPLICATION.NAME' | translate}}</clr-dg-column>
<clr-dg-column *ngIf="projectless">{{'REPLICATION.PROJECT' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.LAST_START_TIME' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.ACTIVATION' | translate}}</clr-dg-column>
<clr-dg-row *clrDgItems="let p of rules" [clrDgItem]="p" (click)="selectRule(p)" [style.backgroundColor]="(!projectless && selectedId === p.id) ? '#eee' : ''">
<clr-dg-action-overflow>
<button class="action-item" (click)="editRule(p)">{{'REPLICATION.EDIT_POLICY' | translate}}</button>
<button class="action-item" (click)="toggleRule(p)">{{ (p.enabled === 0 ? 'REPLICATION.ENABLE' : 'REPLICATION.DISABLE') | translate}}</button>
<button class="action-item" (click)="deleteRule(p)">{{'REPLICATION.DELETE_POLICY' | translate}}</button>
</clr-dg-action-overflow>
<clr-dg-cell>
<ng-template [ngIf]="projectless">
<a href="javascript:void(0)">{{p.name}}</a>
</ng-template>
<ng-template [ngIf]="!projectless">
{{p.name}}
</ng-template>
</clr-dg-cell>
<clr-dg-cell *ngIf="projectless">{{p.project_name}}</clr-dg-cell>
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
<clr-dg-cell>{{p.target_name}}</clr-dg-cell>
<clr-dg-cell>
<ng-template [ngIf]="p.start_time === nullTime">-</ng-template>
<ng-template [ngIf]="p.start_time !== nullTime">{{p.start_time | date: 'short'}}</ng-template>
</clr-dg-cell>
<clr-dg-cell>
{{ (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-datagrid>`;

View File

@ -0,0 +1,135 @@
// 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, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { ReplicationService } from '../service/replication.service';
import { ReplicationRule } from '../service/interface';
import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
import { ConfirmationMessage } from '../confirmation-dialog/confirmation-message';
import { ConfirmationAcknowledgement } from '../confirmation-dialog/confirmation-state-message';
import { ConfirmationState, ConfirmationTargets, ConfirmationButtons } from '../shared/shared.const';
import { TranslateService } from '@ngx-translate/core';
import { ErrorHandler } from '../error-handler/error-handler';
import { toPromise } from '../utils';
import { LIST_REPLICATION_RULE_STYLE } from './list-replication-rule.component.css';
import { LIST_REPLICATION_RULE_TEMPLATE } from './list-replication-rule.component.html';
@Component({
selector: 'list-replication-rule',
template: LIST_REPLICATION_RULE_TEMPLATE,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ListReplicationRuleComponent {
nullTime: string = '0001-01-01T00:00:00Z';
@Input() rules: ReplicationRule[];
@Input() projectless: boolean;
@Input() selectedId: number | string;
@Output() reload = new EventEmitter<boolean>();
@Output() selectOne = new EventEmitter<ReplicationRule>();
@Output() editOne = new EventEmitter<ReplicationRule>();
@Output() toggleOne = new EventEmitter<ReplicationRule>();
@ViewChild('toggleConfirmDialog')
toggleConfirmDialog: ConfirmationDialogComponent;
@ViewChild('deletionConfirmDialog')
deletionConfirmDialog: ConfirmationDialogComponent;
constructor(
private replicationService: ReplicationService,
private translateService: TranslateService,
private errorHandler: ErrorHandler,
private ref: ChangeDetectorRef) {
setInterval(()=>ref.markForCheck(), 500);
}
toggleConfirm(message: ConfirmationAcknowledgement) {
if(message &&
message.source === ConfirmationTargets.TOGGLE_CONFIRM &&
message.state === ConfirmationState.CONFIRMED) {
let rule: ReplicationRule = message.data;
if(rule) {
rule.enabled = rule.enabled === 0 ? 1 : 0;
toPromise<any>(this.replicationService
.enableReplicationRule(rule.id || '', rule.enabled))
.then(() =>
this.translateService.get('REPLICATION.TOGGLED_SUCCESS')
.subscribe(res=>this.errorHandler.info(res)))
.catch(error => this.errorHandler.error(error));
}
}
}
deletionConfirm(message: ConfirmationAcknowledgement) {
if (message &&
message.source === ConfirmationTargets.POLICY &&
message.state === ConfirmationState.CONFIRMED) {
toPromise<any>(this.replicationService
.deleteReplicationRule(message.data))
.then(() => {
this.translateService.get('REPLICATION.DELETED_SUCCESS')
.subscribe(res=>this.errorHandler.info(res));
this.reload.emit(true);
})
.catch(error => {
if(error && error.status === 412) {
this.translateService.get('REPLICATION.FAILED_TO_DELETE_POLICY_ENABLED')
.subscribe(res=>this.errorHandler.error(res));
} else {
this.errorHandler.error(error);
}
});
}
}
selectRule(rule: ReplicationRule): void {
this.selectedId = rule.id || '';
this.selectOne.emit(rule);
}
editRule(rule: ReplicationRule) {
this.editOne.emit(rule);
}
toggleRule(rule: ReplicationRule) {
let toggleConfirmMessage: ConfirmationMessage = new ConfirmationMessage(
rule.enabled === 1 ? 'REPLICATION.TOGGLE_DISABLE_TITLE' : 'REPLICATION.TOGGLE_ENABLE_TITLE',
rule.enabled === 1 ? 'REPLICATION.CONFIRM_TOGGLE_DISABLE_POLICY': 'REPLICATION.CONFIRM_TOGGLE_ENABLE_POLICY',
rule.name || '',
rule,
ConfirmationTargets.TOGGLE_CONFIRM
);
this.toggleConfirmDialog.open(toggleConfirmMessage);
}
deleteRule(rule: ReplicationRule) {
let deletionMessage: ConfirmationMessage = new ConfirmationMessage(
'REPLICATION.DELETION_TITLE',
'REPLICATION.DELETION_SUMMARY',
rule.name || '',
rule.id,
ConfirmationTargets.POLICY,
ConfirmationButtons.DELETE_CANCEL);
this.deletionConfirmDialog.open(deletionMessage);
}
}

View File

@ -0,0 +1,6 @@
import { Type } from '@angular/core';
import { ReplicationComponent } from './replication.component';
export const REPLICATION_DIRECTIVES: Type<any>[] = [
ReplicationComponent
];

View File

@ -0,0 +1,18 @@
export const REPLICATION_STYLE: string = `
.option-left {
padding-left: 16px;
margin-top: 24px;
}
.option-right {
padding-right: 16px;
margin-top: 18px;
}
.option-left-down {
margin-top: 36px;
}
.option-right-down {
padding-right: 16px;
margin-top: 24px;
}`;

View File

@ -0,0 +1,63 @@
export const REPLICATION_TEMPLATE: string = `
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="row flex-items-xs-between">
<div class="flex-xs-middle option-left">
<button class="btn btn-link" (click)="openModal()"><clr-icon shape="add"></clr-icon> {{'REPLICATION.REPLICATION_RULE' | translate}}</button>
<create-edit-rule [projectId]="projectId" (reload)="reloadRules($event)"></create-edit-rule>
</div>
<div class="flex-xs-middle option-right">
<div class="select" style="float: left;">
<select (change)="doFilterRuleStatus($event)">
<option *ngFor="let r of ruleStatus" value="{{r.key}}">{{r.description | translate}}</option>
</select>
</div>
<hbr-filter filterPlaceholder='{{"REPLICATION.FILTER_POLICIES_PLACEHOLDER" | translate}}' (filter)="doSearchRules($event)" [currentValue]="search.ruleName"></hbr-filter>
<a href="javascript:void(0)" (click)="refreshRules()">
<clr-icon shape="refresh"></clr-icon>
</a>
</div>
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<list-replication-rule [rules]="changedRules" [projectless]="false" [selectedId]="initSelectedId" (selectOne)="selectOneRule($event)" (editOne)="openEditRule($event)" (reload)="reloadRules($event)"></list-replication-rule>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="row flex-items-xs-between">
<h5 class="flex-items-xs-bottom option-left-down" style="margin-left: 14px;">{{'REPLICATION.REPLICATION_JOBS' | 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 filterPlaceholder='{{"REPLICATION.FILTER_JOBS_PLACEHOLDER" | translate}}' (filter)="doSearchJobs($event)" [currentValue]="search.repoName" ></hbr-filter>
<a href="javascript:void(0)" (click)="refreshJobs()">
<clr-icon shape="refresh"></clr-icon>
</a>
</div>
</div>
<div class="row flex-items-xs-right option-right" [hidden]="currentJobSearchOption === 0">
<div class="select" style="float: left;">
<select (change)="doFilterJobStatus($event)">
<option *ngFor="let j of jobStatus" value="{{j.key}}" [selected]="currentJobStatus.key === j.key">{{j.description | translate}}</option>
</select>
</div>
<div class="flex-items-xs-middle">
<clr-icon shape="date"></clr-icon>
<label for="fromDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="fromTimeInvalid" class="tooltip tooltip-validation invalid tooltip-sm">
<input id="fromDateInput" type="date" #fromTime="ngModel" name="from" [(ngModel)]="search.startTime" dateValidator placeholder="dd/mm/yyyy" (change)="doJobSearchByStartTime(fromTime.value)">
<span *ngIf="fromTimeInvalid" class="tooltip-content">
{{'AUDIT_LOG.INVALID_DATE' | translate }}
</span>
</label>
<clr-icon shape="date"></clr-icon>
<label for="toDateInput" aria-haspopup="true" role="tooltip" [class.invalid]="toTimeInvalid" class="tooltip tooltip-validation invalid tooltip-sm">
<input id="toDateInput" type="date" #toTime="ngModel" name="to" [(ngModel)]="search.endTime" dateValidator placeholder="dd/mm/yyyy" (change)="doJobSearchByEndTime(toTime.value)">
<span *ngIf="toTimeInvalid" class="tooltip-content">
{{'AUDIT_LOG.INVALID_DATE' | translate }}
</span>
</label>
</div>
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<list-replication-job [jobs]="changedJobs" [totalPage]="jobsTotalPage" [totalRecordCount]="jobsTotalRecordCount" (paginate)="fetchReplicationJobs($event)"></list-replication-job>
</div>
</div>`;

View File

@ -0,0 +1,287 @@
// 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, OnInit, ViewChild, Input } from '@angular/core';
// import { ActivatedRoute } from '@angular/router';
import { ResponseOptions } from '@angular/http';
import { NgModel } from '@angular/forms';
import { CreateEditRuleComponent } from '../create-edit-rule/create-edit-rule.component';
import { ErrorHandler } from '../error-handler/error-handler';
import { ReplicationService } from '../service/replication.service';
import { RequestQueryParams } from '../service/RequestQueryParams';
// import { SessionUser } from '../shared/session-user';
import { ReplicationRule, ReplicationJob, Endpoint } from '../service/interface';
import { State } from 'clarity-angular';
import { toPromise } from '../utils';
import { TranslateService } from '@ngx-translate/core';
import { REPLICATION_STYLE } from './replication.component.css';
import { REPLICATION_TEMPLATE } from './replication.component.html';
const ruleStatus: {[key: string]: any} = [
{ 'key': 'all', 'description': 'REPLICATION.ALL_STATUS'},
{ 'key': '1', 'description': 'REPLICATION.ENABLED'},
{ 'key': '0', 'description': 'REPLICATION.DISABLED'}
];
const jobStatus: {[key: string]: any} = [
{ 'key': 'all', 'description': 'REPLICATION.ALL' },
{ 'key': 'pending', 'description': 'REPLICATION.PENDING' },
{ 'key': 'running', 'description': 'REPLICATION.RUNNING' },
{ 'key': 'error', 'description': 'REPLICATION.ERROR' },
{ 'key': 'retrying', 'description': 'REPLICATION.RETRYING' },
{ 'key': 'stopped' , 'description': 'REPLICATION.STOPPED' },
{ 'key': 'finished', 'description': 'REPLICATION.FINISHED' },
{ 'key': 'canceled', 'description': 'REPLICATION.CANCELED' }
];
const optionalSearch: {} = {0: 'REPLICATION.ADVANCED', 1: 'REPLICATION.SIMPLE'};
export class SearchOption {
ruleId: number | string;
ruleName: string = '';
repoName: string = '';
status: string = '';
startTime: string = '';
startTimestamp: string = '';
endTime: string = '';
endTimestamp: string = '';
page: number = 1;
pageSize: number = 5;
}
@Component({
selector: 'hbr-replication',
template: REPLICATION_TEMPLATE
})
export class ReplicationComponent implements OnInit {
@Input() projectId: number | string;
search: SearchOption = new SearchOption();
ruleStatus = ruleStatus;
currentRuleStatus: {key: string, description: string};
jobStatus = jobStatus;
currentJobStatus: {key: string, description: string};
changedRules: ReplicationRule[];
changedJobs: ReplicationJob[];
initSelectedId: number | string;
rules: ReplicationRule[];
jobs: ReplicationJob[];
jobsTotalRecordCount: number;
jobsTotalPage: number;
toggleJobSearchOption = optionalSearch;
currentJobSearchOption: number;
@ViewChild(CreateEditRuleComponent)
createEditPolicyComponent: CreateEditRuleComponent;
@ViewChild('fromTime') fromTimeInput: NgModel;
@ViewChild('toTime') toTimeInput: NgModel;
get fromTimeInvalid(): boolean {
return (this.fromTimeInput.errors && this.fromTimeInput.errors.dateValidator && (this.fromTimeInput.dirty || this.fromTimeInput.touched)) || false;
}
get toTimeInvalid(): boolean {
return (this.toTimeInput.errors && this.toTimeInput.errors.dateValidator && (this.toTimeInput.dirty || this.toTimeInput.touched)) || false;
}
constructor(
private errorHandler: ErrorHandler,
private replicationService: ReplicationService,
private translateService: TranslateService) {
}
ngOnInit(): void {
this.projectId = 1;
this.currentRuleStatus = this.ruleStatus[0];
this.currentJobStatus = this.jobStatus[0];
this.currentJobSearchOption = 0;
this.retrievePolicies();
// let isCreate = this.route.snapshot.parent.queryParams['is_create'];
// if (isCreate && <boolean>isCreate) {
// this.openModal();
// }
}
retrievePolicies(): void {
toPromise<ReplicationRule[]>(this.replicationService
.getReplicationRules(this.projectId, this.search.ruleName))
.then(response=>{
this.changedRules = response || [];
if(this.changedRules && this.changedRules.length > 0) {
this.initSelectedId = this.changedRules[0].id || '';
}
this.rules = this.changedRules;
if(this.changedRules && this.changedRules.length > 0) {
this.search.ruleId = this.changedRules[0].id || '';
this.fetchReplicationJobs();
}
},
error=>this.errorHandler.error(error)
);
}
openModal(): void {
this.createEditPolicyComponent.openCreateEditRule(true);
}
openEditRule(rule: ReplicationRule) {
if(rule) {
let editable = true;
if(rule.enabled === 1) {
editable = false;
}
this.createEditPolicyComponent.openCreateEditRule(editable, rule.id);
}
}
fetchReplicationJobs(state?: State) {
if(state && state.page && state.page.to) {
this.search.page = state.page.to + 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);
params.set('page', this.search.page + '');
params.set('page_size', this.search.pageSize + '');
toPromise<any>(this.replicationService
.getJobs(this.search.ruleId, params))
.then(
response=>{
this.jobsTotalRecordCount = response.headers.get('x-total-count');
this.jobsTotalPage = Math.ceil(this.jobsTotalRecordCount / this.search.pageSize);
this.changedJobs = response.json();
this.jobs = this.changedJobs;
for(let i = 0; i < this.jobs.length; i++) {
let j = this.jobs[i];
if(j.status == 'retrying' || j.status == 'error') {
this.translateService.get('REPLICATION.FOUND_ERROR_IN_JOBS')
.subscribe(res=>this.errorHandler.error(res));
break;
}
}
},
error=>this.errorHandler.error(error)
);
}
selectOneRule(rule: ReplicationRule) {
if(rule) {
this.search.ruleId = rule.id || '';
this.search.repoName = '';
this.search.status = '';
this.currentJobSearchOption = 0;
this.currentJobStatus = { 'key': 'all', 'description': 'REPLICATION.ALL' };
this.fetchReplicationJobs();
}
}
doSearchRules(ruleName: string) {
this.search.ruleName = ruleName;
this.retrievePolicies();
}
doFilterRuleStatus($event: any) {
if ($event && $event.target && $event.target["value"]) {
let status = $event.target["value"];
this.currentRuleStatus = this.ruleStatus.find((r: any)=>r.key === status);
if(this.currentRuleStatus.key === 'all') {
this.changedRules = this.rules;
} else {
this.changedRules = this.rules.filter(policy=>policy.enabled === +this.currentRuleStatus.key);
}
}
}
doFilterJobStatus($event: any) {
if ($event && $event.target && $event.target["value"]) {
let status = $event.target["value"];
this.currentJobStatus = this.jobStatus.find((r: any)=>r.key === status);
if(this.currentJobStatus.key === 'all') {
status = '';
}
this.search.status = status;
this.doSearchJobs(this.search.repoName);
}
}
doSearchJobs(repoName: string) {
this.search.repoName = repoName;
this.fetchReplicationJobs();
}
reloadRules(isReady: boolean) {
if(isReady) {
this.search.ruleName = '';
this.retrievePolicies();
}
}
refreshRules() {
this.retrievePolicies();
}
refreshJobs() {
this.fetchReplicationJobs();
}
toggleSearchJobOptionalName(option: number) {
(option === 1) ? this.currentJobSearchOption = 0 : this.currentJobSearchOption = 1;
}
convertDate(strDate: string): string {
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*/;
}
return strDate;
}
doJobSearchByStartTime(strDate: string) {
this.search.startTimestamp = '';
if(this.fromTimeInput.valid && strDate) {
strDate = this.convertDate(strDate);
this.search.startTimestamp = new Date(strDate).getTime() / 1000 + '';
}
this.fetchReplicationJobs();
}
doJobSearchByEndTime(strDate: string) {
this.search.endTimestamp = '';
if(this.toTimeInput.valid && strDate) {
strDate = this.convertDate(strDate);
let oneDayOffset = 3600 * 24;
this.search.endTimestamp = (new Date(strDate).getTime() / 1000 + oneDayOffset) + '';
}
this.fetchReplicationJobs();
}
}

View File

@ -75,8 +75,8 @@ export interface Tag extends Base {
export interface Endpoint extends Base {
endpoint: string;
name: string;
username: string;
password: string;
username?: string;
password?: string;
type: number;
}
@ -87,9 +87,9 @@ export interface Endpoint extends Base {
* @interface ReplicationRule
*/
export interface ReplicationRule extends Base {
project_id: number;
project_id: number | string;
project_name: string;
target_id: number;
target_id: number | string;
target_name: string;
enabled: number;
description?: string;

View File

@ -84,7 +84,7 @@ export abstract class ReplicationService {
*
* @memberOf ReplicationService
*/
abstract enableReplicationRule(ruleId: number | string): Observable<any> | Promise<any> | any;
abstract enableReplicationRule(ruleId: number | string, enablement: number): Observable<any> | Promise<any> | any;
/**
* Disable the specified replication rule.
@ -113,7 +113,7 @@ export abstract class ReplicationService {
*
* @memberOf ReplicationService
*/
abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable<ReplicationJob[]> | Promise<ReplicationJob[]> | ReplicationJob[];
abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable<ReplicationJob[]> | Promise<ReplicationJob[]> | ReplicationJob[] | Promise<any>;
}
/**
@ -169,7 +169,7 @@ export class ReplicationDefaultService extends ReplicationService {
}
let url: string = `${this._ruleBaseUrl}/${ruleId}`;
return this.http.get(url, HTTP_JSON_OPTIONS).toPromise()
return this.http.get(url).toPromise()
.then(response => response.json() as ReplicationRule)
.catch(error => Promise.reject(error));
}
@ -206,13 +206,13 @@ export class ReplicationDefaultService extends ReplicationService {
.catch(error => Promise.reject(error));
}
public enableReplicationRule(ruleId: number | string): Observable<any> | Promise<any> | any {
public enableReplicationRule(ruleId: number | string, enablement: number): Observable<any> | Promise<any> | any {
if (!ruleId || ruleId <= 0) {
return Promise.reject('Bad argument');
}
let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`;
return this.http.put(url, { enabled: 1 }, HTTP_JSON_OPTIONS).toPromise()
return this.http.put(url, { enabled: enablement }, HTTP_JSON_OPTIONS).toPromise()
.then(response => response)
.catch(error => Promise.reject(error));
}
@ -228,7 +228,7 @@ export class ReplicationDefaultService extends ReplicationService {
.catch(error => Promise.reject(error));
}
public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable<ReplicationJob[]> | Promise<ReplicationJob[]> | ReplicationJob[] {
public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable<ReplicationJob[]> | Promise<ReplicationJob[]> | ReplicationJob[] | Promise<any> {
if (!ruleId || ruleId <= 0) {
return Promise.reject('Bad argument');
}
@ -239,7 +239,7 @@ 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 => response)
.catch(error => Promise.reject(error));
}
}