Breadcrumb e pagina commesse
This commit is contained in:
13
TecniStamp/TecniStamp.Service/FeatureService.cs
Normal file
13
TecniStamp/TecniStamp.Service/FeatureService.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using OAService.Service.Servizi.Implementazioni;
|
||||
using TecniStamp.Domain;
|
||||
using TecniStamp.Service.Interfaces;
|
||||
using TecniStamp.Service.Repository;
|
||||
|
||||
namespace TecniStamp.Service;
|
||||
|
||||
public class FeatureService : TService<Feature>, IFeatureService
|
||||
{
|
||||
public FeatureService(ITecniStampUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using OAService.Service.Servizi.Interfacce;
|
||||
using TecniStamp.Domain;
|
||||
|
||||
namespace TecniStamp.Service.Interfaces;
|
||||
|
||||
public interface IFeatureService : ITService<Feature>
|
||||
{
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
public interface IManagerService
|
||||
{
|
||||
IFeatureService FeatureService { get; set; }
|
||||
IPermissionService PermissionService { get; set; }
|
||||
IRuoloService RuoloService{ get; set; }
|
||||
ISezioneService SezioneService { get; set; }
|
||||
|
||||
@ -4,14 +4,16 @@ namespace TecniStamp.Service;
|
||||
|
||||
public class ManagerService : IManagerService
|
||||
{
|
||||
public ManagerService(IUserService userService, ISezioneService sezioneService, IPermissionService permissionService, IRuoloService ruoloService)
|
||||
public ManagerService(IUserService userService, ISezioneService sezioneService, IPermissionService permissionService, IRuoloService ruoloService, IFeatureService featureService)
|
||||
{
|
||||
UtenteService = userService;
|
||||
SezioneService = sezioneService;
|
||||
PermissionService = permissionService;
|
||||
RuoloService = ruoloService;
|
||||
FeatureService = featureService;
|
||||
}
|
||||
|
||||
public IFeatureService FeatureService { get; set; }
|
||||
public IPermissionService PermissionService { get; set; }
|
||||
public IRuoloService RuoloService { get; set; }
|
||||
public ISezioneService SezioneService { get; set; }
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
<base href="/"/>
|
||||
<link rel="stylesheet" href="bootstrap/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="app.css"/>
|
||||
<link rel="stylesheet" href="css/space.css"/>
|
||||
<link rel="stylesheet" href="TecniStamp.styles.css"/>
|
||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
@page "/anagrafiche"
|
||||
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Components.Widget
|
||||
@using TecniStamp.Model.Common
|
||||
@using TecniStamp.Utils
|
||||
|
||||
<PageTitle>Anagrafiche</PageTitle>
|
||||
<Breadcrumb Items="BreadcrumbList" />
|
||||
|
||||
<main role="main">
|
||||
|
||||
@ -1,23 +1,19 @@
|
||||
@page "/Anagrafiche/Operatori"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Domain
|
||||
@using TecniStamp.Model
|
||||
@using TecniStamp.Model.Common
|
||||
@using TecniStamp.Utils
|
||||
|
||||
@rendermode InteractiveServer
|
||||
@inject AuthenticationStateProvider auth
|
||||
|
||||
<PageTitle>Operatori</PageTitle>
|
||||
<Breadcrumb Items="BreadcrumbList" />
|
||||
|
||||
<div class="page-wrapper">
|
||||
<!-- BEGIN PAGE BODY -->
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<main role="main">
|
||||
<div class="container-fluid h-100 mt-5">
|
||||
<div class="row justify-content-start">
|
||||
<div class="row row-cards">
|
||||
<div class="col">
|
||||
<!-- Page pre-title -->
|
||||
<h2 class="page-title">Operatori</h2>
|
||||
</div>
|
||||
<div class="col-auto ms-auto">
|
||||
<div class="btn-list">
|
||||
<a href="/Anagrafiche/Operatori/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
|
||||
@ -51,11 +47,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@code {
|
||||
List<UserViewModel> utenti;
|
||||
RadzenDataGrid<UserViewModel> userGrid;
|
||||
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Carica la lista degli utenti non eliminati, ordinandoli per cognome e nome.
|
||||
@ -69,6 +66,8 @@
|
||||
includi: x => x.Include(y => y.Ruolo),
|
||||
ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome)))
|
||||
.Select(x => (UserViewModel)x).ToList();
|
||||
|
||||
BreadcrumbList = await BreadcrumbUtils.BuildBreadcrumbByFeature(_managerService, "Operatori_Insert");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -2,28 +2,26 @@
|
||||
@page "/Anagrafiche/Operatori/Modifica/{UserId:guid}"
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
|
||||
@using TecniStamp.Domain
|
||||
@using TecniStamp.Model
|
||||
@using TecniStamp.Utils
|
||||
|
||||
@using TecniStamp.Model.Common
|
||||
|
||||
@rendermode InteractiveServer
|
||||
|
||||
<PageTitle>@pageTitle</PageTitle>
|
||||
<Breadcrumb Items="BreadcrumbList" />
|
||||
|
||||
<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">
|
||||
<main role="main">
|
||||
<div class="container-fluid h-100 mt-5">
|
||||
<div class="row justify-content-start">
|
||||
<div class="row row-cards">
|
||||
<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">
|
||||
@ -87,8 +85,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
@code {
|
||||
[Parameter] public Guid? UserId { get; set; }
|
||||
@ -98,6 +95,7 @@
|
||||
private string pageTitle => Model?.Id == Guid.Empty ? "Nuovo operatore" : $"Modifica operatore {Model}";
|
||||
private List<RuoloViewModel> ruoli { get; set; } = new();
|
||||
|
||||
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
@ -109,6 +107,8 @@
|
||||
|
||||
ruoli = (await _managerService.RuoloService.RicercaQueryable(x => x.Eliminato == false))
|
||||
.Select(x => (RuoloViewModel)x).ToList();
|
||||
|
||||
BreadcrumbList = await BreadcrumbUtils.BuildBreadcrumbByFeature(_managerService, "Operatori_Insert", "Modifica", "/Anagrafiche/Operatori");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Model
|
||||
|
||||
@rendermode InteractiveServer
|
||||
|
||||
<PageTitle>Ruoli</PageTitle>
|
||||
|
||||
<div class="page-wrapper">
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
@page "/Anagrafiche/ruoli/Modifica"
|
||||
@page "/Anagrafiche/ruoli/Modifica/{RuoloId:guid}"
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Domain
|
||||
@using TecniStamp.Model
|
||||
|
||||
|
||||
@ -1,130 +1,223 @@
|
||||
@page "/Carico"
|
||||
@page "/carico"
|
||||
@using System.Globalization
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Model.Carico
|
||||
@using TecniStamp.Model.Common
|
||||
@using TecniStamp.Utils
|
||||
|
||||
<RadzenDataGrid Data="@righe" TItem="CalendarioRigaViewModel"
|
||||
ColumnWidth="120px"
|
||||
AllowFiltering="false"
|
||||
AllowSorting="false">
|
||||
<PageTitle>Carico Macchinari</PageTitle>
|
||||
<Breadcrumb Items="BreadcrumbList" />
|
||||
|
||||
<Columns>
|
||||
<!-- Colonna fissa -->
|
||||
<RadzenDataGridColumn TItem="CalendarioRigaViewModel"
|
||||
Property="Lavorazione"
|
||||
Title="Lavorazione"
|
||||
Frozen="true"
|
||||
Width="100px" />
|
||||
<main role="main">
|
||||
<div class="container-fluid h-100 mt-10">
|
||||
<div class="row justify-content-start">
|
||||
<div class="calendar-wrapper">
|
||||
<div class="calendar-scroll">
|
||||
<table class="calendar-table">
|
||||
<thead>
|
||||
<!-- Riga MESI -->
|
||||
<tr class="month-row">
|
||||
<th class="sticky-col month-spacer"></th>
|
||||
|
||||
<!-- Colonne dinamiche: settimane -->
|
||||
@foreach (var settimana in settimane)
|
||||
{
|
||||
<RadzenDataGridColumn TItem="CalendarioRigaViewModel"
|
||||
Title="@($"SETTIMANA {settimana.Numero}")"
|
||||
Width="175px">
|
||||
<Template Context="riga">
|
||||
@{
|
||||
riga.Settimane.TryGetValue(settimana.Numero, out var cella);
|
||||
}
|
||||
@foreach (var m in mesiHeader)
|
||||
{
|
||||
<th class="month-cell" colspan="@m.ColSpan">
|
||||
@m.Nome
|
||||
</th>
|
||||
}
|
||||
</tr>
|
||||
|
||||
@if (cella != null)
|
||||
{
|
||||
<div class="calendar-card">
|
||||
<div class="card-header">
|
||||
<span class="status">@cella.Stato</span>
|
||||
<RadzenButton Icon="more_horiz"
|
||||
Size="ButtonSize.Small"
|
||||
ButtonStyle="ButtonStyle.Light" />
|
||||
</div>
|
||||
<!-- Riga SETTIMANE -->
|
||||
<tr class="week-row">
|
||||
<th class="sticky-col week-spacer">Lavorazione</th>
|
||||
|
||||
<div class="card-body">
|
||||
<small>Commesse: @cella.Stato</small>
|
||||
</div>
|
||||
@foreach (var s in settimane)
|
||||
{
|
||||
<th class="week-cell">
|
||||
SETTIMANA @s.Numero
|
||||
</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<RadzenProgressBar Value="@cella.Percentuale"
|
||||
ShowValue="false"
|
||||
Unit="%"
|
||||
Style="height:12px"
|
||||
Color="@GetColor(cella.Percentuale)" />
|
||||
<tbody>
|
||||
@foreach (var riga in righe)
|
||||
{
|
||||
<tr>
|
||||
<td class="sticky-col row-title">
|
||||
@riga.Lavorazione
|
||||
</td>
|
||||
|
||||
</div>
|
||||
}
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
}
|
||||
@foreach (var s in settimane)
|
||||
{
|
||||
riga.Settimane.TryGetValue(s.Numero, out var cella);
|
||||
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
<td class="data-cell">
|
||||
@if (cella is not null)
|
||||
{
|
||||
<div class="calendar-card">
|
||||
<div class="card-top">
|
||||
<span class="status">@cella.Stato</span>
|
||||
|
||||
<div class="card-actions">
|
||||
<RadzenButton Text="Vedi dettaglio"
|
||||
Size="ButtonSize.Small"
|
||||
ButtonStyle="ButtonStyle.Light"
|
||||
Click="@(() => ApriDettaglio(riga, s, cella))"/>
|
||||
<RadzenButton Icon="more_horiz"
|
||||
Size="ButtonSize.Small"
|
||||
ButtonStyle="ButtonStyle.Light"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
<div class="card-body">
|
||||
<div class="sub">Commesse: @cella.Commesse</div>
|
||||
<div class="sub small">@cella.Ore/@cella.Capacita h</div>
|
||||
</div>
|
||||
|
||||
<RadzenProgressBar Value="@cella.Percentuale"
|
||||
ShowValue="true"
|
||||
Unit="%"
|
||||
ProgressBarStyle="@GetProgressStyle(cella.Percentuale)"
|
||||
Style="height:8px"/>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@code
|
||||
{
|
||||
// ====== DATA ======
|
||||
private List<SettimanaViewModel> settimane = new();
|
||||
private List<MeseHeaderViewModel> mesiHeader = new();
|
||||
private List<CalendarioRigaViewModel> righe = new();
|
||||
protected override async Task OnInitializedAsync()
|
||||
|
||||
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
settimane = GeneraSettimaneAnno(2026);
|
||||
var settimanePerMese = settimane
|
||||
.GroupBy(s => new { s.Anno, Mese = s.Inizio.Month })
|
||||
.Select(g => new
|
||||
settimane = GeneraSettimaneDaPrimoGennaio(2026);
|
||||
|
||||
// Header mesi: raggruppa le settimane per mese (in base alla data di inizio settimana)
|
||||
mesiHeader = settimane
|
||||
.GroupBy(s => s.Inizio.Month)
|
||||
.Select(g => new MeseHeaderViewModel
|
||||
{
|
||||
Mese = g.Key.Mese,
|
||||
Nome = new DateTime(2026, g.Key.Mese, 1).ToString("MMMM").ToUpper(),
|
||||
Count = g.Count()
|
||||
Mese = g.Key,
|
||||
Nome = new DateTime(2026, g.Key, 1).ToString("MMMM", CultureInfo.GetCultureInfo("it-IT")).ToUpperInvariant(),
|
||||
ColSpan = g.Count()
|
||||
})
|
||||
.ToList();
|
||||
|
||||
|
||||
// Mock righe/celle
|
||||
righe = new List<CalendarioRigaViewModel>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Id = 1,
|
||||
Lavorazione = "Taglio laser – Commessa A",
|
||||
Settimane = new Dictionary<int, CalendarioCellaViewModel>
|
||||
Lavorazione = "TAGLIO",
|
||||
Settimane =
|
||||
{
|
||||
[6] = new() { Ore = 16, Stato = "InCorso", Percentuale = 50 },
|
||||
[7] = new() { Ore = 24, Stato = "InCorso", Percentuale = 75 }
|
||||
[3] = new() { Ore = 90, Capacita = 100, Stato = "Estremamente Saturo", Commesse = "24-24, 25-25, ..." },
|
||||
[4] = new() { Ore = 100, Capacita = 100, Stato = "Saturo", Commesse = "16-24, 28-24, ..." }
|
||||
}
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = 2,
|
||||
Lavorazione = "Saldatura – Commessa A",
|
||||
Settimane = new Dictionary<int, CalendarioCellaViewModel>
|
||||
Lavorazione = "TORNITURA",
|
||||
Settimane =
|
||||
{
|
||||
[7] = new() { Ore = 32, Stato = "Pianificato", Percentuale = 40},
|
||||
[8] = new() { Ore = 16, Stato = "Pianificato", Percentuale = 60}
|
||||
[1] = new() { Ore = 100, Capacita = 100, Stato = "Saturo", Commesse = "15-24, 25-24, ..." },
|
||||
[5] = new() { Ore = 60, Capacita = 100, Stato = "Non Saturo", Commesse = "35-25, 65-25, ..." }
|
||||
}
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = 3,
|
||||
Lavorazione = "Verniciatura – Commessa B",
|
||||
Settimane = new Dictionary<int, CalendarioCellaViewModel>
|
||||
Lavorazione = "FRESATURA",
|
||||
Settimane =
|
||||
{
|
||||
[8] = new() { Ore = 40, Stato = "Pianificato", Percentuale = 90}
|
||||
[2] = new() { Ore = 40, Capacita = 100, Stato = "Non Saturo", Commesse = "12-11, 44-11, ..." },
|
||||
[3] = new() { Ore = 100, Capacita = 100, Stato = "Saturo", Commesse = "17-22, 19-22, ..." }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static List<SettimanaViewModel> GeneraSettimaneAnno(int anno)
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
BreadcrumbList = await BreadcrumbUtils.BuildBreadcrumbByFeature(_managerService, "Carico_Info");
|
||||
}
|
||||
|
||||
private void ApriDettaglio(CalendarioRigaViewModel riga, SettimanaViewModel settimana, CalendarioCellaViewModel cella)
|
||||
{
|
||||
// qui ci attacchi un RadzenDialogService se vuoi
|
||||
// es: DialogService.Open(...)
|
||||
|
||||
Console.WriteLine($"Dettaglio: {riga.Lavorazione} - W{settimana.Numero} - {cella.Ore}/{cella.Capacita}");
|
||||
}
|
||||
|
||||
private static ProgressBarStyle GetProgressStyle(int percentuale)
|
||||
{
|
||||
// taralo come vuoi
|
||||
if (percentuale >= 100) return ProgressBarStyle.Success;
|
||||
if (percentuale >= 80) return ProgressBarStyle.Warning;
|
||||
return ProgressBarStyle.Info;
|
||||
}
|
||||
|
||||
// ====== ISO WEEKS (corretto) ======
|
||||
private static List<SettimanaViewModel> GeneraSettimaneISO(int anno)
|
||||
{
|
||||
var list = new List<SettimanaViewModel>();
|
||||
|
||||
// ISOWeek è disponibile su .NET 6+ (quindi ok per Blazor moderno)
|
||||
int weeksInYear = ISOWeek.GetWeeksInYear(anno);
|
||||
|
||||
for (int w = 1; w <= weeksInYear; w++)
|
||||
{
|
||||
// Lunedì della settimana ISO
|
||||
DateTime start = ISOWeek.ToDateTime(anno, w, DayOfWeek.Monday);
|
||||
DateTime end = start.AddDays(6);
|
||||
|
||||
list.Add(new SettimanaViewModel
|
||||
{
|
||||
Anno = anno,
|
||||
Numero = w,
|
||||
Inizio = start,
|
||||
Fine = end
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<SettimanaViewModel> GeneraSettimaneDaPrimoGennaio(int anno)
|
||||
{
|
||||
var settimane = new List<SettimanaViewModel>();
|
||||
|
||||
// ISO: settimana 1 = quella che contiene il 4 gennaio
|
||||
var jan4 = new DateTime(anno, 1, 4);
|
||||
var start = new DateTime(anno, 1, 1);
|
||||
var endOfYear = new DateTime(anno, 12, 31);
|
||||
|
||||
// lunedì della settimana 1
|
||||
var startOfWeek1 = jan4.AddDays(-(int)(jan4.DayOfWeek == DayOfWeek.Sunday
|
||||
? 6
|
||||
: jan4.DayOfWeek - DayOfWeek.Monday));
|
||||
int weekNumber = 1;
|
||||
var currentStart = start;
|
||||
|
||||
var currentStart = startOfWeek1;
|
||||
var weekNumber = 1;
|
||||
|
||||
while (currentStart.Year <= anno)
|
||||
while (currentStart <= endOfYear)
|
||||
{
|
||||
var currentEnd = currentStart.AddDays(6);
|
||||
if (currentEnd > endOfYear)
|
||||
currentEnd = endOfYear;
|
||||
|
||||
settimane.Add(new SettimanaViewModel
|
||||
{
|
||||
@ -140,9 +233,4 @@
|
||||
|
||||
return settimane;
|
||||
}
|
||||
|
||||
object GetColor(int valuePercentuale)
|
||||
{
|
||||
return "Red";
|
||||
}
|
||||
}
|
||||
@ -1,35 +1,118 @@
|
||||
.calendar-month-header {
|
||||
display: grid;
|
||||
grid-template-columns: 250px repeat(53, 120px);
|
||||
border-bottom: 1px solid #ddd;
|
||||
.calendar-wrapper {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.calendar-scroll {
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
max-height: 70vh;
|
||||
}
|
||||
|
||||
.calendar-table {
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
width: max-content; /* importantissimo per far lavorare lo scroll orizzontale */
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
/* larghezze: devono combaciare con il tuo mock */
|
||||
.calendar-table th,
|
||||
.calendar-table td {
|
||||
border: 1px solid #e3e3e3;
|
||||
width: 120px;
|
||||
min-width: 120px;
|
||||
padding: 8px;
|
||||
vertical-align: top;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* Colonna sticky (lavorazioni) */
|
||||
.sticky-col {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 3;
|
||||
width: 250px !important;
|
||||
min-width: 250px !important;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* header sticky in alto */
|
||||
thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 4;
|
||||
background: #f5f5f5;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* incrocio sticky (top + left) */
|
||||
thead .sticky-col {
|
||||
z-index: 6;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.month-header {
|
||||
.month-row th {
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
padding: 8px 0;
|
||||
border-left: 1px solid #ddd;
|
||||
font-size: 12px;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
|
||||
.month-spacer {
|
||||
border-right: 1px solid #ddd;
|
||||
.week-row th {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.row-title {
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
text-transform: uppercase;
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
.data-cell {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.calendar-card {
|
||||
background: #f7f7f7;
|
||||
border-radius: 6px;
|
||||
padding: 6px;
|
||||
box-shadow: inset 0 0 0 1px #ddd;
|
||||
padding: 8px;
|
||||
box-shadow: inset 0 0 0 1px #dedede;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
.card-top {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
justify-content: space-between;
|
||||
font-size: 12px;
|
||||
margin-bottom: 4px;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #444;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-body .sub {
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.card-body .small {
|
||||
font-size: 10px;
|
||||
color: #888;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
@page "/commesse"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Model.Common
|
||||
@using TecniStamp.Utils
|
||||
|
||||
<PageTitle>Commesse</PageTitle>
|
||||
<Breadcrumb Items="BreadcrumbList" />
|
||||
|
||||
@code {
|
||||
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
BreadcrumbList = await BreadcrumbUtils.BuildBreadcrumbByFeature(_managerService, "Commesse_Info");
|
||||
}
|
||||
}
|
||||
@ -3,10 +3,10 @@
|
||||
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using TecniStamp.Components.Widget
|
||||
@using TecniStamp.Model.Common
|
||||
@using TecniStamp.Utils
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
<Breadcrumb Items="BreadcrumbList" />
|
||||
|
||||
<main role="main">
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
@using Microsoft.JSInterop
|
||||
@using TecniStamp
|
||||
@using TecniStamp.Components
|
||||
@using TecniStamp.Components.Widget
|
||||
|
||||
@using Radzen
|
||||
@using Radzen.Blazor
|
||||
|
||||
@ -3,6 +3,22 @@
|
||||
public class CalendarioCellaViewModel
|
||||
{
|
||||
public int Ore { get; set; }
|
||||
public int Capacita { get; set; } = 100;
|
||||
public string Stato { get; set; }
|
||||
public string Commesse { get; set; } = "";
|
||||
public int Percentuale { get; set; }
|
||||
}
|
||||
|
||||
public class MeseHeaderViewModel
|
||||
{
|
||||
public int Mese { get; set; }
|
||||
public string Nome { get; set; } = "";
|
||||
public int ColSpan { get; set; }
|
||||
}
|
||||
|
||||
public class CalendarioHeaderViewModel
|
||||
{
|
||||
public int Mese { get; set; }
|
||||
public string Nome { get; set; }
|
||||
public int Count { get; set; }
|
||||
}
|
||||
@ -1,11 +1,25 @@
|
||||
using TecniStamp.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TecniStamp.Domain;
|
||||
using TecniStamp.Model.Common;
|
||||
using TecniStamp.Service.Interfaces;
|
||||
|
||||
namespace TecniStamp.Utils;
|
||||
|
||||
public static class BreadcrumbUtils
|
||||
{
|
||||
public static List<BreadcrumbViewModel> BuildBreadcrumb(Sezione sezione)
|
||||
public static async Task<List<BreadcrumbViewModel>> BuildBreadcrumbByFeature(IManagerService _managerService, string featureName,
|
||||
string? extraText = null,
|
||||
string? parentUrlOverride = null)
|
||||
{
|
||||
var section = await _managerService.FeatureService.RicercaPer(x => x.Nome == featureName,
|
||||
includi:x => x.Include(y => y.Sezione).ThenInclude(x => x.Parent));
|
||||
return BuildBreadcrumb(section.Sezione, extraText, parentUrlOverride);
|
||||
}
|
||||
|
||||
public static List<BreadcrumbViewModel> BuildBreadcrumb(
|
||||
Sezione sezione,
|
||||
string? extraText = null,
|
||||
string? parentUrlOverride = null)
|
||||
{
|
||||
var stack = new Stack<Sezione>();
|
||||
var current = sezione;
|
||||
@ -37,9 +51,30 @@ public static class BreadcrumbUtils
|
||||
});
|
||||
}
|
||||
|
||||
breadcrumb.Last().IsActive = true;
|
||||
breadcrumb.Last().Url = null;
|
||||
if (!string.IsNullOrWhiteSpace(extraText))
|
||||
{
|
||||
// 🔹 rendo cliccabile il penultimo (la sezione)
|
||||
var parent = breadcrumb.Last();
|
||||
parent.IsActive = false;
|
||||
parent.Url = parentUrlOverride;
|
||||
|
||||
// 🔹 aggiungo la voce finale custom
|
||||
breadcrumb.Add(new BreadcrumbViewModel
|
||||
{
|
||||
Text = extraText,
|
||||
Url = null,
|
||||
IsActive = true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// comportamento originale (index)
|
||||
var last = breadcrumb.Last();
|
||||
last.IsActive = true;
|
||||
last.Url = null;
|
||||
}
|
||||
|
||||
return breadcrumb;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user