mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-06 13:27:45 +00:00
feat(console): set email verified on change, user create (#2847)
* feat: set email verified on change * user create
This commit is contained in:
parent
a533872c66
commit
fb43b13232
@ -1,34 +1,34 @@
|
||||
<cnsl-detail-layout [backRouterLink]="[ '/users/list/machines']" title="{{ 'USER.CREATE.TITLE' | translate }}"
|
||||
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
|
||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
|
||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
|
||||
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
|
||||
<div class="content">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.MACHINE.USERNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="userName" required />
|
||||
<span cnsl-error *ngIf="userName?.invalid && userName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
<span cnsl-error *ngIf="userName?.invalid && userName?.errors?.noEmailValidator">
|
||||
{{ 'USER.VALIDATION.NOEMAIL' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.MACHINE.NAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="name" required />
|
||||
<span cnsl-error *ngIf="name?.invalid && name?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.MACHINE.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="description" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" [disabled]="userForm.invalid" type="submit" mat-raised-button>{{ 'ACTIONS.CREATE' |
|
||||
translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
|
||||
<div class="content">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.MACHINE.USERNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="userName" required />
|
||||
<span cnslError *ngIf="userName?.invalid && userName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
<span cnslError *ngIf="userName?.invalid && userName?.errors?.noEmailValidator">
|
||||
{{ 'USER.VALIDATION.NOEMAIL' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.MACHINE.NAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="name" required />
|
||||
<span cnslError *ngIf="name?.invalid && name?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.MACHINE.DESCRIPTION' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="description" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" [disabled]="userForm.invalid" type="submit" mat-raised-button>{{ 'ACTIONS.CREATE' |
|
||||
translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</cnsl-detail-layout>
|
@ -1,95 +1,104 @@
|
||||
<cnsl-detail-layout [backRouterLink]="[ '/users/list/humans']" title="{{ 'USER.CREATE.TITLE' | translate }}"
|
||||
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
|
||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
|
||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
|
||||
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
|
||||
<div class="content">
|
||||
<p class="section">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.EMAIL' | translate }}*</cnsl-label>
|
||||
<input cnslInput matRipple formControlName="email" required />
|
||||
<span cnslError *ngIf="email?.invalid && !email?.errors?.required">
|
||||
{{ 'USER.VALIDATION.NOTANEMAIL' | translate }}
|
||||
</span>
|
||||
<span cnslError *ngIf="email?.invalid && email?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.USERNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="userName" required
|
||||
[ngStyle]="{'padding-right': suffixPadding ? suffixPadding : '10px'}" />
|
||||
<span #suffix *ngIf="envSuffixLabel" cnslSuffix>{{envSuffixLabel}}</span>
|
||||
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
|
||||
<div class="content">
|
||||
<p class="section">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.EMAIL' | translate }}*</cnsl-label>
|
||||
<input cnslInput matRipple formControlName="email" required />
|
||||
<span cnslError *ngIf="email?.invalid && !email?.errors?.required">
|
||||
{{ 'USER.VALIDATION.NOTANEMAIL' | translate }}
|
||||
</span>
|
||||
<span cnslError *ngIf="email?.invalid && email?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.USERNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="userName" required
|
||||
[ngStyle]="{'padding-right': suffixPadding ? suffixPadding : '10px'}" />
|
||||
<span #suffix *ngIf="envSuffixLabel" cnslSuffix>{{envSuffixLabel}}</span>
|
||||
|
||||
<span cnslError *ngIf="userName?.invalid && userName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
<span cnslError *ngIf="userName?.invalid && userName?.errors?.noEmailValidator">
|
||||
{{ 'USER.VALIDATION.NOEMAIL' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="content">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="firstName" required />
|
||||
<span cnslError *ngIf="firstName?.invalid && firstName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.LASTNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="lastName" required />
|
||||
<span cnslError *ngIf="lastName?.invalid && lastName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="nickName" />
|
||||
<span cnslError *ngIf="nickName?.invalid && nickName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<span cnslError *ngIf="userName?.invalid && userName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
<span cnslError *ngIf="userName?.invalid && userName?.errors?.noEmailValidator">
|
||||
{{ 'USER.VALIDATION.NOEMAIL' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="content">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="firstName" required />
|
||||
<span cnslError *ngIf="firstName?.invalid && firstName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.LASTNAME' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="lastName" required />
|
||||
<span cnslError *ngIf="lastName?.invalid && lastName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="nickName" />
|
||||
<span cnslError *ngIf="nickName?.invalid && nickName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
|
||||
<div class="email-is-verified">
|
||||
<mat-checkbox class="verified-checkbox" formControlName="isVerified">
|
||||
{{'USER.LOGINMETHODS.EMAIL.ISVERIFIED' | translate}}
|
||||
</mat-checkbox>
|
||||
<cnsl-info-section class="full-width desc">
|
||||
<span>{{'USER.LOGINMETHODS.EMAIL.ISVERIFIEDDESC' | translate}}</span>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.GENDER' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="gender">
|
||||
<mat-option *ngFor="let gender of genders" [value]="gender">
|
||||
{{ 'GENDERS.'+gender | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<span cnslError *ngIf="gender?.invalid && gender?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="preferredLanguage">
|
||||
<mat-option *ngFor="let language of languages" [value]="language">
|
||||
{{ 'LANGUAGES.'+language | translate }}
|
||||
</mat-option>
|
||||
<span cnslError *ngIf="preferredLanguage?.invalid && preferredLanguage?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
<p class="section">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.ADDRESSANDPHONESECTION' | translate }}</p>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.GENDER' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="gender">
|
||||
<mat-option *ngFor="let gender of genders" [value]="gender">
|
||||
{{ 'GENDERS.'+gender | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<span cnslError *ngIf="gender?.invalid && gender?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="preferredLanguage">
|
||||
<mat-option *ngFor="let language of languages" [value]="language">
|
||||
{{ 'LANGUAGES.'+language | translate }}
|
||||
</mat-option>
|
||||
<span cnslError *ngIf="preferredLanguage?.invalid && preferredLanguage?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.PHONE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="phone" />
|
||||
<span cnslError *ngIf="phone?.invalid && phone?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" [disabled]="userForm.invalid" type="submit" mat-raised-button>{{ 'ACTIONS.CREATE' |
|
||||
translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
<p class="section">{{ 'USER.CREATE.ADDRESSANDPHONESECTION' | translate }}</p>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'USER.PROFILE.PHONE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="phone" />
|
||||
<span cnslError *ngIf="phone?.invalid && phone?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</span>
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" [disabled]="userForm.invalid" type="submit" mat-raised-button>{{ 'ACTIONS.CREATE' |
|
||||
translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</cnsl-detail-layout>
|
@ -1,4 +1,3 @@
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
padding-top: 1rem;
|
||||
@ -7,8 +6,8 @@
|
||||
button {
|
||||
margin-top: 3rem;
|
||||
display: block;
|
||||
padding: .5rem 4rem;
|
||||
border-radius: .5rem;
|
||||
padding: 0.5rem 4rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,19 +17,25 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
margin: 0 -.5rem;
|
||||
margin: 0 -0.5rem;
|
||||
|
||||
.section {
|
||||
padding: .5rem;
|
||||
padding: 0.5rem;
|
||||
flex-basis: 100%;
|
||||
color: var(--grey);
|
||||
font-size: .9rem;
|
||||
letter-spacing: .05em;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.formfield {
|
||||
flex: 1 0 33%;
|
||||
margin: 0 .5rem;
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
.email-is-verified {
|
||||
margin: 0 0.5rem;
|
||||
flex-basis: 100%;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
@ -38,26 +38,29 @@ export class UserCreateComponent implements OnDestroy {
|
||||
) {
|
||||
this.loading = true;
|
||||
this.loadOrg();
|
||||
this.mgmtService.getOrgIAMPolicy().then((resp) => {
|
||||
if (resp.policy?.userLoginMustBeDomain) {
|
||||
this.userLoginMustBeDomain = resp.policy.userLoginMustBeDomain;
|
||||
}
|
||||
this.initForm();
|
||||
this.loading = false;
|
||||
this.envSuffixLabel = this.envSuffix();
|
||||
this.changeDetRef.detectChanges();
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
this.initForm();
|
||||
this.loading = false;
|
||||
this.envSuffixLabel = this.envSuffix();
|
||||
this.changeDetRef.detectChanges();
|
||||
});
|
||||
this.mgmtService
|
||||
.getOrgIAMPolicy()
|
||||
.then((resp) => {
|
||||
if (resp.policy?.userLoginMustBeDomain) {
|
||||
this.userLoginMustBeDomain = resp.policy.userLoginMustBeDomain;
|
||||
}
|
||||
this.initForm();
|
||||
this.loading = false;
|
||||
this.envSuffixLabel = this.envSuffix();
|
||||
this.changeDetRef.detectChanges();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
this.initForm();
|
||||
this.loading = false;
|
||||
this.envSuffixLabel = this.envSuffix();
|
||||
this.changeDetRef.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
private async loadOrg(): Promise<void> {
|
||||
const domains = (await this.mgmtService.listOrgDomains());
|
||||
const found = domains.resultList.find(resp => resp.isPrimary);
|
||||
const domains = await this.mgmtService.listOrgDomains();
|
||||
const found = domains.resultList.find((resp) => resp.isPrimary);
|
||||
if (found) {
|
||||
this.primaryDomain = found;
|
||||
}
|
||||
@ -66,32 +69,26 @@ export class UserCreateComponent implements OnDestroy {
|
||||
private initForm(): void {
|
||||
this.userForm = this.fb.group({
|
||||
email: ['', [Validators.required, Validators.email]],
|
||||
userName: ['',
|
||||
[
|
||||
Validators.required,
|
||||
Validators.minLength(2),
|
||||
],
|
||||
],
|
||||
userName: ['', [Validators.required, Validators.minLength(2)]],
|
||||
firstName: ['', Validators.required],
|
||||
lastName: ['', Validators.required],
|
||||
nickName: [''],
|
||||
gender: [],
|
||||
preferredLanguage: [''],
|
||||
phone: [''],
|
||||
isVerified: [false, []],
|
||||
});
|
||||
|
||||
this.userForm.controls['phone'].valueChanges.pipe(
|
||||
takeUntil(this.destroyed$),
|
||||
debounceTime(300)).subscribe(value => {
|
||||
const phoneNumber = parsePhoneNumber(value ?? '', 'CH');
|
||||
if (phoneNumber) {
|
||||
const formmatted = phoneNumber.formatInternational();
|
||||
const country = phoneNumber.country;
|
||||
if (this.phone && country && this.phone.value && this.phone.value !== formmatted) {
|
||||
this.phone.setValue(formmatted);
|
||||
}
|
||||
this.userForm.controls['phone'].valueChanges.pipe(takeUntil(this.destroyed$), debounceTime(300)).subscribe((value) => {
|
||||
const phoneNumber = parsePhoneNumber(value ?? '', 'CH');
|
||||
if (phoneNumber) {
|
||||
const formmatted = phoneNumber.formatInternational();
|
||||
const country = phoneNumber.country;
|
||||
if (this.phone && country && this.phone.value && this.phone.value !== formmatted) {
|
||||
this.phone.setValue(formmatted);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public createUser(): void {
|
||||
@ -110,7 +107,10 @@ export class UserCreateComponent implements OnDestroy {
|
||||
humanReq.setUserName(this.userName?.value);
|
||||
humanReq.setProfile(profileReq);
|
||||
|
||||
humanReq.setEmail(new AddHumanUserRequest.Email().setEmail(this.email?.value));
|
||||
const emailreq = new AddHumanUserRequest.Email();
|
||||
emailreq.setEmail(this.email?.value);
|
||||
emailreq.setIsEmailVerified(this.isVerified?.value);
|
||||
humanReq.setEmail(emailreq);
|
||||
|
||||
if (this.phone && this.phone.value) {
|
||||
humanReq.setPhone(new AddHumanUserRequest.Phone().setPhone(this.phone.value));
|
||||
@ -123,7 +123,7 @@ export class UserCreateComponent implements OnDestroy {
|
||||
this.toast.showInfo('USER.TOAST.CREATED', true);
|
||||
this.router.navigate(['users', data.userId]);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
this.loading = false;
|
||||
this.toast.showError(error);
|
||||
});
|
||||
@ -137,6 +137,9 @@ export class UserCreateComponent implements OnDestroy {
|
||||
public get email(): AbstractControl | null {
|
||||
return this.userForm.get('email');
|
||||
}
|
||||
public get isVerified(): AbstractControl | null {
|
||||
return this.userForm.get('isVerified');
|
||||
}
|
||||
public get userName(): AbstractControl | null {
|
||||
return this.userForm.get('userName');
|
||||
}
|
||||
|
@ -11,29 +11,31 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { UserCreateRoutingModule } from './user-create-routing.module';
|
||||
import { UserCreateComponent } from './user-create.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [UserCreateComponent],
|
||||
imports: [
|
||||
UserCreateRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MatSelectModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatProgressBarModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
DetailLayoutModule,
|
||||
InputModule,
|
||||
MatRippleModule,
|
||||
],
|
||||
declarations: [UserCreateComponent],
|
||||
imports: [
|
||||
UserCreateRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MatSelectModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatProgressBarModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
InfoSectionModule,
|
||||
DetailLayoutModule,
|
||||
InputModule,
|
||||
MatRippleModule,
|
||||
],
|
||||
})
|
||||
export class UserCreateModule { }
|
||||
export class UserCreateModule {}
|
||||
|
@ -27,11 +27,11 @@
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 0 -.5rem;
|
||||
margin: 0 -0.5rem;
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
margin: 0 .5rem;
|
||||
border-radius: 0.5rem;
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,11 +39,11 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
margin: -1.5rem -.5rem;
|
||||
margin: -1.5rem -0.5rem;
|
||||
|
||||
.app-card {
|
||||
flex: 1;
|
||||
margin: .5rem;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@
|
||||
|
||||
.resendemail {
|
||||
margin-right: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.side-padding {
|
||||
|
@ -227,9 +227,9 @@ export class AuthUserDetailComponent implements OnDestroy {
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRefPhone.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.savePhone(resp);
|
||||
dialogRefPhone.afterClosed().subscribe((resp: { value: string; isVerified: boolean }) => {
|
||||
if (resp && resp.value) {
|
||||
this.savePhone(resp.value);
|
||||
}
|
||||
});
|
||||
break;
|
||||
@ -247,9 +247,9 @@ export class AuthUserDetailComponent implements OnDestroy {
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRefEmail.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.saveEmail(resp);
|
||||
dialogRefEmail.afterClosed().subscribe((resp: { value: string; isVerified: boolean }) => {
|
||||
if (resp && resp.value) {
|
||||
this.saveEmail(resp.value);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -1,22 +1,32 @@
|
||||
<h1 mat-dialog-title>
|
||||
<span class="title">{{data.titleKey | translate}}</span>
|
||||
<span class="title">{{data.titleKey | translate}}</span>
|
||||
</h1>
|
||||
<p class="desc">{{data.descriptionKey | translate}}</p>
|
||||
<div mat-dialog-content>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{data.labelKey | translate }} <span *ngIf="isPhone && phoneCountry">({{ phoneCountry }})</span>
|
||||
</cnsl-label>
|
||||
<input [formControl]="valueControl" cnslInput
|
||||
(keydown.enter)="valueControl.valid ? closeDialogWithValue() : null" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{data.labelKey | translate }} <span *ngIf="isPhone && phoneCountry">({{ phoneCountry }})</span>
|
||||
</cnsl-label>
|
||||
<input [formControl]="valueControl" cnslInput
|
||||
(keydown.enter)="valueControl.valid ? closeDialogWithValue() : null" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<ng-container *ngIf="data.type === EditDialogType.EMAIL && data.isVerifiedTextKey">
|
||||
<mat-checkbox class="verified-checkbox" [(ngModel)]="isVerified">
|
||||
{{data.isVerifiedTextKey |
|
||||
translate}}
|
||||
</mat-checkbox>
|
||||
<cnsl-info-section class="full-width desc">
|
||||
<span>{{data.isVerifiedTextDescKey | translate}}</span>
|
||||
</cnsl-info-section>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button cdkFocusInitial color="primary" mat-button class="ok-button" (click)="closeDialog()">
|
||||
{{data.cancelKey | translate}}
|
||||
</button>
|
||||
<button cdkFocusInitial color="primary" mat-button class="ok-button" (click)="closeDialog()">
|
||||
{{data.cancelKey | translate}}
|
||||
</button>
|
||||
|
||||
<button [disabled]="valueControl.invalid" cdkFocusInitial color="primary" mat-raised-button class="ok-button"
|
||||
(click)="closeDialogWithValue()">
|
||||
{{data.confirmKey | translate}}
|
||||
</button>
|
||||
<button [disabled]="valueControl.invalid" cdkFocusInitial color="primary" mat-raised-button class="ok-button"
|
||||
(click)="closeDialogWithValue()">
|
||||
{{data.confirmKey | translate}}
|
||||
</button>
|
||||
</div>
|
@ -2,6 +2,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.verified-checkbox {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
color: var(--grey);
|
||||
@ -12,10 +16,10 @@
|
||||
justify-content: flex-end;
|
||||
|
||||
.ok-button {
|
||||
margin-left: .5rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
@ -15,16 +15,17 @@ export enum EditDialogType {
|
||||
})
|
||||
export class EditDialogComponent {
|
||||
public isPhone: boolean = false;
|
||||
public isVerified: boolean = false;
|
||||
public phoneCountry: string = 'CH';
|
||||
public valueControl: FormControl = new FormControl(['', [Validators.required]]);
|
||||
constructor(public dialogRef: MatDialogRef<EditDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
public EditDialogType: any = EditDialogType;
|
||||
constructor(public dialogRef: MatDialogRef<EditDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
this.valueControl.setValue(data.value);
|
||||
if (data.type === EditDialogType.PHONE) {
|
||||
this.isPhone = true;
|
||||
}
|
||||
|
||||
this.valueControl.valueChanges.subscribe(value => {
|
||||
this.valueControl.valueChanges.subscribe((value) => {
|
||||
if (value && value.length > 1) {
|
||||
this.changeValue(value);
|
||||
}
|
||||
@ -53,6 +54,6 @@ export class EditDialogComponent {
|
||||
}
|
||||
|
||||
closeDialogWithValue(): void {
|
||||
this.dialogRef.close(this.valueControl.value);
|
||||
this.dialogRef.close({ value: this.valueControl.value, isVerified: this.isVerified });
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
}
|
||||
|
||||
p {
|
||||
margin: .5rem 0;
|
||||
margin: 0.5rem 0;
|
||||
font-size: 14px;
|
||||
color: var(--grey);
|
||||
}
|
||||
@ -30,13 +30,13 @@
|
||||
}
|
||||
|
||||
.actions-trigger {
|
||||
margin-top: .25rem;
|
||||
margin-top: 0.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
margin-left: .5rem;
|
||||
margin-right: -.5rem;
|
||||
margin-left: 0.5rem;
|
||||
margin-right: -0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,3 +66,7 @@
|
||||
.side-padding {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.resendemail {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
@ -229,10 +229,10 @@ export class UserDetailComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
public saveEmail(email: string): void {
|
||||
public saveEmail(email: string, isVerified: boolean): void {
|
||||
if (this.user.id && email) {
|
||||
this.mgmtUserService
|
||||
.updateHumanEmail(this.user.id, email)
|
||||
.updateHumanEmail(this.user.id, email, isVerified)
|
||||
.then(() => {
|
||||
this.toast.showInfo('USER.TOAST.EMAILSAVED', true);
|
||||
if (this.user.state === UserState.USER_STATE_INITIAL) {
|
||||
@ -355,9 +355,9 @@ export class UserDetailComponent implements OnInit {
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRefPhone.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.savePhone(resp);
|
||||
dialogRefPhone.afterClosed().subscribe((resp: { value: string; isVerified: boolean }) => {
|
||||
if (resp && resp.value) {
|
||||
this.savePhone(resp.value);
|
||||
}
|
||||
});
|
||||
break;
|
||||
@ -369,15 +369,17 @@ export class UserDetailComponent implements OnInit {
|
||||
labelKey: 'ACTIONS.NEWVALUE',
|
||||
titleKey: 'USER.LOGINMETHODS.EMAIL.EDITTITLE',
|
||||
descriptionKey: 'USER.LOGINMETHODS.EMAIL.EDITDESC',
|
||||
isVerifiedTextKey: 'USER.LOGINMETHODS.EMAIL.ISVERIFIED',
|
||||
isVerifiedTextDescKey: 'USER.LOGINMETHODS.EMAIL.ISVERIFIEDDESC',
|
||||
value: this.user.human?.email?.email,
|
||||
type: EditDialogType.EMAIL,
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRefEmail.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.saveEmail(resp);
|
||||
dialogRefEmail.afterClosed().subscribe((resp: { value: string; isVerified: boolean }) => {
|
||||
if (resp && resp.value) {
|
||||
this.saveEmail(resp.value, resp.isVerified);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -899,32 +899,24 @@ export class ManagementService {
|
||||
return this.grpcService.mgmt.listHumanLinkedIDPs(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public getAction(
|
||||
id: string,
|
||||
): Promise<GetActionResponse.AsObject> {
|
||||
public getAction(id: string): Promise<GetActionResponse.AsObject> {
|
||||
const req = new GetActionRequest();
|
||||
req.setId(id);
|
||||
return this.grpcService.mgmt.getAction(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.getAction(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public createAction(
|
||||
req: CreateActionRequest,
|
||||
): Promise<CreateActionResponse.AsObject> {
|
||||
return this.grpcService.mgmt.createAction(req, null).then(resp => resp.toObject());
|
||||
public createAction(req: CreateActionRequest): Promise<CreateActionResponse.AsObject> {
|
||||
return this.grpcService.mgmt.createAction(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public updateAction(
|
||||
req: UpdateActionRequest,
|
||||
): Promise<UpdateActionResponse.AsObject> {
|
||||
return this.grpcService.mgmt.updateAction(req, null).then(resp => resp.toObject());
|
||||
public updateAction(req: UpdateActionRequest): Promise<UpdateActionResponse.AsObject> {
|
||||
return this.grpcService.mgmt.updateAction(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public deleteAction(
|
||||
id: string,
|
||||
): Promise<DeleteActionResponse.AsObject> {
|
||||
public deleteAction(id: string): Promise<DeleteActionResponse.AsObject> {
|
||||
const req = new DeleteActionRequest();
|
||||
req.setId(id);
|
||||
return this.grpcService.mgmt.deleteAction(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.deleteAction(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public listActions(
|
||||
@ -949,23 +941,19 @@ export class ManagementService {
|
||||
metadata.setAsc(asc);
|
||||
}
|
||||
req.setQuery(metadata);
|
||||
return this.grpcService.mgmt.listActions(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.listActions(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public getFlow(
|
||||
type: FlowType
|
||||
): Promise<GetFlowResponse.AsObject> {
|
||||
public getFlow(type: FlowType): Promise<GetFlowResponse.AsObject> {
|
||||
const req = new GetFlowRequest();
|
||||
req.setType(type);
|
||||
return this.grpcService.mgmt.getFlow(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.getFlow(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public clearFlow(
|
||||
type: FlowType
|
||||
): Promise<ClearFlowResponse.AsObject> {
|
||||
public clearFlow(type: FlowType): Promise<ClearFlowResponse.AsObject> {
|
||||
const req = new ClearFlowRequest();
|
||||
req.setType(type);
|
||||
return this.grpcService.mgmt.clearFlow(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.clearFlow(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public setTriggerActions(
|
||||
@ -977,7 +965,7 @@ export class ManagementService {
|
||||
req.setActionIdsList(actionIdsList);
|
||||
req.setFlowType(type);
|
||||
req.setTriggerType(triggerType);
|
||||
return this.grpcService.mgmt.setTriggerActions(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.setTriggerActions(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public getIAM(): Promise<GetIAMResponse.AsObject> {
|
||||
@ -1468,10 +1456,13 @@ export class ManagementService {
|
||||
return this.grpcService.mgmt.getHumanEmail(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public updateHumanEmail(userId: string, email: string): Promise<UpdateHumanEmailResponse.AsObject> {
|
||||
public updateHumanEmail(userId: string, email: string, isVerified?: boolean): Promise<UpdateHumanEmailResponse.AsObject> {
|
||||
const req = new UpdateHumanEmailRequest();
|
||||
req.setUserId(userId);
|
||||
req.setEmail(email);
|
||||
if (isVerified) {
|
||||
req.setIsEmailVerified(isVerified);
|
||||
}
|
||||
return this.grpcService.mgmt.updateHumanEmail(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
|
@ -419,6 +419,8 @@
|
||||
"EMAIL": {
|
||||
"TITLE": "E-Mail",
|
||||
"VALID": "Validiert",
|
||||
"ISVERIFIED": "Email Verifiziert",
|
||||
"ISVERIFIEDDESC": "Wenn die Email als verifiziert angegeben wird, wird keine Initialisierungsmail versendet.",
|
||||
"RESEND": "Verifikationsmail erneut senden",
|
||||
"EDITTITLE": "Email ändern",
|
||||
"EDITDESC": "Geben Sie die neue Email in dem darunterliegenden Feld ein!"
|
||||
|
@ -419,6 +419,8 @@
|
||||
"EMAIL": {
|
||||
"TITLE": "E-mail",
|
||||
"VALID": "validated",
|
||||
"ISVERIFIED": "Email Verified",
|
||||
"ISVERIFIEDDESC": "If the email is indicated as verified, no initialization email will be sent.",
|
||||
"RESEND": "Resend Verification E-mail",
|
||||
"EDITTITLE": "Change Email",
|
||||
"EDITDESC": "Enter the new email in the field below."
|
||||
|
@ -419,6 +419,8 @@
|
||||
"EMAIL": {
|
||||
"TITLE": "E-mail",
|
||||
"VALID": "convalidato",
|
||||
"ISVERIFIED": "Email Verificato",
|
||||
"ISVERIFIEDDESC": "Se l'email viene indicata come verificata, non verrà inviata alcuna email di inizializzazione.",
|
||||
"RESEND": "Invia di nuovo l'e-mail di verifica",
|
||||
"EDITTITLE": "Cambiare l'e-mail",
|
||||
"EDITDESC": "Inserisci la nuova email nel campo sottostante."
|
||||
|
Loading…
x
Reference in New Issue
Block a user