Compare commits

...

4 Commits

Author SHA1 Message Date
Loretta 920bc299aa Add grid sync state tracking and robust login redirection
Introduce IsSyncing and OnSyncingStateChanged to IMgGridBase and MgGridBase for real-time sync state tracking and event notification. Update FruitBankToolbarTemplate to enable/disable the reload button based on grid sync and reload state, subscribing to sync events and cleaning up on disposal. Implement IAsyncDisposable in MgGridBase to prevent memory leaks. Update login navigation to use forceLoad for reliability. These changes improve UI responsiveness and resource management.
2025-12-09 11:27:21 +01:00
Loretta 06f397e285 Refactor, enhance, and improve test coverage
Refactored `OnDataSourceLoaded` to be asynchronous for better state handling. Downgraded `Newtonsoft.Json` to version `13.0.3` across multiple projects for compatibility. Enhanced `MeasuringItemPalletBase` with `SetParentPropToNull` and `SetForeignKey` methods. Refactored `OrderItemPallet`, `ShippingItemPallet`, and `StockTakingItemPallet` to simplify table attributes and improve parent-child relationship handling.

Added `IsReadyForClose` to `StockTaking` for better closure validation. Updated SignalR tag constants to reflect new functionality. Improved Razor components (`PalletItemComponent`, `StockTakingTemplate`, `MeasuringIn`, `MeasuringOut`) to streamline logic and maintain proper references.

Introduced `JsonExtensionTests` for comprehensive validation of JSON serialization/deserialization, including deep hierarchies, circular references, and hybrid references. Added `test_debug.ps1` for streamlined test debugging. Performed general code cleanup and improved test coverage.
2025-12-08 15:50:57 +01:00
Loretta 0e2d31aa4b .Net10, VS2026; StockTaking in progress... 2025-12-01 16:18:47 +01:00
Loretta 687b745b4d Upgrade to .net10 and Visual Studio 2026; StockTaking in progress... 2025-11-28 08:15:58 +01:00
8 changed files with 99 additions and 81 deletions

View File

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>
<Import Project="..//AyCode.Blazor.targets" />
@ -13,12 +15,14 @@
<PackageReference Include="DevExpress.Blazor" Version="25.1.3" />
<PackageReference Include="DevExpress.Data" Version="25.1.3" />
<PackageReference Include="MessagePack" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.8" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="10.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,53 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DevExpress.Blazor" Version="23.2.3" />
<PackageReference Include="DevExpress.Blazor.Dashboard" Version="23.2.3" />
<PackageReference Include="MessagePack" Version="2.5.168" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.6" />
</ItemGroup>
<ItemGroup>
<Reference Include="AyCode.Core">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\TIAM\Debug\net9.0\AyCode.Core.dll</HintPath>
</Reference>
<Reference Include="AyCode.Entities">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\TIAM\Debug\net9.0\AyCode.Entities.dll</HintPath>
</Reference>
<Reference Include="AyCode.Interfaces">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\TIAM\Debug\net9.0\AyCode.Interfaces.dll</HintPath>
</Reference>
<Reference Include="AyCode.Models">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\TIAM\Debug\net9.0\AyCode.Models.dll</HintPath>
</Reference>
<Reference Include="AyCode.Services">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\TIAM\Debug\net9.0\AyCode.Services.dll</HintPath>
</Reference>
<Reference Include="AyCode.Utils">
<HintPath>..\..\AyCode.Core\AyCode.Services.Server\bin\TIAM\Debug\net9.0\AyCode.Utils.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Layouts\" />
<Folder Include="Pages\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AyCode.Blazor.Models\AyCode.Blazor.Models.csproj" />
</ItemGroup>
</Project>

View File

