Browse Source

Merge pull request #6628 from abpframework/feat/6539

Applied extensibility to the modules for the Angular UI
pull/6643/head
Mehmet Erim 6 years ago
committed by GitHub
parent
commit
cbe58e3ef3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 106
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html
  2. 34
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts
  3. 177
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.html
  4. 65
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts
  5. 31
      npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts
  6. 32
      npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-props.ts
  7. 30
      npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts
  8. 15
      npm/ng-packs/packages/identity/src/lib/defaults/default-roles-toolbar-actions.ts
  9. 30
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts
  10. 26
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-props.ts
  11. 61
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts
  12. 15
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-toolbar-actions.ts
  13. 91
      npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts
  14. 1
      npm/ng-packs/packages/identity/src/lib/guards/index.ts
  15. 3
      npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts
  16. 41
      npm/ng-packs/packages/identity/src/lib/identity.module.ts
  17. 42
      npm/ng-packs/packages/identity/src/lib/models/config-options.ts
  18. 2
      npm/ng-packs/packages/identity/src/lib/models/index.ts
  19. 91
      npm/ng-packs/packages/identity/src/lib/tokens/extensions.token.ts
  20. 1
      npm/ng-packs/packages/identity/src/lib/tokens/index.ts

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

@ -5,77 +5,17 @@
<h5 class="card-title">{{ 'AbpIdentity::Roles' | abpLocalization }}</h5> <h5 class="card-title">{{ 'AbpIdentity::Roles' | abpLocalization }}</h5>
</div> </div>
<div class="text-right col col-md-6"> <div class="text-right col col-md-6">
<button <abp-page-toolbar [record]="data$ | async"></abp-page-toolbar>
*abpPermission="'AbpIdentity.Roles.Create'"
id="create-role"
class="btn btn-primary"
type="button"
(click)="add()"
>
<i class="fa fa-plus mr-1"></i>
<span>{{ 'AbpIdentity::NewRole' | abpLocalization }}</span>
</button>
</div> </div>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
<ngx-datatable [rows]="data$ | async" [count]="totalCount$ | async" [list]="list" default> <abp-extensible-table
<ngx-datatable-column [data]="data$ | async"
[name]="'AbpIdentity::Actions' | abpLocalization" [recordsTotal]="totalCount$ | async"
[maxWidth]="150" [list]="list"
[sortable]="false" ></abp-extensible-table>
>
<ng-template let-row="row" ngx-datatable-cell-template>
<div ngbDropdown container="body" class="d-inline-block">
<button
class="btn btn-primary btn-sm dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
ngbDropdownToggle
>
<i class="fa fa-cog mr-1"></i>{{ 'AbpIdentity::Actions' | abpLocalization }}
</button>
<div ngbDropdownMenu>
<button
*abpPermission="'AbpIdentity.Roles.Update'"
ngbDropdownItem
(click)="edit(row.id)"
>
{{ 'AbpIdentity::Edit' | abpLocalization }}
</button>
<button
*abpPermission="'AbpIdentity.Roles.ManagePermissions'"
ngbDropdownItem
(click)="openPermissionsModal(row.name)"
>
{{ 'AbpIdentity::Permissions' | abpLocalization }}
</button>
<ng-container *ngIf="!row.isStatic">
<button
*abpPermission="'AbpIdentity.Roles.Delete'"
ngbDropdownItem
(click)="delete(row.id, row.name)"
>
{{ 'AbpIdentity::Delete' | abpLocalization }}
</button>
</ng-container>
</div>
</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column [name]="'AbpIdentity::RoleName' | abpLocalization" prop="name">
<ng-template let-row="row" ngx-datatable-cell-template>
{{ row.name }}
<span *ngIf="row.isDefault" class="badge badge-pill badge-success ml-1">{{
'AbpIdentity::DisplayName:IsDefault' | abpLocalization
}}</span>
<span *ngIf="row.isPublic" class="badge badge-pill badge-info ml-1">{{
'AbpIdentity::DisplayName:IsPublic' | abpLocalization
}}</span>
</ng-template>
</ngx-datatable-column>
</ngx-datatable>
</div> </div>
</div> </div>
@ -85,36 +25,8 @@
</ng-template> </ng-template>
<ng-template #abpBody> <ng-template #abpBody>
<form #formRef [formGroup]="form" (ngSubmit)="save()" validateOnSubmit> <form [formGroup]="form" (ngSubmit)="save()" validateOnSubmit>
<div class="form-group"> <abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
<label for="role-name">{{ 'AbpIdentity::RoleName' | abpLocalization }}</label
><span> * </span>
<input autofocus type="text" id="role-name" class="form-control" formControlName="name" />
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="role-is-default"
class="custom-control-input"
formControlName="isDefault"
/>
<label class="custom-control-label" for="role-is-default">{{
'AbpIdentity::DisplayName:IsDefault' | abpLocalization
}}</label>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="role-is-public"
class="custom-control-input"
formControlName="isPublic"
/>
<label class="custom-control-label" for="role-is-public">{{
'AbpIdentity::DisplayName:IsPublic' | abpLocalization
}}</label>
</div>
</form> </form>
</ng-template> </ng-template>
@ -122,7 +34,7 @@
<button type="button" class="btn btn-secondary" #abpClose> <button type="button" class="btn btn-secondary" #abpClose>
{{ 'AbpIdentity::Cancel' | abpLocalization }} {{ 'AbpIdentity::Cancel' | abpLocalization }}
</button> </button>
<abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="onClickSaveButton()">{{ <abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="save()">{{
'AbpIdentity::Save' | abpLocalization 'AbpIdentity::Save' | abpLocalization
}}</abp-button> }}</abp-button>
</ng-template> </ng-template>

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

