Browse Source

feature(identity): change add/edit modal

pull/1556/head
TheDiaval 7 years ago
parent
commit
1ca585f1ac
  1. 40
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html
  2. 16
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts
  3. 205
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  4. 151
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts
  5. 2
      npm/ng-packs/packages/identity/src/lib/identity.module.ts

40
npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html

@ -58,17 +58,13 @@
</div> </div>
</div> </div>
<ng-template #modalContent let-modal> <abp-modal size="md" [(visible)]="isModalVisible" *ngIf="isModalVisible" [centered]="true">
<div class="modal-header"> <ng-template #abpHeader>
<h5 class="modal-title" id="modal-basic-title"> <h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocalization }}</h3>
{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocalization }} </ng-template>
</h5>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss()"> <ng-template #abpBody>
<span aria-hidden="true">&times;</span> <form [formGroup]="form">
</button>
</div>
<form [formGroup]="form" (ngSubmit)="save()">
<div class="modal-body">
<div class="form-group"> <div class="form-group">
<label for="role-name">{{ 'AbpIdentity::RoleName' | abpLocalization }}</label <label for="role-name">{{ 'AbpIdentity::RoleName' | abpLocalization }}</label
><span> * </span> ><span> * </span>
@ -88,18 +84,18 @@
'AbpIdentity::DisplayName:IsPublic' | abpLocalization 'AbpIdentity::DisplayName:IsPublic' | abpLocalization
}}</label> }}</label>
</div> </div>
</div> </form>
</ng-template>
<div class="modal-footer"> <ng-template #abpFooter>
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="modal.close()"> <button type="button" class="btn btn-secondary" #abpClose>
{{ 'AbpIdentity::Cancel' | abpLocalization }} {{ 'AbpIdentity::Cancel' | abpLocalization }}
</button> </button>
<button type="submit" class="btn btn-primary"> <button type="button" class="btn btn-primary" (click)="save()">
<i class="fa fa-check mr-1"></i> <span>{{ 'AbpIdentity::Save' | abpLocalization }}</span> <i class="fa fa-check mr-1"></i> <span>{{ 'AbpIdentity::Save' | abpLocalization }}</span>
</button> </button>
</div> </ng-template>
</form> </abp-modal>
</ng-template>
<abp-permission-management <abp-permission-management
[(visible)]="visiblePermissions" [(visible)]="visiblePermissions"

16
npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts

