Skip to content

Commit 124f84b

Browse files
authored
feat(TableFilter): redesign filter system (#6020)
* doc: 更新注释 * refactor: 重新设计 FilterTemplate 模板 * refactor: 移除预编译宏 * refactor: 重新设计过滤器 * refactor: 增加枚举类型过滤器 * refactor: 增加布尔类型过滤器 * refactor: 重构 Filter 结构 * refactor: 更新 TableColumnDateTimeFilter 组件 * feat: 增加 TableColumnStringFilter 组件 * feat: 增加 NumberFilter 组件 * refactor: 更新 NumberFilter 组件 * refactor: 增加 Lookup 过滤器 * chore: 移除老的过滤器 * refactor: 增加 TableColumnMultiFilter 过滤去 * refactor: 恢复组件名称 * doc: 根据最新组件设计重构自定义过滤组件 * refactor: 增加忽略检查设置 * refactor: 增加 HasFilter 扩展方法 * doc: 更新示例 * refactor: 精简代码 * refactor: 重构过滤器 * refactor: 更新扩展方法 * refactor: 精简代码 * test: 更新单元测试 * refactor: 重构代码 * refactor: 调整过滤器结构 * refactor: 重构代码 * refactor: 代码重构 * doc: 更新示例 * refactor: 增加 Count 参数 * refactor: 增加 IsHeaderRow 参数设置 * refactor: 重构 IsHeaderRow 逻辑 * refactor: 重构组件名称 * feat: 设计 Title 参数 * refactor: 重构方法名称 * revert: 撤销更改 * revert: 回复文档示例 * Revert "revert: 回复文档示例" This reverts commit 38140b5. * Revert "revert: 撤销更改" This reverts commit bd7699d. * doc: 更新示例 * refactor: 移除 FieldKey 接口参数 * refactor: 更新过滤器类名 * refactor: 重构代码 * test: 增加单元测试 * test: 更新 EnumFilter 单元测试 * test: 增加 BoolFilter 单元测试 * test: 增加 EnumFilter 单元测试 * test: 增加 DateTimeFilter 单元测试 * test: 增加 NumberFilter 单元测试 * test: 增加 LookupFilter 单元测试 * test: 增加 MultiFilter 单元测试 * refactor: 精简代码 * refactor: 代码格式化 * refactor: 更改判断逻辑 * doc: 增加注释 * refactor: 增加 SearchFilterAction 单元测试 * refactor: 精简代码 * refactor: 使用 razor 文件 * refactor: 重构代码 * test: 补充单元测试 * refactor: 重构代码 * test: 增加单元测试 * refactor: 精简代码 * test: 更新单元测试 * test: 更新单元测试
1 parent 051fdba commit 124f84b

File tree

60 files changed

+1724
-1908
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1724
-1908
lines changed
Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,10 @@
11
@inherits FilterBase
22

3-
<Select Items="@Items" @bind-Value="@Value" OnSelectedItemChanged="_ => OnFilterValueChanged()"></Select>
3+
@if (IsHeaderRow)
4+
{
45

5-
@code {
6-
private int Value = 10;
7-
8-
/// <summary>
9-
/// OnInitialized 方法
10-
/// </summary>
11-
protected override void OnInitialized()
12-
{
13-
base.OnInitialized();
14-
15-
if (TableFilter != null) TableFilter.ShowMoreButton = false;
16-
17-
Items = new SelectedItem[]
18-
{
19-
new SelectedItem { Value = "10", Text = "大于 10" },
20-
new SelectedItem { Value = "50", Text = "大于 50" },
21-
new SelectedItem { Value = "100", Text = "大于 100" }
22-
};
23-
}
24-
25-
/// <summary>
26-
/// 重置过滤条件方法
27-
/// </summary>
28-
public override void Reset()
29-
{
30-
Value = 10;
31-
32-
StateHasChanged();
33-
}
34-
35-
/// <summary>
36-
/// 生成过滤条件方法
37-
/// </summary>
38-
/// <returns></returns>
39-
public override FilterKeyValueAction GetFilterConditions()
40-
{
41-
var filter = new FilterKeyValueAction() { Filters = new() };
42-
filter.Filters.Add(new FilterKeyValueAction()
43-
{
44-
FieldKey = FieldKey,
45-
FieldValue = Value,
46-
FilterAction = FilterAction.GreaterThan
47-
});
48-
return filter;
49-
}
6+
}
7+
else
8+
{
9+
<Select Items="@_items" @bind-Value="@Value"></Select>
5010
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
5+
6+
namespace BootstrapBlazor.Server.Components.Components;
7+
8+
/// <summary>
9+
///
10+
/// </summary>
11+
public partial class CustomerFilter
12+
{
13+
private int? Value;
14+
15+
private readonly IEnumerable<SelectedItem> _items = new SelectedItem[]
16+
{
17+
new() { Value = "", Text = "请选择 ..." },
18+
new() { Value = "10", Text = "大于 10" },
19+
new() { Value = "50", Text = "大于 50" },
20+
new() { Value = "80", Text = "大于 80" }
21+
};
22+
23+
/// <summary>
24+
/// 重置过滤条件方法
25+
/// </summary>
26+
public override void Reset()
27+
{
28+
Value = null;
29+
StateHasChanged();
30+
}
31+
32+
/// <summary>
33+
/// 生成过滤条件方法
34+
/// </summary>
35+
/// <returns></returns>
36+
public override FilterKeyValueAction GetFilterConditions()
37+
{
38+
var filter = new FilterKeyValueAction();
39+
if (Value != null)
40+
{
41+
filter.Filters.Add(new FilterKeyValueAction()
42+
{
43+
FieldKey = FieldKey,
44+
FieldValue = Value.Value,
45+
FilterAction = FilterAction.GreaterThan
46+
});
47+
}
48+
return filter;
49+
}
50+
}

src/BootstrapBlazor.Server/Components/Samples/Table/TablesFilter.razor

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
</DemoBlock>
4747

4848
<DemoBlock Title="@Localizer["FilterTemplateTitle"]"
49-
Introduction="@Localizer["FilterTemplateIntro"]" Name="CustomerFilter">
49+
Introduction="@Localizer["FilterTemplateIntro"]" Name="CustomFilter">
5050
<section ignore>@((MarkupString)Localizer["TablesFilterTemplateDescription", ComponentSourceCodeUrl].Value)</section>
5151

5252
<Table TItem="Foo"
@@ -65,7 +65,7 @@
6565
</TableColumn>
6666
<TableColumn @bind-Field="@context.Count" Width="100" Sortable="true" Filterable="true">
6767
<FilterTemplate>
68-
<CustomerFilter></CustomerFilter>
68+
<Filter TFilter="CustomerFilter"></Filter>
6969
</FilterTemplate>
7070
</TableColumn>
7171
</TableColumns>
@@ -81,12 +81,12 @@
8181
ShowSkeleton="true" ShowFilterHeader="true"
8282
OnQueryAsync="@OnQueryAsync">
8383
<TableColumns>
84-
<TableColumn @bind-Field="@context.DateTime" Width="180" Sortable="true" />
85-
<TableColumn @bind-Field="@context.Name" Width="100" Sortable="true" />
86-
<TableColumn @bind-Field="@context.Address" Sortable="true" />
84+
<TableColumn @bind-Field="@context.DateTime" Width="180" Sortable="true" Filterable="true" />
85+
<TableColumn @bind-Field="@context.Name" Width="100" Sortable="true" Filterable="true" />
86+
<TableColumn @bind-Field="@context.Address" Sortable="true" Filterable="true" />
8787
<TableColumn @bind-Field="@context.Complete" Width="100" Sortable="true" Filterable="true" />
8888
<TableColumn @bind-Field="@context.Education" Width="100" Sortable="true" Filterable="true" />
89-
<TableColumn @bind-Field="@context.Count" Width="100" Sortable="true" DefaultSort="true" DefaultSortOrder="@SortOrder.Desc" />
89+
<TableColumn @bind-Field="@context.Count" Width="100" Sortable="true" Filterable="true" DefaultSort="true" DefaultSortOrder="@SortOrder.Desc" />
9090
</TableColumns>
9191
</Table>
9292
</DemoBlock>
@@ -211,22 +211,22 @@
211211
<TableColumn @bind-Field="@context.DateTime" Width="180" Sortable="true" />
212212
<TableColumn @bind-Field="@context.Name" Width="100" Sortable="true" Filterable="true">
213213
<FilterTemplate>
214-
<MultiFilter Items="_nameMultiFilterItems"></MultiFilter>
214+
<Filter TFilter="MultiFilter" FilterParameters="_multiFilterParameter1"></Filter>
215215
</FilterTemplate>
216216
</TableColumn>
217217
<TableColumn @bind-Field="@context.Address" Sortable="true" Filterable="true">
218218
<FilterTemplate>
219-
<MultiFilter OnGetItemsAsync="OnGetAddressItemsAsync"></MultiFilter>
219+
<Filter TFilter="MultiFilter" FilterParameters="_multiFilterParameter2"></Filter>
220220
</FilterTemplate>
221221
</TableColumn>
222222
<TableColumn @bind-Field="@context.Complete" Width="100" Sortable="true" Filterable="true">
223223
<FilterTemplate>
224-
<MultiFilter ShowSearch="false" Items="Items.Select(i => new SelectedItem(i.Complete.ToString()!, i.Complete.ToString()!)).DistinctBy(i => i.Value)"></MultiFilter>
224+
<Filter TFilter="MultiFilter" FilterParameters="_multiFilterParameter3"></Filter>
225225
</FilterTemplate>
226226
</TableColumn>
227227
<TableColumn @bind-Field="@context.Education" Width="100" Sortable="true" Filterable="true">
228228
<FilterTemplate>
229-
<MultiFilter ShowSearch="false" Items="Items.Select(i => new SelectedItem(i.Education.ToString()!, i.Education.ToString()!)).DistinctBy(i => i.Value)"></MultiFilter>
229+
<Filter TFilter="MultiFilter" FilterParameters="_multiFilterParameter4"></Filter>
230230
</FilterTemplate>
231231
</TableColumn>
232232
<TableColumn @bind-Field="@context.Count" Width="150" Sortable="true" />

src/BootstrapBlazor.Server/Components/Samples/Table/TablesFilter.razor.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ public partial class TablesFilter
2929
[NotNull]
3030
private Table<Foo>? TableSetFilter { get; set; }
3131

32-
private IEnumerable<SelectedItem> _nameMultiFilterItems = default!;
32+
private readonly Dictionary<string, object> _multiFilterParameter1 = new();
33+
private readonly Dictionary<string, object> _multiFilterParameter2 = new();
34+
private readonly Dictionary<string, object> _multiFilterParameter3 = new();
35+
private readonly Dictionary<string, object> _multiFilterParameter4 = new();
3336

3437
/// <summary>
3538
/// OnInitialized 方法
@@ -39,7 +42,18 @@ protected override void OnInitialized()
3942
base.OnInitialized();
4043

4144
Items = Foo.GenerateFoo(FooLocalizer);
42-
_nameMultiFilterItems = Items.Select(i => new SelectedItem(i.Name!, i.Name!)).DistinctBy(i => i.Value);
45+
var items1 = Items.Select(i => new SelectedItem(i.Name!, i.Name!)).DistinctBy(i => i.Value);
46+
_multiFilterParameter1.Add(nameof(MultiFilter.Items), items1);
47+
48+
_multiFilterParameter2.Add(nameof(MultiFilter.OnGetItemsAsync), new Func<Task<List<SelectedItem>>>(OnGetAddressItemsAsync));
49+
50+
var items3 = Items.Select(i => new SelectedItem(i.Complete.ToString(), i.Complete.ToString())).DistinctBy(i => i.Value);
51+
_multiFilterParameter3.Add(nameof(MultiFilter.Items), items3);
52+
_multiFilterParameter3.Add(nameof(MultiFilter.ShowSearch), false);
53+
54+
var items4 = Items.Select(i => new SelectedItem(i.Education.ToString()!, i.Education.ToString()!)).DistinctBy(i => i.Value);
55+
_multiFilterParameter4.Add(nameof(MultiFilter.Items), items4);
56+
_multiFilterParameter4.Add(nameof(MultiFilter.ShowSearch), false);
4357
}
4458

4559
private async Task<List<SelectedItem>> OnGetAddressItemsAsync()

src/BootstrapBlazor/Components/Filters/BoolFilter.razor

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33

44
@if (IsHeaderRow)
55
{
6-
<Select Items="@Items" @bind-Value="@Value" OnSelectedItemChanged="_ => OnFilterValueChanged()" IsPopover="true"></Select>
6+
<Select Items="@Items" @bind-Value="@_value" ShowLabel="false" SkipValidate="true"
7+
OnSelectedItemChanged="_ => OnFilterAsync()" IsPopover="true"></Select>
78
}
89
else
910
{
10-
<Select Items="@Items" @bind-Value="@Value"></Select>
11+
<Select Items="@Items" @bind-Value="@_value" ShowLabel="false" SkipValidate="true"></Select>
1112
}

src/BootstrapBlazor/Components/Filters/BoolFilter.razor.cs

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,20 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

6-
using Microsoft.Extensions.Localization;
7-
86
namespace BootstrapBlazor.Components;
97

108
/// <summary>
11-
/// 布尔类型过滤条件
9+
/// BoolFilter component is used for boolean value filtering in table column.
1210
/// </summary>
1311
public partial class BoolFilter
1412
{
15-
private string Value { get; set; } = "";
16-
17-
[Inject]
18-
[NotNull]
19-
private IStringLocalizer<TableFilter>? Localizer { get; set; }
20-
2113
/// <summary>
22-
/// <inheritdoc/>
14+
/// Gets or sets the filter candidate items. It is recommended to use static data to avoid performance loss.
2315
/// </summary>
24-
protected override void OnInitialized()
25-
{
26-
base.OnInitialized();
16+
[Parameter]
17+
public IEnumerable<SelectedItem>? Items { get; set; }
2718

28-
if (TableFilter != null)
29-
{
30-
TableFilter.ShowMoreButton = false;
31-
}
32-
}
19+
private string? _value;
3320

3421
/// <summary>
3522
/// <inheritdoc/>
@@ -38,20 +25,20 @@ protected override void OnParametersSet()
3825
{
3926
base.OnParametersSet();
4027

41-
Items ??= new SelectedItem[]
42-
{
43-
new("", Localizer["BoolFilter.AllText"].Value),
44-
new("true", Localizer["BoolFilter.TrueText"].Value),
45-
new("false", Localizer["BoolFilter.FalseText"].Value)
46-
};
28+
Items ??=
29+
[
30+
new SelectedItem("", Localizer["BoolFilter.AllText"].Value),
31+
new SelectedItem("true", Localizer["BoolFilter.TrueText"].Value),
32+
new SelectedItem("false", Localizer["BoolFilter.FalseText"].Value)
33+
];
4734
}
4835

4936
/// <summary>
5037
/// <inheritdoc/>
5138
/// </summary>
5239
public override void Reset()
5340
{
54-
Value = "";
41+
_value = null;
5542
StateHasChanged();
5643
}
5744

@@ -61,13 +48,13 @@ public override void Reset()
6148
/// <returns></returns>
6249
public override FilterKeyValueAction GetFilterConditions()
6350
{
64-
var filter = new FilterKeyValueAction() { Filters = [] };
65-
if (!string.IsNullOrEmpty(Value))
51+
var filter = new FilterKeyValueAction();
52+
if (!string.IsNullOrEmpty(_value))
6653
{
67-
filter.Filters.Add(new FilterKeyValueAction()
54+
filter.Filters.Add(new FilterKeyValueAction
6855
{
6956
FieldKey = FieldKey,
70-
FieldValue = Value == "true",
57+
FieldValue = _value == "true",
7158
FilterAction = FilterAction.Equal
7259
});
7360
}
@@ -79,14 +66,10 @@ public override FilterKeyValueAction GetFilterConditions()
7966
/// </summary>
8067
public override async Task SetFilterConditionsAsync(FilterKeyValueAction filter)
8168
{
82-
var first = filter.Filters?.FirstOrDefault() ?? filter;
69+
var first = filter.Filters.FirstOrDefault() ?? filter;
8370
if (first.FieldValue is bool value)
8471
{
85-
Value = value ? "true" : "false";
86-
}
87-
else if (first.FieldValue is null)
88-
{
89-
Value = "";
72+
_value = value ? "true" : "false";
9073
}
9174
await base.SetFilterConditionsAsync(filter);
9275
}
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
@namespace BootstrapBlazor.Components
2-
@inherits FilterBase
2+
@inherits MultipleFilterBase
33

44
@if (IsHeaderRow)
55
{
66
<div class="@FilterRowClassString">
7-
<DateTimePicker class="is-filter" @bind-Value="Value1" OnValueChanged="_ => OnFilterValueChanged()"></DateTimePicker>
8-
<FilterButton Items="Items" @bind-Value="Action1" OnSelectedItemChanged="_ => OnFilterValueChanged()" OnClearFilter="OnClearFilter" />
7+
<DateTimePicker class="is-filter" @bind-Value="_value1" OnValueChanged="_ => OnFilterAsync()"
8+
ShowLabel="false" SkipValidate="true"></DateTimePicker>
9+
<FilterButton Items="Items" @bind-Value="_action1" OnSelectedItemChanged="_ => OnFilterAsync()" OnClearFilter="OnClearFilter"></FilterButton>
910
</div>
1011
}
1112
else
1213
{
13-
<Select Items="Items" @bind-Value="Action1"></Select>
14-
15-
<DateTimePicker class="is-filter" @bind-Value="Value1"></DateTimePicker>
14+
<Select Items="Items" @bind-Value="_action1" ShowLabel="false" SkipValidate="true"></Select>
15+
<DateTimePicker class="is-filter" @bind-Value="_value1" ShowLabel="false" SkipValidate="true"></DateTimePicker>
1616

1717
@if (Count > 0)
1818
{
1919
<FilterLogicItem @bind-Logic="Logic"></FilterLogicItem>
20-
21-
<Select Items="Items" @bind-Value="Action2"></Select>
22-
23-
<DateTimePicker class="is-filter" @bind-Value="Value2"></DateTimePicker>
20+
<Select Items="Items" @bind-Value="_action2" ShowLabel="false" SkipValidate="true"></Select>
21+
<DateTimePicker class="is-filter" @bind-Value="_value2" ShowLabel="false" SkipValidate="true"></DateTimePicker>
2422
}
2523
}

0 commit comments

Comments
 (0)