370 lines
17 KiB
Plaintext
370 lines
17 KiB
Plaintext
@page "/customers"
|
|
@rendermode InteractiveWebAssembly
|
|
@using IntegryControlPanel.Client.Models
|
|
@using Microsoft.AspNetCore.Authorization
|
|
@using System.Net.Http.Json
|
|
@attribute [Authorize]
|
|
|
|
@inject HttpClient Http
|
|
@inject ISnackbar Snackbar
|
|
|
|
<PageTitle>Gestione Clienti</PageTitle>
|
|
|
|
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="mt-4">
|
|
<MudText Typo="Typo.h4" GutterBottom="true">
|
|
<MudIcon Icon="@Icons.Material.Filled.Business" Class="mr-3"/>
|
|
Gestione Clienti
|
|
</MudText>
|
|
|
|
<MudCard>
|
|
<MudCardContent>
|
|
@if (isLoading)
|
|
{
|
|
<MudGrid>
|
|
<MudItem xs="12" Class="d-flex justify-center">
|
|
<MudProgressCircular Color="Color.Primary" Indeterminate="true"/>
|
|
<MudText Class="ml-3">Caricamento clienti...</MudText>
|
|
</MudItem>
|
|
</MudGrid>
|
|
}
|
|
else if (customers?.Any() == true)
|
|
{
|
|
<MudDataGrid Items="@customers"
|
|
ReadOnly="true"
|
|
SortMode="SortMode.Multiple"
|
|
Filterable="true"
|
|
Hideable="true"
|
|
ColumnResizeMode="ResizeMode.Container"
|
|
Style="width: 100%;">
|
|
<Columns>
|
|
<PropertyColumn Property="x => x.Name" Title="Cliente">
|
|
<CellTemplate>
|
|
<MudText Typo="Typo.body2">
|
|
@context.Item.DisplayName
|
|
</MudText>
|
|
<MudText Typo="Typo.body1" Style="font-weight: bold;">
|
|
@context.Item.Name
|
|
</MudText>
|
|
<MudText Typo="Typo.subtitle2" Color="Color.Secondary">
|
|
@* #@context.Item.Id - @context.Item.Slug *@
|
|
@context.Item.PartitaIva
|
|
</MudText>
|
|
</CellTemplate>
|
|
</PropertyColumn>
|
|
<PropertyColumn Property="x => x.Active" Title="Stato">
|
|
<CellTemplate>
|
|
@* <MudChip Color="@(context.Item.Active == true ? Color.Success : Color.Error)"
|
|
Size="Size.Small">
|
|
@(context.Item.Active == true ? "Attivo" : "Inattivo")
|
|
</MudChip> *@
|
|
<MudText Style="font-weight:bold;" Color="@(context.Item.Active == true ? Color.Success : Color.Error)">
|
|
@(context.Item.Active == true ? "Attivo" : "Inattivo")
|
|
</MudText>
|
|
@* <MudCheckBox Value="context.Item.Active"></MudCheckBox> *@
|
|
</CellTemplate>
|
|
</PropertyColumn>
|
|
<TemplateColumn Title="Azioni" Sortable="false" Filterable="false">
|
|
<CellTemplate>
|
|
<MudButton Variant="Variant.Filled"
|
|
Color="Color.Primary"
|
|
Size="Size.Small"
|
|
StartIcon="@Icons.Material.Filled.Visibility"
|
|
OnClick="@(() => ShowCustomerDetails(context.Item))">
|
|
Dettagli
|
|
</MudButton>
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
</Columns>
|
|
</MudDataGrid>
|
|
}
|
|
else
|
|
{
|
|
<MudAlert Severity="Severity.Info">
|
|
<MudText>Nessun cliente trovato.</MudText>
|
|
</MudAlert>
|
|
}
|
|
</MudCardContent>
|
|
</MudCard>
|
|
|
|
<!-- Customer Details Dialog -->
|
|
<MudDialog @bind-Visible="isDetailsDialogVisible" Options="dialogOptions">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h5">
|
|
<MudIcon Icon="@Icons.Material.Filled.Business" Class="mr-3"/>
|
|
Dettagli Cliente: @selectedCustomer?.Name
|
|
</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
@if (selectedCustomer != null)
|
|
{
|
|
<MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-6">
|
|
<!-- Customer Info Tab -->
|
|
<MudTabPanel Text="Informazioni Cliente" Icon="@Icons.Material.Filled.Info">
|
|
<MudGrid>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="ID" Value="@selectedCustomer.Id.ToString()" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Nome" Value="@selectedCustomer.Name" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Slug" Value="@selectedCustomer.Slug" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Partita IVA" Value="@selectedCustomer.PartitaIva" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudSwitch T="bool?" @bind-Value="selectedCustomer.Active"
|
|
Label="Cliente Attivo"
|
|
ReadOnly="true"
|
|
Color="Color.Success"/>
|
|
</MudItem>
|
|
</MudGrid>
|
|
</MudTabPanel>
|
|
|
|
<!-- Servers Tab -->
|
|
<MudTabPanel Text="Server" Icon="@Icons.Material.Filled.Computer">
|
|
@if (isLoadingServers)
|
|
{
|
|
<MudProgressCircular Color="Color.Primary" Indeterminate="true"/>
|
|
<MudText Class="ml-3">Caricamento server...</MudText>
|
|
}
|
|
else if (customerServers?.Any() == true)
|
|
{
|
|
<MudDataGrid Items="@customerServers" Dense="true" Hover="true">
|
|
<Columns>
|
|
<PropertyColumn Property="x => x.Id" Title="ID"/>
|
|
<PropertyColumn Property="x => x.Ip" Title="IP"/>
|
|
<PropertyColumn Property="x => x.Port" Title="Porta"/>
|
|
<PropertyColumn Property="x => x.OsName" Title="Sistema Operativo"/>
|
|
<PropertyColumn Property="x => x.JavaVersion" Title="Versione Java"/>
|
|
<PropertyColumn Property="x => x.LastUpdate" Title="Ultimo Aggiornamento" Format="dd/MM/yyyy HH:mm"/>
|
|
</Columns>
|
|
</MudDataGrid>
|
|
}
|
|
else
|
|
{
|
|
<MudAlert Severity="Severity.Info">Nessun server configurato per questo cliente.</MudAlert>
|
|
}
|
|
</MudTabPanel>
|
|
|
|
<!-- Devices Tab -->
|
|
<MudTabPanel Text="Dispositivi" Icon="@Icons.Material.Filled.DeviceHub">
|
|
@if (isLoadingDevices)
|
|
{
|
|
<MudProgressCircular Color="Color.Primary" Indeterminate="true"/>
|
|
<MudText Class="ml-3">Caricamento dispositivi...</MudText>
|
|
}
|
|
else if (customerDevices?.Any() == true)
|
|
{
|
|
<MudDataGrid Items="@customerDevices" Dense="true" Hover="true">
|
|
<Columns>
|
|
<PropertyColumn Property="x => x.Id" Title="ID"/>
|
|
<PropertyColumn Property="x => x.Ip" Title="IP"/>
|
|
<PropertyColumn Property="x => x.Port" Title="Porta"/>
|
|
<PropertyColumn Property="x => x.Info" Title="Informazioni"/>
|
|
</Columns>
|
|
</MudDataGrid>
|
|
}
|
|
else
|
|
{
|
|
<MudAlert Severity="Severity.Info">Nessun dispositivo configurato per questo cliente.</MudAlert>
|
|
}
|
|
</MudTabPanel>
|
|
|
|
<!-- Application Info Tab -->
|
|
<MudTabPanel Text="Applicazioni" Icon="@Icons.Material.Filled.Apps">
|
|
@if (selectedCustomer.ApplicationInfos?.Any() == true)
|
|
{
|
|
<MudDataGrid Items="@selectedCustomer.ApplicationInfos" Dense="true" Hover="true">
|
|
<Columns>
|
|
<PropertyColumn Property="x => x.Id" Title="ID"/>
|
|
<PropertyColumn Property="x => x.Name" Title="Nome Applicazione"/>
|
|
<PropertyColumn Property="x => x.AnnoMagaz" Title="Anno Magazzino"/>
|
|
<PropertyColumn Property="x => x.AnnoContab" Title="Anno Contabilità"/>
|
|
<TemplateColumn Title="Nuovo Update">
|
|
<CellTemplate>
|
|
<MudChip Color="@(context.Item.NewUpdProgMaga ? Color.Success : Color.Default)"
|
|
Size="Size.Small">
|
|
@(context.Item.NewUpdProgMaga ? "Sì" : "No")
|
|
</MudChip>
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
</Columns>
|
|
</MudDataGrid>
|
|
}
|
|
else
|
|
{
|
|
<MudAlert Severity="Severity.Info">Nessuna applicazione configurata per questo cliente.</MudAlert>
|
|
}
|
|
</MudTabPanel>
|
|
|
|
<!-- PVMS Info Tab -->
|
|
<MudTabPanel Text="PVMS Info" Icon="@Icons.Material.Filled.Settings">
|
|
@if (selectedCustomer.PvmsInfos?.Any() == true)
|
|
{
|
|
@foreach (var pvms in selectedCustomer.PvmsInfos)
|
|
{
|
|
<MudCard Class="mb-4">
|
|
<MudCardContent>
|
|
<MudGrid>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Versione PHP" Value="@pvms.PhpVersion" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Timezone" Value="@pvms.Timezone" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="ImageMagick" Value="@pvms.Imagick" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Memory Limit" Value="@pvms.MemoryLimit" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Max Execution Time" Value="@pvms.MaxExecutionTime.ToString()" ReadOnly="true"/>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudTextField Label="Max Input Vars" Value="@pvms.MaxInputVars.ToString()" ReadOnly="true"/>
|
|
</MudItem>
|
|
</MudGrid>
|
|
</MudCardContent>
|
|
</MudCard>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<MudAlert Severity="Severity.Info">Nessuna informazione PVMS disponibile per questo cliente.</MudAlert>
|
|
}
|
|
</MudTabPanel>
|
|
</MudTabs>
|
|
}
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton Color="Color.Primary"
|
|
Variant="Variant.Filled"
|
|
OnClick="CloseDetailsDialog">
|
|
Chiudi
|
|
</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
</MudContainer>
|
|
|
|
@code {
|
|
private List<CustomerWithAnagInfoDto>? customers;
|
|
private long? selectedCustomerId;
|
|
private Customer? selectedCustomer;
|
|
private List<Server>? customerServers;
|
|
private List<Device>? customerDevices;
|
|
|
|
private bool isLoading = true;
|
|
private bool isLoadingServers = false;
|
|
private bool isLoadingDevices = false;
|
|
private bool isDetailsDialogVisible = false;
|
|
|
|
private DialogOptions dialogOptions = new()
|
|
{
|
|
MaxWidth = MaxWidth.ExtraLarge,
|
|
FullWidth = true,
|
|
CloseButton = true
|
|
};
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
try
|
|
{
|
|
await LoadCustomers();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"❌ Customers page - OnInitializedAsync error: {ex.Message}");
|
|
Console.WriteLine($"📋 Stack trace: {ex.StackTrace}");
|
|
Snackbar.Add($"Errore nell'inizializzazione della pagina: {ex.Message}", Severity.Error);
|
|
}
|
|
}
|
|
|
|
private async Task LoadCustomers()
|
|
{
|
|
try
|
|
{
|
|
isLoading = true;
|
|
StateHasChanged(); // Force UI update
|
|
|
|
customers = await Http.GetFromJsonAsync<List<CustomerWithAnagInfoDto>>("api/CustomerAnagInfo/");
|
|
}
|
|
catch (HttpRequestException httpEx)
|
|
{
|
|
Console.WriteLine($"🌐 LoadCustomers - HTTP error: {httpEx.Message}");
|
|
Snackbar.Add($"Errore di connessione: {httpEx.Message}", Severity.Error);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"❌ LoadCustomers - Generic error: {ex.Message}");
|
|
Console.WriteLine($"📋 Stack trace: {ex.StackTrace}");
|
|
Snackbar.Add($"Errore nel caricamento dei clienti: {ex.Message}", Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
isLoading = false;
|
|
StateHasChanged(); // Force UI update
|
|
}
|
|
}
|
|
|
|
private async Task ShowCustomerDetails(CustomerWithAnagInfoDto customer)
|
|
{
|
|
selectedCustomerId = customer.Id;
|
|
isDetailsDialogVisible = true;
|
|
|
|
// Load complete customer details with all related data
|
|
try
|
|
{
|
|
selectedCustomer = await Http.GetFromJsonAsync<Customer>($"api/IntegryData/customers/{customer.Id}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Errore nel caricamento dei dettagli del cliente: {ex.Message}", Severity.Error);
|
|
}
|
|
|
|
// Load related data
|
|
await LoadCustomerServers(customer.Id);
|
|
await LoadCustomerDevices(customer.Id);
|
|
}
|
|
|
|
private async Task LoadCustomerServers(int customerId)
|
|
{
|
|
try
|
|
{
|
|
isLoadingServers = true;
|
|
customerServers = await Http.GetFromJsonAsync<List<Server>>($"api/IntegryData/customers/{customerId}/servers");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Errore nel caricamento dei server: {ex.Message}", Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
isLoadingServers = false;
|
|
}
|
|
}
|
|
|
|
private async Task LoadCustomerDevices(int customerId)
|
|
{
|
|
try
|
|
{
|
|
isLoadingDevices = true;
|
|
customerDevices = await Http.GetFromJsonAsync<List<Device>>($"api/IntegryData/customers/{customerId}/devices");
|
|
}
|
|
finally
|
|
{
|
|
isLoadingDevices = false;
|
|
}
|
|
}
|
|
|
|
private void CloseDetailsDialog()
|
|
{
|
|
isDetailsDialogVisible = false;
|
|
selectedCustomerId = null;
|
|
customerServers = null;
|
|
customerDevices = null;
|
|
}
|
|
|
|
} |