feat: deduplicated player adding
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<main class="main">
|
<main class="main">
|
||||||
<app-screen-basic [players]="players"></app-screen-basic>
|
<app-screen-edit [players]="players"></app-screen-edit>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<router-outlet />
|
<router-outlet />
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import { filter, take } from 'rxjs';
|
|||||||
import { ScreenBasicComponent } from "./screen-basic/screen-basic.component";
|
import { ScreenBasicComponent } from "./screen-basic/screen-basic.component";
|
||||||
import { ScreenRotationsComponent } from './screen-rotations/screen-rotations.component';
|
import { ScreenRotationsComponent } from './screen-rotations/screen-rotations.component';
|
||||||
import { Player } from './model';
|
import { Player } from './model';
|
||||||
|
import { ScreenEditComponent } from './screen-edit/screen-edit.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [NgbModule, RouterOutlet, CommonModule, FormsModule, ScreenBasicComponent, ScreenRotationsComponent],
|
imports: [NgbModule, RouterOutlet, CommonModule, FormsModule, ScreenBasicComponent, ScreenRotationsComponent, ScreenEditComponent],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.less'
|
styleUrl: './app.component.less'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -25,7 +25,18 @@ export class Player{
|
|||||||
const values = 'OOOO'
|
const values = 'OOOO'
|
||||||
return [this.name, values];
|
return [this.name, values];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
valueOf(): string{
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
static deSerialize(name: string, values: string): Player{
|
static deSerialize(name: string, values: string): Player{
|
||||||
return new Player(name);
|
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">
|
<p>rotations!</p>
|
||||||
<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>
|
|
||||||
@@ -2,8 +2,6 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { Player } from '../model';
|
import { Player } from '../model';
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
import { ModalRotationsComponent } from '../modal-rotations/modal-rotations.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-screen-rotations',
|
selector: 'app-screen-rotations',
|
||||||
@@ -13,28 +11,4 @@ import { ModalRotationsComponent } from '../modal-rotations/modal-rotations.comp
|
|||||||
})
|
})
|
||||||
export class ScreenRotationsComponent {
|
export class ScreenRotationsComponent {
|
||||||
@Input() players!: Player[];
|
@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