commit
This commit is contained in:
@ -2,15 +2,17 @@
|
|||||||
@using Microsoft.EntityFrameworkCore
|
@using Microsoft.EntityFrameworkCore
|
||||||
@using TecniStamp.Domain
|
@using TecniStamp.Domain
|
||||||
@using TecniStamp.Model
|
@using TecniStamp.Model
|
||||||
|
@using TecniStamp.Utils
|
||||||
|
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
@inject AuthenticationStateProvider auth
|
||||||
|
|
||||||
<PageTitle>Operatori</PageTitle>
|
<PageTitle>Operatori</PageTitle>
|
||||||
|
|
||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
<!-- BEGIN PAGE BODY -->
|
<!-- BEGIN PAGE BODY -->
|
||||||
<div class="page-body">
|
<div class="page-body">
|
||||||
<div class="container-fluid">
|
<div class="container-xl">
|
||||||
<div class="row row-cards">
|
<div class="row row-cards">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<!-- Page pre-title -->
|
<!-- Page pre-title -->
|
||||||
@ -18,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-auto ms-auto">
|
<div class="col-auto ms-auto">
|
||||||
<div class="btn-list">
|
<div class="btn-list">
|
||||||
<a href="/Anagrafiche/Operatore/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
|
<a href="/Anagrafiche/Operatori/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
|
||||||
Nuovo Operatore
|
Nuovo Operatore
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -38,7 +40,7 @@
|
|||||||
<RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="200px">
|
<RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="200px">
|
||||||
<Template Context="user">
|
<Template Context="user">
|
||||||
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(user))" @onclick:stopPropagation="true" />
|
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(user))" @onclick:stopPropagation="true" />
|
||||||
<RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" @onclick:stopPropagation="true" />
|
<RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(user))" @onclick:stopPropagation="true" />
|
||||||
</Template>
|
</Template>
|
||||||
</RadzenDataGridColumn>
|
</RadzenDataGridColumn>
|
||||||
</Columns>
|
</Columns>
|
||||||
@ -76,4 +78,23 @@
|
|||||||
{
|
{
|
||||||
_navManager.NavigateTo($"/Anagrafiche/Operatori/Modifica/{cliente.Id}");
|
_navManager.NavigateTo($"/Anagrafiche/Operatori/Modifica/{cliente.Id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chiede conferma ed elimina l’utente; se confermato, aggiorna la lista
|
||||||
|
/// ricaricandola dal database.
|
||||||
|
/// </summary>
|
||||||
|
private async Task DeleteRow(UserViewModel user)
|
||||||
|
{
|
||||||
|
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare l'utente {user.Nome}?", "Conferma eliminazione", new ConfirmOptions { OkButtonText = "Sì", CancelButtonText = "No", Width = "400px" });
|
||||||
|
|
||||||
|
if (ok == true)
|
||||||
|
{
|
||||||
|
await _managerService.UtenteService.Elimina(user.Id, await MembershipUtils.GetUserId(auth));
|
||||||
|
utenti = (await _managerService.UtenteService.RicercaQueryable(
|
||||||
|
x => x.Eliminato == false,
|
||||||
|
includi: x => x.Include(y => y.Ruolo),
|
||||||
|
ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome)))
|
||||||
|
.Select(x => (UserViewModel)x).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,7 +54,8 @@
|
|||||||
|
|
||||||
<div class="col-3 mb-3">
|
<div class="col-3 mb-3">
|
||||||
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Ruolo</RadzenText>
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Ruolo</RadzenText>
|
||||||
<RadzenDropDown Style="width: 100%" TValue="Guid" @bind-Value=@Model.RuoloId Data=@ruoli TextProperty="Nome" ValueProperty="Id" Name="ruoliDrop" />
|
<RadzenDropDown Style="width: 100%" TValue="Guid" @bind-Value=@Model.RuoloId Data=@ruoli TextProperty="Nome" ValueProperty="Id" Name="ruoliDrop"/>
|
||||||
|
<ValidationMessage For="@(() => Model.RuoloId)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,73 @@
|
|||||||
@page "/anagrafiche/ruoli"
|
@page "/anagrafiche/ruoli"
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
@using TecniStamp.Model
|
||||||
|
|
||||||
|
<PageTitle>Ruoli</PageTitle>
|
||||||
|
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<!-- BEGIN PAGE BODY -->
|
||||||
|
<div class="page-body">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="row row-cards">
|
||||||
|
<div class="col">
|
||||||
|
<!-- Page pre-title -->
|
||||||
|
<h2 class="page-title">Ruoli</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto ms-auto">
|
||||||
|
<div class="btn-list">
|
||||||
|
<a href="/Anagrafiche/Ruoli/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
|
||||||
|
Nuovo Ruolo
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<RadzenDataGrid @ref="ruoliGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
|
||||||
|
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
|
||||||
|
Data="@ruoli" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single">
|
||||||
|
<Columns>
|
||||||
|
<RadzenDataGridColumn Property="@nameof(RuoloViewModel.Nome)" Title="Nome" Width="160px" />
|
||||||
|
|
||||||
|
<RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="200px">
|
||||||
|
<Template Context="ruolo">
|
||||||
|
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(ruolo))" @onclick:stopPropagation="true" />
|
||||||
|
<RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" @onclick:stopPropagation="true" />
|
||||||
|
</Template>
|
||||||
|
</RadzenDataGridColumn>
|
||||||
|
</Columns>
|
||||||
|
</RadzenDataGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
List<RuoloViewModel> ruoli;
|
||||||
|
RadzenDataGrid<RuoloViewModel> ruoliGrid;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Carica la lista dei ruoli non eliminati, ordinandoli per nome.
|
||||||
|
/// </summary>
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
|
ruoli = (await _managerService.RuoloService.RicercaQueryable(
|
||||||
|
x => x.Eliminato == false,
|
||||||
|
includi: x => x.Include(y => y.UtenteCreazione),
|
||||||
|
ordinamento: x => x.OrderBy(y => y.Nome)))
|
||||||
|
.Select(x => (RuoloViewModel)x).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apre la pagina di modifica per il cliente selezionato.
|
||||||
|
/// </summary>
|
||||||
|
private async Task EditRow(RuoloViewModel ruolo)
|
||||||
|
{
|
||||||
|
_navManager.NavigateTo($"/Anagrafiche/Ruoli/Modifica/{ruolo.Id}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,115 @@
|
|||||||
|
@page "/Anagrafiche/ruoli/Modifica"
|
||||||
|
@page "/Anagrafiche/ruoli/Modifica/{RuoloId:guid}"
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
@using TecniStamp.Domain
|
||||||
|
@using TecniStamp.Model
|
||||||
|
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
<PageTitle>@pageTitle</PageTitle>
|
||||||
|
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<!-- BEGIN PAGE HEADER -->
|
||||||
|
<div class="page-header d-print-none" aria-label="Page header">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="row g-2 align-items-center">
|
||||||
|
<div class="col">
|
||||||
|
<h2 class="page-title">@pageTitle</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END PAGE HEADER -->
|
||||||
|
<!-- BEGIN PAGE BODY -->
|
||||||
|
<div class="page-body">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="row row-cards">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row g-5">
|
||||||
|
<EditForm Model="Model" OnValidSubmit="onRuoloSave" FormName="editRuoloForm">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Descrizione</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Nome" @bind-Value="@Model.Nome" />
|
||||||
|
<ValidationMessage For="@(() => Model.Nome)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-4 mb-3">
|
||||||
|
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
||||||
|
Annulla
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary w-100">
|
||||||
|
Salva
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter] public Guid? RuoloId { get; set; }
|
||||||
|
|
||||||
|
public RuoloViewModel Model { get; set; } = new();
|
||||||
|
|
||||||
|
private string pageTitle => Model?.Id == Guid.Empty ? "Nuovo Ruolo" : $"Modifica Ruolo {Model}";
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
|
Model = RuoloId.GetValueOrDefault() == Guid.Empty
|
||||||
|
? new RuoloViewModel()
|
||||||
|
: await _managerService.RuoloService.RicercaPer(x => x.Id == RuoloId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Salva l’utente: recupera o crea il modello, applica le modifiche dalla UI,
|
||||||
|
/// gestisce l’hash della password se inserita e registra tutto a database
|
||||||
|
/// usando l’ID dell’utente autenticato.
|
||||||
|
/// </summary>
|
||||||
|
private async Task onRuoloSave()
|
||||||
|
{
|
||||||
|
var state = await _auth.GetAuthenticationStateAsync();
|
||||||
|
var idClaim = state.User.FindFirst("UserId")?.Value;
|
||||||
|
if (string.IsNullOrEmpty(idClaim))
|
||||||
|
{
|
||||||
|
// gestisci errore (utente non autenticato o claim mancante)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var model = await _managerService.RuoloService.RicercaPer(x => x.Id == Model.Id, solaLettura: false)
|
||||||
|
?? new Ruolo();
|
||||||
|
|
||||||
|
model = Model.Map(model);
|
||||||
|
|
||||||
|
await _managerService.UtenteService.Salva(model, Guid.Parse(idClaim));
|
||||||
|
_navManager.NavigateTo($"/Anagrafiche/ruoli/Modifica/{Model.Id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Torna all’elenco utenti senza applicare altre azioni.
|
||||||
|
/// </summary>
|
||||||
|
private void backToHome()
|
||||||
|
{
|
||||||
|
_navManager.NavigateTo("/Anagrafiche/Operatori");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +1,24 @@
|
|||||||
using TecniStamp.Domain;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using TecniStamp.Domain;
|
||||||
|
|
||||||
namespace TecniStamp.Model;
|
namespace TecniStamp.Model;
|
||||||
|
|
||||||
public class UserViewModel : BaseViewModel
|
public class UserViewModel : BaseViewModel
|
||||||
{
|
{
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "L'email è obbligatoria")]
|
||||||
|
[EmailAddress(ErrorMessage = "Formato email non valido")]
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Il nome è obbligatorio")]
|
||||||
public string Nome { get; set; }
|
public string Nome { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Il cognome è obbligatorio")]
|
||||||
public string Cognome { get; set; }
|
public string Cognome { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Il ruolo è obbligatorio")]
|
||||||
public Guid RuoloId { get; set; }
|
public Guid RuoloId { get; set; }
|
||||||
public string Ruolo { get; set; }
|
public string Ruolo { get; set; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user