Breadcrumb
This commit is contained in:
@ -1,15 +1,18 @@
|
|||||||
@page "/anagrafiche"
|
@page "/anagrafiche"
|
||||||
|
|
||||||
@using Microsoft.EntityFrameworkCore
|
@using Microsoft.EntityFrameworkCore
|
||||||
@using TecniStamp.Components.Widget
|
@using TecniStamp.Components.Widget
|
||||||
@using TecniStamp.Domain
|
@using TecniStamp.Model.Common
|
||||||
@using TecniStamp.Utils
|
@using TecniStamp.Utils
|
||||||
|
|
||||||
|
<Breadcrumb Items="BreadcrumbList" />
|
||||||
|
|
||||||
<main role="main">
|
<main role="main">
|
||||||
<div class="container-fluid h-100 mt-10">
|
<div class="container-fluid h-100 mt-10">
|
||||||
<div class="row justify-content-start">
|
<div class="row justify-content-start">
|
||||||
@foreach (var item in TileList)
|
@foreach (var item in TileList)
|
||||||
{
|
{
|
||||||
<HomeTile Text="@item.Nome" Icon="@item.Icona" Url="@item.Url" Blank="@item.Blank" />
|
<HomeTile Model="@item" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -17,23 +20,41 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
public List<Sezione> TileList { get; set; } = new();
|
public List<TileViewModel> TileList { get; set; } = new();
|
||||||
|
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
var roleId = await MembershipUtils.GetRoleId(_auth);
|
var roleId = await MembershipUtils.GetRoleId(_auth);
|
||||||
var parentSection = await _managerService.SezioneService.RicercaPer(x => x.Nome == "Anagrafiche");
|
|
||||||
var subSection = (await _managerService.SezioneService.RicercaQueryable(x => x.ParentId == parentSection.Id))
|
|
||||||
.Select(x => x.Id);
|
|
||||||
|
|
||||||
var permissionList = (await _managerService.PermissionService.RicercaQueryable(
|
var parentSection = await _managerService.SezioneService
|
||||||
x => x.RuoloId == roleId && subSection.Contains(x.Feature.Sezione.Id),
|
.RicercaPer(x => x.Nome == "Anagrafiche");
|
||||||
includi: x => x.Include(y => y.Feature).ThenInclude(z => z.Sezione),
|
|
||||||
ordinamento: x => x.OrderBy(y => y.Feature.Sezione.Ordinamento)));
|
var subSectionIds = await (await _managerService.SezioneService
|
||||||
|
.RicercaQueryable(x => x.ParentId == parentSection.Id))
|
||||||
|
.Select(x => x.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var permissionList = await (await _managerService.PermissionService
|
||||||
|
.RicercaQueryable(
|
||||||
|
x => x.RuoloId == roleId &&
|
||||||
|
subSectionIds.Contains(x.Feature.Sezione.Id),
|
||||||
|
includi: x => x
|
||||||
|
.Include(y => y.Feature)
|
||||||
|
.ThenInclude(z => z.Sezione)
|
||||||
|
))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
TileList = permissionList
|
TileList = permissionList
|
||||||
.Select(x => x.Feature.Sezione).Distinct().ToList();
|
.Select(x => x.Feature.Sezione)
|
||||||
|
.DistinctBy(x => x.Id)
|
||||||
|
.OrderBy(x => x.Ordinamento)
|
||||||
|
.Select(x => new TileViewModel(x))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
BreadcrumbList = BreadcrumbUtils.BuildBreadcrumb(parentSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
@page "/anagrafiche/ruoli"
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -4,40 +4,51 @@
|
|||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Microsoft.EntityFrameworkCore
|
@using Microsoft.EntityFrameworkCore
|
||||||
@using TecniStamp.Components.Widget
|
@using TecniStamp.Components.Widget
|
||||||
@using TecniStamp.Domain
|
@using TecniStamp.Model.Common
|
||||||
@using TecniStamp.Utils
|
@using TecniStamp.Utils
|
||||||
|
|
||||||
<div class="card bg-primary-lt position-fixed w-100 rounded-0 shadow-sm" style="top: 58px; left:0; z-index: 100;">
|
<Breadcrumb Items="BreadcrumbList" />
|
||||||
<div class="card-body py-2">
|
|
||||||
<ol class="breadcrumb breadcrumb-arrows ">
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main role="main">
|
<main role="main">
|
||||||
<div class="container-fluid h-100 mt-10">
|
<div class="container-fluid h-100 mt-10">
|
||||||
<div class="row justify-content-start">
|
<div class="row justify-content-start">
|
||||||
@foreach (var item in TileList)
|
@foreach (var item in TileList)
|
||||||
{
|
{
|
||||||
<HomeTile Text="@item.Nome" Icon="@item.Icona" Url="@item.Url" Blank="@item.Blank" />
|
<HomeTile Model="item" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public List<Sezione> TileList { get; set; } = new();
|
public List<TileViewModel> TileList { get; set; } = new();
|
||||||
|
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
var roleId = await MembershipUtils.GetRoleId(_auth);
|
var roleId = await MembershipUtils.GetRoleId(_auth);
|
||||||
TileList = (await _managerService.PermissionService.RicercaQueryable(
|
|
||||||
|
var sezioniList = await (await _managerService.PermissionService
|
||||||
|
.RicercaQueryable(
|
||||||
x => x.RuoloId == roleId &&
|
x => x.RuoloId == roleId &&
|
||||||
(x.Feature.Sezione.ParentId == null || x.Feature.Sezione.Parent.ParentId == null),
|
(x.Feature.Sezione.ParentId == null ||
|
||||||
includi:x => x.Include(y => y.Feature).ThenInclude(z => z.Sezione),
|
x.Feature.Sezione.Parent.ParentId == null),
|
||||||
ordinamento:x => x.OrderBy(y => y.Feature.Sezione.Ordinamento)))
|
includi: x => x
|
||||||
.Select(x => x.Feature.Sezione.Parent ?? x.Feature.Sezione).Distinct().ToList();
|
.Include(y => y.Feature)
|
||||||
|
.ThenInclude(z => z.Sezione)
|
||||||
|
.ThenInclude(s => s.Parent)
|
||||||
|
))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
TileList = sezioniList
|
||||||
|
.Select(x => x.Feature.Sezione.Parent ?? x.Feature.Sezione)
|
||||||
|
.DistinctBy(x => x.Id)
|
||||||
|
.OrderBy(x => x.Ordinamento)
|
||||||
|
.Select(x => new TileViewModel(x))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
BreadcrumbList = BreadcrumbUtils.BuildBreadcrumb(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
26
TecniStamp/TecniStamp/Components/Widget/Breadcrumb.razor
Normal file
26
TecniStamp/TecniStamp/Components/Widget/Breadcrumb.razor
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
@using TecniStamp.Model.Common
|
||||||
|
<div class="card bg-primary-lt position-fixed w-100 rounded-0 shadow-sm" style="top: 58px; left:0; z-index: 100;">
|
||||||
|
<div class="card-body py-2">
|
||||||
|
<ol class="breadcrumb breadcrumb-arrows">
|
||||||
|
@foreach (var item in Items)
|
||||||
|
{
|
||||||
|
if (item.IsActive)
|
||||||
|
{
|
||||||
|
<li class="breadcrumb-item active" aria-current="page">
|
||||||
|
@item.Text
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@item.Url">@item.Text</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@code {
|
||||||
|
[Parameter, EditorRequired]
|
||||||
|
public IReadOnlyList<BreadcrumbViewModel> Items { get; set; } = [];
|
||||||
|
}
|
||||||
@ -1,20 +1,18 @@
|
|||||||
<div class="col-md-3 col-sm-6 col-12 mb-4">
|
@using TecniStamp.Model.Common
|
||||||
|
<div class="col-md-3 col-sm-6 col-12 mb-4">
|
||||||
<div class="card cards custom-card card-link py-4 shadow-sm border-2 rounded-3 hover-effect position-relative">
|
<div class="card cards custom-card card-link py-4 shadow-sm border-2 rounded-3 hover-effect position-relative">
|
||||||
<a class="stretched-link text-decoration-none text-dark" href="@Url" @(Blank ? "target=\"_blank\"" : "") ></a>
|
<a class="stretched-link text-decoration-none text-dark" href="@Model.Url" @(Model.Blank ? "target=\"_blank\"" : "") ></a>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h1 class="text-center mb-2">
|
<h1 class="text-center mb-2">
|
||||||
<i class="@Icon" style="font-size:65px;"></i>
|
<i class="@Model.Icon" style="font-size:65px;"></i>
|
||||||
</h1>
|
</h1>
|
||||||
<h1 class="mb-0 text-center">
|
<h1 class="mb-0 text-center">
|
||||||
@Text
|
@Model.Text
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public string Url { get; set; }
|
[Parameter] public TileViewModel Model { get; set; } = new();
|
||||||
[Parameter] public bool Blank { get; set; } = false;
|
|
||||||
[Parameter] public string Icon { get; set; }
|
|
||||||
[Parameter] public string Text { get; set; }
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace TecniStamp.Model.Common;
|
||||||
|
|
||||||
|
public class BreadcrumbViewModel
|
||||||
|
{
|
||||||
|
public string Text { get; set; }
|
||||||
|
public string? Url { get; set; }
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
}
|
||||||
27
TecniStamp/TecniStamp/Model/Common/TileViewModel.cs
Normal file
27
TecniStamp/TecniStamp/Model/Common/TileViewModel.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using TecniStamp.Domain;
|
||||||
|
|
||||||
|
namespace TecniStamp.Model.Common;
|
||||||
|
|
||||||
|
public class TileViewModel
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public bool Blank { get; set; } = false;
|
||||||
|
public string Icon { get; set; }
|
||||||
|
public string Text { get; set; }
|
||||||
|
public int Ordinamento { get; set; }
|
||||||
|
|
||||||
|
public TileViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileViewModel(Sezione model)
|
||||||
|
{
|
||||||
|
Id = model.Id;
|
||||||
|
Url = model.Url;
|
||||||
|
Blank = model.Blank;
|
||||||
|
Icon = model.Icona;
|
||||||
|
Text = model.Nome;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
TecniStamp/TecniStamp/Utils/BreadcrumbUtils.cs
Normal file
45
TecniStamp/TecniStamp/Utils/BreadcrumbUtils.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using TecniStamp.Domain;
|
||||||
|
using TecniStamp.Model.Common;
|
||||||
|
|
||||||
|
namespace TecniStamp.Utils;
|
||||||
|
|
||||||
|
public static class BreadcrumbUtils
|
||||||
|
{
|
||||||
|
public static List<BreadcrumbViewModel> BuildBreadcrumb(Sezione sezione)
|
||||||
|
{
|
||||||
|
var stack = new Stack<Sezione>();
|
||||||
|
var current = sezione;
|
||||||
|
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
stack.Push(current);
|
||||||
|
current = current.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var breadcrumb = new List<BreadcrumbViewModel>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Text = "Home",
|
||||||
|
Url = "/",
|
||||||
|
IsActive = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (stack.Any())
|
||||||
|
{
|
||||||
|
var s = stack.Pop();
|
||||||
|
breadcrumb.Add(new BreadcrumbViewModel
|
||||||
|
{
|
||||||
|
Text = s.Nome,
|
||||||
|
Url = s.Url,
|
||||||
|
IsActive = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumb.Last().IsActive = true;
|
||||||
|
breadcrumb.Last().Url = null;
|
||||||
|
|
||||||
|
return breadcrumb;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user