]> source.dussan.org Git - archiva.git/blob
c6ea8a92e4754c601dfba1751305a287c204aa90
[archiva.git] /
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an
13  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  * KIND, either express or implied.  See the License for the
15  * specific language governing permissions and limitations
16  * under the License.
17  */
18
19 import {environment} from "../../../../environments/environment";
20 import {ErrorResult} from "../../../model/error-result";
21 import {UserInfo} from "../../../model/user-info";
22 import {
23     AbstractControl,
24     FormControl,
25     ValidatorFn,
26     Validators,
27     FormBuilder,
28     ValidationErrors,
29     FormGroup
30 } from "@angular/forms";
31 import {User} from "../../../model/user";
32 import {of, timer} from "rxjs";
33 import {catchError, map, switchMap} from "rxjs/operators";
34 import { UserService } from 'src/app/services/user.service';
35
36 export class ManageUsersBaseComponent {
37
38     editProperties = ['user_id', 'full_name', 'email', 'locked', 'password_change_required',
39         'password', 'confirm_password', 'validated'];
40     minUserIdSize = environment.application.minUserIdLength;
41     success: boolean = false;
42     error: boolean = false;
43     errorResult: ErrorResult;
44     result: UserInfo;
45     user: string;
46
47     userForm = this.fb.group({
48         user_id: ['', [Validators.required, Validators.minLength(this.minUserIdSize), whitespaceValidator()], this.userUidExistsValidator()],
49         full_name: ['', Validators.required],
50         email: ['', [Validators.required, Validators.email]],
51         locked: [false],
52         password_change_required: [true],
53         password: [''],
54         confirm_password: [''],
55         validated: [true]
56     }, {
57         validator: MustMatch('password', 'confirm_password')
58     })
59
60     constructor(public userService: UserService, public fb: FormBuilder) {
61     }
62
63
64     public copyFromForm(properties: string[]): User {
65         let user: any = new User();
66         for (let prop of properties) {
67             user[prop] = this.userForm.get(prop).value;
68         }
69         console.log("User " + user);
70         return user;
71     }
72
73     public copyToForm(properties: string[], user: User): void {
74         let propMap = {};
75         for (let prop of properties) {
76             let propValue = user[prop] == null ? '' : user[prop];
77             propMap[prop] = propValue;
78         }
79         this.userForm.patchValue(propMap);
80         console.log("User " + user);
81     }
82
83
84     valid(field: string): string[] {
85         let formField = this.userForm.get(field);
86         if (formField.dirty || formField.touched) {
87             if (formField.valid) {
88                 return ['is-valid']
89             } else {
90                 return ['is-invalid']
91             }
92         } else {
93             return ['']
94         }
95     }
96
97     /**
98      * Async validator with debounce time
99      * @constructor
100      */
101     userUidExistsValidator() {
102
103         return (ctrl: FormControl) => {
104             // debounceTimer() does not work here, as the observable is created with each keystroke
105             // but angular does unsubscribe on previous started async observables.
106             return timer(500).pipe(
107                 switchMap((userid) => this.userService.userExists(ctrl.value)),
108                 catchError(() => of(null)),
109                 map(exists => (exists ? {userexists: true} : null))
110             );
111         }
112     }
113
114     forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
115         return (control: AbstractControl): { [key: string]: any } | null => {
116             const forbidden = nameRe.test(control.value);
117             return forbidden ? {forbiddenName: {value: control.value}} : null;
118         };
119     }
120 }
121
122 export function whitespaceValidator(): ValidatorFn {
123     return (control: AbstractControl): ValidationErrors | null => {
124         const hasWhitespace =  /\s/g.test(control.value);
125         return hasWhitespace ? {containsWhitespace: {value: control.value}} : null;
126     };
127 }
128 export function MustMatch(controlName: string, matchingControlName: string) : ValidatorFn  {
129     return (formGroup: FormGroup): ValidationErrors | null => {
130         const control = formGroup.controls[controlName];
131         const matchingControl = formGroup.controls[matchingControlName];
132
133         if (matchingControl.errors && !matchingControl.errors.mustMatch) {
134             // return if another validator has already found an error on the matchingControl
135             return;
136         }
137
138         // set error on matchingControl if validation fails
139         if (control.value !== matchingControl.value) {
140             matchingControl.setErrors({mustMatch: true});
141         } else {
142             matchingControl.setErrors(null);
143         }
144     }
145 }