}
}
},
+ "make-plural": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz",
+ "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true
},
+ "messageformat": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz",
+ "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==",
+ "requires": {
+ "make-plural": "^4.3.0",
+ "messageformat-formatters": "^2.0.1",
+ "messageformat-parser": "^4.1.2"
+ }
+ },
+ "messageformat-formatters": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz",
+ "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg=="
+ },
+ "messageformat-parser": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz",
+ "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg=="
+ },
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
- "dev": true
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"minipass": {
"version": "3.1.3",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
+ "ngx-translate-messageformat-compiler": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/ngx-translate-messageformat-compiler/-/ngx-translate-messageformat-compiler-4.8.0.tgz",
+ "integrity": "sha512-A1Zg2sC0uCc1r8siT1M2DFcLhgjX6aEIu2g5NGnPh51KGtGqQqXHiXx2qCxz1U9sKMlYrvCZzfxzJ2kaCTtw+A==",
+ "requires": {
+ "tslib": "^1.10.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"bootstrap": "^4.5.0",
"flag-icon-css": "^3.5.0",
"jquery": "^3.5.1",
+ "messageformat": "^2.3.0",
+ "ngx-translate-messageformat-compiler": "^4.8.0",
"popper.js": "^1.16.1",
"rxjs": "~6.6.3",
"service": "^0.1.4",
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClient, HttpClientModule } from '@angular/common/http';
-import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
+import { TranslateLoader, TranslateModule, TranslateCompiler } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
+import { TranslateMessageFormatCompiler, MESSAGE_FORMAT_CONFIG } from 'ngx-translate-messageformat-compiler';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
ReactiveFormsModule,
HttpClientModule,
TranslateModule.forRoot({
+ compiler: {
+ provide: TranslateCompiler,
+ useClass: TranslateMessageFormatCompiler
+ },
loader: {
provide: TranslateLoader,
useFactory: httpTranslateLoader,
NgbPaginationModule,
NgbTooltipModule
],
- providers: [],
+ providers: [
+ { provide: MESSAGE_FORMAT_CONFIG, useValue: { locales: ['en', 'de'] }}
+ ],
bootstrap: [AppComponent]
})
export class AppModule { }
user_manager_id:string;
validation_token:string;
language:string;
+ location;
}
[ngClass]="valid('user_id')"
placeholder="{{'users.input.user_id'|translate}}">
<small>{{'users.input.small.user_id'|translate:{'minSize':this.minUserIdSize} }}</small>
+ <div *ngIf="userForm.get('user_id').invalid" class="invalid-feedback">
+ <div *ngIf="userForm.get('user_id').errors.required">
+ {{'form.error.required'|translate}}
+ </div>
+ <div *ngIf="userForm.get('user_id').errors.containsWhitespace">
+ {{'form.error.containsWhitespace'|translate}}
+ </div>
+ <div *ngIf="userForm.get('user_id').errors.userexists">
+ {{'form.error.userexists'|translate}}
+ </div>
+ </div>
+
</div>
<div class="form-group col-md-8">
<label for="full_name">{{'users.attributes.full_name' |translate}}</label>
</div>
<div class="form-group col-md-8">
<div class="form-check">
- <input class="form-check-input" type="checkbox" value="" formControlName="locked" id="locked">
+ <input class="form-check-input" type="checkbox" formControlName="locked" id="locked">
<label class="form-check-label" for="locked">
{{'users.attributes.locked'|translate}}
</label>
</div>
<div class="form-check">
- <input class="form-check-input" type="checkbox" value="" formControlName="password_change_required"
+ <input class="form-check-input" type="checkbox" formControlName="password_change_required"
id="password_change_required" checked>
<label class="form-check-label" for="password_change_required">
{{'users.attributes.password_change_required'|translate}}
</label>
</div>
+ <div class="form-check">
+ <input class="form-check-input" type="checkbox" formControlName="validated"
+ id="validated" checked>
+ <label class="form-check-label" for="validated">
+ {{'users.attributes.validated'|translate}}
+ </label>
+ </div>
</div>
<div class="form-group col-md-8">
<button class="btn btn-primary" type="submit"
- [disabled]="!userForm.valid">{{'users.add.submit'|translate}}</button>
+ [attr.disabled]="userForm.valid?null:true">{{'users.add.submit'|translate}}</button>
</div>
<div *ngIf="success" class="alert alert-success" role="alert">
- User <a [routerLink]="['user','users','edit',userid]">{{userid}}</a> was added to the list.
+ User <a [routerLink]="['user','users','edit',result?.user_id]">{{result?.userid}}</a> was added to the list.
</div>
<div *ngIf="error" class="alert alert-danger" role="alert" >
- <h4 class="alert-heading">Errors</h4>
+ <h4 class="alert-heading">{{'users.add.errortitle'|translate}}</h4>
<ng-container *ngFor="let message of errorResult?.error_messages; first as isFirst" >
<hr *ngIf="!isFirst">
<p>{{message.message}}</p>
*/
import {Component, OnInit} from '@angular/core';
-import {Validators, FormBuilder, FormGroup} from '@angular/forms';
+import {
+ FormBuilder,
+ FormGroup,
+ Validators,
+ FormControl,
+ AsyncValidator,
+ AbstractControl,
+ ValidationErrors,
+ ValidatorFn
+} from '@angular/forms';
import {UserService} from "../../../../services/user.service";
import {User} from "../../../../model/user";
-import { UserInfo } from 'src/app/model/user-info';
-import {HttpErrorResponse} from "@angular/common/http";
import {ErrorResult} from "../../../../model/error-result";
-import {catchError} from "rxjs/operators";
-import {of, throwError} from 'rxjs';
+import {catchError, debounceTime, distinctUntilChanged, map, switchMap} from "rxjs/operators";
+import {throwError, Observable, of, pipe, timer} from 'rxjs';
import {environment} from "../../../../../environments/environment";
+import {UserInfo} from "../../../../model/user-info";
@Component({
selector: 'app-manage-users-add',
})
export class ManageUsersAddComponent implements OnInit {
- minUserIdSize=environment.application.minUserIdLength;
- success:boolean=false;
- error:boolean=false;
- errorResult:ErrorResult;
- result:string;
- userid:string;
+ editProperties = ['user_id', 'full_name', 'email', 'locked', 'password_change_required',
+ 'password', 'confirm_password', 'validated'];
+ minUserIdSize = environment.application.minUserIdLength;
+ success: boolean = false;
+ error: boolean = false;
+ errorResult: ErrorResult;
+ result: UserInfo;
+ user: string;
userForm = this.fb.group({
- user_id: ['', [Validators.required, Validators.minLength(this.minUserIdSize)]],
+ user_id: ['', [Validators.required, Validators.minLength(this.minUserIdSize), whitespaceValidator()],this.userUidExistsValidator()],
full_name: ['', Validators.required],
- email: ['', [Validators.required,Validators.email]],
+ email: ['', [Validators.required, Validators.email]],
locked: [false],
password_change_required: [true],
password: [''],
confirm_password: [''],
+ validated: [true]
}, {
validator: MustMatch('password', 'confirm_password')
})
onSubmit() {
// Process checkout data here
- this.result=null;
+ this.result = null;
if (this.userForm.valid) {
- let user = this.copyForm(['user_id','full_name','email','locked','password_change_required',
- 'password','confirm_password'])
+ let user = this.copyFromForm(this.editProperties);
console.info('Adding user ' + user);
- this.userService.addUser(user).pipe(catchError((error : ErrorResult)=> {
- console.log("Error " + error + " - " + typeof (error) + " - " + JSON.stringify(error));
- if (error.status==422) {
- console.warn("Validation error");
+ this.userService.addUser(user).pipe(catchError((error: ErrorResult) => {
+ // console.log("Error " + error + " - " + typeof (error) + " - " + JSON.stringify(error));
+ if (error.status == 422) {
+ // console.warn("Validation error");
+ let pwdErrors = {};
+ for (let message of error.error_messages) {
+ if (message.error_key.startsWith('user.password.violation')) {
+ pwdErrors[message.error_key] = message.message;
+ }
+ }
+ this.userForm.get('password').setErrors(pwdErrors);
}
this.errorResult = error;
- this.success=false;
- this.error=true;
- return throwError(error);
- })).subscribe((location : string ) => {
- this.result = location;
- this.success=true;
+ this.success = false;
+ this.error = true;
+ return [];
+ // return throwError(error);
+ })).subscribe((user: UserInfo) => {
+ this.result = user;
+ this.success = true;
this.error = false;
- this.userid = location.substring(location.lastIndexOf('/') + 1);
});
}
}
- private copyForm(properties:string[]) : User {
- let user : any = new User();
+ public copyFromForm(properties: string[]): User {
+ let user: any = new User();
for (let prop of properties) {
user[prop] = this.userForm.get(prop).value;
}
return user;
}
+ public copyToForm(properties: string[], user: User): void {
+ let propMap = {};
+ for (let prop of properties) {
+ let propValue = user[prop] == null ? '' : user[prop];
+ propMap[prop] = propValue;
+ }
+ this.userForm.patchValue(propMap);
+ console.log("User " + user);
+ }
- valid(field:string) : string[] {
- let formField = this.userForm.get(field);
- if (formField.dirty||formField.touched) {
- if (formField.valid) {
- return ['is-valid']
+
+ valid(field: string): string[] {
+ let formField = this.userForm.get(field);
+ if (formField.dirty || formField.touched) {
+ if (formField.valid) {
+ return ['is-valid']
+ } else {
+ return ['is-invalid']
+ }
} else {
- return ['is-invalid']
+ return ['']
+ }
+ }
+
+ getAllErrors(formGroup: FormGroup, errors: string[] = []) : string[] {
+ Object.keys(formGroup.controls).forEach(field => {
+ const control = formGroup.get(field);
+ if (control instanceof FormControl && control.errors != null) {
+ let keys = Object.keys(control.errors).map(errorKey=>field+'.'+errorKey);
+ errors = errors.concat(keys);
+ } else if (control instanceof FormGroup) {
+ errors = errors.concat(this.getAllErrors(control));
+ }
+ });
+ return errors;
+ }
+
+ getAttributeErrors(control:string):string[] {
+ return Object.keys(this.userForm.get(control).errors);
+ }
+
+ /**
+ * Async validator with debounce time
+ * @constructor
+ */
+ userUidExistsValidator() {
+
+ return (ctrl : FormControl) => {
+ // debounceTimer() does not work here, as the observable is created with each keystroke
+ // but angular does unsubscribe on previous started async observables.
+ return timer(500).pipe(
+ switchMap((userid) => this.userService.userExists(ctrl.value)),
+ catchError(() => of(null)),
+ map(exists => (exists ? {userexists: true} : null))
+ );
}
- } else {
- return ['']
- }
}
+ forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
+ return (control: AbstractControl): {[key: string]: any} | null => {
+ const forbidden = nameRe.test(control.value);
+ return forbidden ? {forbiddenName: {value: control.value}} : null;
+ };
+ }
}
-export function MustMatch(controlName: string, matchingControlName: string) {
- return (formGroup: FormGroup) => {
+export function whitespaceValidator(): ValidatorFn {
+ return (control: AbstractControl): ValidationErrors | null => {
+ const hasWhitespace = /\s/g.test(control.value);
+ return hasWhitespace ? {containsWhitespace: {value: control.value}} : null;
+ };
+}
+export function MustMatch(controlName: string, matchingControlName: string) : ValidatorFn {
+ return (formGroup: FormGroup): ValidationErrors | null => {
const control = formGroup.controls[controlName];
const matchingControl = formGroup.controls[matchingControlName];
// set error on matchingControl if validation fails
if (control.value !== matchingControl.value) {
- matchingControl.setErrors({ mustMatch: true });
+ matchingControl.setErrors({mustMatch: true});
} else {
matchingControl.setErrors(null);
}
}
-}
\ No newline at end of file
+}
+
-->
<form class="mt-3 mb-3" [formGroup]="userForm" (ngSubmit)="onSubmit()">
- <div class="form-group row col-md-8">
- <div class="col-md-1">Edit <span class="fas fa-edit"></span></div>
+ <div class="form-group row col-md-8" *ngIf="!editUser.permanent">
+ <div class="col-md-1">Edit <span class="fas fa-edit"></span></div>
<div class="col-md-6">
- <input class="form-check-input" type="checkbox" [value]="editMode"
- (change)="editMode=!editMode"
- >
+ <input class="form-check-input" type="checkbox" [value]="editMode"
+ (change)="editMode=!editMode"
+ >
</div>
</div>
<div class="form-group row col-md-8">
<label class="col-md-2 col-form-label" for="user_id">{{'users.attributes.user_id' |translate}}</label>
- <div class="col-md-6" >
- <input type="text" formControlName="user_id" id="user_id"
- [ngClass]="valid('user_id')"
- value="{{editUser.user_id}}" [attr.readonly]="!editMode">
- <small *ngIf="editMode">{{'users.input.small.user_id'|translate:{'minSize':this.minUserIdSize} }}</small>
+ <div class="col-md-6">
+ <input type="text" formControlName="user_id" id="user_id"
+ [ngClass]="valid('user_id')"
+ [attr.readonly]="true">
</div>
</div>
<div class="form-group row col-md-8">
<label class="col-md-2 col-form-label" for="full_name">{{'users.attributes.full_name' |translate}}</label>
- <div class="col-md-6" >
- <input type="text" formControlName="full_name" id="full_name"
- [ngClass]="valid('full_name')" value="{{editUser.full_name}}" [attr.readonly]="!editMode" >
- <small *ngIf="editMode">{{'users.input.small.full_name'|translate}}</small>
+ <div class="col-md-6">
+ <input type="text" formControlName="full_name" id="full_name"
+ [ngClass]="valid('full_name')" [attr.readonly]="editMode?null:true">
+ <small *ngIf="editMode">{{'users.input.small.full_name'|translate}}</small>
</div>
</div>
<div class="form-group row col-md-8">
<label class="col-md-2 col-form-label" for="email">{{'users.attributes.email' |translate}}</label>
- <div class="col-md-6" >
- <input type="text" formControlName="email" id="email"
- [ngClass]="valid('email')" value="{{editUser.email}}" [attr.readonly]="!editMode">
+ <div class="col-md-6">
+ <input type="text" formControlName="email" id="email"
+ [ngClass]="valid('email')" value="{{editUser.email}}" [attr.readonly]="editMode?null:true">
</div>
</div>
<div class="form-group row col-md-8" *ngIf="editMode">
<label class="col-md-2 col-form-label" for="password">{{'users.attributes.password' |translate}}</label>
- <div class="col-md-6" >
- <input type="password" class="form-control" formControlName="password" id="password"
- [ngClass]="valid('password')"
- placeholder="{{'users.input.password'|translate}}">
+ <div class="col-md-6">
+ <input type="password" class="form-control" formControlName="password" id="password"
+ [ngClass]="valid('password')"
+ placeholder="{{'users.input.password'|translate}}">
+ <small>{{'users.edit.small.password'|translate}}</small>
</div>
</div>
<div class="form-group row col-md-8" *ngIf="editMode">
- <label class="col-md-2 col-form-label" for="confirm_password">{{'users.attributes.confirm_password' |translate}}</label>
+ <label class="col-md-2 col-form-label"
+ for="confirm_password">{{'users.attributes.confirm_password' |translate}}</label>
<div class="col-md-6">
- <input type="password" class="form-control" formControlName="confirm_password" id="confirm_password"
- [ngClass]="valid('confirm_password')"
- placeholder="{{'users.input.confirm_password'|translate}}">
+ <input type="password" class="form-control" formControlName="confirm_password" id="confirm_password"
+ [ngClass]="valid('confirm_password')"
+ placeholder="{{'users.input.confirm_password'|translate}}">
</div>
</div>
<div class="form-group row col-md-8">
<div class="col-md-2">Flags</div>
<div class="col-md-6">
- <div class="form-check">
- <input class="form-check-input" type="checkbox" value="{{editUser.locked}}" formControlName="locked" id="locked" [attr.disabled]="editMode?null:true">
- <label class="form-check-label" for="locked" >
- {{'users.attributes.locked'|translate}}
- </label>
+ <div class="form-check">
+ <input class="form-check-input" type="checkbox" formControlName="locked"
+ id="locked" [attr.disabled]="editMode?null:true">
+ <label class="form-check-label " for="locked">
+ {{'users.attributes.locked'|translate}}
+ </label>
+ </div>
+ <div class="form-check" >
+ <input class="form-check-input" type="checkbox"
+ formControlName="password_change_required"
+ id="password_change_required" [attr.disabled]="editMode?null:true">
+ <label class="form-check-label" for="password_change_required" >
+ {{'users.attributes.password_change_required'|translate}}
+ </label>
+ </div>
+ <div class="form-check">
+ <input class="form-check-input" type="checkbox"
+ formControlName="validated"
+ id="validated" [attr.disabled]="editMode?null:true">
+ <label class="form-check-label" for="validated">
+ {{'users.attributes.validated'|translate}}
+ </label>
+ </div>
</div>
- <div class="form-check">
- <input class="form-check-input" type="checkbox" value="{{editUser.password_change_required}}" formControlName="password_change_required"
- id="password_change_required" [attr.disabled]="editMode?null:true">
- <label class="form-check-label" for="password_change_required">
- {{'users.attributes.password_change_required'|translate}}
- </label>
+ </div>
+ <div class="form-group row col-md-8">
+ <label class="col-md-2 col-form-label" for="created">{{'users.attributes.created' |translate}}</label>
+ <div class="col-md-6">
+ <input type="text" id="created" class="form-control-plaintext"
+ value="{{editUser.timestamp_account_creation|date:'yyyy-MM-ddTHH:mm:ss'}}" [attr.readonly]="true">
+ </div>
+ </div>
+ <div class="form-group row col-md-8">
+ <label class="col-md-2 col-form-label" for="last_login">{{'users.attributes.last_login' |translate}}</label>
+ <div class="col-md-6">
+ <input type="text" id="last_login" class="form-control-plaintext"
+ value="{{editUser.timestamp_last_login|date:'yyyy-MM-ddTHH:mm:ss'}}" [attr.readonly]="true">
</div>
+ </div>
+ <div class="form-group row col-md-8">
+ <label class="col-md-2 col-form-label" for="email">{{'users.attributes.last_password_change' |translate}}</label>
+ <div class="col-md-6">
+ <input type="text" id="last_password_change" class="form-control-plaintext"
+ value="{{editUser.timestamp_last_password_change|date:'yyyy-MM-ddTHH:mm:ss'}}" [attr.readonly]="true">
</div>
</div>
+
<div class="form-group col-md-8" *ngIf="editMode">
<button class="btn btn-primary" type="submit"
- [disabled]="!userForm.valid">{{'users.edit.submit'|translate}}</button>
+ [disabled]="userForm.invalid || !userForm.dirty">{{'users.edit.submit'|translate}}</button>
</div>
<div *ngIf="success" class="alert alert-success" role="alert">
User <a [routerLink]="['user','users','edit',userid]">{{userid}}</a> was added to the list.
</div>
- <div *ngIf="error" class="alert alert-danger" role="alert" >
+ <div *ngIf="editMode && error" class="alert alert-danger" role="alert">
<h4 class="alert-heading">Errors</h4>
- <ng-container *ngFor="let message of errorResult?.error_messages; first as isFirst" >
+ <ng-container *ngFor="let message of errorResult?.error_messages; first as isFirst">
<hr *ngIf="!isFirst">
<p>{{message.message}}</p>
</ng-container>
</div>
+ <div *ngIf="editMode && userForm.invalid" class="alert alert-danger" role="alert" >
+ <h4 class="alert-heading">Errors</h4>
+ <ng-container *ngFor="let message of getAllErrors(userForm); first as isFirst" >
+ <hr *ngIf="!isFirst">
+ <p>{{message}}</p>
+ </ng-container>
+ </div>
</form>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import {UserService} from "../../../../services/user.service";
-import {FormBuilder, Validators} from "@angular/forms";
+import {FormBuilder, FormControl, Validators} from "@angular/forms";
import {ManageUsersAddComponent, MustMatch} from "../manage-users-add/manage-users-add.component";
import {environment} from "../../../../../environments/environment";
import {map, switchMap} from 'rxjs/operators';
})
export class ManageUsersEditComponent extends ManageUsersAddComponent implements OnInit {
+ editProperties = ['user_id', 'full_name', 'email', 'locked', 'password_change_required',
+ 'password', 'confirm_password', 'validated'];
editUser;
+ originUser;
editMode:boolean=false;
+ minUserIdSize=0;
constructor(private route: ActivatedRoute, public userService: UserService, public fb: FormBuilder) {
super(userService, fb);
this.editUser = this.route.params.pipe(map (params => params.userid ), switchMap(userid => userService.getUser(userid)) ).subscribe(user => {
- this.editUser = user;});
+ this.editUser = user;
+ this.originUser = user;
+ this.copyToForm(this.editProperties, this.editUser);});
}
ngOnInit(): void {
-
+ this.userForm.setControl('user_id', new FormControl());
}
valid(field: string): string[] {
}
+ onSubmit() {
+ this.copyFromForm(this.editProperties)
+
+ }
+
+
}
}
- public addUser(user: User): Observable<string> {
- return this.rest.executeResponseCall<string>("post", "redback", "users", user).pipe(
+ public addUser(user: User): Observable<UserInfo> {
+ return this.rest.executeResponseCall<UserInfo>("post", "redback", "users", user).pipe(
catchError((error: HttpErrorResponse) => {
return throwError(this.rest.getTranslatedErrorResult(error));
- }), map((httpResponse: HttpResponse<string>) => httpResponse.headers.get('Location')));
+ }), map((httpResponse: HttpResponse<UserInfo>) => {
+ if (httpResponse.status==201) {
+ let user = httpResponse.body;
+ user.location = httpResponse.headers.get('Location');
+ return user;
+ } else {
+ throwError(new HttpErrorResponse({headers:httpResponse.headers,status:httpResponse.status,statusText:"Bad response code"}))
+ }
+ }));
}
public getUser(userid: string): Observable<UserInfo> {
return throwError(this.rest.getTranslatedErrorResult(error));
}));
}
+
+ public updateUser(user:User): Observable<UserInfo> {
+ return this.rest.executeRestCall<UserInfo>("put", "redback", "users/" + user.user_id, user).pipe(
+ catchError((error: HttpErrorResponse) => {
+ return throwError(this.rest.getTranslatedErrorResult(error));
+ }));
+ }
+
+ public userExists(userid:string): Observable<boolean> {
+ console.log("Checking user " + userid);
+ return this.rest.executeResponseCall<string>("head", "redback", "users/" + userid, null).pipe(
+ catchError((error: HttpErrorResponse) => {
+ if (error.status==404) {
+ console.log("Status 404")
+ return [false];
+ } else {
+ return throwError(this.rest.getTranslatedErrorResult(error));
+ }
+ }), map((httpResponse: HttpResponse<string>) => httpResponse.status == 200));
+ }
+
}
},
"api" : {
"rb.auth.invalid_credentials": "Invalid credentials given",
- "user.password.violation.numeric" : "Password must have at least {{arg0}} numeric characters."
+ "user.password.violation.length": "You must provide a password between {arg0} and {arg1} characters in length.",
+ "user.password.violation.alpha": "You must provide a password containing at least {arg0} alphabetic {arg0, plural, one {character} other {characters}}.",
+ "user.password.violation.numeric":"You must provide a password containing at least {arg0} numeric {arg0, plural, one {character} other {characters}}.",
+ "user.password.violation.reuse":"The password must not match any of the previous {arg0} {arg0, plural, one {password} other {passwords}}.",
+ "user.password.violation.alphanum.only":"You must provide a password containing all alpha-numeric characters.",
+ "user.password.violation.whitespace.detected":"You must provide a password without whitespace characters."
},
"users": {
"attributes":{
"permanent": "Permanent",
"last_password_change": "Last Password Change",
"password": "Password",
- "confirm_password": "Confirm Password"
+ "confirm_password": "Confirm Password"
},
"input" : {
"small": {
- "user_id": "Must be a unique key with at least {{minSize}} characters. No spaces allowed.",
+ "user_id": "Must be a unique key with at least {minSize} characters. No spaces allowed.",
"full_name": "This is the display name of the user"
},
"user_id": "Enter user ID",
},
"add": {
"head": "Add User",
- "submit": "Add User"
+ "submit": "Add User",
+ "errortitle": "Could not add the user. Please check the following error messages."
+ },
+ "edit": {
+ "submit": "Save Changes",
+ "head": "View/Edit User",
+ "small": {
+ "password": "If the password field is empty, it will not be updated."
+ }
}
},
"search": {
"input": "Search"
},
"form": {
- "submit": "Submit"
+ "submit": "Submit",
+ "error": {
+ "required": "Value is empty. This is required.",
+ "containsWhitespace": "Value must not contain whitespace.",
+ "userexists": "This user exists already."
+ }
},
"password": {
"violations" : {