diff --git a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor
index bd7d400..54385da 100644
--- a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor
+++ b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor
@@ -32,6 +32,7 @@
+
@L["DisplayName:IsDefault"]
@@ -53,6 +54,7 @@
+
@L["DisplayName:IsDefault"]
@@ -67,4 +69,4 @@
@if (HasManagePermissionsPermission)
{
-}
+}
\ No newline at end of file
diff --git a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor.cs b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor.cs
index 41ee96a..0c2047b 100644
--- a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor.cs
+++ b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/RoleManagement.razor.cs
@@ -10,6 +10,7 @@ using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
using Volo.Abp.Identity;
using Volo.Abp.Identity.Localization;
+using Volo.Abp.ObjectExtending;
namespace Lsw.Abp.IdentityManagement.Blazor.AntDesignUI.Pages;
@@ -90,19 +91,18 @@ public partial class RoleManagement
Title = L["RoleName"],
Data = nameof(IdentityRoleDto.Name),
Component = typeof(RoleNameComponent)
- },
- new TableColumn
- {
- Title = L["Actions"],
- Actions = EntityActions.Get()
- },
+ }
});
+ RoleManagementTableColumns.AddRange(GetExtensionTableColumns(IdentityModuleExtensionConsts.ModuleName,
+ IdentityModuleExtensionConsts.EntityNames.Role));
+
+ RoleManagementTableColumns.Add(new TableColumn
+ {
+ Title = L["Actions"],
+ Actions = EntityActions.Get()
+ });
- //TODO Implement object extensions
- // RoleManagementTableColumns.AddRange(GetExtensionTableColumns(IdentityModuleExtensionConsts.ModuleName,
- // IdentityModuleExtensionConsts.EntityNames.Role));
-
return base.SetTableColumnsAsync();
}
diff --git a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor
index f731647..d76e5dd 100644
--- a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor
+++ b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor
@@ -41,7 +41,7 @@
-
+
@@ -55,15 +55,16 @@
@L["DisplayName:LockoutEnabled"]
+
-
+
- @foreach (var role in NewUserRoles)
- {
-
- @role.Name
-
- }
+ @foreach (var role in NewUserRoles)
+ {
+
+ @role.Name
+
+ }
}
@@ -92,7 +93,7 @@
-
+
@@ -106,15 +107,17 @@
@L["DisplayName:LockoutEnabled"]
+
+
-
+
- @foreach (var role in EditUserRoles)
- {
-
- @role.Name
-
- }
+ @foreach (var role in EditUserRoles)
+ {
+
+ @role.Name
+
+ }
}
@@ -126,4 +129,4 @@
@if (HasManagePermissionsPermission)
{
-}
+}
\ No newline at end of file
diff --git a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor.cs b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor.cs
index e7523d0..2e91505 100644
--- a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor.cs
+++ b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/Pages/UserManagement.razor.cs
@@ -11,6 +11,7 @@ using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
using Volo.Abp.Identity;
using Volo.Abp.Identity.Localization;
+using Volo.Abp.ObjectExtending;
namespace Lsw.Abp.IdentityManagement.Blazor.AntDesignUI.Pages;
@@ -177,14 +178,18 @@ public partial class UserManagement
{
Title = L["PhoneNumber"],
Data = nameof(IdentityUserDto.PhoneNumber),
- },
- new TableColumn
- {
- Title = L["Actions"],
- Actions = EntityActions.Get()
- },
+ }
});
+ UserManagementTableColumns.AddRange(GetExtensionTableColumns(IdentityModuleExtensionConsts.ModuleName,
+ IdentityModuleExtensionConsts.EntityNames.User));
+
+ UserManagementTableColumns.Add(new TableColumn
+ {
+ Title = L["Actions"],
+ Actions = EntityActions.Get()
+ });
+
return base.SetEntityActionsAsync();
}
diff --git a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/_Imports.razor b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/_Imports.razor
index 3996685..cc2925a 100644
--- a/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/_Imports.razor
+++ b/modules/IdentityManagement/Lsw.Abp.IdentityManagement.Blazor.AntDesignUI/_Imports.razor
@@ -2,6 +2,7 @@
@using Volo.Abp.AspNetCore.Components.Web
@using Lsw.Abp.AntDesignUI
@using Lsw.Abp.AntDesignUI.Components
+@using Lsw.Abp.AntDesignUI.Components.ObjectExtending
@using AntDesign
@using AntDesign.TableModels
@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Layout
diff --git a/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor b/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor
index 6eda37d..63cd59e 100644
--- a/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor
+++ b/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor
@@ -39,7 +39,7 @@
-
+
}
@@ -55,7 +55,7 @@
-
+
}
@@ -63,4 +63,4 @@
@if (HasManageFeaturesPermission)
{
-}
+}
\ No newline at end of file
diff --git a/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor.cs b/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor.cs
index 4284f5f..ebc6dd2 100644
--- a/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor.cs
+++ b/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/Pages/TenantManagement.razor.cs
@@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Authorization;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
using Volo.Abp.FeatureManagement;
+using Volo.Abp.ObjectExtending;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.Localization;
@@ -117,18 +118,19 @@ public partial class TenantManagement
{
Title = L["TenantName"],
Data = nameof(TenantDto.Name),
- },
- new TableColumn
- {
- Title = L["Actions"],
- Actions = EntityActions.Get()
- },
+ }
});
- // TenantManagementTableColumns.AddRange(GetExtensionTableColumns(
- // TenantManagementModuleExtensionConsts.ModuleName,
- // TenantManagementModuleExtensionConsts.EntityNames.Tenant));
+ TenantManagementTableColumns.AddRange(GetExtensionTableColumns(
+ TenantManagementModuleExtensionConsts.ModuleName,
+ TenantManagementModuleExtensionConsts.EntityNames.Tenant));
+ TenantManagementTableColumns.Add(new TableColumn
+ {
+ Title = L["Actions"],
+ Actions = EntityActions.Get()
+ });
+
return base.SetTableColumnsAsync();
}
}
diff --git a/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/_Imports.razor b/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/_Imports.razor
index d5ec4b0..e2a7a78 100644
--- a/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/_Imports.razor
+++ b/modules/TenantManagement/Lsw.Abp.TenantManagement.Blazor.AntDesignUI/_Imports.razor
@@ -3,5 +3,6 @@
@using AntDesign
@using Lsw.Abp.AntDesignUI
@using Lsw.Abp.AntDesignUI.Components
+@using Lsw.Abp.AntDesignUI.Components.ObjectExtending
@using Lsw.Abp.FeatureManagement.Blazor.AntDesignUI.Components
@using Lsw.Abp.AspnetCore.Components.Web.AntDesignTheme.Layout
diff --git a/src/Lsw.Abp.AntDesignUI/AbpCrudPageBase.cs b/src/Lsw.Abp.AntDesignUI/AbpCrudPageBase.cs
index 8fa7e60..0141637 100644
--- a/src/Lsw.Abp.AntDesignUI/AbpCrudPageBase.cs
+++ b/src/Lsw.Abp.AntDesignUI/AbpCrudPageBase.cs
@@ -7,6 +7,7 @@ using AntDesign.TableModels;
using JetBrains.Annotations;
using Localization.Resources.AbpUi;
using Lsw.Abp.AntDesignUI.Components;
+using Lsw.Abp.AntDesignUI.Components.ObjectExtending;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
@@ -17,6 +18,9 @@ using Volo.Abp.AspNetCore.Components;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
using Volo.Abp.Authorization;
+using Volo.Abp.Localization;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.ObjectExtending.Modularity;
namespace Lsw.Abp.AntDesignUI;
@@ -580,6 +584,48 @@ public abstract class AbpCrudPageBase<
{
return ValueTask.CompletedTask;
}
+
+ protected virtual IEnumerable GetExtensionTableColumns(string moduleName, string entityType)
+ {
+ var properties = ModuleExtensionConfigurationHelper.GetPropertyConfigurations(moduleName, entityType);
+ foreach (var propertyInfo in properties)
+ {
+ if (propertyInfo.IsAvailableToClients && propertyInfo.UI.OnTable.IsVisible)
+ {
+ if (propertyInfo.Name.EndsWith("_Text"))
+ {
+ var lookupPropertyName = propertyInfo.Name.RemovePostFix("_Text");
+ var lookupPropertyDefinition = properties.SingleOrDefault(t => t.Name == lookupPropertyName);
+ yield return new TableColumn
+ {
+ Title = lookupPropertyDefinition.GetLocalizedDisplayName(StringLocalizerFactory),
+ Data = $"ExtraProperties[{propertyInfo.Name}]"
+ };
+ }
+ else
+ {
+ var column = new TableColumn
+ {
+ Title = propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory),
+ Data = $"ExtraProperties[{propertyInfo.Name}]"
+ };
+
+ if (propertyInfo.IsDate() || propertyInfo.IsDateTime())
+ {
+ column.DisplayFormat = propertyInfo.GetDateEditInputFormatOrNull();
+ }
+
+ if (propertyInfo.Type.IsEnum)
+ {
+ column.ValueConverter = (val) =>
+ EnumHelper.GetLocalizedMemberName(propertyInfo.Type, val.As().ExtraProperties[propertyInfo.Name], StringLocalizerFactory);
+ }
+
+ yield return column;
+ }
+ }
+ }
+ }
}
diff --git a/src/Lsw.Abp.AntDesignUI/AntDesignUiObjectExtensionPropertyInfoExtensions.cs b/src/Lsw.Abp.AntDesignUI/AntDesignUiObjectExtensionPropertyInfoExtensions.cs
new file mode 100644
index 0000000..e75b2e8
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/AntDesignUiObjectExtensionPropertyInfoExtensions.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.Reflection;
+
+namespace Lsw.Abp.AntDesignUI;
+
+public static class AntDesignUiObjectExtensionPropertyInfoExtensions
+{
+ private static readonly HashSet NumberTypes = new HashSet {
+ typeof(int),
+ typeof(long),
+ typeof(byte),
+ typeof(sbyte),
+ typeof(short),
+ typeof(ushort),
+ typeof(uint),
+ typeof(long),
+ typeof(ulong),
+ typeof(float),
+ typeof(double),
+ typeof(decimal),
+ typeof(int?),
+ typeof(long?),
+ typeof(byte?),
+ typeof(sbyte?),
+ typeof(short?),
+ typeof(ushort?),
+ typeof(uint?),
+ typeof(long?),
+ typeof(ulong?),
+ typeof(float?),
+ typeof(double?),
+ typeof(decimal?)
+ };
+
+ private static readonly HashSet TextEditSupportedAttributeTypes = new HashSet {
+ typeof(EmailAddressAttribute),
+ typeof(UrlAttribute),
+ typeof(PhoneAttribute)
+ };
+
+ public static string GetDateEditInputFormatOrNull(this IBasicObjectExtensionPropertyInfo property)
+ {
+ if (property.IsDate())
+ {
+ return "{0:yyyy-MM-dd}";
+ }
+
+ if (property.IsDateTime())
+ {
+ return "{0:yyyy-MM-dd HH:mm}";
+ }
+
+ return null;
+ }
+
+ public static string GetTextInputValueOrNull(this IBasicObjectExtensionPropertyInfo property, object value)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+
+ if (TypeHelper.IsFloatingType(property.Type))
+ {
+ return value.ToString()?.Replace(',', '.');
+ }
+
+ return value.ToString();
+ }
+
+ public static T GetInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value)
+ {
+ if (value == null)
+ {
+ return default;
+ }
+
+ return (T)value;
+ }
+
+ public static string GetTextInputMode(this ObjectExtensionPropertyInfo propertyInfo)
+ {
+ foreach (var attribute in propertyInfo.Attributes)
+ {
+ var textRoleByAttribute = GetTextInputModeFromAttributeOrNull(attribute);
+ if (textRoleByAttribute != null)
+ {
+ return textRoleByAttribute;
+ }
+ }
+
+ return GetTextInputModeFromTypeOrNull(propertyInfo.Type)
+ ?? "text"; //default
+ }
+
+ private static string GetTextInputModeFromTypeOrNull(Type type)
+ {
+ // if (TypeHelper.IsFloatingType(type))
+ // {
+ // return "number";
+ // }
+
+ if (NumberTypes.Contains(type))
+ {
+ return "number";
+ }
+
+ return null;
+ }
+
+ private static string GetTextInputModeFromAttributeOrNull(Attribute attribute)
+ {
+ if (attribute is EmailAddressAttribute)
+ {
+ return "email";
+ }
+
+ if (attribute is UrlAttribute)
+ {
+ return "url";
+ }
+
+
+ if (attribute is PhoneAttribute)
+ {
+ return "tel";
+ }
+
+ if (attribute is DataTypeAttribute dataTypeAttribute)
+ {
+ switch (dataTypeAttribute.DataType)
+ {
+ case DataType.EmailAddress:
+ return "email";
+ case DataType.Url:
+ return "url";
+ case DataType.PhoneNumber:
+ return "tel";
+ }
+ }
+
+ return null;
+ }
+
+ public static string GetTextRole(this ObjectExtensionPropertyInfo propertyInfo)
+ {
+ foreach (var attribute in propertyInfo.Attributes)
+ {
+ var textRoleByAttribute = GetTextRoleFromAttributeOrNull(attribute);
+ if (textRoleByAttribute != null)
+ {
+ return textRoleByAttribute;
+ }
+ }
+
+ return "text"; //default
+ }
+
+ private static string GetTextRoleFromAttributeOrNull(Attribute attribute)
+ {
+ if (attribute is EmailAddressAttribute)
+ {
+ return "email";
+ }
+
+ if (attribute is UrlAttribute)
+ {
+ return "url";
+ }
+
+ if (attribute is DataTypeAttribute dataTypeAttribute)
+ {
+ switch (dataTypeAttribute.DataType)
+ {
+ case DataType.Password:
+ return "password";
+ case DataType.EmailAddress:
+ return "email";
+ case DataType.Url:
+ return "url";
+ }
+ }
+
+ return null;
+ }
+
+ public static Type GetInputType(this ObjectExtensionPropertyInfo propertyInfo)
+ {
+ foreach (var attribute in propertyInfo.Attributes)
+ {
+ var inputTypeByAttribute = GetInputTypeFromAttributeOrNull(attribute);
+ if (inputTypeByAttribute != null)
+ {
+ return inputTypeByAttribute;
+ }
+ }
+ return GetInputTypeFromTypeOrNull(propertyInfo.Type)
+ ?? typeof(TextExtensionProperty<,>); //default
+ }
+
+ private static Type GetInputTypeFromAttributeOrNull(Attribute attribute)
+ {
+ var hasTextEditSupport = TextEditSupportedAttributeTypes.Any(t => t == attribute.GetType());
+
+ if (hasTextEditSupport)
+ {
+ return typeof(TextExtensionProperty<,>);
+ }
+
+
+ if (attribute is DataTypeAttribute dataTypeAttribute)
+ {
+ switch (dataTypeAttribute.DataType)
+ {
+ case DataType.Password:
+ return typeof(TextExtensionProperty<,>);
+ case DataType.Date:
+ return typeof(DateTimeExtensionProperty<,>);
+ case DataType.Time:
+ return typeof(TimeExtensionProperty<,>);
+ case DataType.EmailAddress:
+ return typeof(TextExtensionProperty<,>);
+ case DataType.Url:
+ return typeof(TextExtensionProperty<,>);
+ case DataType.PhoneNumber:
+ return typeof(TextExtensionProperty<,>);
+ case DataType.DateTime:
+ return typeof(DateTimeExtensionProperty<,>);
+ }
+ }
+
+ return null;
+ }
+
+ private static Type GetInputTypeFromTypeOrNull(Type type)
+ {
+ if (type == typeof(bool))
+ {
+ return typeof(CheckExtensionProperty<,>);
+ }
+
+ if (type == typeof(DateTime))
+ {
+ return typeof(DateTimeExtensionProperty<,>);
+ }
+
+ if (NumberTypes.Contains(type))
+ {
+ return typeof(TextExtensionProperty<,>);
+ }
+
+ return null;
+ }
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/AbpExtensibleDataGrid.razor b/src/Lsw.Abp.AntDesignUI/Components/AbpExtensibleDataGrid.razor
index 8e684e6..9ff6def 100644
--- a/src/Lsw.Abp.AntDesignUI/Components/AbpExtensibleDataGrid.razor
+++ b/src/Lsw.Abp.AntDesignUI/Components/AbpExtensibleDataGrid.razor
@@ -1,4 +1,5 @@
-@typeparam TItem
+@using Volo.Abp.Data
+@typeparam TItem
+ Responsive="@Responsive"
+ TableLayout=""
+ ScrollX="100%">
@if (Columns != null)
{
@@ -17,7 +20,7 @@
{
if (column.Actions.Any())
{
-
+
@foreach (var action in column.Actions)
{
@@ -75,7 +78,42 @@
}
else
{
-
+
+ @{
+ var entity = context as IHasExtraProperties;
+ var propertyName = ExtensionPropertiesRegex.Match(column.Data).Groups[1].Value;
+ var propertyValue = entity.GetProperty(propertyName);
+ if (propertyValue is bool)
+ {
+ if ((bool) propertyValue)
+ {
+
+ }
+ else
+ {
+
+ }
+ }
+ else
+ {
+ if (column.ValueConverter != null)
+ {
+ @(GetConvertedFieldValue(context, column))
+ }
+ else
+ {
+ if (column.DisplayFormat == null)
+ {
+ @propertyValue
+ }
+ else
+ {
+ @string.Format(column.DisplayFormatProvider, column.DisplayFormat, propertyValue)
+ }
+ }
+ }
+ }
+
}
}
}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/CheckExtensionProperty.razor b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/CheckExtensionProperty.razor
new file mode 100644
index 0000000..4aef585
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/CheckExtensionProperty.razor
@@ -0,0 +1,13 @@
+@typeparam TEntity
+@typeparam TResourceType
+@using Volo.Abp.Localization
+@inherits ExtensionPropertyComponentBase
+
+@if (PropertyInfo != null && Entity != null)
+{
+
+
+ @PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)
+
+
+}
\ No newline at end of file
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs
new file mode 100644
index 0000000..ac9ad4c
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs
@@ -0,0 +1,16 @@
+using Volo.Abp.Data;
+
+namespace Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+
+public partial class CheckExtensionProperty
+ where TEntity : IHasExtraProperties
+{
+ protected bool Value {
+ get {
+ return PropertyInfo.GetInputValueOrDefault(Entity.GetProperty(PropertyInfo.Name));
+ }
+ set {
+ Entity.SetProperty(PropertyInfo.Name, value, false);
+ }
+ }
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/DateTimeExtensionProperty.razor b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
new file mode 100644
index 0000000..1e26bbe
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
@@ -0,0 +1,15 @@
+@typeparam TEntity
+@typeparam TResourceType
+@using Volo.Abp.Localization
+@inherits ExtensionPropertyComponentBase
+
+@if (PropertyInfo != null && Entity != null)
+{
+
+
+
+}
\ No newline at end of file
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs
new file mode 100644
index 0000000..23ea070
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs
@@ -0,0 +1,17 @@
+using System;
+using Volo.Abp.Data;
+
+namespace Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+
+public partial class DateTimeExtensionProperty
+ where TEntity : IHasExtraProperties
+{
+ protected DateTime? Value {
+ get {
+ return PropertyInfo.GetInputValueOrDefault(Entity.GetProperty(PropertyInfo.Name));
+ }
+ set {
+ Entity.SetProperty(PropertyInfo.Name, value, false);
+ }
+ }
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/EnumHelper.cs b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/EnumHelper.cs
new file mode 100644
index 0000000..d1ea1db
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/EnumHelper.cs
@@ -0,0 +1,28 @@
+using System;
+using Microsoft.Extensions.Localization;
+using Volo.Abp.Localization;
+
+namespace Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+
+public static class EnumHelper
+{
+ public static string GetLocalizedMemberName(Type enumType, object value, IStringLocalizerFactory stringLocalizerFactory)
+ {
+ var memberName = enumType.GetEnumName(value);
+ var localizedMemberName = AbpInternalLocalizationHelper.LocalizeWithFallback(
+ new[]
+ {
+ stringLocalizerFactory.CreateDefaultOrNull()
+ },
+ new[]
+ {
+ $"Enum:{enumType.Name}.{memberName}",
+ $"{enumType.Name}.{memberName}",
+ memberName
+ },
+ memberName
+ );
+
+ return localizedMemberName;
+ }
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionProperties.razor b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionProperties.razor
new file mode 100644
index 0000000..138c88a
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionProperties.razor
@@ -0,0 +1,27 @@
+@typeparam TEntityType
+@typeparam TResourceType
+@using Volo.Abp.ObjectExtending
+@using Volo.Abp.Data
+
+@{
+ Entity.SetDefaultsForExtraProperties();
+
+ foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties())
+ {
+ if (!propertyInfo.Name.EndsWith("_Text"))
+ {
+ if (propertyInfo.Type.IsEnum)
+ {
+
+ }
+ else if (!propertyInfo.Lookup.Url.IsNullOrEmpty())
+ {
+
+ }
+ else
+ {
+ @ExtensionPropertyRender(propertyInfo)
+ }
+ }
+ }
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionProperties.razor.cs b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionProperties.razor.cs
new file mode 100644
index 0000000..8725068
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionProperties.razor.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Components;
+using Microsoft.Extensions.Localization;
+using Volo.Abp.AspNetCore.Components.Web;
+using Volo.Abp.Data;
+using Volo.Abp.ObjectExtending;
+
+namespace Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+
+public partial class ExtensionProperties : ComponentBase
+ where TEntityType : IHasExtraProperties
+{
+ [Inject]
+ public IStringLocalizerFactory StringLocalizerFactory { get; set; }
+
+ [Parameter]
+ public AbpBlazorMessageLocalizerHelper LH { get; set; }
+
+ [Parameter]
+ public TEntityType Entity { get; set; }
+
+ private RenderFragment ExtensionPropertyRender(ObjectExtensionPropertyInfo propertyInfo) => builder =>
+ {
+ var inputType = propertyInfo.GetInputType();
+ builder.OpenComponent(0, inputType.MakeGenericType(typeof(TEntityType), typeof(TResourceType)));
+ builder.AddAttribute(1, "PropertyInfo", propertyInfo);
+ builder.AddAttribute(2, "Entity", Entity);
+ builder.AddAttribute(3, "LH", LH);
+ builder.CloseComponent();
+ };
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs
new file mode 100644
index 0000000..5229093
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs
@@ -0,0 +1,76 @@
+using System.ComponentModel.DataAnnotations;
+using Microsoft.AspNetCore.Components;
+using Microsoft.Extensions.Localization;
+using Volo.Abp.AspNetCore.Components.Web;
+using Volo.Abp.Data;
+using Volo.Abp.ObjectExtending;
+
+namespace Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+
+public abstract class ExtensionPropertyComponentBase : OwningComponentBase
+ where TEntity : IHasExtraProperties
+{
+ [Inject]
+ public IStringLocalizerFactory StringLocalizerFactory { get; set; }
+
+ [Parameter]
+ public TEntity Entity { get; set; }
+
+ [Parameter]
+ public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
+
+ [Parameter]
+ public AbpBlazorMessageLocalizerHelper LH { get; set; }
+ //
+ // protected virtual void Validate(ValidatorEventArgs e)
+ // {
+ // e.Status = ValidationStatus.Success;
+ //
+ // var validationAttributes = PropertyInfo.GetValidationAttributes();
+ // var validationContext = new ValidationContext(Entity)
+ // {
+ // DisplayName = PropertyInfo.Name,
+ // MemberName = PropertyInfo.Name
+ // };
+ //
+ // foreach (var validationAttribute in validationAttributes)
+ // {
+ // var result = validationAttribute.GetValidationResult(e.Value, validationContext);
+ // if (result == ValidationResult.Success || result == null)
+ // {
+ // continue;
+ // }
+ //
+ // var errorMessage = result.ErrorMessage;
+ // if (LH != null)
+ // {
+ // var formattedErrorMessage = GetDefaultErrorMessage(validationAttribute);
+ // var errorMessageString = ValidationAttributeHelper.RevertErrorMessagePlaceholders(formattedErrorMessage);
+ // var errorMessageArguments = ValidationMessageLocalizerAttributeFinder.FindAll(errorMessage, errorMessageString)
+ // ?.OrderBy(x => x.Index)
+ // ?.Select(x => x.Argument);
+ //
+ // errorMessage = LH.Localize(errorMessageString, errorMessageArguments);
+ // }
+ //
+ // e.MemberNames = result.MemberNames;
+ // e.Status = ValidationStatus.Error;
+ // e.ErrorText = errorMessage;
+ // break;
+ // }
+ // }
+ //
+ // private static string GetDefaultErrorMessage(ValidationAttribute validationAttribute)
+ // {
+ // if (validationAttribute is StringLengthAttribute stringLengthAttribute && stringLengthAttribute.MinimumLength != 0)
+ // {
+ // var nullable = ValidationAttributeHelper.ValidationAttributeCustomErrorMessageSetProperty.GetValue((object) validationAttribute) as bool?;
+ // var flag = true;
+ // if (!(nullable.GetValueOrDefault() == flag & nullable.HasValue))
+ // {
+ // return ValidationAttributeHelper.SetErrorMessagePlaceholders("The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.");
+ // }
+ // }
+ // return ValidationAttributeHelper.SetErrorMessagePlaceholders(ValidationAttributeHelper.ValidationAttributeErrorMessageStringProperty.GetValue((object) validationAttribute) as string);
+ // }
+}
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/LookupExtensionProperty.razor b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/LookupExtensionProperty.razor
new file mode 100644
index 0000000..5819bff
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/LookupExtensionProperty.razor
@@ -0,0 +1,16 @@
+@typeparam TEntity
+@typeparam TResourceType
+@using Volo.Abp.Localization
+@inherits ExtensionPropertyComponentBase
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs
new file mode 100644
index 0000000..fb2555f
--- /dev/null
+++ b/src/Lsw.Abp.AntDesignUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+using AntDesign;
+using Microsoft.AspNetCore.Components;
+using Volo.Abp.AspNetCore.Components.Web.Extensibility;
+using Volo.Abp.Data;
+
+namespace Lsw.Abp.AntDesignUI.Components.ObjectExtending;
+
+public partial class LookupExtensionProperty
+ where TEntity : IHasExtraProperties
+{
+ protected List> lookupItems;
+
+ [Inject] public ILookupApiRequestService LookupApiService { get; set; }
+
+ public string TextPropertyName => PropertyInfo.Name + "_Text";
+
+ private string SelectedValue { get; set; }
+
+ private Func