Browse Source

Merge pull request #7686 from abpframework/blazor-module-extensions

Blazor module extensions
pull/6647/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
8f90168189
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/Extensibility/TableColumns/TableColumn.cs
  2. 49
      framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
  3. 261
      framework/src/Volo.Abp.BlazoriseUI/BlazoriseUiObjectExtensionPropertyInfoExtensions.cs
  4. 60
      framework/src/Volo.Abp.BlazoriseUI/Components/AbpExtensibleDataGrid.razor
  5. 8
      framework/src/Volo.Abp.BlazoriseUI/Components/AbpExtensibleDataGrid.razor.cs
  6. 11
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor
  7. 32
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs
  8. 17
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
  9. 37
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs
  10. 33
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/EnumHelper.cs
  11. 29
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor
  12. 21
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs
  13. 18
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor
  14. 149
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs
  15. 13
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor
  16. 61
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor.cs
  17. 14
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor
  18. 33
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor.cs
  19. 13
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor
  20. 37
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor.cs
  21. 40
      framework/src/Volo.Abp.BlazoriseUI/ObjectExtensionPropertyInfoBlazorExtensions.cs
  22. 28
      framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj
  23. 27
      modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs
  24. 3
      modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor
  25. 8
      modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs
  26. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/global.css
  27. 60
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/global.js
  28. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/index.html

13
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/Extensibility/TableColumns/TableColumn.cs

@ -1,28 +1,25 @@
using JetBrains.Annotations;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Components.Extensibility.EntityActions;
namespace Volo.Abp.AspNetCore.Components.Extensibility.TableColumns
{
public class TableColumn : IEquatable<TableColumn>
public class TableColumn
{
public string Title { get; set; }
public string Data { get; set; }
[CanBeNull]
public string DisplayFormat { get; set; }
[CanBeNull]
public Type Component { get; set; }
public List<EntityAction> Actions { get; set; }
[CanBeNull]
public Func<object,string> ValueConverter { get; set; }
public TableColumn()
{
Actions = new List<EntityAction>();
}
public bool Equals(TableColumn other)
{
return string.Equals(Title, other?.Title, StringComparison.OrdinalIgnoreCase) &&
string.Equals(Data, other?.Data, StringComparison.OrdinalIgnoreCase);
}
}
}

49
framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs

@ -15,9 +15,12 @@ using Volo.Abp.Application.Services;
using Volo.Abp.AspNetCore.Components;
using Volo.Abp.AspNetCore.Components.Extensibility.EntityActions;
using Volo.Abp.AspNetCore.Components.Extensibility.TableColumns;
using Volo.Abp.AspNetCore.Components.WebAssembly;
using Volo.Abp.Localization;
using Volo.Abp.Authorization;
using Volo.Abp.BlazoriseUI.Components;
using Volo.Abp.BlazoriseUI.Components.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI
{
@ -476,10 +479,52 @@ namespace Volo.Abp.BlazoriseUI
{
return ValueTask.CompletedTask;
}
protected virtual ValueTask SetToolbarItemsAsync()
{
return ValueTask.CompletedTask;
}
protected virtual IEnumerable<TableColumn> 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, StringLocalizerFactory);
}
yield return column;
}
}
}
}
}
}

261
framework/src/Volo.Abp.BlazoriseUI/BlazoriseUiObjectExtensionPropertyInfoExtensions.cs

@ -0,0 +1,261 @@
using Blazorise;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Volo.Abp.BlazoriseUI.Components.ObjectExtending;
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 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 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 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(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;
}
}
}

60
framework/src/Volo.Abp.BlazoriseUI/Components/AbpExtensibleDataGrid.razor

