Skip to content

Commit 7de19b7

Browse files
feat: Enhance DashboardController to fetch game server data concurrently and enrich telemetry information
1 parent 1072218 commit 7de19b7

3 files changed

Lines changed: 54 additions & 4 deletions

File tree

src/XtremeIdiots.Portal.Web/Controllers/DashboardController.cs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.AspNetCore.Authorization;
33
using Microsoft.AspNetCore.Mvc;
44

5+
using XtremeIdiots.Portal.Repository.Abstractions.Constants.V1;
56
using XtremeIdiots.Portal.Repository.Api.Client.V1;
67
using XtremeIdiots.Portal.Web.Auth.Constants;
78
using XtremeIdiots.Portal.Web.Extensions;
@@ -70,7 +71,43 @@ public async Task<IActionResult> Index(CancellationToken cancellationToken = def
7071
// Agent telemetry (non-critical — dashboard renders without it)
7172
try
7273
{
73-
viewModel.AgentStatuses = await agentTelemetryService.GetAllServersStatusAsync(cancellationToken).ConfigureAwait(false);
74+
var telemetryTask = agentTelemetryService.GetAllServersStatusAsync(cancellationToken);
75+
var gameServersTask = repositoryApiClient.GameServers.V1.GetGameServers(
76+
null, null, GameServerFilter.AgentEnabled, 0, 100,
77+
GameServerOrder.BannerServerListPosition, cancellationToken);
78+
79+
await Task.WhenAll(telemetryTask, gameServersTask).ConfigureAwait(false);
80+
81+
var telemetry = await telemetryTask.ConfigureAwait(false);
82+
var gameServersResponse = await gameServersTask.ConfigureAwait(false);
83+
84+
var serverLookup = gameServersResponse.IsSuccess && gameServersResponse.Result?.Data?.Items is not null
85+
? gameServersResponse.Result.Data.Items
86+
.GroupBy(gs => gs.GameServerId)
87+
.ToDictionary(g => g.Key, g => g.First())
88+
: [];
89+
90+
// Enrich telemetry with server names from the repository API
91+
var telemetryByServer = telemetry
92+
.GroupBy(t => t.ServerId)
93+
.ToDictionary(g => g.Key, g => g.First());
94+
viewModel.AgentStatuses = serverLookup.Values.Select(gs =>
95+
{
96+
telemetryByServer.TryGetValue(gs.GameServerId, out var summary);
97+
98+
return new AgentServerSummary
99+
{
100+
ServerId = gs.GameServerId,
101+
ServerTitle = string.IsNullOrWhiteSpace(gs.LiveTitle) ? gs.Title : gs.LiveTitle,
102+
GameType = gs.GameType.ToString(),
103+
LastEventReceived = summary?.LastEventReceived,
104+
EventsLastHour = summary?.EventsLastHour ?? 0,
105+
PlayerCount = summary?.PlayerCount ?? 0,
106+
CurrentMap = summary?.CurrentMap ?? gs.LiveMap,
107+
IsAgentActive = summary?.IsAgentActive ?? false,
108+
ActivityStatus = summary?.ActivityStatus ?? AgentActivityStatus.Offline
109+
};
110+
}).ToList();
74111
}
75112
catch (Exception ex)
76113
{

src/XtremeIdiots.Portal.Web/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@
135135

136136
builder.Services.AddCors(options =>
137137
{
138-
var corsOrigin = GetConfigValue(builder.Configuration, "XtremeIdiots:Forums:BaseUrl", "XtremeIdiots:Forums:BaseUrl configuration is required");
138+
var corsBaseUrl = GetConfigValue(builder.Configuration, "XtremeIdiots:Forums:BaseUrl", "XtremeIdiots:Forums:BaseUrl configuration is required");
139+
if (!Uri.TryCreate(corsBaseUrl, UriKind.Absolute, out var corsUri))
140+
throw new InvalidOperationException($"XtremeIdiots:Forums:BaseUrl value '{corsBaseUrl}' is not a valid absolute URI for CORS origin configuration");
141+
var corsOrigin = corsUri.GetLeftPart(UriPartial.Authority);
139142
options.AddPolicy("CorsPolicy",
140143
policy => policy
141144
.WithOrigins(corsOrigin)

src/XtremeIdiots.Portal.Web/wwwroot/js/forum-widget.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@
4141

4242
function ago(dateStr) {
4343
if (!dateStr) return '';
44-
return portalDate.formatRelativeTime(dateStr);
44+
var diff = (Date.now() - new Date(dateStr).getTime()) / 1000;
45+
if (diff < 60) return 'just now';
46+
if (diff < 3600) return Math.floor(diff / 60) + 'm ago';
47+
if (diff < 86400) return Math.floor(diff / 3600) + 'h ago';
48+
if (diff < 604800) return Math.floor(diff / 86400) + 'd ago';
49+
return new Date(dateStr).toLocaleDateString();
4550
}
4651

4752
function getActionIcon(actionType) {
@@ -279,7 +284,12 @@
279284
container.innerHTML = '<div class="xi-pw-error">Unable to load notifications</div>';
280285
return;
281286
}
282-
renderWidget(container, data);
287+
try {
288+
renderWidget(container, data);
289+
} catch (e) {
290+
console.error('Forum widget render error:', e);
291+
container.innerHTML = '<div class="xi-pw-error">Unable to display notifications</div>';
292+
}
283293
});
284294
}
285295

0 commit comments

Comments
 (0)