diff --git a/src/BootstrapBlazor/Components/Filters/FilterBase.cs b/src/BootstrapBlazor/Components/Filters/FilterBase.cs index 698e65ba2e045e43a27ed3665cdcdb54b5e833ed..6ca9b68cf8fa731fcff4487a634584c1f199be0b 100644 --- a/src/BootstrapBlazor/Components/Filters/FilterBase.cs +++ b/src/BootstrapBlazor/Components/Filters/FilterBase.cs @@ -36,7 +36,7 @@ public abstract class FilterBase : ComponentBase, IFilterAction /// /// 获得 当前过滤条件是否激活 /// - protected bool HasFilter => TableFilter?.HasFilter ?? false; + protected bool HasFilter => TableFilter!.HasFilter; // IsHeaderRow 为真时使用 TableFilter 不为空 /// /// 获得/设置 条件数量 diff --git a/src/BootstrapBlazor/Components/Filters/NumberFilter.razor.cs b/src/BootstrapBlazor/Components/Filters/NumberFilter.razor.cs index 80df967de398cd831e26ed3a1c38bd8a80cc6739..26434b41e6f11ea90876553b3099c3b4f4d455a9 100644 --- a/src/BootstrapBlazor/Components/Filters/NumberFilter.razor.cs +++ b/src/BootstrapBlazor/Components/Filters/NumberFilter.razor.cs @@ -42,12 +42,12 @@ public partial class NumberFilter Items = new SelectedItem[] { - new SelectedItem("GreaterThanOrEqual", Localizer["GreaterThanOrEqual"]?.Value ?? "GreaterThanOrEqual"), - new SelectedItem("LessThanOrEqual", Localizer["LessThanOrEqual"]?.Value ?? "LessThanOrEqual"), - new SelectedItem("GreaterThan", Localizer["GreaterThan"]?.Value ?? "GreaterThan"), - new SelectedItem("LessThan", Localizer["LessThan"]?.Value ?? "LessThan"), - new SelectedItem("Equal", Localizer["Equal"]?.Value ?? "Equal"), - new SelectedItem("NotEqual", Localizer["NotEqual"]?.Value ?? "NotEqual") + new SelectedItem("GreaterThanOrEqual", Localizer["GreaterThanOrEqual"].Value), + new SelectedItem("LessThanOrEqual", Localizer["LessThanOrEqual"].Value), + new SelectedItem("GreaterThan", Localizer["GreaterThan"].Value), + new SelectedItem("LessThan", Localizer["LessThan"].Value), + new SelectedItem("Equal", Localizer["Equal"].Value), + new SelectedItem("NotEqual", Localizer["NotEqual"].Value) }; } @@ -61,6 +61,7 @@ public partial class NumberFilter Action1 = FilterAction.GreaterThanOrEqual; Action2 = FilterAction.LessThanOrEqual; Count = 0; + Logic = FilterLogic.And; StateHasChanged(); } @@ -71,19 +72,26 @@ public partial class NumberFilter public override IEnumerable GetFilterConditions() { var filters = new List(); - if (Value1 != null) filters.Add(new FilterKeyValueAction() + if (Value1 != null) { - FieldKey = FieldKey, - FieldValue = Value1, - FilterAction = Action1 - }); - if (Count > 0 && Value2 != null) filters.Add(new FilterKeyValueAction() + filters.Add(new FilterKeyValueAction() + { + FieldKey = FieldKey, + FieldValue = Value1, + FilterAction = Action1 + }); + } + + if (Count > 0 && Value2 != null) { - FieldKey = FieldKey, - FieldValue = Value2, - FilterAction = Action2, - FilterLogic = Logic - }); + filters.Add(new FilterKeyValueAction() + { + FieldKey = FieldKey, + FieldValue = Value2, + FilterAction = Action2, + FilterLogic = Logic + }); + } return filters; } } diff --git a/test/UnitTest/Components/TableBoolFilterTest.cs b/test/UnitTest/Components/TableBoolFilterTest.cs index e6a960f16857feb17a5a4bd2264c14cd9cf629b0..76b4ba0dcb7a45e310dc4151789ff865885fde30 100644 --- a/test/UnitTest/Components/TableBoolFilterTest.cs +++ b/test/UnitTest/Components/TableBoolFilterTest.cs @@ -17,6 +17,7 @@ public class TableBoolFilterTest : BootstrapBlazorTestBase var filter = cut.Instance; cut.InvokeAsync(() => filter.Reset()); } + [Fact] public void GetFilterConditions_Ok() { diff --git a/test/UnitTest/Components/TableDateTimeFilterTest.cs b/test/UnitTest/Components/TableDateTimeFilterTest.cs index cdeb1e21f7ed658ee494483acd86d83862951f74..7d5337b5f4f652e95625d8aaa898f44a720b9d63 100644 --- a/test/UnitTest/Components/TableDateTimeFilterTest.cs +++ b/test/UnitTest/Components/TableDateTimeFilterTest.cs @@ -18,6 +18,7 @@ public class TableDateTimeFilterTest : BootstrapBlazorTestBase var filter = cut.Instance; cut.InvokeAsync(() => filter.Reset()); } + [Fact] public void GetFilterConditions_Ok() { diff --git a/test/UnitTest/Components/TableFilterTest.cs b/test/UnitTest/Components/TableFilterTest.cs index 40d61de2c229b020dee981e323b936d8299d06f7..06575d93a30927b9a234898fe279d94cdbe103c3 100644 --- a/test/UnitTest/Components/TableFilterTest.cs +++ b/test/UnitTest/Components/TableFilterTest.cs @@ -108,8 +108,8 @@ public class TableFilterTest : BootstrapBlazorTestBase var column = new TableColumn(); column.SetParametersAsync(ParameterView.FromDictionary(new Dictionary() { - ["Field"] = foo.Name, - ["FieldExpression"] = foo.GenerateValueExpression() + [nameof(TableColumn.Field)] = foo.Name, + [nameof(TableColumn.FieldExpression)] = foo.GenerateValueExpression(), })); pb.Add(a => a.IsHeaderRow, true); pb.Add(a => a.Column, column); diff --git a/test/UnitTest/Components/TableNumberFilterTest.cs b/test/UnitTest/Components/TableNumberFilterTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..12ff6f4d6c32f0c99679a118a63d831342b7acb6 --- /dev/null +++ b/test/UnitTest/Components/TableNumberFilterTest.cs @@ -0,0 +1,154 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +using BootstrapBlazor.Shared; +using UnitTest.Extensions; + +namespace UnitTest.Components; + +public class TableNumberFilterTest : BootstrapBlazorTestBase +{ + [Fact] + public void Reset_Ok() + { + var cut = Context.RenderComponent>(); + + var filter = cut.Instance; + cut.InvokeAsync(() => filter.Reset()); + } + + [Fact] + public void GetFilterConditions_Ok() + { + var cut = Context.RenderComponent>(); + + var filter = cut.Instance; + IEnumerable? condtions = null; + cut.InvokeAsync(() => condtions = filter.GetFilterConditions()); + Assert.Empty(condtions); + + // Set Value + var dt = cut.FindComponent>(); + cut.InvokeAsync(() => dt.Instance.SetValue(10)); + cut.InvokeAsync(() => condtions = filter.GetFilterConditions()); + Assert.Single(condtions); + } + + [Fact] + public void Count_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Count, 2); + }); + + var logic = cut.FindComponent(); + Assert.NotNull(logic); + + var conditions = cut.Instance.GetFilterConditions(); + Assert.Empty(conditions); + + var dt = cut.FindComponent>().Instance; + cut.InvokeAsync(() => dt.SetValue(10)); + + conditions = cut.Instance.GetFilterConditions(); + Assert.Single(conditions); + + dt = cut.FindComponents>()[1].Instance; + cut.InvokeAsync(() => dt.SetValue(10)); + + conditions = cut.Instance.GetFilterConditions(); + Assert.Equal(2, conditions.Count()); + } + + [Fact] + public void NotNumber_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.Count, 2); + }); + } + + [Fact] + public void Misc_Ok() + { + var cut = Context.RenderComponent(pb => + { + pb.AddChildContent>(pb => + { + pb.Add(a => a.Items, new List() { new Foo() }); + pb.Add(a => a.RenderMode, TableRenderMode.Table); + pb.Add(a => a.ShowFilterHeader, true); + pb.Add(a => a.TableColumns, new RenderFragment(foo => builder => + { + var index = 0; + builder.OpenComponent>(index++); + builder.AddAttribute(index++, nameof(TableColumn.Field), foo.Count); + builder.AddAttribute(index++, nameof(TableColumn.FieldExpression), foo.GenerateValueExpression(nameof(Foo.Count), typeof(int))); + builder.AddAttribute(index++, nameof(TableColumn.Filterable), true); + builder.CloseComponent(); + })); + }); + }); + var filter = cut.FindComponent>(); + var input = filter.FindComponent>(); + IEnumerable? condtions = null; + + // Click ToDay Cell + cut.InvokeAsync(() => + { + input.Instance.SetValue(10); + }); + + // OnFilterValueChanged + var filterButton = cut.FindComponent>(); + var logics = filterButton.FindAll(".dropdown-item"); + Assert.Equal(6, logics.Count); + cut.InvokeAsync(() => + { + logics[1].Click(); + condtions = filter.Instance.GetFilterConditions(); + }); + Assert.Single(condtions); + Assert.Equal(10, condtions!.First().FieldValue); + Assert.Equal(FilterAction.LessThanOrEqual, condtions!.First().FilterAction); + + // OnClearFilter + cut.InvokeAsync(() => + { + filterButton.Find(".fa-ban").Click(); + condtions = filter.Instance.GetFilterConditions(); + }); + Assert.Single(condtions); + Assert.Equal(0, condtions!.First().FieldValue); + Assert.Equal(FilterAction.GreaterThanOrEqual, condtions!.First().FilterAction); + } + + [Fact] + public void NotNumberType_OnFilterValueChanged() + { + var cut = Context.RenderComponent(pb => + { + var foo = new Foo(); + var column = new TableColumn(); + column.SetParametersAsync(ParameterView.FromDictionary(new Dictionary() + { + [nameof(TableColumn.Field)] = foo.Name, + [nameof(TableColumn.FieldExpression)] = foo.GenerateValueExpression(), + [nameof(TableColumn.FilterTemplate)] = new RenderFragment(builder => + { + builder.OpenComponent>(0); + builder.CloseComponent(); + }) + })); + pb.Add(a => a.IsHeaderRow, true); + pb.Add(a => a.Column, column); + }); + + // InHeaderRow 非数字类型过滤器测试 + var input = cut.FindComponent>().Instance; + cut.InvokeAsync(() => input.SetValue("10")); + } +}