From 373f94cb61344d8d307942fc4edf904952d14a6d Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Thu, 15 Aug 2019 08:57:53 +0300 Subject: [PATCH] refactor(bookstore-angular): sync via docs --- .../angular/src/app/app-routing.module.ts | 2 + .../books/book-list/book-list.component.html | 102 ++++++++++++++++ .../books/book-list/book-list.component.scss | 0 .../book-list/book-list.component.spec.ts | 25 ++++ .../books/book-list/book-list.component.ts | 91 +++++++++++++++ .../src/app/books/books-routing.module.ts | 10 +- .../src/app/books/books.component.html | 109 +----------------- .../angular/src/app/books/books.component.ts | 69 +---------- .../angular/src/app/books/books.module.ts | 3 +- .../books.service.spec.ts | 0 .../{services => shared}/books.service.ts | 31 +++-- .../src/app/home/home-routing.module.ts | 4 +- .../src/app/store/actions/books.actions.ts | 13 ++- .../angular/src/app/store/models/books.ts | 19 +-- .../src/app/store/states/books.state.ts | 39 ++++--- .../src/environments/environment.hmr.ts | 4 + .../src/environments/environment.prod.ts | 4 + .../angular/src/environments/environment.ts | 4 + 18 files changed, 310 insertions(+), 219 deletions(-) create mode 100644 samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.html create mode 100644 samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.scss create mode 100644 samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.spec.ts create mode 100644 samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.ts rename samples/BookStore-Angular-MongoDb/angular/src/app/books/{services => shared}/books.service.spec.ts (100%) rename samples/BookStore-Angular-MongoDb/angular/src/app/books/{services => shared}/books.service.ts (50%) diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/app-routing.module.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/app-routing.module.ts index d18817b0f5..3d09337cf4 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/app-routing.module.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/app-routing.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ABP } from '@abp/ng.core'; import { TENANT_MANAGEMENT_ROUTES } from '@abp/ng.tenant-management'; +import { ApplicationLayoutComponent } from '@abp/ng.theme.basic'; const routes: Routes = [ { @@ -33,6 +34,7 @@ const routes: Routes = [ }, { path: 'books', + component: ApplicationLayoutComponent, loadChildren: () => import('./books/books.module').then(m => m.BooksModule), data: { routes: { diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.html b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.html new file mode 100644 index 0000000000..888def12dc --- /dev/null +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.html @@ -0,0 +1,102 @@ +
+
+
+
+
+ Books +
+
+
+ +
+
+
+
+ + + + Actions + Book name + Book type + Publish date + Price + + + + + +
+ +
+ + +
+
+ + {{ data.name }} + {{ booksType[data.type] }} + {{ data.publishDate | date }} + {{ data.price }} + +
+
+
+
+ + + +

{{ selectedBook.id ? 'Edit' : 'New Book' }}

+
+ + +
+
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+
+
+ + + + Save + +
diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.scss b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.spec.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.spec.ts new file mode 100644 index 0000000000..3462bd783b --- /dev/null +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BookListComponent } from './book-list.component'; + +describe('BookListComponent', () => { + let component: BookListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BookListComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BookListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.ts new file mode 100644 index 0000000000..a58ff49694 --- /dev/null +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/book-list/book-list.component.ts @@ -0,0 +1,91 @@ +import { Component, OnInit } from '@angular/core'; +import { Store, Select } from '@ngxs/store'; +import { BooksState } from '../../store/states'; +import { Observable } from 'rxjs'; +import { Books } from '../../store/models'; +import { GetBooks, CreateUpdateBook, DeleteBook } from '../../store/actions'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; +import { BooksService } from '../shared/books.service'; +import { ConfirmationService, Toaster } from '@abp/ng.theme.shared'; + +@Component({ + selector: 'app-book-list', + templateUrl: './book-list.component.html', + styleUrls: ['./book-list.component.scss'], + providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], +}) +export class BookListComponent implements OnInit { + @Select(BooksState.getBooks) + books$: Observable; + + booksType = Books.BookType; + + loading = false; + + isModalOpen = false; + + form: FormGroup; + + bookTypeArr = Object.keys(Books.BookType).filter(bookType => typeof this.booksType[bookType] === 'number'); + + selectedBook = {} as Books.Book; + + constructor( + private store: Store, + private fb: FormBuilder, + private booksService: BooksService, + private confirmationService: ConfirmationService, + ) {} + + ngOnInit() { + this.loading = true; + this.store.dispatch(new GetBooks()).subscribe(() => { + this.loading = false; + }); + } + + buildForm() { + this.form = this.fb.group({ + name: [this.selectedBook.name || '', Validators.required], + type: this.selectedBook.type || null, + publishDate: this.selectedBook.publishDate ? new Date(this.selectedBook.publishDate) : null, + price: this.selectedBook.price || null, + }); + } + + onAdd() { + this.selectedBook = {} as Books.Book; + this.buildForm(); + this.isModalOpen = true; + } + + onEdit(id: string) { + this.booksService.getById(id).subscribe(book => { + this.selectedBook = book; + this.buildForm(); + this.isModalOpen = true; + }); + } + + save() { + if (this.form.invalid) { + return; + } + + this.store.dispatch(new CreateUpdateBook(this.form.value, this.selectedBook.id)).subscribe(() => { + this.isModalOpen = false; + this.form.reset(); + }); + } + + delete(id: string, name: string) { + this.confirmationService + .error(`${name} will be deleted. Do you confirm that?`, 'Are you sure?') + .subscribe(status => { + if (status === Toaster.Status.confirm) { + this.store.dispatch(new DeleteBook(id)); + } + }); + } +} diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books-routing.module.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books-routing.module.ts index 4d54fc0a71..8bd5f84e71 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books-routing.module.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books-routing.module.ts @@ -1,10 +1,14 @@ import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { LayoutApplicationComponent } from '@abp/ng.theme.basic'; +import { RouterModule, Routes } from '@angular/router'; import { BooksComponent } from './books.component'; +import { BookListComponent } from './book-list/book-list.component'; const routes: Routes = [ - { path: '', component: LayoutApplicationComponent, children: [{ path: '', component: BooksComponent }] }, + { + path: '', + component: BooksComponent, + children: [{ path: '', component: BookListComponent }], + }, ]; @NgModule({ diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.html b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.html index e68bf6f22e..0680b43f9c 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.html +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.html @@ -1,108 +1 @@ -
-
-
-
-
- Books -
-
-
- -
-
-
-
- - - - Actions - Book name - Book type - Publish date - Price - - - - - -
- -
- - -
-
- - {{ data.name }} - {{ bookType[data.type] }} - {{ data.publishDate | date }} - {{ data.price }} - -
-
-
-
- - - -

{{ selectedBook?.id ? 'Edit' : 'New Book' }}

-
- - -
-
- * - -
- -
- - -
- -
- - -
- -
- - -
-
-
- - - - Save - -
+ diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.ts index cab994e23c..cb6de9aadd 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.ts @@ -1,73 +1,8 @@ -import { Component, OnInit } from '@angular/core'; -import { Store, Select } from '@ngxs/store'; -import { BooksState } from '../store/states'; -import { Observable } from 'rxjs'; -import { Books } from '../store/models'; -import { BooksGet, BooksSave } from '../store/actions'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { NgbDateAdapter, NgbDateNativeAdapter } from '@ng-bootstrap/ng-bootstrap'; -import { BooksService } from './services/books.service'; +import { Component } from '@angular/core'; @Component({ selector: 'app-books', templateUrl: './books.component.html', styleUrls: ['./books.component.scss'], - providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], }) -export class BooksComponent implements OnInit { - @Select(BooksState.getBooks) - books$: Observable; - - bookType = Books.Type; - - bookTypes = Object.keys(Books.Type).filter(bookType => typeof this.bookType[bookType] === 'number'); - - loading = false; - - isModalOpen = false; - - form: FormGroup; - - selectedBook = {} as Books.Item; - - constructor(private store: Store, private fb: FormBuilder, private booksService: BooksService) {} - - ngOnInit() { - this.loading = true; - this.store.dispatch(new BooksGet()).subscribe(() => (this.loading = false)); - } - - buildForm() { - this.form = this.fb.group({ - name: [this.selectedBook.name || '', Validators.required], - type: this.selectedBook.type || null, - publishDate: this.selectedBook.publishDate ? new Date(this.selectedBook.publishDate) : null, - price: this.selectedBook.price || null, - }); - } - - onAdd() { - this.selectedBook = {} as Books.Item; - this.buildForm(); - this.isModalOpen = true; - } - - onEdit(id: string) { - this.booksService.getById(id).subscribe(book => { - this.selectedBook = book; - this.buildForm(); - this.isModalOpen = true; - }); - } - - save() { - if (this.form.invalid) { - return; - } - - this.store.dispatch(new BooksSave(this.form.value, this.selectedBook.id)).subscribe(() => { - this.isModalOpen = false; - this.form.reset(); - }); - } -} +export class BooksComponent {} diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.module.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.module.ts index 4dd8f39cfe..40090b0717 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.module.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/books.module.ts @@ -5,9 +5,10 @@ import { BooksRoutingModule } from './books-routing.module'; import { BooksComponent } from './books.component'; import { SharedModule } from '../shared/shared.module'; import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; +import { BookListComponent } from './book-list/book-list.component'; @NgModule({ - declarations: [BooksComponent], + declarations: [BooksComponent, BookListComponent], imports: [CommonModule, BooksRoutingModule, SharedModule, NgbDatepickerModule], }) export class BooksModule {} diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.spec.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/shared/books.service.spec.ts similarity index 100% rename from samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.spec.ts rename to samples/BookStore-Angular-MongoDb/angular/src/app/books/shared/books.service.spec.ts diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/books/shared/books.service.ts similarity index 50% rename from samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.ts rename to samples/BookStore-Angular-MongoDb/angular/src/app/books/shared/books.service.ts index d65ac9d125..19e73a49f7 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/books/shared/books.service.ts @@ -18,32 +18,41 @@ export class BooksService { return this.rest.request(request); } - getById(id: string): Observable { + create(body: Books.CreateUpdateBookInput): Observable { + const request: Rest.Request = { + method: 'POST', + url: '/api/app/book', + body, + }; + + return this.rest.request(request); + } + + getById(id: string): Observable { const request: Rest.Request = { method: 'GET', url: `/api/app/book/${id}`, }; - return this.rest.request(request); + return this.rest.request(request); } - update(body: Books.SaveRequest, id: string): Observable { - const request: Rest.Request = { + update(body: Books.CreateUpdateBookInput, id: string): Observable { + const request: Rest.Request = { method: 'PUT', url: `/api/app/book/${id}`, body, }; - return this.rest.request(request); + return this.rest.request(request); } - add(body: Books.SaveRequest): Observable { - const request: Rest.Request = { - method: 'POST', - url: '/api/app/book', - body, + delete(id: string): Observable { + const request: Rest.Request = { + method: 'DELETE', + url: `/api/app/book/${id}`, }; - return this.rest.request(request); + return this.rest.request(request); } } diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/home/home-routing.module.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/home/home-routing.module.ts index 70f7e5de7a..367affb583 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/home/home-routing.module.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/home/home-routing.module.ts @@ -1,12 +1,12 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home.component'; -import { LayoutApplicationComponent } from '@abp/ng.theme.basic'; +import { ApplicationLayoutComponent } from '@abp/ng.theme.basic'; const routes: Routes = [ { path: '', - component: LayoutApplicationComponent, + component: ApplicationLayoutComponent, children: [{ path: '', component: HomeComponent }], }, ]; diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/store/actions/books.actions.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/store/actions/books.actions.ts index e684890c6e..56370675d0 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/store/actions/books.actions.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/store/actions/books.actions.ts @@ -1,10 +1,15 @@ import { Books } from '../models'; -export class BooksGet { +export class GetBooks { static readonly type = '[Books] Get'; } -export class BooksSave { - static readonly type = '[Books] Save'; - constructor(public payload: Books.SaveRequest, public id?: string) {} +export class CreateUpdateBook { + static readonly type = '[Books] Create Update Book'; + constructor(public payload: Books.CreateUpdateBookInput, public id?: string) {} +} + +export class DeleteBook { + static readonly type = '[Books] Delete'; + constructor(public id: string) {} } diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/store/models/books.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/store/models/books.ts index 8e74598b47..7e629bd4a3 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/store/models/books.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/store/models/books.ts @@ -1,15 +1,16 @@ -import { ABP } from '@abp/ng.core'; - export namespace Books { export interface State { - data: Response; + books: Response; } - export type Response = ABP.PagedResponse; + export interface Response { + items: Book[]; + totalCount: number; + } - export interface Item { + export interface Book { name: string; - type: Type; + type: BookType; publishDate: string; price: number; lastModificationTime: string; @@ -19,7 +20,7 @@ export namespace Books { id: string; } - export enum Type { + export enum BookType { Undefined, Adventure, Biography, @@ -31,9 +32,9 @@ export namespace Books { Poetry, } - export interface SaveRequest { + export interface CreateUpdateBookInput { name: string; - type: Type; + type: BookType; publishDate: string; price: number; } diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts index fe6a701ed1..fb958142de 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts @@ -1,36 +1,47 @@ import { State, Action, StateContext, Selector } from '@ngxs/store'; -import { BooksGet, BooksSave } from '../actions/books.actions'; import { Books } from '../models/books'; -import { BooksService } from '../../books/services/books.service'; +import { BooksService } from '../../books/shared/books.service'; import { tap, switchMap } from 'rxjs/operators'; +import { GetBooks, CreateUpdateBook, DeleteBook } from '../actions/books.actions'; @State({ name: 'BooksState', - defaults: { data: {} } as Books.State, + defaults: { books: {} } as Books.State, }) export class BooksState { @Selector() - static getBooks({ data }: Books.State) { - return data.items || []; + static getBooks({ books }: Books.State) { + return books.items || []; } constructor(private booksService: BooksService) {} - @Action(BooksGet) - getBooks({ patchState }: StateContext) { + @Action(GetBooks) + get({ patchState }: StateContext) { return this.booksService.get().pipe( - tap(data => { + tap(books => { patchState({ - data, + books, }); }), ); } - @Action(BooksSave) - addBooks({ dispatch }: StateContext, { payload, id }: BooksSave) { - return (id ? this.booksService.update(payload, id) : this.booksService.add(payload)).pipe( - switchMap(() => dispatch(new BooksGet())), - ); + @Action(CreateUpdateBook) + save({ dispatch }: StateContext, { payload, id }: CreateUpdateBook) { + let request; + + if (id) { + request = this.booksService.update(payload, id); + } else { + request = this.booksService.create(payload); + } + + return request.pipe(switchMap(() => dispatch(new GetBooks()))); + } + + @Action(DeleteBook) + delete({ dispatch }: StateContext, { id }: DeleteBook) { + return this.booksService.delete(id).pipe(switchMap(() => dispatch(new GetBooks()))); } } diff --git a/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.hmr.ts b/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.hmr.ts index 65b05ebac2..43f4d06be4 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.hmr.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.hmr.ts @@ -1,6 +1,10 @@ export const environment = { production: false, hmr: true, + application: { + name: 'BookStore', + logoUrl: '', + }, oAuthConfig: { issuer: 'https://localhost:44359', clientId: 'BookStore_ConsoleTestApp', diff --git a/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.prod.ts b/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.prod.ts index 4848d1bd44..d56d02f60f 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.prod.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.prod.ts @@ -1,6 +1,10 @@ export const environment = { production: true, hmr: false, + application: { + name: 'BookStore', + logoUrl: '', + }, oAuthConfig: { issuer: 'https://localhost:44359', clientId: 'BookStore_ConsoleTestApp', diff --git a/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.ts b/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.ts index e4bd2964f9..ac83b4714b 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/environments/environment.ts @@ -1,6 +1,10 @@ export const environment = { production: false, hmr: false, + application: { + name: 'BookStore', + logoUrl: '', + }, oAuthConfig: { issuer: 'https://localhost:44359', clientId: 'BookStore_ConsoleTestApp',