mirror of https://github.com/abpframework/abp.git
13 changed files with 752 additions and 1 deletions
@ -0,0 +1,324 @@ |
|||||
|
using Blazorise; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Linq; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
using Volo.Abp.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI |
||||
|
{ |
||||
|
public static class BlazoriseUiObjectExtensionPropertyInfoExtensions |
||||
|
{ |
||||
|
private static readonly HashSet<Type> NumberTypes = new HashSet<Type> { |
||||
|
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<Type> TextEditSupportedAttributeTypes = new HashSet<Type> { |
||||
|
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-ddTHH: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<T>(this IBasicObjectExtensionPropertyInfo property, object value) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return default; |
||||
|
} |
||||
|
|
||||
|
return (T)value; |
||||
|
} |
||||
|
|
||||
|
public static bool GetBooleanInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return (bool)value; |
||||
|
} |
||||
|
|
||||
|
public static DateTime? GetDateInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return default; |
||||
|
} |
||||
|
|
||||
|
return (DateTime?)value; |
||||
|
} |
||||
|
|
||||
|
public static TimeSpan? GetTimeInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return default; |
||||
|
} |
||||
|
|
||||
|
return (TimeSpan?)value; |
||||
|
} |
||||
|
|
||||
|
public static TextInputMode GetTextInputMode(this ObjectExtensionPropertyInfo propertyInfo) |
||||
|
{ |
||||
|
foreach (var attribute in propertyInfo.Attributes) |
||||
|
{ |
||||
|
var textRoleByAttribute = GetTextInputModeFromAttributeOrNull(attribute); |
||||
|
if (textRoleByAttribute != null) |
||||
|
{ |
||||
|
return textRoleByAttribute.Value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return GetTextInputModeFromTypeOrNull(propertyInfo.Type) |
||||
|
?? TextInputMode.None; //default
|
||||
|
} |
||||
|
|
||||
|
private static TextInputMode? GetTextInputModeFromTypeOrNull(Type type) |
||||
|
{ |
||||
|
if (TypeHelper.IsFloatingType(type)) |
||||
|
{ |
||||
|
return TextInputMode.Decimal; |
||||
|
} |
||||
|
|
||||
|
if (NumberTypes.Contains(type)) |
||||
|
{ |
||||
|
return TextInputMode.Numeric; |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
private static TextInputMode? GetTextInputModeFromAttributeOrNull(Attribute attribute) |
||||
|
{ |
||||
|
if (attribute is EmailAddressAttribute) |
||||
|
{ |
||||
|
return TextInputMode.Email; |
||||
|
} |
||||
|
|
||||
|
if (attribute is UrlAttribute) |
||||
|
{ |
||||
|
return TextInputMode.Url; |
||||
|
} |
||||
|
|
||||
|
//if (attribute is HiddenInputAttribute)
|
||||
|
//{
|
||||
|
// return "hidden";
|
||||
|
//}
|
||||
|
|
||||
|
if (attribute is PhoneAttribute) |
||||
|
{ |
||||
|
return TextInputMode.Tel; |
||||
|
} |
||||
|
|
||||
|
if (attribute is DataTypeAttribute dataTypeAttribute) |
||||
|
{ |
||||
|
switch (dataTypeAttribute.DataType) |
||||
|
{ |
||||
|
case DataType.EmailAddress: |
||||
|
return TextInputMode.Email; |
||||
|
case DataType.Url: |
||||
|
return TextInputMode.Url; |
||||
|
case DataType.PhoneNumber: |
||||
|
return TextInputMode.Tel; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public static TextRole GetTextRole(this ObjectExtensionPropertyInfo propertyInfo) |
||||
|
{ |
||||
|
foreach (var attribute in propertyInfo.Attributes) |
||||
|
{ |
||||
|
var textRoleByAttribute = GetTextRoleFromAttributeOrNull(attribute); |
||||
|
if (textRoleByAttribute != null) |
||||
|
{ |
||||
|
return textRoleByAttribute.Value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return TextRole.Text; //default
|
||||
|
} |
||||
|
|
||||
|
private static TextRole? GetTextRoleFromAttributeOrNull(Attribute attribute) |
||||
|
{ |
||||
|
if (attribute is EmailAddressAttribute) |
||||
|
{ |
||||
|
return TextRole.Email; |
||||
|
} |
||||
|
|
||||
|
if (attribute is UrlAttribute) |
||||
|
{ |
||||
|
return TextRole.Url; |
||||
|
} |
||||
|
|
||||
|
//if (attribute is HiddenInputAttribute)
|
||||
|
//{
|
||||
|
// return "hidden";
|
||||
|
//}
|
||||
|
|
||||
|
//if (attribute is PhoneAttribute)
|
||||
|
//{
|
||||
|
// return TextRole.Tel;
|
||||
|
//}
|
||||
|
|
||||
|
if (attribute is DataTypeAttribute dataTypeAttribute) |
||||
|
{ |
||||
|
switch (dataTypeAttribute.DataType) |
||||
|
{ |
||||
|
case DataType.Password: |
||||
|
return TextRole.Password; |
||||
|
case DataType.EmailAddress: |
||||
|
return TextRole.Email; |
||||
|
case DataType.Url: |
||||
|
return TextRole.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(TextEdit); //default
|
||||
|
} |
||||
|
|
||||
|
private static Type GetInputTypeFromAttributeOrNull(Attribute attribute) |
||||
|
{ |
||||
|
var hasTextEditSupport = TextEditSupportedAttributeTypes.Any(t => t == attribute.GetType()); |
||||
|
|
||||
|
if (hasTextEditSupport) |
||||
|
{ |
||||
|
return typeof(TextEdit); |
||||
|
} |
||||
|
|
||||
|
//if (attribute is EmailAddressAttribute)
|
||||
|
//{
|
||||
|
// return TextInputMode.Email;
|
||||
|
//}
|
||||
|
|
||||
|
//if (attribute is UrlAttribute)
|
||||
|
//{
|
||||
|
// return TextInputMode.Url;
|
||||
|
//}
|
||||
|
|
||||
|
//if (attribute is HiddenInputAttribute)
|
||||
|
//{
|
||||
|
// return "hidden";
|
||||
|
//}
|
||||
|
|
||||
|
//if (attribute is PhoneAttribute)
|
||||
|
//{
|
||||
|
// return TextInputMode.Tel;
|
||||
|
//}
|
||||
|
|
||||
|
if (attribute is DataTypeAttribute dataTypeAttribute) |
||||
|
{ |
||||
|
switch (dataTypeAttribute.DataType) |
||||
|
{ |
||||
|
case DataType.Password: |
||||
|
return typeof(TextEdit); |
||||
|
case DataType.Date: |
||||
|
return typeof(DateEdit<>); |
||||
|
case DataType.Time: |
||||
|
return typeof(TimeEdit<>); |
||||
|
case DataType.EmailAddress: |
||||
|
return typeof(TextEdit); |
||||
|
case DataType.Url: |
||||
|
return typeof(TextEdit); |
||||
|
case DataType.PhoneNumber: |
||||
|
return typeof(TextEdit); |
||||
|
case DataType.DateTime: |
||||
|
return typeof(DateEdit<>); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
private static Type GetInputTypeFromTypeOrNull(Type type) |
||||
|
{ |
||||
|
if (type == typeof(bool)) |
||||
|
{ |
||||
|
return typeof(Check<>); |
||||
|
} |
||||
|
|
||||
|
if (type == typeof(DateTime)) |
||||
|
{ |
||||
|
return typeof(DateEdit<>); |
||||
|
} |
||||
|
|
||||
|
if (NumberTypes.Contains(type)) |
||||
|
{ |
||||
|
return typeof(TextEdit); |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
@typeparam TEntityType |
||||
|
@typeparam TResourceType |
||||
|
@using Volo.Abp.ObjectExtending |
||||
|
@using Volo.Abp.Localization |
||||
|
@using Volo.Abp.Data |
||||
|
|
||||
|
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<TEntityType>()) |
||||
|
{ |
||||
|
if (!propertyInfo.Name.EndsWith("_Text")) |
||||
|
{ |
||||
|
if (propertyInfo.Type.IsEnum) |
||||
|
{ |
||||
|
<SelectExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" /> |
||||
|
} |
||||
|
else if (!propertyInfo.Lookup.Url.IsNullOrEmpty()) |
||||
|
{ |
||||
|
<LookupExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" /> |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var inputType = propertyInfo.GetInputType(); |
||||
|
if (inputType == typeof(TextEdit)) |
||||
|
{ |
||||
|
<TextExtensionProperty TEntity="TEntityType" TResourceType="TResourceType" PropertyInfo="@propertyInfo" Entity="@Entity"> |
||||
|
|
||||
|
</TextExtensionProperty> |
||||
|
} |
||||
|
else if (inputType == typeof(Check<>)) |
||||
|
{ |
||||
|
<Field> |
||||
|
<Check TValue="bool" CheckedChanged="(val) => CheckedChanged(val, propertyInfo.Name)" Checked="@(propertyInfo.GetInputValueOrDefault<bool>(Entity.GetProperty(propertyInfo.Name)))">@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</Check> |
||||
|
</Field> |
||||
|
} |
||||
|
else if (inputType == typeof(TimeEdit<>)) |
||||
|
{ |
||||
|
<Field> |
||||
|
<FieldLabel>@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>--> |
||||
|
<TimeEdit TValue="TimeSpan?" Time="@(propertyInfo.GetInputValueOrDefault<TimeSpan?>(Entity.GetProperty(propertyInfo.Name)))" TimeChanged="(val) => TimeChanged(val, propertyInfo.Name)"> |
||||
|
<Feedback> |
||||
|
<ValidationError /> |
||||
|
</Feedback> |
||||
|
</TimeEdit> |
||||
|
</Field> |
||||
|
} |
||||
|
else if (inputType == typeof(DateEdit<>)) |
||||
|
{ |
||||
|
<Field> |
||||
|
<FieldLabel>@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
||||
|
<DateEdit TValue="DateTime?" |
||||
|
Pattern="@propertyInfo.GetDateEditInputFormatOrNull()" |
||||
|
Date="@(propertyInfo.GetInputValueOrDefault<DateTime?>(Entity.GetProperty(propertyInfo.Name)))" |
||||
|
DateChanged="(val) => DateTimeChanged(val, propertyInfo.Name)"> |
||||
|
<Feedback> |
||||
|
<ValidationError /> |
||||
|
</Feedback> |
||||
|
</DateEdit> |
||||
|
</Field> |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using System; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.Data; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
||||
|
{ |
||||
|
public partial class ExtensionProperties<TEntityType, TResourceType> : ComponentBase |
||||
|
where TEntityType : IHasExtraProperties |
||||
|
{ |
||||
|
[Inject] |
||||
|
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public AbpBlazorMessageLocalizerHelper<TResourceType> LH { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public TEntityType Entity { get; set; } |
||||
|
|
||||
|
protected void TextChanged(string value, string propertyName) |
||||
|
{ |
||||
|
Entity.SetProperty(propertyName, value); |
||||
|
} |
||||
|
|
||||
|
protected void CheckedChanged(bool value, string propertyName) |
||||
|
{ |
||||
|
Entity.SetProperty(propertyName, value); |
||||
|
} |
||||
|
|
||||
|
protected void TimeChanged(TimeSpan? value, string propertyName) |
||||
|
{ |
||||
|
Entity.SetProperty(propertyName, value); |
||||
|
} |
||||
|
|
||||
|
protected void DateTimeChanged(DateTime? value, string propertyName) |
||||
|
{ |
||||
|
Entity.SetProperty(propertyName, value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
@typeparam TEntity |
||||
|
@typeparam TResourceType |
||||
|
@using Abp.Localization |
||||
|
@using Blazorise.Components |
||||
|
|
||||
|
<Field> |
||||
|
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
||||
|
<Autocomplete Data="@lookupItems" |
||||
|
TItem="SelectItem<object>" |
||||
|
TValue="object" |
||||
|
TextField="item=>item.Text" |
||||
|
ValueField="item=>item.Value" |
||||
|
@bind-SelectedValue="@SelectedValue" |
||||
|
SearchChanged="@SearchFilterChangedAsync"> |
||||
|
</Autocomplete> |
||||
|
</Field> |
||||
@ -0,0 +1,92 @@ |
|||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Net.Http; |
||||
|
using System.Text.Json; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
||||
|
{ |
||||
|
public partial class LookupExtensionProperty<TEntity, TResourceType> : ComponentBase |
||||
|
where TEntity : IHasExtraProperties |
||||
|
{ |
||||
|
protected List<SelectItem<object>> lookupItems; |
||||
|
|
||||
|
[Inject] |
||||
|
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
||||
|
|
||||
|
[Inject] |
||||
|
public HttpClient Client { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public TEntity Entity { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public ObjectExtensionPropertyInfo PropertyInfo { get; set; } |
||||
|
|
||||
|
public object SelectedValue |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return Entity.GetProperty(PropertyInfo.Name); |
||||
|
} |
||||
|
set |
||||
|
{ |
||||
|
Entity.SetProperty(PropertyInfo.Name, value); |
||||
|
UpdateLookupTextProperty(value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public LookupExtensionProperty() |
||||
|
{ |
||||
|
lookupItems = new List<SelectItem<object>>(); |
||||
|
} |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
lookupItems = await GetLookupItemsAsync(string.Empty); |
||||
|
} |
||||
|
|
||||
|
protected virtual void UpdateLookupTextProperty(object value) |
||||
|
{ |
||||
|
var lookupPropertyName = $"{PropertyInfo.Name}_Text"; |
||||
|
var selectedItemText = lookupItems.SingleOrDefault(t => t.Value.Equals(value)).Text; |
||||
|
Entity.SetProperty(lookupPropertyName, selectedItemText); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<List<SelectItem<object>>> GetLookupItemsAsync(string filter) |
||||
|
{ |
||||
|
var selectItems = new List<SelectItem<object>>(); |
||||
|
var url = PropertyInfo.Lookup.Url; |
||||
|
if (!filter.IsNullOrEmpty()) |
||||
|
{ |
||||
|
url += $"{PropertyInfo.Lookup.FilterParamName}={filter.Trim()}"; |
||||
|
} |
||||
|
|
||||
|
var responseStream = await Client.GetStreamAsync(url); |
||||
|
|
||||
|
var document = await JsonDocument.ParseAsync(responseStream); |
||||
|
var itemsArrayProp = document.RootElement.GetProperty(PropertyInfo.Lookup.ResultListPropertyName); |
||||
|
foreach (var item in itemsArrayProp.EnumerateArray()) |
||||
|
{ |
||||
|
selectItems.Add(new SelectItem<object> |
||||
|
{ |
||||
|
Text = item.GetProperty(PropertyInfo.Lookup.DisplayPropertyName).GetString(), |
||||
|
Value = JsonSerializer.Deserialize(item.GetProperty(PropertyInfo.Lookup.ValuePropertyName).GetRawText(), PropertyInfo.Type) |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return selectItems; |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task SearchFilterChangedAsync(string filter) |
||||
|
{ |
||||
|
lookupItems = await GetLookupItemsAsync(filter); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
@typeparam TEntity |
||||
|
@typeparam TResourceType |
||||
|
@using Abp.Localization |
||||
|
|
||||
|
<Field> |
||||
|
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
||||
|
<Select TValue="int" SelectedValue="@SelectedValue" SelectedValueChanged="@SelectedValueChanged"> |
||||
|
@foreach (var item in GetSelectItemsFromEnum()) |
||||
|
{ |
||||
|
<SelectItem Value="@item.Value">@item.Text</SelectItem> |
||||
|
} |
||||
|
</Select> |
||||
|
</Field> |
||||
@ -0,0 +1,84 @@ |
|||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
||||
|
{ |
||||
|
public partial class SelectExtensionProperty<TEntity, TResourceType> : ComponentBase |
||||
|
where TEntity : IHasExtraProperties |
||||
|
{ |
||||
|
[Inject] |
||||
|
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public TEntity Entity { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public ObjectExtensionPropertyInfo PropertyInfo { get; set; } |
||||
|
|
||||
|
public int SelectedValue |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return Entity.GetProperty<int>(PropertyInfo.Name); |
||||
|
} |
||||
|
set |
||||
|
{ |
||||
|
Entity.SetProperty(PropertyInfo.Name, value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual IEnumerable<SelectItem<int>> GetSelectItemsFromEnum() |
||||
|
{ |
||||
|
var isNullableType = Nullable.GetUnderlyingType(PropertyInfo.Type) != null; |
||||
|
var enumType = PropertyInfo.Type; |
||||
|
|
||||
|
if (isNullableType) |
||||
|
{ |
||||
|
enumType = Nullable.GetUnderlyingType(PropertyInfo.Type); |
||||
|
yield return new SelectItem<int>(); |
||||
|
} |
||||
|
|
||||
|
foreach (var enumValue in enumType.GetEnumValues()) |
||||
|
{ |
||||
|
var memberName = enumType.GetEnumName(enumValue); |
||||
|
var localizedMemberName = AbpInternalLocalizationHelper.LocalizeWithFallback( |
||||
|
new[] |
||||
|
{ |
||||
|
// containerLocalizer,
|
||||
|
StringLocalizerFactory.CreateDefaultOrNull() |
||||
|
}, |
||||
|
new[] |
||||
|
{ |
||||
|
$"Enum:{enumType.Name}.{memberName}", |
||||
|
$"{enumType.Name}.{memberName}", |
||||
|
memberName |
||||
|
}, |
||||
|
memberName |
||||
|
); |
||||
|
|
||||
|
yield return new SelectItem<int> |
||||
|
{ |
||||
|
Value = (int)enumValue, |
||||
|
Text = localizedMemberName |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
protected virtual void SelectedValueChanged(int value) |
||||
|
{ |
||||
|
SelectedValue = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class SelectItem<TValue> |
||||
|
{ |
||||
|
public string Text { get; set; } |
||||
|
public TValue Value { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
@typeparam TEntity |
||||
|
@typeparam TResourceType |
||||
|
@using Volo.Abp.BlazoriseUI |
||||
|
@using Volo.Abp.Localization |
||||
|
|
||||
|
@if (PropertyInfo != null && Entity != null) |
||||
|
{ |
||||
|
<Field> |
||||
|
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
||||
|
<TextEdit @bind-Text="@Value" Role="@PropertyInfo.GetTextRole()" InputMode="@PropertyInfo.GetTextInputMode()"> |
||||
|
<Feedback> |
||||
|
<ValidationError /> |
||||
|
</Feedback> |
||||
|
</TextEdit> |
||||
|
</Field> |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
|
||||
|
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
||||
|
{ |
||||
|
public partial class TextExtensionProperty<TEntity, TResourceType> : ComponentBase |
||||
|
where TEntity : IHasExtraProperties |
||||
|
{ |
||||
|
[Inject] |
||||
|
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public TEntity Entity { get; set; } |
||||
|
|
||||
|
[Parameter] |
||||
|
public ObjectExtensionPropertyInfo PropertyInfo { get; set; } |
||||
|
|
||||
|
|
||||
|
protected string Value |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return PropertyInfo.GetTextInputValueOrNull(Entity.GetProperty(PropertyInfo.Name)); |
||||
|
} |
||||
|
set |
||||
|
{ |
||||
|
Entity.SetProperty(PropertyInfo.Name, value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.ObjectExtending |
||||
|
{ |
||||
|
public static class ObjectExtensionPropertyInfoBlazorExtensions |
||||
|
{ |
||||
|
private static readonly Type[] DateTimeTypes = |
||||
|
{ |
||||
|
typeof(DateTime), |
||||
|
typeof(DateTime?), |
||||
|
typeof(DateTimeOffset), |
||||
|
typeof(DateTimeOffset?) |
||||
|
}; |
||||
|
|
||||
|
public static bool IsDate(this IBasicObjectExtensionPropertyInfo property) |
||||
|
{ |
||||
|
return DateTimeTypes.Contains(property.Type) && |
||||
|
property.GetDataTypeOrNull() == DataType.Date; |
||||
|
} |
||||
|
|
||||
|
public static bool IsDateTime(this IBasicObjectExtensionPropertyInfo property) |
||||
|
{ |
||||
|
return DateTimeTypes.Contains(property.Type) && |
||||
|
!property.IsDate(); |
||||
|
} |
||||
|
|
||||
|
public static DataType? GetDataTypeOrNull(this IBasicObjectExtensionPropertyInfo property) |
||||
|
{ |
||||
|
return property |
||||
|
.Attributes |
||||
|
.OfType<DataTypeAttribute>() |
||||
|
.FirstOrDefault()?.DataType; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue