chore(Table): revert add visible on AutoGenerateBaseAttribute (#2107)

* refactor: 更新示例代码

* revert: 撤销 Visible 参数的移动

* refactor: 重构方法提高可读性

* refactor: 更新方法可见性消除警告信息

* test: 更新单元测试

* refactor: 精简代码

* test: 更新单元测试

* test: 更新单元测试

* test: 更新单元测试

* test: 更新单元测试

* test: 更新单元测试

* test: 更新单元测试

* chore: bump version 7.10.5-beta03
This commit is contained in:
Argo Zhang
2023-09-11 00:33:12 +08:00
committed by GitHub
parent 304ad477d1
commit 2919c67709
14 changed files with 82 additions and 64 deletions

View File

@@ -51,7 +51,7 @@ public partial class TablesColumn
{
IEnumerable<Foo> items = Items;
// 过滤
// 先处理过滤再处理排序 提高性能
var isFiltered = false;
if (options.Filters.Any())
{
@@ -63,8 +63,7 @@ public partial class TablesColumn
var isSorted = false;
if (!string.IsNullOrEmpty(options.SortName))
{
var invoker = Foo.GetNameSortFunc();
items = invoker(items, options.SortName, options.SortOrder);
items = items.Sort(options.SortName, options.SortOrder);
isSorted = true;
}
@@ -84,14 +83,12 @@ public partial class TablesColumn
});
}
private static Task<bool> OnSaveAsync(Foo foo, ItemChangedType changedType)
{
return Task.FromResult(true);
}
private static Task<bool> OnSaveAsync(Foo foo, ItemChangedType changedType) => Task.FromResult(true);
private static Task OnColumnCreating(List<ITableColumn> columns)
{
foreach (var item in columns.Where(item => item.GetFieldName() == nameof(Foo.Name)))
var item = columns.Find(i => i.GetFieldName() == nameof(Foo.Name));
if (item != null)
{
item.Readonly = true;
}

View File

@@ -58,9 +58,4 @@ public abstract class AutoGenerateBaseAttribute : Attribute
/// 获得/设置 是否可以拷贝列 默认 false 不可以
/// </summary>
public bool ShowCopyColumn { get; set; }
/// <summary>
/// 获得/设置 列是否显示 默认为 true 可见的
/// </summary>
public bool Visible { get; set; } = true;
}

View File

@@ -80,6 +80,11 @@ public class AutoGenerateColumnAttribute : AutoGenerateBaseAttribute, ITableColu
/// </summary>
public bool Fixed { get; set; }
/// <summary>
/// 获得/设置 列是否显示 默认为 true 可见的
/// </summary>
public bool Visible { get; set; } = true;
/// <summary>
/// 获得/设置 列 td 自定义样式 默认为 null 未设置
/// </summary>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<Version>7.10.5-beta02</Version>
<Version>7.10.5-beta03</Version>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">

View File

@@ -126,11 +126,7 @@ public partial class NullSwitch
OnInnerText ??= Localizer[nameof(OnInnerText)];
OffInnerText ??= Localizer[nameof(OffInnerText)];
if (CurrentValue == null)
{
CurrentValue = DefaultValueWhenNull;
}
CurrentValue ??= DefaultValueWhenNull;
}
/// <summary>

View File

@@ -28,7 +28,6 @@ public static class IEditItemExtensions
if (source.ShowCopyColumn) dest.ShowCopyColumn = source.ShowCopyColumn;
if (source.Sortable) dest.Sortable = source.Sortable;
if (source.TextEllipsis) dest.TextEllipsis = source.TextEllipsis;
if (!source.Visible) dest.Visible = source.Visible;
}
/// <summary>

View File

