Ruolo di default e permessi

This commit is contained in:
2026-02-06 21:19:25 +01:00
parent b24dbc8fc3
commit 85d099e372
16 changed files with 1532 additions and 50 deletions

View File

@ -16,4 +16,5 @@ public class Ruolo : EntitaBase
[InverseProperty(nameof(Permission.Ruolo))]
public virtual List<Permission> Permessi { get; set; }
public virtual bool Default { get; set; }
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace StandManager.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class RuoloDiDefault : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "Default",
table: "Ruolo",
type: "bit",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Default",
table: "Ruolo");
}
}
}

View File

@ -728,6 +728,9 @@ namespace StandManager.Infrastructure.Migrations
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Default")
.HasColumnType("bit");
b.Property<bool>("Eliminato")
.HasColumnType("bit");

View File

@ -47,11 +47,27 @@
<!-- BEGIN NAVBAR MENU -->
<ul class="navbar-nav">
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management" destination="/management" iconName="fa-home" title="Home"/>
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Utenti" destination="/management/Utenti" iconName="fa-user" title="Utenti"/>
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Clienti" destination="/management/Clienti" iconName="fa-address-card" title="Clienti"/>
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Eventi" destination="/management/Eventi" iconName="fa-calendar" title="Eventi"/>
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Ruoli" destination="/management/Ruoli" iconName="fa-lock" title="Ruoli"/>
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Iscrizioni" destination="/management/Iscrizioni" iconName="fa-lock" title="Iscrizioni"/>
@if (canSeeUser)
{
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Utenti" destination="/management/Utenti" iconName="fa-user" title="Utenti"/>
}
@if (canSeeClienti)
{
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Clienti" destination="/management/Clienti" iconName="fa-address-card" title="Clienti"/>
}
@if (canSeeEventi)
{
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Eventi" destination="/management/Eventi" iconName="fa-calendar" title="Eventi"/>
}
@if (canSeeRuoli)
{
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Ruoli" destination="/management/Ruoli" iconName="fa-lock" title="Ruoli"/>
}
@if (canSeeIscrizioni)
{
<NavigationItem currentUrl="@currentUrl" requiredUrl="/management/Iscrizioni" destination="/management/Iscrizioni" iconName="fa-lock" title="Iscrizioni"/>
}
</ul>
</div>
</div>
@ -68,10 +84,23 @@
public HttpContext? httpContext { get; set; }
private string currentUrl = string.Empty;
private MembershipUtilsPermission _permission { get; set; }
private bool canSeeUser = false;
private bool canSeeClienti = false;
private bool canSeeEventi = false;
private bool canSeeRuoli = false;
private bool canSeeIscrizioni = false;
protected override async Task OnInitializedAsync()
{
base.OnInitializedAsync();
currentUrl = NavManager.ToBaseRelativePath(NavManager.Uri);
_permission = new MembershipUtilsPermission(_managerService, _auth);
canSeeUser = await _permission.CheckPermission("InsertUser");
canSeeClienti = await _permission.CheckPermission("InsertCustomer");
canSeeEventi = await _permission.CheckPermission("InsertEvent");
canSeeRuoli = await _permission.CheckPermission("InsertRole");
canSeeIscrizioni = await _permission.CheckPermission("SeeRegistration");
}
}

View File

