Fix rilevamento modifiche nella scheda: articoli e allegati
Uscendo dalla scheda il prompt di salvataggio non compariva e il pulsante "Salva" restava nascosto, perche' IsDirty non vedeva il lavoro fatto: - gli articoli scelti dalla griglia (OpenSelectArt) non marcavano mai la scheda come modificata; - ValueComparer confronta solo i campi del form, quindi ogni RecalcDirty() successivo azzerava il flag alzato con forceTrue da scanner e allegati. Non bastava confrontare Articoli: Clone() e' un MemberwiseClone, quindi _originalScheda condivide la stessa lista. Ora il confronto usa uno snapshot dei barcode preso all'apertura piu' un flag per gli allegati (che vivono in AttachedList fino al salvataggio), e RecalcDirty() perde forceTrue: non puo' piu' essere azzerato. Le chiamate su insert/remove degli articoli erano anche fatte prima della modifica della lista, quindi valutavano lo stato precedente. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -230,6 +230,11 @@
|
||||
private int _noteFieldKey;
|
||||
private bool IsDirty { get; set; }
|
||||
private Scheda _originalScheda = null!;
|
||||
// Clone() e' un MemberwiseClone, quindi _originalScheda condivide la stessa lista
|
||||
// Articoli: per accorgerci degli articoli aggiunti/rimossi serve uno snapshot a parte.
|
||||
private List<string> _originalBarcodes = [];
|
||||
// Gli allegati vivono in AttachedList finche' non si salva: li tracciamo con un flag.
|
||||
private bool _attachmentsDirty;
|
||||
private List<AttachedDto>? AttachedList { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
@@ -240,6 +245,7 @@
|
||||
OnScannerService.OnErrorScan += OnErrorScan;
|
||||
|
||||
_originalScheda = Scheda.Clone();
|
||||
_originalBarcodes = Scheda.Articoli.ConvertAll(x => x.Barcode);
|
||||
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
|
||||
|
||||
LoadAttached();
|
||||
@@ -456,14 +462,29 @@
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void RecalcDirty(bool forceTrue = false)
|
||||
private void RecalcDirty()
|
||||
{
|
||||
IsDirty = forceTrue || !ValueComparer.AreEqual(Scheda, _originalScheda);
|
||||
IsDirty = _attachmentsDirty
|
||||
|| !ValueComparer.AreEqual(Scheda, _originalScheda)
|
||||
|| !BarcodesUnchanged();
|
||||
|
||||
if (IsDirty) LabelSave = !IsNew ? "Aggiorna" : "Salva";
|
||||
else LabelSave = null;
|
||||
}
|
||||
|
||||
private bool BarcodesUnchanged()
|
||||
{
|
||||
if (Scheda.Articoli.Count != _originalBarcodes.Count) return false;
|
||||
|
||||
for (var i = 0; i < _originalBarcodes.Count; i++)
|
||||
{
|
||||
if (!Scheda.Articoli[i].Barcode.Equals(_originalBarcodes[i], StringComparison.Ordinal))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class ValueComparer
|
||||
{
|
||||
public static bool AreEqual(Scheda? a, Scheda? b)
|
||||
@@ -526,7 +547,8 @@
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
RecalcDirty(true);
|
||||
_attachmentsDirty = true;
|
||||
RecalcDirty();
|
||||
|
||||
// Processa in background e aggiorna UI man mano (o a blocchi)
|
||||
_ = Task.Run(async () =>
|
||||
@@ -618,7 +640,11 @@
|
||||
})
|
||||
);
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
RecalcDirty();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -631,7 +657,8 @@
|
||||
AttachedList[index].ToRemove = true;
|
||||
|
||||
AttachedList.RemoveAt(index);
|
||||
RecalcDirty(true);
|
||||
_attachmentsDirty = true;
|
||||
RecalcDirty();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
@@ -701,14 +728,13 @@
|
||||
|
||||
if (art != null)
|
||||
{
|
||||
RecalcDirty(true);
|
||||
|
||||
Scheda.Articoli.Insert(0, new SchedaArticolo
|
||||
{
|
||||
Barcode = art.Barcode,
|
||||
Descrizione = art.Descrizione
|
||||
});
|
||||
|
||||
RecalcDirty();
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
@@ -748,8 +774,8 @@
|
||||
var index = Scheda.Articoli.FindIndex(x => x.Barcode.Equals(barcode));
|
||||
if (index < 0) return;
|
||||
|
||||
RecalcDirty(true);
|
||||
Scheda.Articoli.RemoveAt(index);
|
||||
RecalcDirty();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user