LayerDetails page
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Typo="Typo.body2">
|
||||
✅ Zalogowano przez Google
|
||||
✅ Signed in via Google
|
||||
</MudText>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
@@ -37,6 +37,6 @@
|
||||
else
|
||||
{
|
||||
<MudAlert Severity="Severity.Warning" Class="mt-4">
|
||||
Nie jesteś zalogowany
|
||||
You are not logged in
|
||||
</MudAlert>
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
@using MudBlazor.Internal
|
||||
<MudExpansionPanels Class="mb-4">
|
||||
<MudExpansionPanel Icon="@Icons.Material.Filled.FilterList"
|
||||
Text="Filtry"
|
||||
Text="Filters"
|
||||
Expanded="true">
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
<MudTextField @bind-Value="filterRequest.Search"
|
||||
Label="Szukaj"
|
||||
Placeholder="Nazwa, numer..."
|
||||
Label="Search"
|
||||
Placeholder="Name, number..."
|
||||
Immediate="true"
|
||||
DebounceInterval="500"
|
||||
OnDebounceIntervalElapsed="SearchLayers"
|
||||
Clearable="true"/>
|
||||
|
||||
</MudItem>
|
||||
|
||||
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
OnClick="ClearFilters"
|
||||
StartIcon="Icons.Material.Filled.Clear">
|
||||
Wyczyść filtry
|
||||
Clear filters
|
||||
</MudButton>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
@@ -32,7 +32,10 @@
|
||||
Dense="true"
|
||||
Hover="true"
|
||||
Loading="isLoading"
|
||||
LoadingProgressColor="Color.Info">
|
||||
LoadingProgressColor="Color.Info"
|
||||
OnRowClick="@((TableRowClickEventArgs<LayerDto> args) => OnRowClick(args.Item))"
|
||||
T="LayerDto"
|
||||
Style="cursor: pointer;">
|
||||
<HeaderContent>
|
||||
<MudTh>Name</MudTh>
|
||||
<MudTh>Type</MudTh>
|
||||
@@ -45,7 +48,7 @@
|
||||
<MudText>No layers to display</MudText>
|
||||
</NoRecordsContent>
|
||||
<LoadingContent>
|
||||
Ładowanie...
|
||||
Loading...
|
||||
</LoadingContent>
|
||||
</MudTable>
|
||||
|
||||
@@ -54,8 +57,8 @@
|
||||
<MudGrid Class="mt-4" AlignItems="Center.Center">
|
||||
<MudItem xs="12" sm="6">
|
||||
<MudText Typo="Typo.body2">
|
||||
Wyniki @((layers.Page - 1) * layers.PageSize + 1) - @Math.Min(layers.Page * layers.PageSize, layers.TotalCount)
|
||||
z @layers.TotalCount
|
||||
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">
|
||||
|
||||
@@ -6,10 +6,11 @@ using MudBlazor;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Components;
|
||||
|
||||
public partial class LayerListComponent : ComponentBase
|
||||
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!;
|
||||
|
||||
|
||||
private PagedResult<LayerDto> layers = new();
|
||||
@@ -54,6 +55,11 @@ public partial class LayerListComponent : ComponentBase
|
||||
private async Task ClearFilters()
|
||||
{
|
||||
filterRequest = new LayerFilterRequest();
|
||||
await LoadLayers();
|
||||
await LoadLayers();
|
||||
}
|
||||
|
||||
private void OnRowClick(LayerDto layer)
|
||||
{
|
||||
NavigationManager.NavigateTo($"/layers/{layer.Id}");
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
<MudCard Class="login-card" Elevation="8">
|
||||
<MudCardContent Class="pa-8 d-flex flex-column align-center">
|
||||
<MudText Typo="Typo.h4" Class="mb-4">Witaj w DiunaBI</MudText>
|
||||
<MudText Typo="Typo.h4" Class="mb-4">Welcome to DiunaBI</MudText>
|
||||
<MudText Typo="Typo.body1" Class="mb-6 text-center">
|
||||
Zaloguj się używając konta Google
|
||||
Sign in using your Google account
|
||||
</MudText>
|
||||
|
||||
|
||||
<MudButton
|
||||
Variant="Variant.Filled"
|
||||
StartIcon="@Icons.Custom.Brands.Google"
|
||||
@@ -22,11 +22,11 @@
|
||||
@if (_isLoading)
|
||||
{
|
||||
<MudProgressCircular Class="mr-3" Size="Size.Small" Indeterminate="true"></MudProgressCircular>
|
||||
<span>Weryfikacja...</span>
|
||||
<span>Verifying...</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>Zaloguj z Google</span>
|
||||
<span>Sign in with Google</span>
|
||||
}
|
||||
</MudButton>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_errorMessage = "Błąd inicjalizacji Google Sign-In.";
|
||||
_errorMessage = "Google Sign-In initialization error.";
|
||||
Console.Error.WriteLine($"❌ Google Sign-In initialization error: {ex.Message}");
|
||||
Console.Error.WriteLine($"Stack trace: {ex.StackTrace}");
|
||||
}
|
||||
@@ -89,12 +89,12 @@
|
||||
_isLoading = true;
|
||||
_errorMessage = string.Empty;
|
||||
StateHasChanged();
|
||||
|
||||
|
||||
await JS.InvokeVoidAsync("requestGoogleSignIn");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_errorMessage = "Błąd podczas logowania. Spróbuj ponownie";
|
||||
_errorMessage = "Login error. Please try again";
|
||||
_isLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
@@ -124,16 +124,16 @@
|
||||
{
|
||||
Console.WriteLine($"❌ Validation failed: {errorMessage}");
|
||||
_instance._isLoading = false;
|
||||
_instance._errorMessage = errorMessage ?? "Nie udało się zalogować.";
|
||||
_instance._errorMessage = errorMessage ?? "Login failed.";
|
||||
}
|
||||
|
||||
|
||||
await _instance.InvokeAsync(() => _instance.StateHasChanged());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"❌ OnGoogleSignInSuccess error: {ex.Message}");
|
||||
_instance._isLoading = false;
|
||||
_instance._errorMessage = "Błąd podczas weryfikacji użytkownika.";
|
||||
_instance._errorMessage = "User verification error.";
|
||||
await _instance.InvokeAsync(() => _instance.StateHasChanged());
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@
|
||||
if (_instance != null)
|
||||
{
|
||||
_instance._isLoading = false;
|
||||
_instance._errorMessage = "Błąd logowania Google. Spróbuj ponownie";
|
||||
_instance._errorMessage = "Google login error. Please try again";
|
||||
await _instance.InvokeAsync(() => _instance.StateHasChanged());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<AuthGuard>
|
||||
<MudThemeProvider/>
|
||||
<MudThemeProvider Theme="_theme"/>
|
||||
<MudDialogProvider/>
|
||||
<MudSnackbarProvider/>
|
||||
|
||||
@@ -44,6 +44,18 @@
|
||||
private bool _drawerOpen = true;
|
||||
private DrawerVariant _drawerVariant = DrawerVariant.Persistent;
|
||||
|
||||
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}");
|
||||
|
||||
112
src/Backend/DiunaBI.UI.Shared/Pages/LayerDetailPage.razor
Normal file
112
src/Backend/DiunaBI.UI.Shared/Pages/LayerDetailPage.razor
Normal file
@@ -0,0 +1,112 @@
|
||||
@page "/layers/{id:guid}"
|
||||
@using DiunaBI.UI.Shared.Services
|
||||
@using DiunaBI.Application.DTOModels
|
||||
@using MudBlazor
|
||||
@inject LayerService LayerService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<MudCard>
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h5">Layer Details</MudText>
|
||||
</CardHeaderContent>
|
||||
<CardHeaderActions>
|
||||
<MudButton Variant="Variant.Text" OnClick="Export">Export</MudButton>
|
||||
@if (layer != null && layer.Type == LayerType.Administration)
|
||||
{
|
||||
<MudButton Variant="Variant.Text" Href="@($"/layers/edit/{layer.Id}/duplicate")">Duplicate</MudButton>
|
||||
<MudButton Variant="Variant.Text" Href="@($"/layers/edit/{layer.Id}")">Edit</MudButton>
|
||||
}
|
||||
@if (layer != null && layer.Type == LayerType.Processed)
|
||||
{
|
||||
<MudButton Variant="Variant.Text" OnClick="ProcessLayer">Process Layer</MudButton>
|
||||
}
|
||||
</CardHeaderActions>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
@if (isLoading)
|
||||
{
|
||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" />
|
||||
}
|
||||
else if (layer == null)
|
||||
{
|
||||
<MudAlert Severity="Severity.Error">Layer not found</MudAlert>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudGrid>
|
||||
<MudItem xs="12" md="6">
|
||||
<MudTextField @bind-Value="layer.Name"
|
||||
Label="Name"
|
||||
Variant="Variant.Outlined"
|
||||
ReadOnly="true"
|
||||
FullWidth="true"/>
|
||||
</MudItem>
|
||||
<MudItem xs="12" md="6">
|
||||
@if (layer.IsCancelled)
|
||||
{
|
||||
<MudAlert Severity="Severity.Warning" Dense="true">
|
||||
This layer is cancelled. Will not be used in any further processing.
|
||||
</MudAlert>
|
||||
}
|
||||
</MudItem>
|
||||
<MudItem xs="12" md="6">
|
||||
<MudTextField Value="@layer.CreatedAt.ToString("g")"
|
||||
Label="Created"
|
||||
Variant="Variant.Outlined"
|
||||
ReadOnly="true"
|
||||
FullWidth="true"
|
||||
Adornment="Adornment.End"
|
||||
AdornmentText="@(layer.CreatedBy?.Username ?? "")"/>
|
||||
</MudItem>
|
||||
<MudItem xs="12" md="6">
|
||||
<MudTextField Value="@layer.ModifiedAt.ToString("g")"
|
||||
Label="Modified"
|
||||
Variant="Variant.Outlined"
|
||||
ReadOnly="true"
|
||||
FullWidth="true"
|
||||
Adornment="Adornment.End"
|
||||
AdornmentText="@(layer.ModifiedBy?.Username ?? "")"/>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
|
||||
<MudDivider Class="my-4"/>
|
||||
|
||||
<MudTable Items="@records"
|
||||
Dense="true"
|
||||
Striped="true"
|
||||
FixedHeader="true"
|
||||
FixedFooter="true"
|
||||
Height="600px">
|
||||
<HeaderContent>
|
||||
<MudTh>Code</MudTh>
|
||||
@foreach (var column in displayedColumns)
|
||||
{
|
||||
<MudTh>@column</MudTh>
|
||||
}
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd DataLabel="Code">@context.Code</MudTd>
|
||||
@foreach (var column in displayedColumns)
|
||||
{
|
||||
<MudTd DataLabel="@column">@GetRecordValue(context, column)</MudTd>
|
||||
}
|
||||
</RowTemplate>
|
||||
<FooterContent>
|
||||
<MudTd><b>Value1 sum</b></MudTd>
|
||||
@foreach (var column in displayedColumns)
|
||||
{
|
||||
@if (column == "Value1")
|
||||
{
|
||||
<MudTd><b>@valueSum.ToString("N2")</b></MudTd>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudTd></MudTd>
|
||||
}
|
||||
}
|
||||
</FooterContent>
|
||||
</MudTable>
|
||||
}
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
122
src/Backend/DiunaBI.UI.Shared/Pages/LayerDetailPage.razor.cs
Normal file
122
src/Backend/DiunaBI.UI.Shared/Pages/LayerDetailPage.razor.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using DiunaBI.Application.DTOModels;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DiunaBI.UI.Shared.Pages;
|
||||
|
||||
public partial class LayerDetailPage : ComponentBase
|
||||
{
|
||||
[Parameter]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Inject]
|
||||
private ISnackbar Snackbar { get; set; } = null!;
|
||||
|
||||
private LayerDto? layer;
|
||||
private List<RecordDto> records = new();
|
||||
private List<string> displayedColumns = new();
|
||||
private double valueSum = 0;
|
||||
private bool isLoading = false;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadLayer();
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await LoadLayer();
|
||||
}
|
||||
|
||||
private async Task LoadLayer()
|
||||
{
|
||||
isLoading = true;
|
||||
StateHasChanged();
|
||||
|
||||
try
|
||||
{
|
||||
layer = await LayerService.GetLayerByIdAsync(Id);
|
||||
|
||||
if (layer != null && layer.Records != null)
|
||||
{
|
||||
records = layer.Records;
|
||||
CalculateDisplayedColumns();
|
||||
CalculateValueSum();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Error loading layer: {ex.Message}");
|
||||
Snackbar.Add("Error loading layer", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateDisplayedColumns()
|
||||
{
|
||||
displayedColumns.Clear();
|
||||
|
||||
// Check which Value columns have data
|
||||
for (int i = 1; i <= 32; i++)
|
||||
{
|
||||
var columnName = $"Value{i}";
|
||||
var hasData = records.Any(r => GetRecordValueByName(r, columnName) != null);
|
||||
|
||||
if (hasData)
|
||||
{
|
||||
displayedColumns.Add(columnName);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if Desc1 has data
|
||||
if (records.Any(r => !string.IsNullOrEmpty(r.Desc1)))
|
||||
{
|
||||
displayedColumns.Add("Description1");
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateValueSum()
|
||||
{
|
||||
valueSum = records
|
||||
.Where(r => r.Value1.HasValue)
|
||||
.Sum(r => r.Value1!.Value);
|
||||
}
|
||||
|
||||
private string GetRecordValue(RecordDto record, string columnName)
|
||||
{
|
||||
if (columnName == "Description1")
|
||||
{
|
||||
return record.Desc1 ?? string.Empty;
|
||||
}
|
||||
|
||||
var value = GetRecordValueByName(record, columnName);
|
||||
return value.HasValue ? value.Value.ToString("N2") : string.Empty;
|
||||
}
|
||||
|
||||
private double? GetRecordValueByName(RecordDto record, string columnName)
|
||||
{
|
||||
var property = typeof(RecordDto).GetProperty(columnName, BindingFlags.Public | BindingFlags.Instance);
|
||||
if (property != null && property.PropertyType == typeof(double?))
|
||||
{
|
||||
return property.GetValue(record) as double?;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void Export()
|
||||
{
|
||||
// TODO: Implement export functionality
|
||||
Snackbar.Add("Export functionality coming soon", Severity.Error);
|
||||
}
|
||||
|
||||
private void ProcessLayer()
|
||||
{
|
||||
// TODO: Implement process layer functionality
|
||||
Snackbar.Add("Process layer functionality coming soon", Severity.Error);
|
||||
}
|
||||
}
|
||||
@@ -68,25 +68,25 @@ public class AuthService
|
||||
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
{
|
||||
Console.WriteLine("❌ User not found in DiunaBI database");
|
||||
return (false, "Użytkownik nie istnieje w bazie DiunaBI.");
|
||||
return (false, "User does not exist in DiunaBI database.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"❌ Backend error: {response.StatusCode}");
|
||||
return (false, "Błąd serwera DiunaBI. Spróbuj ponownie.");
|
||||
return (false, "DiunaBI server error. Please try again.");
|
||||
}
|
||||
|
||||
return (false, "Nieoczekiwany błąd.");
|
||||
|
||||
return (false, "Unexpected error.");
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Network error: {ex.Message}");
|
||||
return (false, "Nie można połączyć się z serwerem DiunaBI.");
|
||||
return (false, "Cannot connect to DiunaBI server.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Validation error: {ex.Message}");
|
||||
return (false, "Błąd podczas weryfikacji użytkownika.");
|
||||
return (false, "User verification error.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,9 +105,9 @@ public class AuthService
|
||||
{
|
||||
_apiToken = token;
|
||||
_userInfo = JsonSerializer.Deserialize<UserInfo>(userInfoJson);
|
||||
|
||||
// Przywróć header
|
||||
_httpClient.DefaultRequestHeaders.Authorization =
|
||||
|
||||
// Restore header
|
||||
_httpClient.DefaultRequestHeaders.Authorization =
|
||||
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _apiToken);
|
||||
|
||||
Console.WriteLine($"✅ Session restored: {_userInfo?.Email}");
|
||||
|
||||
@@ -3,17 +3,17 @@ html, body {
|
||||
}
|
||||
|
||||
a, .btn-link {
|
||||
color: #006bb7;
|
||||
color: #e7163d;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
background-color: #e7163d;
|
||||
border-color: #c01234;
|
||||
}
|
||||
|
||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #e7163d;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
Reference in New Issue
Block a user