Rimetti i reparti richiudibili e il "+" sul reparto

Le schede di un reparto erano un elenco fisso: con quattro reparti aperti
la pagina diventava un rotolo, e per aggiungere una scheda a un reparto
preciso bisognava passare dal comando generale e ridichiarare il reparto.

La testata del reparto torna a essere un comando: si tocca per richiudere
il gruppo, e la freccia dice da che parte sta. I conteggi salgono nella
testata ("3 schede · 1 da inviare · 1 da completare") invece di stare nel
corpo: un reparto compattato non deve nascondere quello che gli manca.

Accanto torna il "+", che apre la scheda nuova con il reparto gia'
scelto. E' l'unica differenza con il "+" della barra, ed e' quella che
toglie un passaggio a chi sta lavorando su un reparto alla volta.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 16:45:50 +02:00
parent b9de075f45
commit 70a0d0f5fa
2 changed files with 177 additions and 33 deletions
@@ -151,49 +151,64 @@
}
else
{
@* Un reparto per volta: la testata si tocca per richiudere il
gruppo, e i conteggi restano scritti li' anche da chiuso — un
reparto compattato non deve nascondere quello che gli manca. *@
@foreach (var group in SchedeGrouped)
{
var reparto = group.Key;
var chiuso = IsCollapsed(reparto);
var daInviare = group.Value.CountDaInviare();
var daCompletare = group.Value.CountBozze();
<section>
<div class="section-header">
<div class="section-header__text">
<h2 class="section-header__title">@group.Key.Descrizione</h2>
<p class="section-header__desc">
@(group.Value.Count == 1 ? "1 scheda" : $"{group.Value.Count} schede")
</p>
<section class="reparto @(chiuso ? "reparto--collapsed" : "")">
<div class="reparto__head">
<button type="button" class="reparto__toggle" @onclick="@(() => Toggle(reparto))"
aria-expanded="@((!chiuso).ToString().ToLowerInvariant())">
<i class="reparto__chevron ri-arrow-down-s-line" aria-hidden="true"></i>
<span class="reparto__text">
<span class="reparto__title">@reparto.Descrizione</span>
<span class="reparto__meta">@Conteggi(group.Value)</span>
</span>
</button>
<div class="reparto__actions">
@if (!IsCompleted)
{
@* Da qui la scheda nasce gia' con il suo reparto: e'
l'unica differenza con il "+" della barra. *@
<button type="button" class="reparto__add"
disabled="@(!NetworkService.IsNetworkAvailable())"
aria-label="@($"Nuova scheda nel reparto {reparto.Descrizione}")"
title="@($"Nuova scheda in {reparto.Descrizione}")"
@onclick="@(() => CreateNewScheda(reparto))">
<i class="ri-add-line" aria-hidden="true"></i>
</button>
@if (NetworkService.IsNetworkAvailable() && daInviare > 0)
{
<MudButton Variant="Variant.Outlined" Size="Size.Small"
StartIcon="@Icons.Material.Rounded.CloudUpload"
aria-label="@($"Invia le schede del reparto {reparto.Descrizione}")"
OnClick="@(() => ExportReparto(reparto))">
Invia @daInviare
</MudButton>
}
}
</div>
@if (!IsCompleted && NetworkService.IsNetworkAvailable() && daInviare > 0)
{
<div class="section-header__aside">
<MudButton Variant="Variant.Outlined" Size="Size.Small"
StartIcon="@Icons.Material.Rounded.CloudUpload"
aria-label="@($"Invia le schede del reparto {group.Key.Descrizione}")"
OnClick="@(() => ExportReparto(group.Key))">
Invia @daInviare
</MudButton>
</div>
}
</div>
@if (daCompletare > 0)
@if (!chiuso)
{
<div class="badge-row" style="margin-bottom: var(--space-10);">
<Badge Spec="@SyncState.Bozza.ToBadge()" Text="@($"{daCompletare} da completare")"/>
<div class="card-list reparto__body">
@foreach (var scheda in group.Value)
{
<SchedaCard Scheda="scheda" Ispezione="Ispezione"
OnSchedaDeleted="OnSchedaDeleted"
OnSchedaModified="OnSchedaModified"
OnBusyChanged="@(b => VisibleOverlay = b)"/>
}
</div>
}
<div class="card-list">
@foreach (var scheda in group.Value)
{
<SchedaCard Scheda="scheda" Ispezione="Ispezione"
OnSchedaDeleted="OnSchedaDeleted"
OnSchedaModified="OnSchedaModified"
OnBusyChanged="@(b => VisibleOverlay = b)"/>
}
</div>
</section>
}
}
@@ -296,6 +311,43 @@
if (modal is { Canceled: false }) LoadSchede();
}
/// Stessa scheda nuova, ma con il reparto gia' scelto: partendo da un
/// reparto non ha senso richiederlo.
private async Task CreateNewScheda(JtbFasiDto reparto)
{
var modal = await Dialog.OpenFormScheda(
Ispezione.CodMdep, Ispezione.Data, true, new Scheda { Reparto = reparto }
);
if (modal is { Canceled: false }) LoadSchede();
}
// I reparti richiusi stanno qui e non nell'entita': e' uno stato della
// schermata, non del documento.
private readonly HashSet<string> _collapsed = new(StringComparer.OrdinalIgnoreCase);
private bool IsCollapsed(JtbFasiDto reparto) =>
reparto.CodJfas is not null && _collapsed.Contains(reparto.CodJfas);
private void Toggle(JtbFasiDto reparto)
{
if (reparto.CodJfas is null) return;
if (!_collapsed.Remove(reparto.CodJfas)) _collapsed.Add(reparto.CodJfas);
}
private static string Conteggi(List<Scheda> schede)
{
var parti = new List<string> { schede.Count == 1 ? "1 scheda" : $"{schede.Count} schede" };
var daInviare = schede.CountDaInviare();
if (daInviare > 0) parti.Add($"{daInviare} da inviare");
var bozze = schede.CountBozze();
if (bozze > 0) parti.Add($"{bozze} da completare");
return string.Join(" · ", parti);
}
private async Task ConfirmCompleteInspection()
{
_actionsOpen = false;