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.
This commit is contained in:
Loretta 2025-12-09 11:27:21 +01:00
parent 346d433196
commit 4ef318973f
3 changed files with 82 additions and 26 deletions

View File

@ -1,4 +1,5 @@
@using AyCode.Core.Loggers;
@using AyCode.Blazor.Components.Components.Grids
@using AyCode.Core.Loggers;
@using AyCode.Core.Extensions
@using AyCode.Core.Helpers
@using AyCode.Utils.Extensions
@ -10,6 +11,8 @@
@using FruitBankHybrid.Shared.Services.Loggers;
@using FruitBankHybrid.Shared.Services.SignalRs
@implements IDisposable
@inject IEnumerable<IAcLogWriterClientBase> LogWriters
@inject FruitBankSignalRClient FruitBankSignalRClient
@inject LoggedInModel LoggedInModel;
@ -30,23 +33,6 @@
<DxToolbarItem Text="Reload data" BeginGroup="true" Click="ReloadData_Click" Enabled="@BtnReloadDataEnabled" />
<DxToolbarItem BeginGroup="true">
</DxToolbarItem>
@* <DxToolbarItem BeginGroup="true">
<Template Context="toolbar_item_context">
<DxSearchBox @bind-Text="GridSearchText"
BindValueMode="BindValueMode.OnInput"
ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto"
aria-label="Search" />
</Template>
</DxToolbarItem>*@
@* @if (DxToolbarItems != null)
{
foreach (var toolBarItem in DxToolbarItems)
{
@toolBarItem
}
//@DxToolbarItem
} *@
@ToolbarItemsExtended
@ -60,20 +46,67 @@
public ToolbarBase Toolbar { get; set; }
const string ExportFileName = "ExportResult";
public bool BtnReloadDataEnabled = true;
private bool _isReloadInProgress;
private bool _isGridSyncing;
private IMgGridBase? _mgGrid;
/// <summary>
/// Reload button is enabled only when no sync operation is in progress
/// </summary>
public bool BtnReloadDataEnabled => !_isReloadInProgress && !_isGridSyncing;
public bool EditItemsEnabled { get; set; } = true;
private LoggerClient<GridShippingItemTemplate> _logger;
protected override async Task OnInitializedAsync()
protected override void OnInitialized()
{
_logger = new LoggerClient<GridShippingItemTemplate>(LogWriters.ToArray());
}
protected override void OnParametersSet()
{
// Subscribe to grid syncing state changes if Grid implements IMgGridBase
if (Grid is IMgGridBase mgGrid && !ReferenceEquals(_mgGrid, mgGrid))
{
// Unsubscribe from previous grid
if (_mgGrid != null)
{
_mgGrid.OnSyncingStateChanged -= OnGridSyncingStateChanged;
}
_mgGrid = mgGrid;
_mgGrid.OnSyncingStateChanged += OnGridSyncingStateChanged;
// Get initial syncing state
_isGridSyncing = _mgGrid.IsSyncing;
}
}
private void OnGridSyncingStateChanged(bool isSyncing)
{
_isGridSyncing = isSyncing;
InvokeAsync(StateHasChanged);
}
public void Dispose()
{
if (_mgGrid != null)
{
_mgGrid.OnSyncingStateChanged -= OnGridSyncingStateChanged;
}
}
async Task ReloadData_Click(ToolbarItemClickEventArgs e)
{
BtnReloadDataEnabled = false;
await OnReloadDataClick.InvokeAsync();
BtnReloadDataEnabled = true;
_isReloadInProgress = true;
try
{
await OnReloadDataClick.InvokeAsync();
}
finally
{
_isReloadInProgress = false;
}
}
async Task NewItem_Click()

View File

@ -40,15 +40,27 @@ public partial class MainLayout : LayoutComponentBase
{
_logger = new LoggerClient<MainLayout>(LogWriters.ToArray());
_logger.Info("OnInitializedAsync");
var loginUri = NavManager.ToAbsoluteUri("/Login").ToString();
FruitBankSignalRClient.OnMessageReceived += SignalRClientOnMessageReceived;
var loginUri = NavManager.ToAbsoluteUri("/Login").ToString();
if (!LoggedInModel.IsLoggedIn && NavManager.Uri != loginUri)
{
NavManager.NavigateTo("/Login");
NavManager.NavigateTo("/Login", forceLoad: true);
}
}
//protected override void OnAfterRender(bool firstRender)
//{
// if (!firstRender) return;
// var loginUri = NavManager.ToAbsoluteUri("/Login").ToString();
// if (!LoggedInModel.IsLoggedIn && NavManager.Uri != loginUri)
// {
// NavManager.NavigateTo("/Login", forceLoad: true);
// }
//}
private async Task SignalRClientOnMessageReceived(int messageTag, string? jsonMessage)
{
if (messageTag != SignalRTags.NotificationReceived || !LoggedInModel.IsLoggedIn) return;

View File

@ -13,6 +13,17 @@ public partial class Home : ComponentBase
protected override void OnInitialized()
{
if (!LoggedInModel.IsLoggedIn) NavManager.NavigateTo("/Login");
if (!LoggedInModel.IsLoggedIn)
{
NavManager.NavigateTo("/Login", forceLoad: true);
}
}
//protected override void OnAfterRender(bool firstRender)
//{
// if (firstRender && !LoggedInModel.IsLoggedIn)
// {
// NavManager.NavigateTo("/Login", forceLoad: true);
// }
//}
}