@ -48,7 +48,8 @@
<div class="row">
<div class="col-4 mb-3">
<RadzenFormField Text="Provincia" Variant="Variant.Flat" Style="width: 100%;">
<RadzenDropDown TValue="Guid ?" @bind-Value="@iscrizione.ProvinciaId" Change="@(args => onProvinciaChanged(args))" Style="width: 100%" TextProperty="Info" ValueProperty="Id" Placeholder="Seleziona la provincia"
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
TValue="Guid ?" @bind-Value="@iscrizione.ProvinciaId" Change="@(args => onProvinciaChanged(args))" Style="width: 100%" TextProperty="Info" ValueProperty="Id" Placeholder="Seleziona la provincia"
Data="@provList" Size="ButtonSize.Small" />
</RadzenFormField>
</div>
@ -59,7 +60,8 @@
</div>
<div class="col-4 mb-3">
<RadzenFormField Text="Comune" Variant="Variant.Flat" Style="width: 100%;">
<RadzenDropDown TValue="Guid ?" @bind-Value="@iscrizione.ComuneId" Style="width: 100%" TextProperty="Info" ValueProperty="Id" Placeholder="Seleziona il comune"
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
TValue="Guid ?" @bind-Value="@iscrizione.ComuneId" Style="width: 100%" TextProperty="Info" ValueProperty="Id" Placeholder="Seleziona il comune"
Data="@comuniList" Size="ButtonSize.Small" />
</RadzenFormField>
</div>
@ -113,7 +115,8 @@
{
<div class="col-6 mb-3">
<RadzenFormField Text="Destinazione" Variant="Variant.Flat" Style="width: 100%;">
<RadzenDropDown @bind-Value="@iscrizione.DestinazioneId" TValue="Guid ?" Style="width: 100%" ValueProperty="Id" TextProperty="Info" Placeholder="Seleziona la destinazione"
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
@bind-Value="@iscrizione.DestinazioneId" TValue="Guid ?" Style="width: 100%" ValueProperty="Id" TextProperty="Info" Placeholder="Seleziona la destinazione"
Data="@destinazioniList" Size="ButtonSize.Small" />
</RadzenFormField>
</div>

View File

@ -21,15 +21,15 @@
</div>
<div class="col-auto ms-auto">
<div class="btn-list">
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUpload ChooseText="Importa da excel" />
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUploadComuni ChooseText="Importa comuni da excel" />
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUploadProvince ChooseText="Importa province da excel" />
<a href="/management/Clienti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo cliente
</a>
@if (canAdd)
{
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUpload ChooseText="Importa da excel"/>
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUploadComuni ChooseText="Importa comuni da excel"/>
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUploadProvince ChooseText="Importa province da excel"/>
<a href="/management/Clienti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo cliente
</a>
}
</div>
</div>
<div class="col-lg-12">
@ -46,8 +46,8 @@
<RadzenDataGridColumn Context="cliente" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Width="250px">
<Template Context="cliente">
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(cliente))" @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(cliente))" @onclick:stopPropagation="true" />
<RadzenButton Icon="edit" Visible="canEdit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(cliente))" @onclick:stopPropagation="true" />
<RadzenButton Icon="delete" Visible="canDelete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(cliente))" @onclick:stopPropagation="true" />
</Template>
</RadzenDataGridColumn>
</Columns>
@ -64,6 +64,10 @@
List<Cliente> clienti;
RadzenDataGrid<Cliente> clientiGrid;
private bool canAdd = false;
private bool canEdit = false;
private bool canDelete = false;
/// <summary>
/// Carica lelenco dei clienti non eliminati, includendo lagente,
/// e prepara i dati per la visualizzazione in pagina.
@ -77,6 +81,10 @@
includi: x => x.Include(y => y.Agente).Include(y => y.Capoarea),
ordinamento: x => x.OrderBy(y => y.RagioneSociale)))
.ToList();
var permissionUtils = new MembershipUtilsPermission(_managerService, _auth);
canAdd = await permissionUtils.CheckPermission("InsertUser");
canEdit = await permissionUtils.CheckPermission("EditCustomer");
canDelete = await permissionUtils.CheckPermission("DeleteCustomer");
}
/// <summary>
@ -84,6 +92,8 @@
/// </summary>
private async Task EditRow(ClienteViewModel cliente)
{
if (!canEdit)
return;
_navManager.NavigateTo($"/management/Clienti/Modifica/{cliente.Id}");
}
@ -93,6 +103,9 @@
/// </summary>
private async Task DeleteRow(ClienteViewModel cliente)
{
if (!canDelete)
return;
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare il cliente {cliente.RagioneSociale}?", "Conferma eliminazione", new ConfirmOptions { OkButtonText = "Sì", CancelButtonText = "No", Width = "400px" });
if (ok == true)
@ -105,6 +118,8 @@
private async Task onUpload(UploadChangeEventArgs args)
{
if(!canAdd)
return;
var file = args.Files.FirstOrDefault();
if (file == null ||
!file.Name.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
@ -126,6 +141,8 @@
private async Task onUploadComuni(UploadChangeEventArgs args)
{
if(!canAdd)
return;
var file = args.Files.FirstOrDefault();
if (file == null ||
!file.Name.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
@ -147,6 +164,8 @@
private async Task onUploadProvince(UploadChangeEventArgs args)
{
if(!canAdd)
return;
var file = args.Files.FirstOrDefault();
if (file == null ||
!file.Name.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))

View File

@ -84,12 +84,14 @@
<div class="row">
<div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Agente</RadzenText>
<RadzenDropDown Style="width: 100%" TValue="Guid ?" @bind-Value=@cliente.AgenteId Data=@agenti TextProperty="Info" ValueProperty="Id" Name="agenteDrop" Disabled="@(!(cliente.CapoareaId == idClaim) && !isAdmin)" />
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Capoarea</RadzenText>
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
Style="width: 100%" TValue="Guid ?" @bind-Value=@cliente.CapoareaId Data=@capiarea TextProperty="Info" ValueProperty="Id" Name="capoareaDrop" Disabled="!isAdmin" Change="(x => OnCapoareaChange(x))" />
</div>
<div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Capoarea</RadzenText>
<RadzenDropDown Style="width: 100%" TValue="Guid ?" @bind-Value=@cliente.CapoareaId Data=@capiarea TextProperty="Info" ValueProperty="Id" Name="capoareaDrop" Disabled="!isAdmin" Change="(x => OnCapoareaChange(x))" />
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Agente</RadzenText>
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
Style="width: 100%" TValue="Guid ?" @bind-Value=@cliente.AgenteId Data=@agenti TextProperty="Info" ValueProperty="Id" Name="agenteDrop" Disabled="@(!(cliente.CapoareaId == idClaim) && !isAdmin)" />
</div>
</div>

View File

@ -21,9 +21,12 @@
</div>
<div class="col-auto ms-auto">
<div class="btn-list">
<a href="/management/Eventi/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo evento
</a>
@if (canAdd)
{
<a href="/management/Eventi/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo evento
</a>
}
</div>
</div>
<div class="col-lg-12">
@ -39,9 +42,9 @@
<RadzenDataGridColumn Context="evento" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Width="250px">
<Template Context="evento">
<RadzenButton Icon="calendar_clock" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => SendInvitation(evento))" @onclick:stopPropagation="true" MouseEnter="@(args => ShowTooltip(args, new TooltipOptions() { Text = "Invia invito" }))" />
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(evento))" @onclick:stopPropagation="true" MouseEnter="@(args => ShowTooltip(args, new TooltipOptions() { Text = "Modifica evento" }))" />
<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(evento))" @onclick:stopPropagation="true" MouseEnter="@(args => ShowTooltip(args, new TooltipOptions() { Text = "Rimuovi evento" }))" />
<RadzenButton Visible="canEdit" Icon="calendar_clock" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => SendInvitation(evento))" @onclick:stopPropagation="true" MouseEnter="@(args => ShowTooltip(args, new TooltipOptions() { Text = "Invia invito" }))" />
<RadzenButton Visible="canEdit" Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(evento))" @onclick:stopPropagation="true" MouseEnter="@(args => ShowTooltip(args, new TooltipOptions() { Text = "Modifica evento" }))" />
<RadzenButton Visible="canDelete" Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(evento))" @onclick:stopPropagation="true" MouseEnter="@(args => ShowTooltip(args, new TooltipOptions() { Text = "Rimuovi evento" }))" />
</Template>
</RadzenDataGridColumn>
</Columns>
@ -58,20 +61,32 @@
List<EventoViewModel> eventi;
RadzenDataGrid<EventoViewModel> eventiGrid;
private bool canAdd = false;
private bool canEdit = false;
private bool canDelete = false;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
eventi = (await _managerService.EventoService.RicercaQueryable(x => x.Eliminato == false)).Select(x => (EventoViewModel)x).ToList();
var permissionUtils = new MembershipUtilsPermission(_managerService, _auth);
canAdd = await permissionUtils.CheckPermission("InsertEvent");
canEdit = await permissionUtils.CheckPermission("EditEvent");
canDelete = await permissionUtils.CheckPermission("DeleteEvent");
}
private async Task EditRow(EventoViewModel evento)
{
if(!canEdit)
return;
_navManager.NavigateTo($"/management/Eventi/Modifica/{evento.Id}");
}
private async Task DeleteRow(EventoViewModel evento)
{
if(!canDelete)
return;
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare l'evento {evento.Titolo}?", "Conferma eliminazione", new ConfirmOptions { OkButtonText = "Sì", CancelButtonText = "No", Width = "400px" });
if (ok == true)

View File

@ -33,7 +33,7 @@
<RadzenDataGridColumn Context="iscrizioni" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Width="250px">
<Template Context="iscrizioni">
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(iscrizioni))" @onclick:stopPropagation="true" />
<RadzenButton Visible="canEdit" Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(iscrizioni))" @onclick:stopPropagation="true" />
</Template>
</RadzenDataGridColumn>
</Columns>
@ -50,6 +50,10 @@
List<IscrizioneEventoViewModel> iscrizioni;
RadzenDataGrid<IscrizioneEventoViewModel> iscrizioniGrid;
private bool canSee = false;
private bool canEdit = false;
protected override async Task OnInitializedAsync()
{
@ -61,6 +65,12 @@
.Include(y => y.Evento).Include(y => y.InvitoEvento).Include(y => y.Agente).Include(y => y.Capoarea),
ordinamento: x => x.OrderByDescending(y => y.DataCreazione)))
.Select(x => (IscrizioneEventoViewModel)x).ToList();
var permissionUtils = new MembershipUtilsPermission(_managerService, _auth);
canSee = await permissionUtils.CheckPermission("SeeRegistration");
canEdit = await permissionUtils.CheckPermission("EditRegistration");
if (!canSee)
_navManager.NavigateTo("/management");
}
private void RowRender(RowRenderEventArgs<IscrizioneEventoViewModel> args)

