From f160b368a99590e5064b4e3c69800e82b9db92c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 19 May 2020 01:41:47 +0300 Subject: [PATCH] handle dates and datetimes on datatables MVC UI --- .../ui-extensions.js | 19 ++- ...UiObjectExtensionPropertyInfoExtensions.cs | 114 +++++++++++++++--- .../CachedObjectExtensionsDtoService.cs | 24 +++- .../ObjectExtendingPropertyInfoExtensions.cs | 113 +++-------------- .../IBasicObjectExtensionPropertyInfo.cs | 38 ++++++ .../ExtensionPropertyConfiguration.cs | 2 +- .../ModuleExtensionConfigurationHelper.cs | 1 + .../ObjectExtensionPropertyInfo.cs | 2 +- 8 files changed, 185 insertions(+), 128 deletions(-) create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js index 40e22d3da9..eacfecc867 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js @@ -96,7 +96,7 @@ get: _get }; })(); - + function initializeObjectExtensions() { var getShortEnumTypeName = function (enumType) { @@ -209,19 +209,18 @@ orderable: false }; + if (property.config.typeSimple === 'enum') { - columnConfig.render = function (data, type, row) { + columnConfig.render = function(data, type, row) { var value = getValueFromRow(property, row); return localizeEnumMember(property, value); } - } - else if (property.config.typeSimple === 'boolean') { - columnConfig.render = function (data, type, row) { - var value = getValueFromRow(property, row); - if (value) { - return ''; - } else { - return ''; + } else { + var defaultRenderer = abp.libs.datatables.defaultRenderers[property.config.typeSimple]; + if (defaultRenderer) { + columnConfig.render = function (data, type, row) { + var value = getValueFromRow(property, row); + return defaultRenderer(value); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/ObjectExtending/MvcUiObjectExtensionPropertyInfoExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/ObjectExtending/MvcUiObjectExtensionPropertyInfoExtensions.cs index bac7787028..608374e9e8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/ObjectExtending/MvcUiObjectExtensionPropertyInfoExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/ObjectExtending/MvcUiObjectExtensionPropertyInfoExtensions.cs @@ -1,19 +1,40 @@ using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Linq; +using Microsoft.AspNetCore.Mvc; namespace Volo.Abp.ObjectExtending { public static class MvcUiObjectExtensionPropertyInfoExtensions { - private static readonly Type[] DateTypes = new[] - { - typeof(DateTime), typeof(DateTimeOffset) + 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(int?), + typeof(long?), + typeof(byte?), + typeof(sbyte?), + typeof(short?), + typeof(ushort?), + typeof(uint?), + typeof(long?), + typeof(ulong?), + typeof(float?), + typeof(double?), }; - public static string GetInputFormatOrNull(this ObjectExtensionPropertyInfo property) + public static string GetInputFormatOrNull(this IBasicObjectExtensionPropertyInfo property) { - if (IsDate(property)) + if (property.IsDate()) { return "{0:yyyy-MM-dd}"; } @@ -21,24 +42,85 @@ namespace Volo.Abp.ObjectExtending return null; } - private static bool IsDate(ObjectExtensionPropertyInfo property) + public static string GetInputType(this ObjectExtensionPropertyInfo propertyInfo) + { + foreach (var attribute in propertyInfo.Attributes) + { + var inputTypeByAttribute = GetInputTypeFromAttributeOrNull(attribute); + if (inputTypeByAttribute != null) + { + return inputTypeByAttribute; + } + } + + return GetInputTypeFromTypeOrNull(propertyInfo.Type) + ?? "text"; //default + } + + private static string GetInputTypeFromAttributeOrNull(Attribute attribute) { - if (!DateTypes.Contains(property.Type)) + if (attribute is EmailAddressAttribute) { - return false; + return "email"; } - var dataTypeAttribute = property - .Attributes - .OfType() - .FirstOrDefault(); + if (attribute is UrlAttribute) + { + return "url"; + } + + if (attribute is HiddenInputAttribute) + { + return "hidden"; + } + + if (attribute is PhoneAttribute) + { + return "tel"; + } - if (dataTypeAttribute == null) + if (attribute is DataTypeAttribute dataTypeAttribute) { - return false; + switch (dataTypeAttribute.DataType) + { + case DataType.Password: + return "password"; + case DataType.Date: + return "date"; + case DataType.Time: + return "time"; + case DataType.EmailAddress: + return "email"; + case DataType.Url: + return "url"; + case DataType.PhoneNumber: + return "tel"; + case DataType.DateTime: + return "datetime-local"; + } } - return dataTypeAttribute.DataType == DataType.Date; + return null; + } + + private static string GetInputTypeFromTypeOrNull(Type type) + { + if (type == typeof(bool)) + { + return "checkbox"; + } + + if (type == typeof(DateTime)) + { + return "datetime-local"; + } + + if (NumberTypes.Contains(type)) + { + return "number"; + } + + return null; } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs index 870ff0368e..76d73820b2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs @@ -107,9 +107,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending var extensionPropertyDto = new ExtensionPropertyDto { Type = TypeHelper.GetFullNameHandlingNullableAndGenerics(propertyConfig.Type), - TypeSimple = propertyConfig.Type.IsEnum - ? "enum" - : TypeHelper.GetSimplifiedName(propertyConfig.Type), + TypeSimple = GetSimpleTypeName(propertyConfig), Attributes = new List(), DisplayName = CreateDisplayNameDto(propertyConfig), Configuration = new Dictionary(), @@ -161,6 +159,26 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending return extensionPropertyDto; } + protected virtual string GetSimpleTypeName(ExtensionPropertyConfiguration propertyConfig) + { + if (propertyConfig.Type.IsEnum) + { + return "enum"; + } + + if (propertyConfig.IsDate()) + { + return "date"; + } + + if (propertyConfig.IsDateTime()) + { + return "datetime"; + } + + return TypeHelper.GetSimplifiedName(propertyConfig.Type); + } + protected virtual LocalizableStringDto CreateDisplayNameDto(ExtensionPropertyConfiguration propertyConfig) { if (propertyConfig.DisplayName == null) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs index 04339eedd3..dc8a28e89f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/ObjectExtendingPropertyInfoExtensions.cs @@ -1,116 +1,35 @@ using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Mvc; +using System.Linq; namespace Volo.Abp.ObjectExtending { public static class ObjectExtensionPropertyInfoAspNetCoreMvcExtensions { - 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(int?), - typeof(long?), - typeof(byte?), - typeof(sbyte?), - typeof(short?), - typeof(ushort?), - typeof(uint?), - typeof(long?), - typeof(ulong?), - typeof(float?), - typeof(double?), + private static readonly Type[] DateTimeTypes = + { + typeof(DateTime), + typeof(DateTimeOffset) }; - public static string GetInputType(this ObjectExtensionPropertyInfo propertyInfo) + public static bool IsDate(this IBasicObjectExtensionPropertyInfo property) { - foreach (var attribute in propertyInfo.Attributes) - { - var inputTypeByAttribute = GetInputTypeFromAttributeOrNull(attribute); - if (inputTypeByAttribute != null) - { - return inputTypeByAttribute; - } - } - - return GetInputTypeFromTypeOrNull(propertyInfo.Type) - ?? "text"; //default + return DateTimeTypes.Contains(property.Type) && + property.GetDataTypeOrNull() == DataType.Date; } - private static string GetInputTypeFromAttributeOrNull(Attribute attribute) + public static bool IsDateTime(this IBasicObjectExtensionPropertyInfo property) { - if (attribute is EmailAddressAttribute) - { - return "email"; - } - - if (attribute is UrlAttribute) - { - return "url"; - } - - if (attribute is HiddenInputAttribute) - { - return "hidden"; - } - - if (attribute is PhoneAttribute) - { - return "tel"; - } - - if (attribute is DataTypeAttribute dataTypeAttribute) - { - switch (dataTypeAttribute.DataType) - { - case DataType.Password: - return "password"; - case DataType.Date: - return "date"; - case DataType.Time: - return "time"; - case DataType.EmailAddress: - return "email"; - case DataType.Url: - return "url"; - case DataType.PhoneNumber: - return "tel"; - case DataType.DateTime: - return "datetime-local"; - } - } - - return null; + return DateTimeTypes.Contains(property.Type) && + !property.IsDate(); } - private static string GetInputTypeFromTypeOrNull(Type type) + public static DataType? GetDataTypeOrNull(this IBasicObjectExtensionPropertyInfo property) { - if (type == typeof(bool)) - { - return "checkbox"; - } - - if (type == typeof(DateTime)) - { - return "datetime-local"; - } - - if (NumberTypes.Contains(type)) - { - return "number"; - } - - return null; + return property + .Attributes + .OfType() + .FirstOrDefault()?.DataType; } } } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs new file mode 100644 index 0000000000..de9bb35b01 --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/IBasicObjectExtensionPropertyInfo.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using Volo.Abp.Localization; + +namespace Volo.Abp.ObjectExtending +{ + public interface IBasicObjectExtensionPropertyInfo + { + [NotNull] + public string Name { get; } + + [NotNull] + public Type Type { get; } + + [NotNull] + public List Attributes { get; } + + [NotNull] + public List> Validators { get; } + + [CanBeNull] + public ILocalizableString DisplayName { get; } + + /// + /// Uses as the default value if was not set. + /// + [CanBeNull] + public object DefaultValue { get; set; } + + /// + /// Used with the first priority to create the default value for the property. + /// Uses to the if this was not set. + /// + [CanBeNull] + public Func DefaultValueFactory { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs index 6d66e51337..0a19a82018 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs @@ -6,7 +6,7 @@ using Volo.Abp.Reflection; namespace Volo.Abp.ObjectExtending.Modularity { - public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName + public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName, IBasicObjectExtensionPropertyInfo { [NotNull] public EntityExtensionConfiguration EntityExtensionConfiguration { get; } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs index cb5be17c1f..f4a5b149d6 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using JetBrains.Annotations; namespace Volo.Abp.ObjectExtending.Modularity diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs index 12b32ab241..ddd8fbbc3c 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs @@ -7,7 +7,7 @@ using Volo.Abp.Reflection; namespace Volo.Abp.ObjectExtending { - public class ObjectExtensionPropertyInfo : IHasNameWithLocalizableDisplayName + public class ObjectExtensionPropertyInfo : IHasNameWithLocalizableDisplayName, IBasicObjectExtensionPropertyInfo { [NotNull] public ObjectExtensionInfo ObjectExtension { get; }