From 034837ce1b1433de5dadd30485c590b8cce3bb9e Mon Sep 17 00:00:00 2001 From: Ivaylo Ivanov Date: Sat, 21 Mar 2020 14:47:58 +0100 Subject: [PATCH] US03: Make it possible to update a hourse through the web UI --- .../src/app/app-routing.module.ts | 4 +- frontend/wendys-friends/src/app/app.module.ts | 4 +- .../update-horse/update-horse.component.html | 61 ++++++++ .../update-horse/update-horse.component.scss | 0 .../update-horse/update-horse.component.ts | 132 ++++++++++++++++++ .../src/app/service/horse.service.ts | 5 + 6 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 frontend/wendys-friends/src/app/component/update-horse/update-horse.component.html create mode 100644 frontend/wendys-friends/src/app/component/update-horse/update-horse.component.scss create mode 100644 frontend/wendys-friends/src/app/component/update-horse/update-horse.component.ts diff --git a/frontend/wendys-friends/src/app/app-routing.module.ts b/frontend/wendys-friends/src/app/app-routing.module.ts index a742756..ac49a94 100644 --- a/frontend/wendys-friends/src/app/app-routing.module.ts +++ b/frontend/wendys-friends/src/app/app-routing.module.ts @@ -1,8 +1,9 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import {OwnerComponent} from './component/owner/owner.component'; +import { OwnerComponent } from './component/owner/owner.component'; import { HorseComponent } from './component/horse/horse.component'; import { AddHorseComponent } from './component/add-horse/add-horse.component'; +import { UpdateHorseComponent } from './component/update-horse/update-horse.component'; const routes: Routes = [ @@ -10,6 +11,7 @@ const routes: Routes = [ {path: 'owner', component: OwnerComponent}, {path: 'horse', component: HorseComponent}, {path: 'horse/add', component: AddHorseComponent}, + {path: 'horse/:id/edit', component: UpdateHorseComponent}, ]; @NgModule({ diff --git a/frontend/wendys-friends/src/app/app.module.ts b/frontend/wendys-friends/src/app/app.module.ts index 7de480e..47b5baf 100644 --- a/frontend/wendys-friends/src/app/app.module.ts +++ b/frontend/wendys-friends/src/app/app.module.ts @@ -9,6 +9,7 @@ import {HeaderComponent} from './component/header/header.component'; import {OwnerComponent} from './component/owner/owner.component'; import { HorseComponent } from './component/horse/horse.component'; import { AddHorseComponent } from './component/add-horse/add-horse.component'; +import { UpdateHorseComponent } from './component/update-horse/update-horse.component'; @NgModule({ declarations: [ @@ -16,7 +17,8 @@ import { AddHorseComponent } from './component/add-horse/add-horse.component'; HeaderComponent, OwnerComponent, HorseComponent, - AddHorseComponent + AddHorseComponent, + UpdateHorseComponent ], imports: [ BrowserModule, diff --git a/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.html b/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.html new file mode 100644 index 0000000..5daabeb --- /dev/null +++ b/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.html @@ -0,0 +1,61 @@ + + + + +
+

Add new horse

+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
\ No newline at end of file diff --git a/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.scss b/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.ts b/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.ts new file mode 100644 index 0000000..420366a --- /dev/null +++ b/frontend/wendys-friends/src/app/component/update-horse/update-horse.component.ts @@ -0,0 +1,132 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Params} from '@angular/router'; +import { Horse } from '../../dto/horse'; +import { HorseService } from '../../service/horse.service'; + +@Component({ + selector: 'app-update-horse', + templateUrl: './update-horse.component.html', + styleUrls: ['./update-horse.component.scss'] +}) +export class UpdateHorseComponent implements OnInit { + error = false; + success: string; + errorMessage = ''; + horse: Horse = new Horse(null, null, null, null, null, null, null, null); + imageToUpload: File = null; + + constructor(private horseService: HorseService, private route: ActivatedRoute) { } + + ngOnInit(): void { + // Extract id from url + const horseId: string = this.route.snapshot.paramMap.get('id'); + + // Get current value of the horse and save it + this.horseService.getHorseById(parseInt(horseId, 10)).subscribe( + (horse: Horse) => { + this.horse = horse; + }, + error => { + this.defaultServiceErrorHandling(error); + } + ); + } + + /** + * Will be called on a click on the success alert close button + */ + public vanishAlert() { + this.success = null; + } + + /** + * Will be called on a click on the error alert close button + */ + public vanishError() { + this.errorMessage = null; + } + + /** + * Handles the input on the image input. + * Inspired from: + * https://stackoverflow.com/questions/47936183/angular-file-upload + * @param files + */ + public handleImageInput(files: FileList) { + var imageFile: File = files.item(0); + + // Generate a random bytes name to avoid conflicts + var fileExt: string = imageFile.name.split('.').pop(); + var newFileName: string = this.generateHex(20) + '.' + fileExt; + this.horse.imagePath = newFileName; + + // Upload the file + this.uploadFile(imageFile, newFileName) + } + + /** + * Updates a horse and loads it + * @param horse + */ + public updateHorse() { + console.log("PUT horse to API") + console.log(this.horse); + // TODO: Make it possible for the horse to be added with an owner + this.horseService.updateHorse(this.horse).subscribe( + (result: Horse) => { + this.success = result.name; + }, + error => { + this.defaultServiceErrorHandling(error); + } + ); + } + + /** + * Uploads the file to the backend with the specified file name + * @param file + * @param newFileName + */ + private uploadFile(file: File, newFileName: string){ + this.horseService.postFile(file, newFileName).subscribe( + () => { + console.log("Image successfully uploaded"); + }, error => { + this.defaultServiceErrorHandling(error) + }); + } + + /** + * Generates a random hex with the specified length + * Inspired from: + * https://stackoverflow.com/a/27747377 + * @param len + */ + private generateHex(len: number): string { + var arr = new Uint8Array((len) / 2) + window.crypto.getRandomValues(arr) + return Array.from(arr, this.dec2hex).join('') + } + + /** + * Converts a decimal to its hex value + * @param dec + */ + private dec2hex(dec: number): string { + return ('0' + dec.toString(16)).substr(-2) + } + + private defaultServiceErrorHandling(error: any) { + console.log(error); + this.error = true; + if (error.status === 0) { + // If status is 0, the backend is probably down + this.errorMessage = 'The backend seems not to be reachable'; + } else if (error.error.message === 'No message available') { + // If no detailed error message is provided, fall back to the simple error name + this.errorMessage = error.error.error; + } else { + this.errorMessage = error.error.message; + } + } +} diff --git a/frontend/wendys-friends/src/app/service/horse.service.ts b/frontend/wendys-friends/src/app/service/horse.service.ts index 3774b24..299046f 100644 --- a/frontend/wendys-friends/src/app/service/horse.service.ts +++ b/frontend/wendys-friends/src/app/service/horse.service.ts @@ -31,6 +31,11 @@ export class HorseService { return this.httpClient.post(this.messageBaseUri, horse); } + updateHorse(horse: Horse): Observable { + console.log('Update horse with id ' + horse.id + ': '+ JSON.stringify(horse)); + return this.httpClient.put(this.messageBaseUri + '/' + horse.id, horse); + } + /** * */