View File

@ -118,7 +118,8 @@
<div class="row">
<div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Capoarea</RadzenText>
<RadzenDropDown Style="width: 100%" TValue="Guid ?" @bind-Value=@iscrizione.CapoareaId Data=@capiarea TextProperty="Info" ValueProperty="Id" Name="capoareaDrop" Change="(x => OnCapoareaChange(x))" />
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
Style="width: 100%" TValue="Guid ?" @bind-Value=@iscrizione.CapoareaId Data=@capiarea TextProperty="Info" ValueProperty="Id" Name="capoareaDrop" Change="(x => OnCapoareaChange(x))" />
<RadzenAlert AlertStyle="AlertStyle.Danger" ShowIcon="false" Variant="Variant.Flat" Shade="Shade.Lighter" Visible="capoareaDaConfermare" AllowClose="false">
Capoarea da confermare
</RadzenAlert>
@ -126,7 +127,8 @@
<div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Agente</RadzenText>
<RadzenDropDown Style="width: 100%" TValue="Guid ?" @bind-Value=@iscrizione.AgenteId Data=@agenti TextProperty="Info" ValueProperty="Id" Name="agenteDrop" Disabled="@(agenti.Count() == 0)" />
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
Style="width: 100%" TValue="Guid ?" @bind-Value=@iscrizione.AgenteId Data=@agenti TextProperty="Info" ValueProperty="Id" Name="agenteDrop" Disabled="@(agenti.Count() == 0)" />
</div>
</div>
@ -189,7 +191,7 @@
ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome)))
.Select(x => (UtenteViewModel)x).ToList();
if (iscrizione.ProvinciaId.HasValue && iscrizione.CapoareaId.GetValueOrDefault() == Guid.Empty)
if (iscrizione.ProvinciaId.GetValueOrDefault() != Guid.Empty && iscrizione.CapoareaId.GetValueOrDefault() == Guid.Empty)
{
capoareaDaConfermare = true;
var dbProv = await _managerService.ProvinciaIstatService.RicercaPer(x => x.Id == iscrizione.ProvinciaId);

View File

@ -18,9 +18,12 @@
</div>
<div class="col-auto ms-auto">
<div class="btn-list">
<a href="/management/Ruoli/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo ruolo
</a>
@if (canAdd)
{
<a href="/management/Ruoli/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo ruolo
</a>
}
</div>
</div>
<div class="col-lg-12">
@ -34,8 +37,8 @@
<RadzenDataGridColumn Context="ruolo" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Width="250px">
<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" Click="@(args => DeleteRow(ruolo))" @onclick:stopPropagation="true" />
<RadzenButton Visible="canEdit" 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 Visible="canDelete" Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(ruolo))" @onclick:stopPropagation="true" />
</Template>
</RadzenDataGridColumn>
</Columns>
@ -51,6 +54,9 @@
@code {
List<RuoloViewModel> ruoli;
private bool canAdd = false;
private bool canEdit = false;
private bool canDelete = false;
/// <summary>
/// Carica lelenco dei clienti non eliminati, includendo lagente,
/// e prepara i dati per la visualizzazione in pagina.
@ -63,6 +69,11 @@
x => x.Eliminato == false,
ordinamento: x => x.OrderBy(y => y.Nome)))
.Select(x => (RuoloViewModel)x).ToList();
var permissionUtils = new MembershipUtilsPermission(_managerService, _auth);
canAdd = await permissionUtils.CheckPermission("InsertRole");
canEdit = await permissionUtils.CheckPermission("EditRole");
canDelete = await permissionUtils.CheckPermission("DeleteRole");
}
/// <summary>

