@using EntKube.Web.Data @using EntKube.Web.Services @inject TenantService TenantService @* ═══════════════════════════════════════════════════════════════════ App Detail — app-level header + environment cards. All per-environment content (deployments, resources, governance, metrics, external access) is handled by AppEnvironmentDetail. ═══════════════════════════════════════════════════════════════════ *@ @if (selectedEnvironment is not null) { } else { @* --- Back button --- *@ @* --- App header --- *@

@App.Name

@CustomerName Created @App.CreatedAt.ToString("MMM d, yyyy")
@if (!confirmDelete) { }
@* --- Linked environments (clickable cards → per-env detail) --- *@
Environments
@if (showLinkPanel) {
Select which environments this app is deployed in.
@if (allEnvironments is not null && allEnvironments.Count == 0) { } else if (allEnvironments is not null) {
@foreach (Data.Environment env in allEnvironments) { bool isLinked = linkedEnvIds.Contains(env.Id);
@env.Name @if (isLinked) { Active }
}
}
} @if (linkedEnvironments is not null && linkedEnvironments.Count == 0) {
} else if (linkedEnvironments is not null) {
@foreach (Data.Environment env in linkedEnvironments) { int deployCount = deployCountByEnv.GetValueOrDefault(env.Id, 0);
@env.Name
@if (deployCount > 0) { @deployCount deployment@(deployCount == 1 ? "" : "s") } else { No deployments }
}
}
} @code { [Parameter] public required Data.App App { get; set; } [Parameter] public Guid TenantId { get; set; } [Parameter] public string CustomerName { get; set; } = ""; [Parameter] public EventCallback OnBack { get; set; } [Parameter] public EventCallback OnDeleted { get; set; } private bool confirmDelete; private bool deleting; private bool showLinkPanel; private List? allEnvironments; private List? linkedEnvironments; private HashSet linkedEnvIds = new(); private Dictionary deployCountByEnv = new(); private Data.Environment? selectedEnvironment; protected override async Task OnInitializedAsync() { await LoadEnvironments(); } private async Task DeleteApp() { deleting = true; await TenantService.DeleteAppAsync(App.Id); deleting = false; confirmDelete = false; await OnDeleted.InvokeAsync(); } private async Task LoadEnvironments() { allEnvironments = await TenantService.GetEnvironmentsAsync(TenantId); List apps = await TenantService.GetAppsAsync(App.CustomerId); Data.App? freshApp = apps.FirstOrDefault(a => a.Id == App.Id); linkedEnvIds = freshApp?.AppEnvironments.Select(ae => ae.EnvironmentId).ToHashSet() ?? new(); linkedEnvironments = allEnvironments.Where(e => linkedEnvIds.Contains(e.Id)).ToList(); deployCountByEnv = (freshApp?.Deployments ?? []) .GroupBy(d => d.EnvironmentId) .ToDictionary(g => g.Key, g => g.Count()); } private async Task ToggleEnvironment(Guid envId, bool currentlyLinked) { if (currentlyLinked) await TenantService.UnlinkAppFromEnvironmentAsync(App.Id, envId); else await TenantService.LinkAppToEnvironmentAsync(App.Id, envId); await LoadEnvironments(); } }