@@ -204,7 +204,7 @@ public static class Utility
/// <returns></returns>
public static TModel Clone<TModel>(TModel item)
{
TModel ret = item;
var ret = item;
if (item != null)
{
if (item is ICloneable cloneable)
@@ -275,38 +275,40 @@ public static class Utility
public static IEnumerable<ITableColumn> GetTableColumns(Type type, IEnumerable<ITableColumn>? source = null)
{
var cols = new List<ITableColumn>(50);
var attrModel = type.GetCustomAttribute<AutoGenerateClassAttribute>(true);
var classAttribute = type.GetCustomAttribute<AutoGenerateClassAttribute>(true);
var props = type.GetProperties().Where(p => !p.IsStatic());
foreach (var prop in props)
{
ITableColumn? tc;
var attr = prop.GetCustomAttribute<AutoGenerateColumnAttribute>(true);
var columnAttribute = prop.GetCustomAttribute<AutoGenerateColumnAttribute>(true);
// Issue: 增加定义设置标签 AutoGenerateClassAttribute
// https://gitee.com/LongbowEnterprise/BootstrapBlazor/issues/I381ED
var displayName = attr?.Text ?? Utility.GetDisplayName(type, prop.Name);
if (attr == null)
var displayName = columnAttribute?.Text ?? Utility.GetDisplayName(type, prop.Name);
if (columnAttribute == null)
{
tc = new InternalTableColumn(prop.Name, prop.PropertyType, displayName);
if (attrModel != null)
if (classAttribute != null)
{
tc.InheritValue(attrModel);
tc.InheritValue(classAttribute);
}
}
else
{
if (attr.Ignore) continue;
if (columnAttribute.Ignore) continue;
attr.Text = displayName;
attr.FieldName = prop.Name;
attr.PropertyType = prop.PropertyType;
columnAttribute.Text = displayName;
columnAttribute.FieldName = prop.Name;
columnAttribute.PropertyType = prop.PropertyType;
if (attrModel != null)
if (classAttribute != null)
{
attr.InheritValue(attrModel);
var visible = columnAttribute.Visible;
columnAttribute.InheritValue(classAttribute);
columnAttribute.Visible = visible;
}
tc = attr;
tc = columnAttribute;
}
// 替换属性 手写优先
@@ -662,7 +664,16 @@ public static class Utility
return ret;
}
private static Func<TType, Task> CreateOnValueChangedCallback<TModel, TType>(TModel model, ITableColumn col, Func<TModel, ITableColumn, object?, Task> callback) => new(v => callback(model, col, v));
/// <summary>
/// 创建 <see cref="Func{T, TResult}"/> 委托方法
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <typeparam name="TType"></typeparam>
/// <param name="model"></param>
/// <param name="col"></param>
/// <param name="callback"></param>
/// <returns></returns>
public static Func<TType, Task> CreateOnValueChangedCallback<TModel, TType>(TModel model, ITableColumn col, Func<TModel, ITableColumn, object?, Task> callback) => new(v => callback(model, col, v));
/// <summary>
/// 创建 OnValueChanged 回调委托
@@ -672,7 +683,7 @@ public static class Utility
/// <returns></returns>
public static Expression<Func<TModel, ITableColumn, Func<TModel, ITableColumn, object?, Task>, object>> CreateOnValueChanged<TModel>(Type fieldType)
{
var method = typeof(Utility).GetMethod(nameof(CreateOnValueChangedCallback), BindingFlags.Static | BindingFlags.NonPublic)!.MakeGenericMethod(typeof(TModel), fieldType);
var method = typeof(Utility).GetMethod(nameof(CreateOnValueChangedCallback), BindingFlags.Static | BindingFlags.Public)!.MakeGenericMethod(typeof(TModel), fieldType);
var exp_p1 = Expression.Parameter(typeof(TModel));
var exp_p2 = Expression.Parameter(typeof(ITableColumn));
var exp_p3 = Expression.Parameter(typeof(Func<,,,>).MakeGenericType(typeof(TModel), typeof(ITableColumn), typeof(object), typeof(Task)));
@@ -781,14 +792,22 @@ public static class Utility
var exp_p1 = Expression.Parameter(typeof(ComponentBase));
var exp_p2 = Expression.Parameter(typeof(object));
var exp_p3 = Expression.Parameter(typeof(string));
var method = typeof(Utility).GetMethod(nameof(CreateCallback), BindingFlags.Static | BindingFlags.NonPublic)!.MakeGenericMethod(fieldType);
var method = typeof(Utility).GetMethod(nameof(CreateCallback), BindingFlags.Static | BindingFlags.Public)!.MakeGenericMethod(fieldType);
var body = Expression.Call(null, method, exp_p1, exp_p2, exp_p3);
return Expression.Lambda<Func<ComponentBase, object, string, object>>(Expression.Convert(body, typeof(object)), exp_p1, exp_p2, exp_p3);
}
}
private static EventCallback<TType> CreateCallback<TType>(ComponentBase component, object model, string fieldName) => EventCallback.Factory.Create<TType>(component, t => CacheManager.SetPropertyValue(model, fieldName, t));
/// <summary>
/// 创建 <see cref="EventCallback{TValue}"/> 方法
/// </summary>
/// <typeparam name="TType"></typeparam>
/// <param name="component"></param>
/// <param name="model"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
public static EventCallback<TType> CreateCallback<TType>(ComponentBase component, object model, string fieldName) => EventCallback.Factory.Create<TType>(component, t => CacheManager.SetPropertyValue(model, fieldName, t));
/// <summary>
/// 获得指定泛型的 IEditorItem 集合

View File

@@ -69,9 +69,9 @@ public class LogoutTest : BootstrapBlazorTestBase
cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.PrefixDisplayNameText, "prefix_displayname");
pb.Add(a => a.PrefixDisplayNameText, "prefix_display_name");
});
Assert.Contains("prefix_displayname", cut.Markup);
cut.WaitForAssertion(() => cut.Contains("prefix_display_name"));
}
[Fact]

