feat: deduplicated player adding
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<main class="main">
|
||||
<app-screen-basic [players]="players"></app-screen-basic>
|
||||
<app-screen-edit [players]="players"></app-screen-edit>
|
||||
</main>
|
||||
|
||||
<router-outlet />
|
||||
|
||||
@@ -8,10 +8,11 @@ import { filter, take } from 'rxjs';
|
||||
import { ScreenBasicComponent } from "./screen-basic/screen-basic.component";
|
||||
import { ScreenRotationsComponent } from './screen-rotations/screen-rotations.component';
|
||||
import { Player } from './model';
|
||||
import { ScreenEditComponent } from './screen-edit/screen-edit.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
imports: [NgbModule, RouterOutlet, CommonModule, FormsModule, ScreenBasicComponent, ScreenRotationsComponent],
|
||||
imports: [NgbModule, RouterOutlet, CommonModule, FormsModule, ScreenBasicComponent, ScreenRotationsComponent, ScreenEditComponent],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.less'
|
||||
})
|
||||
|
||||
@@ -25,7 +25,18 @@ export class Player{
|
||||
const values = 'OOOO'
|
||||
return [this.name, values];
|
||||
}
|
||||
|
||||
valueOf(): string{
|
||||
return this.name;
|
||||
}
|
||||
static deSerialize(name: string, values: string): Player{
|
||||
return new Player(name);
|
||||
}
|
||||
static isNew(newplayer:Player, players: Player[]): boolean {
|
||||
const seen = new Set<string>(players.map(p => p.name));
|
||||
if (seen.has(newplayer.name)){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
30
src/app/screen-edit/screen-edit.component.html
Normal file
30
src/app/screen-edit/screen-edit.component.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="justify-content-md-center">
|
||||
<h1>Players: {{ players.length }}</h1>
|
||||
<div class="input-group mb-3">
|
||||
<input
|
||||
type="text"
|
||||
[(ngModel)]="newItem"
|
||||
class="form-control"
|
||||
placeholder="Enter a name..."
|
||||
(keyup.enter)="addItem()"
|
||||
/>
|
||||
<button class="btn btn-primary" type="button" (click)="addItem()" >
|
||||
<i class="bi bi-plus-lg"></i> Add
|
||||
</button>
|
||||
</div>
|
||||
@if (alertMessage) {
|
||||
<ngb-alert #selfClosingAlert type="danger" (closed)="alertMessage = ''">{{ alertMessage }}</ngb-alert>
|
||||
}
|
||||
<div class="container mt-4">
|
||||
<ul class="list-group mb-3">
|
||||
@for (player of players; track $index) {
|
||||
<li class="list-group-item">
|
||||
<a (click)="openPlayerModal(player)" style="display: block; cursor: pointer;">{{ player.name }}</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
0
src/app/screen-edit/screen-edit.component.less
Normal file
0
src/app/screen-edit/screen-edit.component.less
Normal file
23
src/app/screen-edit/screen-edit.component.spec.ts
Normal file
23
src/app/screen-edit/screen-edit.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ScreenEditComponent } from './screen-edit.component';
|
||||
|
||||
describe('ScreenEditComponent', () => {
|
||||
let component: ScreenEditComponent;
|
||||
let fixture: ComponentFixture<ScreenEditComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ScreenEditComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ScreenEditComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
63
src/app/screen-edit/screen-edit.component.ts
Normal file
63
src/app/screen-edit/screen-edit.component.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Component, Input, ViewChild } from '@angular/core';
|
||||
import { NgbAlert, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Player } from '../model';
|
||||
import { ModalRotationsComponent } from '../modal-rotations/modal-rotations.component';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Subject } from 'rxjs/internal/Subject';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { debounceTime, tap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-screen-edit',
|
||||
imports: [FormsModule, NgbAlert],
|
||||
templateUrl: './screen-edit.component.html',
|
||||
styleUrl: './screen-edit.component.less'
|
||||
})
|
||||
export class ScreenEditComponent {
|
||||
@Input() players!: Player[];
|
||||
@ViewChild('selfClosingAlert', { static: false })selfClosingAlert!: NgbAlert;
|
||||
private _message$ = new Subject<string>();
|
||||
newItem: string = "";
|
||||
alertMessage = '';
|
||||
|
||||
constructor(private modalService: NgbModal) {
|
||||
this._message$
|
||||
.pipe(
|
||||
takeUntilDestroyed(),
|
||||
tap((message) => (this.alertMessage = message)),
|
||||
debounceTime(5000),
|
||||
)
|
||||
.subscribe(() => this.selfClosingAlert?.close());
|
||||
}
|
||||
|
||||
addItem() {
|
||||
const name = this.newItem.trim()
|
||||
if (name) {
|
||||
let newPlayer = new Player(name);
|
||||
if (Player.isNew(newPlayer, this.players)){
|
||||
this.players.push(newPlayer);
|
||||
this.newItem = '';
|
||||
}
|
||||
else{
|
||||
this.setAlertMessage(newPlayer.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openPlayerModal(player: Player){
|
||||
const modalRef = this.modalService.open(ModalRotationsComponent);
|
||||
modalRef.componentInstance.player = player;
|
||||
/*
|
||||
modalRef.result.then((updatedPlayer) => {
|
||||
// Handle the updated player data if needed
|
||||
console.log('Player updated:', updatedPlayer);
|
||||
}).catch((error) => {
|
||||
console.log('Modal dismissed');
|
||||
});
|
||||
*/
|
||||
}
|
||||
public setAlertMessage(s: string) {
|
||||
this._message$.next(`"${s}" already exists. Please choose a unique name.`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +1 @@
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="container mt-4">
|
||||
<h2>Players</h2>
|
||||
<ul class="list-group mb-3">
|
||||
@for (player of players; track $index) {
|
||||
<li class="list-group-item">{{ player.name }}</li>
|
||||
<button class="btn btn-outline-primary" (click)="openPlayerModal(player)">
|
||||
<div>Edit Roles</div>
|
||||
</button>
|
||||
}
|
||||
</ul>
|
||||
<div class="input-group mb-3">
|
||||
<input
|
||||
type="text"
|
||||
[(ngModel)]="newItem"
|
||||
class="form-control"
|
||||
placeholder="Enter a name..."
|
||||
(keyup.enter)="addItem()"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-outline-secondary"
|
||||
type="button"
|
||||
(click)="addItem()"
|
||||
>
|
||||
<i class="bi bi-plus-lg"></i> Add
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p>rotations!</p>
|
||||
@@ -2,8 +2,6 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Player } from '../model';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ModalRotationsComponent } from '../modal-rotations/modal-rotations.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-screen-rotations',
|
||||
@@ -13,28 +11,4 @@ import { ModalRotationsComponent } from '../modal-rotations/modal-rotations.comp
|
||||
})
|
||||
export class ScreenRotationsComponent {
|
||||
@Input() players!: Player[];
|
||||
newItem: string = "";
|
||||
|
||||
constructor(private modalService: NgbModal) {}
|
||||
|
||||
addItem() {
|
||||
if (this.newItem.trim()) {
|
||||
this.players.push( new Player(this.newItem));
|
||||
this.newItem = "";
|
||||
}
|
||||
}
|
||||
|
||||
openPlayerModal(player: Player){
|
||||
const modalRef = this.modalService.open(ModalRotationsComponent);
|
||||
modalRef.componentInstance.player = player;
|
||||
/*
|
||||
modalRef.result.then((updatedPlayer) => {
|
||||
// Handle the updated player data if needed
|
||||
console.log('Player updated:', updatedPlayer);
|
||||
}).catch((error) => {
|
||||
console.log('Modal dismissed');
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user