From 0a5b7a06f4a4e50f2beb2ed0d76a77f890869190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20G=C3=B3reczny?= Date: Fri, 22 Jan 2021 21:15:19 +0100 Subject: [PATCH] SES-160 game-master page --- .../Services/ShopkeeperService.cs | 6 +- .../ClientApp/src/app/app.module.ts | 7 +- ...ame-master-shopkeepers-table.component.css | 6 + ...me-master-shopkeepers-table.component.html | 8 +- ...game-master-shopkeepers-table.component.ts | 92 +++++++++- .../new-shopkeeper-dialog.component.css | 62 +++++++ .../new-shopkeeper-dialog.component.html | 104 +++++++++++ .../new-shopkeeper-dialog.component.ts | 170 ++++++++++++++++++ .../src/services/shopkeeper.service.ts | 78 +++++++- .../ShopkeeperItemsViewModel.ts | 6 + ...keeperItemsWithItemNameAndTypeViewModel.ts | 8 + .../ShopkeeperWithItemsViewModel.ts | 8 + .../Controllers/ShopkeeperController.cs | 7 +- 13 files changed, 540 insertions(+), 22 deletions(-) create mode 100644 SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.css create mode 100644 SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.html create mode 100644 SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.ts create mode 100644 SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsViewModel.ts create mode 100644 SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsWithItemNameAndTypeViewModel.ts create mode 100644 SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsViewModel.ts diff --git a/SessionCompanion/SessionCompanion.Services/Services/ShopkeeperService.cs b/SessionCompanion/SessionCompanion.Services/Services/ShopkeeperService.cs index cfbdde3..73ec699 100644 --- a/SessionCompanion/SessionCompanion.Services/Services/ShopkeeperService.cs +++ b/SessionCompanion/SessionCompanion.Services/Services/ShopkeeperService.cs @@ -42,14 +42,14 @@ namespace SessionCompanion.Services.Services await Repository.Update(shopkeeper); } await Repository.Save(); - return new SuccessResponse("Shopkeepers updated") { StatusCode = 200 }; + return new SuccessResponse(200, "Shopkeepers updated"); } var newActiveShopkeeper = shopkeepers.Where(c => c.Id.Equals(shopkeeperId)).Single(); newActiveShopkeeper.IsAvailable = false; await Repository.Update(newActiveShopkeeper); await Repository.Save(); - return new SuccessResponse("Shopkeepers updated") { StatusCode = 200 }; + return new SuccessResponse(200, "Shopkeepers updated"); } catch (Exception e) { @@ -61,7 +61,7 @@ namespace SessionCompanion.Services.Services { try { - var activeShopkeeper = await Repository.Get(c => c.IsAvailable.Equals(true)).SingleAsync(); + var activeShopkeeper = await Repository.Get(c => c.IsAvailable.Equals(true)).FirstOrDefaultAsync(); if (activeShopkeeper != null && shopkeeperWithItemsViewModel.IsAvailable) { activeShopkeeper.IsAvailable = false; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts index 3a7f6a6..1b290e7 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts @@ -28,6 +28,7 @@ import { MatDialogModule, MatTooltipModule, MatSnackBarModule, + MatStepperModule, } from '@angular/material'; import { UserService } from '../services/user.service'; import { StoreModule } from '@ngrx/store'; @@ -52,7 +53,7 @@ import { MonsterService } from '../services/monster.service'; import { SpellDetailsDialogComponent } from './components/spell-details-dialog/spell-details-dialog.component'; import { GameMasterShopkeepersTableComponent } from './components/game-master-shopkeepers-table/game-master-shopkeepers-table.component'; import { PlayerWeaponsTableComponent } from './components/player-weapons-table/player-weapons-table.component'; -import {EquipmentService} from "../services/equipment.service"; +import { EquipmentService } from '../services/equipment.service'; import { PlayerArmorsTableComponent } from './components/player-armors-table/player-armors-table.component'; import { PlayerOtherEquipmentTableComponent } from './components/player-other-equipment-table/player-other-equipment-table.component'; import { SendMessageActionComponent } from './components/game-master-character-actions-dialog/actions-components/send-message-action/send-message-action.component'; @@ -63,6 +64,7 @@ import { GameMasterTurntrackerComponent } from './components/game-master-turntra import { DragDropModule } from '@angular/cdk/drag-drop'; import { ChooseMonsterDialogComponent } from './components/choose-monster-dialog/choose-monster-dialog.component'; import { ShopkeeperService } from '../services/shopkeeper.service'; +import { NewShopkeeperDialogComponent } from './components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component'; @NgModule({ declarations: [ @@ -91,6 +93,7 @@ import { ShopkeeperService } from '../services/shopkeeper.service'; MessageDialogComponent, GameMasterTurntrackerComponent, ChooseMonsterDialogComponent, + NewShopkeeperDialogComponent, ], imports: [ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), @@ -122,6 +125,7 @@ import { ShopkeeperService } from '../services/shopkeeper.service'; DynamicModule, MatSnackBarModule, DragDropModule, + MatStepperModule, ], providers: [ UserService, @@ -153,6 +157,7 @@ import { ShopkeeperService } from '../services/shopkeeper.service'; MessageDialogComponent, GameMasterTurntrackerComponent, ChooseMonsterDialogComponent, + NewShopkeeperDialogComponent, ], }) export class AppModule {} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.css index 07509b6..146ed35 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.css @@ -42,3 +42,9 @@ button { .mat-column-actions { text-align: center; } + +.add-new-shopkeeper-button { + float: right; + color: whitesmoke; + border-color: whitesmoke; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.html index 9d7b8bf..307dece 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.html @@ -20,10 +20,10 @@ (click)="DeactivateShopkeeper(row.id)"> Deactivate - - @@ -40,3 +40,7 @@ + + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.ts index 6c6a000..17ead8c 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/game-master-shopkeepers-table.component.ts @@ -8,6 +8,8 @@ import { ShopkeeperService } from '../../../services/shopkeeper.service'; import { first } from 'rxjs/operators'; import { ErrorResponse } from '../../../types/ErrorResponse'; import { HttpErrorResponse } from '@angular/common/http'; +import { MatDialog } from '@angular/material'; +import { NewShopkeeperDialogComponent } from './shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component'; @Component({ selector: 'app-game-master-shopkeepers-table', @@ -17,13 +19,21 @@ import { HttpErrorResponse } from '@angular/common/http'; export class GameMasterShopkeepersTableComponent implements OnInit { displayedColumns: string[] = ['name', 'actions']; dataSource: MatTableDataSource; + isAnyAvailable: boolean = false; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; @ViewChild(MatSort, { static: true }) sort: MatSort; - constructor(private shopkeeperService: ShopkeeperService) {} + constructor( + private shopkeeperService: ShopkeeperService, + public dialog: MatDialog + ) {} ngOnInit() { + this.GetAllShopkeepers(); + } + + GetAllShopkeepers() { this.shopkeeperService .GetAllShopkeepers() .pipe(first()) @@ -32,6 +42,9 @@ export class GameMasterShopkeepersTableComponent implements OnInit { this.dataSource = new MatTableDataSource(result); this.dataSource.sort = this.sort; this.dataSource.paginator = this.paginator; + if (result.find((e) => e.isAvailable) != null) { + this.isAnyAvailable = true; + } }, (error: ErrorResponse | HttpErrorResponse) => { console.error(error); @@ -44,15 +57,80 @@ export class GameMasterShopkeepersTableComponent implements OnInit { } ActivateShopkeeper(shopkeeperId: number) { - if (this.dataSource.data.find((e) => e.isAvailable) != null) { - this.dataSource.data.find((e) => e.id == shopkeeperId).isAvailable = true; - this.shopkeeperService.ChangeShopkeeperStatus(shopkeeperId, true); - } + this.shopkeeperService + .ChangeShopkeeperStatus(shopkeeperId, true) + .pipe(first()) + .subscribe( + (result) => { + this.dataSource.data.find( + (e) => e.id == shopkeeperId + ).isAvailable = true; + this.isAnyAvailable = true; + }, + (error: ErrorResponse | HttpErrorResponse) => { + console.error(error); + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } + ); } DeactivateShopkeeper(shopkeeperId: number) { - this.dataSource.data.find((e) => e.id == shopkeeperId).isAvailable = false; - this.shopkeeperService.ChangeShopkeeperStatus(shopkeeperId, false); + this.shopkeeperService + .ChangeShopkeeperStatus(shopkeeperId, false) + .pipe(first()) + .subscribe( + (result) => { + this.dataSource.data.find( + (e) => e.id == shopkeeperId + ).isAvailable = false; + this.isAnyAvailable = false; + }, + (error: ErrorResponse | HttpErrorResponse) => { + console.error(error); + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } + ); + } + + RemoveShopkeeper(shopkeeperId: number) { + let currentStatus = this.dataSource.data.find((e) => e.id == shopkeeperId) + .isAvailable; + this.shopkeeperService + .RemoveShopkeeper(shopkeeperId, currentStatus) + .pipe(first()) + .subscribe( + (result) => { + if (currentStatus == true) { + this.isAnyAvailable = false; + } + this.dataSource.data = this.dataSource.data.filter( + (e) => e.id != shopkeeperId + ); + }, + (error: ErrorResponse | HttpErrorResponse) => { + console.error(error); + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } + ); + } + + AddNewShopkeeper() { + this.dialog + .open(NewShopkeeperDialogComponent) + .afterClosed() + .pipe(first()) + .subscribe(() => { + this.GetAllShopkeepers(); + }); } applyFilter(event: Event) { diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.css new file mode 100644 index 0000000..6dbe130 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.css @@ -0,0 +1,62 @@ +::ng-deep .mat-horizontal-content-container { + overflow-y: auto !important; + max-height: 500px; +} + +table { + background-color: initial; +} + +mat-paginator { + background-color: initial; + color: white; +} + +::ng-deep .mat-select-arrow { + color: whitesmoke; +} + +::ng-deep .mat-select-value { + color: white; +} + +.button-to-right { + float: right; +} + +.button-to-right > button { + color: whitesmoke; +} + +td, +th { + color: whitesmoke; +} + +.shopkeeper-create-button { + color: #7bce7b !important; +} + +.shopkeeper-stepper-main { + background-color: #4f5c69; +} + +::ng-deep .mat-step-label { + color: white !important; +} + +::ng-deep .mat-step-icon-selected { + background-color: #df7c0f !important; +} + +::ng-deep .mat-step-icon-state-edit { + background-color: #df7c0f !important; +} + +::ng-deep mat-dialog-container { + background-color: #4f5c69 !important; +} + +::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background { + background-color: #df7c0f; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.html new file mode 100644 index 0000000..8d3e06f --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.html @@ -0,0 +1,104 @@ + + +
+ Fill out your shop name + + Name + + +
+
+ +
+
+ + Select items +
+ + + + + + + + + + + + + + + + + + + + + + + +
Select + + + + Name {{row.itemName}} Type {{row.itemType}}
No data found
+ + +
+
+ + +
+
+ + Set a quantity +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name {{row.itemName}} Type {{row.itemType}} Amount + + + + Remove + +
No data found
+ + +
+
+ + +
+
+
+ diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.ts new file mode 100644 index 0000000..59412fc --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-shopkeepers-table/shopkeeper-dialogs/new-shopkeeper-dialog/new-shopkeeper-dialog.component.ts @@ -0,0 +1,170 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { WeaponService } from '../../../../../services/weapon.service'; +import { ArmorService } from '../../../../../services/armor.service'; +import { ShopkeeperItemsWithItemNameAndTypeViewModel } from '../../../../../types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsWithItemNameAndTypeViewModel'; +import { first, map } from 'rxjs/operators'; +import { forkJoin, Observable } from 'rxjs'; +import { SelectionModel } from '@angular/cdk/collections'; +import { + MatDialog, + MatDialogRef, + MatHorizontalStepper, +} from '@angular/material'; +import { ShopkeeperService } from '../../../../../services/shopkeeper.service'; +import { ShopkeeperWithItemsViewModel } from '../../../../../types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsViewModel'; +import { ShopkeeperItemsViewModel } from '../../../../../types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsViewModel'; + +@Component({ + selector: 'app-new-shopkeeper-dialog', + templateUrl: './new-shopkeeper-dialog.component.html', + styleUrls: ['./new-shopkeeper-dialog.component.css'], +}) +export class NewShopkeeperDialogComponent implements OnInit { + displayedColumnsForFinal: string[] = [ + 'itemName', + 'itemType', + 'amount', + 'actions', + ]; + displayedColumns: string[] = ['select', 'itemName', 'itemType']; + dataSourceWithAllitems: MatTableDataSource; + selection = new SelectionModel( + true, + [] + ); + finalDataSource: MatTableDataSource; + nameFormGroup: FormGroup; + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + @ViewChild(MatPaginator, { static: true }) paginatorForFinal: MatPaginator; + @ViewChild(MatSort, { static: true }) sortForFinal: MatSort; + + constructor( + private formBuilder: FormBuilder, + private weaponService: WeaponService, + private armorService: ArmorService, + private shopkeeperService: ShopkeeperService, + public dialogRef: MatDialogRef + ) {} + + ngOnInit() { + this.GetAllWeaponsAndArmors() + .pipe(first()) + .subscribe((res) => { + this.dataSourceWithAllitems = new MatTableDataSource( + res + ); + this.dataSourceWithAllitems.sort = this.sort; + this.dataSourceWithAllitems.paginator = this.paginator; + }); + + this.finalDataSource = new MatTableDataSource( + [] + ); + this.finalDataSource.paginator = this.paginatorForFinal; + this.finalDataSource.sort = this.sortForFinal; + + this.nameFormGroup = this.formBuilder.group({ + name: ['', Validators.required], + }); + } + + GetAllWeaponsAndArmors(): Observable< + ShopkeeperItemsWithItemNameAndTypeViewModel[] + > { + return forkJoin([ + this.armorService.GetAllArmors(), + this.weaponService.GetAllWeapons(), + ]).pipe( + first(), + map(([armors, weapons]) => { + let resultArray: ShopkeeperItemsWithItemNameAndTypeViewModel[]; + + resultArray = weapons.map( + (e) => { + return { + shopkeeperId: null, + amount: 1, + armorId: null, + weaponId: e.id, + itemName: e.name, + itemType: 'Weapon', + }; + } + ); + + return [ + ...resultArray, + ...armors.map((e) => { + return { + shopkeeperId: null, + amount: 1, + armorId: null, + weaponId: e.id, + itemName: e.name, + itemType: 'Armor', + }; + }), + ]; + }) + ); + } + + ToFinalStep(stepper: MatHorizontalStepper) { + this.selection.selected.forEach((item) => { + if ( + this.finalDataSource.data.filter( + (e) => e.armorId == item.armorId && e.weaponId == item.weaponId + ).length == 0 + ) { + this.finalDataSource.data = [...this.finalDataSource.data, item]; + } + }); + + this.selection.clear(); + + stepper.next(); + } + + CreateShopkeeper() { + if (this.finalDataSource.data.length > 0) { + let filteredData = this.finalDataSource.data.filter((e) => e.amount > 0); + let shopkeeperModel: ShopkeeperWithItemsViewModel = { + id: null, + name: this.nameFormGroup.value.name, + isAvailable: false, + items: filteredData.map((item) => { + return { + shopkeeperId: null, + armorId: item.armorId, + weaponId: item.weaponId, + amount: item.amount, + }; + }), + }; + this.shopkeeperService + .CreateShopkeeper(shopkeeperModel) + .pipe(first()) + .subscribe((result) => { + this.dialogRef.close(); + }); + } + } + + RemoveItem(weaponId: number, armorId: number) { + if (weaponId != null) { + this.finalDataSource.data = this.finalDataSource.data.filter( + (e) => e.weaponId != weaponId + ); + } else if (armorId != null) { + this.finalDataSource.data = this.finalDataSource.data.filter( + (e) => e.armorId != armorId + ); + } + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/services/shopkeeper.service.ts b/SessionCompanion/SessionCompanion/ClientApp/src/services/shopkeeper.service.ts index e3f8cf6..f29a9d0 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/services/shopkeeper.service.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/services/shopkeeper.service.ts @@ -1,5 +1,5 @@ import { Inject, Injectable } from '@angular/core'; -import { HttpClient, HttpParams } from '@angular/common/http'; +import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { Observable, of, throwError } from 'rxjs'; import { ShopkeeperViewModel } from '../types/viewmodels/shopkeeper-viewmodels/ShopkeeperViewModel'; import { Either } from '../types/Either'; @@ -7,6 +7,7 @@ import { ErrorResponse } from '../types/ErrorResponse'; import { switchMap } from 'rxjs/operators'; import { SuccessResponse } from '../types/SuccessResponse'; import { ShopkeeperWithItemsDetailsViewModel } from '../types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsDetailsViewModel'; +import { ShopkeeperWithItemsViewModel } from '../types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsViewModel'; Injectable({ providedIn: 'root', @@ -24,7 +25,6 @@ export class ShopkeeperService { ) .pipe( switchMap((response) => { - debugger; if (response.isLeft) { return of(response.left); } else { @@ -41,7 +41,6 @@ export class ShopkeeperService { ) .pipe( switchMap((response) => { - debugger; if (response.isLeft) { return of(response.left); } else { @@ -51,17 +50,82 @@ export class ShopkeeperService { ); } - ChangeShopkeeperStatus(shopkeeperId: number, newStatus: boolean) { + CreateShopkeeper( + shopkeeperModel: ShopkeeperWithItemsViewModel + ): Observable { + const params = new HttpParams().set( + 'shopkeeperWithItemsViewModel', + JSON.stringify(shopkeeperModel) + ); + const httpOptions = { + headers: new HttpHeaders({ 'Content-Type': 'application/json' }), + }; + + console.log(params); + + return this.http + .post>( + this.baseUrl + 'createNewShopkeeper', + shopkeeperModel, + httpOptions + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); + } + + ChangeShopkeeperStatus( + shopkeeperId: number, + newStatus: boolean + ): Observable { const params = new HttpParams() .set('shopkeeperId', shopkeeperId.toString()) .set('availability', newStatus.toString()); - this.http.post(this.baseUrl + 'getShopkeepers', params); + + return this.http + .put>( + this.baseUrl + 'changeShopkeeperStatus', + null, + { params } + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); } - RemoveShopkeeper(shopkeeperId: number, currentStatus: boolean) { + RemoveShopkeeper( + shopkeeperId: number, + currentStatus: boolean + ): Observable { const params = new HttpParams() .set('shopkeeperId', shopkeeperId.toString()) .set('wasAvailable', currentStatus.toString()); - this.http.post(this.baseUrl + 'getShopkeepers', params); + + return this.http + .delete>( + this.baseUrl + 'removeShopkeeper', + { params } + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsViewModel.ts new file mode 100644 index 0000000..8d68c64 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsViewModel.ts @@ -0,0 +1,6 @@ +export interface ShopkeeperItemsViewModel { + shopkeeperId: number; + armorId: number; + weaponId: number; + amount: number; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsWithItemNameAndTypeViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsWithItemNameAndTypeViewModel.ts new file mode 100644 index 0000000..d571708 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperItemsWithItemNameAndTypeViewModel.ts @@ -0,0 +1,8 @@ +export interface ShopkeeperItemsWithItemNameAndTypeViewModel { + shopkeeperId: number; + armorId: number; + weaponId: number; + amount: number; + itemName: string; + itemType: string; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsViewModel.ts new file mode 100644 index 0000000..0271936 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/shopkeeper-viewmodels/ShopkeeperWithItemsViewModel.ts @@ -0,0 +1,8 @@ +import { ShopkeeperItemsViewModel } from './ShopkeeperItemsViewModel'; + +export interface ShopkeeperWithItemsViewModel { + id: number; + name: string; + isAvailable: boolean; + items: ShopkeeperItemsViewModel[]; +} diff --git a/SessionCompanion/SessionCompanion/Controllers/ShopkeeperController.cs b/SessionCompanion/SessionCompanion/Controllers/ShopkeeperController.cs index 0a05544..dfcc2b0 100644 --- a/SessionCompanion/SessionCompanion/Controllers/ShopkeeperController.cs +++ b/SessionCompanion/SessionCompanion/Controllers/ShopkeeperController.cs @@ -55,7 +55,7 @@ namespace SessionCompanion.Controllers /// /// SuccesResponse/ErrorResponse [HttpPut("changeShopkeeperStatus")] - public async Task> ChangeShopkeeperStatus([Required] int shopkeeperId, [Required] bool availability) + public async Task> ChangeShopkeeperStatus([FromQuery][Required] int shopkeeperId, [FromQuery][Required] bool availability) { var result = await _service.ChangeShopkeeperStatus(shopkeeperId, availability); if (result.IsLeft && availability) @@ -74,11 +74,14 @@ namespace SessionCompanion.Controllers public async Task> CreateNewShopKeeper([Required] ShopkeeperWithItemsViewModel shopkeeperWithItemsViewModel) { if (!ModelState.IsValid) + { return new ErrorResponse() { StatusCode = 500, Message = "Model is invalid" }; + } + return await _service.CreateNewShopKeeper(shopkeeperWithItemsViewModel); } - [HttpPost("removeShopkeeper")] + [HttpDelete("removeShopkeeper")] public async Task> RemoveShopkeeper([Required] int shopkeeperId, bool wasAvailable) { await this._service.Delete(shopkeeperId);