Skip to content

Commit 4a5b7d8

Browse files
feat: Add health status indicators for maps in Manage Maps view to enhance visibility of issues
1 parent 8119ccc commit 4a5b7d8

1 file changed

Lines changed: 103 additions & 10 deletions

File tree

src/XtremeIdiots.Portal.Web/Views/MapManager/Manage.cshtml

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@
6060
</ul>
6161

6262
<div class="tab-content pt-3">
63+
@{
64+
var mapsById = Model.Maps.ToDictionary(m => m.MapId);
65+
var mapsByName = Model.Maps.ToDictionary(m => m.MapName, StringComparer.OrdinalIgnoreCase);
66+
var serverMapNames = Model.ServerMaps.Select(m => m.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
67+
var serverMapsByName = Model.ServerMaps.ToDictionary(m => m.Name, StringComparer.OrdinalIgnoreCase);
68+
}
6369

6470
@* Tab 1: Current Rotation *@
6571
<div class="tab-pane fade show active" id="rotation-tab" role="tabpanel" aria-labelledby="rotation-tab-btn">
@@ -80,6 +86,35 @@
8086
· @(Model.ActiveRotation.MapRotationMaps?.Count ?? 0) maps · Version @Model.ActiveRotation.Version
8187
</small>
8288
</div>
89+
@{
90+
var rotMapsForHealth = Model.ActiveRotation.MapRotationMaps ?? [];
91+
var missingFromHost = rotMapsForHealth.Count(rm =>
92+
{
93+
var mapName = mapsById.TryGetValue(rm.MapId, out var m) ? m.MapName : null;
94+
return mapName != null && !serverMapNames.Contains(mapName);
95+
});
96+
var problematicCount = rotMapsForHealth.Count(rm => mapsById.TryGetValue(rm.MapId, out var m) && m.MapStatus == MapHealthStatus.Problematic);
97+
var blacklistedCount = rotMapsForHealth.Count(rm => mapsById.TryGetValue(rm.MapId, out var m) && m.MapStatus == MapHealthStatus.Blacklisted);
98+
}
99+
@if (missingFromHost > 0 || problematicCount > 0 || blacklistedCount > 0)
100+
{
101+
<div class="alert alert-warning py-2 mb-3">
102+
<i class="fa-solid fa-triangle-exclamation me-1"></i>
103+
<strong>Health warnings:</strong>
104+
@if (missingFromHost > 0)
105+
{
106+
<span class="ms-2"><span class="badge bg-danger"><i class="fa-solid fa-cloud-arrow-up"></i> @missingFromHost Not On Host</span></span>
107+
}
108+
@if (blacklistedCount > 0)
109+
{
110+
<span class="ms-2"><span class="badge bg-danger"><i class="fa-solid fa-ban"></i> @blacklistedCount Blacklisted</span></span>
111+
}
112+
@if (problematicCount > 0)
113+
{
114+
<span class="ms-2"><span class="badge bg-warning text-dark"><i class="fa-solid fa-triangle-exclamation"></i> @problematicCount Problematic</span></span>
115+
}
116+
</div>
117+
}
83118
<div class="table-responsive">
84119
<table id="mapRotationTable" class="table table-striped table-hover w-100">
85120
<thead>
@@ -96,20 +131,30 @@
96131
@for (var i = 0; i < sortedRotMaps.Count; i++)
97132
{
98133
var rotMap = sortedRotMaps[i];
99-
var map = Model.Maps.FirstOrDefault(m => m.MapId == rotMap.MapId);
134+
mapsById.TryGetValue(rotMap.MapId, out var map);
100135
var mapName = map?.MapName ?? rotMap.MapId.ToString();
101-
var remoteMatch = Model.ServerMaps.FirstOrDefault(x => string.Equals(x.Name, mapName, StringComparison.OrdinalIgnoreCase));
136+
var remoteMatch = serverMapsByName.ContainsKey(mapName);
102137
<tr>
103138
<td><small class="text-muted">@(i + 1)</small></td>
104-
<td>@mapName</td>
105139
<td>
106-
@if (remoteMatch != null)
140+
@mapName
141+
@if (map?.MapStatus == MapHealthStatus.Blacklisted)
142+
{
143+
<span class="badge bg-danger ms-1" title="This map is blacklisted"><i class="fa-solid fa-ban"></i> Blacklisted</span>
144+
}
145+
else if (map?.MapStatus == MapHealthStatus.Problematic)
146+
{
147+
<span class="badge bg-warning text-dark ms-1" title="This map has known issues"><i class="fa-solid fa-triangle-exclamation"></i> Problematic</span>
148+
}
149+
</td>
150+
<td>
151+
@if (remoteMatch)
107152
{
108153
<span class="badge bg-success">On Host</span>
109154
}
110155
else
111156
{
112-
<span class="badge bg-danger">Not On Host</span>
157+
<span class="badge bg-danger"><i class="fa-solid fa-cloud-arrow-up"></i> Not On Host</span>
113158
}
114159
</td>
115160
<td>
@@ -149,18 +194,28 @@
149194
<tbody>
150195
@foreach (var item in Model.RconMaps.OrderBy(x => x.MapName))
151196
{
152-
var map = Model.Maps.FirstOrDefault(x => x.MapName == item.MapName);
153-
var remoteMatch = Model.ServerMaps.FirstOrDefault(x => x.Name == item.MapName);
197+
mapsByName.TryGetValue(item.MapName, out var map);
198+
var remoteMatch = serverMapsByName.ContainsKey(item.MapName);
154199
<tr>
155-
<td>@item.MapName</td>
156200
<td>
157-
@if (remoteMatch != null)
201+
@item.MapName
202+
@if (map?.MapStatus == MapHealthStatus.Blacklisted)
203+
{
204+
<span class="badge bg-danger ms-1" title="This map is blacklisted"><i class="fa-solid fa-ban"></i> Blacklisted</span>
205+
}
206+
else if (map?.MapStatus == MapHealthStatus.Problematic)
207+
{
208+
<span class="badge bg-warning text-dark ms-1" title="This map has known issues"><i class="fa-solid fa-triangle-exclamation"></i> Problematic</span>
209+
}
210+
</td>
211+
<td>
212+
@if (remoteMatch)
158213
{
159214
<span class="badge bg-success">On Host</span>
160215
}
161216
else
162217
{
163-
<span class="badge bg-danger">Not On Host</span>
218+
<span class="badge bg-danger"><i class="fa-solid fa-cloud-arrow-up"></i> Not On Host</span>
164219
}
165220
</td>
166221
<td>
@@ -204,13 +259,15 @@
204259
<th>Name</th>
205260
<th>Path</th>
206261
<th style="width: 110px;">Rotation Status</th>
262+
<th style="width: 100px;">Health</th>
207263
<th style="width: 120px;">Modified</th>
208264
<th style="width: 60px;"></th>
209265
</tr>
210266
</thead>
211267
<tbody>
212268
@foreach (var item in Model.ServerMaps)
213269
{
270+
mapsByName.TryGetValue(item.Name, out var portalMap);
214271
<tr>
215272
<td>@item.Name</td>
216273
<td><small class="text-muted">@item.FullName</small></td>
@@ -228,6 +285,20 @@
228285
}
229286
}
230287
</td>
288+
<td>
289+
@if (portalMap?.MapStatus == MapHealthStatus.Blacklisted)
290+
{
291+
<span class="badge bg-danger" title="This map is blacklisted"><i class="fa-solid fa-ban"></i> Blacklisted</span>
292+
}
293+
else if (portalMap?.MapStatus == MapHealthStatus.Problematic)
294+
{
295+
<span class="badge bg-warning text-dark" title="This map has known issues"><i class="fa-solid fa-triangle-exclamation"></i> Problematic</span>
296+
}
297+
else
298+
{
299+
<span class="badge bg-light text-muted">OK</span>
300+
}
301+
</td>
231302
<td><small>@item.Modified.ToString("yyyy-MM-dd")</small></td>
232303
<td>
233304
<partial name="DeleteMapFromHostPartial" model="@(new DeleteMapFromHostModel(Model.GameServer.GameServerId, item.Name))"></partial>
@@ -270,6 +341,7 @@
270341
<tr>
271342
<th>Rotation</th>
272343
<th style="width: 80px;">Mode</th>
344+
<th style="width: 80px;">Health</th>
273345
<th style="width: 90px;">Deploy</th>
274346
<th style="width: 90px;">Active</th>
275347
<th style="width: 80px;"></th>
@@ -294,6 +366,27 @@
294366
</small>
295367
</td>
296368
<td><span class="badge bg-info">@(rotation?.GameMode ?? "")</span></td>
369+
<td>
370+
@{
371+
var rotMaps = rotation?.MapRotationMaps ?? [];
372+
var healthIssues = rotMaps.Count(rm => mapsById.TryGetValue(rm.MapId, out var m) && m.MapStatus != MapHealthStatus.OK);
373+
var notOnHost = rotMaps.Count(rm => {
374+
var mapName = mapsById.TryGetValue(rm.MapId, out var m) ? m.MapName : null;
375+
return mapName != null && !serverMapNames.Contains(mapName);
376+
});
377+
var totalWarnings = healthIssues + notOnHost;
378+
}
379+
@if (totalWarnings > 0)
380+
{
381+
<span class="badge bg-warning text-dark" title="@healthIssues health issue(s), @notOnHost not on host">
382+
<i class="fa-solid fa-triangle-exclamation"></i> @totalWarnings
383+
</span>
384+
}
385+
else
386+
{
387+
<span class="badge bg-light text-muted">OK</span>
388+
}
389+
</td>
297390
<td>
298391
@switch (assignment.DeploymentState)
299392
{

0 commit comments

Comments
 (0)