Gestiti allegati nel form
This commit is contained in:
@@ -1,10 +1,14 @@
|
|||||||
using SteUp.Shared.Core.Dto;
|
using SteUp.Shared.Core.Dto;
|
||||||
|
using SteUp.Shared.Core.Helpers;
|
||||||
using SteUp.Shared.Core.Interface.System;
|
using SteUp.Shared.Core.Interface.System;
|
||||||
|
|
||||||
namespace SteUp.Maui.Core.Services;
|
namespace SteUp.Maui.Core.Services;
|
||||||
|
|
||||||
public class AttachedService : IAttachedService
|
public class AttachedService : IAttachedService
|
||||||
{
|
{
|
||||||
|
private static string AttachedRoot =>
|
||||||
|
Path.Combine(FileSystem.CacheDirectory, "attached");
|
||||||
|
|
||||||
public async Task<AttachedDto?> SelectImageFromCamera()
|
public async Task<AttachedDto?> SelectImageFromCamera()
|
||||||
{
|
{
|
||||||
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
|
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
|
||||||
@@ -18,6 +22,7 @@ public class AttachedService : IAttachedService
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = await MediaPicker.Default.CapturePhotoAsync();
|
result = await MediaPicker.Default.CapturePhotoAsync();
|
||||||
|
result?.FileName = $"img_{DateTime.Now:ddMMyyy_hhmmss}{result.FileName[result.FileName.IndexOf('.')..]}";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -29,17 +34,16 @@ public class AttachedService : IAttachedService
|
|||||||
return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AttachedDto?> SelectImageFromGallery()
|
public async Task<List<AttachedDto>?> SelectImageFromGallery()
|
||||||
{
|
{
|
||||||
|
List<FileResult>? resultList;
|
||||||
var storagePerm = await Permissions.RequestAsync<Permissions.StorageRead>();
|
var storagePerm = await Permissions.RequestAsync<Permissions.StorageRead>();
|
||||||
if (storagePerm != PermissionStatus.Granted)
|
if (storagePerm != PermissionStatus.Granted)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
FileResult? result;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = await MediaPicker.Default.PickPhotoAsync();
|
resultList = await MediaPicker.Default.PickPhotosAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -48,7 +52,15 @@ public class AttachedService : IAttachedService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
if (resultList.IsNullOrEmpty()) return null;
|
||||||
|
|
||||||
|
List<AttachedDto> returnList = [];
|
||||||
|
foreach (var fileResult in resultList)
|
||||||
|
{
|
||||||
|
returnList.Add(await ConvertToDto(fileResult, AttachedDto.TypeAttached.Image));
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<AttachedDto> ConvertToDto(FileResult file, AttachedDto.TypeAttached type)
|
private static async Task<AttachedDto> ConvertToDto(FileResult file, AttachedDto.TypeAttached type)
|
||||||
@@ -86,6 +98,15 @@ public class AttachedService : IAttachedService
|
|||||||
return filePath;
|
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)
|
public Task OpenFile(string fileName, string filePath)
|
||||||
{
|
{
|
||||||
#if IOS
|
#if IOS
|
||||||
@@ -98,4 +119,31 @@ public class AttachedService : IAttachedService
|
|||||||
});
|
});
|
||||||
#endif
|
#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, '_'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
52
SteUp.Maui/Core/Services/ImageThumb.cs
Normal file
52
SteUp.Maui/Core/Services/ImageThumb.cs
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
SafeAreaEdges="All"
|
SafeAreaEdges="All"
|
||||||
BackgroundColor="{DynamicResource PageBackgroundColor}">
|
BackgroundColor="{DynamicResource PageBackgroundColor}">
|
||||||
|
|
||||||
<BlazorWebView HostPage="wwwroot/index.html">
|
<BlazorWebView x:Name="BlazorWebView" HostPage="wwwroot/index.html">
|
||||||
<BlazorWebView.RootComponents>
|
<BlazorWebView.RootComponents>
|
||||||
<RootComponent Selector="#app" ComponentType="{x:Type shared:Components.Routes}" />
|
<RootComponent Selector="#app" ComponentType="{x:Type shared:Components.Routes}" />
|
||||||
</BlazorWebView.RootComponents>
|
</BlazorWebView.RootComponents>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="it.integry.SteUp">
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/appicon"
|
android:icon="@mipmap/appicon"
|
||||||
@@ -10,4 +10,19 @@
|
|||||||
<!-- Rete -->
|
<!-- Rete -->
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
|
<!-- Fotocamera -->
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
|
<!-- Storage / Media -->
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<!-- Android 10+ -->
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
||||||
|
|
||||||
|
<!-- Android 13+ -->
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="10.0.40" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="10.0.40" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.3" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.3" />
|
||||||
<PackageReference Include="Sentry.Maui" Version="6.1.0" />
|
<PackageReference Include="Sentry.Maui" Version="6.1.0" />
|
||||||
|
<PackageReference Include="SkiaSharp" Version="3.119.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
6
SteUp.Shared/Components/Pages/NotFound.razor
Normal file
6
SteUp.Shared/Components/Pages/NotFound.razor
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@page "/not-found"
|
||||||
|
@using SteUp.Shared.Components.Layout
|
||||||
|
@layout MainLayout
|
||||||
|
|
||||||
|
<h3>Not Found</h3>
|
||||||
|
<p>Sorry, the content you are looking for does not exist.</p>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<ErrorBoundary @ref="ErrorBoundary">
|
<ErrorBoundary @ref="ErrorBoundary">
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
<CascadingAuthenticationState>
|
<CascadingAuthenticationState>
|
||||||
<Router AppAssembly="@typeof(Routes).Assembly">
|
<Router AppAssembly="@typeof(Routes).Assembly" NotFoundPage="typeof(Pages.NotFound)">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)">
|
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)">
|
||||||
<Authorizing>
|
<Authorizing>
|
||||||
@@ -23,12 +23,6 @@
|
|||||||
</AuthorizeRouteView>
|
</AuthorizeRouteView>
|
||||||
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
||||||
</Found>
|
</Found>
|
||||||
<NotFound>
|
|
||||||
<PageTitle>Not found</PageTitle>
|
|
||||||
<LayoutView>
|
|
||||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
|
||||||
</LayoutView>
|
|
||||||
</NotFound>
|
|
||||||
</Router>
|
</Router>
|
||||||
</CascadingAuthenticationState>
|
</CascadingAuthenticationState>
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
@@ -44,7 +38,7 @@
|
|||||||
@code {
|
@code {
|
||||||
|
|
||||||
private ErrorBoundary? ErrorBoundary { get; set; }
|
private ErrorBoundary? ErrorBoundary { get; set; }
|
||||||
private ExceptionModal ExceptionModal { get; set; }
|
private ExceptionModal ExceptionModal { get; set; } = null!;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
var puntoVendita = SteupDataService.PuntiVenditaList.Find(x =>
|
var puntoVendita = SteupDataService.PuntiVenditaList.Find(x =>
|
||||||
x.CodMdep != null && x.CodMdep.EqualsIgnoreCase(Ispezione.CodMdep)
|
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");
|
PuntoVendita = puntoVendita ?? throw new Exception("Punto vendita non trovato");
|
||||||
OnLoading = false;
|
OnLoading = false;
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<MudMessageBox @ref="_confirmSave" Title="Attenzione!" CancelText="Non salvare">
|
||||||
|
<MessageContent>
|
||||||
|
Sono state apportate delle modifiche. Vuoi salvarle prima di continuare?
|
||||||
|
</MessageContent>
|
||||||
|
<YesButton>
|
||||||
|
<MudButton Size="Size.Small" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
|
Salva
|
||||||
|
</MudButton>
|
||||||
|
</YesButton>
|
||||||
|
</MudMessageBox>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private MudMessageBox? _confirmSave;
|
||||||
|
|
||||||
|
public async Task<bool?> ShowAsync()
|
||||||
|
{
|
||||||
|
if (_confirmSave == null) return null;
|
||||||
|
return await _confirmSave.ShowAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,117 +5,47 @@
|
|||||||
|
|
||||||
<MudDialog Class="disable-safe-area">
|
<MudDialog Class="disable-safe-area">
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<HeaderLayout SmallHeader="true" Cancel="true" OnCancel="@(() => MudDialog.Cancel())" Title="@TitleModal"/>
|
<HeaderLayout SmallHeader="true" Cancel="true" OnCancel="@(() => MudDialog.Cancel())" Title="Aggiungi allegati"/>
|
||||||
|
|
||||||
@if (RequireNewName)
|
<div style="margin-bottom: 1rem;" class="content attached">
|
||||||
{
|
<MudFab Size="Size.Small" Color="Color.Primary"
|
||||||
<MudTextField @bind-Value="NewName" Class="px-3" Variant="Variant.Outlined"/>
|
StartIcon="@Icons.Material.Rounded.CameraAlt"
|
||||||
}
|
Label="Camera" OnClick="@OnCamera"/>
|
||||||
else
|
|
||||||
{
|
|
||||||
<div style="margin-bottom: 1rem;" class="content attached">
|
|
||||||
<MudFab Size="Size.Small" Color="Color.Primary"
|
|
||||||
StartIcon="@Icons.Material.Rounded.CameraAlt"
|
|
||||||
Label="Camera" OnClick="@OnCamera"/>
|
|
||||||
|
|
||||||
<MudFab Size="Size.Small" Color="Color.Primary"
|
<MudFab Size="Size.Small" Color="Color.Primary"
|
||||||
StartIcon="@Icons.Material.Rounded.Image"
|
StartIcon="@Icons.Material.Rounded.Image"
|
||||||
Label="Galleria" OnClick="@OnGallery"/>
|
Label="Galleria" OnClick="@OnGallery"/>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
|
||||||
@if (RequireNewName)
|
|
||||||
{
|
|
||||||
<MudButton Disabled="NewName.IsNullOrEmpty()" Class="my-3" Size="Size.Small" Variant="Variant.Filled"
|
|
||||||
Color="Color.Primary"
|
|
||||||
StartIcon="@Icons.Material.Rounded.Check" OnClick="@OnNewName">
|
|
||||||
Salva
|
|
||||||
</MudButton>
|
|
||||||
}
|
|
||||||
</DialogActions>
|
|
||||||
</MudDialog>
|
</MudDialog>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
|
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
[Parameter] public bool CanAddPosition { get; set; }
|
[Parameter] public bool CanAddPosition { get; set; }
|
||||||
|
|
||||||
private AttachedDto? Attached { get; set; }
|
|
||||||
|
|
||||||
private bool _requireNewName;
|
private List<AttachedDto>? Attached { get; set; }
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
RequireNewName = false;
|
|
||||||
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
|
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnCamera()
|
private async Task OnCamera()
|
||||||
{
|
{
|
||||||
Attached = await AttachedService.SelectImageFromCamera();
|
var selectImageFromCamera = await AttachedService.SelectImageFromCamera();
|
||||||
|
|
||||||
if (Attached != null)
|
if (selectImageFromCamera != null)
|
||||||
{
|
{
|
||||||
RequireNewName = true;
|
Attached ??= [];
|
||||||
StateHasChanged();
|
Attached.Add(selectImageFromCamera);
|
||||||
|
MudDialog.Close(Attached);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnGallery()
|
private async Task OnGallery()
|
||||||
{
|
{
|
||||||
Attached = await AttachedService.SelectImageFromGallery();
|
Attached = await AttachedService.SelectImageFromGallery();
|
||||||
|
|
||||||
if (Attached != null)
|
if (Attached != null) MudDialog.Close(Attached);
|
||||||
{
|
|
||||||
RequireNewName = true;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,135 +1,126 @@
|
|||||||
@using SteUp.Shared.Components.Layout
|
@using SteUp.Shared.Components.Layout
|
||||||
@using SteUp.Shared.Components.Layout.Overlay
|
@using SteUp.Shared.Components.Layout.Overlay
|
||||||
|
@using SteUp.Shared.Components.Layout.Spinner
|
||||||
@using SteUp.Shared.Components.SingleElements.Card.ModalForm
|
@using SteUp.Shared.Components.SingleElements.Card.ModalForm
|
||||||
|
@using SteUp.Shared.Components.SingleElements.MessageBox
|
||||||
@using SteUp.Shared.Core.Dto
|
@using SteUp.Shared.Core.Dto
|
||||||
@using SteUp.Shared.Core.Entities
|
@using SteUp.Shared.Core.Entities
|
||||||
@using SteUp.Shared.Core.Interface.IntegryApi
|
@using SteUp.Shared.Core.Interface.IntegryApi
|
||||||
|
@using SteUp.Shared.Core.Interface.System
|
||||||
@using SteUp.Shared.Core.Interface.System.Network
|
@using SteUp.Shared.Core.Interface.System.Network
|
||||||
@inject INetworkService NetworkService
|
@inject INetworkService NetworkService
|
||||||
@inject IDialogService Dialog
|
@inject IDialogService Dialog
|
||||||
@inject IIntegryApiService IntegryApiService
|
@inject IIntegryApiService IntegryApiService
|
||||||
|
@inject IAttachedService AttachedService
|
||||||
|
|
||||||
<MudDialog Class="customDialog-form">
|
<MudDialog Class="customDialog-form">
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
<MudForm @ref="_form">
|
||||||
<HeaderLayout Cancel="true" OnCancel="@(() => MudDialog.Cancel())" LabelSave="@LabelSave"
|
<HeaderLayout Cancel="true" OnCancel="@Cancel" LabelSave="@LabelSave"
|
||||||
OnSave="Save" Title="Scheda"/>
|
OnSave="Save" Title="Scheda"/>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
||||||
<CardFormModal Title="Reparto" Loading="SteupDataService.Reparti.IsNullOrEmpty()">
|
<CardFormModal Title="Reparto" Loading="SteupDataService.Reparti.IsNullOrEmpty()">
|
||||||
<MudSelectExtended ReadOnly="IsView" T="JtbFasiDto?" Variant="Variant.Text"
|
<MudSelectExtended ReadOnly="IsView" T="JtbFasiDto?" Variant="Variant.Text"
|
||||||
@bind-Value="Scheda.Reparto" ToStringFunc="@(x => x?.Descrizione)"
|
@bind-Value="Scheda.Reparto" ToStringFunc="@(x => x?.Descrizione)"
|
||||||
@bind-Value:after="OnAfterChangeValue">
|
@bind-Value:after="OnAfterChangeValue" Required="true"
|
||||||
@foreach (var fasi in SteupDataService.Reparti)
|
RequiredError="Reparto obbligatorio">
|
||||||
{
|
@foreach (var fasi in SteupDataService.Reparti)
|
||||||
<MudSelectItemExtended Class="custom-item-select" Value="@fasi">
|
{
|
||||||
@fasi.Descrizione
|
<MudSelectItemExtended Class="custom-item-select" Value="@fasi">
|
||||||
</MudSelectItemExtended>
|
@fasi.Descrizione
|
||||||
}
|
</MudSelectItemExtended>
|
||||||
</MudSelectExtended>
|
}
|
||||||
</CardFormModal>
|
</MudSelectExtended>
|
||||||
|
</CardFormModal>
|
||||||
|
|
||||||
<CardFormModal Title="Motivo" Loading="SteupDataService.TipiAttività.IsNullOrEmpty()">
|
<CardFormModal Title="Motivo" Loading="SteupDataService.TipiAttività.IsNullOrEmpty()">
|
||||||
<MudSelectExtended ReadOnly="IsView" T="string?" Variant="Variant.Text"
|
<MudSelectExtended ReadOnly="@(IsView || Scheda.CodJfas.IsNullOrEmpty())" T="string?"
|
||||||
@bind-Value="Scheda.ActivityTypeId" @bind-Value:after="OnAfterChangeValue">
|
Variant="Variant.Text"
|
||||||
@foreach (var type in SteupDataService.TipiAttività)
|
@bind-Value="Scheda.ActivityTypeId" @bind-Value:after="OnAfterChangeValue"
|
||||||
{
|
Required="true" RequiredError="Motivo obbligatorio">
|
||||||
<MudSelectItemExtended Class="custom-item-select"
|
@foreach (var type in SteupDataService.TipiAttività.Where(x => x.CodJfas.EqualsIgnoreCase(Scheda.CodJfas!)))
|
||||||
Value="@type.ActivityTypeId">@type.ActivityTypeId</MudSelectItemExtended>
|
{
|
||||||
}
|
<MudSelectItemExtended Class="custom-item-select"
|
||||||
</MudSelectExtended>
|
Value="@type.ActivityTypeId">@type.ActivityTypeId</MudSelectItemExtended>
|
||||||
</CardFormModal>
|
}
|
||||||
|
</MudSelectExtended>
|
||||||
|
</CardFormModal>
|
||||||
|
|
||||||
@* <div class="container-chip-attached"> *@
|
@if (!AttachedList.IsNullOrEmpty())
|
||||||
@* @if (!AttachedList.IsNullOrEmpty()) *@
|
{
|
||||||
@* { *@
|
<div class="container-attached">
|
||||||
@* foreach (var item in AttachedList!.Select((p, index) => new { p, index })) *@
|
<div class="scroll-attached">
|
||||||
@* { *@
|
@foreach (var item in AttachedList!.Select((p, index) => new { p, index }))
|
||||||
@* if (item.p.Type == AttachedDTO.TypeAttached.Position) *@
|
{
|
||||||
@* { *@
|
<MudCard>
|
||||||
@* <MudChip T="string" Icon="@Icons.Material.Rounded.LocationOn" Color="Color.Success" *@
|
@if (!item.p.ThumbPath.IsNullOrEmpty())
|
||||||
@* OnClick="@(() => OpenPosition(item.p))" *@
|
{
|
||||||
@* OnClose="@(() => OnRemoveAttached(item.index))"> *@
|
<MudCardMedia Image="@item.p.ThumbPath" Height="100"/>
|
||||||
@* @item.p.Description *@
|
}
|
||||||
@* </MudChip> *@
|
<MudCardContent Class="image_card">
|
||||||
@* } *@
|
<MudText Typo="Typo.subtitle1"><b>@item.p.Name</b></MudText>
|
||||||
@* else *@
|
<MudIconButton Variant="Variant.Outlined" Icon="@Icons.Material.Rounded.Close"
|
||||||
@* { *@
|
Size="Size.Small" Color="Color.Error"
|
||||||
@* <MudChip T="string" Color="Color.Default" OnClick="@(() => OpenAttached(item.p))" *@
|
OnClick="@(() => OnRemoveAttached(item.index))"/>
|
||||||
@* OnClose="@(() => OnRemoveAttached(item.index))"> *@
|
</MudCardContent>
|
||||||
@* @item.p.Name *@
|
</MudCard>
|
||||||
@* </MudChip> *@
|
}
|
||||||
@* } *@
|
</div>
|
||||||
@* } *@
|
</div>
|
||||||
@* } *@
|
}
|
||||||
@* *@
|
|
||||||
@* @if (!IsLoading) *@
|
@if (!IsView)
|
||||||
@* { *@
|
{
|
||||||
@* if (ActivityFileList != null) *@
|
<div class="container-button">
|
||||||
@* { *@
|
<MudButton Class="button-settings green-icon"
|
||||||
@* foreach (var file in ActivityFileList) *@
|
FullWidth="true"
|
||||||
@* { *@
|
StartIcon="@Icons.Material.Rounded.AttachFile"
|
||||||
@* <MudChip T="string" OnClick="@(() => OpenAttached(file.FileName))" *@
|
Size="Size.Medium"
|
||||||
@* OnClose="@(() => DeleteAttach(file))" Color="Color.Default"> *@
|
OnClick="@OpenAddAttached"
|
||||||
@* @file.FileName *@
|
Variant="Variant.Outlined">
|
||||||
@* </MudChip> *@
|
Aggiungi foto
|
||||||
@* } *@
|
</MudButton>
|
||||||
@* } *@
|
</div>
|
||||||
@* } *@
|
}
|
||||||
@* else *@
|
|
||||||
@* { *@
|
<CardFormModal Title="Scadenza">
|
||||||
@* <MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="my-7"/> *@
|
<MudSelectExtended FullWidth="true" ReadOnly="@IsView" T="int" Variant="Variant.Text"
|
||||||
@* } *@
|
@bind-Value="@Scheda.Scadenza" @bind-Value:after="OnAfterChangeValue">
|
||||||
@* </div> *@
|
<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">
|
<div class="container-button">
|
||||||
<MudButton Class="button-settings green-icon"
|
<MudButton Class="button-settings blue-icon"
|
||||||
FullWidth="true"
|
FullWidth="true"
|
||||||
StartIcon="@Icons.Material.Rounded.AttachFile"
|
StartIcon="@Icons.Material.Rounded.Description"
|
||||||
Size="Size.Medium"
|
Size="Size.Medium"
|
||||||
OnClick="@OpenAddAttached"
|
OnClick="@SuggestActivityDescription"
|
||||||
Variant="Variant.Outlined">
|
Variant="Variant.Outlined">
|
||||||
Aggiungi foto
|
Suggerisci note descrittive
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</MudForm>
|
||||||
|
|
||||||
|
<ConfirmUpdateActivity @ref="_confirmUpdateMessage"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</MudDialog>
|
</MudDialog>
|
||||||
|
|
||||||
@@ -148,10 +139,17 @@
|
|||||||
private bool VisibleOverlay { get; set; }
|
private bool VisibleOverlay { get; set; }
|
||||||
private bool SuccessAnimation { 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;
|
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 (await CheckSavePreAction())
|
||||||
|
{
|
||||||
// if (result is { Canceled: false, Data: not null } && result.Data.GetType() == typeof(AttachedDTO))
|
await AttachedService.CleanTempStorageAsync();
|
||||||
// {
|
MudDialog.Cancel();
|
||||||
// var attached = (AttachedDTO)result.Data;
|
}
|
||||||
//
|
|
||||||
// if (attached.Type == AttachedDTO.TypeAttached.Position)
|
|
||||||
// CanAddPosition = false;
|
|
||||||
//
|
|
||||||
// AttachedList ??= [];
|
|
||||||
// AttachedList.Add(attached);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Form
|
||||||
|
|
||||||
private void OnAfterChangeValue()
|
private void OnAfterChangeValue()
|
||||||
{
|
{
|
||||||
if (!IsNew)
|
RecalcDirty();
|
||||||
LabelSave = "Aggiorna";
|
|
||||||
|
|
||||||
StateHasChanged();
|
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()
|
private void SuggestActivityDescription()
|
||||||
{
|
{
|
||||||
if (Scheda.ActivityTypeId == null)
|
if (Scheda.ActivityTypeId == null)
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
.container-chip-attached {
|
.container-attached {
|
||||||
width: 100%;
|
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 {
|
.container-button {
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ public interface ISteupDataService
|
|||||||
List<PuntoVenditaDto> PuntiVenditaList { get; }
|
List<PuntoVenditaDto> PuntiVenditaList { get; }
|
||||||
InspectionPageState InspectionPageState { get; set; }
|
InspectionPageState InspectionPageState { get; set; }
|
||||||
List<JtbFasiDto> Reparti { get; }
|
List<JtbFasiDto> Reparti { get; }
|
||||||
List<StbActivityTypeDto> TipiAttività { get; }
|
List<ActivityTypeDto> TipiAttività { get; }
|
||||||
}
|
}
|
||||||
@@ -42,5 +42,5 @@ public class SteupDataService(
|
|||||||
public InspectionPageState InspectionPageState { get; set; } = new();
|
public InspectionPageState InspectionPageState { get; set; } = new();
|
||||||
public List<PuntoVenditaDto> PuntiVenditaList { get; private set; } = [];
|
public List<PuntoVenditaDto> PuntiVenditaList { get; private set; } = [];
|
||||||
public List<JtbFasiDto> Reparti { get; private set; } = [];
|
public List<JtbFasiDto> Reparti { get; private set; } = [];
|
||||||
public List<StbActivityTypeDto> TipiAttività { get; private set; } = [];
|
public List<ActivityTypeDto> TipiAttività { get; private set; } = [];
|
||||||
}
|
}
|
||||||
12
SteUp.Shared/Core/Dto/ActivityTypeDto.cs
Normal file
12
SteUp.Shared/Core/Dto/ActivityTypeDto.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
@@ -10,6 +10,9 @@ public class AttachedDto
|
|||||||
public string? Path { get; set; }
|
public string? Path { get; set; }
|
||||||
|
|
||||||
public byte[]? FileBytes { get; set; }
|
public byte[]? FileBytes { get; set; }
|
||||||
|
|
||||||
|
public string? TempPath { get; set; }
|
||||||
|
public string? ThumbPath { get; set; }
|
||||||
|
|
||||||
public Stream? FileContent =>
|
public Stream? FileContent =>
|
||||||
FileBytes is null ? null : new MemoryStream(FileBytes);
|
FileBytes is null ? null : new MemoryStream(FileBytes);
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace SteUp.Shared.Core.Dto;
|
|
||||||
|
|
||||||
public class StbActivityTypeDto
|
|
||||||
{
|
|
||||||
[JsonPropertyName("activityTypeId")]
|
|
||||||
public string? ActivityTypeId { get; set; }
|
|
||||||
}
|
|
||||||
9
SteUp.Shared/Core/Entities/EntityBase.cs
Normal file
9
SteUp.Shared/Core/Entities/EntityBase.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace SteUp.Shared.Core.Entities;
|
||||||
|
|
||||||
|
public class EntityBase<T>
|
||||||
|
{
|
||||||
|
public T Clone()
|
||||||
|
{
|
||||||
|
return (T)MemberwiseClone();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ using SteUp.Shared.Core.Enum;
|
|||||||
|
|
||||||
namespace SteUp.Shared.Core.Entities;
|
namespace SteUp.Shared.Core.Entities;
|
||||||
|
|
||||||
public class Ispezione
|
public class Ispezione : EntityBase<Ispezione>
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public string CodMdep { get; set; } = string.Empty;
|
public string CodMdep { get; set; } = string.Empty;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using SteUp.Shared.Core.Dto;
|
|||||||
|
|
||||||
namespace SteUp.Shared.Core.Entities;
|
namespace SteUp.Shared.Core.Entities;
|
||||||
|
|
||||||
public class Scheda
|
public class Scheda : EntityBase<Scheda>
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
@@ -28,24 +28,24 @@ public class Scheda
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_reparto == null && CodJfas != null)
|
if (field == null && CodJfas != null)
|
||||||
{
|
{
|
||||||
_reparto = new JtbFasiDto
|
field = new JtbFasiDto
|
||||||
{
|
{
|
||||||
CodJfas = CodJfas,
|
CodJfas = CodJfas,
|
||||||
Descrizione = DescrizioneReparto
|
Descrizione = DescrizioneReparto
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return _reparto;
|
|
||||||
|
return field;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_reparto = value;
|
field = value;
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
|
|
||||||
CodJfas = value.CodJfas;
|
CodJfas = value.CodJfas;
|
||||||
DescrizioneReparto = value.Descrizione;
|
DescrizioneReparto = value.Descrizione;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private JtbFasiDto? _reparto;
|
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ using SteUp.Shared.Core.Dto;
|
|||||||
|
|
||||||
namespace SteUp.Shared.Core.Helpers;
|
namespace SteUp.Shared.Core.Helpers;
|
||||||
|
|
||||||
public class ModalHelper
|
public abstract class ModalHelper
|
||||||
{
|
{
|
||||||
public static async Task<DialogResult?> OpenSelectShop(IDialogService dialog)
|
public static async Task<DialogResult?> OpenSelectShop(IDialogService dialog)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ public interface IIntegrySteupService
|
|||||||
//Retrieve
|
//Retrieve
|
||||||
Task<List<PuntoVenditaDto>> RetrievePuntiVendita();
|
Task<List<PuntoVenditaDto>> RetrievePuntiVendita();
|
||||||
Task<List<JtbFasiDto>> RetrieveReparti();
|
Task<List<JtbFasiDto>> RetrieveReparti();
|
||||||
Task<List<StbActivityTypeDto>> RetrieveActivityType();
|
Task<List<ActivityTypeDto>> RetrieveActivityType();
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,11 @@ namespace SteUp.Shared.Core.Interface.System;
|
|||||||
public interface IAttachedService
|
public interface IAttachedService
|
||||||
{
|
{
|
||||||
Task<AttachedDto?> SelectImageFromCamera();
|
Task<AttachedDto?> SelectImageFromCamera();
|
||||||
Task<AttachedDto?> SelectImageFromGallery();
|
Task<List<AttachedDto>?> SelectImageFromGallery();
|
||||||
|
|
||||||
Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default);
|
Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default);
|
||||||
|
Task CleanTempStorageAsync(CancellationToken ct = default);
|
||||||
Task OpenFile(string fileName, string filePath);
|
Task OpenFile(string fileName, string filePath);
|
||||||
|
|
||||||
|
Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(byte[] bytes, string fileName, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,8 @@ public class IntegrySteupService(IIntegryApiRestClient integryApiRestClient) : I
|
|||||||
public Task<List<JtbFasiDto>> RetrieveReparti() =>
|
public Task<List<JtbFasiDto>> RetrieveReparti() =>
|
||||||
integryApiRestClient.AuthorizedGet<List<JtbFasiDto>>($"{BaseRequest}/retrieveReparti")!;
|
integryApiRestClient.AuthorizedGet<List<JtbFasiDto>>($"{BaseRequest}/retrieveReparti")!;
|
||||||
|
|
||||||
public Task<List<StbActivityTypeDto>> RetrieveActivityType() =>
|
public Task<List<ActivityTypeDto>> RetrieveActivityType() =>
|
||||||
integryApiRestClient.AuthorizedGet<List<StbActivityTypeDto>>($"{BaseRequest}/retrieveActivityType")!;
|
integryApiRestClient.AuthorizedGet<List<ActivityTypeDto>>($"{BaseRequest}/retrieveActivityType")!;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,10 @@
|
|||||||
height: calc(100vh - (.6rem + 40px));
|
height: calc(100vh - (.6rem + 40px));
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
gap: 1.5rem;
|
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) {
|
@supports (-webkit-touch-callout: none) {
|
||||||
|
|||||||
Reference in New Issue
Block a user