Agent skill

abp-angular

ABP Angular UI patterns - generate-proxy, ListService, PermissionGuard, abpLocalization pipe, ConfirmationService, ToasterService, ConfigStateService. Use when building or reviewing Angular UI components, routing, or service integration in ABP Angular projects.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/abp-angular

SKILL.md

ABP Angular UI

Docs: https://abp.io/docs/latest/framework/ui/angular/overview

Project Structure

src/app/
├── proxy/              # Auto-generated service proxies
├── shared/             # Shared components, pipes, directives
├── book/               # Feature module
│   ├── book.module.ts
│   ├── book-routing.module.ts
│   ├── book-list/
│   │   ├── book-list.component.ts
│   │   ├── book-list.component.html
│   │   └── book-list.component.scss
│   └── book-detail/

Generate Service Proxies

bash
abp generate-proxy -t ng

This generates typed service classes in src/app/proxy/.

List Component Pattern

typescript
@Component({
  selector: 'app-book-list',
  templateUrl: './book-list.component.html'
})
export class BookListComponent implements OnInit {
  books = { items: [], totalCount: 0 } as PagedResultDto<BookDto>;

  constructor(
    public readonly list: ListService,
    private bookService: BookService,
    private confirmation: ConfirmationService
  ) {}

  ngOnInit(): void {
    this.hookToQuery();
  }

  private hookToQuery(): void {
    this.list.hookToQuery(query =>
      this.bookService.getList(query)
    ).subscribe(response => {
      this.books = response;
    });
  }

  create(): void {
    // Open create modal
  }

  delete(book: BookDto): void {
    this.confirmation
      .warn('::AreYouSureToDelete', '::AreYouSure')
      .subscribe(status => {
        if (status === Confirmation.Status.confirm) {
          this.bookService.delete(book.id).subscribe(() => this.list.get());
        }
      });
  }
}

Localization

typescript
// In component
constructor(private localizationService: LocalizationService) {}

getText(): string {
  return this.localizationService.instant('::Books');
}
html
<!-- In template -->
<h1>{{ '::Books' | abpLocalization }}</h1>

<!-- With parameters -->
<p>{{ '::WelcomeMessage' | abpLocalization: userName }}</p>

Authorization

Permission Directive

html
<button *abpPermission="'BookStore.Books.Create'">Create</button>

Permission Guard

typescript
const routes: Routes = [
  {
    path: '',
    component: BookListComponent,
    canActivate: [PermissionGuard],
    data: {
      requiredPolicy: 'BookStore.Books'
    }
  }
];

Programmatic Check

typescript
constructor(private permissionService: PermissionService) {}

canCreate(): boolean {
  return this.permissionService.getGrantedPolicy('BookStore.Books.Create');
}

Forms with Validation

typescript
@Component({...})
export class BookFormComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.buildForm();
  }

  buildForm(): void {
    this.form = this.fb.group({
      name: ['', [Validators.required, Validators.maxLength(128)]],
      price: [0, [Validators.required, Validators.min(0)]]
    });
  }

  save(): void {
    if (this.form.invalid) return;

    this.bookService.create(this.form.value).subscribe(() => {
      // Handle success
    });
  }
}
html
<form [formGroup]="form" (ngSubmit)="save()">
  <div class="form-group">
    <label for="name">{{ '::Name' | abpLocalization }}</label>
    <input type="text" id="name" formControlName="name" class="form-control" />
  </div>

  <button type="submit" class="btn btn-primary" [disabled]="form.invalid">
    {{ '::Save' | abpLocalization }}
  </button>
</form>

Configuration API

typescript
constructor(private configService: ConfigStateService) {}

getCurrentUser(): CurrentUserDto {
  return this.configService.getOne('currentUser');
}

getSettings(): void {
  const setting = this.configService.getSetting('MyApp.MaxItemCount');
}

Modal Service

typescript
constructor(private modalService: ModalService) {}

openCreateModal(): void {
  const modalRef = this.modalService.open(BookFormComponent, {
    size: 'lg'
  });

  modalRef.result.then(result => {
    if (result) {
      this.list.get();
    }
  });
}

Toast Notifications

typescript
constructor(private toaster: ToasterService) {}

showSuccess(): void {
  this.toaster.success('::BookCreatedSuccessfully', '::Success');
}

showError(error: string): void {
  this.toaster.error(error, '::Error');
}

Lazy Loading Modules

typescript
// app-routing.module.ts
const routes: Routes = [
  {
    path: 'books',
    loadChildren: () => import('./book/book.module').then(m => m.BookModule)
  }
];

Theme & Styling

  • Use Bootstrap classes
  • ABP provides theme variables via CSS custom properties
  • Component-specific styles in .component.scss

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results