mirror of https://github.com/abpframework/abp
parent
d153ec19ee
commit
c1145ab0db
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,19 @@
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()" [mapErrorsFn]="mapErrorsFn">
|
||||
<div class="form-group">
|
||||
<label for="current-password">{{ 'AbpIdentity::DisplayName:CurrentPassword' | abpLocalization }}</label
|
||||
><span> * </span
|
||||
><input type="password" id="current-password" class="form-control" formControlName="password" autofocus />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="new-password">{{ 'AbpIdentity::DisplayName:NewPassword' | abpLocalization }}</label
|
||||
><span> * </span><input type="password" id="new-password" class="form-control" formControlName="newPassword" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="confirm-new-password">{{ 'AbpIdentity::DisplayName:NewPasswordConfirm' | abpLocalization }}</label
|
||||
><span> * </span
|
||||
><input type="password" id="confirm-new-password" class="form-control" formControlName="repeatNewPassword" />
|
||||
</div>
|
||||
<abp-button iconClass="fa fa-check" buttonClass="btn btn-primary color-white" (click)="onSubmit()">{{
|
||||
'AbpIdentity::Save' | abpLocalization
|
||||
}}</abp-button>
|
||||
</form>
|
@ -0,0 +1,63 @@
|
||||
import { ChangePassword } from '@abp/ng.core';
|
||||
import { ToasterService } from '@abp/ng.theme.shared';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { comparePasswords, Validation } from '@ngx-validate/core';
|
||||
import { Store } from '@ngxs/store';
|
||||
import snq from 'snq';
|
||||
|
||||
const { minLength, required } = Validators;
|
||||
|
||||
const PASSWORD_FIELDS = ['newPassword', 'repeatNewPassword'];
|
||||
|
||||
@Component({
|
||||
selector: 'abp-change-password-form',
|
||||
templateUrl: './change-password.component.html',
|
||||
})
|
||||
export class ChangePasswordComponent implements OnInit {
|
||||
form: FormGroup;
|
||||
|
||||
mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => {
|
||||
if (PASSWORD_FIELDS.indexOf(control.name) < 0) return errors;
|
||||
|
||||
return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch'));
|
||||
}
|
||||
|
||||
constructor(private fb: FormBuilder, private store: Store, private toasterService: ToasterService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.form = this.fb.group(
|
||||
{
|
||||
password: ['', required],
|
||||
newPassword: ['', required],
|
||||
repeatNewPassword: ['', required],
|
||||
},
|
||||
{
|
||||
validators: [comparePasswords(PASSWORD_FIELDS)],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
if (this.form.invalid) return;
|
||||
|
||||
this.store
|
||||
.dispatch(
|
||||
new ChangePassword({
|
||||
currentPassword: this.form.get('password').value,
|
||||
newPassword: this.form.get('newPassword').value,
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.form.reset();
|
||||
this.toasterService.success('AbpAccount::PasswordChangedMessage', 'Success', { life: 5000 });
|
||||
},
|
||||
error: err => {
|
||||
this.toasterService.error(snq(() => err.error.error.message, 'AbpAccount::DefaultErrorMessage'), 'Error', {
|
||||
life: 7000,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
@ -1,2 +1,5 @@
|
||||
export * from './change-password/change-password.component';
|
||||
export * from './login/login.component';
|
||||
export * from './manage-profile/manage-profile.component';
|
||||
export * from './register/register.component';
|
||||
export * from './personal-settings/personal-settings.component';
|
||||
|
@ -0,0 +1,36 @@
|
||||
<div class="row entry-row">
|
||||
<div class="col-auto"></div>
|
||||
<div id="breadcrumb" class="col-md-auto pl-md-0"></div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
|
||||
<div id="ManageProfileWrapper">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<ul class="nav flex-column nav-pills" id="nav-tab" role="tablist">
|
||||
<li class="nav-item pointer" (click)="selectedTab = 0">
|
||||
<a class="nav-link" [ngClass]="{ active: selectedTab === 0 }" role="tab">{{
|
||||
'AbpUi::ChangePassword' | abpLocalization
|
||||
}}</a>
|
||||
</li>
|
||||
<li class="nav-item pointer" (click)="selectedTab = 1">
|
||||
<a class="nav-link" [ngClass]="{ active: selectedTab === 1 }" role="tab">{{
|
||||
'AbpAccount::PersonalSettings' | abpLocalization
|
||||
}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<div class="tab-content" *ngIf="selectedTab === 0">
|
||||
<div class="tab-pane fade show active" role="tabpanel">
|
||||
<abp-change-password-form></abp-change-password-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-content" *ngIf="selectedTab === 1">
|
||||
<div class="tab-pane fade show active" role="tabpanel">
|
||||
<abp-personal-settings-form></abp-personal-settings-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,13 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'abp-manage-profile',
|
||||
templateUrl: './manage-profile.component.html',
|
||||
})
|
||||
export class ManageProfileComponent implements OnInit {
|
||||
selectedTab = 0;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<form novalidate *ngIf="form" [formGroup]="form" (ngSubmit)="submit()">
|
||||
<div class="form-group">
|
||||
<label for="username">{{ 'AbpIdentity::DisplayName:UserName' | abpLocalization }}</label
|
||||
><span> * </span><input type="text" id="username" class="form-control" formControlName="userName" autofocus />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="name">{{ 'AbpIdentity::DisplayName:Name' | abpLocalization }}</label
|
||||
><input type="text" id="name" class="form-control" formControlName="name" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="surname">{{ 'AbpIdentity::DisplayName:Surname' | abpLocalization }}</label
|
||||
><input type="text" id="surname" class="form-control" formControlName="surname" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email-address">{{ 'AbpIdentity::DisplayName:Email' | abpLocalization }}</label
|
||||
><span> * </span><input type="text" id="email-address" class="form-control" formControlName="email" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="phone-number">{{ 'AbpIdentity::DisplayName:PhoneNumber' | abpLocalization }}</label
|
||||
><input type="text" id="phone-number" class="form-control" formControlName="phoneNumber" />
|
||||
</div>
|
||||
<abp-button iconClass="fa fa-check" buttonClass="btn btn-primary color-white" (click)="submit()">
|
||||
{{ 'AbpIdentity::Save' | abpLocalization }}</abp-button
|
||||
>
|
||||
</form>
|
@ -0,0 +1,52 @@
|
||||
import { GetProfile, Profile, ProfileState, UpdateProfile } from '@abp/ng.core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Select, Store } from '@ngxs/store';
|
||||
import { Observable } from 'rxjs';
|
||||
import { take, withLatestFrom } from 'rxjs/operators';
|
||||
import { ToasterService } from '@abp/ng.theme.shared';
|
||||
|
||||
const { maxLength, required, email } = Validators;
|
||||
|
||||
@Component({
|
||||
selector: 'abp-personal-settings-form',
|
||||
templateUrl: './personal-settings.component.html',
|
||||
})
|
||||
export class PersonalSettingsComponent implements OnInit {
|
||||
@Select(ProfileState.getProfile)
|
||||
profile$: Observable<Profile.Response>;
|
||||
|
||||
form: FormGroup;
|
||||
|
||||
constructor(private fb: FormBuilder, private store: Store, private toasterService: ToasterService) {}
|
||||
|
||||
buildForm() {
|
||||
this.store
|
||||
.dispatch(new GetProfile())
|
||||
.pipe(
|
||||
withLatestFrom(this.profile$),
|
||||
take(1),
|
||||
)
|
||||
.subscribe(([, profile]) => {
|
||||
this.form = this.fb.group({
|
||||
userName: [profile.userName, [required, maxLength(256)]],
|
||||
email: [profile.email, [required, email, maxLength(256)]],
|
||||
name: [profile.name || '', [maxLength(64)]],
|
||||
surname: [profile.surname || '', [maxLength(64)]],
|
||||
phoneNumber: [profile.phoneNumber || '', [maxLength(16)]],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.form.invalid) return;
|
||||
|
||||
this.store.dispatch(new UpdateProfile(this.form.value)).subscribe(() => {
|
||||
this.toasterService.success('AbpAccount::PersonalSettingsSaved', 'Success', { life: 5000 });
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.buildForm();
|
||||
}
|
||||
}
|
Loading…
Reference in new issue