View File

@ -23,9 +23,12 @@
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUpload ChooseText="Importa mail utenti da CSV" />
<a href="/management/Utenti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo utente
</a>
@if (canAdd)
{
<a href="/management/Utenti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo utente
</a>
}
</div>
</div>
<div class="col-lg-12">
@ -43,8 +46,8 @@
<RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Width="200px">
<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="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" />
<RadzenButton Visible="canEdit" 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 Visible="canDelete" 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>
</RadzenDataGridColumn>
</Columns>
@ -61,6 +64,11 @@
IQueryable<Utente> utenti;
RadzenDataGrid<Utente> userGrid;
private Ruolo? ruolo;
private bool canAdd = false;
private bool canEdit = false;
private bool canDelete = false;
/// <summary>
/// Carica la lista degli utenti non eliminati, ordinandoli per cognome e nome.
@ -73,6 +81,11 @@
x => x.Eliminato == false,
includi: x => x.Include(y => y.Ruolo).Include(y => y.Capoarea),
ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome));
var permissionUtils = new MembershipUtilsPermission(_managerService, _auth);
canAdd = await permissionUtils.CheckPermission("InsertUser");
canEdit = await permissionUtils.CheckPermission("EditUser");
canDelete = await permissionUtils.CheckPermission("DeleteUser");
}
/// <summary>

