mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-06 18:50:09 +01:00
Modify member name checking
This commit is contained in:
parent
cf65c39cef
commit
26d20bd9aa
@ -72,6 +72,10 @@ export class GlobalSearchComponent implements OnInit, OnDestroy {
|
|||||||
if (this.searchSub) {
|
if (this.searchSub) {
|
||||||
this.searchSub.unsubscribe();
|
this.searchSub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.closeSub) {
|
||||||
|
this.closeSub.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Handle the term inputting event
|
//Handle the term inputting event
|
||||||
|
@ -1,41 +1,44 @@
|
|||||||
<clr-modal [(clrModalOpen)]="addMemberOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
<clr-modal [(clrModalOpen)]="addMemberOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
|
||||||
<h3 class="modal-title">{{'MEMBER.NEW_MEMBER' | translate}}</h3>
|
<h3 class="modal-title">{{'MEMBER.NEW_MEMBER' | translate}}</h3>
|
||||||
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
<inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></inline-alert>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form #memberForm="ngForm">
|
<form #memberForm="ngForm">
|
||||||
<section class="form-block">
|
<section class="form-block">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="member_name" class="col-md-4 form-group-label-override">{{'MEMBER.NAME' | translate}}</label>
|
<label for="member_name" class="col-md-4 form-group-label-override required">{{'MEMBER.NAME' | translate}}</label>
|
||||||
<label for="member_name" aria-haspopup="true" role="tooltip" [class.invalid]="memberName.invalid && (memberName.dirty || memberName.touched)" [class.valid]="memberName.valid" class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
|
<label for="member_name" aria-haspopup="true" role="tooltip" [class.invalid]="!isMemberNameValid" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
|
||||||
<input type="text" id="member_name" [(ngModel)]="member.username" name="name" size="20" #memberName="ngModel" required targetExists="MEMBER_NAME" [projectId]="projectId">
|
<input type="text" id="member_name" [(ngModel)]="member.username"
|
||||||
<span class="tooltip-content" *ngIf="memberName.errors && memberName.errors.required && (memberName.dirty || memberName.touched)">
|
name="member_name"
|
||||||
{{ 'MEMBER.USERNAME_IS_REQUIRED' | translate }}
|
size="20"
|
||||||
</span>
|
#memberName="ngModel"
|
||||||
<span class="tooltip-content" *ngIf="memberName.errors && memberName.errors.targetExists && (memberName.dirty || memberName.touched)">
|
required
|
||||||
{{ 'MEMBER.USERNAME_ALREADY_EXISTS' | translate }}
|
(keyup)='handleValidation()'>
|
||||||
|
<span class="tooltip-content">
|
||||||
|
{{ memberTooltip | translate }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label class="col-md-4 form-group-label-override">{{'MEMBER.ROLE' | translate}}</label>
|
<div class="form-group">
|
||||||
<div class="radio">
|
<label class="col-md-4 form-group-label-override">{{'MEMBER.ROLE' | translate}}</label>
|
||||||
<input type="radio" name="roleRadios" id="checkrads_project_admin" [value]="1" [(ngModel)]="member.role_id">
|
<div class="radio">
|
||||||
<label for="checkrads_project_admin">{{'MEMBER.PROJECT_ADMIN' | translate}}</label>
|
<input type="radio" name="member_role" id="checkrads_project_admin" [value]="1" [(ngModel)]="member.role_id">
|
||||||
</div>
|
<label for="checkrads_project_admin">{{'MEMBER.PROJECT_ADMIN' | translate}}</label>
|
||||||
<div class="radio">
|
</div>
|
||||||
<input type="radio" name="roleRadios" id="checkrads_developer" [value]="2" [(ngModel)]="member.role_id">
|
<div class="radio">
|
||||||
<label for="checkrads_developer">{{'MEMBER.DEVELOPER' | translate}}</label>
|
<input type="radio" name="member_role" id="checkrads_developer" [value]="2" [(ngModel)]="member.role_id">
|
||||||
</div>
|
<label for="checkrads_developer">{{'MEMBER.DEVELOPER' | translate}}</label>
|
||||||
<div class="radio">
|
</div>
|
||||||
<input type="radio" name="roleRadios" id="checkrads_guest" [value]="3" [(ngModel)]="member.role_id">
|
<div class="radio">
|
||||||
<label for="checkrads_guest">{{'MEMBER.GUEST' | translate}}</label>
|
<input type="radio" name="member_role" id="checkrads_guest" [value]="3" [(ngModel)]="member.role_id">
|
||||||
</div>
|
<label for="checkrads_guest">{{'MEMBER.GUEST' | translate}}</label>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
</form>
|
</section>
|
||||||
</div>
|
</form>
|
||||||
<div class="modal-footer">
|
</div>
|
||||||
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-primary" [disabled]="memberForm.form.invalid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
|
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
|
||||||
</div>
|
<button type="button" class="btn btn-primary" [disabled]="!isValid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
|
||||||
</clr-modal>
|
</div>
|
||||||
|
</clr-modal>
|
@ -11,10 +11,19 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, EventEmitter, Output, ViewChild, AfterViewChecked } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
Input,
|
||||||
|
EventEmitter,
|
||||||
|
Output,
|
||||||
|
ViewChild,
|
||||||
|
AfterViewChecked,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy
|
||||||
|
} from '@angular/core';
|
||||||
import { Response } from '@angular/http';
|
import { Response } from '@angular/http';
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
|
|
||||||
import { MemberService } from '../member.service';
|
import { MemberService } from '../member.service';
|
||||||
|
|
||||||
import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
|
||||||
@ -24,18 +33,21 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
|
|
||||||
import { Member } from '../member';
|
import { Member } from '../member';
|
||||||
|
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import 'rxjs/add/operator/debounceTime';
|
||||||
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'add-member',
|
selector: 'add-member',
|
||||||
templateUrl: 'add-member.component.html',
|
templateUrl: 'add-member.component.html',
|
||||||
styleUrls: [ 'add-member.component.css' ]
|
styleUrls: ['add-member.component.css']
|
||||||
})
|
})
|
||||||
export class AddMemberComponent implements AfterViewChecked {
|
export class AddMemberComponent implements AfterViewChecked, OnInit, OnDestroy {
|
||||||
|
|
||||||
member: Member = new Member();
|
member: Member = new Member();
|
||||||
initVal: Member = new Member();
|
|
||||||
|
|
||||||
addMemberOpened: boolean;
|
addMemberOpened: boolean;
|
||||||
|
|
||||||
memberForm: NgForm;
|
memberForm: NgForm;
|
||||||
|
|
||||||
staticBackdrop: boolean = true;
|
staticBackdrop: boolean = true;
|
||||||
@ -52,49 +64,87 @@ export class AddMemberComponent implements AfterViewChecked {
|
|||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Output() added = new EventEmitter<boolean>();
|
@Output() added = new EventEmitter<boolean>();
|
||||||
|
|
||||||
constructor(private memberService: MemberService,
|
isMemberNameValid: boolean = true;
|
||||||
private messageHandlerService: MessageHandlerService,
|
memberTooltip: string = 'MEMBER.USERNAME_IS_REQUIRED';
|
||||||
private translateService: TranslateService) {}
|
nameChecker: Subject<string> = new Subject<string>();
|
||||||
|
checkOnGoing: boolean = false;
|
||||||
|
|
||||||
|
constructor(private memberService: MemberService,
|
||||||
|
private messageHandlerService: MessageHandlerService,
|
||||||
|
private translateService: TranslateService) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.nameChecker
|
||||||
|
.debounceTime(500)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.subscribe((name: string) => {
|
||||||
|
let cont = this.currentForm.controls['member_name'];
|
||||||
|
if (cont) {
|
||||||
|
this.isMemberNameValid = cont.valid;
|
||||||
|
if (cont.valid) {
|
||||||
|
this.checkOnGoing = true;
|
||||||
|
this.memberService
|
||||||
|
.listMembers(this.projectId, cont.value).toPromise()
|
||||||
|
.then((members: Member[]) => {
|
||||||
|
if (members.filter(m => { return m.username === cont.value }).length > 0) {
|
||||||
|
this.isMemberNameValid = false;
|
||||||
|
this.memberTooltip = 'MEMBER.USERNAME_ALREADY_EXISTS';
|
||||||
|
}
|
||||||
|
this.checkOnGoing = false;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.checkOnGoing = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.memberTooltip = 'MEMBER.USERNAME_IS_REQUIRED';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.nameChecker.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
if(!this.member.username || this.member.username.length === 0) { return; }
|
if (!this.member.username || this.member.username.length === 0) { return; }
|
||||||
this.memberService
|
this.memberService
|
||||||
.addMember(this.projectId, this.member.username, +this.member.role_id)
|
.addMember(this.projectId, this.member.username, +this.member.role_id)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response => {
|
||||||
this.messageHandlerService.showSuccess('MEMBER.ADDED_SUCCESS');
|
this.messageHandlerService.showSuccess('MEMBER.ADDED_SUCCESS');
|
||||||
this.added.emit(true);
|
this.added.emit(true);
|
||||||
this.addMemberOpened = false;
|
this.addMemberOpened = false;
|
||||||
},
|
},
|
||||||
error=>{
|
error => {
|
||||||
if (error instanceof Response) {
|
if (error instanceof Response) {
|
||||||
let errorMessageKey: string;
|
let errorMessageKey: string;
|
||||||
switch(error.status){
|
switch (error.status) {
|
||||||
case 404:
|
case 404:
|
||||||
errorMessageKey = 'MEMBER.USERNAME_DOES_NOT_EXISTS';
|
errorMessageKey = 'MEMBER.USERNAME_DOES_NOT_EXISTS';
|
||||||
break;
|
break;
|
||||||
case 409:
|
case 409:
|
||||||
errorMessageKey = 'MEMBER.USERNAME_ALREADY_EXISTS';
|
errorMessageKey = 'MEMBER.USERNAME_ALREADY_EXISTS';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errorMessageKey = 'MEMBER.UNKNOWN_ERROR';
|
errorMessageKey = 'MEMBER.UNKNOWN_ERROR';
|
||||||
}
|
|
||||||
if(this.messageHandlerService.isAppLevel(error)) {
|
|
||||||
this.messageHandlerService.handleError(error);
|
|
||||||
this.addMemberOpened = false;
|
|
||||||
} else {
|
|
||||||
this.translateService
|
|
||||||
.get(errorMessageKey)
|
|
||||||
.subscribe(errorMessage=>this.inlineAlert.showInlineError(errorMessage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
if (this.messageHandlerService.isAppLevel(error)) {
|
||||||
|
this.messageHandlerService.handleError(error);
|
||||||
|
this.addMemberOpened = false;
|
||||||
|
} else {
|
||||||
|
this.translateService
|
||||||
|
.get(errorMessageKey)
|
||||||
|
.subscribe(errorMessage => this.inlineAlert.showInlineError(errorMessage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
if(this.hasChanged) {
|
if (this.hasChanged) {
|
||||||
this.inlineAlert.showInlineConfirmation({message: 'ALERT.FORM_CHANGE_CONFIRMATION'});
|
this.inlineAlert.showInlineConfirmation({ message: 'ALERT.FORM_CHANGE_CONFIRMATION' });
|
||||||
} else {
|
} else {
|
||||||
this.addMemberOpened = false;
|
this.addMemberOpened = false;
|
||||||
this.memberForm.reset();
|
this.memberForm.reset();
|
||||||
@ -102,19 +152,17 @@ export class AddMemberComponent implements AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewChecked(): void {
|
ngAfterViewChecked(): void {
|
||||||
this.memberForm = this.currentForm;
|
if (this.memberForm !== this.currentForm) {
|
||||||
if(this.memberForm) {
|
this.memberForm = this.currentForm;
|
||||||
this.memberForm.valueChanges.subscribe(data=>{
|
}
|
||||||
for(let i in data) {
|
if (this.memberForm) {
|
||||||
let origin = this.initVal[i];
|
this.memberForm.valueChanges.subscribe(data => {
|
||||||
let current = data[i];
|
let memberName = data['member_name'];
|
||||||
if(current && current !== origin) {
|
if (memberName && memberName !== '') {
|
||||||
this.hasChanged = true;
|
this.hasChanged = true;
|
||||||
break;
|
this.inlineAlert.close();
|
||||||
} else {
|
} else {
|
||||||
this.hasChanged = false;
|
this.hasChanged = false;
|
||||||
this.inlineAlert.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -132,6 +180,19 @@ export class AddMemberComponent implements AfterViewChecked {
|
|||||||
this.addMemberOpened = true;
|
this.addMemberOpened = true;
|
||||||
this.hasChanged = false;
|
this.hasChanged = false;
|
||||||
this.member.role_id = 1;
|
this.member.role_id = 1;
|
||||||
|
this.member.username = '';
|
||||||
|
this.isMemberNameValid = true;
|
||||||
|
this.memberTooltip = 'MEMBER.USERNAME_IS_REQUIRED';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleValidation(): void {
|
||||||
|
let cont = this.currentForm.controls['member_name'];
|
||||||
|
if (cont) {
|
||||||
|
this.nameChecker.next(cont.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isValid(): boolean {
|
||||||
|
return this.currentForm && this.currentForm.valid && this.isMemberNameValid;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user