Gestiti allegati nel form
This commit is contained in:
@@ -1,135 +1,126 @@
|
||||
@using SteUp.Shared.Components.Layout
|
||||
@using SteUp.Shared.Components.Layout.Overlay
|
||||
@using SteUp.Shared.Components.Layout.Spinner
|
||||
@using SteUp.Shared.Components.SingleElements.Card.ModalForm
|
||||
@using SteUp.Shared.Components.SingleElements.MessageBox
|
||||
@using SteUp.Shared.Core.Dto
|
||||
@using SteUp.Shared.Core.Entities
|
||||
@using SteUp.Shared.Core.Interface.IntegryApi
|
||||
@using SteUp.Shared.Core.Interface.System
|
||||
@using SteUp.Shared.Core.Interface.System.Network
|
||||
@inject INetworkService NetworkService
|
||||
@inject IDialogService Dialog
|
||||
@inject IIntegryApiService IntegryApiService
|
||||
@inject IAttachedService AttachedService
|
||||
|
||||
<MudDialog Class="customDialog-form">
|
||||
<DialogContent>
|
||||
|
||||
<HeaderLayout Cancel="true" OnCancel="@(() => MudDialog.Cancel())" LabelSave="@LabelSave"
|
||||
OnSave="Save" Title="Scheda"/>
|
||||
<MudForm @ref="_form">
|
||||
<HeaderLayout Cancel="true" OnCancel="@Cancel" LabelSave="@LabelSave"
|
||||
OnSave="Save" Title="Scheda"/>
|
||||
|
||||
<div class="content">
|
||||
<div class="content">
|
||||
|
||||
<CardFormModal Title="Reparto" Loading="SteupDataService.Reparti.IsNullOrEmpty()">
|
||||
<MudSelectExtended ReadOnly="IsView" T="JtbFasiDto?" Variant="Variant.Text"
|
||||
@bind-Value="Scheda.Reparto" ToStringFunc="@(x => x?.Descrizione)"
|
||||
@bind-Value:after="OnAfterChangeValue">
|
||||
@foreach (var fasi in SteupDataService.Reparti)
|
||||
{
|
||||
<MudSelectItemExtended Class="custom-item-select" Value="@fasi">
|
||||
@fasi.Descrizione
|
||||
</MudSelectItemExtended>
|
||||
}
|
||||
</MudSelectExtended>
|
||||
</CardFormModal>
|
||||
<CardFormModal Title="Reparto" Loading="SteupDataService.Reparti.IsNullOrEmpty()">
|
||||
<MudSelectExtended ReadOnly="IsView" T="JtbFasiDto?" Variant="Variant.Text"
|
||||
@bind-Value="Scheda.Reparto" ToStringFunc="@(x => x?.Descrizione)"
|
||||
@bind-Value:after="OnAfterChangeValue" Required="true"
|
||||
RequiredError="Reparto obbligatorio">
|
||||
@foreach (var fasi in SteupDataService.Reparti)
|
||||
{
|
||||
<MudSelectItemExtended Class="custom-item-select" Value="@fasi">
|
||||
@fasi.Descrizione
|
||||
</MudSelectItemExtended>
|
||||
}
|
||||
</MudSelectExtended>
|
||||
</CardFormModal>
|
||||
|
||||
<CardFormModal Title="Motivo" Loading="SteupDataService.TipiAttività.IsNullOrEmpty()">
|
||||
<MudSelectExtended ReadOnly="IsView" T="string?" Variant="Variant.Text"
|
||||
@bind-Value="Scheda.ActivityTypeId" @bind-Value:after="OnAfterChangeValue">
|
||||
@foreach (var type in SteupDataService.TipiAttività)
|
||||
{
|
||||
<MudSelectItemExtended Class="custom-item-select"
|
||||
Value="@type.ActivityTypeId">@type.ActivityTypeId</MudSelectItemExtended>
|
||||
}
|
||||
</MudSelectExtended>
|
||||
</CardFormModal>
|
||||
<CardFormModal Title="Motivo" Loading="SteupDataService.TipiAttività.IsNullOrEmpty()">
|
||||
<MudSelectExtended ReadOnly="@(IsView || Scheda.CodJfas.IsNullOrEmpty())" T="string?"
|
||||
Variant="Variant.Text"
|
||||
@bind-Value="Scheda.ActivityTypeId" @bind-Value:after="OnAfterChangeValue"
|
||||
Required="true" RequiredError="Motivo obbligatorio">
|
||||
@foreach (var type in SteupDataService.TipiAttività.Where(x => x.CodJfas.EqualsIgnoreCase(Scheda.CodJfas!)))
|
||||
{
|
||||
<MudSelectItemExtended Class="custom-item-select"
|
||||
Value="@type.ActivityTypeId">@type.ActivityTypeId</MudSelectItemExtended>
|
||||
}
|
||||
</MudSelectExtended>
|
||||
</CardFormModal>
|
||||
|
||||
@* <div class="container-chip-attached"> *@
|
||||
@* @if (!AttachedList.IsNullOrEmpty()) *@
|
||||
@* { *@
|
||||
@* foreach (var item in AttachedList!.Select((p, index) => new { p, index })) *@
|
||||
@* { *@
|
||||
@* if (item.p.Type == AttachedDTO.TypeAttached.Position) *@
|
||||
@* { *@
|
||||
@* <MudChip T="string" Icon="@Icons.Material.Rounded.LocationOn" Color="Color.Success" *@
|
||||
@* OnClick="@(() => OpenPosition(item.p))" *@
|
||||
@* OnClose="@(() => OnRemoveAttached(item.index))"> *@
|
||||
@* @item.p.Description *@
|
||||
@* </MudChip> *@
|
||||
@* } *@
|
||||
@* else *@
|
||||
@* { *@
|
||||
@* <MudChip T="string" Color="Color.Default" OnClick="@(() => OpenAttached(item.p))" *@
|
||||
@* OnClose="@(() => OnRemoveAttached(item.index))"> *@
|
||||
@* @item.p.Name *@
|
||||
@* </MudChip> *@
|
||||
@* } *@
|
||||
@* } *@
|
||||
@* } *@
|
||||
@* *@
|
||||
@* @if (!IsLoading) *@
|
||||
@* { *@
|
||||
@* if (ActivityFileList != null) *@
|
||||
@* { *@
|
||||
@* foreach (var file in ActivityFileList) *@
|
||||
@* { *@
|
||||
@* <MudChip T="string" OnClick="@(() => OpenAttached(file.FileName))" *@
|
||||
@* OnClose="@(() => DeleteAttach(file))" Color="Color.Default"> *@
|
||||
@* @file.FileName *@
|
||||
@* </MudChip> *@
|
||||
@* } *@
|
||||
@* } *@
|
||||
@* } *@
|
||||
@* else *@
|
||||
@* { *@
|
||||
@* <MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="my-7"/> *@
|
||||
@* } *@
|
||||
@* </div> *@
|
||||
@if (!AttachedList.IsNullOrEmpty())
|
||||
{
|
||||
<div class="container-attached">
|
||||
<div class="scroll-attached">
|
||||
@foreach (var item in AttachedList!.Select((p, index) => new { p, index }))
|
||||
{
|
||||
<MudCard>
|
||||
@if (!item.p.ThumbPath.IsNullOrEmpty())
|
||||
{
|
||||
<MudCardMedia Image="@item.p.ThumbPath" Height="100"/>
|
||||
}
|
||||
<MudCardContent Class="image_card">
|
||||
<MudText Typo="Typo.subtitle1"><b>@item.p.Name</b></MudText>
|
||||
<MudIconButton Variant="Variant.Outlined" Icon="@Icons.Material.Rounded.Close"
|
||||
Size="Size.Small" Color="Color.Error"
|
||||
OnClick="@(() => OnRemoveAttached(item.index))"/>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!IsView)
|
||||
{
|
||||
<div class="container-button">
|
||||
<MudButton Class="button-settings green-icon"
|
||||
FullWidth="true"
|
||||
StartIcon="@Icons.Material.Rounded.AttachFile"
|
||||
Size="Size.Medium"
|
||||
OnClick="@OpenAddAttached"
|
||||
Variant="Variant.Outlined">
|
||||
Aggiungi foto
|
||||
</MudButton>
|
||||
</div>
|
||||
}
|
||||
|
||||
<CardFormModal Title="Scadenza">
|
||||
<MudSelectExtended FullWidth="true" ReadOnly="@IsView" T="int" Variant="Variant.Text"
|
||||
@bind-Value="@Scheda.Scadenza" @bind-Value:after="OnAfterChangeValue">
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="24H" Value="24"/>
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="1 Settimana" Value="168"/>
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="1 Mese" Value="730"/>
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="2 Mesi" Value="1460"/>
|
||||
</MudSelectExtended>
|
||||
</CardFormModal>
|
||||
|
||||
<CardFormModal Title="Responsabile">
|
||||
<MudTextField FullWidth="true" ReadOnly="IsView" T="string?" Variant="Variant.Text"
|
||||
@bind-Value="Scheda.Responsabile" @bind-Value:after="OnAfterChangeValue"
|
||||
DebounceInterval="500" OnDebounceIntervalElapsed="OnAfterChangeValue"/>
|
||||
</CardFormModal>
|
||||
|
||||
<CardFormModal Title="Note">
|
||||
<MudTextField ReadOnly="IsView" T="string?" Variant="Variant.Text" Lines="3"
|
||||
@bind-Value="Scheda.Note" @bind-Value:after="OnAfterChangeValue"
|
||||
DebounceInterval="500" OnDebounceIntervalElapsed="OnAfterChangeValue"/>
|
||||
</CardFormModal>
|
||||
|
||||
@if (!IsView)
|
||||
{
|
||||
<div class="container-button">
|
||||
<MudButton Class="button-settings green-icon"
|
||||
<MudButton Class="button-settings blue-icon"
|
||||
FullWidth="true"
|
||||
StartIcon="@Icons.Material.Rounded.AttachFile"
|
||||
StartIcon="@Icons.Material.Rounded.Description"
|
||||
Size="Size.Medium"
|
||||
OnClick="@OpenAddAttached"
|
||||
OnClick="@SuggestActivityDescription"
|
||||
Variant="Variant.Outlined">
|
||||
Aggiungi foto
|
||||
Suggerisci note descrittive
|
||||
</MudButton>
|
||||
</div>
|
||||
}
|
||||
|
||||
<CardFormModal Title="Scadenza">
|
||||
<MudSelectExtended FullWidth="true" ReadOnly="@IsView" T="int" Variant="Variant.Text"
|
||||
@bind-Value="@Scheda.Scadenza" @bind-Value:after="OnAfterChangeValue">
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="24H" Value="24"/>
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="1 Settimana" Value="168"/>
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="1 Mese" Value="730"/>
|
||||
<MudSelectItemExtended Class="custom-item-select" Text="2 Mesi" Value="1460"/>
|
||||
</MudSelectExtended>
|
||||
</CardFormModal>
|
||||
|
||||
<CardFormModal Title="Responsabile">
|
||||
<MudTextField FullWidth="true" ReadOnly="IsView" T="string?" Variant="Variant.Text"
|
||||
@bind-Value="Scheda.Responsabile" @bind-Value:after="OnAfterChangeValue"
|
||||
DebounceInterval="500" OnDebounceIntervalElapsed="OnAfterChangeValue"/>
|
||||
</CardFormModal>
|
||||
|
||||
<CardFormModal Title="Note">
|
||||
<MudTextField ReadOnly="IsView" T="string?" Variant="Variant.Text" Lines="3"
|
||||
@bind-Value="Scheda.Note" @bind-Value:after="OnAfterChangeValue"
|
||||
DebounceInterval="500" OnDebounceIntervalElapsed="OnAfterChangeValue"/>
|
||||
</CardFormModal>
|
||||
|
||||
<div class="container-button">
|
||||
<MudButton Class="button-settings blue-icon"
|
||||
FullWidth="true"
|
||||
StartIcon="@Icons.Material.Rounded.Description"
|
||||
Size="Size.Medium"
|
||||
OnClick="@SuggestActivityDescription"
|
||||
Variant="Variant.Outlined">
|
||||
Suggerisci note descrittive
|
||||
</MudButton>
|
||||
</div>
|
||||
</div>
|
||||
</MudForm>
|
||||
|
||||
<ConfirmUpdateActivity @ref="_confirmUpdateMessage"/>
|
||||
</DialogContent>
|
||||
</MudDialog>
|
||||
|
||||
@@ -148,10 +139,17 @@
|
||||
private bool VisibleOverlay { get; set; }
|
||||
private bool SuccessAnimation { get; set; }
|
||||
|
||||
private string? LabelSave { get; set; }
|
||||
private ConfirmUpdateActivity _confirmUpdateMessage = null!;
|
||||
private MudForm _form = null!;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
private string? LabelSave { get; set; }
|
||||
private bool IsDirty { get; set; }
|
||||
private Scheda _originalScheda = null!;
|
||||
private List<AttachedDto>? AttachedList { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_originalScheda = Scheda.Clone();
|
||||
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
|
||||
}
|
||||
|
||||
@@ -159,30 +157,129 @@
|
||||
{
|
||||
}
|
||||
|
||||
private async Task OpenAddAttached()
|
||||
private async Task Cancel()
|
||||
{
|
||||
var result = await ModalHelper.OpenAddAttached(Dialog);
|
||||
|
||||
// if (result is { Canceled: false, Data: not null } && result.Data.GetType() == typeof(AttachedDTO))
|
||||
// {
|
||||
// var attached = (AttachedDTO)result.Data;
|
||||
//
|
||||
// if (attached.Type == AttachedDTO.TypeAttached.Position)
|
||||
// CanAddPosition = false;
|
||||
//
|
||||
// AttachedList ??= [];
|
||||
// AttachedList.Add(attached);
|
||||
// }
|
||||
if (await CheckSavePreAction())
|
||||
{
|
||||
await AttachedService.CleanTempStorageAsync();
|
||||
MudDialog.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
#region Form
|
||||
|
||||
private void OnAfterChangeValue()
|
||||
{
|
||||
if (!IsNew)
|
||||
LabelSave = "Aggiorna";
|
||||
|
||||
RecalcDirty();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void RecalcDirty()
|
||||
{
|
||||
IsDirty = !ValueComparer.AreEqual(Scheda, _originalScheda);
|
||||
|
||||
if (IsDirty) LabelSave = !IsNew ? "Aggiorna" : "Salva";
|
||||
else LabelSave = null;
|
||||
}
|
||||
|
||||
private static class ValueComparer
|
||||
{
|
||||
public static bool AreEqual(Scheda? a, Scheda? b)
|
||||
{
|
||||
if (a is null || b is null) return a == b;
|
||||
|
||||
return
|
||||
a.CodJfas == b.CodJfas &&
|
||||
a.DescrizioneReparto == b.DescrizioneReparto &&
|
||||
a.ActivityTypeId == b.ActivityTypeId &&
|
||||
a.Note == b.Note &&
|
||||
a.Responsabile == b.Responsabile &&
|
||||
a.Scadenza == b.Scadenza;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CheckSavePreAction()
|
||||
{
|
||||
if (!IsDirty) return true;
|
||||
|
||||
var resul = await _confirmUpdateMessage.ShowAsync();
|
||||
if (resul is not true) return true;
|
||||
|
||||
VisibleOverlay = true;
|
||||
StateHasChanged();
|
||||
|
||||
await Submit();
|
||||
|
||||
VisibleOverlay = false;
|
||||
StateHasChanged();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task Submit()
|
||||
{
|
||||
await _form.Validate();
|
||||
if (_form.IsValid) await Save();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region File
|
||||
|
||||
private async Task OpenAddAttached()
|
||||
{
|
||||
var result = await ModalHelper.OpenAddAttached(Dialog);
|
||||
if (result is not { Canceled: false, Data: List<AttachedDto> attachedList }) return;
|
||||
|
||||
VisibleOverlay = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Task.Yield();
|
||||
|
||||
// prepara placeholder in UI subito (così vedi le card con spinner)
|
||||
AttachedList ??= [];
|
||||
foreach (var a in attachedList)
|
||||
AttachedList.Add(new AttachedDto { Name = a.Name, MimeType = a.MimeType, FileBytes = a.FileBytes });
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
// Processa in background e aggiorna UI man mano (o a blocchi)
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
for (var i = 0; i < attachedList.Count; i++)
|
||||
{
|
||||
var a = attachedList[i];
|
||||
if (a.FileBytes is null || a.Name is null) continue;
|
||||
|
||||
var (origUrl, thumbUrl) = await AttachedService.SaveAndCreateThumbAsync(a.FileBytes, a.Name);
|
||||
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
var target = AttachedList![AttachedList.Count - attachedList.Count + i];
|
||||
target.TempPath = origUrl;
|
||||
target.ThumbPath = thumbUrl;
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
VisibleOverlay = false;
|
||||
StateHasChanged();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void OnRemoveAttached(int index)
|
||||
{
|
||||
if (AttachedList is null || index < 0 || index >= AttachedList.Count)
|
||||
return;
|
||||
|
||||
AttachedList.RemoveAt(index);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SuggestActivityDescription()
|
||||
{
|
||||
if (Scheda.ActivityTypeId == null)
|
||||
|
||||
Reference in New Issue
Block a user