Separated CSS from Dashboard.razor by moving all dashboard-related styles into a new Dashboard.razor.css file. This improves maintainability and keeps styling concerns separate from markup and logic.
123 lines
4.2 KiB
Plaintext
123 lines
4.2 KiB
Plaintext
@page "/dashboard"
|
|
@page "/dashboards/{DashboardId?}"
|
|
@implements IAsyncDisposable
|
|
@inject Microsoft.Extensions.Configuration.IConfiguration Configuration
|
|
@inject NavigationManager Navigation
|
|
@inject DashboardApiClient DashboardApi
|
|
|
|
<PageTitle>Dashboards</PageTitle>
|
|
|
|
<div class="dashboard-shell">
|
|
<aside class="dashboard-nav">
|
|
<div class="dashboard-nav-title">Dashboards</div>
|
|
@if (dashboards.Count == 0)
|
|
{
|
|
<div class="px-3 py-2 text-muted">Keine Dashboards vorhanden.</div>
|
|
}
|
|
else
|
|
{
|
|
@foreach (var dashboard in dashboards)
|
|
{
|
|
<NavLink class="dashboard-nav-link" href="@($"dashboards/{dashboard.Id}?mode={(IsDesigner ? "designer" : "viewer")}")">@dashboard.Name</NavLink>
|
|
}
|
|
}
|
|
</aside>
|
|
<section class="dashboard-content">
|
|
<div class="mb-3">
|
|
<DxButton RenderStyle="ButtonRenderStyle.Primary" Click="@ToggleMode">
|
|
@(IsDesigner ? "Zum Viewer wechseln" : "Zum Designer wechseln")
|
|
</DxButton>
|
|
</div>
|
|
<DxDashboard @key="DashboardKey" Endpoint="@DashboardEndpoint" InitialDashboardId="@SelectedDashboardId" WorkingMode="@CurrentMode" style="width: 100%; height: 800px;">
|
|
</DxDashboard>
|
|
</section>
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter] public string? DashboardId { get; set; }
|
|
[SupplyParameterFromQuery] public string? Mode { get; set; }
|
|
|
|
private readonly List<DashboardInfoDto> dashboards = new();
|
|
private HubConnection? _hubConnection;
|
|
|
|
private bool IsDesigner => !string.Equals(Mode, "viewer", StringComparison.OrdinalIgnoreCase);
|
|
private WorkingMode CurrentMode => IsDesigner ? WorkingMode.Designer : WorkingMode.ViewerOnly;
|
|
private string SelectedDashboardId { get; set; } = string.Empty;
|
|
private string DashboardKey => $"{SelectedDashboardId}-{(IsDesigner ? "designer" : "viewer")}";
|
|
|
|
private string DashboardEndpoint => $"{Configuration["ApiBaseUrl"]?.TrimEnd('/')}/api/dashboard";
|
|
private string HubEndpoint => $"{Configuration["ApiBaseUrl"]?.TrimEnd('/')}/hubs/dashboards";
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await RefreshDashboards();
|
|
|
|
_hubConnection = new HubConnectionBuilder()
|
|
.WithUrl(HubEndpoint)
|
|
.WithAutomaticReconnect()
|
|
.Build();
|
|
|
|
_hubConnection.On("DashboardsChanged", async () =>
|
|
{
|
|
await RefreshDashboards();
|
|
});
|
|
|
|
await _hubConnection.StartAsync();
|
|
}
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
if (dashboards.Count == 0)
|
|
{
|
|
await RefreshDashboards();
|
|
}
|
|
|
|
var requestedId = string.IsNullOrWhiteSpace(DashboardId) || string.Equals(DashboardId, "default", StringComparison.OrdinalIgnoreCase)
|
|
? null
|
|
: DashboardId;
|
|
|
|
var resolved = !string.IsNullOrWhiteSpace(requestedId)
|
|
? dashboards.FirstOrDefault(d => string.Equals(d.Id, requestedId, StringComparison.OrdinalIgnoreCase))
|
|
: dashboards.FirstOrDefault(d => string.Equals(d.Id, "DefaultDashboard", StringComparison.OrdinalIgnoreCase))
|
|
?? dashboards.FirstOrDefault();
|
|
|
|
if (resolved == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SelectedDashboardId = resolved.Id;
|
|
|
|
if (!string.Equals(DashboardId, resolved.Id, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Navigation.NavigateTo($"dashboards/{resolved.Id}?mode={(IsDesigner ? "designer" : "viewer")}", replace: true);
|
|
}
|
|
}
|
|
|
|
private void ToggleMode()
|
|
{
|
|
var targetMode = IsDesigner ? "viewer" : "designer";
|
|
Navigation.NavigateTo($"dashboards/{SelectedDashboardId}?mode={targetMode}", replace: true);
|
|
}
|
|
|
|
private async Task RefreshDashboards()
|
|
{
|
|
var latest = await DashboardApi.GetAllAsync();
|
|
if (latest.Count == dashboards.Count && latest.All(d => dashboards.Any(x => x.Id == d.Id && x.Name == d.Name)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
dashboards.Clear();
|
|
dashboards.AddRange(latest);
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
if (_hubConnection != null)
|
|
{
|
|
await _hubConnection.DisposeAsync();
|
|
}
|
|
}
|
|
} |