222 lines
8.4 KiB
Plaintext
222 lines
8.4 KiB
Plaintext
@page "/tenants/{Slug}"
|
|
@using EntKube.Web.Data
|
|
@using EntKube.Web.Services
|
|
@using Microsoft.EntityFrameworkCore
|
|
@rendermode InteractiveServer
|
|
@inject TenantService TenantService
|
|
@inject UserAccessService UserAccessService
|
|
@inject AuthenticationStateProvider AuthStateProvider
|
|
@inject NavigationManager Navigation
|
|
|
|
<PageTitle>@(tenant?.Name ?? "Tenant")</PageTitle>
|
|
|
|
@if (tenant is null)
|
|
{
|
|
<div class="text-center py-5">
|
|
<div class="spinner-border text-primary" role="status"></div>
|
|
<p class="text-muted mt-2">Loading tenant...</p>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<nav aria-label="breadcrumb" class="mb-3">
|
|
<ol class="breadcrumb small">
|
|
<li class="breadcrumb-item"><a href="/tenants" class="text-decoration-none"><i class="bi bi-building me-1"></i>Tenants</a></li>
|
|
<li class="breadcrumb-item active">@tenant.Name</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<div class="d-flex align-items-center mb-4">
|
|
<i class="bi bi-building fs-3 me-2 text-primary"></i>
|
|
<div>
|
|
<h2 class="mb-0">@tenant.Name</h2>
|
|
<small class="text-muted"><code>@tenant.Slug</code></small>
|
|
</div>
|
|
</div>
|
|
|
|
<ul class="nav nav-pills mb-4 gap-1">
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "environments" ? "active" : "")" @onclick='() => activeTab = "environments"'>
|
|
<i class="bi bi-layers me-1"></i>Environments
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "customers" ? "active" : "")" @onclick='() => activeTab = "customers"'>
|
|
<i class="bi bi-people me-1"></i>Customers
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "vault" ? "active" : "")" @onclick='() => activeTab = "vault"'>
|
|
<i class="bi bi-shield-lock me-1"></i>Vault
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "groups" ? "active" : "")" @onclick='() => activeTab = "groups"'>
|
|
<i class="bi bi-diagram-3 me-1"></i>Groups
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "databases" ? "active" : "")" @onclick='() => activeTab = "databases"'>
|
|
<i class="bi bi-database me-1"></i>Databases
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "storage" ? "active" : "")" @onclick='() => activeTab = "storage"'>
|
|
<i class="bi bi-bucket me-1"></i>Storage
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "identity" ? "active" : "")" @onclick='() => activeTab = "identity"'>
|
|
<i class="bi bi-person-badge me-1"></i>Identity
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "registry" ? "active" : "")" @onclick='() => activeTab = "registry"'>
|
|
<i class="bi bi-archive me-1"></i>Registry
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "messaging" ? "active" : "")" @onclick='() => activeTab = "messaging"'>
|
|
<i class="bi bi-collection me-1"></i>Messaging
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "cache" ? "active" : "")" @onclick='() => activeTab = "cache"'>
|
|
<i class="bi bi-lightning-charge me-1"></i>Cache
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "overview" ? "active" : "")" @onclick='() => activeTab = "overview"'>
|
|
<i class="bi bi-speedometer2 me-1"></i>Overview
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "incidents" ? "active" : "")" @onclick='() => activeTab = "incidents"'>
|
|
<i class="bi bi-bell-fill me-1"></i>Incidents
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "notifications" ? "active" : "")" @onclick='() => activeTab = "notifications"'>
|
|
<i class="bi bi-send-fill me-1"></i>Notifications
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "maintenance" ? "active" : "")" @onclick='() => activeTab = "maintenance"'>
|
|
<i class="bi bi-tools me-1"></i>Maintenance
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "sla" ? "active" : "")" @onclick='() => activeTab = "sla"'>
|
|
<i class="bi bi-shield-check me-1"></i>SLA
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "networking" ? "active" : "")" @onclick='() => activeTab = "networking"'>
|
|
<i class="bi bi-shield-lock me-1"></i>Networking
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link @(activeTab == "git" ? "active" : "")" @onclick='() => activeTab = "git"'>
|
|
<i class="bi bi-git me-1"></i>Git
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content">
|
|
@switch (activeTab)
|
|
{
|
|
case "environments":
|
|
<EnvironmentTab TenantId="tenant.Id" />
|
|
break;
|
|
case "customers":
|
|
<CustomerTab TenantId="tenant.Id" />
|
|
break;
|
|
case "vault":
|
|
<VaultTab TenantId="tenant.Id" />
|
|
break;
|
|
case "groups":
|
|
<GroupTab TenantId="tenant.Id" />
|
|
break;
|
|
case "databases":
|
|
<DatabaseTab TenantId="tenant.Id" />
|
|
break;
|
|
case "storage":
|
|
<StorageTab TenantId="tenant.Id" />
|
|
break;
|
|
case "identity":
|
|
<IdentityTab TenantId="tenant.Id" />
|
|
break;
|
|
case "registry":
|
|
<RegistryTab TenantId="tenant.Id" />
|
|
break;
|
|
case "messaging":
|
|
<MessagingTab TenantId="tenant.Id" />
|
|
break;
|
|
case "cache":
|
|
<CacheTab TenantId="tenant.Id" />
|
|
break;
|
|
case "overview":
|
|
<TenantMonitoringOverview TenantId="tenant.Id" TenantSlug="tenant.Slug" />
|
|
break;
|
|
case "incidents":
|
|
<IncidentManagement TenantId="tenant.Id" />
|
|
break;
|
|
case "notifications":
|
|
<NotificationChannels TenantId="tenant.Id" />
|
|
break;
|
|
case "maintenance":
|
|
<MaintenanceWindows TenantId="tenant.Id" />
|
|
break;
|
|
case "sla":
|
|
<SlaTargetManager TenantId="tenant.Id" />
|
|
break;
|
|
case "networking":
|
|
<NetworkingTab TenantId="tenant.Id" />
|
|
break;
|
|
case "git":
|
|
<GitReposTab TenantId="tenant.Id" />
|
|
break;
|
|
}
|
|
</div>
|
|
}
|
|
|
|
@code {
|
|
[Parameter] public string Slug { get; set; } = "";
|
|
|
|
private Tenant? tenant;
|
|
private string activeTab = "environments";
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
AuthenticationState authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
|
System.Security.Claims.ClaimsPrincipal user = authState.User;
|
|
|
|
if (user.Identity?.IsAuthenticated != true)
|
|
{
|
|
Navigation.NavigateTo("/Account/Login", forceLoad: true);
|
|
return;
|
|
}
|
|
|
|
string? userId = user.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
|
|
if (userId is null)
|
|
{
|
|
Navigation.NavigateTo("/Account/Login", forceLoad: true);
|
|
return;
|
|
}
|
|
|
|
tenant = await TenantService.GetTenantBySlugAsync(Slug);
|
|
|
|
if (tenant is null)
|
|
{
|
|
Navigation.NavigateTo("/tenants");
|
|
return;
|
|
}
|
|
|
|
bool canAccess = await UserAccessService.HasTenantAccessAsync(userId, tenant.Id);
|
|
if (!canAccess)
|
|
{
|
|
bool hasMembership = await UserAccessService.HasAnyTenantMembershipAsync(userId);
|
|
Navigation.NavigateTo(hasMembership ? "/tenants" : "/portal");
|
|
}
|
|
}
|
|
} |