Browse Source

IndexedDb, bugfixes ans type background color

master
Flo Smilari 4 years ago
parent
commit
7bceb922c6

+ 26
- 12
Pages/CaritasServiceFundVeloFoundKeyDataPage.razor View File

@@ -72,16 +72,28 @@
</div>
@if (OnlineStatusProvider.Online) {
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-1 justify-content-center" style="text-align: center">
<MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default" @onclick="InitializeMapPosition">
<label>
<svg xmlns="http://www.w3.org/2000/svg" height="48px" width="48px" viewBox="0 0 24 24" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M13 3.06V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06c-.46-4.17-3.77-7.48-7.94-7.94zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" />
<circle cx="12" cy="12" opacity=".3" r="2" />
<path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" />
</svg>
</label>
</MatRipple>
<div>
<MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default" @onclick="InitializeDeviceMapPosition">
<label>
<svg xmlns="http://www.w3.org/2000/svg" height="48px" width="48px" viewBox="0 0 24 24" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M13 3.06V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06c-.46-4.17-3.77-7.48-7.94-7.94zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" />
<circle cx="12" cy="12" opacity=".3" r="2" />
<path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" />
</svg>
</label>
</MatRipple>
</div>
<div style="margin-top:1rem">
<MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default" @onclick="InitializeBicycleMapPosition">
<label>
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 20 20" height="48px" viewBox="0 0 20 20" width="48px" fill="#000000">
<g><rect fill="none" height="20" width="20" /></g>
<g><g><path d="M15.5,9h-0.68l-1.58-4.34C13.1,4.26,12.72,4,12.3,4H10v1h2.3l1.46,4H8.75L8.38,8H10V7H6v1h1.32l1.46,4H7.95 C7.7,10.19,6.13,8.86,4.2,9.01c-1.64,0.13-3.01,1.46-3.18,3.1C0.8,14.25,2.41,16,4.5,16c1.79,0,3.21-1.29,3.45-3h4.1 c0.25,1.81,1.83,3.14,3.75,2.99c1.64-0.13,3.01-1.46,3.18-3.1C19.2,10.75,17.59,9,15.5,9z M6.95,13c-0.23,1.15-1.22,2-2.45,2 C3.1,15,2,13.9,2,12.5S3.1,10,4.5,10c1.23,0,2.23,0.85,2.45,2H4v1H6.95z M12.05,12H9.84l-0.73-2h3.92 C12.5,10.52,12.16,11.22,12.05,12z M15.5,15c-1.4,0-2.5-1.1-2.5-2.5c0-0.94,0.5-1.73,1.24-2.16l1.03,2.83l0.94-0.34l-1.02-2.8 C15.3,10.02,15.4,10,15.5,10c1.4,0,2.5,1.1,2.5,2.5S16.9,15,15.5,15z" /></g></g>
</svg>
</label>
</MatRipple>
</div>
</div>
<div class="mat-layout-grid-cell mat-layout-grid-cell-span-3">
<div class="w-100 fv-osm-tile map-wrapper">
@@ -220,7 +232,7 @@
LatLng coordinates = new LatLng(report.GeographicInfo.Latitude, report.GeographicInfo.Longitude);
MouseEvent mouseEvent = new MouseEvent();
mouseEvent.LatLng = coordinates;
await InitializeMapPosition();
await InitializeBicycleMapPosition();
await AddBicycleMarkerOnClickPosition(mouseEvent);
StateHasChanged();
}
@@ -301,13 +313,14 @@
}
}
private void refreshGUIFromDto() {
private async void refreshGUIFromDto() {
FoundReport report = ReportDataProvider.GetFoundReport();
bicycleGeoPosition.Address = report.GeographicInfo.Address;
bicycleGeoPosition.Zip = report.GeographicInfo.Postcode;
bicycleGeoPosition.City = report.GeographicInfo.Town;
bicycleGeoPosition.Latitude = report.GeographicInfo.Latitude;
bicycleGeoPosition.Longitude = report.GeographicInfo.Longitude;
bicycleGeoPosition.DisplayCity = await GetFormattedAddressZipAndTown(ReportDataProvider);
imgUrl = report.FotoString;
selectedColor = Array.Find(Colors, color => color.Id == report.FarbeId);
selectedBrand = String.IsNullOrEmpty(report.NeueMarke) ? Array.Find(Brands, brand => brand.Id == report.MarkeId) : new Brand(-999, report.NeueMarke);
@@ -315,6 +328,7 @@
frameNumber = report.RahmenNummer;
remark = report.Bemerkung;
abholadresseIsNotContact = !report.AbholadresseIstKontakt;
StateHasChanged();
}
private void updateDtoFromGUI() {

+ 16
- 14
Pages/CaritasServiceFundVeloFoundKeyDataPage.razor.cs View File

@@ -38,8 +38,7 @@ namespace cwebplusApp.Pages {
private NominatimService NominatimService { get; set; }
private static NominatimReverseAddress addressDto;
private static NominatimReverseAddress AddressDto { get => addressDto; set { addressDto = value; } }
private NominatimReverseAddress addressDto;
public CaritasServiceFundVeloKeyDataPageBase() : base() {
@@ -66,14 +65,16 @@ namespace cwebplusApp.Pages {
await this.mapRef.OnClick(async (MouseEvent mouseEvent) => await OnMouseMapClicked(mouseEvent));
}
protected async Task InitializeMapPosition() {
protected async Task InitializeDeviceMapPosition() {
CreateBicycleMarkerOptions();
await AddEventsToMap();
if (this.bicycleGeoPosition.Latitude == 0 && this.bicycleGeoPosition.Longitude == 0) {
await ShowDeviceGeoLocation();
} else {
await ShowBicycleGeoLocation();
}
await ShowDeviceGeoLocation();
}
protected async Task InitializeBicycleMapPosition() {
CreateBicycleMarkerOptions();
await AddEventsToMap();
await ShowBicycleGeoLocation();
}
protected async Task<string> GetFormattedAddressZipAndTown(ReportDataProvider ReportDataProvider) {
@@ -81,6 +82,12 @@ namespace cwebplusApp.Pages {
this.bicycleGeoPosition.Latitude = ReportDataProvider.GetFoundReport().GeographicInfo.Latitude;
this.bicycleGeoPosition.Longitude = ReportDataProvider.GetFoundReport().GeographicInfo.Longitude;
addressDto = await NominatimService.GetAddressForCoordinates(this.bicycleGeoPosition.Latitude, this.bicycleGeoPosition.Longitude);
if (addressDto == null) {
addressDto = new();
addressDto.address = new();
addressDto.address.postcode = ReportDataProvider.GetFoundReport().GeographicInfo.Postcode;
addressDto.address.town = ReportDataProvider.GetFoundReport().GeographicInfo.Town;
}
}
return GetFormattedAddressZipAndTown(addressDto);
}
@@ -126,11 +133,6 @@ namespace cwebplusApp.Pages {
if (this.bicycleGeoPosition.Latitude != 0 && this.bicycleGeoPosition.Longitude != 0) {
LatLng geoPosition = new(this.bicycleGeoPosition.Latitude, this.bicycleGeoPosition.Longitude);
if (this.devicePositionMarker != null) {
await devicePositionMarker.Remove();
}
this.devicePositionMarker = await this.MarkerFactory.CreateAndAddToMap(geoPosition, this.mapRef);
await this.mapRef.SetZoom(16);
await this.mapRef.SetView(geoPosition);
}
@@ -145,7 +147,7 @@ namespace cwebplusApp.Pages {
}
private static string SplitAndGetFirstPostcode(string postcode) {
return postcode.Split("-", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0];
return String.IsNullOrEmpty(postcode)? "": postcode.Split("-", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0];
}
private async Task OnMouseMapClicked(MouseEvent mouseEvent) {

+ 3
- 2
Pages/CaritasServiceFundVeloLostFoundPage.razor View File

@@ -61,13 +61,14 @@
@code {
private int NbrPendingReports;
private int NbrPendingReports = 0;
protected async override void OnInitialized() {
base.OnInitialized();
PageHistoryManager.AddPageToHistory(NavigationManager.Uri);
ReportDataProvider.Report = null;
ReportDataProvider.ReportRepositoryItem = null;
StateHasChanged();
NbrPendingReports = await ReportRepositoryService.GetNbrOfPendingReports();
StateHasChanged();
}
@@ -93,6 +94,6 @@
}
private string getOpacity() {
return NbrPendingReports > 0 ? "opacity:1.0" : "opacity:0.5";
return NbrPendingReports > 0 ? "opacity:1.0" : "opacity:0.5";
}
}

+ 18
- 5
Pages/CaritasServiceFundVeloPendingOverviewPage.razor View File

@@ -8,6 +8,7 @@
@inject ReportDataProvider ReportDataProvider
@inject ReportRepositoryService ReportRepositoryService
@inject IStringLocalizer<Resources> i18n;
@inject Toaster Toaster;
<div class="row px-3 h-100">
<div class="row no-gutters align-items-start w-100" style="padding-top: 1rem;">
@@ -30,9 +31,9 @@
</div>
<div style="padding-top: 0.8rem">@context.ID</div>
</td>
<td>@translateType(context.ReportType)</td>
<td>@ReportRepositoryService.GetCurrentDateTimeFromMillis(context.ID)</td>
<td>@getAddress(context)</td>
<td style="@getTypeBackgroundStyle(context.ReportType)">@translateType(context.ReportType)</td>
<td style="white-space: nowrap">@ReportRepositoryService.GetCurrentDateTimeFromMillis(context.ID)</td>
<td style="white-space: nowrap">@getAddress(context)</td>
<td>@getPicture(context)</td>
<td>
<MatIconButton Icon="delete_forever" OnClick="@(_ => DeleteReport(context))"></MatIconButton>
@@ -73,6 +74,11 @@
return i18n.GetString("ReportType." + type);
}
private string getTypeBackgroundStyle(ReportRepositoryItem.Type type) {
return ReportRepositoryItem.Type.FOUND.Equals(type) ? "background: linear-gradient(45deg, darkseagreen, transparent)" : "background: linear-gradient(45deg, darksalmon, transparent)";
}
private string getAddress(ReportRepositoryItem item) {
return ReportRepositoryItem.Type.FOUND.Equals(item.ReportType) ? ((FoundReportRepositoryItem)item).Report.GeographicInfo.Address : "";
}
@@ -82,8 +88,15 @@
return "";
}
private void DeleteReport(ReportRepositoryItem item) {
private async void DeleteReport(ReportRepositoryItem item) {
try {
await ReportRepositoryService.DeleteReport(item);
pendingReports.Remove(item);
StateHasChanged();
Toaster.ShowSuccess(i18n.GetString("Success.DeleteReport.Title"), i18n.GetString("Success.DeleteReport.Msg", item.ID));
} catch (Exception ex) {
Toaster.ShowWarning(i18n.GetString("Error.DeleteReport.Title"), i18n.GetString("Error.DeleteReport.Msg", item.ID));
}
}
private void SendReport(ReportRepositoryItem item) {

+ 26
- 2
Program.cs View File

@@ -7,8 +7,10 @@ using MatBlazor;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using TG.Blazor.IndexedDB;
namespace CaritasPWA {
public class Program {
@@ -18,12 +20,12 @@ namespace CaritasPWA {
builder.Services.AddMatBlazor();
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddSingleton<IBicycleRestService, BicycleRestService>();
builder.Services.AddScoped<IBicycleRestService, BicycleRestService>();
builder.Services.AddSingleton<AppState>();
builder.Services.AddSingleton<PageHistoryManager>();
builder.Services.AddSingleton<ReportDataProvider>();
builder.Services.AddSingleton<OnlineStatusProvider>();
builder.Services.AddSingleton<ReportRepositoryService>();
builder.Services.AddScoped<ReportRepositoryService>();
builder.Services.AddScoped<Toaster>();
builder.Services.AddScoped<UserDataProvider>();
builder.Services.AddScoped<MasterDataService>();
@@ -44,6 +46,28 @@ namespace CaritasPWA {
config.HideTransitionDuration = 150;
});
builder.Services.AddIndexedDB(dbStore => {
dbStore.DbName = "CwebPlusAppDB";
dbStore.Version = 1;
dbStore.Stores.Add(new StoreSchema {
Name = "FoundReportRepositoryItems",
PrimaryKey = new IndexSpec { Name = "id", KeyPath = "id", Auto = true },
Indexes = new List<IndexSpec> {
new IndexSpec{Name="serverRefNbr", KeyPath = "serverRefNbr", Auto=false},
new IndexSpec{Name="status", KeyPath = "status", Auto=false}
}
});
dbStore.Stores.Add(new StoreSchema {
Name = "MissingReportRepositoryItems",
PrimaryKey = new IndexSpec { Name = "id", KeyPath = "id", Auto = true },
Indexes = new List<IndexSpec> {
new IndexSpec{Name="serverRefNbr", KeyPath = "serverRefNbr", Auto=false},
new IndexSpec{Name="status", KeyPath = "status", Auto=false}
}
});
});
await builder.Build().RunAsync();
}

+ 8
- 0
Shared/Models/FoundReportRepositoryItem.cs View File

@@ -4,8 +4,16 @@
private FoundReport report;
public FoundReport Report { get => report; set => report = value; }
public FoundReportRepositoryItem() : base(Type.FOUND, null) {
}
public FoundReportRepositoryItem(FoundReport _report, long identifier) : base(Type.FOUND, identifier) {
this.report = _report;
}
public override FoundReport GetReport() {
return report;
}
}
}

+ 7
- 0
Shared/Models/MissingReportRepositoryItem.cs View File

@@ -4,8 +4,15 @@
private MissingReport report;
public MissingReport Report { get => report; set => report = value; }
public MissingReportRepositoryItem() : base(Type.MISSING, null) {
}
public MissingReportRepositoryItem(MissingReport _report, long identifier) : base(Type.MISSING, identifier) {
this.report = _report;
}
public override MissingReport GetReport() {
return report;
}
}
}

+ 9
- 5
Shared/Models/ReportRepositoryItem.cs View File

@@ -4,21 +4,23 @@ namespace cwebplusApp.Shared.Models {
public abstract class ReportRepositoryItem {
public enum Type { FOUND, MISSING }
public enum State { PENDING, TRANSMITTED }
private long id;
private string serverRefNbr;
private bool transmitted;
private State status;
private Type reportType;
public long ID { get => id; set => id = value; }
public string ServerRefNbr { get => serverRefNbr; set => serverRefNbr = value; }
public bool Transmitted { get => transmitted; set => transmitted = value; }
public State Status { get => status; set => status = value; }
public Type ReportType { get => reportType; set => reportType = value; }
public ReportRepositoryItem(Type _reportType, long identifier) {
this.id = identifier;
public ReportRepositoryItem(Type _reportType, long? identifier) {
this.id = identifier.HasValue ? identifier.Value : 0;
this.reportType = _reportType;
this.transmitted = false;
this.status = State.PENDING;
}
public override bool Equals(Object obj) {
@@ -37,5 +39,7 @@ namespace cwebplusApp.Shared.Models {
public override string ToString() {
return base.ToString();
}
public abstract Report GetReport();
}
}

+ 12
- 0
Shared/ResourceFiles/Resources.de.resx View File

@@ -273,6 +273,12 @@
<data name="DevelopedBy" xml:space="preserve">
<value>Entwickelt durch</value>
</data>
<data name="Error.DeleteReport.Msg" xml:space="preserve">
<value>Die Meldung mit der ID {0:d} konnte nicht gelöscht werden!</value>
</data>
<data name="Error.DeleteReport.Title" xml:space="preserve">
<value>Löschung der Meldung fehlgeschlagen!</value>
</data>
<data name="Error.GeoLocation.Msg" xml:space="preserve">
<value>Die Geoposition konnte nicht ermittelt werden. Fehlermeldung : {0:s}</value>
</data>
@@ -462,6 +468,12 @@
<data name="Specifications" xml:space="preserve">
<value>Angaben</value>
</data>
<data name="Success.DeleteReport.Msg" xml:space="preserve">
<value>Die Meldung mit der ID {0:d} wurde erfolgreich gelöscht!</value>
</data>
<data name="Success.DeleteReport.Title" xml:space="preserve">
<value>Meldung gelöscht!</value>
</data>
<data name="Type" xml:space="preserve">
<value>Typ</value>
</data>

+ 12
- 0
Shared/ResourceFiles/Resources.fr.resx View File

@@ -273,6 +273,12 @@
<data name="DevelopedBy" xml:space="preserve">
<value>Développé par</value>
</data>
<data name="Error.DeleteReport.Msg" xml:space="preserve">
<value>Le rapport avec l'ID {0:d} n'a pas pu être supprimé !</value>
</data>
<data name="Error.DeleteReport.Title" xml:space="preserve">
<value>La suppression du rapport a échoué !</value>
</data>
<data name="Error.GeoLocation.Msg" xml:space="preserve">
<value>La géoposition n'a pas pu être déterminée. Message d'erreur : {0:s}</value>
</data>
@@ -462,6 +468,12 @@
<data name="Specifications" xml:space="preserve">
<value>Description détaillée</value>
</data>
<data name="Success.DeleteReport.Msg" xml:space="preserve">
<value>Le rapport avec l'ID {0:d} a été supprimé avec succès!</value>
</data>
<data name="Success.DeleteReport.Title" xml:space="preserve">
<value>Rapport supprimé!</value>
</data>
<data name="Type" xml:space="preserve">
<value>Typ</value>
</data>

+ 12
- 0
Shared/ResourceFiles/Resources.it.resx View File

@@ -273,6 +273,12 @@
<data name="DevelopedBy" xml:space="preserve">
<value>Sviluppata da</value>
</data>
<data name="Error.DeleteReport.Msg" xml:space="preserve">
<value>Il rapporto con ID {0:d} non può essere cancellato!</value>
</data>
<data name="Error.DeleteReport.Title" xml:space="preserve">
<value>Cancellazione del rapporto fallita!</value>
</data>
<data name="Error.GeoLocation.Msg" xml:space="preserve">
<value>Non è stato possibile determinare la posizione geografica. Messaggio d'errore: {0:s}</value>
</data>
@@ -462,6 +468,12 @@
<data name="Specifications" xml:space="preserve">
<value>Descrizione dettagliata</value>
</data>
<data name="Success.DeleteReport.Msg" xml:space="preserve">
<value>Il rapporto con l'ID {0:d} è stato cancellato con successo!</value>
</data>
<data name="Success.DeleteReport.Title" xml:space="preserve">
<value>Rapporto cancellato!</value>
</data>
<data name="Type" xml:space="preserve">
<value>Tipo</value>
</data>

+ 12
- 0
Shared/ResourceFiles/Resources.resx View File

@@ -273,6 +273,12 @@
<data name="DevelopedBy" xml:space="preserve">
<value>Developed by</value>
</data>
<data name="Error.DeleteReport.Msg" xml:space="preserve">
<value>The Report with ID {0:d} could not be deleted!</value>
</data>
<data name="Error.DeleteReport.Title" xml:space="preserve">
<value>Report deletion failed!</value>
</data>
<data name="Error.GeoLocation.Msg" xml:space="preserve">
<value>The Geo Location couldn't be get. ErrorMessage : {0:s}</value>
</data>
@@ -462,6 +468,12 @@
<data name="Specifications" xml:space="preserve">
<value>Specifications</value>
</data>
<data name="Success.DeleteReport.Msg" xml:space="preserve">
<value>The Report with ID {0:d} was successfully deleted!</value>
</data>
<data name="Success.DeleteReport.Title" xml:space="preserve">
<value>Report deleted!</value>
</data>
<data name="Type" xml:space="preserve">
<value>Type</value>
</data>

+ 4
- 4
Shared/Services/BicycleRestService.cs View File

@@ -88,7 +88,7 @@ namespace cwebplusApp.Shared.Services {
public async Task<ReportResponse> SendFoundReport(Report report) {
string subResourceUrl = configuration.GetValue<string>("subresource_url_foundreport");
return await SendReport(report, subResourceUrl, new FoundReportRepositoryItem((FoundReport)report, ReportRepositoryService.GetCurrentTimeInMillis()));
return await SendReport(report, subResourceUrl, new FoundReportRepositoryItem((FoundReport)report, 0));
}
public async Task<ReportResponse> SendFoundReport(FoundReportRepositoryItem reportRepositoryItem) {
@@ -98,7 +98,7 @@ namespace cwebplusApp.Shared.Services {
public async Task<ReportResponse> SendMissingReport(Report report) {
string subResourceUrl = configuration.GetValue<string>("subresource_url_missingreport");
return await SendReport(report, subResourceUrl, new MissingReportRepositoryItem((MissingReport)report, ReportRepositoryService.GetCurrentTimeInMillis()));
return await SendReport(report, subResourceUrl, new MissingReportRepositoryItem((MissingReport)report, 0));
}
public async Task<ReportResponse> SendMissingReport(MissingReportRepositoryItem reportRepositoryItem) {
@@ -149,7 +149,7 @@ namespace cwebplusApp.Shared.Services {
protected async Task<ReportResponse> SendReport(Report report, string subResourceUrl, ReportRepositoryItem reportRepositoryItem) {
ReportResponse response = null;
if (onlineStatusProvider.Online && !reportRepositoryItem.Transmitted) {
if (onlineStatusProvider.Online && ReportRepositoryItem.State.PENDING.Equals(reportRepositoryItem.Status)) {
if (httpClient != null) {
if (!String.IsNullOrEmpty(subResourceUrl)) {
string reportJson = JsonConvert.SerializeObject(report);
@@ -160,7 +160,7 @@ namespace cwebplusApp.Shared.Services {
response.StatusCode = httpResult.StatusCode;
if (HttpStatusCode.OK == response.StatusCode) {
reportRepositoryItem.ServerRefNbr = response.Data[0];
reportRepositoryItem.Transmitted = true;
reportRepositoryItem.Status = ReportRepositoryItem.State.TRANSMITTED;
await reportRepositoryService.SaveReport(reportRepositoryItem);
}
return response;

+ 68
- 78
Shared/Services/ReportRepositoryService.cs View File

@@ -1,22 +1,23 @@
using cwebplusApp.Shared.Models;
using Microsoft.JSInterop;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TG.Blazor.IndexedDB;
namespace cwebplusApp.Shared.Services {
public sealed class ReportRepositoryService {
private const string KeyNameFoundReports = "foundReportRepository";
private const string KeyNameMissingReports = "missingReportRepository";
private const string FoundReportRepository_Store_Name = "FoundReportRepositoryItems";
private const string MissingReportRepository_Store_Name = "MissingReportRepositoryItems";
private readonly IJSRuntime jsRuntime;
private bool initialized;
public event EventHandler Changed;
private readonly IndexedDBManager dbManager;
public ReportRepositoryService(IJSRuntime jsRuntime) {
public ReportRepositoryService(IJSRuntime jsRuntime, IndexedDBManager _dbManager) {
this.jsRuntime = jsRuntime;
this.dbManager = _dbManager;
}
public async Task SaveReport(ReportRepositoryItem reportRepositoryItem) {
@@ -28,97 +29,86 @@ namespace cwebplusApp.Shared.Services {
}
public async ValueTask<List<FoundReportRepositoryItem>> GetFoundReports() {
// Register the Storage event handler. This handler calls OnStorageUpdated when the storage changed.
// This way, you can reload the settings when another instance of the application (tab / window) save the settings
if (!initialized) {
// Create a reference to the current object, so the JS function can call the public method "OnStorageUpdated"
var reference = DotNetObjectReference.Create(this);
await this.jsRuntime.InvokeVoidAsync("BlazorRegisterStorageEvent", reference);
this.initialized = true;
}
// Read the JSON string that contains the data from the local storage
List<FoundReportRepositoryItem> result;
var str = await this.jsRuntime.InvokeAsync<string>("BlazorGetLocalStorage", KeyNameFoundReports);
if (str != null) {
result = JsonConvert.DeserializeObject<List<FoundReportRepositoryItem>>(str) ?? new();
} else {
result = new();
}
return result;
return await this.dbManager.GetRecords<FoundReportRepositoryItem>(FoundReportRepository_Store_Name);
}
public async ValueTask<List<FoundReportRepositoryItem>> GetPendingFoundReports() {
List<FoundReportRepositoryItem> pendingFoundReps = new();
List<FoundReportRepositoryItem> foundReps = await GetFoundReports();
foreach (FoundReportRepositoryItem report in foundReps) {
if (!report.Transmitted) {
pendingFoundReps.Add(report);
}
}
return pendingFoundReps;
var indexSearch = new StoreIndexQuery<ReportRepositoryItem.State> {
Storename = FoundReportRepository_Store_Name,
IndexName = "status",
QueryValue = ReportRepositoryItem.State.PENDING
};
return new List<FoundReportRepositoryItem>(await this.dbManager.GetAllRecordsByIndex<ReportRepositoryItem.State, FoundReportRepositoryItem>(indexSearch));
}
public async ValueTask<List<MissingReportRepositoryItem>> GetMissingReports() {
// Register the Storage event handler. This handler calls OnStorageUpdated when the storage changed.
// This way, you can reload the settings when another instance of the application (tab / window) save the settings
if (!initialized) {
// Create a reference to the current object, so the JS function can call the public method "OnStorageUpdated"
var reference = DotNetObjectReference.Create(this);
await this.jsRuntime.InvokeVoidAsync("BlazorRegisterStorageEvent", reference);
this.initialized = true;
}
// Read the JSON string that contains the data from the local storage
List<MissingReportRepositoryItem> result;
var str = await this.jsRuntime.InvokeAsync<string>("BlazorGetLocalStorage", KeyNameMissingReports);
if (str != null) {
result = JsonConvert.DeserializeObject<List<MissingReportRepositoryItem>>(str) ?? new();
} else {
result = new();
}
return result;
public async ValueTask<List<FoundReportRepositoryItem>> GetTransmittedFoundReports() {
var indexSearch = new StoreIndexQuery<ReportRepositoryItem.State> {
Storename = FoundReportRepository_Store_Name,
IndexName = "status",
QueryValue = ReportRepositoryItem.State.TRANSMITTED
};
return new List<FoundReportRepositoryItem>(await this.dbManager.GetAllRecordsByIndex<ReportRepositoryItem.State, FoundReportRepositoryItem>(indexSearch));
}
public async ValueTask<List<MissingReportRepositoryItem>> GetPendingMissingReports() {
List<MissingReportRepositoryItem> pendingMissingReps = new();
List<MissingReportRepositoryItem> missingReps = await GetMissingReports();
foreach (MissingReportRepositoryItem report in missingReps) {
if (!report.Transmitted) {
pendingMissingReps.Add(report);
}
}
return pendingMissingReps;
public async ValueTask<List<MissingReportRepositoryItem>> GetMissingReports() {
return await this.dbManager.GetRecords<MissingReportRepositoryItem>(MissingReportRepository_Store_Name);
}
public async Task SaveFoundReport(FoundReportRepositoryItem foundReportRepositoryItem) {
List<FoundReportRepositoryItem> foundReps = await GetFoundReports();
foundReps.Remove(foundReportRepositoryItem);
foundReps.Add(foundReportRepositoryItem);
var json = JsonConvert.SerializeObject(foundReps);
await jsRuntime.InvokeVoidAsync("BlazorSetLocalStorage", KeyNameFoundReports, json);
public async ValueTask<List<MissingReportRepositoryItem>> GetPendingMissingReports() {
var indexSearch = new StoreIndexQuery<ReportRepositoryItem.State> {
Storename = MissingReportRepository_Store_Name,
IndexName = "status",
QueryValue = ReportRepositoryItem.State.PENDING
};
return new List<MissingReportRepositoryItem>(await this.dbManager.GetAllRecordsByIndex<ReportRepositoryItem.State, MissingReportRepositoryItem>(indexSearch));
}
public async Task SaveMissingReport(MissingReportRepositoryItem missingReportRepositoryItem) {
List<MissingReportRepositoryItem> missingReps = await GetMissingReports();
missingReps.Remove(missingReportRepositoryItem);
missingReps.Add(missingReportRepositoryItem);
var json = JsonConvert.SerializeObject(missingReps);
await jsRuntime.InvokeVoidAsync("BlazorSetLocalStorage", KeyNameMissingReports, json);
public async ValueTask<List<MissingReportRepositoryItem>> GetTransmittedMissingReports() {
var indexSearch = new StoreIndexQuery<ReportRepositoryItem.State> {
Storename = MissingReportRepository_Store_Name,
IndexName = "status",
QueryValue = ReportRepositoryItem.State.TRANSMITTED
};
return new List<MissingReportRepositoryItem>(await this.dbManager.GetAllRecordsByIndex<ReportRepositoryItem.State, MissingReportRepositoryItem>(indexSearch));
}
public async ValueTask<int> GetNbrOfPendingReports() {
List<FoundReportRepositoryItem> foundReportRepositoryItems = await GetPendingFoundReports();
IList<FoundReportRepositoryItem> foundReportRepositoryItems = await GetPendingFoundReports();
List<MissingReportRepositoryItem> missingReportRepositoryItems = await GetPendingMissingReports();
return foundReportRepositoryItems.Count + missingReportRepositoryItems.Count;
}
// This method is called from BlazorRegisterStorageEvent when the storage changed
[JSInvokable]
public void OnStorageUpdated(string key) {
if (key == KeyNameMissingReports || key == KeyNameFoundReports) {
// Reset the settings. The next call to Get will reload the data
Changed?.Invoke(this, EventArgs.Empty);
public async Task SaveFoundReport(FoundReportRepositoryItem foundReportRepositoryItem) {
var newRecord = new StoreRecord<FoundReportRepositoryItem> {
Storename = FoundReportRepository_Store_Name,
Data = foundReportRepositoryItem
};
if (foundReportRepositoryItem.ID == 0) {
foundReportRepositoryItem.ID = GetCurrentTimeInMillis();
await this.dbManager.AddRecord(newRecord);
} else {
await this.dbManager.UpdateRecord(newRecord);
}
}
public async Task SaveMissingReport(MissingReportRepositoryItem missingReportRepositoryItem) {
var newRecord = new StoreRecord<MissingReportRepositoryItem> {
Storename = MissingReportRepository_Store_Name,
Data = missingReportRepositoryItem
};
if (missingReportRepositoryItem.ID == 0) {
missingReportRepositoryItem.ID = GetCurrentTimeInMillis();
await this.dbManager.AddRecord(newRecord);
} else {
await this.dbManager.UpdateRecord(newRecord);
}
}
public async Task DeleteReport(ReportRepositoryItem reportRepositoryItem) {
if (reportRepositoryItem is FoundReportRepositoryItem) {
await this.dbManager.DeleteRecord(FoundReportRepository_Store_Name, reportRepositoryItem.ID);
} else {
await this.dbManager.DeleteRecord(MissingReportRepository_Store_Name, reportRepositoryItem.ID);
}
}

+ 2
- 0
_Imports.razor View File

@@ -4,12 +4,14 @@
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Localization
@using Microsoft.JSInterop
@using MatBlazor
@using BlazorAnimate
@using FisSst.BlazorMaps
@using BlazorGeolocation
@using TG.Blazor.IndexedDB
@using CaritasPWA
@using cwebplusApp.Shared
@using cwebplusApp.Shared.ResourceFiles

+ 1
- 0
cwebplusApp.csproj View File

@@ -23,6 +23,7 @@
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
<PackageReference Include="TG.Blazor.IndexedDB" Version="1.5.0-preview" />
</ItemGroup>
<ItemGroup>

+ 1
- 0
wwwroot/index.html View File

@@ -33,6 +33,7 @@
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="_content/TG.Blazor.IndexedDB/indexedDb.Blazor.js"></script>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')

+ 2
- 1
wwwroot/service-worker.js View File

@@ -45,6 +45,7 @@ const assets = [
'_content/matblazor/dist/matblazor.js',
'_content/blazoranimate/blazoranimateinterop.js',
'_content/blazoranimate/aos.css',
'_content/TG.Blazor.IndexedDB/indexedDb.Blazor.js',
'_framework/blazor.webassembly.js',
'_framework/blazor.boot.json',
'_framework/dotnet.5.0.9.js',
@@ -92,7 +93,7 @@ self.addEventListener('activate', event => {
// fetch events (Network first strategy, no cache update after install)
self.addEventListener('fetch', function (event) {
event.respondWith(fromNetwork(event.request, 6000).catch(function () {
event.respondWith(fromNetwork(event.request, 15000).catch(function () {
return fromCache(event.request);
}));
});

Loading…
Cancel
Save