@ -1,7 +1,6 @@
import { Component, TemplateRef, ViewChild } from '@angular/core'; import { Component, TemplateRef, ViewChild } from '@angular/core';
import { Select, Store } from '@ngxs/store'; import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { IdentityState } from '../../states/identity.state'; import { IdentityState } from '../../states/identity.state';
import { Identity } from '../../models/identity'; import { Identity } from '../../models/identity';
@ -26,6 +25,8 @@ export class RolesComponent {
selected: Identity.RoleItem; selected: Identity.RoleItem;
isModalVisible: boolean;
visiblePermissions: boolean = false; visiblePermissions: boolean = false;
providerKey: string; providerKey: string;
@ -33,12 +34,7 @@ export class RolesComponent {
@ViewChild('modalContent', { static: false }) @ViewChild('modalContent', { static: false })
modalContent: TemplateRef<any>; modalContent: TemplateRef<any>;
constructor( constructor(private confirmationService: ConfirmationService, private fb: FormBuilder, private store: Store) {}
private confirmationService: ConfirmationService,
private modalService: NgbModal,
private fb: FormBuilder,
private store: Store,
) {}
createForm() { createForm() {
this.form = this.fb.group({ this.form = this.fb.group({
@ -50,7 +46,7 @@ export class RolesComponent {
openModal() { openModal() {
this.createForm(); this.createForm();
this.modalService.open(this.modalContent); this.isModalVisible = true;
} }
onAdd() { onAdd() {
@ -77,7 +73,9 @@ export class RolesComponent {
? new IdentityUpdateRole({ ...this.form.value, id: this.selected.id }) ? new IdentityUpdateRole({ ...this.form.value, id: this.selected.id })
: new IdentityAddRole(this.form.value), : new IdentityAddRole(this.form.value),
) )
.subscribe(() => this.modalService.dismissAll()); .subscribe(() => {
this.isModalVisible = false;
});
} }
delete(id: string, name: string) { delete(id: string, name: string) {

205
npm/ng-packs/packages/identity/src/lib/components/users/users.component.html

@ -77,119 +77,118 @@
</div> </div>
</div> </div>
<ng-template #modalContent let-modal> <abp-modal [(visible)]="isModalVisible" *ngIf="isModalVisible" [centered]="true">
<div class="modal-header"> <ng-template #abpHeader>
<h5 class="modal-title" id="modal-basic-title"> <h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}</h3>
{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }} </ng-template>
</h5>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss()">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form [formGroup]="form" (ngSubmit)="save()">
<div class="modal-body">
<ngb-tabset>
<ngb-tab [title]="'AbpIdentity::UserInformations' | abpLocalization">
<ng-template ngbTabContent>
<div class="mt-2">
<div class="form-group">
<label for="user-name">{{ 'AbpIdentity::UserName' | abpLocalization }}</label
><span> * </span>
<input type="text" id="user-name" class="form-control" formControlName="userName" />
</div>
<div class="form-group"> <ng-template #abpBody>
<label for="name">{{ 'AbpIdentity::Name' | abpLocalization }}</label> <perfect-scrollbar class="ps-show-always" style="max-height: 65vh;">
<input type="text" id="name" class="form-control" formControlName="name" /> <form [formGroup]="form">
</div> <ngb-tabset>
<ngb-tab [title]="'AbpIdentity::UserInformations' | abpLocalization">
<ng-template ngbTabContent>
<div class="mt-2">
<div class="form-group">
<label for="user-name">{{ 'AbpIdentity::UserName' | abpLocalization }}</label
><span> * </span>
<input type="text" id="user-name" class="form-control" formControlName="userName" />
</div>
<div class="form-group"> <div class="form-group">
<label for="surname">{{ 'AbpIdentity::DisplayName:Surname' | abpLocalization }}</label> <label for="name">{{ 'AbpIdentity::DisplayName:Name' | abpLocalization }}</label>
<input type="text" id="surname" class="form-control" formControlName="surname" /> <input type="text" id="name" class="form-control" formControlName="name" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">{{ 'AbpIdentity::Password' | abpLocalization }}</label <label for="surname">{{ 'AbpIdentity::DisplayName:Surname' | abpLocalization }}</label>
><span> * </span> <input type="text" id="surname" class="form-control" formControlName="surname" />
<input </div>
type="password"
id="password"
autocomplete="new-password"
class="form-control"
formControlName="password"
/>
</div>
<div class="form-group"> <div class="form-group">
<label for="email">{{ 'AbpIdentity::EmailAddress' | abpLocalization }}</label <label for="password">{{ 'AbpIdentity::Password' | abpLocalization }}</label
><span> * </span> ><span> * </span>
<input type="text" id="email" class="form-control" formControlName="email" /> <input
</div> type="password"
id="password"
autocomplete="new-password"
class="form-control"
formControlName="password"
/>
</div>
<div class="form-group"> <div class="form-group">
<label for="phone-number">{{ 'AbpIdentity::PhoneNumber' | abpLocalization }}</label> <label for="email">{{ 'AbpIdentity::EmailAddress' | abpLocalization }}</label
<input type="text" id="phone-number" class="form-control" formControlName="phoneNumber" /> ><span> * </span>
</div> <input type="text" id="email" class="form-control" formControlName="email" />
</div>
<div class="custom-checkbox custom-control mb-2"> <div class="form-group">
<input <label for="phone-number">{{ 'AbpIdentity::PhoneNumber' | abpLocalization }}</label>
type="checkbox" <input type="text" id="phone-number" class="form-control" formControlName="phoneNumber" />
id="lockout-checkbox" </div>
class="custom-control-input"
formControlName="lockoutEnabled"
/>
<label class="custom-control-label" for="lockout-checkbox">{{
'AbpIdentity::DisplayName:LockoutEnabled' | abpLocalization
}}</label>
</div>
<div class="custom-checkbox custom-control mb-2"> <div class="custom-checkbox custom-control mb-2">
<input <input
type="checkbox" type="checkbox"
id="two-factor-checkbox" id="lockout-checkbox"
class="custom-control-input" class="custom-control-input"
formControlName="twoFactorEnabled" formControlName="lockoutEnabled"
/> />
<label class="custom-control-label" for="two-factor-checkbox">{{ <label class="custom-control-label" for="lockout-checkbox">{{
'AbpIdentity::DisplayName:TwoFactorEnabled' | abpLocalization 'AbpIdentity::DisplayName:LockoutEnabled' | abpLocalization
}}</label> }}</label>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="two-factor-checkbox"
class="custom-control-input"
formControlName="twoFactorEnabled"
/>
<label class="custom-control-label" for="two-factor-checkbox">{{
'AbpIdentity::DisplayName:TwoFactorEnabled' | abpLocalization
}}</label>
</div>
</div> </div>
</div> </ng-template>
</ng-template> </ngb-tab>
</ngb-tab> <ngb-tab [title]="'AbpIdentity::Roles' | abpLocalization">
<ngb-tab [title]="'AbpIdentity::Roles' | abpLocalization"> <ng-template ngbTabContent>
<ng-template ngbTabContent> <div class="mt-2">
<div class="mt-2"> <div
<div *ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn"
*ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn" class="custom-checkbox custom-control mb-2"
class="custom-checkbox custom-control mb-2" >
> <input
<input type="checkbox"
type="checkbox" name="Roles[0].IsAssigned"
name="Roles[0].IsAssigned" value="true"
value="true" class="custom-control-input"
class="custom-control-input" [attr.id]="'roles-' + i"
[attr.id]="'roles-' + i" [formControl]="roleGroup.controls[roles[i].name]"
[formControl]="roleGroup.controls[roles[i].name]" />
/> <label class="custom-control-label" [attr.for]="'roles-' + i">{{ roles[i].name }}</label>
<label class="custom-control-label" [attr.for]="'roles-' + i">{{ roles[i].name }}</label> </div>
</div> </div>
</div> </ng-template>
</ng-template> </ngb-tab>
</ngb-tab> </ngb-tabset>
</ngb-tabset> </form>
</div> </perfect-scrollbar>
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
{{ 'AbpIdentity::Cancel' | abpLocalization }}
</button>
<button type="button" class="btn btn-primary" (click)="save()">
<i class="fa fa-check mr-1"></i> <span>{{ 'AbpIdentity::Save' | abpLocalization }}</span>
</button>
</ng-template>
</abp-modal>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="modal.close()">
{{ 'AbpIdentity::Cancel' | abpLocalization }}
</button>
<button type="submit" class="btn btn-primary">
<i class="fa fa-check mr-1"></i> <span>{{ 'AbpIdentity::Save' | abpLocalization }}</span>
</button>
</div>
</form>
</ng-template>
<abp-permission-management <abp-permission-management
[(visible)]="visiblePermissions" [(visible)]="visiblePermissions"
providerName="User" providerName="User"

151
npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts

@ -1,27 +1,37 @@
import { Component, TemplateRef, ViewChild, TrackByFunction, OnInit } from '@angular/core'; import { ABP } from "@abp/ng.core";
import { Select, Store } from '@ngxs/store'; import { ConfirmationService, Toaster } from "@abp/ng.theme.shared";
import { Observable, combineLatest, Subject } from 'rxjs'; import {
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; Component,
import { FormBuilder, FormGroup, Validators, FormArray, AbstractControl } from '@angular/forms'; OnInit,
import { IdentityState } from '../../states/identity.state'; TemplateRef,
import { Identity } from '../../models/identity'; TrackByFunction,
ViewChild
} from "@angular/core";
import {
AbstractControl,
FormArray,
FormBuilder,
FormGroup,
Validators
} from "@angular/forms";
import { validatePassword } from "@ngx-validate/core";
import { Select, Store } from "@ngxs/store";
import { combineLatest, Observable, Subject } from "rxjs";
import { debounceTime, filter, map, pluck, take } from "rxjs/operators";
import snq from "snq";
import { import {
IdentityUpdateUser,
IdentityAddUser, IdentityAddUser,
IdentityDeleteUser, IdentityDeleteUser,
IdentityGetUserById, IdentityGetUserById,
IdentityGetUserRoles,
IdentityGetUsers, IdentityGetUsers,
} from '../../actions/identity.actions'; IdentityUpdateUser
import { pluck, filter, map, take, debounceTime } from 'rxjs/operators'; } from "../../actions/identity.actions";
import { ConfirmationService, Toaster } from '@abp/ng.theme.shared'; import { Identity } from "../../models/identity";
import snq from 'snq'; import { IdentityState } from "../../states/identity.state";
import { IdentityGetUserRoles } from '../../actions/identity.actions';
import { validatePassword } from '@ngx-validate/core';
import { ABP } from '@abp/ng.core';
@Component({ @Component({
selector: 'abp-users', selector: "abp-users",
templateUrl: './users.component.html', templateUrl: "./users.component.html"
}) })
export class UsersComponent implements OnInit { export class UsersComponent implements OnInit {
@Select(IdentityState.getUsers) @Select(IdentityState.getUsers)
@ -30,7 +40,7 @@ export class UsersComponent implements OnInit {
@Select(IdentityState.getUsersTotalCount) @Select(IdentityState.getUsersTotalCount)
totalCount$: Observable<number>; totalCount$: Observable<number>;
@ViewChild('modalContent', { static: false }) @ViewChild("modalContent", { static: false })
modalContent: TemplateRef<any>; modalContent: TemplateRef<any>;
form: FormGroup; form: FormGroup;
@ -46,24 +56,29 @@ export class UsersComponent implements OnInit {
providerKey: string; providerKey: string;
pageQuery: ABP.PageQueryParams = { pageQuery: ABP.PageQueryParams = {
sorting: 'userName', sorting: "userName"
}; };
isModalVisible: boolean;
loading: boolean = false; loading: boolean = false;
search$ = new Subject<string>(); search$ = new Subject<string>();
trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index; trackByFn: TrackByFunction<AbstractControl> = (index, item) =>
Object.keys(item)[0] || index;
get roleGroups(): FormGroup[] { get roleGroups(): FormGroup[] {
return snq(() => (this.form.get('roleNames') as FormArray).controls as FormGroup[], []); return snq(
() => (this.form.get("roleNames") as FormArray).controls as FormGroup[],
[]
);
} }
constructor( constructor(
private confirmationService: ConfirmationService, private confirmationService: ConfirmationService,
private modalService: NgbModal,
private fb: FormBuilder, private fb: FormBuilder,
private store: Store, private store: Store
) {} ) {}
ngOnInit() { ngOnInit() {
@ -78,34 +93,51 @@ export class UsersComponent implements OnInit {
this.form = this.fb.group({ this.form = this.fb.group({
password: [ password: [
'', "",
[ [
Validators.required, Validators.required,
Validators.maxLength(32), Validators.maxLength(32),
Validators.minLength(6), Validators.minLength(6),
validatePassword(['small', 'capital', 'number', 'special']), validatePassword(["small", "capital", "number", "special"])
], ]
],
userName: [
this.selected.userName || "",
[Validators.required, Validators.maxLength(256)]
],
email: [
this.selected.email || "",
[Validators.required, Validators.email, Validators.maxLength(256)]
],
name: [this.selected.name || "", [Validators.maxLength(64)]],
surname: [this.selected.surname || "", [Validators.maxLength(64)]],
phoneNumber: [
this.selected.phoneNumber || "",
[Validators.maxLength(16)]
],
lockoutEnabled: [
this.selected.twoFactorEnabled || (this.selected.id ? false : true)
],
twoFactorEnabled: [
this.selected.twoFactorEnabled || (this.selected.id ? false : true)
], ],
userName: [this.selected.userName || '', [Validators.required, Validators.maxLength(256)]],
email: [this.selected.email || '', [Validators.required, Validators.email, Validators.maxLength(256)]],
name: [this.selected.name || '', [Validators.maxLength(64)]],
surname: [this.selected.surname || '', [Validators.maxLength(64)]],
phoneNumber: [this.selected.phoneNumber || '', [Validators.maxLength(16)]],
lockoutEnabled: [this.selected.twoFactorEnabled || (this.selected.id ? false : true)],
twoFactorEnabled: [this.selected.twoFactorEnabled || (this.selected.id ? false : true)],
roleNames: this.fb.array( roleNames: this.fb.array(
this.roles.map(role => this.roles.map(role =>
this.fb.group({ this.fb.group({
[role.name]: [!!snq(() => this.selectedUserRoles.find(userRole => userRole.id === role.id))], [role.name]: [
}), !!snq(() =>
), this.selectedUserRoles.find(userRole => userRole.id === role.id)
), )
]
})
)
)
}); });
} }
openModal() { openModal() {
this.buildForm(); this.buildForm();
this.modalService.open(this.modalContent); this.isModalVisible = true;
} }
onAdd() { onAdd() {
@ -115,12 +147,15 @@ export class UsersComponent implements OnInit {
} }
onEdit(id: string) { onEdit(id: string) {
combineLatest([this.store.dispatch(new IdentityGetUserById(id)), this.store.dispatch(new IdentityGetUserRoles(id))]) combineLatest([
this.store.dispatch(new IdentityGetUserById(id)),
this.store.dispatch(new IdentityGetUserRoles(id))
])
.pipe( .pipe(
filter(([res1, res2]) => res1 && res2), filter(([res1, res2]) => res1 && res2),
map(([state, _]) => state), map(([state, _]) => state),
pluck('IdentityState'), pluck("IdentityState"),
take(1), take(1)
) )
.subscribe((state: Identity.State) => { .subscribe((state: Identity.State) => {
this.selected = state.selectedUser; this.selected = state.selectedUser;
@ -134,8 +169,11 @@ export class UsersComponent implements OnInit {
const { roleNames } = this.form.value; const { roleNames } = this.form.value;
const mappedRoleNames = snq( const mappedRoleNames = snq(
() => roleNames.filter(role => !!role[Object.keys(role)[0]]).map(role => Object.keys(role)[0]), () =>
[], roleNames
.filter(role => !!role[Object.keys(role)[0]])
.map(role => Object.keys(role)[0]),
[]
); );
this.store this.store
@ -144,18 +182,27 @@ export class UsersComponent implements OnInit {
? new IdentityUpdateUser({ ? new IdentityUpdateUser({
...this.form.value, ...this.form.value,
id: this.selected.id, id: this.selected.id,
roleNames: mappedRoleNames, roleNames: mappedRoleNames
})
: new IdentityAddUser({
...this.form.value,
roleNames: mappedRoleNames
}) })
: new IdentityAddUser({ ...this.form.value, roleNames: mappedRoleNames }),
) )
.subscribe(() => this.modalService.dismissAll()); .subscribe(() => {
this.isModalVisible = false;
});
} }
delete(id: string, userName: string) { delete(id: string, userName: string) {
this.confirmationService this.confirmationService
.warn('AbpIdentity::UserDeletionConfirmationMessage', 'AbpIdentity::AreYouSure', { .warn(
messageLocalizationParams: [userName], "AbpIdentity::UserDeletionConfirmationMessage",
}) "AbpIdentity::AreYouSure",
{
messageLocalizationParams: [userName]
}
)
.subscribe((status: Toaster.Status) => { .subscribe((status: Toaster.Status) => {
if (status === Toaster.Status.confirm) { if (status === Toaster.Status.confirm) {
this.store.dispatch(new IdentityDeleteUser(id)); this.store.dispatch(new IdentityDeleteUser(id));
@ -172,6 +219,8 @@ export class UsersComponent implements OnInit {
get() { get() {
this.loading = true; this.loading = true;
this.store.dispatch(new IdentityGetUsers(this.pageQuery)).subscribe(() => (this.loading = false)); this.store
.dispatch(new IdentityGetUsers(this.pageQuery))
.subscribe(() => (this.loading = false));
} }
} }

2
npm/ng-packs/packages/identity/src/lib/identity.module.ts

@ -10,6 +10,7 @@ import { UsersComponent } from './components/users/users.component';
import { PermissionManagementModule } from '@abp/ng.permission-management'; import { PermissionManagementModule } from '@abp/ng.permission-management';
import { TableModule } from 'primeng/table'; import { TableModule } from 'primeng/table';
import { NgxValidateCoreModule } from '@ngx-validate/core'; import { NgxValidateCoreModule } from '@ngx-validate/core';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
@NgModule({ @NgModule({
declarations: [RolesComponent, UsersComponent], declarations: [RolesComponent, UsersComponent],
@ -23,6 +24,7 @@ import { NgxValidateCoreModule } from '@ngx-validate/core';
NgbDropdownModule, NgbDropdownModule,
PermissionManagementModule, PermissionManagementModule,
NgxValidateCoreModule, NgxValidateCoreModule,
PerfectScrollbarModule,
], ],
}) })
export class IdentityModule {} export class IdentityModule {}

Loading…
Cancel
Save