@ -1,7 +1,7 @@
@typeparam TItem
@using Blazorise.DataGrid;
@using Volo.Abp.AspNetCore.Components.Extensibility
@using Volo.Abp.Data
@using Volo.Abp.BlazoriseUI.Components.ObjectExtending
<DataGrid TItem="TItem"
Data="@Data"
@ -47,7 +47,7 @@
{
@if (column.Component != null)
{
<DataGridColumn TItem="TItem" Field="@column.Data" Caption="@column.Title">
<DataGridColumn TItem="TItem" Field="@typeof(TItem).GetProperties().First().Name" Caption="@column.Title">
<DisplayTemplate>
@RenderCustomTableColumnComponent(column.Component, context)
</DisplayTemplate>
@ -55,7 +55,59 @@
}
else
{
<DataGridColumn TItem="TItem" Field="@column.Data" Caption="@column.Title"/>
if (!ExtensionPropertiesRegex.IsMatch(column.Data))
{
<DataGridColumn TItem="TItem" Field="@column.Data" Caption="@column.Title"/>
}
else
{
<DataGridColumn TItem="TItem" Field="@nameof(IHasExtraProperties.ExtraProperties)" Caption="@column.Title">
<DisplayTemplate>
@{
var entity = context as IHasExtraProperties;
var propertyName = ExtensionPropertiesRegex.Match(column.Data).Groups[1].Value;
var propertyValue = entity.GetProperty(propertyName);
if (propertyValue != null && propertyValue.GetType() == typeof(bool))
{
if ((bool) propertyValue)
{
<Icon class="text-success" Name="IconName.Check"/>
}
else
{
<Icon class="text-danger" Name="IconName.Times"/>
}
}
else
{
if (column.ValueConverter != null)
{
if (column.DisplayFormat == null)
{
@(column.ValueConverter(propertyValue))
}
else
{
@(string.Format(column.DisplayFormat, column.ValueConverter(propertyValue)))
}
}
else
{
if (column.DisplayFormat == null)
{
@(propertyValue)
}
else
{
@(string.Format(column.DisplayFormat, propertyValue))
}
}
}
}
</DisplayTemplate>
</DataGridColumn>
}
}
}
}

8
framework/src/Volo.Abp.BlazoriseUI/Components/AbpExtensibleDataGrid.razor.cs

@ -5,6 +5,9 @@ using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.AspNetCore.Components.Extensibility.TableColumns;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Localization;
namespace Volo.Abp.BlazoriseUI.Components
{
@ -15,6 +18,8 @@ namespace Volo.Abp.BlazoriseUI.Components
protected Dictionary<string, DataGridEntityActionsColumn<TItem>> ActionColumns =
new Dictionary<string, DataGridEntityActionsColumn<TItem>>();
protected Regex ExtensionPropertiesRegex = new Regex(@"ExtraProperties\[(.*?)\]");
[Parameter] public IEnumerable<TItem> Data { get; set; }
[Parameter] public EventCallback<DataGridReadDataEventArgs<TItem>> ReadData { get; set; }
@ -27,6 +32,9 @@ namespace Volo.Abp.BlazoriseUI.Components
[Parameter] public IEnumerable<TableColumn> Columns { get; set; }
[Inject]
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
protected virtual RenderFragment RenderCustomTableColumnComponent(Type type, object data)
{
return (builder) =>

11
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor

@ -0,0 +1,11 @@
@typeparam TEntity
@typeparam TResourceType
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@if (PropertyInfo != null && Entity != null)
{
<Field>
<Check TValue="bool" @bind-Checked="@Value">@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</Check>
</Field>
}

32
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs

@ -0,0 +1,32 @@
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 CheckExtensionProperty<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 bool Value
{
get
{
return PropertyInfo.GetInputValueOrDefault<bool>(Entity.GetProperty(PropertyInfo.Name));
}
set
{
Entity.SetProperty(PropertyInfo.Name, value, false);
}
}
}
}

17
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor

@ -0,0 +1,17 @@
@typeparam TEntity
@typeparam TResourceType
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@if (PropertyInfo != null && Entity != null)
{
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<DateEdit TValue="DateTime?"
InputMode="@(PropertyInfo.IsDate() ? DateInputMode.Date : DateInputMode.DateTime)"
Pattern="@PropertyInfo.GetDateEditInputFormatOrNull()"
@bind-Date="@Value">
</DateEdit>
</Field>
}

