From 3b6bd9c681362efa0b83a8bcf20fc2e4f5057f7c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 22 May 2026 13:09:43 +0800 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20=E6=81=A2=E5=A4=8D=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E7=B1=BB=E5=9E=8B=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Table/Table.razor.Edit.cs | 3 +- .../Components/Table/Table.razor.Toolbar.cs | 31 ++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs index 9216fbd4583..33a281ba220 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs @@ -558,7 +558,8 @@ protected async Task QueryData(bool triggerByPagination = false, bool firstQuery var queryOption = BuildQueryPageOptions(firstQuery); queryOption.IsTriggerByPagination = triggerByPagination; - if (DynamicContext != null) + + if (OnQueryAsync == null && typeof(TItem).IsAssignableTo(typeof(IDynamicObject))) { QueryDynamicItems(queryOption, DynamicContext, isAutoQuery); } diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs index 0a2aa60bc01..91ff894c37c 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs @@ -1237,26 +1237,29 @@ private void ResetDynamicContext() } } - private void QueryDynamicItems(QueryPageOptions queryOption, IDynamicObjectContext context, bool isAutoQuery = true) + private void QueryDynamicItems(QueryPageOptions queryOption, IDynamicObjectContext? context, bool isAutoQuery = true) { if (isAutoQuery) { _rowsCache = null; - var items = context.GetItems(); - if (context.OnFilterCallback != null) + if (context != null) { - items = context.OnFilterCallback(queryOption, items); - } - if (IsPagination) - { - TotalCount = items.Count(); - PageCount = (int)Math.Ceiling(TotalCount * 1.0 / Math.Max(1, _pageItems)); - PageIndex = GetSafePageIndex(); - items = items.Skip((PageIndex - 1) * _pageItems).Take(_pageItems); - } - QueryItems = items.Cast().ToList(); + var items = context.GetItems(); + if (context.OnFilterCallback != null) + { + items = context.OnFilterCallback(queryOption, items); + } + if (IsPagination) + { + TotalCount = items.Count(); + PageCount = (int)Math.Ceiling(TotalCount * 1.0 / Math.Max(1, _pageItems)); + PageIndex = GetSafePageIndex(); + items = items.Skip((PageIndex - 1) * _pageItems).Take(_pageItems); + } + QueryItems = items.Cast().ToList(); - ResetSelectedRows(QueryItems); + ResetSelectedRows(QueryItems); + } } } From f3d32331f541beb532c53f869f190361ee777167 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 22 May 2026 13:31:01 +0800 Subject: [PATCH 2/4] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Pages/Online.razor | 86 +++++++++- .../Components/Pages/Online.razor.cs | 147 +++--------------- 2 files changed, 103 insertions(+), 130 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Pages/Online.razor b/src/BootstrapBlazor.Server/Components/Pages/Online.razor index 52bf67c4d7b..67736fe90d1 100644 --- a/src/BootstrapBlazor.Server/Components/Pages/Online.razor +++ b/src/BootstrapBlazor.Server/Components/Pages/Online.razor @@ -1,9 +1,91 @@ -@page "/online" +@page "/online" @layout MainLayout @inject IStringLocalizer Localizer

@Localizer["SubTitle"]:@ConnectionService.Connections.Count

