Capoarea
This commit is contained in:
2
.idea/config/applicationhost.config
generated
2
.idea/config/applicationhost.config
generated
@ -156,7 +156,7 @@
|
||||
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||
<site name="StandManager" id="1">
|
||||
<application path="/" applicationPool="StandManager AppPool">
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\g.vitari\Documents\Git\StandManager\StandManager" />
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\g.vitari\Documents\Git\StandManager_Locale\StandManager" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:21401:localhost" />
|
||||
|
||||
@ -19,6 +19,10 @@ public class Cliente : EntitaBase
|
||||
public Guid? AgenteId { get; set; }
|
||||
public Utente Agente { get; set; }
|
||||
|
||||
[ForeignKey(nameof(Capoarea))]
|
||||
public Guid? CapoareaId { get; set; }
|
||||
public Utente Capoarea { get; set; }
|
||||
|
||||
[InverseProperty(nameof(Destinazione.Cliente))]
|
||||
public List<Destinazione> Destinazioni { get; set; }
|
||||
|
||||
|
||||
@ -17,5 +17,6 @@ public enum FeatureType
|
||||
Insert = 0,
|
||||
Edit,
|
||||
Delete,
|
||||
Capoarea = 50,
|
||||
AdminGlobal = 100
|
||||
}
|
||||
|
||||
@ -21,6 +21,10 @@ public class Utente : EntitaBase
|
||||
public Guid? RuoloId { get; set; }
|
||||
public Ruolo Ruolo { get; set; }
|
||||
|
||||
[ForeignKey(nameof(Capoarea))]
|
||||
public Guid? CapoareaId { get; set; }
|
||||
public Utente Capoarea { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Nome} {Cognome}";
|
||||
|
||||
1022
StandManager.Infrastructure/Migrations/20251217125158_Capoarea.Designer.cs
generated
Normal file
1022
StandManager.Infrastructure/Migrations/20251217125158_Capoarea.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace StandManager.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Capoarea : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "CapoareaId",
|
||||
table: "Utente",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "CapoareaId",
|
||||
table: "Cliente",
|
||||
type: "uniqueidentifier",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Utente_CapoareaId",
|
||||
table: "Utente",
|
||||
column: "CapoareaId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Cliente_CapoareaId",
|
||||
table: "Cliente",
|
||||
column: "CapoareaId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Cliente_Utente_CapoareaId",
|
||||
table: "Cliente",
|
||||
column: "CapoareaId",
|
||||
principalTable: "Utente",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Utente_Utente_CapoareaId",
|
||||
table: "Utente",
|
||||
column: "CapoareaId",
|
||||
principalTable: "Utente",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Cliente_Utente_CapoareaId",
|
||||
table: "Cliente");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Utente_Utente_CapoareaId",
|
||||
table: "Utente");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Utente_CapoareaId",
|
||||
table: "Utente");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Cliente_CapoareaId",
|
||||
table: "Cliente");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CapoareaId",
|
||||
table: "Utente");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CapoareaId",
|
||||
table: "Cliente");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,9 @@ namespace StandManager.Infrastructure.Migrations
|
||||
b.Property<string>("Cap")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<Guid?>("CapoareaId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("Citta")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
@ -85,6 +88,8 @@ namespace StandManager.Infrastructure.Migrations
|
||||
|
||||
b.HasIndex("AgenteId");
|
||||
|
||||
b.HasIndex("CapoareaId");
|
||||
|
||||
b.HasIndex("IdUtenteCreazione");
|
||||
|
||||
b.HasIndex("IdUtenteModifica");
|
||||
@ -633,6 +638,9 @@ namespace StandManager.Infrastructure.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<Guid?>("CapoareaId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("CodiceAgente")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
@ -676,6 +684,8 @@ namespace StandManager.Infrastructure.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CapoareaId");
|
||||
|
||||
b.HasIndex("IdUtenteCreazione");
|
||||
|
||||
b.HasIndex("IdUtenteModifica");
|
||||
@ -691,6 +701,10 @@ namespace StandManager.Infrastructure.Migrations
|
||||
.WithMany()
|
||||
.HasForeignKey("AgenteId");
|
||||
|
||||
b.HasOne("StandManager.Domain.Entita.Utente", "Capoarea")
|
||||
.WithMany()
|
||||
.HasForeignKey("CapoareaId");
|
||||
|
||||
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdUtenteCreazione");
|
||||
@ -705,6 +719,8 @@ namespace StandManager.Infrastructure.Migrations
|
||||
|
||||
b.Navigation("Agente");
|
||||
|
||||
b.Navigation("Capoarea");
|
||||
|
||||
b.Navigation("TipologiaCliente");
|
||||
|
||||
b.Navigation("UtenteCreazione");
|
||||
@ -946,6 +962,10 @@ namespace StandManager.Infrastructure.Migrations
|
||||
|
||||
modelBuilder.Entity("StandManager.Domain.Entita.Utente", b =>
|
||||
{
|
||||
b.HasOne("StandManager.Domain.Entita.Utente", "Capoarea")
|
||||
.WithMany()
|
||||
.HasForeignKey("CapoareaId");
|
||||
|
||||
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdUtenteCreazione");
|
||||
@ -958,6 +978,8 @@ namespace StandManager.Infrastructure.Migrations
|
||||
.WithMany("Utenti")
|
||||
.HasForeignKey("RuoloId");
|
||||
|
||||
b.Navigation("Capoarea");
|
||||
|
||||
b.Navigation("Ruolo");
|
||||
|
||||
b.Navigation("UtenteCreazione");
|
||||
|
||||
13
StandManager.Service/FeatureService.cs
Normal file
13
StandManager.Service/FeatureService.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using OAService.Service.Servizi.Implementazioni;
|
||||
using StandManager.Domain.Entita;
|
||||
using StandManager.Service.Interfaces;
|
||||
using StandManager.Service.Repository;
|
||||
|
||||
namespace StandManager.Service;
|
||||
|
||||
public class FeatureService : TService<Feature>, IFeatureService
|
||||
{
|
||||
public FeatureService(IStandManagerUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
}
|
||||
9
StandManager.Service/Interfaces/IFeatureService.cs
Normal file
9
StandManager.Service/Interfaces/IFeatureService.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using OAService.Service.Repository;
|
||||
using OAService.Service.Servizi.Interfacce;
|
||||
using StandManager.Domain.Entita;
|
||||
|
||||
namespace StandManager.Service.Interfaces;
|
||||
|
||||
public interface IFeatureService : ITService<Feature>
|
||||
{
|
||||
}
|
||||
@ -5,9 +5,13 @@
|
||||
public IClienteService ClienteService{ get; set; }
|
||||
public IDestinazioneService DestinazioneService{ get; set; }
|
||||
public IEventoService EventoService{ get; set; }
|
||||
public IFeatureService FeatureService{ get; set; }
|
||||
public IInvitoEventoService InvitoEventoService{ get; set; }
|
||||
public IIscrizioneEventoService IscrizioneEventoService{ get; set; }
|
||||
public IPermissionService PermissionService{ get; set; }
|
||||
public IReferenteService ReferenteService{ get; set; }
|
||||
public IRuoloService RuoloService{ get; set; }
|
||||
public ISezioneService SezioneService{ get; set; }
|
||||
public ITipologiaClienteService TipologiaClienteService { get; set; }
|
||||
public IUtenteService UtenteService { get; set; }
|
||||
}
|
||||
|
||||
9
StandManager.Service/Interfaces/IPermissionService.cs
Normal file
9
StandManager.Service/Interfaces/IPermissionService.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using OAService.Service.Repository;
|
||||
using OAService.Service.Servizi.Interfacce;
|
||||
using StandManager.Domain.Entita;
|
||||
|
||||
namespace StandManager.Service.Interfaces;
|
||||
|
||||
public interface IPermissionService : ITService<Permission>
|
||||
{
|
||||
}
|
||||
9
StandManager.Service/Interfaces/IRuoloService.cs
Normal file
9
StandManager.Service/Interfaces/IRuoloService.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using OAService.Service.Repository;
|
||||
using OAService.Service.Servizi.Interfacce;
|
||||
using StandManager.Domain.Entita;
|
||||
|
||||
namespace StandManager.Service.Interfaces;
|
||||
|
||||
public interface IRuoloService : ITService<Ruolo>
|
||||
{
|
||||
}
|
||||
9
StandManager.Service/Interfaces/ISezioneService.cs
Normal file
9
StandManager.Service/Interfaces/ISezioneService.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using OAService.Service.Repository;
|
||||
using OAService.Service.Servizi.Interfacce;
|
||||
using StandManager.Domain.Entita;
|
||||
|
||||
namespace StandManager.Service.Interfaces;
|
||||
|
||||
public interface ISezioneService : ITService<Sezione>
|
||||
{
|
||||
}
|
||||
@ -6,7 +6,7 @@ public class ManagerService : IManagerService
|
||||
{
|
||||
public ManagerService(IUtenteService utenteService, IClienteService clienteService, IDestinazioneService destinazioneService, IEventoService eventoService,
|
||||
IInvitoEventoService invitoEventoService, IIscrizioneEventoService iscrizioneEventoService, IReferenteService referenteService,
|
||||
ITipologiaClienteService tipologiaClienteService)
|
||||
ITipologiaClienteService tipologiaClienteService, IFeatureService featureService, IPermissionService permissionService, IRuoloService ruoloService, ISezioneService sezioneService)
|
||||
{
|
||||
UtenteService = utenteService;
|
||||
ClienteService = clienteService;
|
||||
@ -16,14 +16,22 @@ public class ManagerService : IManagerService
|
||||
IscrizioneEventoService = iscrizioneEventoService;
|
||||
ReferenteService = referenteService;
|
||||
TipologiaClienteService = tipologiaClienteService;
|
||||
FeatureService = featureService;
|
||||
PermissionService = permissionService;
|
||||
RuoloService = ruoloService;
|
||||
SezioneService = sezioneService;
|
||||
}
|
||||
|
||||
public IUtenteService UtenteService { get; set; }
|
||||
public IClienteService ClienteService { get; set; }
|
||||
public IDestinazioneService DestinazioneService { get; set; }
|
||||
public IEventoService EventoService { get; set; }
|
||||
public IFeatureService FeatureService { get; set; }
|
||||
public IInvitoEventoService InvitoEventoService{ get; set; }
|
||||
public IIscrizioneEventoService IscrizioneEventoService { get; set; }
|
||||
public IPermissionService PermissionService { get; set; }
|
||||
public IReferenteService ReferenteService { get; set; }
|
||||
public IRuoloService RuoloService { get; set; }
|
||||
public ISezioneService SezioneService { get; set; }
|
||||
public ITipologiaClienteService TipologiaClienteService { get; set; }
|
||||
}
|
||||
13
StandManager.Service/PermissionService.cs
Normal file
13
StandManager.Service/PermissionService.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using OAService.Service.Servizi.Implementazioni;
|
||||
using StandManager.Domain.Entita;
|
||||
using StandManager.Service.Interfaces;
|
||||
using StandManager.Service.Repository;
|
||||
|
||||
namespace StandManager.Service;
|
||||
|
||||
public class PermissionService : TService<Permission>, IPermissionService
|
||||
{
|
||||
public PermissionService(IStandManagerUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
}
|
||||
13
StandManager.Service/RuoloService.cs
Normal file
13
StandManager.Service/RuoloService.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using OAService.Service.Servizi.Implementazioni;
|
||||
using StandManager.Domain.Entita;
|
||||
using StandManager.Service.Interfaces;
|
||||
using StandManager.Service.Repository;
|
||||
|
||||
namespace StandManager.Service;
|
||||
|
||||
public class RuoloService : TService<Ruolo>, IRuoloService
|
||||
{
|
||||
public RuoloService(IStandManagerUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
}
|
||||
13
StandManager.Service/SezioneService.cs
Normal file
13
StandManager.Service/SezioneService.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using OAService.Service.Servizi.Implementazioni;
|
||||
using StandManager.Domain.Entita;
|
||||
using StandManager.Service.Interfaces;
|
||||
using StandManager.Service.Repository;
|
||||
|
||||
namespace StandManager.Service;
|
||||
|
||||
public class SezioneService : TService<Sezione>, ISezioneService
|
||||
{
|
||||
public SezioneService(IStandManagerUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -43,40 +43,14 @@
|
||||
<div class="container-xl">
|
||||
<div class="row flex-column flex-md-row flex-fill align-items-center">
|
||||
<div class="col">
|
||||
|
||||
<!-- BEGIN NAVBAR MENU -->
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item @GetActiveClass("/management")">
|
||||
<a class="nav-link" href="/management">
|
||||
<span class="nav-link-icon d-md-none d-lg-inline-block">
|
||||
<i class="fa-solid fa-house"></i>
|
||||
</span>
|
||||
<span class="nav-link-title"> Home </span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item @GetActiveClass("/management/Utenti")">
|
||||
<a class="nav-link" href="/management/Utenti">
|
||||
<span class="nav-link-icon d-md-none d-lg-inline-block">
|
||||
<i class="fa-solid fa-user"></i>
|
||||
</span>
|
||||
<span class="nav-link-title"> Utenti </span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item @GetActiveClass("/management/Clienti")">
|
||||
<a class="nav-link" href="/management/Clienti">
|
||||
<span class="nav-link-icon d-md-none d-lg-inline-block">
|
||||
<i class="fa-solid fa-address-card"></i>
|
||||
</span>
|
||||
<span class="nav-link-title"> Clienti </span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item @GetActiveClass("/management/Eventi")">
|
||||
<a class="nav-link" href="/management/Eventi">
|
||||
<span class="nav-link-icon d-md-none d-lg-inline-block">
|
||||
<i class="fa-solid fa-calendar"></i>
|
||||
</span>
|
||||
<span class="nav-link-title"> Eventi </span>
|
||||
</a>
|
||||
</li>
|
||||
<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"/>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -99,20 +73,4 @@
|
||||
base.OnInitializedAsync();
|
||||
currentUrl = NavManager.ToBaseRelativePath(NavManager.Uri);
|
||||
}
|
||||
|
||||
private string GetActiveClass(string href)
|
||||
{
|
||||
string currentClean = currentUrl.Split("management").Last();
|
||||
string hrefClean = href.Split("management").Last();
|
||||
|
||||
|
||||
if (currentClean.Contains("?"))
|
||||
currentClean = currentClean.Substring(0, currentClean.IndexOf("?"));
|
||||
|
||||
var isActive = (currentClean.Contains(hrefClean, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(hrefClean)
|
||||
|| (string.IsNullOrEmpty(hrefClean) && string.IsNullOrEmpty(currentClean)));
|
||||
|
||||
return isActive ? "active" : "";
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
@implements IDisposable
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">StandManager</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
|
||||
|
||||
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
|
||||
<nav class="flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="weather">
|
||||
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="auth">
|
||||
<span class="bi bi-lock-nav-menu" aria-hidden="true"></span> Auth Required
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="/Management">
|
||||
<span class="bi bi-person-fill-nav-menu" aria-hidden="true"></span> @context.User.Identity?.Name
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<input type="hidden" name="ReturnUrl" value="@currentUrl" />
|
||||
<button @onclick="onLogoutPressed" class="nav-link">
|
||||
<span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true"></span> Logout
|
||||
</button>
|
||||
</div>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="Account/Register">
|
||||
<span class="bi bi-person-nav-menu" aria-hidden="true"></span> Register
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="/management/login">
|
||||
<span class="bi bi-person-badge-nav-menu" aria-hidden="true"></span> Login
|
||||
</NavLink>
|
||||
</div>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private string? currentUrl;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
currentUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
|
||||
NavigationManager.LocationChanged += OnLocationChanged;
|
||||
}
|
||||
|
||||
private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
|
||||
{
|
||||
currentUrl = NavigationManager.ToBaseRelativePath(e.Location);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
NavigationManager.LocationChanged -= OnLocationChanged;
|
||||
}
|
||||
|
||||
public void onLogoutPressed()
|
||||
{
|
||||
var a = "";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,125 +0,0 @@
|
||||
.navbar-toggler {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
width: 3.5rem;
|
||||
height: 2.5rem;
|
||||
color: white;
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 1rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.navbar-toggler:checked {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.bi {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
margin-right: 0.75rem;
|
||||
top: -1px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-lock-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath d='M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2zM5 8h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-person-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person' viewBox='0 0 16 16'%3E%3Cpath d='M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-person-badge-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person-badge' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3zM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z'/%3E%3Cpath d='M4.5 0A2.5 2.5 0 0 0 2 2.5V14a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2.5A2.5 2.5 0 0 0 11.5 0h-7zM3 2.5A1.5 1.5 0 0 1 4.5 1h7A1.5 1.5 0 0 1 13 2.5v10.795a4.2 4.2 0 0 0-.776-.492C11.392 12.387 10.063 12 8 12s-3.392.387-4.224.803a4.2 4.2 0 0 0-.776.492V2.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-person-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person-fill' viewBox='0 0 16 16'%3E%3Cpath d='M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3Zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-arrow-bar-left-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-arrow-bar-left' viewBox='0 0 16 16'%3E%3Cpath d='M12.5 15a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5ZM10 8a.5.5 0 0 1-.5.5H3.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L3.707 7.5H9.5a.5.5 0 0 1 .5.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep .nav-link {
|
||||
color: #d7d7d7;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep .nav-link:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-toggler:checked ~ .nav-scrollable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
31
StandManager/Components/NavigationItem.razor
Normal file
31
StandManager/Components/NavigationItem.razor
Normal file
@ -0,0 +1,31 @@
|
||||
<li class="nav-item @GetActiveClass()">
|
||||
<a class="nav-link" href="@destination">
|
||||
<span class="nav-link-icon d-md-none d-lg-inline-block">
|
||||
<i class="fa-solid @iconName"></i>
|
||||
</span>
|
||||
<span class="nav-link-title"> @title </span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@code{
|
||||
[Parameter] public string currentUrl { get; set; } = "";
|
||||
[Parameter] public string requiredUrl { get; set; } = "/";
|
||||
[Parameter] public string destination { get; set; } = "/";
|
||||
[Parameter] public string iconName { get; set; } = "fa-user";
|
||||
[Parameter] public string title { get; set; }
|
||||
|
||||
private string GetActiveClass()
|
||||
{
|
||||
var currentClean = currentUrl.Split("management").Last();
|
||||
var hrefClean = requiredUrl.Split("management").Last();
|
||||
|
||||
if (currentClean.Contains("?"))
|
||||
currentClean = currentClean.Substring(0, currentClean.IndexOf("?"));
|
||||
|
||||
var isActive = (currentClean.Contains(hrefClean, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(hrefClean)
|
||||
|| (string.IsNullOrEmpty(hrefClean) && string.IsNullOrEmpty(currentClean)));
|
||||
|
||||
return isActive ? "active" : "";
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,6 +9,7 @@
|
||||
@using StandManager.Infrastructure.DAL.Context
|
||||
@using StandManager.Model
|
||||
@using System.Security.Claims
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using StandManager.Service.Interfaces
|
||||
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@ -66,7 +67,8 @@
|
||||
/// </summary>
|
||||
private async Task HandleValidSubmit(EditContext args)
|
||||
{
|
||||
var user = await _managerService.UtenteService.RicercaPer(x => x.Email == model.Email);
|
||||
var user = await _managerService.UtenteService.RicercaPer(x => x.Email == model.Email,
|
||||
includi:x => x.Include(y => y.Ruolo));
|
||||
var hasher = new PasswordHasher<Utente>();
|
||||
|
||||
if (user == null ||
|
||||
@ -81,7 +83,8 @@
|
||||
{
|
||||
new Claim(ClaimTypes.Name, user.Email),
|
||||
new Claim(ClaimTypes.Role, "Admin"),
|
||||
new Claim("UserId", user.Id.ToString())
|
||||
new Claim("UserId", user.Id.ToString()),
|
||||
new Claim("RoleId", user.RuoloId?.ToString())
|
||||
};
|
||||
|
||||
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
@ -169,18 +169,19 @@
|
||||
@code {
|
||||
[Parameter]
|
||||
public Guid? ClienteId { get; set; }
|
||||
public Guid idClaim { get; set; }
|
||||
|
||||
[SupplyParameterFromForm]
|
||||
private ClienteViewModel cliente { get; set; } = new();
|
||||
|
||||
private IEnumerable<UtenteViewModel> agenti { get; set; } = new List<UtenteViewModel>();
|
||||
private List<TipologiaClienteViewModel> tipologiaCliente { get; set; } = new();
|
||||
private List<LookupViewModel<int>> statoCliente { get; set; } = new List<LookupViewModel<int>>();
|
||||
private List<LookupViewModel<int>> statoCliente { get; set; } = new();
|
||||
RadzenDataGrid<DestinazioneViewModel> destinazioniGrid;
|
||||
|
||||
private string pageTitle => cliente?.Id == Guid.Empty ? "Nuovo cliente" : "Modifica cliente";
|
||||
|
||||
private DialogOptions editNewDialogOption { get; set; } = new DialogOptions()
|
||||
private DialogOptions editNewDialogOption { get; set; } = new()
|
||||
{
|
||||
Resizable = false,
|
||||
Draggable = false,
|
||||
@ -194,7 +195,19 @@
|
||||
/// </summary>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
agenti = (await _managerService.UtenteService.RicercaQueryable(x => x.Eliminato == false, ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome)))
|
||||
idClaim = await MembershipUtils.GetUserId(auth);
|
||||
var idRuolo = await MembershipUtils.GetRoleId(auth);
|
||||
var ruolo = await _managerService.RuoloService.RicercaPer(
|
||||
x => x.Id == idRuolo && x.Permessi.Any(y => y.Feature.Type == FeatureType.Capoarea || y.Feature.Type == FeatureType.AdminGlobal),
|
||||
includi:x => x.Include(y => y.Permessi).ThenInclude(z => z.Feature));
|
||||
|
||||
var isAdmin = ruolo?.Permessi.Where(x => x.Eliminato == false)?.Any(x => x.Feature.Type == FeatureType.AdminGlobal) ?? false;
|
||||
agenti = ruolo == null
|
||||
? [await _managerService.UtenteService.RicercaPer(x => x.Id == idClaim)]
|
||||
: (await _managerService.UtenteService.RicercaQueryable(
|
||||
x => x.Eliminato == false && (isAdmin || x.CapoareaId == idClaim),
|
||||
includi: x => x.Include(y => y.Capoarea),
|
||||
ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome)))
|
||||
.Select(x => (UtenteViewModel)x).ToList();
|
||||
var eUtils = new EnumUtils();
|
||||
tipologiaCliente = (await _managerService.TipologiaClienteService.RicercaQueryable(ordinamento: x => x.OrderBy(y => y.Nome))).Select(x => (TipologiaClienteViewModel)x).ToList();
|
||||
@ -225,8 +238,6 @@
|
||||
/// </summary>
|
||||
private async Task onClienteSave()
|
||||
{
|
||||
var idClaim = await MembershipUtils.GetUserId(auth);
|
||||
|
||||
var model = await _managerService.ClienteService.RicercaPer(x => x.Id == cliente.Id, solaLettura: false)
|
||||
?? new Cliente() { Destinazioni = new List<Destinazione>() };
|
||||
|
||||
|
||||
97
StandManager/Components/Pages/Management/Ruoli.razor
Normal file
97
StandManager/Components/Pages/Management/Ruoli.razor
Normal file
@ -0,0 +1,97 @@
|
||||
@attribute [Authorize]
|
||||
@page "/management/Ruoli"
|
||||
@using ClosedXML.Excel
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using StandManager.Model
|
||||
@using System.Threading.Tasks
|
||||
|
||||
@rendermode InteractiveServer
|
||||
|
||||
@inject AuthenticationStateProvider auth
|
||||
|
||||
<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 -->
|
||||
<div class="page-pretitle">Overview</div>
|
||||
<h2 class="page-title">Ruoli</h2>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="table-responsive">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
|
||||
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
|
||||
Data="@ruoli" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn Property="@nameof(RuoloViewModel.Id)" Filterable="false" Title="ID" Width="200px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn Property="@nameof(RuoloViewModel.Nome)" Title="Nome" Width="250px" />
|
||||
|
||||
<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" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
List<RuoloViewModel> ruoli;
|
||||
|
||||
/// <summary>
|
||||
/// Carica l’elenco dei clienti non eliminati, includendo l’agente,
|
||||
/// e prepara i dati per la visualizzazione in pagina.
|
||||
/// </summary>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
ruoli = (await _managerService.RuoloService.RicercaQueryable(
|
||||
x => x.Eliminato == false,
|
||||
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($"/management/Ruoli/Modifica/{ruolo.Id}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiede conferma ed elimina il cliente scelto; se confermato,
|
||||
/// aggiorna la lista ricaricandola dal database.
|
||||
/// </summary>
|
||||
private async Task DeleteRow(RuoloViewModel ruolo)
|
||||
{
|
||||
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare il ruolo {ruolo.Nome}?", "Conferma eliminazione", new ConfirmOptions { OkButtonText = "Sì", CancelButtonText = "No", Width = "400px" });
|
||||
|
||||
if (ok == true)
|
||||
{
|
||||
await _managerService.RuoloService.Elimina(ruolo.Id, await MembershipUtils.GetUserId(auth));
|
||||
ruoli = (await _managerService.RuoloService.RicercaQueryable(x => x.Eliminato == false))
|
||||
.Select(x => (RuoloViewModel)x).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
175
StandManager/Components/Pages/Management/Ruoli_Edit.razor
Normal file
175
StandManager/Components/Pages/Management/Ruoli_Edit.razor
Normal file
@ -0,0 +1,175 @@
|
||||
@attribute [Authorize]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
@page "/management/Ruoli/Modifica"
|
||||
@page "/management/Ruoli/Modifica/{RuoloId:guid}"
|
||||
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using StandManager.Model
|
||||
@inject AuthenticationStateProvider auth
|
||||
|
||||
<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="ruolo" OnValidSubmit="onRuoloSave" FormName="editRuoloForm">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
<div class="col-12">
|
||||
<div class="row">
|
||||
<div class="col-4 mb-3">
|
||||
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Nome</RadzenText>
|
||||
<RadzenTextBox Style="width: 100%" aria-label="Nome" @bind-Value="@ruolo.Nome" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 mb-3">
|
||||
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
||||
Annulla
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-3 mb-3">
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
Salva
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="advanced-table">
|
||||
<div class="table-responsive">
|
||||
<RadzenDataGrid @ref="permessiGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
|
||||
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" AllowGrouping="true"
|
||||
Data="@permessi" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single" Render="@OnRender">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn Property="@nameof(PermissionRowViewModel.Selected)" Filterable="true" Width="200px" TextAlign="TextAlign.Center">
|
||||
<Template Context="permesso">
|
||||
<RadzenCheckBox TValue="bool" Value="@permesso.Selected" Change=@(args => onSelected(args, permesso))></RadzenCheckBox>
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn Property="@nameof(PermissionRowViewModel.Ordinamento)" Visible="false" SortOrder="SortOrder.Ascending" />
|
||||
<RadzenDataGridColumn Property="@nameof(PermissionRowViewModel.OrdinamentoFeature)" Visible="false" SortOrder="SortOrder.Ascending" />
|
||||
<RadzenDataGridColumn Property="@nameof(PermissionRowViewModel.Nome)" Groupable="true" GroupProperty="Nome" Filterable="true" Width="200px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn Property="@nameof(PermissionRowViewModel.NomeFeature)" Title="Nome" Width="250px" />
|
||||
<RadzenDataGridColumn Property="@nameof(PermissionRowViewModel.DescrizioneFeature)" Title="Descrizione" Width="250px" />
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public Guid? RuoloId { get; set; }
|
||||
|
||||
[SupplyParameterFromForm]
|
||||
private RuoloViewModel? ruolo { get; set; } = new();
|
||||
private List<PermissionRowViewModel> permessi { get; set; } = new();
|
||||
private RadzenDataGrid<PermissionRowViewModel> permessiGrid { get; set; }
|
||||
|
||||
private string pageTitle => ruolo?.Id == Guid.Empty ? "Nuovo ruolo" : "Modifica ruolo";
|
||||
|
||||
/// <summary>
|
||||
/// Recupera l’utente da modificare se è stato passato un ID,
|
||||
/// altrimenti inizializza un nuovo modello vuoto.
|
||||
/// </summary>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ruolo = RuoloId.GetValueOrDefault() != Guid.Empty
|
||||
? await _managerService.RuoloService.RicercaPer(x => x.Id == RuoloId)
|
||||
: new RuoloViewModel();
|
||||
|
||||
var sections = (await
|
||||
_managerService.SezioneService.RicercaQueryable(x => x.Eliminato == false, includi: x => x.Include(y => y.Features))).ToList();
|
||||
var permissions = await _managerService.PermissionService.RicercaQueryable(x => x.Ruolo.Id == ruolo.Id && x.Eliminato == false);
|
||||
|
||||
permessi = [];
|
||||
foreach (var section in sections)
|
||||
permessi.AddRange(section.Features.Where(x => !x.Eliminato).Select(x => new PermissionRowViewModel(section, x, permissions)).ToList());
|
||||
}
|
||||
|
||||
void OnRender(DataGridRenderEventArgs<PermissionRowViewModel> args)
|
||||
{
|
||||
if (!args.FirstRender) return;
|
||||
args.Grid.Groups.Add(new GroupDescriptor(){ Property = "Nome", SortOrder = SortOrder.Descending });
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <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 idClaim = await MembershipUtils.GetUserId(auth);
|
||||
|
||||
var model = await _managerService.RuoloService.RicercaPer(x => x.Id == ruolo.Id, solaLettura: false)
|
||||
?? new Ruolo();
|
||||
|
||||
model.Nome = ruolo.Nome;
|
||||
|
||||
await _managerService.RuoloService.Salva(model, idClaim);
|
||||
_navManager.NavigateTo("/management/Ruoli");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Torna all’elenco ruoli senza applicare altre azioni.
|
||||
/// </summary>
|
||||
private void backToHome()
|
||||
{
|
||||
_navManager.NavigateTo("/management/Ruoli");
|
||||
}
|
||||
|
||||
private async Task onSelected(bool selected, PermissionRowViewModel permissionRow)
|
||||
{
|
||||
var idClaim = await MembershipUtils.GetUserId(auth);
|
||||
var ruoloPermission = await _managerService.PermissionService.RicercaPer(
|
||||
x => x.RuoloId == ruolo.Id && x.IdFeature == permissionRow.IdFeature && x.Eliminato == false,
|
||||
includi: x => x.Include(y => y.Ruolo).Include(y => y.Feature),
|
||||
solaLettura: false);
|
||||
if (ruoloPermission == null && selected)
|
||||
{
|
||||
var permission = new Permission()
|
||||
{
|
||||
RuoloId = ruolo.Id,
|
||||
IdFeature = permissionRow.IdFeature
|
||||
};
|
||||
await _managerService.PermissionService.Salva(permission, idClaim);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _managerService.PermissionService.Elimina(ruoloPermission?.Id ?? Guid.Empty, idClaim);
|
||||
}
|
||||
permissionRow.Selected = selected;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
@attribute [Authorize]
|
||||
@page "/management/Utenti"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
|
||||
@rendermode InteractiveServer
|
||||
|
||||
@ -35,8 +36,10 @@
|
||||
<RadzenDataGridColumn Property="@nameof(Utente.Nome)" Title="Nome" Width="160px" />
|
||||
<RadzenDataGridColumn Property="@nameof(Utente.Cognome)" Title="Cognome" Width="160px" />
|
||||
<RadzenDataGridColumn Property="@nameof(Utente.Email)" Title="Mail" Width="200px" />
|
||||
<RadzenDataGridColumn Property="Ruolo.Nome" Title="Ruolo" Width="200px" />
|
||||
<RadzenDataGridColumn Property="Capoarea.Nome" Title="Capoarea" Width="200px" />
|
||||
|
||||
<RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Right">
|
||||
<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" />
|
||||
@ -63,7 +66,10 @@
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
utenti = await _managerService.UtenteService.RicercaQueryable(x => x.Eliminato == false, ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome));
|
||||
utenti = await _managerService.UtenteService.RicercaQueryable(
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -80,12 +86,15 @@
|
||||
/// </summary>
|
||||
private async Task DeleteRow(Utente user)
|
||||
{
|
||||
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare l'utente {user.ToString()}?", "Conferma eliminazione", new ConfirmOptions { OkButtonText = "Sì", CancelButtonText = "No", Width = "400px" });
|
||||
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare l'utente {user}?", "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);
|
||||
utenti = await _managerService.UtenteService.RicercaQueryable(
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
@page "/management/Utenti/Modifica/{UserId:guid}"
|
||||
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using StandManager.Model
|
||||
@inject AuthenticationStateProvider auth
|
||||
|
||||
@ -52,6 +53,16 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4 mb-3">
|
||||
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Ruolo</RadzenText>
|
||||
<RadzenDropDown Style="width: 100%" TValue="Guid" @bind-Value=@utente.RuoloId Data=@ruoli TextProperty="Nome" ValueProperty="Id" Name="ruoliDrop" />
|
||||
</div>
|
||||
|
||||
<div class="col-4 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\" />
|
||||
</div>
|
||||
|
||||
<div class="col-4 mb-3">
|
||||
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Password</RadzenText>
|
||||
<RadzenPassword Style="width: 100%" aria-label="Password" @bind-Value="@utente.Password"/>
|
||||
@ -59,12 +70,12 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 mb-3">
|
||||
<div class="col-4 mb-3">
|
||||
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
||||
Annulla
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-3 mb-3">
|
||||
<div class="col-4 mb-3">
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
Salva
|
||||
</button>
|
||||
@ -87,6 +98,8 @@
|
||||
|
||||
[SupplyParameterFromForm]
|
||||
private UtenteViewModel? utente { get; set; } = new();
|
||||
private List<UtenteViewModel> capoareaList { get; set; } = new();
|
||||
private List<RuoloViewModel> ruoli { get; set; } = new();
|
||||
|
||||
private string pageTitle => utente?.Id == Guid.Empty ? "Nuovo utente" : "Modifica utente";
|
||||
|
||||
@ -97,9 +110,21 @@
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (UserId.GetValueOrDefault() != Guid.Empty)
|
||||
utente = await _managerService.UtenteService.RicercaPer(x => x.Id == UserId);
|
||||
utente = await _managerService.UtenteService.RicercaPer(
|
||||
x => x.Id == UserId,
|
||||
includi:x => x.Include(y => y.Ruolo).Include(y => y.Capoarea));
|
||||
else
|
||||
utente = new UtenteViewModel();
|
||||
|
||||
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(
|
||||
u => ruoliCapoarea.Any(r => r.Id == u.RuoloId)
|
||||
)).Select(x => (UtenteViewModel)x).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -128,6 +153,9 @@
|
||||
model.Password = hasher.HashPassword(model, utente.Password);
|
||||
}
|
||||
|
||||
model.RuoloId = utente.RuoloId;
|
||||
model.CapoareaId = utente.CapoareaId;
|
||||
|
||||
await _managerService.UtenteService.Salva(model, Guid.Parse(idClaim));
|
||||
_navManager.NavigateTo("/management/Utenti");
|
||||
}
|
||||
|
||||
26
StandManager/Model/PermissionRowViewModel.cs
Normal file
26
StandManager/Model/PermissionRowViewModel.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using StandManager.Domain.Entita;
|
||||
|
||||
namespace StandManager.Model;
|
||||
|
||||
public class PermissionRowViewModel
|
||||
{
|
||||
public PermissionRowViewModel(Sezione section, Feature feature, IQueryable<Permission> permissions)
|
||||
{
|
||||
Nome = section.Nome;
|
||||
IdSezione = section.Id;
|
||||
NomeFeature = feature.Nome;
|
||||
DescrizioneFeature = feature.Descrizione;
|
||||
IdFeature = feature.Id;
|
||||
Ordinamento = section.Ordinamento;
|
||||
OrdinamentoFeature = feature.Ordinamento;
|
||||
Selected = permissions.Any(y => y.Feature.Id == feature.Id);
|
||||
}
|
||||
public Guid IdSezione { get; set; }
|
||||
public string Nome { get; set; }
|
||||
public Guid IdFeature { get; set; }
|
||||
public string NomeFeature { get; set; }
|
||||
public string DescrizioneFeature { get; set; }
|
||||
public int Ordinamento { get; set; }
|
||||
public int OrdinamentoFeature { get; set; }
|
||||
public bool Selected { get; set; }
|
||||
}
|
||||
20
StandManager/Model/RuoloViewModel.cs
Normal file
20
StandManager/Model/RuoloViewModel.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using StandManager.Domain.Entita;
|
||||
|
||||
namespace StandManager.Model;
|
||||
|
||||
public class RuoloViewModel
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Nome { get; set; }
|
||||
|
||||
public static implicit operator RuoloViewModel(Ruolo model)
|
||||
{
|
||||
return model == null
|
||||
? null
|
||||
: new RuoloViewModel()
|
||||
{
|
||||
Nome = model.Nome,
|
||||
Id = model.Id
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,8 @@ namespace StandManager.Model
|
||||
public string Nome { get; set; }
|
||||
[Required(ErrorMessage = "Il cognome è obbligatorio")]
|
||||
public string Cognome { get; set; }
|
||||
public Guid RuoloId { get; set; }
|
||||
public Guid CapoareaId { get; set; }
|
||||
public string Info => $"{Nome} {Cognome}";
|
||||
|
||||
public static implicit operator UtenteViewModel(Utente? model)
|
||||
@ -26,7 +28,9 @@ namespace StandManager.Model
|
||||
Username = model.Username,
|
||||
Email = model.Email,
|
||||
Nome = model.Nome,
|
||||
Cognome = model.Cognome
|
||||
Cognome = model.Cognome,
|
||||
RuoloId = model.Ruolo?.Id ?? Guid.Empty,
|
||||
CapoareaId = model.Capoarea?.Id ?? Guid.Empty
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -11,4 +11,12 @@ public static class MembershipUtils
|
||||
|
||||
return Guid.Parse(idClaim ?? Guid.Empty.ToString());
|
||||
}
|
||||
|
||||
public static async Task<Guid> GetRoleId(AuthenticationStateProvider auth)
|
||||
{
|
||||
var state = await auth.GetAuthenticationStateAsync();
|
||||
var idClaim = state.User.FindFirst("RoleId")?.Value;
|
||||
|
||||
return Guid.Parse(idClaim ?? Guid.Empty.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user