diff --git a/src/BootstrapBlazor.Shared/Locales/en.json b/src/BootstrapBlazor.Shared/Locales/en.json index aa2b144fb..22d8cb036 100644 --- a/src/BootstrapBlazor.Shared/Locales/en.json +++ b/src/BootstrapBlazor.Shared/Locales/en.json @@ -424,18 +424,19 @@ "Introduce": "Added component ErrorLogger Through this component, global logs and exceptions can be output uniformly; currently, the Blazor framework does not provide a MVC like < b>Global exception The overall solution, for the time being, you need to use try/catch in the code block for exception capture", "H1": "Instructions", "Step1": "1. Add AddLogging to the Startup file to enable the net core system log function", - "Step1Introduce": "使用 AddFileLogger 需要引用 Longbow.Logging 组件包", + "Step1Introduce": "Use AddFileLogger need to reference Longbow.Logging component package", "Step2": "2. Use BlazorLogger to wrap the content, such as: Body in MainLayout", "Step3": "3. Use cascading parameters in the code to get examples", "Step4": "4. Console or IIS output visible log information", - "Step5": "5. 控制是否显示错误明细信息", - "Step5Intro": "通过配置文件 appsettings.json,开发环境下为 appsettings.Development.json,未设置时默认为 false 不显示,默认行为仅做弹窗提示防止敏感信息暴露", + "Step5": "5. Controls whether error details are displayed", + "Step5Intro": "Through the configuration file appsettings.json, which is appsettings.Development.json in the development environment, if not set, it defaults to false and is not displayed. The default behavior is only a pop-up prompt to prevent the exposure of sensitive information", "Block1Title": "Test", "Block1Intro": "This function is to obtain the component instance through the cascade parameter and use its function", "ExceptionTestIntroduce": "In this example code, an error code that divides by zero is written. Because try/catch is used to capture the exception, the error message is displayed in the console below", "ButtonText": "test", - "Block2Title": "自定义错误处理", - "Block2Intro": "通过设置 OnErrorHandleAsync 回调方法,设置自定义异常处理逻辑" + "Block2Title": "OnErrorHandleAsync", + "Block2Intro": "Set custom exception handling logic by setting OnErrorHandleAsync callback method", + "Tips": "Both the Layout component and the Tab component have built-in ErrorLogger components. Please do not add them in the above two components. The following is the simplified example code" }, "BootstrapBlazor.Shared.Samples.Splits": { "Title": "Split", diff --git a/src/BootstrapBlazor.Shared/Locales/zh.json b/src/BootstrapBlazor.Shared/Locales/zh.json index fdf0f5b93..336df51d4 100644 --- a/src/BootstrapBlazor.Shared/Locales/zh.json +++ b/src/BootstrapBlazor.Shared/Locales/zh.json @@ -435,7 +435,8 @@ "ExceptionTestIntroduce": "本例代码中写了一个除以零的错误代码,并且未使用 try/catch 对异常进行捕获,系统并不会崩溃导致不可用,
可通过设置 ErrorContent异常信息 进行自定义布局显示
", "ButtonText": "测试", "Block2Title": "自定义错误处理", - "Block2Intro": "通过设置 OnErrorHandleAsync 回调方法,设置自定义异常处理逻辑" + "Block2Intro": "通过设置 OnErrorHandleAsync 回调方法,设置自定义异常处理逻辑", + "Tips": "Layout 组件与 Tab 组件均已内置 ErrorLogger 组件请勿在上述两个组件内额外添加使用,下面是精简后的示例代码" }, "BootstrapBlazor.Shared.Samples.Splits": { "Title": "Split 面板分割", diff --git a/src/BootstrapBlazor.Shared/Samples/GlobalException.razor b/src/BootstrapBlazor.Shared/Samples/GlobalException.razor index 68ef1447c..574364c65 100644 --- a/src/BootstrapBlazor.Shared/Samples/GlobalException.razor +++ b/src/BootstrapBlazor.Shared/Samples/GlobalException.razor @@ -68,4 +68,16 @@ + +

+ @((MarkupString)Localizer["Tips"].Value) +

+
+ +
<Layout OnErrorHandleAsync="OnErrorHandleAsync">
+    <Main>
+        @@Body
+    </Main>
+</Layout>
+ diff --git a/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs b/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs index 5e53954c5..86b31313d 100644 --- a/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs +++ b/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs @@ -8,271 +8,272 @@ using BootstrapBlazor.Shared.Components; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace BootstrapBlazor.Shared.Samples +namespace BootstrapBlazor.Shared.Samples; + +/// +/// +/// +public sealed partial class Timelines { + private readonly ConcurrentQueue _messages = new(); + + private readonly CancellationTokenSource _cancelTokenSource = new(); + + private readonly AutoResetEvent _locker = new(true); + + private IEnumerable Messages => _messages; + + private bool IsReverse { get; set; } + + private static Color GetColor() + { + var second = DateTime.Now.Second; + return (second % 3) switch + { + 1 => Color.Danger, + 2 => Color.Info, + _ => Color.None + }; + } + /// /// /// - public sealed partial class Timelines + /// + protected override async Task OnInitializedAsync() { - private readonly ConcurrentQueue _messages = new(); + await base.OnInitializedAsync(); - private readonly CancellationTokenSource _cancelTokenSource = new(); - - private readonly AutoResetEvent _locker = new(true); - - private IEnumerable Messages => _messages; - - private bool IsReverse { get; set; } - - private static Color GetColor() + var _ = Task.Run(async () => { - var second = DateTime.Now.Second; - return (second % 3) switch + do { - 1 => Color.Danger, - 2 => Color.Info, - _ => Color.None - }; - } + _locker.WaitOne(); + _messages.Enqueue(new ConsoleMessageItem { Message = $"{DateTimeOffset.Now}: Dispatch Message", Color = GetColor() }); - /// - /// - /// - /// - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - - var _ = Task.Run(async () => - { - do + if (_messages.Count > 8) { - _locker.WaitOne(); - _messages.Enqueue(new ConsoleMessageItem { Message = $"{DateTimeOffset.Now}: Dispatch Message", Color = GetColor() }); - - if (_messages.Count > 8) - { - _messages.TryDequeue(out var _); - } - await InvokeAsync(StateHasChanged); - _locker.Set(); - await Task.Delay(2000, _cancelTokenSource.Token); + _messages.TryDequeue(out var _); } - while (!_cancelTokenSource.IsCancellationRequested); - }); - - Items = new SelectedItem[] - { - new SelectedItem("1",Localizer["SelectedItem1"]){ Active=true }, - new SelectedItem("2",Localizer["SelectedItem2"]) - }; - } - - /// - /// - /// - /// - /// - - public Task OnStateChanged(IEnumerable values, SelectedItem value) - { - IsReverse = value.Text == Localizer["SelectedItem2"]; - StateHasChanged(); - return Task.CompletedTask; - } - - /// - /// - /// - private IEnumerable Items { get; set; } - - /// - /// - /// - private IEnumerable TimelineItems => new TimelineItem[] - { - new TimelineItem { - Content = Localizer["TimelineItemContent1"], - Description = DateTime.Now.ToString("yyyy-MM-dd") - }, - new TimelineItem{ - Content = Localizer["TimelineItemContent2"], - Description = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") - }, - new TimelineItem - { - Content = Localizer["TimelineItemContent3"], - Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd") + await InvokeAsync(StateHasChanged); + _locker.Set(); + await Task.Delay(2000, _cancelTokenSource.Token); } - }; + while (!_cancelTokenSource.IsCancellationRequested); + }); - /// - /// - /// - private IEnumerable CustomerTimelineItems => new TimelineItem[] + Items = new SelectedItem[] { - new TimelineItem - { - Content = Localizer["TimelineItemContent4"], - Description = DateTime.Now.ToString("yyyy-MM-dd") - }, - new TimelineItem - { - Color = Color.Success, - Content = Localizer["TimelineItemContent5"], - Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd") - }, - new TimelineItem - { - Color = Color.Danger, - Icon = "fa fa-fw fa-fa", - Content = Localizer["TimelineItemContent6"], - Description = DateTime.Now.AddDays(3).ToString("yyyy-MM-dd") - } - }; - - /// - /// - /// - private IEnumerable GetCustomerComponentTimelineItems() => new TimelineItem[] - { - new TimelineItem - { - Color = Color.Success, - Component = BootstrapDynamicComponent.CreateComponent(new Dictionary - { - [nameof(BootstrapBlazor.Components.Console.Items)] = Messages - }), - Description = Localizer["Description1"] - }, - new TimelineItem - { - Color = Color.Info, - Component = BootstrapDynamicComponent.CreateComponent(), - Description = Localizer["Description2"] - }, - new TimelineItem - { - Color = Color.Warning, - Component = BootstrapDynamicComponent.CreateComponent(), - Description = Localizer["Description3"] - } - }; - - /// - /// - /// - private readonly IEnumerable AlternateTimelineItems = new TimelineItem[] - { - new TimelineItem - { - Content = "Create a services site 2015-09-01", - }, - new TimelineItem - { - Color = Color.Success, - Content = "Solve initial network problems 2015-09-01", - }, - new TimelineItem - { - Color = Color.Danger, - Content = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.", - }, - new TimelineItem - { - Color = Color.Warning, - Content = "Network problems being solved 2015-09-01", - }, - new TimelineItem - { - Color = Color.Info, - Content = "Create a services site 2015-09-01", - } - }; - - /// - /// 获得属性方法 - /// - /// - private IEnumerable GetAttributes() => new AttributeItem[] - { - // TODO: 移动到数据库中 - new AttributeItem() { - Name = "Items", - Description = Localizer["Items"], - Type = "IEnumerable", - ValueList = "—", - DefaultValue = " — " - }, - new AttributeItem() { - Name = "IsReverse", - Description = Localizer["IsReverse"], - Type = "boolean", - ValueList = "true|false", - DefaultValue = "false" - }, - new AttributeItem() { - Name = "IsLeft", - Description = Localizer["IsLeft"], - Type = "boolean", - ValueList = "true|false", - DefaultValue = "false" - }, - new AttributeItem() { - Name = "IsAlternate", - Description = Localizer["IsAlternate"], - Type = "boolean", - ValueList = "true|false", - DefaultValue = "false" - }, - }; - - /// - /// 获得属性方法 - /// - /// - private IEnumerable GetTimelineItemAttributes() => new AttributeItem[] - { - // TODO: 移动到数据库中 - new AttributeItem() { - Name = nameof(TimelineItem.Color), - Description = Localizer["Color"], - Type = "Color", - ValueList = " — ", - DefaultValue = " — " - }, - new AttributeItem() { - Name = nameof(TimelineItem.Content), - Description = Localizer["Content"], - Type = "string", - ValueList = " — ", - DefaultValue = " — " - }, - new AttributeItem() { - Name = nameof(TimelineItem.Icon), - Description = Localizer["Icon"], - Type = "string", - ValueList = " — ", - DefaultValue = " — " - }, - new AttributeItem() { - Name = nameof(TimelineItem.Description), - Description = Localizer["Description"], - Type = "string", - ValueList = " — ", - DefaultValue = " — " - }, - new AttributeItem() { - Name = nameof(TimelineItem.Component), - Description = Localizer["Component"], - Type = nameof(BootstrapDynamicComponent), - ValueList = " — ", - DefaultValue = " — " - } + new SelectedItem("1", Localizer["SelectedItem1"]) { Active=true }, + new SelectedItem("2", Localizer["SelectedItem2"]) }; } + + /// + /// + /// + /// + /// + + public Task OnStateChanged(IEnumerable values, SelectedItem value) + { + IsReverse = value.Text == Localizer["SelectedItem2"]; + StateHasChanged(); + return Task.CompletedTask; + } + + /// + /// + /// + private IEnumerable Items { get; set; } = Enumerable.Empty(); + + /// + /// + /// + private IEnumerable TimelineItems => new TimelineItem[] + { + new TimelineItem + { + Content = Localizer["TimelineItemContent1"], + Description = DateTime.Now.ToString("yyyy-MM-dd") + }, + new TimelineItem + { + Content = Localizer["TimelineItemContent2"], + Description = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + }, + new TimelineItem + { + Content = Localizer["TimelineItemContent3"], + Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd") + } + }; + + /// + /// + /// + private IEnumerable CustomerTimelineItems => new TimelineItem[] + { + new TimelineItem + { + Content = Localizer["TimelineItemContent4"], + Description = DateTime.Now.ToString("yyyy-MM-dd") + }, + new TimelineItem + { + Color = Color.Success, + Content = Localizer["TimelineItemContent5"], + Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd") + }, + new TimelineItem + { + Color = Color.Danger, + Icon = "fa fa-fw fa-fa", + Content = Localizer["TimelineItemContent6"], + Description = DateTime.Now.AddDays(3).ToString("yyyy-MM-dd") + } + }; + + /// + /// + /// + private IEnumerable GetCustomerComponentTimelineItems() => new TimelineItem[] + { + new TimelineItem + { + Color = Color.Success, + Component = BootstrapDynamicComponent.CreateComponent(new Dictionary + { + [nameof(BootstrapBlazor.Components.Console.Items)] = Messages + }), + Description = Localizer["Description1"] + }, + new TimelineItem + { + Color = Color.Info, + Component = BootstrapDynamicComponent.CreateComponent(), + Description = Localizer["Description2"] + }, + new TimelineItem + { + Color = Color.Warning, + Component = BootstrapDynamicComponent.CreateComponent(), + Description = Localizer["Description3"] + } + }; + + /// + /// + /// + private readonly IEnumerable AlternateTimelineItems = new TimelineItem[] + { + new TimelineItem + { + Content = "Create a services site 2015-09-01", + }, + new TimelineItem + { + Color = Color.Success, + Content = "Solve initial network problems 2015-09-01", + }, + new TimelineItem + { + Color = Color.Danger, + Content = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.", + }, + new TimelineItem + { + Color = Color.Warning, + Content = "Network problems being solved 2015-09-01", + }, + new TimelineItem + { + Color = Color.Info, + Content = "Create a services site 2015-09-01", + } + }; + + /// + /// 获得属性方法 + /// + /// + private IEnumerable GetAttributes() => new AttributeItem[] + { + // TODO: 移动到数据库中 + new AttributeItem() { + Name = "Items", + Description = Localizer["Items"], + Type = "IEnumerable", + ValueList = "—", + DefaultValue = " — " + }, + new AttributeItem() { + Name = "IsReverse", + Description = Localizer["IsReverse"], + Type = "boolean", + ValueList = "true|false", + DefaultValue = "false" + }, + new AttributeItem() { + Name = "IsLeft", + Description = Localizer["IsLeft"], + Type = "boolean", + ValueList = "true|false", + DefaultValue = "false" + }, + new AttributeItem() { + Name = "IsAlternate", + Description = Localizer["IsAlternate"], + Type = "boolean", + ValueList = "true|false", + DefaultValue = "false" + } + }; + + /// + /// 获得属性方法 + /// + /// + private IEnumerable GetTimelineItemAttributes() => new AttributeItem[] + { + new AttributeItem() { + Name = nameof(TimelineItem.Color), + Description = Localizer["Color"], + Type = "Color", + ValueList = " — ", + DefaultValue = " — " + }, + new AttributeItem() { + Name = nameof(TimelineItem.Content), + Description = Localizer["Content"], + Type = "string", + ValueList = " — ", + DefaultValue = " — " + }, + new AttributeItem() { + Name = nameof(TimelineItem.Icon), + Description = Localizer["Icon"], + Type = "string", + ValueList = " — ", + DefaultValue = " — " + }, + new AttributeItem() { + Name = nameof(TimelineItem.Description), + Description = Localizer["Description"], + Type = "string", + ValueList = " — ", + DefaultValue = " — " + }, + new AttributeItem() { + Name = nameof(TimelineItem.Component), + Description = Localizer["Component"], + Type = nameof(BootstrapDynamicComponent), + ValueList = " — ", + DefaultValue = " — " + } + }; }