Visualize ItemSlotCharacteristics and add new ones
All checks were successful
E2E Testing / test (push) Successful in 1m42s

This commit is contained in:
Sebastian Böckelmann 2024-05-11 10:54:52 +02:00
parent 4eb428277d
commit 99454753a6
13 changed files with 236 additions and 12 deletions

View File

@ -94,6 +94,13 @@ import {
import {
InventorySlotEditorComponent
} from "./editor/character-editor/inventory-slot-editor/inventory-slot-editor.component";
import {
InventorySlotCharacteristicEditorComponent
} from "./editor/character-editor/inventory-slot-editor/inventory-slot-characteristic-editor/inventory-slot-characteristic-editor.component";
import {MatAutocomplete, MatAutocompleteTrigger} from "@angular/material/autocomplete";
import {
CharacteristicSelectorComponent
} from "./editor/character-editor/inventory-slot-editor/inventory-slot-characteristic-editor/characteristic-selector/characteristic-selector.component";
// AoT requires an exported function for factories
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@ -124,7 +131,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
ItemEditorComponent,
ItemgroupInheritorComponent,
InheritedItemCharacteristicEditorComponent,
InventorySlotEditorComponent
InventorySlotEditorComponent,
InventorySlotCharacteristicEditorComponent,
CharacteristicSelectorComponent
],
imports: [
BrowserModule,
@ -188,7 +197,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
MatExpansionPanelTitle,
MatCardTitle,
MatExpansionPanelHeader,
MatExpansionPanelDescription
MatExpansionPanelDescription,
MatAutocomplete,
MatAutocompleteTrigger
],
providers: [],
bootstrap: [AppComponent]

View File

