Browse Source

feature(book-store): add add & update book

pull/1606/head
mehmet-erim 7 years ago
parent
commit
acb3790473
  1. 77
      samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.html
  2. 50
      samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.ts
  3. 3
      samples/BookStore-Angular-MongoDb/angular/src/app/books/books.module.ts
  4. 29
      samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.ts
  5. 7
      samples/BookStore-Angular-MongoDb/angular/src/app/store/actions/books.actions.ts
  6. 7
      samples/BookStore-Angular-MongoDb/angular/src/app/store/models/books.ts
  7. 11
      samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts
  8. 2
      samples/BookStore-Angular-MongoDb/angular/src/environments/environment.hmr.ts
  9. 2
      samples/BookStore-Angular-MongoDb/angular/src/environments/environment.prod.ts
  10. 2
      samples/BookStore-Angular-MongoDb/angular/src/environments/environment.ts

77
samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.html

@ -6,12 +6,18 @@
Books
</h5>
</div>
<div class="text-right col col-md-6">
<button id="create-role" class="btn btn-primary" type="button" (click)="onAdd()">
<i class="fa fa-plus mr-1"></i> <span>New book</span>
</button>
</div>
</div>
</div>
<div class="card-body">
<p-table [value]="books$ | async" [loading]="loading" [paginator]="true" [rows]="10">
<ng-template pTemplate="header">
<tr>
<th>Actions</th>
<th>Book name</th>
<th>Book type</th>
<th>Publish date</th>
@ -20,6 +26,24 @@
</ng-template>
<ng-template pTemplate="body" let-data>
<tr>
<td>
<div ngbDropdown class="d-inline-block">
<button
class="btn btn-primary btn-sm dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
ngbDropdownToggle
>
<i class="fa fa-cog mr-1"></i>Actions
</button>
<div ngbDropdownMenu>
<button ngbDropdownItem (click)="onEdit(data.id)">Edit</button>
<!-- <button ngbDropdownItem (click)="delete(data.id, data.name)">
Delete
</button> -->
</div>
</div>
</td>
<td>{{ data.name }}</td>
<td>{{ bookType[data.type] }}</td>
<td>{{ data.publishDate | date }}</td>
@ -29,3 +53,56 @@
</p-table>
</div>
</div>
<abp-modal [(visible)]="isModalOpen">
<ng-template #abpHeader>
<h3>{{ selectedBook?.id ? 'Edit' : 'New Book' }}</h3>
</ng-template>
<ng-template #abpBody>
<form [formGroup]="form">
<div class="form-group">
<label for="book-name">Name</label><span> * </span>
<input type="text" id="book-name" class="form-control" formControlName="name" autofocus />
</div>
<div class="form-group">
<label for="book-price">Price</label>
<input type="number" id="book-price" class="form-control" formControlName="price" />
</div>
<div class="form-group">
<label for="book-type">Type</label>
<select class="form-control" id="book-type" formControlName="type">
<option [ngValue]="null">Select a book type</option>
<option [ngValue]="bookType[type]" *ngFor="let type of bookTypes"> {{ type }}</option>
</select>
</div>
<div class="form-group">
<label>Publish date</label>
<input
#datepicker="ngbDatepicker"
class="form-control"
name="datepicker"
formControlName="publishDate"
ngbDatepicker
(click)="datepicker.toggle()"
/>
</div>
</form>
</ng-template>
<ng-template #abpFooter>
<button type="button" class="btn btn-secondary" #abpClose>
Cancel
</button>
<abp-button
[requestType]="['POST', 'PUT']"
requestURLContainSearchValue="book"
iconClass="fa fa-check"
(click)="save()"
>Save</abp-button
>
</ng-template>
</abp-modal>

50
samples/BookStore-Angular-MongoDb/angular/src/app/books/books.component.ts

@ -3,12 +3,16 @@ import { Store, Select } from '@ngxs/store';
import { BooksState } from '../store/states';
import { Observable } from 'rxjs';
import { Books } from '../store/models';
import { BooksGet } from '../store/actions';
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';
@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)
@ -16,12 +20,54 @@ export class BooksComponent implements OnInit {
bookType = Books.Type;
bookTypes = Object.keys(Books.Type).filter(bookType => typeof this.bookType[bookType] === 'number');
loading = false;
constructor(private store: Store) {}
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();
});
}
}

