Files
NowChess-Frontend/src/app/pages/bots/bots.component.ts
T
Janis Eccarius 8e2afb93f3 feat: NCWF-5/6/7/8/9 chess analysis page and engine integration
- NCWF-5: scaffold /analysis route with ChessBoard viewer and navigation
- NCWF-6: FEN / PGN / Game-ID input form with depth selector
- NCWF-7: extend GameApiService with analyzePosition(); add AnalysisService
  with game-wide annotation pipeline; proxy /api/analysis -> :8087
- NCWF-8: EvalTimelineComponent — SVG win-chance chart per ply
- NCWF-9: AnnotatedMoveListComponent — quality labels (!! ! ?! ? ??)
  derived from win-chance delta

Also fix pre-existing app.spec.ts failure (missing provideHttpClient).
Apply project-wide prettier formatting pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:55:14 +02:00

124 lines
3.1 KiB
TypeScript

import { Component, DestroyRef, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { BotService } from '../../services/bot.service';
import { Bot, BotWithToken } from '../../models/bot.models';
@Component({
selector: 'app-bots',
standalone: true,
imports: [CommonModule, RouterLink, FormsModule],
templateUrl: './bots.component.html',
styleUrl: './bots.component.css',
})
export class BotsComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
private readonly botService = inject(BotService);
bots: Bot[] = [];
loading = true;
showCreate = false;
newBotName = '';
creating = false;
createError: string | null = null;
revealedTokens: Record<string, string> = {};
revealingId: string | null = null;
copiedId: string | null = null;
deletingId: string | null = null;
ngOnInit(): void {
this.loadBots();
}
loadBots(): void {
this.loading = true;
this.botService
.list()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe({
next: (bots) => {
this.bots = bots;
this.loading = false;
},
error: () => {
this.loading = false;
},
});
}
openCreate(): void {
this.newBotName = '';
this.createError = null;
this.showCreate = true;
}
cancelCreate(): void {
this.showCreate = false;
}
submitCreate(): void {
const name = this.newBotName.trim();
if (!name) return;
this.creating = true;
this.createError = null;
this.botService.create(name).subscribe({
next: (bot: BotWithToken) => {
this.creating = false;
this.showCreate = false;
this.bots = [bot, ...this.bots];
this.revealedTokens[bot.id] = bot.token;
},
error: (err) => {
this.creating = false;
this.createError = err.error?.message ?? err.error?.error ?? 'Failed to create bot.';
},
});
}
revealToken(botId: string): void {
if (this.revealedTokens[botId]) {
delete this.revealedTokens[botId];
return;
}
this.revealingId = botId;
this.botService.rotateToken(botId).subscribe({
next: (token) => {
this.revealingId = null;
this.revealedTokens[botId] = token;
},
error: () => {
this.revealingId = null;
},
});
}
copyToken(botId: string): void {
const token = this.revealedTokens[botId];
if (!token) return;
navigator.clipboard.writeText(token).then(() => {
this.copiedId = botId;
setTimeout(() => {
this.copiedId = null;
}, 2000);
});
}
deleteBot(botId: string): void {
this.deletingId = botId;
this.botService.delete(botId).subscribe({
next: () => {
this.deletingId = null;
this.bots = this.bots.filter((b) => b.id !== botId);
delete this.revealedTokens[botId];
},
error: () => {
this.deletingId = null;
},
});
}
}