@ -0,0 +1,12 @@
<mat-form-field class="example-full-width">
<mat-label>Number</mat-label>
<input matInput
aria-label="State"
[matAutocomplete]="auto"
[formControl]="myControl">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="onOptionSelected()">
@for (option of filteredOptions | async; track option) {
<mat-option [value]="option.characteristicName">{{option.characteristicName}}</mat-option>
}
</mat-autocomplete>
</mat-form-field>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CharacteristicSelectorComponent } from './characteristic-selector.component';
describe('CharacteristicSelectorComponent', () => {
let component: CharacteristicSelectorComponent;
let fixture: ComponentFixture<CharacteristicSelectorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CharacteristicSelectorComponent]
})
.compileComponents();
fixture = TestBed.createComponent(CharacteristicSelectorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,46 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {AsyncPipe} from "@angular/common";
import {FormControl, FormsModule} from "@angular/forms";
import {MatAutocomplete, MatOption} from "@angular/material/autocomplete";
import {MatFormField, MatLabel} from "@angular/material/form-field";
import {MatInput} from "@angular/material/input";
import {map, Observable, startWith} from "rxjs";
import {ItemGroupCharacteristic} from "../../../../../project/game-model/inventory/ItemgroupCharacteristic";
@Component({
selector: 'app-characteristic-selector',
templateUrl: './characteristic-selector.component.html',
styleUrl: './characteristic-selector.component.scss'
})
export class CharacteristicSelectorComponent implements OnInit{
myControl = new FormControl('');
@Input() options: ItemGroupCharacteristic[] = []
@Input() selectedInput: ItemGroupCharacteristic | undefined
filteredOptions: Observable<ItemGroupCharacteristic[]>;
@Output('onSelectOption') selectedOptionEmitter: EventEmitter<ItemGroupCharacteristic> = new EventEmitter<ItemGroupCharacteristic>();
constructor() {
this.filteredOptions = this.myControl.valueChanges.pipe(
startWith(''),
map(state => (state ? this._filterStates(state) : this.options.slice())),
);
}
ngOnInit() {
if(this.selectedInput != undefined) {
this.myControl.setValue(this.selectedInput.characteristicName);
}
}
private _filterStates(value: any): ItemGroupCharacteristic[] {
const filterValue = value.toLowerCase();
return this.options.filter(state => state.characteristicName.toLowerCase().includes(filterValue));
}
onOptionSelected() {
const selectedOption = this.options.find(characteristic => characteristic.characteristicName.toLowerCase() === this.myControl.value!.toLowerCase());
this.selectedOptionEmitter.emit(selectedOption!)
}
}

View File

@ -0,0 +1,44 @@
<table mat-table [dataSource]="datasource" class="mat-elevation-z8">
<ng-container matColumnDef="increasing">
<th mat-header-cell *matHeaderCellDef>Increasing Characteristic</th>
<td mat-cell *matCellDef="let slotCharacteristic">
<span *ngIf="editedCharacteristic !== slotCharacteristic">{{slotCharacteristic.increasingCharacteristic.characteristicName}}</span>
<app-characteristic-selector *ngIf="editedCharacteristic === slotCharacteristic"
[options]="availableCharacteristics"
[selectedInput]="slotCharacteristic.increasingCharacteristic"
(onSelectOption)="onSelectIncreasingCharacteristic($event, slotCharacteristic)">
</app-characteristic-selector>
</td>
</ng-container>
<ng-container matColumnDef="decreasing">
<th mat-header-cell *matHeaderCellDef>Decreasing Characteristic</th>
<td mat-cell *matCellDef="let slotCharacteristic">
<span *ngIf="editedCharacteristic !== slotCharacteristic">{{slotCharacteristic.increasingCharacteristic.characteristicName}}</span>
<app-characteristic-selector *ngIf="editedCharacteristic === slotCharacteristic"
[options]="availableCharacteristics"
[selectedInput]="slotCharacteristic.decreasingCharacteristic"
(onSelectOption)="onSelectDecreasingCharacteristic($event, slotCharacteristic)">
</app-characteristic-selector>
</td>
</ng-container>
<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let slotCharacteristic">
<button mat-icon-button (click)="finishEditing()" *ngIf="editedCharacteristic === slotCharacteristic"><mat-icon>done</mat-icon></button>
<button mat-icon-button *ngIf="editedCharacteristic !== slotCharacteristic" [disabled]="editedCharacteristic != null"><mat-icon>edit</mat-icon></button>
</td>
</ng-container>
<ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef>
<button mat-icon-button (click)="addInventorySlotCharacteristic()"><mat-icon>add</mat-icon></button>
</th>
<td mat-cell *matCellDef="let slotCharacteristic">
<button mat-icon-button color="warn"><mat-icon>delete</mat-icon></button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

View File

@ -0,0 +1,9 @@
.table {
width: 100%;
}
.mat-column-edit, .mat-column-delete {
width: 32px;
align-content: center;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { InventorySlotCharacteristicEditorComponent } from './inventory-slot-characteristic-editor.component';
describe('InventorySlotCharacteristicEditorComponent', () => {
let component: InventorySlotCharacteristicEditorComponent;
let fixture: ComponentFixture<InventorySlotCharacteristicEditorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [InventorySlotCharacteristicEditorComponent]
})
.compileComponents();
fixture = TestBed.createComponent(InventorySlotCharacteristicEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,51 @@
import {Component, Input, OnInit} from '@angular/core';
import {InventorySlot} from "../../../../project/game-model/inventory/intentory-slots/InventorySlot";
import {ItemGroupCharacteristic} from "../../../../project/game-model/inventory/ItemgroupCharacteristic";
import {ItemGroup} from "../../../../project/game-model/inventory/ItemGroup";
import {MatTable, MatTableDataSource} from "@angular/material/table";
import {
InventoryCharacteristic
} from "../../../../project/game-model/inventory/intentory-slots/InventoryCharacteristic";
@Component({
selector: 'app-inventory-slot-characteristic-editor',
templateUrl: './inventory-slot-characteristic-editor.component.html',
styleUrl: './inventory-slot-characteristic-editor.component.scss'
})
export class InventorySlotCharacteristicEditorComponent implements OnInit{
@Input() inventorySlot: InventorySlot | undefined
@Input() itemgroups: ItemGroup[] = []
availableCharacteristics: ItemGroupCharacteristic[] = []
datasource: MatTableDataSource<InventoryCharacteristic> = new MatTableDataSource<InventoryCharacteristic>();
displayedColumns: string[] = ['increasing', 'decreasing', 'edit', 'delete']
editedCharacteristic: InventoryCharacteristic | null = null;
ngOnInit() {
this.itemgroups.forEach(itemgroup => {
this.availableCharacteristics = this.availableCharacteristics.concat(itemgroup.itemGroupCharacteristics);
})
this.datasource.data = this.inventorySlot!.slotCharacteristics;
}
addInventorySlotCharacteristic() {
const slotCharacteristic = new InventoryCharacteristic(null, null);
this.inventorySlot!.addSlotCharacteristic(slotCharacteristic);
this.datasource.data = this.inventorySlot!.slotCharacteristics;
this.editedCharacteristic = slotCharacteristic;
}
finishEditing() {
this.editedCharacteristic = null;
}
onSelectIncreasingCharacteristic(selectedCharacteristic: ItemGroupCharacteristic, slotCharacteristic: InventoryCharacteristic) {
slotCharacteristic.increasingCharacteristic = selectedCharacteristic;
}
onSelectDecreasingCharacteristic(selectedCharacteristic: ItemGroupCharacteristic, slotCharacteristic: InventoryCharacteristic) {
slotCharacteristic.decreasingCharacteristic = selectedCharacteristic;
}
}

View File

@ -47,10 +47,7 @@
<div class="example-element-detail"
[@detailExpand]="element == expandedSlot ? 'expanded' : 'collapsed'">
<div class="example-element-description">
Something
</div>
<app-inventory-slot-characteristic-editor [inventorySlot]="element" [itemgroups]="itemgroups"></app-inventory-slot-characteristic-editor>
</div>
</td>
</ng-container>

View File

@ -27,7 +27,6 @@ tr.example-element-row:not(.example-expanded-row):active {
.example-element-detail {
overflow: hidden;
display: flex;
}
.example-element-diagram {

View File

@ -1,14 +1,16 @@
import {ItemGroupCharacteristic} from "../ItemgroupCharacteristic";
export class InventoryCharacteristic {
increasingCharacteristic: ItemGroupCharacteristic
decreasingCharacteristic: ItemGroupCharacteristic
increasingCharacteristic: ItemGroupCharacteristic | null
decreasingCharacteristic: ItemGroupCharacteristic | null
constructor(increasingCharacteristic: ItemGroupCharacteristic, decreasingCharacteristic: ItemGroupCharacteristic) {
constructor(increasingCharacteristic: ItemGroupCharacteristic | null, decreasingCharacteristic: ItemGroupCharacteristic | null) {
this.increasingCharacteristic = increasingCharacteristic;
this.decreasingCharacteristic = decreasingCharacteristic;
}
isValid() {
return this.increasingCharacteristic != null && this.decreasingCharacteristic != null;
}
}

View File

@ -3,6 +3,7 @@ import {InventoryCharacteristic} from "./InventoryCharacteristic";
import {ItemGroup} from "../ItemGroup";
export class InventorySlot {
slotName: string
slotCharacteristics: InventoryCharacteristic[] = []
requiredInheritances: ItemGroup[] = [] //if empty: non reqierements
@ -12,5 +13,11 @@ export class InventorySlot {
this.slotName = slotName;
}
addSlotCharacteristic(slotCharacteristic: InventoryCharacteristic) {
const found = this.slotCharacteristics.find(characteristiic => characteristiic.increasingCharacteristic === slotCharacteristic.increasingCharacteristic
&& characteristiic.decreasingCharacteristic === slotCharacteristic.decreasingCharacteristic)
if(found == undefined) {
this.slotCharacteristics.push(slotCharacteristic);
}
}
}