UI refactor (structure cleanup)
Some checks failed
Build Docker Images / test (map[name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Failing after 1m18s
Build Docker Images / test (map[name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Failing after 1m18s
Build Docker Images / build-and-push (map[image_suffix:morska name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Failing after 1m38s
Build Docker Images / build-and-push (map[image_suffix:pedrollopl name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Failing after 1m37s
Some checks failed
Build Docker Images / test (map[name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Failing after 1m18s
Build Docker Images / test (map[name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Failing after 1m18s
Build Docker Images / build-and-push (map[image_suffix:morska name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Failing after 1m38s
Build Docker Images / build-and-push (map[image_suffix:pedrollopl name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Failing after 1m37s
This commit is contained in:
@@ -1,42 +0,0 @@
|
||||
@page "/dashboard"
|
||||
@using DiunaBI.UI.Shared.Services
|
||||
@using MudBlazor
|
||||
@inject AuthService AuthService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@if (AuthService.IsAuthenticated && AuthService.CurrentUser != null)
|
||||
{
|
||||
<MudCard Class="mt-4" Elevation="2">
|
||||
<MudCardHeader>
|
||||
<CardHeaderAvatar>
|
||||
@if (!string.IsNullOrEmpty(AuthService.CurrentUser.AvatarUrl))
|
||||
{
|
||||
<MudAvatar Size="Size.Large" Style="background: transparent;">
|
||||
<img src="@AuthService.CurrentUser.AvatarUrl" alt="Avatar" style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%;" />
|
||||
</MudAvatar>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudAvatar Color="Color.Primary" Size="Size.Large">
|
||||
@(AuthService.CurrentUser.FullName.Length > 0 ? AuthService.CurrentUser.FullName.Substring(0, 1) : "?")
|
||||
</MudAvatar>
|
||||
}
|
||||
</CardHeaderAvatar>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h6">@AuthService.CurrentUser.FullName</MudText>
|
||||
<MudText Typo="Typo.body2">@AuthService.CurrentUser.Email</MudText>
|
||||
</CardHeaderContent>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Typo="Typo.body2">
|
||||
✅ Signed in via Google
|
||||
</MudText>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudAlert Severity="Severity.Warning" Class="mt-4">
|
||||
You are not logged in
|
||||
</MudAlert>
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
@using MudBlazor.Internal
|
||||
<MudExpansionPanels Class="mb-4">
|
||||
<MudExpansionPanel Icon="@Icons.Material.Filled.FilterList"
|
||||
Text="Filters"
|
||||
Expanded="true">
|
||||
<MudGrid AlignItems="Center">
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
<MudTextField @bind-Value="filterRequest.Search"
|
||||
Label="Search"
|
||||
Placeholder="Name, source..."
|
||||
Immediate="true"
|
||||
DebounceInterval="500"
|
||||
OnDebounceIntervalElapsed="SearchDataInbox"
|
||||
Clearable="true"/>
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" sm="12" md="4" Class="d-flex justify-end">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Clear"
|
||||
OnClick="ClearFilters"
|
||||
Color="Color.Default"
|
||||
Size="Size.Medium"
|
||||
Title="Clear filters"/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudExpansionPanel>
|
||||
</MudExpansionPanels>
|
||||
|
||||
<MudDivider Class="my-4"></MudDivider>
|
||||
|
||||
<MudTable Items="dataInbox.Items"
|
||||
Dense="true"
|
||||
Hover="true"
|
||||
Loading="isLoading"
|
||||
LoadingProgressColor="Color.Primary"
|
||||
OnRowClick="@((TableRowClickEventArgs<DataInboxDto> args) => OnRowClick(args.Item))"
|
||||
T="DataInboxDto"
|
||||
Style="cursor: pointer;">
|
||||
<HeaderContent>
|
||||
<MudTh>Name</MudTh>
|
||||
<MudTh>Source</MudTh>
|
||||
<MudTh>Created At</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate Context="row">
|
||||
<MudTd DataLabel="Name"><div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">@row.Name</div></MudTd>
|
||||
<MudTd DataLabel="Source"><div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">@row.Source</div></MudTd>
|
||||
<MudTd DataLabel="Created At"><div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">@row.CreatedAt.ToString("yyyy-MM-dd HH:mm:ss")</div></MudTd>
|
||||
</RowTemplate>
|
||||
<NoRecordsContent>
|
||||
<MudText>No data inbox items to display</MudText>
|
||||
</NoRecordsContent>
|
||||
<LoadingContent>
|
||||
Loading...
|
||||
</LoadingContent>
|
||||
</MudTable>
|
||||
|
||||
@if (dataInbox.TotalCount > 0)
|
||||
{
|
||||
<MudGrid Class="mt-4" AlignItems="Center.Center">
|
||||
<MudItem xs="12" sm="6">
|
||||
<MudText Typo="Typo.body2">
|
||||
Results @((dataInbox.Page - 1) * dataInbox.PageSize + 1) - @Math.Min(dataInbox.Page * dataInbox.PageSize, dataInbox.TotalCount)
|
||||
of @dataInbox.TotalCount
|
||||
</MudText>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" Class="d-flex justify-end">
|
||||
<MudPagination Count="dataInbox.TotalPages"
|
||||
Selected="dataInbox.Page"
|
||||
SelectedChanged="OnPageChanged"
|
||||
ShowFirstButton="true"
|
||||
ShowLastButton="true"
|
||||
Variant="Variant.Outlined"
|
||||
/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
using DiunaBI.UI.Shared.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using DiunaBI.Application.DTOModels;
|
||||
using DiunaBI.Application.DTOModels.Common;
|
||||
using MudBlazor;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Components;
|
||||
|
||||
public partial class DataInboxListComponent : ComponentBase
|
||||
{
|
||||
[Inject] private DataInboxService DataInboxService { get; set; } = default!;
|
||||
[Inject] private ISnackbar Snackbar { get; set; } = default!;
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] private DataInboxFilterStateService FilterStateService { get; set; } = default!;
|
||||
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
|
||||
|
||||
|
||||
private PagedResult<DataInboxDto> dataInbox = new();
|
||||
private DataInboxFilterRequest filterRequest = new();
|
||||
private bool isLoading = false;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
filterRequest = FilterStateService.FilterRequest;
|
||||
await LoadDataInbox();
|
||||
}
|
||||
|
||||
private async Task LoadDataInbox()
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
try
|
||||
{
|
||||
FilterStateService.UpdateFilter(filterRequest);
|
||||
dataInbox = await DataInboxService.GetDataInboxAsync(filterRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Loading data inbox failed: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SearchDataInbox()
|
||||
{
|
||||
filterRequest.Page = 1;
|
||||
await LoadDataInbox();
|
||||
}
|
||||
|
||||
private async Task OnPageChanged(int page)
|
||||
{
|
||||
filterRequest.Page = page;
|
||||
await LoadDataInbox();
|
||||
}
|
||||
|
||||
private async Task ClearFilters()
|
||||
{
|
||||
filterRequest = new DataInboxFilterRequest();
|
||||
FilterStateService.ClearFilter();
|
||||
await LoadDataInbox();
|
||||
}
|
||||
|
||||
private void OnRowClick(DataInboxDto dataInboxItem)
|
||||
{
|
||||
NavigationManager.NavigateTo($"/datainbox/{dataInboxItem.Id}");
|
||||
}
|
||||
|
||||
private async Task OnRowRightClick(MouseEventArgs e, DataInboxDto dataInboxItem)
|
||||
{
|
||||
var url = NavigationManager.ToAbsoluteUri($"/datainbox/{dataInboxItem.Id}").ToString();
|
||||
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
@page "/"
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@code
|
||||
{
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
Navigation.NavigateTo("/dashboard");
|
||||
}
|
||||
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
@using MudBlazor.Internal
|
||||
@using DiunaBI.Domain.Entities
|
||||
<MudExpansionPanels Class="mb-4">
|
||||
<MudExpansionPanel Icon="@Icons.Material.Filled.FilterList"
|
||||
Text="Filters"
|
||||
Expanded="true">
|
||||
<MudGrid AlignItems="Center">
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudSelect T="JobStatus?"
|
||||
@bind-Value="selectedStatus"
|
||||
Label="Status"
|
||||
Placeholder="All statuses"
|
||||
Clearable="true"
|
||||
OnClearButtonClick="OnStatusClear">
|
||||
@foreach (JobStatus status in Enum.GetValues(typeof(JobStatus)))
|
||||
{
|
||||
<MudSelectItem T="JobStatus?" Value="@status">@status.ToString()</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudSelect T="JobType?"
|
||||
@bind-Value="selectedJobType"
|
||||
Label="Job Type"
|
||||
Placeholder="All types"
|
||||
Clearable="true"
|
||||
OnClearButtonClick="OnJobTypeClear">
|
||||
@foreach (JobType type in Enum.GetValues(typeof(JobType)))
|
||||
{
|
||||
<MudSelectItem T="JobType?" Value="@type">@type.ToString()</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" sm="12" md="6" Class="d-flex justify-end align-center">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Refresh"
|
||||
OnClick="LoadJobs"
|
||||
Color="Color.Primary"
|
||||
Size="Size.Medium"
|
||||
Title="Refresh"/>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Clear"
|
||||
OnClick="ClearFilters"
|
||||
Color="Color.Default"
|
||||
Size="Size.Medium"
|
||||
Title="Clear filters"/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudExpansionPanel>
|
||||
</MudExpansionPanels>
|
||||
|
||||
<MudDivider Class="my-4"></MudDivider>
|
||||
|
||||
<MudTable Items="jobs.Items"
|
||||
Dense="true"
|
||||
Hover="true"
|
||||
Loading="isLoading"
|
||||
LoadingProgressColor="Color.Primary"
|
||||
OnRowClick="@((TableRowClickEventArgs<QueueJob> args) => OnRowClick(args.Item))"
|
||||
T="QueueJob"
|
||||
Style="cursor: pointer;">
|
||||
<HeaderContent>
|
||||
<MudTh>Layer Name</MudTh>
|
||||
<MudTh>Plugin</MudTh>
|
||||
<MudTh>Type</MudTh>
|
||||
<MudTh>Status</MudTh>
|
||||
<MudTh>Priority</MudTh>
|
||||
<MudTh>Retry</MudTh>
|
||||
<MudTh>Created</MudTh>
|
||||
<MudTh>Last Attempt</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate Context="row">
|
||||
<MudTd DataLabel="Layer Name">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
@row.LayerName
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Plugin">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
@row.PluginName
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Type">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
<MudChip T="string" Size="Size.Small" Color="@GetJobTypeColor(row.JobType)">@row.JobType</MudChip>
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Status">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
<MudChip T="string" Size="Size.Small" Color="@GetStatusColor(row.Status)">@row.Status</MudChip>
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Priority">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
@row.Priority
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Retry">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
@row.RetryCount / @row.MaxRetries
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Created">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
@row.CreatedAt.ToString("yyyy-MM-dd HH:mm")
|
||||
</div>
|
||||
</MudTd>
|
||||
<MudTd DataLabel="Last Attempt">
|
||||
<div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">
|
||||
@(row.LastAttemptAt?.ToString("yyyy-MM-dd HH:mm") ?? "-")
|
||||
</div>
|
||||
</MudTd>
|
||||
</RowTemplate>
|
||||
<NoRecordsContent>
|
||||
<MudText>No jobs to display</MudText>
|
||||
</NoRecordsContent>
|
||||
<LoadingContent>
|
||||
Loading...
|
||||
</LoadingContent>
|
||||
</MudTable>
|
||||
|
||||
@if (jobs.TotalCount > 0)
|
||||
{
|
||||
<MudGrid Class="mt-4" AlignItems="Center.Center">
|
||||
<MudItem xs="12" sm="6">
|
||||
<MudText Typo="Typo.body2">
|
||||
Results @((jobs.Page - 1) * jobs.PageSize + 1) - @Math.Min(jobs.Page * jobs.PageSize, jobs.TotalCount)
|
||||
of @jobs.TotalCount
|
||||
</MudText>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" Class="d-flex justify-end">
|
||||
<MudPagination Count="jobs.TotalPages"
|
||||
Selected="jobs.Page"
|
||||
SelectedChanged="OnPageChanged"
|
||||
ShowFirstButton="true"
|
||||
ShowLastButton="true"
|
||||
Variant="Variant.Outlined"
|
||||
/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
using DiunaBI.UI.Shared.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using DiunaBI.Application.DTOModels.Common;
|
||||
using DiunaBI.Domain.Entities;
|
||||
using MudBlazor;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Components;
|
||||
|
||||
public partial class JobListComponent : ComponentBase, IDisposable
|
||||
{
|
||||
[Inject] private JobService JobService { get; set; } = default!;
|
||||
[Inject] private EntityChangeHubService HubService { get; set; } = default!;
|
||||
[Inject] private ISnackbar Snackbar { get; set; } = default!;
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
|
||||
|
||||
private PagedResult<QueueJob> jobs = new();
|
||||
private bool isLoading = false;
|
||||
private int currentPage = 1;
|
||||
private int pageSize = 50;
|
||||
private JobStatus? selectedStatus = null;
|
||||
private JobType? selectedJobType = null;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadJobs();
|
||||
|
||||
// Subscribe to SignalR entity changes
|
||||
HubService.EntityChanged += OnEntityChanged;
|
||||
}
|
||||
|
||||
private async void OnEntityChanged(string module, string id, string operation)
|
||||
{
|
||||
Console.WriteLine($"🔔 JobListComponent.OnEntityChanged called: module={module}, id={id}, operation={operation}");
|
||||
|
||||
// Only react if it's a QueueJobs change
|
||||
if (module.Equals("QueueJobs", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Console.WriteLine($"📨 Job {id} changed, refreshing job list");
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
Console.WriteLine($"🔄 LoadJobs starting...");
|
||||
await LoadJobs();
|
||||
Console.WriteLine($"🔄 StateHasChanged calling...");
|
||||
StateHasChanged();
|
||||
Console.WriteLine($"✅ Job list refresh complete");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"⏭️ Skipping - module '{module}' is not QueueJobs");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadJobs()
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
try
|
||||
{
|
||||
jobs = await JobService.GetJobsAsync(currentPage, pageSize, selectedStatus, selectedJobType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Loading jobs failed: {ex.Message}");
|
||||
Snackbar.Add("Failed to load jobs", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnPageChanged(int page)
|
||||
{
|
||||
currentPage = page;
|
||||
await LoadJobs();
|
||||
}
|
||||
|
||||
private async Task ClearFilters()
|
||||
{
|
||||
selectedStatus = null;
|
||||
selectedJobType = null;
|
||||
currentPage = 1;
|
||||
await LoadJobs();
|
||||
}
|
||||
|
||||
private async Task OnStatusClear()
|
||||
{
|
||||
selectedStatus = null;
|
||||
currentPage = 1;
|
||||
await LoadJobs();
|
||||
}
|
||||
|
||||
private async Task OnJobTypeClear()
|
||||
{
|
||||
selectedJobType = null;
|
||||
currentPage = 1;
|
||||
await LoadJobs();
|
||||
}
|
||||
|
||||
private void OnRowClick(QueueJob job)
|
||||
{
|
||||
NavigationManager.NavigateTo($"/jobs/{job.Id}");
|
||||
}
|
||||
|
||||
private async Task OnRowRightClick(MouseEventArgs e, QueueJob job)
|
||||
{
|
||||
var url = NavigationManager.ToAbsoluteUri($"/jobs/{job.Id}").ToString();
|
||||
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
||||
}
|
||||
|
||||
private Color GetStatusColor(JobStatus status)
|
||||
{
|
||||
return status switch
|
||||
{
|
||||
JobStatus.Pending => Color.Default,
|
||||
JobStatus.Running => Color.Info,
|
||||
JobStatus.Completed => Color.Success,
|
||||
JobStatus.Failed => Color.Error,
|
||||
JobStatus.Retrying => Color.Warning,
|
||||
_ => Color.Default
|
||||
};
|
||||
}
|
||||
|
||||
private Color GetJobTypeColor(JobType jobType)
|
||||
{
|
||||
return jobType switch
|
||||
{
|
||||
JobType.Import => Color.Primary,
|
||||
JobType.Process => Color.Secondary,
|
||||
_ => Color.Default
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HubService.EntityChanged -= OnEntityChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
@using MudBlazor.Internal
|
||||
@using DiunaBI.Application.DTOModels
|
||||
<MudExpansionPanels Class="mb-4">
|
||||
<MudExpansionPanel Icon="@Icons.Material.Filled.FilterList"
|
||||
Text="Filters"
|
||||
Expanded="true">
|
||||
<MudGrid AlignItems="Center">
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
<MudTextField @bind-Value="filterRequest.Search"
|
||||
Label="Search"
|
||||
Placeholder="Name, number..."
|
||||
Immediate="true"
|
||||
DebounceInterval="500"
|
||||
OnDebounceIntervalElapsed="SearchLayers"
|
||||
Clearable="true"/>
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
<MudSelect T="LayerType?"
|
||||
Value="filterRequest.Type"
|
||||
ValueChanged="OnTypeChanged"
|
||||
Label="Type"
|
||||
Placeholder="All types"
|
||||
Clearable="true"
|
||||
OnClearButtonClick="OnTypeClear">
|
||||
@foreach (LayerType type in Enum.GetValues(typeof(LayerType)))
|
||||
{
|
||||
<MudSelectItem T="LayerType?" Value="@type">@type.ToString()</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudItem>
|
||||
|
||||
<MudItem xs="12" sm="12" md="4" Class="d-flex justify-end">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Clear"
|
||||
OnClick="ClearFilters"
|
||||
Color="Color.Default"
|
||||
Size="Size.Medium"
|
||||
Title="Clear filters"/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
</MudExpansionPanel>
|
||||
</MudExpansionPanels>
|
||||
|
||||
<MudDivider Class="my-4"></MudDivider>
|
||||
|
||||
<MudTable Items="layers.Items"
|
||||
Dense="true"
|
||||
Hover="true"
|
||||
Loading="isLoading"
|
||||
LoadingProgressColor="Color.Primary"
|
||||
OnRowClick="@((TableRowClickEventArgs<LayerDto> args) => OnRowClick(args.Item))"
|
||||
T="LayerDto"
|
||||
Style="cursor: pointer;">
|
||||
<HeaderContent>
|
||||
<MudTh>Name</MudTh>
|
||||
<MudTh>Type</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate Context="row">
|
||||
<MudTd DataLabel="Name"><div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">@row.Name</div></MudTd>
|
||||
<MudTd DataLabel="Type"><div @oncontextmenu="@(async (e) => await OnRowRightClick(e, row))" @oncontextmenu:preventDefault="true">@row.Type</div></MudTd>
|
||||
</RowTemplate>
|
||||
<NoRecordsContent>
|
||||
<MudText>No layers to display</MudText>
|
||||
</NoRecordsContent>
|
||||
<LoadingContent>
|
||||
Loading...
|
||||
</LoadingContent>
|
||||
</MudTable>
|
||||
|
||||
@if (layers.TotalCount > 0)
|
||||
{
|
||||
<MudGrid Class="mt-4" AlignItems="Center.Center">
|
||||
<MudItem xs="12" sm="6">
|
||||
<MudText Typo="Typo.body2">
|
||||
Results @((layers.Page - 1) * layers.PageSize + 1) - @Math.Min(layers.Page * layers.PageSize, layers.TotalCount)
|
||||
of @layers.TotalCount
|
||||
</MudText>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" Class="d-flex justify-end">
|
||||
<MudPagination Count="layers.TotalPages"
|
||||
Selected="layers.Page"
|
||||
SelectedChanged="OnPageChanged"
|
||||
ShowFirstButton="true"
|
||||
ShowLastButton="true"
|
||||
Variant="Variant.Outlined"
|
||||
/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
using DiunaBI.UI.Shared.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using DiunaBI.Application.DTOModels;
|
||||
using DiunaBI.Application.DTOModels.Common;
|
||||
using MudBlazor;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Components;
|
||||
|
||||
public partial class LayerListComponent : ComponentBase
|
||||
{
|
||||
[Inject] private LayerService LayerService { get; set; } = default!;
|
||||
[Inject] private ISnackbar Snackbar { get; set; } = default!;
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] private LayerFilterStateService FilterStateService { get; set; } = default!;
|
||||
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
|
||||
|
||||
|
||||
private PagedResult<LayerDto> layers = new();
|
||||
private LayerFilterRequest filterRequest = new();
|
||||
private bool isLoading = false;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
filterRequest = FilterStateService.FilterRequest;
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private async Task LoadLayers()
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
try
|
||||
{
|
||||
FilterStateService.UpdateFilter(filterRequest);
|
||||
layers = await LayerService.GetLayersAsync(filterRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Loading layers failed: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SearchLayers()
|
||||
{
|
||||
filterRequest.Page = 1;
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private async Task OnPageChanged(int page)
|
||||
{
|
||||
filterRequest.Page = page;
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private async Task ClearFilters()
|
||||
{
|
||||
filterRequest = new LayerFilterRequest();
|
||||
FilterStateService.ClearFilter();
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private async Task OnTypeClear()
|
||||
{
|
||||
filterRequest.Type = null;
|
||||
filterRequest.Page = 1;
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private async Task OnTypeChanged(LayerType? type)
|
||||
{
|
||||
filterRequest.Type = type;
|
||||
filterRequest.Page = 1;
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private void OnRowClick(LayerDto layer)
|
||||
{
|
||||
NavigationManager.NavigateTo($"/layers/{layer.Id}");
|
||||
}
|
||||
|
||||
private async Task OnRowRightClick(MouseEventArgs e, LayerDto layer)
|
||||
{
|
||||
var url = NavigationManager.ToAbsoluteUri($"/layers/{layer.Id}").ToString();
|
||||
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
||||
}
|
||||
}
|
||||
8
DiunaBI.UI.Shared/Components/Layout/EmptyLayout.razor
Normal file
8
DiunaBI.UI.Shared/Components/Layout/EmptyLayout.razor
Normal file
@@ -0,0 +1,8 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<MudThemeProvider/>
|
||||
<MudDialogProvider/>
|
||||
<MudSnackbarProvider/>
|
||||
|
||||
|
||||
@Body
|
||||
98
DiunaBI.UI.Shared/Components/Layout/MainLayout.razor
Normal file
98
DiunaBI.UI.Shared/Components/Layout/MainLayout.razor
Normal file
@@ -0,0 +1,98 @@
|
||||
@using MudBlazor
|
||||
@using DiunaBI.UI.Shared.Services
|
||||
@inject AppConfig AppConfig
|
||||
@inject EntityChangeHubService HubService
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<AuthGuard>
|
||||
<MudThemeProvider Theme="_theme"/>
|
||||
<MudPopoverProvider/>
|
||||
<MudDialogProvider/>
|
||||
<MudSnackbarProvider/>
|
||||
|
||||
<MudLayout>
|
||||
<MudBreakpointProvider OnBreakpointChanged="OnBreakpointChanged"></MudBreakpointProvider>
|
||||
<MudAppBar Elevation="0">
|
||||
<MudIconButton
|
||||
Icon="@Icons.Material.Filled.Menu"
|
||||
Color="Color.Inherit"
|
||||
Edge="Edge.Start"
|
||||
OnClick="ToggleDrawer"
|
||||
Class="mud-hidden-md-up"/>
|
||||
<MudSpacer/>
|
||||
<MudText Typo="Typo.h6">@AppConfig.AppName</MudText>
|
||||
</MudAppBar>
|
||||
|
||||
<MudDrawer @bind-Open="_drawerOpen"
|
||||
Anchor="Anchor.Start"
|
||||
Variant="@_drawerVariant"
|
||||
Elevation="1"
|
||||
ClipMode="DrawerClipMode.Always"
|
||||
Class="mud-width-250">
|
||||
<div class="nav-logo" style="text-align: center; padding: 20px;">
|
||||
<a href="https://www.diunabi.com" target="_blank">
|
||||
<img src="_content/DiunaBI.UI.Shared/images/logo.png" alt="DiunaBI" style="max-width: 180px; height: auto;" />
|
||||
</a>
|
||||
</div>
|
||||
<MudNavMenu>
|
||||
<MudNavLink Href="/dashboard" Icon="@Icons.Material.Filled.Dashboard">Dashboard</MudNavLink>
|
||||
<MudNavLink Href="/layers" Icon="@Icons.Material.Filled.Inventory">Layers</MudNavLink>
|
||||
<MudNavLink Href="/datainbox" Icon="@Icons.Material.Filled.Inbox">Data Inbox</MudNavLink>
|
||||
<MudNavLink Href="/jobs" Icon="@Icons.Material.Filled.WorkHistory">Jobs</MudNavLink>
|
||||
</MudNavMenu>
|
||||
</MudDrawer>
|
||||
|
||||
<MudMainContent>
|
||||
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="my-4">
|
||||
@Body
|
||||
</MudContainer>
|
||||
</MudMainContent>
|
||||
</MudLayout>
|
||||
</AuthGuard>
|
||||
|
||||
@code {
|
||||
|
||||
private bool _drawerOpen = true;
|
||||
private DrawerVariant _drawerVariant = DrawerVariant.Persistent;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Initialize SignalR connection when layout loads
|
||||
await HubService.InitializeAsync();
|
||||
}
|
||||
|
||||
private MudTheme _theme = new MudTheme()
|
||||
{
|
||||
PaletteLight = new PaletteLight()
|
||||
{
|
||||
Primary = "#e7163d",
|
||||
PrimaryDarken = "#c01234",
|
||||
PrimaryLighten = "#f04366",
|
||||
Secondary = "#424242",
|
||||
AppbarBackground = "#e7163d",
|
||||
}
|
||||
};
|
||||
|
||||
void ToggleDrawer()
|
||||
{
|
||||
Console.WriteLine($"ToogleDrawer clickkk {DateTime.Now}");
|
||||
_drawerOpen = !_drawerOpen;
|
||||
}
|
||||
|
||||
private void OnBreakpointChanged(Breakpoint breakpoint)
|
||||
{
|
||||
if (breakpoint < Breakpoint.Md)
|
||||
{
|
||||
_drawerVariant = DrawerVariant.Temporary;
|
||||
_drawerOpen = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_drawerVariant = DrawerVariant.Persistent;
|
||||
_drawerOpen = true;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user