From 947fd0a2ba69737b471b51b394ff5ca425e085ef Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 11:03:07 +0300 Subject: [PATCH 01/10] feat: add default actions and props for roles page --- .../defaults/default-roles-entity-actions.ts | 31 ++++++++++++++++++ .../defaults/default-roles-entity-props.ts | 32 +++++++++++++++++++ .../lib/defaults/default-roles-form-props.ts | 30 +++++++++++++++++ .../defaults/default-roles-toolbar-actions.ts | 15 +++++++++ 4 files changed, 108 insertions(+) create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-props.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-roles-toolbar-actions.ts diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts new file mode 100644 index 00000000000..2a2822c62e2 --- /dev/null +++ b/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([ + { + 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, + }, +]); diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-props.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-props.ts new file mode 100644 index 00000000000..bd3a49def2c --- /dev/null +++ b/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([ + { + 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 + ? `${t( + 'AbpIdentity::DisplayName:IsDefault', + )}` + : '') + + (isPublic + ? `${t( + 'AbpIdentity::DisplayName:IsPublic', + )}` + : ''), + ); + }, + }, +]); diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts new file mode 100644 index 00000000000..a9cf9662576 --- /dev/null +++ b/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([ + { + type: ePropType.String, + name: 'name', + displayName: 'AbpIdentity::RoleName', + id: 'role-name', + disabled: (data: PropData) => 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; diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-toolbar-actions.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-roles-toolbar-actions.ts new file mode 100644 index 00000000000..271aced7017 --- /dev/null +++ b/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([ + { + text: 'AbpIdentity::NewRole', + action: data => { + const component = data.getInjected(RolesComponent); + component.add(); + }, + permission: 'AbpIdentity.Roles.Create', + icon: 'fa fa-plus', + }, +]); From e8c5ff86213d3f336729438a757e0fdc0bae2733 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 11:03:14 +0300 Subject: [PATCH 02/10] feat: add default actions and props for users page --- .../defaults/default-users-entity-actions.ts | 30 +++++++++ .../defaults/default-users-entity-props.ts | 26 ++++++++ .../lib/defaults/default-users-form-props.ts | 61 +++++++++++++++++++ .../defaults/default-users-toolbar-actions.ts | 15 +++++ 4 files changed, 132 insertions(+) create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-props.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/defaults/default-users-toolbar-actions.ts diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts new file mode 100644 index 00000000000..f8be7740ff5 --- /dev/null +++ b/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([ + { + 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', + }, +]); diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-props.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-props.ts new file mode 100644 index 00000000000..f9d7c217bee --- /dev/null +++ b/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([ + { + 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, + }, +]); diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts new file mode 100644 index 00000000000..3092bdf7e83 --- /dev/null +++ b/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([ + { + 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', +); diff --git a/npm/ng-packs/packages/identity/src/lib/defaults/default-users-toolbar-actions.ts b/npm/ng-packs/packages/identity/src/lib/defaults/default-users-toolbar-actions.ts new file mode 100644 index 00000000000..b1e62a9e183 --- /dev/null +++ b/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([ + { + text: 'AbpIdentity::NewUser', + action: data => { + const component = data.getInjected(UsersComponent); + component.add(); + }, + permission: 'AbpIdentity.Users.Create', + icon: 'fa fa-plus', + }, +]); From 16ade94ffcc6876c5fbafc8218f85fef3463b21e Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 11:37:18 +0300 Subject: [PATCH 03/10] feat: add identity extension injection tokens --- .../src/lib/tokens/extensions.token.ts | 91 +++++++++++++++++++ .../packages/identity/src/lib/tokens/index.ts | 1 + 2 files changed, 92 insertions(+) create mode 100644 npm/ng-packs/packages/identity/src/lib/tokens/extensions.token.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/tokens/index.ts diff --git a/npm/ng-packs/packages/identity/src/lib/tokens/extensions.token.ts b/npm/ng-packs/packages/identity/src/lib/tokens/extensions.token.ts new file mode 100644 index 00000000000..14e506da0a6 --- /dev/null +++ b/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( + 'IDENTITY_ENTITY_ACTION_CONTRIBUTORS', +); + +export const IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS = new InjectionToken( + 'IDENTITY_TOOLBAR_ACTION_CONTRIBUTORS', +); + +export const IDENTITY_ENTITY_PROP_CONTRIBUTORS = new InjectionToken( + 'IDENTITY_ENTITY_PROP_CONTRIBUTORS', +); + +export const IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS = new InjectionToken( + 'IDENTITY_CREATE_FORM_PROP_CONTRIBUTORS', +); + +export const IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS = new InjectionToken( + 'IDENTITY_EDIT_FORM_PROP_CONTRIBUTORS', +); + +// Fix for TS4023 -> https://github.com/microsoft/TypeScript/issues/9944#issuecomment-254693497 +type EntityActionContributors = Partial<{ + [eIdentityComponents.Roles]: EntityActionContributorCallback[]; + [eIdentityComponents.Users]: EntityActionContributorCallback[]; +}>; +type ToolbarActionContributors = Partial<{ + [eIdentityComponents.Roles]: ToolbarActionContributorCallback[]; + [eIdentityComponents.Users]: ToolbarActionContributorCallback[]; +}>; +type EntityPropContributors = Partial<{ + [eIdentityComponents.Roles]: EntityPropContributorCallback[]; + [eIdentityComponents.Users]: EntityPropContributorCallback[]; +}>; +type CreateFormPropContributors = Partial<{ + [eIdentityComponents.Roles]: CreateFormPropContributorCallback[]; + [eIdentityComponents.Users]: CreateFormPropContributorCallback[]; +}>; +type EditFormPropContributors = Partial<{ + [eIdentityComponents.Roles]: EditFormPropContributorCallback[]; + [eIdentityComponents.Users]: EditFormPropContributorCallback[]; +}>; diff --git a/npm/ng-packs/packages/identity/src/lib/tokens/index.ts b/npm/ng-packs/packages/identity/src/lib/tokens/index.ts new file mode 100644 index 00000000000..33233400a26 --- /dev/null +++ b/npm/ng-packs/packages/identity/src/lib/tokens/index.ts @@ -0,0 +1 @@ +export * from './extensions.token'; From be52bc4978612388a55381135d13f9dfaf018512 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 11:41:33 +0300 Subject: [PATCH 04/10] feat: add contributor types for identity config --- .../identity/src/lib/models/config-options.ts | 42 +++++++++++++++++++ .../packages/identity/src/lib/models/index.ts | 2 + 2 files changed, 44 insertions(+) create mode 100644 npm/ng-packs/packages/identity/src/lib/models/config-options.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/models/index.ts diff --git a/npm/ng-packs/packages/identity/src/lib/models/config-options.ts b/npm/ng-packs/packages/identity/src/lib/models/config-options.ts new file mode 100644 index 00000000000..6a1fc29a000 --- /dev/null +++ b/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[]; + [eIdentityComponents.Users]: EntityActionContributorCallback[]; +}>; + +export type IdentityToolbarActionContributors = Partial<{ + [eIdentityComponents.Roles]: ToolbarActionContributorCallback[]; + [eIdentityComponents.Users]: ToolbarActionContributorCallback[]; +}>; + +export type IdentityEntityPropContributors = Partial<{ + [eIdentityComponents.Roles]: EntityPropContributorCallback[]; + [eIdentityComponents.Users]: EntityPropContributorCallback[]; +}>; + +export type IdentityCreateFormPropContributors = Partial<{ + [eIdentityComponents.Roles]: CreateFormPropContributorCallback[]; + [eIdentityComponents.Users]: CreateFormPropContributorCallback[]; +}>; + +export type IdentityEditFormPropContributors = Partial<{ + [eIdentityComponents.Roles]: EditFormPropContributorCallback[]; + [eIdentityComponents.Users]: EditFormPropContributorCallback[]; +}>; + +export interface IdentityConfigOptions { + entityActionContributors?: IdentityEntityActionContributors; + toolbarActionContributors?: IdentityToolbarActionContributors; + entityPropContributors?: IdentityEntityPropContributors; + createFormPropContributors?: IdentityCreateFormPropContributors; + editFormPropContributors?: IdentityEditFormPropContributors; +} diff --git a/npm/ng-packs/packages/identity/src/lib/models/index.ts b/npm/ng-packs/packages/identity/src/lib/models/index.ts new file mode 100644 index 00000000000..c7964853da3 --- /dev/null +++ b/npm/ng-packs/packages/identity/src/lib/models/index.ts @@ -0,0 +1,2 @@ +export * from './config-options'; +export * from './identity'; From 4139946862bd4cac231feab97bc0cfc91a60e624 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 11:43:02 +0300 Subject: [PATCH 05/10] feat: add identity extension guard --- .../src/lib/guards/extensions.guard.ts | 91 +++++++++++++++++++ .../packages/identity/src/lib/guards/index.ts | 1 + 2 files changed, 92 insertions(+) create mode 100644 npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/guards/index.ts diff --git a/npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts b/npm/ng-packs/packages/identity/src/lib/guards/extensions.guard.ts new file mode 100644 index 00000000000..3b5d592acc6 --- /dev/null +++ b/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 { + 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), + ); + } +} diff --git a/npm/ng-packs/packages/identity/src/lib/guards/index.ts b/npm/ng-packs/packages/identity/src/lib/guards/index.ts new file mode 100644 index 00000000000..480f14c40b6 --- /dev/null +++ b/npm/ng-packs/packages/identity/src/lib/guards/index.ts @@ -0,0 +1 @@ +export * from './extensions.guard'; From b12031fc86ea9645b3e93b3bb9d88a56c6668877 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 12:07:04 +0300 Subject: [PATCH 06/10] feat: use extension tokens and guard in identity module --- .../identity/src/lib/identity.module.ts | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/npm/ng-packs/packages/identity/src/lib/identity.module.ts b/npm/ng-packs/packages/identity/src/lib/identity.module.ts index 036c7e36076..e2b832350a3 100644 --- a/npm/ng-packs/packages/identity/src/lib/identity.module.ts +++ b/npm/ng-packs/packages/identity/src/lib/identity.module.ts @@ -1,14 +1,24 @@ import { CoreModule, LazyModuleFactory } from '@abp/ng.core'; import { PermissionManagementModule } from '@abp/ng.permission-management'; import { ThemeSharedModule } from '@abp/ng.theme.shared'; +import { UiExtensionsModule } from '@abp/ng.theme.shared/extensions'; import { ModuleWithProviders, NgModule, NgModuleFactory } from '@angular/core'; import { NgbDropdownModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { NgxValidateCoreModule } from '@ngx-validate/core'; import { NgxsModule } from '@ngxs/store'; import { RolesComponent } from './components/roles/roles.component'; import { UsersComponent } from './components/users/users.component'; +import { IdentityExtensionsGuard } from './guards/extensions.guard'; import { IdentityRoutingModule } from './identity-routing.module'; +import { IdentityConfigOptions } from './models/config-options'; 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({ declarations: [RolesComponent, UsersComponent], @@ -19,20 +29,43 @@ import { IdentityState } from './states/identity.state'; IdentityRoutingModule, NgbNavModule, ThemeSharedModule, + UiExtensionsModule, NgbDropdownModule, PermissionManagementModule, NgxValidateCoreModule, ], }) export class IdentityModule { - static forChild(): ModuleWithProviders { + static forChild(options: IdentityConfigOptions = {}): ModuleWithProviders { return { 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 { - return new LazyModuleFactory(IdentityModule.forChild()); + static forLazy(options: IdentityConfigOptions = {}): NgModuleFactory { + return new LazyModuleFactory(IdentityModule.forChild(options)); } } From e5cbd970c529159b93a6e90322910770edb8e316 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 12:07:35 +0300 Subject: [PATCH 07/10] feat: use extensions guard in identity routing module --- .../packages/identity/src/lib/identity-routing.module.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts index 27986ae0d75..3b290e851b7 100644 --- a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts +++ b/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 { UsersComponent } from './components/users/users.component'; import { eIdentityComponents } from './enums/components'; +import { IdentityExtensionsGuard } from './guards/extensions.guard'; const routes: Routes = [ { path: '', redirectTo: 'roles', pathMatch: 'full' }, { path: '', component: DynamicLayoutComponent, - canActivate: [AuthGuard, PermissionGuard], + canActivate: [AuthGuard, PermissionGuard, IdentityExtensionsGuard], children: [ { path: 'roles', From 35f4c955485f2bf5c043a3811cc702c592a20d01 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 12:08:20 +0300 Subject: [PATCH 08/10] feat: use extensible components in role page --- .../lib/components/roles/roles.component.html | 106 ++---------------- .../lib/components/roles/roles.component.ts | 34 +++--- 2 files changed, 29 insertions(+), 111 deletions(-) diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html index 1a49d9cbd6a..fd8925df563 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html @@ -5,77 +5,17 @@
{{ 'AbpIdentity::Roles' | abpLocalization }}
- +
- - - -
- -
- - - - - -
-
-
-
- - - {{ row.name }} - {{ - 'AbpIdentity::DisplayName:IsDefault' | abpLocalization - }} - {{ - 'AbpIdentity::DisplayName:IsPublic' | abpLocalization - }} - - -
+
@@ -85,36 +25,8 @@

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocali -
-
- * - -
- -
- - -
- -
- - -
+ +
@@ -122,7 +34,7 @@

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocali - {{ + {{ 'AbpIdentity::Save' | abpLocalization }} diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts index 8df9762b97b..c1410ff1488 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts @@ -1,8 +1,13 @@ import { ListService, PagedAndSortedResultRequestDto } from '@abp/ng.core'; import { ePermissionManagementComponents } from '@abp/ng.permission-management'; import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared'; -import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { + 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 { Observable } from 'rxjs'; import { finalize, pluck } from 'rxjs/operators'; @@ -13,13 +18,20 @@ import { GetRoles, UpdateRole, } from '../../actions/identity.actions'; +import { eIdentityComponents } from '../../enums/components'; import { IdentityRoleDto } from '../../proxy/identity/models'; import { IdentityState } from '../../states/identity.state'; @Component({ selector: 'abp-roles', templateUrl: './roles.component.html', - providers: [ListService], + providers: [ + ListService, + { + provide: EXTENSIONS_IDENTIFIER, + useValue: eIdentityComponents.Roles, + }, + ], }) export class RolesComponent implements OnInit { @Select(IdentityState.getRoles) @@ -51,9 +63,9 @@ export class RolesComponent implements OnInit { constructor( public readonly list: ListService, - private confirmationService: ConfirmationService, - private fb: FormBuilder, - private store: Store, + protected confirmationService: ConfirmationService, + protected store: Store, + protected injector: Injector, ) {} ngOnInit() { @@ -61,14 +73,8 @@ export class RolesComponent implements OnInit { } buildForm() { - this.form = this.fb.group({ - name: new FormControl({ value: this.selected.name || '', disabled: this.selected.isStatic }, [ - Validators.required, - Validators.maxLength(256), - ]), - isDefault: [this.selected.isDefault || false], - isPublic: [this.selected.isPublic || false], - }); + const data = new FormPropData(this.injector, this.selected); + this.form = generateFormFromProps(data); } openModal() { From b0182a5f048d4885ea9a82ff55e1520577c6ccb0 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 12:24:39 +0300 Subject: [PATCH 09/10] feat: use extensible components in user page --- .../lib/components/users/users.component.html | 179 ++---------------- .../lib/components/users/users.component.ts | 65 +++---- 2 files changed, 39 insertions(+), 205 deletions(-) diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html index 05dae5f0d93..a266dc717d9 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html @@ -5,16 +5,7 @@
{{ 'AbpIdentity::Users' | abpLocalization }}
- +
@@ -30,170 +21,22 @@
{{ 'AbpIdentity::Users' | abpLocalization }}
- - - -
- -
- - - -
-
-
-
- - - -
+ - + -

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}

+

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocalization }}

-
- -
- - -
+ +
@@ -201,7 +44,7 @@

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocali - {{ + {{ 'AbpIdentity::Save' | abpLocalization }} diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index 3588ad02b05..da533ba62a2 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -1,6 +1,11 @@ import { ListService } from '@abp/ng.core'; 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 { Component, Injector, @@ -9,14 +14,7 @@ import { TrackByFunction, ViewChild, } from '@angular/core'; -import { - AbstractControl, - FormArray, - FormBuilder, - FormControl, - FormGroup, - Validators, -} from '@angular/forms'; +import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { Select, Store } from '@ngxs/store'; import { Observable } from 'rxjs'; import { finalize, pluck, switchMap, take } from 'rxjs/operators'; @@ -29,6 +27,7 @@ import { GetUsers, UpdateUser, } from '../../actions/identity.actions'; +import { eIdentityComponents } from '../../enums/components'; import { Identity } from '../../models/identity'; import { IdentityUserService } from '../../proxy/identity/identity-user.service'; import { @@ -41,7 +40,13 @@ import { IdentityState } from '../../states/identity.state'; @Component({ selector: 'abp-users', templateUrl: './users.component.html', - providers: [ListService], + providers: [ + ListService, + { + provide: EXTENSIONS_IDENTIFIER, + useValue: eIdentityComponents.Users, + }, + ], }) export class UsersComponent implements OnInit { @Select(IdentityState.getUsers) @@ -83,11 +88,11 @@ export class UsersComponent implements OnInit { constructor( public readonly list: ListService, - private injector: Injector, - private confirmationService: ConfirmationService, - private fb: FormBuilder, - private store: Store, - private identityUserService: IdentityUserService, + protected confirmationService: ConfirmationService, + protected userService: IdentityUserService, + protected fb: FormBuilder, + protected store: Store, + protected injector: Injector, ) {} ngOnInit() { @@ -95,19 +100,14 @@ export class UsersComponent implements OnInit { } 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.form = this.fb.group({ - 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.id ? this.selected.lockoutEnabled : true], - roleNames: this.fb.array( + this.form.addControl( + 'roleNames', + this.fb.array( this.roles.map(role => this.fb.group({ [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(); - } + ); }); } From 388ff9075e14392c542cb5de698954c0817bf54b Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Mon, 14 Dec 2020 15:25:28 +0300 Subject: [PATCH 10/10] fix: use NewUser instead of NewRole --- .../identity/src/lib/components/users/users.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html index a266dc717d9..9963224c2d8 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html @@ -31,7 +31,7 @@
{{ 'AbpIdentity::Users' | abpLocalization }}
-

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocalization }}

+

{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}