mirror of
https://github.com/dotnetcore/BootstrapBlazor.git
synced 2025-12-20 10:26:41 +08:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'">
|
||||
|
||||
@@ -126,11 +126,7 @@ public partial class NullSwitch
|
||||
|
||||
OnInnerText ??= Localizer[nameof(OnInnerText)];
|
||||
OffInnerText ??= Localizer[nameof(OffInnerText)];
|
||||
|
||||
if (CurrentValue == null)
|
||||
{
|
||||
CurrentValue = DefaultValueWhenNull;
|
||||
}
|
||||
CurrentValue ??= DefaultValueWhenNull;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 集合
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user