class GamesTable {
constructor(gamesBodyEl, battlesnakeUrl, onGameClick) {
this._el = gamesBodyEl;
this._battlesnakeUrl = battlesnakeUrl;
this._onGameClick = onGameClick;
}
render(games, activeGameId) {
this._el.innerHTML = games.map((g) => `
${GamesTable._shortId(g.game_id)} ${Utils.safeString(GamesTable._displayGameTypeOrMap(g))} |
${Utils.toTitle(g.status)} |
${g.status === "running" ? "-" : g.winner_you ? "Win" : "Loss"} |
${Utils.safeString(g.final_turn)} |
`).join("");
for (const row of this._el.querySelectorAll("tr")) {
row.addEventListener("click", (event) => {
event.preventDefault();
const gameId = row.getAttribute("data-game-id");
if (gameId) this._onGameClick(gameId);
});
}
if (activeGameId) this.setActive(activeGameId);
}
setActive(gameId) {
this._clearActive();
const active = this._el.querySelector(`tr[data-game-id="${gameId}"]`);
if (active) active.classList.add("active");
}
_clearActive() {
for (const row of this._el.querySelectorAll("tr")) {
row.classList.remove("active");
}
}
static _shortId(gameId) {
return String(gameId || "-").slice(0, 8);
}
static _displayGameTypeOrMap(game) {
const mapName = String((game && game.map) || "").trim();
const gameType = String((game && game.game_type) || "").trim();
if (gameType.toLowerCase() === "duel" && mapName.toLowerCase() === "standard") return "duel";
if (mapName && mapName.toLowerCase() !== "empty") return mapName;
return gameType || "-";
}
}