37
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending
{
public partial class DateTimeExtensionProperty<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 DateTime? Value
{
get
{
return PropertyInfo.GetInputValueOrDefault<DateTime?>(Entity.GetProperty(PropertyInfo.Name));
}
set
{
Entity.SetProperty(PropertyInfo.Name, value, false);
}
}
}
}

33
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/EnumHelper.cs

@ -0,0 +1,33 @@
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Localization;
namespace Volo.Abp.BlazoriseUI.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;
}
}
}

29
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor

@ -0,0 +1,29 @@
@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();
__builder.OpenComponent(0, inputType.MakeGenericType(new[] { typeof(TEntityType), typeof(TResourceType) }));
__builder.AddAttribute(1, "PropertyInfo", propertyInfo);
__builder.AddAttribute(2, "Entity", Entity);
__builder.CloseComponent();
}
}
}

21
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs

@ -0,0 +1,21 @@
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; }
}
}

18
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor

@ -0,0 +1,18 @@
@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"
SelectedValue="@SelectedValue"
SelectedValueChanged="@SelectedValueChanged"
SearchChanged="@SearchFilterChangedAsync">
</Autocomplete>
</Field>

149
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs

@ -0,0 +1,149 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.Http;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.MultiTenancy;
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; }
[Parameter]
public TEntity Entity { get; set; }
[Parameter]
public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
[Inject]
public IRemoteServiceHttpClientAuthenticator ClientAuthenticator { get; set; }
[Inject]
public IHttpClientFactory HttpClientFactory { get; set; }
[Inject]
public ICurrentTenant CurrentTenant { get; set; }
[Inject]
public IOptions<AbpRemoteServiceOptions> RemoteServiceOptions { get; set; }
public string TextPropertyName => PropertyInfo.Name + "_Text";
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 void OnParametersSet()
{
var value = Entity.GetProperty(PropertyInfo.Name);
if (value != null)
{
lookupItems.Add(new SelectItem<object>
{
Text = Entity.GetProperty(TextPropertyName).ToString(),
Value = value
});
}
}
protected virtual void UpdateLookupTextProperty(object value)
{
var selectedItemText = lookupItems.SingleOrDefault(t => t.Value.Equals(value)).Text;
Entity.SetProperty(TextPropertyName, selectedItemText);
}
protected virtual async Task<List<SelectItem<object>>> GetLookupItemsAsync(string filter)
{
var selectItems = new List<SelectItem<object>>();
var url = PropertyInfo.Lookup.Url;
var uri = new Uri(url, UriKind.RelativeOrAbsolute);
if (!filter.IsNullOrEmpty())
{
url += $"?{PropertyInfo.Lookup.FilterParamName}={filter.Trim()}";
}
var client = HttpClientFactory.CreateClient();
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
AddHeaders(requestMessage);
if (!uri.IsAbsoluteUri)
{
var remoteServiceConfig = RemoteServiceOptions.Value.RemoteServices.GetConfigurationOrDefault("Default");
client.BaseAddress = new Uri(remoteServiceConfig.BaseUrl);
await ClientAuthenticator.Authenticate(new RemoteServiceHttpClientAuthenticateContext(client, requestMessage, new RemoteServiceConfiguration(remoteServiceConfig.BaseUrl), string.Empty));
}
var response = await client.SendAsync(requestMessage);
var document = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
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 void SelectedValueChanged(object selectedItem)
{
SelectedValue = selectedItem;
}
protected async Task SearchFilterChangedAsync(string filter)
{
lookupItems = await GetLookupItemsAsync(filter);
}
protected virtual void AddHeaders(HttpRequestMessage requestMessage)
{
if (CurrentTenant.Id.HasValue)
{
requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString());
}
var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name;
if (!currentCulture.IsNullOrEmpty())
{
requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(currentCulture));
}
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MimeTypes.Application.Json));
}
}
}

13
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor

@ -0,0 +1,13 @@
@typeparam TEntity
@typeparam TResourceType
@using Abp.Localization
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<Select @bind-SelectedValue="@SelectedValue" >
@foreach (var item in SelectItems)
{
<SelectItem Value="@item.Value">@item.Text</SelectItem>
}
</Select>
</Field>

61
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor.cs

@ -0,0 +1,61 @@
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
{
protected List<SelectItem<int>> SelectItems = new ();
[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, false); }
}
protected virtual List<SelectItem<int>> GetSelectItemsFromEnum()
{
var selectItems = new List<SelectItem<int>>();
foreach (var enumValue in PropertyInfo.Type.GetEnumValues())
{
selectItems.Add( new SelectItem<int>
{
Value = (int) enumValue,
Text = EnumHelper.GetLocalizedMemberName(PropertyInfo.Type, enumValue, StringLocalizerFactory)
});
}
return selectItems;
}
protected override void OnParametersSet()
{
SelectItems = GetSelectItemsFromEnum();
StateHasChanged();
if (!Entity.HasProperty(PropertyInfo.Name))
{
SelectedValue = (int)PropertyInfo.Type.GetEnumValues().GetValue(0);
}
}
}
public class SelectItem<TValue>
{
public string Text { get; set; }
public TValue Value { get; set; }
}
}

14
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor

@ -0,0 +1,14 @@
@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()">
</TextEdit>
</Field>
}

33
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor.cs

@ -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);
}
}
}
}

13
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor

@ -0,0 +1,13 @@
@typeparam TEntity
@typeparam TResourceType
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@if (PropertyInfo != null && Entity != null)
{
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>-->
<TimeEdit TValue="TimeSpan?" @bind-Time="@Value">
</TimeEdit>
</Field>
}

37
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor.cs

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending
{
public partial class TimeExtensionProperty<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 TimeSpan? Value
{
get
{
return PropertyInfo.GetInputValueOrDefault<TimeSpan?>(Entity.GetProperty(PropertyInfo.Name));
}
set
{
Entity.SetProperty(PropertyInfo.Name, value, false);
}
}
}
}

40
framework/src/Volo.Abp.BlazoriseUI/ObjectExtensionPropertyInfoBlazorExtensions.cs

@ -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;
}
}
}

28
framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj

@ -1,20 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly\Volo.Abp.AspNetCore.Components.WebAssembly.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Blazorise" Version="0.9.3-preview8" />
<PackageReference Include="Blazorise.DataGrid" Version="0.9.3-preview8" />
<PackageReference Include="Blazorise.Snackbar" Version="0.9.3-preview8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly\Volo.Abp.AspNetCore.Components.WebAssembly.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Blazorise" Version="0.9.3-preview8" />
<PackageReference Include="Blazorise.DataGrid" Version="0.9.3-preview8" />
<PackageReference Include="Blazorise.Snackbar" Version="0.9.3-preview8" />
<PackageReference Include="Blazorise.Components" Version="0.9.3-preview8" />
</ItemGroup>
</Project>

27
modules/identity/src/Volo.Abp.Identity.Blazor/AbpIdentityBlazorModule.cs

@ -3,7 +3,10 @@ using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing;
using Volo.Abp.AutoMapper;
using Volo.Abp.BlazoriseUI;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.PermissionManagement.Blazor;
using Volo.Abp.Threading;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Identity.Blazor
@ -16,6 +19,8 @@ namespace Volo.Abp.Identity.Blazor
)]
public class AbpIdentityBlazorModule : AbpModule
{
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpIdentityBlazorModule>();
@ -35,5 +40,27 @@ namespace Volo.Abp.Identity.Blazor
options.AdditionalAssemblies.Add(typeof(AbpIdentityBlazorModule).Assembly);
});
}
public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
IdentityModuleExtensionConsts.ModuleName,
IdentityModuleExtensionConsts.EntityNames.Role,
createFormTypes: new[] { typeof(IdentityRoleCreateDto) },
editFormTypes: new[] { typeof(IdentityRoleUpdateDto) }
);
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
IdentityModuleExtensionConsts.ModuleName,
IdentityModuleExtensionConsts.EntityNames.User,
createFormTypes: new[] { typeof(IdentityUserCreateDto) },
editFormTypes: new[] { typeof(IdentityUserUpdateDto) }
);
});
}
}
}

