Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
IsPagination="true" PageItemsSource="@PageItemsSource"
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
ShowToolbar="true" ShowAddButton="false" ShowEditButton="false" ShowDeleteButton="false"
ShowExtendButtons="false" ShowColumnList="true"
ShowExtendButtons="false" ShowColumnList="true" ClientTableName="testtable"
OnQueryAsync="@OnQueryAsync">
<TableColumns>
<TableColumn @bind-Field="@context.DateTime" Width="180" />
Expand Down
4 changes: 4 additions & 0 deletions src/BootstrapBlazor/Components/Table/ColumnVisibleItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone

using System.Text.Json.Serialization;

namespace BootstrapBlazor.Components;

/// <summary>
/// Table 组件列可见性类
/// </summary>
/// <param name="name"></param>
/// <param name="visible"></param>
[JsonConverter(typeof(ColumnVisibleItemConverter))]
public class ColumnVisibleItem(string name, bool visible)
{
/// <summary>
Expand All @@ -20,6 +23,7 @@ public class ColumnVisibleItem(string name, bool visible)
/// <summary>
/// 获得 列名称
/// </summary>
[JsonIgnore]
public string? DisplayName { get; set; }

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ private async Task OnToggleColumnVisible(string columnName, bool visible)
{
_resetColumns = true;
}

if (!string.IsNullOrEmpty(ClientTableName))
{
await InvokeVoidAsync("saveColumnList", ClientTableName, _visibleColumns);
}
if (OnColumnVisibleChanged != null)
{
await OnColumnVisibleChanged(columnName, visible);
Expand Down
8 changes: 4 additions & 4 deletions src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ public async Task AddAsync()
{
// 数据源为 DataTable 新建后重建行与列
await DynamicContext.AddAsync(SelectedRows.OfType<IDynamicObject>());
ResetDynamicContext();
await ResetDynamicContext();

if (!IsKeepSelectedRowAfterAdd)
{
Expand Down Expand Up @@ -1030,7 +1030,7 @@ protected async Task DeleteAsync()
if (DynamicContext != null)
{
await DynamicContext.DeleteAsync(SelectedRows.OfType<IDynamicObject>());
ResetDynamicContext();
await ResetDynamicContext();
SelectedRows.Clear();
await OnSelectedRowsChanged();
}
Expand Down Expand Up @@ -1098,7 +1098,7 @@ async Task<bool> DeleteItemsAsync()
}
}

private void ResetDynamicContext()
private async Task ResetDynamicContext()
{
if (DynamicContext != null)
{
Expand All @@ -1112,7 +1112,7 @@ private void ResetDynamicContext()
FirstFixedColumnCache.Clear();
LastFixedColumnCache.Clear();

InternalResetVisibleColumns(Columns);
await InternalResetVisibleColumns(Columns);

var queryOption = BuildQueryPageOptions();
// 设置是否为首次查询
Expand Down
28 changes: 24 additions & 4 deletions src/BootstrapBlazor/Components/Table/Table.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@
if (!FirstRender)
{
// 动态列模式
ResetDynamicContext();

Check warning on line 984 in src/BootstrapBlazor/Components/Table/Table.razor.cs

View workflow job for this annotation

GitHub Actions / run test

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

// resize column width;
ResetColumnWidth(Columns);
Expand Down Expand Up @@ -1123,6 +1123,24 @@

private readonly JsonSerializerOptions _serializerOption = new(JsonSerializerDefaults.Web);

private async Task ReloadColumnVisibleFromBrowserAsync()
{
if (!string.IsNullOrEmpty(ClientTableName))
{
// 读取浏览器配置
var clientColumns = await InvokeAsync<List<ColumnVisibleItem>>("reloadColumnList", ClientTableName);
clientColumns ??= [];
foreach (var column in _visibleColumns)
{
var item = clientColumns.FirstOrDefault(i => i.Name == column.Name);
if (item != null)
{
column.Visible = item.Visible;
}
}
}
}

private async Task ReloadColumnWidthFromBrowserAsync(List<ITableColumn> columns)
{
List<ColumnWidth>? ret = null;
Expand Down Expand Up @@ -1207,7 +1225,9 @@
await OnColumnCreating(cols);
}

InternalResetVisibleColumns(cols);
await InternalResetVisibleColumns(cols);

await ReloadColumnVisibleFromBrowserAsync();

Columns.Clear();
Columns.AddRange(cols.OrderFunc());
Expand Down Expand Up @@ -1258,7 +1278,7 @@
}
}

private void InternalResetVisibleColumns(List<ITableColumn> columns, IEnumerable<ColumnVisibleItem>? items = null)
private async Task InternalResetVisibleColumns(List<ITableColumn> columns, IEnumerable<ColumnVisibleItem>? items = null)
{
var cols = columns.Select(i => new ColumnVisibleItem(i.GetFieldName(), i.GetVisible()) { DisplayName = i.GetDisplayName() }).ToList();
if (items != null)
Expand All @@ -1284,15 +1304,15 @@
/// 设置 列可见方法
/// </summary>
/// <param name="columns"></param>
public void ResetVisibleColumns(IEnumerable<ColumnVisibleItem> columns)
public async Task ResetVisibleColumns(IEnumerable<ColumnVisibleItem> columns)
{
// https://github.com/dotnetcore/BootstrapBlazor/issues/6823
if (AllowResizing)
{
_resetColumns = true;
}

InternalResetVisibleColumns(Columns, columns);
await InternalResetVisibleColumns(Columns, columns);
StateHasChanged();
}

Expand Down
18 changes: 18 additions & 0 deletions src/BootstrapBlazor/Components/Table/Table.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ export function init(id, invoke, options) {
reset(id)
}

export function saveColumnList(tableName, columns) {
const key = `bb-table-column-visiable-${tableName}`
return localStorage.setItem(key, JSON.stringify(columns));
}

export function reloadColumnList(tableName) {
const key = `bb-table-column-visiable-${tableName}`
const json = localStorage.getItem(key);
let columns = [];
if (json) {
try {
columns = JSON.parse(json);
}
catch { }
}
return columns;
}

export function reloadColumnWidth(tableName) {
const key = `bb-table-column-width-${tableName}`
return localStorage.getItem(key);
Expand Down
64 changes: 64 additions & 0 deletions src/BootstrapBlazor/Converter/ColumnVisibleItemConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone

using System.Text.Json;
using System.Text.Json.Serialization;

namespace BootstrapBlazor.Components;

public class ColumnVisibleItemConverter : JsonConverter<ColumnVisibleItem>

Check warning on line 11 in src/BootstrapBlazor/Converter/ColumnVisibleItemConverter.cs

View workflow job for this annotation

GitHub Actions / run test

Missing XML comment for publicly visible type or member 'ColumnVisibleItemConverter'
{
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="reader"></param>
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
public override ColumnVisibleItem? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string? name = null;
bool visible = false;
if (reader.TokenType == JsonTokenType.StartObject)
{
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
break;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
if (propertyName == "name")
{
reader.Read();
name = reader.GetString();
}
else if (propertyName == "visible")
{
reader.Read();
visible = reader.GetBoolean();
}
}
}
}
return new ColumnVisibleItem(name, visible);

Check warning on line 48 in src/BootstrapBlazor/Converter/ColumnVisibleItemConverter.cs

View workflow job for this annotation

GitHub Actions / run test

Possible null reference argument for parameter 'name' in 'ColumnVisibleItem.ColumnVisibleItem(string name, bool visible)'.
}

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="options"></param>
public override void Write(Utf8JsonWriter writer, ColumnVisibleItem value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("name", value.Name);
writer.WriteBoolean("visible", value.Visible);
writer.WriteEndObject();
}
}
2 changes: 0 additions & 2 deletions src/BootstrapBlazor/Converter/JsonQueryPageOptionConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class JsonQueryPageOptionsConverter : JsonConverter<QueryPageOptions>
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public override QueryPageOptions? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var ret = new QueryPageOptions();
Expand Down Expand Up @@ -203,7 +202,6 @@ public class JsonQueryPageOptionsConverter : JsonConverter<QueryPageOptions>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="options"></param>
/// <exception cref="NotImplementedException"></exception>
public override void Write(Utf8JsonWriter writer, QueryPageOptions value, JsonSerializerOptions options)
{
writer.WriteStartObject();
Expand Down
7 changes: 7 additions & 0 deletions test/UnitTest/Components/TableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,12 @@ public void ResetFilter_Null()
[Fact]
public async Task ShowColumnList_Ok()
{
// 设置客户端存储
Context.JSInterop.Setup<List<ColumnVisibleItem>>("reloadColumnList", "test").SetResult(
[
new("Name", false),
new("Address", true)
]);
var show = false;
var localizer = Context.Services.GetRequiredService<IStringLocalizer<Foo>>();
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
Expand Down Expand Up @@ -764,6 +770,7 @@ public async Task ShowColumnList_Ok()
builder.AddAttribute(2, "FieldExpression", Utility.GenerateValueExpression(foo, "Address", typeof(string)));
builder.CloseComponent();
});
pb.Add(a => a.ClientTableName, "test");
});
});
cut.Contains("Test_Column_List");
Expand Down
14 changes: 13 additions & 1 deletion test/UnitTest/Converters/JsonDescriptionEnumConverterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@
Assert.Equal("\"\"", json);
}

