Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

extend-angular-module-ui

/extend-angular-module-ui

Rozszerza interfejs modułu ABP Angular (na przykład Identity) przez system rozszerzeń: akcje w wierszu i na pasku narzędzi, kolumny i pola formularzy, bez forkowania modułu.

Repozytorium
abp-skills ↗
Licencja
MIT
Ostatnia zmiana repozytorium
05.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 05.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Rozszerza interfejs modułu ABP Angular (na przykład Identity) przez system rozszerzeń: akcje w wierszu i na pasku narzędzi, kolumny i pola formularzy, bez forkowania modułu.

Oryginalny opis (EN)

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

Jak działa

  1. When to Use
  2. When Not to Use
  3. The five contributor buckets
  4. Building items and mutating the list
  5. Registering the contributors
  6. Validation
  7. Common Pitfalls
Sekcje z nagłówków SKILL.md, w oryginale · 106 linii, 659 słów
Podgląd SKILL.md
---
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.

Wersje

W bazie nie ma innych skilli o nazwie extend-angular-module-ui.

Migawka bazy z 13.11.2026 · wersja paczki 6e30297cd576 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100angular
    Pokazuje, jak używać custom elements w Angularze, w tym wymaganą konfigurację CUSTOM_ELEMENTS_SCHEMA, w modułach i komponentach standalone.
  • 100extend-application-shell
    Rozszerza powłokę i layout aplikacji ABP w MVC i Blazor hakami layoutu, globalnymi paskami narzędzi, nagłówkiem strony i brandingiem, bez kopiowania layoutu motywu.
  • 100angular-architecture
    Ustala standardy struktury projektu Angular, modułów funkcji i lazy loadingu.
  • 100abp-ui
    Opisuje warstwę UI w ABP Framework 10.x: MVC i Razor Pages, Blazor, Angular, React, theming LeptonX, menu contributor i dynamiczne proxy.
  • 100abp-ui
    Opisuje warstwę UI w ABP Framework 10.x: MVC i Razor Pages, Blazor, Angular, React, theming LeptonX, menu contributor i dynamiczne proxy.
  • 85{setup-skill-name}
    Prawdopodobnie szablon instalacji modułu w projekcie, z nazwą i kodem modułu do uzupełnienia przed użyciem.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.