Modify member name checking

This commit is contained in:
Steven Zou 2017-05-16 18:01:54 -07:00
parent cf65c39cef
commit 26d20bd9aa
3 changed files with 162 additions and 94 deletions

View File

@ -72,6 +72,10 @@ export class GlobalSearchComponent implements OnInit, OnDestroy {
if (this.searchSub) {
this.searchSub.unsubscribe();
}
if (this.closeSub) {
this.closeSub.unsubscribe();
}
}
//Handle the term inputting event

View File

@ -5,29 +5,32 @@
<form #memberForm="ngForm">
<section class="form-block">
<div class="form-group">
<label for="member_name" class="col-md-4 form-group-label-override">{{'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">
<input type="text" id="member_name" [(ngModel)]="member.username" name="name" size="20" #memberName="ngModel" required targetExists="MEMBER_NAME" [projectId]="projectId">
<span class="tooltip-content" *ngIf="memberName.errors && memberName.errors.required && (memberName.dirty || memberName.touched)">
{{ 'MEMBER.USERNAME_IS_REQUIRED' | translate }}
</span>
<span class="tooltip-content" *ngIf="memberName.errors && memberName.errors.targetExists && (memberName.dirty || memberName.touched)">
{{ 'MEMBER.USERNAME_ALREADY_EXISTS' | translate }}
<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]="!isMemberNameValid" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<input type="text" id="member_name" [(ngModel)]="member.username"
name="member_name"
size="20"
#memberName="ngModel"
required
(keyup)='handleValidation()'>
<span class="tooltip-content">
{{ memberTooltip | translate }}
</span>
</label>
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
</div>
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'MEMBER.ROLE' | translate}}</label>
<div class="radio">
<input type="radio" name="roleRadios" id="checkrads_project_admin" [value]="1" [(ngModel)]="member.role_id">
<input type="radio" name="member_role" id="checkrads_project_admin" [value]="1" [(ngModel)]="member.role_id">
<label for="checkrads_project_admin">{{'MEMBER.PROJECT_ADMIN' | translate}}</label>
</div>
<div class="radio">
<input type="radio" name="roleRadios" id="checkrads_developer" [value]="2" [(ngModel)]="member.role_id">
<input type="radio" name="member_role" id="checkrads_developer" [value]="2" [(ngModel)]="member.role_id">
<label for="checkrads_developer">{{'MEMBER.DEVELOPER' | translate}}</label>
</div>
<div class="radio">
<input type="radio" name="roleRadios" id="checkrads_guest" [value]="3" [(ngModel)]="member.role_id">
<input type="radio" name="member_role" id="checkrads_guest" [value]="3" [(ngModel)]="member.role_id">
<label for="checkrads_guest">{{'MEMBER.GUEST' | translate}}</label>
</div>
</div>
@ -36,6 +39,6 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="memberForm.form.invalid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="!isValid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
</div>
</clr-modal>

View File

@ -11,7 +11,16 @@
// 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, 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 { NgForm } from '@angular/forms';
@ -24,15 +33,18 @@ import { TranslateService } from '@ngx-translate/core';
import { Member } from '../member';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
@Component({
selector: 'add-member',
templateUrl: 'add-member.component.html',
styleUrls: ['add-member.component.css']
})
export class AddMemberComponent implements AfterViewChecked {
export class AddMemberComponent implements AfterViewChecked, OnInit, OnDestroy {
member: Member = new Member();
initVal: Member = new Member();
addMemberOpened: boolean;
@ -52,10 +64,48 @@ export class AddMemberComponent implements AfterViewChecked {
@Input() projectId: number;
@Output() added = new EventEmitter<boolean>();
isMemberNameValid: boolean = true;
memberTooltip: string = 'MEMBER.USERNAME_IS_REQUIRED';
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 {
if (!this.member.username || this.member.username.length === 0) { return; }
this.memberService
@ -102,19 +152,17 @@ export class AddMemberComponent implements AfterViewChecked {
}
ngAfterViewChecked(): void {
if (this.memberForm !== this.currentForm) {
this.memberForm = this.currentForm;
}
if (this.memberForm) {
this.memberForm.valueChanges.subscribe(data => {
for(let i in data) {
let origin = this.initVal[i];
let current = data[i];
if(current && current !== origin) {
let memberName = data['member_name'];
if (memberName && memberName !== '') {
this.hasChanged = true;
break;
this.inlineAlert.close();
} else {
this.hasChanged = false;
this.inlineAlert.close();
}
}
});
}
@ -132,6 +180,19 @@ export class AddMemberComponent implements AfterViewChecked {
this.addMemberOpened = true;
this.hasChanged = false;
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;
}
}