-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs b/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs index 0d073bfb809..ad5e995d495 100644 --- a/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs @@ -3,8 +3,6 @@ // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone -using System.Data; - namespace BootstrapBlazor.Server.Components.Pages; /// @@ -16,18 +14,10 @@ public partial class Online : IDisposable [NotNull] private IConnectionService? ConnectionService { get; set; } - [Inject] - [NotNull] - private WebClientService? WebClientService { get; set; } - - private DynamicObjectContext? DataTableDynamicContext { get; set; } - - private readonly DataTable _table = new(); - + private readonly List _items = []; + private static readonly Comparison ConnectionComparer = static (x, y) => x.ConnectionTime.CompareTo(y.ConnectionTime); private CancellationTokenSource? _cancellationTokenSource; - private string? _clientId; - /// /// /// @@ -35,8 +25,6 @@ protected override void OnInitialized() { base.OnInitialized(); - CreateTable(); - BuildContext(); } @@ -44,135 +32,38 @@ protected override void OnInitialized() /// /// /// - protected override void OnAfterRender(bool firstRender) + protected override async Task OnAfterRenderAsync(bool firstRender) { - base.OnAfterRender(firstRender); + await base.OnAfterRenderAsync(firstRender); if (firstRender) { - Task.Run(async () => + _cancellationTokenSource ??= new CancellationTokenSource(); + using var _timer = new PeriodicTimer(TimeSpan.FromSeconds(10)); + + try { - var client = await WebClientService.GetClientInfo(); - _clientId = client.Id; - _cancellationTokenSource ??= new CancellationTokenSource(); - while (_cancellationTokenSource is { IsCancellationRequested: false }) + while (await _timer.WaitForNextTickAsync(_cancellationTokenSource.Token)) { - try - { - BuildContext(); - await InvokeAsync(StateHasChanged); - await Task.Delay(10000, _cancellationTokenSource.Token); - } - catch - { - // ignored - } + BuildContext(); + await InvokeAsync(StateHasChanged); } - }); + } + catch (OperationCanceledException) { } } } - private void CreateTable() - { - _table.Columns.Add("Id", typeof(string)); - _table.Columns.Add("ConnectionTime", typeof(DateTimeOffset)); - _table.Columns.Add("LastBeatTime", typeof(DateTimeOffset)); - _table.Columns.Add("Dur", typeof(TimeSpan)); - _table.Columns.Add("Ip", typeof(string)); - _table.Columns.Add("City", typeof(string)); - _table.Columns.Add("OS", typeof(string)); - _table.Columns.Add("Device", typeof(string)); - _table.Columns.Add("Browser", typeof(string)); - _table.Columns.Add("Language", typeof(string)); - _table.Columns.Add("Engine", typeof(string)); - _table.Columns.Add("RequestUrl", typeof(string)); - } - private void BuildContext() { - _table.Rows.Clear(); - var rows = ConnectionService.Connections.Sort(["ConnectionTime"]); - foreach (var item in rows) - { - _table.Rows.Add( - item.Id, - item.ConnectionTime, - item.LastBeatTime, - item.LastBeatTime - item.ConnectionTime, - item.ClientInfo?.Ip ?? "", - item.ClientInfo?.City ?? "", - item.ClientInfo?.OS ?? "", - item.ClientInfo?.Device.ToString() ?? "", - item.ClientInfo?.Browser ?? "", - item.ClientInfo?.Language ?? "", - item.ClientInfo?.Engine ?? "", - item.ClientInfo?.RequestUrl ?? "" - ); - } - _table.AcceptChanges(); - - //table - DataTableDynamicContext = new DataTableDynamicContext(_table, (context, col) => - { - col.Text = Localizer[col.GetFieldName()]; - if (col.GetFieldName() == "Id") - { - col.Ignore = true; - } - else if (col.GetFieldName() == "ConnectionTime") - { - col.FormatString = "yyyy/MM/dd HH:mm:ss"; - col.Width = 118; - } - else if (col.GetFieldName() == "LastBeatTime") - { - col.FormatString = "yyyy/MM/dd HH:mm:ss"; - col.Width = 118; - } - else if (col.GetFieldName() == "Dur") - { - col.FormatString = @"dd\.hh\:mm\:ss"; - col.Width = 54; - } - else if (col.GetFieldName() == "Ip") - { - col.Template = v => builder => builder.AddContent(0, FormatIp(v)); - } - else if (col.GetFieldName() == "RequestUrl") - { - col.Template = v => builder => - { - if (v is IDynamicObject val) - { - var url = val.GetValue("RequestUrl")?.ToString(); - if (!string.IsNullOrEmpty(url)) - { - builder.AddContent(0, new MarkupString($"{url}")); - } - } - }; - } - }); - } - - private static string FormatIp(object v) - { - var ret = ""; - if (v is IDynamicObject val) - { - var ip = val.GetValue("Ip")?.ToString(); - if (!string.IsNullOrEmpty(ip)) - { - ret = ip.MaskIpString(); - } - } - return ret; + _items.Clear(); + _items.AddRange(ConnectionService.Connections); + _items.Sort(ConnectionComparer); } - private string? SetRowClassFormatter(DynamicObject context) + private static string GetDurString(ConnectionItem item) { - var id = context.GetValue("id")?.ToString(); - return _clientId == id ? "active" : null; + var dur = item.LastBeatTime - item.ConnectionTime; + return dur.ToString("dd\\.hh\\:mm\\:ss"); } private void Dispose(bool disposing) From ebf93ff95b5d3bac396ea046c152a44130c510b1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 22 May 2026 13:40:33 +0800 Subject: [PATCH 3/4] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Pages/Online.razor.cs | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs b/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs index ad5e995d495..13306be9e40 100644 --- a/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Pages/Online.razor.cs @@ -17,6 +17,7 @@ public partial class Online : IDisposable private readonly List _items = []; private static readonly Comparison ConnectionComparer = static (x, y) => x.ConnectionTime.CompareTo(y.ConnectionTime); private CancellationTokenSource? _cancellationTokenSource; + private Task? _refreshTask; /// /// @@ -36,21 +37,26 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); - if (firstRender) + if (firstRender && _refreshTask == null) { _cancellationTokenSource ??= new CancellationTokenSource(); - using var _timer = new PeriodicTimer(TimeSpan.FromSeconds(10)); + _refreshTask = RefreshAsync(_cancellationTokenSource.Token); + } + } - try + private async Task RefreshAsync(CancellationToken cancellationToken) + { + using var timer = new PeriodicTimer(TimeSpan.FromSeconds(10)); + + try + { + while (await timer.WaitForNextTickAsync(cancellationToken)) { - while (await _timer.WaitForNextTickAsync(_cancellationTokenSource.Token)) - { - BuildContext(); - await InvokeAsync(StateHasChanged); - } + BuildContext(); + await InvokeAsync(StateHasChanged); } - catch (OperationCanceledException) { } } + catch (OperationCanceledException) { } } private void BuildContext() @@ -76,6 +82,7 @@ private void Dispose(bool disposing) _cancellationTokenSource.Dispose(); _cancellationTokenSource = null; } + _refreshTask = null; } } From 28c69f372a3fd6f02743dcff30d644981c750c1f Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 22 May 2026 13:41:22 +0800 Subject: [PATCH 4/4] chore: bump version 10.6.3 --- src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index a4d0d8e72d0..e24c2502f0b 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@  - 10.6.2 + 10.6.3