[Fact]
public void ColumnVisibleItemConverter_Ok()
{
var item = new ColumnVisibleItem("name", true) { DisplayName = "display" };
var json = JsonSerializer.Serialize(item);

Assert.Equal("{\"name\":\"name\",\"visible\":true}", json);

var item1 = JsonSerializer.Deserialize<ColumnVisibleItem>(json);
Assert.Equal("name", item1.Name);

Check warning on line 64 in test/UnitTest/Converters/JsonDescriptionEnumConverterTest.cs

View workflow job for this annotation

GitHub Actions / run test

Dereference of a possibly null reference.
Assert.True(item1.Visible);
}

[JsonConverter(typeof(JsonDescriptionEnumConverter<TestEnum>))]
public enum TestEnum
{
Expand Down Expand Up @@ -100,5 +113,4 @@
[Description("bold italic")]
Bold_Italic,
}

}
2 changes: 1 addition & 1 deletion test/UnitTest/Utils/UtilityTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ public void GetJsonStringByTypeName_UseKeyWhenValueIsNull()
// improve code coverage
var option = Context.Services.GetRequiredService<IOptions<JsonLocalizationOptions>>().Value;
option.UseKeyWhenValueIsNull = true;
var items = Utility.GetJsonStringByTypeName(option, this.GetType().Assembly, "UnitTest.Utils.UtilityTest", "en-US", true);
var items = Utility.GetJsonStringByTypeName(option, GetType().Assembly, "UnitTest.Utils.UtilityTest", "en-US", true);

var test1 = items.FirstOrDefault(i => i.Name == "Test-Null");
Assert.NotNull(test1);
Expand Down
Loading