3
samples/BookStore-Angular-MongoDb/angular/src/app/books/books.module.ts

@ -4,9 +4,10 @@ import { CommonModule } from '@angular/common';
import { BooksRoutingModule } from './books-routing.module';
import { BooksComponent } from './books.component';
import { SharedModule } from '../shared/shared.module';
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap';
@NgModule({
declarations: [BooksComponent],
imports: [CommonModule, BooksRoutingModule, SharedModule],
imports: [CommonModule, BooksRoutingModule, SharedModule, NgbDatepickerModule],
})
export class BooksModule {}

29
samples/BookStore-Angular-MongoDb/angular/src/app/books/services/books.service.ts

@ -17,4 +17,33 @@ export class BooksService {
return this.rest.request<null, Books.Response>(request);
}
getById(id: string): Observable<Books.Item> {
const request: Rest.Request<null> = {
method: 'GET',
url: `/api/app/book/${id}`,
};
return this.rest.request<null, Books.Item>(request);
}
update(body: Books.SaveRequest, id: string): Observable<Books.Item> {
const request: Rest.Request<Books.SaveRequest> = {
method: 'PUT',
url: `/api/app/book/${id}`,
body,
};
return this.rest.request<Books.SaveRequest, Books.Item>(request);
}
add(body: Books.SaveRequest): Observable<Books.Item> {
const request: Rest.Request<Books.SaveRequest> = {
method: 'POST',
url: '/api/app/book',
body,
};
return this.rest.request<Books.SaveRequest, Books.Item>(request);
}
}

7
samples/BookStore-Angular-MongoDb/angular/src/app/store/actions/books.actions.ts

@ -1,3 +1,10 @@
import { Books } from '../models';
export class BooksGet {
static readonly type = '[Books] Get';
}
export class BooksSave {
static readonly type = '[Books] Save';
constructor(public payload: Books.SaveRequest, public id?: string) {}
}

7
samples/BookStore-Angular-MongoDb/angular/src/app/store/models/books.ts

@ -30,4 +30,11 @@ export namespace Books {
ScienceFiction,
Poetry,
}
export interface SaveRequest {
name: string;
type: Type;
publishDate: string;
price: number;
}
}

11
samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts

@ -1,8 +1,8 @@
import { State, Action, StateContext, Selector } from '@ngxs/store';
import { BooksGet } from '../actions/books.actions';
import { BooksGet, BooksSave } from '../actions/books.actions';
import { Books } from '../models/books';
import { BooksService } from '../../books/services/books.service';
import { tap } from 'rxjs/operators';
import { tap, switchMap } from 'rxjs/operators';
@State<Books.State>({
name: 'BooksState',
@ -26,4 +26,11 @@ export class BooksState {
}),
);
}
@Action(BooksSave)
addBooks({ dispatch }: StateContext<Books.State>, { payload, id }: BooksSave) {
return (id ? this.booksService.update(payload, id) : this.booksService.add(payload)).pipe(
switchMap(() => dispatch(new BooksGet())),
);
}
}

2
samples/BookStore-Angular-MongoDb/angular/src/environments/environment.hmr.ts

@ -3,7 +3,7 @@ export const environment = {
hmr: true,
oAuthConfig: {
issuer: 'https://localhost:44359',
clientId: 'BookStore_App',
clientId: 'BookStore_ConsoleTestApp',
dummyClientSecret: '1q2w3e*',
scope: 'BookStore',
showDebugInformation: true,

2
samples/BookStore-Angular-MongoDb/angular/src/environments/environment.prod.ts

@ -3,7 +3,7 @@ export const environment = {
hmr: false,
oAuthConfig: {
issuer: 'https://localhost:44359',
clientId: 'BookStore_App',
clientId: 'BookStore_ConsoleTestApp',
dummyClientSecret: '1q2w3e*',
scope: 'BookStore',
showDebugInformation: true,

2
samples/BookStore-Angular-MongoDb/angular/src/environments/environment.ts

@ -3,7 +3,7 @@ export const environment = {
hmr: false,
oAuthConfig: {
issuer: 'https://localhost:44359',
clientId: 'BookStore_App',
clientId: 'BookStore_ConsoleTestApp',
dummyClientSecret: '1q2w3e*',
scope: 'BookStore',
showDebugInformation: true,

Loading…
Cancel
Save