diff --git a/docs/en/Tutorials/Part-9.md b/docs/en/Tutorials/Part-9.md index 2164526645..32149f1485 100644 --- a/docs/en/Tutorials/Part-9.md +++ b/docs/en/Tutorials/Part-9.md @@ -509,9 +509,9 @@ That's all! You can run the application and try to edit an author. {{else if UI == "NG"}} -## The Book List Page +## The Author List Page, Create & Delete Authors -Run the following command line to create a new module, named `BookModule` in the root folder of the angular application: +Run the following command line to create a new module, named `AuthorModule` in the root folder of the angular application: ```bash yarn ng generate module author --module app --routing --route authors @@ -543,16 +543,18 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../shared/shared.module'; import { AuthorRoutingModule } from './author-routing.module'; import { AuthorComponent } from './author.component'; +import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ declarations: [AuthorComponent], - imports: [SharedModule, AuthorRoutingModule], + imports: [SharedModule, AuthorRoutingModule, NgbDatepickerModule], }) export class AuthorModule {} ``` - Added the `SharedModule`. `SharedModule` exports some common modules needed to create user interfaces. - `SharedModule` already exports the `CommonModule`, so we've removed the `CommonModule`. +- Added `NgbDatepickerModule` that will be used later on the author create and edit forms. ### Menu Definition @@ -630,17 +632,31 @@ import { Component, OnInit } from '@angular/core'; import { ListService, PagedResultDto } from '@abp/ng.core'; import { AuthorDto } from './models'; import { AuthorService } from './services'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; @Component({ selector: 'app-author', templateUrl: './author.component.html', styleUrls: ['./author.component.scss'], - providers: [ListService], + providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], }) export class AuthorComponent implements OnInit { author = { items: [], totalCount: 0 } as PagedResultDto; - constructor(public readonly list: ListService, private authorService: AuthorService) {} + isModalOpen = false; + + form: FormGroup; + + selectedAuthor = new AuthorDto(); + + constructor( + public readonly list: ListService, + private authorService: AuthorService, + private fb: FormBuilder, + private confirmation: ConfirmationService + ) {} ngOnInit(): void { const authorStreamCreator = (query) => this.authorService.getListByInput(query); @@ -649,14 +665,162 @@ export class AuthorComponent implements OnInit { this.author = response; }); } + + createAuthor() { + this.selectedAuthor = new AuthorDto(); + this.buildForm(); + this.isModalOpen = true; + } + + editAuthor(id: string) { + this.authorService.getById(id).subscribe((author) => { + this.selectedAuthor = author; + this.buildForm(); + this.isModalOpen = true; + }); + } + + buildForm() { + this.form = this.fb.group({ + name: [this.selectedAuthor.name || '', Validators.required], + birthDate: [ + this.selectedAuthor.birthDate ? new Date(this.selectedAuthor.birthDate) : null, + Validators.required, + ], + }); + } + + save() { + if (this.form.invalid) { + return; + } + + if (this.selectedAuthor.id) { + this.authorService + .updateByIdAndInput(this.form.value, this.selectedAuthor.id) + .subscribe(() => { + this.isModalOpen = false; + this.form.reset(); + this.list.get(); + }); + } else { + this.authorService.createByInput(this.form.value).subscribe(() => { + this.isModalOpen = false; + this.form.reset(); + this.list.get(); + }); + } + } + + delete(id: string) { + this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure') + .subscribe((status) => { + if (status === Confirmation.Status.confirm) { + this.authorService.deleteById(id).subscribe(() => this.list.get()); + } + }); + } } ``` -- We imported and injected the generated `AuthorService`. -- We are using the [ListService](https://docs.abp.io/en/abp/latest/UI/Angular/List-Service), a utility service of the ABP Framework which provides easy pagination, sorting and searching. - Open the `/src/app/author/author.component.html` and replace the content as below: +````html +
+
+
+
+
+ {{ '::Menu:Authors' | abpLocalization }} +
+
+
+
+ +
+
+
+
+
+ + + +
+ +
+ + +
+
+
+
+ + + + {{ row.birthDate | date }} + + +
+
+
+ + + +

{{ (selectedAuthor.id ? '::Edit' : '::NewAuthor') | abpLocalization }}

+
+ + +
+
+ * + +
+ +
+ * + +
+
+
+ + + + + + +
+```` + ### Localizations This page uses some localization keys we need to declare. Open the `en.json` file under the `Localization/BookStore` folder of the `Acme.BookStore.Domain.Shared` project and add the following entries: @@ -669,8 +833,6 @@ This page uses some localization keys we need to declare. Open the `en.json` fil "NewAuthor": "New author" ```` -Notice that we've added more keys. They will be used in the next sections. - ### Run the Application Run and login to the application. **You can not see the menu item since you don't have permission yet.** Go to the `identity/roles` page, click to the *Actions* button and select the *Permissions* action for the **admin role**: @@ -681,6 +843,8 @@ As you see, the admin role has no *Author Management* permissions yet. Click to ![bookstore-authors-page](images/bookstore-angular-authors-page.png) +That's all! This is a fully working CRUD page, you can create, edit and delete authors. + > **Tip**: If you run the `.DbMigrator` console application after defining a new permission, it automatically grants these new permissions to the admin role and you don't need to manually grant the permissions yourself. {{end}} diff --git a/docs/en/Tutorials/images/bookstore-angular-authors-page.png b/docs/en/Tutorials/images/bookstore-angular-authors-page.png index 806ac3a495..bbd865e44b 100644 Binary files a/docs/en/Tutorials/images/bookstore-angular-authors-page.png and b/docs/en/Tutorials/images/bookstore-angular-authors-page.png differ