Skip to content

Commit 29be951

Browse files
authored
feat(Table): support edit item in Drawer (#3588)
* feat: 增加抽屉编辑模式 * refactor: 增加抽屉分支 * doc: 更新注释文档 * refactor: 修复表格样式错误 * feat: 抽屉组件增加样式参数 * feat: Table 支持抽屉模式编辑 * doc: 更新示例 * refactor: 调整参数顺序增加 CloseButtonIcon 参数 * refactor: 增加保存按钮与关闭按钮图标 * refactor: 更改 OnSaveAsync 回调方法 * doc: 更新 Dialog 示例 * refactor: 使用 DialogCloseButton 精简 SearchDialog * refactor: 精简搜索按钮 * refactor: 重构代码使用 DialogCloseButton 精简逻辑 * doc: 增加方法注释 * refactor: 重构代码消除提示信息 * refactor: 增加 SaveButtonIcon 参数代替 SaveIcon * refactor: 重构代码 * refactor: 更新模态框逻辑 * refactor: 增加模态框内置逻辑 * refactor: 精简扩展方法逻辑 * doc: 更新注释文档 * refactor: 修复表格样式错误 * doc: 更新 Dialog 示例 * refactor: 使用 DialogCloseButton 精简 SearchDialog * refactor: 精简搜索按钮 * refactor: 重构代码使用 DialogCloseButton 精简逻辑 * doc: 增加方法注释 * refactor: 重构代码消除提示信息 * refactor: 增加 SaveButtonIcon 参数代替 SaveIcon * refactor: 重构代码 * refactor: 更新模态框逻辑 * refactor: 增加模态框内置逻辑 * refactor: 精简扩展方法逻辑 * refactor: 精简代码 * refactor: 更新配置类 * refactor: 更改阻塞任务变量名称 * refactor: 增加 Icon 参数赋值 * refactor: 移除不必要标签 * test: 更新单元测试 * refactor: 移除 Footer 组件 ShowCloseButton 相关代码复用 ModalDialog 组件 * test: 更新单元测试 * chore: 增加过期标识 * test: 更新单元测试 * refactor: 撤销冗余代码 * test: 更新单元测试 * refactor: 代码重构 * refactor: 重构代码提高复用率 * test: 增加单元测试 * feat: 增加清理浏览器 dom 逻辑 * refactor: 增加接口提高代码复用率 * test: 增加单元测试 * fix: 更新图标错误问题 * refactor: 更改写法提高代码覆盖率 * refactor: 更改类可见性 * test: 更新单元测试 * refactor: 调整代码顺序提高可读性 * test: 更新单元测试 * chore: bump version 8.6.0
1 parent 1e7000b commit 29be951

21 files changed

+983
-157
lines changed

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

+19
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,25 @@
164164
<TableColumn @bind-Field="@context.Complete" IsVisibleWhenEdit="false" />
165165
</TableColumns>
166166
</Table>
167+
168+
<section ignore>
169+
<p>@((MarkupString)Localizer["TablesEditModeDrawer"].Value)</p>
170+
</section>
171+
<Table TItem="Foo"
172+
IsPagination="true" PageItemsSource="@PageItemsSource"
173+
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
174+
ShowToolbar="true" ShowExtendButtons="true" ShowSkeleton="true"
175+
AddModalTitle="@Localizer["TablesEditModeAddModalTitle"]" EditModalTitle="@Localizer["TablesEditModeEditModalTitle"]"
176+
EditMode="EditMode.Drawer" @bind-Items="@BindItems" InsertRowMode="InsertMode">
177+
<TableColumns>
178+
<TableColumn @bind-Field="@context.DateTime" Width="180" />
179+
<TableColumn @bind-Field="@context.Name" />
180+
<TableColumn @bind-Field="@context.Address" Rows="3" />
181+
<TableColumn @bind-Field="@context.Education" />
182+
<TableColumn @bind-Field="@context.Count" IsVisibleWhenAdd="false" />
183+
<TableColumn @bind-Field="@context.Complete" IsVisibleWhenEdit="false" />
184+
</TableColumns>
185+
</Table>
167186
</DemoBlock>
168187

169188
<DemoBlock Title="@Localizer["TablesEditInjectDataServiceTitle"]" Introduction="@Localizer["TablesEditInjectDataServiceIntro"]" Name="InjectDataService">

src/BootstrapBlazor.Server/Locales/en-US.json

+1
Original file line numberDiff line numberDiff line change
@@ -5085,6 +5085,7 @@
50855085
"TablesEditModeAddModalTitle": "Add test data window",
50865086
"TablesEditModeEditModalTitle": "Edit Test Data Window",
50875087
"TablesEditModeInCell": "<code>InCell</code> Pattern example",
5088+
"TablesEditModeDrawer": "<code>Drawer</code> Pattern example",
50885089
"TablesEditShowSearchPlaceHolderString": "Cannot be empty, within 50 characters",
50895090
"TablesEditInjectDataServiceDescription": "The database operations of adding, deleting, modifying and checking are performed by registering the data service without assigning the following callback delegates. The priority level is that the callback method is called first if there is a callback method.",
50905091
"TablesEditInjectDataServiceTips1": "Startup file injects data service",

src/BootstrapBlazor.Server/Locales/zh-CN.json

+1
Original file line numberDiff line numberDiff line change
@@ -5085,6 +5085,7 @@
50855085
"TablesEditModeAddModalTitle": "增加测试数据窗口",
50865086
"TablesEditModeEditModalTitle": "编辑测试数据窗口",
50875087
"TablesEditModeInCell": "<code>InCell</code> 模式示例",
5088+
"TablesEditModeDrawer": "<code>Drawer</code> 模式示例",
50885089
"TablesEditInjectDataServiceDescription": "通过注册数据服务进行增、删、改、查的数据库操作,而无需对以下回调委托进行赋值,优先级别为有回调方法优先调用回调方法,如无则调用注入服务进行数据操作",
50895090
"TablesEditInjectDataServiceTips1": "Startup 文件注入数据服务",
50905091
"TablesEditInjectDataServiceTips2": "实现原理与用法介绍",

src/BootstrapBlazor/BootstrapBlazor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>8.5.12-beta04</Version>
4+
<Version>8.6.0</Version>
55
</PropertyGroup>
66

77
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">

src/BootstrapBlazor/Components/Dialog/EditDialog.razor.cs

+39-25
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,55 @@ namespace BootstrapBlazor.Components;
1313
public partial class EditDialog<TModel>
1414
{
1515
/// <summary>
16-
/// 获得/设置 保存回调委托
16+
/// 获得/设置 查询时是否显示正在加载中动画 默认为 false
1717
/// </summary>
1818
[Parameter]
19-
#if NET6_0_OR_GREATER
20-
[EditorRequired]
21-
#endif
22-
public Func<EditContext, Task>? OnSaveAsync { get; set; }
19+
public bool ShowLoading { get; set; }
2320

2421
/// <summary>
25-
/// 获得/设置 获得/设置 重置按钮文本
22+
/// 获得/设置 组件是否采用 Tracking 模式对编辑项进行直接更新 默认 false
2623
/// </summary>
2724
[Parameter]
28-
[NotNull]
29-
public string? CloseButtonText { get; set; }
25+
public bool IsTracking { get; set; }
3026

3127
/// <summary>
32-
/// 获得/设置 查询时是否显示正在加载中动画 默认为 false
28+
/// 获得/设置 实体类编辑模式 Add 还是 Update
3329
/// </summary>
3430
[Parameter]
35-
public bool ShowLoading { get; set; }
31+
public ItemChangedType ItemChangedType { get; set; }
3632

3733
/// <summary>
38-
/// 获得/设置 组件是否采用 Tracking 模式对编辑项进行直接更新 默认 false
34+
/// 获得/设置 保存按钮图标
3935
/// </summary>
4036
[Parameter]
41-
public bool IsTracking { get; set; }
37+
public string? SaveButtonIcon { get; set; }
4238

4339
/// <summary>
44-
/// 获得/设置 实体类编辑模式 Add 还是 Update
40+
/// 获得/设置 保存按钮文本
4541
/// </summary>
4642
[Parameter]
47-
public ItemChangedType ItemChangedType { get; set; }
43+
public string? SaveButtonText { get; set; }
4844

4945
/// <summary>
50-
/// 获得/设置 查询按钮文本
46+
/// 获得/设置 保存回调委托 返回 false 时保持编辑弹窗 返回 true 时关闭编辑弹窗
5147
/// </summary>
5248
[Parameter]
53-
[NotNull]
54-
public string? SaveButtonText { get; set; }
49+
#if NET6_0_OR_GREATER
50+
[EditorRequired]
51+
#endif
52+
public Func<EditContext, Task<bool>>? OnSaveAsync { get; set; }
53+
54+
/// <summary>
55+
/// 获得/设置 关闭按钮图标
56+
/// </summary>
57+
[Parameter]
58+
public string? CloseButtonIcon { get; set; }
59+
60+
/// <summary>
61+
/// 获得/设置 获得/设置 重置按钮文本
62+
/// </summary>
63+
[Parameter]
64+
public string? CloseButtonText { get; set; }
5565

5666
/// <summary>
5767
/// 获得/设置 关闭弹窗回调方法
@@ -71,11 +81,8 @@ public partial class EditDialog<TModel>
7181
[Parameter]
7282
public RenderFragment<TModel>? FooterTemplate { get; set; }
7383

74-
/// <summary>
75-
/// 获得/设置 保存按钮图标
76-
/// </summary>
77-
[Parameter]
78-
public string? SaveButtonIcon { get; set; }
84+
[CascadingParameter]
85+
private Func<Task>? CloseAsync { get; set; }
7986

8087
[Inject]
8188
[NotNull]
@@ -92,6 +99,7 @@ protected override void OnParametersSet()
9299
{
93100
base.OnParametersSet();
94101

102+
CloseButtonIcon ??= IconTheme.GetIconByKey(ComponentIcons.DialogCloseButtonIcon);
95103
SaveButtonIcon ??= IconTheme.GetIconByKey(ComponentIcons.DialogSaveButtonIcon);
96104

97105
CloseButtonText ??= Localizer[nameof(CloseButtonText)];
@@ -103,8 +111,13 @@ private async Task OnValidSubmitAsync(EditContext context)
103111
if (OnSaveAsync != null)
104112
{
105113
await ToggleLoading(true);
106-
await OnSaveAsync(context);
114+
var save = await OnSaveAsync(context);
107115
await ToggleLoading(false);
116+
117+
if (save && CloseAsync != null)
118+
{
119+
await CloseAsync();
120+
}
108121
}
109122
}
110123

@@ -132,8 +145,9 @@ public async ValueTask ToggleLoading(bool state)
132145
if (!IsTracking)
133146
{
134147
builder.OpenComponent<DialogCloseButton>(20);
135-
builder.AddAttribute(21, nameof(Button.Text), CloseButtonText);
136-
builder.AddAttribute(22, nameof(Button.OnClickWithoutRender), OnCloseAsync);
148+
builder.AddAttribute(21, nameof(Button.Icon), CloseButtonIcon);
149+
builder.AddAttribute(22, nameof(Button.Text), CloseButtonText);
150+
builder.AddAttribute(23, nameof(Button.OnClickWithoutRender), OnCloseAsync);
137151
builder.CloseComponent();
138152
}
139153
builder.OpenComponent<Button>(30);

src/BootstrapBlazor/Components/Dialog/EditDialogOption.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace BootstrapBlazor.Components;
99
/// <summary>
1010
/// 编辑弹窗配置类
1111
/// </summary>
12-
public class EditDialogOption<TModel> : DialogOption
12+
public class EditDialogOption<TModel> : DialogOption, ITableEditDialogOption<TModel>
1313
{
1414
/// <summary>
1515
/// 构造函数

src/BootstrapBlazor/Components/Drawer/Drawer.razor.scss

+21
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@
1616
margin: 0;
1717
z-index: var(--bb-drawer-zindex);
1818

19+
&.drawer-table-edit {
20+
.drawer-body {
21+
padding: 0;
22+
}
23+
24+
.drawer-content {
25+
padding: var(--bb-drawer-body-padding);
26+
}
27+
28+
.form-footer {
29+
margin: 1rem -1rem -.5rem -1rem;
30+
padding: .5rem 1rem 0 1rem;
31+
border-top: 1px solid var(--bs-border-color);
32+
text-align: right;
33+
34+
button:not(:last-child) {
35+
margin-right: .25rem;
36+
}
37+
}
38+
}
39+
1940
&.no-bd {
2041
pointer-events: none;
2142
}

src/BootstrapBlazor/Components/Drawer/DrawerContainer.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ private void RenderDrawer(RenderTreeBuilder builder, DrawerOption option)
5050
{
5151
builder.OpenComponent<Drawer>(0);
5252
builder.SetKey(option);
53-
builder.AddMultipleAttributes(1, GetParameters(option));
53+
54+
if (!string.IsNullOrEmpty(option.Class))
55+
{
56+
builder.AddAttribute(1, "class", option.Class);
57+
}
58+
builder.AddMultipleAttributes(2, GetParameters(option));
5459
builder.CloseComponent();
5560
}
5661

@@ -90,6 +95,9 @@ private async Task OnCloseAsync(DrawerOption option)
9095
{
9196
await option.OnCloseAsync();
9297
}
98+
99+
_option = null;
100+
StateHasChanged();
93101
}
94102

95103
/// <summary>

src/BootstrapBlazor/Components/Drawer/DrawerOption.cs

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ namespace BootstrapBlazor.Components;
99
/// </summary>
1010
public class DrawerOption
1111
{
12+
/// <summary>
13+
/// 获得/设置 Drawer 组件样式
14+
/// </summary>
15+
public string? Class { get; set; }
16+
1217
/// <summary>
1318
/// 获得/设置 抽屉宽度 左右布局时生效
1419
/// </summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
using Microsoft.AspNetCore.Components.Forms;
6+
7+
namespace BootstrapBlazor.Components;
8+
9+
/// <summary>
10+
/// Table 编辑配置接口
11+
/// </summary>
12+
public interface ITableEditDialogOption<TModel>
13+
{
14+
/// <summary>
15+
/// 获得/设置 组件是否采用 Tracking 模式对编辑项进行直接更新 默认 false
16+
/// </summary>
17+
bool IsTracking { get; set; }
18+
19+
/// <summary>
20+
/// 获得/设置 是否显示标签 默认为 true 显示标签
21+
/// </summary>
22+
bool ShowLabel { get; set; }
23+
24+
/// <summary>
25+
/// 获得/设置 实体类编辑模式 Add 还是 Update
26+
/// </summary>
27+
ItemChangedType ItemChangedType { get; set; }
28+
29+
/// <summary>
30+
/// 获得/设置 每行显示组件数量 默认为 null
31+
/// </summary>
32+
int? ItemsPerRow { get; set; }
33+
34+
/// <summary>
35+
/// 获得/设置 设置行内组件布局格式 默认 Row 布局
36+
/// </summary>
37+
RowType RowType { get; set; }
38+
39+
/// <summary>
40+
/// 获得/设置 设置 <see cref="RowType" /> Inline 模式下标签对齐方式 默认 None 等效于 Left 左对齐
41+
/// </summary>
42+
Alignment LabelAlign { get; set; }
43+
44+
/// <summary>
45+
/// 获得/设置 查询时是否显示正在加载中动画 默认为 false
46+
/// </summary>
47+
bool ShowLoading { get; set; }
48+
49+
/// <summary>
50+
/// 获得/设置 未分组编辑项布局位置 默认 false 在尾部
51+
/// </summary>
52+
bool ShowUnsetGroupItemsOnTop { get; set; }
53+
54+
/// <summary>
55+
/// 获得/设置 编辑框模型
56+
/// </summary>
57+
TModel? Model { get; set; }
58+
59+
/// <summary>
60+
/// 获得/设置 是否禁用表单内回车自动提交功能 默认 null 未设置
61+
/// </summary>
62+
bool? DisableAutoSubmitFormByEnter { get; set; }
63+
64+
/// <summary>
65+
/// 获得/设置 保存按钮文本
66+
/// </summary>
67+
string? SaveButtonText { get; set; }
68+
69+
/// <summary>
70+
/// 获得/设置 保存按钮图标 默认 null 使用当前主题图标
71+
/// </summary>
72+
string? SaveButtonIcon { get; set; }
73+
74+
/// <summary>
75+
/// 获得/设置 关闭按钮文本
76+
/// </summary>
77+
string? CloseButtonText { get; set; }
78+
79+
/// <summary>
80+
/// 获得/设置 关闭按钮图标 默认 null 使用当前主题图标
81+
/// </summary>
82+
string? CloseButtonIcon { get; set; }
83+
84+
/// <summary>
85+
/// 获得 编辑项集合
86+
/// </summary>
87+
IEnumerable<IEditorItem>? Items { get; set; }
88+
89+
/// <summary>
90+
/// 获得/设置 保存回调委托
91+
/// </summary>
92+
Func<EditContext, Task<bool>>? OnEditAsync { get; set; }
93+
94+
/// <summary>
95+
/// 获得/设置 关闭弹窗回调方法
96+
/// </summary>
97+
Func<Task>? OnCloseAsync { get; set; }
98+
99+
/// <summary>
100+
/// 获得/设置 EditDialog Body 模板
101+
/// </summary>
102+
RenderFragment<TModel>? DialogBodyTemplate { get; set; }
103+
104+
/// <summary>
105+
/// 获得/设置 EditDialog Footer 模板
106+
/// </summary>
107+
RenderFragment<TModel>? DialogFooterTemplate { get; set; }
108+
}

0 commit comments

Comments
 (0)