Commit 791004c1 authored by pfh's avatar pfh
Browse files

Add username adn pwd for target and unselected project name and target first time

parent 6f857411
Showing with 211 additions and 102 deletions
+211 -102
......@@ -241,15 +241,16 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this.onGoing = false;
this.close();
}).catch(error => {
this.onGoing = false;
let errorMessageKey = this.handleErrorMessageKey(error.status);
this.translateService
.get(errorMessageKey)
.subscribe(res => {
this.inlineAlert.showInlineError(res);
this.onGoing = false;
});
}
);
this.forceRefreshView(1000);
}
updateEndpoint() {
......@@ -295,6 +296,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this.onGoing = false;
}
);
this.forceRefreshView(100);
}
handleErrorMessageKey(status: number): string {
......
......@@ -13,14 +13,14 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
<clr-dg-column [clrDgField]="'targets'">{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.TRIGGER_MODE' | 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-cell (click)="selectRule(p)">{{p.name}}</clr-dg-cell>
<clr-dg-cell *ngIf="!projectScope" (click)="selectRule(p)">
<a href="javascript:void(0)" (click)="redirectTo(p)">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
<clr-dg-row *clrDgItems="let p of changedRules" [clrDgItem]="p" (click)="selectRule(p)" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
<clr-dg-cell>{{p.name}}</clr-dg-cell>
<clr-dg-cell *ngIf="!projectScope">
<a href="javascript:void(0)">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
</clr-dg-cell>
<clr-dg-cell (click)="selectRule(p)">{{p.description ? p.description : '-'}}</clr-dg-cell>
<clr-dg-cell (click)="selectRule(p)">{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>
<clr-dg-cell (click)="selectRule(p)">{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
<clr-dg-cell>{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>
<clr-dg-cell>{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<span *ngIf="pagination.totalItems">{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'REPLICATION.OF' | translate}} </span>{{pagination.totalItems }} {{'REPLICATION.ITEMS' | translate}}
......
......@@ -187,7 +187,6 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
selectRule(rule: ReplicationRule): void {
this.selectedId = rule.id || '';
this.selectedRow = null;
this.selectOne.emit(rule);
}
......
......@@ -31,7 +31,7 @@
"clarity-icons": "^0.10.17",
"clarity-ui": "^0.10.17",
"core-js": "^2.4.1",
"harbor-ui": "0.6.30",
"harbor-ui": "0.6.32",
"intl": "^1.2.5",
"mutationobserver-shim": "^0.3.2",
"ngx-cookie": "^1.0.0",
......
......@@ -8,7 +8,7 @@
<label for="create_project_name" class="col-md-3 form-group-label-override required">{{'PROJECT.NAME' | translate}}</label>
<label for="create_project_name" aria-haspopup="true" role="tooltip" [class.invalid]="!isNameValid" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<input type="text" id="create_project_name" [(ngModel)]="project.name"
name="create_project_name" size="255"
name="create_project_name" size="255" style="width: 296px;"
required
pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
minlength="2"
......
<clr-modal [(clrModalOpen)]="ismodelOpen">
<clr-modal [(clrModalOpen)]="ismodelOpen" [clrModalClosable]="false">
<h3 class="modal-title">{{'PROJECT.ALL_PROJECTS' | translate}}</h3>
<inline-alert class="modal-title" ></inline-alert>
<div class="modal-body">
......
......@@ -17,6 +17,7 @@ import {CreateEditEndpointComponent} from "harbor-ui/src/create-edit-endpoint/cr
const ONE_HOUR_SECONDS: number = 3600;
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
const FAKE_PASSWORD = 'rjGcfuRu';
@Component ({
selector: 'repliction-rule',
......@@ -33,11 +34,12 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
weeklySchedule: boolean;
isScheduleOpt: boolean;
isImmediate: boolean = true;
noProjectInfo: string;
noEndpointInfo: boolean;
noProjectInfo: string = "";
noSelectedProject: boolean = true;
noSelectedEndpoint: boolean = true;
filterCount: number = 0;
selectedprojectList: Project[] = [];
triggerNames: string[] = ['Immediate', 'Scheduled', 'Manual'];
triggerNames: string[] = ['Manual', 'Immediate', 'Scheduled'];
scheduleNames: string[] = ['Daily', 'Weekly'];
weekly: string[] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
filterSelect: string[] = ['repository', 'tag'];
......@@ -50,6 +52,8 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
isRuleNameExist: boolean = false;
isSubmitOver: boolean = false;
nameChecker: Subject<string> = new Subject<string>();
firstEndpointData: { [key: string]: string };
realEndpointData: { [key: string]: string } = this.initEndpointData();
confirmSub: Subscription;
ruleForm: FormGroup;
......@@ -61,6 +65,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
@ViewChild(CreateEditEndpointComponent)
createEditEndpointComponent: CreateEditEndpointComponent;
baseFilterData(name: string, option: string[], state: boolean) {
return {
name: name,
......@@ -70,6 +75,13 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
};
}
initEndpointData(): { [key: string]: string } {
return{
userName: "",
password: ""
};
}
constructor(public projectService: ProjectService,
private router: Router,
private fb: FormBuilder,
......@@ -83,11 +95,14 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
Promise.all([this.repService.getEndpoints(), this.repService.listProjects()])
.then(res => {
if (!res[0]) {
this.noEndpointInfo = true;
this.noSelectedEndpoint = true;
}else {
this.targetList = res[0];
if (!this.policyId) {
this.setTarget([res[0][0]]);
this.realEndpointData.userName = res[0][0].username;
this.realEndpointData.password = FAKE_PASSWORD;
this.firstEndpointData = Object.assign({}, this.realEndpointData);
}
}
if (!res[1]) {
......@@ -98,6 +113,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
if (!this.policyId && this.projectId) {
this.setProject( res[1].filter(rule => rule.project_id === this.projectId));
this.noSelectedProject = false;
}
}
if (!this.policyId) {
......@@ -148,7 +164,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
get isVaild() {
return !(this.isRuleNameExist || this.noProjectInfo || this.noEndpointInfo || this.inProgress || this.isSubmitOver);
return !(this.isRuleNameExist || this.noSelectedProject || this.noSelectedEndpoint || this.inProgress || this.isSubmitOver);
}
createForm() {
......@@ -169,7 +185,6 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
replicate_existing_image_now: true,
replicate_deletion: false
});
}
updateForm(rule: ReplicationRule): void {
......@@ -182,7 +197,14 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
replicate_deletion: rule.replicate_deletion
});
this.setProject(rule.projects);
this.noSelectedProject = false;
this.setTarget(rule.targets);
this.noSelectedEndpoint = false;
this.realEndpointData.userName = rule.targets[0].username;
this.realEndpointData.password = FAKE_PASSWORD;
this.firstEndpointData = Object.assign({}, this.realEndpointData);
if (rule.filters) {
this.setFilter(rule.filters);
this.updateFilter(rule.filters);
......@@ -250,6 +272,9 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
if ($event && $event.target && event.target['value']) {
let selecedTarget: Target = this.targetList.find(target => target.id === +$event.target['value']);
this.setTarget([selecedTarget]);
this.noSelectedEndpoint = false;
this.realEndpointData.userName = selecedTarget.username;
this.firstEndpointData = Object.assign({}, this.realEndpointData);
}
}
......@@ -258,7 +283,12 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
selectedProject(project: Project): void {
this.setProject([project]);
if (!project) {
this.noSelectedProject = true;
}else {
this.noSelectedProject = false;
this.setProject([project]);
}
}
addNewFilter(): void {
......@@ -308,15 +338,15 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
selectTrigger($event: any): void {
if ($event && $event.target && $event.target['value']) {
let val: string = $event.target['value'];
if (val === this.triggerNames[1]) {
if (val === this.triggerNames[2]) {
this.isScheduleOpt = true;
this.isImmediate = false;
}
if (val === this.triggerNames[0]) {
if (val === this.triggerNames[1]) {
this.isScheduleOpt = false;
this.isImmediate = true;
}
if (val === this.triggerNames[2]) {
if (val === this.triggerNames[0]) {
this.isScheduleOpt = false;
this.isImmediate = false;
}
......@@ -381,7 +411,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
trigger['schedule_param']['weekday'] = 1;
}
}else {
if (trigger['kind'] === this.triggerNames[2]) {
if (trigger['kind'] === this.triggerNames[0]) {
this.isImmediate = false;
}
trigger['schedule_param'] = { type: this.scheduleNames[0],
......@@ -412,50 +442,86 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
onSubmit() {
// add new Replication rule
this.inProgress = true;
let endpointId: string | number = this.ruleForm.value.targets[0].id;
let pullData: { [key: string]: string | number } = this.initEndpointData();
if (compareValue(this.firstEndpointData, this.realEndpointData)) {
this.saveRuleOpe();
}else {
if (this.realEndpointData.userName !== this.firstEndpointData.userName) {
pullData.userName = this.realEndpointData.userName;
}else {
delete pullData.userName;
}
if (this.realEndpointData.password !== this.firstEndpointData.password) {
pullData.password = this.realEndpointData.password;
}else {
delete pullData.password;
}
pullData.id = endpointId;
this.repService.pingEndpoint(pullData)
.then((res: any) => {
delete pullData.id;
this.repService.updateEndpoint(endpointId, pullData)
.then((res: any) => {
this.saveRuleOpe();
})
.catch((error: any) => {
this.inProgress = false;
this.msgHandler.handleError(error);
});
})
.catch((error: any) => {
this.inProgress = false;
this.msgHandler.handleError('DESTINATION.TEST_CONNECTION_FAILURE');
return false;
});
}
}
saveRuleOpe(): void {
// add new Replication rule
let copyRuleForm: ReplicationRule = this.ruleForm.value;
copyRuleForm.trigger = this.setTriggerVaule(copyRuleForm.trigger);
if (!this.policyId) {
this.repService.createReplicationRule(copyRuleForm)
.then(() => {
this.msgHandler.showSuccess('REPLICATION.CREATED_SUCCESS');
this.inProgress = false;
this.isSubmitOver = true;
setTimeout(() => {
this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
if (this.projectId) {
this.router.navigate(['harbor/projects', this.projectId, 'replications']);
}else {
this.router.navigate(['/harbor/replications']);
}
}, 2000);
this.msgHandler.showSuccess('REPLICATION.CREATED_SUCCESS');
this.inProgress = false;
this.isSubmitOver = true;
setTimeout(() => {
this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
if (this.projectId) {
this.router.navigate(['harbor/projects', this.projectId, 'replications']);
}else {
this.router.navigate(['/harbor/replications']);
}
}, 2000);
}).catch((error: any) => {
}).catch((error: any) => {
this.inProgress = false;
this.msgHandler.handleError(error);
});
} else {
this.repService.updateReplicationRule(this.policyId, this.ruleForm.value)
.then(() => {
this.msgHandler.showSuccess('REPLICATION.UPDATED_SUCCESS');
this.inProgress = false;
this.isSubmitOver = true;
setTimeout(() => {
this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
if (this.projectId) {
this.router.navigate(['harbor/projects', this.projectId, 'replications']);
}else {
this.router.navigate(['/harbor/replications']);
}
}, 2000);
this.msgHandler.showSuccess('REPLICATION.UPDATED_SUCCESS');
this.inProgress = false;
this.isSubmitOver = true;
setTimeout(() => {
this.copyUpdateForm = Object.assign({}, this.ruleForm.value);
if (this.projectId) {
this.router.navigate(['harbor/projects', this.projectId, 'replications']);
}else {
this.router.navigate(['/harbor/replications']);
}
}, 2000);
}).catch((error: any) => {
}).catch((error: any) => {
this.inProgress = false;
this.msgHandler.handleError(error);
});
}
}
openModal() {
......@@ -467,8 +533,10 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
Promise.all([this.repService.getEndpoints()]).then(res => {
this.targetList = res[0];
this.setTarget([this.targetList[this.targetList.length - 1]]);
this.noSelectedEndpoint = false;
this.realEndpointData.userName = this.targetList[this.targetList.length - 1].username;
this.firstEndpointData = Object.assign({}, this.realEndpointData);
});
this.noEndpointInfo = false;
}
}
......
......@@ -23,9 +23,11 @@ label:first-child {
font-size: 15px;
left: -10px !important;
}
.endpointSelect{ width: 290px;}
.filterSelect{width: 320px;}
.filterSelect label{width: 160px;}
.inputWidth{width: 310px;}
.endpointSelect{ width: 290px; margin-right: 34px;}
.filterSelect{width: 350px;}
.filterSelect clr-icon{margin-left: 10px;}
.filterSelect label{width: 175px;}
.filterSelect label input{width: 100%;}
.cursor{cursor: pointer;}
.pull-left{float: left;}
......@@ -34,7 +36,9 @@ label:first-child {
.form-group{ min-height: 36px;}
.projectInput{float: left;}
.projectInput input{width: 185px;background-color: white;}
.switchIcon{width:20px;height:20px; margin-top: 2px;margin-left: 5px;}
.addEndpoint{ display: inline-block; line-height: 20px; margin-top: 8px;
vertical-align: bottom; padding-left:10px; cursor: pointer;}
\ No newline at end of file
.projectInput input{background-color: white;}
.switchIcon{width:20px;height:20px; margin-top: 16px;margin-left: 10px;}
.addEndpoint{ margin-top: .25em !important;}
.shadow{position: absolute;top: 8px;}
.shadow1{width:270px; height: 24px;background-color: #fafafa; z-index: 10; top:5px;}
.hoverBg:hover{display: none;}
\ No newline at end of file
......@@ -2,37 +2,37 @@
<a class="cursor" *ngIf="!projectId" (click)="backReplication()">< {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}}</a>
<a class="cursor" *ngIf="projectId" (click)="backProjectReplication()"><{{'SIDE_NAV.PROJECTS' | translate}} &nbsp; {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate | lowercase}}</a>
<h1 class="sub-header-title">{{headerTitle | translate}}</h1>
<form [formGroup]="ruleForm" (ngSubmit)="onSubmit()" novalidate>
<form [formGroup]="ruleForm" novalidate>
<section class="form-block">
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.NAME' | translate}}<span class="colorRed">*</span></label>
<label class="col-md-8" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
[class.invalid]='(ruleForm.controls.name.touched && ruleForm.controls.name.invalid) || isRuleNameExist'>
<input type="text" id="ruleName" required formControlName="name" #ruleName (keyup)='checkRuleName()' autocomplete="off">
<input type="text" id="ruleName" class="inputWidth" required maxlength="255" formControlName="name" #ruleName (keyup)='checkRuleName()' autocomplete="off">
<span class="tooltip-content">{{ruleNameTooltip | translate}}</span>
</label><span class="spinner spinner-inline spinner-pos" [hidden]="!inNameChecking"></span>
</div>
<!--Description-->
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.DESCRIPTION' | translate}}</label>
<textarea type="text" id="ruleDescription" style=" width: 355px;" row= 3; formControlName="description"></textarea>
<textarea type="text" id="ruleDescription" class="inputWidth" row= 3; formControlName="description"></textarea>
</div>
<!--Projects-->
<h4>{{'REPLICATION.SOURCE' | translate}}</h4>
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'PROJECT.PROJECTS' | translate}}<span class="colorRed">*</span></label>
<div formArrayName="projects">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.SOURCE' | translate}}&nbsp;{{'PROJECT.PROJECTS' | translate | lowercase}}<span class="colorRed">*</span></label>
<div formArrayName="projects" [style.visibility]="noSelectedProject?'hidden':'visible'">
<div class="projectInput" *ngFor="let project of projects.controls; let i= index" [formGroupName]="i">
<input formControlName="name" class="label" readonly value="name">
<input formControlName="name" type="text" class="inputWidth" disabled value="name">
</div>
</div>
<clr-icon *ngIf="!(noProjectInfo || projectId)" shape="search" class="is-solid switchIcon" (click)="openProjectModel()"></clr-icon>
<label *ngIf="noProjectInfo" class="colorRed">{{noProjectInfo | translate}}</label>
<clr-icon *ngIf="!(noProjectInfo.length !=0 || projectId)" shape="search" class="is-solid switchIcon" (click)="openProjectModel()"></clr-icon>
<label *ngIf="noProjectInfo.length != 0" class="colorRed">{{noProjectInfo | translate}}</label>
<div class="shadow" [hidden]="!noSelectedProject || noProjectInfo.length != 0"><input type="text" class="inputWidth" disabled ></div>
</div>
<!--images/Filter-->
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.FILTER' | translate}}</label>
<label class="col-md-4 form-group-label-override">{{'REPLICATION.SOURCE_IMAGES_FILTER' | translate}}</label>
<div formArrayName="filters">
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index" [formGroupName]="i">
<div>
......@@ -53,43 +53,44 @@
<clr-icon shape="plus-circle" class="is-solid" [hidden]="isFilterHide" (click)="addNewFilter()" style="margin-top: 11px;"></clr-icon>
</div>
<!--Targets-->
<h4>{{'REPLICATION.TARGETS' | translate}}</h4>
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'DESTINATION.ENDPOINT' | translate}} <span class="colorRed">*</span></label>
<div formArrayName="targets">
<div class="select endpointSelect pull-left" *ngFor="let target of targets.controls; let i= index" [formGroupName]="i">
<select id="ruleTarget" (change)="targetChange($event)" formControlName="id">
<select id="ruleTarget " class="inputWidth" (mouseenter)="noSelectedEndpoint= false" (change)="targetChange($event)" formControlName="id">
<option *ngFor="let target of targetList" value="{{target.id}}">{{target.name}}: {{target.endpoint}}</option>
</select>
</div>
<a class="addEndpoint" (click)="openModal()"><clr-icon shape="plus" style="vertical-align: sub;"></clr-icon>{{'REPLICATION.NEW' | translate}}</a>
</div>
<button class="btn btn-info btn-sm addEndpoint" (click)="openModal()"><clr-icon shape="plus"></clr-icon>&nbsp;{{'REPLICATION.NEW' | translate}}</button>
<div [hidden]="noSelectedEndpoint">userName: &nbsp;&nbsp;<input type="text" [(ngModel)]="realEndpointData.userName" [ngModelOptions]="{standalone:true}"></div>
<div [hidden]="noSelectedEndpoint">password: &nbsp;&nbsp;<input type="password" [(ngModel)]="realEndpointData.password" [ngModelOptions]="{standalone:true}"></div>
</div>
<div class="shadow shadow1 hoverBg" #shadowDiv [hidden]="!noSelectedEndpoint || !targetList.length"></div>
</div>
<!--Trigger-->
<h4>{{'REPLICATION.TRIGGER' | translate}}</h4>
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.MODE' | translate}}</label>
<label class="col-md-4 form-group-label-override">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
<div formGroupName="trigger">
<!--on trigger-->
<div class="select floatSet pull-left">
<div class="select floatSet">
<select id="ruleTrigger" formControlName="kind" (change)="selectTrigger($event)">
<option value="Manual">{{'REPLICATION.MANUAL' | translate}}</option>
<option value="Immediate">{{'REPLICATION.IMMEDIATE' | translate}}</option>
<option value="Scheduled">{{'REPLICATION.SCHEDULE' | translate}}</option>
<option value="Manual">{{'REPLICATION.MANUAL' | translate}}</option>
</select>
</div>
<!--on push-->
<div style="float: left;" formGroupName="schedule_param">
<div class="select floatSet pull-left" [hidden]="!isScheduleOpt">
<div formGroupName="schedule_param">
<div class="select floatSet" [hidden]="!isScheduleOpt">
<select name="scheduleType" formControlName="type" (change)="selectSchedule($event)">
<option value="Daily">{{'REPLICATION.DAILY' | translate}}</option>
<option value="Weekly">{{'REPLICATION.WEEKLY' | translate}}</option>
</select>
</div>
<!--weekly-->
<span style="float: left;" [hidden]="!weeklySchedule || !isScheduleOpt">on &nbsp;&nbsp;</span>
<div [hidden]="!weeklySchedule || !isScheduleOpt" class="select floatSet pull-left">
<span [hidden]="!weeklySchedule || !isScheduleOpt">on &nbsp;&nbsp;</span>
<div [hidden]="!weeklySchedule || !isScheduleOpt" class="select floatSet">
<select name="scheduleDay" formControlName="weekday">
<option value="1">{{'WEEKLY.MONDAY' | translate}}</option>
<option value="2">{{'WEEKLY.TUESDAY' | translate}}</option>
......@@ -110,22 +111,18 @@
{{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}
</clr-checkbox>
</div>
</div>
<!--Setting-->
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'REPLICATION.SETTING' | translate}}</label>
<div class="col-lg-7 padLeft0">
<clr-checkbox [clrChecked]="true" id="ruleExit" formControlName="replicate_existing_image_now">
{{'REPLICATION.REPLICATE_IMMEDIATE' | translate}}
</clr-checkbox>
</div>
<div style="width: 100%;" >
<clr-checkbox [clrChecked]="true" id="ruleExit" formControlName="replicate_existing_image_now">
{{'REPLICATION.REPLICATE_IMMEDIATE' | translate}}
</clr-checkbox>
</div>
</div>
<div class="offset-md-4">
<span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
<br>
<button type="button" id="ruleBtnCancel" class="btn btn-outline" [disabled]="!hasFormChange()" (click)="onCancel()">{{ 'BUTTON.CANCEL' | translate }}</button>
<button type="submit" id="ruleBtnOk" class="btn btn-primary" [disabled]="!ruleForm.valid || !isVaild || !hasFormChange()">{{ 'BUTTON.OK' | translate }}</button>
<button type="button" id="ruleBtnCancel" class="btn btn-outline" [disabled]="!hasFormChange() || this.inProgress || this.isSubmitOver" (click)="onCancel()">{{ 'BUTTON.CANCEL' | translate }}</button>
<button type="submit" id="ruleBtnOk" class="btn btn-primary" (click)="onSubmit()" [disabled]="!ruleForm.valid || !isVaild || !hasFormChange()">{{ 'BUTTON.OK' | translate }}</button>
</div><!-- [disabled]="!ruleForm.valid"-->
</section>
</form>
......
......@@ -72,4 +72,31 @@ export class ReplicationRuleServie {
.catch(error => Promise.reject(error));
}
public updateEndpoint(endpointId: number | string, endpoint: any): Promise<any> | any {
if (!endpointId || endpointId <= 0) {
return Promise.reject('Bad request argument.');
}
if (!endpoint) {
return Promise.reject('Invalid endpoint.');
}
let requestUrl: string = `/api/targets/${endpointId}`;
return this.http
.put(requestUrl, JSON.stringify(endpoint), HTTP_JSON_OPTIONS)
.toPromise()
.then(response=>response.status)
.catch(error=>Promise.reject(error));
}
public pingEndpoint(endpoint: any): Promise<any> | any {
if (!endpoint) {
return Promise.reject('Invalid endpoint.');
}
let requestUrl: string = `/api/targets/ping`;
return this.http
.post(requestUrl, endpoint, HTTP_JSON_OPTIONS)
.toPromise()
.then(response=>response.status)
.catch(error=>Promise.reject(error));
}
}
......@@ -4,15 +4,26 @@ import {Project} from "../../project/project";
*/
export class Target {
id: 0;
endpoint: 'string';
name: 'string';
username: 'string';
password: 'string';
type: 0;
id: number;
endpoint: string;
name: string;
username: string;
password: string;
type: number;
insecure: true;
creation_time: 'string';
update_time: 'string';
creation_time: string;
update_time: string;
constructor() {
this.id = -1;
this.endpoint = "";
this.name = "";
this.username = "";
this.password = "";
this.type = 0;
this.insecure = true;
this.creation_time = "";
this.update_time = "";
}
}
export class Filter {
......
......@@ -277,6 +277,7 @@ export class UserComponent implements OnInit, OnDestroy {
//Refresh the user list
refreshUser(from: number, to: number): void {
this.selectedRow = [];
//Start to get
this.currentTerm = '';
this.onGoing = true;
......
......@@ -324,7 +324,7 @@
"JOB_LOG_VIEWER": "View Replication Job Log",
"NO_ENDPOINT_INFO": "Please go to registries and add an endpoint first",
"NO_PROJECT_INFO": "Please go to projects and add a project name first",
"FILTER": "Filter",
"SOURCE_IMAGES_FILTER": "Source images filter",
"SCHEDULE": "Scheduled",
"MANUAL": "Manual",
"IMMEDIATE": "Immediate",
......
......@@ -324,7 +324,7 @@
"JOB_LOG_VIEWER": "View Replication Job Log",
"NO_ENDPOINT_INFO": "Please go to registries and add an endpoint first",
"NO_PROJECT_INFO": "Please go to projects and add a project name first",
"FILTER": "Filter",
"SOURCE_IMAGES_FILTER": "Source images filter",
"SCHEDULE": "Scheduled",
"MANUAL": "Manual",
"IMMEDIATE": "Immediate",
......
......@@ -324,7 +324,7 @@
"JOB_LOG_VIEWER": "查看复制任务日志",
"NO_ENDPOINT_INFO": "请先添加目标",
"NO_PROJECT_INFO": "请先去项目添加一个新的项目名称",
"FILTER": "过滤",
"SOURCE_IMAGES_FILTER": "源镜像过滤",
"SCHEDULE": "定时",
"MANUAL": "手动",
"IMMEDIATE": "即刻",
......@@ -335,7 +335,7 @@
"TARGETS":"目标",
"MODE": "模式",
"TRIGGER_MODE": "触发模式",
"SOURCE": "源",
"SOURCE": "源",
"REPLICATE": "复制",
"DELETE_REMOTE_IMAGES":"删除本地镜像时同时也删除远程的镜像。",
"REPLICATE_IMMEDIATE":"立即复制现有的镜像。",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment