mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-12-05 05:29:47 +08:00
!2259 doc(#I4OBAA): add doc for ErrorLogger inside Layout
* doc: 增加 Layout 组件配合使用说明 * doc: 更新资源文件 * doc: 格式化文档
This commit is contained in:
parent
f97b7b2e30
commit
d23c047a00
@ -424,18 +424,19 @@
|
||||
"Introduce": "Added component <code>ErrorLogger</code> Through this component, global logs and exceptions can be output uniformly; currently, the <code>Blazor</code> framework does not provide a <code>MVC</code> like < b>Global exception</b> The overall solution, for the time being, you need to use <code>try/catch</code> in the code block for exception capture",
|
||||
"H1": "Instructions",
|
||||
"Step1": "1. Add <code>AddLogging</code> to the <code>Startup</code> file to enable the <code>net core</code> system log function",
|
||||
"Step1Introduce": "使用 <code>AddFileLogger</code> 需要引用 <b>Longbow.Logging</b> 组件包",
|
||||
"Step1Introduce": "Use <code>AddFileLogger</code> need to reference <b>Longbow.Logging</b> component package",
|
||||
"Step2": "2. Use <code>BlazorLogger</code> to wrap the content, such as: <code>Body</code> in <code>MainLayout</code>",
|
||||
"Step3": "3. Use cascading parameters in the code to get examples",
|
||||
"Step4": "4. Console or <b>IIS</b> output visible log information",
|
||||
"Step5": "5. 控制是否显示错误明细信息",
|
||||
"Step5Intro": "通过配置文件 <code>appsettings.json</code>,开发环境下为 <code>appsettings.Development.json</code>,未设置时默认为 <code>false</code> 不显示,默认行为仅做弹窗提示防止敏感信息暴露",
|
||||
"Step5": "5. Controls whether error details are displayed",
|
||||
"Step5Intro": "Through the configuration file <code>appsettings.json</code>, which is <code>appsettings.Development.json</code> in the development environment, if not set, it defaults to <code>false</code> 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 <code>try/catch</code> is used to capture the exception, the error message is displayed in the console below",
|
||||
"ButtonText": "test",
|
||||
"Block2Title": "自定义错误处理",
|
||||
"Block2Intro": "通过设置 <code>OnErrorHandleAsync</code> 回调方法,设置自定义异常处理逻辑"
|
||||
"Block2Title": "OnErrorHandleAsync",
|
||||
"Block2Intro": "Set custom exception handling logic by setting <code>OnErrorHandleAsync </code> callback method",
|
||||
"Tips": "Both the <code>Layout</code> component and the <code>Tab</code> component have built-in <code>ErrorLogger</code> components. Please do not add them in the above two components. The following is the simplified example code"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.Splits": {
|
||||
"Title": "Split",
|
||||
|
@ -435,7 +435,8 @@
|
||||
"ExceptionTestIntroduce": "本例代码中写了一个除以零的错误代码,并且未使用 <code>try/catch</code> 对异常进行捕获,系统并不会崩溃导致不可用,<ul class='ul-demo'><li><code>Debug</code> 模式下会显示错误的 <b>描述信息</b> 与 <b>堆栈信息</b></li><li><code>Release</code> 模式下默认使用 <code>Toast</code> 进行弹窗提示</li></ul><div>可通过设置 <code>ErrorContent</code> 对 <b>异常信息</b> 进行自定义布局显示</div>",
|
||||
"ButtonText": "测试",
|
||||
"Block2Title": "自定义错误处理",
|
||||
"Block2Intro": "通过设置 <code>OnErrorHandleAsync</code> 回调方法,设置自定义异常处理逻辑"
|
||||
"Block2Intro": "通过设置 <code>OnErrorHandleAsync</code> 回调方法,设置自定义异常处理逻辑",
|
||||
"Tips": "<code>Layout</code> 组件与 <code>Tab</code> 组件均已内置 <code>ErrorLogger</code> 组件请勿在上述两个组件内额外添加使用,下面是精简后的示例代码"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.Splits": {
|
||||
"Title": "Split 面板分割",
|
||||
|
@ -68,4 +68,16 @@
|
||||
</ErrorLogger>
|
||||
</DemoBlock>
|
||||
|
||||
<Tips class="mt-3">
|
||||
<p>
|
||||
@((MarkupString)Localizer["Tips"].Value)
|
||||
</p>
|
||||
</Tips>
|
||||
|
||||
<Pre><Layout OnErrorHandleAsync="OnErrorHandleAsync">
|
||||
<Main>
|
||||
@@Body
|
||||
</Main>
|
||||
</Layout></Pre>
|
||||
|
||||
<AttributeTable Items="@GetAttributes()" />
|
||||
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class Timelines
|
||||
{
|
||||
private readonly ConcurrentQueue<ConsoleMessageItem> _messages = new();
|
||||
|
||||
private readonly CancellationTokenSource _cancelTokenSource = new();
|
||||
|
||||
private readonly AutoResetEvent _locker = new(true);
|
||||
|
||||
private IEnumerable<ConsoleMessageItem> 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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class Timelines
|
||||
/// <returns></returns>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
private readonly ConcurrentQueue<ConsoleMessageItem> _messages = new();
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
private readonly CancellationTokenSource _cancelTokenSource = new();
|
||||
|
||||
private readonly AutoResetEvent _locker = new(true);
|
||||
|
||||
private IEnumerable<ConsoleMessageItem> 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() });
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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"])
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <param name="value"></param>
|
||||
|
||||
public Task OnStateChanged(IEnumerable<SelectedItem> values, SelectedItem value)
|
||||
{
|
||||
IsReverse = value.Text == Localizer["SelectedItem2"];
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<SelectedItem> Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<TimelineItem> 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);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<TimelineItem> 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")
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<TimelineItem> GetCustomerComponentTimelineItems() => new TimelineItem[]
|
||||
{
|
||||
new TimelineItem
|
||||
{
|
||||
Color = Color.Success,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<BootstrapBlazor.Components.Console>(new Dictionary<string, object?>
|
||||
{
|
||||
[nameof(BootstrapBlazor.Components.Console.Items)] = Messages
|
||||
}),
|
||||
Description = Localizer["Description1"]
|
||||
},
|
||||
new TimelineItem
|
||||
{
|
||||
Color = Color.Info,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<Counter>(),
|
||||
Description = Localizer["Description2"]
|
||||
},
|
||||
new TimelineItem
|
||||
{
|
||||
Color = Color.Warning,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<FetchData>(),
|
||||
Description = Localizer["Description3"]
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private readonly IEnumerable<TimelineItem> 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",
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获得属性方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
|
||||
{
|
||||
// TODO: 移动到数据库中
|
||||
new AttributeItem() {
|
||||
Name = "Items",
|
||||
Description = Localizer["Items"],
|
||||
Type = "IEnumerable<TimelineItem>",
|
||||
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"
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获得属性方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerable<AttributeItem> 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"])
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <param name="value"></param>
|
||||
|
||||
public Task OnStateChanged(IEnumerable<SelectedItem> values, SelectedItem value)
|
||||
{
|
||||
IsReverse = value.Text == Localizer["SelectedItem2"];
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<SelectedItem> Items { get; set; } = Enumerable.Empty<SelectedItem>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<TimelineItem> 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")
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<TimelineItem> 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")
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private IEnumerable<TimelineItem> GetCustomerComponentTimelineItems() => new TimelineItem[]
|
||||
{
|
||||
new TimelineItem
|
||||
{
|
||||
Color = Color.Success,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<BootstrapBlazor.Components.Console>(new Dictionary<string, object?>
|
||||
{
|
||||
[nameof(BootstrapBlazor.Components.Console.Items)] = Messages
|
||||
}),
|
||||
Description = Localizer["Description1"]
|
||||
},
|
||||
new TimelineItem
|
||||
{
|
||||
Color = Color.Info,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<Counter>(),
|
||||
Description = Localizer["Description2"]
|
||||
},
|
||||
new TimelineItem
|
||||
{
|
||||
Color = Color.Warning,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<FetchData>(),
|
||||
Description = Localizer["Description3"]
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private readonly IEnumerable<TimelineItem> 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",
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获得属性方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
|
||||
{
|
||||
// TODO: 移动到数据库中
|
||||
new AttributeItem() {
|
||||
Name = "Items",
|
||||
Description = Localizer["Items"],
|
||||
Type = "IEnumerable<TimelineItem>",
|
||||
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"
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获得属性方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerable<AttributeItem> 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 = " — "
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user