extend-angular-module-ui
/extend-angular-module-ui
Extend a shipped ABP Angular module's UI (Identity, etc.) through the extension system — add row/toolbar actions, columns, and create/edit form fields without forking. USE FOR: the five contributor buckets (entity/toolbar-action, entity-prop, create/edit-form-prop contributors) keyed by the module's component enum; the EntityAction/ToolbarAction/EntityProp/FormProp factories; ePropType; the LinkedList mutators addTail/addByIndex/addAfter/dropByIndex (there is no patch/remove/insertByIndex — patch is drop-plus-reconstruct); registering via createRoutes in a lazy loadChildren (or the deprecated
- Author
- abpframework ↗
- Repository
- abp-skills ↗
- Licence
- MIT
- Last repository change
- 05.10.2026
Assessment and security
- Files in this package
- 1
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 05.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
Extend a shipped ABP Angular module's UI (Identity, etc.) through the extension system — add row/toolbar actions, columns, and create/edit form fields without forking. USE FOR: the five contributor buckets (entity/toolbar-action, entity-prop, create/edit-form-prop contributors) keyed by the module's component enum; the EntityAction/ToolbarAction/EntityProp/FormProp factories; ePropType; the LinkedList mutators addTail/addByIndex/addAfter/dropByIndex (there is no patch/remove/insertByIndex — patch is drop-plus-reconstruct); registering via createRoutes in a lazy loadChildren (or the deprecated
Original author description
Extend a shipped ABP Angular module's UI (Identity, etc.) through the extension system — add row/toolbar actions, columns, and create/edit form fields without forking. USE FOR: the five contributor buckets (entity/toolbar-action, entity-prop, create/edit-form-prop contributors) keyed by the module's component enum; the EntityAction/ToolbarAction/EntityProp/FormProp factories; ePropType; the LinkedList mutators addTail/addByIndex/addAfter/dropByIndex (there is no patch/remove/insertByIndex — patch is drop-plus-reconstruct); registering via createRoutes in a lazy loadChildren (or the deprecated
How it works
- When to Use
- When Not to Use
- The five contributor buckets
- Building items and mutating the list
- Registering the contributors
- Validation
- Common Pitfalls
SKILL.md preview
---
name: extend-angular-module-ui
description: >
Extend a shipped ABP Angular module's UI (Identity, etc.) through the extension system — add row/toolbar actions, columns, and create/edit form fields without forking.
USE FOR: the five contributor buckets (entity/toolbar-action, entity-prop, create/edit-form-prop contributors) keyed by the module's component enum; the EntityAction/ToolbarAction/EntityProp/FormProp factories; ePropType; the LinkedList mutators addTail/addByIndex/addAfter/dropByIndex (there is no patch/remove/insertByIndex — patch is drop-plus-reconstruct); registering via createRoutes in a lazy loadChildren (or the deprecated Module.forLazy); EXTENSIONS_IDENTIFIER; the @abp/ng.components/extensible package.
DO NOT USE FOR: building your own non-module list/form (build-angular-lists-and-forms); proxy consumption, menus, permission directives, replaceable components (angular-ui); adding server-side extra properties to the entity/DTO (extend-objects-with-extra-properties); component testing (test-angular-ui).
license: MIT
---
# Extend Angular Module UI (ABP)
ABP's shipped Angular modules (Identity, Tenant Management, …) expose their grids and create/edit forms to a **contributor** system so you can add actions, columns, and fields without forking the module. Models write these by hand or fork the component; the extension API is the supported path.
## When to Use
- Adding a row action, toolbar button, extra column, or extra create/edit field to a **shipped module's** page.
- Reordering or replacing an existing column/field on such a page.
## When Not to Use
- **Your own feature's list/form** (not a shipped module) — use **build-angular-lists-and-forms**.
- **Proxies, menus, permission directives, replaceable components** — use **angular-ui**.
- **Persisting the extra field on the backend** (the entity/DTO side) — use **extend-objects-with-extra-properties**; the UI contributor only renders it.
- **Testing** — use **test-angular-ui**.
## The five contributor buckets
Each module exposes a typed options object with five buckets, keyed by that module's **component enum**. Identity's, for example:
```ts
import { eIdentityComponents } from '@abp/ng.identity';
import { IdentityEntityActionContributors, IdentityEntityPropContributors } from '@abp/ng.identity';
export const identityEntityActionContributors: IdentityEntityActionContributors = {
[eIdentityComponents.Users]: [ /* contributor callbacks */ ],
};
```
The buckets are `entityActionContributors` (row actions), `toolbarActionContributors` (page toolbar buttons), `entityPropContributors` (data-table columns), `createFormPropContributors` and `editFormPropContributors` (form fields — create and edit are separate). A contributor is a callback that receives the current list and mutates it.
## Building items and mutating the list
Items come from factories in `@abp/ng.components/extensible`: `EntityAction`, `ToolbarAction`, `EntityProp` (a column), `FormProp` (a field). Column/field types use the `ePropType` enum (`String`, `Boolean`, `Date`, `DateTime`, `Email`, `Enum`, `Number`, `Password`, `Text`, `Time`, `Typeahead`, …).
The list passed to a contributor is a **doubly-linked list**, so you position items explicitly:
```ts
import {
EntityAction, EntityActionList,
EntityProp, EntityPropList,
FormProp, FormPropList, ePropType,
} from '@abp/ng.components/extensible';
import { IdentityUserDto } from '@abp/ng.identity/proxy';
import { Validators } from '@angular/forms';
// row action -> appended to the row dropdown
export function sayHi(actionList: EntityActionList<IdentityUserDto>) {
actionList.addTail(new EntityAction<IdentityUserDto>({
text: 'Say Hi',
action: data => alert(data.record.userName), // text + action are required
}));
}
// custom column -> inserted right after userName
export function nameColumn(propList: EntityPropList<IdentityUserDto>) {
propList.addAfter(
new EntityProp<IdentityUserDto>({ type: ePropType.String, name: 'name', displayName: '::Name', sortable: true }),
'userName',
(value, name) => value.name === name,
);
}
// create-form field -> inserted at index 4
export function birthday(propList: FormPropList<IdentityUserDto>) {
propList.addByIndex(
new FormProp<IdentityUserDto>({ type: ePropType.Date, name: 'birthday', displayName: '::Birthday', validators: () => [Validators.required] }),
4,
);
}
```
Mutators: `addTail` / `addHead` / `addByIndex(item, position)` / `addAfter(item, sibling, compareFn)` / `addBefore` / `add(item).byIndex(n)`, and the `dropByIndex` / `dropByValue` family. There is **no** `patch`, `remove`, or `insertByIndex` — to "patch" an existing column, `dropByIndex(i)` it, then re-add a `new EntityProp({ ...droppedNode.value, valueResolver })`.
## Registering the contributors
In the current standalone setup, pass the buckets to the module's `createRoutes(options)` in the lazy route:
```ts
{
path: 'identity',
loadChildren: () => import('@abp/ng.identity').then(c => c.createRoutes({
entityActionContributors: identityEntityActionContributors,
entityPropContributors: identityEntityPropContributors,
createFormPropContributors: identityCreateFormPropContributors,
})),
}
```
(The legacy NgModule path, `IdentityModule.forLazy(options)`, takes the same options object but is deprecated.) Each page binds its bucket via the `EXTENSIONS_IDENTIFIER` token it provides.
For `@volo/abp.ng.*` module UIs, follow that module's own documentation for its UI extension APIs.
## Validation
- Add a column and confirm it renders in the grid at the position you chose and sorts if `sortable`.
- Add a create-form field and confirm it appears in the modal, validates, and round-trips (with the backend extra-property wired separately).
## Common Pitfalls
- **Inventing `patch` / `remove` / `insertByIndex`.** They don't exist. Use `dropByIndex` + re-add for patch, the `drop*` family for remove, `addByIndex` / `add().byIndex()` for insert-at-index.
- **Wrong bucket for create vs edit.** Create and edit forms have separate buckets; adding to only one leaves the other unchanged.
- **Expecting the column to persist data.** The UI contributor renders a value; the entity/DTO extra property is a backend concern — see **extend-objects-with-extra-properties**.
- **Building your own feature's grid here.** That's **build-angular-lists-and-forms**; this skill is only for extending *shipped* modules' pages.
Versions
The database has no other skills named extend-angular-module-ui.
Database snapshot: 13.11.2026 · package version 6e30297cd576 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100angular
Show how to use custom elements in Angular, including required CUSTOM_ELEMENTS_SCHEMA configuration. Use when the user asks to "use in Angular", "Angular custom elements", "custom elements in Angular", "CUSTOM_ELEMENTS_SCHEMA", or mentions "Angular module", "standalone… - 100extend-application-shell
Extend the ABP application shell/layout across MVC and Blazor with layout hooks, global/page toolbars, the page header, and branding — without copying the theme layout. USE FOR: injecting content into the layout via AbpLayoutHookOptions + LayoutHooks (MVC ViewComponent hooks;… - 100angular-architecture
Standards for Angular project structure, feature modules, and lazy loading. Use when structuring Angular apps, defining feature modules, or configuring lazy loading. - 100abp-ui
ABP Framework v10.x (10.4–10.6) UI: MVC/Razor Pages (AbpPageModel), Blazor (AbpComponentBase), Angular, React (--modern), theming (LeptonX), menu contributor, dynamic proxy. Use when developing frontend, UI, pages, or components in ABP. - 100abp-ui
ABP Framework v10.x (10.4–10.6) UI: MVC/Razor Pages (AbpPageModel), Blazor (AbpComponentBase), Angular, React (--modern), theming (LeptonX), menu contributor, dynamic proxy. Use when developing frontend, UI, pages, or components in ABP. - 85{setup-skill-name}
Sets up {module-name} module in a project. Use when the user requests to 'install {module-code} module', 'configure {module-name}', or 'setup {module-name}'.