Compare commits
19
Commits
9799f6b0c7
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2db0f2479 | ||
|
|
df827216c3 | ||
|
|
817cd606b6 | ||
|
|
495f335b72 | ||
|
|
ed7c28feac | ||
|
|
42e2403362 | ||
|
|
f59c8d3aaf | ||
|
|
249b301920 | ||
|
|
885b3cc6b6 | ||
|
|
7e1492d118 | ||
|
|
fd0c218ab5 | ||
|
|
deda374b5b | ||
|
|
e1ca03f646 | ||
|
|
92271e20fb | ||
|
|
e524c12a96 | ||
|
|
de889ef8c7 | ||
|
|
0e00fb273a | ||
|
|
f1a17a64db | ||
|
|
c3772733ea |
No files matched your search
@@ -155,14 +155,29 @@ public class IspezioniService(AppDbContext db) : IIspezioniService
|
|||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<Scheda>> GetAllSchedeOfIspezioneAsync(string codMdep, DateTime data, string rilevatore) =>
|
public async Task<List<Scheda>> GetAllSchedeOfIspezioneAsync(string codMdep, DateTime data, string rilevatore)
|
||||||
db.Schede
|
{
|
||||||
|
// Le versioni precedenti dell'app hanno lasciato schede non bozza senza
|
||||||
|
// reparto o motivo: risultano inviabili ma il server le rifiuta, e
|
||||||
|
// bloccano la conclusione dell'ispezione. Tornano bozze, cosi' il
|
||||||
|
// rilevatore le completa. Quelle gia' inviate non si toccano.
|
||||||
|
await db.Schede
|
||||||
|
.Where(x => x.CodMdep == codMdep &&
|
||||||
|
x.Data == data &&
|
||||||
|
x.Rilevatore == rilevatore &&
|
||||||
|
!x.Bozza &&
|
||||||
|
x.ActivityId == null &&
|
||||||
|
(string.IsNullOrEmpty(x.CodJfas) || string.IsNullOrEmpty(x.ActivityTypeId)))
|
||||||
|
.ExecuteUpdateAsync(s => s.SetProperty(x => x.Bozza, true));
|
||||||
|
|
||||||
|
return await db.Schede
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Include(s => s.Articoli)
|
.Include(s => s.Articoli)
|
||||||
.Where(x => x.CodMdep == codMdep &&
|
.Where(x => x.CodMdep == codMdep &&
|
||||||
x.Data == data &&
|
x.Data == data &&
|
||||||
x.Rilevatore == rilevatore)
|
x.Rilevatore == rilevatore)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public Task<Scheda?> GetSchedaAsync(int schedaId) =>
|
public Task<Scheda?> GetSchedaAsync(int schedaId) =>
|
||||||
db.Schede
|
db.Schede
|
||||||
|
|||||||
@@ -8,12 +8,21 @@ namespace SteUp.Maui.Core.Services;
|
|||||||
|
|
||||||
public class AttachedService(ILogger<FileManager> logger) : IAttachedService
|
public class AttachedService(ILogger<FileManager> logger) : IAttachedService
|
||||||
{
|
{
|
||||||
public async Task<AttachedDto?> SelectImageFromCamera()
|
public bool IsCameraAvailable => MediaPicker.Default.IsCaptureSupported;
|
||||||
|
|
||||||
|
public async Task<bool> RequestCameraPermissions()
|
||||||
{
|
{
|
||||||
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
|
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
|
||||||
var storagePerm = await Permissions.RequestAsync<Permissions.StorageWrite>();
|
var storagePerm = await Permissions.RequestAsync<Permissions.StorageWrite>();
|
||||||
|
|
||||||
if (cameraPerm != PermissionStatus.Granted || storagePerm != PermissionStatus.Granted)
|
return cameraPerm == PermissionStatus.Granted && storagePerm == PermissionStatus.Granted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenAppSettings() => AppInfo.Current.ShowSettingsUI();
|
||||||
|
|
||||||
|
public async Task<AttachedDto?> SelectImageFromCamera()
|
||||||
|
{
|
||||||
|
if (!await RequestCameraPermissions())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
FileResult? result;
|
FileResult? result;
|
||||||
@@ -28,7 +37,10 @@ public class AttachedService(ILogger<FileManager> logger) : IAttachedService
|
|||||||
logger.LogError(ex, ex.Message);
|
logger.LogError(ex, ex.Message);
|
||||||
Console.WriteLine($"Errore cattura foto: {ex.Message}");
|
Console.WriteLine($"Errore cattura foto: {ex.Message}");
|
||||||
SentrySdk.CaptureException(ex);
|
SentrySdk.CaptureException(ex);
|
||||||
return null;
|
|
||||||
|
// Rilancia: restituire null qui era indistinguibile da un annullamento,
|
||||||
|
// e il rilevatore toccava "Aggiungi una foto" senza vedere nulla.
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result is null ? null : await UtilityFile.ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
return result is null ? null : await UtilityFile.ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
||||||
|
|||||||
@@ -25,4 +25,11 @@
|
|||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
<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_VIDEO" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
|
|
||||||
|
<!-- Android 11+: rende visibile l'app fotocamera di sistema a MediaPicker -->
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -30,8 +30,8 @@
|
|||||||
<ApplicationId>it.integry.SteUp</ApplicationId>
|
<ApplicationId>it.integry.SteUp</ApplicationId>
|
||||||
|
|
||||||
<!-- Versions -->
|
<!-- Versions -->
|
||||||
<ApplicationDisplayVersion>1.2.0</ApplicationDisplayVersion>
|
<ApplicationDisplayVersion>1.2.4</ApplicationDisplayVersion>
|
||||||
<ApplicationVersion>6</ApplicationVersion>
|
<ApplicationVersion>10</ApplicationVersion>
|
||||||
|
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
|
||||||
<!-- <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">-->
|
<!-- <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">-->
|
||||||
@@ -116,12 +116,12 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommunityToolkit.Maui" Version="14.1.0" />
|
<PackageReference Include="CommunityToolkit.Maui" Version="14.1.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="IntegryApiClient.MAUI" Version="2.0.1" />
|
<PackageReference Include="IntegryApiClient.MAUI" Version="2.6.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.7" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.8" />
|
||||||
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.51" />
|
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.51" />
|
||||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="10.0.51" />
|
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="10.0.51" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="10.0.51" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="10.0.51" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.7" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.8" />
|
||||||
<PackageReference Include="Sentry.Maui" Version="6.4.1" />
|
<PackageReference Include="Sentry.Maui" Version="6.4.1" />
|
||||||
<PackageReference Include="SkiaSharp" Version="3.119.2" />
|
<PackageReference Include="SkiaSharp" Version="3.119.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -157,6 +157,7 @@
|
|||||||
@foreach (var group in SchedeGrouped)
|
@foreach (var group in SchedeGrouped)
|
||||||
{
|
{
|
||||||
var reparto = group.Key;
|
var reparto = group.Key;
|
||||||
|
var senzaReparto = ReferenceEquals(reparto, SenzaReparto);
|
||||||
var chiuso = IsCollapsed(reparto);
|
var chiuso = IsCollapsed(reparto);
|
||||||
var daInviare = group.Value.CountDaInviare();
|
var daInviare = group.Value.CountDaInviare();
|
||||||
|
|
||||||
@@ -172,7 +173,9 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="reparto__actions">
|
<div class="reparto__actions">
|
||||||
@if (!IsCompleted)
|
@* Il gruppo "Senza reparto" raccoglie solo bozze da
|
||||||
|
sistemare: non ha un "+" ne' un invio suo. *@
|
||||||
|
@if (!IsCompleted && !senzaReparto)
|
||||||
{
|
{
|
||||||
@* Da qui la scheda nasce gia' con il suo reparto: e'
|
@* Da qui la scheda nasce gia' con il suo reparto: e'
|
||||||
l'unica differenza con il "+" della barra. *@
|
l'unica differenza con il "+" della barra. *@
|
||||||
@@ -326,13 +329,15 @@
|
|||||||
// schermata, non del documento.
|
// schermata, non del documento.
|
||||||
private readonly HashSet<string> _collapsed = new(StringComparer.OrdinalIgnoreCase);
|
private readonly HashSet<string> _collapsed = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private bool IsCollapsed(JtbFasiDto reparto) =>
|
// Il gruppo "Senza reparto" non ha codice: la chiave vuota e' la sua.
|
||||||
reparto.CodJfas is not null && _collapsed.Contains(reparto.CodJfas);
|
private static string CollapseKey(JtbFasiDto reparto) => reparto.CodJfas ?? string.Empty;
|
||||||
|
|
||||||
|
private bool IsCollapsed(JtbFasiDto reparto) => _collapsed.Contains(CollapseKey(reparto));
|
||||||
|
|
||||||
private void Toggle(JtbFasiDto reparto)
|
private void Toggle(JtbFasiDto reparto)
|
||||||
{
|
{
|
||||||
if (reparto.CodJfas is null) return;
|
var key = CollapseKey(reparto);
|
||||||
if (!_collapsed.Remove(reparto.CodJfas)) _collapsed.Add(reparto.CodJfas);
|
if (!_collapsed.Remove(key)) _collapsed.Add(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Conteggi(List<Scheda> schede)
|
private static string Conteggi(List<Scheda> schede)
|
||||||
@@ -542,15 +547,22 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Una bozza si puo' salvare anche senza reparto: senza questo gruppo
|
||||||
|
// sparirebbe dall'elenco pur restando sul dispositivo e contata fra le bozze.
|
||||||
|
private static readonly JtbFasiDto SenzaReparto = new() { Descrizione = "Senza reparto" };
|
||||||
|
|
||||||
private void GroupSchede()
|
private void GroupSchede()
|
||||||
{
|
{
|
||||||
SchedeGrouped = SchedeList
|
var grouped = new Dictionary<JtbFasiDto, List<Scheda>>();
|
||||||
.Where(s => s.Reparto != null)
|
|
||||||
.GroupBy(s => s.CodJfas)
|
// In testa: sono schede a meta' che chiedono di essere completate.
|
||||||
.ToDictionary(
|
var senzaReparto = SchedeList.FindAll(s => s.Reparto == null);
|
||||||
g => g.First().Reparto!,
|
if (senzaReparto.Count > 0) grouped[SenzaReparto] = senzaReparto;
|
||||||
g => g.ToList()
|
|
||||||
);
|
foreach (var g in SchedeList.Where(s => s.Reparto != null).GroupBy(s => s.CodJfas))
|
||||||
|
grouped[g.First().Reparto!] = g.ToList();
|
||||||
|
|
||||||
|
SchedeGrouped = grouped;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSchedaModified(Scheda obj)
|
private void OnSchedaModified(Scheda obj)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<div class="list-card" aria-label="@SemanticLabel">
|
<div class="list-card" aria-label="@SemanticLabel">
|
||||||
<div class="list-card__head">
|
<div class="list-card__head">
|
||||||
<div class="list-card__ident">
|
<div class="list-card__ident">
|
||||||
<div class="t-ident">@Scheda.DescrizioneReparto</div>
|
<div class="t-ident">@(Scheda.DescrizioneReparto ?? "Senza reparto")</div>
|
||||||
<h3 class="list-card__title">@Titolo</h3>
|
<h3 class="list-card__title">@Titolo</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
private string SemanticLabel =>
|
private string SemanticLabel =>
|
||||||
$"Scheda {Titolo}, reparto {Scheda.DescrizioneReparto}, {SyncState.ToBadge().Label}, {ArticoliLabel}, {FotoLabel}";
|
$"Scheda {Titolo}, reparto {Scheda.DescrizioneReparto ?? "non indicato"},{SyncState.ToBadge().Label}, {ArticoliLabel}, {FotoLabel}";
|
||||||
|
|
||||||
private async Task SetBusy(bool value)
|
private async Task SetBusy(bool value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,7 +40,32 @@
|
|||||||
|
|
||||||
private async Task OnCamera()
|
private async Task OnCamera()
|
||||||
{
|
{
|
||||||
var selectImageFromCamera = await AttachedService.SelectImageFromCamera();
|
if (!await AttachedService.RequestCameraPermissions())
|
||||||
|
{
|
||||||
|
Snackbar.Clear();
|
||||||
|
Snackbar.Add("Per scattare le foto serve il permesso della fotocamera", Severity.Warning, config =>
|
||||||
|
{
|
||||||
|
config.Action = "Impostazioni";
|
||||||
|
config.OnClick = _ =>
|
||||||
|
{
|
||||||
|
AttachedService.OpenAppSettings();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachedDto? selectImageFromCamera;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
selectImageFromCamera = await AttachedService.SelectImageFromCamera();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Snackbar.Clear();
|
||||||
|
Snackbar.Add("Non è stato possibile scattare la foto, riprova", Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selectImageFromCamera != null)
|
if (selectImageFromCamera != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -754,12 +754,60 @@
|
|||||||
|
|
||||||
#region File
|
#region File
|
||||||
|
|
||||||
|
// Dopo un rifiuto definitivo Android non ripropone la richiesta: il
|
||||||
|
// permesso si riattiva solo dalle impostazioni, quindi le apriamo noi.
|
||||||
|
private void ShowCameraPermissionDenied()
|
||||||
|
{
|
||||||
|
Snackbar.Clear();
|
||||||
|
Snackbar.Add("Per scattare le foto serve il permesso della fotocamera", Severity.Warning, config =>
|
||||||
|
{
|
||||||
|
config.Action = "Impostazioni";
|
||||||
|
config.OnClick = _ =>
|
||||||
|
{
|
||||||
|
AttachedService.OpenAppSettings();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async Task OpenAddAttached()
|
private async Task OpenAddAttached()
|
||||||
{
|
{
|
||||||
var selectImageFromCamera = await AttachedService.SelectImageFromCamera();
|
List<AttachedDto>? attachedList;
|
||||||
if (selectImageFromCamera == null) return;
|
|
||||||
|
if (AttachedService.IsCameraAvailable)
|
||||||
var attachedList = new List<AttachedDto> { selectImageFromCamera };
|
{
|
||||||
|
if (!await AttachedService.RequestCameraPermissions())
|
||||||
|
{
|
||||||
|
ShowCameraPermissionDenied();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachedDto? selectImageFromCamera;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
selectImageFromCamera = await AttachedService.SelectImageFromCamera();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Gia' registrato e inviato a Sentry dal servizio
|
||||||
|
Snackbar.Clear();
|
||||||
|
Snackbar.Add("Non è stato possibile scattare la foto, riprova", Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectImageFromCamera == null) return;
|
||||||
|
attachedList = [selectImageFromCamera];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Senza fotocamera "Aggiungi una foto" non avrebbe altra strada:
|
||||||
|
// si passa alla galleria invece di lasciare il rilevatore fermo.
|
||||||
|
Snackbar.Clear();
|
||||||
|
Snackbar.Add("Fotocamera non disponibile: scegli la foto dalla galleria", Severity.Warning);
|
||||||
|
|
||||||
|
attachedList = await AttachedService.SelectImageFromGallery();
|
||||||
|
if (attachedList is null || attachedList.Count == 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
OnLoading = true;
|
OnLoading = true;
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
@@ -848,29 +896,32 @@
|
|||||||
|
|
||||||
var modal = await WithChildDialog(() => Dialog.OpenSelectArt(articoli));
|
var modal = await WithChildDialog(() => Dialog.OpenSelectArt(articoli));
|
||||||
|
|
||||||
|
// Gli articoli si aggiungono sul thread della UI, come fanno le scansioni:
|
||||||
|
// toccare Scheda.Articoli da qui mentre arriva una lettura (o mentre la
|
||||||
|
// lista viene disegnata) puo' far perdere articoli.
|
||||||
await InvokeAsync(() =>
|
await InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
OnLoading = false;
|
OnLoading = false;
|
||||||
TextLoading = null;
|
TextLoading = null;
|
||||||
|
|
||||||
|
if (modal is { Canceled: false, Data: List<ArticoliInGrigliaDto> articoliSelezionati })
|
||||||
|
{
|
||||||
|
// Quelli gia' sparati non si aggiungono di nuovo.
|
||||||
|
Scheda.Articoli.InsertRange(0, articoliSelezionati
|
||||||
|
.DistinctBy(x => x.Barcode)
|
||||||
|
.Where(x => !ContainsBarcode(x.Barcode))
|
||||||
|
.Select(x => new SchedaArticolo
|
||||||
|
{
|
||||||
|
Barcode = x.Barcode,
|
||||||
|
Descrizione = x.Descrizione
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
RecalcDirty();
|
||||||
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (modal is { Canceled: false, Data: List<ArticoliInGrigliaDto> articoliSelezionati })
|
|
||||||
{
|
|
||||||
Scheda.Articoli.InsertRange(0, articoliSelezionati.ConvertAll(x => new SchedaArticolo
|
|
||||||
{
|
|
||||||
Barcode = x.Barcode,
|
|
||||||
Descrizione = x.Descrizione
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
await InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
RecalcDirty();
|
|
||||||
StateHasChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,7 +987,7 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (value is null) return;
|
if (value is null) return;
|
||||||
if (Scheda.Articoli.Any(x => x.Barcode.Equals(value))) return;
|
if (ContainsBarcode(value)) return;
|
||||||
|
|
||||||
await InvokeAsync(() =>
|
await InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
@@ -951,6 +1002,11 @@
|
|||||||
OnLoading = false;
|
OnLoading = false;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
|
// Il controllo va ripetuto sul barcode restituito: il server puo' rispondere
|
||||||
|
// con un barcode diverso da quello letto (lo stesso gia' scelto dalla griglia),
|
||||||
|
// e due letture ravvicinate superano entrambe il controllo iniziale.
|
||||||
|
if (art != null && ContainsBarcode(art.Barcode)) return;
|
||||||
|
|
||||||
if (art != null)
|
if (art != null)
|
||||||
{
|
{
|
||||||
Scheda.Articoli.Insert(0, new SchedaArticolo
|
Scheda.Articoli.Insert(0, new SchedaArticolo
|
||||||
@@ -984,6 +1040,8 @@
|
|||||||
|
|
||||||
private void OnErrorScan(string? value) => OnError(new Exception(value), value);
|
private void OnErrorScan(string? value) => OnError(new Exception(value), value);
|
||||||
|
|
||||||
|
private bool ContainsBarcode(string barcode) => Scheda.Articoli.Any(x => x.Barcode.Equals(barcode));
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void OnError(Exception? e, string? errorMessage)
|
private void OnError(Exception? e, string? errorMessage)
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ namespace SteUp.Shared.Core.Interface.System;
|
|||||||
|
|
||||||
public interface IAttachedService
|
public interface IAttachedService
|
||||||
{
|
{
|
||||||
|
bool IsCameraAvailable { get; }
|
||||||
|
|
||||||
|
/// <summary>Chiede i permessi per scattare; false se negati.</summary>
|
||||||
|
Task<bool> RequestCameraPermissions();
|
||||||
|
|
||||||
|
void OpenAppSettings();
|
||||||
|
|
||||||
|
/// <summary>Null se l'utente annulla; lancia se lo scatto fallisce.</summary>
|
||||||
Task<AttachedDto?> SelectImageFromCamera();
|
Task<AttachedDto?> SelectImageFromCamera();
|
||||||
Task<List<AttachedDto>?> SelectImageFromGallery();
|
Task<List<AttachedDto>?> SelectImageFromGallery();
|
||||||
}
|
}
|
||||||
@@ -11,13 +11,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IntegryApiClient.Core" Version="2.0.1" />
|
<PackageReference Include="IntegryApiClient.Core" Version="2.6.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.7" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="MudBlazor" Version="9.0.0" />
|
<PackageReference Include="MudBlazor" Version="9.0.0" />
|
||||||
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="9.0.1" />
|
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="9.0.1" />
|
||||||
<PackageReference Include="Sentry" Version="6.4.1" />
|
<PackageReference Include="Sentry" Version="6.4.1" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.17.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.18.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.7" />
|
||||||
<PackageReference Include="Microsoft.Maui.Essentials" Version="10.0.51" />
|
<PackageReference Include="Microsoft.Maui.Essentials" Version="10.0.51" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IntegryApiClient.Blazor" Version="2.0.1" />
|
<PackageReference Include="IntegryApiClient.Blazor" Version="2.6.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.7" />
|
||||||
|
|||||||
Reference in new issue
Block a user