@ -1,8 +1,13 @@
import { ListService, PagedAndSortedResultRequestDto } from '@abp/ng.core'; import { ListService, PagedAndSortedResultRequestDto } from '@abp/ng.core';
import { ePermissionManagementComponents } from '@abp/ng.permission-management'; import { ePermissionManagementComponents } from '@abp/ng.permission-management';
import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared'; import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import {
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; EXTENSIONS_IDENTIFIER,
FormPropData,
generateFormFromProps,
} from '@abp/ng.theme.shared/extensions';
import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Select, Store } from '@ngxs/store'; import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { finalize, pluck } from 'rxjs/operators'; import { finalize, pluck } from 'rxjs/operators';
@ -13,13 +18,20 @@ import {
GetRoles, GetRoles,
UpdateRole, UpdateRole,
} from '../../actions/identity.actions'; } from '../../actions/identity.actions';
import { eIdentityComponents } from '../../enums/components';
import { IdentityRoleDto } from '../../proxy/identity/models'; import { IdentityRoleDto } from '../../proxy/identity/models';
import { IdentityState } from '../../states/identity.state'; import { IdentityState } from '../../states/identity.state';
@Component({ @Component({
selector: 'abp-roles', selector: 'abp-roles',
templateUrl: './roles.component.html', templateUrl: './roles.component.html',
providers: [ListService], providers: [
ListService,
{
provide: EXTENSIONS_IDENTIFIER,
useValue: eIdentityComponents.Roles,
},
],
}) })
export class RolesComponent implements OnInit { export class RolesComponent implements OnInit {
@Select(IdentityState.getRoles) @Select(IdentityState.getRoles)
@ -51,9 +63,9 @@ export class RolesComponent implements OnInit {
constructor( constructor(
public readonly list: ListService<PagedAndSortedResultRequestDto>, public readonly list: ListService<PagedAndSortedResultRequestDto>,
private confirmationService: ConfirmationService, protected confirmationService: ConfirmationService,
private fb: FormBuilder, protected store: Store,
private store: Store, protected injector: Injector,
) {} ) {}
ngOnInit() { ngOnInit() {
@ -61,14 +73,8 @@ export class RolesComponent implements OnInit {
} }
buildForm() { buildForm() {
this.form = this.fb.group({ const data = new FormPropData(this.injector, this.selected);
name: new FormControl({ value: this.selected.name || '', disabled: this.selected.isStatic }, [ this.form = generateFormFromProps(data);
Validators.required,
Validators.maxLength(256),
]),
isDefault: [this.selected.isDefault || false],
isPublic: [this.selected.isPublic || false],
});
} }
openModal() { openModal() {

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

@ -5,16 +5,7 @@
<h5 class="card-title">{{ 'AbpIdentity::Users' | abpLocalization }}</h5> <h5 class="card-title">{{ 'AbpIdentity::Users' | abpLocalization }}</h5>
</div> </div>
<div class="text-right col col-md-6"> <div class="text-right col col-md-6">
<button <abp-page-toolbar [record]="data$ | async"></abp-page-toolbar>
*abpPermission="'AbpIdentity.Users.Create'"
id="create-role"
class="btn btn-primary"
type="button"
(click)="add()"
>
<i class="fa fa-plus mr-1"></i>
<span>{{ 'AbpIdentity::NewUser' | abpLocalization }}</span>
</button>
</div> </div>
</div> </div>
</div> </div>
@ -30,170 +21,22 @@
</div> </div>
</div> </div>
<ngx-datatable [rows]="data$ | async" [count]="totalCount$ | async" [list]="list" default> <abp-extensible-table
<ngx-datatable-column [data]="data$ | async"
[name]="'AbpIdentity::Actions' | abpLocalization" [recordsTotal]="totalCount$ | async"
[maxWidth]="150" [list]="list"
[sortable]="false" ></abp-extensible-table>
>
<ng-template let-row="row" ngx-datatable-cell-template>
<div ngbDropdown container="body" class="d-inline-block">
<button
class="btn btn-primary btn-sm dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
ngbDropdownToggle
>
<i class="fa fa-cog mr-1"></i>{{ 'AbpIdentity::Actions' | abpLocalization }}
</button>
<div ngbDropdownMenu>
<button
*abpPermission="'AbpIdentity.Users.Update'"
ngbDropdownItem
(click)="edit(row.id)"
>
{{ 'AbpIdentity::Edit' | abpLocalization }}
</button>
<button
*abpPermission="'AbpIdentity.Users.ManagePermissions'"
ngbDropdownItem
(click)="openPermissionsModal(row.id)"
>
{{ 'AbpIdentity::Permissions' | abpLocalization }}
</button>
<button
*abpPermission="'AbpIdentity.Users.Delete'"
ngbDropdownItem
(click)="delete(row.id, row.userName)"
>
{{ 'AbpIdentity::Delete' | abpLocalization }}
</button>
</div>
</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column
[width]="200"
[name]="'AbpIdentity::UserName' | abpLocalization"
prop="userName"
></ngx-datatable-column>
<ngx-datatable-column
[width]="200"
[name]="'AbpIdentity::EmailAddress' | abpLocalization"
prop="email"
></ngx-datatable-column>
<ngx-datatable-column
[width]="200"
[name]="'AbpIdentity::PhoneNumber' | abpLocalization"
prop="phoneNumber"
></ngx-datatable-column>
</ngx-datatable>
</div> </div>
</div> </div>
<abp-modal size="md" [(visible)]="isModalVisible" [busy]="modalBusy" (disappear)="form = null"> <abp-modal size="md" [(visible)]="isModalVisible" [busy]="modalBusy">
<ng-template #abpHeader> <ng-template #abpHeader>
<h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}</h3> <h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}</h3>
</ng-template> </ng-template>
<ng-template #abpBody> <ng-template #abpBody>
<ng-template #loaderRef <form [formGroup]="form" (ngSubmit)="save()" validateOnSubmit>
><div class="text-center"><i class="fa fa-pulse fa-spinner"></i></div <abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
></ng-template>
<form *ngIf="form; else loaderRef" [formGroup]="form" (ngSubmit)="save()">
<ul ngbNav #nav="ngbNav" class="nav-tabs">
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
<ng-template ngbNavContent>
<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"
autofocus
/>
</div>
<div class="form-group">
<label for="name">{{ 'AbpIdentity::DisplayName:Name' | abpLocalization }}</label>
<input type="text" id="name" class="form-control" formControlName="name" />
</div>
<div class="form-group">
<label for="surname">{{
'AbpIdentity::DisplayName:Surname' | abpLocalization
}}</label>
<input type="text" id="surname" class="form-control" formControlName="surname" />
</div>
<div class="form-group">
<label for="password">{{ 'AbpIdentity::Password' | abpLocalization }}</label
><span *ngIf="!selected.userName"> * </span>
<input
type="password"
id="password"
autocomplete="new-password"
class="form-control"
formControlName="password"
/>
</div>
<div class="form-group">
<label for="email">{{ 'AbpIdentity::EmailAddress' | abpLocalization }}</label
><span> * </span>
<input type="text" id="email" class="form-control" formControlName="email" />
</div>
<div class="form-group">
<label for="phone-number">{{ 'AbpIdentity::PhoneNumber' | abpLocalization }}</label>
<input
type="text"
id="phone-number"
class="form-control"
formControlName="phoneNumber"
/>
</div>
<div class="custom-checkbox custom-control mb-2">
<input
type="checkbox"
id="lockout-checkbox"
class="custom-control-input"
formControlName="lockoutEnabled"
/>
<label class="custom-control-label" for="lockout-checkbox">{{
'AbpIdentity::DisplayName:LockoutEnabled' | abpLocalization
}}</label>
</div>
</ng-template>
</li>
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
<ng-template ngbNavContent>
<div
*ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn"
class="custom-checkbox custom-control mb-2"
>
<input
type="checkbox"
class="custom-control-input"
[attr.id]="'roles-' + i"
[formControl]="roleGroup.controls[roles[i].name]"
/>
<label class="custom-control-label" [attr.for]="'roles-' + i">{{
roles[i].name
}}</label>
</div>
</ng-template>
</li>
</ul>
<div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div>
</form> </form>
</ng-template> </ng-template>
@ -201,7 +44,7 @@
<button type="button" class="btn btn-secondary" #abpClose> <button type="button" class="btn btn-secondary" #abpClose>
{{ 'AbpIdentity::Cancel' | abpLocalization }} {{ 'AbpIdentity::Cancel' | abpLocalization }}
</button> </button>
<abp-button iconClass="fa fa-check" (click)="save()" [disabled]="form?.invalid">{{ <abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="save()">{{
'AbpIdentity::Save' | abpLocalization 'AbpIdentity::Save' | abpLocalization
}}</abp-button> }}</abp-button>
</ng-template> </ng-template>

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

@ -1,6 +1,11 @@
import { ListService } from '@abp/ng.core'; import { ListService } from '@abp/ng.core';
import { ePermissionManagementComponents } from '@abp/ng.permission-management'; import { ePermissionManagementComponents } from '@abp/ng.permission-management';
import { Confirmation, ConfirmationService, getPasswordValidators } from '@abp/ng.theme.shared'; import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
import {
EXTENSIONS_IDENTIFIER,
FormPropData,
generateFormFromProps,
} from '@abp/ng.theme.shared/extensions';
import { import {
Component, Component,
Injector, Injector,
@ -9,14 +14,7 @@ import {
TrackByFunction, TrackByFunction,
ViewChild, ViewChild,
} from '@angular/core'; } from '@angular/core';
import { import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms';
AbstractControl,
FormArray,
FormBuilder,
FormControl,
FormGroup,
Validators,
} from '@angular/forms';
import { Select, Store } from '@ngxs/store'; import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { finalize, pluck, switchMap, take } from 'rxjs/operators'; import { finalize, pluck, switchMap, take } from 'rxjs/operators';
@ -29,6 +27,7 @@ import {
GetUsers, GetUsers,
UpdateUser, UpdateUser,
} from '../../actions/identity.actions'; } from '../../actions/identity.actions';
import { eIdentityComponents } from '../../enums/components';
import { Identity } from '../../models/identity'; import { Identity } from '../../models/identity';
import { IdentityUserService } from '../../proxy/identity/identity-user.service'; import { IdentityUserService } from '../../proxy/identity/identity-user.service';
import { import {
@ -41,7 +40,13 @@ import { IdentityState } from '../../states/identity.state';
@Component({ @Component({
selector: 'abp-users', selector: 'abp-users',
templateUrl: './users.component.html', templateUrl: './users.component.html',
providers: [ListService], providers: [
ListService,
{
provide: EXTENSIONS_IDENTIFIER,
useValue: eIdentityComponents.Users,
},
],
}) })
export class UsersComponent implements OnInit { export class UsersComponent implements OnInit {
@Select(IdentityState.getUsers) @Select(IdentityState.getUsers)
@ -83,11 +88,11 @@ export class UsersComponent implements OnInit {
constructor( constructor(
public readonly list: ListService<GetIdentityUsersInput>, public readonly list: ListService<GetIdentityUsersInput>,
private injector: Injector, protected confirmationService: ConfirmationService,
private confirmationService: ConfirmationService, protected userService: IdentityUserService,
private fb: FormBuilder, protected fb: FormBuilder,
private store: Store, protected store: Store,
private identityUserService: IdentityUserService, protected injector: Injector,
) {} ) {}
ngOnInit() { ngOnInit() {
@ -95,19 +100,14 @@ export class UsersComponent implements OnInit {
} }
buildForm() { buildForm() {
this.identityUserService.getAssignableRoles().subscribe(({ items }) => { const data = new FormPropData(this.injector, this.selected);
this.form = generateFormFromProps(data);
this.userService.getAssignableRoles().subscribe(({ items }) => {
this.roles = items; this.roles = items;
this.form = this.fb.group({ this.form.addControl(
userName: [this.selected.userName || '', [Validators.required, Validators.maxLength(256)]], 'roleNames',
email: [ this.fb.array(
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.id ? this.selected.lockoutEnabled : true],
roleNames: this.fb.array(
this.roles.map(role => this.roles.map(role =>
this.fb.group({ this.fb.group({
[role.name]: [ [role.name]: [
@ -118,16 +118,7 @@ export class UsersComponent implements OnInit {
}), }),
), ),
), ),
}); );
const passwordValidators = getPasswordValidators(this.injector);
this.form.addControl('password', new FormControl('', [...passwordValidators]));
if (!this.selected.userName) {
this.form.get('password').setValidators([...passwordValidators, Validators.required]);
this.form.get('password').updateValueAndValidity();
}
}); });
} }

31
npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts

@ -0,0 +1,31 @@
import { EntityAction } from '@abp/ng.theme.shared/extensions';
import { RolesComponent } from '../components/roles/roles.component';
import { IdentityRoleDto } from '../proxy/identity/models';
export const DEFAULT_ROLES_ENTITY_ACTIONS = EntityAction.createMany<IdentityRoleDto>([
{
text: 'AbpIdentity::Edit',
action: data => {
const component = data.getInjected(RolesComponent);
component.edit(data.record.id);
},
permission: 'AbpIdentity.Roles.Update',
},
{
text: 'AbpIdentity::Permissions',
action: data => {
const component = data.getInjected(RolesComponent);
component.openPermissionsModal(data.record.name);
},
permission: 'AbpIdentity.Roles.ManagePermissions',
},
{
text: 'AbpIdentity::Delete',
action: data => {
const component = data.getInjected(RolesComponent);
component.delete(data.record.id, data.record.name);
},
permission: 'AbpIdentity.Roles.Delete',
visible: data => !data.record.isStatic,
},
]);

32
npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-props.ts

@ -0,0 +1,32 @@
import { LocalizationService } from '@abp/ng.core';
import { EntityProp, ePropType } from '@abp/ng.theme.shared/extensions';
import { of } from 'rxjs';
import { IdentityRoleDto } from '../proxy/identity/models';
export const DEFAULT_ROLES_ENTITY_PROPS = EntityProp.createMany<IdentityRoleDto>([
{
type: ePropType.String,
name: 'name',
displayName: 'AbpIdentity::RoleName',
sortable: true,
valueResolver: data => {
const l10n = data.getInjected(LocalizationService);
const t = l10n.instant.bind(l10n);
const { isDefault, isPublic, name } = data.record;
return of(
name +
(isDefault
? `<span class="badge badge-pill badge-success ml-1">${t(
'AbpIdentity::DisplayName:IsDefault',
)}</span>`
: '') +
(isPublic
? `<span class="badge badge-pill badge-info ml-1">${t(
'AbpIdentity::DisplayName:IsPublic',
)}</span>`
: ''),
);
},
},
]);

30
npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts

@ -0,0 +1,30 @@
import { ePropType, FormProp, PropData } from '@abp/ng.theme.shared/extensions';
import { Validators } from '@angular/forms';
import { IdentityRoleDto } from '../proxy/identity/models';
export const DEFAULT_ROLES_CREATE_FORM_PROPS = FormProp.createMany<IdentityRoleDto>([
{
type: ePropType.String,
name: 'name',
displayName: 'AbpIdentity::RoleName',
id: 'role-name',
disabled: (data: PropData<IdentityRoleDto>) => data.record && data.record.isStatic,
validators: () => [Validators.required],
},
{
type: ePropType.Boolean,
name: 'isDefault',
displayName: 'AbpIdentity::DisplayName:IsDefault',
id: 'role-is-default',
defaultValue: false,
},
{
type: ePropType.Boolean,
name: 'isPublic',
displayName: 'AbpIdentity::DisplayName:IsPublic',
id: 'role-is-public',
defaultValue: false,
},
]);
export const DEFAULT_ROLES_EDIT_FORM_PROPS = DEFAULT_ROLES_CREATE_FORM_PROPS;

15
npm/ng-packs/packages/identity/src/lib/defaults/default-roles-toolbar-actions.ts

@ -0,0 +1,15 @@
import { ToolbarAction } from '@abp/ng.theme.shared/extensions';
import { RolesComponent } from '../components/roles/roles.component';
import { IdentityRoleDto } from '../proxy/identity/models';
export const DEFAULT_ROLES_TOOLBAR_ACTIONS = ToolbarAction.createMany<IdentityRoleDto[]>([
{
text: 'AbpIdentity::NewRole',
action: data => {
const component = data.getInjected(RolesComponent);
component.add();
},
permission: 'AbpIdentity.Roles.Create',
icon: 'fa fa-plus',
},
]);

30
npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts

@ -0,0 +1,30 @@
import { EntityAction } from '@abp/ng.theme.shared/extensions';
import { UsersComponent } from '../components/users/users.component';
import { IdentityUserDto } from '../proxy/identity/models';
export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUserDto>([
{
text: 'AbpIdentity::Edit',
action: data => {
const component = data.getInjected(UsersComponent);
component.edit(data.record.id);
},
permission: 'AbpIdentity.Users.Update',
},
{
text: 'AbpIdentity::Permissions',
action: data => {
const component = data.getInjected(UsersComponent);
component.openPermissionsModal(data.record.id);
},
permission: 'AbpIdentity.Users.ManagePermissions',
},
{
text: 'AbpIdentity::Delete',
action: data => {
const component = data.getInjected(UsersComponent);
component.delete(data.record.id, data.record.name || data.record.userName);
},
permission: 'AbpIdentity.Users.Delete',
},
]);

26
npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-props.ts

@ -0,0 +1,26 @@
import { EntityProp, ePropType } from '@abp/ng.theme.shared/extensions';
import { IdentityUserDto } from '../proxy/identity/models';
export const DEFAULT_USERS_ENTITY_PROPS = EntityProp.createMany<IdentityUserDto>([
{
type: ePropType.String,
name: 'userName',
displayName: 'AbpIdentity::UserName',
sortable: true,
columnWidth: 250,
},
{
type: ePropType.String,
name: 'email',
displayName: 'AbpIdentity::EmailAddress',
sortable: true,
columnWidth: 250,
},
{
type: ePropType.String,
name: 'phoneNumber',
displayName: 'AbpIdentity::PhoneNumber',
sortable: true,
columnWidth: 250,
},
]);

61
npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts

@ -0,0 +1,61 @@
import { getPasswordValidators } from '@abp/ng.theme.shared';
import { ePropType, FormProp } from '@abp/ng.theme.shared/extensions';
import { Validators } from '@angular/forms';
import { IdentityUserDto } from '../proxy/identity/models';
export const DEFAULT_USERS_CREATE_FORM_PROPS = FormProp.createMany<IdentityUserDto>([
{
type: ePropType.String,
name: 'userName',
displayName: 'AbpIdentity::UserName',
id: 'user-name',
validators: () => [Validators.required, Validators.maxLength(256)],
},
{
type: ePropType.Password,
name: 'password',
displayName: 'AbpIdentity::Password',
id: 'password',
autocomplete: 'new-password',
validators: data => [Validators.required, ...getPasswordValidators({ get: data.getInjected })],
},
{
type: ePropType.String,
name: 'name',
displayName: 'AbpIdentity::DisplayName:Name',
id: 'name',
validators: () => [Validators.maxLength(64)],
},
{
type: ePropType.String,
name: 'surname',
displayName: 'AbpIdentity::DisplayName:Surname',
id: 'surname',
validators: () => [Validators.maxLength(64)],
},
{
type: ePropType.Email,
name: 'email',
displayName: 'AbpIdentity::EmailAddress',
id: 'email',
validators: () => [Validators.required, Validators.maxLength(256), Validators.email],
},
{
type: ePropType.String,
name: 'phoneNumber',
displayName: 'AbpIdentity::PhoneNumber',
id: 'phone-number',
validators: () => [Validators.maxLength(16)],
},
{
type: ePropType.Boolean,
name: 'lockoutEnabled',
displayName: 'AbpIdentity::DisplayName:LockoutEnabled',
id: 'lockout-checkbox',
defaultValue: true,
},
]);
export const DEFAULT_USERS_EDIT_FORM_PROPS = DEFAULT_USERS_CREATE_FORM_PROPS.filter(
prop => prop.name !== 'password',
);

15
npm/ng-packs/packages/identity/src/lib/defaults/default-users-toolbar-actions.ts

@ -0,0 +1,15 @@
import { ToolbarAction } from '@abp/ng.theme.shared/extensions';
import { UsersComponent } from '../components/users/users.component';
import { IdentityUserDto } from '../proxy/identity/models';
export const DEFAULT_USERS_TOOLBAR_ACTIONS = ToolbarAction.createMany<IdentityUserDto[]>([
{
text: 'AbpIdentity::NewUser',
action: data => {
const component = data.getInjected(UsersComponent);
component.add();
},
permission: 'AbpIdentity.Users.Create',
icon: 'fa fa-plus',
},
]);

91
npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts

@ -0,0 +1,91 @@
import { ConfigStateService } from '@abp/ng.core';
import {
ExtensionsService,
getObjectExtensionEntitiesFromStore,
mapEntitiesToContributors,
mergeWithDefaultActions,
mergeWithDefaultProps,
} from '@abp/ng.theme.shared/extensions';
import { Injectable, Injector } from '@angular/core';
import { CanActivate } from '@angular/router';
import { Observable } from 'rxjs';
import { map, mapTo, tap } from 'rxjs/operators';
import { eIdentityComponents } from '../enums/components';
import {
IdentityCreateFormPropContributors,
IdentityEditFormPropContributors,
IdentityEntityActionContributors,
IdentityEntityPropContributors,
IdentityToolbarActionContributors,
} from '../models/config-options';
import {
DEFAULT_IDENTITY_CREATE_FORM_PROPS,
DEFAULT_IDENTITY_EDIT_FORM_PROPS,
DEFAULT_IDENTITY_ENTITY_ACTIONS,
DEFAULT_IDENTITY_ENTITY_PROPS,
DEFAULT_IDENTITY_TOOLBAR_ACTIONS,
IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS,
IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS,
IDENTITY_ENTITY_ACTION_CONTRIBUTORS,
IDENTITY_ENTITY_PROP_CONTRIBUTORS,
IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS,
} from '../tokens/extensions.token';
@Injectable()
export class IdentityExtensionsGuard implements CanActivate {
constructor(private injector: Injector) {}
canActivate(): Observable<boolean> {
const extensions: ExtensionsService = this.injector.get(ExtensionsService);
const actionContributors: IdentityEntityActionContributors =
this.injector.get(IDENTITY_ENTITY_ACTION_CONTRIBUTORS, null) || {};
const toolbarContributors: IdentityToolbarActionContributors =
this.injector.get(IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS, null) || {};
const propContributors: IdentityEntityPropContributors =
this.injector.get(IDENTITY_ENTITY_PROP_CONTRIBUTORS, null) || {};
const createFormContributors: IdentityCreateFormPropContributors =
this.injector.get(IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS, null) || {};
const editFormContributors: IdentityEditFormPropContributors =
this.injector.get(IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS, null) || {};
const configState = this.injector.get(ConfigStateService);
return getObjectExtensionEntitiesFromStore(configState, 'Identity').pipe(
map(entities => ({
[eIdentityComponents.Roles]: entities.Role,
[eIdentityComponents.Users]: entities.User,
})),
mapEntitiesToContributors(configState, 'AbpIdentity'),
tap(objectExtensionContributors => {
mergeWithDefaultActions(
extensions.entityActions,
DEFAULT_IDENTITY_ENTITY_ACTIONS,
actionContributors,
);
mergeWithDefaultActions(
extensions.toolbarActions,
DEFAULT_IDENTITY_TOOLBAR_ACTIONS,
toolbarContributors,
);
mergeWithDefaultProps(
extensions.entityProps,
DEFAULT_IDENTITY_ENTITY_PROPS,
objectExtensionContributors.prop,
propContributors,
);
mergeWithDefaultProps(
extensions.createFormProps,
DEFAULT_IDENTITY_CREATE_FORM_PROPS,
objectExtensionContributors.createForm,
createFormContributors,
);
mergeWithDefaultProps(
extensions.editFormProps,
DEFAULT_IDENTITY_EDIT_FORM_PROPS,
objectExtensionContributors.editForm,
editFormContributors,
);
}),
mapTo(true),
);
}
}

1
npm/ng-packs/packages/identity/src/lib/guards/index.ts

@ -0,0 +1 @@
export * from './extensions.guard';

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

@ -10,13 +10,14 @@ import { RouterModule, Routes } from '@angular/router';
import { RolesComponent } from './components/roles/roles.component'; import { RolesComponent } from './components/roles/roles.component';
import { UsersComponent } from './components/users/users.component'; import { UsersComponent } from './components/users/users.component';
import { eIdentityComponents } from './enums/components'; import { eIdentityComponents } from './enums/components';
import { IdentityExtensionsGuard } from './guards/extensions.guard';
const routes: Routes = [ const routes: Routes = [
{ path: '', redirectTo: 'roles', pathMatch: 'full' }, { path: '', redirectTo: 'roles', pathMatch: 'full' },
{ {
path: '', path: '',
component: DynamicLayoutComponent, component: DynamicLayoutComponent,
canActivate: [AuthGuard, PermissionGuard], canActivate: [AuthGuard, PermissionGuard, IdentityExtensionsGuard],
children: [ children: [
{ {
path: 'roles', path: 'roles',

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

@ -1,14 +1,24 @@
import { CoreModule, LazyModuleFactory } from '@abp/ng.core'; import { CoreModule, LazyModuleFactory } from '@abp/ng.core';
import { PermissionManagementModule } from '@abp/ng.permission-management'; import { PermissionManagementModule } from '@abp/ng.permission-management';
import { ThemeSharedModule } from '@abp/ng.theme.shared'; import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { UiExtensionsModule } from '@abp/ng.theme.shared/extensions';
import { ModuleWithProviders, NgModule, NgModuleFactory } from '@angular/core'; import { ModuleWithProviders, NgModule, NgModuleFactory } from '@angular/core';
import { NgbDropdownModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbDropdownModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxValidateCoreModule } from '@ngx-validate/core'; import { NgxValidateCoreModule } from '@ngx-validate/core';
import { NgxsModule } from '@ngxs/store'; import { NgxsModule } from '@ngxs/store';
import { RolesComponent } from './components/roles/roles.component'; import { RolesComponent } from './components/roles/roles.component';
import { UsersComponent } from './components/users/users.component'; import { UsersComponent } from './components/users/users.component';
import { IdentityExtensionsGuard } from './guards/extensions.guard';
import { IdentityRoutingModule } from './identity-routing.module'; import { IdentityRoutingModule } from './identity-routing.module';
import { IdentityConfigOptions } from './models/config-options';
import { IdentityState } from './states/identity.state'; import { IdentityState } from './states/identity.state';
import {
IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS,
IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS,
IDENTITY_ENTITY_ACTION_CONTRIBUTORS,
IDENTITY_ENTITY_PROP_CONTRIBUTORS,
IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS,
} from './tokens/extensions.token';
@NgModule({ @NgModule({
declarations: [RolesComponent, UsersComponent], declarations: [RolesComponent, UsersComponent],
@ -19,20 +29,43 @@ import { IdentityState } from './states/identity.state';
IdentityRoutingModule, IdentityRoutingModule,
NgbNavModule, NgbNavModule,
ThemeSharedModule, ThemeSharedModule,
UiExtensionsModule,
NgbDropdownModule, NgbDropdownModule,
PermissionManagementModule, PermissionManagementModule,
NgxValidateCoreModule, NgxValidateCoreModule,
], ],
}) })
export class IdentityModule { export class IdentityModule {
static forChild(): ModuleWithProviders<IdentityModule> { static forChild(options: IdentityConfigOptions = {}): ModuleWithProviders<IdentityModule> {
return { return {
ngModule: IdentityModule, ngModule: IdentityModule,
providers: [], providers: [
{
provide: IDENTITY_ENTITY_ACTION_CONTRIBUTORS,
useValue: options.entityActionContributors,
},
{
provide: IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS,
useValue: options.toolbarActionContributors,
},
{
provide: IDENTITY_ENTITY_PROP_CONTRIBUTORS,
useValue: options.entityPropContributors,
},
{
provide: IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS,
useValue: options.createFormPropContributors,
},
{
provide: IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS,
useValue: options.editFormPropContributors,
},
IdentityExtensionsGuard,
],
}; };
} }
static forLazy(): NgModuleFactory<IdentityModule> { static forLazy(options: IdentityConfigOptions = {}): NgModuleFactory<IdentityModule> {
return new LazyModuleFactory(IdentityModule.forChild()); return new LazyModuleFactory(IdentityModule.forChild(options));
} }
} }

42
npm/ng-packs/packages/identity/src/lib/models/config-options.ts

@ -0,0 +1,42 @@
import {
CreateFormPropContributorCallback,
EditFormPropContributorCallback,
EntityActionContributorCallback,
EntityPropContributorCallback,
ToolbarActionContributorCallback,
} from '@abp/ng.theme.shared/extensions';
import { eIdentityComponents } from '../enums/components';
import { IdentityRoleDto, IdentityUserDto } from '../proxy/identity/models';
export type IdentityEntityActionContributors = Partial<{
[eIdentityComponents.Roles]: EntityActionContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: EntityActionContributorCallback<IdentityUserDto>[];
}>;
export type IdentityToolbarActionContributors = Partial<{
[eIdentityComponents.Roles]: ToolbarActionContributorCallback<IdentityRoleDto[]>[];
[eIdentityComponents.Users]: ToolbarActionContributorCallback<IdentityUserDto[]>[];
}>;
export type IdentityEntityPropContributors = Partial<{
[eIdentityComponents.Roles]: EntityPropContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: EntityPropContributorCallback<IdentityUserDto>[];
}>;
export type IdentityCreateFormPropContributors = Partial<{
[eIdentityComponents.Roles]: CreateFormPropContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: CreateFormPropContributorCallback<IdentityUserDto>[];
}>;
export type IdentityEditFormPropContributors = Partial<{
[eIdentityComponents.Roles]: EditFormPropContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: EditFormPropContributorCallback<IdentityUserDto>[];
}>;
export interface IdentityConfigOptions {
entityActionContributors?: IdentityEntityActionContributors;
toolbarActionContributors?: IdentityToolbarActionContributors;
entityPropContributors?: IdentityEntityPropContributors;
createFormPropContributors?: IdentityCreateFormPropContributors;
editFormPropContributors?: IdentityEditFormPropContributors;
}

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

@ -0,0 +1,2 @@
export * from './config-options';
export * from './identity';

91
npm/ng-packs/packages/identity/src/lib/tokens/extensions.token.ts

@ -0,0 +1,91 @@
import {
CreateFormPropContributorCallback,
EditFormPropContributorCallback,
EntityActionContributorCallback,
EntityPropContributorCallback,
ToolbarActionContributorCallback,
} from '@abp/ng.theme.shared/extensions';
import { InjectionToken } from '@angular/core';
import { DEFAULT_ROLES_ENTITY_ACTIONS } from '../defaults/default-roles-entity-actions';
import { DEFAULT_ROLES_ENTITY_PROPS } from '../defaults/default-roles-entity-props';
import {
DEFAULT_ROLES_CREATE_FORM_PROPS,
DEFAULT_ROLES_EDIT_FORM_PROPS,
} from '../defaults/default-roles-form-props';
import { DEFAULT_ROLES_TOOLBAR_ACTIONS } from '../defaults/default-roles-toolbar-actions';
import { DEFAULT_USERS_ENTITY_ACTIONS } from '../defaults/default-users-entity-actions';
import { DEFAULT_USERS_ENTITY_PROPS } from '../defaults/default-users-entity-props';
import {
DEFAULT_USERS_CREATE_FORM_PROPS,
DEFAULT_USERS_EDIT_FORM_PROPS,
} from '../defaults/default-users-form-props';
import { DEFAULT_USERS_TOOLBAR_ACTIONS } from '../defaults/default-users-toolbar-actions';
import { eIdentityComponents } from '../enums/components';
import { IdentityRoleDto, IdentityUserDto } from '../proxy/identity/models';
export const DEFAULT_IDENTITY_ENTITY_ACTIONS = {
[eIdentityComponents.Roles]: DEFAULT_ROLES_ENTITY_ACTIONS,
[eIdentityComponents.Users]: DEFAULT_USERS_ENTITY_ACTIONS,
};
export const DEFAULT_IDENTITY_TOOLBAR_ACTIONS = {
[eIdentityComponents.Roles]: DEFAULT_ROLES_TOOLBAR_ACTIONS,
[eIdentityComponents.Users]: DEFAULT_USERS_TOOLBAR_ACTIONS,
};
export const DEFAULT_IDENTITY_ENTITY_PROPS = {
[eIdentityComponents.Roles]: DEFAULT_ROLES_ENTITY_PROPS,
[eIdentityComponents.Users]: DEFAULT_USERS_ENTITY_PROPS,
};
export const DEFAULT_IDENTITY_CREATE_FORM_PROPS = {
[eIdentityComponents.Roles]: DEFAULT_ROLES_CREATE_FORM_PROPS,
[eIdentityComponents.Users]: DEFAULT_USERS_CREATE_FORM_PROPS,
};
export const DEFAULT_IDENTITY_EDIT_FORM_PROPS = {
[eIdentityComponents.Roles]: DEFAULT_ROLES_EDIT_FORM_PROPS,
[eIdentityComponents.Users]: DEFAULT_USERS_EDIT_FORM_PROPS,
};
export const IDENTITY_ENTITY_ACTION_CONTRIBUTORS = new InjectionToken<EntityActionContributors>(
'IDENTITY_ENTITY_ACTION_CONTRIBUTORS',
);
export const IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS = new InjectionToken<ToolbarActionContributors>(
'IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS',
);
export const IDENTITY_ENTITY_PROP_CONTRIBUTORS = new InjectionToken<EntityPropContributors>(
'IDENTITY_ENTITY_PROP_CONTRIBUTORS',
);
export const IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS = new InjectionToken<CreateFormPropContributors>(
'IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS',
);
export const IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS = new InjectionToken<EditFormPropContributors>(
'IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS',
);
// Fix for TS4023 -> https://github.com/microsoft/TypeScript/issues/9944#issuecomment-254693497
type EntityActionContributors = Partial<{
[eIdentityComponents.Roles]: EntityActionContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: EntityActionContributorCallback<IdentityUserDto>[];
}>;
type ToolbarActionContributors = Partial<{
[eIdentityComponents.Roles]: ToolbarActionContributorCallback<IdentityRoleDto[]>[];
[eIdentityComponents.Users]: ToolbarActionContributorCallback<IdentityUserDto[]>[];
}>;
type EntityPropContributors = Partial<{
[eIdentityComponents.Roles]: EntityPropContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: EntityPropContributorCallback<IdentityUserDto>[];
}>;
type CreateFormPropContributors = Partial<{
[eIdentityComponents.Roles]: CreateFormPropContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: CreateFormPropContributorCallback<IdentityUserDto>[];
}>;
type EditFormPropContributors = Partial<{
[eIdentityComponents.Roles]: EditFormPropContributorCallback<IdentityRoleDto>[];
[eIdentityComponents.Users]: EditFormPropContributorCallback<IdentityUserDto>[];
}>;

1
npm/ng-packs/packages/identity/src/lib/tokens/index.ts

@ -0,0 +1 @@
export * from './extensions.token';
Loading…
Cancel
Save