View File

@@ -112,13 +112,13 @@ public class MenuTest : BootstrapBlazorTestBase
{
pb.Add(m => m.IsVertical, true);
});
Assert.Contains("Menu1", cut.Markup);
cut.WaitForAssertion(() => cut.Contains("Menu1"));
cut.SetParametersAndRender(pb =>
{
pb.Add(m => m.Items, null);
});
Assert.Contains("submenu", cut.Markup);
cut.WaitForAssertion(() => cut.Contains("submenu"));
}
[Fact]
@@ -283,7 +283,7 @@ public class MenuTest : BootstrapBlazorTestBase
{
pb.Add(m => m.IsVertical, true);
});
Assert.Contains("accordion", cut.Markup);
cut.WaitForAssertion(() => cut.Contains("accordion"));
}
[Fact]
@@ -301,14 +301,14 @@ public class MenuTest : BootstrapBlazorTestBase
pb.Add(m => m.IsVertical, true);
pb.Add(m => m.IsExpandAll, false);
});
Assert.DoesNotContain("data-bb-expand", cut.Markup);
cut.WaitForAssertion(() => cut.DoesNotContain("data-bb-expand"));
cut.SetParametersAndRender(pb =>
{
pb.Add(m => m.IsVertical, true);
pb.Add(m => m.IsExpandAll, true);
});
Assert.Contains("data-bb-expand=\"true\"", cut.Markup);
cut.WaitForAssertion(() => cut.Contains("data-bb-expand=\"true\""));
}
[Fact]

View File

@@ -84,11 +84,11 @@ public class ModalDialogTest : BootstrapBlazorTestBase
Assert.Contains("btn-maximize", cut.Markup);
var button = cut.Find(".btn-maximize");
cut.InvokeAsync(() => button.Click());
Assert.Contains("modal-fullscreen", cut.Markup);
button.Click();
cut.WaitForAssertion(() => cut.Contains("modal-fullscreen"));
cut.InvokeAsync(() => button.Click());
Assert.DoesNotContain("modal-fullscreen", cut.Markup);
button.Click();
cut.WaitForAssertion(() => cut.DoesNotContain("modal-fullscreen"));
}
[Fact]

View File

@@ -5350,7 +5350,7 @@ public class TableTest : TableTestBase
{
pb.Add(a => a.ShowDeleteButton, false);
});
Assert.DoesNotContain("fa-solid fa-xmark", table.Markup);
cut.WaitForAssertion(() => cut.DoesNotContain("fa-solid fa-xmark"));
}
[Fact]

View File

