diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md new file mode 100644 index 0000000000..ccba01247f --- /dev/null +++ b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/POST.md @@ -0,0 +1,325 @@ +# Convert Create/Edit Modals to Page + +In this document we will explain how to convert BookStore's Books create & edit modals to regular angular component pages. + +## Before + +![bookstore-crud-before](images/old.gif) + +## After + +![bookstore-crud-after](images/new.gif) + +# BooksComponent + +This is the main component of the books management. Create & Update operations are done in this page. So we'll remove create & update operations from this page and move a separate angular component for each operation. Each component will be a page. + +- Remove Create & Update modal on template + + ![remove-modal](images/books-remove-modals.png) + +- Modify **NewBook** button with a link to **CreateBookComponent** page. + + ```html + + ``` + +- Modify **Edit** button with a link to **EditBookComponent** page. + + ```html + + ``` + +- Remove all unused methods and variables in the `BookComponent` except **book** variable, **ngOnInit** and **delete** methods. + + + ![bookstore-remove-unsued](images/books-remove-unused.png) + +- Also we can clear unncessary imports + + ![bookstore-remove-unsued-imports](images/books-remove-unused-imports.png) + + + +# CreateBookComponent Page + +Create new component by name `create-book` in your project. +```bash + yarn ng g c book/create-book --skip-tests --style=none +``` + +- `create-book.component.html` + +```html +
+
+
+
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ + + +
+
+
+
+``` + +- `create-book.component.ts` + +```ts +import { Component, inject } from '@angular/core'; +import { Router } from '@angular/router'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { map } from 'rxjs'; +import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { BookService, bookTypeOptions } from '@proxy/books'; + +const { required } = Validators; + +@Component({ + selector: 'app-create-book', + templateUrl: './create-book.component.html', + providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], +}) +export class CreateBookComponent { + //inject() function came with Angular v14, detail: https://angular.io/api/core/inject + private readonly router = inject(Router); + private readonly fb = inject(FormBuilder); + private readonly bookService = inject(BookService); + + form: FormGroup; + authors$ = this.bookService.getAuthorLookup().pipe(map(({ items }) => items)); + bookTypes = bookTypeOptions; + + private buildForm() { + this.form = this.fb.group({ + authorId: [null, required], + name: [null, required], + type: [null, required], + publishDate: [undefined, required], + price: [null, required], + }); + } + + constructor() { + this.buildForm(); + } + + save() { + if (this.form.invalid) return; + + this.bookService.create(this.form.value).subscribe(() => { + this.router.navigate(['/books']); + }); + } +} +``` + +# EditBookComponent Page + +Create new component by name **edit-book** in your project. + +```bash + yarn ng g c book/edit-book --skip-tests --style=none +``` + +- `edit-book.component.html` + +```html +
+
+
+
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ + + +
+
+
+
+``` + +- `edit-book.component.ts` + +```ts +import { Component, inject } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { filter, map, switchMap, tap } from 'rxjs'; +import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { BookDto, BookService, bookTypeOptions } from '@proxy/books'; + +const { required } = Validators; + +@Component({ + selector: 'app-edit-book', + templateUrl: './edit-book.component.html', + providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], +}) +export class EditBookComponent { + //inject() function came with Angular v14, detail: https://angular.io/api/core/inject + private readonly router = inject(Router); + private readonly activatedRoute = inject(ActivatedRoute); + private readonly fb = inject(FormBuilder); + private readonly bookService = inject(BookService); + + id: string; + form: FormGroup; + authors$ = this.bookService.getAuthorLookup().pipe(map(({ items }) => items)); + bookTypes = bookTypeOptions; + + private buildForm(book: BookDto): void { + this.form = this.fb.group({ + authorId: [book.authorId, required], + name: [book.name, required], + type: [book.type, required], + publishDate: [new Date(book.publishDate), required], + price: [book.price, required], + }); + } + + constructor() { + this.activatedRoute.params + .pipe( + filter(params => params.id), + tap(({ id }) => (this.id = id)), + switchMap(({ id }) => this.bookService.get(id)), + tap(book => this.buildForm(book)) + ) + .subscribe(); + } + + save(): void { + if (this.form.invalid) return; + + this.bookService.update(this.id, this.form.value).subscribe(() => { + this.router.navigate(['/books']); + }); + } +} +``` + +# Update BookRoutingModule +Finally add 2 item to routes array in the `book-routing.module.ts` +```ts +import { CreateBookComponent } from './create-book/create-book.component'; +import { EditBookComponent } from './edit-book/edit-book.component'; + +const routes: Routes = [ + { path: '', component: BookComponent, canActivate: [AuthGuard, PermissionGuard] }, + { path: 'create', component: CreateBookComponent }, + { path: 'edit/:id', component: EditBookComponent }, +]; +``` + + +You can check the following commit for details: https://github.com/abpframework/abp-samples/commit/351ad5e093036702edbb15169968935496afea0e diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-modals.png b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-modals.png new file mode 100644 index 0000000000..4396819fcd Binary files /dev/null and b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-modals.png differ diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-unused-imports.png b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-unused-imports.png new file mode 100644 index 0000000000..198db3f243 Binary files /dev/null and b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-unused-imports.png differ diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-unused.png b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-unused.png new file mode 100644 index 0000000000..f95c90c44d Binary files /dev/null and b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/books-remove-unused.png differ diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/new.gif b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/new.gif new file mode 100644 index 0000000000..a2e15e9c8d Binary files /dev/null and b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/new.gif differ diff --git a/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/old.gif b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/old.gif new file mode 100644 index 0000000000..499af9f28c Binary files /dev/null and b/docs/en/Community-Articles/2023-04-15-Converting-Create-Edit-Modal-To-Page/images/old.gif differ