From 5e574cd19ed1f1b5339870dd1853efadfeaf5eb5 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sat, 15 Nov 2025 08:13:35 +0100 Subject: [PATCH 1/3] fixes --- FruitBank.Common/Dtos/ProductDto.cs | 3 --- .../Grids/Products/GridStockQuantityHistoryDto.cs | 10 +++------- .../Products/GridStockQuantityHistoryDtoTemplate.razor | 9 ++------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/FruitBank.Common/Dtos/ProductDto.cs b/FruitBank.Common/Dtos/ProductDto.cs index fafd9f0..c42991b 100644 --- a/FruitBank.Common/Dtos/ProductDto.cs +++ b/FruitBank.Common/Dtos/ProductDto.cs @@ -3,11 +3,8 @@ using LinqToDB.Mapping; using Mango.Nop.Core.Dtos; using Mango.Nop.Core.Extensions; using Newtonsoft.Json; -using Nop.Core; //using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Common; -using Nop.Core.Domain.Orders; -using System.Globalization; using System.Linq.Expressions; namespace FruitBank.Common.Dtos; diff --git a/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDto.cs b/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDto.cs index 31ea073..2a28f4f 100644 --- a/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDto.cs +++ b/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDto.cs @@ -1,19 +1,15 @@ -using AyCode.Core.Interfaces; -using DevExpress.Blazor; +using DevExpress.Blazor; using FruitBank.Common.Dtos; -using FruitBank.Common.Entities; using FruitBank.Common.SignalRs; -using FruitBankHybrid.Shared.Pages; using Microsoft.AspNetCore.Components; -namespace FruitBankHybrid.Shared.Components.Grids.ShippingItems; +namespace FruitBankHybrid.Shared.Components.Grids.Products; public class GridStockQuantityHistoryDto : FruitBankListGridBase, IGrid { public GridStockQuantityHistoryDto() : base() { - if (IsMasterGrid) GetAllMessageTag = SignalRTags.GetStockQuantityHistoryDtos; - else GetAllMessageTag = SignalRTags.GetStockQuantityHistoryDtosByProductId; + GetAllMessageTag = IsMasterGrid ? SignalRTags.GetStockQuantityHistoryDtos : SignalRTags.GetStockQuantityHistoryDtosByProductId; //AddMessageTag = SignalRTags.AddShippingItem; //UpdateMessageTag = SignalRTags.UpdateShippingItem; diff --git a/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor b/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor index a59afca..aa68938 100644 --- a/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor +++ b/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor @@ -1,9 +1,6 @@ @using AyCode.Core.Loggers; -@using AyCode.Core.Extensions -@using AyCode.Core.Helpers @using AyCode.Utils.Extensions @using FruitBank.Common.Dtos -@using FruitBank.Common.Entities @using FruitBankHybrid.Shared.Components.Grids.ShippingItems @using FruitBankHybrid.Shared.Components.Toolbars @using FruitBankHybrid.Shared.Databases @@ -57,17 +54,15 @@ [Inject] public required DatabaseClient Database { get; set; } [Parameter] public object[]? ContextIds { get; set; } - [Parameter] public bool IsMasterGrid { get; set; } = false; + [Parameter] public bool IsMasterGrid { get; set; } [Parameter] public IEnumerable? ProductDtos { get; set; } [Parameter] public List? StockQuantityHistoryDtos { get; set; } string GridCss => !IsMasterGrid ? "hide-toolbar" : string.Empty; - const string ExportFileName = "ExportResult"; - public GridStockQuantityHistoryDto Grid { get; set; } - private LoggerClient _logger; + private LoggerClient _logger = null!; protected override async Task OnInitializedAsync() { From d2d4ea56c5f49bbdc737a76284e68ef58d6d5860 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sat, 15 Nov 2025 15:42:43 +0100 Subject: [PATCH 2/3] improvements, fixes --- .../Components/GridProductDto.cs | 9 ++++- .../Components/GridProductDtoTemplate.razor | 38 ++++++++++++------- .../Components/MgGridBase.cs | 13 +++++-- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/FruitBankHybrid.Shared/Components/GridProductDto.cs b/FruitBankHybrid.Shared/Components/GridProductDto.cs index 619e85c..2da7718 100644 --- a/FruitBankHybrid.Shared/Components/GridProductDto.cs +++ b/FruitBankHybrid.Shared/Components/GridProductDto.cs @@ -1,5 +1,12 @@ -namespace FruitBankHybrid.Shared.Components; +using DevExpress.Blazor; + +namespace FruitBankHybrid.Shared.Components; public class GridProductDto : MgGridBase { + protected override void CustomizeElementHideDetailButton(GridCustomizeElementEventArgs e) + { + //Felülírjuk, h ne adja hozzá a "hideDetailButton" css class-t! + return; + } } \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor index 639a476..bd29465 100644 --- a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor +++ b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor @@ -1,4 +1,5 @@ -@using AyCode.Core.Helpers +@using System.Threading +@using AyCode.Core.Helpers @using AyCode.Utils.Extensions @using DevExpress.Internal.About @using FruitBank.Common.Dtos @@ -27,19 +28,19 @@ - @if (IsMasterGrid && LoggedInModel.IsDeveloper) + @if (IsMasterGrid) { var productId = ((ProductDto)context.DataItem).Id; - + @{ //GetOrderDtosFromDbAsync(productId).Forget(); //var orderDtos = _orderDtos?.Where(o => o.OrderItemDtos.Any(oi => oi.ProductId == productId)).ToList() ?? []; } - + @{ //GetOrderItemDtosFromDbAsync(productId).Forget(); //var orderItemDtos = _orderItemDtos?.Where(oi => oi.ProductId == productId).ToList() ?? []; @@ -77,6 +78,9 @@ private List? _currentOrderDtos; private List? _currentOrderItemDtos; + private readonly SemaphoreSlim _lockOrderDtosByProductId = new(1); + private readonly SemaphoreSlim _lockOrderItemDtosByProductId = new(1); + private readonly Dictionary> _orderDtosByProductId = new(); private readonly Dictionary> _orderItemDtosByProductId = new(); @@ -125,29 +129,37 @@ private async Task> GetOrderDtosFromDbAsync(int productId) { - if (_orderDtosByProductId.TryGetValue(productId, out var orderDtos)) return orderDtos; + using(await _lockOrderDtosByProductId.UseWaitAsync()) + { + if (_orderDtosByProductId.TryGetValue(productId, out var orderDtos)) return orderDtos; - orderDtos = await FruitBankSignalRClient.GetAllOrderDtoByProductId(productId) ?? []; - _orderDtosByProductId[productId] = orderDtos; + orderDtos = await FruitBankSignalRClient.GetAllOrderDtoByProductId(productId) ?? []; + _orderDtosByProductId[productId] = orderDtos; - return _currentOrderDtos = orderDtos; + return _currentOrderDtos = orderDtos; + } } private async Task> GetOrderItemDtosFromDbAsync(int productId) { - if (_orderItemDtosByProductId.TryGetValue(productId, out var orderItemDtos)) return orderItemDtos; + using (await _lockOrderItemDtosByProductId.UseWaitAsync()) + { + if (_orderItemDtosByProductId.TryGetValue(productId, out var orderItemDtos)) return orderItemDtos; - orderItemDtos = await FruitBankSignalRClient.GetAllOrderItemDtoByProductId(productId) ?? []; - _orderItemDtosByProductId[productId] = orderItemDtos; + orderItemDtos = await FruitBankSignalRClient.GetAllOrderItemDtoByProductId(productId) ?? []; + _orderItemDtosByProductId[productId] = orderItemDtos; - return _currentOrderItemDtos = orderItemDtos; + return _currentOrderItemDtos = orderItemDtos; + } } protected async Task OnFocusedRowChanged(GridFocusedRowChangedEventArgs e) { + if (!LoggedInModel.IsDeveloper) return; + var productDto = (ProductDto)e.DataItem; - //if (e.Grid.IsDetailRowExpanded(e.VisibleIndex)) + if (e.Grid.IsDetailRowExpanded(e.VisibleIndex)) { _currentOrderDtos = null; _currentOrderDtos = productDto != null ? await GetOrderDtosFromDbAsync(productDto.Id) : []; diff --git a/FruitBankHybrid.Shared/Components/MgGridBase.cs b/FruitBankHybrid.Shared/Components/MgGridBase.cs index e14fa07..87b6622 100644 --- a/FruitBankHybrid.Shared/Components/MgGridBase.cs +++ b/FruitBankHybrid.Shared/Components/MgGridBase.cs @@ -41,6 +41,14 @@ public class MgGridBase : DxGrid // Layouts = JsonSerializer.Deserialize>(json); } + protected virtual void CustomizeElementHideDetailButton(GridCustomizeElementEventArgs e) + { + if (e.ElementType == GridElementType.DataRow && !LoggedInModel.IsDeveloper) + { + e.CssClass = "hideDetailButton"; + } + } + protected void OnCustomizeElement(GridCustomizeElementEventArgs e) { //if (!IsMasterGrid) e.CssClass = "hideDetailButton"; @@ -50,10 +58,7 @@ public class MgGridBase : DxGrid e.CssClass = " alt-item"; } - if(e.ElementType == GridElementType.DataRow && !LoggedInModel.IsDeveloper) - { - e.CssClass = "hideDetailButton"; - } + CustomizeElementHideDetailButton(e); if (e.ElementType == GridElementType.HeaderCell) { From a43c7e68585bdab186fdd161b19d05b1853547b1 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sun, 16 Nov 2025 19:21:06 +0100 Subject: [PATCH 3/3] MapHub TransportSendTimeout, WebSockets.CloseTimeout fix; etc... --- ...ollection.cs => MgObservableCollection.cs} | 87 ++++++++++++------- FruitBank.Common/Models/LoggedInModel.cs | 1 + .../Components/GridProductDtoTemplate.razor | 3 +- .../Databases/DatabaseClient.cs | 4 +- FruitBankHybrid.Shared/Pages/Login.razor | 1 + FruitBankHybrid.Shared/Pages/Login.razor.cs | 11 ++- .../SignalRs/FruitBankSignalRClient.cs | 8 ++ 7 files changed, 79 insertions(+), 36 deletions(-) rename FruitBank.Common/{FastObservableCollection.cs => MgObservableCollection.cs} (50%) diff --git a/FruitBank.Common/FastObservableCollection.cs b/FruitBank.Common/MgObservableCollection.cs similarity index 50% rename from FruitBank.Common/FastObservableCollection.cs rename to FruitBank.Common/MgObservableCollection.cs index c2944a0..fbb27ba 100644 --- a/FruitBank.Common/FastObservableCollection.cs +++ b/FruitBank.Common/MgObservableCollection.cs @@ -1,12 +1,11 @@ using System.Collections; -using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; namespace FruitBank.Common { - public interface IFastObservableCollection + public interface IMgFastObservableCollection { public void AddRange(IEnumerable other); public void Replace(IEnumerable other); @@ -14,20 +13,20 @@ namespace FruitBank.Common public void Synchronize(NotifyCollectionChangedEventArgs args); } - public interface IFastObservableCollection: IFastObservableCollection + public interface IMgFastObservableCollection : IMgFastObservableCollection { public void Replace(IEnumerable other); public void Sort(IComparer comparer); public void SortAndReplace(IEnumerable other, IComparer comparer); } - - public class FastObservableCollection : ObservableCollection, IFastObservableCollection + + public class MgObservableCollection : ObservableCollection, IMgFastObservableCollection { - private bool suppressChangedEvent = false; + private bool _suppressChangedEvent; public void Replace(IEnumerable other) { - suppressChangedEvent = true; + _suppressChangedEvent = true; Clear(); AddRange(other); @@ -35,45 +34,45 @@ namespace FruitBank.Common public void Replace(IEnumerable other) { - suppressChangedEvent = true; + _suppressChangedEvent = true; Clear(); foreach (T item in other) Add(item); - suppressChangedEvent = false; + _suppressChangedEvent = false; OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - OnPropertyChanged(new(nameof(Count))); + OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count))); } public void AddRange(IEnumerable other) { - suppressChangedEvent = true; + _suppressChangedEvent = true; - foreach (object item in other) + foreach (var item in other) { if (item is T tItem) Add(tItem); } - suppressChangedEvent = false; + _suppressChangedEvent = false; OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - OnPropertyChanged(new(nameof(Count))); + OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count))); } public void RemoveRange(IEnumerable other) { - suppressChangedEvent = true; + _suppressChangedEvent = true; - foreach (object item in other) + foreach (var item in other) { if (item is T tItem) Remove(tItem); } - suppressChangedEvent = false; + _suppressChangedEvent = false; OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - OnPropertyChanged(new(nameof(Count))); + OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count))); } public void SortAndReplace(IEnumerable other, IComparer comparer) @@ -94,23 +93,28 @@ namespace FruitBank.Common public void Synchronize(NotifyCollectionChangedEventArgs args) { - if (args.Action == NotifyCollectionChangedAction.Add && args.NewItems != null) + switch (args.Action) { - AddRange(args.NewItems); - } - else if (args.Action == NotifyCollectionChangedAction.Remove && args.OldItems != null) - { - RemoveRange(args.OldItems); - } - else if (args.Action == NotifyCollectionChangedAction.Reset) - { - Clear(); + case NotifyCollectionChangedAction.Add when args.NewItems != null: + AddRange(args.NewItems); + break; + case NotifyCollectionChangedAction.Remove when args.OldItems != null: + RemoveRange(args.OldItems); + break; + case NotifyCollectionChangedAction.Reset: + Clear(); + break; + case NotifyCollectionChangedAction.Replace: + case NotifyCollectionChangedAction.Move: + break; + default: + throw new ArgumentOutOfRangeException(); } } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { - if (suppressChangedEvent) + if (_suppressChangedEvent) return; base.OnPropertyChanged(e); @@ -118,10 +122,31 @@ namespace FruitBank.Common protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { - if (suppressChangedEvent) + if (_suppressChangedEvent) return; base.OnCollectionChanged(e); } - } + + //protected override void ClearItems() + //{ + // base.ClearItems(); + //} + + //protected override void InsertItem(int index, T item) + //{ + // base.InsertItem(index, item); + //} + + //protected override void MoveItem(int oldIndex, int newIndex) + //{ + // base.MoveItem(oldIndex, newIndex); + //} + + //public override event NotifyCollectionChangedEventHandler? CollectionChanged + //{ + // add => base.CollectionChanged += value; + // remove => base.CollectionChanged -= value; + //} + } } \ No newline at end of file diff --git a/FruitBank.Common/Models/LoggedInModel.cs b/FruitBank.Common/Models/LoggedInModel.cs index 00602e5..3ed0f8b 100644 --- a/FruitBank.Common/Models/LoggedInModel.cs +++ b/FruitBank.Common/Models/LoggedInModel.cs @@ -48,5 +48,6 @@ public class LoggedInModel { CustomerDto = null; CustomerRoles.Clear(); + //MeasuringUsers.Clear(); } } \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor index bd29465..c6d35e3 100644 --- a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor +++ b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor @@ -87,6 +87,7 @@ public GridProductDto Grid { get; set; } [Parameter] public bool IsMasterGrid { get; set; } = false; + [Parameter] public IEnumerable? ProductDtos { get; set; } //[Parameter] public List? OrderDtos { get; set; } //[Parameter] public List? OrderItemDtos { get; set; } @@ -129,7 +130,7 @@ private async Task> GetOrderDtosFromDbAsync(int productId) { - using(await _lockOrderDtosByProductId.UseWaitAsync()) + using (await _lockOrderDtosByProductId.UseWaitAsync()) { if (_orderDtosByProductId.TryGetValue(productId, out var orderDtos)) return orderDtos; diff --git a/FruitBankHybrid.Shared/Databases/DatabaseClient.cs b/FruitBankHybrid.Shared/Databases/DatabaseClient.cs index 39adbb8..01ce922 100644 --- a/FruitBankHybrid.Shared/Databases/DatabaseClient.cs +++ b/FruitBankHybrid.Shared/Databases/DatabaseClient.cs @@ -55,7 +55,7 @@ public class ShippingItemTable : SignalRDataSourceList } } -public class ProductDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : FastObservableCollection +public class ProductDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : MgObservableCollection { private readonly SemaphoreSlim _semaphoreSlim = new(1); public async Task LoadDataAsync(bool onlyIfEmpty = true) @@ -80,7 +80,7 @@ public class ProductDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : Fa return this; } } -public class OrderDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : FastObservableCollection +public class OrderDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : MgObservableCollection { private readonly SemaphoreSlim _semaphoreSlim = new(1); diff --git a/FruitBankHybrid.Shared/Pages/Login.razor b/FruitBankHybrid.Shared/Pages/Login.razor index fe8c60c..01d9cb1 100644 --- a/FruitBankHybrid.Shared/Pages/Login.razor +++ b/FruitBankHybrid.Shared/Pages/Login.razor @@ -1,4 +1,5 @@ @page "/Login" +@using FruitBank.Common.Models @using Mango.Nop.Core.Dtos

