From d54014ef309d91698e03e66a13dcf5ca3c5da1a1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 22 Aug 2025 09:19:40 +0800 Subject: [PATCH 01/14] test(Upload): add unit test for upload reset (#6667) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 更改写法消除警告信息 * feat: 增加 Reset 方法 * doc: 代码格式化 * revert: 撤销新方法 * test: 增加单元测试 --- src/BootstrapBlazor/Components/Upload/ButtonUpload.razor | 3 ++- src/BootstrapBlazor/Components/Upload/UploadBase.cs | 2 +- test/UnitTest/Components/UploadButtonTest.cs | 9 ++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/BootstrapBlazor/Components/Upload/ButtonUpload.razor b/src/BootstrapBlazor/Components/Upload/ButtonUpload.razor index 66815687591..7c53f357dd3 100644 --- a/src/BootstrapBlazor/Components/Upload/ButtonUpload.razor +++ b/src/BootstrapBlazor/Components/Upload/ButtonUpload.razor @@ -7,7 +7,8 @@ }
- @if (ShowUploadFileList) diff --git a/src/BootstrapBlazor/Components/Upload/UploadBase.cs b/src/BootstrapBlazor/Components/Upload/UploadBase.cs index 77c9cc61b05..054bdb04125 100644 --- a/src/BootstrapBlazor/Components/Upload/UploadBase.cs +++ b/src/BootstrapBlazor/Components/Upload/UploadBase.cs @@ -149,7 +149,7 @@ protected async Task OnFileChange(InputFileChangeEventArgs args) fileCount = MaxFileCount.Value; // 计算剩余可上传数量 - fileCount = fileCount - Files.Count; + fileCount -= Files.Count; if (fileCount <= 0) { // 如果剩余可上传数量小于等于 0 则不允许继续上传 diff --git a/test/UnitTest/Components/UploadButtonTest.cs b/test/UnitTest/Components/UploadButtonTest.cs index f5d15d31332..f5df1a93510 100644 --- a/test/UnitTest/Components/UploadButtonTest.cs +++ b/test/UnitTest/Components/UploadButtonTest.cs @@ -86,7 +86,7 @@ public void ButtonUpload_IsDisabled_Ok() } [Fact] - public void InputUpload_IsMultiple() + public async Task InputUpload_IsMultiple() { var cut = Context.RenderComponent>(pb => { @@ -108,6 +108,13 @@ public void InputUpload_IsMultiple() var button = cut.Find(".btn-browser"); Assert.True(button.IsDisabled()); + // 调用 Reset 方法 + await cut.InvokeAsync(() => cut.Instance.Reset()); + + // 重置后上传按钮应该被启用 + button = cut.Find(".btn-browser"); + Assert.False(button.IsDisabled()); + // 开启多选功能 cut.SetParametersAndRender(pb => { From 54f416c51e5b2ff11514fc5a1ba9cee34866bc0f Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 22 Aug 2025 19:26:28 +0800 Subject: [PATCH 02/14] feat(DateTimePicker): add PickTimeMode parameter (#6670) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 代码格式化 * style: 微调日历数字字体大小 * doc: 代码格式化 * refactor: 结束时间精确到毫秒 * refactor: 代码格式化 * refactor: 私有属性改为变量 * feat: 增加时间选择器 * style: 调整间隙 * feat: 增加选择时间方式枚举参数 * refactor: 增加切换视图时关闭时间选择器逻辑 * feat: 增加秒针控制 * doc: 更新示例 * chore: bump version 9.10.0-beta01 * feat: 增加 PickTimeMode 参数 * test: 增加单元测试 --- .../Components/Samples/DateTimePickers.razor | 2 +- src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- .../DateTimePicker/DatePickerBody.razor | 21 +++++-- .../DateTimePicker/DatePickerBody.razor.cs | 58 ++++++++++++++++--- .../DateTimePicker/DatePickerBody.razor.scss | 32 +++++++++- .../DateTimePicker/DateTimePicker.razor | 6 +- .../DateTimePicker/DateTimePicker.razor.cs | 6 ++ .../Components/DateTimePicker/PickTimeMode.cs | 22 +++++++ .../DateTimeRange/DateTimeRange.razor.cs | 10 ++-- .../Components/TimePicker/TimePicker.razor | 4 -- .../UnitTest/Components/DateTimePickerTest.cs | 34 +++++++++++ 11 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 src/BootstrapBlazor/Components/DateTimePicker/PickTimeMode.cs diff --git a/src/BootstrapBlazor.Server/Components/Samples/DateTimePickers.razor b/src/BootstrapBlazor.Server/Components/Samples/DateTimePickers.razor index d515b753b46..2f92e5742a4 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/DateTimePickers.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/DateTimePickers.razor @@ -5,7 +5,7 @@

@Localizer["Description"]

- diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 1eb7e4c700e..a11bab70aa0 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@  - 9.9.3 + 9.10.0-beta01 diff --git a/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor b/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor index 4c373fdc0a1..8db866aa238 100644 --- a/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor +++ b/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor @@ -40,7 +40,7 @@
@YearString @MonthString - @if (IsDateTimeMode) + @if (IsDateTimeMode && PickTimeMode == PickTimeMode.Clock) { @CurrentTime.ToString(TimeFormat) } @@ -80,12 +80,12 @@ else if (IsDisabled(day)) { - @if(ShowLunar) + @if (ShowLunar) { @text @GetLunarText(day) } - else if(DayDisabledTemplate != null) + else if (DayDisabledTemplate != null) { @DayDisabledTemplate(day) } @@ -155,7 +155,8 @@ @ChildContent - @@ -164,6 +165,18 @@
+ @if (IsDateTimeMode && PickTimeMode == PickTimeMode.Dropdown) + { +
+ @TimePlaceHolder + + +
+ } @if (ShowFooter) { - -@code { - -} diff --git a/test/UnitTest/Components/DateTimePickerTest.cs b/test/UnitTest/Components/DateTimePickerTest.cs index 8cb7b56ba3f..1cd102d62d8 100644 --- a/test/UnitTest/Components/DateTimePickerTest.cs +++ b/test/UnitTest/Components/DateTimePickerTest.cs @@ -322,6 +322,7 @@ public void SwitchTimeView_Ok() { builder.Add(a => a.Value, new DateTime(2023, 10, 1, 1, 0, 0)); builder.Add(a => a.ViewMode, DatePickerViewMode.DateTime); + builder.Add(a => a.PickTimeMode, PickTimeMode.Clock); }); var labels = cut.FindAll(".picker-panel-header-label"); @@ -354,6 +355,39 @@ public void NotDateTime_Error() Context.RenderComponent>(); }); } + + [Fact] + public async Task PickTimeMode_Ok() + { + var cut = Context.RenderComponent(builder => + { + builder.Add(a => a.ViewMode, DatePickerViewMode.DateTime); + builder.Add(a => a.PickTimeMode, PickTimeMode.Dropdown); + builder.Add(a => a.ShowFooter, true); + builder.Add(a => a.Value, DateTime.Today.AddDays(-1)); + builder.Add(a => a.TimeFormat, "hh\\:mm"); + }); + + cut.Contains("picker-panel-time"); + + // 点击时间选择器 + var input = cut.Find(".picker-panel-time .form-control"); + await cut.InvokeAsync(() => input.Click()); + cut.Contains("picker-panel-time show"); + + // 点击时间选择器下拉框中的确定按钮 + var picker = cut.FindComponent(); + await cut.InvokeAsync(() => picker.Instance.OnClose!()); + + var ts = DateTime.Now.TimeOfDay; + await cut.InvokeAsync(() => picker.Instance.OnConfirm!(ts)); + Assert.Contains(ts.ToString("hh\\:mm"), cut.Markup); + + cut.SetParametersAndRender(pb => + { + pb.Add(a => a.TimeFormat, null); + }); + } #endregion #region DatePicker From 412e8ee552651f00e8fd8f5f4e29477d12afd930 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 23 Aug 2025 17:05:12 +0800 Subject: [PATCH 03/14] feat(BreadcrumbItem): add CssClass property (#6673) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 增加 IsFixed 关键字 * doc: 更新注释 * refactor: 精简代码 * test: 更新单元测试 * refactor: 精简代码 * refactor: 调整级联参数位置 * feat: 增加 CssClass 参数 支持自定义样式 * test: 更新单元测试 * doc: 更新注释 --- .../Components/Breadcrumb/Breadcrumb.razor | 16 ++++++------ .../Components/Breadcrumb/Breadcrumb.razor.cs | 17 ++++++++++--- .../Components/Breadcrumb/BreadcrumbItem.cs | 25 ++++++++----------- .../Components/Button/Button.razor.cs | 4 +-- test/UnitTest/Components/BreadcrumbsTest.cs | 10 +++++++- 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor b/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor index 9fc96613e83..1d744c44023 100644 --- a/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor +++ b/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor @@ -1,20 +1,20 @@ @namespace BootstrapBlazor.Components @inherits BootstrapComponentBase - - @code { RenderFragment RenderItem => item => - @
  • + @
  • @if (!string.IsNullOrEmpty(item.Url)) { @item.Text @@ -24,4 +24,4 @@ @item.Text }
  • ; -} \ No newline at end of file +} diff --git a/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor.cs b/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor.cs index c790638bc16..84961d8ea67 100644 --- a/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor.cs +++ b/src/BootstrapBlazor/Components/Breadcrumb/Breadcrumb.razor.cs @@ -14,11 +14,20 @@ public sealed partial class Breadcrumb /// 获得/设置 数据集 /// [Parameter] - public IEnumerable Value { get; set; } = Enumerable.Empty(); + [NotNull] + public IEnumerable? Value { get; set; } - private string? GetItemClassName(BreadcrumbItem item) => CssBuilder.Default("breadcrumb-item") + private static string? GetItemClassString(BreadcrumbItem item) => CssBuilder.Default("breadcrumb-item") + .AddClass(item.CssClass) .Build(); - private string? CurrentPage(BreadcrumbItem item) => CssBuilder.Default() - .Build(); + /// + /// + /// + protected override void OnParametersSet() + { + base.OnParametersSet(); + + Value ??= []; + } } diff --git a/src/BootstrapBlazor/Components/Breadcrumb/BreadcrumbItem.cs b/src/BootstrapBlazor/Components/Breadcrumb/BreadcrumbItem.cs index 24635d4f8aa..c9d275198e7 100644 --- a/src/BootstrapBlazor/Components/Breadcrumb/BreadcrumbItem.cs +++ b/src/BootstrapBlazor/Components/Breadcrumb/BreadcrumbItem.cs @@ -6,28 +6,25 @@ namespace BootstrapBlazor.Components; /// -/// BreadcrumbItem 实体类 +/// BreadcrumbItem Class /// -public class BreadcrumbItem +/// +/// +/// +public class BreadcrumbItem(string text, string? url = null, string? cssClass = null) { /// - /// 获得/设置 导航地址 + /// 获得/设置 显示文字 /// - public string? Url { get; } + public string Text { get; } = text; /// - /// 获得/设置 显示文字 + /// 获得/设置 导航地址 /// - public string Text { get; } + public string? Url { get; } = url; /// - /// 构造函数 + /// 获得/设置 样式名称 /// - /// - /// - public BreadcrumbItem(string text, string? url = null) - { - Text = text; - Url = url; - } + public string? CssClass { get; } = cssClass; } diff --git a/src/BootstrapBlazor/Components/Button/Button.razor.cs b/src/BootstrapBlazor/Components/Button/Button.razor.cs index 3cda232e70b..b573dfee3ff 100644 --- a/src/BootstrapBlazor/Components/Button/Button.razor.cs +++ b/src/BootstrapBlazor/Components/Button/Button.razor.cs @@ -22,10 +22,8 @@ public partial class Button : ButtonBase protected ElementReference ButtonElement { get; set; } /// - /// OnAfterRenderAsync 方法 + /// /// - /// - /// protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); diff --git a/test/UnitTest/Components/BreadcrumbsTest.cs b/test/UnitTest/Components/BreadcrumbsTest.cs index e72cfa98a75..298216ef7ef 100644 --- a/test/UnitTest/Components/BreadcrumbsTest.cs +++ b/test/UnitTest/Components/BreadcrumbsTest.cs @@ -13,7 +13,7 @@ public void ButtonStyle_Ok() var DataSource = new List { new("Library"), - new("Data") + new("Data", "", "cssClass") }; var cut = Context.RenderComponent(pb => @@ -21,6 +21,7 @@ public void ButtonStyle_Ok() pb.Add(b => b.Value, DataSource); }); Assert.Contains("Library", cut.Markup); + Assert.Contains("class=\"breadcrumb-item cssClass\"", cut.Markup); Assert.DoesNotContain("href", cut.Markup); DataSource.Add(new BreadcrumbItem("Home", "https://www.blazor.zone/")); @@ -35,5 +36,12 @@ public void ButtonStyle_Ok() { pb.Add(b => b.AdditionalAttributes, new Dictionary() { ["tag"] = "tagok" }); }); + cut.Contains("tag=\"tagok\""); + + cut.SetParametersAndRender(pb => + { + pb.Add(b => b.Value, null); + }); + Assert.DoesNotContain("li", cut.Markup); } } From 9314754df8c74921a7034c9ef62f96901ddeab04 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 23 Aug 2025 20:22:35 +0800 Subject: [PATCH 04/14] doc(MaskOption): update ZIndex documentation (#6675) --- src/BootstrapBlazor.Server/Components/Samples/Masks.razor | 3 +++ src/BootstrapBlazor.Server/Locales/en-US.json | 1 + src/BootstrapBlazor.Server/Locales/zh-CN.json | 1 + 3 files changed, 5 insertions(+) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Masks.razor b/src/BootstrapBlazor.Server/Components/Samples/Masks.razor index 627504bd0fd..ff6c80c6de7 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Masks.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Masks.razor @@ -6,6 +6,9 @@

    @Localizer["MaskDescription"]

    +
    +
    @((MarkupString)Localizer["MaskNormalDesc"].Value)
    +
    diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 3f262a8381b..fa9c2d5a420 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -456,6 +456,7 @@ "MaskDescription": "By calling the service display and hide methods, a mask layer is displayed to mask the data.", "MaskNormalTitle": "Basic usage", "MaskNormalIntro": "Call the MaskService mask service example method Show to display a mask, and call the instance method Close to close the mask after 3 seconds", + "MaskNormalDesc": "You can adjust the ZIndex Opacity BackgroundColor parameters via MaskOption", "ShowMaskButtonText": "Show", "MaskContainerTitle": "Container", "MaskContainerIntro": "Specify the mask position by setting the MaskOption parameter ContainerId", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 53c6acca4c0..c9a3da3827a 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -456,6 +456,7 @@ "MaskDescription": "通过调用服务显示,隐藏方法,显示一个遮罩层对数据进行遮罩操作", "MaskNormalTitle": "基本用法", "MaskNormalIntro": "调用 MaskService 遮罩服务示例方法 Show 方法显示一个遮罩,3 秒后调用实例方法 Close 关闭遮罩", + "MaskNormalDesc": "可以通过 MaskOption 调整 ZIndex Opacity BackgroundColor 参数", "ShowMaskButtonText": "打开", "MaskContainerTitle": "指定容器", "MaskContainerIntro": "通过设置 MaskOption 参数 ContainerId 指定遮罩出现位置", From 7082fa746394760d7c72d9d2ca034cfc5d242a1f Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sun, 24 Aug 2025 10:07:18 +0800 Subject: [PATCH 05/14] doc(FilterBase): update OnFilterAsync documentation (#6677) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc: 代码格式化 * refactor: 更新 OnFilterAsync 回调方法文档 * doc: update OnFilterAsync documentation --- .../Components/Components/CustomerFilter.razor | 2 -- src/BootstrapBlazor.Server/Locales/en-US.json | 2 +- src/BootstrapBlazor.Server/Locales/zh-CN.json | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Components/CustomerFilter.razor b/src/BootstrapBlazor.Server/Components/Components/CustomerFilter.razor index a3110a6adc1..05ff6bcdc02 100644 --- a/src/BootstrapBlazor.Server/Components/Components/CustomerFilter.razor +++ b/src/BootstrapBlazor.Server/Components/Components/CustomerFilter.razor @@ -9,5 +9,3 @@ else { } - - diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index fa9c2d5a420..1a53ff3e4c6 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -5715,7 +5715,7 @@ "SetFilterInCodeIntro": "Example shows how to set filters through code", "SetFilterInCodeButtonText1": "Name contains 01", "SetFilterInCodeButtonText2": "Reset All Filter", - "TablesFilterTemplateDescription": "

    The FilterTemplate type is RenderFragment its value is a custom component, and the component must inherit the filterBase In this case, the last column in this case, the Quantity column, uses the custom component by filtering the template CustomerFilter [portal] CustomerFilter component source code

    Notes:

    • Custom filter components are wrapped with FilterProvider, and FilterProvider must be under the FilterTemplate node
    • Filters can be fine-tuned through the parameters of the FilterProvider component; for example, by setting ShowMoreButton to control whether the + - symbol is displayed
    • ", + "TablesFilterTemplateDescription": "

      The FilterTemplate type is RenderFragment its value is a custom component, and the component must inherit the filterBase In this case, the last column in this case, the Quantity column, uses the custom component by filtering the template CustomerFilter [portal] CustomerFilter component source code

      Notes:

      • Custom filter components are wrapped with FilterProvider, and FilterProvider must be under the FilterTemplate node
      • Filters can be fine-tuned through the parameters of the FilterProvider component; for example, by setting ShowMoreButton to control whether the + - symbol is displayed
      • Before v9.6.2, use OnFilterValueChanged to trigger the filter callback. After refactoring, use OnFilterAsync to trigger the filter callback method.
      • ", "CustomerFilterItem1": "All", "CustomerFilterItem2": "Greater than 10", "CustomerFilterItem3": "Greater than 50", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index c9a3da3827a..c6e1bf16f76 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -5716,7 +5716,7 @@ "SetFilterInCodeIntro": "示例展示如何通过代码设置过滤条件", "SetFilterInCodeButtonText1": "名称包含01", "SetFilterInCodeButtonText2": "重置条件", - "TablesFilterTemplateDescription": "

        FilterTemplate 类型为 RenderFragment 其值为自定义组件,组件必须继承 FilterBase 本例中最后一列 数量列 通过筛选模板使用自定义组件 CustomerFilter [传送门] CustomerFilter 组件源码

        注意事项:

        • 自定义过滤组件使用 FilterProvider 包裹,FilterProvider必须在 FilterTemplate 节点下
        • 通过 FilterProvider 组件的参数可微调过滤器;例如通过设置 ShowMoreButton 控制是否显示 + - 符号
        • ", + "TablesFilterTemplateDescription": "

          FilterTemplate 类型为 RenderFragment 其值为自定义组件,组件必须继承 FilterBase 本例中最后一列 数量列 通过筛选模板使用自定义组件 CustomerFilter [传送门] CustomerFilter 组件源码

          注意事项:

          • 自定义过滤组件使用 FilterProvider 包裹,FilterProvider必须在 FilterTemplate 节点下
          • 通过 FilterProvider 组件的参数可微调过滤器;例如通过设置 ShowMoreButton 控制是否显示 + - 符号
          • v9.6.2 版本前,使用 OnFilterValueChanged 触发过滤回调,重构后使用 OnFilterAsync 触发过滤回调方法
          • ", "CustomerFilterItem1": "全部", "CustomerFilterItem2": "大于 10", "CustomerFilterItem3": "大于 50", From 3b2b55b19b15ad570c9884addb3b37a27cde1723 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Mon, 25 Aug 2025 12:38:04 +0800 Subject: [PATCH 06/14] doc(EditorForm): add IsDisplay parameter documentation (#6679) --- .../Components/Samples/EditorForms.razor | 8 ++++++++ .../Components/Samples/EditorForms.razor.cs | 1 + src/BootstrapBlazor.Server/Locales/en-US.json | 4 +++- src/BootstrapBlazor.Server/Locales/zh-CN.json | 5 ++++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor index 3e3169ae42e..fa0cb79b386 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor @@ -130,6 +130,14 @@ + + + + + + + + diff --git a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs index a693c96005a..ccaac6089fd 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs @@ -49,6 +49,7 @@ protected override void OnInitialized() DateTime = new DateTime(1997, 12, 05), Education = EnumEducation.Middle }; + Model.Hobby = Foo.GenerateHobbies(FooLocalizer).Take(3).Select(i => i.Text); } [NotNull] diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 1a53ff3e4c6..152909e805e 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -2639,7 +2639,9 @@ "TestName": "Tom", "TestAddress": "The test address", "AutoGenerateDescription": "In this example, by setting the autoGenerate AllItem value to false, turning off auto-generation, and rendering the form editing by manually adding two EditoItem edits", - "SkipValidateDescription": "In some cases, the value of some columns in the form may be a secondary classification, etc., and you need to know the information for a level 1 classification, at which point the first-level classification requires additional components to render if Select, which is independent of the current context binding model Model, which requires that you set the SkipValidate value to true, turn off model validation for this component" + "SkipValidateDescription": "In some cases, the value of some columns in the form may be a secondary classification, etc., and you need to know the information for a level 1 classification, at which point the first-level classification requires additional components to render if Select, which is independent of the current context binding model Model, which requires that you set the SkipValidate value to true, turn off model validation for this component", + "IsDisplayTitle": "Readonly Form", + "IsDisplayIntro": "Make the entire form non-editable by setting IsDisplay=\"true\"" }, "BootstrapBlazor.Server.Components.Samples.FloatingLabels": { "FloatingLabelsTitle": "FloatingLabel", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index c6e1bf16f76..baa9180c2c8 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -2640,7 +2640,10 @@ "TestName": "张三", "TestAddress": "测试地址", "AutoGenerateDescription": "本例中通过设置 AutoGenerateAllItem 值为 false,关闭自动生成功能,通过手动增加两个 EditorItem 编辑项来呈现表单编辑", - "SkipValidateDescription": "在某些情况下表单中有些列的值可能是二级分类等等,需要知道一级分类的信息,这个时候一级分类需要额外的组件来呈现,如果 Select,而这个组件是与当前上下文绑定模型 Model 无关的,这种需求中通过设置 SkipValidate 值为 true,关闭此组件的模型验证功能即可" + "SkipValidateDescription": "在某些情况下表单中有些列的值可能是二级分类等等,需要知道一级分类的信息,这个时候一级分类需要额外的组件来呈现,如果 Select,而这个组件是与当前上下文绑定模型 Model 无关的,这种需求中通过设置 SkipValidate 值为 true,关闭此组件的模型验证功能即可", + "IsDisplayTitle": "只读表单", + "IsDisplayIntro": "通过设置 IsDisplay=\"true\" 使整个表单不可编辑" + }, "BootstrapBlazor.Server.Components.Samples.FloatingLabels": { "FloatingLabelsTitle": "FloatingLabel 输入框", From 21363123dcffaff25579e56923d61bedb6517546 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 26 Aug 2025 15:22:01 +0800 Subject: [PATCH 07/14] doc(ITcpSocketClient): update SetDataPackageAdapter documentation (#6681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc: 更新扩展方法文档 * chore: bump version 9.0.1 --- .../BootstrapBlazor.Server.csproj | 2 +- .../Components/Samples/Sockets/Adapters.razor | 13 +++++++------ .../Samples/Sockets/Adapters.razor.cs | 18 ++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index 5d4ca951ed0..ef49367be52 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -74,7 +74,7 @@ - + diff --git a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor index 77df9c61d3f..7e980048213 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor @@ -44,16 +44,17 @@
          • 不使用 数据适配器 要分两次接收才能接收完整
          • 使用 数据适配器 一次即可接收完整数据包
          -
          private readonly DataPackageAdapter _dataAdapter = new()
          -{
          -    // 数据适配器内部使用固定长度数据处理器
          -    DataPackageHandler = new FixLengthDataPackageHandler(12)
          -};
          +    
          // 数据适配器内部使用固定长度数据处理器
          +private readonly DataPackageAdapter _dataAdapter = new(new FixLengthDataPackageHandler(12));
           
          -_dataAdapter.ReceivedCallBack += async Data =>
          +_dataAdapter.ReceivedCallBack = async Data =>
           {
               // 此处接收到的数据 Data 为完整响应数据
           };
          +
          // 实战中可以使用 ITcpSocketClient 扩展方法 SetDataPackageAdapter 简化代码
          +_client.SetDataPackageAdapter(_dataAdapter, UpdateReceiveLog);
          + +

          本例中使用的模拟服务端代码如下:

          diff --git a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs index b8871f39141..d7e60e20a07 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs @@ -25,10 +25,7 @@ public partial class Adapters : IDisposable private readonly CancellationTokenSource _connectTokenSource = new(); private readonly CancellationTokenSource _sendTokenSource = new(); private readonly CancellationTokenSource _receiveTokenSource = new(); - private readonly DataPackageAdapter _dataAdapter = new() - { - DataPackageHandler = new FixLengthDataPackageHandler(12) - }; + private readonly DataPackageAdapter _dataAdapter = new(new FixLengthDataPackageHandler(12)); private bool _useDataAdapter = true; /// @@ -46,13 +43,14 @@ protected override void OnInitialized() // 设置本地使用的 IP地址与端口 options.LocalEndPoint = new IPEndPoint(IPAddress.Loopback, 0); }); + + // 此处代码分开写是为了判断 _useDataAdapter 参数 _client.ReceivedCallBack += OnReceivedAsync; + _dataAdapter.ReceivedCallBack = UpdateReceiveLog; + + // 实战中可以通过下面一句话设置数据适配器与回调方法 + // _client.SetDataPackageAdapter(_dataAdapter, UpdateReceiveLog); - _dataAdapter.ReceivedCallBack += async data => - { - // 直接处理接收的数据 - await UpdateReceiveLog(data); - }; } private async Task OnConnectAsync() @@ -102,7 +100,7 @@ private async ValueTask OnReceivedAsync(ReadOnlyMemory data) } } - private async Task UpdateReceiveLog(ReadOnlyMemory data) + private async ValueTask UpdateReceiveLog(ReadOnlyMemory data) { var payload = Encoding.UTF8.GetString(data.Span); var body = BitConverter.ToString(data.ToArray()); From 481b744cc2d6f7474eab680d09bb80e52f93bcb1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 26 Aug 2025 15:37:00 +0800 Subject: [PATCH 08/14] doc(Table): update EditDialogIsDraggable documentation (#6683) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc(Table): 更新文档 * doc: 更新示例 --- .../Components/Samples/Table/TablesEdit.razor | 2 +- src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesEdit.razor b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesEdit.razor index 74d13c8bda0..476d62ee397 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesEdit.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesEdit.razor @@ -74,7 +74,7 @@ diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs index 2efb69731d5..b209d325ae6 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs @@ -757,7 +757,7 @@ protected async Task SaveAsync(EditContext context, ItemChangedType changedType) public Size EditDialogSize { get; set; } = Size.ExtraExtraLarge; /// - /// 获得/设置 编辑框是否可以拖拽 默认 false 不可以拖拽 + /// 获得/设置 编辑框是否可以拖拽 默认 false 不可以拖拽,参数 值为 false 时此参数才生效 /// [Parameter] public bool EditDialogIsDraggable { get; set; } @@ -769,7 +769,7 @@ protected async Task SaveAsync(EditContext context, ItemChangedType changedType) public FullScreenSize EditDialogFullScreenSize { get; set; } /// - /// 获得/设置 编辑框是否显示最大化按钮 默认 true 显示 + /// 获得/设置 编辑框是否显示最大化按钮 默认 true 显示,此时 参数无效 /// [Parameter] public bool EditDialogShowMaximizeButton { get; set; } = true; From 69339a5f438dabceddcc576f35ce6b89f0ff9b50 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 27 Aug 2025 17:26:14 +0800 Subject: [PATCH 09/14] doc(ITcpSocketClient): update AddDataPackageAdapter documentation (#6686) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc: 增加配置示例文档 * doc: 增加本地化资源文件 * doc: 更新示例 * doc: 更新数据适配器文档 * chore: 更新依赖包 * doc: 更新文档 --- .../BootstrapBlazor.Server.csproj | 3 +- .../Components/Samples/SocketFactories.razor | 4 +- .../Components/Samples/Sockets/Adapters.razor | 5 ++- .../Samples/Sockets/Adapters.razor.cs | 2 +- .../Samples/Sockets/DataEntities.razor | 43 ++++++++++++++++++- src/BootstrapBlazor.Server/Locales/en-US.json | 4 +- src/BootstrapBlazor.Server/Locales/zh-CN.json | 4 +- 7 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index ef49367be52..8734c47a161 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -68,13 +68,14 @@ + - + diff --git a/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor b/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor index 250d040910f..823d74aaf76 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/SocketFactories.razor @@ -61,7 +61,9 @@ private async Task CreateClient() { DataPackageHandler = new FixLengthDataPackageHandler(4) }; - client.SetDataPackageAdapter(adapter, buffer => + + // 如果 client 不销毁切记使用 RemoveDataPackageAdapter 移除回调委托防止内存泄露 + client.AddDataPackageAdapter(adapter, buffer => { // buffer 即是接收到的数据 return ValueTask.CompletedTask; diff --git a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor index 7e980048213..2831e0fa2e8 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor @@ -51,8 +51,9 @@ _dataAdapter.ReceivedCallBack = async Data => { // 此处接收到的数据 Data 为完整响应数据 }; -
          // 实战中可以使用 ITcpSocketClient 扩展方法 SetDataPackageAdapter 简化代码
          -_client.SetDataPackageAdapter(_dataAdapter, UpdateReceiveLog);
          +
          // 实战中可以使用 ITcpSocketClient 扩展方法 AddDataPackageAdapter 简化代码
          +// 如果 _client 实例在当前页面不销毁时,切记使用 AddDataPackageAdapter 移除当前页面加载的 UpdateReceiveLog 回调方法避免内存泄露
          +_client.AddDataPackageAdapter(_dataAdapter, UpdateReceiveLog);

          本例中使用的模拟服务端代码如下:

          diff --git a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs index d7e60e20a07..b421951b9ed 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Sockets/Adapters.razor.cs @@ -49,7 +49,7 @@ protected override void OnInitialized() _dataAdapter.ReceivedCallBack = UpdateReceiveLog; // 实战中可以通过下面一句话设置数据适配器与回调方法 - // _client.SetDataPackageAdapter(_dataAdapter, UpdateReceiveLog); + // _client.AddDataPackageAdapter(_dataAdapter, UpdateReceiveLog); } diff --git a/src/BootstrapBlazor.Server/Components/Samples/Sockets/DataEntities.razor b/src/BootstrapBlazor.Server/Components/Samples/Sockets/DataEntities.razor index f1498c51879..517b2629302 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Sockets/DataEntities.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Sockets/DataEntities.razor @@ -63,7 +63,7 @@ class MockEntity
        • DataUInt64LittleEndianConverter 转成 ulong 无符号整形小端读取
        • 自定义数据类型转化器示例

          -
          [SocketTypeDataConverter(Type = typeof(DataConverter<MockEntity>))]
          +    
          [DataTypeConverter(Type = typeof(DataConverter<MockEntity>))]
           class MockEntity
           {
               [DataPropertyConverter(Type = typeof(byte[]), Offset = 0, Length = 5)]
          @@ -84,3 +84,44 @@ class MockEntity
           }

          更多技术细节可以参考以上内置提供的转换器源码

          + + +

          通过 ConfigureDataConverters 可以配置任意类型(第三方程序集中无源码类型)自定数据转换

          +
          class MockEntity
          +{
          +    public byte[]? Header { get; set; }
          +
          +    public byte[]? Body { get; set; }
          +}
          +
          service.ConfigureDataConverters(options =>
          +{
          +    // 配置 MockEntity 转换
          +    options.AddTypeConverter<MockEntity>();
          +
          +    // 配置 MockEntity 属性 Header 转换逻辑 从起始位置 0 开始读取 5 个字节
          +    options.AddPropertyConverter<MockEntity>(entity => entity.Header, new DataPropertyConverterAttribute()
          +    {
          +        Offset = 0,
          +        Length = 5
          +    });
          +
          +    // 配置 MockEntity 属性 Body 转换逻辑 从起始位置 5 开始读取 2 个字节
          +    options.AddPropertyConverter<MockEntity>(entity => entity.Body, new DataPropertyConverterAttribute()
          +    {
          +        Offset = 5,
          +        Length = 2
          +    });
          +});
          +

          通过调用 ITcpSocketClient 实例泛型扩展方法 AddDataPackageAdapter 在回调方法 OnReceiveAsync 中直接拿到数据实体类

          +
          // 创建一个数据适配器
          +var adapter = new DataPackageAdapter(new FixLengthDataPackageHandler(7));
          +
          +// 设置数据适配器与回调方法
          +_client.AddDataPackageAdapter<MockEntity>(adapter, OnReceiveAsync);
          +
          private async Task OnReceiveAsync(MockEntity? entity)
          +{
          +    return Task.CompletedTask;
          +}
          +
          diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 152909e805e..e9e7490f9bd 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -7163,7 +7163,9 @@ "DataEntityTitle": "Socket Auto Entity", "DataEntityDescription": "After receiving the communication data, it is automatically converted into the entity class required by the business", "NormalTitle": "Basic usage", - "NormalIntro": "Enable automatic data conversion through the DataTypeConverterAttribute attribute" + "NormalIntro": "Enable automatic data conversion through the DataTypeConverterAttribute attribute", + "ConfigTitle": "DataType Converter", + "ConfigIntro": "Use the ConfigureDataConverters method to map the entity class and automatically convert the received data" }, "BootstrapBlazor.Server.Components.Samples.NetworkMonitors": { "NetworkMonitorTitle": "NetworkMonitor", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index baa9180c2c8..8f0312dbdb7 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -7165,7 +7165,9 @@ "DataEntityTitle": "Socket 数据转化实体类", "DataEntityDescription": "接收到通讯数据后自动转成业务需要的实体类", "NormalTitle": "基本用法", - "NormalIntro": "通过 DataTypeConverterAttribute 标签开启数据自动转换功能" + "NormalIntro": "通过 DataTypeConverterAttribute 标签开启数据自动转换功能", + "ConfigTitle": "数据实体类映射配置", + "ConfigIntro": "使用 ConfigureDataConverters 方法对实体类进行映射配置将接收到的数据自动转化" }, "BootstrapBlazor.Server.Components.Samples.NetworkMonitors": { "NetworkMonitorTitle": "NetworkMonitor 网络状态", From 6d3d2f92584fa647e3079529a6bc46eb2f77704d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 28 Aug 2025 09:00:45 +0800 Subject: [PATCH 10/14] feat(Plyr): bump version 9.0.2 (#6688) bump plyr version 3.8.3 --- src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index 8734c47a161..c3240179a1a 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -64,7 +64,7 @@ - + From c9860150d5228aab8fb0490e39dc437f7a9618b6 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 28 Aug 2025 11:42:36 +0800 Subject: [PATCH 11/14] doc(BaiduOcr): add config documentation (#6690) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc: 文档格式化 * doc: 更新配置文档 * doc: 更新资源文件 * doc: 更新文档 --- .../Components/Samples/BaiduOcr.razor | 27 ++++++++++++------- .../Components/Samples/BaiduOcr.razor.cs | 23 +++++++++------- src/BootstrapBlazor.Server/Locales/en-US.json | 4 ++- src/BootstrapBlazor.Server/Locales/zh-CN.json | 7 ++--- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor b/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor index ce35e36a6f8..3a527a26ae7 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor @@ -1,22 +1,29 @@ @page "/ocr" -@inject IBaiduOcr OcrService -@inject IStringLocalizer Localizer -@inject ToastService ToastService

          @Localizer["Title"]

          @Localizer["SubTitle"]

          @Localizer["BaiduOcrDesc"] + +

          @Localizer["BaiduOcrIntro"]

          +

          @((MarkupString)Localizer["BaiduOcrStep1"].Value)

          +

          @((MarkupString)Localizer["BaiduOcrStep1Desc"].Value)

          +
          {
          +    "BaiduOcrOption": {
          +      "AppId": "",
          +      "ApiKey": "",
          +      "Secret": ""
          +    }
          +}
          +

          @((MarkupString)Localizer["BaiduOcrStep2"].Value)

          +
          [Inject, NotNull]
          +private IBaiduOcr? OcrService { get; set; }
          - - -

          @Localizer["BaiduOcrIntro"]

          -

          @((MarkupString)Localizer["BaiduOcrStep1"].Value)

          -

          @((MarkupString)Localizer["BaiduOcrStep2"].Value)

          +

          @((MarkupString)Localizer["BaiduOcrStep3"].Value)

          - + @if (Invoice != null) {
          @@ -128,7 +135,7 @@ - diff --git a/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor.cs index aa4a2ca02c9..9d1c8501063 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/BaiduOcr.razor.cs @@ -12,16 +12,21 @@ namespace BootstrapBlazor.Server.Components.Samples; /// public partial class BaiduOcr : IDisposable { - private InvoiceEntity? Invoice { get; set; } + [Inject, NotNull] + private IBaiduOcr? OcrService { get; set; } - /*以下示例为本站特殊处理逻辑可不参考*/ - private bool IsLoading { get; set; } + [Inject, NotNull] + private IStringLocalizer? Localizer { get; set; } - private string ButtonIcon { get; } = "fa-solid fa-cloud-arrow-up"; + [Inject, NotNull] + private ToastService? ToastService { get; set; } - private string LoadingIcon { get; } = "fa-solid fa-spinner fa-spin-pulse"; + private InvoiceEntity? Invoice { get; set; } + + /*以下示例为本站特殊处理逻辑可不参考*/ + private bool _isLoading; - private string Icon => IsLoading ? LoadingIcon : ButtonIcon; + private string Icon => _isLoading ? "fa-solid fa-spinner fa-spin-pulse" : "fa-solid fa-cloud-arrow-up"; /// /// 取消请求令牌 @@ -33,12 +38,12 @@ private async Task OnClickToUploadBlock(UploadFile file) if (file.File != null) { // 设置 按钮禁用 - IsLoading = true; + _isLoading = true; StateHasChanged(); // 获得上传文件 var payload = await file.GetBytesAsync(file.File.Size); - if (payload != null && payload.Length > 0) + if (payload is { Length: > 0 }) { try { @@ -60,7 +65,7 @@ private async Task OnClickToUploadBlock(UploadFile file) } } - IsLoading = false; + _isLoading = false; StateHasChanged(); } } diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index e9e7490f9bd..36fa83486b2 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -650,7 +650,9 @@ "BaiduOcrDesc": "本组件通过调用 Baidu AI 平台文字识别接口进行增值税发票文字识别。支持对增值税普票、专票、全电发票(新版全国统一电子发票,专票/普票)、卷票、区块链发票的所有字段进行结构化识别,包括发票基本信息、销售方及购买方信息、商品信息、价税信息等,其中五要素字段的识别准确率超过 99.9%; 同时,支持对增值税卷票的 21 个关键字段进行识别,包括发票类型、发票代码、发票号码、机打号码、机器编号、收款人、销售方名称、销售方纳税人识别号、开票日期、购买方名称、购买方纳税人识别号、项目、单价、数量、金额、税额、合计金额(小写)、合计金额(大写)、校验码、省、市,四要素字段的识别准确率可达95%。上传图片不能超过 4M", "BaiduOcrIntro": "Usage", "BaiduOcrStep1": "1. Get IBaiduOcr instance by inject service", - "BaiduOcrStep2": "2. Call IBaiduOcr instance method", + "BaiduOcrStep1Desc": "Update the appsettings.json file with the following configuration. Please register on Baidu AI Open Platform and apply for relevant parameter values.", + "BaiduOcrStep2": "2. Get IBaiduOcr instance by inject service", + "BaiduOcrStep3": "3. Call IBaiduOcr instance method", "VerifyVatInvoiceTitle": "增值税验真", "VerifyVatInvoiceIntro": "通过调用 IBaiduOcr 服务实例的发票验真方法 VerifyInvoiceAsync 返回 InvoiceVerifyResult 其属性 Validtrue 时为真" }, diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 8f0312dbdb7..1a656900f65 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -465,7 +465,6 @@ "MultipleMaskContainerDesc": "组件内自己设置 Mask 组件,调用 MaskService 实例方法 Show 时,通过第二个参数指定 Mask 实例即可", "MaskCloseTitle": "代码关闭弹窗", "MaskCloseIntro": "通过使用 DialogCloseButton 组件或者级联参数关闭弹窗" - }, "BootstrapBlazor.Server.Components.Samples.Messages": { "MessagesTitle": "Message 消息提示", @@ -650,8 +649,10 @@ "VatInvoiceIntro": "通过上传增值税发票图片调用百度 Ocr 接口进行文字识别", "BaiduOcrDesc": "本组件通过调用 Baidu AI 平台文字识别接口进行增值税发票文字识别。支持对增值税普票、专票、全电发票(新版全国统一电子发票,专票/普票)、卷票、区块链发票的所有字段进行结构化识别,包括发票基本信息、销售方及购买方信息、商品信息、价税信息等,其中五要素字段的识别准确率超过 99.9%; 同时,支持对增值税卷票的 21 个关键字段进行识别,包括发票类型、发票代码、发票号码、机打号码、机器编号、收款人、销售方名称、销售方纳税人识别号、开票日期、购买方名称、购买方纳税人识别号、项目、单价、数量、金额、税额、合计金额(小写)、合计金额(大写)、校验码、省、市,四要素字段的识别准确率可达95%。上传图片不能超过 4M", "BaiduOcrIntro": "使用方法", - "BaiduOcrStep1": "1. 通过注入服务获得 IBaiduOcr 实例", - "BaiduOcrStep2": "2. 调用服务相对应的识别方法即可", + "BaiduOcrStep1": "1. 配置 BaiduOcrOption", + "BaiduOcrStep1Desc": "更新 appsettings.json 文件,配置如下:相关参数值请在 百度 AI 开放平台 注册后开通申请", + "BaiduOcrStep2": "2. 通过注入服务获得 IBaiduOcr 实例", + "BaiduOcrStep3": "3. 调用服务相对应的识别方法即可", "VerifyVatInvoiceTitle": "增值税验真", "VerifyVatInvoiceIntro": "通过调用 IBaiduOcr 服务实例的发票验真方法 VerifyInvoiceAsync 返回 InvoiceVerifyResult 其属性 Validtrue 时为真" }, From 12ea8d8c4db1b7f41dfca8fab53e69bf5964af0b Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 28 Aug 2025 11:58:24 +0800 Subject: [PATCH 12/14] feat(SelectTree): add auto active value function (#6691) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 文档格式化 * feat: 增加选中节点逻辑 * doc: 更新可编辑文档 * refactor: 精简代码 --- .../Components/Samples/SelectTrees.razor | 5 ++++- src/BootstrapBlazor.Server/Locales/en-US.json | 1 + src/BootstrapBlazor.Server/Locales/zh-CN.json | 1 + src/BootstrapBlazor/Components/Select/SelectTree.razor | 2 +- src/BootstrapBlazor/Components/Select/SelectTree.razor.cs | 6 ++++-- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/SelectTrees.razor b/src/BootstrapBlazor.Server/Components/Samples/SelectTrees.razor index 8cea4ffd6fe..ea284db84eb 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/SelectTrees.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/SelectTrees.razor @@ -50,7 +50,10 @@ + Name="IsEditable"> +
          +
          @((MarkupString)Localizer["SelectTreesEditDesc"].Value)
          +
          diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 36fa83486b2..294fad37e76 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -4893,6 +4893,7 @@ "SelectTreesClientValidationIntro": "validate the value when submit the form. Inside ValidateForm", "SelectTreesEditTitle": "Edit", "SelectTreesEditIntro": "By setting IsEditable=\"true\" you can edit the input textbox", + "SelectTreesEditDesc": "After setting IsEditable=\"true\", the content displayed in the text box is the Value value of the node selected in the TreeView, the input value may not be in the Items collection", "SelectTreesIsPopoverTitle": "IsPopover", "SelectTreesIsPopoverIntro": "Set IsPopover to true, use popover render UI prevent The dropdown menu cannot be fully displayed because the parent container is set to overflow: hidden", "SelectTreesClientValidationButtonText": "Submit" diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 1a656900f65..18dfe6e2363 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -4894,6 +4894,7 @@ "SelectTreesClientValidationIntro": "组件内置 ValidateForm 可设置验证规则", "SelectTreesEditTitle": "可输入", "SelectTreesEditIntro": "通过设置 IsEditable=\"true\" 可设置下拉框选择后文本框可输入", + "SelectTreesEditDesc": "设置 IsEditable=\"true\" 后,文本框显示的内容为 TreeView 选中节点的 Value 值,输入值可以不在 Items 集合中", "SelectTreesIsPopoverTitle": "悬浮弹窗", "SelectTreesIsPopoverIntro": "通过设置 IsPopover 参数,组件使用 popover 渲染 UI 防止由于父容器设置 overflow: hidden; 使弹窗无法显示问题", "SelectTreesClientValidationButtonText": "提交" diff --git a/src/BootstrapBlazor/Components/Select/SelectTree.razor b/src/BootstrapBlazor/Components/Select/SelectTree.razor index 84678968bb0..b7649e13151 100644 --- a/src/BootstrapBlazor/Components/Select/SelectTree.razor +++ b/src/BootstrapBlazor/Components/Select/SelectTree.razor @@ -20,7 +20,7 @@
          [Parameter] [NotNull] -#if NET6_0_OR_GREATER [EditorRequired] -#endif public List>? Items { get; set; } /// @@ -168,6 +166,7 @@ public partial class SelectTree : IModelEqualityComparer private TreeViewItem? _selectedItem; private List>? _itemCache; private List>? _expandedItemsCache; + private TreeView _tv = default!; private string? SelectTreeCustomClassString => CssBuilder.Default(CustomClassString) .AddClass("select-tree", IsPopover) @@ -235,6 +234,9 @@ private void OnChange(ChangeEventArgs args) if (args.Value is string v) { CurrentValueAsString = v; + + // 选中节点更改为当前值 + _tv.SetActiveItem(Value); } } From 058d93ddf70993917d2661868ccc7d0a6468acc6 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 28 Aug 2025 12:01:16 +0800 Subject: [PATCH 13/14] fix(SvgEditor): update images path (#6693) --- src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index c3240179a1a..e2e099f94e6 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -71,7 +71,7 @@ - + From c5606b1dc2aad1de255b08ca3ee7dae470aa7c3e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 29 Aug 2025 08:46:16 +0800 Subject: [PATCH 14/14] doc(Localization): add Ukrainian (uk-UA) localization file (#6695) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc: add Ukrainian locales * chore: bump version 9.10.0 Co-Authored-By: Alexandr * doc: 文档格式化 * chore: 增加资源文件 --------- Co-authored-by: Alexandr --- BootstrapBlazor.sln | 1 + localization/uk-UA.json | 373 +++++++++++++++++++++ src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- 3 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 localization/uk-UA.json diff --git a/BootstrapBlazor.sln b/BootstrapBlazor.sln index 812c3e06e39..5947d0d889a 100644 --- a/BootstrapBlazor.sln +++ b/BootstrapBlazor.sln @@ -46,6 +46,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "localization", "localizatio localization\pt.json = localization\pt.json localization\ru-RU.json = localization\ru-RU.json localization\th-TH.json = localization\th-TH.json + localization\uk-UA.json = localization\uk-UA.json localization\zh-TW.json = localization\zh-TW.json EndProjectSection EndProject diff --git a/localization/uk-UA.json b/localization/uk-UA.json new file mode 100644 index 00000000000..a79faef5fe5 --- /dev/null +++ b/localization/uk-UA.json @@ -0,0 +1,373 @@ +{ + "BootstrapBlazor.Components.AutoComplete": { + "NoDataTip": "Немає даних", + "PlaceHolder": "Введіть текст" + }, + "BootstrapBlazor.Components.Captcha": { + "HeaderText": "Капча", + "BarText": "Пересуньте вправо, щоб розв’язати головоломку", + "FailedText": "Не вдалося завантажити", + "LoadText": "Завантаження ..." + }, + "BootstrapBlazor.Components.Calendar": { + "PreviousYear": "Попередній рік", + "PreviousMonth": "Попередній місяць", + "Today": "Сьогодні", + "NextMonth": "Наступний місяць", + "NextYear": "Наступний рік", + "PreviousWeek": "Попередній тиждень", + "WeekText": "Тиждень", + "NextWeek": "Наступний тиждень", + "WeekHeaderText": "", + "WeekLists": "Нд,Пн,Вт,Ср,Чт,Пт,Сб", + "WeekNumberText": "{0} тижнів", + "Months": "Січень,Лютий,Березень,Квітень,Травень,Червень,Липень,Серпень,Вересень,Жовтень,Листопад,Грудень", + "Title": "{0} {1}" + }, + "BootstrapBlazor.Components.Cascader": { + "PlaceHolder": "Будь ласка, виберіть ..." + }, + "BootstrapBlazor.Components.Console": { + "AutoScrollText": "Автопрокрутка", + "ClearButtonText": "Очистити", + "HeaderText": "Моніторинг", + "LightTitle": "Індикатор" + }, + "BootstrapBlazor.Components.DateTimePicker": { + "DatePlaceHolder": "Виберіть дату", + "TimePlaceHolder": "Виберіть час", + "DateTimePlaceHolderText": "Будь ласка, виберіть ...", + "DatePlaceHolderText": "Будь ласка, виберіть ...", + "TimeFormat": "hh\\:mm\\:ss", + "DateFormat": "d.M.yyyy", + "DateTimeFormat": "d.M.yyyy HH\\:mm\\:ss", + "AiraPrevYearLabel": "Попередній рік", + "AiraNextYearLabel": "Наступний рік", + "AiraPrevMonthLabel": "Попередній місяць", + "AiraNextMonthLabel": "Наступний місяць", + "ClearButtonText": "Очистити", + "NowButtonText": "Зараз", + "ConfirmButtonText": "Ок", + "CancelButtonText": "Скасувати", + "YearText": "{0}", + "MonthText": "{0}", + "YearPeriodText": "{0} р - {1} р", + "MonthLists": "Січень, Лютий, Березень, Квітень, Травень, Червень, Липень, Серпень, Вересень, Жовтень, Листопад, Грудень", + "Months": "Січень,Лютий,Березень,Квітень,Травень,Червень,Липень,Серпень,Вересень,Жовтень,Листопад,Грудень", + "WeekLists": "Нд,Пн,Вт,Ср,Чт,Пт,Сб", + "GenericTypeErroMessage": "Компонент DateTimePicker підтримує тільки DateTime або Nullable\u003CDateTime\u003E", + "Today": "Сьогодні", + "Yesterday": "Вчора", + "Week": "Тиждень тому" + }, + "BootstrapBlazor.Components.DateTimeRange": { + "SeparateText": "До", + "StartPlaceHolderText": "Дата початку", + "EndPlaceHolderText": "Дата завершення", + "ClearButtonText": "Очистити", + "TodayButtonText": "Сьогодні", + "ConfirmButtonText": "Ок", + "DateTimeFormat": "d.M.yyyy hh\\:mm\\:ss tt", + "DateFormat": "d.M.yyyy", + "Last7Days": "Останні 7 днів", + "Last30Days": "Останні 30 днів", + "ThisMonth": "Цей місяць", + "LastMonth": "Минулий місяць" + }, + "BootstrapBlazor.Components.Toggle": { + "OffText": "Згорнути", + "OnText": "Розширювати" + }, + "BootstrapBlazor.Components.Timer": { + "CancelText": "Скасувати", + "PauseText": "Пауза", + "ResumeText": "Продовжити", + "StarText": "Таймер" + }, + "BootstrapBlazor.Components.Transfer": { + "LeftPanelText": "Усі", + "MaxErrorMessage": "Можна вибрати до {0} елементів", + "MinErrorMessage": "Будь ласка, виберіть щонайменше {0} елементів", + "RightPanelText": "Обраний" + }, + "BootstrapBlazor.Components.BootstrapInputNumber": { + "ParsingErrorMessage": "Поле {0} має бути числом." + }, + "BootstrapBlazor.Components.ResultDialogOption": { + "ButtonYesText": "Так", + "ButtonNoText": "Ні", + "ButtonCloseText": "Зачинити" + }, + "BootstrapBlazor.Components.TransferPanel": { + "SearchPlaceHolderString": "Будь ласка, введіть ...", + "Text": "Список" + }, + "BootstrapBlazor.Components.DropdownList": { + "PlaceHolder": "Будь ласка, виберіть ..." + }, + "BootstrapBlazor.Components.EditDialog": { + "CloseButtonText": "Закрыть", + "SaveButtonText": "Сохранить" + }, + "BootstrapBlazor.Components.Editor": { + "PlaceHolder": "Натисніть, щоб редагувати" + }, + "BootstrapBlazor.Components.EditorForm": { + "ModelInvalidOperationExceptionMessage": "ValidateForm MODEL не збігається з {0} MODEL", + "PlaceHolderText": "Будь ласка, введіть ..." + }, + "BootstrapBlazor.Components.Empty": { + "Text": "Немає даних" + }, + "BootstrapBlazor.Components.EqualToValidator": { + "ErrorMessage": "Будь ласка, введіть те саме значення ще раз" + }, + "BootstrapBlazor.Components.ErrorLogger": { + "ToastTitle": "Помилка застосунку" + }, + "BootstrapBlazor.Components.FilterLogicItem": { + "And": "І", + "Or": "Або" + }, + "BootstrapBlazor.Components.GoTop": { + "TooltipText": "Нагору" + }, + "BootstrapBlazor.Components.Handwritten": { + "ClearButtonText": "Очистити", + "SaveButtonText": "Зберегти" + }, + "BootstrapBlazor.Components.InsertRowMode": { + "First": "Перший", + "Last": "Останній" + }, + "BootstrapBlazor.Components.IconDialog": { + "ButtonText": "Копировать", + "CopiedTooltipText": "Скопированы", + "DialogHeaderText": "Выбранный значок", + "LabelFullText": "Html", + "LabelText": "Значок" + }, + "BootstrapBlazor.Components.Layout": { + "TooltipText": "Клікніть, щоб розгорнути/згорнути бокову панель" + }, + "BootstrapBlazor.Components.Logout": { + "PrefixDisplayNameText": "Вітаємо", + "PrefixUserNameText": "Обліковий запис:" + }, + "BootstrapBlazor.Components.LogoutLink": { + "Text": "Вийти" + }, + "BootstrapBlazor.Components.Menu": { + "InvalidOperationExceptionMessage": "Компонент бокового меню не можна використовувати окремо. Будь ласка, використовуйте компонент Menu, щоб встановити IsVertical = true" + }, + "BootstrapBlazor.Components.ModalDialog": { + "CloseButtonText": "Закрити", + "SaveButtonText": "Зберегти", + "PrintButtonText": "Друк", + "ExportPdfButtonText": "Експорт у Pdf" + }, + "BootstrapBlazor.Components.MultiSelect": { + "PlaceHolder": "Виберіть елементи ...", + "SelectAllText": "Усі", + "ReverseSelectText": "Інвертувати", + "ClearText": "Очистити", + "MinErrorMessage": "Виберіть щонайменше {0} елементів", + "MaxErrorMessage": "Максимум {0} елементів можна вибрати", + "NoSearchDataText": "Немає результатів" + }, + "BootstrapBlazor.Components.Pagination": { + "GotoNavigatorLabelText": "Перейти до" + }, + "BootstrapBlazor.Components.NullableBoolItemsAttribute": { + "FalseValueDisplayText": "Помилковий", + "NullValueDisplayText": "Вибрати...", + "TrueValueDisplayText": "Істинний" + }, + "BootstrapBlazor.Components.PopConfirmButton": { + "CloseButtonText": "Скасувати", + "ConfirmButtonText": "Ок", + "Content": "Ви впевнені, що хочете виконати цю операцію?" + }, + "BootstrapBlazor.Components.PrintButton": { + "Text": "Друк" + }, + "BootstrapBlazor.Components.QueryBuilder": { + "And": "і", + "Contains": "Містить", + "Equal": "Дорівнює", + "GreaterThan": "Більше, ніж", + "GreaterThanOrEqual": "БільшеНіжАбоДорівнює", + "GroupText": "Група", + "ItemText": "Пункт", + "LessThan": "МеньшеНіж", + "LessThanOrEqual": "МеньшеНіжАбоДорівнює", + "NotContains": "Не містить", + "NotEqual": "Не дорівнює", + "Or": "або" + }, + "BootstrapBlazor.Components.Repeater": { + "EmptyText": "Немає даних" + }, + "BootstrapBlazor.Components.Search": { + "SearchButtonText": "Пошук", + "NoDataTip": "Записи не знайдено" + }, + "BootstrapBlazor.Components.SearchDialog": { + "QueryButtonText": "Запит", + "ResetButtonText": "Скинути" + }, + "BootstrapBlazor.Components.Select": { + "PlaceHolder": "Будь ласка, виберіть ...", + "NoSearchDataText": "Немає результатів" + }, + "BootstrapBlazor.Components.SelectTree": { + "PlaceHolder": "Будь ласка, виберіть ..." + }, + "BootstrapBlazor.Components.Tree": { + "NotSetOnTreeExpandErrorMessage": "не заданий параметр OnExpandNodeAsync" + }, + "BootstrapBlazor.Components.StringLengthValidator": { + "ErrorMessage": "Будь ласка, введіть значення менше або дорівнює {{0}}" + }, + "BootstrapBlazor.Components.SweetAlert": { + "CloseButtonText": "Закрити", + "CancelButtonText": "Скасувати", + "ConfirmButtonText": "Підтвердити" + }, + "BootstrapBlazor.Components.Switch": { + "OnInnerText": "ВІДКЛ", + "OffInnerText": "ВКЛ" + }, + "BootstrapBlazor.Components.SwitchButton": { + "OffText": "ВІДКЛ", + "OnText": "ВКЛ" + }, + "BootstrapBlazor.Components.Tab": { + "CloseCurrentTabText": "Закрити", + "CloseOtherTabsText": "Закрити інші", + "CloseAllTabsText": "Закрити всі", + "NotFoundTabText": "Не знайдено", + "RefreshToolbarTooltipText": "Оновити", + "FullscreenToolbarTooltipText": "На весь екран", + "PrevTabNavLinkTooltipText": "Попередня вкладка", + "NextTabNavLinkTooltipText": "Наступна вкладка", + "CloseTabNavLinkTooltipText": "Закрити", + "ContextRefresh": "Оновити", + "ContextClose": "Закрити", + "ContextCloseOther": "Закрити інші вкладки", + "ContextCloseAll": "Закрити всі вкладки", + "ContextFullScreen": "Повний екран" + }, + "BootstrapBlazor.Components.Table": { + "AddButtonText": "Додати", + "EditButtonText": "Редагувати", + "UpdateButtonText": "Оновити", + "DeleteButtonText": "Видалити", + "CancelButtonText": "Скасувати", + "SaveButtonText": "Зберегти", + "CloseButtonText": "Закрити", + "CancelDeleteButtonText": "Скасувати", + "ConfirmDeleteButtonText": "Видалити", + "ConfirmDeleteContentText": "Ви впевнені, що хочете ВИДАЛИТИ всі вибрані рядки?", + "RefreshButtonText": "Оновити", + "CardViewButtonText": "Перегляд", + "ColumnButtonTitleText": "Показати/Приховати стовпці", + "ColumnButtonText": "Стовпці", + "ExportButtonText": "Експорт", + "SearchPlaceholderText": "Пошук", + "SearchButtonText": "Пошук", + "ResetSearchButtonText": "Скинути", + "AdvanceButtonText": "Розширений пошук", + "AdvancedSortModalTitle": "Сортування", + "AdvancedSortButtonText": "Розширене сортування", + "CheckboxDisplayText": "Усі", + "EditModalTitle": "Редагувати", + "AddModalTitle": "Додати", + "LineNoText": "№", + "ColumnButtonTemplateHeaderText": "Дії", + "SearchTooltip": "Введіть будь-який рядок для глобального пошуку", + "SearchModalTitle": "Пошук", + "AddButtonToastTitle": "Додати дані", + "AddButtonToastContent": "Не вдалося додати дані. Будь ласка, реалізуйте метод OnAddAsync", + "EditButtonToastTitle": "Редагувати дані", + "EditButtonToastNotSelectContent": "Не вдалося зберегти. Будь ласка, реалізуйте метод OnSaveAsync", + "EditButtonToastReadonlyContent": "Вибрані дані неможливо редагувати", + "EditButtonToastMoreSelectContent": "Можна редагувати лише один рядок", + "EditButtonToastNoSaveMethodContent": "Неможливо редагувати. Будь ласка, реалізуйте метод OnSaveAsync", + "SaveButtonToastTitle": "Зберегти дані", + "SaveButtonToastContent": "Не вдалося зберегти дані. Будь ласка, реалізуйте метод OnSaveAsync", + "SaveButtonToastResultContent": "Дані збережено {0}, автоматичне закриття через {1}с", + "SuccessText": "Успішно", + "FailText": "Помилка", + "DeleteButtonToastTitle": "Видалити дані", + "DeleteButtonToastContent": "Будь ласка, виберіть рядки для видалення, автоматичне закриття через {0}с", + "DeleteButtonToastResultContent": "Дані видалено {0}, автоматичне закриття через {1}с", + "DeleteButtonToastCanNotDeleteContent": "Серед вибраних є дані, які неможливо видалити, автоматичне закриття через {0}с", + "DataServiceInvalidOperationText": "Неможливо надати значення для властивості 'DataService' у типі 'BootstrapBlazor.Components.Table`1[[{0}]]'. Немає зареєстрованого сервісу типу 'BootstrapBlazor.Components.IDataService`1[{0}]'.", + "NotSetOnTreeExpandErrorMessage": "не встановлено параметр OnTreeExpand", + "UnsetText": "Зрост.", + "SortAscText": "Спад.", + "SortDescText": "Не встановлено", + "EmptyText": "Немає даних", + "ExportToastTitle": "Експорт", + "ExportToastContent": "Експортовано дані {0}, автоматичне закриття через {1}с", + "ExportToastInProgressContent": "Експортування даних, зачекайте, автоматичне закриття через {0}с", + "ExportCsvDropdownItemText": "MS-Csv", + "ExportExcelDropdownItemText": "MS-Excel", + "ExportPdfDropdownItemText": "Pdf", + "PageInfoText": "{0} - {1} Всього {2}", + "PageItemsText": "{0}/стор.", + "CopyColumnTooltipText": "Скопіювати дані стовпця у буфер", + "CopyColumnCopiedTooltipText": "Скопійовано!", + "ColumnWidthTooltipPrefix": "ширина: ", + "ColumnToolboxTitle": "Інструменти", + "AlignLeftText": "Ліворуч", + "AlignLeftTooltipText": "Клікніть, щоб вирівняти текст у цьому стовпці ліворуч", + "AlignCenterText": "По центру", + "AlignCenterTooltipText": "Клікніть, щоб вирівняти текст у цьому стовпці по центру", + "AlignRightText": "Праворуч", + "AlignRightTooltipText": "Клікніть, щоб вирівняти текст у цьому стовпці праворуч" + }, + "BootstrapBlazor.Components.TableAdvancedSortDialog": { + "AscText": "За зростанням", + "DescText": "За спаданням" + }, + "BootstrapBlazor.Components.TableFilter": { + "BoolFilter.AllText": "Усі", + "BoolFilter.FalseText": "Хиба", + "BoolFilter.TrueText": "Істина", + "ClearButtonText": "Очистити", + "Contains": "Містить", + "EnumFilter.AllText": "Усі", + "Equal": "Рівний", + "FilterButtonText": "Фільтр", + "GreaterThan": "Більше, ніж", + "GreaterThanOrEqual": "БільшеНіжАбоДорівнює", + "LessThan": "МеншеНіж", + "LessThanOrEqual": "МеншеНіжАбоДорівнює", + "NotContains": "Не містить", + "NotEqual": "Не дорівнює", + "NotSupportedMessage": "Непідтримуваний тип фільтра, будь ласка, налаштуйте фільтр за допомогою FilterTemplate" + }, + "BootstrapBlazor.Components.SignaturePad": { + "ChangeColorBtnTitle": "Змінити колір", + "ClearBtnTitle": "Очистити", + "CloseBtnTitle": "Закрити", + "SaveBase64BtnTitle": "Добре", + "SaveJPGBtnTitle": "JPG", + "SavePNGBtnTitle": "PNG", + "SaveSVGBtnTitle": "SVG", + "SignAboveLabel": "Підпис", + "SignatureAlertText": "Будь ласка, спочатку поставте підпис", + "UndoBtnTitle": "Скасувати" + }, + "BootstrapBlazor.Components.Splitting": { + "Text": "Завантаження..." + }, + "BootstrapBlazor.Components.UploadBase": { + "BrowserButtonText": "Огляд", + "DeleteButtonText": "Видалити", + "FileExtensions": "Файл має мати одне з таких розширень: {0}", + "FileSizeValidation": "Розмір файлу не повинен перевищувати {0}" + } +} diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index a11bab70aa0..c66fc2b2b96 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@  - 9.10.0-beta01 + 9.10.0