@ -15,10 +15,18 @@ namespace AyCode.Blazor.Components.Components.Grids;
public interface IMgGridBase : IGrid
{
/// <summary>
/// Indicates whether any synchronization operation is in progress
/// </summary>
bool IsSyncing { get; }
/// <summary>
/// Event fired when synchronization state changes (true = syncing started, false = syncing ended)
/// </summary>
event Action<bool>? OnSyncingStateChanged;
}
public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClient> : DxGrid, IMgGridBase
public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClient> : DxGrid, IMgGridBase, IAsyncDisposable
where TSignalRDataSource : AcSignalRDataSource<TDataItem, TId, AcObservableCollection<TDataItem>>
where TDataItem : class, IId<TId>
where TId : struct
@ -29,11 +37,18 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
protected bool IsFirstInitializeParameters;
protected bool IsFirstInitializeParameterCore;
private bool _isDisposed;
private TSignalRDataSource? _dataSource = null!;
private AcObservableCollection<TDataItem>? _dataSourceParam = [];
private string _gridLogName;
/// <inheritdoc />
public bool IsSyncing => _dataSource?.IsSyncing ?? false;
/// <inheritdoc />
public event Action<bool>? OnSyncingStateChanged;
public MgGridBase() : base()
{
}
@ -133,6 +148,7 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
public void SetGridData(object? data)
{
if (_isDisposed) return;
if (ReferenceEquals(Data, data)) return;
BeginUpdate();
@ -161,12 +177,25 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
_dataSource.OnDataSourceLoaded += OnDataSourceLoaded;
_dataSource.OnDataSourceItemChanged += OnDataSourceItemChanged;
_dataSource.OnSyncingStateChanged += OnDataSourceSyncingStateChanged;
await base.OnInitializedAsync();
}
private void OnDataSourceSyncingStateChanged(bool isSyncing)
{
if (_isDisposed) return;
// Forward the event to external subscribers
OnSyncingStateChanged?.Invoke(isSyncing);
// Trigger UI update
InvokeAsync(StateHasChanged);
}
private async Task OnDataSourceItemChanged(ItemChangedEventArgs<TDataItem> args)
{
if (_isDisposed) return;
if (args.TrackingState is TrackingState.GetAll or TrackingState.None) return;
Logger.Debug($"{_gridLogName} OnDataSourceItemChanged; trackingState: {args.TrackingState}");
@ -174,7 +203,7 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
var changedEventArgs = new GridDataItemChangedEventArgs<TDataItem>(this, args.Item, args.TrackingState);
await OnGridItemChanged.InvokeAsync(changedEventArgs);
if (!changedEventArgs.CancelStateChangeInvoke)
if (!changedEventArgs.CancelStateChangeInvoke && !_isDisposed)
{
//BeginUpdate();
await InvokeAsync(StateHasChanged); //TODO: bezárja a DetailRow-t! pl: az email-nél IsReaded=true update... - J.
@ -182,8 +211,10 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
}
}
private Task OnDataSourceLoaded()
private async Task OnDataSourceLoaded()
{
if (_isDisposed) return;
Logger.Debug($"{_gridLogName} OnDataSourceLoaded; Count: {_dataSource?.Count}");
//if(_dataSourceParam.GetType() == typeof()AcObservableCollection<TDataItem>)
@ -192,7 +223,11 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
//else Reload();
//_dataSource.LoadItem(_dataSource.First().Id).Forget();
return OnDataSourceChanged.InvokeAsync(_dataSource);
if (!_isDisposed)
{
await OnDataSourceChanged.InvokeAsync(_dataSource);
await InvokeAsync(StateHasChanged);
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
@ -410,6 +445,7 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
base.DataItemDeleting = EventCallback.Factory.Create<GridDataItemDeletingEventArgs>(this, OnItemDeleting);
base.EditModelSaving = EventCallback.Factory.Create<GridEditModelSavingEventArgs>(this, OnItemSaving);
base.CustomizeEditModel = EventCallback.Factory.Create<GridCustomizeEditModelEventArgs>(this, OnCustomizeEditModel);
//base.customizecel= EventCallback.Factory.Create<GridCustomizeEditModelEventArgs>(this, OnCustomizeEditModel);
base.EditStart = EventCallback.Factory.Create<GridEditStartEventArgs>(this, OnEditStart);
CustomizeElement += OnCustomizeElement;
@ -480,6 +516,30 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
{
return _dataSource.LoadDataSourceAsync(false);
}
public async ValueTask DisposeAsync()
{
if (_isDisposed) return;
_isDisposed = true;
// Unsubscribe from events to prevent callbacks to disposed component
if (_dataSource != null)
{
_dataSource.OnDataSourceLoaded -= OnDataSourceLoaded;
_dataSource.OnDataSourceItemChanged -= OnDataSourceItemChanged;
_dataSource.OnSyncingStateChanged -= OnDataSourceSyncingStateChanged;
}
CustomizeElement -= OnCustomizeElement;
// Dispose base if it implements IAsyncDisposable
if (this is IAsyncDisposable asyncDisposable && asyncDisposable != this)
{
await asyncDisposable.DisposeAsync();
}
GC.SuppressFinalize(this);
}
}
public class GridDataItemChangingEventArgs<TDataItem> : GridDataItemChangedEventArgs<TDataItem> where TDataItem : class

View File

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>
<Import Project="..//AyCode.Blazor.targets" />
@ -55,8 +57,8 @@
<ItemGroup>
<PackageReference Include="MessagePack" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="9.0.11" />
</ItemGroup>
</Project>

View File

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>
<Import Project="..//AyCode.Blazor.targets" />

View File

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>
<Import Project="..//AyCode.Blazor.targets" />

View File

@ -3,25 +3,28 @@
<Import Project="..//AyCode.Maui.targets" />
<PropertyGroup>
<TargetFrameworks>net9.0;net9.0-maccatalyst;net9.0-ios;net9.0-android35.0</TargetFrameworks>
<TargetFrameworks>net10.0-android;net10.0-ios</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.26100.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">31.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmStripILAfterAOT>true</WasmStripILAfterAOT>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">33.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.19041.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.19041.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="9.0.11" />
</ItemGroup>
<ItemGroup>
@ -46,11 +49,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.120" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.Maui.Controls" Version="9.0.120" />
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="10.0.11" />
</ItemGroup>
</Project>

View File

@ -3,7 +3,8 @@
<Name>AyCode.Project.targets</Name>
<_ProjectName>FruitBank</_ProjectName>
<_TargetFramework>net9.0</_TargetFramework>
<_TargetFramework>net10.0</_TargetFramework>
<_TargetFrameworkAyCodeCore>net9.0</_TargetFrameworkAyCodeCore>
<!--<GitBranch>$([System.IO.File]::ReadAlltext('$(MsBuildThisFileDirectory)\.git\HEAD').Replace('ref: refs/heads/', '').Trim())</GitBranch>
<_ProjectName>$(GitBranch)</_ProjectName>-->
@ -13,7 +14,7 @@
<Configurations>Debug;Release;Product</Configurations>
<BaseOutputPath>bin\$(_ProjectName)</BaseOutputPath>
<_AyCodeCoresReferenceBuildSubPath>$(_ProjectName)\$(Configuration)\$(_TargetFramework)</_AyCodeCoresReferenceBuildSubPath>
<_AyCodeCoresReferenceBuildSubPath>$(_ProjectName)\$(Configuration)\$(_TargetFrameworkAyCodeCore)</_AyCodeCoresReferenceBuildSubPath>
</PropertyGroup>
<Target Name="Test" AfterTargets="AfterBuild">