From b39b7ba751cceb8ba5eff760bf545aaff67fe742 Mon Sep 17 00:00:00 2001 From: MarcoE Date: Fri, 20 Feb 2026 15:29:32 +0100 Subject: [PATCH] Gestiti allegati nel form --- SteUp.Maui/Core/Services/AttachedService.cs | 58 ++- SteUp.Maui/Core/Services/ImageThumb.cs | 52 +++ SteUp.Maui/MainPage.xaml | 2 +- SteUp.Maui/MainPage.xaml.cs | 63 +++- .../Platforms/Android/AndroidManifest.xml | 17 +- SteUp.Maui/SteUp.Maui.csproj | 1 + SteUp.Shared/Components/Pages/NotFound.razor | 6 + SteUp.Shared/Components/Routes.razor | 10 +- .../SingleElements/Card/InspectionCard.razor | 2 +- .../MessageBox/ConfirmUpdateActivity.razor | 21 ++ .../Modal/ModalAddAttached.razor | 106 +----- .../Modal/ModalFormScheda.razor | 347 +++++++++++------- .../Modal/ModalFormScheda.razor.css | 19 +- .../Core/Data/Contracts/ISteupDataService.cs | 2 +- SteUp.Shared/Core/Data/SteupDataService.cs | 2 +- SteUp.Shared/Core/Dto/ActivityTypeDto.cs | 12 + SteUp.Shared/Core/Dto/AttachedDto.cs | 3 + SteUp.Shared/Core/Dto/StbActivityTypeDto.cs | 9 - SteUp.Shared/Core/Entities/EntityBase.cs | 9 + SteUp.Shared/Core/Entities/Ispezione.cs | 2 +- SteUp.Shared/Core/Entities/Scheda.cs | 14 +- SteUp.Shared/Core/Helpers/ModalHelper.cs | 2 +- .../IntegryApi/IIntegrySteupService.cs | 2 +- .../Core/Interface/System/IAttachedService.cs | 5 +- .../Core/Services/IntegrySteupService.cs | 4 +- SteUp.Shared/wwwroot/css/form.css | 5 +- 26 files changed, 512 insertions(+), 263 deletions(-) create mode 100644 SteUp.Maui/Core/Services/ImageThumb.cs create mode 100644 SteUp.Shared/Components/Pages/NotFound.razor create mode 100644 SteUp.Shared/Components/SingleElements/MessageBox/ConfirmUpdateActivity.razor create mode 100644 SteUp.Shared/Core/Dto/ActivityTypeDto.cs delete mode 100644 SteUp.Shared/Core/Dto/StbActivityTypeDto.cs create mode 100644 SteUp.Shared/Core/Entities/EntityBase.cs diff --git a/SteUp.Maui/Core/Services/AttachedService.cs b/SteUp.Maui/Core/Services/AttachedService.cs index d2da0e0..61d6bd5 100644 --- a/SteUp.Maui/Core/Services/AttachedService.cs +++ b/SteUp.Maui/Core/Services/AttachedService.cs @@ -1,10 +1,14 @@ using SteUp.Shared.Core.Dto; +using SteUp.Shared.Core.Helpers; using SteUp.Shared.Core.Interface.System; namespace SteUp.Maui.Core.Services; public class AttachedService : IAttachedService { + private static string AttachedRoot => + Path.Combine(FileSystem.CacheDirectory, "attached"); + public async Task SelectImageFromCamera() { var cameraPerm = await Permissions.RequestAsync(); @@ -18,6 +22,7 @@ public class AttachedService : IAttachedService try { result = await MediaPicker.Default.CapturePhotoAsync(); + result?.FileName = $"img_{DateTime.Now:ddMMyyy_hhmmss}{result.FileName[result.FileName.IndexOf('.')..]}"; } catch (Exception ex) { @@ -29,17 +34,16 @@ public class AttachedService : IAttachedService return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image); } - public async Task SelectImageFromGallery() + public async Task?> SelectImageFromGallery() { + List? resultList; var storagePerm = await Permissions.RequestAsync(); if (storagePerm != PermissionStatus.Granted) return null; - FileResult? result; - try { - result = await MediaPicker.Default.PickPhotoAsync(); + resultList = await MediaPicker.Default.PickPhotosAsync(); } catch (Exception ex) { @@ -48,7 +52,15 @@ public class AttachedService : IAttachedService return null; } - return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image); + if (resultList.IsNullOrEmpty()) return null; + + List returnList = []; + foreach (var fileResult in resultList) + { + returnList.Add(await ConvertToDto(fileResult, AttachedDto.TypeAttached.Image)); + } + + return returnList; } private static async Task ConvertToDto(FileResult file, AttachedDto.TypeAttached type) @@ -86,6 +98,15 @@ public class AttachedService : IAttachedService return filePath; } + public Task CleanTempStorageAsync(CancellationToken ct = default) + { + return Task.Run(() => + { + if (Directory.Exists(AttachedRoot)) + Directory.Delete(AttachedRoot, true); + }, ct); + } + public Task OpenFile(string fileName, string filePath) { #if IOS @@ -98,4 +119,31 @@ public class AttachedService : IAttachedService }); #endif } + + public async Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync( + byte[] bytes, string fileName, CancellationToken ct = default) + { + Directory.CreateDirectory(AttachedRoot); + + var id = Guid.NewGuid().ToString("N"); + var safeName = SanitizeFileName(fileName); + + var originalFile = $"{id}_{safeName}"; + var thumbFile = $"{id}_thumb.jpg"; + + var originalPath = Path.Combine(AttachedRoot, originalFile); + await File.WriteAllBytesAsync(originalPath, bytes, ct); + + var thumbPath = Path.Combine(AttachedRoot, thumbFile); + await ImageThumb.CreateThumbnailAsync(originalPath, thumbPath, maxSide: 320, quality: 70, ct); + + return ($"https://localfiles/attached/{originalFile}", + $"https://localfiles/attached/{thumbFile}"); + } + + private static string SanitizeFileName(string fileName) + { + var name = Path.GetFileName(fileName); + return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_')); + } } \ No newline at end of file diff --git a/SteUp.Maui/Core/Services/ImageThumb.cs b/SteUp.Maui/Core/Services/ImageThumb.cs new file mode 100644 index 0000000..2ba4ff0 --- /dev/null +++ b/SteUp.Maui/Core/Services/ImageThumb.cs @@ -0,0 +1,52 @@ +using SkiaSharp; + +namespace SteUp.Maui.Core.Services; + +public static class ImageThumb +{ + public static async Task CreateThumbnailAsync( + string inputPath, + string outputPath, + int maxSide = 320, + int quality = 70, + CancellationToken ct = default) + { + // Leggi bytes (meglio in async) + var data = await File.ReadAllBytesAsync(inputPath, ct); + + using var codec = SKCodec.Create(new SKMemoryStream(data)); + if (codec is null) + throw new InvalidOperationException("Formato immagine non supportato o file corrotto."); + + // Decodifica + var info = codec.Info; + using var bitmap = SKBitmap.Decode(codec); + if (bitmap is null) + throw new InvalidOperationException("Impossibile decodificare l'immagine."); + + // Calcola resize mantenendo aspect ratio + var w = bitmap.Width; + var h = bitmap.Height; + + if (w <= 0 || h <= 0) throw new InvalidOperationException("Dimensioni immagine non valide."); + + var scale = (float)maxSide / Math.Max(w, h); + if (scale > 1f) scale = 1f; // non ingrandire + + var newW = Math.Max(1, (int)Math.Round(w * scale)); + var newH = Math.Max(1, (int)Math.Round(h * scale)); + + using var resized = bitmap.Resize(new SKImageInfo(newW, newH), SKFilterQuality.Medium); + if (resized is null) + throw new InvalidOperationException("Resize fallito."); + + using var image = SKImage.FromBitmap(resized); + using var encoded = image.Encode(SKEncodedImageFormat.Jpeg, quality); + + Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!); + + await using var fs = File.Open(outputPath, FileMode.Create, FileAccess.Write, FileShare.None); + encoded.SaveTo(fs); + await fs.FlushAsync(ct); + } +} \ No newline at end of file diff --git a/SteUp.Maui/MainPage.xaml b/SteUp.Maui/MainPage.xaml index ea92419..f6025b4 100644 --- a/SteUp.Maui/MainPage.xaml +++ b/SteUp.Maui/MainPage.xaml @@ -6,7 +6,7 @@ SafeAreaEdges="All" BackgroundColor="{DynamicResource PageBackgroundColor}"> - + diff --git a/SteUp.Maui/MainPage.xaml.cs b/SteUp.Maui/MainPage.xaml.cs index 740b7a5..ce956c3 100644 --- a/SteUp.Maui/MainPage.xaml.cs +++ b/SteUp.Maui/MainPage.xaml.cs @@ -1,10 +1,59 @@ -namespace SteUp.Maui +namespace SteUp.Maui; + +public partial class MainPage : ContentPage { - public partial class MainPage : ContentPage + private static readonly string AttachedDir = + Path.Combine(FileSystem.CacheDirectory, "attached"); + + private const string Prefix = "https://localfiles/attached/"; + + public MainPage() { - public MainPage() - { - InitializeComponent(); - } + InitializeComponent(); + + Directory.CreateDirectory(AttachedDir); + + BlazorWebView.WebResourceRequested += BlazorWebView_WebResourceRequested; } -} + + private static void BlazorWebView_WebResourceRequested(object? sender, WebViewWebResourceRequestedEventArgs e) + { + var uri = e.Uri.ToString(); + if (string.IsNullOrWhiteSpace(uri) || + !uri.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase)) + return; + + var fileName = uri[Prefix.Length..]; + + fileName = fileName.Replace("\\", "/"); + if (fileName.Contains("..") || fileName.Contains('/')) + { + e.Handled = true; + e.SetResponse(400, "Bad Request"); + return; + } + + var fullPath = Path.Combine(AttachedDir, fileName); + + if (!File.Exists(fullPath)) + { + e.Handled = true; + e.SetResponse(404, "Not Found"); + return; + } + + e.Handled = true; + e.SetResponse(200, "OK", GetContentType(fullPath), File.OpenRead(fullPath)); + } + + private static string GetContentType(string path) + { + return Path.GetExtension(path).ToLowerInvariant() switch + { + ".png" => "image/png", + ".jpg" or ".jpeg" => "image/jpeg", + ".webp" => "image/webp", + _ => "application/octet-stream" + }; + } +} \ No newline at end of file diff --git a/SteUp.Maui/Platforms/Android/AndroidManifest.xml b/SteUp.Maui/Platforms/Android/AndroidManifest.xml index 191be83..e4623c3 100644 --- a/SteUp.Maui/Platforms/Android/AndroidManifest.xml +++ b/SteUp.Maui/Platforms/Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + + + + + + + + + + + + + + + + diff --git a/SteUp.Maui/SteUp.Maui.csproj b/SteUp.Maui/SteUp.Maui.csproj index 857225a..fb21d0b 100644 --- a/SteUp.Maui/SteUp.Maui.csproj +++ b/SteUp.Maui/SteUp.Maui.csproj @@ -121,6 +121,7 @@ + diff --git a/SteUp.Shared/Components/Pages/NotFound.razor b/SteUp.Shared/Components/Pages/NotFound.razor new file mode 100644 index 0000000..3a3cde1 --- /dev/null +++ b/SteUp.Shared/Components/Pages/NotFound.razor @@ -0,0 +1,6 @@ +@page "/not-found" +@using SteUp.Shared.Components.Layout +@layout MainLayout + +

Not Found

+

Sorry, the content you are looking for does not exist.

\ No newline at end of file diff --git a/SteUp.Shared/Components/Routes.razor b/SteUp.Shared/Components/Routes.razor index 40c698a..8ec23dd 100644 --- a/SteUp.Shared/Components/Routes.razor +++ b/SteUp.Shared/Components/Routes.razor @@ -4,7 +4,7 @@ - + @@ -23,12 +23,6 @@ - - Not found - -

Sorry, there's nothing at this address.

-
-
@@ -44,7 +38,7 @@ @code { private ErrorBoundary? ErrorBoundary { get; set; } - private ExceptionModal ExceptionModal { get; set; } + private ExceptionModal ExceptionModal { get; set; } = null!; protected override async Task OnInitializedAsync() { diff --git a/SteUp.Shared/Components/SingleElements/Card/InspectionCard.razor b/SteUp.Shared/Components/SingleElements/Card/InspectionCard.razor index 675f589..c05242f 100644 --- a/SteUp.Shared/Components/SingleElements/Card/InspectionCard.razor +++ b/SteUp.Shared/Components/SingleElements/Card/InspectionCard.razor @@ -92,7 +92,7 @@ var puntoVendita = SteupDataService.PuntiVenditaList.Find(x => x.CodMdep != null && x.CodMdep.EqualsIgnoreCase(Ispezione.CodMdep) ); - await Task.Delay(500); + await Task.Delay(250); PuntoVendita = puntoVendita ?? throw new Exception("Punto vendita non trovato"); OnLoading = false; diff --git a/SteUp.Shared/Components/SingleElements/MessageBox/ConfirmUpdateActivity.razor b/SteUp.Shared/Components/SingleElements/MessageBox/ConfirmUpdateActivity.razor new file mode 100644 index 0000000..9291311 --- /dev/null +++ b/SteUp.Shared/Components/SingleElements/MessageBox/ConfirmUpdateActivity.razor @@ -0,0 +1,21 @@ + + + Sono state apportate delle modifiche. Vuoi salvarle prima di continuare? + + + + Salva + + + + +@code +{ + private MudMessageBox? _confirmSave; + + public async Task ShowAsync() + { + if (_confirmSave == null) return null; + return await _confirmSave.ShowAsync(); + } +} \ No newline at end of file diff --git a/SteUp.Shared/Components/SingleElements/Modal/ModalAddAttached.razor b/SteUp.Shared/Components/SingleElements/Modal/ModalAddAttached.razor index 19339bb..4564ddd 100644 --- a/SteUp.Shared/Components/SingleElements/Modal/ModalAddAttached.razor +++ b/SteUp.Shared/Components/SingleElements/Modal/ModalAddAttached.razor @@ -5,117 +5,47 @@ - + - @if (RequireNewName) - { - - } - else - { -
- +
+ - -
- } + +
- - @if (RequireNewName) - { - - Salva - - } -
@code { [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; [Parameter] public bool CanAddPosition { get; set; } - - private AttachedDto? Attached { get; set; } - private bool _requireNewName; - - private bool RequireNewName - { - get => _requireNewName; - set - { - _requireNewName = value; - TitleModal = _requireNewName ? "Nome allegato" : "Aggiungi allegati"; - StateHasChanged(); - } - } - - private string TitleModal { get; set; } = "Aggiungi allegati"; - - private string? _newName; - - private string? NewName - { - get => _newName; - set - { - _newName = value; - StateHasChanged(); - } - } + private List? Attached { get; set; } protected override void OnInitialized() { - RequireNewName = false; Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter; } private async Task OnCamera() { - Attached = await AttachedService.SelectImageFromCamera(); - - if (Attached != null) + var selectImageFromCamera = await AttachedService.SelectImageFromCamera(); + + if (selectImageFromCamera != null) { - RequireNewName = true; - StateHasChanged(); + Attached ??= []; + Attached.Add(selectImageFromCamera); + MudDialog.Close(Attached); } } private async Task OnGallery() { Attached = await AttachedService.SelectImageFromGallery(); - - if (Attached != null) - { - RequireNewName = true; - StateHasChanged(); - } + + if (Attached != null) MudDialog.Close(Attached); } - - private void OnNewName() - { - if (Attached != null) - { - switch (Attached.Type) - { - case AttachedDto.TypeAttached.Image: - { - var extension = Path.GetExtension(Attached.Name); - Attached.Name = NewName! + extension; - - break; - } - default: - throw new ArgumentOutOfRangeException(); - } - } - - MudDialog.Close(Attached); - } - } \ No newline at end of file diff --git a/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor b/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor index 738b98a..5c84ab3 100644 --- a/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor +++ b/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor @@ -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 - - + + -
+
- - - @foreach (var fasi in SteupDataService.Reparti) - { - - @fasi.Descrizione - - } - - + + + @foreach (var fasi in SteupDataService.Reparti) + { + + @fasi.Descrizione + + } + + - - - @foreach (var type in SteupDataService.TipiAttività) - { - @type.ActivityTypeId - } - - + + + @foreach (var type in SteupDataService.TipiAttività.Where(x => x.CodJfas.EqualsIgnoreCase(Scheda.CodJfas!))) + { + @type.ActivityTypeId + } + + - @*
*@ - @* @if (!AttachedList.IsNullOrEmpty()) *@ - @* { *@ - @* foreach (var item in AttachedList!.Select((p, index) => new { p, index })) *@ - @* { *@ - @* if (item.p.Type == AttachedDTO.TypeAttached.Position) *@ - @* { *@ - @* *@ - @* @item.p.Description *@ - @* *@ - @* } *@ - @* else *@ - @* { *@ - @* *@ - @* @item.p.Name *@ - @* *@ - @* } *@ - @* } *@ - @* } *@ - @* *@ - @* @if (!IsLoading) *@ - @* { *@ - @* if (ActivityFileList != null) *@ - @* { *@ - @* foreach (var file in ActivityFileList) *@ - @* { *@ - @* *@ - @* @file.FileName *@ - @* *@ - @* } *@ - @* } *@ - @* } *@ - @* else *@ - @* { *@ - @* *@ - @* } *@ - @*
*@ + @if (!AttachedList.IsNullOrEmpty()) + { +
+
+ @foreach (var item in AttachedList!.Select((p, index) => new { p, index })) + { + + @if (!item.p.ThumbPath.IsNullOrEmpty()) + { + + } + + @item.p.Name + + + + } +
+
+ } + + @if (!IsView) + { +
+ + Aggiungi foto + +
+ } + + + + + + + + + + + + + + + + + - @if (!IsView) - {
- - Aggiungi foto + Suggerisci note descrittive
- } - - - - - - - - - - - - - - - - - - -
- - Suggerisci note descrittive -
-
+ + + @@ -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? 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 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 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) diff --git a/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor.css b/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor.css index 0f671f9..292748f 100644 --- a/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor.css +++ b/SteUp.Shared/Components/SingleElements/Modal/ModalFormScheda.razor.css @@ -1,6 +1,21 @@ -.container-chip-attached { +.container-attached { width: 100%; - margin-bottom: 1rem; +} + +.scroll-attached { + max-height: 185px; + overflow: auto; + display: flex; + gap: 1rem; + flex-direction: column; + padding: .5rem; +} + +.container-attached ::deep .image_card { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px; } .container-button { diff --git a/SteUp.Shared/Core/Data/Contracts/ISteupDataService.cs b/SteUp.Shared/Core/Data/Contracts/ISteupDataService.cs index d6a1414..749033d 100644 --- a/SteUp.Shared/Core/Data/Contracts/ISteupDataService.cs +++ b/SteUp.Shared/Core/Data/Contracts/ISteupDataService.cs @@ -11,5 +11,5 @@ public interface ISteupDataService List PuntiVenditaList { get; } InspectionPageState InspectionPageState { get; set; } List Reparti { get; } - List TipiAttività { get; } + List TipiAttività { get; } } \ No newline at end of file diff --git a/SteUp.Shared/Core/Data/SteupDataService.cs b/SteUp.Shared/Core/Data/SteupDataService.cs index 985341c..e7c0b1d 100644 --- a/SteUp.Shared/Core/Data/SteupDataService.cs +++ b/SteUp.Shared/Core/Data/SteupDataService.cs @@ -42,5 +42,5 @@ public class SteupDataService( public InspectionPageState InspectionPageState { get; set; } = new(); public List PuntiVenditaList { get; private set; } = []; public List Reparti { get; private set; } = []; - public List TipiAttività { get; private set; } = []; + public List TipiAttività { get; private set; } = []; } \ No newline at end of file diff --git a/SteUp.Shared/Core/Dto/ActivityTypeDto.cs b/SteUp.Shared/Core/Dto/ActivityTypeDto.cs new file mode 100644 index 0000000..0a6d7a2 --- /dev/null +++ b/SteUp.Shared/Core/Dto/ActivityTypeDto.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace SteUp.Shared.Core.Dto; + +public class ActivityTypeDto +{ + [JsonPropertyName("activityTypeId")] + public string ActivityTypeId { get; set; } = string.Empty; + + [JsonPropertyName("codJfas")] + public string CodJfas { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/SteUp.Shared/Core/Dto/AttachedDto.cs b/SteUp.Shared/Core/Dto/AttachedDto.cs index 8c7e34a..404c738 100644 --- a/SteUp.Shared/Core/Dto/AttachedDto.cs +++ b/SteUp.Shared/Core/Dto/AttachedDto.cs @@ -10,6 +10,9 @@ public class AttachedDto public string? Path { get; set; } public byte[]? FileBytes { get; set; } + + public string? TempPath { get; set; } + public string? ThumbPath { get; set; } public Stream? FileContent => FileBytes is null ? null : new MemoryStream(FileBytes); diff --git a/SteUp.Shared/Core/Dto/StbActivityTypeDto.cs b/SteUp.Shared/Core/Dto/StbActivityTypeDto.cs deleted file mode 100644 index 176ef5d..0000000 --- a/SteUp.Shared/Core/Dto/StbActivityTypeDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json.Serialization; - -namespace SteUp.Shared.Core.Dto; - -public class StbActivityTypeDto -{ - [JsonPropertyName("activityTypeId")] - public string? ActivityTypeId { get; set; } -} \ No newline at end of file diff --git a/SteUp.Shared/Core/Entities/EntityBase.cs b/SteUp.Shared/Core/Entities/EntityBase.cs new file mode 100644 index 0000000..5fff2d8 --- /dev/null +++ b/SteUp.Shared/Core/Entities/EntityBase.cs @@ -0,0 +1,9 @@ +namespace SteUp.Shared.Core.Entities; + +public class EntityBase +{ + public T Clone() + { + return (T)MemberwiseClone(); + } +} \ No newline at end of file diff --git a/SteUp.Shared/Core/Entities/Ispezione.cs b/SteUp.Shared/Core/Entities/Ispezione.cs index c2b6d56..283065b 100644 --- a/SteUp.Shared/Core/Entities/Ispezione.cs +++ b/SteUp.Shared/Core/Entities/Ispezione.cs @@ -3,7 +3,7 @@ using SteUp.Shared.Core.Enum; namespace SteUp.Shared.Core.Entities; -public class Ispezione +public class Ispezione : EntityBase { [Required] public string CodMdep { get; set; } = string.Empty; diff --git a/SteUp.Shared/Core/Entities/Scheda.cs b/SteUp.Shared/Core/Entities/Scheda.cs index d6b1363..48e929a 100644 --- a/SteUp.Shared/Core/Entities/Scheda.cs +++ b/SteUp.Shared/Core/Entities/Scheda.cs @@ -4,7 +4,7 @@ using SteUp.Shared.Core.Dto; namespace SteUp.Shared.Core.Entities; -public class Scheda +public class Scheda : EntityBase { [Key] public int Id { get; set; } @@ -28,24 +28,24 @@ public class Scheda { get { - if (_reparto == null && CodJfas != null) + if (field == null && CodJfas != null) { - _reparto = new JtbFasiDto + field = new JtbFasiDto { CodJfas = CodJfas, Descrizione = DescrizioneReparto }; } - return _reparto; + + return field; } set { - _reparto = value; + field = value; if (value == null) return; - + CodJfas = value.CodJfas; DescrizioneReparto = value.Descrizione; } } - private JtbFasiDto? _reparto; } \ No newline at end of file diff --git a/SteUp.Shared/Core/Helpers/ModalHelper.cs b/SteUp.Shared/Core/Helpers/ModalHelper.cs index 34db451..6fb1e72 100644 --- a/SteUp.Shared/Core/Helpers/ModalHelper.cs +++ b/SteUp.Shared/Core/Helpers/ModalHelper.cs @@ -4,7 +4,7 @@ using SteUp.Shared.Core.Dto; namespace SteUp.Shared.Core.Helpers; -public class ModalHelper +public abstract class ModalHelper { public static async Task OpenSelectShop(IDialogService dialog) { diff --git a/SteUp.Shared/Core/Interface/IntegryApi/IIntegrySteupService.cs b/SteUp.Shared/Core/Interface/IntegryApi/IIntegrySteupService.cs index 8ac0172..fb26aca 100644 --- a/SteUp.Shared/Core/Interface/IntegryApi/IIntegrySteupService.cs +++ b/SteUp.Shared/Core/Interface/IntegryApi/IIntegrySteupService.cs @@ -7,5 +7,5 @@ public interface IIntegrySteupService //Retrieve Task> RetrievePuntiVendita(); Task> RetrieveReparti(); - Task> RetrieveActivityType(); + Task> RetrieveActivityType(); } \ No newline at end of file diff --git a/SteUp.Shared/Core/Interface/System/IAttachedService.cs b/SteUp.Shared/Core/Interface/System/IAttachedService.cs index 3a00cfb..9353902 100644 --- a/SteUp.Shared/Core/Interface/System/IAttachedService.cs +++ b/SteUp.Shared/Core/Interface/System/IAttachedService.cs @@ -5,8 +5,11 @@ namespace SteUp.Shared.Core.Interface.System; public interface IAttachedService { Task SelectImageFromCamera(); - Task SelectImageFromGallery(); + Task?> SelectImageFromGallery(); Task SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default); + Task CleanTempStorageAsync(CancellationToken ct = default); Task OpenFile(string fileName, string filePath); + + Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(byte[] bytes, string fileName, CancellationToken ct = default); } \ No newline at end of file diff --git a/SteUp.Shared/Core/Services/IntegrySteupService.cs b/SteUp.Shared/Core/Services/IntegrySteupService.cs index ec421b7..cb054d9 100644 --- a/SteUp.Shared/Core/Services/IntegrySteupService.cs +++ b/SteUp.Shared/Core/Services/IntegrySteupService.cs @@ -16,8 +16,8 @@ public class IntegrySteupService(IIntegryApiRestClient integryApiRestClient) : I public Task> RetrieveReparti() => integryApiRestClient.AuthorizedGet>($"{BaseRequest}/retrieveReparti")!; - public Task> RetrieveActivityType() => - integryApiRestClient.AuthorizedGet>($"{BaseRequest}/retrieveActivityType")!; + public Task> RetrieveActivityType() => + integryApiRestClient.AuthorizedGet>($"{BaseRequest}/retrieveActivityType")!; #endregion } \ No newline at end of file diff --git a/SteUp.Shared/wwwroot/css/form.css b/SteUp.Shared/wwwroot/css/form.css index 473eeef..08e35ae 100644 --- a/SteUp.Shared/wwwroot/css/form.css +++ b/SteUp.Shared/wwwroot/css/form.css @@ -21,7 +21,10 @@ height: calc(100vh - (.6rem + 40px)); overflow: auto; gap: 1.5rem; - padding: 0 .75rem 2rem 75rem !important; + padding-top: unset !important; + padding-bottom: 2rem !important; + padding-left: .75rem !important; + padding-right: .75rem !important; } @supports (-webkit-touch-callout: none) {