Entity prop extension system allows you to add a new column to the data table for an entity or change/remove an already existing one. A "Name" column was added to the user management page below:
You will have access to the current entity in your code and display its value, make the column sortable, perform visibility checks, and more. You can also render custom HTML in table cells.
@ -18,10 +18,14 @@ In this example, we will add a "Name" column and display the value of the `name`
The following code prepares a constant named `identityEntityPropContributors`, ready to be imported and used in your root module:
```js
// entity-prop-contributors.ts
// src/app/entity-prop-contributors.ts
import {
eIdentityComponents,
IdentityEntityPropContributors,
IdentityUserDto,
} from '@abp/ng.identity';
import { EntityProp, EntityPropList, ePropType } from '@abp/ng.theme.shared/extensions';
import { IdentityEntityPropContributors, IdentityUserDto } from '@volo/abp.ng.identity';
const nameProp = new EntityProp<IdentityUserDto>({
type: ePropType.String,
@ -32,62 +36,45 @@ const nameProp = new EntityProp<IdentityUserDto>({
});
export function namePropContributor(propList: EntityPropList<IdentityUserDto>) {
The list of props, conveniently named as `propList`, is a **doubly linked list**. That is why we have used the `addAfter` method, which adds a node with given value after the first node that has the previous value. You may find [all available methods here](../Common/Utils/Linked-List.md).
> **Important Note 1:** AoT compilation does not support function calls in decorator metadata. This is why we have defined `namePropContributor` as an exported function declaration here. Please do not forget exporting your contributor callbacks and forget about lambda functions (a.k.a. arrow functions). Please refer to [AoT metadata errors](https://angular.io/guide/aot-metadata-errors#function-calls-not-supported) for details.
> **Important Note 2:** Please use one of the following if Ivy is not enabled in your project. Otherwise, you will get an "Expression form not supported." error.
@ -97,12 +84,18 @@ That is it, `nameProp` entity prop will be added, and you will see the "Name" co
You can use the `valueResolver` to render an HTML string in the table. Imagine we want to show a red times icon (❌) next to unconfirmed emails and phones, instead of showing a green check icon next to confirmed emails and phones. The contributors below would do that for you.
Form prop extension system allows you to add a new field to the create and/or edit forms for a form or change/remove an already existing one. A "Date of Birth" field was added to the user management page below:

<imgalt="Form Prop Extension Example: 'Date of Birth' Field"src="./images/form-prop-extensions---birthday-field.gif"width="800px"style="max-width:100%">
You can validate the field, perform visibility checks, and do more. You will also have access to the current entity when creating a contibutor for an edit form.
@ -18,16 +18,20 @@ In this example, we will add a "Date of Birth" field in the user management page
The following code prepares two constants named `identityCreateFormPropContributors` and `identityEditFormPropContributors`, ready to be imported and used in your root module:
```js
// form-prop-contributors.ts
// src/app/form-prop-contributors.ts
import { Validators } from '@angular/forms';
import {
eIdentityComponents,
IdentityCreateFormPropContributors,
IdentityUserDto,
} from '@abp/ng.identity';
import { ePropType, FormProp, FormPropList } from '@abp/ng.theme.shared/extensions';
import { IdentityCreateFormPropContributors, IdentityEditFormPropContributors, IdentityUserDto } from '@volo/abp.ng.identity';
import { Validators } from '@angular/forms';
const birthdayProp = new FormProp<IdentityUserDto>({
type: ePropType.Date,
name: 'birthday',
displayName: 'Date of Birth',
displayName: 'AbpIdentity::Birthday',
validators: () => [Validators.required],
});
@ -36,63 +40,49 @@ export function birthdayPropContributor(propList: FormPropList<IdentityUserDto>)
// you may define different contributors for edit form if you like
```
The list of props, conveniently named as `propList`, is a **doubly linked list**. That is why we have used the `addByIndex` method, which adds the given value to the specified index of the list. You may find [all available methods here](../Common/Utils/Linked-List.md).
> **Important Note 1:** AoT compilation does not support function calls in decorator metadata. This is why we have defined `birthdayPropContributor` as an exported function declaration here. Please do not forget exporting your contributor callbacks and forget about lambda functions (a.k.a. arrow functions). Please refer to [AoT metadata errors](https://angular.io/guide/aot-metadata-errors#function-calls-not-supported) for details.
> **Important Note 2:** Please use one of the following if Ivy is not enabled in your project. Otherwise, you will get an "Expression form not supported." error.
Import `identityCreateFormPropContributors` and `identityEditFormPropContributors` in your routing module and pass it to the static `forLazy` method of `IdentityModule` as seen below:
Entity action extension system allows you to add a new action to the action menu for an entity. A "Click Me" action was added to the user management page below:
You can take any action (open a modal, make an HTTP API call, redirect to another page... etc) by writing your custom code. You can access to the current entity in your code.
You can take any action (open a modal, make an HTTP API call, redirect to another page... etc) by writing your custom code. You can also access the current entity in your code.
## How to Set Up
@ -17,10 +17,14 @@ In this example, we will add a "Click Me!" action and alert the current row's `u
The following code prepares a constant named `identityEntityActionContributors`, ready to be imported and used in your root module:
```js
// entity-action-contributors.ts
// src/app/entity-action-contributors.ts
import {
eIdentityComponents,
IdentityEntityActionContributors,
IdentityUserDto,
} from '@abp/ng.identity';
import { EntityAction, EntityActionList } from '@abp/ng.theme.shared/extensions';
import { IdentityEntityActionContributors, IdentityUserDto } from '@volo/abp.ng.identity';
const alertUserName = new EntityAction<IdentityUserDto>({
text: 'Click Me!',
@ -31,9 +35,7 @@ const alertUserName = new EntityAction<IdentityUserDto>({
// See EntityActionOptions in API section for all options
});
export function alertUserNameContributor(
actionList: EntityActionList<IdentityUserDto>,
) {
export function alertUserNameContributor(actionList: EntityActionList<IdentityUserDto>) {
The list of actions, conveniently named as `actionList`, is a **doubly linked list**. That is why we have used the `addTail` method, which adds the given value to the end of the list. You may find [all available methods here](../Common/Utils/Linked-List.md).
> **Important Note 1:** AoT compilation does not support function calls in decorator metadata. This is why we have defined `alertUserNameContributor` as an exported function declaration here. Please do not forget exporting your contributor callbacks and forget about lambda functions (a.k.a. arrow functions). Please refer to [AoT metadata errors](https://angular.io/guide/aot-metadata-errors#function-calls-not-supported) for details.
> **Important Note 2:** Please use one of the following if Ivy is not enabled in your project. Otherwise, you will get an "Expression form not supported." error.
That is it, `alertUserName` entity action will be added as the last action on the grid dropdown in the users page (`UsersComponent`) of the `IdentityModule`.
That is it, `alertUserName` entity action will be added as the last action on the grid dropdown in the "Users" page (`UsersComponent`) of the `IdentityModule`.
## How to Place a Custom Modal and Trigger It by Entity Actions
Incase you need to place a custom modal that will be triggered by an entity action, there are two ways to do it: A quick one and an elaborate one.
Let's employ dependency injection to extend the functionality of `IdentityModule` and add a quick view action for the User entity. We will take a lazy-loaded approach.
It should now be working well with lazy-loading. The files are compact in the description to make it quicker to explain. You may split the files as you wish.
That's it. As you see, we reached the `IdentityExtendedComponent` through dependency injection and called one of its methods in our action. The specific user was also available via `data.record`, so we were able to display a summary view.
## API
@ -374,7 +332,7 @@ You may find a full example below.
Page toolbar extension system allows you to add a new action to the toolbar of a page. A "Click Me" action was added to the user management page below:
You can take any action (open a modal, make an HTTP API call, redirect to another page... etc) by writing your custom code. You can also access to page data (the main record, usually an entity list) in your code. Additionally, you can pass in custom components instead of using the default button.
@ -17,10 +17,14 @@ In this example, we will add a "Click Me!" action and log `userName` of all user
The following code prepares a constant named `identityToolbarActionContributors`, ready to be imported and used in your root module:
```js
// toolbar-action-contributors.ts
// src/app/toolbar-action-contributors.ts
import { ToolbarActionList, ToolbarAction } from '@abp/ng.theme.shared/extensions';
import { IdentityToolbarActionContributors, IdentityUserDto } from '@volo/abp.ng.identity';
import {
eIdentityComponents,
IdentityToolbarActionContributors,
IdentityUserDto,
} from '@abp/ng.identity';
import { ToolbarAction, ToolbarActionList } from '@abp/ng.theme.shared/extensions';
const logUserNames = new ToolbarAction<IdentityUserDto[]>({
text: 'Click Me!',
@ -31,9 +35,7 @@ const logUserNames = new ToolbarAction<IdentityUserDto[]>({
// See ToolbarActionOptions in API section for all options
});
export function logUserNamesContributor(
actionList: ToolbarActionList<IdentityUserDto[]>
) {
export function logUserNamesContributor(actionList: ToolbarActionList<IdentityUserDto[]>) {
The list of actions, conveniently named as `actionList`, is a **doubly linked list**. That is why we have used the `addHead` method, which adds the given value to the beginning of the list. You may find [all available methods here](../Common/Utils/Linked-List.md).
> **Important Note:** AoT compilation does not support function calls in decorator metadata. This is why we have defined `logUserNamesContributor` as an exported function declaration here. Please do not forget exporting your contributor callbacks and forget about lambda functions (a.k.a. arrow functions). Please refer to [AoT metadata errors](https://angular.io/guide/aot-metadata-errors#function-calls-not-supported) for details.
### Step 2. Import and Use Toolbar Action Contributors
Import `identityToolbarActionContributors` in your routing module and pass it to the static `forLazy` method of `IdentityModule` as seen below:
```js
// src/app/app-routing.module.ts
// other imports
import { identityToolbarActionContributors } from './toolbar-action-contributors';
@ -85,22 +84,22 @@ That is it, `logUserNames` toolbar action will be added as the first action on t
In this example, we will add a custom "Click Me!" button and log `userName` of all users in the user management page of the [Identity Module](../../Modules/Identity.md) to the console.
Here, `EXTENSIONS_ACTION_DATA` token provides us the context from the page toolbar. Therefore, we are able to reach the page data via `record`, which is an array of users, i.e. `IdentityUserDto[]`.
@ -123,11 +123,14 @@ Here, `EXTENSIONS_ACTION_DATA` token provides us the context from the page toolb
The following code prepares a constant named `identityToolbarActionContributors`, ready to be imported and used in your root module. When `ToolbarComponent` is used instead of `ToolbarAction`, we can pass a component in:
```js
// toolbar-action-contributors.ts
// src/app/toolbar-action-contributors.ts
import {
eIdentityComponents,
IdentityToolbarActionContributors,
IdentityUserDto,
} from '@abp/ng.identity';
import { ToolbarActionList, ToolbarComponent } from '@abp/ng.theme.shared/extensions';
import { IdentityUserDto } from '@volo/abp.ng.identity';
import { IdentityToolbarActionContributors } from '@volo/abp.ng.identity/config';
import { ClickMeButtonComponent } from './click-me-button.component';
const logUserNames = new ToolbarComponent<IdentityUserDto[]>({
@ -135,9 +138,7 @@ const logUserNames = new ToolbarComponent<IdentityUserDto[]>({
// See ToolbarActionOptions in API section for all options
});
export function logUserNamesContributor(
actionList: ToolbarActionList<IdentityUserDto[]>
) {
export function logUserNamesContributor(actionList: ToolbarActionList<IdentityUserDto[]>) {
The list of actions, conveniently named as `actionList`, is a **doubly linked list**. That is why we have used the `addHead` method, which adds the given value to the beginning of the list. You may find [all available methods here](../Common/Utils/Linked-List.md).
> **Important Note 1:** AoT compilation does not support function calls in decorator metadata. This is why we have defined `logUserNamesContributor` as an exported function declaration here. Please do not forget exporting your contributor callbacks and forget about lambda functions (a.k.a. arrow functions). Please refer to [AoT metadata errors](https://angular.io/guide/aot-metadata-errors#function-calls-not-supported) for details.
> **Important Note 2:** Please use one of the following if Ivy is not enabled in your project. Otherwise, you will get an "Expression form not supported." error.
### Step 3. Import and Use Toolbar Action Contributors
Import `identityToolbarActionContributors` in your routing module and pass it to the static `forLazy` method of `IdentityModule` as seen below. If Ivy is not enabled in your project, do not forget putting `ClickMeButtonComponent` into `entryComponents`:
Import `identityToolbarActionContributors` in your routing module and pass it to the static `forLazy` method of `IdentityModule` as seen below.
```js
// src/app/app-routing.module.ts
// other imports
import { identityToolbarActionContributors } from './toolbar-action-contributors';
That is it, `logUserNames` toolbar action will be added as the first action on the page toolbar in the users page (`UsersComponent`) of the `IdentityModule` and it will be triggered by a custom button, i.e. `ClickMeButtonComponent`. Please note that **component projection is not limited to buttons** and you may use other UI components.