Bejelentkezés

diff --git a/FruitBankHybrid.Shared/Pages/Login.razor.cs b/FruitBankHybrid.Shared/Pages/Login.razor.cs index 87bbeac..d225de6 100644 --- a/FruitBankHybrid.Shared/Pages/Login.razor.cs +++ b/FruitBankHybrid.Shared/Pages/Login.razor.cs @@ -1,6 +1,7 @@ using AyCode.Core.Loggers; using AyCode.Utils.Extensions; using FruitBank.Common.Models; +using FruitBankHybrid.Shared.Databases; using FruitBankHybrid.Shared.Services.Loggers; using FruitBankHybrid.Shared.Services.SignalRs; using Mango.Nop.Core.Dtos; @@ -35,8 +36,14 @@ public partial class Login : ComponentBase if (!LoggedInModel.IsLoggedIn) { - LoggedInModel.MeasuringUsers = await FruitBankSignalRClient.GetMeasuringUsers() ?? []; - SelectedUser = LoggedInModel.MeasuringUsers.FirstOrDefault(); + using (await ObjectLock.GetSemaphore().UseWaitAsync()) + { + if (LoggedInModel.MeasuringUsers.Count == 0) + { + LoggedInModel.MeasuringUsers = await FruitBankSignalRClient.GetMeasuringUsers() ?? []; + SelectedUser = LoggedInModel.MeasuringUsers.FirstOrDefault(); + } + } } else _rolesText = string.Join("; ", LoggedInModel.CustomerRoles.Select(x => x.Name)); diff --git a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs index e672593..08e5adb 100644 --- a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs +++ b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs @@ -15,6 +15,7 @@ using FruitBankHybrid.Shared.Services.Loggers; using Mango.Nop.Core.Dtos; using Mango.Nop.Core.Models; using MessagePack.Resolvers; +using Microsoft.AspNetCore.SignalR.Client; using Nop.Core.Domain.Customers; using System.Collections.ObjectModel; using System.ServiceModel.Channels; @@ -25,6 +26,13 @@ namespace FruitBankHybrid.Shared.Services.SignalRs { public FruitBankSignalRClient( /*IServiceProvider serviceProvider, */ IEnumerable logWriters) : base($"{FruitBankConstClient.BaseUrl}/{FruitBankConstClient.DefaultHubName}", new LoggerClient(nameof(FruitBankSignalRClient), logWriters.ToArray())) { + //var hubConnection = new HubConnectionBuilder() + // .WithUrl("fullHubName") + // .WithAutomaticReconnect() + // .WithStatefulReconnect() + // .WithKeepAliveInterval(TimeSpan.FromSeconds(60)) + // .WithServerTimeout(TimeSpan.FromSeconds(120)) + ConstHelper.NameByValue(0); }