Merge pull request #4172 from pengpengshui/batchDelection

Modify replication list unsave when modify username or possword
This commit is contained in:
pengpengshui 2018-01-29 19:10:25 +08:00 committed by GitHub
commit f4270213ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 38 additions and 25 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -102,7 +102,7 @@ You can add members with different roles to an existing project. You can add a L
![browse project](img/new_add_member.png)
### Updating and removing members
You can update or remove a member by clicking the icon on the left.
You can check one or more members, then click `MEMBER ACTION`, choose one role to batch switch checked members's roles. You can also click `MEMBER.REMOVE` to batch remove checked members.
![browse project](img/new_remove_update_member.png)
@ -162,7 +162,7 @@ Entering a keyword in the search field at the top lists all matching projects an
## Administrator options
### Managing user
Administrator can add "Administrator" role to an ordinary user by click button on the left and select "Set as Administrator". To delete a user, select "Delete". Deleting user is only supported under database authentication mode.
Administrator can add "Administrator" role to one or more ordinary users by checking checkboxes and clicking `SET AS ADMINISTRATOR`. To delete users, checked checkboxes and select `DELETE`. Deleting user is only supported under database authentication mode.
![browse project](img/new_set_admin_remove_user.png)

View File

@ -170,7 +170,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
//Open the modal now
this.open();
this.forceRefreshView(1000);
this.forceRefreshView(2000);
})
.catch(error => this.errorHandler.error(error));
} else {
@ -208,12 +208,12 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
.then(
response => {
this.inlineAlert.showInlineSuccess({ message: "DESTINATION.TEST_CONNECTION_SUCCESS" });
this.forceRefreshView(1000);
this.forceRefreshView(2000);
this.testOngoing = false;
}).catch(
error => {
this.inlineAlert.showInlineError('DESTINATION.TEST_CONNECTION_FAILURE');
this.forceRefreshView(1000);
this.forceRefreshView(2000);
this.testOngoing = false;
});
}
@ -240,6 +240,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this.reload.emit(true);
this.onGoing = false;
this.close();
this.forceRefreshView(2000);
}).catch(error => {
this.onGoing = false;
let errorMessageKey = this.handleErrorMessageKey(error.status);
@ -248,10 +249,10 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
.subscribe(res => {
this.inlineAlert.showInlineError(res);
});
this.forceRefreshView(1000);
this.forceRefreshView(2000);
}
);
this.forceRefreshView(1000);
}
updateEndpoint() {
@ -285,6 +286,7 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this.reload.emit(true);
this.close();
this.onGoing = false;
this.forceRefreshView(2000);
})
.catch(
error => {
@ -295,10 +297,10 @@ export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy
this.inlineAlert.showInlineError(res);
});
this.onGoing = false;
this.forceRefreshView(1000);
this.forceRefreshView(2000);
}
);
this.forceRefreshView(1000);
}
handleErrorMessageKey(status: number): string {

View File

@ -16,7 +16,7 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
<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>
<a href="javascript:void(0)" (click)="redirectTo(p)">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
</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>

View File

@ -66,6 +66,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
@Output() selectOne = new EventEmitter<ReplicationRule>();
@Output() editOne = new EventEmitter<ReplicationRule>();
@Output() toggleOne = new EventEmitter<ReplicationRule>();
@Output() hideJobs = new EventEmitter<any>();
@Output() redirect = new EventEmitter<ReplicationRule>();
@Output() openNewRule = new EventEmitter<any>();
@Output() replicateManual = new EventEmitter<ReplicationRule[]>();
@ -132,6 +133,8 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
if (this.rules && this.rules.length > 0) {
this.selectedId = this.rules[0].id || '';
this.selectOne.emit(this.rules[0]);
} else {
this.hideJobs.emit();
}
this.changedRules = this.rules;
this.selectedRow = this.changedRules[0];

View File

@ -11,7 +11,7 @@ export const REPLICATION_TEMPLATE: string = `
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<hbr-list-replication-rule #listReplicationRule [readonly]="readonly" [projectId]="projectId" [isSystemAdmin]="isSystemAdmin" (replicateManual)=replicateManualRule($event) (selectOne)="selectOneRule($event)" (openNewRule)="openModal()" (editOne)="openEditRule($event)" (reload)="reloadRules($event)" [loading]="loading" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"></hbr-list-replication-rule>
<hbr-list-replication-rule #listReplicationRule [readonly]="readonly" [projectId]="projectId" [isSystemAdmin]="isSystemAdmin" (replicateManual)=replicateManualRule($event) (selectOne)="selectOneRule($event)" (hideJobs)="hideJobs()" (openNewRule)="openModal()" (editOne)="openEditRule($event)" (reload)="reloadRules($event)" [loading]="loading" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"></hbr-list-replication-rule>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="padding-left:0px;">
<div *ngIf="withReplicationJob" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">

View File

@ -352,6 +352,10 @@ export class ReplicationComponent implements OnInit, OnDestroy {
this.loadFirstPage();
}
hideJobs() {
this.search.ruleId = 0;
}
stopJobs() {
if (this.jobs && this.jobs.length) {
this.isStopOnGoing = true;

View File

@ -39,7 +39,7 @@ export const TAG_TEMPLATE = `
<clr-dg-column style="width: 150px;"[clrDgSortBy]="createdComparator">{{'REPOSITORY.CREATED' | translate}}</clr-dg-column>
<clr-dg-column style="width: 140px;" [clrDgField]="'docker_version'" *ngIf="!withClair">{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'TAG.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *ngFor="let t of tags" [clrDgItem]='t'>
<clr-dg-row *clrDgItems="let t of tags" [clrDgItem]='t'>
<clr-dg-cell class="truncated" style="width: 160px;" [ngSwitch]="withClair">
<a *ngSwitchCase="true" href="javascript:void(0)" (click)="onTagClick(t)" title="{{t.name}}">{{t.name}}</a>
<span *ngSwitchDefault>{{t.name}}</span>

View File

@ -31,7 +31,7 @@
"clarity-icons": "^0.10.17",
"clarity-ui": "^0.10.17",
"core-js": "^2.4.1",
"harbor-ui": "0.6.34",
"harbor-ui": "0.6.37",
"intl": "^1.2.5",
"mutationobserver-shim": "^0.3.2",
"ngx-cookie": "^1.0.0",

View File

@ -31,7 +31,7 @@
<clr-datagrid [(clrDgSelected)]="selectedRow" (clrDgSelectedChange)="SelectedChange()">
<clr-dg-column>{{'MEMBER.NAME' | translate}}</clr-dg-column>
<clr-dg-column>{{'MEMBER.ROLE' | translate}}</clr-dg-column>
<clr-dg-row *ngFor="let m of members" [clrDgItem]="m">
<clr-dg-row *clrDgItems="let m of members" [clrDgItem]="m">
<clr-dg-cell>{{m.username}}</clr-dg-cell>
<clr-dg-cell>
<span *ngIf="ChangeRoleOngoing(m.username)" class="spinner spinner-inline"> Loading... </span>

View File

@ -25,6 +25,7 @@ const FAKE_PASSWORD = 'rjGcfuRu';
styleUrls: ['replication-rule.css']
})
export class ReplicationRuleComponent implements OnInit, OnDestroy {
_localTime: Date = new Date();
policyId: number;
@ -33,7 +34,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
isFilterHide: boolean = false;
weeklySchedule: boolean;
isScheduleOpt: boolean;
isImmediate: boolean = true;
isImmediate: boolean = false;
noProjectInfo: string = "";
noSelectedProject: boolean = true;
noSelectedEndpoint: boolean = true;
@ -59,6 +60,8 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
ruleForm: FormGroup;
copyUpdateForm: ReplicationRule;
emptyEndpoint = new Target();
@ViewChild(ListProjectModelComponent)
projectListModel: ListProjectModelComponent;
@ -91,7 +94,6 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
private confirmService: ConfirmationDialogService,
public ref: ChangeDetectorRef) {
this.createForm();
Promise.all([this.repService.getEndpoints(), this.repService.listProjects()])
.then(res => {
if (!res[0]) {
@ -99,6 +101,7 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}else {
this.targetList = res[0];
if (!this.policyId) {
res[0].unshift(this.emptyEndpoint);
this.setTarget([res[0][0]]);
this.realEndpointData.userName = res[0][0].username;
this.realEndpointData.password = FAKE_PASSWORD;
@ -270,6 +273,10 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
targetChange($event: any) {
if ($event && $event.target && event.target['value']) {
if ($event.target['value'] === '-1') {
this.noSelectedEndpoint = true;
return;
}
let selecedTarget: Target = this.targetList.find(target => target.id === +$event.target['value']);
this.setTarget([selecedTarget]);
this.noSelectedEndpoint = false;
@ -437,10 +444,9 @@ export class ReplicationRuleComponent implements OnInit, OnDestroy {
}
public hasFormChange(): boolean {
return !isEmptyObject(this.getChanges());
return !isEmptyObject(this.getChanges()) || !compareValue(this.firstEndpointData, this.realEndpointData);
}
onSubmit() {
this.inProgress = true;
let endpointId: string | number = this.ruleForm.value.targets[0].id;

View File

@ -37,8 +37,7 @@ label:first-child {
.projectInput{float: left;}
.projectInput input{background-color: white;}
.switchIcon{width:20px;height:20px; margin-top: 16px;margin-left: 10px;}
.switchIcon{width:20px;height:20px; margin-top: 10px;margin-left: 10px; cursor: pointer;}
.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;}
.is-solid{cursor: pointer;}

View File

@ -57,15 +57,14 @@
<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 " 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 id="ruleTarget " class="inputWidth" (change)="targetChange($event)" formControlName="id">
<option *ngFor="let target of targetList" value="{{target.id}}">{{target.name}}<span [hidden]="!target.name">:</span> {{target.endpoint}}</option>
</select>
</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-->