@@ -369,8 +369,11 @@ public class TreeViewTest : BootstrapBlazorTestBase
cut.Find(".fa-caret-right.visible").Click();
// 展开第一个节点生成一行子节点
var nodes = cut.FindAll(".tree-item");
cut.WaitForState(() => nodes.Count == 3);
cut.WaitForAssertion(() =>
{
var nodes = cut.FindAll(".tree-item");
Assert.Equal(3, nodes.Count);
});
// 重新设置数据源更新组件,保持状态
items = TreeFoo.GetTreeItems();
@@ -381,8 +384,11 @@ public class TreeViewTest : BootstrapBlazorTestBase
{
pb.Add(a => a.Items, items);
});
nodes = cut.FindAll(".tree-item");
cut.WaitForState(() => nodes.Count == 3);
cut.WaitForAssertion(() =>
{
var nodes = cut.FindAll(".tree-item");
Assert.Equal(3, nodes.Count);
});
// 设置 IsReset=true 更新数据源后不保持状态
items = TreeFoo.GetTreeItems();
@@ -394,8 +400,11 @@ public class TreeViewTest : BootstrapBlazorTestBase
pb.Add(a => a.Items, items);
pb.Add(a => a.IsReset, true);
});
cut.WaitForState(() => nodes.Count == 3);
Assert.Equal(3, nodes.Count);
cut.WaitForAssertion(() =>
{
var nodes = cut.FindAll(".tree-item");
Assert.Equal(2, nodes.Count);
});
}
[Fact]

View File

@@ -111,14 +111,14 @@ public class ValidateTest : BootstrapBlazorTestBase
{
builder.Add(a => a.ShowLabel, false);
});
Assert.DoesNotContain("label", cut.Markup);
cut.WaitForAssertion(() => cut.DoesNotContain("label"));
// IsShowLabel 为空时 不显示标签
cut.SetParametersAndRender(builder =>
{
builder.Add(a => a.ShowLabel, null);
});
Assert.DoesNotContain("label", cut.Markup);
cut.WaitForAssertion(() => cut.DoesNotContain("label"));
// 开启双向绑定时 IsShowLabel 为空时 不显示标签
cut.SetParametersAndRender(builder =>
@@ -127,7 +127,7 @@ public class ValidateTest : BootstrapBlazorTestBase
builder.Add(a => a.Value, model.Name);
builder.Add(a => a.ValueExpression, model.GenerateValueExpression());
});
Assert.DoesNotContain("label", cut.Markup);
cut.WaitForAssertion(() => cut.DoesNotContain("label"));
// 开启双向绑定时 IsShowLabel=false 时 不显示标签
cut.SetParametersAndRender(builder =>
@@ -136,7 +136,7 @@ public class ValidateTest : BootstrapBlazorTestBase
builder.Add(a => a.Value, model.Name);
builder.Add(a => a.ValueExpression, model.GenerateValueExpression());
});
Assert.DoesNotContain("label", cut.Markup);
cut.WaitForAssertion(() => cut.DoesNotContain("label"));
// 开启双向绑定时 IsShowLabel=true 时 显示标签
cut.SetParametersAndRender(builder =>
@@ -145,7 +145,7 @@ public class ValidateTest : BootstrapBlazorTestBase
builder.Add(a => a.Value, model.Name);
builder.Add(a => a.ValueExpression, model.GenerateValueExpression());
});
Assert.Contains("label", cut.Markup);
cut.WaitForAssertion(() => cut.Contains("label"));
}
[Fact]

View File

@@ -21,8 +21,7 @@ public class ITableColumnExtensionsTest
ShowTips = true,
Sortable = true,
TextEllipsis = true,
ShowCopyColumn = true,
Visible = false
ShowCopyColumn = true
};
col.InheritValue(attr);
Assert.Equal(Alignment.Center, col.Align);
@@ -35,7 +34,6 @@ public class ITableColumnExtensionsTest
Assert.True(col.Sortable);
Assert.True(col.TextEllipsis);
Assert.True(col.ShowCopyColumn);
Assert.False(col.Visible);
}
[Fact]