View File

@ -67,7 +67,8 @@
</div>
<div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Capoarea</RadzenText>
<RadzenDropDown Style="width: 100%" TValue="Guid?" @bind-Value=@utente.CapoareaId Data=@capoareaList TextProperty="Nome" ValueProperty="Id" Name="capoareaDrop\" />
<RadzenDropDown FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.Contains" AllowFiltering="true"
Style="width: 100%" TValue="Guid?" @bind-Value=@utente.CapoareaId Data=@capoareaList TextProperty="Nome" ValueProperty="Id" Name="capoareaDrop\" />
</div>
<div class="col-3 mb-3">
@ -125,13 +126,13 @@
ruoli = (await _managerService.RuoloService.RicercaQueryable(x => x.Eliminato == false))
.Select(x => (RuoloViewModel)x).ToList();
var ruoliCapoarea = await _managerService.RuoloService.RicercaQueryable(
x => x.Permessi.Any(y => y.Feature.Type == FeatureType.AdminGlobal || y.Feature.Type == FeatureType.Capoarea),
includi: x => x.Include(y => y.Permessi).ThenInclude(z => z.Feature));
capoareaList = (await _managerService.UtenteService.RicercaQueryable(x => x.IsCapoarea,
ordinamento:y => y.OrderBy(z => z.Nome).ThenBy(w => w.Cognome)))
.Select(x => (UtenteViewModel)x).ToList();
if (utente.Id == Guid.Empty)
utente.RuoloId = ruoli.FirstOrDefault(x => x.Default)?.Id;
}
/// <summary>

View File

@ -6,6 +6,7 @@ public class RuoloViewModel
{
public Guid Id { get; set; }
public string Nome { get; set; }
public bool Default { get; set; }
public static implicit operator RuoloViewModel(Ruolo model)
{
@ -14,7 +15,8 @@ public class RuoloViewModel
: new RuoloViewModel()
{
Nome = model.Nome,
Id = model.Id
Id = model.Id,
Default = model.Default
};
}
}

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components.Authorization;
using StandManager.Service.Interfaces;
namespace StandManager.Utils;
@ -20,3 +21,27 @@ public static class MembershipUtils
return Guid.Parse(idClaim ?? Guid.Empty.ToString());
}
}
public partial class MembershipUtilsPermission
{
private readonly IManagerService _managerService;
private readonly AuthenticationStateProvider _auth;
public MembershipUtilsPermission(IManagerService managerService, AuthenticationStateProvider auth)
{
_managerService = managerService;
_auth = auth;
}
public async Task<bool> CheckPermission(string featureName)
{
var state = await _auth.GetAuthenticationStateAsync();
var idClaim = state.User.FindFirst("RoleId")?.Value;
var parsed = Guid.Parse(idClaim ?? Guid.Empty.ToString());
var perm = await _managerService.RuoloService.RicercaPer(x =>
x.Id == parsed && x.Permessi.Any(y => y.Feature.Nome == featureName && y.Eliminato == false) && x.Eliminato == false);
return perm != null;
}
}