3
modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor

@ -7,6 +7,7 @@
@using Microsoft.Extensions.Localization
@using Volo.Abp.Identity.Localization
@using Volo.Abp.AspNetCore.Components.WebAssembly.Theming
@using Volo.Abp.BlazoriseUI.Components.ObjectExtending
@inject AbpBlazorMessageLocalizerHelper<IdentityResource> LH
@inherits AbpCrudPageBase<IIdentityRoleAppService, IdentityRoleDto, Guid, GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleUpdateDto>
@ -53,6 +54,7 @@
</Feedback>
</TextEdit>
</Field>
<ExtensionProperties TEntityType="IdentityRoleCreateDto" TResourceType="IdentityResource" Entity="@NewEntity" LH="@LH"/>
</Validation>
<Field>
<Check TValue="bool" @bind-Checked="@NewEntity.IsDefault">@L["DisplayName:IsDefault"]</Check>
@ -91,6 +93,7 @@
</Feedback>
</TextEdit>
</Field>
<ExtensionProperties TEntityType="IdentityRoleUpdateDto" TResourceType="IdentityResource" Entity="@EditingEntity" LH="@LH" />
</Validation>
<Field>
<Check TValue="bool" @bind-Checked="@EditingEntity.IsDefault">@L["DisplayName:IsDefault"]</Check>

8
modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs

@ -8,6 +8,8 @@ using Volo.Abp.AspNetCore.Components.Extensibility.TableColumns;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.PageToolbars;
using Volo.Abp.Identity.Localization;
using Volo.Abp.PermissionManagement.Blazor.Components;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Data;
namespace Volo.Abp.Identity.Blazor.Pages.Identity
{
@ -23,7 +25,7 @@ namespace Volo.Abp.Identity.Blazor.Pages.Identity
protected PageToolbar Toolbar { get; set; }
private List<TableColumn> RoleManagementTableColumns => TableColumns.Get<RoleManagement>();
protected List<TableColumn> RoleManagementTableColumns => TableColumns.Get<RoleManagement>();
public RoleManagement()
{
@ -76,8 +78,7 @@ namespace Volo.Abp.Identity.Blazor.Pages.Identity
protected override ValueTask SetTableColumnsAsync()
{
TableColumns
.Get<RoleManagement>()
RoleManagementTableColumns
.AddRange(new TableColumn[]
{
new TableColumn
@ -93,6 +94,7 @@ namespace Volo.Abp.Identity.Blazor.Pages.Identity
},
});
RoleManagementTableColumns.AddRange(GetExtensionTableColumns(IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.Role));
return base.SetTableColumnsAsync();
}

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/global.css

File diff suppressed because one or more lines are too long

60
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/global.js

File diff suppressed because one or more lines are too long

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/index.html

@ -8,7 +8,7 @@
<base href="/" />
<!--ABP:Styles-->
<link href="global.css?_v=637453952859170535" rel="stylesheet"/>
<link href="global.css?_v=637478857386074368" rel="stylesheet"/>
<link href="main.css" rel="stylesheet"/>
<!--/ABP:Styles-->
</head>
@ -22,7 +22,7 @@
</div>
<!--ABP:Scripts-->
<script src="global.js?_v=637453952867128601"></script>
<script src="global.js?_v=637478857393944411"></script>
<!--/ABP:Scripts-->
</body>

Loading…
Cancel
Save