From cf0f68bbe508eeecbb4fbf3f77fe11f77b73c02d Mon Sep 17 00:00:00 2001 From: utilcore <8907060@qq.com> Date: Tue, 2 Apr 2024 09:04:47 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=96=B0=E5=A2=9E=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=99=A8=E7=BB=84=E4=BB=B6=20=20.=202.=20=E6=96=B0=E5=A2=9E=E9=A2=9C=E8=89=B2=E5=9D=97?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=20.=203.=20Razor?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E7=9B=91=E8=A7=86=E6=9C=8D=E5=8A=A1=20Util.U?= =?UTF-8?q?i.Razor.RazorWatchService=20=E6=94=B9=E8=BF=9B=E6=96=B0?= =?UTF-8?q?=E5=A2=9ERazor=E6=96=87=E4=BB=B6=E5=92=8C=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/version.props | 2 +- src/Util.Ui.Angular/Configs/AngularConst.cs | 16 + .../Components/Avatars/AvatarTagHelper.cs | 1 - .../Avatars/Renders/AvatarRender.cs | 1 - .../Components/Cards/Builders/CardBuilder.cs | 1 - .../Builders/ColorBlockBuilder.cs | 57 +++ .../Builders/ColorPickerBuilder.cs | 157 ++++++++ .../ColorPickers/ColorBlockTagHelper.cs | 49 +++ .../ColorPickers/ColorPickerTagHelper.cs | 132 +++++++ .../ColorPickers/Renders/ColorBlockRender.cs | 37 ++ .../ColorPickers/Renders/ColorPickerRender.cs | 39 ++ .../DatePickers/DatePickerTagHelper.cs | 1 - .../Inputs/TextareaCountTagHelper.cs | 1 - .../Lists/ListItemMetaTitleTagHelper.cs | 1 - .../Enums/ColorPickerFormat.cs | 22 ++ .../Enums/ColorPickerTrigger.cs | 17 + src/Util.Ui/01-Util.Ui.csproj | 1 + src/Util.Ui/Configs/UiConst.cs | 16 + .../Razor/Internal/RazorViewContainer.cs | 41 +- src/Util.Ui/Razor/RazorOptions.cs | 4 +- src/Util.Ui/Razor/RazorWatchService.cs | 163 ++++---- .../ColorPickers/ColorBlockTagHelperTest.cs | 118 ++++++ .../ColorPickerTagHelperTest.Expression.cs | 27 ++ .../ColorPickers/ColorPickerTagHelperTest.cs | 353 ++++++++++++++++++ .../Razor/RazorViewContainerTest.cs | 46 ++- 25 files changed, 1190 insertions(+), 113 deletions(-) create mode 100644 src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorBlockBuilder.cs create mode 100644 src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorPickerBuilder.cs create mode 100644 src/Util.Ui.NgZorro/Components/ColorPickers/ColorBlockTagHelper.cs create mode 100644 src/Util.Ui.NgZorro/Components/ColorPickers/ColorPickerTagHelper.cs create mode 100644 src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorBlockRender.cs create mode 100644 src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorPickerRender.cs create mode 100644 src/Util.Ui.NgZorro/Enums/ColorPickerFormat.cs create mode 100644 src/Util.Ui.NgZorro/Enums/ColorPickerTrigger.cs create mode 100644 test/Util.Ui.NgZorro.Tests/ColorPickers/ColorBlockTagHelperTest.cs create mode 100644 test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.Expression.cs create mode 100644 test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.cs diff --git a/build/version.props b/build/version.props index f1d53f884..e3c985d5b 100644 --- a/build/version.props +++ b/build/version.props @@ -2,7 +2,7 @@ 8 0 - 10 + 11 $(VersionMajor).$(VersionMinor).$(VersionPatch) diff --git a/src/Util.Ui.Angular/Configs/AngularConst.cs b/src/Util.Ui.Angular/Configs/AngularConst.cs index 06aa0a86b..289e6352c 100644 --- a/src/Util.Ui.Angular/Configs/AngularConst.cs +++ b/src/Util.Ui.Angular/Configs/AngularConst.cs @@ -53,6 +53,10 @@ public static class AngularConst { /// public const string BindAcl = "bind-acl"; /// + /// 触发器 + /// + public const string BindTrigger = "bind-trigger"; + /// /// 首页 /// public const string BindHome = "bind-home"; @@ -73,6 +77,10 @@ public static class AngularConst { /// public const string BindRecursiveBreadcrumb = "bind-recursive-breadcrumb"; /// + /// 禁用透明度 + /// + public const string BindDisabledAlpha = "bind-disabled-alpha"; + /// /// 定宽 /// public const string BindWide = "bind-wide"; @@ -81,6 +89,10 @@ public static class AngularConst { /// public const string BindFixed = "bind-fixed"; /// + /// 显示文本 + /// + public const string BindShowText = "bind-show-text"; + /// /// 行数 /// public const string BindLines = "bind-lines"; @@ -117,6 +129,10 @@ public static class AngularConst { /// public const string BindText = "bind-text"; /// + /// 默认值 + /// + public const string BindDefaultValue = "bind-default-value"; + /// /// 值 /// public const string BindValue = "bind-value"; diff --git a/src/Util.Ui.NgZorro/Components/Avatars/AvatarTagHelper.cs b/src/Util.Ui.NgZorro/Components/Avatars/AvatarTagHelper.cs index 8439a19c2..e5469ac01 100644 --- a/src/Util.Ui.NgZorro/Components/Avatars/AvatarTagHelper.cs +++ b/src/Util.Ui.NgZorro/Components/Avatars/AvatarTagHelper.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Razor.TagHelpers; using Util.Ui.Angular.TagHelpers; -using Util.Ui.Configs; using Util.Ui.NgZorro.Components.Avatars.Renders; using Util.Ui.NgZorro.Enums; using Util.Ui.Renders; diff --git a/src/Util.Ui.NgZorro/Components/Avatars/Renders/AvatarRender.cs b/src/Util.Ui.NgZorro/Components/Avatars/Renders/AvatarRender.cs index 42589c73b..bfe7aaf7b 100644 --- a/src/Util.Ui.NgZorro/Components/Avatars/Renders/AvatarRender.cs +++ b/src/Util.Ui.NgZorro/Components/Avatars/Renders/AvatarRender.cs @@ -1,5 +1,4 @@ using Util.Ui.Builders; -using Util.Ui.Configs; using Util.Ui.NgZorro.Components.Avatars.Builders; using Util.Ui.NgZorro.Components.Comments.Configs; using Util.Ui.Renders; diff --git a/src/Util.Ui.NgZorro/Components/Cards/Builders/CardBuilder.cs b/src/Util.Ui.NgZorro/Components/Cards/Builders/CardBuilder.cs index 95a87892b..99c26bee9 100644 --- a/src/Util.Ui.NgZorro/Components/Cards/Builders/CardBuilder.cs +++ b/src/Util.Ui.NgZorro/Components/Cards/Builders/CardBuilder.cs @@ -1,7 +1,6 @@ using Util.Ui.Angular.Builders; using Util.Ui.Angular.Configs; using Util.Ui.Angular.Extensions; -using Util.Ui.Configs; using Util.Ui.NgZorro.Configs; using Util.Ui.NgZorro.Enums; using Util.Ui.NgZorro.Extensions; diff --git a/src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorBlockBuilder.cs b/src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorBlockBuilder.cs new file mode 100644 index 000000000..7a9f31888 --- /dev/null +++ b/src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorBlockBuilder.cs @@ -0,0 +1,57 @@ +using Util.Ui.Angular.Builders; +using Util.Ui.Angular.Configs; +using Util.Ui.NgZorro.Enums; + +namespace Util.Ui.NgZorro.Components.ColorPickers.Builders; + +/// +/// 颜色块标签生成器 +/// +public class ColorBlockBuilder : AngularTagBuilder { + /// + /// 配置 + /// + private readonly Config _config; + + /// + /// 初始化颜色块标签生成器 + /// + /// 配置 + public ColorBlockBuilder( Config config ) : base( config, "nz-color-block" ) { + _config = config; + } + + /// + /// 配置颜色 + /// + public ColorBlockBuilder Color() { + AttributeIfNotEmpty( "nzColor", _config.GetValue( UiConst.Color ) ); + AttributeIfNotEmpty( "[nzColor]", _config.GetValue( AngularConst.BindColor ) ); + return this; + } + + /// + /// 配置控件尺寸 + /// + public ColorBlockBuilder Size() { + AttributeIfNotEmpty( "nzSize", _config.GetValue( UiConst.Size )?.Description() ); + AttributeIfNotEmpty( "[nzSize]", _config.GetValue( AngularConst.BindSize ) ); + return this; + } + + /// + /// 配置事件 + /// + public ColorBlockBuilder Events() { + AttributeIfNotEmpty( "(nzOnClick)", _config.GetValue( UiConst.OnClick ) ); + return this; + } + + /// + /// 配置 + /// + public override void Config() { + base.Config(); + Color().Size().Events(); + } +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorPickerBuilder.cs b/src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorPickerBuilder.cs new file mode 100644 index 000000000..7f28cb6d8 --- /dev/null +++ b/src/Util.Ui.NgZorro/Components/ColorPickers/Builders/ColorPickerBuilder.cs @@ -0,0 +1,157 @@ +using Util.Ui.Angular.Configs; +using Util.Ui.NgZorro.Components.Base; +using Util.Ui.NgZorro.Configs; +using Util.Ui.NgZorro.Enums; +using Util.Ui.NgZorro.Extensions; + +namespace Util.Ui.NgZorro.Components.ColorPickers.Builders; + +/// +/// 颜色选择标签生成器 +/// +public class ColorPickerBuilder : FormControlBuilderBase { + /// + /// 配置 + /// + private readonly Config _config; + + /// + /// 初始化颜色选择标签生成器 + /// + /// 配置 + public ColorPickerBuilder( Config config ) : base( config, "nz-color-picker" ) { + _config = config; + } + + /// + /// 配置标题 + /// + public ColorPickerBuilder Title() { + SetTitle( _config.GetValue( UiConst.Title ) ); + AttributeIfNotEmpty( "[nzTitle]", _config.GetValue( AngularConst.BindTitle ) ); + return this; + } + + /// + /// 设置表单标签文本 + /// + private void SetTitle( string value ) { + var options = NgZorroOptionsService.GetOptions(); + if ( options.EnableI18n ) { + this.AttributeByI18n( "[nzTitle]", value ); + return; + } + AttributeIfNotEmpty( "nzTitle", value ); + } + + /// + /// 配置颜色默认值 + /// + public ColorPickerBuilder DefaultValue() { + AttributeIfNotEmpty( "nzDefaultValue", _config.GetValue( UiConst.DefaultValue ) ); + AttributeIfNotEmpty( "[nzDefaultValue]", _config.GetValue( AngularConst.BindDefaultValue ) ); + return this; + } + + /// + /// 配置颜色值 + /// + public ColorPickerBuilder Value() { + AttributeIfNotEmpty( "nzValue", _config.GetValue( UiConst.Value ) ); + AttributeIfNotEmpty( "[nzValue]", _config.GetValue( AngularConst.BindValue ) ); + return this; + } + + /// + /// 配置显示颜色文本 + /// + public ColorPickerBuilder ShowText() { + AttributeIfNotEmpty( "[nzShowText]", _config.GetBoolValue( UiConst.ShowText ) ); + AttributeIfNotEmpty( "[nzShowText]", _config.GetValue( AngularConst.BindShowText ) ); + return this; + } + + /// + /// 配置控件尺寸 + /// + public ColorPickerBuilder Size() { + AttributeIfNotEmpty( "nzSize", _config.GetValue( UiConst.Size )?.Description() ); + AttributeIfNotEmpty( "[nzSize]", _config.GetValue( AngularConst.BindSize ) ); + return this; + } + + /// + /// 配置禁用 + /// + public ColorPickerBuilder Disabled() { + AttributeIfNotEmpty( "[nzDisabled]", _config.GetBoolValue( UiConst.Disabled ) ); + AttributeIfNotEmpty( "[nzDisabled]", _config.GetValue( AngularConst.BindDisabled ) ); + return this; + } + + /// + /// 配置禁用透明度 + /// + public ColorPickerBuilder DisabledAlpha() { + AttributeIfNotEmpty( "[nzDisabledAlpha]", _config.GetBoolValue( UiConst.DisabledAlpha ) ); + AttributeIfNotEmpty( "[nzDisabledAlpha]", _config.GetValue( AngularConst.BindDisabledAlpha ) ); + return this; + } + + /// + /// 配置触发模式 + /// + public ColorPickerBuilder Trigger() { + AttributeIfNotEmpty( "nzTrigger", _config.GetValue( UiConst.Trigger )?.Description() ); + AttributeIfNotEmpty( "[nzTrigger]", _config.GetValue( AngularConst.BindTrigger ) ); + return this; + } + + /// + /// 配置允许清除 + /// + public ColorPickerBuilder AllowClear() { + AttributeIfNotEmpty( "[nzAllowClear]", _config.GetBoolValue( UiConst.AllowClear ) ); + AttributeIfNotEmpty( "[nzAllowClear]", _config.GetValue( AngularConst.BindAllowClear ) ); + return this; + } + + /// + /// 配置颜色格式 + /// + public ColorPickerBuilder Format() { + AttributeIfNotEmpty( "nzFormat", _config.GetValue( UiConst.Format )?.Description() ); + AttributeIfNotEmpty( "[nzFormat]", _config.GetValue( AngularConst.BindFormat ) ); + return this; + } + + /// + /// 配置显示弹出窗口 + /// + public ColorPickerBuilder Open() { + AttributeIfNotEmpty( "[nzOpen]", _config.GetValue( UiConst.Open ) ); + return this; + } + + /// + /// 配置事件 + /// + public ColorPickerBuilder Events() { + AttributeIfNotEmpty( "(nzOnChange)", _config.GetValue( UiConst.OnChange ) ); + AttributeIfNotEmpty( "(nzOnClear)", _config.GetValue( UiConst.OnClear ) ); + AttributeIfNotEmpty( "(nzOnFormatChange)", _config.GetValue( UiConst.OnFormatChange ) ); + AttributeIfNotEmpty( "(nzOnOpenChange)", _config.GetValue( UiConst.OnOpenChange ) ); + return this; + } + + /// + /// 配置 + /// + public override void Config() { + base.ConfigBase( _config ); + ConfigForm().Name().DefaultValue().Value() + .Title().ShowText().Size().Disabled().DisabledAlpha() + .Trigger().AllowClear().Format().Open() + .Events(); + } +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Components/ColorPickers/ColorBlockTagHelper.cs b/src/Util.Ui.NgZorro/Components/ColorPickers/ColorBlockTagHelper.cs new file mode 100644 index 000000000..e59ab8865 --- /dev/null +++ b/src/Util.Ui.NgZorro/Components/ColorPickers/ColorBlockTagHelper.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Util.Ui.Angular.TagHelpers; +using Util.Ui.NgZorro.Components.ColorPickers.Renders; +using Util.Ui.NgZorro.Enums; +using Util.Ui.Renders; + +namespace Util.Ui.NgZorro.Components.ColorPickers; + +/// +/// 颜色块,生成的标签为<nz-color-block></nz-color-block> +/// +[HtmlTargetElement( "util-color-block" )] +public class ColorBlockTagHelper : AngularTagHelperBase { + /// + /// 配置 + /// + private Config _config; + /// + /// nzColor, 颜色值, 默认值: #1677ff + /// + public string Color { get; set; } + /// + /// [nzColor], 颜色值, 默认值: #1677ff + /// + public string BindColor { get; set; } + /// + /// nzSize,控件尺寸, 可选值: 'default' | 'small' | 'large' , 默认值: 'default' + /// + public InputSize Size { get; set; } + /// + /// [nzSize],控件尺寸, 可选值: 'default' | 'small' | 'large' , 默认值: 'default' + /// + public string BindSize { get; set; } + /// + /// (nzOnClick),点击事件 ,类型: EventEmitter<boolean> + /// + public string OnClick { get; set; } + + /// + protected override void ProcessBefore( TagHelperContext context, TagHelperOutput output ) { + _config = new Config( context, output ); + } + + /// + protected override IRender GetRender( TagHelperContext context, TagHelperOutput output, TagHelperContent content ) { + _config.Content = content; + return new ColorBlockRender( _config ); + } +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Components/ColorPickers/ColorPickerTagHelper.cs b/src/Util.Ui.NgZorro/Components/ColorPickers/ColorPickerTagHelper.cs new file mode 100644 index 000000000..7a74b3899 --- /dev/null +++ b/src/Util.Ui.NgZorro/Components/ColorPickers/ColorPickerTagHelper.cs @@ -0,0 +1,132 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Util.Ui.NgZorro.Components.Base; +using Util.Ui.NgZorro.Components.ColorPickers.Renders; +using Util.Ui.NgZorro.Components.Selects.Helpers; +using Util.Ui.NgZorro.Enums; +using Util.Ui.Renders; + +namespace Util.Ui.NgZorro.Components.ColorPickers; + +/// +/// 颜色选择器,生成的标签为<nz-color-picker></nz-color-picker> +/// +[HtmlTargetElement( "util-color-picker" )] +public class ColorPickerTagHelper : FormControlTagHelperBase { + /// + /// 配置 + /// + private Config _config; + /// + /// nzTitle,标题,支持i18n + /// + public string Title { get; set; } + /// + /// [nzTitle],标题,类型: string|TemplateRef<void> + /// + public string BindTitle { get; set; } + /// + /// nzDefaultValue, 颜色默认值, 类型: string|NzColor + /// + public string DefaultValue { get; set; } + /// + /// [nzDefaultValue], 颜色默认值, 类型: string|NzColor + /// + public string BindDefaultValue { get; set; } + /// + /// nzValue, 颜色值, 类型: string|NzColor + /// + public string Value { get; set; } + /// + /// [nzValue], 颜色值, 类型: string|NzColor + /// + public string BindValue { get; set; } + /// + /// [nzShowText],是否显示颜色文本,默认值: false + /// + public bool ShowText { get; set; } + /// + /// [nzShowText],是否显示颜色文本,默认值: false + /// + public string BindShowText { get; set; } + /// + /// nzSize,控件尺寸, 可选值: 'default' | 'small' | 'large' , 默认值: 'default' + /// + public InputSize Size { get; set; } + /// + /// [nzSize],控件尺寸, 可选值: 'default' | 'small' | 'large' , 默认值: 'default' + /// + public string BindSize { get; set; } + /// + /// [nzDisabled],是否禁用, 默认值: false + /// + public bool Disabled { get; set; } + /// + /// [nzDisabled],是否禁用, 默认值: false + /// + public string BindDisabled { get; set; } + /// + /// [nzDisabledAlpha],是否禁用透明度, 默认值: false + /// + public bool DisabledAlpha { get; set; } + /// + /// [nzDisabledAlpha],是否禁用透明度, 默认值: false + /// + public string BindDisabledAlpha { get; set; } + /// + /// nzTrigger,触发模式, 可选值: hover|click ,默认值: click + /// + public ColorPickerTrigger Trigger { get; set; } + /// + /// [nzTrigger],触发模式, 可选值: hover|click ,默认值: click + /// + public string BindTrigger { get; set; } + /// + /// [nzAllowClear], 是否允许清除选择的颜色, 默认值: false + /// + public bool AllowClear { get; set; } + /// + /// [nzAllowClear], 是否允许清除选择的颜色, 默认值: false + /// + public string BindAllowClear { get; set; } + /// + /// nzFormat,颜色格式, 可选值: rgb|hex|hsb ,默认值: hex + /// + public ColorPickerFormat Format { get; set; } + /// + /// [nzFormat],颜色格式, 可选值: rgb|hex|hsb ,默认值: hex + /// + public string BindFormat { get; set; } + /// + /// [nzOpen],是否显示弹出窗口 ,默认值: false + /// + public string Open { get; set; } + /// + /// (nzOnChange),颜色变化事件 ,类型: EventEmitter<{color: NzColor;format: string}> + /// + public string OnChange { get; set; } + /// + /// (nzOnClear),清除颜色事件 ,类型: EventEmitter<boolean> + /// + public string OnClear { get; set; } + /// + /// (nzOnFormatChange),颜色格式变化事件 ,类型: EventEmitter<'rgb'|'hex'|'hsb'> + /// + public string OnFormatChange { get; set; } + /// + /// (nzOnOpenChange),打开颜色面板事件 ,类型: EventEmitter<boolean> + /// + public string OnOpenChange { get; set; } + + /// + protected override void ProcessBefore( TagHelperContext context, TagHelperOutput output ) { + _config = new Config( context, output ); + var service = new SelectService( _config ); + service.Init(); + } + + /// + protected override IRender GetRender( TagHelperContext context, TagHelperOutput output, TagHelperContent content ) { + _config.Content = content; + return new ColorPickerRender( _config ); + } +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorBlockRender.cs b/src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorBlockRender.cs new file mode 100644 index 000000000..8f76b83a7 --- /dev/null +++ b/src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorBlockRender.cs @@ -0,0 +1,37 @@ +using Util.Ui.Builders; +using Util.Ui.NgZorro.Components.ColorPickers.Builders; +using Util.Ui.Renders; + +namespace Util.Ui.NgZorro.Components.ColorPickers.Renders; + +/// +/// 颜色块渲染器 +/// +public class ColorBlockRender : RenderBase { + /// + /// 配置 + /// + private readonly Config _config; + + /// + /// 初始化颜色块渲染器 + /// + /// 配置 + public ColorBlockRender( Config config ){ + _config = config; + } + + /// + /// 获取标签生成器 + /// + protected override TagBuilder GetTagBuilder() { + var builder = new ColorBlockBuilder( _config ); + builder.Config(); + return builder; + } + + /// + public override IHtmlContent Clone() { + return new ColorBlockRender( _config.Copy() ); + } +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorPickerRender.cs b/src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorPickerRender.cs new file mode 100644 index 000000000..ff0a2b57a --- /dev/null +++ b/src/Util.Ui.NgZorro/Components/ColorPickers/Renders/ColorPickerRender.cs @@ -0,0 +1,39 @@ +using Util.Ui.Builders; +using Util.Ui.Extensions; +using Util.Ui.NgZorro.Components.Base; +using Util.Ui.NgZorro.Components.ColorPickers.Builders; + +namespace Util.Ui.NgZorro.Components.ColorPickers.Renders; + +/// +/// 颜色选择渲染器 +/// +public class ColorPickerRender : FormControlRenderBase { + /// + /// 配置 + /// + private readonly Config _config; + + /// + /// 初始化颜色选择渲染器 + /// + /// 配置 + public ColorPickerRender( Config config ) : base( config ) { + _config = config; + } + + /// + /// 添加表单控件 + /// + protected override void AppendControl( TagBuilder formControlBuilder ) { + var builder = new ColorPickerBuilder( _config ); + builder.Config(); + _config.Content.AppendTo( builder ); + formControlBuilder.AppendContent( builder ); + } + + /// + public override IHtmlContent Clone() { + return new ColorPickerRender( _config.Copy() ); + } +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Components/DatePickers/DatePickerTagHelper.cs b/src/Util.Ui.NgZorro/Components/DatePickers/DatePickerTagHelper.cs index b154ed83d..eb5b78dcf 100644 --- a/src/Util.Ui.NgZorro/Components/DatePickers/DatePickerTagHelper.cs +++ b/src/Util.Ui.NgZorro/Components/DatePickers/DatePickerTagHelper.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Razor.TagHelpers; -using Util.Ui.Configs; using Util.Ui.NgZorro.Components.Base; using Util.Ui.NgZorro.Components.DatePickers.Renders; using Util.Ui.NgZorro.Components.Inputs.Helpers; diff --git a/src/Util.Ui.NgZorro/Components/Inputs/TextareaCountTagHelper.cs b/src/Util.Ui.NgZorro/Components/Inputs/TextareaCountTagHelper.cs index f339eb1b2..ad3423a39 100644 --- a/src/Util.Ui.NgZorro/Components/Inputs/TextareaCountTagHelper.cs +++ b/src/Util.Ui.NgZorro/Components/Inputs/TextareaCountTagHelper.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Razor.TagHelpers; using Util.Ui.Angular.TagHelpers; -using Util.Ui.Configs; using Util.Ui.NgZorro.Components.Inputs.Renders; using Util.Ui.Renders; diff --git a/src/Util.Ui.NgZorro/Components/Lists/ListItemMetaTitleTagHelper.cs b/src/Util.Ui.NgZorro/Components/Lists/ListItemMetaTitleTagHelper.cs index aeec2f198..6389c108e 100644 --- a/src/Util.Ui.NgZorro/Components/Lists/ListItemMetaTitleTagHelper.cs +++ b/src/Util.Ui.NgZorro/Components/Lists/ListItemMetaTitleTagHelper.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Razor.TagHelpers; using Util.Ui.Angular.TagHelpers; -using Util.Ui.Configs; using Util.Ui.NgZorro.Components.Lists.Renders; using Util.Ui.Renders; diff --git a/src/Util.Ui.NgZorro/Enums/ColorPickerFormat.cs b/src/Util.Ui.NgZorro/Enums/ColorPickerFormat.cs new file mode 100644 index 000000000..42155afb6 --- /dev/null +++ b/src/Util.Ui.NgZorro/Enums/ColorPickerFormat.cs @@ -0,0 +1,22 @@ +namespace Util.Ui.NgZorro.Enums; + +/// +/// 颜色选择器格式 +/// +public enum ColorPickerFormat { + /// + /// rgb + /// + [Description( "rgb" )] + Rgb, + /// + /// hex + /// + [Description( "hex" )] + Hex, + /// + /// hsb + /// + [Description( "hsb" )] + Hsb +} \ No newline at end of file diff --git a/src/Util.Ui.NgZorro/Enums/ColorPickerTrigger.cs b/src/Util.Ui.NgZorro/Enums/ColorPickerTrigger.cs new file mode 100644 index 000000000..ad45141d8 --- /dev/null +++ b/src/Util.Ui.NgZorro/Enums/ColorPickerTrigger.cs @@ -0,0 +1,17 @@ +namespace Util.Ui.NgZorro.Enums; + +/// +/// 颜色选择器触发行为 +/// +public enum ColorPickerTrigger { + /// + /// 点击触发 + /// + [Description( "click" )] + Click, + /// + /// 移入触发 + /// + [Description( "hover" )] + Hover +} \ No newline at end of file diff --git a/src/Util.Ui/01-Util.Ui.csproj b/src/Util.Ui/01-Util.Ui.csproj index a4130693c..2811881b0 100644 --- a/src/Util.Ui/01-Util.Ui.csproj +++ b/src/Util.Ui/01-Util.Ui.csproj @@ -30,6 +30,7 @@ + diff --git a/src/Util.Ui/Configs/UiConst.cs b/src/Util.Ui/Configs/UiConst.cs index 3bd528b27..b1e21abf7 100644 --- a/src/Util.Ui/Configs/UiConst.cs +++ b/src/Util.Ui/Configs/UiConst.cs @@ -41,6 +41,18 @@ public static class UiConst { /// public const string EnableFixedColumn = "enable-fixed-column"; /// + /// 格式变化事件 + /// + public const string OnFormatChange = "on-format-change"; + /// + /// 显示文本 + /// + public const string ShowText = "show-text"; + /// + /// 默认值 + /// + public const string DefaultValue = "default-value"; + /// /// 起始日期 /// public const string BeginDate = "begin-date"; @@ -401,6 +413,10 @@ public static class UiConst { /// public const string Disabled = "disabled"; /// + /// 禁用透明度 + /// + public const string DisabledAlpha = "disabled-alpha"; + /// /// 禁用日期 /// public const string DisabledDate = "disabled-date"; diff --git a/src/Util.Ui/Razor/Internal/RazorViewContainer.cs b/src/Util.Ui/Razor/Internal/RazorViewContainer.cs index 032eaa1e1..a2bea9b00 100644 --- a/src/Util.Ui/Razor/Internal/RazorViewContainer.cs +++ b/src/Util.Ui/Razor/Internal/RazorViewContainer.cs @@ -79,34 +79,40 @@ public void AddView( RazorView view ) { /// /// 初始化视图容器 /// - /// 视图内容集合 - public void Init( IDictionary viewContents ) { - if ( viewContents == null ) + /// 视图路径列表 + public void Init( List paths ) { + if ( paths == null ) return; - foreach ( var viewContent in viewContents ) - CreateView( viewContent.Key, viewContent.Value ); + foreach ( var path in paths ) + AddView( path ); } /// - /// 创建视图 + /// 添加视图 /// /// 视图路径 - /// 视图文件内容 - public RazorView CreateView( string path, string content ) { + public RazorView AddView( string path ) { if ( path.IsEmpty() ) return null; + var content = GetContent( path ); if ( content.IsEmpty() ) return null; - RazorView result = FindOrCreateView( path, content ); + RazorView view = FindOrCreateView( path, content ); var partViewPaths = _partViewPathResolver.Resolve( path, content ) ?? []; foreach ( var partViewPath in partViewPaths ) { - var partViewContent = GetContent( partViewPath ); - var partView = CreateView( partViewPath, partViewContent ); + var partView = AddView( partViewPath ); if ( partView != null ) - result.AddPartView( (PartView)partView ); + view.AddPartView( (PartView)partView ); } - AddView( result ); - return result; + AddView( view ); + return view; + } + + /// + /// 获取Razor文件内容 + /// + protected string GetContent( string relativePath ) { + return _contentResolver.Resolve( relativePath ); } /// @@ -127,13 +133,6 @@ protected bool IsPartView( string content ) { return content.SafeString().StartsWith( "@page" ) == false; } - /// - /// 获取Razor文件内容 - /// - protected string GetContent( string relativePath ) { - return _contentResolver.Resolve( relativePath ); - } - /// /// 获取关联的视图路径列表,如果是主视图,获取它本身的路径,如果是分部视图,获取引用它的主视图路径集合 /// diff --git a/src/Util.Ui/Razor/RazorOptions.cs b/src/Util.Ui/Razor/RazorOptions.cs index c8e86f41b..453133049 100644 --- a/src/Util.Ui/Razor/RazorOptions.cs +++ b/src/Util.Ui/Razor/RazorOptions.cs @@ -41,9 +41,9 @@ public class RazorOptions { /// public int StartInitDelay { get; set; } = 1000; /// - /// 修改Razor页面生成Html文件的延迟时间,单位: 毫秒, 默认值:100 ,注意: 延迟太短可能导致生成异常 + /// 修改Razor页面生成Html文件的延迟时间,单位: 毫秒, 默认值:300 ,注意: 延迟太短可能导致生成异常 /// - public int HtmlRenderDelayOnRazorChange { get; set; } = 100; + public int HtmlRenderDelayOnRazorChange { get; set; } = 300; /// /// 启动Razor监视服务时是否预热,默认值: true /// diff --git a/src/Util.Ui/Razor/RazorWatchService.cs b/src/Util.Ui/Razor/RazorWatchService.cs index d77a23b58..9a0b72e8b 100644 --- a/src/Util.Ui/Razor/RazorWatchService.cs +++ b/src/Util.Ui/Razor/RazorWatchService.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.Configuration; +using System.Reactive.Linq; +using System.Reactive.Subjects; +using Microsoft.Extensions.Configuration; using Util.Helpers; using Util.Ui.Razor.Internal; @@ -19,11 +21,7 @@ public class RazorWatchService : IRazorWatchService { /// /// Razor视图容器 /// - private RazorViewContainer _container; - /// - /// 分部视图路径解析器 - /// - private readonly IPartViewPathResolver _resolver; + private readonly RazorViewContainer _container; /// /// Http客户端 /// @@ -40,18 +38,79 @@ public class RazorWatchService : IRazorWatchService { /// 是否生成缺失的html /// private bool _isGenerateMissingHtml; + /// + /// 新增视图事件 + /// + private readonly SequentialSimpleAsyncSubject _addViewSubject; /// /// 初始化Razor页面监听服务 /// public RazorWatchService( IServiceProvider serviceProvider, IPartViewPathResolver resolver, HttpClient client, - IActionDescriptorCollectionProvider provider, IOptions options ) { + IActionDescriptorCollectionProvider provider, IOptions options ) { Ioc.SetServiceProviderAction( () => serviceProvider ); _watcher = new FileWatcher(); - _resolver = resolver; _client = client; _provider = provider; _options = options.Value; + _container = new RazorViewContainer( resolver ); + _addViewSubject = new SequentialSimpleAsyncSubject(); + InitAddViewSubject(); + } + + /// + /// 初始化添加视图事件 + /// + private void InitAddViewSubject() { + _addViewSubject.Where( path => path.IsEmpty() == false ) + .Delay( TimeSpan.FromSeconds( 1 ) ) + .SubscribeAsync( async path => { + WriteLog( $"发现新增文件: {path}" ); + _container.AddView( path ); + EnableOverrideHtml( false ); + await Request( path ); + EnableOverrideHtml(); + await Task.Delay( 200 ); + } ); + } + + /// + /// 启用Html覆盖 + /// + protected void EnableOverrideHtml( bool isOverrideHtml = true ) { + _options.EnableOverrideHtml = isOverrideHtml; + } + + /// + /// 发送请求 + /// + /// 视图路径 + /// 是否写入日志 + /// 请求次数 + public async Task Request( string path, bool isWrite = true, int times = 0 ) { + try { + times++; + if ( times > 3 ) + return; + await Task.Delay( TimeSpan.FromMilliseconds( _options.HtmlRenderDelayOnRazorChange ) ); + var requestPath = Url.JoinPath( GetApplicationUrl(), "view", path.RemoveStart( _options.RazorRootDirectory ).RemoveEnd( ".cshtml" ) ); + WriteLog( $"发送请求: {requestPath}", isWrite ); + var response = await _client.GetAsync( requestPath ); + if ( response.IsSuccessStatusCode ) { + WriteLog( $"请求成功: {requestPath}", isWrite ); + return; + } + await Task.Delay( 2000 ); + if ( response.StatusCode == HttpStatusCode.NotFound ) { + await AddView( path ); + return; + } + await Request( path, isWrite, times ); + } + catch ( InvalidOperationException ) { + await Task.Delay( 2000 ); + await Request( path, isWrite, times ); + } } /// @@ -61,11 +120,11 @@ public virtual async Task StartAsync( CancellationToken cancellationToken ) { InitRazorViewContainer(); await Task.Factory.StartNew( async () => { await Task.Delay( _options.StartInitDelay, cancellationToken ); - await GenerateMissingHtml( cancellationToken ); - await Preheat( cancellationToken ); + await GenerateMissingHtml(); + await Preheat(); IsStartComplete = true; WriteLog( "初始化完成." ); - await StartWatch( cancellationToken ); + await StartWatch(); }, cancellationToken ); } @@ -75,28 +134,25 @@ await Task.Factory.StartNew( async () => { private void WriteLog( string content, bool isWrite = true ) { if ( isWrite == false ) return; - Console.WriteLine( $"dbug: Util应用框架 - Razor监听服务 - {content}" ); + Console.WriteLine( $"dbug: {DateTime.Now.ToMillisecondString()} - Util应用框架 - Razor监听服务 - {content}" ); } /// /// 初始化Razor视图容器 /// protected virtual void InitRazorViewContainer() { - _container = new RazorViewContainer( _resolver ); - _container.Init( GetAllViewContents() ); + _container.Init( GetAllViewPaths() ); } /// - /// 获取所有视图内容列表 + /// 获取所有主视图路径列表 /// - protected Dictionary GetAllViewContents() { - var result = new Dictionary(); + protected List GetAllViewPaths() { + var result = new List(); var descriptors = GetPageActionDescriptors(); - foreach ( var descriptor in descriptors ) { - var content = GetContent( descriptor.RelativePath ); - result.TryAdd( descriptor.RelativePath, content ); - } - return result; + foreach ( var descriptor in descriptors ) + result.Add( descriptor.RelativePath ); + return result.Distinct().ToList(); } /// @@ -106,25 +162,10 @@ protected List GetPageActionDescriptors() { return _provider.ActionDescriptors.Items.OfType().ToList(); } - /// - /// 获取Razor文件内容 - /// - protected string GetContent( string relativePath ) { - var path = GetProjectPath( relativePath ); - return Util.Helpers.File.ReadToString( path ); - } - - /// - /// 获取项目路径 - /// - protected string GetProjectPath( string relativePath ) { - return Url.JoinPath( Common.GetCurrentDirectory(), relativePath ); - } - /// /// 生成缺失的html /// - protected async Task GenerateMissingHtml( CancellationToken cancellationToken ) { + protected async Task GenerateMissingHtml() { WriteLog( "准备生成缺失的html..." ); EnableGenerateHtml(); EnableOverrideHtml( false ); @@ -134,7 +175,7 @@ protected async Task GenerateMissingHtml( CancellationToken cancellationToken ) if ( Exists( files.Select( t => t.FullName ).ToList(), path ) ) continue; _isGenerateMissingHtml = true; - await Request( path, cancellationToken ); + await Request( path ); } EnableOverrideHtml(); WriteLog( "生成缺失的html完成..." ); @@ -148,10 +189,10 @@ protected void EnableGenerateHtml( bool isGenerateHtml = true ) { } /// - /// 启用Html覆盖 + /// 获取项目路径 /// - protected void EnableOverrideHtml( bool isOverrideHtml = true ) { - _options.EnableOverrideHtml = isOverrideHtml; + protected string GetProjectPath( string relativePath ) { + return Url.JoinPath( Common.GetCurrentDirectory(), relativePath ); } /// @@ -164,21 +205,6 @@ protected bool Exists( List htmlPaths, string razorPath ) { return htmlPaths.Any( t => t.Replace( "\\", "/" ).EndsWith( path, StringComparison.OrdinalIgnoreCase ) ); } - /// - /// 生成Html - /// - /// 视图路径 - /// 取消令牌 - /// 是否写入日志 - public async Task Request( string path, CancellationToken cancellationToken = default, bool isWrite = true ) { - await Task.Delay( _options.HtmlRenderDelayOnRazorChange, cancellationToken ); - var requestPath = Url.JoinPath( GetApplicationUrl(), "view", path.RemoveStart( _options.RazorRootDirectory ).RemoveEnd( ".cshtml" ) ); - WriteLog( $"发送请求: {requestPath}", isWrite ); - var response = await _client.GetAsync( requestPath, cancellationToken ); - if ( response.IsSuccessStatusCode ) - WriteLog( $"请求成功: {requestPath}", isWrite ); - } - /// /// 获取应用地址 /// @@ -195,10 +221,17 @@ protected string GetApplicationUrl() { return null; } + /// + /// 添加视图 + /// + protected async Task AddView( string path ) { + await _addViewSubject.OnNextAsync( path ); + } + /// /// Razor页面预热 /// - protected async Task Preheat( CancellationToken cancellationToken ) { + protected async Task Preheat() { if ( _isGenerateMissingHtml ) return; if ( _options.EnablePreheat == false ) @@ -207,20 +240,20 @@ protected async Task Preheat( CancellationToken cancellationToken ) { EnableGenerateHtml( false ); var paths = _container.GetRandomPaths(); foreach ( var path in paths ) - await Request( path, cancellationToken, false ); + await Request( path, false ); WriteLog( "Razor页面预热完成..." ); } /// /// 启动监听器 /// - protected virtual Task StartWatch( CancellationToken cancellationToken ) { + protected virtual Task StartWatch() { WriteLog( "开始监听..." ); var path = GetProjectPath( _options.RazorRootDirectory.RemoveStart( "/" ) ); _watcher.Path( path ) .Filter( "*.cshtml" ) - .OnChangedAsync( async ( _, e ) => await GenerateAsync( e.FullPath, cancellationToken ) ) - .OnRenamedAsync( async ( _, e ) => await GenerateAsync( e.FullPath, cancellationToken ) ) + .OnChangedAsync( async ( _, e ) => await GenerateAsync( e.FullPath ) ) + .OnRenamedAsync( async ( _, e ) => await GenerateAsync( e.FullPath ) ) .Start(); return Task.CompletedTask; } @@ -228,7 +261,7 @@ protected virtual Task StartWatch( CancellationToken cancellationToken ) { /// /// 生成Html /// - private async Task GenerateAsync( string fullPath, CancellationToken cancellationToken ) { + private async Task GenerateAsync( string fullPath ) { if ( IsCshtml( fullPath ) == false ) return; EnableGenerateHtml(); @@ -237,11 +270,11 @@ private async Task GenerateAsync( string fullPath, CancellationToken cancellatio WriteLog( $"发现修改: {file.FullName.Replace( "\\", "/" )}" ); var viewPaths = _container.GetViewPaths( path ); if ( viewPaths == null || viewPaths.Count == 0 ) { - WriteLog( $"未找到可更新的视图路径: {path}" ); + await AddView( path ); return; } foreach ( var viewPath in viewPaths ) - await Request( viewPath, cancellationToken ); + await Request( viewPath ); } /// diff --git a/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorBlockTagHelperTest.cs b/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorBlockTagHelperTest.cs new file mode 100644 index 000000000..8eda80fe6 --- /dev/null +++ b/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorBlockTagHelperTest.cs @@ -0,0 +1,118 @@ +using System.Text; +using Util.Ui.Angular.Configs; +using Util.Ui.Configs; +using Util.Ui.NgZorro.Components.ColorPickers; +using Util.Ui.NgZorro.Configs; +using Util.Ui.NgZorro.Enums; +using Util.Ui.TagHelpers; +using Xunit; +using Xunit.Abstractions; + +namespace Util.Ui.NgZorro.Tests.ColorPickers { + /// + /// 颜色块测试 + /// + public class ColorBlockTagHelperTest { + /// + /// 输出工具 + /// + private readonly ITestOutputHelper _output; + /// + /// TagHelper包装器 + /// + private readonly TagHelperWrapper _wrapper; + + /// + /// 测试初始化 + /// + public ColorBlockTagHelperTest( ITestOutputHelper output ) { + _output = output; + _wrapper = new ColorBlockTagHelper().ToWrapper(); + } + + /// + /// 获取结果 + /// + private string GetResult() { + var result = _wrapper.GetResult(); + _output.WriteLine( result ); + return result; + } + + /// + /// 测试默认输出 + /// + [Fact] + public void TestDefault() { + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色值 + /// + [Fact] + public void TestColor() { + _wrapper.SetContextAttribute( UiConst.Color, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色值 + /// + [Fact] + public void TestBindColor() { + _wrapper.SetContextAttribute( AngularConst.BindColor, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试控件尺寸 + /// + [Fact] + public void TestSize() { + _wrapper.SetContextAttribute( UiConst.Size, InputSize.Large ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试控件尺寸 + /// + [Fact] + public void TestBindSize() { + _wrapper.SetContextAttribute( AngularConst.BindSize, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试内容 + /// + [Fact] + public void TestContent() { + _wrapper.AppendContent( "a" ); + var result = new StringBuilder(); + result.Append( "a" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试点击事件 + /// + [Fact] + public void TestOnChange() { + _wrapper.SetContextAttribute( UiConst.OnClick, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.Expression.cs b/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.Expression.cs new file mode 100644 index 000000000..14255356b --- /dev/null +++ b/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.Expression.cs @@ -0,0 +1,27 @@ +using System.Text; +using Xunit; + +namespace Util.Ui.NgZorro.Tests.ColorPickers { + /// + /// 颜色选择测试 - 表达式解析测试 + /// + public partial class ColorPickerTagHelperTest { + /// + /// 测试解析表达式属性for + /// + [Fact] + public void TestFor_1() { + _wrapper.SetExpression( t => t.Name ); + var result = new StringBuilder(); + result.Append( "" ); + result.Append( "姓名" ); + result.Append( "" ); + result.Append( "" ); + result.Append( "" ); + result.Append( "" ); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.cs b/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.cs new file mode 100644 index 000000000..30f9f5c73 --- /dev/null +++ b/test/Util.Ui.NgZorro.Tests/ColorPickers/ColorPickerTagHelperTest.cs @@ -0,0 +1,353 @@ +using System.Text; +using Util.Helpers; +using Util.Ui.Angular.Configs; +using Util.Ui.Configs; +using Util.Ui.NgZorro.Components.ColorPickers; +using Util.Ui.NgZorro.Configs; +using Util.Ui.NgZorro.Enums; +using Util.Ui.NgZorro.Tests.Samples; +using Util.Ui.TagHelpers; +using Xunit; +using Xunit.Abstractions; + +namespace Util.Ui.NgZorro.Tests.ColorPickers { + /// + /// 颜色选择测试 + /// + public partial class ColorPickerTagHelperTest { + /// + /// 输出工具 + /// + private readonly ITestOutputHelper _output; + /// + /// TagHelper包装器 + /// + private readonly TagHelperWrapper _wrapper; + + /// + /// 测试初始化 + /// + public ColorPickerTagHelperTest( ITestOutputHelper output ) { + _output = output; + _wrapper = new ColorPickerTagHelper().ToWrapper(); + Id.SetId( "id" ); + } + + /// + /// 获取结果 + /// + private string GetResult() { + var result = _wrapper.GetResult(); + _output.WriteLine( result ); + return result; + } + + /// + /// 测试默认输出 + /// + [Fact] + public void TestDefault() { + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试标题 + /// + [Fact] + public void TestTitle() { + _wrapper.SetContextAttribute( UiConst.Title, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试标题 - 支持多语言 + /// + [Fact] + public void TestTitle_I18n() { + NgZorroOptionsService.SetOptions( new NgZorroOptions { EnableI18n = true } ); + _wrapper.SetContextAttribute( UiConst.Title, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试标题 + /// + [Fact] + public void TestBindTitle() { + _wrapper.SetContextAttribute( AngularConst.BindTitle, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色默认值 + /// + [Fact] + public void TestDefaultValue() { + _wrapper.SetContextAttribute( UiConst.DefaultValue, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色默认值 + /// + [Fact] + public void TestBindDefaultValue() { + _wrapper.SetContextAttribute( AngularConst.BindDefaultValue, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色值 + /// + [Fact] + public void TestValue() { + _wrapper.SetContextAttribute( UiConst.Value, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色值 + /// + [Fact] + public void TestBindValue() { + _wrapper.SetContextAttribute( AngularConst.BindValue, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试显示颜色文本 + /// + [Fact] + public void TestShowText() { + _wrapper.SetContextAttribute( UiConst.ShowText, true ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试显示颜色文本 + /// + [Fact] + public void TestBindShowText() { + _wrapper.SetContextAttribute( AngularConst.BindShowText, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试控件尺寸 + /// + [Fact] + public void TestSize() { + _wrapper.SetContextAttribute( UiConst.Size, InputSize.Large ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试控件尺寸 + /// + [Fact] + public void TestBindSize() { + _wrapper.SetContextAttribute( AngularConst.BindSize, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试禁用 + /// + [Fact] + public void TestDisabled() { + _wrapper.SetContextAttribute( UiConst.Disabled, true ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试禁用 + /// + [Fact] + public void TestBindDisabled() { + _wrapper.SetContextAttribute( AngularConst.BindDisabled, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试禁用透明度 + /// + [Fact] + public void TestDisabledAlpha() { + _wrapper.SetContextAttribute( UiConst.DisabledAlpha, true ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试禁用透明度 + /// + [Fact] + public void TestBindDisabledAlpha() { + _wrapper.SetContextAttribute( AngularConst.BindDisabledAlpha, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试触发模式 + /// + [Fact] + public void TestTrigger() { + _wrapper.SetContextAttribute( UiConst.Trigger, ColorPickerTrigger.Hover ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试触发模式 + /// + [Fact] + public void TestBindTrigger() { + _wrapper.SetContextAttribute( AngularConst.BindTrigger, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试允许清除 + /// + [Fact] + public void TestAllowClear() { + _wrapper.SetContextAttribute( UiConst.AllowClear, true ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试允许清除 + /// + [Fact] + public void TestBindAllowClear() { + _wrapper.SetContextAttribute( AngularConst.BindAllowClear, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色格式 + /// + [Fact] + public void TestFormat() { + _wrapper.SetContextAttribute( UiConst.Format, ColorPickerFormat.Hsb ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色格式 + /// + [Fact] + public void TestBindFormat() { + _wrapper.SetContextAttribute( AngularConst.BindFormat, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试显示弹出窗口 + /// + [Fact] + public void TestOpen() { + _wrapper.SetContextAttribute( UiConst.Open, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试内容 + /// + [Fact] + public void TestContent() { + _wrapper.AppendContent( "a" ); + var result = new StringBuilder(); + result.Append( "a" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色变化事件 + /// + [Fact] + public void TestOnChange() { + _wrapper.SetContextAttribute( UiConst.OnChange, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试清除事件 + /// + [Fact] + public void TestOnClear() { + _wrapper.SetContextAttribute( UiConst.OnClear, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试颜色格式变化事件 + /// + [Fact] + public void TestOnFormatChange() { + _wrapper.SetContextAttribute( UiConst.OnFormatChange, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + + /// + /// 测试打开颜色面板事件 + /// + [Fact] + public void TestOnOpenChange() { + _wrapper.SetContextAttribute( UiConst.OnOpenChange, "a" ); + var result = new StringBuilder(); + result.Append( "" ); + Assert.Equal( result.ToString(), GetResult() ); + } + } +} \ No newline at end of file diff --git a/test/Util.Ui.Tests/Razor/RazorViewContainerTest.cs b/test/Util.Ui.Tests/Razor/RazorViewContainerTest.cs index e35158ce9..50037fb8a 100644 --- a/test/Util.Ui.Tests/Razor/RazorViewContainerTest.cs +++ b/test/Util.Ui.Tests/Razor/RazorViewContainerTest.cs @@ -32,29 +32,30 @@ public RazorViewContainerTest() { } /// - /// 测试创建视图 - 不包含分部视图 + /// 测试添加视图 - 不包含分部视图 /// [Fact] - public void TestCreateView_1() { + public void TestAddView_1() { //变量定义 var path = "/path1"; var content = "@page a"; //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); //执行 - var result = _container.CreateView( path, content ); + var result = _container.AddView( path ); Assert.True( result is MainView ); Assert.Equal( path, result.Path ); Assert.Empty( result.PartViews ); } /// - /// 测试创建视图 - 1个分部视图 + /// 测试添加视图 - 1个分部视图 /// [Fact] - public void TestCreateView_2() { + public void TestAddView_2() { //变量定义 var path = "/path1"; var content = "@page a"; @@ -62,10 +63,11 @@ public void TestCreateView_2() { //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [partPath] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); _mockContentResolver.Setup( t => t.Resolve( partPath ) ).Returns( "a" ); //执行 - var result = _container.CreateView( path, content ); + var result = _container.AddView( path ); Assert.True( result is MainView ); Assert.Equal( path, result.Path ); Assert.Single( result.PartViews ); @@ -74,7 +76,7 @@ public void TestCreateView_2() { } /// - /// 测试创建视图 - 2个分部视图 + /// 测试添加视图 - 2个分部视图 /// [Fact] public void TestCreateView_3() { @@ -86,11 +88,12 @@ public void TestCreateView_3() { //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [path2, path3] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); _mockContentResolver.Setup( t => t.Resolve( path2 ) ).Returns( "a" ); _mockContentResolver.Setup( t => t.Resolve( path3 ) ).Returns( "a" ); //执行 - var result = _container.CreateView( path, content ); + var result = _container.AddView( path ); Assert.Equal( 2, result.PartViews.Count ); Assert.Equal( path2, result.PartViews[0].Path ); Assert.Single( result.PartViews[0].MainViews ); @@ -99,7 +102,7 @@ public void TestCreateView_3() { } /// - /// 测试创建视图 - 2个分部视图 - 分部视图嵌套 + /// 测试添加视图 - 2个分部视图 - 分部视图嵌套 /// [Fact] public void TestCreateView_4() { @@ -114,12 +117,13 @@ public void TestCreateView_4() { //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [path2, path3] ); _mockPartViewPathResolver.Setup( t => t.Resolve( path3, content2 ) ).Returns( [path4] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); _mockContentResolver.Setup( t => t.Resolve( path2 ) ).Returns( "a" ); _mockContentResolver.Setup( t => t.Resolve( path3 ) ).Returns( content2 ); _mockContentResolver.Setup( t => t.Resolve( path4 ) ).Returns( "a" ); //执行 - var result = _container.CreateView( path, content ); + var result = _container.AddView( path ); Assert.Equal( 2, result.PartViews.Count ); Assert.Equal( path2, result.PartViews[0].Path ); Assert.Single( result.PartViews[0].MainViews ); @@ -138,13 +142,14 @@ public void TestGetViewPaths_1() { //变量定义 var path = "/path1"; var content = "@page a"; - var dic = new Dictionary { { path, content } }; + var list = new List { path }; //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); //初始化容器 - _container.Init( dic ); + _container.Init( list ); //执行 var result = _container.GetViewPaths( path ); @@ -161,14 +166,15 @@ public void TestGetViewPaths_2() { var path = "/path1"; var content = "@page a"; var partPath = "/path2"; - var dic = new Dictionary { { path, content } }; + var list = new List { path }; //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [partPath] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); _mockContentResolver.Setup( t => t.Resolve( partPath ) ).Returns( "a" ); //初始化容器 - _container.Init( dic ); + _container.Init( list ); //执行 var result = _container.GetViewPaths( partPath ); @@ -186,15 +192,17 @@ public void TestGetViewPaths_3() { var path2 = "/path2"; var content = "@page a"; var partPath = "/partPath"; - var dic = new Dictionary { { path, content }, { path2, content } }; + var list = new List { path, path2 }; //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [partPath] ); _mockPartViewPathResolver.Setup( t => t.Resolve( path2, content ) ).Returns( [partPath] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); + _mockContentResolver.Setup( t => t.Resolve( path2 ) ).Returns( content ); _mockContentResolver.Setup( t => t.Resolve( partPath ) ).Returns( "a" ); //初始化容器 - _container.Init( dic ); + _container.Init( list ); //执行 var result = _container.GetViewPaths( partPath ); @@ -215,17 +223,19 @@ public void TestGetViewPaths_4() { var content2 = "a"; var partPath = "/partPath"; var partPath2 = "/partPath2"; - var dic = new Dictionary { { path, content }, { path2, content } }; + var list = new List { path, path2 }; //方法设置 _mockPartViewPathResolver.Setup( t => t.Resolve( path, content ) ).Returns( [partPath] ); _mockPartViewPathResolver.Setup( t => t.Resolve( path2, content ) ).Returns( [partPath2] ); _mockPartViewPathResolver.Setup( t => t.Resolve( partPath2, content2 ) ).Returns( [partPath] ); + _mockContentResolver.Setup( t => t.Resolve( path ) ).Returns( content ); + _mockContentResolver.Setup( t => t.Resolve( path2 ) ).Returns( content ); _mockContentResolver.Setup( t => t.Resolve( partPath ) ).Returns( "a" ); _mockContentResolver.Setup( t => t.Resolve( partPath2 ) ).Returns( content2 ); //初始化容器 - _container.Init( dic ); + _container.Init( list ); //执行 var result = _container.GetViewPaths( partPath );